From: <sag...@us...> - 2012-09-11 15:09:10
|
Revision: 1350 http://modplug.svn.sourceforge.net/modplug/?rev=1350&view=rev Author: saga-games Date: 2012-09-11 15:08:58 +0000 (Tue, 11 Sep 2012) Log Message: ----------- [Imp] DMF Loader: Improved effect conversion (effect merging, effect memory) [Fix] 8SVX Loader: Loops are now also loaded properly if the loop end is precisely at the sample end. [Mod] OpenMPT: Version is now 1.20.02.09 Modified Paths: -------------- trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/LOAD_AMF.CPP trunk/OpenMPT/soundlib/LOAD_DMF.CPP trunk/OpenMPT/soundlib/SampleFormats.cpp trunk/OpenMPT/soundlib/modcommand.cpp Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-09-11 14:41:55 UTC (rev 1349) +++ trunk/OpenMPT/mptrack/version.h 2012-09-11 15:08:58 UTC (rev 1350) @@ -19,7 +19,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 02 -#define VER_MINORMINOR 08 +#define VER_MINORMINOR 09 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2012-09-11 14:41:55 UTC (rev 1349) +++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2012-09-11 15:08:58 UTC (rev 1350) @@ -132,7 +132,7 @@ file.ReadArray(data); p->note = NOTE_NONE; - if(data[0]) + if(data[0] && data[0] + 12 + NOTE_MIN <= NOTE_MAX) { p->note = data[0] + 12 + NOTE_MIN; } Modified: trunk/OpenMPT/soundlib/LOAD_DMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2012-09-11 14:41:55 UTC (rev 1349) +++ trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2012-09-11 15:08:58 UTC (rev 1350) @@ -195,6 +195,70 @@ } +// Try using effect memory (zero paramer) to give the effect swapper some optimization hints. +void ApplyEffectMemory(const ModCommand *m, ROWINDEX row, CHANNELINDEX numChannels, uint8 effect, uint8 ¶m) +//------------------------------------------------------------------------------------------------------------- +{ + if(effect == CMD_NONE || param == 0) + { + return; + } + + const bool isTonePortaEffect = (effect == CMD_PORTAMENTOUP || effect == CMD_PORTAMENTODOWN || effect == CMD_TONEPORTAMENTO); + const bool isVolSlideEffect = (effect == CMD_VOLUMESLIDE || effect == CMD_TONEPORTAVOL || effect == CMD_VIBRATOVOL); + + while(row > 0) + { + m -= numChannels; + row--; + + // First, keep some extra rules in mind for portamento, where effect memory is shared between various commands. + bool isSame = (effect == m->command); + if(isTonePortaEffect && (m->command == CMD_PORTAMENTOUP || m->command == CMD_PORTAMENTODOWN || m->command == CMD_TONEPORTAMENTO)) + { + if(m->param < 0xE0) + { + // Avoid effect param for fine slides, or else we could accidentally put this command in the volume column, where fine slides won't work! + isSame = true; + } else + { + return; + } + } else if(isVolSlideEffect && (m->command == CMD_VOLUMESLIDE || m->command == CMD_TONEPORTAVOL || m->command == CMD_VIBRATOVOL)) + { + isSame = true; + } + if(isTonePortaEffect + && (m->volcmd == VOLCMD_PORTAUP || m->volcmd == VOLCMD_PORTADOWN || m->volcmd == VOLCMD_TONEPORTAMENTO) + && m->vol != 0) + { + // Uuh... Don't even try + return; + } else if(isVolSlideEffect + && (m->volcmd == VOLCMD_FINEVOLUP || m->volcmd == VOLCMD_FINEVOLDOWN || m->volcmd == VOLCMD_VOLSLIDEUP || m->volcmd == VOLCMD_VOLSLIDEDOWN) + && m->vol != 0) + { + // Same! + return; + } + + if(isSame) + { + if(param != m->param && m->param != 0) + { + // No way to optimize this + return; + } else if(param == m->param) + { + // Yay! + param = 0; + return; + } + } + } +} + + PATTERNINDEX ConvertDMFPattern(const LPCBYTE lpStream, const DWORD dwMemLength, DMF_PATTERNSETTINGS &settings, CSoundFile *pSndFile) //---------------------------------------------------------------------------------------------------------------------------------- { @@ -427,6 +491,7 @@ uint8 effect1 = CMD_NONE, effect2 = CMD_NONE, effect3 = CMD_NONE; uint8 effectParam1 = 0, effectParam2 = 0, effectParam3 = 0; + bool useMem2 = false, useMem3 = false; // Effect can use memory if necessary //////////////////////////////////////////////////////////////// // 0x10: Volume @@ -532,14 +597,17 @@ { effect2 = CMD_NONE; } + useMem2 = true; break; case 3: // Arpeggio effect2 = CMD_ARPEGGIO; + useMem2 = true; break; case 4: // Portamento Up case 5: // Portamento Down effectParam2 = DMFporta2MPT(effectParam2, settings.internalTicks, true); effect2 = static_cast<ModCommand::COMMAND>(effect2 == 4 ? CMD_PORTAMENTOUP : CMD_PORTAMENTODOWN); + useMem2 = true; break; case 6: // Portamento to Note if(m->note == NOTE_NONE) @@ -548,11 +616,13 @@ } effectParam2 = DMFporta2MPT(effectParam2, settings.internalTicks, false); effect2 = CMD_TONEPORTAMENTO; + useMem2 = true; break; case 7: // Scratch to Note (neat! but we don't have such an effect...) m->note = CLAMP(effectParam2 + 25, NOTE_MIN, NOTE_MAX); effect2 = CMD_TONEPORTAMENTO; effectParam2 = 0xFF; + useMem2 = true; break; case 8: // Vibrato Sine case 9: // Vibrato Triangle (ramp down should be close enough) @@ -564,10 +634,12 @@ } effect2 = CMD_VIBRATO; effectParam2 = DMFvibrato2MPT(effectParam2, settings.internalTicks); + useMem2 = true; break; case 11: // Note Tremolo effectParam2 = DMFtremor2MPT(effectParam2, settings.internalTicks); effect2 = CMD_TREMOR; + useMem2 = true; break; case 12: // Note Cut effectParam2 = DMFdelay2MPT(effectParam2, settings.internalTicks); @@ -580,6 +652,7 @@ effect2 = CMD_NONE; m->note = NOTE_NOTECUT; } + useMem2 = true; break; default: effect2 = CMD_NONE; @@ -601,10 +674,12 @@ case 2: // Volume Slide Down effectParam3 = DMFslide2MPT(effectParam3, settings.internalTicks, (effect3 == 1)); effect3 = CMD_VOLUMESLIDE; + useMem3 = true; break; case 3: // Volume Tremolo (actually this is Tremor) effectParam3 = DMFtremor2MPT(effectParam3, settings.internalTicks); effect3 = CMD_TREMOR; + useMem3 = true; break; case 4: // Tremolo Sine case 5: // Tremolo Triangle (ramp down should be close enough) @@ -616,6 +691,7 @@ } effect3 = CMD_TREMOLO; effectParam3 = DMFvibrato2MPT(effectParam3, settings.internalTicks); + useMem3 = true; break; case 7: // Set Balance effect3 = CMD_PANNING8; @@ -624,10 +700,12 @@ case 9: // Slide Balance Right effectParam3 = DMFslide2MPT(effectParam3, settings.internalTicks, (effect3 == 8)); effect3 = CMD_PANNINGSLIDE; + useMem3 = true; break; case 10: // Balance Vibrato Left/Right (always sine modulated) effect3 = CMD_PANBRELLO; effectParam3 = DMFvibrato2MPT(effectParam3, settings.internalTicks); + useMem3 = true; break; default: effect3 = CMD_NONE; @@ -635,6 +713,16 @@ } } + // Let's see if we can help the effect swapper by reducing some effect parameters to "continue" parameters. + if(useMem2) + { + ApplyEffectMemory(m, nRow, pSndFile->GetNumChannels(), effect2, effectParam2); + } + if(useMem3) + { + ApplyEffectMemory(m, nRow, pSndFile->GetNumChannels(), effect3, effectParam3); + } + // I guess this is close enough to "not retriggering the note" if(slideNote && m->IsNote()) { Modified: trunk/OpenMPT/soundlib/SampleFormats.cpp =================================================================== --- trunk/OpenMPT/soundlib/SampleFormats.cpp 2012-09-11 14:41:55 UTC (rev 1349) +++ trunk/OpenMPT/soundlib/SampleFormats.cpp 2012-09-11 15:08:58 UTC (rev 1350) @@ -1857,7 +1857,7 @@ if (len > 4) { sample.nLength = len; - if ((sample.nLoopStart + 4 < sample.nLoopEnd) && (sample.nLoopEnd < sample.nLength)) sample.uFlags |= CHN_LOOP; + if ((sample.nLoopStart + 4 < sample.nLoopEnd) && (sample.nLoopEnd <= sample.nLength)) sample.uFlags |= CHN_LOOP; SampleIO( SampleIO::_8bit, Modified: trunk/OpenMPT/soundlib/modcommand.cpp =================================================================== --- trunk/OpenMPT/soundlib/modcommand.cpp 2012-09-11 14:41:55 UTC (rev 1349) +++ trunk/OpenMPT/soundlib/modcommand.cpp 2012-09-11 15:08:58 UTC (rev 1350) @@ -853,8 +853,9 @@ case CMD_VIBRATO: if(force) param = min(param & 0x0F, 9); - else if((param & 0x0F) > 9) + else if((param & 0x0F) > 9 || (param & 0xF0) != 0) return false; + param &= 0x0F; effect = VOLCMD_VIBRATODEPTH; break; case CMD_FINEVIBRATO: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |