From: <sv...@op...> - 2024-07-20 17:06:00
|
Author: sagamusix Date: Sat Jul 20 19:05:52 2024 New Revision: 21206 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=21206 Log: [Fix] r6129 broke old plugin behaviour: Previously it was possible to send MIDI notes to channel plugins if the current instrument had a valid MIDI channel. The old behaviour is now re-enabled for old modules. Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/soundlib/Snd_defs.h trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp trunk/OpenMPT/soundlib/UpgradeModule.cpp Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp ============================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp Sat Jul 20 16:22:36 2024 (r21205) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp Sat Jul 20 19:05:52 2024 (r21206) @@ -668,7 +668,7 @@ case kST3EffectMemory: desc = _T("Most effects share the same memory"); break; case kST3PortaSampleChange: desc = _T("Portamento with instrument number applies volume settings of new sample, but not the new sample itself (GUS)"); break; case kST3VibratoMemory: desc = _T("Do not remember vibrato type in effect memory"); break; - case kST3LimitPeriod: desc = _T("ModPlug Tracker frequency limits"); break; + case kST3LimitPeriod: desc = _T("Stop note when reaching the format's maximum note frequency"); break; case KST3PortaAfterArpeggio: desc = _T("Portamento immediately following an arpeggio effect continues at the last arpeggiated note"); break; case kMODOneShotLoops: desc = _T("ProTracker one-shot loops"); break; case kMODIgnorePanning: desc = _T("Ignore panning commands"); break; @@ -713,6 +713,7 @@ case kITEmptyNoteMapSlotIgnoreCell: desc = _T("Ignore pattern cell completely when trying to play unmapped instrument note"); break; case kITOffsetWithInstrNumber: desc = _T("Offset command with instrument number recalls offset with last note"); break; case kContinueSampleWithoutInstr: desc = _T("New note without instrument number does not play looped samples from the start"); break; + case kMIDINotesFromChannelPlugin: desc = _T("MIDI notes can be sent to channel plugins"); break; default: MPT_ASSERT_NOTREACHED(); } Modified: trunk/OpenMPT/soundlib/Snd_defs.h ============================================================================== --- trunk/OpenMPT/soundlib/Snd_defs.h Sat Jul 20 16:22:36 2024 (r21205) +++ trunk/OpenMPT/soundlib/Snd_defs.h Sat Jul 20 19:05:52 2024 (r21206) @@ -597,6 +597,7 @@ kITEmptyNoteMapSlotIgnoreCell, // IT ignores the entire pattern cell when trying to play an unmapped note of an instrument kITOffsetWithInstrNumber, // IT applies offset commands even if just an instrument number without note is present kContinueSampleWithoutInstr, // FTM: A note without instrument number continues looped samples with the new pitch instead of retriggering them + kMIDINotesFromChannelPlugin, // Behaviour before OpenMPT 1.26: Channel plugin can be used to send MIDI notes // Add new play behaviours here. Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp Sat Jul 20 16:22:36 2024 (r21205) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp Sat Jul 20 19:05:52 2024 (r21206) @@ -2477,7 +2477,7 @@ case NewNoteAction::NoteCut: case NewNoteAction::NoteFade: // Switch off note played on this plugin, on this tracker channel and midi channel - SendMIDINote(nChn, NOTE_KEYOFF, 0); + SendMIDINote(nChn, NOTE_KEYOFF, 0, m_playBehaviour[kMIDINotesFromChannelPlugin] ? pPlugin : nullptr); srcChn.nArpeggioLastNote = NOTE_NONE; srcChn.lastMidiNoteWithoutArp = NOTE_NONE; break; @@ -5748,24 +5748,22 @@ } -void CSoundFile::SendMIDINote(CHANNELINDEX chn, uint16 note, uint16 volume) +void CSoundFile::SendMIDINote(CHANNELINDEX chn, uint16 note, uint16 volume, IMixPlugin *plugin) { #ifndef NO_PLUGINS auto &channel = m_PlayState.Chn[chn]; const ModInstrument *pIns = channel.pModInstrument; // instro sends to a midi chan - if (pIns && pIns->HasValidMIDIChannel()) + if(pIns && pIns->HasValidMIDIChannel()) { - PLUGINDEX plug = pIns->nMixPlug; - if(plug > 0 && plug <= MAX_MIXPLUGINS) + if(plugin == nullptr && pIns->nMixPlug > 0 && pIns->nMixPlug <= MAX_MIXPLUGINS) + plugin = m_MixPlugins[pIns->nMixPlug - 1].pMixPlugin; + + if(plugin != nullptr) { - IMixPlugin *pPlug = m_MixPlugins[plug - 1].pMixPlugin; - if (pPlug != nullptr) - { - pPlug->MidiCommand(*pIns, note, volume, chn); - if(note < NOTE_MIN_SPECIAL) - channel.nLeftVU = channel.nRightVU = 0xFF; - } + plugin->MidiCommand(*pIns, note, volume, chn); + if(note < NOTE_MIN_SPECIAL) + channel.nLeftVU = channel.nRightVU = 0xFF; } } #endif // NO_PLUGINS @@ -6743,17 +6741,12 @@ // If it looks like this is an NNA channel, we need to find the master channel. // This ensures we pick up the right ChnSettings. if(channel.nMasterChn > 0) - { nChn = channel.nMasterChn - 1; - } if(nChn < ChnSettings.size()) - { plugin = ChnSettings[nChn].nMixPlugin; - } else - { + else plugin = 0; - } } return plugin; } @@ -6768,13 +6761,10 @@ if(chn.pModInstrument != nullptr) { // TODO this looks fishy. Shouldn't it check the mute status of the instrument itself?! - if(respectMutes == RespectMutes && chn.pModSample && chn.pModSample->uFlags[CHN_MUTE]) - { + if(respectMutes == RespectMutes && chn.pModInstrument->dwFlags[INS_MUTE]) plug = 0; - } else - { + else plug = chn.pModInstrument->nMixPlug; - } } return plug; } Modified: trunk/OpenMPT/soundlib/Sndfile.h ============================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h Sat Jul 20 16:22:36 2024 (r21205) +++ trunk/OpenMPT/soundlib/Sndfile.h Sat Jul 20 19:05:52 2024 (r21206) @@ -1100,7 +1100,7 @@ void ParseMIDIMacro(PlayState &playState, CHANNELINDEX nChn, bool isSmooth, const mpt::span<const char> macro, mpt::span<uint8> &out, uint8 param = 0, PLUGINDEX plugin = 0) const; static float CalculateSmoothParamChange(const PlayState &playState, float currentValue, float param); void SendMIDIData(PlayState &playState, CHANNELINDEX nChn, bool isSmooth, const mpt::span<const uint8> macro, PLUGINDEX plugin); - void SendMIDINote(CHANNELINDEX chn, uint16 note, uint16 volume); + void SendMIDINote(CHANNELINDEX chn, uint16 note, uint16 volume, IMixPlugin *plugin = nullptr); int SetupChannelFilter(ModChannel &chn, bool bReset, int envModifier = 256) const; int HandleNoteChangeFilter(ModChannel &chn) const; Modified: trunk/OpenMPT/soundlib/Sndmix.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp Sat Jul 20 16:22:36 2024 (r21205) +++ trunk/OpenMPT/soundlib/Sndmix.cpp Sat Jul 20 19:05:52 2024 (r21206) @@ -2658,7 +2658,7 @@ ModCommand::NOTE realNote = note; if(ModCommand::IsNote(note)) realNote = pIns->NoteMap[note - NOTE_MIN]; - SendMIDINote(nChn, realNote, static_cast<uint16>(chn.nVolume)); + SendMIDINote(nChn, realNote, static_cast<uint16>(chn.nVolume), m_playBehaviour[kMIDINotesFromChannelPlugin] ? pPlugin : nullptr); } else if(hasVolCommand) { pPlugin->MidiCC(MIDIEvents::MIDICC_Volume_Fine, vol, nChn); @@ -2692,7 +2692,7 @@ // Experimental VST panning //ProcessMIDIMacro(nChn, false, m_MidiCfg.Global[MIDIOUT_PAN], 0, nPlugin); if(m_playBehaviour[kPluginIgnoreTonePortamento] || !chn.rowCommand.IsTonePortamento()) - SendMIDINote(nChn, realNote, static_cast<uint16>(velocity)); + SendMIDINote(nChn, realNote, static_cast<uint16>(velocity), m_playBehaviour[kMIDINotesFromChannelPlugin] ? pPlugin : nullptr); } const bool processVolumeAlsoOnNote = (pIns->pluginVelocityHandling == PLUGIN_VELOCITYHANDLING_VOLUME); Modified: trunk/OpenMPT/soundlib/UpgradeModule.cpp ============================================================================== --- trunk/OpenMPT/soundlib/UpgradeModule.cpp Sat Jul 20 16:22:36 2024 (r21205) +++ trunk/OpenMPT/soundlib/UpgradeModule.cpp Sat Jul 20 19:05:52 2024 (r21206) @@ -431,9 +431,11 @@ // OpenMPT 1.18 fixed the depth of random pan in compatible mode. // OpenMPT 1.26 fixes it in normal mode too. if(!compatModeIT || m_dwLastSavedWithVersion < MPT_V("1.18.00.00")) - { ins->nPanSwing = static_cast<uint8>((ins->nPanSwing + 3) / 4u); - } + + // Before OpenMPT 1.26 (r6129), it was possible to trigger MIDI notes using channel plugins if the instrument had a valid MIDI channel. + if(!ins->nMixPlug && ins->HasValidMIDIChannel() && m_dwLastSavedWithVersion >= MPT_V("1.17.00.00")) + m_playBehaviour.set(kMIDINotesFromChannelPlugin); } } |