From: <sag...@us...> - 2013-09-29 00:12:03
|
Revision: 2795 http://sourceforge.net/p/modplug/code/2795 Author: saga-games Date: 2013-09-29 00:11:57 +0000 (Sun, 29 Sep 2013) Log Message: ----------- [Fix] VST: Send SysEx messages to plugins as SysEx instead of short messages. This fixes SysEx messages sent through OpenMPT's MIDI Input/Output plugin, as it didn't ignore the fourth byte of short messages. Modified Paths: -------------- trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/plugins/PlugInterface.h trunk/OpenMPT/soundlib/plugins/PluginEventQueue.h Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2013-09-28 21:36:13 UTC (rev 2794) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2013-09-29 00:11:57 UTC (rev 2795) @@ -118,10 +118,10 @@ VSTPluginLib *p = m_pVstHead; while (p) { - if (p == pLib) return TRUE; + if (p == pLib) return true; p = p->pNext; } - return FALSE; + return false; } @@ -201,7 +201,7 @@ if(error != ERROR_MOD_NOT_FOUND) // "File not found errors" are annoying. { TCHAR szBuf[256]; - wsprintf(szBuf, "Warning: encountered problem when loading plugin dll. Error %d: %s", error, GetErrorMessage(error).c_str()); + wsprintf(szBuf, "Warning: encountered problem when loading plugin dll. Error %x: %s", error, GetErrorMessage(error).c_str()); Reporting::Error(szBuf, "DEBUG: Error when loading plugin dll"); } #endif //_DEBUG @@ -2082,7 +2082,6 @@ Bypass(); CString processMethod = (m_Effect.flags & effFlagsCanReplacing) ? "processReplacing" : "process"; CVstPluginManager::ReportPlugException("The plugin %s threw an exception in %s. It has automatically been set to \"Bypass\".", m_pMixStruct->GetName(), processMethod); - vstEvents.Clear(); } ASSERT(outputBuffers != nullptr); @@ -2255,15 +2254,15 @@ } -bool CVstPlugin::MidiSend(DWORD dwMidiCode) -//----------------------------------------- +bool CVstPlugin::MidiSend(uint32 dwMidiCode) +//------------------------------------------ { // Note-Offs go at the start of the queue. bool insertAtFront = (MIDIEvents::GetTypeFromEvent(dwMidiCode) == MIDIEvents::evNoteOff); VstMidiEvent event; event.type = kVstMidiType; - event.byteSize = sizeof(VstMidiEvent); + event.byteSize = sizeof(event); event.deltaFrames = 0; event.flags = 0; event.noteLength = 0; @@ -2272,7 +2271,7 @@ event.noteOffVelocity = 0; event.reserved1 = 0; event.reserved2 = 0; - *(DWORD *)event.midiData = dwMidiCode; + memcpy(event.midiData, &dwMidiCode, 4); #ifdef VST_LOG Log("Sending Midi %02X.%02X.%02X\n", event.midiData[0]&0xff, event.midiData[1]&0xff, event.midiData[2]&0xff); @@ -2282,6 +2281,23 @@ } +bool CVstPlugin::MidiSysexSend(const char *message, uint32 length) +//---------------------------------------------------------------- +{ + VstMidiSysexEvent event; + event.type = kVstSysExType; + event.byteSize = sizeof(event); + event.deltaFrames = 0; + event.flags = 0; + event.dumpBytes = length; + event.resvd1 = 0; + event.sysexDump = const_cast<char *>(message); // We will make our own copy in VstEventQueue::Enqueue + event.resvd2 = 0; + + return vstEvents.Enqueue(reinterpret_cast<VstEvent *>(&event)); +} + + void CVstPlugin::HardAllNotesOff() //-------------------------------- { @@ -2504,7 +2520,7 @@ note -= NOTE_MIN; // Reset pitch bend on each new note, tracker style. - // This is done if the pitch wheel has been moved or there was a vibrato on the previous row (in which case the highest bit of the pitch bend memory is set) + // This is done if the pitch wheel has been moved or there was a vibrato on the previous row (in which case the "vstVibratoFlag" bit of the pitch bend memory is set) if(m_MidiCh[nMidiCh].midiPitchBendPos != EncodePitchBendParam(MIDIEvents::pitchBendCentre)) { MidiPitchBend(nMidiCh, EncodePitchBendParam(MIDIEvents::pitchBendCentre)); Modified: trunk/OpenMPT/mptrack/Vstplug.h =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.h 2013-09-28 21:36:13 UTC (rev 2794) +++ trunk/OpenMPT/mptrack/Vstplug.h 2013-09-29 00:11:57 UTC (rev 2795) @@ -240,7 +240,8 @@ void RestoreAllParameters(long nProg=-1); //rewbs.plugDefaultProgram - added param void RecalculateGain(); void Process(float *pOutL, float *pOutR, size_t nSamples); - bool MidiSend(DWORD dwMidiCode); + bool MidiSend(uint32 dwMidiCode); + bool MidiSysexSend(const char *message, uint32 length); void MidiCC(uint8 nMidiCh, MIDIEvents::MidiCC nController, uint8 nParam, CHANNELINDEX trackChannel); void MidiPitchBend(uint8 nMidiCh, int32 increment, int8 pwd); void MidiVibrato(uint8 nMidiCh, int32 depth, int8 pwd); Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2013-09-28 21:36:13 UTC (rev 2794) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2013-09-29 00:11:57 UTC (rev 2795) @@ -3976,7 +3976,7 @@ pChn->nCutOff = param; } else { - pChn->nCutOff = (BYTE)CalculateSmoothParamChange((float)pChn->nCutOff, (float)param); + pChn->nCutOff = (uint8)CalculateSmoothParamChange((float)pChn->nCutOff, (float)param); } pChn->nRestoreCutoffOnNewNote = 0; } @@ -4000,7 +4000,7 @@ pChn->nResonance = param; } else { - pChn->nResonance = (BYTE)CalculateSmoothParamChange((float)pChn->nResonance, (float)param); + pChn->nResonance = (uint8)CalculateSmoothParamChange((float)pChn->nResonance, (float)param); } } @@ -4080,12 +4080,17 @@ IMixPlugin *pPlugin = m_MixPlugins[nPlug - 1].pMixPlugin; if ((pPlugin) && (m_MixPlugins[nPlug - 1].pMixState)) { - // currently, we don't support sending long MIDI messages in one go... split it up - for(size_t pos = 0; pos < macroLen; pos += 3) + if(macro[0] == 0xF0) { - DWORD curData = 0; - memcpy(&curData, macro + pos, std::min<size_t>(3, macroLen - pos)); - pPlugin->MidiSend(curData); + pPlugin->MidiSysexSend(reinterpret_cast<const char *>(macro), macroLen); + } else + { + for(size_t pos = 0; pos < macroLen; pos += 3) + { + uint32 curData = 0; + memcpy(&curData, macro + pos, std::min<size_t>(3, macroLen - pos)); + pPlugin->MidiSend(curData); + } } } } Modified: trunk/OpenMPT/soundlib/plugins/PlugInterface.h =================================================================== --- trunk/OpenMPT/soundlib/plugins/PlugInterface.h 2013-09-28 21:36:13 UTC (rev 2794) +++ trunk/OpenMPT/soundlib/plugins/PlugInterface.h 2013-09-29 00:11:57 UTC (rev 2795) @@ -40,7 +40,8 @@ virtual void SaveAllParameters() = 0; virtual void RestoreAllParameters(long nProg=-1) = 0; //rewbs.plugDefaultProgram: added param virtual void Process(float *pOutL, float *pOutR, size_t nSamples) = 0; - virtual bool MidiSend(DWORD dwMidiCode) = 0; + virtual bool MidiSend(uint32 dwMidiCode) = 0; + virtual bool MidiSysexSend(const char *message, uint32 length) = 0; virtual void MidiCC(uint8 nMidiCh, MIDIEvents::MidiCC nController, uint8 nParam, CHANNELINDEX trackChannel) = 0; virtual void MidiPitchBend(uint8 nMidiCh, int32 increment, int8 pwd) = 0; virtual void MidiVibrato(uint8 nMidiCh, int32 depth, int8 pwd) = 0; @@ -150,7 +151,7 @@ { IMixPlugin *pMixPlugin; SNDMIXPLUGINSTATE *pMixState; - ULONG nPluginDataSize; + uint32 nPluginDataSize; char *pPluginData; SNDMIXPLUGININFO Info; float fDryRatio; Modified: trunk/OpenMPT/soundlib/plugins/PluginEventQueue.h =================================================================== --- trunk/OpenMPT/soundlib/plugins/PluginEventQueue.h 2013-09-28 21:36:13 UTC (rev 2794) +++ trunk/OpenMPT/soundlib/plugins/PluginEventQueue.h 2013-09-29 00:11:57 UTC (rev 2795) @@ -87,6 +87,18 @@ BiggestVstEvent copyEvent; memcpy(©Event, event, std::min(size_t(event->byteSize), sizeof(copyEvent))); + if(copyEvent.type == kVstSysExType) + { + // SysEx messages need to be copied, as the space used for the dump might be freed in the meantime. + VstMidiSysexEvent *e = reinterpret_cast<VstMidiSysexEvent *>(©Event); + e->sysexDump = new (std::nothrow) char[e->dumpBytes]; + if(e->sysexDump == nullptr) + { + return false; + } + memcpy(e->sysexDump, reinterpret_cast<const VstMidiSysexEvent *>(event)->sysexDump, e->dumpBytes); + } + Util::lock_guard<Util::mutex> lock(criticalSection); if(insertFront) { @@ -116,6 +128,14 @@ Util::lock_guard<Util::mutex> lock(criticalSection); if(numEvents) { + // Release temporarily allocated buffer for SysEx messages + for(VstInt32 i = 0; i < numEvents; i++) + { + if(events[i]->type == kVstSysExType) + { + delete[] reinterpret_cast<VstMidiSysexEvent *>(events[i])->sysexDump; + } + } eventQueue.erase(eventQueue.begin(), eventQueue.begin() + numEvents); numEvents = 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |