From: <sag...@us...> - 2013-02-19 02:28:50
|
Revision: 1539 http://sourceforge.net/p/modplug/code/1539 Author: saga-games Date: 2013-02-19 02:28:38 +0000 (Tue, 19 Feb 2013) Log Message: ----------- [New] Experimental support for IT-compressed samples in IT/MPTM files. To enable, set ITCompressionMono=1 and/or ITCompressionStereo=0 in mptrack.ini's [Misc] section, set ITCompressionVerification=1 to verify if samples are compressed correctly. Compressed stereo samples won't load in older versions of OpenMPT, and compressed samples will cause trouble in general with some versions (because of how the hacked-on extra info after the sample data block is searched). [Mod] OpenMPT: Version is now 1.21.01.15 Modified Paths: -------------- trunk/OpenMPT/common/version.h trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters trunk/OpenMPT/soundlib/ITTools.cpp trunk/OpenMPT/soundlib/ITTools.h trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_itp.cpp trunk/OpenMPT/soundlib/SampleFormats.cpp trunk/OpenMPT/soundlib/SampleIO.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/common/version.h =================================================================== --- trunk/OpenMPT/common/version.h 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/common/version.h 2013-02-19 02:28:38 UTC (rev 1539) @@ -19,7 +19,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 21 #define VER_MINOR 01 -#define VER_MINORMINOR 14 +#define VER_MINORMINOR 15 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2013-02-19 02:28:38 UTC (rev 1539) @@ -1811,13 +1811,16 @@ StringFixer::SetNullTerminator(szFileName); SanitizeFilename(szFileName); + int index = 0; FileDlgResult files = CTrackApp::ShowOpenSaveFileDialog(false, (m_pSndFile->GetType() == MOD_TYPE_XM) ? "xi" : "iti", szFileName, (m_pSndFile->GetType() == MOD_TYPE_XM) ? "FastTracker II Instruments (*.xi)|*.xi|" - "Impulse Tracker Instruments (*.iti)|*.iti||" : "Impulse Tracker Instruments (*.iti)|*.iti|" + "Compressed Impulse Tracker Instruments (*.iti)|*.iti||" : + "Impulse Tracker Instruments (*.iti)|*.iti|" + "Compressed Impulse Tracker Instruments (*.iti)|*.iti|" "FastTracker II Instruments (*.xi)|*.xi||", - CMainFrame::GetSettings().GetWorkingDirectory(DIR_INSTRUMENTS)); + CMainFrame::GetSettings().GetWorkingDirectory(DIR_INSTRUMENTS), false, &index); if(files.abort) return; BeginWaitCursor(); @@ -1825,7 +1828,7 @@ _splitpath(files.first_file.c_str(), drive, path, NULL, ext); BOOL bOk = FALSE; if (!lstrcmpi(ext, ".iti")) - bOk = m_pSndFile->SaveITIInstrument(m_nInstrument, files.first_file.c_str()); + bOk = m_pSndFile->SaveITIInstrument(m_nInstrument, files.first_file.c_str(), index == (m_pSndFile->GetType() == MOD_TYPE_XM ? 3 : 2)); else bOk = m_pSndFile->SaveXIInstrument(m_nInstrument, files.first_file.c_str()); Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2013-02-19 02:28:38 UTC (rev 1539) @@ -513,7 +513,7 @@ const bool xi = _stricmp(&m_SndFile.m_szInstrumentPath[i][len - 2],"xi") == 0; if(iti || (!iti && !xi && m_SndFile.m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) - m_SndFile.SaveITIInstrument(i+1, m_SndFile.m_szInstrumentPath[i]); + m_SndFile.SaveITIInstrument(i+1, m_SndFile.m_szInstrumentPath[i], false); if(xi || (!xi && !iti && m_SndFile.m_nType == MOD_TYPE_XM)) m_SndFile.SaveXIInstrument(i+1, m_SndFile.m_szInstrumentPath[i]); } @@ -2106,10 +2106,10 @@ if(pat != PATTERNINDEX_INVALID) { ORDERINDEX ord = 0; - for(ORDERINDEX i = 0; i < m_SndFile.Order.size(); i++) + for (ORDERINDEX i = 0; i < m_SndFile.Order.size(); i++) { - if(m_SndFile.Order[i] == pat) ord = i; - if(m_SndFile.Order[i] == m_SndFile.Order.GetInvalidPatIndex()) break; + if (m_SndFile.Order[i] == pat) ord = i; + if (m_SndFile.Order[i] == m_SndFile.Order.GetInvalidPatIndex()) break; } ViewPattern(pat, ord); } @@ -2120,7 +2120,7 @@ //---------------------------- { SAMPLEINDEX smp = InsertSample(); - if(smp != SAMPLEINDEX_INVALID) ViewSample(smp); + if (smp != SAMPLEINDEX_INVALID) ViewSample(smp); } @@ -2128,7 +2128,7 @@ //-------------------------------- { INSTRUMENTINDEX ins = InsertInstrument(); - if(ins != INSTRUMENTINDEX_INVALID) ViewInstrument(ins); + if (ins != INSTRUMENTINDEX_INVALID) ViewInstrument(ins); } Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2013-02-19 02:28:38 UTC (rev 1539) @@ -1584,7 +1584,7 @@ //------------------------------------ { TV_INSERTSTRUCT tvis; - CHAR s[_MAX_PATH+32], szPath[_MAX_PATH] = ""; + char s[_MAX_PATH+32], szPath[_MAX_PATH] = ""; if (!m_hInsLib) return; SetRedraw(FALSE); @@ -1716,7 +1716,7 @@ const size_t len = strlen(s); for(size_t i = 0; i < len; i++) { - s[i] = tolower(s[i + 1]); + s[i] = (char)tolower(s[i + 1]); } } @@ -3190,7 +3190,7 @@ BOOL xi = _stricmp(&pSndFile->m_szInstrumentPath[modItemID - 1][size-2],"xi") == 0; if(iti || (!iti && !xi && pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) - pSndFile->SaveITIInstrument((INSTRUMENTINDEX)modItemID, pSndFile->m_szInstrumentPath[modItemID - 1]); + pSndFile->SaveITIInstrument((INSTRUMENTINDEX)modItemID, pSndFile->m_szInstrumentPath[modItemID - 1], false); if(xi || (!xi && !iti && pSndFile->m_nType == MOD_TYPE_XM)) pSndFile->SaveXIInstrument((INSTRUMENTINDEX)modItemID, pSndFile->m_szInstrumentPath[modItemID - 1]); Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2013-02-19 02:28:38 UTC (rev 1539) @@ -489,6 +489,10 @@ > </File> <File + RelativePath="..\soundlib\ITCompression.cpp" + > + </File> + <File RelativePath="..\common\serialization_utils.cpp" > </File> @@ -1031,6 +1035,10 @@ > </File> <File + RelativePath="..\soundlib\ITCompression.h" + > + </File> + <File RelativePath="..\common\serialization_utils.h" > </File> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2013-02-19 02:28:38 UTC (rev 1539) @@ -172,6 +172,7 @@ <ClCompile Include="..\common\AudioCriticalSection.cpp" /> <ClCompile Include="..\common\misc_util.cpp" /> <ClCompile Include="..\common\Reporting.cpp" /> + <ClCompile Include="..\soundlib\ITCompression.cpp" /> <ClCompile Include="..\soundlib\ITTools.cpp" /> <ClCompile Include="..\soundlib\MIDIEvents.cpp" /> <ClCompile Include="..\soundlib\MIDIMacros.cpp" /> @@ -329,6 +330,7 @@ <ClInclude Include="..\common\typedefs.h" /> <ClInclude Include="..\soundlib\ChunkReader.h" /> <ClInclude Include="..\soundlib\FileReader.h" /> + <ClInclude Include="..\soundlib\ITCompression.h" /> <ClInclude Include="..\soundlib\ITTools.h" /> <ClInclude Include="..\soundlib\MIDIEvents.h" /> <ClInclude Include="..\soundlib\MIDIMacros.h" /> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2013-02-19 02:28:38 UTC (rev 1539) @@ -424,6 +424,9 @@ <ClCompile Include="VstPresets.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\soundlib\ITCompression.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="AbstractVstEditor.h"> @@ -753,6 +756,9 @@ <ClInclude Include="VstPresets.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\soundlib\ITCompression.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="res\bitmap1.bmp"> Modified: trunk/OpenMPT/soundlib/ITTools.cpp =================================================================== --- trunk/OpenMPT/soundlib/ITTools.cpp 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/soundlib/ITTools.cpp 2013-02-19 02:28:38 UTC (rev 1539) @@ -467,8 +467,8 @@ // Convert OpenMPT's internal sample representation to an ITSample. -void ITSample::ConvertToIT(const ModSample &mptSmp, MODTYPE fromType) -//------------------------------------------------------------------- +void ITSample::ConvertToIT(const ModSample &mptSmp, MODTYPE fromType, bool compress, bool compressIT215) +//------------------------------------------------------------------------------------------------------ { MemsetZero(*this); @@ -502,6 +502,15 @@ flags |= ITSample::sample16Bit; } cvt = ITSample::cvtSignedSample; + + if(compress) + { + flags |= ITSample::sampleCompressed; + if(compressIT215) + { + cvt |= ITSample::cvtIT215Compression; + } + } } else { flags = 0x00; Modified: trunk/OpenMPT/soundlib/ITTools.h =================================================================== --- trunk/OpenMPT/soundlib/ITTools.h 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/soundlib/ITTools.h 2013-02-19 02:28:38 UTC (rev 1539) @@ -291,7 +291,7 @@ void ConvertEndianness(); // Convert OpenMPT's internal sample representation to an ITSample. - void ConvertToIT(const ModSample &mptSmp, MODTYPE fromType); + void ConvertToIT(const ModSample &mptSmp, MODTYPE fromType, bool compress, bool compressIT215); // Convert an ITSample to OpenMPT's internal sample representation. size_t ConvertToMPT(ModSample &mptSmp) const; // Retrieve the internal sample format flags for this instrument. Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2013-02-19 02:28:38 UTC (rev 1539) @@ -651,16 +651,12 @@ } // Load instrument and song extensions. - if(mptStartPos >= file.GetPosition()) + LoadExtendedInstrumentProperties(file, &interpretModPlugMade); + if(interpretModPlugMade) { - if(interpretModPlugMade) - { - m_nMixLevels = mixLevels_original; - } - FileReader chunk = file.GetChunk(mptStartPos - file.GetPosition()); - LoadExtendedInstrumentProperties(chunk, &interpretModPlugMade); - LoadExtendedSongProperties(GetType(), chunk, &interpretModPlugMade); + m_nMixLevels = mixLevels_original; } + LoadExtendedSongProperties(GetType(), file, &interpretModPlugMade); const PATTERNINDEX numPats = Util::Min(static_cast<PATTERNINDEX>(patPos.size()), GetModSpecifications().patternsMax); @@ -859,7 +855,7 @@ // 0-64: Set Volume if(vol <= 64) { m[ch].volcmd = VOLCMD_VOLUME; m[ch].vol = vol; } else // 128-192: Set Panning - if((vol >= 128) && (vol <= 192)) { m[ch].volcmd = VOLCMD_PANNING; m[ch].vol = vol - 128; } else + if(vol >= 128 && vol <= 192) { m[ch].volcmd = VOLCMD_PANNING; m[ch].vol = vol - 128; } else // 65-74: Fine Volume Up if(vol < 75) { m[ch].volcmd = VOLCMD_FINEVOLUP; m[ch].vol = vol - 65; } else // 75-84: Fine Volume Down @@ -873,18 +869,18 @@ // 115-124: Pitch Slide Down if(vol < 125) { m[ch].volcmd = VOLCMD_PORTAUP; m[ch].vol = vol - 115; } else // 193-202: Portamento To - if((vol >= 193) && (vol <= 202)) { m[ch].volcmd = VOLCMD_TONEPORTAMENTO; m[ch].vol = vol - 193; } else + if(vol >= 193 && vol <= 202) { m[ch].volcmd = VOLCMD_TONEPORTAMENTO; m[ch].vol = vol - 193; } else // 203-212: Vibrato depth - if((vol >= 203) && (vol <= 212)) + if(vol >= 203 && vol <= 212) { m[ch].volcmd = VOLCMD_VIBRATODEPTH; m[ch].vol = vol - 203; - // Old versions of ModPlug saved this as vibrato speed instead, so let's fix that - if(m_dwLastSavedWithVersion && m_dwLastSavedWithVersion <= MAKE_VERSION_NUMERIC(1, 17, 02, 54)) + // Old versions of ModPlug saved this as vibrato speed instead, so let's fix that. + if(m[ch].vol && m_dwLastSavedWithVersion && m_dwLastSavedWithVersion <= MAKE_VERSION_NUMERIC(1, 17, 02, 54)) m[ch].volcmd = VOLCMD_VIBRATOSPEED; } else // 213-222: Unused (was velocity) // 223-232: Offset - if((vol >= 223) && (vol <= 232)) { m[ch].volcmd = VOLCMD_OFFSET; m[ch].vol = vol - 223; } + if(vol >= 223 && vol <= 232) { m[ch].volcmd = VOLCMD_OFFSET; m[ch].vol = vol - 223; } lastValue[ch].volcmd = m[ch].volcmd; lastValue[ch].vol = m[ch].vol; } @@ -1027,6 +1023,9 @@ #pragma warning(disable:4100) +#ifdef MODPLUG_TRACKER +#include "../mptrack/Mptrack.h" // For config filename +#endif // MODPLUG_TRACKER bool CSoundFile::SaveIT(LPCSTR lpszFileName, bool compatibilityExport) //-------------------------------------------------------------------- @@ -1069,9 +1068,9 @@ itHeader.patnum = min(Patterns.GetNumPatterns(), specs.patternsMax); // Parapointers - vector<DWORD> patpos(itHeader.patnum, 0); - vector<DWORD> smppos(itHeader.smpnum, 0); - vector<DWORD> inspos(itHeader.insnum, 0); + vector<uint32> patpos(itHeader.patnum, 0); + vector<uint32> smppos(itHeader.smpnum, 0); + vector<uint32> inspos(itHeader.insnum, 0); //VERSION if(GetType() == MOD_TYPE_MPT) @@ -1482,7 +1481,13 @@ // Writing Sample Data for (UINT nsmp=1; nsmp<=itHeader.smpnum; nsmp++) { - itss.ConvertToIT(Samples[nsmp], GetType()); +#ifdef MODPLUG_TRACKER + bool compress = ::GetPrivateProfileInt("Misc", Samples[nsmp].GetNumChannels() > 1 ? "ITCompressionStereo" : "ITCompressionMono", 0, theApp.GetConfigFileName()) != 0; +#else + bool compress = false; +#endif + // Old MPT will only consider the IT2.15 compression flag if the header version also indicates IT2.15. + itss.ConvertToIT(Samples[nsmp], GetType(), compress, itHeader.cmwt >= 0x215); StringFixer::WriteString<StringFixer::nullTerminated>(itss.name, m_szNames[nsmp]); @@ -1569,196 +1574,6 @@ #endif // MODPLUG_NO_FILESAVE -////////////////////////////////////////////////////////////////////////////// -// IT 2.14 compression - -DWORD ITReadBits(DWORD &bitbuf, UINT &bitnum, const uint8 *(&ibuf), CHAR n) -//------------------------------------------------------------------------- -{ - DWORD retval = 0; - UINT i = n; - - if (n > 0) - { - do - { - if (!bitnum) - { - bitbuf = *ibuf++; - bitnum = 8; - } - retval >>= 1; - retval |= bitbuf << 31; - bitbuf >>= 1; - bitnum--; - i--; - } while (i); - i = n; - } - return (retval >> (32-i)); -} - - -void ITUnpack8Bit(LPSTR pSample, DWORD dwLen, const uint8 *lpMemFile, DWORD dwMemLength, bool it215) -//-------------------------------------------------------------------------------------------------- -{ - LPSTR pDst = pSample; - const uint8 *pSrc = lpMemFile; - DWORD wHdr = 0; - DWORD wCount = 0; - DWORD bitbuf = 0; - UINT bitnum = 0; - BYTE bLeft = 0, bTemp = 0, bTemp2 = 0; - - while (dwLen) - { - if (!wCount) - { - wCount = 0x8000; - wHdr = *((LPWORD)pSrc); - pSrc += 2; - bLeft = 9; - bTemp = bTemp2 = 0; - bitbuf = bitnum = 0; - } - DWORD d = wCount; - if (d > dwLen) d = dwLen; - // Unpacking - DWORD dwPos = 0; - do - { - WORD wBits = (WORD)ITReadBits(bitbuf, bitnum, pSrc, bLeft); - if (bLeft < 7) - { - DWORD i = 1 << (bLeft-1); - DWORD j = wBits & 0xFFFF; - if (i != j) goto UnpackByte; - wBits = (WORD)(ITReadBits(bitbuf, bitnum, pSrc, 3) + 1) & 0xFF; - bLeft = ((BYTE)wBits < bLeft) ? (BYTE)wBits : (BYTE)((wBits+1) & 0xFF); - goto Next; - } - if (bLeft < 9) - { - WORD i = (0xFF >> (9 - bLeft)) + 4; - WORD j = i - 8; - if ((wBits <= j) || (wBits > i)) goto UnpackByte; - wBits -= j; - bLeft = ((BYTE)(wBits & 0xFF) < bLeft) ? (BYTE)(wBits & 0xFF) : (BYTE)((wBits+1) & 0xFF); - goto Next; - } - if (bLeft >= 10) goto SkipByte; - if (wBits >= 256) - { - bLeft = (BYTE)(wBits + 1) & 0xFF; - goto Next; - } - UnpackByte: - if (bLeft < 8) - { - BYTE shift = 8 - bLeft; - char c = (char)(wBits << shift); - c >>= shift; - wBits = (WORD)c; - } - wBits += bTemp; - bTemp = (BYTE)wBits; - bTemp2 += bTemp; - pDst[dwPos] = (it215) ? bTemp2 : bTemp; - - SkipByte: - dwPos++; - Next: - if (pSrc >= lpMemFile+dwMemLength+1) return; - } while (dwPos < d); - // Move On - wCount -= d; - dwLen -= d; - pDst += d; - } -} - - -void ITUnpack16Bit(LPSTR pSample, DWORD dwLen, const uint8 *lpMemFile, DWORD dwMemLength, bool it215) -//--------------------------------------------------------------------------------------------------- -{ - signed short *pDst = (signed short *)pSample; - const uint8 *pSrc = lpMemFile; - DWORD wHdr = 0; - DWORD wCount = 0; - DWORD bitbuf = 0; - UINT bitnum = 0; - BYTE bLeft = 0; - signed short wTemp = 0, wTemp2 = 0; - - while (dwLen) - { - if (!wCount) - { - wCount = 0x4000; - wHdr = *((LPWORD)pSrc); - pSrc += 2; - bLeft = 17; - wTemp = wTemp2 = 0; - bitbuf = bitnum = 0; - } - DWORD d = wCount; - if (d > dwLen) d = dwLen; - // Unpacking - DWORD dwPos = 0; - do - { - DWORD dwBits = ITReadBits(bitbuf, bitnum, pSrc, bLeft); - if (bLeft < 7) - { - DWORD i = 1 << (bLeft-1); - DWORD j = dwBits; - if (i != j) goto UnpackByte; - dwBits = ITReadBits(bitbuf, bitnum, pSrc, 4) + 1; - bLeft = ((BYTE)(dwBits & 0xFF) < bLeft) ? (BYTE)(dwBits & 0xFF) : (BYTE)((dwBits+1) & 0xFF); - goto Next; - } - if (bLeft < 17) - { - DWORD i = (0xFFFF >> (17 - bLeft)) + 8; - DWORD j = (i - 16) & 0xFFFF; - if ((dwBits <= j) || (dwBits > (i & 0xFFFF))) goto UnpackByte; - dwBits -= j; - bLeft = ((BYTE)(dwBits & 0xFF) < bLeft) ? (BYTE)(dwBits & 0xFF) : (BYTE)((dwBits+1) & 0xFF); - goto Next; - } - if (bLeft >= 18) goto SkipByte; - if (dwBits >= 0x10000) - { - bLeft = (BYTE)(dwBits + 1) & 0xFF; - goto Next; - } - UnpackByte: - if (bLeft < 16) - { - BYTE shift = 16 - bLeft; - signed short c = (signed short)(dwBits << shift); - c >>= shift; - dwBits = (DWORD)c; - } - dwBits += wTemp; - wTemp = (signed short)dwBits; - wTemp2 += wTemp; - pDst[dwPos] = (it215) ? wTemp2 : wTemp; - - SkipByte: - dwPos++; - Next: - if (pSrc >= lpMemFile+dwMemLength+1) return; - } while (dwPos < d); - // Move On - wCount -= d; - dwLen -= d; - pDst += d; - if (pSrc >= lpMemFile+dwMemLength) break; - } -} - - #ifndef MODPLUG_NO_FILESAVE UINT CSoundFile::SaveMixPlugins(FILE *f, BOOL bUpdate) Modified: trunk/OpenMPT/soundlib/Load_itp.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_itp.cpp 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/soundlib/Load_itp.cpp 2013-02-19 02:28:38 UTC (rev 1539) @@ -449,7 +449,7 @@ if(!sampleUsed[nsmp - 1] && Samples[nsmp].pSample) { ITSample itss; - itss.ConvertToIT(Samples[nsmp], GetType()); + itss.ConvertToIT(Samples[nsmp], GetType(), false, false); StringFixer::WriteString<StringFixer::nullTerminated>(itss.name, m_szNames[nsmp]); Modified: trunk/OpenMPT/soundlib/SampleFormats.cpp =================================================================== --- trunk/OpenMPT/soundlib/SampleFormats.cpp 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/soundlib/SampleFormats.cpp 2013-02-19 02:28:38 UTC (rev 1539) @@ -28,7 +28,7 @@ bool CSoundFile::ReadSampleFromFile(SAMPLEINDEX nSample, const LPBYTE lpMemFile, DWORD dwFileLength) //-------------------------------------------------------------------------------------------------- { - FileReader file(reinterpret_cast<const char *>(lpMemFile), dwFileLength); + FileReader file(lpMemFile, dwFileLength); if(!nSample || nSample >= MAX_SAMPLES) return false; if(!ReadWAVSample(nSample, file) && !ReadXISample(nSample, file) @@ -55,7 +55,7 @@ bool CSoundFile::ReadInstrumentFromFile(INSTRUMENTINDEX nInstr, const LPBYTE lpMemFile, DWORD dwFileLength) //--------------------------------------------------------------------------------------------------------- { - FileReader file(reinterpret_cast<const char *>(lpMemFile), dwFileLength); + FileReader file(lpMemFile, dwFileLength); if ((!nInstr) || (nInstr >= MAX_INSTRUMENTS)) return false; if ((!ReadXIInstrument(nInstr, file)) && (!ReadPATInstrument(nInstr, lpMemFile, dwFileLength)) @@ -84,6 +84,7 @@ || psig[0] == LittleEndian('CaLf') // FLAC signature #endif // NO_FLAC #ifndef NO_MP3_SAMPLES + || (lpMemFile[0] == 0xFF && lpMemFile[1] == 0xFB) // MP2 signature || (lpMemFile[0] == 0xFF && lpMemFile[1] == 0xFB) // MP3 signature || (lpMemFile[0] == 'I' && lpMemFile[1] == 'D' && lpMemFile[2] == '3') // MP3 signature #endif // NO_MP3_SAMPLES @@ -318,9 +319,9 @@ if(!wavFile.IsValid() || wavFile.GetNumChannels() == 0 || wavFile.GetNumChannels() > 2 - || wavFile.GetBitsPerSample() == 0 + || (wavFile.GetBitsPerSample() == 0 && wavFile.GetSampleFormat() != WAVFormatChunk::fmtMP3) || wavFile.GetBitsPerSample() > 32 - || (wavFile.GetSampleFormat() != WAVFormatChunk::fmtPCM && wavFile.GetSampleFormat() != WAVFormatChunk::fmtFloat && wavFile.GetSampleFormat() != WAVFormatChunk::fmtIMA_ADPCM)) + || (wavFile.GetSampleFormat() != WAVFormatChunk::fmtPCM && wavFile.GetSampleFormat() != WAVFormatChunk::fmtFloat && wavFile.GetSampleFormat() != WAVFormatChunk::fmtIMA_ADPCM && wavFile.GetSampleFormat() != WAVFormatChunk::fmtMP3)) { return false; } @@ -347,6 +348,10 @@ } IMAADPCMUnpack16((int16 *)sample.pSample, sample.nLength, sampleChunk.GetRawData(), sampleChunk.BytesLeft(), wavFile.GetBlockAlign()); AdjustSampleLoop(sample); + } else if(wavFile.GetSampleFormat() == WAVFormatChunk::fmtMP3) + { + // MP3 in WAV + return ReadMP3Sample(nSample, sampleChunk); } else { // PCM / Float @@ -1579,12 +1584,11 @@ } -bool CSoundFile::SaveITIInstrument(INSTRUMENTINDEX nInstr, const LPCSTR lpszFileName) const -//----------------------------------------------------------------------------------------- +bool CSoundFile::SaveITIInstrument(INSTRUMENTINDEX nInstr, const LPCSTR lpszFileName, bool compress) const +//-------------------------------------------------------------------------------------------------------- { ITInstrumentEx iti; ModInstrument *pIns = Instruments[nInstr]; - uint32 filePos; FILE *f; if((!pIns) || (!lpszFileName)) return false; @@ -1614,39 +1618,33 @@ } smpmap.clear(); - filePos = instSize; + uint32 filePos = instSize; iti.ConvertEndianness(); fwrite(&iti, 1, instSize, f); filePos += smptable.size() * sizeof(ITSample); - // Writing sample headers + // Writing sample headers + data + vector<SampleIO> sampleFlags; for(vector<SAMPLEINDEX>::iterator iter = smptable.begin(); iter != smptable.end(); iter++) { ITSample itss; - itss.ConvertToIT(Samples[*iter], GetType()); + itss.ConvertToIT(Samples[*iter], GetType(), compress, compress); StringFixer::WriteString<StringFixer::nullTerminated>(itss.name, m_szNames[*iter]); itss.samplepointer = filePos; itss.ConvertEndianness(); fwrite(&itss, 1, sizeof(itss), f); - filePos += Samples[*iter].GetSampleSizeInBytes(); - } - // Writing Sample Data - for(vector<SAMPLEINDEX>::iterator iter = smptable.begin(); iter != smptable.end(); iter++) - { - const ModSample &sample = Samples[*iter]; - // TODO we should actually use ITSample::GetSampleFormat() instead of re-computing the flags here. - SampleIO( - (sample.uFlags & CHN_16BIT) ? SampleIO::_16bit : SampleIO::_8bit, - (sample.uFlags & CHN_STEREO) ? SampleIO::stereoSplit : SampleIO::mono, - SampleIO::littleEndian, - SampleIO::signedPCM) - .WriteSample(f, sample); + // Write sample + off_t curPos = ftell(f); + fseek(f, filePos, SEEK_SET); + filePos += itss.GetSampleFormat(0x0214).WriteSample(f, Samples[*iter]); + fseek(f, curPos, SEEK_SET); } + fseek(f, 0, SEEK_END); int32 code = 'MPTX'; SwapBytesLE(code); fwrite(&code, 1, sizeof(int32), f); // Write extension tag Modified: trunk/OpenMPT/soundlib/SampleIO.cpp =================================================================== --- trunk/OpenMPT/soundlib/SampleIO.cpp 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/soundlib/SampleIO.cpp 2013-02-19 02:28:38 UTC (rev 1539) @@ -14,14 +14,13 @@ #include "Loaders.h" #include "SampleIO.h" #include "SampleFormatConverters.h" +#include "ITCompression.h" // External decompressors extern void AMSUnpack(const char * const source, size_t sourceSize, char * const dest, const size_t destSize, char packCharacter); extern uint16 MDLReadBits(uint32 &bitbuf, uint32 &bitnum, const uint8 *(&ibuf), int8 n); extern int DMFUnpack(LPBYTE psample, const uint8 *ibuf, const uint8 *ibufmax, uint32 maxlen); -extern void ITUnpack8Bit(LPSTR pSample, DWORD dwLen, const uint8 *lpMemFile, DWORD dwMemLength, bool it215); -extern void ITUnpack16Bit(LPSTR pSample, DWORD dwLen, const uint8 *lpMemFile, DWORD dwMemLength, bool it215); // Read a sample from memory @@ -294,17 +293,9 @@ } else if(GetEncoding() == IT214 || GetEncoding() == IT215) { // IT 2.14 / 2.15 compressed samples - if(fileSize > 4) - { - bytesRead = fileSize; - if(GetBitDepth() == 8) - { - ITUnpack8Bit(sample.pSample, sample.nLength, sourceBuf, fileSize, GetEncoding() == IT215); - } else if(GetBitDepth() == 16) - { - ITUnpack16Bit(sample.pSample, sample.nLength, sourceBuf, fileSize, GetEncoding() == IT215); - } - } + size_t startPos = file.GetPosition(); + ITDecompression(file, sample, GetEncoding() == IT215); + bytesRead = file.GetPosition() - startPos; } else if(GetEncoding() == AMS && GetChannelFormat() == mono) { // AMS compressed samples @@ -531,6 +522,13 @@ if (bufcount) if(f) fwrite(buffer, 1, bufcount, f); } + else if(GetEncoding() == IT214 || GetEncoding() == IT215) + { + // IT2.14-encoded samples + ITCompression its(sample, GetEncoding() == IT215, f); + len = its.GetCompressedSize(); + } + // Default: assume 8-bit PCM data else { Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2013-02-19 02:25:59 UTC (rev 1538) +++ trunk/OpenMPT/soundlib/Sndfile.h 2013-02-19 02:28:38 UTC (rev 1539) @@ -648,7 +648,7 @@ bool ReadPATInstrument(INSTRUMENTINDEX nInstr, const LPBYTE lpMemFile, DWORD dwFileLength); bool ReadSampleAsInstrument(INSTRUMENTINDEX nInstr, const LPBYTE lpMemFile, DWORD dwFileLength); bool SaveXIInstrument(INSTRUMENTINDEX nInstr, const LPCSTR lpszFileName) const; - bool SaveITIInstrument(INSTRUMENTINDEX nInstr, const LPCSTR lpszFileName) const; + bool SaveITIInstrument(INSTRUMENTINDEX nInstr, const LPCSTR lpszFileName, bool compress) const; // I/O from another sound file bool ReadInstrumentFromSong(INSTRUMENTINDEX targetInstr, const CSoundFile *pSrcSong, INSTRUMENTINDEX sourceInstr); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |