From: <sag...@us...> - 2015-02-22 21:37:44
|
Revision: 4788 http://sourceforge.net/p/modplug/code/4788 Author: saga-games Date: 2015-02-22 21:37:31 +0000 (Sun, 22 Feb 2015) Log Message: ----------- [Mod] Apply DNA and NNA settings when previewing notes in the instrument editor (http://bugs.openmpt.org/view.php?id=437) Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2015-02-22 16:18:51 UTC (rev 4787) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2015-02-22 21:37:31 UTC (rev 4788) @@ -1060,8 +1060,6 @@ { CriticalSection cs; - //OnPlayerPause(); // pause song - pausing VSTis is too slow - // All notes off for(CHANNELINDEX i = 0; i < MAX_CHANNELS; i++) { @@ -1140,14 +1138,12 @@ chn.nLength = chn.nLoopEnd = chn.pModSample->nLength; } - //rewbs.vstiLive + // VSTi preview if (nins <= m_SndFile.GetNumInstruments()) { const ModInstrument *pIns = m_SndFile.Instruments[nins]; if (pIns && pIns->HasValidMIDIChannel()) // instro sends to a midi chan { - // UINT nPlugin = m_SndFile.GetBestPlugin(nChn, PRIORITISE_INSTRUMENT, EVEN_IF_MUTED); - PLUGINDEX nPlugin = 0; if (chn.pModInstrument) nPlugin = chn.pModInstrument->nMixPlug; // First try instrument plugin @@ -1165,8 +1161,6 @@ } } } - //end rewbs.vstiLive - } else { CriticalSection cs; Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2015-02-22 16:18:51 UTC (rev 4787) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2015-02-22 21:37:31 UTC (rev 4788) @@ -15,13 +15,12 @@ #include "InputHandler.h" #include "Childfrm.h" #include "Moddoc.h" -#include "globals.h" -#include "ctrl_ins.h" -#include "view_ins.h" +#include "Globals.h" +#include "Ctrl_ins.h" +#include "View_ins.h" #include "Dlsbank.h" #include "channelManagerDlg.h" #include "ScaleEnvPointsDlg.h" -#include "view_ins.h" #include "../soundlib/MIDIEvents.h" #include "../common/StringFixer.h" @@ -1933,28 +1932,56 @@ } else if (m_nInstrument && !m_baPlayingNote[note]) { - //rewbs.instViewNNA - /* CSoundFile *pSoundFile = pModDoc->GetSoundFile(); - if (pSoundFile && m_baPlayingNote>0 && m_nPlayingChannel>=0) + CSoundFile &sndFile = pModDoc->GetrSoundFile(); + ModInstrument *pIns = sndFile.Instruments[m_nInstrument]; + if ((!pIns) || (!pIns->Keyboard[note - NOTE_MIN] && !pIns->nMixPlug)) return; + { - ModChannel *pChn = &(pSoundFile->Chn[m_nPlayingChannel]); //Get pointer to channel playing last note. - if (pChn->pHeader) //is it valid? + if (pMainFrm->GetModPlaying() != pModDoc) { - DWORD tempflags = pChn->dwFlags; - pChn->dwFlags = 0; - pModDoc->GetSoundFile()->CheckNNA(m_nPlayingChannel, m_nInstrument, note, FALSE); //if so, apply NNA - pChn->dwFlags = tempflags; + sndFile.m_SongFlags.set(SONG_PAUSED); + pMainFrm->PlayMod(pModDoc); } + CriticalSection cs; + // Apply NNA/DNA + for(CHANNELINDEX chn = sndFile.GetNumChannels(); chn < MAX_CHANNELS; chn++) + { + const ModChannel &channel = sndFile.m_PlayState.Chn[chn]; + if(channel.pModInstrument == pIns && channel.nMasterChn == 0 && ModCommand::IsNote(channel.nNote) + && (channel.nLength || pIns->HasValidMIDIChannel()) && !m_baPlayingNote[channel.nNote]) + { + CHANNELINDEX nnaChn = sndFile.CheckNNA(chn, m_nInstrument, note, false); + // We need to update this mix channel immediately since new notes may be triggered between ticks, in which case + // ChnMix may not contain the moved channel yet and the past note will stop playing for the rest of this tick! + if(nnaChn != CHANNELINDEX_INVALID) + { + CHANNELINDEX origChnPos = CHANNELINDEX_INVALID; + for(CHANNELINDEX i = 0; i < sndFile.m_nMixChannels; i++) + { + if(sndFile.m_PlayState.ChnMix[i] == nnaChn) + { + // Nothing to do + origChnPos = CHANNELINDEX_INVALID; + break; + } else if(sndFile.m_PlayState.ChnMix[i] == chn) + { + origChnPos = i; + } + } + if(origChnPos != CHANNELINDEX_INVALID) + { + sndFile.m_PlayState.ChnMix[origChnPos] = nnaChn; + } + } + } + } + m_baPlayingNote[note] = true; + pModDoc->PlayNote(note, m_nInstrument, 0, false); } - */ - ModInstrument *pIns = pModDoc->GetrSoundFile().Instruments[m_nInstrument]; - if ((!pIns) || (!pIns->Keyboard[note - NOTE_MIN] && !pIns->nMixPlug)) return; - m_baPlayingNote[note] = true; //rewbs.instViewNNA - pModDoc->PlayNote(note, m_nInstrument, 0, false); //rewbs.instViewNNA s[0] = 0; if ((note) && (note <= NOTE_MAX)) { - const std::string temp = pModDoc->GetrSoundFile().GetNoteName(note, m_nInstrument); + const std::string temp = sndFile.GetNoteName(note, m_nInstrument); mpt::String::Copy(s, temp.c_str()); } pMainFrm->SetInfoText(s); Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2015-02-22 16:18:51 UTC (rev 4787) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2015-02-22 21:37:31 UTC (rev 4788) @@ -1589,13 +1589,13 @@ if (!pChn->nFadeOutVol) return 0; // All channels are used: check for lowest volume CHANNELINDEX result = 0; - DWORD vol = 64*65536; // 25% - DWORD envpos = 0xFFFFFF; + uint32_t vol = 64*65536; // 25% + uint32_t envpos = int32_max; const ModChannel *pj = &m_PlayState.Chn[m_nChannels]; for (CHANNELINDEX j=m_nChannels; j<MAX_CHANNELS; j++, pj++) { if (!pj->nFadeOutVol) return j; - DWORD v = pj->nVolume; + uint32_t v = pj->nVolume; if(pj->dwFlags[CHN_NOTEFADE]) v = v * pj->nFadeOutVol; else @@ -1612,26 +1612,27 @@ } -void CSoundFile::CheckNNA(CHANNELINDEX nChn, UINT instr, int note, bool forceCut) -//------------------------------------------------------------------------------- +CHANNELINDEX CSoundFile::CheckNNA(CHANNELINDEX nChn, UINT instr, int note, bool forceCut) +//--------------------------------------------------------------------------------------- { + CHANNELINDEX nnaChn = CHANNELINDEX_INVALID; ModChannel *pChn = &m_PlayState.Chn[nChn]; const ModInstrument *pIns = nullptr; if(!ModCommand::IsNote(note)) { - return; + return nnaChn; } // Always NNA cut - using if(!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_MT2)) || !m_nInstruments || forceCut) { if(!pChn->nLength || pChn->dwFlags[CHN_MUTE] || !(pChn->rightVol | pChn->leftVol)) { - return; + return CHANNELINDEX_INVALID; } - CHANNELINDEX n = GetNNAChannel(nChn); - if(!n) return; - ModChannel &chn = m_PlayState.Chn[n]; + nnaChn = GetNNAChannel(nChn); + if(!nnaChn) return CHANNELINDEX_INVALID; + ModChannel &chn = m_PlayState.Chn[nnaChn]; // Copy Channel chn = *pChn; chn.dwFlags.reset(CHN_VIBRATO | CHN_TREMOLO | CHN_MUTE | CHN_PORTAMENTO); @@ -1646,7 +1647,7 @@ pChn->nLength = pChn->nPos = pChn->nPosLo = 0; pChn->nROfs = pChn->nLOfs = 0; pChn->rightVol = pChn->leftVol = 0; - return; + return nnaChn; } if(instr >= MAX_INSTRUMENTS) instr = 0; const ModSample *pSample = pChn->pModSample; @@ -1669,14 +1670,14 @@ // Impulse Tracker ignores empty slots. // We won't ignore them if a plugin is assigned to this slot, so that VSTis still work as intended. // Test case: emptyslot.it, PortaInsNum.it, gxsmp.it, gxsmp2.it - return; + return CHANNELINDEX_INVALID; } } } else pSample = nullptr; } ModChannel *p = pChn; //if (!pIns) return; - if (pChn->dwFlags[CHN_MUTE]) return; + if (pChn->dwFlags[CHN_MUTE]) return CHANNELINDEX_INVALID; bool applyDNAtoPlug; //rewbs.VSTiNNA @@ -1794,20 +1795,16 @@ //if ((pChn->nVolume) && (pChn->nLength)) if((pChn->nVolume != 0 && pChn->nLength != 0) || applyNNAtoPlug) //rewbs.VSTiNNA { - CHANNELINDEX n = GetNNAChannel(nChn); - if(n != 0) + nnaChn = GetNNAChannel(nChn); + if(nnaChn != 0) { - ModChannel *p = &m_PlayState.Chn[n]; + ModChannel *p = &m_PlayState.Chn[nnaChn]; // Copy Channel *p = *pChn; - p->dwFlags.reset(CHN_VIBRATO | CHN_TREMOLO | CHN_MUTE | CHN_PORTAMENTO); + p->dwFlags.reset(CHN_VIBRATO | CHN_TREMOLO | CHN_PORTAMENTO); p->nPanbrelloOffset = 0; - //rewbs: Copy mute and FX status from master chan. - //I'd like to copy other flags too, but this would change playback behaviour. - p->dwFlags.set(pChn->dwFlags & (CHN_MUTE | CHN_NOFX)); - - p->nMasterChn = nChn + 1; + p->nMasterChn = nChn < GetNumChannels() ? nChn + 1 : 0; p->nCommand = CMD_NONE; //rewbs.VSTiNNA if(applyNNAtoPlug && pPlugin) @@ -1849,6 +1846,7 @@ pChn->nROfs = pChn->nLOfs = 0; } } + return nnaChn; } Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2015-02-22 16:18:51 UTC (rev 4787) +++ trunk/OpenMPT/soundlib/Sndfile.h 2015-02-22 21:37:31 UTC (rev 4788) @@ -486,9 +486,8 @@ public: bool m_bPositionChanged; // Report to plugins that we jumped around in the module - protected: + public: CHANNELINDEX ChnMix[MAX_CHANNELS]; // Channels to be mixed - public: ModChannel Chn[MAX_CHANNELS]; // Mixing channels... First m_nChannel channels are master channels (i.e. they are never NNA channels)! protected: @@ -772,7 +771,7 @@ bool ProcessRow(); bool ProcessEffects(); CHANNELINDEX GetNNAChannel(CHANNELINDEX nChn) const; - void CheckNNA(CHANNELINDEX nChn, UINT instr, int note, bool forceCut); + CHANNELINDEX CheckNNA(CHANNELINDEX nChn, UINT instr, int note, bool forceCut); void NoteChange(ModChannel *pChn, int note, bool bPorta = false, bool bResetEnv = true, bool bManual = false) const; void InstrumentChange(ModChannel *pChn, UINT instr, bool bPorta = false, bool bUpdVol = true, bool bResetEnv = true) const; void ApplyInstrumentPanning(ModChannel *pChn, const ModInstrument *instr, const ModSample *smp) const; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |