From: <man...@us...> - 2014-01-05 14:27:56
|
Revision: 3560 http://sourceforge.net/p/modplug/code/3560 Author: manxorist Date: 2014-01-05 14:27:48 +0000 (Sun, 05 Jan 2014) Log Message: ----------- [Doc] libopenmpt: Add high-level overview changelog. Modified Paths: -------------- trunk/OpenMPT/build/auto/package_libopenmpt_win32.cmd trunk/OpenMPT/build/auto/package_libopenmpt_win64.cmd trunk/OpenMPT/libopenmpt/Doxyfile trunk/OpenMPT/libopenmpt/dox/index.dox Added Paths: ----------- trunk/OpenMPT/libopenmpt/dox/changelog.md Modified: trunk/OpenMPT/build/auto/package_libopenmpt_win32.cmd =================================================================== --- trunk/OpenMPT/build/auto/package_libopenmpt_win32.cmd 2014-01-04 18:54:22 UTC (rev 3559) +++ trunk/OpenMPT/build/auto/package_libopenmpt_win32.cmd 2014-01-05 14:27:48 UTC (rev 3560) @@ -20,7 +20,8 @@ copy /y ..\..\libopenmpt\doc\xmp-openmpt.txt .\ || goto error copy /y ..\..\libopenmpt\doc\foo_openmpt.txt .\ || goto error copy /y ..\..\LICENSE .\ || goto error -"C:\Program Files\7-Zip\7z.exe" a -t7z -mx=9 libopenmpt-win32-r%GOT_REVISION%.7z libopenmpt.dll libmodplug.dll in_openmpt.dll xmp-openmpt.dll foo_openmpt.dll libopenmpt_settings.dll openmpt123.exe inc\libopenmpt\libopenmpt.h inc\libopenmpt\libopenmpt.hpp inc\libopenmpt\libopenmpt_config.h inc\libopenmpt\libopenmpt_version.h lib\Win32\libopenmpt.lib bin\Win32\libopenmpt.dll in_openmpt.txt xmp-openmpt.txt foo_openmpt.txt LICENSE || goto error +copy /y ..\..\libopenmpt\dox\changelog.md .\ || goto error +"C:\Program Files\7-Zip\7z.exe" a -t7z -mx=9 libopenmpt-win32-r%GOT_REVISION%.7z libopenmpt.dll libmodplug.dll in_openmpt.dll xmp-openmpt.dll foo_openmpt.dll libopenmpt_settings.dll openmpt123.exe inc\libopenmpt\libopenmpt.h inc\libopenmpt\libopenmpt.hpp inc\libopenmpt\libopenmpt_config.h inc\libopenmpt\libopenmpt_version.h lib\Win32\libopenmpt.lib bin\Win32\libopenmpt.dll in_openmpt.txt xmp-openmpt.txt foo_openmpt.txt LICENSE changelog.md || goto error "C:\Program Files\7-Zip\7z.exe" a -ttar libopenmpt-win32.tar libopenmpt-win32-r%GOT_REVISION%.7z || goto error del /f /q libopenmpt-win32-r%GOT_REVISION%.7z cd ..\.. || goto error Modified: trunk/OpenMPT/build/auto/package_libopenmpt_win64.cmd =================================================================== --- trunk/OpenMPT/build/auto/package_libopenmpt_win64.cmd 2014-01-04 18:54:22 UTC (rev 3559) +++ trunk/OpenMPT/build/auto/package_libopenmpt_win64.cmd 2014-01-05 14:27:48 UTC (rev 3560) @@ -17,7 +17,8 @@ copy /y libopenmpt.lib lib\x64\ || goto error copy /y libopenmpt.dll bin\x64\ || goto error copy /y ..\..\LICENSE .\ || goto error -"C:\Program Files\7-Zip\7z.exe" a -t7z -mx=9 libopenmpt-win64-r%GOT_REVISION%.7z libopenmpt.dll libmodplug.dll openmpt123.exe inc\libopenmpt\libopenmpt.h inc\libopenmpt\libopenmpt.hpp inc\libopenmpt\libopenmpt_config.h inc\libopenmpt\libopenmpt_version.h lib\x64\libopenmpt.lib bin\x64\libopenmpt.dll LICENSE || goto error +copy /y ..\..\libopenmpt\dox\changelog.md .\ || goto error +"C:\Program Files\7-Zip\7z.exe" a -t7z -mx=9 libopenmpt-win64-r%GOT_REVISION%.7z libopenmpt.dll libmodplug.dll openmpt123.exe inc\libopenmpt\libopenmpt.h inc\libopenmpt\libopenmpt.hpp inc\libopenmpt\libopenmpt_config.h inc\libopenmpt\libopenmpt_version.h lib\x64\libopenmpt.lib bin\x64\libopenmpt.dll LICENSE changelog.md || goto error "C:\Program Files\7-Zip\7z.exe" a -ttar libopenmpt-win64.tar libopenmpt-win64-r%GOT_REVISION%.7z || goto error del /f /q libopenmpt-win64-r%GOT_REVISION%.7z cd ..\.. || goto error Modified: trunk/OpenMPT/libopenmpt/Doxyfile =================================================================== --- trunk/OpenMPT/libopenmpt/Doxyfile 2014-01-04 18:54:22 UTC (rev 3559) +++ trunk/OpenMPT/libopenmpt/Doxyfile 2014-01-05 14:27:48 UTC (rev 3560) @@ -739,6 +739,7 @@ README.md \ libopenmpt/dox/dependencies.md \ libopenmpt/dox/tests.md \ + libopenmpt/dox/changelog.md \ libopenmpt/dox/todo.md \ libopenmpt/libopenmpt.hpp \ libopenmpt/libopenmpt.h \ Added: trunk/OpenMPT/libopenmpt/dox/changelog.md =================================================================== --- trunk/OpenMPT/libopenmpt/dox/changelog.md (rev 0) +++ trunk/OpenMPT/libopenmpt/dox/changelog.md 2014-01-05 14:27:48 UTC (rev 3560) @@ -0,0 +1,20 @@ + +Changelog {#changelog} +========= + +For fully detailed change log, please see the source repository directly. This +is just a high-level summary. + +### libopenmpt svn + + * [Bug] MT2 loader crash. + * [Bug] Saving settings in in_openmpt and xmp-openmpt did not work. + * [Bug] Load libopenmpt_settings.dll als from below Plugins directory in + Winamp. + + * DBM playback improvements. + +### 2013-12-31 - libopenmpt 0.2.3532-beta1 + + * First release. + Modified: trunk/OpenMPT/libopenmpt/dox/index.dox =================================================================== --- trunk/OpenMPT/libopenmpt/dox/index.dox 2014-01-04 18:54:22 UTC (rev 3559) +++ trunk/OpenMPT/libopenmpt/dox/index.dox 2014-01-05 14:27:48 UTC (rev 3560) @@ -11,6 +11,7 @@ * - \ref md_README "README" * - \ref dependencies "Dependencies" * - \ref tests "Tests" + * - \ref changelog "Changelog" * - \ref todo "TODO" * \subsection toc_apis APIs * - libopenmpt This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-01-05 17:18:13
|
Revision: 3564 http://sourceforge.net/p/modplug/code/3564 Author: saga-games Date: 2014-01-05 17:18:06 +0000 (Sun, 05 Jan 2014) Log Message: ----------- [Mod] Tree view: Don't rely on current directory being set to the module directory when intializing tree view (so that current directory doesn't have to be set in the main code anymore) - as a consequence, set the default current directory to the executable's directory. [Fix] Tree view: Deleting samples / instruments from the treeview didn't update the tree view properly if more than one sample / instrument was removed (this could happen when deleting the last empty sample / instr and there were more empty slots before that) [Imp] Tree view: Shift+Del in instrument browser = delete file permanently (like in Windows Explorer) [Mod] OpenMPT: Version is now 1.22.07.12 Modified Paths: -------------- trunk/OpenMPT/common/versionNumber.h trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/mptrack/View_tre.cpp Modified: trunk/OpenMPT/common/versionNumber.h =================================================================== --- trunk/OpenMPT/common/versionNumber.h 2014-01-05 17:11:53 UTC (rev 3563) +++ trunk/OpenMPT/common/versionNumber.h 2014-01-05 17:18:06 UTC (rev 3564) @@ -17,7 +17,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 22 #define VER_MINOR 07 -#define VER_MINORMINOR 11 +#define VER_MINORMINOR 12 //Version string. For example "1.17.02.28" #define MPT_VERSION_STR VER_STRINGIZE(VER_MAJORMAJOR) "." VER_STRINGIZE(VER_MAJOR) "." VER_STRINGIZE(VER_MINOR) "." VER_STRINGIZE(VER_MINORMINOR) Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2014-01-05 17:11:53 UTC (rev 3563) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2014-01-05 17:18:06 UTC (rev 3564) @@ -698,6 +698,7 @@ WCHAR wcsDir[MAX_PATH]; GetFullPathNameW(m_szExePath.AsNative().c_str(), CountOf(wcsDir), wcsDir, NULL); m_szExePath = mpt::PathString::FromNative(wcsDir); + SetCurrentDirectoryW(wcsDir); } m_szConfigDirectory = mpt::PathString(); Modified: trunk/OpenMPT/mptrack/TrackerSettings.cpp =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-01-05 17:11:53 UTC (rev 3563) +++ trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-01-05 17:18:06 UTC (rev 3564) @@ -494,10 +494,6 @@ { TrackerDirectories::Instance().m_szWorkingDirectory[i] = TrackerDirectories::Instance().m_szDefaultDirectory[i]; } - if(!TrackerDirectories::Instance().m_szDefaultDirectory[DIR_MODS].empty()) - { - SetCurrentDirectoryW(TrackerDirectories::Instance().m_szDefaultDirectory[DIR_MODS].AsNative().c_str()); - } m_szKbdFile = theApp.RelativePathToAbsolute(m_szKbdFile); // Last fixup: update config version Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2014-01-05 17:11:53 UTC (rev 3563) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2014-01-05 17:18:06 UTC (rev 3564) @@ -194,12 +194,15 @@ if(!IsSampleBrowser()) { - m_InstrLibPath = TrackerDirectories::Instance().GetDefaultDirectory(DIR_SAMPLES); - if(m_InstrLibPath.empty()) + const Directory dirs[] = { DIR_SAMPLES, DIR_INSTRUMENTS, DIR_MODS }; + for(int i = 0; i < CountOf(dirs); i++) { - m_InstrLibPath = TrackerDirectories::Instance().GetDefaultDirectory(DIR_INSTRUMENTS); - if(m_InstrLibPath.empty()) + m_InstrLibPath = TrackerDirectories::Instance().GetDefaultDirectory(dirs[i]); + if(!m_InstrLibPath.empty()) { + break; + } else if(i == CountOf(dirs) - 1) + { // Resort to current directory. WCHAR curDir[MAX_PATH]; GetCurrentDirectoryW(CountOf(curDir), curDir); @@ -1464,19 +1467,26 @@ case MODITEM_SAMPLE: wsprintf(s, _T("Remove sample %u?"), modItemID); - if(Reporting::Confirm(s, false, true) == cnfNo) break; - modDoc->GetSampleUndo().PrepareUndo((SAMPLEINDEX)modItemID, sundo_replace); - if (modDoc->RemoveSample((SAMPLEINDEX)modItemID)) + if(Reporting::Confirm(s, false, true) == cnfYes) { - modDoc->UpdateAllViews(NULL, (UINT(modItemID) << HINT_SHIFT_SMP) | HINT_SMPNAMES|HINT_SAMPLEDATA|HINT_SAMPLEINFO); + modDoc->GetSampleUndo().PrepareUndo((SAMPLEINDEX)modItemID, sundo_replace); + const SAMPLEINDEX oldNumSamples = modDoc->GetNumSamples(); + if (modDoc->RemoveSample((SAMPLEINDEX)modItemID)) + { + modDoc->UpdateAllViews(NULL, (modDoc->GetNumSamples() != oldNumSamples ? 0 : (UINT(modItemID) << HINT_SHIFT_SMP)) | HINT_SMPNAMES|HINT_SAMPLEDATA|HINT_SAMPLEINFO); + } } break; case MODITEM_INSTRUMENT: wsprintf(s, _T("Remove instrument %u?"), modItemID); - if(Reporting::Confirm(s, false, true) == cnfYes && modDoc->RemoveInstrument((INSTRUMENTINDEX)modItemID)) + if(Reporting::Confirm(s, false, true) == cnfYes) { - modDoc->UpdateAllViews(NULL, (UINT(modItemID) << HINT_SHIFT_INS) | HINT_MODTYPE|HINT_ENVELOPE|HINT_INSTRUMENT); + const INSTRUMENTINDEX oldNumInstrs = modDoc->GetNumInstruments(); + if(modDoc->RemoveInstrument((INSTRUMENTINDEX)modItemID)) + { + modDoc->UpdateAllViews(NULL, (modDoc->GetNumInstruments() != oldNumInstrs ? 0 : (UINT(modItemID) << HINT_SHIFT_INS)) | HINT_MODTYPE|HINT_ENVELOPE|HINT_INSTRUMENT); + } } break; @@ -1505,7 +1515,7 @@ fos.hwnd = m_hWnd; fos.wFunc = FO_DELETE; fos.pFrom = fullPath.c_str(); - fos.fFlags = FOF_ALLOWUNDO; + fos.fFlags = CMainFrame::GetInputHandler()->ShiftPressed() ? 0 : FOF_ALLOWUNDO; if ((0 == SHFileOperationW(&fos)) && (!fos.fAnyOperationsAborted)) RefreshInstrumentLibrary(); } break; @@ -3391,6 +3401,7 @@ // Gets the root parent of an item, i.e. if C is a child of B and B is a child of A, GetParentRootItem(C) returns A. +// A root item is considered to be its own parent, i.e. the returned value is only ever NULL if the input value was NULL. HTREEITEM CModTree::GetParentRootItem(HTREEITEM hItem) //---------------------------------------------------- { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-01-12 22:52:32
|
Revision: 3570 http://sourceforge.net/p/modplug/code/3570 Author: saga-games Date: 2014-01-12 22:52:21 +0000 (Sun, 12 Jan 2014) Log Message: ----------- [Imp] UMX Loader: Added support for Unreal 1997/98 beta files (patch by sezero, http://bugs.openmpt.org/view.php?id=472) [Fix] UAX Loader: Unnecessary empty sample slots were being created. [Mod] OpenMPT: Version is now 1.22.07.13 Modified Paths: -------------- trunk/OpenMPT/common/versionNumber.h trunk/OpenMPT/soundlib/Load_umx.cpp Modified: trunk/OpenMPT/common/versionNumber.h =================================================================== --- trunk/OpenMPT/common/versionNumber.h 2014-01-12 18:03:25 UTC (rev 3569) +++ trunk/OpenMPT/common/versionNumber.h 2014-01-12 22:52:21 UTC (rev 3570) @@ -17,7 +17,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 22 #define VER_MINOR 07 -#define VER_MINORMINOR 12 +#define VER_MINORMINOR 13 //Version string. For example "1.17.02.28" #define MPT_VERSION_STR VER_STRINGIZE(VER_MAJORMAJOR) "." VER_STRINGIZE(VER_MAJOR) "." VER_STRINGIZE(VER_MINOR) "." VER_STRINGIZE(VER_MINORMINOR) Modified: trunk/OpenMPT/soundlib/Load_umx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_umx.cpp 2014-01-12 18:03:25 UTC (rev 3569) +++ trunk/OpenMPT/soundlib/Load_umx.cpp 2014-01-12 22:52:21 UTC (rev 3570) @@ -59,8 +59,8 @@ // Read compressed unreal integers - similar to MIDI integers, but signed values are possible. -int32 ReadUMXIndex(FileReader &chunk) -//----------------------------------- +static int32 ReadUMXIndex(FileReader &chunk) +//------------------------------------------ { enum { @@ -99,8 +99,8 @@ // Read an entry from the name table. -std::string ReadUMXNameTableEntry(FileReader &chunk, uint16 packageVersion) -//------------------------------------------------------------------------- +static std::string ReadUMXNameTableEntry(FileReader &chunk, uint16 packageVersion) +//-------------------------------------------------------------------------------- { std::string name; if(packageVersion >= 64) @@ -132,23 +132,32 @@ // Read an entry from the import table. -int32 ReadUMXImportTableEntry(FileReader &chunk) -//---------------------------------------------- +static int32 ReadUMXImportTableEntry(FileReader &chunk, uint16 packageVersion) +//---------------------------------------------------------------------------- { ReadUMXIndex(chunk); // Class package ReadUMXIndex(chunk); // Class name - chunk.Skip(4); // Package + if(packageVersion >= 60) + { + chunk.Skip(4); // Package + } else + { + ReadUMXIndex(chunk); // ?? + } return ReadUMXIndex(chunk); // Object name (offset into the name table) } // Read an entry from the export table. -void ReadUMXExportTableEntry(FileReader &chunk, int32 &objClass, int32 &objOffset, int32 &objSize, int32 &objName) -//---------------------------------------------------------------------------------------------------------------- +static void ReadUMXExportTableEntry(FileReader &chunk, int32 &objClass, int32 &objOffset, int32 &objSize, int32 &objName, uint16 packageVersion) +//---------------------------------------------------------------------------------------------------------------------------------------------- { objClass = ReadUMXIndex(chunk); // Object class ReadUMXIndex(chunk); // Object parent - chunk.Skip(4); // Internal package / group of the object + if(packageVersion >= 60) + { + chunk.Skip(4); // Internal package / group of the object + } objName = ReadUMXIndex(chunk); // Object name (offset into the name table) chunk.Skip(4); // Object flags objSize = ReadUMXIndex(chunk); @@ -189,7 +198,7 @@ classes.reserve(fileHeader.importCount); for(uint32 i = 0; i < fileHeader.importCount; i++) { - int32 objName = ReadUMXImportTableEntry(file); + int32 objName = ReadUMXImportTableEntry(file, fileHeader.packageVersion); if(static_cast<size_t>(objName) < names.size()) { classes.push_back(objName); @@ -209,7 +218,7 @@ for(uint32 i = 0; i < fileHeader.exportCount; i++) { int32 objClass, objOffset, objSize, objName; - ReadUMXExportTableEntry(file, objClass, objOffset, objSize, objName); + ReadUMXExportTableEntry(file, objClass, objOffset, objSize, objName, fileHeader.packageVersion); if(objSize <= 0 || objClass >= 0) { @@ -246,15 +255,24 @@ if(chunk.IsValid()) { + if(fileHeader.packageVersion < 40) + { + chunk.Skip(8); // 00 00 00 00 00 00 00 00 + } + if(fileHeader.packageVersion < 60) + { + chunk.Skip(16); // 81 00 00 00 00 00 FF FF FF FF FF FF FF FF 00 00 + } // Read object properties size_t propertyName = static_cast<size_t>(ReadUMXIndex(chunk)); - if(propertyName >= names.size() || strcmp(names[propertyName].c_str(), "none")) + /*if(propertyName >= names.size() || strcmp(names[propertyName].c_str(), "none")) { - // Can't bother to implement property reading, as no UMX or UAX files I've seen so far use properties for the relevant objects. + // Can't bother to implement property reading, as no UMX files I've seen so far use properties for the relevant objects, + // and only the UAX files in the Unreal 1997/98 beta seem to use this and still load just fine when ignoring it. // If it should be necessary to implement this, check CUnProperty.cpp in http://ut-files.com/index.php?dir=Utilities/&file=utcms_source.zip ASSERT(false); continue; - } + }*/ if(fileHeader.packageVersion >= 120) { @@ -305,7 +323,6 @@ // Read as sample if(ReadSampleFromFile(GetNumSamples() + 1, fileChunk, true)) { - m_nSamples++; if(static_cast<size_t>(objName) < names.size()) { mpt::String::Copy(m_szNames[GetNumSamples()], names[objName]); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-01-15 18:39:14
|
Revision: 3576 http://sourceforge.net/p/modplug/code/3576 Author: saga-games Date: 2014-01-15 18:39:04 +0000 (Wed, 15 Jan 2014) Log Message: ----------- [Ref] CommandSet: Use std::vector instead of CArray. Modified Paths: -------------- trunk/OpenMPT/mptrack/CommandSet.cpp trunk/OpenMPT/mptrack/CommandSet.h trunk/OpenMPT/soundlib/Sndfile.cpp Modified: trunk/OpenMPT/mptrack/CommandSet.cpp =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.cpp 2014-01-15 17:46:44 UTC (rev 3575) +++ trunk/OpenMPT/mptrack/CommandSet.cpp 2014-01-15 18:39:04 UTC (rev 3576) @@ -30,7 +30,8 @@ #endif -CCommandSet::CCommandSet(void) +CCommandSet::CCommandSet() +//------------------------ { // Which keybinding rules to enforce? enforceRule[krPreventDuplicate] = true; @@ -48,20 +49,11 @@ enforceRule[krPropagateSampleManipulation] = true; // enforceRule[krCheckContextHierarchy] = true; - commands.SetSize(kcNumCommands); SetupCommands(); SetupContextHierarchy(); } -CCommandSet::~CCommandSet(void) -{ - //CHAR s[64]; - //wsprintf(s, "pointer = %lX",plocalCmdSet); - //Reporting::Notification("about to remove all", MB_OK | MB_ICONEXCLAMATION); //disabled by rewbs - //commands.RemoveAll(); -} - //------------------------------------------------------- // Setup //------------------------------------------------------- @@ -696,7 +688,7 @@ KeyCombination curKc; //Avoid duplicate - for (int k=0; k<commands[cmd].kcList.GetSize(); k++) + for(size_t k = 0; k < commands[cmd].kcList.size(); k++) { curKc=commands[cmd].kcList[k]; if (curKc==kc) @@ -713,7 +705,7 @@ break; if (IsDummyCommand((CommandID)curCmd)) //no need to check against a dummy key continue; - for (int k=0; k<commands[curCmd].kcList.GetSize(); k++) + for(size_t k = 0; k < commands[curCmd].kcList.size(); k++) { //search all keys for curCommand curKc=commands[curCmd].kcList[k]; bool crossContext=false; @@ -742,10 +734,9 @@ } } - if (pos>=0) - commands[cmd].kcList.InsertAt(pos, kc); - else - commands[cmd].kcList.Add(kc); + if (pos < 0) + pos = commands[cmd].kcList.size(); + commands[cmd].kcList.insert(commands[cmd].kcList.begin() + pos, kc); //enfore rules on CommandSet report+=EnforceAll(kc, cmd, true); @@ -765,7 +756,7 @@ CString CCommandSet::Remove(int pos, CommandID cmd) //------------------------------------------------- { - if (pos>=0 && pos<commands[cmd].kcList.GetSize()) + if (pos>=0 && (size_t)pos<commands[cmd].kcList.size()) { return Remove(commands[cmd].kcList[pos], cmd); } @@ -779,15 +770,15 @@ //----------------------------------------------------------- { //find kc in commands[cmd].kcList - int index=-1; - for (index=0; index<commands[cmd].kcList.GetSize(); index++) + std::vector<KeyCombination>::const_iterator index; + for(index = commands[cmd].kcList.begin(); index != commands[cmd].kcList.end(); index++) { - if (kc==commands[cmd].kcList[index]) + if (kc == *index) break; } - if (index>=0 && index<commands[cmd].kcList.GetSize()) + if (index != commands[cmd].kcList.end()) { - commands[cmd].kcList.RemoveAt(index); + commands[cmd].kcList.erase(index); Log("Removed a key\n"); return EnforceAll(kc, cmd, false); } @@ -816,7 +807,7 @@ if(inCmd >= kcStartPatNavigation && inCmd <= kcEndPatNavigation) {//Check that it is a nav cmd CommandID cmdNavSelection = (CommandID)(kcStartPatNavigationSelect + (inCmd-kcStartPatNavigation)); - for(int kSel=0; kSel<commands[kcSelect].kcList.GetSize(); kSel++) + for(size_t kSel = 0; kSel < commands[kcSelect].kcList.size(); kSel++) {//for all selection modifiers curKc=commands[kcSelect].kcList[kSel]; newKc=inKc; @@ -836,7 +827,7 @@ else if(inCmd >= kcStartOrderlistNavigation && inCmd <= kcEndOrderlistNavigation) {//Check that it is a nav cmd CommandID cmdNavSelection = (CommandID)(kcStartOrderlistNavigationSelect+ (inCmd-kcStartOrderlistNavigation)); - for (int kSel=0; kSel<commands[kcSelect].kcList.GetSize(); kSel++) + for(size_t kSel = 0; kSel < commands[kcSelect].kcList.size(); kSel++) {//for all selection modifiers curKc=commands[kcSelect].kcList[kSel]; newKc=inKc; @@ -860,7 +851,7 @@ for(int curCmd=kcStartPatNavigation; curCmd<=kcEndPatNavigation; curCmd++) { // for all nav commands - for(int k = 0; k < commands[curCmd].kcList.GetSize(); k++) + for(size_t k = 0; k < commands[curCmd].kcList.size(); k++) { // for all keys for this command CommandID cmdNavSelection = (CommandID)(kcStartPatNavigationSelect + (curCmd-kcStartPatNavigation)); @@ -879,7 +870,7 @@ } // end all nav commands for(int curCmd = kcStartOrderlistNavigation; curCmd <= kcEndOrderlistNavigation; curCmd++) {// for all nav commands - for(int k = 0; k < commands[curCmd].kcList.GetSize(); k++) + for(size_t k = 0; k < commands[curCmd].kcList.size(); k++) {// for all keys for this command CommandID cmdNavSelection = (CommandID)(kcStartOrderlistNavigationSelect+ (curCmd-kcStartOrderlistNavigation)); newKc=commands[curCmd].kcList[k]; // get all properties from the current nav cmd key @@ -906,7 +897,7 @@ // all selection keys will work even when this new selection key is pressed if(inCmd >= kcStartPatNavigation && inCmd <= kcEndPatNavigation) {//if this is a navigation command - for(int kSel = 0; kSel < commands[kcSelect].kcList.GetSize(); kSel++) + for(size_t kSel = 0; kSel < commands[kcSelect].kcList.size(); kSel++) {//for all deselection modifiers newKcSel = commands[kcSelect].kcList[kSel]; // get all properties from the selection key newKcSel.AddModifier(inKc); // add modifiers from the new nav command @@ -924,7 +915,7 @@ // Same for orderlist navigation if(inCmd >= kcStartOrderlistNavigation && inCmd <= kcEndOrderlistNavigation) {//if this is a navigation command - for(int kSel = 0; kSel < commands[kcSelect].kcList.GetSize(); kSel++) + for(size_t kSel = 0; kSel < commands[kcSelect].kcList.size(); kSel++) {//for all deselection modifiers newKcSel=commands[kcSelect].kcList[kSel]; // get all properties from the selection key newKcSel.AddModifier(inKc); // add modifiers from the new nav command @@ -945,7 +936,7 @@ { for(int curCmd = kcStartPatNavigation; curCmd <= kcEndPatNavigation; curCmd++) {//for all nav commands - for(int k = 0; k < commands[curCmd].kcList.GetSize(); k++) + for(size_t k = 0; k < commands[curCmd].kcList.size(); k++) {// for all keys for this command newKcSel=inKc; // get all properties from the selection key newKcSel.AddModifier(commands[curCmd].kcList[k]); //add the nav keys' modifiers @@ -963,7 +954,7 @@ for(int curCmd = kcStartOrderlistNavigation; curCmd <= kcEndOrderlistNavigation; curCmd++) {//for all nav commands - for(int k = 0; k <commands[curCmd].kcList.GetSize(); k++) + for(size_t k = 0; k < commands[curCmd].kcList.size(); k++) {// for all keys for this command newKcSel=inKc; // get all properties from the selection key newKcSel.AddModifier(commands[curCmd].kcList[k]); //add the nav keys' modifiers @@ -1030,7 +1021,7 @@ { // On getting a new selection key, make this selection key work with all copy selects' modifiers // On getting a new selection key, make all copyselects work with this key's modifiers - for (int k=0; k<commands[kcCopySelect].kcList.GetSize(); k++) + for(size_t k = 0; k < commands[kcCopySelect].kcList.size(); k++) { newKcSel=inKc; newKcSel.AddModifier(commands[kcCopySelect].kcList[k]); @@ -1052,7 +1043,7 @@ { // On getting a new copyselection key, make this copyselection key work with all selects' modifiers // On getting a new copyselection key, make all selects work with this key's modifiers - for(int k = 0; k < commands[kcSelect].kcList.GetSize(); k++) + for(size_t k = 0; k < commands[kcSelect].kcList.size(); k++) { newKcSel=commands[kcSelect].kcList[k]; newKcSel.AddModifier(inKc); @@ -1079,7 +1070,7 @@ if (inCmd>=kcVPStartNotes && inCmd<=kcVPEndNotes) { int noteOffset = inCmd - kcVPStartNotes; - for (int k=0; k<commands[kcChordModifier].kcList.GetSize(); k++) + for(size_t k = 0; k < commands[kcChordModifier].kcList.size(); k++) {//for all chord modifier keys newKc=inKc; newKc.AddModifier(commands[kcChordModifier].kcList[k]); @@ -1100,7 +1091,7 @@ int noteOffset; for (int curCmd=kcVPStartNotes; curCmd<=kcVPEndNotes; curCmd++) {//for all notes - for (int k=0; k<commands[curCmd].kcList.GetSize(); k++) + for (size_t k=0; k<commands[curCmd].kcList.size(); k++) {//for all keys for this note noteOffset = curCmd - kcVPStartNotes; newKc=commands[curCmd].kcList[k]; @@ -1202,7 +1193,7 @@ } else if (!adding && (inCmd<kcSetSpacing && kcSetSpacing9<inCmd)) { - for (int k=0; k<commands[kcSetSpacing].kcList.GetSize(); k++) + for (size_t k=0; k<commands[kcSetSpacing].kcList.size(); k++) { KeyCombination spacing = commands[kcSetSpacing].kcList[k]; if ((('0'<=inKc.KeyCode() && inKc.KeyCode()<='9')||(VK_NUMPAD0<=inKc.KeyCode() && inKc.KeyCode()<=VK_NUMPAD9)) && !adding) @@ -1302,7 +1293,7 @@ CommandID curCmd = forcedModifiers[i]; //for all of this command's key combinations - for (int k=0; k<commands[curCmd].kcList.GetSize(); k++) + for (size_t k=0; k<commands[curCmd].kcList.size(); k++) { curKc = commands[curCmd].kcList[k]; if ((!curKc.Modifier()) || (curKc.KeyCode()!=VK_SHIFT && curKc.KeyCode()!=VK_CONTROL && curKc.KeyCode()!=VK_MENU && curKc.KeyCode()!=0 && @@ -1328,8 +1319,8 @@ //propagate to InstrumentView newCmd = kcStartInstrumentMisc+offset; - commands[newCmd].kcList.SetSize(commands[inCmd].kcList.GetSize()); - for (int k=0; k<commands[inCmd].kcList.GetSize(); k++) + commands[newCmd].kcList.resize(commands[inCmd].kcList.size()); + for (size_t k=0; k<commands[inCmd].kcList.size(); k++) { commands[newCmd].kcList[k] = commands[inCmd].kcList[k]; commands[newCmd].kcList[k].Context(kCtxViewInstruments); @@ -1372,8 +1363,8 @@ //------------------------------------- { KeyCombination curKc; - CArray<KeyEventType, KeyEventType> eventTypes; - CArray<InputTargetContext, InputTargetContext> contexts; + std::vector<KeyEventType> eventTypes; + std::vector<InputTargetContext> contexts; //Clear map km.clear(); @@ -1384,40 +1375,40 @@ if(IsDummyCommand((CommandID)cmd)) continue; - for(INT_PTR k=0; k<commands[cmd].kcList.GetSize(); k++) + for(size_t k=0; k<commands[cmd].kcList.size(); k++) { - contexts.RemoveAll(); - eventTypes.RemoveAll(); + std::vector<KeyEventType> eventTypes; + std::vector<InputTargetContext> contexts; curKc = commands[cmd].kcList[k]; //Handle keyEventType mask. if (curKc.EventType() & kKeyEventDown) - eventTypes.Add(kKeyEventDown); + eventTypes.push_back(kKeyEventDown); if (curKc.EventType() & kKeyEventUp) - eventTypes.Add(kKeyEventUp); + eventTypes.push_back(kKeyEventUp); if (curKc.EventType() & kKeyEventRepeat) - eventTypes.Add(kKeyEventRepeat); + eventTypes.push_back(kKeyEventRepeat); //ASSERT(eventTypes.GetSize()>0); //Handle super-contexts (contexts that represent a set of sub contexts) if (curKc.Context() == kCtxViewPatterns) { - contexts.Add(kCtxViewPatternsNote); - contexts.Add(kCtxViewPatternsIns); - contexts.Add(kCtxViewPatternsVol); - contexts.Add(kCtxViewPatternsFX); - contexts.Add(kCtxViewPatternsFXparam); + contexts.push_back(kCtxViewPatternsNote); + contexts.push_back(kCtxViewPatternsIns); + contexts.push_back(kCtxViewPatternsVol); + contexts.push_back(kCtxViewPatternsFX); + contexts.push_back(kCtxViewPatternsFXparam); } else if(curKc.Context() == kCtxCtrlPatterns) { - contexts.Add(kCtxCtrlOrderlist); + contexts.push_back(kCtxCtrlOrderlist); } else { - contexts.Add(curKc.Context()); + contexts.push_back(curKc.Context()); } - for (int cx=0; cx<contexts.GetSize(); cx++) + for (size_t cx=0; cx<contexts.size(); cx++) { - for (int ke=0; ke<eventTypes.GetSize(); ke++) + for (size_t ke=0; ke<eventTypes.size(); ke++) { km[KeyCombination(contexts[cx], curKc.Modifier(), curKc.KeyCode(), eventTypes[ke])] = (CommandID)cmd; } @@ -1432,7 +1423,7 @@ //----------------------------------------- { // copy constructors should take care of complexity (I hope) - for (int cmd = 0; cmd < commands.GetSize(); cmd++) + for (size_t cmd = 0; cmd < CountOf(commands); cmd++) commands[cmd] = source->commands[cmd]; } @@ -1447,7 +1438,7 @@ int CCommandSet::GetKeyListSize(CommandID cmd) //-------------------------------------------- { - return commands[cmd].kcList.GetSize(); + return commands[cmd].kcList.size(); } @@ -1858,7 +1849,7 @@ CString CCommandSet::GetKeyTextFromCommand(CommandID c, UINT key) //--------------------------------------------------------------- { - if ( static_cast<INT_PTR>(key) < commands[c].kcList.GetSize()) + if ( key < commands[c].kcList.size()) return commands[c].kcList[0].GetKeyText(); else return ""; Modified: trunk/OpenMPT/mptrack/CommandSet.h =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.h 2014-01-15 17:46:44 UTC (rev 3575) +++ trunk/OpenMPT/mptrack/CommandSet.h 2014-01-15 18:39:04 UTC (rev 3576) @@ -9,7 +9,6 @@ #pragma once -#include "afxtempl.h" #include <string> #include "../common/FlagSet.h" struct CModSpecifications; @@ -1216,21 +1215,19 @@ struct CommandStruct { -//public: + std::vector<KeyCombination> kcList; + CString Message; UINT UID; bool isDummy; bool isHidden; - CString Message; - CArray <KeyCombination, KeyCombination> kcList; - //KeyCombination kcList[10]; - bool operator = (const CommandStruct &other) + bool operator= (const CommandStruct &other) { UID = other.UID; Message = other.Message; isDummy = other.isDummy; isHidden = other.isHidden; - kcList.Copy(other.kcList); + kcList = other.kcList; return true; } @@ -1288,16 +1285,13 @@ int FindCmd(int uid); bool KeyCombinationConflict(KeyCombination kc1, KeyCombination kc2, bool &crossCxtConflict); - //members - CArray <CommandStruct,CommandStruct> commands; - //CArray<CArray<bool,bool>, CArray<bool,bool> > m_isParentContext; + CommandStruct commands[kcNumCommands]; bool m_isParentContext[kCtxMaxInputContexts][kCtxMaxInputContexts]; bool enforceRule[kNumRules]; public: - CCommandSet(void); - ~CCommandSet(void); + CCommandSet(); //Population CString Add(KeyCombination kc, CommandID cmd, bool overwrite, int pos = -1); @@ -1326,4 +1320,3 @@ void UpgradeKeymap(CCommandSet *pCommands, int oldVersion); }; -//end rewbs.customKeys \ No newline at end of file Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2014-01-15 17:46:44 UTC (rev 3575) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2014-01-15 18:39:04 UTC (rev 3576) @@ -11,8 +11,9 @@ #include "stdafx.h" #ifdef MODPLUG_TRACKER -#include "../mptrack/mainfrm.h" -#include "../mptrack/moddoc.h" +#include "../mptrack/Mptrack.h" // For CTrackApp::OpenURL +#include "../mptrack/TrackerSettings.h" +#include "../mptrack/Moddoc.h" #include "../mptrack/Reporting.h" #endif // MODPLUG_TRACKER #include "../common/version.h" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-01-15 21:00:13
|
Revision: 3578 http://sourceforge.net/p/modplug/code/3578 Author: saga-games Date: 2014-01-15 20:59:59 +0000 (Wed, 15 Jan 2014) Log Message: ----------- [Mod] MOD/S3M: If sample number next to a portamento effect differs from the previous number, the old sample is now kept (but the new default volume is being applied) (http://bugs.openmpt.org/view.php?id=474) . [Fix] Fixed potential overflow in MMCMP unpacker (fix from libmodplug) [Mod] OpenMPT: Version is now 1.22.07.14 Modified Paths: -------------- trunk/OpenMPT/common/versionNumber.h trunk/OpenMPT/soundlib/Mmcmp.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp Modified: trunk/OpenMPT/common/versionNumber.h =================================================================== --- trunk/OpenMPT/common/versionNumber.h 2014-01-15 20:43:07 UTC (rev 3577) +++ trunk/OpenMPT/common/versionNumber.h 2014-01-15 20:59:59 UTC (rev 3578) @@ -17,7 +17,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 22 #define VER_MINOR 07 -#define VER_MINORMINOR 13 +#define VER_MINORMINOR 14 //Version string. For example "1.17.02.28" #define MPT_VERSION_STR VER_STRINGIZE(VER_MAJORMAJOR) "." VER_STRINGIZE(VER_MAJOR) "." VER_STRINGIZE(VER_MINOR) "." VER_STRINGIZE(VER_MINORMINOR) Modified: trunk/OpenMPT/soundlib/Mmcmp.cpp =================================================================== --- trunk/OpenMPT/soundlib/Mmcmp.cpp 2014-01-15 20:43:07 UTC (rev 3577) +++ trunk/OpenMPT/soundlib/Mmcmp.cpp 2014-01-15 20:59:59 UTC (rev 3578) @@ -149,7 +149,9 @@ { for (UINT i=0; i<pblk->sub_blk; i++) { - if ((psubblk->unpk_pos > dwFileSize) || (psubblk->unpk_pos + psubblk->unpk_size > dwFileSize)) break; + if ((psubblk->unpk_pos >= dwFileSize) || + (psubblk->unpk_size >= dwFileSize) || + (psubblk->unpk_size > dwFileSize - psubblk->unpk_pos)) break; #ifdef MMCMP_LOG Log(" Unpacked sub-block %d: offset %d, size=%d\n", i, psubblk->unpk_pos, psubblk->unpk_size); #endif Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-01-15 20:43:07 UTC (rev 3577) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-01-15 20:59:59 UTC (rev 3578) @@ -688,23 +688,24 @@ bool returnAfterVolumeAdjust = false; - // IT compatibility: No sample change (also within multi-sample instruments) during portamento when using Compatible Gxx. - // Test case: PortaInsNumCompat.it, PortaSampleCompat.it - if(bPorta && pChn->pModSample != nullptr && pChn->pModSample != pSmp && IsCompatibleMode(TRK_IMPULSETRACKER) && m_SongFlags[SONG_ITCOMPATGXX]) - { - pSmp = pChn->pModSample; - } - // instrumentChanged is used for IT carry-on env option bool instrumentChanged = (pIns != pChn->pModInstrument); const bool sampleChanged = (pChn->pModSample != nullptr) && (pSmp != pChn->pModSample); - if(!instrumentChanged) + if(sampleChanged && bPorta) { - // Special XM hack - if ((bPorta) && (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2)) && (pIns) - && sampleChanged) + // IT compatibility: No sample change (also within multi-sample instruments) during portamento when using Compatible Gxx. + // Test case: PortaInsNumCompat.it, PortaSampleCompat.it + if(IsCompatibleMode(TRK_IMPULSETRACKER) && m_SongFlags[SONG_ITCOMPATGXX]) { + pSmp = pChn->pModSample; + } + + // Special XM hack (also applies to MOD / S3M) + // Test case: PortaSmpChange.mod, PortaSmpChange.s3m + if((!instrumentChanged && (GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2)) && pIns) + || (GetType() & (MOD_TYPE_MOD | MOD_TYPE_S3M))) + { // FT2 doesn't change the sample in this case, // but still uses the sample info from the old one (bug?) returnAfterVolumeAdjust = true; @@ -734,11 +735,13 @@ // Update Volume if (bUpdVol) { - pChn->nVolume = 0; - if(pSmp) - pChn->nVolume = pSmp->nVolume; - else + if(!(GetType() & (MOD_TYPE_MOD | MOD_TYPE_S3M)) || pSmp->pSample != nullptr) { + pChn->nVolume = 0; + if(pSmp) + pChn->nVolume = pSmp->nVolume; + } else + { if(pIns && pIns->nMixPlug) pChn->nVolume = pChn->GetVSTVolume(); } @@ -3110,8 +3113,7 @@ pChn->nPortamentoDest = 0; pChn->m_CalculateFreq = true; } - } - else + } else { pChn->m_PortamentoFineSteps += slide; pChn->nPortamentoDest -= slide; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-01-19 22:03:03
|
Revision: 3583 http://sourceforge.net/p/modplug/code/3583 Author: saga-games Date: 2014-01-19 22:02:56 +0000 (Sun, 19 Jan 2014) Log Message: ----------- [New] Added hidden setting for loading a default template (DefaultTemplate in [Paths] section, can be either a full path or just a filename that can be found in the template folder). [Mod] OpenMPT: Version is now 1.22.07.15 Modified Paths: -------------- trunk/OpenMPT/common/versionNumber.h trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/Mptrack.h trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/mptrack/TrackerSettings.h Modified: trunk/OpenMPT/common/versionNumber.h =================================================================== --- trunk/OpenMPT/common/versionNumber.h 2014-01-17 21:33:18 UTC (rev 3582) +++ trunk/OpenMPT/common/versionNumber.h 2014-01-19 22:02:56 UTC (rev 3583) @@ -17,7 +17,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 22 #define VER_MINOR 07 -#define VER_MINORMINOR 14 +#define VER_MINORMINOR 15 //Version string. For example "1.17.02.28" #define MPT_VERSION_STR VER_STRINGIZE(VER_MAJORMAJOR) "." VER_STRINGIZE(VER_MAJOR) "." VER_STRINGIZE(VER_MINOR) "." VER_STRINGIZE(VER_MINORMINOR) Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2014-01-17 21:33:18 UTC (rev 3582) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2014-01-19 22:02:56 UTC (rev 3583) @@ -2137,29 +2137,8 @@ const bool bAvailable = Util::sdOs::IsPathFileAvailable(sPath, Util::sdOs::FileModeRead); if (bAvailable) { - CDocument* pDoc = theApp.OpenDocumentFile(sPath, bTemplateFile ? FALSE : TRUE); - if (pDoc != nullptr) - { - ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CModDoc)) == TRUE); - CModDoc* pModDoc = static_cast<CModDoc*>(pDoc); - pModDoc->ClearFilePath(); // Clear path so that saving will not take place in templates/examples folder. - // Remove extension from title, so that saving the file will not suggest a filename like e.g. "template.mptm.mptm". - const CString title = pModDoc->GetTitle(); - const int dotPos = title.ReverseFind('.'); - if(dotPos >= 0) - { - pModDoc->SetTitle(title.Left(dotPos)); - } - - if (bTemplateFile) - { - pModDoc->GetSoundFile()->GetFileHistory().clear(); // Reset edit history for template files - pModDoc->GetSoundFile()->m_dwCreatedWithVersion = MptVersion::num; - pModDoc->GetSoundFile()->m_dwLastSavedWithVersion = 0; - } - } - } - else + theApp.GetModDocTemplate()->OpenTemplateFile(sPath, !bTemplateFile); + } else { const bool bExists = Util::sdOs::IsPathFileAvailable(sPath, Util::sdOs::FileModeExists); Reporting::Notification(L"The file '" + sPath.ToWide() + L"' " + (bExists ? L"exists but can't be read" : L"does not exist")); @@ -2460,7 +2439,6 @@ } //end rewbs.VSTTimeInfo -//rewbs.customKeys // We have swicthed focus to a new module - might need to update effect keys to reflect module type bool CMainFrame::UpdateEffectKeys() //--------------------------------- @@ -2473,10 +2451,8 @@ return false; } -//end rewbs.customKeys -//rewbs.fix3116 void CMainFrame::OnKillFocus(CWnd* pNewWnd) //----------------------------------------- { @@ -2484,10 +2460,9 @@ //rewbs: ensure modifiers are reset when we leave the window (e.g. alt-tab) CMainFrame::GetMainFrame()->GetInputHandler()->SetModifierMask(0); - //end rewbs } -//end rewbs.fix3116 + void CMainFrame::OnShowWindow(BOOL bShow, UINT /*nStatus*/) //--------------------------------------------------------- { @@ -2542,7 +2517,7 @@ void CMainFrame::OnHelp() //----------------------- { - mpt::PathString helpFile = theApp.GetAppDirPath() + MPT_PATHSTRING("OpenMPT Manual.pdf"); + const mpt::PathString helpFile = theApp.GetAppDirPath() + MPT_PATHSTRING("OpenMPT Manual.pdf"); if(!theApp.OpenFile(helpFile)) { Reporting::Error(L"Could not find help file:\n" + helpFile.ToWide()); @@ -2687,7 +2662,7 @@ for(size_t i = 0; i < TrackerSettings::Instance().mruFiles.size(); i++) { - std::wstring s = StringifyW(i + 1) + L" "; + std::wstring s = mpt::ToWString(i + 1) + L" "; // Add mnemonics if(i < 9) { Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2014-01-17 21:33:18 UTC (rev 3582) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2014-01-19 22:02:56 UTC (rev 3583) @@ -111,6 +111,41 @@ } +CDocument* CModDocTemplate::OpenTemplateFile(const mpt::PathString &filename, bool isExampleTune) +//----------------------------------------------------------------------------------------------- +{ + CDocument *doc = OpenDocumentFile(filename, isExampleTune ? TRUE : FALSE, TRUE); + if(doc) + { + CModDoc *modDoc = static_cast<CModDoc *>(doc); + // Clear path so that saving will not take place in templates/examples folder. + modDoc->ClearFilePath(); + if(!isExampleTune) + { + CMultiDocTemplate::SetDefaultTitle(modDoc); + m_nUntitledCount++; + // Name has changed... + CMainFrame::GetMainFrame()->UpdateTree(modDoc, HINT_MODGENERAL); + + // Reset edit history for template files + modDoc->GetrSoundFile().GetFileHistory().clear(); + modDoc->GetrSoundFile().m_dwCreatedWithVersion = MptVersion::num; + modDoc->GetrSoundFile().m_dwLastSavedWithVersion = 0; + } else + { + // Remove extension from title, so that saving the file will not suggest a filename like e.g. "example.it.it". + const CString title = modDoc->GetTitle(); + const int dotPos = title.ReverseFind('.'); + if(dotPos >= 0) + { + modDoc->SetTitle(title.Left(dotPos)); + } + } + } + return doc; +} + + #ifdef _DEBUG #define DDEDEBUG #endif @@ -986,6 +1021,24 @@ { if (!m_bInitialized) return; + // Build from template + const mpt::PathString templateFile = TrackerSettings::Instance().defaultTemplateFile; + if(!templateFile.empty()) + { + const mpt::PathString dirs[] = { GetConfigPath(), GetAppDirPath(), mpt::PathString() }; + for(size_t i = 0; i < CountOf(dirs); i++) + { + if(Util::sdOs::IsPathFileAvailable(dirs[i] + templateFile, Util::sdOs::FileModeExists)) + { + if(m_pModTemplate->OpenTemplateFile(dirs[i] + templateFile) != nullptr) + { + return; + } + } + } + } + + // Default module type MODTYPE nNewType = TrackerSettings::Instance().defaultModType; bool bIsProject = false; Modified: trunk/OpenMPT/mptrack/Mptrack.h =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.h 2014-01-17 21:33:18 UTC (rev 3582) +++ trunk/OpenMPT/mptrack/Mptrack.h 2014-01-19 22:02:56 UTC (rev 3583) @@ -118,6 +118,7 @@ CMultiDocTemplate(nIDResource, pDocClass, pFrameClass, pViewClass) {} CDocument* OpenDocumentFile(const mpt::PathString &filename, BOOL addToMru = TRUE, BOOL makeVisible = TRUE); + CDocument* OpenTemplateFile(const mpt::PathString &filename, bool isExampleTune = false); // inherited members, overload them all #if MPT_COMPILER_MSVC && MPT_MSVC_BEFORE(2010,0) Modified: trunk/OpenMPT/mptrack/TrackerSettings.cpp =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-01-17 21:33:18 UTC (rev 3582) +++ trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-01-19 22:02:56 UTC (rev 3583) @@ -197,6 +197,8 @@ , m_MayNormalizeSamplesOnLoad(conf, "Sample Editor", "MayNormalizeSamplesOnLoad", true) // Export , ExportDefaultToSoundcardSamplerate(conf, "Export", "DefaultToSoundcardSamplerate", true) + // Default template + , defaultTemplateFile(conf, "Paths", "DefaultTemplate", mpt::PathString()) // MRU List , mruListLength(conf, "Misc", "MRUListLength", 10) { Modified: trunk/OpenMPT/mptrack/TrackerSettings.h =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.h 2014-01-17 21:33:18 UTC (rev 3582) +++ trunk/OpenMPT/mptrack/TrackerSettings.h 2014-01-19 22:02:56 UTC (rev 3583) @@ -362,6 +362,8 @@ // Paths mpt::PathString m_szKbdFile; + // Default template + Setting<mpt::PathString> defaultTemplateFile; Setting<uint32> mruListLength; std::vector<mpt::PathString> mruFiles; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-01-20 21:45:51
|
Revision: 3584 http://sourceforge.net/p/modplug/code/3584 Author: saga-games Date: 2014-01-20 21:45:44 +0000 (Mon, 20 Jan 2014) Log Message: ----------- [Fix] Instrument editor: XM panning envelope should have a range of 0...63 instead of 0...64 (whyyyyy) [Fix] Tree view: Possible crash when loading a module with no patterns. Modified Paths: -------------- trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/soundlib/XMTools.h Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2014-01-19 22:02:56 UTC (rev 3583) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2014-01-20 21:45:44 UTC (rev 3584) @@ -314,7 +314,8 @@ } if(nValue >= 0) { - if(nValue > 64) nValue = 64; + const int maxVal = (GetDocument()->GetModType() != MOD_TYPE_XM || m_nEnv != ENV_PANNING) ? 64 : 63; + LimitMax(nValue, maxVal); if(nValue != envelope->Values[nPoint]) { envelope->Values[nPoint] = (uint8)nValue; Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2014-01-19 22:02:56 UTC (rev 3583) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2014-01-20 21:45:44 UTC (rev 3584) @@ -170,6 +170,7 @@ { SetEvent(m_hWatchDirKillThread); WaitForSingleObject(watchDirThread, INFINITE); + CloseHandle(watchDirThread); } } @@ -934,7 +935,7 @@ } } // Add Patterns - if (info.hPatterns && (hintFlagPart & (HINT_MODTYPE | HINT_PATNAMES))) + if (info.hPatterns && (hintFlagPart & (HINT_MODTYPE | HINT_PATNAMES)) && sndFile.Patterns.Size() > 0) { const PATTERNINDEX nPat = (PATTERNINDEX)(lHint >> HINT_SHIFT_PAT); info.tiPatterns.resize(sndFile.Patterns.Size(), NULL); @@ -1821,6 +1822,7 @@ PostMessage(WM_COMMAND, ID_MODTREE_REFRESHINSTRLIB); } } while(result != WAIT_OBJECT_0); + CloseHandle(m_hWatchDirKillThread); } Modified: trunk/OpenMPT/soundlib/XMTools.h =================================================================== --- trunk/OpenMPT/soundlib/XMTools.h 2014-01-19 22:02:56 UTC (rev 3583) +++ trunk/OpenMPT/soundlib/XMTools.h 2014-01-20 21:45:44 UTC (rev 3584) @@ -58,8 +58,8 @@ }; uint8 sampleMap[96]; // Note -> Sample assignment - uint16 volEnv[24]; // Volume envelope nodes / values - uint16 panEnv[24]; // Panning envelope nodes / values + uint16 volEnv[24]; // Volume envelope nodes / values (0...64) + uint16 panEnv[24]; // Panning envelope nodes / values (0...63) uint8 volPoints; // Volume envelope length uint8 panPoints; // Panning envelope length uint8 volSustain; // Volume envelope sustain point This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-01-26 00:32:39
|
Revision: 3586 http://sourceforge.net/p/modplug/code/3586 Author: saga-games Date: 2014-01-26 00:32:32 +0000 (Sun, 26 Jan 2014) Log Message: ----------- [Fix] VST: Poise by One Small Clue should no longer crash if the editor is still open when unloading the plugin. [Mod] OpenMPT: Version is now 1.22.07.16 Modified Paths: -------------- trunk/OpenMPT/common/versionNumber.h trunk/OpenMPT/mptrack/Vstplug.cpp Modified: trunk/OpenMPT/common/versionNumber.h =================================================================== --- trunk/OpenMPT/common/versionNumber.h 2014-01-25 14:41:14 UTC (rev 3585) +++ trunk/OpenMPT/common/versionNumber.h 2014-01-26 00:32:32 UTC (rev 3586) @@ -17,7 +17,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 22 #define VER_MINOR 07 -#define VER_MINORMINOR 15 +#define VER_MINORMINOR 16 //Version string. For example "1.17.02.28" #define MPT_VERSION_STR VER_STRINGIZE(VER_MAJORMAJOR) "." VER_STRINGIZE(VER_MAJOR) "." VER_STRINGIZE(VER_MINOR) "." VER_STRINGIZE(VER_MINORMINOR) Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2014-01-25 14:41:14 UTC (rev 3585) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2014-01-26 00:32:32 UTC (rev 3586) @@ -818,18 +818,6 @@ #endif CriticalSection cs; - // First thing to do, if we don't want to hang in a loop - if (m_Factory.pPluginsList == this) m_Factory.pPluginsList = m_pNext; - if (m_pMixStruct) - { - m_pMixStruct->pMixPlugin = nullptr; - m_pMixStruct->pMixState = nullptr; - m_pMixStruct = nullptr; - } - if (m_pNext) m_pNext->m_pPrev = m_pPrev; - if (m_pPrev) m_pPrev->m_pNext = m_pNext; - m_pPrev = nullptr; - m_pNext = nullptr; if (m_pEditor) { if (m_pEditor->m_hWnd) m_pEditor->OnClose(); @@ -844,6 +832,20 @@ if (m_Effect.numOutputs > 1) Dispatch(effConnectOutput, 1, 0, nullptr, 0); } Suspend(); + + // First thing to do, if we don't want to hang in a loop + if (m_Factory.pPluginsList == this) m_Factory.pPluginsList = m_pNext; + if (m_pMixStruct) + { + m_pMixStruct->pMixPlugin = nullptr; + m_pMixStruct->pMixState = nullptr; + m_pMixStruct = nullptr; + } + if (m_pNext) m_pNext->m_pPrev = m_pPrev; + if (m_pPrev) m_pPrev->m_pNext = m_pNext; + m_pPrev = nullptr; + m_pNext = nullptr; + CVstPlugin::Dispatch(effClose, 0, 0, nullptr, 0); if(m_hLibrary) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <man...@us...> - 2014-01-27 09:19:49
|
Revision: 3590 http://sourceforge.net/p/modplug/code/3590 Author: manxorist Date: 2014-01-27 09:19:41 +0000 (Mon, 27 Jan 2014) Log Message: ----------- [Imp] libopenmpt: Support building with neither Win32, nor iconv, nor a C++11 compliant compiler. For UTF-8 conversion, a custom conversion routine is used in this case. #define MPT_CHARSET_CUSTOMUTF8 to build that way. This allows building with the Android NDK. Modified Paths: -------------- trunk/OpenMPT/common/mptString.cpp trunk/OpenMPT/common/version.cpp trunk/OpenMPT/libopenmpt/dox/dependencies.md Modified: trunk/OpenMPT/common/mptString.cpp =================================================================== --- trunk/OpenMPT/common/mptString.cpp 2014-01-27 00:19:14 UTC (rev 3589) +++ trunk/OpenMPT/common/mptString.cpp 2014-01-27 09:19:41 UTC (rev 3590) @@ -12,6 +12,8 @@ #if defined(MPT_CHARSET_CPP) #include <codecvt> +#elif defined(MPT_CHARSET_CUSTOMUTF8) +#include <cstdlib> #endif #include <iomanip> #include <iterator> @@ -23,7 +25,7 @@ #include <cstdarg> -#if !defined(MPT_CHARSET_CPP) && !defined(WIN32) +#if !defined(MPT_CHARSET_CPP) && !defined(MPT_CHARSET_CUSTOMUTF8) && !defined(WIN32) #include <iconv.h> #endif // !WIN32 @@ -85,7 +87,7 @@ }; */ -#if defined(MPT_CHARSET_CPP) +#if defined(MPT_CHARSET_CPP) || defined(MPT_CHARSET_CUSTOMUTF8) static const uint32 CharsetTableISO8859_15[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, @@ -254,7 +256,7 @@ return res; } -#if defined(MPT_CHARSET_CPP) +#if defined(MPT_CHARSET_CPP) || defined(MPT_CHARSET_CUSTOMUTF8) static std::wstring FromAscii(const std::string &str, wchar_t replacement = L'\uFFFD') //------------------------------------------------------------------------------------ @@ -473,6 +475,8 @@ return String::ToAscii(str, replacement); // fallback } +#if defined(MPT_CHARSET_CPP) + static std::wstring FromUTF8(const std::string &str, wchar_t replacement = L'\uFFFD') //----------------------------------------------------------------------------------- { @@ -489,6 +493,167 @@ return conv.to_bytes(str); } +#elif defined(MPT_CHARSET_CUSTOMUTF8) + +static std::wstring FromUTF8(const std::string &str, wchar_t replacement = L'\uFFFD') +//----------------------------------------------------------------------------------- +{ + const std::string &in = str; + + std::wstring out; + + // state: + std::size_t charsleft = 0; + uint32 ucs4 = 0; + + for ( std::string::const_iterator i = in.begin(); i != in.end(); ++i ) { + + uint8 c = *i; + + if ( charsleft == 0 ) { + + if ( ( c & 0x80 ) == 0x00 ) { + out.push_back( (wchar_t)c ); + } else if ( ( c & 0xE0 ) == 0xC0 ) { + ucs4 = c & 0x1F; + charsleft = 1; + } else if ( ( c & 0xF0 ) == 0xE0 ) { + ucs4 = c & 0x0F; + charsleft = 2; + } else if ( ( c & 0xF8 ) == 0xF0 ) { + ucs4 = c & 0x07; + charsleft = 3; + } else { + out.push_back( replacement ); + ucs4 = 0; + charsleft = 0; + } + + } else { + + if ( ( c & 0xC0 ) != 0x80 ) { + out.push_back( replacement ); + ucs4 = 0; + charsleft = 0; + } + ucs4 <<= 6; + ucs4 |= c & 0x3F; + charsleft--; + + if ( charsleft == 0 ) { + if ( sizeof( wchar_t ) == 2 ) { + if ( ucs4 > 0x1fffff ) { + out.push_back( replacement ); + ucs4 = 0; + charsleft = 0; + } + if ( ucs4 <= 0xffff ) { + out.push_back( (uint16)ucs4 ); + } else { + uint32 surrogate = ucs4 - 0x10000; + uint16 hi_sur = static_cast<uint16>( ( 0x36 << 10 ) | ( (surrogate>>10) & ((1<<10)-1) ) ); + uint16 lo_sur = static_cast<uint16>( ( 0x37 << 10 ) | ( (surrogate>> 0) & ((1<<10)-1) ) ); + out.push_back( hi_sur ); + out.push_back( lo_sur ); + } + } else { + out.push_back( ucs4 ); + } + ucs4 = 0; + } + + } + + } + + if ( charsleft != 0 ) { + out.push_back( replacement ); + ucs4 = 0; + charsleft = 0; + } + + return out; + +} + +static std::string ToUTF8(const std::wstring &str, char replacement = '?') +//------------------------------------------------------------------------ +{ + const std::wstring &in = str; + + std::string out; + + for ( std::size_t i=0; i<in.length(); i++ ) { + + wchar_t c = in[i]; + if ( c > 0x1fffff || c < 0 ) { + out.push_back( replacement ); + } + + uint32 ucs4 = 0; + if ( sizeof( wchar_t ) == 2 ) { + if ( i + 1 < in.length() ) { + // check for surrogate pair + uint16 hi_sur = in[i+0]; + uint16 lo_sur = in[i+1]; + if ( hi_sur >> 10 == 0x36 && lo_sur >> 10 == 0x37 ) { + // surrogate pair + ++i; + hi_sur &= (1<<10)-1; + lo_sur &= (1<<10)-1; + ucs4 = ( (uint32)hi_sur << 10 ) | ( (uint32)lo_sur << 0 ); + } else { + // no surrogate pair + ucs4 = (uint32)(uint16)c; + } + } else { + // no surrogate possible + ucs4 = (uint32)(uint16)c; + } + } else { + ucs4 = c; + } + + uint8 utf8[6]; + std::size_t numchars = 0; + for ( numchars = 0; numchars < 6; numchars++ ) { + utf8[numchars] = ucs4 & 0x3F; + ucs4 >>= 6; + if ( ucs4 == 0 ) { + break; + } + } + numchars++; + + if ( numchars == 1 ) { + out.push_back( utf8[0] ); + continue; + } + + if ( numchars == 2 && utf8[numchars-1] == 0x01 ) { + // generate shortest form + out.push_back( utf8[0] | 0x40 ); + continue; + } + + std::size_t charsleft = numchars; + while ( charsleft > 0 ) { + if ( charsleft == numchars ) { + out.push_back( utf8[ charsleft - 1 ] | ( ((1<<numchars)-1) << (8-numchars) ) ); + } else { + out.push_back( utf8[ charsleft - 1 ] | 0x80 ); + } + charsleft--; + } + + } + + return out; + +} + +#endif // MPT_CHARSET_CPP || MPT_CHARSET_CUSTOMUTF8 + #elif defined(WIN32) static UINT CharsetToCodepage(Charset charset) { @@ -587,7 +752,7 @@ std::copy(out.begin(), out.end(), std::back_inserter(result)); return result; } - #if defined(MPT_CHARSET_CPP) + #if defined(MPT_CHARSET_CPP) || defined(MPT_CHARSET_CUSTOMUTF8) std::string out; switch(charset) { @@ -669,7 +834,7 @@ if(charset == CharsetCP437AMS2) out = String::From8bit(in, CharsetTableCP437AMS2); return out; } - #if defined(MPT_CHARSET_CPP) + #if defined(MPT_CHARSET_CPP) || defined(MPT_CHARSET_CUSTOMUTF8) std::string in; std::copy(src.begin(), src.end(), std::back_inserter(in)); std::wstring out; @@ -751,7 +916,7 @@ { return Tdststring(reinterpret_cast<const typename Tdststring::value_type*>(&*src.begin()), reinterpret_cast<const typename Tdststring::value_type*>(&*src.end())); } - #if defined(MPT_CHARSET_CPP) || defined(WIN32) + #if defined(MPT_CHARSET_CPP) || defined(MPT_CHARSET_CUSTOMUTF8) || defined(WIN32) return EncodeImpl<Tdststring>(to, DecodeImpl(from, src)); #else // !WIN32 if(to == CharsetCP437AMS || to == CharsetCP437AMS2 || from == CharsetCP437AMS || from == CharsetCP437AMS2) Modified: trunk/OpenMPT/common/version.cpp =================================================================== --- trunk/OpenMPT/common/version.cpp 2014-01-27 00:19:14 UTC (rev 3589) +++ trunk/OpenMPT/common/version.cpp 2014-01-27 09:19:41 UTC (rev 3590) @@ -201,6 +201,8 @@ retval += " +WINAPI"; #elif defined(MPT_CHARSET_CPP) retval += " +CODECVT"; + #elif defined(MPT_CHARSET_CUSTOMUTF8) + retval += " +CUSTOMUTF8"; #else retval += " +ICONV"; #endif Modified: trunk/OpenMPT/libopenmpt/dox/dependencies.md =================================================================== --- trunk/OpenMPT/libopenmpt/dox/dependencies.md 2014-01-27 00:19:14 UTC (rev 3589) +++ trunk/OpenMPT/libopenmpt/dox/dependencies.md 2014-01-27 09:19:41 UTC (rev 3590) @@ -26,9 +26,9 @@ * Building on Unix-like systems requires: * **GNU make** * **pkg-config** - -Note that, when building with a C++11 compliant compiler or when building on Windows, libopenmpt can be built without any dependency on other libraries except the C++ standard library. +Note that it is possible to build libopenmpt without either Win32, iconv or a C++1 compliant compiler, in which case a custom UTF8 conversion routine is used. `#define MPT_CHARSET_CUSTOMUTF8` in your build system to build that way. It is, however, recommended to stick with the system-rpovided character set conversions. + ### openmpt123 * Supported compilers for building openmpt: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <man...@us...> - 2014-01-27 09:43:47
|
Revision: 3591 http://sourceforge.net/p/modplug/code/3591 Author: manxorist Date: 2014-01-27 09:43:38 +0000 (Mon, 27 Jan 2014) Log Message: ----------- [New] build: Add a simple Android NDK makefile for libopenmpt. Modified Paths: -------------- trunk/OpenMPT/README.md Added Paths: ----------- trunk/OpenMPT/build/android_ndk/ trunk/OpenMPT/build/android_ndk/Android.mk trunk/OpenMPT/build/android_ndk/Application.mk trunk/OpenMPT/build/android_ndk/README.AndroidNDK.txt Modified: trunk/OpenMPT/README.md =================================================================== --- trunk/OpenMPT/README.md 2014-01-27 09:19:41 UTC (rev 3590) +++ trunk/OpenMPT/README.md 2014-01-27 09:43:38 UTC (rev 3591) @@ -135,8 +135,12 @@ `PREFIX` defaults to `/usr/local`. A `DESTDIR=` parameter is also supported. + - Android NDK + See `build/android_ndk/README.AndroidNDK.txt`. + + Coding conventions ------------------ Index: trunk/OpenMPT/build/android_ndk =================================================================== --- trunk/OpenMPT/build/android_ndk 2014-01-27 09:19:41 UTC (rev 3590) +++ trunk/OpenMPT/build/android_ndk 2014-01-27 09:43:38 UTC (rev 3591) Property changes on: trunk/OpenMPT/build/android_ndk ___________________________________________________________________ Added: tsvn:logminsize ## -0,0 +1 ## +10 \ No newline at end of property Added: trunk/OpenMPT/build/android_ndk/Android.mk =================================================================== --- trunk/OpenMPT/build/android_ndk/Android.mk (rev 0) +++ trunk/OpenMPT/build/android_ndk/Android.mk 2014-01-27 09:43:38 UTC (rev 3591) @@ -0,0 +1,99 @@ + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := openmpt + +LOCAL_CPP_FEATURES += exceptions +LOCAL_CPP_FEATURES += rtti + +LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/common $(LOCAL_PATH)/common/svn_version_default + +LOCAL_CFLAGS := -DLIBOPENMPT_BUILD -DMPT_CHARSET_CUSTOMUTF8 -DMPT_WITH_ZLIB +LOCAL_CPPFLAGS := -std=c++11 -DLIBOPENMPT_BUILD -DMPT_CHARSET_CUSTOMUTF8 -DMPT_WITH_ZLIB +LOCAL_LDLIBS := -lz + +LOCAL_SRC_FILES := \ + common/AudioCriticalSection.cpp \ + common/stdafx.cpp \ + common/misc_util.cpp \ + common/mptPathString.cpp \ + common/mptString.cpp \ + common/Profiler.cpp \ + common/serialization_utils.cpp \ + common/typedefs.cpp \ + common/version.cpp \ + libopenmpt/libopenmpt_c.cpp \ + libopenmpt/libopenmpt_cxx.cpp \ + libopenmpt/libopenmpt_impl.cpp \ + libopenmpt/libopenmpt_ext.cpp \ + soundlib/Dither.cpp \ + soundlib/Dlsbank.cpp \ + soundlib/Fastmix.cpp \ + soundlib/ITCompression.cpp \ + soundlib/ITTools.cpp \ + soundlib/Load_669.cpp \ + soundlib/Load_amf.cpp \ + soundlib/Load_ams.cpp \ + soundlib/Load_dbm.cpp \ + soundlib/Load_digi.cpp \ + soundlib/Load_dmf.cpp \ + soundlib/Load_dsm.cpp \ + soundlib/Load_far.cpp \ + soundlib/Load_gdm.cpp \ + soundlib/Load_imf.cpp \ + soundlib/Load_it.cpp \ + soundlib/Load_itp.cpp \ + soundlib/load_j2b.cpp \ + soundlib/Load_mdl.cpp \ + soundlib/Load_med.cpp \ + soundlib/Load_mid.cpp \ + soundlib/Load_mo3.cpp \ + soundlib/Load_mod.cpp \ + soundlib/Load_mt2.cpp \ + soundlib/Load_mtm.cpp \ + soundlib/Load_okt.cpp \ + soundlib/Load_psm.cpp \ + soundlib/Load_ptm.cpp \ + soundlib/Load_s3m.cpp \ + soundlib/Load_stm.cpp \ + soundlib/Load_ult.cpp \ + soundlib/Load_umx.cpp \ + soundlib/Load_wav.cpp \ + soundlib/Load_xm.cpp \ + soundlib/Message.cpp \ + soundlib/MIDIEvents.cpp \ + soundlib/MIDIMacros.cpp \ + soundlib/MixerLoops.cpp \ + soundlib/MixerSettings.cpp \ + soundlib/Mmcmp.cpp \ + soundlib/ModChannel.cpp \ + soundlib/modcommand.cpp \ + soundlib/ModInstrument.cpp \ + soundlib/ModSample.cpp \ + soundlib/ModSequence.cpp \ + soundlib/modsmp_ctrl.cpp \ + soundlib/mod_specifications.cpp \ + soundlib/patternContainer.cpp \ + soundlib/pattern.cpp \ + soundlib/RowVisitor.cpp \ + soundlib/S3MTools.cpp \ + soundlib/SampleFormats.cpp \ + soundlib/SampleIO.cpp \ + soundlib/Sndfile.cpp \ + soundlib/Snd_flt.cpp \ + soundlib/Snd_fx.cpp \ + soundlib/Sndmix.cpp \ + soundlib/SoundFilePlayConfig.cpp \ + soundlib/Tables.cpp \ + soundlib/Tagging.cpp \ + soundlib/tuningbase.cpp \ + soundlib/tuningCollection.cpp \ + soundlib/tuning.cpp \ + soundlib/WAVTools.cpp \ + soundlib/WindowedFIR.cpp \ + soundlib/XMTools.cpp \ + test/test.cpp + +include $(BUILD_SHARED_LIBRARY) Property changes on: trunk/OpenMPT/build/android_ndk/Android.mk ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/x-makefile \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: trunk/OpenMPT/build/android_ndk/Application.mk =================================================================== --- trunk/OpenMPT/build/android_ndk/Application.mk (rev 0) +++ trunk/OpenMPT/build/android_ndk/Application.mk 2014-01-27 09:43:38 UTC (rev 3591) @@ -0,0 +1,2 @@ + +APP_STL := gnustl_shared Property changes on: trunk/OpenMPT/build/android_ndk/Application.mk ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/x-makefile \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: trunk/OpenMPT/build/android_ndk/README.AndroidNDK.txt =================================================================== --- trunk/OpenMPT/build/android_ndk/README.AndroidNDK.txt (rev 0) +++ trunk/OpenMPT/build/android_ndk/README.AndroidNDK.txt 2014-01-27 09:43:38 UTC (rev 3591) @@ -0,0 +1,10 @@ + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +This is preliminarily documentation. +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + 1. Copy the whole libopenmpt source tree below your jni directory. + 2. Copy build/android_ndk/* into the root of libopenmpt, i.e. also into the + jni directory and adjust as needed. + 3. Use ndk-build as usual. + Property changes on: trunk/OpenMPT/build/android_ndk/README.AndroidNDK.txt ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <man...@us...> - 2014-02-01 13:50:53
|
Revision: 3601 http://sourceforge.net/p/modplug/code/3601 Author: manxorist Date: 2014-02-01 13:50:38 +0000 (Sat, 01 Feb 2014) Log Message: ----------- Merged branches/floatmixer-loopfix-new: New floatmixer + loop fix branch, based on the current HEAD revisions with further fixes and improvements. [New] Removed ugly macro-based mixer by template-based mixer with both support for integer and floating point mixing. (FP mixer doesn't compile yet) [Fix] Interpolation around loop points is now handled correctly (at least at the loop end). [Ref] One more table documentation, and an unused removed extern Modified Paths: -------------- trunk/OpenMPT/common/typedefs.h trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj.filters trunk/OpenMPT/libopenmpt/libopenmptDLL.vcxproj trunk/OpenMPT/libopenmpt/libopenmptDLL.vcxproj.filters trunk/OpenMPT/libopenmpt/libopenmpt_test.vcxproj trunk/OpenMPT/libopenmpt/libopenmpt_test.vcxproj.filters trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/ModConvert.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Undo.cpp trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters trunk/OpenMPT/sounddsp/EQ.cpp trunk/OpenMPT/sounddsp/EQ.h trunk/OpenMPT/sounddsp/Reverb.cpp trunk/OpenMPT/sounddsp/Reverb.h trunk/OpenMPT/soundlib/AudioReadTarget.h trunk/OpenMPT/soundlib/Dither.cpp trunk/OpenMPT/soundlib/Dlsbank.cpp trunk/OpenMPT/soundlib/Fastmix.cpp trunk/OpenMPT/soundlib/Load_ams.cpp trunk/OpenMPT/soundlib/Load_itp.cpp trunk/OpenMPT/soundlib/Load_wav.cpp trunk/OpenMPT/soundlib/MixerLoops.cpp trunk/OpenMPT/soundlib/MixerLoops.h trunk/OpenMPT/soundlib/ModChannel.h trunk/OpenMPT/soundlib/ModSample.cpp trunk/OpenMPT/soundlib/ModSample.h trunk/OpenMPT/soundlib/Resampler.h trunk/OpenMPT/soundlib/SampleFormatConverters.h trunk/OpenMPT/soundlib/SampleFormats.cpp trunk/OpenMPT/soundlib/SampleIO.cpp trunk/OpenMPT/soundlib/Snd_defs.h trunk/OpenMPT/soundlib/Snd_flt.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp trunk/OpenMPT/soundlib/SoundFilePlayConfig.cpp trunk/OpenMPT/soundlib/Tables.cpp trunk/OpenMPT/soundlib/WindowedFIR.cpp trunk/OpenMPT/soundlib/WindowedFIR.h trunk/OpenMPT/soundlib/modsmp_ctrl.cpp trunk/OpenMPT/soundlib/modsmp_ctrl.h trunk/OpenMPT/soundlib/plugins/PlugInterface.h Added Paths: ----------- trunk/OpenMPT/soundlib/FloatMixer.h trunk/OpenMPT/soundlib/IntMixer.h trunk/OpenMPT/soundlib/Mixer.h trunk/OpenMPT/soundlib/MixerInterface.h Property Changed: ---------------- trunk/OpenMPT/ Index: trunk/OpenMPT =================================================================== --- trunk/OpenMPT 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT 2014-02-01 13:50:38 UTC (rev 3601) Property changes on: trunk/OpenMPT ___________________________________________________________________ Modified: svn:mergeinfo ## -1,3 +1,4 ## +/branches/floatmixer-loopfix-new:3572-3600 /branches/manx/build-speedup:1586-1589 /branches/manx/gcc-fixes:2018-2022,2024-2048,2052-2071,2075-2077,2080,2087-2089 /branches/manx/header-dependencies-cleanups:1394-1397,1401-1402,1405-1406 \ No newline at end of property Modified: trunk/OpenMPT/common/typedefs.h =================================================================== --- trunk/OpenMPT/common/typedefs.h 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/common/typedefs.h 2014-02-01 13:50:38 UTC (rev 3601) @@ -94,6 +94,15 @@ +// Use MPT_RESTRICT to indicate that a pointer is guaranteed to not be aliased. +#if MPT_COMPILER_MSVC || MPT_COMPILER_GCC || MPT_COMPILER_CLANG +#define MPT_RESTRICT __restrict +#else +#define MPT_RESTRICT +#endif + + + // Some functions might be deprecated although they are still in use. // Tag them with "MPT_DEPRECATED". #if MPT_COMPILER_MSVC Modified: trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj 2014-02-01 13:50:38 UTC (rev 3601) @@ -202,12 +202,16 @@ <ClInclude Include="..\soundlib\Dlsbank.h" /> <ClInclude Include="..\soundlib\Endianness.h" /> <ClInclude Include="..\soundlib\FileReader.h" /> + <ClInclude Include="..\soundlib\FloatMixer.h" /> + <ClInclude Include="..\soundlib\IntMixer.h" /> <ClInclude Include="..\soundlib\ITCompression.h" /> <ClInclude Include="..\soundlib\ITTools.h" /> <ClInclude Include="..\soundlib\Loaders.h" /> <ClInclude Include="..\soundlib\Message.h" /> <ClInclude Include="..\soundlib\MIDIEvents.h" /> <ClInclude Include="..\soundlib\MIDIMacros.h" /> + <ClInclude Include="..\soundlib\Mixer.h" /> + <ClInclude Include="..\soundlib\MixerInterface.h" /> <ClInclude Include="..\soundlib\MixerLoops.h" /> <ClInclude Include="..\soundlib\MixerSettings.h" /> <ClInclude Include="..\soundlib\ModChannel.h" /> Modified: trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj.filters =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj.filters 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj.filters 2014-02-01 13:50:38 UTC (rev 3601) @@ -245,6 +245,18 @@ <ClInclude Include="libopenmpt_ext.hpp"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\soundlib\FloatMixer.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> + <ClInclude Include="..\soundlib\IntMixer.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> + <ClInclude Include="..\soundlib\Mixer.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> + <ClInclude Include="..\soundlib\MixerInterface.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="..\common\AudioCriticalSection.cpp"> Modified: trunk/OpenMPT/libopenmpt/libopenmptDLL.vcxproj =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmptDLL.vcxproj 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/libopenmpt/libopenmptDLL.vcxproj 2014-02-01 13:50:38 UTC (rev 3601) @@ -210,12 +210,16 @@ <ClInclude Include="..\soundlib\Dlsbank.h" /> <ClInclude Include="..\soundlib\Endianness.h" /> <ClInclude Include="..\soundlib\FileReader.h" /> + <ClInclude Include="..\soundlib\FloatMixer.h" /> + <ClInclude Include="..\soundlib\IntMixer.h" /> <ClInclude Include="..\soundlib\ITCompression.h" /> <ClInclude Include="..\soundlib\ITTools.h" /> <ClInclude Include="..\soundlib\Loaders.h" /> <ClInclude Include="..\soundlib\Message.h" /> <ClInclude Include="..\soundlib\MIDIEvents.h" /> <ClInclude Include="..\soundlib\MIDIMacros.h" /> + <ClInclude Include="..\soundlib\Mixer.h" /> + <ClInclude Include="..\soundlib\MixerInterface.h" /> <ClInclude Include="..\soundlib\MixerLoops.h" /> <ClInclude Include="..\soundlib\MixerSettings.h" /> <ClInclude Include="..\soundlib\ModChannel.h" /> Modified: trunk/OpenMPT/libopenmpt/libopenmptDLL.vcxproj.filters =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmptDLL.vcxproj.filters 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/libopenmpt/libopenmptDLL.vcxproj.filters 2014-02-01 13:50:38 UTC (rev 3601) @@ -251,6 +251,18 @@ <ClInclude Include="libopenmpt_ext.hpp"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\soundlib\FloatMixer.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> + <ClInclude Include="..\soundlib\IntMixer.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> + <ClInclude Include="..\soundlib\Mixer.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> + <ClInclude Include="..\soundlib\MixerInterface.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="..\common\AudioCriticalSection.cpp"> Modified: trunk/OpenMPT/libopenmpt/libopenmpt_test.vcxproj =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmpt_test.vcxproj 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/libopenmpt/libopenmpt_test.vcxproj 2014-02-01 13:50:38 UTC (rev 3601) @@ -206,12 +206,16 @@ <ClInclude Include="..\soundlib\Dlsbank.h" /> <ClInclude Include="..\soundlib\Endianness.h" /> <ClInclude Include="..\soundlib\FileReader.h" /> + <ClInclude Include="..\soundlib\FloatMixer.h" /> + <ClInclude Include="..\soundlib\IntMixer.h" /> <ClInclude Include="..\soundlib\ITCompression.h" /> <ClInclude Include="..\soundlib\ITTools.h" /> <ClInclude Include="..\soundlib\Loaders.h" /> <ClInclude Include="..\soundlib\Message.h" /> <ClInclude Include="..\soundlib\MIDIEvents.h" /> <ClInclude Include="..\soundlib\MIDIMacros.h" /> + <ClInclude Include="..\soundlib\Mixer.h" /> + <ClInclude Include="..\soundlib\MixerInterface.h" /> <ClInclude Include="..\soundlib\MixerLoops.h" /> <ClInclude Include="..\soundlib\MixerSettings.h" /> <ClInclude Include="..\soundlib\ModChannel.h" /> Modified: trunk/OpenMPT/libopenmpt/libopenmpt_test.vcxproj.filters =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmpt_test.vcxproj.filters 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/libopenmpt/libopenmpt_test.vcxproj.filters 2014-02-01 13:50:38 UTC (rev 3601) @@ -245,6 +245,18 @@ <ClInclude Include="libopenmpt_ext.hpp"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\soundlib\FloatMixer.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> + <ClInclude Include="..\soundlib\IntMixer.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> + <ClInclude Include="..\soundlib\Mixer.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> + <ClInclude Include="..\soundlib\MixerInterface.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="..\common\AudioCriticalSection.cpp"> Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2014-02-01 13:50:38 UTC (rev 3601) @@ -805,6 +805,7 @@ sample.filename[0] = '\0'; m_sndFile.m_szNames[m_nSample][0] = '\0'; if(!sample.nC5Speed) sample.nC5Speed = 22050; + sample.PrecomputeLoops(m_sndFile, false); } else { m_modDoc.GetSampleUndo().Undo(m_nSample); @@ -1204,7 +1205,7 @@ if (bOk) { - m_modDoc.AdjustEndOfSample(iSmp); + sample.PrecomputeLoops(m_sndFile, false); m_modDoc.UpdateAllViews(NULL, (iSmp << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, NULL); } } @@ -1261,7 +1262,7 @@ p[i] = (signed char)l; } } - m_modDoc.AdjustEndOfSample(m_nSample); + sample.PrecomputeLoops(m_sndFile, false); m_modDoc.UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, NULL); m_modDoc.SetModified(); EndWaitCursor(); @@ -1413,7 +1414,7 @@ pOriginal = sample.pSample; dwNewLen = sample.nLength + (dwEnd - dwStart); pNewSample = NULL; - if (dwNewLen + 4 <= MAX_SAMPLE_LENGTH) pNewSample = CSoundFile::AllocateSample((dwNewLen + 4)*newsmplsize); + if (dwNewLen <= MAX_SAMPLE_LENGTH) pNewSample = ModSample::AllocateSample(dwNewLen, newsmplsize); if (pNewSample) { m_modDoc.GetSampleUndo().PrepareUndo(m_nSample, sundo_replace); @@ -1467,7 +1468,7 @@ } } } - if (sample.uFlags & CHN_16BIT) + if (sample.uFlags[CHN_16BIT]) { if (dwStart > 0) memcpy(pNewSample, pOriginal, dwStart*smplsize); if (dwEnd < sample.nLength) memcpy(((LPSTR)pNewSample)+(dwStart+(dwEnd-dwStart)*2)*smplsize, ((LPSTR)pOriginal)+(dwEnd*smplsize), (sample.nLength-dwEnd)*smplsize); @@ -1500,6 +1501,9 @@ sample.uFlags.set(CHN_16BIT); ctrlSmp::ReplaceSample(sample, (LPSTR)pNewSample, dwNewLen, m_sndFile); + // Update loop wrap-around buffer + sample.PrecomputeLoops(m_sndFile); + if(!selection.selectionActive) { if(!(m_sndFile.GetType() & MOD_TYPE_MOD)) @@ -1507,10 +1511,7 @@ if(sample.nC5Speed < 1000000) sample.nC5Speed *= 2; if(sample.RelativeTone < 84) sample.RelativeTone += 12; } - } - - m_modDoc.AdjustEndOfSample(m_nSample); - if (selection.selectionActive == true) + } else { SetSelectionPoints(dwStart, dwEnd + (dwEnd - dwStart)); } @@ -1549,7 +1550,7 @@ dwNewLen = sample.nLength - dwRemove; dwEnd = dwStart+dwRemove*2; pNewSample = NULL; - if ((dwNewLen > 32) && (dwRemove)) pNewSample = CSoundFile::AllocateSample((dwNewLen + 4) * smplsize); + if ((dwNewLen >= 4) && (dwRemove)) pNewSample = ModSample::AllocateSample(dwNewLen, smplsize); if (pNewSample) { @@ -1616,6 +1617,9 @@ if (sample.nSustainEnd > dwNewLen) sample.nSustainEnd = dwNewLen; ctrlSmp::ReplaceSample(sample, (LPSTR)pNewSample, dwNewLen, m_sndFile); + // Update loop wrap-around buffer + sample.PrecomputeLoops(m_sndFile); + if(!selection.selectionActive) { if(!(m_sndFile.GetType() & MOD_TYPE_MOD)) @@ -1623,10 +1627,7 @@ if(sample.nC5Speed > 2000) sample.nC5Speed /= 2; if(sample.RelativeTone > -84) sample.RelativeTone -= 12; } - } - - m_modDoc.AdjustEndOfSample(m_nSample); - if (selection.selectionActive == true) + } else { SetSelectionPoints(dwStart, dwStart + dwRemove); } @@ -1724,10 +1725,19 @@ //Update loop points only if no error occured. if(errorcode == 0) { - sample.nLoopStart = (UINT)MIN(sample.nLoopStart * (m_dTimeStretchRatio / 100.0), sample.nLength); - sample.nLoopEnd = (UINT)MIN(sample.nLoopEnd * (m_dTimeStretchRatio/100.0), sample.nLength); - sample.nSustainStart = (UINT)MIN(sample.nSustainStart * (m_dTimeStretchRatio/100.0), sample.nLength); - sample.nSustainEnd = (UINT)MIN(sample.nSustainEnd * (m_dTimeStretchRatio/100.0), sample.nLength); + // Update loop wrap-around buffer + sample.SetLoop( + static_cast<SmpLength>(sample.nLoopStart * (m_dTimeStretchRatio / 100.0)), + static_cast<SmpLength>(sample.nLoopEnd * (m_dTimeStretchRatio / 100.0)), + sample.uFlags[CHN_LOOP], + sample.uFlags[CHN_PINGPONGLOOP], + m_sndFile); + sample.SetSustainLoop( + static_cast<SmpLength>(sample.nSustainStart * (m_dTimeStretchRatio / 100.0)), + static_cast<SmpLength>(sample.nSustainEnd * (m_dTimeStretchRatio / 100.0)), + sample.uFlags[CHN_SUSTAINLOOP], + sample.uFlags[CHN_PINGPONGSUSTAIN], + m_sndFile); } } @@ -1851,7 +1861,7 @@ void *pNewSample = nullptr; if(nNewSampleLength <= MAX_SAMPLE_LENGTH) { - pNewSample = CSoundFile::AllocateSample(nNewSampleLength * nChn * smpsize); + pNewSample = ModSample::AllocateSample(nNewSampleLength, nChn * smpsize); } if(pNewSample == nullptr) { @@ -2270,7 +2280,7 @@ p[i] = (signed char)n; } } - m_modDoc.AdjustEndOfSample(m_nSample); + sample.PrecomputeLoops(m_sndFile, false); m_modDoc.UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, NULL); m_modDoc.SetModified(); } @@ -2559,23 +2569,25 @@ ModSample &sample = m_sndFile.GetSample(m_nSample); bool wasDisabled = !sample.uFlags[CHN_LOOP]; - // 0: Off, 1: On, 2: PingPong + // Loop type index: 0: Off, 1: On, 2: PingPong sample.uFlags.set(CHN_LOOP, n > 0); sample.uFlags.set(CHN_PINGPONGLOOP, n == 2); // set loop points if theren't any - if(wasDisabled && ((sample.uFlags & CHN_LOOP) != 0) && (sample.nLoopStart == sample.nLoopEnd) && (sample.nLoopStart == 0)) + if(wasDisabled && sample.uFlags[CHN_LOOP] && sample.nLoopStart == sample.nLoopEnd) { SampleSelectionPoints selection = GetSelectionPoints(); if(selection.selectionActive) { - sample.nLoopStart = selection.nStart; - sample.nLoopEnd = selection.nEnd; + sample.SetLoop(selection.nStart, selection.nEnd, true, n == 2, m_sndFile); } else { - sample.nLoopEnd = sample.nLength; + sample.SetLoop(0, sample.nLength, true, n == 2, m_sndFile); } m_modDoc.UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA | HINT_SAMPLEINFO, NULL); + } else + { + sample.PrecomputeLoops(m_sndFile); } ctrlSmp::UpdateLoopPoints(sample, m_sndFile); m_modDoc.SetModified(); @@ -2590,8 +2602,7 @@ SmpLength n = GetDlgItemInt(IDC_EDIT1); if ((n >= 0) && (n < sample.nLength) && ((n < sample.nLoopEnd) || !sample.uFlags[CHN_LOOP])) { - sample.nLoopStart = n; - ctrlSmp::UpdateLoopPoints(sample, m_sndFile); + sample.SetLoop(n, sample.nLoopEnd, sample.uFlags[CHN_LOOP], sample.uFlags[CHN_PINGPONGLOOP], m_sndFile); m_modDoc.UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, this); m_modDoc.SetModified(); } @@ -2606,8 +2617,7 @@ SmpLength n = GetDlgItemInt(IDC_EDIT2); if ((n >= 0) && (n <= sample.nLength) && ((n > sample.nLoopStart) || !sample.uFlags[CHN_LOOP])) { - sample.nLoopEnd = n; - ctrlSmp::UpdateLoopPoints(sample, m_sndFile); + sample.SetLoop(sample.nLoopStart, n, sample.uFlags[CHN_LOOP], sample.uFlags[CHN_PINGPONGLOOP], m_sndFile); m_modDoc.UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, this); m_modDoc.SetModified(); } @@ -2622,24 +2632,26 @@ ModSample &sample = m_sndFile.GetSample(m_nSample); bool wasDisabled = !sample.uFlags[CHN_SUSTAINLOOP]; - // 0: Off, 1: On, 2: PingPong + // Loop type index: 0: Off, 1: On, 2: PingPong sample.uFlags.set(CHN_SUSTAINLOOP, n > 0); sample.uFlags.set(CHN_PINGPONGSUSTAIN, n == 2); // set sustain loop points if theren't any - if(wasDisabled && ((sample.uFlags & CHN_SUSTAINLOOP) != 0) && (sample.nSustainStart == sample.nSustainEnd) && (sample.nSustainStart == 0)) + if(wasDisabled && sample.uFlags[CHN_SUSTAINLOOP] && sample.nSustainStart == sample.nSustainEnd) { SampleSelectionPoints selection = GetSelectionPoints(); if(selection.selectionActive) { - sample.nSustainStart = selection.nStart; - sample.nSustainEnd = selection.nEnd; + sample.SetSustainLoop(selection.nStart, selection.nEnd, true, n == 2, m_sndFile); } else { - sample.nSustainEnd = sample.nLength; + sample.SetSustainLoop(0, sample.nLength, true, n == 2, m_sndFile); } m_modDoc.UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA | HINT_SAMPLEINFO, NULL); + } else + { + sample.PrecomputeLoops(m_sndFile); } ctrlSmp::UpdateLoopPoints(sample, m_sndFile); m_modDoc.SetModified(); @@ -2655,8 +2667,7 @@ if ((n >= 0) && (n <= sample.nLength) && ((n < sample.nSustainEnd) || !sample.uFlags[CHN_SUSTAINLOOP])) { - sample.nSustainStart = n; - ctrlSmp::UpdateLoopPoints(sample, m_sndFile); + sample.SetSustainLoop(n, sample.nSustainEnd, sample.uFlags[CHN_SUSTAINLOOP], sample.uFlags[CHN_PINGPONGSUSTAIN], m_sndFile); m_modDoc.UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, this); m_modDoc.SetModified(); } @@ -2672,8 +2683,7 @@ if ((n >= 0) && (n <= sample.nLength) && ((n > sample.nSustainStart) || !sample.uFlags[CHN_SUSTAINLOOP])) { - sample.nSustainEnd = n; - ctrlSmp::UpdateLoopPoints(sample, m_sndFile); + sample.SetSustainLoop(sample.nSustainStart, n, sample.uFlags[CHN_SUSTAINLOOP], sample.uFlags[CHN_PINGPONGSUSTAIN], m_sndFile); m_modDoc.UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, this); m_modDoc.SetModified(); } @@ -2786,9 +2796,8 @@ { wsprintf(s, "%u", sample.nLoopStart); m_EditLoopStart.SetWindowText(s); - m_modDoc.AdjustEndOfSample(m_nSample); redraw = true; - ctrlSmp::UpdateLoopPoints(sample, m_sndFile); + sample.PrecomputeLoops(m_sndFile); } m_SpinLoopStart.SetPos(0); } @@ -2831,9 +2840,8 @@ { wsprintf(s, "%u", sample.nLoopEnd); m_EditLoopEnd.SetWindowText(s); - m_modDoc.AdjustEndOfSample(m_nSample); redraw = true; - ctrlSmp::UpdateLoopPoints(sample, m_sndFile); + sample.PrecomputeLoops(m_sndFile); } m_SpinLoopEnd.SetPos(0); } @@ -2878,7 +2886,7 @@ wsprintf(s, "%u", sample.nSustainStart); m_EditSustainStart.SetWindowText(s); redraw = true; - ctrlSmp::UpdateLoopPoints(sample, m_sndFile); + sample.PrecomputeLoops(m_sndFile); } m_SpinSustainStart.SetPos(0); } @@ -2922,7 +2930,7 @@ wsprintf(s, "%u", sample.nSustainEnd); m_EditSustainEnd.SetWindowText(s); redraw = true; - ctrlSmp::UpdateLoopPoints(sample, m_sndFile); + sample.PrecomputeLoops(m_sndFile); } m_SpinSustainEnd.SetPos(0); } Modified: trunk/OpenMPT/mptrack/ModConvert.cpp =================================================================== --- trunk/OpenMPT/mptrack/ModConvert.cpp 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/mptrack/ModConvert.cpp 2014-02-01 13:50:38 UTC (rev 3601) @@ -484,6 +484,9 @@ CriticalSection cs; m_SndFile.ChangeModTypeTo(nNewType); + // In case we need to update IT bidi loop handling pre-computation or loops got changed... + m_SndFile.PrecomputeSampleLoops(false); + // Song flags if(!(CSoundFile::GetModSpecifications(nNewType).songFlags & SONG_LINEARSLIDES) && m_SndFile.m_SongFlags[SONG_LINEARSLIDES]) { Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/mptrack/Moddoc.h 2014-02-01 13:50:38 UTC (rev 3601) @@ -308,7 +308,6 @@ CHANNELINDEX GetNumChannels() const { return m_SndFile.m_nChannels; } UINT GetPatternSize(PATTERNINDEX nPat) const; - BOOL AdjustEndOfSample(UINT nSample); bool IsChildSample(INSTRUMENTINDEX nIns, SAMPLEINDEX nSmp) const; INSTRUMENTINDEX FindSampleParent(SAMPLEINDEX sample) const; UINT FindInstrumentChild(UINT nIns) const; Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2014-02-01 13:50:38 UTC (rev 3601) @@ -322,23 +322,24 @@ for(SAMPLEINDEX i = 0; i < newNumSamples; i++) { const SAMPLEINDEX origSlot = newOrder[i]; + ModSample &target = m_SndFile.GetSample(i + 1); if(origSlot > 0 && origSlot <= oldNumSamples) { // Copy an original sample. - m_SndFile.GetSample(i + 1) = sampleHeaders[origSlot]; + target = sampleHeaders[origSlot]; if(--sampleCount[origSlot] > 0 && sampleHeaders[origSlot].pSample != nullptr) { // This sample slot is referenced multiple times, so we have to copy the actual sample. - m_SndFile.GetSample(i + 1).pSample = m_SndFile.AllocateSample(m_SndFile.GetSample(i + 1).GetSampleSizeInBytes()); - memcpy(m_SndFile.GetSample(i + 1).pSample, sampleHeaders[origSlot].pSample, m_SndFile.GetSample(i + 1).GetSampleSizeInBytes()); - ctrlSmp::AdjustEndOfSample(m_SndFile.GetSample(i + 1), m_SndFile); + target.pSample = ModSample::AllocateSample(target.nLength, target.GetSampleSizeInBytes()); + memcpy(target.pSample, sampleHeaders[origSlot].pSample, target.GetSampleSizeInBytes()); + target.PrecomputeLoops(m_SndFile, false); } strcpy(m_SndFile.m_szNames[i + 1], sampleNames[origSlot].c_str()); } else { // Invalid sample reference. - m_SndFile.GetSample(i + 1).Initialize(m_SndFile.GetType()); - m_SndFile.GetSample(i + 1).pSample = nullptr; + target.Initialize(m_SndFile.GetType()); + target.pSample = nullptr; strcpy(m_SndFile.m_szNames[i + 1], ""); } } @@ -583,19 +584,6 @@ } -BOOL CModDoc::AdjustEndOfSample(UINT nSample) -//------------------------------------------- -{ - if (nSample >= MAX_SAMPLES) return FALSE; - ModSample &sample = m_SndFile.GetSample(nSample); - if ((!sample.nLength) || (!sample.pSample)) return FALSE; - - ctrlSmp::AdjustEndOfSample(sample, m_SndFile); - - return TRUE; -} - - PATTERNINDEX CModDoc::InsertPattern(ORDERINDEX nOrd, ROWINDEX nRows) //------------------------------------------------------------------ { Modified: trunk/OpenMPT/mptrack/Undo.cpp =================================================================== --- trunk/OpenMPT/mptrack/Undo.cpp 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/mptrack/Undo.cpp 2014-02-01 13:50:38 UTC (rev 3601) @@ -326,7 +326,7 @@ const size_t bytesPerSample = oldSample.GetBytesPerSample(); const size_t changeLen = changeEnd - changeStart; - undo.samplePtr = sndFile.AllocateSample((changeLen + 4) * bytesPerSample); + undo.samplePtr = ModSample::AllocateSample(changeLen, bytesPerSample); if(undo.samplePtr == nullptr) return false; memcpy(undo.samplePtr, static_cast<const char *>(oldSample.pSample) + changeStart * bytesPerSample, changeLen * bytesPerSample); @@ -408,7 +408,7 @@ case sundo_delete: // insert deleted data - pNewSample = static_cast<char *>(sndFile.AllocateSample(undo.OldSample.GetSampleSizeInBytes() + 4 * bytesPerSample)); + pNewSample = static_cast<char *>(ModSample::AllocateSample(undo.OldSample.nLength, bytesPerSample)); if(pNewSample == nullptr) return false; replace = true; memcpy(pNewSample, pCurrentSample, undo.changeStart * bytesPerSample); @@ -437,7 +437,7 @@ { ctrlSmp::ReplaceSample(sample, pNewSample, undo.OldSample.nLength, sndFile); } - ctrlSmp::AdjustEndOfSample(sample, sndFile); + sample.PrecomputeLoops(sndFile, true); RemoveLastUndoStep(smp); @@ -462,7 +462,7 @@ //------------------------------------------------------------------------ { if(!SampleBufferExists(smp, false) || step >= UndoBuffer[smp - 1].size()) return; - CSoundFile::FreeSample(UndoBuffer[smp - 1][step].samplePtr); + ModSample::FreeSample(UndoBuffer[smp - 1][step].samplePtr); UndoBuffer[smp - 1].erase(UndoBuffer[smp - 1].begin() + step); } Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2014-02-01 13:50:38 UTC (rev 3601) @@ -1414,7 +1414,7 @@ else if(sndFile.GetSample(m_nSample).GetElementarySampleSize() == 1) SetSampleData<int8, uint8>(sndFile.GetSample(m_nSample).pSample, point, old); - ctrlSmp::AdjustEndOfSample(sndFile.GetSample(m_nSample), sndFile); + sndFile.GetSample(m_nSample).PrecomputeLoops(sndFile, false); InvalidateSample(); pModDoc->SetModified(); @@ -1433,12 +1433,11 @@ //------------------------------------------------- { CModDoc *pModDoc = GetDocument(); - CSoundFile *pSndFile; DWORD len; if(m_dwStatus[SMPSTATUS_MOUSEDRAG] || (!pModDoc)) return; - pSndFile = pModDoc->GetSoundFile(); - ModSample &sample = pSndFile->GetSample(m_nSample); + CSoundFile &sndFile = pModDoc->GetrSoundFile(); + ModSample &sample = sndFile.GetSample(m_nSample); len = sample.nLength; if (!len) @@ -1472,6 +1471,8 @@ else if(sample.GetElementarySampleSize() == 1) SetInitialDrawPoint<int8, uint8>(sample.pSample, point); + sndFile.GetSample(m_nSample).PrecomputeLoops(sndFile, false); + InvalidateSample(); pModDoc->SetModified(); } else @@ -1724,11 +1725,8 @@ { if ((sample.nLoopStart != m_dwBeginSel) || (sample.nLoopEnd != m_dwEndSel)) { - sample.nLoopStart = m_dwBeginSel; - sample.nLoopEnd = m_dwEndSel; - sample.uFlags |= CHN_LOOP; + sample.SetLoop(m_dwBeginSel, m_dwEndSel, true, sample.uFlags[CHN_PINGPONGLOOP], sndFile); pModDoc->SetModified(); - pModDoc->AdjustEndOfSample(m_nSample); pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEINFO | HINT_SAMPLEDATA, NULL); } } @@ -1748,11 +1746,8 @@ { if ((sample.nSustainStart != m_dwBeginSel) || (sample.nSustainEnd != m_dwEndSel)) { - sample.nSustainStart = m_dwBeginSel; - sample.nSustainEnd = m_dwEndSel; - sample.uFlags |= CHN_SUSTAINLOOP; + sample.SetSustainLoop(m_dwBeginSel, m_dwEndSel, true, sample.uFlags[CHN_PINGPONGSUSTAIN], sndFile); pModDoc->SetModified(); - pModDoc->AdjustEndOfSample(m_nSample); pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEINFO | HINT_SAMPLEDATA, NULL); } } @@ -1863,9 +1858,10 @@ { sample.uFlags.reset(CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); } + + sample.PrecomputeLoops(sndFile); } SetCurSel(0, 0); - pModDoc->AdjustEndOfSample(m_nSample); pModDoc->SetModified(); pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | dwUpdateFlags, NULL); } @@ -1976,7 +1972,7 @@ BeginWaitCursor(); if ((pModDoc) && (OpenClipboard())) { - CHAR s[32], s2[32]; + char s[MAX_SAMPLENAME], s2[MAX_SAMPLEFILENAME]; HGLOBAL hCpy = ::GetClipboardData(CF_WAVE); LPBYTE p; @@ -1984,27 +1980,27 @@ { pModDoc->GetSampleUndo().PrepareUndo(m_nSample, sundo_replace); - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - DWORD dwMemSize = GlobalSize(hCpy); + CSoundFile &sndFile = pModDoc->GetrSoundFile(); + ModSample &sample = sndFile.GetSample(m_nSample); - ModSample &sample = pSndFile->GetSample(m_nSample); + MemCopy(s, sndFile.m_szNames[m_nSample]); + MemCopy(s2, sample.filename); - memcpy(s, pSndFile->m_szNames[m_nSample], 32); - memcpy(s2, sample.filename, 22); - FileReader file(p, dwMemSize); - pSndFile->ReadSampleFromFile(m_nSample, file, TrackerSettings::Instance().m_MayNormalizeSamplesOnLoad); - if (!pSndFile->m_szNames[m_nSample][0]) -{ - memcpy(pSndFile->m_szNames[m_nSample], s, 32); -} + FileReader file(p, GlobalSize(hCpy)); + sndFile.ReadSampleFromFile(m_nSample, file); + + if(!sndFile.m_szNames[m_nSample][0]) + { + MemCopy(sndFile.m_szNames[m_nSample], s); + } if (!sample.filename[0]) { - memcpy(sample.filename, s2, 22); + MemCopy(sample.filename, s2); } GlobalUnlock(hCpy); SetCurSel(0, 0); - pModDoc->AdjustEndOfSample(m_nSample); + sample.PrecomputeLoops(sndFile, true); pModDoc->SetModified(); pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEINFO | HINT_SAMPLEDATA | HINT_SMPNAMES, NULL); } @@ -2046,15 +2042,15 @@ p[i] = (signed char) ((*((short int *)(p+i*2))) / 256); } sample.uFlags.reset(CHN_16BIT); - for (UINT j=0; j<MAX_CHANNELS; j++) if (sndFile.Chn[j].pSample == sample.pSample) + for (CHANNELINDEX j = 0; j < MAX_CHANNELS; j++) if (sndFile.Chn[j].pSample == sample.pSample) { sndFile.Chn[j].dwFlags.reset(CHN_16BIT); } + sample.PrecomputeLoops(sndFile, false); cs.Leave(); pModDoc->SetModified(); - pModDoc->AdjustEndOfSample(m_nSample); pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA | HINT_SAMPLEINFO, NULL); } } @@ -2191,10 +2187,10 @@ } sample.nLength = nEnd; + sample.PrecomputeLoops(sndFile); cs.Leave(); pModDoc->SetModified(); - pModDoc->AdjustEndOfSample(m_nSample); SetCurSel(0, 0); pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA | HINT_SAMPLEINFO, NULL); } @@ -2380,7 +2376,6 @@ } if (bUpdate) { - pModDoc->AdjustEndOfSample(m_nSample); pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA | HINT_SAMPLEINFO | HINT_SMPNAMES, NULL); pModDoc->SetModified(); } @@ -2451,10 +2446,8 @@ if ((m_dwMenuParam+4 <= sample.nLoopEnd) && (sample.nLoopStart != m_dwMenuParam)) { pModDoc->GetSampleUndo().PrepareUndo(m_nSample, sundo_none); - sample.nLoopStart = m_dwMenuParam; - sample.uFlags |= CHN_LOOP; + sample.SetLoop(m_dwMenuParam, sample.nLoopEnd, true, sample.uFlags[CHN_PINGPONGLOOP], sndFile); pModDoc->SetModified(); - ctrlSmp::UpdateLoopPoints(sample, sndFile); pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEINFO | HINT_SAMPLEDATA, NULL); } } @@ -2472,10 +2465,8 @@ if ((m_dwMenuParam >= sample.nLoopStart+4) && (sample.nLoopEnd != m_dwMenuParam)) { pModDoc->GetSampleUndo().PrepareUndo(m_nSample, sundo_none); - sample.nLoopEnd = m_dwMenuParam; - sample.uFlags |= CHN_LOOP; + sample.SetLoop(sample.nLoopStart, m_dwMenuParam, true, sample.uFlags[CHN_PINGPONGLOOP], sndFile); pModDoc->SetModified(); - ctrlSmp::UpdateLoopPoints(sample, sndFile); pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEINFO | HINT_SAMPLEDATA, NULL); } } @@ -2493,10 +2484,8 @@ if ((m_dwMenuParam+4 <= sample.nSustainEnd) && (sample.nSustainStart != m_dwMenuParam)) { pModDoc->GetSampleUndo().PrepareUndo(m_nSample, sundo_none); - sample.nSustainStart = m_dwMenuParam; - sample.uFlags |= CHN_SUSTAINLOOP; + sample.SetSustainLoop(m_dwMenuParam, sample.nSustainEnd, true, sample.uFlags[CHN_PINGPONGSUSTAIN], sndFile); pModDoc->SetModified(); - ctrlSmp::UpdateLoopPoints(sample, sndFile); pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEINFO | HINT_SAMPLEDATA, NULL); } } @@ -2514,10 +2503,8 @@ if ((m_dwMenuParam >= sample.nSustainStart+4) && (sample.nSustainEnd != m_dwMenuParam)) { pModDoc->GetSampleUndo().PrepareUndo(m_nSample, sundo_none); - sample.nSustainEnd = m_dwMenuParam; - sample.uFlags |= CHN_SUSTAINLOOP; + sample.SetSustainLoop(sample.nSustainStart, m_dwMenuParam, true, sample.uFlags[CHN_PINGPONGSUSTAIN], sndFile); pModDoc->SetModified(); - ctrlSmp::UpdateLoopPoints(sample, sndFile); pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEINFO | HINT_SAMPLEDATA, NULL); } } Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2014-02-01 13:50:38 UTC (rev 3601) @@ -654,7 +654,7 @@ m_MixState.dwFlags = 0; m_MixState.nVolDecayL = 0; m_MixState.nVolDecayR = 0; - m_MixState.pMixBuffer = (int *)((((intptr_t)m_MixBuffer) + 7) & ~7); + m_MixState.pMixBuffer = (mixsample_t *)((((intptr_t)m_MixBuffer) + 7) & ~7); m_MixState.pOutBufferL = mixBuffer.GetInputBuffer(0); m_MixState.pOutBufferR = mixBuffer.GetInputBuffer(1); Modified: trunk/OpenMPT/mptrack/Vstplug.h =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.h 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/mptrack/Vstplug.h 2014-02-01 13:50:38 UTC (rev 3601) @@ -94,6 +94,7 @@ #ifndef NO_VST #include "../soundlib/plugins/PluginEventQueue.h" +#include "../soundlib/Mixer.h" #endif // NO_VST @@ -149,7 +150,7 @@ VSTInstrChannel m_MidiCh[16]; // MIDI channel state PluginMixBuffer<float, MIXBUFFERSIZE> mixBuffer; // Float buffers (input and output) for plugins - int32 m_MixBuffer[MIXBUFFERSIZE * 2 + 2]; // Stereo interleaved + mixsample_t m_MixBuffer[MIXBUFFERSIZE * 2 + 2]; // Stereo interleaved PluginEventQueue<vstNumProcessEvents> vstEvents; // MIDI events that should be sent to the plugin public: Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2014-02-01 13:50:38 UTC (rev 3601) @@ -1015,6 +1015,22 @@ > </File> <File + RelativePath="..\soundlib\FloatMixer.h" + > + </File> + <File + RelativePath="..\soundlib\IntMixer.h" + > + </File> + <File + RelativePath="..\soundlib\Mixer.h" + > + </File> + <File + RelativePath="..\soundlib\MixerInterface.h" + > + </File> + <File RelativePath="..\soundlib\MixerLoops.h" > </File> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2014-02-01 13:50:38 UTC (rev 3601) @@ -463,7 +463,13 @@ <ClCompile Include="..\sounddsp\Reverb.cpp" /> <ClCompile Include="..\soundlib\Dither.cpp" /> <ClCompile Include="..\soundlib\Dlsbank.cpp" /> - <ClCompile Include="..\soundlib\Fastmix.cpp" /> + <ClCompile Include="..\soundlib\Fastmix.cpp"> + <DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ProgramDatabase</DebugInformationFormat> + <InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AnySuitable</InlineFunctionExpansion> + <IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</IntrinsicFunctions> + <InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AnySuitable</InlineFunctionExpansion> + <IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</IntrinsicFunctions> + </ClCompile> <ClCompile Include="..\soundlib\ITCompression.cpp" /> <ClCompile Include="..\soundlib\ITTools.cpp" /> <ClCompile Include="..\soundlib\Load_digi.cpp" /> @@ -660,11 +666,15 @@ <ClInclude Include="..\soundlib\Dlsbank.h" /> <ClInclude Include="..\soundlib\Endianness.h" /> <ClInclude Include="..\soundlib\FileReader.h" /> + <ClInclude Include="..\soundlib\FloatMixer.h" /> + <ClInclude Include="..\soundlib\IntMixer.h" /> <ClInclude Include="..\soundlib\ITCompression.h" /> <ClInclude Include="..\soundlib\ITTools.h" /> <ClInclude Include="..\soundlib\Message.h" /> <ClInclude Include="..\soundlib\MIDIEvents.h" /> <ClInclude Include="..\soundlib\MIDIMacros.h" /> + <ClInclude Include="..\soundlib\Mixer.h" /> + <ClInclude Include="..\soundlib\MixerInterface.h" /> <ClInclude Include="..\soundlib\MixerLoops.h" /> <ClInclude Include="..\soundlib\MixerSettings.h" /> <ClInclude Include="..\soundlib\ModChannel.h" /> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2014-02-01 13:50:38 UTC (rev 3601) @@ -963,6 +963,18 @@ <ClInclude Include="CTreeCtrl.h"> <Filter>Header Files\mptrack</Filter> </ClInclude> + <ClInclude Include="..\soundlib\FloatMixer.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> + <ClInclude Include="..\soundlib\IntMixer.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> + <ClInclude Include="..\soundlib\Mixer.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> + <ClInclude Include="..\soundlib\MixerInterface.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="res\bitmap1.bmp"> Modified: trunk/OpenMPT/sounddsp/EQ.cpp =================================================================== --- trunk/OpenMPT/sounddsp/EQ.cpp 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/sounddsp/EQ.cpp 2014-02-01 13:50:38 UTC (rev 3601) @@ -28,10 +28,6 @@ 160, 172, 184, 196, 208, 220, 232, 244, 256 }; - -static const float32 f2ic = (float32)(1 << 28); -static const float32 i2fc = (float32)(1.0 / (1 << 28)); - static const EQBANDSTRUCT gEQDefaults[MAX_EQ_BANDS*2] = { // Default: Flat EQ Modified: trunk/OpenMPT/sounddsp/EQ.h =================================================================== --- trunk/OpenMPT/sounddsp/EQ.h 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/sounddsp/EQ.h 2014-02-01 13:50:38 UTC (rev 3601) @@ -10,8 +10,8 @@ #pragma once +#include "../soundlib/Mixer.h" // For MIXBUFFERSIZE - #define MAX_EQ_BANDS 6 typedef struct ALIGN(4) _EQBANDSTRUCT Modified: trunk/OpenMPT/sounddsp/Reverb.cpp =================================================================== --- trunk/OpenMPT/sounddsp/Reverb.cpp 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/sounddsp/Reverb.cpp 2014-02-01 13:50:38 UTC (rev 3601) @@ -18,7 +18,7 @@ #pragma warning(disable:4725) // Pentium fdiv bug #pragma warning(disable:4731) // ebp modified -extern void StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs); +extern void StereoFill(int *pBuffer, UINT nSamples, mixsample_t &lpROfs, mixsample_t &lpLOfs); @@ -409,7 +409,7 @@ { if(!gnReverbSend) { // and we did not clear the buffer yet, do it now because we will get new data - StereoFill(MixReverbBuffer, nSamples, &gnRvbROfsVol, &gnRvbLOfsVol); + StereoFill(MixReverbBuffer, nSamples, gnRvbROfsVol, gnRvbLOfsVol); } gnReverbSend = 1; // we will have to process reverb return MixReverbBuffer; @@ -427,7 +427,7 @@ } if(!gnReverbSend) { // no input data in MixReverbBuffer, so the buffer got not cleared in GetReverbSendBuffer(), do it now for decay - StereoFill(MixReverbBuffer, nSamples, &gnRvbROfsVol, &gnRvbLOfsVol); + StereoFill(MixReverbBuffer, nSamples, gnRvbROfsVol, gnRvbLOfsVol); } UINT nIn, nOut; Modified: trunk/OpenMPT/sounddsp/Reverb.h =================================================================== --- trunk/OpenMPT/sounddsp/Reverb.h 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/sounddsp/Reverb.h 2014-02-01 13:50:38 UTC (rev 3601) @@ -11,6 +11,7 @@ #pragma once #ifndef NO_REVERB +#include "../soundlib/Mixer.h" // For MIXBUFFERSIZE ///////////////////////////////////////////////////////////////////////////// // @@ -129,8 +130,7 @@ private: int MixReverbBuffer[MIXBUFFERSIZE * 2]; public: - LONG gnRvbROfsVol; - LONG gnRvbLOfsVol; + mixsample_t gnRvbROfsVol, gnRvbLOfsVol; private: Modified: trunk/OpenMPT/soundlib/AudioReadTarget.h =================================================================== --- trunk/OpenMPT/soundlib/AudioReadTarget.h 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/soundlib/AudioReadTarget.h 2014-02-01 13:50:38 UTC (rev 3601) @@ -13,6 +13,7 @@ #include "SampleFormatConverters.h" #include "SampleFormat.h" #include "MixerLoops.h" +#include "Mixer.h" template<typename Tsample> Modified: trunk/OpenMPT/soundlib/Dither.cpp =================================================================== --- trunk/OpenMPT/soundlib/Dither.cpp 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/soundlib/Dither.cpp 2014-02-01 13:50:38 UTC (rev 3601) @@ -11,11 +11,10 @@ #include "stdafx.h" #include "Dither.h" +#include "Mixer.h" -#include "Snd_defs.h" - ////////////////////////////////////////////////////////////////////////// // Noise Shaping (Dithering) Modified: trunk/OpenMPT/soundlib/Dlsbank.cpp =================================================================== --- trunk/OpenMPT/soundlib/Dlsbank.cpp 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/soundlib/Dlsbank.cpp 2014-02-01 13:50:38 UTC (rev 3601) @@ -1560,6 +1560,7 @@ SampleIO::littleEndian, SampleIO::signedPCM) .ReadSample(sample, chunk); + sample.PrecomputeLoops(sndFile, false); } bWaveForm = (sample.pSample) ? TRUE : FALSE; } else Modified: trunk/OpenMPT/soundlib/Fastmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Fastmix.cpp 2014-02-01 13:41:36 UTC (rev 3600) +++ trunk/OpenMPT/soundlib/Fastmix.cpp 2014-02-01 13:50:38 UTC (rev 3601) @@ -3,1433 +3,259 @@ * ----------- * Purpose: Mixer core for rendering samples, mixing plugins, etc... * Notes : If this is Fastmix.cpp, where is Slowmix.cpp? :) - * This code is ugly like hell and you are probably not going to understand it - * unless you have worked with OpenMPT for a long time - at least I didn't. :) - * I guess that a lot of this could be refactored using inline functions. + * The Visual Studio project settings for this file have been adjusted + * to force function inlining, so that the mixer has a somewhat acceptable + * performance in debug mode. If you need to debug anything here, be sure + * to disable those optimizations if needed. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ +// FIXME: +// - Playing samples backwards should reverse interpolation LUTs for interpolation modes +// with more than two taps since they're not symmetric. We might need separate LUTs +// because otherwise we will add tons of branches. +// - Loop wraparound works pretty well in general, but not at the start of bidi samples. +// - THe loop lookahead stuff might still fail for samples with backward loops. + #include "stdafx.h" #include "Sndfile.h" - #include "MixerLoops.h" -#include "Resampler.h" -#include "WindowedFIR.h" +#ifdef MPT_INTMIXER +#include "IntMixer.h" +#else +#include "FloatMixer.h" +#endif // MPT_INTMIXER -// 4x256 taps polyphase FIR resampling filter -#define gFastSinc CResampler::FastSincTable +namespace MixFuncTable +{ +#ifdef MPT_INTMIXER + typedef Int8MToIntS I8M; + typedef Int16MToIntS I16M; + typedef Int8SToIntS I8S; + typedef Int16SToIntS I16S; +#else + typedef Int8MToFloatS I8M; + typedef Int16MToFloatS I16M; + typedef Int8SToFloatS I8S; + typedef Int16SToFloatS I16S; +#endif // MPT_INTMIXER +// Table index: +// [b1-b0] format (8-bit-mono, 16-bit-mono, 8-bit-stereo, 16-bit-stereo) +// [b2] ramp +// [b3] filter +// [b6-b4] src type -///////////////////////////////////////////////////// -// Mixing Macros +// Sample type / processing type index +enum FunctionIndex +{ + ndx16Bit = 0x01, + ndxStereo = 0x02, + ndxRamp = 0x04, + ndxFilter = 0x08, +}; -#define SNDMIX_BEGINSAMPLELOOP8\ - register ModChannel * const pChn = pChannel;\ - nPos = pChn->nPosLo;\ - const signed char *p = (signed char *)(pChn->pCurrentSample)+pChn->nPos;\ - if (pChn->dwFlags[CHN_STEREO]) p += pChn->nPos;\ - int *pvol = pbuffer;\ - do { - -#define SNDMIX_BEGINSAMPLELOOP16\ - register ModChannel * const pChn = pChannel;\ - nPos = pChn->nPosLo;\ - const signed short *p = (signed short *)(pChn->pCurrentSample)+pChn->nPos;\ - if (pChn->dwFlags[CHN_STEREO]) p += pChn->nPos;\ - int *pvol = pbuffer;\ - do { - -#define SNDMIX_ENDSAMPLELOOP\ - nPos += pChn->nInc;\ - } while (pvol < pbufmax);\ - pChn->nPos += nPos >> 16;\ - pChn->nPosLo = nPos & 0xFFFF; - -#define SNDMIX_ENDSAMPLELOOP8 SNDMIX_ENDSAMPLELOOP -#define SNDMIX_ENDSAMPLELOOP16 SNDMIX_ENDSAMPLELOOP - -////////////////////////////////////////////////////////////////////////////// -// Mono - -// No interpolation -#define SNDMIX_GETMONOVOL8NOIDO\ - int vol = p[nPos >> 16] << 8; - -#define SNDMIX_GETMONOVOL16NOIDO\ - int vol = p[nPos >> 16]; - -// Linear Interpolation -#define SNDMIX_GETMONOVOL8LINEAR\ - int poshi = nPos >> 16;\ - int poslo = (nPos >> 8) & 0xFF;\ - int srcvol = p[poshi];\ - int destvol = p[poshi+1];\ - int vol = (srcvol<<8) + ((int)(poslo * (destvol - srcvol))); - -#define SNDMIX_GETMONOVOL16LINEAR\ - int poshi = nPos >> 16;\ - int poslo = (nPos >> 8) & 0xFF;\ - int srcvol = p[poshi];\ - int destvol = p[poshi+1];\ - int vol = srcvol + ((int)(poslo * (destvol - srcvol)) >> 8); - -// Cubic Spline -#define SNDMIX_GETMONOVOL8HQSRC\ - int poshi = nPos >> 16;\ - int poslo = (nPos >> 6) & 0x3FC;\ - int vol = (gFastSinc[poslo]*p[poshi-1] + gFastSinc[poslo+1]*p[poshi]\ - + gFastSinc[poslo+2]*p[poshi+1] + gFastSinc[poslo+3]*p[poshi+2]) >> 6;\ - -#define SNDMIX_GETMONOVOL16HQSRC\ - int poshi = nPos >> 16;\ - int poslo = (nPos >> 6) & 0x3FC;\ - int vol = (gFastSinc[poslo]*p[poshi-1] + gFastSinc[poslo+1]*p[poshi]\ - + gFastSinc[poslo+2]*p[poshi+1] + gFastSinc[poslo+3]*p[poshi+2]) >> 14;\ - -// 8-taps polyphase -#define SNDMIX_GETMONOVOL8KAISER\ - int poshi = nPos >> 16;\ - const SINC_TYPE *poslo = sinc + ((nPos >> (16-SINC_PHASES_BITS)) & SINC_MASK) * SINC_WIDTH;\ - int vol = ((poslo[0]*p[poshi-3] + poslo[1]*p[poshi-2]\ - + poslo[2]*p[poshi-1] + poslo[3]*p[poshi]\ - + poslo[4]*p[poshi+1] + poslo[5]*p[poshi+2]\ - + poslo[6]*p[poshi+3] + poslo[7]*p[poshi+4]) >> (SINC_QUANTSHIFT-8));\ - -#define SNDMIX_GETMONOVOL16KAISER\ - int poshi = nPos >> 16;\ - const SINC_TYPE *poslo = sinc + ((nPos >> (16-SINC_PHASES_BITS)) & SINC_MASK) * SINC_WIDTH;\ - int vol = ((poslo[0]*p[poshi-3] + poslo[1]*p[poshi-2]\ - + poslo[2]*p[poshi-1] + poslo[3]*p[poshi]\ - + poslo[4]*p[poshi+1] + poslo[5]*p[poshi+2]\ - + poslo[6]*p[poshi+3] + poslo[7]*p[poshi+4]) >> SINC_QUANTSHIFT);\ -// rewbs.resamplerConf -#define SNDMIX_GETMONOVOL8FIRFILTER \ - int poshi = nPos >> 16;\ - int poslo = (nPos & 0xFFFF);\ - int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \ - int vol = (WFIR_lut[firidx+0]*(int)p[poshi+1-4]); \ - vol += (WFIR_lut[firidx+1]*(int)p[poshi+2-4]); \ - vol += (WFIR_lut[firidx+2]*(int)p[poshi+3-4]); \ - vol += (WFIR_lut[firidx+3]*(int)p[poshi+4-4]); \ - vol += (WFIR_lut[firidx+4]*(int)p[poshi+5-4]); \ - vol += (WFIR_lut[firidx+5]*(int)p[poshi+6-4]); \ - vol += (WFIR_lut[firidx+6]*(int)p[poshi+7-4]); \ - vol += (WFIR_lut[firidx+7]*(int)p[poshi+8-4]); \ - vol >>= WFIR_8SHIFT; - -#define SNDMIX_GETMONOVOL16FIRFILTER \ - int poshi = nPos >> 16;\ - int poslo = (nPos & 0xFFFF);\ - int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \ - int vol1 = (WFIR_lut[firidx+0]*(int)p[poshi+1-4]); \ - vol1 += (WFIR_lut[firidx+1]*(int)p[poshi+2-4]); \ - vol1 += (WFIR_lut[firidx+2]*(int)p[poshi+3-4]); \ - vol1 += (WFIR_lut[firidx+3]*(int)p[poshi+4-4]); \ - int vol2 = (WFIR_lut[firidx+4]*(int)p[poshi+5-4]); \ - vol2 += (WFIR_lut[firidx+5]*(int)p[poshi+6-4]); \ - vol2 += (WFIR_lut[firidx+6]*(int)p[poshi+7-4]); \ - vol2 += (WFIR_lut[firidx+7]*(int)p[poshi+8-4]); \ - int vol = ((vol1>>1)+(vol2>>1)) >> (WFIR_16BITSHIFT-1); - - -// end rewbs.resamplerConf -#define SNDMIX_INITSINCTABLE\ - const SINC_TYPE * const sinc = (((pChannel->nInc > 0x13000) || (pChannel->nInc < -0x13000)) ?\ - (((pChannel->nInc > 0x18000) || (pChannel->nInc < -0x18000)) ? pResampler->gDownsample2x : pResampler->gDownsample13x) : pResampler->gKaiserSinc); - -#define SNDMIX_INITFIRTABLE\ - const signed short * const WFIR_lut = pResampler->m_WindowedFIR.lut; - - -///////////////////////////////////////////////////////////////////////////// -// Stereo - -// No interpolation -#define SNDMIX_GETSTEREOVOL8NOIDO\ - int vol_l = p[(nPos>>16)*2] << 8;\ - int vol_r = p[(nPos>>16)*2+1] << 8; - -#define SNDMIX_GETSTEREOVOL16NOIDO\ - int vol_l = p[(nPos>>16)*2];\ - int vol_r = p[(nPos>>16)*2+1]; - -// Linear Interpolation -#define SNDMIX_GETSTEREOVOL8LINEAR\ - int poshi = nPos >> 16;\ - int poslo = (nPos >> 8) & 0xFF;\ - int srcvol_l = p[poshi*2];\ - int vol_l = (srcvol_l<<8) + ((int)(poslo * (p[poshi*2+2] - srcvol_l)));\ - int srcvol_r = p[poshi*2+1];\ - int vol_r = (srcvol_r<<8) + ((int)(poslo * (p[poshi*2+3] - srcvol_r))); - -#define SNDMIX_GETSTEREOVOL16LINEAR\ - int poshi = nPos >> 16;\ - int poslo = (nPos >> 8) & 0xFF;\ - int srcvol_l = p[poshi*2];\ - int vol_l = srcvol_l + ((int)(poslo * (p[poshi*2+2] - srcvol_l)) >> 8);\ - int srcvol_r = p[poshi*2+1];\ - int vol_r = srcvol_r + ((int)(poslo * (p[poshi*2+3] - srcvol_r)) >> 8);\ - -// Cubic Spline -#define SNDMIX_GETSTEREOVOL8HQSRC\ - int poshi = nPos >> 16;\ - int poslo = (nPos >> 6) & 0x3FC;\ - int vol_l = (gFastSinc[poslo]*p[poshi*2-2] + gFastSinc[poslo+1]*p[poshi*2]\ - + gFastSinc[poslo+2]*p[poshi*2+2] + gFastSinc[poslo+3]*p[poshi*2+4]) >> 6;\ - int vol_r = (gFastSinc[poslo]*p[poshi*2-1] + gFastSinc[poslo+1]*p[poshi*2+1]\ - + gFastSinc[poslo+2]*p[poshi*2+3] + gFastSinc[poslo+3]*p[poshi*2+5]) >> 6;\ - -#define SNDMIX_GETSTEREOVOL16HQSRC\ - int poshi = nPos >> 16;\ - int poslo = (nPos >> 6) & 0x3FC;\ - int vol_l = (gFastSinc[poslo]*p[poshi*2-2] + gFastSinc[poslo+1]*p[poshi*2]\ - + gFastSinc[poslo+2]*p[poshi*2+2] + gFastSinc[poslo+3]*p[poshi*2+4]) >> 14;\ - int vol_r = (gFastSinc[poslo]*p[poshi*2-1] + gFastSinc[poslo+1]*p[poshi*2+1]\ - + gFastSinc[poslo+2]*p[poshi*2+3] + gFastSinc[poslo+3]*p[poshi*2+5]) >> 14;\ - -// -> CODE#0025 -// -> DESC="enable polyphase resampling on stereo samples" -// 8-taps polyphase -#define SNDMIX_GETSTEREOVOL8KAISER\ - int poshi = nPos >> 16;\ - const SINC_TYPE *poslo = sinc + ((nPos >> (16-SINC_PHASES_BITS)) & SINC_MASK) * SINC_WIDTH;\ - int vol_l = ((poslo[0]*p[poshi*2-6] + poslo[1]*p[poshi*2-4]\ - + poslo[2]*p[poshi*2-2] + poslo[3]*p[poshi*2]\ - + poslo[4]*p[poshi*2+2] + poslo[5]*p[poshi*2+4]\ - + poslo[6]*p[poshi*2+6] + poslo[7]*p[poshi*2+8]) >> (SINC_QUANTSHIFT-8));\ - int vol_r = ((poslo[0]*p[poshi*2-5] + poslo[1]*p[poshi*2-3]\ - + poslo[2]*p[poshi*2-1] + poslo[3]*p[poshi*2+1]\ - + poslo[4]*p[poshi*2+3] + poslo[5]*p[poshi*2+5]\ - + poslo[6]*p[poshi*2+7] + poslo[7]*p[poshi*2+9]) >> (SINC_QUANTSHIFT-8));\ - -#define SNDMIX_GETSTEREOVOL16KAISER\ - int poshi = nPos >> 16;\ - const SINC_TYPE *poslo = sinc + ((nPos >> (16-SINC_PHASES_BITS)) & SINC_MASK) * SINC_WIDTH;\ - int vol_l = ((poslo[0]*p[poshi*2-6] + poslo[1]*p[poshi*2-4]\ - + poslo[2]*p[poshi*2-2] + poslo[3]*p[poshi*2]\ - + poslo[4]*p[poshi*2+2] + poslo[5]*p[poshi*2+4]\ - + poslo[6]*p[poshi*2+6] + poslo[7]*p[poshi*2+8]) >> SINC_QUANTSHIFT);\ - int vol_r = ((poslo[0]*p[poshi*2-5] + poslo[1]*p[poshi*2-3]\ - + poslo[2]*p[poshi*2-1] + poslo[3]*p[poshi*2+1]\ - + poslo[4]*p[poshi*2+3] + poslo[5]*p[poshi*2+5]\ - + poslo[6]*p[poshi*2+7] + poslo[7]*p[poshi*2+9]) >> SINC_QUANTSHIFT);\ -// rewbs.resamplerConf -// fir interpolation -#define SNDMIX_GETSTEREOVOL8FIRFILTER \ - int poshi = nPos >> 16;\ - int poslo = (nPos & 0xFFFF);\ - int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \ - int vol_l = (WFIR_lut[firidx+0]*(int)p[(poshi+1-4)*2 ]); \ - vol_l += (WFIR_lut[firidx+1]*(int)p[(poshi+2-4)*2 ]); \ - vol_l += (WFIR_lut[firidx+2]*(int)p[(poshi+3-4)*2 ]); \ - vol_l += (WFIR_lut[firidx+3]*(int)p[(poshi+4-4)*2 ]); \ - vol_l += (WFIR_lut[firidx+4]*(int)p[(poshi+5-4)*2 ]); \ - vol_l += (WFIR_lut[firidx+5]*(int)p[(poshi+6-4)*2 ]); \ - vol_l += (WFIR_lut[firidx+6]*(int)p[(poshi+7-4)*2 ]); \ - vol_l += (WFIR_lut[firidx+7]*(int)p[(poshi+8-4)*2 ]); \ - vol_l >>= WFIR_8SHIFT; \ - int vol_r = (WFIR_lut[firidx+0]*(int)p[(poshi+1-4)*2+1]); \ - vol_r += (WFIR_lut[firidx+1]*(int)p[(poshi+2-4)*2+1]); \ - vol_r += (WFIR_lut[firidx+2]*(int)p[(poshi+3-4)*2+1]); \ - vol_r += (WFIR_lut[firidx+3]*(int)p[(poshi+4-4)*2+1]); \ - vol_r += (WFIR_lut[firidx+4]*(int)p[(poshi+5-4)*2+1]); \ - vol_r += (WFIR_lut[firidx+5]*(int)p[(poshi+6-4)*2+1]); \ - vol_r += (WFIR_lut[firidx+6]*(int)p[(poshi+7-4)*2+1]); \ - vol_r += (WFIR_lut[firidx+7]*(int)p[(poshi+8-4)*2+1]); \ - vol_r >>= WFIR_8SHIFT; - -#define SNDMIX_GETSTEREOVOL16FIRFILTER \ - int poshi = nPos >> 16;\ - int poslo = (nPos & 0xFFFF);\ - int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \ - int vol1_l = (WFIR_lut[firidx+0]*(int)p[(poshi+1-4)*2 ]); \ - vol1_l += (WFIR_lut[firidx+1]*(int)p[(poshi+2-4)*2 ]); \ - vol1_l += (WFIR_lut[firidx+2]*(int)p[(poshi+3-4)*2 ]); \ - vol1_l += (WFIR_lut[firidx+3]*(int)p[(poshi+4-4)*2 ]); \ - int vol2_l = (WFIR_lut[firidx+4]*(int)p[(poshi+5-4)*2 ]); \ - vol2_l += (WFIR_lut[firidx+5]*(int)p[(poshi+6-4)*2 ]); \ - vol2_l += (WFIR_lut[firidx+6]*(int)p[(poshi+7-4)*2 ]); \ - vol2_l += (WFIR_lut[firidx+7]*(int)p[(poshi+8-4)*2 ]); \ - int vol_l = ((vol1_l>>1)+(vol2_l>>1)) >> (WFIR_16BITSHIFT-1); \ - int vol1_r = (WFIR_lut[firidx+0]*(int)p[(poshi+1-4)*2+1]); \ - vol1_r += (WFIR_lut[firidx+1]*(int)p[(poshi+2-4)*2+1]); \ - vol1_r += (WFIR_lut[firidx+2]*(int)p[(poshi+3-4)*2+1]); \ - vol1_r += (WFIR_lut[firidx+3]*(int)p[(poshi+4-4)*2+1]); \ - int vol2_r = (WFIR_lut[firidx+4]*(int)p[(poshi+5-4)*2+1]); \ - vol2_r += (WFIR_lut[firidx+5]*(int)p[(poshi+6-4)*2+1]); \ - vol2_r += (WFIR_lut[firidx+6]*(int)p[(poshi+7-4)*2+1]); \ - vol2_r += (WFIR_lut[firidx+7]*(int)p[(poshi+8-4)*2+1]); \ - int vol_r = ((vol1_r>>1)+(vol2_r>>1)) >> (WFIR_16BITSHIFT-1); -//end rewbs.resamplerConf -// -! BEHAVIOUR_CHANGE#0025 - - -///////////////////////////////////////////////////////////////////////////// - -#define SNDMIX_STOREMONOVOL\ - pvol[0] += vol * pChn->leftVol;\ - pvol[1] += vol * pChn->rightVol;\ - pvol += 2; - -#define SNDMIX_STORESTEREOVOL\ - pvol[0] += vol_l * pChn->leftVol;\ - pvol[1] += vol_r * pChn->rightVol;\ - pvol += 2; - -#define SNDMIX_STOREFASTMONOVOL\ - int v = vol * pChn->leftVol;\ - pvol[0] += v;\ - pvol[1] += v;\ - pvol += 2; - -#define SNDMIX_RAMPMONOVOL\ - rampLeftVol += pChn->leftRamp;\ - rampRightVol += pChn->rightRamp;\ - pvol[0] += vol * (rampLeftVol >> VOLUMERAMPPRECISION);\ - pvol[1] += vol * (rampRightVol >> VOLUMERAMPPRECISION);\ - pvol += 2; - -#define SNDMIX_RAMPFASTMONOVOL\ - rampLeftVol += pChn->leftRamp;\ - int fastvol = vol * (rampLeftVol >> VOLUMERAMPPRECISION);\ - pvol[0] += fastvol;\ - pvol[1] += fastvol;\ - pvol += 2; - -#define SNDMIX_RAMPSTEREOVOL\ - rampLeftVol += pChn->leftRamp;\ - rampRightVol += pChn->rightRamp;\ - pvol[0] += vol_l * (rampLeftVol >> VOLUMERAMPPRECISION);\ - pvol[1] += vol_r * (rampRightVol >> VOLUMERAMPPRECISION);\ - pvol += 2; - - -/////////////////////////////////////////////////// -// Resonant Filters - -// Filter values are clipped to double the input range (assuming input is 16-Bit, which it currently is) -#define ClipFilter(x) Clamp(x, 2.0f * (float)int16_min, 2.0f * (float)int16_max) - -// Resonant filter for Mono samples -static forceinline void ProcessMonoFilter(int &vol, ModChannel *pChn) -//------------------------------------------------------------------- +// SRC index +enum ResamplingIndex { - float fy1 = pChn->nFilter_Y1; - float fy2 = pChn->nFilter_Y2; + ndxNoInterpolation = 0x00, + ndxLinear = 0x10, + ndxFastSinc = 0x20, + ndxKaiser = 0x30, + ndxFIRFilter = 0x40, +}; - float fy = ((float)vol * pChn->nFilter_A0 + ClipFilter(fy1) * pChn->nFilter_B0 + ClipFilter(fy2) * pChn->nFilter_B1); - fy2 = fy1; - fy1 = fy - (float)(vol & pChn->nFilter_HP); - vol = (int)fy; +// Build mix function table for given resampling, filter and ramping settings: One function each for 8-Bit / 16-Bit Mono / Stereo +#define BuildMixFuncTableRamp(resampling, filter, ramp) \ + SampleLoop<I8M, resampling<I8M>, filter<I8M>, MixMono ## ramp<I8M> >, \ + SampleLoop<I16M, resampling<I16M>, filter<I16M>, MixMono ## ramp<I16M> >, \ + SampleLoop<I8S, resampling<I8S>, filter<I8S>, MixStereo ## ramp<I8S> >, \ + SampleLoop<I16S, resampling<I16S>, filter<I16S>, MixStereo ## ramp<I16S> > - pChn->nFilter_Y1 = fy1; - pChn->nFilter_Y2 = fy2; -} +// Build mix function table for given resampling, filter settings: With and without ramping +#define BuildMixFuncTableFilter(resampling, filter) \ + BuildMixFuncTableRamp(resampling, filter, NoRamp), \ + BuildMixFuncTableRamp(resampling, filter, Ramp) +// Build mix function table for given resampling settings: With and without filter +#define BuildMixFuncTable(resampling) \ + BuildMixFuncTableFilter(resampling, NoFilter), \ + BuildMixFuncTableFilter(resampling, ResonantFilter) -// Resonant filter for Stereo samples -static forceinline void ProcessStereoFilter(int &vol_l, int &vol_r, ModChannel *pChn) -//----------------------------------------------------------------------------------- +const MixFuncInterface Functions[5 * 16] = { - // Left channel - float fy1 = pChn->nFilter_Y1; - float fy2 = pChn->nFilter_Y2; + BuildMixFuncTable(NoInterpolation), // No SRC + BuildMixFuncTable(LinearInterpolation), // Linear SRC + BuildMixFuncTable(FastSincInterpolation), // Fast Sinc (Cubic Spline) SRC + BuildMixFuncTable(PolyphaseInterpolation), // Kaiser SRC + BuildMixFuncTable(FIRFilterInterpolation), // FIR SRC +}; - float fy = ((float)vol_l * pChn->nFilter_A0 + ClipFilter(fy1) * pChn->nFilter_B0 + ClipFilter(fy2) * pChn->nFilter_B1); - fy2 = fy1; - fy1 = fy - (float)(vol_l & pChn->nFilter_HP); - vol_l = (int)fy; +#undef BuildMixFuncTableRamp +#undef BuildMixFuncTableFilter +#undef BuildMixFuncTable - pChn->nFilter_Y1 = fy1; - pChn->nFilter_Y2 = ... [truncated message content] |
From: <sag...@us...> - 2014-02-01 16:04:19
|
Revision: 3614 http://sourceforge.net/p/modplug/code/3614 Author: saga-games Date: 2014-02-01 16:04:11 +0000 (Sat, 01 Feb 2014) Log Message: ----------- [Fix] Generated loop lookahead data was wrong for stereo samples. [Mod] OpenMPT: Version is now 1.22.07.17 Modified Paths: -------------- trunk/OpenMPT/common/versionNumber.h trunk/OpenMPT/soundlib/modsmp_ctrl.cpp Modified: trunk/OpenMPT/common/versionNumber.h =================================================================== --- trunk/OpenMPT/common/versionNumber.h 2014-02-01 15:44:02 UTC (rev 3613) +++ trunk/OpenMPT/common/versionNumber.h 2014-02-01 16:04:11 UTC (rev 3614) @@ -17,7 +17,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 22 #define VER_MINOR 07 -#define VER_MINORMINOR 16 +#define VER_MINORMINOR 17 //Version string. For example "1.17.02.28" #define MPT_VERSION_STR VER_STRINGIZE(VER_MAJORMAJOR) "." VER_STRINGIZE(VER_MAJOR) "." VER_STRINGIZE(VER_MINOR) "." VER_STRINGIZE(VER_MINORMINOR) Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.cpp =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2014-02-01 15:44:02 UTC (rev 3613) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2014-02-01 16:04:11 UTC (rev 3614) @@ -177,9 +177,9 @@ // Copy sample over to lookahead buffer for(int c = 0; c < numChannels; c++) { - *dest = sampleData[readPosition * numChannels + c]; - dest += writeIncrement; + dest[c] = sampleData[readPosition * numChannels + c]; } + dest += writeIncrement * numChannels; if(readPosition == loopEnd - 1 && readIncrement > 0) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <man...@us...> - 2014-02-01 16:34:48
|
Revision: 3615 http://sourceforge.net/p/modplug/code/3615 Author: manxorist Date: 2014-02-01 16:34:40 +0000 (Sat, 01 Feb 2014) Log Message: ----------- [New] Add an alternate, templated dithering algorithm. Default is still the original ModPlug Tracker dither. (no GUI to select it yet) [Ref] sounddev: Add option to disable the internal dither of sound devices (useful for PortAudio). (no GUI yet) [Ref] Mod Export: Add option to select/disable dithering. (no GUI yet) Modified Paths: -------------- trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mod2wave.cpp trunk/OpenMPT/mptrack/StreamEncoder.h trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/sounddev/SoundDevice.h trunk/OpenMPT/sounddev/SoundDevicePortAudio.cpp trunk/OpenMPT/soundlib/Dither.cpp trunk/OpenMPT/soundlib/Dither.h Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2014-02-01 16:04:11 UTC (rev 3614) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2014-02-01 16:34:40 UTC (rev 3615) @@ -737,6 +737,7 @@ timingInfo.SystemTimestamp = timeInfo.SystemTimestamp; timingInfo.Speed = timeInfo.Speed; m_pSndFile->m_TimingInfo = timingInfo; + m_Dither.SetMode((DitherMode)settings.DitherType); StereoVuMeterTargetWrapper target(settings.sampleFormat, m_Dither, buffer); CSoundFile::samplecount_t renderedFrames = m_pSndFile->Read(numFrames, target); ASSERT(renderedFrames <= numFrames); Modified: trunk/OpenMPT/mptrack/Mod2wave.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mod2wave.cpp 2014-02-01 16:04:11 UTC (rev 3614) +++ trunk/OpenMPT/mptrack/Mod2wave.cpp 2014-02-01 16:34:40 UTC (rev 3615) @@ -845,7 +845,8 @@ encTraits.defaultMode, encTraits.defaultBitrate, encTraits.defaultQuality, - encTraits.defaultFormat + encTraits.defaultFormat, + encTraits.defaultDitherType ) ) ); @@ -951,6 +952,7 @@ } Dither dither; + dither.SetMode((DitherMode)encSettings.Dither.Get()); m_SndFile.ResetChannels(); m_SndFile.SetMixerSettings(mixersettings); Modified: trunk/OpenMPT/mptrack/StreamEncoder.h =================================================================== --- trunk/OpenMPT/mptrack/StreamEncoder.h 2014-02-01 16:04:11 UTC (rev 3614) +++ trunk/OpenMPT/mptrack/StreamEncoder.h 2014-02-01 16:34:40 UTC (rev 3615) @@ -136,6 +136,7 @@ int defaultBitrate; float defaultQuality; int defaultFormat; + int defaultDitherType; Traits() : canCues(false) @@ -149,6 +150,7 @@ , defaultBitrate(0) , defaultQuality(0.0f) , defaultFormat(0) + , defaultDitherType(1) { return; } @@ -168,8 +170,9 @@ Setting<int> Bitrate; Setting<float> Quality; Setting<int> Format; + Setting<int> Dither; - Settings(SettingsContainer &conf, const std::string &encoderName, bool cues, bool tags, uint32 samplerate, uint16 channels, Encoder::Mode mode, int bitrate, float quality, int format) + Settings(SettingsContainer &conf, const std::string &encoderName, bool cues, bool tags, uint32 samplerate, uint16 channels, Encoder::Mode mode, int bitrate, float quality, int format, int dither) : Cues(conf, "Export", encoderName + "_" + "Cues", cues) , Tags(conf, "Export", encoderName + "_" + "Tags", tags) , Samplerate(conf, "Export", encoderName + "_" + "Samplerate", samplerate) @@ -178,6 +181,7 @@ , Bitrate(conf, "Export", encoderName + "_" + "Bitrate", bitrate) , Quality(conf, "Export", encoderName + "_" + "Quality", quality) , Format(conf, "Export", encoderName + "_" + "Format", format) + , Dither(conf, "Export", encoderName + "_" + "Dither", dither) { return; } Modified: trunk/OpenMPT/mptrack/TrackerSettings.cpp =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-02-01 16:04:11 UTC (rev 3614) +++ trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-02-01 16:34:40 UTC (rev 3615) @@ -525,6 +525,7 @@ Setting<bool> ExclusiveMode; Setting<bool> BoostThreadPriority; Setting<bool> UseHardwareTiming; + Setting<int> DitherType; Setting<SoundChannelMapping> ChannelMapping; public: @@ -540,6 +541,7 @@ , ExclusiveMode(conf, L"Sound Settings", deviceInfo.GetIdentifier() + L"_" + L"ExclusiveMode", defaults.ExclusiveMode) , BoostThreadPriority(conf, L"Sound Settings", deviceInfo.GetIdentifier() + L"_" + L"BoostThreadPriority", defaults.BoostThreadPriority) , UseHardwareTiming(conf, L"Sound Settings", deviceInfo.GetIdentifier() + L"_" + L"UseHardwareTiming", defaults.UseHardwareTiming) + , DitherType(conf, L"Sound Settings", deviceInfo.GetIdentifier() + L"_" + L"DitherType", defaults.DitherType) , ChannelMapping(conf, L"Sound Settings", deviceInfo.GetIdentifier() + L"_" + L"ChannelMapping", defaults.ChannelMapping) { // store informational data (not read back, jsut to allow the user to mock with the raw ini file) @@ -559,6 +561,7 @@ ExclusiveMode = settings.ExclusiveMode; BoostThreadPriority = settings.BoostThreadPriority; UseHardwareTiming = settings.UseHardwareTiming; + DitherType = settings.DitherType; ChannelMapping = settings.ChannelMapping; return *this; } @@ -574,6 +577,7 @@ settings.ExclusiveMode = ExclusiveMode; settings.BoostThreadPriority = BoostThreadPriority; settings.UseHardwareTiming = UseHardwareTiming; + settings.DitherType = DitherType; settings.ChannelMapping = ChannelMapping; return settings; } Modified: trunk/OpenMPT/sounddev/SoundDevice.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDevice.h 2014-02-01 16:04:11 UTC (rev 3614) +++ trunk/OpenMPT/sounddev/SoundDevice.h 2014-02-01 16:34:40 UTC (rev 3615) @@ -252,6 +252,7 @@ bool ExclusiveMode; // Use hardware buffers directly bool BoostThreadPriority; // Boost thread priority for glitch-free audio rendering bool UseHardwareTiming; + int DitherType; SoundChannelMapping ChannelMapping; SoundDeviceSettings() : hWnd(NULL) @@ -263,6 +264,7 @@ , ExclusiveMode(false) , BoostThreadPriority(true) , UseHardwareTiming(false) + , DitherType(1) { return; } @@ -279,6 +281,7 @@ && BoostThreadPriority == cmp.BoostThreadPriority && UseHardwareTiming == cmp.UseHardwareTiming && ChannelMapping == cmp.ChannelMapping + && DitherType == cmp.DitherType ; } bool operator != (const SoundDeviceSettings &cmp) const @@ -308,6 +311,7 @@ bool CanUseHardwareTiming; bool CanChannelMapping; bool CanDriverPanel; + bool HasInternalDither; std::wstring ExclusiveModeDescription; SoundDeviceCaps() : currentSampleRate(0) @@ -318,6 +322,7 @@ , CanUseHardwareTiming(false) , CanChannelMapping(false) , CanDriverPanel(false) + , HasInternalDither(false) , ExclusiveModeDescription(L"Use device exclusively") { return; Modified: trunk/OpenMPT/sounddev/SoundDevicePortAudio.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDevicePortAudio.cpp 2014-02-01 16:04:11 UTC (rev 3614) +++ trunk/OpenMPT/sounddev/SoundDevicePortAudio.cpp 2014-02-01 16:34:40 UTC (rev 3615) @@ -97,7 +97,12 @@ framesPerBuffer = paFramesPerBufferUnspecified; // let portaudio choose } if(Pa_IsFormatSupported(NULL, &m_StreamParameters, m_Settings.Samplerate) != paFormatIsSupported) return false; - if(Pa_OpenStream(&m_Stream, NULL, &m_StreamParameters, m_Settings.Samplerate, framesPerBuffer, paNoFlag, StreamCallbackWrapper, (void*)this) != paNoError) return false; + PaStreamFlags flags = paNoFlag; + if(m_Settings.DitherType == 0) + { + flags |= paDitherOff; + } + if(Pa_OpenStream(&m_Stream, NULL, &m_StreamParameters, m_Settings.Samplerate, framesPerBuffer, flags, StreamCallbackWrapper, (void*)this) != paNoError) return false; m_StreamInfo = Pa_GetStreamInfo(m_Stream); if(!m_StreamInfo) { @@ -185,6 +190,7 @@ caps.CanUseHardwareTiming = false; caps.CanChannelMapping = false; caps.CanDriverPanel = false; + caps.HasInternalDither = true; if(m_HostApi == Pa_HostApiTypeIdToHostApiIndex(paWASAPI)) { caps.CanExclusiveMode = true; Modified: trunk/OpenMPT/soundlib/Dither.cpp =================================================================== --- trunk/OpenMPT/soundlib/Dither.cpp 2014-02-01 16:04:11 UTC (rev 3614) +++ trunk/OpenMPT/soundlib/Dither.cpp 2014-02-01 16:34:40 UTC (rev 3615) @@ -13,6 +13,7 @@ #include "Dither.h" #include "Mixer.h" +#include "../common/misc_util.h" ////////////////////////////////////////////////////////////////////////// @@ -122,35 +123,167 @@ } +#define FASTRAND_MAX 0x7fff +#define FASTRAND_BITS 15 + +static forceinline int fastrand(uint32 &state) +//-------------------------------------------- +{ + state = 214013 * state + 2531011; + return (state >> 16) & 0x7FFF; +} + +static forceinline int fastrandbits(uint32 &state, int bits) +//---------------------------------------------------------- +{ + int result = 0; + if(bits > 0 * FASTRAND_BITS) result = (result << FASTRAND_BITS) | fastrand(state); + if(bits > 1 * FASTRAND_BITS) result = (result << FASTRAND_BITS) | fastrand(state); + if(bits > 2 * FASTRAND_BITS) result = (result << FASTRAND_BITS) | fastrand(state); + result &= (1 << bits) - 1; + return result; +} + +template<int targetbits, int channels, int ditherdepth = 1, bool triangular = false, bool shaped = true> +struct Dither_SimpleTemplate +{ +noinline void operator () (int *mixbuffer, std::size_t count, DitherSimpleState &state) +//------------------------------------------------------------------------------------- +{ + STATIC_ASSERT(sizeof(int) == 4); + STATIC_ASSERT(FASTRAND_BITS * 3 >= (32-targetbits) - MIXING_ATTENUATION); + const int rshift = (32-targetbits) - MIXING_ATTENUATION; + if(rshift <= 0) + { + // nothing to dither + return; + } + const int round_mask = ~((1<<rshift)-1); + const int round_offset = 1<<(rshift-1); + const int noise_bits = rshift + (ditherdepth - 1); + const int noise_bias = (1<<(noise_bits-1)); + DitherSimpleState s = state; + for(std::size_t i = 0; i < count; ++i) + { + for(std::size_t channel = 0; channel < channels; ++channel) + { + int noise = 0; + if(triangular) + { + noise = (fastrandbits(s.rng, noise_bits) + fastrandbits(s.rng, noise_bits)) >> 1; + } else + { + noise = fastrandbits(s.rng, noise_bits); + } + noise -= noise_bias; // un-bias + int val = *mixbuffer; + if(shaped) + { + val += (s.error[channel] >> 1); + } + int rounded = (val + noise + round_offset) & round_mask;; + s.error[channel] = val - rounded; + *mixbuffer = rounded; + mixbuffer++; + } + } + state = s; +} +}; + +static void Dither_Simple(int *mixbuffer, std::size_t count, std::size_t channels, int bits, DitherSimpleState &state) +//-------------------------------------------------------------------------------------------------------------------- +{ + switch(bits) + { + case 8: + switch(channels) + { + case 1: + Dither_SimpleTemplate<8,1>()(mixbuffer, count, state); + break; + case 2: + Dither_SimpleTemplate<8,2>()(mixbuffer, count, state); + break; + case 4: + Dither_SimpleTemplate<8,4>()(mixbuffer, count, state); + break; + } + break; + case 16: + switch(channels) + { + case 1: + Dither_SimpleTemplate<16,1>()(mixbuffer, count, state); + break; + case 2: + Dither_SimpleTemplate<16,2>()(mixbuffer, count, state); + break; + case 4: + Dither_SimpleTemplate<16,4>()(mixbuffer, count, state); + break; + } + break; + case 24: + switch(channels) + { + case 1: + Dither_SimpleTemplate<24,1>()(mixbuffer, count, state); + break; + case 2: + Dither_SimpleTemplate<24,2>()(mixbuffer, count, state); + break; + case 4: + Dither_SimpleTemplate<24,4>()(mixbuffer, count, state); + break; + } + break; + } +} + + void Dither::Reset() +//------------------ { state = DitherState(); } + Dither::Dither() +//-------------- { - mode = DitherModPlug; + mode = DitherDefault; } -void Dither::SetMode(DitherMode &mode_) + +void Dither::SetMode(DitherMode mode_) +//------------------------------------ { mode = mode_; } + DitherMode Dither::GetMode() const +//-------------------------------- { return mode; } + void Dither::Process(int *mixbuffer, std::size_t count, std::size_t channels, int bits) +//------------------------------------------------------------------------------------- { switch(mode) { case DitherNone: // nothing break; + case DitherDefault: case DitherModPlug: Dither_ModPlug(mixbuffer, count, channels, bits, state.modplug); break; + case DitherSimple: + Dither_Simple(mixbuffer, count, channels, bits, state.simple); + break; } } Modified: trunk/OpenMPT/soundlib/Dither.h =================================================================== --- trunk/OpenMPT/soundlib/Dither.h 2014-02-01 16:04:11 UTC (rev 3614) +++ trunk/OpenMPT/soundlib/Dither.h 2014-02-01 16:34:40 UTC (rev 3615) @@ -23,15 +23,31 @@ } }; +struct DitherSimpleState +{ + int32 error[4]; + uint32 rng; + DitherSimpleState() { + error[0] = 0; + error[1] = 0; + error[2] = 0; + error[3] = 0; + rng = 0x12345678; + } +}; + struct DitherState { DitherModPlugState modplug; + DitherSimpleState simple; }; enum DitherMode { DitherNone = 0, - DitherModPlug = 1 + DitherDefault = 1, // chosen by OpenMPT code, might change + DitherModPlug = 2, // rectangular, 0.5 bit depth, no noise shaping (original ModPlug Tracker) + DitherSimple = 3 // rectangular, 1 bit depth, simple 1st order noise shaping }; class Dither @@ -41,7 +57,7 @@ DitherMode mode; public: Dither(); - void SetMode(DitherMode &mode); + void SetMode(DitherMode mode); DitherMode GetMode() const; void Reset(); void Process(int *mixbuffer, std::size_t count, std::size_t channels, int bits); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <man...@us...> - 2014-02-01 16:52:36
|
Revision: 3617 http://sourceforge.net/p/modplug/code/3617 Author: manxorist Date: 2014-02-01 16:52:29 +0000 (Sat, 01 Feb 2014) Log Message: ----------- [New] libopenmpt: Allow disabling/selecting dither with ctl_set("dither"). [New] openmpt123: Allow disabling/selecting dither with --dither n . Modified Paths: -------------- trunk/OpenMPT/libopenmpt/libopenmpt_impl.cpp trunk/OpenMPT/openmpt123/openmpt123.cpp trunk/OpenMPT/openmpt123/openmpt123.hpp Modified: trunk/OpenMPT/libopenmpt/libopenmpt_impl.cpp =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmpt_impl.cpp 2014-02-01 16:37:27 UTC (rev 3616) +++ trunk/OpenMPT/libopenmpt/libopenmpt_impl.cpp 2014-02-01 16:52:29 UTC (rev 3617) @@ -23,6 +23,7 @@ #include <cstring> #include "common/version.h" +#include "common/misc_util.h" #include "soundlib/Sndfile.h" #include "soundlib/AudioReadTarget.h" #include "soundlib/FileReader.h" @@ -1031,17 +1032,22 @@ std::vector<std::string> module_impl::get_ctls() const { std::vector<std::string> retval; + retval.push_back( "dither" ); return retval; } std::string module_impl::ctl_get( const std::string & ctl ) const { if ( ctl == "" ) { throw openmpt::exception("unknown ctl"); + } else if ( ctl == "dither" ) { + return mpt::ToString( static_cast<int>( m_Dither->GetMode() ) ); } throw openmpt::exception("unknown ctl"); } void module_impl::ctl_set( const std::string & ctl, const std::string & value ) { if ( ctl == "" ) { throw openmpt::exception("unknown ctl: " + ctl + " := " + value); + } else if ( ctl == "dither" ) { + m_Dither->SetMode( static_cast<DitherMode>( ConvertStrTo<int>( value ) ) ); } throw openmpt::exception("unknown ctl: " + ctl + " := " + value); } Modified: trunk/OpenMPT/openmpt123/openmpt123.cpp =================================================================== --- trunk/OpenMPT/openmpt123/openmpt123.cpp 2014-02-01 16:37:27 UTC (rev 3616) +++ trunk/OpenMPT/openmpt123/openmpt123.cpp 2014-02-01 16:52:29 UTC (rev 3617) @@ -229,6 +229,7 @@ s << "Stereo separation: " << flags.separation << std::endl; s << "Interpolation filter taps: " << flags.filtertaps << std::endl; s << "Volume ramping strength: " << flags.ramping << std::endl; + s << "Output dithering: " << flags.dither << std::endl; s << "Repeat count: " << flags.repeatcount << std::endl; s << "Seek target: " << flags.seek_target << std::endl; s << "Standard output: " << flags.use_stdout << std::endl; @@ -456,6 +457,7 @@ log << " --stereo n Set stereo separation to n % [default: " << commandlineflags().separation << "]" << std::endl; log << " --filter n Set interpolation filter taps to n [1,2,4,8] [default: " << commandlineflags().filtertaps << "]" << std::endl; log << " --ramping n Set volume ramping strength n [0..5] [default: " << commandlineflags().ramping << "]" << std::endl; + log << " --dither n Dither type for 16bit integer output: [0=off,1=auto,2=0.5bit,3=1bit] [default: " << commandlineflags().dither << "]" << std::endl; log << std::endl; log << " --[no-]shuffle Shuffle playlist (-1 means forever) [default: " << commandlineflags().shuffle << "]" << std::endl; log << std::endl; @@ -531,6 +533,10 @@ mod.set_render_param( openmpt::module::RENDER_STEREOSEPARATION_PERCENT, flags.separation ); mod.set_render_param( openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, flags.filtertaps ); mod.set_render_param( openmpt::module::RENDER_VOLUMERAMPING_STRENGTH, flags.ramping ); + std::ostringstream dither_str; + dither_str.imbue( std::locale::classic() ); + dither_str << flags.dither; + mod.ctl_set( "dither", dither_str.str() ); } struct prev_file { int count; prev_file( int c ) : count(c) { } }; @@ -1575,6 +1581,10 @@ std::istringstream istr( nextarg ); istr >> flags.ramping; ++i; + } else if ( arg == "--dither" && nextarg != "" ) { + std::istringstream istr( nextarg ); + istr >> flags.dither; + ++i; } else if ( arg == "--shuffle" ) { flags.shuffle = true; } else if ( arg == "--no-shuffle" ) { Modified: trunk/OpenMPT/openmpt123/openmpt123.hpp =================================================================== --- trunk/OpenMPT/openmpt123/openmpt123.hpp 2014-02-01 16:37:27 UTC (rev 3616) +++ trunk/OpenMPT/openmpt123/openmpt123.hpp 2014-02-01 16:52:29 UTC (rev 3617) @@ -251,6 +251,7 @@ std::int32_t separation; std::int32_t filtertaps; std::int32_t ramping; // ramping strength : -1:default 0:off 1 2 3 4 5 // roughly milliseconds + std::int32_t dither; std::int32_t repeatcount; double seek_target; bool quiet; @@ -304,6 +305,7 @@ separation = 100; filtertaps = 8; ramping = -1; + dither = 1; repeatcount = 0; seek_target = 0.0; quiet = false; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <man...@us...> - 2014-02-01 21:26:12
|
Revision: 3623 http://sourceforge.net/p/modplug/code/3623 Author: manxorist Date: 2014-02-01 21:26:00 +0000 (Sat, 01 Feb 2014) Log Message: ----------- [Mod] Move mixer-related settings from the Soundcard and Player settings pages into their own page. Rename Player settings page to DSP as it only contains DSP-related settings after the move. [Ref] sounddev: Split KeepDeviceRunnig from ExclusiveMode setting. [New] Add dithering option to soundcard settings. [New] Make KeepDeviceRunning and HardwareTiming settings accessable via GUI. [New] Make KeepDeviceOpen and OpenDeviceAtStartup settings accessable via GUI. [Mod] Change the unit of volume ramping settings from samples to microseconds so that stays consistent accross sample rate changes. [Mod] Mod Export: Only show settings pages that are relevant for rendering in player options dialog. [Mod] OpenMPT: Version is now 1.22.07.18 Modified Paths: -------------- trunk/OpenMPT/common/versionNumber.h trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/Mod2wave.cpp trunk/OpenMPT/mptrack/Moptions.h trunk/OpenMPT/mptrack/Mpdlgs.cpp trunk/OpenMPT/mptrack/Mpdlgs.h trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/mptrack/TrackerSettings.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/sounddev/SoundDevice.h trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp trunk/OpenMPT/soundlib/MixerSettings.cpp trunk/OpenMPT/soundlib/MixerSettings.h trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/common/versionNumber.h =================================================================== --- trunk/OpenMPT/common/versionNumber.h 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/common/versionNumber.h 2014-02-01 21:26:00 UTC (rev 3623) @@ -17,7 +17,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 22 #define VER_MINOR 07 -#define VER_MINORMINOR 17 +#define VER_MINORMINOR 18 //Version string. For example "1.17.02.28" #define MPT_VERSION_STR VER_STRINGIZE(VER_MAJORMAJOR) "." VER_STRINGIZE(VER_MAJOR) "." VER_STRINGIZE(VER_MINOR) "." VER_STRINGIZE(VER_MINORMINOR) Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2014-02-01 21:26:00 UTC (rev 3623) @@ -1158,14 +1158,6 @@ } -void CMainFrame::SetPreAmp(UINT n) -//-------------------------------- -{ - TrackerSettings::Instance().MixerPreAmp = n; - if (m_pSndFile) m_pSndFile->SetPreAmp(TrackerSettings::Instance().MixerPreAmp); -} - - void CMainFrame::ResetNotificationBuffer() //---------------------------------------- { @@ -1786,6 +1778,7 @@ COptionsKeyboard keyboard; COptionsColors colors; COptionsPlayer playerdlg; + COptionsMixer mixerdlg; CMidiSetupDlg mididlg(TrackerSettings::Instance().m_dwMidiSetup, TrackerSettings::Instance().m_nMidiDevice); #ifndef NO_EQ CEQSetupDlg eqdlg(&TrackerSettings::Instance().m_EqSettings); @@ -1797,7 +1790,10 @@ #endif // MPT_SETTINGS_CACHE dlg.AddPage(&general); dlg.AddPage(&sounddlg); + dlg.AddPage(&mixerdlg); +#if !defined(NO_REVERB) || !defined(NO_DSP) || !defined(NO_EQ) || !defined(NO_AGC) dlg.AddPage(&playerdlg); +#endif #ifndef NO_EQ dlg.AddPage(&eqdlg); #endif Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2014-02-01 21:26:00 UTC (rev 3623) @@ -470,7 +470,6 @@ BOOL SetupDirectories(const mpt::PathString &szModDir, const mpt::PathString &szSampleDir, const mpt::PathString &szInstrDir, const mpt::PathString &szVstDir, const mpt::PathString &szPresetDir); BOOL SetupMidi(DWORD d, LONG n); - void SetPreAmp(UINT n); HWND GetFollowSong() const; HWND GetFollowSong(const CModDoc *pDoc) const { return (pDoc == GetModPlaying()) ? GetFollowSong() : NULL; } void ResetNotificationBuffer(); Modified: trunk/OpenMPT/mptrack/Mod2wave.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mod2wave.cpp 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/mptrack/Mod2wave.cpp 2014-02-01 21:26:00 UTC (rev 3623) @@ -600,8 +600,16 @@ void CWaveConvert::OnPlayerOptions() //---------------------------------- { - CMainFrame::m_nLastOptionsPage = 2; - CMainFrame::GetMainFrame()->OnViewOptions(); + CPropertySheet dlg("Mixer Settings", this); + COptionsMixer mixerpage; + dlg.AddPage(&mixerpage); + COptionsPlayer dsppage; + dlg.AddPage(&dsppage); +#ifndef NO_EQ + CEQSetupDlg eqpage(&TrackerSettings::Instance().m_EqSettings); + dlg.AddPage(&eqpage); +#endif + dlg.DoModal(); } Modified: trunk/OpenMPT/mptrack/Moptions.h =================================================================== --- trunk/OpenMPT/mptrack/Moptions.h 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/mptrack/Moptions.h 2014-02-01 21:26:00 UTC (rev 3623) @@ -16,6 +16,7 @@ enum { OPTIONS_PAGE_GENERAL=0, OPTIONS_PAGE_SOUNDCARD, + OPTIONS_PAGE_MIXER, OPTIONS_PAGE_PLAYER, OPTIONS_PAGE_EQ, OPTIONS_PAGE_KEYBOARD, Modified: trunk/OpenMPT/mptrack/Mpdlgs.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mpdlgs.cpp 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/mptrack/Mpdlgs.cpp 2014-02-01 21:26:00 UTC (rev 3623) @@ -73,7 +73,8 @@ ON_CBN_SELCHANGE(IDC_COMBO3, OnSettingsChanged) ON_CBN_SELCHANGE(IDC_COMBO4, OnSettingsChanged) ON_CBN_SELCHANGE(IDC_COMBO5, OnSettingsChanged) - ON_CBN_SELCHANGE(IDC_COMBO6, OnSettingsChanged) + ON_CBN_SELCHANGE(IDC_COMBO6, OnSampleFormatChanged) + ON_CBN_SELCHANGE(IDC_COMBO10, OnSettingsChanged) ON_CBN_SELCHANGE(IDC_COMBO9, OnSettingsChanged) ON_CBN_EDITCHANGE(IDC_COMBO2, OnSettingsChanged) ON_CBN_EDITCHANGE(IDC_COMBO_UPDATEINTERVAL, OnSettingsChanged) @@ -82,6 +83,14 @@ END_MESSAGE_MAP() +void COptionsSoundcard::OnSampleFormatChanged() +//--------------------------------------------- +{ + OnSettingsChanged(); + UpdateDither(); +} + + void COptionsSoundcard::DoDataExchange(CDataExchange* pDX) //-------------------------------------------------------- { @@ -91,13 +100,11 @@ DDX_Control(pDX, IDC_COMBO2, m_CbnLatencyMS); DDX_Control(pDX, IDC_COMBO_UPDATEINTERVAL, m_CbnUpdateIntervalMS); DDX_Control(pDX, IDC_COMBO3, m_CbnMixingFreq); - DDX_Control(pDX, IDC_COMBO4, m_CbnPolyphony); DDX_Control(pDX, IDC_COMBO5, m_CbnChannels); DDX_Control(pDX, IDC_COMBO6, m_CbnSampleFormat); + DDX_Control(pDX, IDC_COMBO10, m_CbnDither); DDX_Control(pDX, IDC_COMBO9, m_CbnBaseChannel); DDX_Control(pDX, IDC_BUTTON2, m_BtnDriverPanel); - DDX_Control(pDX, IDC_SLIDER1, m_SliderStereoSep); - DDX_Control(pDX, IDC_SLIDER_PREAMP, m_SliderPreAmp); DDX_Control(pDX, IDC_EDIT_STATISTICS, m_EditStatistics); //}}AFX_DATA_MAP } @@ -110,7 +117,7 @@ , m_CurrentDeviceCaps(theApp.GetSoundDevicesManager()->GetDeviceCaps(dev, TrackerSettings::Instance().GetSampleRates(), CMainFrame::GetMainFrame(), CMainFrame::GetMainFrame()->gpSoundDevice, true)) , m_Settings(TrackerSettings::Instance().GetSoundDeviceSettings(dev)) { - m_PreAmpNoteShowed = false; + return; } @@ -204,41 +211,12 @@ void COptionsSoundcard::UpdateEverything() //---------------------------------------- { - - CHAR s[128]; - - CheckDlgButton(IDC_CHECK2, (TrackerSettings::Instance().MixerFlags & SNDMIX_SOFTPANNING) ? MF_CHECKED : MF_UNCHECKED); - - // Max Mixing Channels + // General { - m_CbnPolyphony.ResetContent(); - for (UINT n = 0; n < CountOf(nCPUMix); n++) - { - wsprintf(s, "%d (%s)", nCPUMix[n], szCPUNames[n]); - m_CbnPolyphony.AddString(s); - if (TrackerSettings::Instance().MixerMaxChannels == nCPUMix[n]) m_CbnPolyphony.SetCurSel(n); - } + CheckDlgButton(IDC_CHECK6, TrackerSettings::Instance().m_SoundSettingsKeepDeviceOpen ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(IDC_CHECK7, TrackerSettings::Instance().m_SoundSettingsOpenDeviceAtStartup ? BST_CHECKED : BST_UNCHECKED); } - // Stereo Separation - { - m_SliderStereoSep.SetRange(0, 4); - m_SliderStereoSep.SetPos(2); - for (int n=0; n<=4; n++) - { - if ((int)TrackerSettings::Instance().MixerStereoSeparation <= (int)(32 << n)) - { - m_SliderStereoSep.SetPos(n); - break; - } - } - UpdateStereoSep(); - } - // Pre-Amplification - { - m_SliderPreAmp.SetTicFreq(5); - m_SliderPreAmp.SetRange(0, 40); - SetPreAmpSliderPosition(); - } + // Sound Device { m_CbnDevice.ResetContent(); @@ -325,6 +303,7 @@ UpdateSampleRates(); UpdateChannels(); UpdateSampleFormat(); + UpdateDither(); } @@ -369,7 +348,6 @@ } m_CbnBaseChannel.SetCurSel(sel); } - m_BtnDriverPanel.ShowWindow(m_CurrentDeviceCaps.CanDriverPanel ? SW_SHOW : SW_HIDE); } @@ -385,7 +363,7 @@ { if(m_CurrentDeviceCaps.CanSampleFormat || (SampleFormatFloat32 == m_Settings.sampleFormat)) { - UINT ndx = m_CbnSampleFormat.AddString("Floating Point"); + UINT ndx = m_CbnSampleFormat.AddString("Float"); m_CbnSampleFormat.SetItemData(ndx, (32+128)); if(SampleFormatFloat32 == m_Settings.sampleFormat) { @@ -409,63 +387,40 @@ } -void COptionsSoundcard::OnHScroll(UINT n, UINT pos, CScrollBar *p) -//---------------------------------------------------------------- +void COptionsSoundcard::UpdateDither() +//------------------------------------ { - CPropertyPage::OnHScroll(n, pos, p); - // stereo sep + UINT n = 0; + m_CbnDither.ResetContent(); + SampleFormat sampleFormat = (SampleFormat)(m_CbnSampleFormat.GetItemData(m_CbnSampleFormat.GetCurSel())); + if(sampleFormat.IsInt()) { - UpdateStereoSep(); + m_CbnDither.EnableWindow(TRUE); + m_CbnDither.AddString("no dithering"); + m_CbnDither.AddString("default dithering"); + m_CbnDither.AddString("0.5bit dithering"); + m_CbnDither.AddString("1bit dithering"); + } else if(m_CurrentDeviceCaps.HasInternalDither) + { + m_CbnDither.EnableWindow(TRUE); + m_CbnDither.AddString("no dithering"); + m_CbnDither.AddString("default dithering"); + } else + { + m_CbnDither.EnableWindow(FALSE); + m_CbnDither.AddString("no dithering"); + m_CbnDither.AddString("no dithering"); } - // PreAmp - if(p == (CScrollBar *)(&m_SliderPreAmp)) + if(m_Settings.DitherType < 0 || m_Settings.DitherType > m_CbnDither.GetCount()) { - if(m_PreAmpNoteShowed == true) - { - int n = m_SliderPreAmp.GetPos(); - if ((n >= 0) && (n <= 40)) // approximately +/- 10dB - { - CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); - if (pMainFrm) pMainFrm->SetPreAmp(64 + (n * 8)); - } - } else - { - m_PreAmpNoteShowed = true; - Reporting::Information(str_preampChangeNote); - SetPreAmpSliderPosition(); - } + m_CbnDither.SetCurSel(1); + } else + { + m_CbnDither.SetCurSel(m_Settings.DitherType); } } -void COptionsSoundcard::UpdateStereoSep() -//--------------------------------------- -{ - CHAR s[64]; - TrackerSettings::Instance().MixerStereoSeparation = 32 << m_SliderStereoSep.GetPos(); - CMainFrame::GetMainFrame()->SetupPlayer(); - wsprintf(s, "%d%%", (TrackerSettings::Instance().MixerStereoSeparation * 100) / 128); - SetDlgItemText(IDC_TEXT1, s); - -} - - -void COptionsSoundcard::SetPreAmpSliderPosition() -//----------------------------------------------- -{ - int n = (TrackerSettings::Instance().MixerPreAmp - 64) / 8; - if ((n < 0) || (n > 40)) n = 16; - m_SliderPreAmp.SetPos(n); -} - - -void COptionsSoundcard::OnVScroll(UINT n, UINT pos, CScrollBar *p) -//---------------------------------------------------------------- -{ - CPropertyPage::OnVScroll(n, pos, p); -} - - void COptionsSoundcard::OnDeviceChanged() //--------------------------------------- { @@ -519,13 +474,22 @@ void COptionsSoundcard::UpdateControls() //-------------------------------------- { + if(!m_CurrentDeviceCaps.CanKeepDeviceRunning) + { + m_Settings.KeepDeviceRunning = false; + } + m_BtnDriverPanel.EnableWindow(m_CurrentDeviceCaps.CanDriverPanel ? TRUE : FALSE); GetDlgItem(IDC_CHECK4)->EnableWindow(m_CurrentDeviceCaps.CanExclusiveMode ? TRUE : FALSE); GetDlgItem(IDC_CHECK5)->EnableWindow(m_CurrentDeviceCaps.CanBoostThreadPriority ? TRUE : FALSE); + GetDlgItem(IDC_CHECK8)->EnableWindow(m_CurrentDeviceCaps.CanKeepDeviceRunning ? TRUE : FALSE); + GetDlgItem(IDC_CHECK9)->EnableWindow(m_CurrentDeviceCaps.CanUseHardwareTiming ? TRUE : FALSE); GetDlgItem(IDC_STATIC_UPDATEINTERVAL)->EnableWindow(m_CurrentDeviceCaps.CanUpdateInterval ? TRUE : FALSE); GetDlgItem(IDC_COMBO_UPDATEINTERVAL)->EnableWindow(m_CurrentDeviceCaps.CanUpdateInterval ? TRUE : FALSE); GetDlgItem(IDC_CHECK4)->SetWindowText(mpt::ToCString(m_CurrentDeviceCaps.ExclusiveModeDescription)); CheckDlgButton(IDC_CHECK4, m_Settings.ExclusiveMode ? MF_CHECKED : MF_UNCHECKED); CheckDlgButton(IDC_CHECK5, m_Settings.BoostThreadPriority ? MF_CHECKED : MF_UNCHECKED); + CheckDlgButton(IDC_CHECK8, m_Settings.KeepDeviceRunning ? MF_CHECKED : MF_UNCHECKED); + CheckDlgButton(IDC_CHECK9, m_Settings.UseHardwareTiming ? MF_CHECKED : MF_UNCHECKED); } @@ -540,12 +504,15 @@ void COptionsSoundcard::OnOK() //---------------------------- { - if(IsDlgButtonChecked(IDC_CHECK2)) - TrackerSettings::Instance().MixerFlags = TrackerSettings::Instance().MixerFlags | SNDMIX_SOFTPANNING; - else - TrackerSettings::Instance().MixerFlags = TrackerSettings::Instance().MixerFlags & ~SNDMIX_SOFTPANNING; + // General + { + TrackerSettings::Instance().m_SoundSettingsKeepDeviceOpen = IsDlgButtonChecked(IDC_CHECK6) ? true : false; + TrackerSettings::Instance().m_SoundSettingsOpenDeviceAtStartup = IsDlgButtonChecked(IDC_CHECK7) ? true : false; + } m_Settings.ExclusiveMode = IsDlgButtonChecked(IDC_CHECK4) ? true : false; m_Settings.BoostThreadPriority = IsDlgButtonChecked(IDC_CHECK5) ? true : false; + m_Settings.KeepDeviceRunning = IsDlgButtonChecked(IDC_CHECK8) ? true : false; + m_Settings.UseHardwareTiming = IsDlgButtonChecked(IDC_CHECK9) ? true : false; // Mixing Freq { m_Settings.Samplerate = m_CbnMixingFreq.GetItemData(m_CbnMixingFreq.GetCurSel()); @@ -564,14 +531,10 @@ UINT n = m_CbnSampleFormat.GetItemData(m_CbnSampleFormat.GetCurSel()); m_Settings.sampleFormat = (SampleFormat)(n & 0xFF); } - // Polyphony + // Dither { - int nmmx = m_CbnPolyphony.GetCurSel(); - if ((nmmx >= 0) && (nmmx < CountOf(nCPUMix))) - { - TrackerSettings::Instance().MixerMaxChannels = nCPUMix[nmmx]; - CMainFrame::GetMainFrame()->SetupPlayer(); - } + UINT n = m_CbnDither.GetCurSel(); + m_Settings.DitherType = (DitherMode)(n); } const SoundDeviceID dev = m_CurrentDeviceInfo.id; // Latency @@ -638,19 +601,338 @@ } +////////////////// +// COptionsMixer + +BEGIN_MESSAGE_MAP(COptionsMixer, CPropertyPage) + ON_WM_HSCROLL() + ON_WM_VSCROLL() + ON_CBN_SELCHANGE(IDC_COMBO_FILTER, OnResamplerChanged) + ON_EN_UPDATE(IDC_WFIRCUTOFF, OnSettingsChanged) + ON_EN_UPDATE(IDC_COMBO_FILTERWINDOW, OnSettingsChanged) + ON_EN_UPDATE(IDC_RAMPING_IN, OnResamplerChanged) + ON_EN_UPDATE(IDC_RAMPING_OUT, OnResamplerChanged) + ON_CBN_SELCHANGE(IDC_COMBO_POLYPHONY, OnSettingsChanged) + // slider stereo sep + ON_COMMAND(IDC_CHECK_SOFTPAN, OnSettingsChanged) + // slider preamp +END_MESSAGE_MAP() + + +void COptionsMixer::DoDataExchange(CDataExchange* pDX) +//---------------------------------------------------- +{ + CPropertyPage::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptionsSoundcard) + DDX_Control(pDX, IDC_COMBO_FILTER, m_CbnResampling); + DDX_Control(pDX, IDC_WFIRCUTOFF, m_CEditWFIRCutoff); + DDX_Control(pDX, IDC_COMBO_FILTERWINDOW, m_CbnWFIRType); + DDX_Control(pDX, IDC_RAMPING_IN, m_CEditRampUp); + DDX_Control(pDX, IDC_RAMPING_OUT, m_CEditRampDown); + DDX_Control(pDX, IDC_EDIT_VOLRAMP_SAMPLES_UP, m_CInfoRampUp); + DDX_Control(pDX, IDC_EDIT_VOLRAMP_SAMPLES_DOWN, m_CInfoRampDown); + DDX_Control(pDX, IDC_COMBO_POLYPHONY, m_CbnPolyphony); + DDX_Control(pDX, IDC_SLIDER_STEREOSEP, m_SliderStereoSep); + // check box soft pan + DDX_Control(pDX, IDC_SLIDER_PREAMP, m_SliderPreAmp); + //}}AFX_DATA_MAP +} + + +BOOL COptionsMixer::OnInitDialog() +//-------------------------------- +{ + CPropertyPage::OnInitDialog(); + + // Resampling type + { + m_CbnResampling.AddString("No Interpolation (1 tap)"); + m_CbnResampling.AddString("Linear (2 tap)"); + m_CbnResampling.AddString("Cubic spline (4 tap)"); + m_CbnResampling.AddString("Polyphase (8 tap)"); + m_CbnResampling.AddString("XMMS-ModPlug (8 tap)"); + m_CbnResampling.SetCurSel(TrackerSettings::Instance().ResamplerMode); + } + + // Resampler bandwidth + { + m_CEditWFIRCutoff.SetWindowText(mpt::ToString(TrackerSettings::Instance().ResamplerCutoffPercent).c_str()); + } + + // Resampler filter window + { + // done in OnResamplerChanged() + } + + // volume ramping + { +#if 0 + m_CEditRampUp.SetWindowText(mpt::ToString(TrackerSettings::Instance().MixerVolumeRampUpSamples).c_str()); + m_CEditRampDown.SetWindowText(mpt::ToString(TrackerSettings::Instance().MixerVolumeRampDownSamples).c_str()); +#else + m_CEditRampUp.SetWindowText(mpt::ToString(TrackerSettings::Instance().GetMixerSettings().GetVolumeRampUpMicroseconds()).c_str()); + m_CEditRampDown.SetWindowText(mpt::ToString(TrackerSettings::Instance().GetMixerSettings().GetVolumeRampDownMicroseconds()).c_str()); +#endif + UpdateRamping(); + } + + // Max Mixing Channels + { + m_CbnPolyphony.ResetContent(); + for (UINT n = 0; n < CountOf(nCPUMix); n++) + { + CHAR s[64]; + wsprintf(s, "%d (%s)", nCPUMix[n], szCPUNames[n]); + m_CbnPolyphony.AddString(s); + if (TrackerSettings::Instance().MixerMaxChannels == nCPUMix[n]) m_CbnPolyphony.SetCurSel(n); + } + } + + // Stereo Separation + { + m_SliderStereoSep.SetRange(0, 4); + m_SliderStereoSep.SetPos(2); + for (int n=0; n<=4; n++) + { + if ((int)TrackerSettings::Instance().MixerStereoSeparation <= (int)(32 << n)) + { + m_SliderStereoSep.SetPos(n); + break; + } + } + UpdateStereoSep(); + } + + // soft pan + { + CheckDlgButton(IDC_CHECK_SOFTPAN, (TrackerSettings::Instance().MixerFlags & SNDMIX_SOFTPANNING) ? BST_CHECKED : BST_UNCHECKED); + } + + // Pre-Amplification + { + m_SliderPreAmp.SetTicFreq(5); + m_SliderPreAmp.SetRange(0, 40); + int n = (TrackerSettings::Instance().MixerPreAmp - 64) / 8; + if ((n < 0) || (n > 40)) n = 16; + m_SliderPreAmp.SetPos(n); + } + + OnResamplerChanged(); + + return TRUE; +} + + +BOOL COptionsMixer::OnSetActive() +//------------------------------- +{ + CMainFrame::m_nLastOptionsPage = OPTIONS_PAGE_MIXER; + return CPropertyPage::OnSetActive(); +} + + +void COptionsMixer::OnResamplerChanged() +//-------------------------------------- +{ + int dwSrcMode = m_CbnResampling.GetCurSel(); + switch(dwSrcMode) + { + case SRCMODE_FIRFILTER: + m_CbnWFIRType.ResetContent(); + m_CbnWFIRType.AddString("Hann"); + m_CbnWFIRType.AddString("Hamming"); + m_CbnWFIRType.AddString("Blackman Exact"); + m_CbnWFIRType.AddString("Blackman 3 Tap 61"); + m_CbnWFIRType.AddString("Blackman 3 Tap 67"); + m_CbnWFIRType.AddString("Blackman Harris"); + m_CbnWFIRType.AddString("Blackman 4 Tap 74"); + m_CbnWFIRType.AddString("Kaiser a=7.5"); + m_CbnWFIRType.SetCurSel(TrackerSettings::Instance().ResamplerSubMode); + break; + case SRCMODE_POLYPHASE: + m_CbnWFIRType.ResetContent(); + m_CbnWFIRType.AddString("Auto"); + m_CbnWFIRType.AddString("Auto"); + m_CbnWFIRType.AddString("Auto"); + m_CbnWFIRType.AddString("Auto"); + m_CbnWFIRType.AddString("Auto"); + m_CbnWFIRType.AddString("Auto"); + m_CbnWFIRType.AddString("Auto"); + m_CbnWFIRType.AddString("Auto"); + m_CbnWFIRType.SetCurSel(TrackerSettings::Instance().ResamplerSubMode); + break; + default: + m_CbnWFIRType.ResetContent(); + m_CbnWFIRType.AddString("none"); + m_CbnWFIRType.AddString("none"); + m_CbnWFIRType.AddString("none"); + m_CbnWFIRType.AddString("none"); + m_CbnWFIRType.AddString("none"); + m_CbnWFIRType.AddString("none"); + m_CbnWFIRType.AddString("none"); + m_CbnWFIRType.AddString("none"); + m_CbnWFIRType.SetCurSel(TrackerSettings::Instance().ResamplerSubMode); + break; + } + switch(dwSrcMode) + { + case SRCMODE_POLYPHASE: + m_CEditWFIRCutoff.EnableWindow(TRUE); + m_CbnWFIRType.EnableWindow(FALSE); + break; + case SRCMODE_FIRFILTER: + m_CEditWFIRCutoff.EnableWindow(TRUE); + m_CbnWFIRType.EnableWindow(TRUE); + break; + default: + m_CEditWFIRCutoff.EnableWindow(FALSE); + m_CbnWFIRType.EnableWindow(FALSE); + break; + } + OnSettingsChanged(); +} + + +void COptionsMixer::OnRampingChanged() +//------------------------------------ +{ + UpdateRamping(); + OnSettingsChanged(); +} + + +void COptionsMixer::OnScroll(UINT n, UINT pos, CScrollBar *p) +//----------------------------------------------------------- +{ + MPT_UNREFERENCED_PARAMETER(n); + MPT_UNREFERENCED_PARAMETER(pos); + MPT_UNREFERENCED_PARAMETER(p); + // stereo sep + { + UpdateStereoSep(); + } +} + + +void COptionsMixer::UpdateRamping() +//--------------------------------- +{ + MixerSettings settings = TrackerSettings::Instance().GetMixerSettings(); + CString s; + m_CEditRampUp.GetWindowText(s); + settings.SetVolumeRampUpMicroseconds(atol(s)); + m_CEditRampDown.GetWindowText(s); + settings.SetVolumeRampDownMicroseconds(atol(s)); + s.Format("%i samples at %i Hz", (int)settings.GetVolumeRampUpSamples(), (int)settings.gdwMixingFreq); + m_CInfoRampUp.SetWindowText(s); + s.Format("%i samples at %i Hz", (int)settings.GetVolumeRampDownSamples(), (int)settings.gdwMixingFreq); + m_CInfoRampDown.SetWindowText(s); +} + + +void COptionsMixer::UpdateStereoSep() +//----------------------------------- +{ + CString s; + s.Format("%d%%", ((32 << m_SliderStereoSep.GetPos()) * 100) / 128); + SetDlgItemText(IDC_TEXT_STEREOSEP, s); +} + + +void COptionsMixer::OnOK() +//------------------------ +{ + // resampler mode + { + TrackerSettings::Instance().ResamplerMode = (ResamplingMode)m_CbnResampling.GetCurSel(); + } + + // resampler bandwidth + { + CString s; + m_CEditWFIRCutoff.GetWindowText(s); + if(s != "") + { + int newCutoff = atoi(s); + Limit(newCutoff, 0, 100); + TrackerSettings::Instance().ResamplerCutoffPercent = newCutoff; + } + { + s.Format("%d", TrackerSettings::Instance().ResamplerCutoffPercent.Get()); + m_CEditWFIRCutoff.SetWindowText(s); + } + } + + // resampler filter window + { + TrackerSettings::Instance().ResamplerSubMode = (uint8)m_CbnWFIRType.GetCurSel(); + } + + // volume ramping + { +#if 0 + CString s; + m_CEditRampUp.GetWindowText(s); + TrackerSettings::Instance().MixerVolumeRampUpSamples = atol(s); + m_CEditRampDown.GetWindowText(s); + TrackerSettings::Instance().MixerVolumeRampDownSamples = atol(s); +#else + MixerSettings settings = TrackerSettings::Instance().GetMixerSettings(); + CString s; + m_CEditRampUp.GetWindowText(s); + settings.SetVolumeRampUpMicroseconds(atol(s)); + m_CEditRampDown.GetWindowText(s); + settings.SetVolumeRampDownMicroseconds(atol(s)); + TrackerSettings::Instance().SetMixerSettings(settings); +#endif + } + + // Polyphony + { + int nmmx = m_CbnPolyphony.GetCurSel(); + if((nmmx >= 0) && (nmmx < CountOf(nCPUMix))) + { + TrackerSettings::Instance().MixerMaxChannels = nCPUMix[nmmx]; + } + } + + // stereo sep + { + TrackerSettings::Instance().MixerStereoSeparation = 32 << m_SliderStereoSep.GetPos(); + } + + // soft pan + { + if(IsDlgButtonChecked(IDC_CHECK2)) + { + TrackerSettings::Instance().MixerFlags = TrackerSettings::Instance().MixerFlags | SNDMIX_SOFTPANNING; + } else + { + TrackerSettings::Instance().MixerFlags = TrackerSettings::Instance().MixerFlags & ~SNDMIX_SOFTPANNING; + } + } + + // pre amp + { + int n = m_SliderPreAmp.GetPos(); + if ((n >= 0) && (n <= 40)) // approximately +/- 10dB + { + TrackerSettings::Instance().MixerPreAmp = 64 + (n * 8); + } + } + + CMainFrame::GetMainFrame()->SetupPlayer(); + + CPropertyPage::OnOK(); +} + + ////////////////////////////////////////////////////////// // COptionsPlayer BEGIN_MESSAGE_MAP(COptionsPlayer, CPropertyPage) ON_WM_HSCROLL() - ON_CBN_SELCHANGE(IDC_COMBO1, OnResamplerChanged) ON_CBN_SELCHANGE(IDC_COMBO2, OnSettingsChanged) - //rewbs.resamplerConf - ON_CBN_SELCHANGE(IDC_WFIRTYPE, OnWFIRTypeChanged) - ON_EN_UPDATE(IDC_WFIRCUTOFF, OnSettingsChanged) - ON_EN_UPDATE(IDC_RAMPING_IN, OnSettingsChanged) - ON_EN_UPDATE(IDC_RAMPING_OUT, OnSettingsChanged) - //end rewbs.resamplerConf ON_COMMAND(IDC_CHECK1, OnSettingsChanged) ON_COMMAND(IDC_CHECK2, OnSettingsChanged) ON_COMMAND(IDC_CHECK3, OnSettingsChanged) @@ -658,7 +940,6 @@ ON_COMMAND(IDC_CHECK5, OnSettingsChanged) ON_COMMAND(IDC_CHECK6, OnSettingsChanged) ON_COMMAND(IDC_CHECK7, OnSettingsChanged) - ON_COMMAND(IDC_BUTTON_DEFAULT_RESAMPLING, OnDefaultResampling) END_MESSAGE_MAP() @@ -667,13 +948,6 @@ { CPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(COptionsPlayer) - DDX_Control(pDX, IDC_COMBO1, m_CbnResampling); - //rewbs.resamplerConf - DDX_Control(pDX, IDC_WFIRTYPE, m_CbnWFIRType); - DDX_Control(pDX, IDC_WFIRCUTOFF, m_CEditWFIRCutoff); - DDX_Control(pDX, IDC_RAMPING_IN, m_CEditRampUp); - DDX_Control(pDX, IDC_RAMPING_OUT, m_CEditRampDown); - //end rewbs.resamplerConf DDX_Control(pDX, IDC_COMBO2, m_CbnReverbPreset); DDX_Control(pDX, IDC_SLIDER1, m_SbXBassDepth); DDX_Control(pDX, IDC_SLIDER2, m_SbXBassRange); @@ -691,17 +965,6 @@ CPropertyPage::OnInitDialog(); dwQuality = TrackerSettings::Instance().MixerDSPMask; - // Resampling type - { - m_CbnResampling.AddString("No Interpolation"); - m_CbnResampling.AddString("Linear"); - m_CbnResampling.AddString("Cubic spline"); - //rewbs.resamplerConf - m_CbnResampling.AddString("Polyphase"); - m_CbnResampling.AddString("XMMS-ModPlug"); - //end rewbs.resamplerConf - m_CbnResampling.SetCurSel(TrackerSettings::Instance().ResamplerMode); - } // Effects #ifndef NO_DSP if (dwQuality & SNDDSP_MEGABASS) CheckDlgButton(IDC_CHECK1, MF_CHECKED); @@ -784,17 +1047,6 @@ m_SbSurroundDepth.ShowWindow(SW_HIDE); m_SbSurroundDelay.ShowWindow(SW_HIDE); #endif - //rewbs.resamplerConf - OnResamplerChanged(); - - char s[16] = ""; - _ltoa(TrackerSettings::Instance().MixerVolumeRampUpSamples, s, 10); - m_CEditRampUp.SetWindowText(s); - - _ltoa(TrackerSettings::Instance().MixerVolumeRampDownSamples, s, 10); - m_CEditRampDown.SetWindowText(s); - - //end rewbs.resamplerConf return TRUE; } @@ -825,91 +1077,36 @@ } } -//rewbs.resamplerConf -void COptionsPlayer::OnWFIRTypeChanged() -{ - TrackerSettings::Instance().ResamplerSubMode = static_cast<BYTE>(m_CbnWFIRType.GetCurSel()); - OnSettingsChanged(); -} -void COptionsPlayer::OnResamplerChanged() -{ - DWORD dwSrcMode = m_CbnResampling.GetCurSel(); - m_CbnWFIRType.ResetContent(); - - char s[10] = ""; - switch (dwSrcMode) - { - case SRCMODE_POLYPHASE: - m_CbnWFIRType.AddString("Kaiser 8 Tap"); - m_CbnWFIRType.SetCurSel(0); - m_CbnWFIRType.EnableWindow(FALSE); - m_CEditWFIRCutoff.EnableWindow(TRUE); - wsprintf(s, "%d", static_cast<int>((TrackerSettings::Instance().ResamplerCutoffPercent))); - break; - case SRCMODE_FIRFILTER: - m_CbnWFIRType.AddString("Hann"); - m_CbnWFIRType.AddString("Hamming"); - m_CbnWFIRType.AddString("Blackman Exact"); - m_CbnWFIRType.AddString("Blackman 3 Tap 61"); - m_CbnWFIRType.AddString("Blackman 3 Tap 67"); - m_CbnWFIRType.AddString("Blackman 4 Tap 92"); - m_CbnWFIRType.AddString("Blackman 4 Tap 74"); - m_CbnWFIRType.AddString("Kaiser 4 Tap"); - m_CbnWFIRType.SetCurSel(TrackerSettings::Instance().ResamplerSubMode); - m_CbnWFIRType.EnableWindow(TRUE); - m_CEditWFIRCutoff.EnableWindow(TRUE); - wsprintf(s, "%d", static_cast<int>((TrackerSettings::Instance().ResamplerCutoffPercent))); - break; - default: - m_CbnWFIRType.AddString("None"); - m_CEditWFIRCutoff.EnableWindow(FALSE); - m_CbnWFIRType.EnableWindow(FALSE); - } - - m_CEditWFIRCutoff.SetWindowText(s); - OnSettingsChanged(); -} - - -void COptionsPlayer::OnDefaultResampling() -//---------------------------------------- -{ - CResamplerSettings resamplerDefaults; - m_CbnResampling.SetCurSel(resamplerDefaults.SrcMode); - OnResamplerChanged(); - m_CbnWFIRType.SetCurSel(resamplerDefaults.gbWFIRType); - m_CEditWFIRCutoff.SetWindowText(Stringify(static_cast<int>(resamplerDefaults.gdWFIRCutoff * 100)).c_str()); - MixerSettings mixerDefaults; - m_CEditRampUp.SetWindowText(Stringify(mixerDefaults.glVolumeRampUpSamples).c_str()); - m_CEditRampDown.SetWindowText(Stringify(mixerDefaults.glVolumeRampDownSamples).c_str()); - OnSettingsChanged(); -} - - void COptionsPlayer::OnOK() //------------------------- { DWORD dwQuality = 0; - DWORD dwSrcMode = 0; + DWORD dwQualityMask = 0; + #ifndef NO_DSP + dwQualityMask |= SNDDSP_MEGABASS; if (IsDlgButtonChecked(IDC_CHECK1)) dwQuality |= SNDDSP_MEGABASS; #endif #ifndef NO_AGC + dwQualityMask |= SNDDSP_AGC; if (IsDlgButtonChecked(IDC_CHECK2)) dwQuality |= SNDDSP_AGC; #endif #ifndef NO_EQ + dwQualityMask |= SNDDSP_EQ; if (IsDlgButtonChecked(IDC_CHECK3)) dwQuality |= SNDDSP_EQ; #endif #ifndef NO_DSP + dwQualityMask |= SNDDSP_SURROUND; + dwQualityMask |= SNDDSP_NOISEREDUCTION; if (IsDlgButtonChecked(IDC_CHECK4)) dwQuality |= SNDDSP_SURROUND; if (IsDlgButtonChecked(IDC_CHECK5)) dwQuality |= SNDDSP_NOISEREDUCTION; #endif #ifndef NO_REVERB + dwQualityMask |= SNDDSP_REVERB; if (IsDlgButtonChecked(IDC_CHECK6)) dwQuality |= SNDDSP_REVERB; #endif - dwSrcMode = m_CbnResampling.GetCurSel(); #ifndef NO_DSP // Bass Expansion @@ -922,7 +1119,6 @@ if (nXBassRange > 21) nXBassRange = 21; TrackerSettings::Instance().m_DSPSettings.m_nXBassDepth = nXBassDepth; TrackerSettings::Instance().m_DSPSettings.m_nXBassRange = nXBassRange; - CMainFrame::GetMainFrame()->SetupPlayer(); } #endif #ifndef NO_REVERB @@ -931,7 +1127,6 @@ // Reverb depth is dynamically changed UINT nReverbType = m_CbnReverbPreset.GetItemData(m_CbnReverbPreset.GetCurSel()); if (nReverbType < NUM_REVERBTYPES) TrackerSettings::Instance().m_ReverbSettings.m_nReverbType = nReverbType; - CMainFrame::GetMainFrame()->SetupPlayer(); } #endif #ifndef NO_DSP @@ -941,31 +1136,11 @@ UINT nProLogicDelay = 5 + (m_SbSurroundDelay.GetPos() * 5); TrackerSettings::Instance().m_DSPSettings.m_nProLogicDepth = nProLogicDepth; TrackerSettings::Instance().m_DSPSettings.m_nProLogicDelay = nProLogicDelay; - CMainFrame::GetMainFrame()->SetupPlayer(); } #endif - //rewbs.resamplerConf - CString s; - m_CEditWFIRCutoff.GetWindowText(s); - if(s != "") - { - int newCutoff = atoi(s); - Limit(newCutoff, 0, 100); - TrackerSettings::Instance().ResamplerCutoffPercent = newCutoff; - } - { - CHAR s[64]; - wsprintf(s, "%d", TrackerSettings::Instance().ResamplerCutoffPercent.Get()); - m_CEditWFIRCutoff.SetWindowText(s); - } - //TrackerSettings::Instance().m_ResamplerSettings.gbWFIRType set in OnWFIRTypeChange - m_CEditRampUp.GetWindowText(s); - TrackerSettings::Instance().MixerVolumeRampUpSamples = atol(s); - m_CEditRampDown.GetWindowText(s); - TrackerSettings::Instance().MixerVolumeRampDownSamples = atol(s); - TrackerSettings::Instance().ResamplerMode = (ResamplingMode)dwSrcMode; TrackerSettings::Instance().MixerDSPMask = dwQuality; + CMainFrame::GetMainFrame()->SetupPlayer(); CPropertyPage::OnOK(); } Modified: trunk/OpenMPT/mptrack/Mpdlgs.h =================================================================== --- trunk/OpenMPT/mptrack/Mpdlgs.h 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/mptrack/Mpdlgs.h 2014-02-01 21:26:00 UTC (rev 3623) @@ -19,12 +19,10 @@ { protected: CComboBoxEx m_CbnDevice; - CComboBox m_CbnLatencyMS, m_CbnUpdateIntervalMS, m_CbnMixingFreq, m_CbnPolyphony, m_CbnChannels, m_CbnSampleFormat; - CSliderCtrl m_SliderStereoSep, m_SliderPreAmp; + CComboBox m_CbnLatencyMS, m_CbnUpdateIntervalMS, m_CbnMixingFreq, m_CbnChannels, m_CbnSampleFormat, m_CbnDither; CComboBox m_CbnBaseChannel; CEdit m_EditStatistics; CButton m_BtnDriverPanel; - bool m_PreAmpNoteShowed; void SetDevice(SoundDeviceID dev, bool forceReload=false); SoundDeviceInfo m_CurrentDeviceInfo; @@ -44,8 +42,8 @@ void UpdateSampleRates(); void UpdateChannels(); void UpdateSampleFormat(); + void UpdateDither(); void UpdateControls(); - void SetPreAmpSliderPosition(); protected: virtual BOOL OnInitDialog(); @@ -55,25 +53,70 @@ void UpdateStereoSep(); afx_msg void OnDeviceChanged(); afx_msg void OnSettingsChanged() { SetModified(TRUE); } - afx_msg void OnHScroll(UINT, UINT, CScrollBar *); - afx_msg void OnVScroll(UINT, UINT, CScrollBar *); + afx_msg void OnSampleFormatChanged(); afx_msg void OnSoundCardRescan(); afx_msg void OnSoundCardDriverPanel(); DECLARE_MESSAGE_MAP() }; +//======================================= +class COptionsMixer: public CPropertyPage +//======================================= +{ +protected: + + CComboBox m_CbnResampling; + CEdit m_CEditWFIRCutoff; + CComboBox m_CbnWFIRType; + + CEdit m_CEditRampUp; + CEdit m_CEditRampDown; + CEdit m_CInfoRampUp; + CEdit m_CInfoRampDown; + + CComboBox m_CbnPolyphony; + + CSliderCtrl m_SliderStereoSep; + + // check box soft pan + + CSliderCtrl m_SliderPreAmp; + +public: + COptionsMixer():CPropertyPage(IDD_OPTIONS_MIXER) {} + +protected: + void UpdateRamping(); + void UpdateStereoSep(); + + virtual BOOL OnInitDialog(); + virtual void OnOK(); + virtual BOOL OnSetActive(); + virtual void DoDataExchange(CDataExchange* pDX); + + afx_msg void OnSettingsChanged() { SetModified(TRUE); } + afx_msg void OnResamplerChanged(); + afx_msg void OnRampingChanged(); + + afx_msg void OnHScroll(UINT n, UINT pos, CScrollBar *p) { CPropertyPage::OnHScroll(n, pos, p); OnScroll(n, pos, p); } + afx_msg void OnVScroll(UINT n, UINT pos, CScrollBar *p) { CPropertyPage::OnVScroll(n, pos, p); OnScroll(n, pos, p); } + void OnScroll(UINT n, UINT pos, CScrollBar *p); + + DECLARE_MESSAGE_MAP() + +}; + + //======================================== class COptionsPlayer: public CPropertyPage //======================================== { protected: - CComboBox m_CbnResampling, m_CbnReverbPreset, m_CbnWFIRType; //rewbs.resamplerConf: added m_CbnWFIRType + CComboBox m_CbnReverbPreset; CSliderCtrl m_SbXBassDepth, m_SbXBassRange; CSliderCtrl m_SbSurroundDepth, m_SbSurroundDelay; CSliderCtrl m_SbReverbDepth; - CEdit m_CEditWFIRCutoff; - CEdit m_CEditRampUp, m_CEditRampDown; public: COptionsPlayer():CPropertyPage(IDD_OPTIONS_PLAYER) {} @@ -85,11 +128,6 @@ virtual void DoDataExchange(CDataExchange* pDX); afx_msg void OnHScroll(UINT, UINT, CScrollBar *); afx_msg void OnSettingsChanged() { SetModified(TRUE); } - //rewbs.resamplerConf - afx_msg void OnWFIRTypeChanged(); - afx_msg void OnResamplerChanged(); - afx_msg void OnDefaultResampling(); - //end rewbs.resamplerConf DECLARE_MESSAGE_MAP() }; Modified: trunk/OpenMPT/mptrack/TrackerSettings.cpp =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-02-01 21:26:00 UTC (rev 3623) @@ -165,9 +165,8 @@ , MixerOutputChannels(conf, "Sound Settings", "ChannelMode", MixerSettings().gnChannels) , MixerPreAmp(conf, "Sound Settings", "PreAmp", MixerSettings().m_nPreAmp) , MixerStereoSeparation(conf, "Sound Settings", "StereoSeparation", MixerSettings().m_nStereoSeparation) - , MixerVolumeRampUpSamples(conf, "Sound Settings", "VolumeRampUpSamples", MixerSettings().glVolumeRampUpSamples) - , MixerVolumeRampDownSamples(conf, "Sound Settings", "VolumeRampDownSamples", MixerSettings().glVolumeRampDownSamples) - , MixerVolumeRampSamples_DEPRECATED(conf, "Sound Settings", "VolumeRampSamples", 42) + , MixerVolumeRampUpMicroseconds(conf, "Sound Settings", "VolumeRampUpMicroseconds", MixerSettings().GetVolumeRampUpMicroseconds()) + , MixerVolumeRampDownMicroseconds(conf, "Sound Settings", "VolumeRampDownMicroseconds", MixerSettings().GetVolumeRampDownMicroseconds()) , ResamplerMode(conf, "Sound Settings", "SrcMode", GetDefaultResamplerMode()) , ResamplerSubMode(conf, "Sound Settings", "XMMSModplugResamplerWFIRType", CResamplerSettings().gbWFIRType) , ResamplerCutoffPercent(conf, "Sound Settings", "ResamplerWFIRCutoff", Util::Round<int32>(CResamplerSettings().gdWFIRCutoff * 100.0)) @@ -430,9 +429,17 @@ } if(storedVersion < MAKE_VERSION_NUMERIC(1,20,00,22)) { - MixerVolumeRampUpSamples = MixerVolumeRampSamples_DEPRECATED.Get(); - MixerVolumeRampDownSamples = MixerVolumeRampSamples_DEPRECATED.Get(); - conf.Remove(MixerVolumeRampSamples_DEPRECATED.GetPath()); + MixerSettings settings = GetMixerSettings(); + settings.SetVolumeRampUpSamples(conf.Read<int32>("Sound Settings", "VolumeRampSamples", 42)); + settings.SetVolumeRampDownSamples(conf.Read<int32>("Sound Settings", "VolumeRampSamples", 42)); + SetMixerSettings(settings); + conf.Remove("Sound Settings", "VolumeRampSamples"); + } else if(storedVersion < MAKE_VERSION_NUMERIC(1,22,07,18)) + { + MixerSettings settings = GetMixerSettings(); + settings.SetVolumeRampUpSamples(conf.Read<int32>("Sound Settings", "VolumeRampUpSamples", MixerSettings().GetVolumeRampUpSamples())); + settings.SetVolumeRampDownSamples(conf.Read<int32>("Sound Settings", "VolumeRampDownSamples", MixerSettings().GetVolumeRampDownSamples())); + SetMixerSettings(settings); } Limit(ResamplerCutoffPercent, 0, 100); @@ -524,6 +531,7 @@ Setting<SampleFormat> sampleFormat; Setting<bool> ExclusiveMode; Setting<bool> BoostThreadPriority; + Setting<bool> KeepDeviceRunning; Setting<bool> UseHardwareTiming; Setting<int> DitherType; Setting<SoundChannelMapping> ChannelMapping; @@ -540,6 +548,7 @@ , sampleFormat(conf, L"Sound Settings", deviceInfo.GetIdentifier() + L"_" + L"SampleFormat", defaults.sampleFormat) , ExclusiveMode(conf, L"Sound Settings", deviceInfo.GetIdentifier() + L"_" + L"ExclusiveMode", defaults.ExclusiveMode) , BoostThreadPriority(conf, L"Sound Settings", deviceInfo.GetIdentifier() + L"_" + L"BoostThreadPriority", defaults.BoostThreadPriority) + , KeepDeviceRunning(conf, L"Sound Settings", deviceInfo.GetIdentifier() + L"_" + L"KeepDeviceRunning", defaults.KeepDeviceRunning) , UseHardwareTiming(conf, L"Sound Settings", deviceInfo.GetIdentifier() + L"_" + L"UseHardwareTiming", defaults.UseHardwareTiming) , DitherType(conf, L"Sound Settings", deviceInfo.GetIdentifier() + L"_" + L"DitherType", defaults.DitherType) , ChannelMapping(conf, L"Sound Settings", deviceInfo.GetIdentifier() + L"_" + L"ChannelMapping", defaults.ChannelMapping) @@ -560,6 +569,7 @@ sampleFormat = settings.sampleFormat; ExclusiveMode = settings.ExclusiveMode; BoostThreadPriority = settings.BoostThreadPriority; + KeepDeviceRunning = settings.KeepDeviceRunning; UseHardwareTiming = settings.UseHardwareTiming; DitherType = settings.DitherType; ChannelMapping = settings.ChannelMapping; @@ -576,6 +586,7 @@ settings.sampleFormat = sampleFormat; settings.ExclusiveMode = ExclusiveMode; settings.BoostThreadPriority = BoostThreadPriority; + settings.KeepDeviceRunning = KeepDeviceRunning; settings.UseHardwareTiming = UseHardwareTiming; settings.DitherType = DitherType; settings.ChannelMapping = ChannelMapping; @@ -638,8 +649,8 @@ settings.gnChannels = MixerOutputChannels; settings.m_nPreAmp = MixerPreAmp; settings.m_nStereoSeparation = MixerStereoSeparation; - settings.glVolumeRampUpSamples = MixerVolumeRampUpSamples; - settings.glVolumeRampDownSamples = MixerVolumeRampDownSamples; + settings.VolumeRampUpMicroseconds = MixerVolumeRampUpMicroseconds; + settings.VolumeRampDownMicroseconds = MixerVolumeRampDownMicroseconds; return settings; } @@ -653,8 +664,8 @@ MixerOutputChannels = settings.gnChannels; MixerPreAmp = settings.m_nPreAmp; MixerStereoSeparation = settings.m_nStereoSeparation; - MixerVolumeRampUpSamples = settings.glVolumeRampUpSamples; - MixerVolumeRampDownSamples = settings.glVolumeRampDownSamples; + MixerVolumeRampUpMicroseconds = settings.VolumeRampUpMicroseconds; + MixerVolumeRampDownMicroseconds = settings.VolumeRampDownMicroseconds; } Modified: trunk/OpenMPT/mptrack/TrackerSettings.h =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.h 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/mptrack/TrackerSettings.h 2014-02-01 21:26:00 UTC (rev 3623) @@ -295,9 +295,8 @@ Setting<uint32> MixerOutputChannels; Setting<uint32> MixerPreAmp; Setting<uint32> MixerStereoSeparation; - Setting<uint32> MixerVolumeRampUpSamples; - Setting<uint32> MixerVolumeRampDownSamples; - Setting<uint32> MixerVolumeRampSamples_DEPRECATED; + Setting<uint32> MixerVolumeRampUpMicroseconds; + Setting<uint32> MixerVolumeRampDownMicroseconds; MixerSettings GetMixerSettings() const; void SetMixerSettings(const MixerSettings &settings); Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/mptrack/mptrack.rc 2014-02-01 21:26:00 UTC (rev 3623) @@ -429,7 +429,7 @@ IDD_OPTIONS_PLAYER DIALOGEX 0, 0, 272, 279 STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Player" +CAPTION "DSP" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN GROUPBOX "Control",IDC_STATIC,6,6,257,150 @@ -458,21 +458,6 @@ CONTROL "Slider2",IDC_SLIDER6,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,149,128,62,15 LTEXT "5ms",IDC_STATIC,131,131,18,8 LTEXT "50ms",IDC_STATIC,211,131,23,8 - GROUPBOX "Sound Quality",IDC_STATIC,6,162,256,114 - LTEXT "Resampling:",IDC_STATIC,18,182,42,8 - COMBOBOX IDC_COMBO1,66,180,114,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "WFIR type:",IDC_STATIC,18,200,42,8 - COMBOBOX IDC_WFIRTYPE,66,198,114,64,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "WFIR cutoff factor:",IDC_STATIC,18,219,63,8 - EDITTEXT IDC_WFIRCUTOFF,156,216,24,14,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "%",IDC_STATIC,186,219,8,8 - LTEXT "Sample ramping (click avoidance):",IDC_STATIC,18,238,109,8 - LTEXT "(can be overridden by instrument setting)",IDC_STATIC,18,248,138,8 - EDITTEXT IDC_RAMPING_IN,156,235,24,14,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "Samples (Ramp In)",IDC_STATIC,182,238,70,8 - EDITTEXT IDC_RAMPING_OUT,156,252,24,14,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "Samples (Ramp Out)",IDC_STATIC,182,255,70,8 - PUSHBUTTON "Default Settings",IDC_BUTTON_DEFAULT_RESAMPLING,186,180,66,12 END IDD_WAVECONVERT DIALOGEX 0, 0, 388, 239 @@ -1300,41 +1285,36 @@ LTEXT "Description",IDC_TEXT1,144,126,111,138 END -IDD_OPTIONS_SOUNDCARD DIALOGEX 0, 0, 268, 263 +IDD_OPTIONS_SOUNDCARD DIALOGEX 0, 0, 274, 281 STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Sound Card" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - GROUPBOX "",IDC_STATIC,6,6,258,114 - LTEXT "Sound Device:",IDC_STATIC,12,18,47,8 - CONTROL "",IDC_COMBO1,"ComboBoxEx32",CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP,12,30,204,96 - PUSHBUTTON "Rescan",IDC_BUTTON1,222,30,36,12 - LTEXT "Latency:",IDC_STATIC,12,48,54,12,SS_CENTERIMAGE - COMBOBOX IDC_COMBO2,72,48,66,83,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - CONTROL "Use device exclusively",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,144,48,102,12 - LTEXT "Update Interval:",IDC_STATIC_UPDATEINTERVAL,12,66,54,12,SS_CENTERIMAGE - COMBOBOX IDC_COMBO_UPDATEINTERVAL,72,66,66,83,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - CONTROL "Boost thread priority",IDC_CHECK5,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,144,66,89,12 - LTEXT "Output format:",IDC_STATIC,12,84,54,12,SS_CENTERIMAGE - COMBOBOX IDC_COMBO3,72,84,66,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBO5,144,84,42,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBO6,192,84,66,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Base channel:",IDC_STATIC_BASECHANNEL,12,102,54,12,SS_CENTERIMAGE - COMBOBOX IDC_COMBO9,72,102,114,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Driver Panel",IDC_BUTTON2,192,102,66,12 - GROUPBOX "",IDC_STATIC,6,126,258,90 - LTEXT "Max. Polyphony:",IDC_STATIC,12,138,54,12,SS_CENTERIMAGE - COMBOBOX IDC_COMBO4,72,138,66,88,CBS_DROPDOWNLIST | WS_TABSTOP - CONTROL "Soft Panning",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,138,78,12 - LTEXT "Stereo Separation:",IDC_STATIC,12,157,62,8 - LTEXT "100%",IDC_TEXT1,80,157,20,8 - RTEXT "Low",IDC_STATIC,22,168,15,14,SS_CENTERIMAGE - CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,46,168,83,18 - LTEXT "High",IDC_STATIC,136,168,16,12,SS_CENTERIMAGE - CTEXT "Pre-Amp",IDC_STATIC,174,156,36,8 - CONTROL "Slider2",IDC_SLIDER_PREAMP,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOOLTIPS | WS_TABSTOP,174,168,74,24 - LTEXT "Note: The Pre-Amp and Soft Panning settings are ignored by songs with mix levels set to 1.17RC3 or later in the Song Properties.",IDC_STATIC,12,195,246,18 - EDITTEXT IDC_EDIT_STATISTICS,6,222,258,36,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP + GROUPBOX "&Device",IDC_STATIC,6,6,264,120 + CONTROL "",IDC_COMBO1,"ComboBoxEx32",CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP,12,18,252,96 + PUSHBUTTON "&Setup device ...",IDC_BUTTON2,48,36,72,12 + PUSHBUTTON "&Rescan device list",IDC_BUTTON1,198,36,66,12 + LTEXT "&Latency:",IDC_STATIC,12,54,30,12,SS_CENTERIMAGE + COMBOBOX IDC_COMBO2,48,54,54,83,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "&Period:",IDC_STATIC_UPDATEINTERVAL,12,72,30,12,SS_CENTERIMAGE + COMBOBOX IDC_COMBO_UPDATEINTERVAL,48,72,54,83,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "&Format:",IDC_STATIC,12,90,30,12,SS_CENTERIMAGE + COMBOBOX IDC_COMBO3,48,90,54,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO5,108,90,42,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO6,156,90,36,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Use device exclusively",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,108,54,84,12 + CONTROL "Keep running",IDC_CHECK8,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,198,54,66,12 + CONTROL "&Boost thread priority",IDC_CHECK5,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,108,72,84,12 + CONTROL "Hardware timing",IDC_CHECK9,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,198,72,66,12 + LTEXT "Base &channel:",IDC_STATIC_BASECHANNEL,12,108,48,12,SS_CENTERIMAGE + COMBOBOX IDC_COMBO9,66,108,198,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "General",IDC_STATIC,6,132,264,48 + CONTROL "Keep device &open when playback is stopped",IDC_CHECK6, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,144,162,12 + CONTROL "Open device at &startup",IDC_CHECK7,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,162,162,12 + GROUPBOX "Stat&istics",IDC_STATIC,6,186,264,60 + EDITTEXT IDC_EDIT_STATISTICS,12,197,252,42,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP + COMBOBOX IDC_COMBO10,198,90,66,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_MIDIMACRO DIALOGEX 0, 0, 358, 354 @@ -1614,7 +1594,41 @@ CONTROL "Resize to",IDC_RADIO_RESIZETO,"Button",BS_AUTORADIOBUTTON,12,60,102,8 END +IDD_OPTIONS_MIXER DIALOGEX 0, 0, 274, 281 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Mixer" +FONT 8, "MS Shell Dlg", 400, 0, 0x0 +BEGIN + GROUPBOX "Resampling",IDC_STATIC,6,6,264,66 + LTEXT "Filter:",IDC_STATIC,12,18,24,12,SS_CENTERIMAGE + COMBOBOX IDC_COMBO_FILTER,54,18,90,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Bandwidth:",IDC_STATIC,12,36,42,12,SS_CENTERIMAGE + EDITTEXT IDC_WFIRCUTOFF,54,36,18,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER + LTEXT "%",IDC_STATIC,78,36,8,12,SS_CENTERIMAGE + LTEXT "Window:",IDC_STATIC,12,54,30,12,SS_CENTERIMAGE + COMBOBOX IDC_COMBO_FILTERWINDOW,54,54,84,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Volume Ramping",IDC_STATIC,6,78,264,48 + LTEXT "\xB5s up",IDC_STATIC,42,90,22,12,SS_CENTERIMAGE + EDITTEXT IDC_RAMPING_IN,12,90,24,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER + EDITTEXT IDC_EDIT_VOLRAMP_SAMPLES_UP,78,90,90,12,ES_AUTOHSCROLL | ES_READONLY + LTEXT "\xB5s down",IDC_STATIC,42,110,28,11,SS_CENTERIMAGE + EDITTEXT IDC_RAMPING_OUT,12,108,24,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER + EDITTEXT IDC_EDIT_VOLRAMP_SAMPLES_DOWN,78,108,90,12,ES_AUTOHSCROLL | ES_READONLY + GROUPBOX "Polyphony",IDC_STATIC,6,132,264,30 + LTEXT "Maximum Mixed Channels:",IDC_STATIC,12,144,84,12,SS_CENTERIMAGE + COMBOBOX IDC_COMBO_POLYPHONY,102,144,66,88,CBS_DROPDOWNLIST | WS_TABSTOP + GROUPBOX "Behaviour",IDC_STATIC,6,168,264,30 + LTEXT "Stereo Separation:",IDC_STATIC,12,180,62,8 + CONTROL "",IDC_SLIDER_STEREOSEP,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,78,180,54,12 + LTEXT "100%",IDC_TEXT_STEREOSEP,132,180,20,8 + GROUPBOX "Pre-1.17RC3 mixing levels",IDC_STATIC,6,204,264,60 + CONTROL "Soft Panning",IDC_CHECK_SOFTPAN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,222,60,12 + LTEXT "Pre-Amp",IDC_STATIC,78,222,30,12,SS_CENTERIMAGE + CONTROL "",IDC_SLIDER_PREAMP,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_TOOLTIPS | WS_TABSTOP,108,216,96,24 + LTEXT "Note: Pre-Amp and Soft Panning settings are ignored by songs with mix levels set to 1.17RC3 or later in Song Properties.",IDC_STATIC,12,240,204,18 +END + ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO @@ -1780,8 +1794,8 @@ IDD_OPTIONS_SOUNDCARD, DIALOG BEGIN - RIGHTMARGIN, 246 - BOTTOMMARGIN, 160 + RIGHTMARGIN, 252 + BOTTOMMARGIN, 178 END IDD_MIDIMACRO, DIALOG @@ -1869,6 +1883,14 @@ TOPMARGIN, 7 BOTTOMMARGIN, 75 END + + IDD_OPTIONS_MIXER, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 267 + TOPMARGIN, 7 + BOTTOMMARGIN, 274 + END END #endif // APSTUDIO_INVOKED Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/mptrack/resource.h 2014-02-01 21:26:00 UTC (rev 3623) @@ -8,6 +8,7 @@ #define IDD_DIRECTORIES 104 #define IDD_WAVECONVERT 105 #define IDD_PROGRESS 106 +#define IDD_OPTIONS_MIXER 107 #define IDD_OPTIONS_KEYBOARD 108 #define IDD_OPTIONS_COLORS 109 #define IDD_OPTIONS_MIDI 111 @@ -200,6 +201,7 @@ #define IDC_COMBO5 1205 #define IDC_COMBO6 1206 #define IDC_COMBO9 1207 +#define IDC_COMBO10 1208 #define IDC_NOTEMAP 1213 #define IDC_TEXT1 1301 #define IDC_TEXT2 1302 @@ -935,6 +937,15 @@ #define IDC_STATIC_UPDATEINTERVAL 2458 #define IDC_COMBO_UPDATEINTERVAL 2459 #define IDC_STATIC_BASECHANNEL 2461 +#define IDC_COMBO_FILTER 2462 +#define IDC_COMBO_POLYPHONY 2463 +#define IDC_SLIDER_STEREOSEP 2464 +#define IDC_CHECK_SOFTPAN 2465 +#define IDC_COMBO_FILTERWINDOW 2466 +#define IDC_TEXT_STEREOSEP 2467 +#define IDC_EDIT_VOLRAMP_SAMPLES_UP 2468 +#define IDC_EDIT_VOLRAMP_SAMPLES_DOWN 2469 +#define IDC_CHECK_KEEPDEVICEOPEN 2470 #define ID_FILE_NEWMOD 32771 #define ID_FILE_NEWXM 32772 #define ID_FILE_NEWS3M 32773 @@ -1216,7 +1227,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 541 #define _APS_NEXT_COMMAND_VALUE 44643 -#define _APS_NEXT_CONTROL_VALUE 2462 +#define _APS_NEXT_CONTROL_VALUE 2471 #define _APS_NEXT_SYMED_VALUE 901 #endif #endif Modified: trunk/OpenMPT/sounddev/SoundDevice.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDevice.h 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/sounddev/SoundDevice.h 2014-02-01 21:26:00 UTC (rev 3623) @@ -251,6 +251,7 @@ SampleFormat sampleFormat; bool ExclusiveMode; // Use hardware buffers directly bool BoostThreadPriority; // Boost thread priority for glitch-free audio rendering + bool KeepDeviceRunning; bool UseHardwareTiming; int DitherType; SoundChannelMapping ChannelMapping; @@ -263,6 +264,7 @@ , sampleFormat(SampleFormatFloat32) , ExclusiveMode(false) , BoostThreadPriority(true) + , KeepDeviceRunning(true) , UseHardwareTiming(false) , DitherType(1) { @@ -279,6 +281,7 @@ && sampleFormat == cmp.sampleFormat && ExclusiveMode == cmp.ExclusiveMode && BoostThreadPriority == cmp.BoostThreadPriority + && KeepDeviceRunning == cmp.KeepDeviceRunning && UseHardwareTiming == cmp.UseHardwareTiming && ChannelMapping == cmp.ChannelMapping && DitherType == cmp.DitherType @@ -308,6 +311,7 @@ bool CanSampleFormat; bool CanExclusiveMode; bool CanBoostThreadPriority; + bool CanKeepDeviceRunning; bool CanUseHardwareTiming; bool CanChannelMapping; bool CanDriverPanel; @@ -319,6 +323,7 @@ , CanSampleFormat(true) , CanExclusiveMode(false) , CanBoostThreadPriority(true) + , CanKeepDeviceRunning(false) , CanUseHardwareTiming(false) , CanChannelMapping(false) , CanDriverPanel(false) Modified: trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp 2014-02-01 21:26:00 UTC (rev 3623) @@ -500,7 +500,7 @@ { ALWAYS_ASSERT_WARN_MESSAGE(!CriticalSection::IsLocked(), "AudioCriticalSection locked while starting ASIO"); - if(m_Settings.ExclusiveMode) + if(m_Settings.KeepDeviceRunning) { if(m_DeviceRunning) { @@ -529,7 +529,7 @@ { ALWAYS_ASSERT_WARN_MESSAGE(!CriticalSection::IsLocked(), "AudioCriticalSection locked while stopping ASIO"); - if(m_Settings.ExclusiveMode) + if(m_Settings.KeepDeviceRunning) { SetRenderSilence(true, true); return; @@ -1192,12 +1192,12 @@ caps.CanUpdateInterval = false; caps.CanSampleFormat = false; - caps.CanExclusiveMode = true; + caps.CanExclusiveMode = false; caps.CanBoostThreadPriority = false; + caps.CanKeepDeviceRunning = true; caps.CanUseHardwareTiming = true; caps.CanChannelMapping = true; caps.CanDriverPanel = true; - caps.ExclusiveModeDescription = L"Keep device running"; TemporaryASIODriverOpener opener(*this); if(!IsDriverOpen()) Modified: trunk/OpenMPT/soundlib/MixerSettings.cpp =================================================================== --- trunk/OpenMPT/soundlib/MixerSettings.cpp 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/soundlib/MixerSettings.cpp 2014-02-01 21:26:00 UTC (rev 3623) @@ -28,31 +28,25 @@ m_nPreAmp = 128; - glVolumeRampUpSamples = 16; - glVolumeRampDownSamples = 42; + VolumeRampUpMicroseconds = 363; // 16 @44100 + VolumeRampDownMicroseconds = 952; // 42 @44100 } - -int32 MixerSettings::GetVolumeRampUpMicroseconds() const +int32 MixerSettings::GetVolumeRampUpSamples() const { - return Util::muldivr(glVolumeRampUpSamples, 1000000, gdwMixingFreq); + return Util::muldivr(VolumeRampUpMicroseconds, gdwMixingFreq, 1000000); } - - -int32 MixerSettings::GetVolumeRampDownMicroseconds() const +int32 MixerSettings::GetVolumeRampDownSamples() const { - return Util::muldivr(glVolumeRampDownSamples, 1000000, gdwMixingFreq); + return Util::muldivr(VolumeRampDownMicroseconds, gdwMixingFreq, 1000000); } - -void MixerSettings::SetVolumeRampUpMicroseconds(int32 rampUpMicroseconds) +void MixerSettings::SetVolumeRampUpSamples(int32 rampUpSamples) { - glVolumeRampUpSamples = Util::muldivr(rampUpMicroseconds, gdwMixingFreq, 1000000); + VolumeRampUpMicroseconds = Util::muldivr(rampUpSamples, 1000000, gdwMixingFreq); } - - -void MixerSettings::SetVolumeRampDownMicroseconds(int32 rampDownMicroseconds) +void MixerSettings::SetVolumeRampDownSamples(int32 rampDownSamples) { - glVolumeRampDownSamples = Util::muldivr(rampDownMicroseconds, gdwMixingFreq, 1000000); + VolumeRampDownMicroseconds = Util::muldivr(rampDownSamples, 1000000, gdwMixingFreq); } Modified: trunk/OpenMPT/soundlib/MixerSettings.h =================================================================== --- trunk/OpenMPT/soundlib/MixerSettings.h 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/soundlib/MixerSettings.h 2014-02-01 21:26:00 UTC (rev 3623) @@ -21,14 +21,19 @@ DWORD gnChannels; DWORD m_nPreAmp; - long glVolumeRampUpSamples; - long glVolumeRampDownSamples; + int32 VolumeRampUpMicroseconds; + int32 VolumeRampDownMicroseconds; + int32 GetVolumeRampUpMicroseconds() const { return VolumeRampUpMicroseconds; } + int32 GetVolumeRampDownMicroseconds() const { return VolumeRampDownMicroseconds; } + void SetVolumeRampUpMicroseconds(int32 rampUpMicroseconds) { VolumeRampUpMicroseconds = rampUpMicroseconds; } + void SetVolumeRampDownMicroseconds(int32 rampDownMicroseconds) { VolumeRampDownMicroseconds = rampDownMicroseconds; } - int32 GetVolumeRampUpMicroseconds() const; - int32 GetVolumeRampDownMicroseconds() const; - void SetVolumeRampUpMicroseconds(int32 rampUpMicroseconds); - void SetVolumeRampDownMicroseconds(int32 rampDownMicroseconds); + int32 GetVolumeRampUpSamples() const; + int32 GetVolumeRampDownSamples() const; + void SetVolumeRampUpSamples(int32 rampUpSamples); + void SetVolumeRampDownSamples(int32 rampDownSamples); + bool IsValid() const { return (gdwMixingFreq > 0) && (gnChannels == 1 || gnChannels == 2 || gnChannels == 4); Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-01 20:47:55 UTC (rev 3622) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-01 21:26:00 UTC (rev 3623) @@ -1509,7 +1509,7 @@ { const bool rampUp = (pChn->newLeftVol > pChn->leftVol) || (pChn->newRightVol > pChn->rightVol); int32 rampLength, globalRampLength, instrRampLength = 0; - rampLength = globalRampLength = (rampUp ? m_MixerSettings.glVolumeRampUpSamples : m_MixerSettings.glVolumeRampDownSamples); + rampLength = globalRampLength = (rampUp ? m_MixerSettings.GetVolumeRampUpSamples() : m_MixerSettings.GetVolumeRampDownSamples()); //XXXih: add real support for bidi ramping here if(GetModFlag(MSF_VOLRAMP) && (GetType() & MOD_TYPE_XM)) @@ -2184,7 +2184,7 @@ const bool rampUp = m_nGlobalVolume > m_nGlobalVolumeDestination; m_nGlobalVolumeDestination = m_nGlobalVolume; - m_nSamplesToGlobalVolRampDest = m_nGlobalVolumeRampAmount = rampUp ? m_MixerSettings.glVolumeRampUpSamples : m_MixerSettings.glVolumeRampDownSamples; + m_nSamplesToGlobalVolRampDest = m_nGlobalVolumeRampAmount = rampUp ? m_MixerSettings.GetVolumeRampUpSamples() : m_MixerSettings.GetVolumeRampDownSamples(); } // calculate ramping step This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-02-02 01:18:53
|
Revision: 3627 http://sourceforge.net/p/modplug/code/3627 Author: saga-games Date: 2014-02-02 01:18:44 +0000 (Sun, 02 Feb 2014) Log Message: ----------- [Ref/Fix] Inconsistencies between ModChannel::pSample and ModChannel::pModSample could lead to a crash in the new loop wraparound code. Remedy this by throwing away the unnecessary ModChannel::pSample. [Fix] Some noise could be generated when stopping the song (this was supposed to be fixed, but sneaked in again when merging the new float/intmixer code) Modified Paths: -------------- trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/soundlib/ModChannel.cpp trunk/OpenMPT/soundlib/ModChannel.h trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndmix.cpp trunk/OpenMPT/soundlib/modsmp_ctrl.cpp trunk/OpenMPT/soundlib/modsmp_ctrl.h Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2014-02-01 23:53:08 UTC (rev 3626) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2014-02-02 01:18:44 UTC (rev 3627) @@ -908,8 +908,8 @@ for(CHANNELINDEX k = 0; k < MAX_CHANNELS; k++) { const ModChannel &chn = m_pSndFile->Chn[k]; - if(chn.pSample == m_pSndFile->GetSample(smp).pSample && chn.nLength != 0 // Corrent sample is set up on this channel - && (!chn.dwFlags[CHN_NOTEFADE] || chn.nFadeOutVol)) // And it hasn't completely faded out yet, so it's still playing + if(chn.pModSample == &m_pSndFile->GetSample(smp) && chn.nLength != 0 // Corrent sample is set up on this channel + && (!chn.dwFlags[CHN_NOTEFADE] || chn.nFadeOutVol)) // And it hasn't completely faded out yet, so it's still playing { notification.pos[k] = chn.nPos; } else Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2014-02-01 23:53:08 UTC (rev 3626) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2014-02-02 01:18:44 UTC (rev 3627) @@ -1094,7 +1094,6 @@ chn.pCurrentSample = sample.pSample; chn.pModInstrument = nullptr; chn.pModSample = &sample; - chn.pSample = sample.pSample; chn.nFineTune = sample.nFineTune; chn.nC5Speed = sample.nC5Speed; chn.nLoopStart = sample.nLoopStart; Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2014-02-01 23:53:08 UTC (rev 3626) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2014-02-02 01:18:44 UTC (rev 3627) @@ -2042,7 +2042,7 @@ p[i] = (signed char) ((*((short int *)(p+i*2))) / 256); } sample.uFlags.reset(CHN_16BIT); - for (CHANNELINDEX j = 0; j < MAX_CHANNELS; j++) if (sndFile.Chn[j].pSample == sample.pSample) + for (CHANNELINDEX j = 0; j < MAX_CHANNELS; j++) if (sndFile.Chn[j].pModSample == &sample) { sndFile.Chn[j].dwFlags.reset(CHN_16BIT); } Modified: trunk/OpenMPT/soundlib/ModChannel.cpp =================================================================== --- trunk/OpenMPT/soundlib/ModChannel.cpp 2014-02-01 23:53:08 UTC (rev 3626) +++ trunk/OpenMPT/soundlib/ModChannel.cpp 2014-02-02 01:18:44 UTC (rev 3627) @@ -47,7 +47,6 @@ nLoopStart = 0; nLoopEnd = 0; nROfs = nLOfs = 0; - pSample = nullptr; pModSample = nullptr; pModInstrument = nullptr; nCutOff = 0x7F; Modified: trunk/OpenMPT/soundlib/ModChannel.h =================================================================== --- trunk/OpenMPT/soundlib/ModChannel.h 2014-02-01 23:53:08 UTC (rev 3626) +++ trunk/OpenMPT/soundlib/ModChannel.h 2014-02-02 01:18:44 UTC (rev 3627) @@ -59,8 +59,7 @@ uint32 nRampLength; // Up to here: 100 bytes - const void *pSample; // Currently playing sample, or previously played sample if no sample is playing. - ModSample *pModSample; // Currently assigned sample slot + ModSample *pModSample; // Currently assigned sample slot (can already be stopped) // Information not used in the mixer ModInstrument *pModInstrument; // Currently assigned instrument slot Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-02-01 23:53:08 UTC (rev 3626) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-02-02 01:18:44 UTC (rev 3627) @@ -947,7 +947,6 @@ } - pChn->pSample = pSmp->pSample; pChn->nTranspose = pSmp->RelativeTone; // FT2 compatibility: Don't reset portamento target with new instrument numbers. @@ -1121,7 +1120,6 @@ if(!bPorta || (!pChn->nLength && !(GetType() & MOD_TYPE_S3M))) { pChn->pModSample = pSmp; - pChn->pSample = pSmp->pSample; pChn->nLength = pSmp->nLength; pChn->nLoopEnd = pSmp->nLength; pChn->nLoopStart = 0; @@ -1384,7 +1382,7 @@ return; } if(instr >= MAX_INSTRUMENTS) instr = 0; - const void *pSample = pChn->pSample; + const ModSample *pSample = pChn->pModSample; pIns = pChn->pModInstrument; if(instr && note) { @@ -1398,7 +1396,7 @@ note = pIns->NoteMap[note - 1]; if ((n) && (n < MAX_SAMPLES)) { - pSample = Samples[n].pSample; + pSample = &Samples[n]; } else if(IsCompatibleMode(TRK_IMPULSETRACKER) && !pIns->HasValidMIDIChannel()) { // Impulse Tracker ignores empty slots. @@ -1432,7 +1430,7 @@ break; // Sample case DCT_SAMPLE: - if(pSample != nullptr && pSample == p->pSample) bOk = true; + if(pSample != nullptr && pSample == p->pModSample) bOk = true; break; // Instrument case DCT_INSTRUMENT: @@ -1955,7 +1953,7 @@ } else { // Sample mode - if(instr < MAX_SAMPLES && pChn->pSample != Samples[instr].pSample) + if(instr < MAX_SAMPLES && pChn->pModSample != &Samples[instr]) note = pChn->nNote; } } Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2014-02-01 23:53:08 UTC (rev 3626) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2014-02-02 01:18:44 UTC (rev 3627) @@ -990,7 +990,6 @@ Chn[i].pModInstrument = nullptr; Chn[i].pModSample = nullptr; Chn[i].pCurrentSample = nullptr; - Chn[i].pSample = nullptr; Chn[i].nLength = 0; } @@ -1633,11 +1632,11 @@ for(CHANNELINDEX i = 0; i < MAX_CHANNELS; i++) { - if(Chn[i].pSample == sample.pSample) + if(Chn[i].pModSample == &sample) { Chn[i].nPos = 0; Chn[i].nLength = 0; - Chn[i].pSample = Chn[i].pCurrentSample = nullptr; + Chn[i].pCurrentSample = nullptr; } } Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-01 23:53:08 UTC (rev 3626) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-02 01:18:44 UTC (rev 3627) @@ -123,7 +123,7 @@ if (nsamples <= 0) return FALSE; if (nsamples > 0x100000) nsamples = 0x100000; m_nBufferCount = nsamples; - uint32 nRampLength = static_cast<uint32>(m_nBufferCount); + int32 nRampLength = static_cast<int32>(m_nBufferCount); // Ramp everything down for (UINT noff=0; noff < m_nMixChannels; noff++) { @@ -392,7 +392,6 @@ Chn[i].nLoopStart = 0; Chn[i].nLoopEnd = 0; Chn[i].pModInstrument = nullptr; - Chn[i].pSample = nullptr; Chn[i].pModSample = nullptr; } } @@ -1877,7 +1876,7 @@ // Check for too big nInc //if (((pChn->nInc >> 16) + 1) >= (int32)(pChn->nLoopEnd - pChn->nLoopStart)) pChn->dwFlags.reset(CHN_LOOP); pChn->newLeftVol = pChn->newRightVol = 0; - pChn->pCurrentSample = ((pChn->pSample) && (pChn->nLength) && (pChn->nInc)) ? pChn->pSample : NULL; + pChn->pCurrentSample = (pChn->pModSample && pChn->pModSample->pSample && pChn->nLength && pChn->nInc) ? pChn->pModSample->pSample : nullptr; if (pChn->pCurrentSample) { // Update VU-Meter (nRealVolume is 14-bit) Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.cpp =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2014-02-01 23:53:08 UTC (rev 3626) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2014-02-02 01:18:44 UTC (rev 3627) @@ -32,7 +32,7 @@ CriticalSection cs; - ctrlChn::ReplaceSample(sndFile.Chn, pOldSmp, pNewSample, nNewLength, setFlags, resetFlags); + ctrlChn::ReplaceSample(sndFile.Chn, &smp, pNewSample, nNewLength, setFlags, resetFlags); smp.pSample = pNewSample; smp.nLength = nNewLength; ModSample::FreeSample(pOldSmp); @@ -500,7 +500,7 @@ smp.nGlobalVol = MIN((WORD)(smp.nGlobalVol / dAmplify), 64); for (CHANNELINDEX i = 0; i < MAX_CHANNELS; i++) { - if(sndFile.Chn[i].pSample == smp.pSample) + if(sndFile.Chn[i].pModSample == &smp) { sndFile.Chn[i].nGlobalVol = smp.nGlobalVol; } @@ -714,7 +714,7 @@ smp.uFlags.reset(CHN_STEREO); for (CHANNELINDEX i = 0; i < MAX_CHANNELS; i++) { - if(sndFile.Chn[i].pSample == smp.pSample) + if(sndFile.Chn[i].pModSample == &smp) { sndFile.Chn[i].dwFlags.reset(CHN_STEREO); } @@ -733,7 +733,7 @@ { void ReplaceSample( ModChannel (&Chn)[MAX_CHANNELS], - const void * const pOldSample, + const ModSample * const pSample, const void * const pNewSample, const SmpLength nNewLength, FlagSet<ChannelFlags> setFlags, @@ -741,9 +741,8 @@ { for (CHANNELINDEX i = 0; i < MAX_CHANNELS; i++) { - if (Chn[i].pSample == pOldSample) + if (Chn[i].pModSample == pSample) { - Chn[i].pSample = pNewSample; if (Chn[i].pCurrentSample != nullptr) Chn[i].pCurrentSample = pNewSample; if (Chn[i].nPos > nNewLength) Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.h =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.h 2014-02-01 23:53:08 UTC (rev 3626) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.h 2014-02-02 01:18:44 UTC (rev 3627) @@ -91,7 +91,7 @@ // Replaces sample from sound channels by given sample. void ReplaceSample( ModChannel (&Chn)[MAX_CHANNELS], - const void * const pOldSample, + const ModSample * const pSample, const void * const pNewSample, const SmpLength nNewLength, FlagSet<ChannelFlags> setFlags, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-02-02 19:29:37
|
Revision: 3632 http://sourceforge.net/p/modplug/code/3632 Author: saga-games Date: 2014-02-02 19:29:27 +0000 (Sun, 02 Feb 2014) Log Message: ----------- [Ref] Remove some tables that can easily be created procedurally (ModSquareTable, ITSquareTable, szDefaultNoteNames) Modified Paths: -------------- trunk/OpenMPT/mptrack/Mptrack.h trunk/OpenMPT/mptrack/PatternClipboard.cpp trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp trunk/OpenMPT/mptrack/PatternEditorDialogs.h trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/mod2midi.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp trunk/OpenMPT/soundlib/Tables.cpp trunk/OpenMPT/soundlib/Tables.h Modified: trunk/OpenMPT/mptrack/Mptrack.h =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.h 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/mptrack/Mptrack.h 2014-02-02 19:29:27 UTC (rev 3632) @@ -399,7 +399,7 @@ // Append note names to combobox. If pSndFile != nullprt, appends only notes that are // available in the module type. If nInstr is given, instrument specific note names are used instead of // default note names. -void AppendNotesToControlEx(CComboBox& combobox, const CSoundFile* const pSndFile = nullptr, const INSTRUMENTINDEX nInstr = MAX_INSTRUMENTS); +void AppendNotesToControlEx(CComboBox& combobox, const CSoundFile &sndFile, const INSTRUMENTINDEX nInstr = MAX_INSTRUMENTS); /////////////////////////////////////////////////// // Tables Modified: trunk/OpenMPT/mptrack/PatternClipboard.cpp =================================================================== --- trunk/OpenMPT/mptrack/PatternClipboard.cpp 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/mptrack/PatternClipboard.cpp 2014-02-02 19:29:27 UTC (rev 3632) @@ -182,17 +182,7 @@ // Note if(selection.ContainsHorizontal(cursor)) { - switch(m->note) - { - case NOTE_NONE: data.Append("..."); break; - case NOTE_KEYOFF: data.Append("==="); break; - case NOTE_NOTECUT: data.Append("^^^"); break; - case NOTE_FADE: data.Append("~~~"); break; - case NOTE_PC: data.Append("PC "); break; - case NOTE_PCS: data.Append("PCS"); break; - default: if(m->IsNote()) data.Append(szDefaultNoteNames[m->note - NOTE_MIN]); - else data.Append("..."); - } + data.Append(CSoundFile::GetNoteName(m->note).c_str()); } else { // No note Modified: trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp =================================================================== --- trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp 2014-02-02 19:29:27 UTC (rev 3632) @@ -168,7 +168,7 @@ { combo->SetItemData(combo->AddString("any"), findAny); } - AppendNotesToControlEx(*combo, &sndFile); + AppendNotesToControlEx(*combo, sndFile); UINT ncount = combo->GetCount(); for (UINT i=0; i<ncount; i++) if (m_Cmd.note == combo->GetItemData(i)) @@ -628,9 +628,9 @@ if ((!parent) || (!pModDoc)) return FALSE; m_hWndView = parent->m_hWnd; m_pModDoc = pModDoc; - m_pageNote = new CPageEditNote(m_pModDoc->GetrSoundFile(), this); - m_pageVolume = new CPageEditVolume(m_pModDoc->GetrSoundFile(), this); - m_pageEffect = new CPageEditEffect(m_pModDoc->GetrSoundFile(), this); + m_pageNote = new CPageEditNote(m_pModDoc->GetrSoundFile(), *this); + m_pageVolume = new CPageEditVolume(m_pModDoc->GetrSoundFile(), *this); + m_pageEffect = new CPageEditEffect(m_pModDoc->GetrSoundFile(), *this); AddPage(m_pageNote); AddPage(m_pageVolume); AddPage(m_pageEffect); @@ -746,11 +746,7 @@ m->instr = instr; m_Command = *m; m_pModDoc->SetModified(); - // -> CODE#0008 - // -> DESC"#define to set pattern max size (number of rows) limit (now set to 1024 instead of 256)" - // m_pModDoc->UpdateAllViews(NULL, (m_nRow << 24) | HINT_PATTERNROW, NULL); m_pModDoc->UpdateAllViews(NULL, (m_nRow << HINT_SHIFT_ROW) | HINT_PATTERNROW, NULL); - // -! BEHAVIOUR_CHANGE#0008 } } @@ -774,11 +770,7 @@ m->volcmd = volcmd; m->vol = vol; m_pModDoc->SetModified(); - // -> CODE#0008 - // -> DESC"#define to set pattern max size (number of rows) limit (now set to 1024 instead of 256)" - // m_pModDoc->UpdateAllViews(NULL, (m_nRow << 24) | HINT_PATTERNROW, NULL); m_pModDoc->UpdateAllViews(NULL, (m_nRow << HINT_SHIFT_ROW) | HINT_PATTERNROW, NULL); - // -! BEHAVIOUR_CHANGE#0008 } } @@ -814,11 +806,7 @@ m->command = command; m->param = param; m_pModDoc->SetModified(); - // -> CODE#0008 - // -> DESC"#define to set pattern max size (number of rows) limit (now set to 1024 instead of 256)" - // m_pModDoc->UpdateAllViews(NULL, (m_nRow << 24) | HINT_PATTERNROW, NULL); m_pModDoc->UpdateAllViews(NULL, (m_nRow << HINT_SHIFT_ROW) | HINT_PATTERNROW, NULL); - // -! BEHAVIOUR_CHANGE#0008 } } @@ -866,15 +854,14 @@ { combo->ResetContent(); combo->SetItemData(combo->AddString("No note"), 0); - AppendNotesToControlEx(*combo, &sndFile, m_nInstr); + AppendNotesToControlEx(*combo, sndFile, m_nInstr); if (ModCommand::IsNoteOrEmpty(m_nNote)) { // Normal note / no note const ModCommand::NOTE noteStart = sndFile.GetModSpecifications().noteMin; combo->SetCurSel(m_nNote - (noteStart - 1)); - } - else + } else { // Special notes for(int i = combo->GetCount() - 1; i >= 0; --i) @@ -951,9 +938,13 @@ } const bool bIsNowParamControl = ModCommand::IsPcNote(m_nNote); if(bWasParamControl != bIsNowParamControl) + { UpdateDialog(); + m_pParent.m_pageVolume->UpdateDialog(); + m_pParent.m_pageEffect->UpdateDialog(); + } - if (m_pParent) m_pParent->UpdateNote(m_nNote, m_nInstr); + m_pParent.UpdateNote(m_nNote, m_nInstr); } @@ -1054,7 +1045,7 @@ { m_nVolume = static_cast<ModCommand::VOL>(slider->GetPos()); } - if (m_pParent) m_pParent->UpdateVolume(m_nVolCmd, m_nVolume); + m_pParent.UpdateVolume(m_nVolCmd, m_nVolume); } @@ -1178,7 +1169,7 @@ } SetDlgItemText(IDC_TEXT1, s); - if ((m_pParent) && (bSet)) m_pParent->UpdateEffect(m_nCommand, m_nParam); + if (bSet) m_pParent.UpdateEffect(m_nCommand, m_nParam); } Modified: trunk/OpenMPT/mptrack/PatternEditorDialogs.h =================================================================== --- trunk/OpenMPT/mptrack/PatternEditorDialogs.h 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/mptrack/PatternEditorDialogs.h 2014-02-02 19:29:27 UTC (rev 3632) @@ -123,11 +123,11 @@ protected: CSoundFile &sndFile; EffectInfo effectInfo; - CEditCommand *m_pParent; + CEditCommand &m_pParent; bool m_bInitialized; public: - CPageEditCommand(CSoundFile &sf, CEditCommand *parent, UINT id) : CPropertyPage(id), sndFile(sf), effectInfo(sf), m_pParent(parent), m_bInitialized(false) {}; + CPageEditCommand(CSoundFile &sf, CEditCommand &parent, UINT id) : CPropertyPage(id), sndFile(sf), effectInfo(sf), m_pParent(parent), m_bInitialized(false) {}; virtual ~CPageEditCommand() {} virtual BOOL OnInitDialog(); @@ -145,7 +145,7 @@ ModCommand::INSTR m_nInstr; public: - CPageEditNote(CSoundFile &sf, CEditCommand *parent) : CPageEditCommand(sf, parent, IDD_PAGEEDITNOTE) {} + CPageEditNote(CSoundFile &sf, CEditCommand &parent) : CPageEditCommand(sf, parent, IDD_PAGEEDITNOTE) {} void Init(ModCommand &m) { m_nNote = m.note; m_nInstr = m.instr; } void UpdateDialog(); @@ -168,7 +168,7 @@ bool m_bIsParamControl; public: - CPageEditVolume(CSoundFile &sf, CEditCommand *parent) : CPageEditCommand(sf, parent, IDD_PAGEEDITVOLUME) {}; + CPageEditVolume(CSoundFile &sf, CEditCommand &parent) : CPageEditCommand(sf, parent, IDD_PAGEEDITVOLUME) {}; void Init(ModCommand &m) { m_nVolCmd = m.volcmd; m_nVolume = m.vol; m_bIsParamControl = m.IsPcNote(); }; void UpdateDialog(); void UpdateRanges(); @@ -200,7 +200,7 @@ ModCommand* m_pModcommand; public: - CPageEditEffect(CSoundFile &sf, CEditCommand *parent) : CPageEditCommand(sf, parent, IDD_PAGEEDITEFFECT) {} + CPageEditEffect(CSoundFile &sf, CEditCommand &parent) : CPageEditCommand(sf, parent, IDD_PAGEEDITEFFECT) {} // -> CODE#0010 // -> DESC="add extended parameter mechanism to pattern effects" void Init(ModCommand &m) { m_nCommand = m.command; m_nParam = m.param; m_pModcommand = &m; m_bIsParamControl = m.IsPcNote(); m_nPlugin = m.instr; m_nPluginParam = m.GetValueVolCol();} @@ -224,6 +224,7 @@ class CEditCommand: public CPropertySheet //======================================= { + friend class CPageEditNote; protected: CPageEditNote *m_pageNote; CPageEditVolume *m_pageVolume; @@ -242,10 +243,7 @@ public: BOOL SetParent(CWnd *parent, CModDoc *pModDoc); BOOL ShowEditWindow(PATTERNINDEX nPat, const PatternCursor &cursor); - // -> CODE#0010 - // -> DESC="add extended parameter mechanism to pattern effects" void OnSelListChange(); - // -! NEW_FEATURE#0010 void UpdateNote(ModCommand::NOTE note, ModCommand::INSTR instr); void UpdateVolume(ModCommand::VOLCMD volcmd, ModCommand::VOL vol); void UpdateEffect(ModCommand::COMMAND command, ModCommand::PARAM param); Modified: trunk/OpenMPT/mptrack/TrackerSettings.cpp =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-02-02 19:29:27 UTC (rev 3632) @@ -897,7 +897,7 @@ for(size_t i = 0; i < CountOf(chords); i++) { uint32 chord; - if((chord = conf.Read<int32>("Chords", szDefaultNoteNames[i], -1)) >= 0) + if((chord = conf.Read<int32>("Chords", CSoundFile::GetNoteName(i + NOTE_MIN), -1)) >= 0) { if((chord & 0xFFFFFFC0) || (!chords[i].notes[0])) { @@ -917,7 +917,7 @@ for(size_t i = 0; i < CountOf(chords); i++) { int32 s = (chords[i].key) | (chords[i].notes[0] << 6) | (chords[i].notes[1] << 12) | (chords[i].notes[2] << 18); - conf.Write<int32>("Chords", szDefaultNoteNames[i], s); + conf.Write<int32>("Chords", CSoundFile::GetNoteName(i + NOTE_MIN), s); } } Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2014-02-02 19:29:27 UTC (rev 3632) @@ -2233,9 +2233,11 @@ ModSample &sample = sndFile.GetSample(m_nSample); uint32 freq = sndFile.GetFreqFromPeriod(sndFile.GetPeriodFromNote(note + (sndFile.GetType() == MOD_TYPE_XM ? sample.RelativeTone : 0), sample.nFineTune, sample.nC5Speed), sample.nC5Speed, 0); - CHAR s[32]; - wsprintf(s, "%s (%d.%02d Hz)", szDefaultNoteNames[note - 1], freq >> FREQ_FRACBITS, Util::muldiv(freq & ((1 << FREQ_FRACBITS) - 1), 100, 1 << FREQ_FRACBITS)); - pMainFrm->SetInfoText(s); + const std::string s = mpt::String::Print("%1 (%2.%3 Hz)", + sndFile.GetNoteName((ModCommand::NOTE)note), + freq >> FREQ_FRACBITS, + mpt::fmt::dec0<2>(Util::muldiv(freq & ((1 << FREQ_FRACBITS) - 1), 100, 1 << FREQ_FRACBITS))); + pMainFrm->SetInfoText(s.c_str()); } } Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2014-02-02 19:29:27 UTC (rev 3632) @@ -517,7 +517,7 @@ for (UINT iPerc=24; iPerc<=84; iPerc++) { DWORD dwImage = IMAGE_NOSAMPLE; - s = mpt::ToWide(mpt::CharsetASCII, szDefaultNoteNames[iPerc]) + L": " + mpt::ToWide(mpt::CharsetASCII, szMidiPercussionNames[iPerc - 24]); + s = mpt::ToWide(mpt::CharsetASCII, CSoundFile::GetNoteName(iPerc + NOTE_MIN)) + L": " + mpt::ToWide(mpt::CharsetASCII, szMidiPercussionNames[iPerc - 24]); const LPARAM param = (MODITEM_MIDIPERCUSSION << MIDILIB_SHIFT) | iPerc; if(!midiLib.MidiMap[iPerc | 0x80].empty()) { Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2014-02-02 19:29:27 UTC (rev 3632) @@ -1287,29 +1287,26 @@ void AppendNotesToControl(CComboBox& combobox, const ModCommand::NOTE noteStart, const ModCommand::NOTE noteEnd) -//------------------------------------------------------------------------------------------------------------------ +//-------------------------------------------------------------------------------------------------------------- { - const ModCommand::NOTE upperLimit = MIN(CountOf(szDefaultNoteNames) - 1, noteEnd); + const ModCommand::NOTE upperLimit = MIN(NOTE_MAX - NOTE_MIN, noteEnd); for(ModCommand::NOTE note = noteStart; note <= upperLimit; ++note) - combobox.SetItemData(combobox.AddString(szDefaultNoteNames[note]), note); + combobox.SetItemData(combobox.AddString(CSoundFile::GetNoteName(note + NOTE_MIN).c_str()), note); } -void AppendNotesToControlEx(CComboBox& combobox, const CSoundFile* const pSndFile /* = nullptr*/, const INSTRUMENTINDEX nInstr/* = MAX_INSTRUMENTS*/) -//---------------------------------------------------------------------------------------------------------------------------------- +void AppendNotesToControlEx(CComboBox& combobox, const CSoundFile &sndFile, const INSTRUMENTINDEX nInstr/* = MAX_INSTRUMENTS*/) +//----------------------------------------------------------------------------------------------------------------------------- { - const ModCommand::NOTE noteStart = (pSndFile != nullptr) ? pSndFile->GetModSpecifications().noteMin : NOTE_MIN; - const ModCommand::NOTE noteEnd = (pSndFile != nullptr) ? pSndFile->GetModSpecifications().noteMax : NOTE_MAX; + const ModCommand::NOTE noteStart = sndFile.GetModSpecifications().noteMin; + const ModCommand::NOTE noteEnd = sndFile.GetModSpecifications().noteMax; for(ModCommand::NOTE nNote = noteStart; nNote <= noteEnd; nNote++) { - if(pSndFile != nullptr && nInstr != MAX_INSTRUMENTS) - combobox.SetItemData(combobox.AddString(pSndFile->GetNoteName(nNote, nInstr).c_str()), nNote); - else - combobox.SetItemData(combobox.AddString(szDefaultNoteNames[nNote - 1]), nNote); + combobox.SetItemData(combobox.AddString(sndFile.GetNoteName(nNote, nInstr).c_str()), nNote); } for(ModCommand::NOTE nNote = NOTE_MIN_SPECIAL - 1; nNote++ < NOTE_MAX_SPECIAL;) { - if(pSndFile == nullptr || pSndFile->GetModSpecifications().HasNote(nNote) == true) - combobox.SetItemData(combobox.AddString(szSpecialNoteNamesMPT[nNote-NOTE_MIN_SPECIAL]), nNote); + if(sndFile.GetModSpecifications().HasNote(nNote)) + combobox.SetItemData(combobox.AddString(szSpecialNoteNamesMPT[nNote - NOTE_MIN_SPECIAL]), nNote); } } Modified: trunk/OpenMPT/mptrack/mod2midi.cpp =================================================================== --- trunk/OpenMPT/mptrack/mod2midi.cpp 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/mptrack/mod2midi.cpp 2014-02-02 19:29:27 UTC (rev 3632) @@ -243,7 +243,7 @@ for (UINT i=0; i<61; i++) { UINT note = i+24; - wsprintf(s, "%d (%s): %s", note, szDefaultNoteNames[note], szMidiPercussionNames[i]); + wsprintf(s, "%d (%s%d): %s", note, szNoteNames[note % 12], note / 12, szMidiPercussionNames[i]); m_CbnProgram.SetItemData(m_CbnProgram.AddString(s), note/*+1*/); //+1 removed by rewbs because MIDI drums appear to be offset by 1 } } else Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2014-02-02 19:29:27 UTC (rev 3632) @@ -31,7 +31,6 @@ #endif // NO_ARCHIVE_SUPPORT extern BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength); -extern const char *szSpecialNoteNames[]; // -> CODE#0027 @@ -1744,22 +1743,37 @@ std::string CSoundFile::GetNoteName(const ModCommand::NOTE note, const INSTRUMENTINDEX inst) const //------------------------------------------------------------------------------------------------ { + // For MPTM instruments with custom tuning, find the appropriate note name. Else, use default note names. + if(ModCommand::IsNote(note) && GetType() == MOD_TYPE_MPT && inst >= 1 && inst <= GetNumInstruments() && Instruments[inst] && Instruments[inst]->pTuning) + { + return Instruments[inst]->pTuning->GetNoteName(note - NOTE_MIDDLEC); + } else + { + return GetNoteName(note); + } +} + + +std::string CSoundFile::GetNoteName(const ModCommand::NOTE note) +//-------------------------------------------------------------- +{ if(ModCommand::IsSpecialNote(note)) { - return szSpecialNoteNames[note - NOTE_MIN_SPECIAL]; + const char specialNoteNames[][4] = { "PCs", "PC ", "~~~", "^^^", "===" }; + STATIC_ASSERT(CountOf(specialNoteNames) == NOTE_MAX_SPECIAL - NOTE_MIN_SPECIAL + 1); + + return specialNoteNames[note - NOTE_MIN_SPECIAL]; + } else if(ModCommand::IsNote(note)) + { + char name[4]; + MemCopy<char[4]>(name, szNoteNames[(note - NOTE_MIN) % 12]); // e.g. "C#" + name[2] = '0' + (note - NOTE_MIN) / 12; // e.g. 5 + return name; //szNoteNames[(note - NOTE_MIN) % 12] + std::string(1, '0' + (note - NOTE_MIN) / 12); } else if(note == NOTE_NONE) { return "..."; - } else if(!ModCommand::IsNote(note)) - { - return "???"; } - - // For MPTM instruments with custom tuning, find the appropriate note name. Else, use default note names. - if(GetType() == MOD_TYPE_MPT && inst >= 1 && inst <= GetNumInstruments() && Instruments[inst] && Instruments[inst]->pTuning) - return Instruments[inst]->pTuning->GetNoteName(note - NOTE_MIDDLEC); - else - return szDefaultNoteNames[note - 1]; + return "???"; } Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/soundlib/Sndfile.h 2014-02-02 19:29:27 UTC (rev 3632) @@ -296,7 +296,8 @@ static CTuning *GetDefaultTuning() {return nullptr;} CTuningCollection& GetTuneSpecificTunings() {return *m_pTuningsTuneSpecific;} - std::string GetNoteName(const ModCommand::NOTE note, const INSTRUMENTINDEX inst = INSTRUMENTINDEX_INVALID) const; + std::string GetNoteName(const ModCommand::NOTE note, const INSTRUMENTINDEX inst) const; + static std::string GetNoteName(const ModCommand::NOTE note); private: CTuningCollection* m_pTuningsTuneSpecific; #ifdef MODPLUG_TRACKER @@ -870,8 +871,7 @@ #endif -extern const char *szNoteNames[12]; -extern const char *szDefaultNoteNames[NOTE_MAX]; +extern const char szNoteNames[12][4]; inline IMixPlugin* CSoundFile::GetInstrumentPlugin(INSTRUMENTINDEX instr) Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-02 19:29:27 UTC (rev 3632) @@ -578,7 +578,10 @@ case 2: // IT compatibility: IT has its own, more precise tables - return IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[position] : ModSquareTable[position]; + if(IsCompatibleMode(TRK_IMPULSETRACKER)) + return position < 128 ? 64 : 0; + else + return position < 32 ? 127 : -127; case 3: //IT compatibility 19. Use random values @@ -1381,7 +1384,7 @@ vdelta = -ITRampDownTable[vibpos]; break; case VIB_SQUARE: - vdelta = ITSquareTable[vibpos]; + vdelta = vibpos < 128 ? 64 : 0; break; case VIB_SINE: default: Modified: trunk/OpenMPT/soundlib/Tables.cpp =================================================================== --- trunk/OpenMPT/soundlib/Tables.cpp 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/soundlib/Tables.cpp 2014-02-02 19:29:27 UTC (rev 3632) @@ -15,38 +15,19 @@ #include "Sndfile.h" #include "Resampler.h" -// rewbs.resamplerConf #include "WindowedFIR.h" -// end rewbs.resamplerConf ///////////////////////////////////////////////////////////////////////////// // Common Tables -const char *szNoteNames[12] = +const char szNoteNames[12][4] = { "C-", "C#", "D-", "D#", "E-", "F-", "F#", "G-", "G#", "A-", "A#", "B-" }; -const char *szDefaultNoteNames[NOTE_MAX] = -{ - "C-0", "C#0", "D-0", "D#0", "E-0", "F-0", "F#0", "G-0", "G#0", "A-0", "A#0", "B-0", - "C-1", "C#1", "D-1", "D#1", "E-1", "F-1", "F#1", "G-1", "G#1", "A-1", "A#1", "B-1", - "C-2", "C#2", "D-2", "D#2", "E-2", "F-2", "F#2", "G-2", "G#2", "A-2", "A#2", "B-2", - "C-3", "C#3", "D-3", "D#3", "E-3", "F-3", "F#3", "G-3", "G#3", "A-3", "A#3", "B-3", - "C-4", "C#4", "D-4", "D#4", "E-4", "F-4", "F#4", "G-4", "G#4", "A-4", "A#4", "B-4", - "C-5", "C#5", "D-5", "D#5", "E-5", "F-5", "F#5", "G-5", "G#5", "A-5", "A#5", "B-5", - "C-6", "C#6", "D-6", "D#6", "E-6", "F-6", "F#6", "G-6", "G#6", "A-6", "A#6", "B-6", - "C-7", "C#7", "D-7", "D#7", "E-7", "F-7", "F#7", "G-7", "G#7", "A-7", "A#7", "B-7", - "C-8", "C#8", "D-8", "D#8", "E-8", "F-8", "F#8", "G-8", "G#8", "A-8", "A#8", "B-8", - "C-9", "C#9", "D-9", "D#9", "E-9", "F-9", "F#9", "G-9", "G#9", "A-9", "A#9", "B-9", -}; -const char *szSpecialNoteNames[] = { "PCs", "PC", "~~~", "^^^", "===" }; -STATIC_ASSERT(CountOf(szSpecialNoteNames) == NOTE_MAX_SPECIAL - NOTE_MIN_SPECIAL + 1); - - /////////////////////////////////////////////////////////// // File Formats Information (name, extension, etc) @@ -397,15 +378,6 @@ 63,59,55,51,47,43,39,35,31,27,23,19,15,11,7,3 }; -// Square wave table -const int8 ModSquareTable[64] = -{ - 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, - 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, - -127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127, - -127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127 -}; - // Random wave table const int8 ModRandomTable[64] = { @@ -459,26 +431,6 @@ -56,-57,-57,-58,-58,-59,-59,-60,-60,-61,-61,-62,-62,-63,-63,-64, }; -// Square wave table -const int8 ITSquareTable[256] = -{ - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; // volume fade tables for Retrig Note: const int8 retrigTable1[16] = Modified: trunk/OpenMPT/soundlib/Tables.h =================================================================== --- trunk/OpenMPT/soundlib/Tables.h 2014-02-02 17:20:53 UTC (rev 3631) +++ trunk/OpenMPT/soundlib/Tables.h 2014-02-02 19:29:27 UTC (rev 3632) @@ -20,11 +20,9 @@ extern const uint16 S3MFineTuneTable[16]; extern const int8 ModSinusTable[64]; extern const int8 ModRampDownTable[64]; -extern const int8 ModSquareTable[64]; extern const int8 ModRandomTable[64]; extern const int8 ITSinusTable[256]; extern const int8 ITRampDownTable[256]; -extern const int8 ITSquareTable[256]; extern const int8 retrigTable1[16]; extern const int8 retrigTable2[16]; extern const uint16 XMPeriodTable[104]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-02-03 17:00:10
|
Revision: 3637 http://sourceforge.net/p/modplug/code/3637 Author: saga-games Date: 2014-02-03 17:00:01 +0000 (Mon, 03 Feb 2014) Log Message: ----------- [Mod] XM: Don't try to be smarter than FT2 and dumbly scale volume column panning to 0,4,8...56,60. Modified Paths: -------------- trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/test/test.cpp Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2014-02-03 13:11:54 UTC (rev 3636) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2014-02-03 17:00:01 UTC (rev 3637) @@ -231,7 +231,7 @@ if(m->volcmd == VOLCMD_PANNING) { - m->vol = ((m->vol * 64 + 8) / 15); + m->vol *= 4; // FT2 does indeed not scale panning symmetrically. } } } @@ -788,7 +788,7 @@ case VOLCMD_FINEVOLUP: vol = 0x90 + (p->vol & 0x0F); break; case VOLCMD_VIBRATOSPEED: vol = 0xA0 + (p->vol & 0x0F); break; case VOLCMD_VIBRATODEPTH: vol = 0xB0 + (p->vol & 0x0F); break; - case VOLCMD_PANNING: vol = 0xC0 + ((p->vol * 15 + 32) / 64); if (vol > 0xCF) vol = 0xCF; break; + case VOLCMD_PANNING: vol = 0xC0 + (p->vol / 4); if (vol > 0xCF) vol = 0xCF; break; case VOLCMD_PANSLIDELEFT: vol = 0xD0 + (p->vol & 0x0F); break; case VOLCMD_PANSLIDERIGHT: vol = 0xE0 + (p->vol & 0x0F); break; case VOLCMD_TONEPORTAMENTO: vol = 0xF0 + (p->vol & 0x0F); break; Modified: trunk/OpenMPT/test/test.cpp =================================================================== --- trunk/OpenMPT/test/test.cpp 2014-02-03 13:11:54 UTC (rev 3636) +++ trunk/OpenMPT/test/test.cpp 2014-02-03 17:00:01 UTC (rev 3637) @@ -1152,7 +1152,7 @@ // Test 4-Bit Panning conversion for(int i = 0; i < 16; i++) { - VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(10 + i, 0)->vol, ((i * 64 + 8) / 15)); + VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(10 + i, 0)->vol, i * 4); } // Plugins This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <man...@us...> - 2014-02-04 16:17:35
|
Revision: 3651 http://sourceforge.net/p/modplug/code/3651 Author: manxorist Date: 2014-02-04 16:17:27 +0000 (Tue, 04 Feb 2014) Log Message: ----------- Merged revision(s) 3636-3650 from branches/manx/unpack-cleanup: [Ref] Unpack: Modernize interface (currently does 1 additional copy of unpacked data which will be removed again when the refactoring is finished). ........ [Fix] PP20 unpacker: Make it endian-safe. [Ref] PP20 unpacker: Convert to FileReader and OpenMPT types. ........ [Fix] PP20 unpacker: Add a check back that was missed in r3640. ........ [Ref] XPK unpacker: Convert to FileReader and OpenMPT types. ........ [Fix] MMCMP unpacker: Make it endian-safe. [Fix] MMCMP unpacker: Make on-disk structures PACKED. [Fix] MMCMP unpacker: Remove unaligned memory accesses. [Fix] MMCMP unpacker: When parsing compressed data fails, actually return false instead of just skipping rest of uncompression and returning garbage uncompressed data. [Ref] MMCMP unpacker: Convert to FileReader and OpenMPT types. ........ [Ref] PP20 unpacker: Remove bogus size checks. [Fix] PP20 unpacker: Do not overrun compressed data buffer and fail decompression in that case. ........ [Ref] Tiny cleanups. ........ [Fix] XPK unpacker: Add proper bounds cheking to all src and dst buffer accesses. Error out on failure. ........ [Ref] XPK unpacker: Remove bogus size checks. ........ [Fix] Add missing include. ........ [Ref] MMCMP unpacker: Remove bogus size checks. [Fix] MMCMP unpacker: Fix off-by-one in bounds check for uncompressed data. [Fix] MMCMP unpacker: Properly validate all other destination buffer position and size values. Error out on failure instead of crashing. ........ [Ref] MMCMP unpacker: Fail if hdrsize in the file header does not match our expectations. ........ Revision Links: -------------- http://sourceforge.net/p/modplug/code/3640 Modified Paths: -------------- trunk/OpenMPT/soundlib/Mmcmp.cpp trunk/OpenMPT/soundlib/Sndfile.cpp Property Changed: ---------------- trunk/OpenMPT/ Index: trunk/OpenMPT =================================================================== --- trunk/OpenMPT 2014-02-04 16:14:11 UTC (rev 3650) +++ trunk/OpenMPT 2014-02-04 16:17:27 UTC (rev 3651) Property changes on: trunk/OpenMPT ___________________________________________________________________ Modified: svn:mergeinfo ## -19,3 +19,4 ## /branches/manx/stdstring-names:2223,2228 /branches/manx/stdstring-song-name:2462-2463 /branches/manx/unarchiver:1887-1888 +/branches/manx/unpack-cleanup:3636-3650 \ No newline at end of property Modified: trunk/OpenMPT/soundlib/Mmcmp.cpp =================================================================== --- trunk/OpenMPT/soundlib/Mmcmp.cpp 2014-02-04 16:14:11 UTC (rev 3650) +++ trunk/OpenMPT/soundlib/Mmcmp.cpp 2014-02-04 16:17:27 UTC (rev 3651) @@ -11,47 +11,105 @@ #include "stdafx.h" #include "Sndfile.h" +#include "FileReader.h" +#include <stdexcept> + + //#define MMCMP_LOG -BOOL XPK_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength); -BOOL PP20_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength); +#ifdef NEEDS_PRAGMA_PACK +#pragma pack(push, 1) +#endif -typedef struct MMCMPFILEHEADER +struct PACKED MMCMPFILEHEADER { - DWORD id_ziRC; // "ziRC" - DWORD id_ONia; // "ONia" - WORD hdrsize; -} MMCMPFILEHEADER, *LPMMCMPFILEHEADER; + char id_ziRC[4]; // "ziRC" + char id_ONia[4]; // "ONia" + uint16 hdrsize; + void ConvertEndianness(); +}; -typedef struct MMCMPHEADER +STATIC_ASSERT(sizeof(MMCMPFILEHEADER) == 10); + +struct PACKED MMCMPHEADER { - WORD version; - WORD nblocks; - DWORD filesize; - DWORD blktable; - BYTE glb_comp; - BYTE fmt_comp; -} MMCMPHEADER, *LPMMCMPHEADER; + uint16 version; + uint16 nblocks; + uint32 filesize; + uint32 blktable; + uint8 glb_comp; + uint8 fmt_comp; + void ConvertEndianness(); +}; -typedef struct MMCMPBLOCK +STATIC_ASSERT(sizeof(MMCMPHEADER) == 14); + +struct PACKED MMCMPBLOCK { - DWORD unpk_size; - DWORD pk_size; - DWORD xor_chk; - WORD sub_blk; - WORD flags; - WORD tt_entries; - WORD num_bits; -} MMCMPBLOCK, *LPMMCMPBLOCK; + uint32 unpk_size; + uint32 pk_size; + uint32 xor_chk; + uint16 sub_blk; + uint16 flags; + uint16 tt_entries; + uint16 num_bits; + void ConvertEndianness(); +}; -typedef struct MMCMPSUBBLOCK +STATIC_ASSERT(sizeof(MMCMPBLOCK) == 20); + +struct PACKED MMCMPSUBBLOCK { - DWORD unpk_pos; - DWORD unpk_size; -} MMCMPSUBBLOCK, *LPMMCMPSUBBLOCK; + uint32 unpk_pos; + uint32 unpk_size; + void ConvertEndianness(); +}; +STATIC_ASSERT(sizeof(MMCMPSUBBLOCK) == 8); + +#ifdef NEEDS_PRAGMA_PACK +#pragma pack(pop) +#endif + +void MMCMPFILEHEADER::ConvertEndianness() +//--------------------------------------- +{ + SwapBytesLE(hdrsize); +} + +void MMCMPHEADER::ConvertEndianness() +//----------------------------------- +{ + SwapBytesLE(version); + SwapBytesLE(nblocks); + SwapBytesLE(filesize); + SwapBytesLE(blktable); + SwapBytesLE(glb_comp); + SwapBytesLE(fmt_comp); +} + +void MMCMPBLOCK::ConvertEndianness() +//---------------------------------- +{ + SwapBytesLE(unpk_size); + SwapBytesLE(pk_size); + SwapBytesLE(xor_chk); + SwapBytesLE(sub_blk); + SwapBytesLE(flags); + SwapBytesLE(tt_entries); + SwapBytesLE(num_bits); +} + +void MMCMPSUBBLOCK::ConvertEndianness() +//------------------------------------- +{ + SwapBytesLE(unpk_pos); + SwapBytesLE(unpk_size); +} + + #define MMCMP_COMP 0x0001 #define MMCMP_DELTA 0x0002 #define MMCMP_16BIT 0x0004 @@ -59,21 +117,21 @@ #define MMCMP_ABS16 0x0200 #define MMCMP_ENDIAN 0x0400 -typedef struct MMCMPBITBUFFER +struct MMCMPBITBUFFER { - UINT bitcount; - DWORD bitbuffer; - LPCBYTE pSrc; - LPCBYTE pEnd; + uint32 bitcount; + uint32 bitbuffer; + const uint8 *pSrc; + const uint8 *pEnd; - DWORD GetBits(UINT nBits); -} MMCMPBITBUFFER; + uint32 GetBits(uint32 nBits); +}; -DWORD MMCMPBITBUFFER::GetBits(UINT nBits) -//--------------------------------------- +uint32 MMCMPBITBUFFER::GetBits(uint32 nBits) +//------------------------------------------ { - DWORD d; + uint32 d; if (!nBits) return 0; while (bitcount < 24) { @@ -86,89 +144,115 @@ return d; } -const DWORD MMCMP8BitCommands[8] = +static const uint32 MMCMP8BitCommands[8] = { 0x01, 0x03, 0x07, 0x0F, 0x1E, 0x3C, 0x78, 0xF8 }; -const UINT MMCMP8BitFetch[8] = +static const uint32 MMCMP8BitFetch[8] = { 3, 3, 3, 3, 2, 1, 0, 0 }; -const DWORD MMCMP16BitCommands[16] = +static const uint32 MMCMP16BitCommands[16] = { 0x01, 0x03, 0x07, 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0x1F0, 0x3F0, 0x7F0, 0xFF0, 0x1FF0, 0x3FF0, 0x7FF0, 0xFFF0 }; -const UINT MMCMP16BitFetch[16] = +static const uint32 MMCMP16BitFetch[16] = { 4, 4, 4, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength) -//--------------------------------------------------------- +static bool MMCMP_IsDstBlockValid(const std::vector<char> &unpackedData, uint32 pos, uint32 len) +//---------------------------------------------------------------------------------------------- { - DWORD dwMemLength = *pdwMemLength; - LPCBYTE lpMemFile = *ppMemFile; - LPBYTE pBuffer; - LPMMCMPFILEHEADER pmfh = (LPMMCMPFILEHEADER)(lpMemFile); - LPMMCMPHEADER pmmh = (LPMMCMPHEADER)(lpMemFile+10); - LPDWORD pblk_table; - DWORD dwFileSize; + if(pos >= unpackedData.size()) return false; + if(len > unpackedData.size()) return false; + if(len > unpackedData.size() - pos) return false; + return true; +} - if ((XPK_Unpack(ppMemFile, pdwMemLength)) - || (PP20_Unpack(ppMemFile, pdwMemLength))) + +static bool MMCMP_IsDstBlockValid(const std::vector<char> &unpackedData, const MMCMPSUBBLOCK &subblk) +//--------------------------------------------------------------------------------------------------- +{ + return MMCMP_IsDstBlockValid(unpackedData, subblk.unpk_pos, subblk.unpk_size); +} + + +bool UnpackMMCMP(std::vector<char> &unpackedData, FileReader &file) +//----------------------------------------------------------------- +{ + file.Rewind(); + unpackedData.clear(); + + MMCMPFILEHEADER mfh; + if(!file.ReadConvertEndianness(mfh)) return false; + if(std::memcmp(mfh.id_ziRC, "ziRC", 4) != 0) return false; + if(std::memcmp(mfh.id_ONia, "ONia", 4) != 0) return false; + if(mfh.hdrsize != sizeof(MMCMPHEADER)) return false; + MMCMPHEADER mmh; + if(!file.ReadConvertEndianness(mmh)) return false; + if(mmh.nblocks == 0) return false; + if(mmh.filesize == 0) return false; + if(mmh.filesize > 0x80000000) return false; + if(mmh.blktable > file.GetLength()) return false; + if(mmh.blktable + 4 * mmh.nblocks > file.GetLength()) return false; + + unpackedData.resize(mmh.filesize); + + for (uint32 nBlock=0; nBlock<mmh.nblocks; nBlock++) { - return TRUE; - } - if ((dwMemLength < 256) || (!pmfh) || (pmfh->id_ziRC != 0x4352697A) || (pmfh->id_ONia != 0x61694e4f) || (pmfh->hdrsize < 14) - || (!pmmh->nblocks) || (pmmh->filesize < 16) || (pmmh->filesize > 0x8000000) - || (pmmh->blktable >= dwMemLength) || (pmmh->blktable + 4*pmmh->nblocks > dwMemLength)) return FALSE; - dwFileSize = pmmh->filesize; - if ((pBuffer = (LPBYTE)calloc(1, (dwFileSize + 31) & ~15)) == NULL) return FALSE; - pblk_table = (LPDWORD)(lpMemFile+pmmh->blktable); - for (UINT nBlock=0; nBlock<pmmh->nblocks; nBlock++) - { - DWORD dwMemPos = pblk_table[nBlock]; - LPMMCMPBLOCK pblk = (LPMMCMPBLOCK)(lpMemFile+dwMemPos); - LPMMCMPSUBBLOCK psubblk = (LPMMCMPSUBBLOCK)(lpMemFile+dwMemPos+20); + if(!file.Seek(mmh.blktable + 4*nBlock)) return false; + if(!file.CanRead(4)) return false; + uint32 blkPos = file.ReadUint32LE(); + if(!file.Seek(blkPos)) return false; + MMCMPBLOCK blk; + if(!file.ReadConvertEndianness(blk)) return false; + std::vector<MMCMPSUBBLOCK> subblks(blk.sub_blk); + for(uint32 i=0; i<blk.sub_blk; ++i) + { + if(!file.ReadConvertEndianness(subblks[i])) return false; + } + MMCMPSUBBLOCK *psubblk = blk.sub_blk > 0 ? &(subblks[0]) : nullptr; - if ((dwMemPos + 20 >= dwMemLength) || (dwMemPos + 20 + pblk->sub_blk*8 >= dwMemLength)) break; - dwMemPos += 20 + pblk->sub_blk*8; + if(blkPos + sizeof(MMCMPBLOCK) + blk.sub_blk * sizeof(MMCMPSUBBLOCK) >= file.GetLength()) return false; + uint32 memPos = blkPos + sizeof(MMCMPBLOCK) + blk.sub_blk * sizeof(MMCMPSUBBLOCK); + #ifdef MMCMP_LOG Log("block %d: flags=%04X sub_blocks=%d", nBlock, (UINT)pblk->flags, (UINT)pblk->sub_blk); Log(" pksize=%d unpksize=%d", pblk->pk_size, pblk->unpk_size); Log(" tt_entries=%d num_bits=%d\n", pblk->tt_entries, pblk->num_bits); #endif // Data is not packed - if (!(pblk->flags & MMCMP_COMP)) + if (!(blk.flags & MMCMP_COMP)) { - for (UINT i=0; i<pblk->sub_blk; i++) + for (uint32 i=0; i<blk.sub_blk; i++) { - if ((psubblk->unpk_pos >= dwFileSize) || - (psubblk->unpk_size >= dwFileSize) || - (psubblk->unpk_size > dwFileSize - psubblk->unpk_pos)) break; + if(!MMCMP_IsDstBlockValid(unpackedData, *psubblk)) return false; #ifdef MMCMP_LOG Log(" Unpacked sub-block %d: offset %d, size=%d\n", i, psubblk->unpk_pos, psubblk->unpk_size); #endif - memcpy(pBuffer+psubblk->unpk_pos, lpMemFile+dwMemPos, psubblk->unpk_size); - dwMemPos += psubblk->unpk_size; + if(!file.Seek(memPos)) return false; + if(file.ReadRaw(&(unpackedData[psubblk->unpk_pos]), psubblk->unpk_size) != psubblk->unpk_size) return false; psubblk++; } } else // Data is 16-bit packed - if (pblk->flags & MMCMP_16BIT) + if (blk.flags & MMCMP_16BIT) { MMCMPBITBUFFER bb; - uint16 *pDest = (uint16 *)(pBuffer + psubblk->unpk_pos); - uint32 dwSize = psubblk->unpk_size >> 1; + uint32 subblk = 0; + if(!MMCMP_IsDstBlockValid(unpackedData, psubblk[subblk])) return false; + char *pDest = &(unpackedData[psubblk[subblk].unpk_pos]); + uint32 dwSize = psubblk[subblk].unpk_size >> 1; uint32 dwPos = 0; - uint32 numbits = pblk->num_bits; - uint32 subblk = 0, oldval = 0; + uint32 numbits = blk.num_bits; + uint32 oldval = 0; #ifdef MMCMP_LOG Log(" 16-bit block: pos=%d size=%d ", psubblk->unpk_pos, psubblk->unpk_size); @@ -178,9 +262,11 @@ #endif bb.bitcount = 0; bb.bitbuffer = 0; - bb.pSrc = lpMemFile+dwMemPos+pblk->tt_entries; - bb.pEnd = lpMemFile+dwMemPos+pblk->pk_size; - while (subblk < pblk->sub_blk) + if(!file.Seek(memPos + blk.tt_entries)) return false; + if(!file.CanRead(blk.pk_size - blk.tt_entries)) return false; + bb.pSrc = reinterpret_cast<const uint8 *>(file.GetRawData()); + bb.pEnd = reinterpret_cast<const uint8 *>(file.GetRawData() - blk.tt_entries + blk.pk_size); + while (subblk < blk.sub_blk) { uint32 newval = 0x10000; uint32 d = bb.GetBits(numbits+1); @@ -210,41 +296,50 @@ if (newval < 0x10000) { newval = (newval & 1) ? (uint32)(-(int32)((newval+1) >> 1)) : (uint32)(newval >> 1); - if (pblk->flags & MMCMP_DELTA) + if (blk.flags & MMCMP_DELTA) { newval += oldval; oldval = newval; } else - if (!(pblk->flags & MMCMP_ABS16)) + if (!(blk.flags & MMCMP_ABS16)) { newval ^= 0x8000; } - pDest[dwPos++] = (uint16)newval; + pDest[dwPos*2 + 0] = (uint8)(((uint16)newval) & 0xff); + pDest[dwPos*2 + 1] = (uint8)(((uint16)newval) >> 8); + dwPos++; } if (dwPos >= dwSize) { subblk++; dwPos = 0; + if(!(subblk < blk.sub_blk)) break; + if(!MMCMP_IsDstBlockValid(unpackedData, psubblk[subblk])) return false; dwSize = psubblk[subblk].unpk_size >> 1; - pDest = (uint16 *)(pBuffer + psubblk[subblk].unpk_pos); + pDest = &(unpackedData[psubblk[subblk].unpk_pos]); } } } else // Data is 8-bit packed { MMCMPBITBUFFER bb; - LPBYTE pDest = pBuffer + psubblk->unpk_pos; - uint32 dwSize = psubblk->unpk_size; + uint32 subblk = 0; + if(!MMCMP_IsDstBlockValid(unpackedData, psubblk[subblk])) return false; + char *pDest = &(unpackedData[psubblk[subblk].unpk_pos]); + uint32 dwSize = psubblk[subblk].unpk_size; uint32 dwPos = 0; - uint32 numbits = pblk->num_bits; - uint32 subblk = 0, oldval = 0; - LPCBYTE ptable = lpMemFile+dwMemPos; + uint32 numbits = blk.num_bits; + uint32 oldval = 0; + if(!file.Seek(memPos)) return false; + const uint8 *ptable = reinterpret_cast<const uint8 *>(file.GetRawData()); bb.bitcount = 0; bb.bitbuffer = 0; - bb.pSrc = lpMemFile+dwMemPos+pblk->tt_entries; - bb.pEnd = lpMemFile+dwMemPos+pblk->pk_size; - while (subblk < pblk->sub_blk) + if(!file.Seek(memPos + blk.tt_entries)) return false; + if(!file.CanRead(blk.pk_size - blk.tt_entries)) return false; + bb.pSrc = reinterpret_cast<const uint8 *>(file.GetRawData()); + bb.pEnd = reinterpret_cast<const uint8 *>(file.GetRawData() - blk.tt_entries + blk.pk_size); + while (subblk < blk.sub_blk) { uint32 newval = 0x100; uint32 d = bb.GetBits(numbits+1); @@ -274,7 +369,7 @@ if (newval < 0x100) { int n = ptable[newval]; - if (pblk->flags & MMCMP_DELTA) + if (blk.flags & MMCMP_DELTA) { n += oldval; oldval = n; @@ -285,15 +380,16 @@ { subblk++; dwPos = 0; + if(!(subblk < blk.sub_blk)) break; + if(!MMCMP_IsDstBlockValid(unpackedData, psubblk[subblk])) return false; dwSize = psubblk[subblk].unpk_size; - pDest = pBuffer + psubblk[subblk].unpk_pos; + pDest = &(unpackedData[psubblk[subblk].unpk_pos]); } } } } - *ppMemFile = pBuffer; - *pdwMemLength = dwFileSize; - return TRUE; + + return true; } @@ -302,19 +398,21 @@ // XPK unpacker // + #ifdef NEEDS_PRAGMA_PACK #pragma pack(push, 1) #endif -typedef struct PACKED _XPKFILEHEADER +struct PACKED XPKFILEHEADER { - DWORD dwXPKF; - DWORD dwSrcLen; - DWORD dwSQSH; - DWORD dwDstLen; - CHAR szName[16]; - DWORD dwReserved; -} XPKFILEHEADER, *PXPKFILEHEADER; + char XPKF[4]; + uint32 SrcLen; + char SQSH[4]; + uint32 DstLen; + char Name[16]; + uint32 Reserved; + void ConvertEndianness(); +}; STATIC_ASSERT(sizeof(XPKFILEHEADER) == 36); @@ -322,14 +420,38 @@ #pragma pack(pop) #endif +void XPKFILEHEADER::ConvertEndianness() +//------------------------------------- +{ + SwapBytesBE(SrcLen); + SwapBytesBE(DstLen); + SwapBytesBE(Reserved); +} -static int bfextu(const BYTE *p,int bo,int bc) + +struct XPK_BufferBounds { - int r; + const uint8 *pSrcBeg; + const uint8 *pSrcEnd; + uint8 *pDstBeg; + uint8 *pDstEnd; +}; + +struct XPK_error : public std::range_error +{ + XPK_error() : std::range_error("invalid XPK data") { } +}; + +static int32 bfextu(const uint8 *p, int32 bo, int32 bc, XPK_BufferBounds &bufs) +//----------------------------------------------------------------------------- +{ + int32 r; p += bo / 8; + if(p < bufs.pSrcBeg || p >= bufs.pSrcEnd) throw XPK_error(); r = *(p++); r <<= 8; + if(p < bufs.pSrcBeg || p >= bufs.pSrcEnd) throw XPK_error(); r |= *(p++); r <<= 8; r |= *p; @@ -340,13 +462,16 @@ return r; } -static int bfexts(const BYTE *p,int bo,int bc) +static int32 bfexts(const uint8 *p, int32 bo, int32 bc, XPK_BufferBounds &bufs) +//----------------------------------------------------------------------------- { - int r; + int32 r; p += bo / 8; + if(p < bufs.pSrcBeg || p >= bufs.pSrcEnd) throw XPK_error(); r = *(p++); r <<= 8; + if(p < bufs.pSrcBeg || p >= bufs.pSrcEnd) throw XPK_error(); r |= *(p++); r <<= 8; r |= *p; @@ -357,19 +482,30 @@ } -void XPK_DoUnpack(const BYTE *src, UINT, BYTE *dst, int len) +static bool XPK_DoUnpack(const uint8 *src, uint32 srcLen, uint8 *dst, int32 len) +//------------------------------------------------------------------------------ { - static BYTE xpk_table[] = { 2,3,4,5,6,7,8,0,3,2,4,5,6,7,8,0,4,3,5,2,6,7,8,0,5,4, - 6,2,3,7,8,0,6,5,7,2,3,4,8,0,7,6,8,2,3,4,5,0,8,7,6,2,3,4,5,0 }; - int d0,d1,d2,d3,d4,d5,d6,a2,a5; - int cp, cup1, type; - const BYTE *c; - BYTE *phist; - BYTE *dstmax = dst + len; + if(len <= 0) return false; + static uint8 xpk_table[] = { + 2,3,4,5,6,7,8,0,3,2,4,5,6,7,8,0,4,3,5,2,6,7,8,0,5,4,6,2,3,7,8,0,6,5,7,2,3,4,8,0,7,6,8,2,3,4,5,0,8,7,6,2,3,4,5,0 + }; + int32 d0,d1,d2,d3,d4,d5,d6,a2,a5; + int32 cp, cup1, type; + const uint8 *c; + uint8 *phist = nullptr; + uint8 *dstmax = dst + len; + + XPK_BufferBounds bufs; + bufs.pSrcBeg = src; + bufs.pSrcEnd = src + srcLen; + bufs.pDstBeg = dst; + bufs.pDstEnd = dst + len; c = src; while (len > 0) { + if(&(c[0]) < bufs.pSrcBeg || &(c[0]) >= bufs.pSrcEnd) throw XPK_error(); + if(&(c[7]) < bufs.pSrcBeg || &(c[7]) >= bufs.pSrcEnd) throw XPK_error(); type = c[0]; cp = (c[4]<<8) | (c[5]); // packed cup1 = (c[6]<<8) | (c[7]); // unpacked @@ -379,6 +515,10 @@ if (type == 0) { // RAW chunk + if(c < bufs.pSrcBeg || c >= bufs.pSrcEnd) throw XPK_error(); + if(c + cp > bufs.pSrcEnd) throw XPK_error(); + if(dst < bufs.pDstBeg || dst >= bufs.pDstEnd) throw XPK_error(); + if(dst + cp > bufs.pDstEnd) throw XPK_error(); memcpy(dst,c,cp); dst+=cp; c+=cp; @@ -399,32 +539,33 @@ d0 = d1 = d2 = a2 = 0; d3 = *(src++); - *dst = (BYTE)d3; + if(dst < bufs.pDstBeg || dst >= bufs.pDstEnd) throw XPK_error(); + *dst = (uint8)d3; if (dst < dstmax) dst++; cup1--; while (cup1 > 0) { if (d1 >= 8) goto l6dc; - if (bfextu(src,d0,1)) goto l75a; + if (bfextu(src,d0,1,bufs)) goto l75a; d0 += 1; d5 = 0; d6 = 8; goto l734; l6dc: - if (bfextu(src,d0,1)) goto l726; + if (bfextu(src,d0,1,bufs)) goto l726; d0 += 1; - if (! bfextu(src,d0,1)) goto l75a; + if (! bfextu(src,d0,1,bufs)) goto l75a; d0 += 1; - if (bfextu(src,d0,1)) goto l6f6; + if (bfextu(src,d0,1,bufs)) goto l6f6; d6 = 2; goto l708; l6f6: d0 += 1; - if (!bfextu(src,d0,1)) goto l706; - d6 = bfextu(src,d0,3); + if (!bfextu(src,d0,1,bufs)) goto l706; + d6 = bfextu(src,d0,3,bufs); d0 += 3; goto l70a; @@ -456,10 +597,11 @@ l734: while ((d5 >= 0) && (cup1 > 0)) { - d4 = bfexts(src,d0,d6); + d4 = bfexts(src,d0,d6,bufs); d0 += d6; d3 -= d4; - *dst = (BYTE)d3; + if(dst < bufs.pDstBeg || dst >= bufs.pDstEnd) throw XPK_error(); + *dst = (uint8)d3; if (dst < dstmax) dst++; cup1--; d5--; @@ -472,52 +614,52 @@ d2 -= d6; } } - return; + return true; l75a: d0 += 1; - if (bfextu(src,d0,1)) goto l766; + if (bfextu(src,d0,1,bufs)) goto l766; d4 = 2; goto l79e; l766: d0 += 1; - if (bfextu(src,d0,1)) goto l772; + if (bfextu(src,d0,1,bufs)) goto l772; d4 = 4; goto l79e; l772: d0 += 1; - if (bfextu(src,d0,1)) goto l77e; + if (bfextu(src,d0,1,bufs)) goto l77e; d4 = 6; goto l79e; l77e: d0 += 1; - if (bfextu(src,d0,1)) goto l792; + if (bfextu(src,d0,1,bufs)) goto l792; d0 += 1; - d6 = bfextu(src,d0,3); + d6 = bfextu(src,d0,3,bufs); d0 += 3; d6 += 8; goto l7a8; l792: d0 += 1; - d6 = bfextu(src,d0,5); + d6 = bfextu(src,d0,5,bufs); d0 += 5; d4 = 16; goto l7a6; l79e: d0 += 1; - d6 = bfextu(src,d0,1); + d6 = bfextu(src,d0,1,bufs); d0 += 1; l7a6: d6 += d4; l7a8: - if (bfextu(src,d0,1)) goto l7c4; + if (bfextu(src,d0,1,bufs)) goto l7c4; d0 += 1; - if (bfextu(src,d0,1)) goto l7bc; + if (bfextu(src,d0,1,bufs)) goto l7bc; d5 = 8; a5 = 0; goto l7ca; @@ -532,7 +674,7 @@ a5 = -0x100; l7ca: d0 += 1; - d4 = bfextu(src,d0,d5); + d4 = bfextu(src,d0,d5,bufs); d0 += d5; d6 -= 3; if (d6 >= 0) @@ -546,8 +688,10 @@ while ((d6 >= 0) && (cup1 > 0)) { + if(phist < bufs.pDstBeg || phist >= bufs.pDstEnd) throw XPK_error(); d3 = *phist++; - *dst = (BYTE)d3; + if(dst < bufs.pDstBeg || dst >= bufs.pDstEnd) throw XPK_error(); + *dst = (uint8)d3; if (dst < dstmax) dst++; cup1--; d6--; @@ -556,27 +700,34 @@ } -BOOL XPK_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength) +bool UnpackXPK(std::vector<char> &unpackedData, FileReader &file) +//--------------------------------------------------------------- { - DWORD dwMemLength = *pdwMemLength; - LPCBYTE lpMemFile = *ppMemFile; - PXPKFILEHEADER pxfh = (PXPKFILEHEADER)lpMemFile; - DWORD dwSrcLen, dwDstLen; - LPBYTE pBuffer; + file.Rewind(); + unpackedData.clear(); - if ((!pxfh) || (dwMemLength < 256) - || (pxfh->dwXPKF != MULTICHAR4_LE_MSVC('F','K','P','X')) || (pxfh->dwSQSH != MULTICHAR4_LE_MSVC('H','S','Q','S'))) return FALSE; - dwSrcLen = BigEndian(pxfh->dwSrcLen); - dwDstLen = BigEndian(pxfh->dwDstLen); - if ((dwSrcLen+8 > dwMemLength) || (dwSrcLen < 256) || (dwDstLen < 256)) return FALSE; + XPKFILEHEADER header; + if(!file.ReadConvertEndianness(header)) return false; + if(std::memcmp(header.XPKF, "XPKF", 4) != 0) return false; + if(std::memcmp(header.SQSH, "SQSH", 4) != 0) return false; + if(header.SrcLen == 0) return false; + if(header.DstLen == 0) return false; + if(!file.CanRead(header.SrcLen + 8 - sizeof(XPKFILEHEADER))) return false; + #ifdef MMCMP_LOG - Log("XPK detected (SrcLen=%d DstLen=%d) filesize=%d\n", dwSrcLen, dwDstLen, dwMemLength); + Log("XPK detected (SrcLen=%d DstLen=%d) filesize=%d\n", header.SrcLen, header.DstLen, file.GetLength()); #endif - if ((pBuffer = (LPBYTE)calloc(1, (dwDstLen + 31) & ~15)) == NULL) return FALSE; - XPK_DoUnpack(lpMemFile+sizeof(XPKFILEHEADER), dwSrcLen+8-sizeof(XPKFILEHEADER), pBuffer, dwDstLen); - *ppMemFile = pBuffer; - *pdwMemLength = dwDstLen; - return TRUE; + unpackedData.resize(header.DstLen); + bool result = false; + try + { + result = XPK_DoUnpack(reinterpret_cast<const uint8 *>(file.GetRawData()), header.SrcLen + 8 - sizeof(XPKFILEHEADER), reinterpret_cast<uint8 *>(&(unpackedData[0])), header.DstLen); + } catch(XPK_error&) + { + return false; + } + + return result; } @@ -585,22 +736,27 @@ // PowerPack PP20 Unpacker // -typedef struct _PPBITBUFFER + +static const uint32 PP20_PACKED_SIZE_MIN = 8; + + +struct PPBITBUFFER { - UINT bitcount; - ULONG bitbuffer; - LPCBYTE pStart; - LPCBYTE pSrc; + uint32 bitcount; + uint32 bitbuffer; + const uint8 *pStart; + const uint8 *pSrc; - ULONG GetBits(UINT n); -} PPBITBUFFER; + uint32 GetBits(uint32 n); +}; -ULONG PPBITBUFFER::GetBits(UINT n) +uint32 PPBITBUFFER::GetBits(uint32 n) +//----------------------------------- { - ULONG result = 0; + uint32 result = 0; - for (UINT i=0; i<n; i++) + for (uint32 i=0; i<n; i++) { if (!bitcount) { @@ -616,10 +772,11 @@ } -void PP20_DoUnpack(const BYTE *pSrc, UINT nSrcLen, BYTE *pDst, UINT nDstLen) +static bool PP20_DoUnpack(const uint8 *pSrc, uint32 nSrcLen, uint8 *pDst, uint32 nDstLen) +//--------------------------------------------------------------------------------------- { PPBITBUFFER BitBuffer; - ULONG nBytesLeft; + uint32 nBytesLeft; BitBuffer.pStart = pSrc; BitBuffer.pSrc = pSrc + nSrcLen - 4; @@ -631,29 +788,30 @@ { if (!BitBuffer.GetBits(1)) { - UINT n = 1; + uint32 n = 1; while (n < nBytesLeft) { - UINT code = BitBuffer.GetBits(2); + uint32 code = BitBuffer.GetBits(2); n += code; if (code != 3) break; } - for (UINT i=0; i<n; i++) + for (uint32 i=0; i<n; i++) { - pDst[--nBytesLeft] = (BYTE)BitBuffer.GetBits(8); + pDst[--nBytesLeft] = (uint8)BitBuffer.GetBits(8); } if (!nBytesLeft) break; } { - UINT n = BitBuffer.GetBits(2)+1; - UINT nbits = pSrc[n-1]; - UINT nofs; + uint32 n = BitBuffer.GetBits(2)+1; + if(n < 1 || n-1 >= nSrcLen) return false; + uint32 nbits = pSrc[n-1]; + uint32 nofs; if (n==4) { nofs = BitBuffer.GetBits( (BitBuffer.GetBits(1)) ? nbits : 7 ); while (n < nBytesLeft) { - UINT code = BitBuffer.GetBits(3); + uint32 code = BitBuffer.GetBits(3); n += code; if (code != 7) break; } @@ -661,35 +819,35 @@ { nofs = BitBuffer.GetBits(nbits); } - for (UINT i=0; i<=n; i++) + for (uint32 i=0; i<=n; i++) { pDst[nBytesLeft-1] = (nBytesLeft+nofs < nDstLen) ? pDst[nBytesLeft+nofs] : 0; if (!--nBytesLeft) break; } } } + return true; } -BOOL PP20_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength) +bool UnpackPP20(std::vector<char> &unpackedData, FileReader &file) +//---------------------------------------------------------------- { - DWORD dwMemLength = *pdwMemLength; - LPCBYTE lpMemFile = *ppMemFile; - DWORD dwDstLen; - LPBYTE pBuffer; + file.Rewind(); + unpackedData.clear(); - if ((!lpMemFile) || (dwMemLength < 256) || (*(DWORD *)lpMemFile != MULTICHAR4_LE_MSVC('0','2','P','P'))) return FALSE; - dwDstLen = (lpMemFile[dwMemLength-4]<<16) | (lpMemFile[dwMemLength-3]<<8) | (lpMemFile[dwMemLength-2]); - //Log("PP20 detected: Packed length=%d, Unpacked length=%d\n", dwMemLength, dwDstLen); - if ((dwDstLen < 512) || (dwDstLen > 0x400000) || (dwDstLen > 16*dwMemLength)) return FALSE; - if ((pBuffer = (LPBYTE)calloc(1, (dwDstLen + 31) & ~15)) == NULL) return FALSE; - PP20_DoUnpack(lpMemFile+4, dwMemLength-4, pBuffer, dwDstLen); - *ppMemFile = pBuffer; - *pdwMemLength = dwDstLen; - return TRUE; + if(!file.CanRead(PP20_PACKED_SIZE_MIN)) return false; + if(!file.ReadMagic("PP20")) return false; + file.Seek(file.GetLength() - 4); + uint32 dstLen = 0; + dstLen |= file.ReadUint8() << 16; + dstLen |= file.ReadUint8() << 8; + dstLen |= file.ReadUint8() << 0; + if(dstLen == 0) return false; + unpackedData.resize(dstLen); + file.Seek(4); + bool result = PP20_DoUnpack(reinterpret_cast<const uint8 *>(file.GetRawData()), file.GetLength() - 4, reinterpret_cast<uint8 *>(&(unpackedData[0])), dstLen); + + return result; } - - - - Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2014-02-04 16:14:11 UTC (rev 3650) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2014-02-04 16:17:27 UTC (rev 3651) @@ -30,9 +30,12 @@ #include "../unarchiver/unarchiver.h" #endif // NO_ARCHIVE_SUPPORT -extern BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength); +bool UnpackXPK(std::vector<char> &unpackedData, FileReader &file); +bool UnpackPP20(std::vector<char> &unpackedData, FileReader &file); +bool UnpackMMCMP(std::vector<char> &unpackedData, FileReader &file); + // -> CODE#0027 // -> DESC="per-instrument volume ramping setup (refered as attack)" @@ -758,10 +761,16 @@ } #endif - BOOL bMMCmp = MMCMP_Unpack(&lpStream, &dwMemLength); - if(bMMCmp) + bool packed = false; + std::vector<char> unpackedData; + if(!packed && UnpackXPK(unpackedData, file)) packed = true; + if(!packed && UnpackPP20(unpackedData, file)) packed = true; + if(!packed && UnpackMMCMP(unpackedData, file)) packed = true; + if(packed) { - file = FileReader(lpStream, dwMemLength); + file = FileReader(&(unpackedData[0]), unpackedData.size()); + lpStream = (LPCBYTE)file.GetRawData(); + dwMemLength = file.GetLength(); } if(!ReadXM(file, loadFlags) @@ -824,12 +833,6 @@ } #endif - if(bMMCmp) - { - free((void*)lpStream); - lpStream = NULL; - } - } else { // New song This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <man...@us...> - 2014-02-04 20:25:05
|
Revision: 3659 http://sourceforge.net/p/modplug/code/3659 Author: manxorist Date: 2014-02-04 20:24:58 +0000 (Tue, 04 Feb 2014) Log Message: ----------- [New] libopenmpt: Remember the module packer type in the container type field. Modified Paths: -------------- trunk/OpenMPT/libopenmpt/foo_openmpt.cpp trunk/OpenMPT/soundlib/Snd_defs.h trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Tables.cpp Modified: trunk/OpenMPT/libopenmpt/foo_openmpt.cpp =================================================================== --- trunk/OpenMPT/libopenmpt/foo_openmpt.cpp 2014-02-04 20:13:54 UTC (rev 3658) +++ trunk/OpenMPT/libopenmpt/foo_openmpt.cpp 2014-02-04 20:24:58 UTC (rev 3659) @@ -165,4 +165,7 @@ "*.j2b" ";" "*.gdm" ";" "*.umx" ";" - "*.mo3" ); + "*.mo3" ";" + "*.xpk" ";" + "*.ppm" ";" + "*.mmcmp" ); Modified: trunk/OpenMPT/soundlib/Snd_defs.h =================================================================== --- trunk/OpenMPT/soundlib/Snd_defs.h 2014-02-04 20:13:54 UTC (rev 3658) +++ trunk/OpenMPT/soundlib/Snd_defs.h 2014-02-04 20:24:58 UTC (rev 3659) @@ -114,6 +114,9 @@ MOD_CONTAINERTYPE_MO3 = 0x1, MOD_CONTAINERTYPE_GDM = 0x2, MOD_CONTAINERTYPE_UMX = 0x3, + MOD_CONTAINERTYPE_XPK = 0x4, + MOD_CONTAINERTYPE_PP20 = 0x5, + MOD_CONTAINERTYPE_MMCMP= 0x6, }; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2014-02-04 20:13:54 UTC (rev 3658) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2014-02-04 20:24:58 UTC (rev 3659) @@ -761,12 +761,12 @@ } #endif - bool packed = false; + MODCONTAINERTYPE packedContainerType = MOD_CONTAINERTYPE_NONE; std::vector<char> unpackedData; - if(!packed && UnpackXPK(unpackedData, file)) packed = true; - if(!packed && UnpackPP20(unpackedData, file)) packed = true; - if(!packed && UnpackMMCMP(unpackedData, file)) packed = true; - if(packed) + if(packedContainerType == MOD_CONTAINERTYPE_NONE && UnpackXPK(unpackedData, file)) packedContainerType = MOD_CONTAINERTYPE_XPK; + if(packedContainerType == MOD_CONTAINERTYPE_NONE && UnpackPP20(unpackedData, file)) packedContainerType = MOD_CONTAINERTYPE_PP20; + if(packedContainerType == MOD_CONTAINERTYPE_NONE && UnpackMMCMP(unpackedData, file)) packedContainerType = MOD_CONTAINERTYPE_MMCMP; + if(packedContainerType != MOD_CONTAINERTYPE_NONE) { file = FileReader(&(unpackedData[0]), unpackedData.size()); lpStream = (LPCBYTE)file.GetRawData(); @@ -820,6 +820,11 @@ m_ContainerType = MOD_CONTAINERTYPE_NONE; } + if(packedContainerType != MOD_CONTAINERTYPE_NONE && m_ContainerType == MOD_CONTAINERTYPE_NONE) + { + m_ContainerType = packedContainerType; + } + if(madeWithTracker.empty()) { madeWithTracker = ModTypeToTracker(GetType()); Modified: trunk/OpenMPT/soundlib/Tables.cpp =================================================================== --- trunk/OpenMPT/soundlib/Tables.cpp 2014-02-04 20:13:54 UTC (rev 3658) +++ trunk/OpenMPT/soundlib/Tables.cpp 2014-02-04 20:24:58 UTC (rev 3659) @@ -98,11 +98,14 @@ static const ModContainerInfo modContainerInfo[] = { // Container formats - { MOD_CONTAINERTYPE_GDM, "General Digital Music", "gdm" }, - { MOD_CONTAINERTYPE_UMX, "Unreal Music", "umx" }, + { MOD_CONTAINERTYPE_GDM, "General Digital Music", "gdm" }, + { MOD_CONTAINERTYPE_UMX, "Unreal Music", "umx" }, #ifndef NO_MO3 - { MOD_CONTAINERTYPE_MO3, "Un4seen MO3", "mo3" }, + { MOD_CONTAINERTYPE_MO3, "Un4seen MO3", "mo3" }, #endif // NO_MO3 + { MOD_CONTAINERTYPE_XPK, "XPK packed", "xpk" }, + { MOD_CONTAINERTYPE_PP20, "PowerPack PP20", "ppm" }, + { MOD_CONTAINERTYPE_MMCMP, "Music Module Compressor", "mmcmp" } }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <man...@us...> - 2014-02-05 13:33:12
|
Revision: 3662 http://sourceforge.net/p/modplug/code/3662 Author: manxorist Date: 2014-02-05 13:33:04 +0000 (Wed, 05 Feb 2014) Log Message: ----------- [New] Mod Export: Allow selecting or disabling dither. Modified Paths: -------------- trunk/OpenMPT/mptrack/Mod2wave.cpp trunk/OpenMPT/mptrack/Mpdlgs.cpp trunk/OpenMPT/mptrack/mod2wave.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/soundlib/Dither.cpp trunk/OpenMPT/soundlib/Dither.h Modified: trunk/OpenMPT/mptrack/Mod2wave.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mod2wave.cpp 2014-02-05 02:27:35 UTC (rev 3661) +++ trunk/OpenMPT/mptrack/Mod2wave.cpp 2014-02-05 13:33:04 UTC (rev 3662) @@ -119,6 +119,7 @@ ON_CBN_SELCHANGE(IDC_COMBO5, OnFileTypeChanged) ON_CBN_SELCHANGE(IDC_COMBO1, OnSamplerateChanged) ON_CBN_SELCHANGE(IDC_COMBO4, OnChannelsChanged) + ON_CBN_SELCHANGE(IDC_COMBO6, OnDitherChanged) ON_CBN_SELCHANGE(IDC_COMBO2, OnFormatChanged) END_MESSAGE_MAP() @@ -153,6 +154,7 @@ DDX_Control(pDX, IDC_COMBO5, m_CbnFileType); DDX_Control(pDX, IDC_COMBO1, m_CbnSampleRate); DDX_Control(pDX, IDC_COMBO4, m_CbnChannels); + DDX_Control(pDX, IDC_COMBO6, m_CbnDither); DDX_Control(pDX, IDC_COMBO2, m_CbnSampleFormat); DDX_Control(pDX, IDC_SPIN3, m_SpinMinOrder); DDX_Control(pDX, IDC_SPIN4, m_SpinMaxOrder); @@ -196,6 +198,7 @@ FillSamplerates(); FillChannels(); FillFormats(); + FillDither(); LoadTags(); @@ -520,6 +523,33 @@ } +void CWaveConvert::FillDither() +//----------------------------- +{ + Encoder::Settings &encSettings = m_Settings.GetEncoderSettings(); + m_CbnDither.CComboBox::ResetContent(); + int format = m_CbnSampleFormat.GetItemData(m_CbnSampleFormat.GetCurSel()) & 0xffff; + if((encTraits->modes & Encoder::ModeEnumerated) && encTraits->formats[format].Sampleformat != SampleFormatInvalid && encTraits->formats[format].Sampleformat != SampleFormatFloat32) + { + m_CbnDither.EnableWindow(TRUE); + for(int dither = 0; dither < NumDitherModes; ++dither) + { + int ndx = m_CbnDither.AddString(mpt::ToCString(Dither::GetModeName((DitherMode)dither) + L" dither")); + m_CbnDither.SetItemData(ndx, dither); + } + } else + { + m_CbnDither.EnableWindow(FALSE); + for(int dither = 0; dither < NumDitherModes; ++dither) + { + int ndx = m_CbnDither.AddString(mpt::ToCString(Dither::GetModeName(DitherNone) + L" dither")); + m_CbnDither.SetItemData(ndx, dither); + } + } + m_CbnDither.SetCurSel(encSettings.Dither); +} + + void CWaveConvert::OnFileTypeChanged() //------------------------------------ { @@ -530,6 +560,7 @@ FillSamplerates(); FillChannels(); FillFormats(); + FillDither(); FillTags(); } @@ -540,6 +571,7 @@ SaveEncoderSettings(); //DWORD dwSamplerate = m_CbnSampleRate.GetItemData(m_CbnSampleRate.GetCurSel()); FillFormats(); + FillDither(); } @@ -549,14 +581,23 @@ SaveEncoderSettings(); //UINT nChannels = m_CbnChannels.GetItemData(m_CbnChannels.GetCurSel()); FillFormats(); + FillDither(); } +void CWaveConvert::OnDitherChanged() +//---------------------------------- +{ + SaveEncoderSettings(); +} + + void CWaveConvert::OnFormatChanged() //---------------------------------- { SaveEncoderSettings(); //DWORD dwFormat = m_CbnSampleFormat.GetItemData(m_CbnSampleFormat.GetCurSel()); + FillDither(); FillTags(); } @@ -755,6 +796,7 @@ { m_Settings.FinalSampleFormat = encTraits->formats[format].Sampleformat; } + encSettings.Dither = m_CbnDither.GetItemData(m_CbnDither.GetCurSel()); encSettings.Format = format; encSettings.Mode = Encoder::ModeEnumerated; encSettings.Bitrate = encTraits->formats[format].Bitrate != 0 ? encTraits->formats[format].Bitrate : encTraits->defaultBitrate; @@ -762,6 +804,7 @@ } else { m_Settings.FinalSampleFormat = SampleFormatFloat32; + encSettings.Dither = m_CbnDither.GetItemData(m_CbnDither.GetCurSel()); Encoder::Mode mode = (Encoder::Mode)((dwFormat >> 24) & 0xff); int quality = (int)((dwFormat >> 0) & 0xff); int bitrate = (int)((dwFormat >> 0) & 0xffff); Modified: trunk/OpenMPT/mptrack/Mpdlgs.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mpdlgs.cpp 2014-02-05 02:27:35 UTC (rev 3661) +++ trunk/OpenMPT/mptrack/Mpdlgs.cpp 2014-02-05 13:33:04 UTC (rev 3662) @@ -390,20 +390,20 @@ if(sampleFormat.IsInt()) { m_CbnDither.EnableWindow(TRUE); - m_CbnDither.AddString("no dithering"); - m_CbnDither.AddString("default dithering"); - m_CbnDither.AddString("0.5bit dithering"); - m_CbnDither.AddString("1bit dithering"); + for(int i=0; i<NumDitherModes; ++i) + { + m_CbnDither.AddString(mpt::ToCString(Dither::GetModeName((DitherMode)i) + L" dithering")); + } } else if(m_CurrentDeviceCaps.HasInternalDither) { m_CbnDither.EnableWindow(TRUE); - m_CbnDither.AddString("no dithering"); - m_CbnDither.AddString("default dithering"); + m_CbnDither.AddString(mpt::ToCString(Dither::GetModeName(DitherNone) + L" dithering")); + m_CbnDither.AddString(mpt::ToCString(Dither::GetModeName(DitherDefault) + L" dithering")); } else { m_CbnDither.EnableWindow(FALSE); - m_CbnDither.AddString("no dithering"); - m_CbnDither.AddString("no dithering"); + m_CbnDither.AddString(mpt::ToCString(Dither::GetModeName(DitherNone) + L" dithering")); + m_CbnDither.AddString(mpt::ToCString(Dither::GetModeName(DitherNone) + L" dithering")); } if(m_Settings.DitherType < 0 || m_Settings.DitherType > m_CbnDither.GetCount()) { Modified: trunk/OpenMPT/mptrack/mod2wave.h =================================================================== --- trunk/OpenMPT/mptrack/mod2wave.h 2014-02-05 02:27:35 UTC (rev 3661) +++ trunk/OpenMPT/mptrack/mod2wave.h 2014-02-05 13:33:04 UTC (rev 3662) @@ -71,7 +71,7 @@ uint64 m_dwFileLimit, m_dwSongLimit; ORDERINDEX m_nNumOrders; - CComboBox m_CbnFileType, m_CbnSampleRate, m_CbnChannels, m_CbnSampleFormat; + CComboBox m_CbnFileType, m_CbnSampleRate, m_CbnChannels, m_CbnDither, m_CbnSampleFormat; CSpinButtonCtrl m_SpinLoopCount, m_SpinMinOrder, m_SpinMaxOrder; bool m_bGivePlugsIdleTime; @@ -88,6 +88,7 @@ void FillSamplerates(); void FillChannels(); void FillFormats(); + void FillDither(); void FillTags(); void LoadTags(); @@ -110,6 +111,7 @@ afx_msg void OnFileTypeChanged(); afx_msg void OnSamplerateChanged(); afx_msg void OnChannelsChanged(); + afx_msg void OnDitherChanged(); afx_msg void OnFormatChanged(); afx_msg void OnPlayerOptions(); //rewbs.resamplerConf DECLARE_MESSAGE_MAP() Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2014-02-05 02:27:35 UTC (rev 3661) +++ trunk/OpenMPT/mptrack/mptrack.rc 2014-02-05 13:33:04 UTC (rev 3662) @@ -470,8 +470,9 @@ GROUPBOX "Format",IDC_STATIC,6,6,186,66 COMBOBOX IDC_COMBO5,12,18,90,82,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Encoder Information",IDC_BUTTON1,108,18,78,12 - COMBOBOX IDC_COMBO1,12,36,90,82,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBO4,108,36,78,82,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO1,12,36,54,82,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO4,72,36,42,82,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO6,120,36,66,82,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO2,12,54,174,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP GROUPBOX "Render",IDC_STATIC,6,78,186,84 PUSHBUTTON "Player &Options",IDC_PLAYEROPTIONS,12,90,60,14,BS_CENTER Modified: trunk/OpenMPT/soundlib/Dither.cpp =================================================================== --- trunk/OpenMPT/soundlib/Dither.cpp 2014-02-05 02:27:35 UTC (rev 3661) +++ trunk/OpenMPT/soundlib/Dither.cpp 2014-02-05 13:33:04 UTC (rev 3662) @@ -19,6 +19,21 @@ ////////////////////////////////////////////////////////////////////////// // Noise Shaping (Dithering) + +std::wstring Dither::GetModeName(DitherMode mode) +//----------------------------------------------- +{ + switch(mode) + { + case DitherNone : return L"no" ; break; + case DitherDefault: return L"default"; break; + case DitherModPlug: return L"0.5 bit"; break; + case DitherSimple : return L"1 bit" ; break; + default : return L"" ; break; + } +} + + #if MPT_COMPILER_MSVC #pragma warning(disable:4731) // ebp modified #endif Modified: trunk/OpenMPT/soundlib/Dither.h =================================================================== --- trunk/OpenMPT/soundlib/Dither.h 2014-02-05 02:27:35 UTC (rev 3661) +++ trunk/OpenMPT/soundlib/Dither.h 2014-02-05 13:33:04 UTC (rev 3662) @@ -47,7 +47,8 @@ DitherNone = 0, DitherDefault = 1, // chosen by OpenMPT code, might change DitherModPlug = 2, // rectangular, 0.5 bit depth, no noise shaping (original ModPlug Tracker) - DitherSimple = 3 // rectangular, 1 bit depth, simple 1st order noise shaping + DitherSimple = 3, // rectangular, 1 bit depth, simple 1st order noise shaping + NumDitherModes }; class Dither @@ -61,4 +62,5 @@ DitherMode GetMode() const; void Reset(); void Process(int *mixbuffer, std::size_t count, std::size_t channels, int bits); + static std::wstring GetModeName(DitherMode mode); }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-02-05 21:19:06
|
Revision: 3664 http://sourceforge.net/p/modplug/code/3664 Author: saga-games Date: 2014-02-05 21:18:59 +0000 (Wed, 05 Feb 2014) Log Message: ----------- [Fix] FT2 compatiblity: If there's a note delay, volume column effects are NOT executed on the first tick and on delayed tick. Test case: VolColDelay.xm [Mod] OpenMPT: Version is now 1.22.07.19 Modified Paths: -------------- trunk/OpenMPT/common/versionNumber.h trunk/OpenMPT/soundlib/Snd_fx.cpp Modified: trunk/OpenMPT/common/versionNumber.h =================================================================== --- trunk/OpenMPT/common/versionNumber.h 2014-02-05 17:40:12 UTC (rev 3663) +++ trunk/OpenMPT/common/versionNumber.h 2014-02-05 21:18:59 UTC (rev 3664) @@ -17,7 +17,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 22 #define VER_MINOR 07 -#define VER_MINORMINOR 18 +#define VER_MINORMINOR 19 //Version string. For example "1.17.02.28" #define MPT_VERSION_STR VER_STRINGIZE(VER_MAJORMAJOR) "." VER_STRINGIZE(VER_MAJOR) "." VER_STRINGIZE(VER_MINOR) "." VER_STRINGIZE(VER_MINORMINOR) Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-02-05 17:40:12 UTC (rev 3663) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-02-05 21:18:59 UTC (rev 3664) @@ -2092,8 +2092,15 @@ so... hxx = (hx | (oldhxx & 0xf0)) ??? TODO is this done correctly? */ - if((volcmd > VOLCMD_PANNING) && (m_nTickCount >= nStartTick)) + bool doVolumeColumn = m_nTickCount >= nStartTick; + // FT2 compatibility: If there's a note delay, volume column effects are NOT executed on the first tick and on delayed tick. + // Test case: VolColDelay.xm + if(IsCompatibleMode(TRK_FASTTRACKER2) && nStartTick != 0) { + doVolumeColumn = m_nTickCount != 0 && m_nTickCount != nStartTick; + } + if(volcmd > VOLCMD_PANNING && doVolumeColumn) + { if (volcmd == VOLCMD_TONEPORTAMENTO) { UINT param = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-02-08 22:36:38
|
Revision: 3672 http://sourceforge.net/p/modplug/code/3672 Author: saga-games Date: 2014-02-08 22:36:26 +0000 (Sat, 08 Feb 2014) Log Message: ----------- [Imp] Mod Conversion: When converting to MOD, try to compensate for the lack of sample tranpose by transposing pattern notes. [Fix] Mod Conversion: When converting from XM to MOD, the sample transpose wasn't reset. Modified Paths: -------------- trunk/OpenMPT/mptrack/ModConvert.cpp trunk/OpenMPT/soundlib/ModSample.cpp Modified: trunk/OpenMPT/mptrack/ModConvert.cpp =================================================================== --- trunk/OpenMPT/mptrack/ModConvert.cpp 2014-02-07 18:59:41 UTC (rev 3671) +++ trunk/OpenMPT/mptrack/ModConvert.cpp 2014-02-08 22:36:26 UTC (rev 3672) @@ -171,6 +171,15 @@ ///////////////////////////// // Converting pattern data + // When converting to MOD, get the new sample transpose setting right here so that we can compensate notes in the pattern. + if(newTypeIsMOD && !oldTypeIsXM) + { + for(SAMPLEINDEX smp = 1; smp <= m_SndFile.GetNumSamples(); smp++) + { + m_SndFile.GetSample(smp).FrequencyToTranspose(); + } + } + for(PATTERNINDEX pat = 0; pat < m_SndFile.Patterns.Size(); pat++) if (m_SndFile.Patterns[pat]) { ModCommand *m = m_SndFile.Patterns[pat]; @@ -178,6 +187,7 @@ // This is used for -> MOD/XM conversion std::vector<std::vector<ModCommand::PARAM> > effMemory(GetNumChannels()); std::vector<ModCommand::VOL> volMemory(GetNumChannels(), 0); + std::vector<ModCommand::INSTR> instrMemory(GetNumChannels(), 0); for(size_t i = 0; i < GetNumChannels(); i++) { effMemory[i].resize(MAX_EFFECTS, 0); @@ -195,6 +205,10 @@ row++; } + ModCommand::INSTR instr = m->instr; + if(m->instr) instrMemory[chn] = instr; + else instr = instrMemory[chn]; + // Deal with volume column slide memory (it's not shared with the effect column) if(oldTypeIsIT_MPT && (newTypeIsMOD_XM || newTypeIsS3M)) { @@ -247,6 +261,13 @@ break; } + + // Compensate for loss of transpose information + if(m->IsNote() && instr && instr <= GetNumSamples()) + { + const int newNote = m->note + m_SndFile.GetSample(instr).RelativeTone; + m->note = static_cast<uint8>(Clamp(newNote, specs.noteMin, specs.noteMax)); + } } m->Convert(nOldType, nNewType); Modified: trunk/OpenMPT/soundlib/ModSample.cpp =================================================================== --- trunk/OpenMPT/soundlib/ModSample.cpp 2014-02-07 18:59:41 UTC (rev 3671) +++ trunk/OpenMPT/soundlib/ModSample.cpp 2014-02-08 22:36:26 UTC (rev 3672) @@ -29,21 +29,19 @@ } else if((toType & (MOD_TYPE_MOD | MOD_TYPE_XM)) && (!(fromType & (MOD_TYPE_MOD | MOD_TYPE_XM)))) { FrequencyToTranspose(); - if(toType & MOD_TYPE_MOD) - { - RelativeTone = 0; - } } // No ping-pong loop, panning and auto-vibrato for MOD / S3M samples if(toType & (MOD_TYPE_MOD | MOD_TYPE_S3M)) { - uFlags &= ~(CHN_PINGPONGLOOP | CHN_PANNING); + uFlags.reset(CHN_PINGPONGLOOP | CHN_PANNING); nVibDepth = 0; nVibRate = 0; nVibSweep = 0; nVibType = VIB_SINE; + + RelativeTone = 0; } // No global volume sustain loops for MOD/S3M/XM @@ -51,30 +49,24 @@ { nGlobalVol = 64; // Sustain loops - convert to normal loops - if((uFlags & CHN_SUSTAINLOOP) != 0) + if(uFlags[CHN_SUSTAINLOOP]) { // We probably overwrite a normal loop here, but since sustain loops are evaluated before normal loops, this is just correct. nLoopStart = nSustainStart; nLoopEnd = nSustainEnd; - uFlags |= CHN_LOOP; - if(uFlags & CHN_PINGPONGSUSTAIN) - { - uFlags |= CHN_PINGPONGLOOP; - } else - { - uFlags &= ~CHN_PINGPONGLOOP; - } + uFlags.set(CHN_LOOP); + uFlags.set(CHN_PINGPONGLOOP, uFlags[CHN_PINGPONGSUSTAIN]); } nSustainStart = nSustainEnd = 0; - uFlags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); + uFlags.reset(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); } // All XM samples have default panning, and XM's autovibrato settings are rather limited. if(toType & MOD_TYPE_XM) { - if(!(uFlags & CHN_PANNING)) + if(!uFlags[CHN_PANNING]) { - uFlags |= CHN_PANNING; + uFlags.set(CHN_PANNING); nPan = 128; } @@ -302,7 +294,7 @@ int ModSample::FrequencyToTranspose(uint32 freq) //---------------------------------------------- { - const float inv_log_2 = 1.44269504089f; // 1.0f/std::log(2.0f) + const float inv_log_2 = 1.44269504089f; // 1.0f/std::log(2.0f) return Util::Round<int>(std::log(freq * (1.0f / 8363.0f)) * (12.0f * 128.0f * inv_log_2)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-02-09 14:31:08
|
Revision: 3679 http://sourceforge.net/p/modplug/code/3679 Author: saga-games Date: 2014-02-09 14:31:01 +0000 (Sun, 09 Feb 2014) Log Message: ----------- [Fix] Extra toolbar separator was showing up in sample editor. [Ref] Silence compiler warning in View_tre.cpp [Var] Fix some typos Modified Paths: -------------- trunk/OpenMPT/libopenmpt/libopenmpt.hpp trunk/OpenMPT/mptrack/View_smp.h trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/soundlib/SoundFilePlayConfig.h Modified: trunk/OpenMPT/libopenmpt/libopenmpt.hpp =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmpt.hpp 2014-02-09 13:47:26 UTC (rev 3678) +++ trunk/OpenMPT/libopenmpt/libopenmpt.hpp 2014-02-09 14:31:01 UTC (rev 3679) @@ -213,7 +213,7 @@ module(); void set_impl( module_impl * i ); public: - //! Contruct a openmpt::module + //! Construct a openmpt::module /*! \param stream Input stream from which the module is loaded. After the constructor has finished successfully, the input position of stream is set to the byte after the last byte that has been read. If the constructor fails, the state of the input position of stream is undefined. \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. Modified: trunk/OpenMPT/mptrack/View_smp.h =================================================================== --- trunk/OpenMPT/mptrack/View_smp.h 2014-02-09 13:47:26 UTC (rev 3678) +++ trunk/OpenMPT/mptrack/View_smp.h 2014-02-09 14:31:01 UTC (rev 3679) @@ -11,7 +11,7 @@ #pragma once -#define SMP_LEFTBAR_BUTTONS 9 +#define SMP_LEFTBAR_BUTTONS 8 #include "modsmp_ctrl.h" Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2014-02-09 13:47:26 UTC (rev 3678) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2014-02-09 14:31:01 UTC (rev 3679) @@ -517,7 +517,7 @@ for (UINT iPerc=24; iPerc<=84; iPerc++) { DWORD dwImage = IMAGE_NOSAMPLE; - s = mpt::ToWide(mpt::CharsetASCII, CSoundFile::GetNoteName(iPerc + NOTE_MIN)) + L": " + mpt::ToWide(mpt::CharsetASCII, szMidiPercussionNames[iPerc - 24]); + s = mpt::ToWide(mpt::CharsetASCII, CSoundFile::GetNoteName((ModCommand::NOTE)(iPerc + NOTE_MIN))) + L": " + mpt::ToWide(mpt::CharsetASCII, szMidiPercussionNames[iPerc - 24]); const LPARAM param = (MODITEM_MIDIPERCUSSION << MIDILIB_SHIFT) | iPerc; if(!midiLib.MidiMap[iPerc | 0x80].empty()) { Modified: trunk/OpenMPT/soundlib/SoundFilePlayConfig.h =================================================================== --- trunk/OpenMPT/soundlib/SoundFilePlayConfig.h 2014-02-09 13:47:26 UTC (rev 3678) +++ trunk/OpenMPT/soundlib/SoundFilePlayConfig.h 2014-02-09 14:31:01 UTC (rev 3679) @@ -88,8 +88,8 @@ void setExtraSampleAttenuation(int attn) { m_extraAttenuation = attn; } // True if format-specific mixing quirks should be emulated. - bool getEmulateQuirks() const { return m_emualteQuirks; } - void setEmulateQuirks(bool emulate) { m_emualteQuirks = emulate; } + bool getEmulateQuirks() const { return m_emulateQuirks; } + void setEmulateQuirks(bool emulate) { m_emulateQuirks = emulate; } protected: @@ -107,6 +107,6 @@ bool m_globalVolumeAppliesToMaster; bool m_ignorePreAmp; bool m_displayDBValues; - bool m_emualteQuirks; + bool m_emulateQuirks; }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2014-02-09 14:31:58
|
Revision: 3680 http://sourceforge.net/p/modplug/code/3680 Author: saga-games Date: 2014-02-09 14:31:52 +0000 (Sun, 09 Feb 2014) Log Message: ----------- [Imp] Sample autotuner is now multi-threaded. Modified Paths: -------------- trunk/OpenMPT/common/thread.h trunk/OpenMPT/mptrack/Autotune.cpp trunk/OpenMPT/mptrack/Autotune.h trunk/OpenMPT/mptrack/UpdateCheck.cpp trunk/OpenMPT/mptrack/UpdateCheck.h Modified: trunk/OpenMPT/common/thread.h =================================================================== --- trunk/OpenMPT/common/thread.h 2014-02-09 14:31:01 UTC (rev 3679) +++ trunk/OpenMPT/common/thread.h 2014-02-09 14:31:52 UTC (rev 3680) @@ -32,7 +32,7 @@ }; operator HANDLE& () { return threadHandle; } - operator bool () { return threadHandle != nullptr; } + operator bool () const { return threadHandle != nullptr; } thread() : threadHandle(nullptr) { } thread(LPTHREAD_START_ROUTINE function, void *userData = nullptr, Priority priority = normal) Modified: trunk/OpenMPT/mptrack/Autotune.cpp =================================================================== --- trunk/OpenMPT/mptrack/Autotune.cpp 2014-02-09 14:31:01 UTC (rev 3679) +++ trunk/OpenMPT/mptrack/Autotune.cpp 2014-02-09 14:31:52 UTC (rev 3680) @@ -11,6 +11,7 @@ #include "stdafx.h" #include <math.h> #include "../common/misc_util.h" +#include "../common/thread.h" #include "../soundlib/Sndfile.h" #include "Autotune.h" @@ -19,24 +20,28 @@ #define BINS_PER_NOTE 32 #define MIN_SAMPLE_LENGTH 2 +#define START_NOTE (24 * BINS_PER_NOTE) // C-2 +#define END_NOTE (96 * BINS_PER_NOTE) // C-8 +#define HISTORY_BINS (12 * BINS_PER_NOTE) // One octave -double Autotune::FrequencyToNote(double freq, double pitchReference) const -//------------------------------------------------------------------------ + +double Autotune::FrequencyToNote(double freq, double pitchReference) +//------------------------------------------------------------------ { return ((12.0 * (log(freq / (pitchReference / 2.0)) / log(2.0))) + 57.0); } -double Autotune::NoteToFrequency(double note, double pitchReference) const -//------------------------------------------------------------------------ +double Autotune::NoteToFrequency(double note, double pitchReference) +//------------------------------------------------------------------ { return pitchReference * pow(2.0, (note - 69.0) / 12.0); } // Calculate the amount of samples for autocorrelation shifting for a given note -SmpLength Autotune::NoteToShift(uint32 sampleFreq, int note, double pitchReference) const -//--------------------------------------------------------------------------------------- +SmpLength Autotune::NoteToShift(uint32 sampleFreq, int note, double pitchReference) +//--------------------------------------------------------------------------------- { const double fundamentalFrequency = NoteToFrequency((double)note / BINS_PER_NOTE, pitchReference); return std::max(Util::Round<SmpLength>((double)sampleFreq / fundamentalFrequency), SmpLength(1)); @@ -88,13 +93,13 @@ sampleOffset = selectionStart; sampleLoopStart = 0; sampleLoopEnd = selectionEnd - selectionStart; - } else if((sample.uFlags & CHN_SUSTAINLOOP) && sample.nSustainEnd >= sample.nSustainStart + MIN_SAMPLE_LENGTH) + } else if(sample.uFlags[CHN_SUSTAINLOOP] && sample.nSustainEnd >= sample.nSustainStart + MIN_SAMPLE_LENGTH) { // A sustain loop is set: Examine sample up to sustain loop and, if necessary, execute the loop several times sampleOffset = 0; sampleLoopStart = sample.nSustainStart; sampleLoopEnd = sample.nSustainEnd; - } else if((sample.uFlags & CHN_LOOP) && sample.nLoopEnd >= sample.nLoopStart + MIN_SAMPLE_LENGTH) + } else if(sample.uFlags[CHN_LOOP] && sample.nLoopEnd >= sample.nLoopStart + MIN_SAMPLE_LENGTH) { // A normal loop is set: Examine sample up to loop and, if necessary, execute the loop several times sampleOffset = 0; @@ -103,7 +108,7 @@ } // We should analyse at least a one second (= GetSampleRate() samples) long sample. - sampleLength = MAX(sampleLoopEnd, sample.GetSampleRate(modType)) + maxShift; + sampleLength = std::max(sampleLoopEnd, sample.GetSampleRate(modType)) + maxShift; if(sampleData != nullptr) { @@ -139,6 +144,48 @@ } +struct AutotuneThreadData +{ + std::vector<uint64> histogram; + double pitchReference; + int8 *sampleData; + SmpLength processLength; + uint32 sampleFreq; + int startNote, endNote; + +}; + +DWORD WINAPI Autotune::AutotuneThread(void *i) +//-------------------------------------------- +{ + AutotuneThreadData &info = *static_cast<AutotuneThreadData *>(i); + info.histogram.resize(HISTORY_BINS, 0); + + // Do autocorrelation and save results in a note histogram (restriced to one octave). + for(int note = info.startNote, noteBin = note; note < info.endNote; note++, noteBin++) + { + + if(noteBin >= HISTORY_BINS) + { + noteBin %= HISTORY_BINS; + } + + const SmpLength autocorrShift = NoteToShift(info.sampleFreq, note, info.pitchReference); + + uint64 autocorrSum = 0; + const int8 *normalData = info.sampleData; + const int8 *shiftedData = info.sampleData + autocorrShift; + // Add up squared differences of all values + for(SmpLength i = info.processLength; i != 0; i--, normalData++, shiftedData++) + { + autocorrSum += (*normalData - *shiftedData) * (*normalData - *shiftedData); + } + info.histogram[noteBin] += autocorrSum; + } + return 0; +} + + bool Autotune::Apply(double pitchReference, int targetNote) //--------------------------------------------------------- { @@ -147,13 +194,9 @@ return false; } - const int autocorrStartNote = 24 * BINS_PER_NOTE; // C-2 - const int autocorrEndNote = 96 * BINS_PER_NOTE; // C-8 - const int historyBins = 12 * BINS_PER_NOTE; // One octave - const uint32 sampleFreq = sample.GetSampleRate(modType); // At the lowest frequency, we get the highest autocorrelation shift amount. - const SmpLength maxShift = NoteToShift(sampleFreq, autocorrStartNote, pitchReference); + const SmpLength maxShift = NoteToShift(sampleFreq, START_NOTE, pitchReference); if(!PrepareSample(maxShift)) { return false; @@ -161,35 +204,46 @@ // We don't process the autocorrelation overhead. const SmpLength processLength = sampleLength - maxShift; - // Histogram for all notes. - std::vector<uint64> autocorrHistogram(historyBins, 0); + // Set up the autocorrelation threads + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + const uint32 numProcs = std::max<uint32>(sysInfo.dwNumberOfProcessors, 1); + const uint32 notesPerThread = (END_NOTE - START_NOTE + 1) / numProcs; + std::vector<AutotuneThreadData> threadInfo(numProcs); + std::vector<HANDLE> threadHandles(numProcs); - // Do autocorrelation and save results in a note histogram (restriced to one octave). - for(int note = autocorrStartNote, noteBin = note; note < autocorrEndNote; note++, noteBin++) + for(uint32 p = 0; p < numProcs; p++) { + threadInfo[p].pitchReference = pitchReference; + threadInfo[p].sampleData = sampleData; + threadInfo[p].processLength = processLength; + threadInfo[p].sampleFreq = sampleFreq; + threadInfo[p].startNote = START_NOTE + p * notesPerThread; + threadInfo[p].endNote = START_NOTE + (p + 1) * notesPerThread; + if(p == numProcs - 1) + threadInfo[p].endNote = END_NOTE; - if(noteBin >= historyBins) - { - noteBin %= historyBins; - } + threadHandles[p] = mpt::thread(AutotuneThread, &threadInfo[p]); + ASSERT(threadHandles[p] != INVALID_HANDLE_VALUE); + } - const SmpLength autocorrShift = NoteToShift(sampleFreq, note, pitchReference); + WaitForMultipleObjects(numProcs, &threadHandles[0], TRUE, INFINITE); - uint64 autocorrSum = 0; - const int8 *normalData = sampleData; - const int8 *shiftedData = sampleData + autocorrShift; - // Add up squared differences of all values - for(SmpLength i = processLength; i != 0; i--, normalData++, shiftedData++) + // Histogram for all notes. + std::vector<uint64> autocorrHistogram(HISTORY_BINS, 0); + + for(uint32 p = 0; p < numProcs; p++) + { + for(int i = 0; i < HISTORY_BINS; i++) { - autocorrSum += (*normalData - *shiftedData) * (*normalData - *shiftedData); + autocorrHistogram[i] += threadInfo[p].histogram[i]; } - autocorrHistogram[noteBin] += autocorrSum; - + CloseHandle(threadHandles[p]); } // Interpolate the histogram... - std::vector<uint64> interpolatedHistogram(historyBins, 0); - for(int i = 0; i < historyBins; i++) + std::vector<uint64> interpolatedHistogram(HISTORY_BINS, 0); + for(int i = 0; i < HISTORY_BINS; i++) { interpolatedHistogram[i] = autocorrHistogram[i]; const int kernelWidth = 4; @@ -197,9 +251,9 @@ { // Choose bins to interpolate with int left = i - ki; - if(left < 0) left += historyBins; + if(left < 0) left += HISTORY_BINS; int right = i + ki; - if(right >= historyBins) right -= historyBins; + if(right >= HISTORY_BINS) right -= HISTORY_BINS; interpolatedHistogram[i] = interpolatedHistogram[i] / 2 + (autocorrHistogram[left] + autocorrHistogram[right]) / 2; } @@ -207,9 +261,9 @@ // ...and find global minimum int minimumBin = 0; - for(int i = 0; i < historyBins; i++) + for(int i = 0; i < HISTORY_BINS; i++) { - const int prev = (i > 0) ? (i - 1) : (historyBins - 1); + const int prev = (i > 0) ? (i - 1) : (HISTORY_BINS - 1); // Are we at the global minimum? if(interpolatedHistogram[prev] < interpolatedHistogram[minimumBin]) { Modified: trunk/OpenMPT/mptrack/Autotune.h =================================================================== --- trunk/OpenMPT/mptrack/Autotune.h 2014-02-09 14:31:01 UTC (rev 3679) +++ trunk/OpenMPT/mptrack/Autotune.h 2014-02-09 14:31:52 UTC (rev 3680) @@ -42,15 +42,16 @@ bool Apply(double pitchReference, int targetNote); protected: - double FrequencyToNote(double freq, double pitchReference) const; - double NoteToFrequency(double note, double pitchReference) const; - SmpLength NoteToShift(uint32 sampleFreq, int note, double pitchReference) const; + static double FrequencyToNote(double freq, double pitchReference); + static double NoteToFrequency(double note, double pitchReference); + static SmpLength NoteToShift(uint32 sampleFreq, int note, double pitchReference); template <class T> void CopySamples(const T* origSample, SmpLength sampleLoopStart, SmpLength sampleLoopEnd); bool PrepareSample(SmpLength maxShift); + static DWORD WINAPI AutotuneThread(void *i); }; Modified: trunk/OpenMPT/mptrack/UpdateCheck.cpp =================================================================== --- trunk/OpenMPT/mptrack/UpdateCheck.cpp 2014-02-09 14:31:01 UTC (rev 3679) +++ trunk/OpenMPT/mptrack/UpdateCheck.cpp 2014-02-09 14:31:52 UTC (rev 3680) @@ -36,7 +36,8 @@ CUpdateCheck *that = new (std::nothrow) CUpdateCheck(autoUpdate); if(that != nullptr) { - that->threadHandle = mpt::thread_member<CUpdateCheck, &CUpdateCheck::UpdateThread>(that, autoUpdate ? mpt::thread::lower : mpt::thread::normal); + mpt::thread threadHandle = mpt::thread_member<CUpdateCheck, &CUpdateCheck::UpdateThread>(that, autoUpdate ? mpt::thread::lower : mpt::thread::normal); + CloseHandle(threadHandle); } } Modified: trunk/OpenMPT/mptrack/UpdateCheck.h =================================================================== --- trunk/OpenMPT/mptrack/UpdateCheck.h 2014-02-09 14:31:01 UTC (rev 3679) +++ trunk/OpenMPT/mptrack/UpdateCheck.h 2014-02-09 14:31:52 UTC (rev 3680) @@ -48,7 +48,6 @@ bool isAutoUpdate; // Are we running an automatic update check? // Runtime resource handles - mpt::thread threadHandle; HINTERNET internetHandle, connectionHandle; // Force creation via "new" as we're using "delete this". Use CUpdateCheck::DoUpdateCheck to create an object. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |