From: <sag...@us...> - 2011-08-08 16:00:51
|
Revision: 970 http://modplug.svn.sourceforge.net/modplug/?rev=970&view=rev Author: saga-games Date: 2011-08-08 16:00:45 +0000 (Mon, 08 Aug 2011) Log Message: ----------- [Imp] Macros are now evaluated on every tick (both smooth and normal MIDI macros), so that volume / pan changes are taken into account immediately. [Mod] OpenMPT: Version is now 1.20.00.05 Modified Paths: -------------- trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2011-08-08 15:00:31 UTC (rev 969) +++ trunk/OpenMPT/mptrack/version.h 2011-08-08 16:00:45 UTC (rev 970) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 04 +#define VER_MINORMINOR 05 //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/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-08-08 15:00:31 UTC (rev 969) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-08-08 16:00:45 UTC (rev 970) @@ -1342,7 +1342,7 @@ // the need for parameter control. The condition cmd == 0 // is to make sure that m_nPlugParamValueStep != 0 because // of NOTE_PCS, not because of macro. - if(pChn->nRowNote == NOTE_PCS || (cmd == 0 && pChn->m_nPlugParamValueStep != 0)) + if(pChn->nRowNote == NOTE_PCS || (cmd == 0 && pChn->m_plugParamValueStep != 0)) { const bool isFirstTick = (m_dwSongFlags & SONG_FIRSTTICK) != 0; if(isFirstTick) @@ -1358,17 +1358,17 @@ { PlugParamValue targetvalue = MODCOMMAND::GetValueEffectCol(pChn->nRowCommand, pChn->nRowParam) / PlugParamValue(MODCOMMAND::maxColumnValue); // Hack: Use m_nPlugInitialParamValue to store the target value, not initial. - pChn->m_nPlugInitialParamValue = targetvalue; - pChn->m_nPlugParamValueStep = (targetvalue - m_MixPlugins[nPlug-1].pMixPlugin->GetParameter(plugparam)) / float(m_nMusicSpeed); + pChn->m_plugInitialParamValue = targetvalue; + pChn->m_plugParamValueStep = (targetvalue - m_MixPlugins[nPlug-1].pMixPlugin->GetParameter(plugparam)) / float(m_nMusicSpeed); } - if(m_nTickCount + 1 == m_nMusicSpeed) + if(m_nTickCount + 1 == GetNumTicksOnCurrentRow()) { // On last tick, set parameter exactly to target value. // Note: m_nPlugInitialParamValue is used to store the target value, // not the initial value as the name suggests. - m_MixPlugins[nPlug-1].pMixPlugin->SetParameter(plugparam, pChn->m_nPlugInitialParamValue); + m_MixPlugins[nPlug-1].pMixPlugin->SetParameter(plugparam, pChn->m_plugInitialParamValue); } else - m_MixPlugins[nPlug-1].pMixPlugin->ModifyParameter(plugparam, pChn->m_nPlugParamValueStep); + m_MixPlugins[nPlug-1].pMixPlugin->ModifyParameter(plugparam, pChn->m_plugParamValueStep); } } @@ -3238,6 +3238,25 @@ } +// Calculate smooth MIDI macro slide parameter for current tick. +float CSoundFile::CalculateSmoothParamChange(float currentValue, float param) const +//--------------------------------------------------------------------------------- +{ + ASSERT(GetNumTicksOnCurrentRow() > m_nTickCount); + const UINT ticksLeft = GetNumTicksOnCurrentRow() - m_nTickCount; + if(ticksLeft > 1) + { + // Slide param + const float step = ((float)param - currentValue) / (float)ticksLeft; + return (currentValue + step); + } else + { + // On last tick, set exact value. + return (float)param; + } +} + + // Process MIDI macro data parsed by ProcessMIDIMacro... return bytes sent on success, 0 on (parse) failure. size_t CSoundFile::SendMIDIData(CHANNELINDEX nChn, bool isSmooth, const unsigned char *macro, size_t macroLen, PLUGINDEX plugin) //------------------------------------------------------------------------------------------------------------------------------ @@ -3274,15 +3293,7 @@ pChn->nCutOff = param; } else { - // on the first tick only, calculate step - if(m_dwSongFlags & SONG_FIRSTTICK) - { - pChn->m_nPlugInitialParamValue = pChn->nCutOff; - // (dwParam & 0x7F) extracts the actual value that we're going to pass - pChn->m_nPlugParamValueStep = (float)((int)param - pChn->m_nPlugInitialParamValue) / (float)GetNumTicksOnCurrentRow(); - } - //update param on all ticks - pChn->nCutOff = (BYTE) (pChn->m_nPlugInitialParamValue + (m_nTickCount + 1) * pChn->m_nPlugParamValueStep + 0.5); + pChn->nCutOff = (BYTE)CalculateSmoothParamChange((float)pChn->nCutOff, (float)param); } pChn->nRestoreCutoffOnNewNote = 0; } @@ -3309,15 +3320,7 @@ pChn->nResonance = param; } else { - // on the first tick only, calculate step - if(m_dwSongFlags & SONG_FIRSTTICK) - { - pChn->m_nPlugInitialParamValue = pChn->nResonance; - // (dwParam & 0x7F) extracts the actual value that we're going to pass - pChn->m_nPlugParamValueStep = (float)((int)param - pChn->m_nPlugInitialParamValue) / (float)GetNumTicksOnCurrentRow(); - } - //update param on all ticks - pChn->nResonance = (BYTE) (pChn->m_nPlugInitialParamValue + (m_nTickCount + 1) * pChn->m_nPlugParamValueStep + 0.5); + pChn->nResonance = (BYTE)CalculateSmoothParamChange((float)pChn->nResonance, (float)param); } } @@ -3350,20 +3353,13 @@ const PLUGINDEX nPlug = (plugin != 0) ? plugin : GetBestPlugin(nChn, PRIORITISE_CHANNEL, EVEN_IF_MUTED); if ((nPlug) && (nPlug <= MAX_MIXPLUGINS) && param < 0x80) { + const float newRatio = 1.0 - (static_cast<float>(param) / 127.0f); if(!isSmooth) { - m_MixPlugins[nPlug - 1].fDryRatio = 1.0 - (static_cast<float>(param) / 127.0f); + m_MixPlugins[nPlug - 1].fDryRatio = newRatio; } else { - // on the first tick only, calculate step - if(m_dwSongFlags & SONG_FIRSTTICK) - { - pChn->m_nPlugInitialParamValue = m_MixPlugins[nPlug - 1].fDryRatio; - // (dwParam & 0x7F) extracts the actual value that we're going to pass - pChn->m_nPlugParamValueStep = ((1 - ((float)(param) / 127.0f)) - pChn->m_nPlugInitialParamValue) / (float)GetNumTicksOnCurrentRow(); - } - //update param on all ticks - m_MixPlugins[nPlug - 1].fDryRatio = pChn->m_nPlugInitialParamValue + (float)(m_nTickCount + 1) * pChn->m_nPlugParamValueStep; + m_MixPlugins[nPlug - 1].fDryRatio = CalculateSmoothParamChange(m_MixPlugins[nPlug - 1].fDryRatio, newRatio); } } return 4; @@ -3378,23 +3374,15 @@ const UINT plugParam = isExtended ? (0x80 + macroCode) : (macroCode & 0x7F); if((nPlug) && (nPlug <= MAX_MIXPLUGINS)) { - IMixPlugin *pPlugin = m_MixPlugins[nPlug-1].pMixPlugin; - if((pPlugin) && (m_MixPlugins[nPlug-1].pMixState)) + IMixPlugin *pPlugin = m_MixPlugins[nPlug - 1].pMixPlugin; + if((pPlugin) && (m_MixPlugins[nPlug - 1].pMixState) && (param < 0x80)) { if(!isSmooth) { - pPlugin->SetZxxParameter(plugParam, param & 0x7F); + pPlugin->SetZxxParameter(plugParam, param); } else { - // on the first tick only, calculate step - if(m_dwSongFlags & SONG_FIRSTTICK) - { - pChn->m_nPlugInitialParamValue = pPlugin->GetZxxParameter(plugParam); - // (dwParam & 0x7F) extracts the actual value that we're going to pass - pChn->m_nPlugParamValueStep = ((int)(param & 0x7F) - pChn->m_nPlugInitialParamValue) / (float)GetNumTicksOnCurrentRow(); - } - //update param on all ticks - pPlugin->SetZxxParameter(plugParam, (UINT) (pChn->m_nPlugInitialParamValue + (m_nTickCount + 1) * pChn->m_nPlugParamValueStep + 0.5)); + pPlugin->SetZxxParameter(plugParam, (UINT)CalculateSmoothParamChange(pPlugin->GetZxxParameter(plugParam), (float)param)); } } } Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2011-08-08 15:00:31 UTC (rev 969) +++ trunk/OpenMPT/soundlib/Sndfile.h 2011-08-08 16:00:45 UTC (rev 970) @@ -253,10 +253,10 @@ BYTE nActiveMacro, nFilterMode; BYTE nEFxSpeed, nEFxDelay; // memory for Invert Loop (EFx, .MOD only) - uint16 m_RowPlugParam; //NOTE_PCs memory. - float m_nPlugParamValueStep; //rewbs.smoothVST - float m_nPlugInitialParamValue; //rewbs.smoothVST - PLUGINDEX m_RowPlug; //NOTE_PCs memory. + //NOTE_PCs memory. + uint16 m_RowPlugParam; + float m_plugParamValueStep, m_plugInitialParamValue; + PLUGINDEX m_RowPlug; void ClearRowCmd() {nRowNote = NOTE_NONE; nRowInstr = 0; nRowVolCmd = VOLCMD_NONE; nRowVolume = 0; nRowCommand = CMD_NONE; nRowParam = 0;} @@ -949,6 +949,7 @@ inline void InvertLoop(MODCHANNEL* pChn); void ProcessMacroOnChannel(CHANNELINDEX nChn); void ProcessMIDIMacro(CHANNELINDEX nChn, bool isSmooth, char *macro, uint8 param = 0, PLUGINDEX plugin = 0); + float CalculateSmoothParamChange(float currentValue, float param) const; size_t SendMIDIData(CHANNELINDEX nChn, bool isSmooth, const unsigned char *macro, size_t macroLen, PLUGINDEX plugin); void SetupChannelFilter(MODCHANNEL *pChn, bool bReset, int flt_modifier = 256) const; // Low-Level effect processing Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2011-08-08 15:00:31 UTC (rev 969) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2011-08-08 16:00:45 UTC (rev 970) @@ -636,7 +636,7 @@ BOOL CSoundFile::ProcessRow() //--------------------------- { - if (++m_nTickCount >= m_nMusicSpeed * (m_nPatternDelay + 1) + m_nFrameDelay) + if (++m_nTickCount >= GetNumTicksOnCurrentRow()) { HandlePatternTransitionEvents(); m_nPatternDelay = 0; @@ -837,7 +837,7 @@ pChn->nRightVol = pChn->nNewRightVol; pChn->dwFlags &= ~(CHN_PORTAMENTO | CHN_VIBRATO | CHN_TREMOLO | CHN_PANBRELLO); pChn->nCommand = 0; - pChn->m_nPlugParamValueStep = 0; + pChn->m_plugParamValueStep = 0; } // Now that we know which pattern we're on, we can update time signatures (global or pattern-specific) @@ -850,7 +850,7 @@ //End of row? stop pattern step (aka "play row"). #ifdef MODPLUG_TRACKER - if (m_nTickCount >= m_nMusicSpeed * (m_nPatternDelay + 1) + m_nFrameDelay - 1) + if (m_nTickCount >= GetNumTicksOnCurrentRow() - 1) { if (m_dwSongFlags & SONG_STEP) { @@ -2340,7 +2340,7 @@ if(pChn->nRowCommand == CMD_MIDI || pChn->nRowCommand == CMD_SMOOTHMIDI) { // Only smooth MIDI macros are processed on every tick - if((pChn->nRowCommand == CMD_MIDI) && !(m_dwSongFlags & SONG_FIRSTTICK)) return; + //if((pChn->nRowCommand == CMD_MIDI) && !(m_dwSongFlags & SONG_FIRSTTICK)) return; if(pChn->nRowParam < 0x80) ProcessMIDIMacro(nChn, (pChn->nRowCommand == CMD_SMOOTHMIDI), m_MidiCfg.szMidiSFXExt[pChn->nActiveMacro], pChn->nRowParam); else This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |