Index: build/premake/ext-rtmidi.lua =================================================================== --- build/premake/ext-rtmidi.lua (nonexistent) +++ build/premake/ext-rtmidi.lua (working copy) @@ -0,0 +1,26 @@ + + project "rtmidi" + uuid "05BBD03D-0985-4D76-8DDD-534DA631C3A8" + language "C++" + location ( "../../build/" .. mpt_projectpathname .. "/ext" ) + mpt_projectname = "rtmidi" + dofile "../../build/premake/premake-defaults-LIBorDLL.lua" + dofile "../../build/premake/premake-defaults.lua" + dofile "../../build/premake/premake-defaults-winver.lua" + targetname "openmpt-rtmidi" + filter {} + filter { "action:vs*" } + characterset "Unicode" + filter {} + files { + "../../include/rtmidi/RtMidi.cpp" + } + files { + "../../include/rtmidi/RtMidi.h" + } + defines { + "__WINDOWS_MM__" + } + links { + "winmm" + } Property changes on: build/premake/ext-rtmidi.lua ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/x-lua \ No newline at end of property Index: build/premake/mpt-OpenMPT-VSTi.lua =================================================================== --- build/premake/mpt-OpenMPT-VSTi.lua (revision 7555) +++ build/premake/mpt-OpenMPT-VSTi.lua (working copy) @@ -87,8 +87,8 @@ "opus", "opusfile", "portaudio", - "portmidi", "r8brain", + "rtmidi", "soundtouch", "vorbis", } Index: build/premake/mpt-OpenMPT.lua =================================================================== --- build/premake/mpt-OpenMPT.lua (revision 7555) +++ build/premake/mpt-OpenMPT.lua (working copy) @@ -122,8 +122,8 @@ "opus", "opusfile", "portaudio", - "portmidi", "r8brain", + "rtmidi", "soundtouch", "vorbis", } Index: build/premake/premake.lua =================================================================== --- build/premake/premake.lua (revision 7555) +++ build/premake/premake.lua (working copy) @@ -376,8 +376,8 @@ dofile "../../build/premake/ext-opus.lua" dofile "../../build/premake/ext-opusfile.lua" dofile "../../build/premake/ext-portaudio.lua" - dofile "../../build/premake/ext-portmidi.lua" dofile "../../build/premake/ext-r8brain.lua" + dofile "../../build/premake/ext-rtmidi.lua" dofile "../../build/premake/ext-smbPitchShift.lua" dofile "../../build/premake/ext-soundtouch.lua" dofile "../../build/premake/ext-UnRAR.lua" @@ -405,8 +405,8 @@ dofile "../../build/premake/ext-opus.lua" dofile "../../build/premake/ext-opusfile.lua" dofile "../../build/premake/ext-portaudio.lua" - dofile "../../build/premake/ext-portmidi.lua" dofile "../../build/premake/ext-r8brain.lua" + dofile "../../build/premake/ext-rtmidi.lua" dofile "../../build/premake/ext-smbPitchShift.lua" dofile "../../build/premake/ext-soundtouch.lua" dofile "../../build/premake/ext-UnRAR.lua" @@ -429,8 +429,8 @@ dofile "../../build/premake/ext-opus.lua" dofile "../../build/premake/ext-opusfile.lua" dofile "../../build/premake/ext-portaudio.lua" - dofile "../../build/premake/ext-portmidi.lua" dofile "../../build/premake/ext-r8brain.lua" + dofile "../../build/premake/ext-rtmidi.lua" dofile "../../build/premake/ext-smbPitchShift.lua" dofile "../../build/premake/ext-soundtouch.lua" dofile "../../build/premake/ext-UnRAR.lua" @@ -455,8 +455,8 @@ dofile "../../build/premake/ext-opus.lua" dofile "../../build/premake/ext-opusfile.lua" dofile "../../build/premake/ext-portaudio.lua" - dofile "../../build/premake/ext-portmidi.lua" dofile "../../build/premake/ext-r8brain.lua" + dofile "../../build/premake/ext-rtmidi.lua" dofile "../../build/premake/ext-smbPitchShift.lua" dofile "../../build/premake/ext-soundtouch.lua" dofile "../../build/premake/ext-UnRAR.lua" @@ -481,8 +481,8 @@ dofile "../../build/premake/ext-opus.lua" dofile "../../build/premake/ext-opusfile.lua" dofile "../../build/premake/ext-portaudio.lua" - dofile "../../build/premake/ext-portmidi.lua" dofile "../../build/premake/ext-pugixml.lua" + dofile "../../build/premake/ext-rtmidi.lua" dofile "../../build/premake/ext-r8brain.lua" dofile "../../build/premake/ext-smbPitchShift.lua" dofile "../../build/premake/ext-soundtouch.lua" Index: plugins/MidiInOut/MidiInOut.cpp =================================================================== --- plugins/MidiInOut/MidiInOut.cpp (revision 7555) +++ plugins/MidiInOut/MidiInOut.cpp (working copy) @@ -20,27 +20,27 @@ OPENMPT_NAMESPACE_BEGIN -int MidiInOut::numInstances = 0; - IMixPlugin* MidiInOut::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) //------------------------------------------------------------------------------------------------ { - return new (std::nothrow) MidiInOut(factory, sndFile, mixStruct); + try + { + return new (std::nothrow) MidiInOut(factory, sndFile, mixStruct); + } catch(RtMidiError &) + { + return nullptr; + } } MidiInOut::MidiInOut(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : IMidiPlugin(factory, sndFile, mixStruct) - , latencyCompensation(true) - , programName(_T("Default")) + , m_latencyCompensation(true) + , m_programName(_T("Default")) + , inputDevice(midiIn) + , outputDevice(midiOut) //--------------------------------------------------------------------------------------- { - if(!numInstances++) - { - Pt_Start(1, nullptr, nullptr); - Pm_Initialize(); - } - m_mixBuffer.Initialize(2, 2); InsertIntoFactoryList(); } @@ -50,13 +50,6 @@ //--------------------- { Suspend(); - - if(--numInstances == 0) - { - // This terminates MIDI output for all instances of the plugin, so only ever do it if this was the only instance left. - Pm_Terminate(); - Pt_Stop(); - } } @@ -93,7 +86,7 @@ size_t MidiInOut::GetChunk(char *(&chunk), bool /*isBank*/) //--------------------------------------------------------- { - const std::string programName8 = mpt::ToCharset(mpt::CharsetUTF8, programName); + const std::string programName8 = mpt::ToCharset(mpt::CharsetUTF8, m_programName); const std::string inputName8 = mpt::ToCharset(mpt::CharsetUTF8, mpt::CharsetLocale, inputDevice.name); const std::string outputName8 = mpt::ToCharset(mpt::CharsetUTF8, mpt::CharsetLocale, outputDevice.name); @@ -106,13 +99,13 @@ mpt::IO::WriteIntLE(s, static_cast(inputDevice.name.size())); mpt::IO::WriteIntLE(s, outputDevice.index); mpt::IO::WriteIntLE(s, static_cast(outputDevice.name.size())); - mpt::IO::WriteIntLE(s, latencyCompensation); + mpt::IO::WriteIntLE(s, m_latencyCompensation); mpt::IO::WriteRaw(s, programName8.c_str(), programName8.size()); mpt::IO::WriteRaw(s, inputName8.c_str(), inputName8.size()); mpt::IO::WriteRaw(s, outputName8.c_str(), outputName8.size()); - chunkData = s.str(); - chunk = const_cast(chunkData.c_str()); - return chunkData.size(); + m_chunkData = s.str(); + chunk = const_cast(m_chunkData.c_str()); + return m_chunkData.size(); } @@ -127,28 +120,33 @@ return; uint32 nameStrSize = file.ReadUint32LE(); - PmDeviceID inID = file.ReadUint32LE(); + MidiDevice::ID inID = file.ReadUint32LE(); uint32 inStrSize = file.ReadUint32LE(); - PmDeviceID outID = file.ReadUint32LE(); + MidiDevice::ID outID = file.ReadUint32LE(); uint32 outStrSize = file.ReadUint32LE(); - latencyCompensation = file.ReadUint32LE() != 0; + m_latencyCompensation = file.ReadUint32LE() != 0; std::string s; file.ReadString(s, nameStrSize); - programName = mpt::ToCString(mpt::CharsetUTF8, s); + m_programName = mpt::ToCString(mpt::CharsetUTF8, s); file.ReadString(s, inStrSize); s = mpt::ToCharset(mpt::CharsetLocale, mpt::CharsetUTF8, s); - if(s != GetDeviceName(inID) || !IsInputDevice(inID)) + if(s != inputDevice.GetPortName(inID)) { // Stored name differs from actual device name - try finding another device with the same name. - const PmDeviceInfo *device; - for(PmDeviceID i = 0; (device = Pm_GetDeviceInfo(i)) != nullptr; i++) + unsigned int ports = midiIn.getPortCount(); + for(unsigned int i = 0; i < ports; i++) { - if(device->input && s == device->name) + try { - inID = i; - break; + if(s == inputDevice.GetPortName(i)) + { + inID = i; + break; + } + } catch(RtMidiError &) + { } } } @@ -155,16 +153,21 @@ file.ReadString(s, outStrSize); s = mpt::ToCharset(mpt::CharsetLocale, mpt::CharsetUTF8, s); - if(s != GetDeviceName(outID) || !IsOutputDevice(outID)) + if(s != outputDevice.GetPortName(outID)) { // Stored name differs from actual device name - try finding another device with the same name. - const PmDeviceInfo *device; - for(PmDeviceID i = 0; (device = Pm_GetDeviceInfo(i)) != nullptr; i++) + unsigned int ports = midiOut.getPortCount(); + for(unsigned int i = 0; i < ports; i++) { - if(device->output && s == device->name) + try { - outID = i; - break; + if(s == outputDevice.GetPortName(i)) + { + outID = i; + break; + } + } catch(RtMidiError &) + { } } } @@ -177,7 +180,7 @@ void MidiInOut::SetParameter(PlugParamIndex index, PlugParamValue value) //---------------------------------------------------------------------- { - PmDeviceID newDevice = ParameterToDeviceID(value); + MidiDevice::ID newDevice = ParameterToDeviceID(value); OpenDevice(newDevice, (index == kInputParameter)); // Update selection in editor @@ -236,61 +239,59 @@ void MidiInOut::Process(float *, float *, uint32 numFrames) //--------------------------------------------------------- { - MPT_LOCK_GUARD lock(mutex); + MPT_LOCK_GUARD lock(m_mutex); - if(outputDevice.stream != nullptr) + if(midiOut.isPortOpen()) { // Send MIDI clock - if(nextClock < 1) + if(m_nextClock < 1) { - Pm_WriteShort(outputDevice.stream, Now(), 0xF8); + std::vector message(1, 0xF8); + midiOut.sendMessage(&message); double bpm = m_SndFile.GetCurrentBPM(); if(bpm != 0.0) { - nextClock += 2.5 * m_SndFile.GetSampleRate() / bpm; + m_nextClock += 2.5 * m_SndFile.GetSampleRate() / bpm; } } - nextClock -= numFrames; + m_nextClock -= numFrames; } +} - // We don't do any audio processing here, but we process incoming MIDI events. - if(inputDevice.stream == nullptr) - return; - while(Pm_Poll(inputDevice.stream)) +void MidiInOut::InputCallback(double /*deltatime*/, std::vector &message) +//-------------------------------------------------------------------------------------- +{ + // We will check the bypass status before passing on the message, and not before entering the function, + // because otherwise we might read garbage if we toggle bypass status in the middle of a SysEx message. + bool isBypassed = IsBypassed(); + if(message.empty()) { - // Read incoming MIDI events. - PmEvent buffer; - Pm_Read(inputDevice.stream, &buffer, 1); - - // Discard events if bypassed - if(IsBypassed()) - continue; - - mpt::byte message[sizeof(buffer.message)]; - memcpy(message, &buffer.message, sizeof(message)); - - if(!bufferedMessage.empty()) + return; + } else if(!m_bufferedMessage.empty()) + { + // SysEx message (continued) + m_bufferedMessage.insert(m_bufferedMessage.end(), message.begin(), message.end()); + if(message.back() == 0xF7) { - bufferedMessage.push_back(buffer.message); - if(buffer.message & 0x80808080) - { - // End of message found! - ReceiveSysex(bufferedMessage.data(), bufferedMessage.size() * sizeof(bufferedMessage[0])); - bufferedMessage.clear(); - } - continue; - } else if(message[0] == 0xF0) - { - // Start of SysEx message... - if(message[1] != 0xF7 && message[2] != 0xF7 && message[3] != 0xF7) - bufferedMessage.push_back(buffer.message); // ...but not the end! - else - ReceiveSysex(message, sizeof(message)); - continue; + // End of message found! + if(!isBypassed) + ReceiveSysex(m_bufferedMessage.data(), m_bufferedMessage.size()); + m_bufferedMessage.clear(); } - - ReceiveMidi(buffer.message); + } else if(message.front() == 0xF0) + { + // Start of SysEx message... + if(message.back() != 0xF7) + m_bufferedMessage.insert(m_bufferedMessage.end(), message.begin(), message.end()); // ...but not the end! + else if(!isBypassed) + ReceiveSysex(message.data(), message.size()); + } else if(!isBypassed) + { + // Regular message + uint32 msg = 0; + memcpy(&msg, message.data(), std::min(message.size(), sizeof(msg))); + ReceiveMidi(msg); } } @@ -301,12 +302,13 @@ { // Resume MIDI I/O m_isResumed = true; - nextClock = 0; + m_nextClock = 0; OpenDevice(inputDevice.index, true); OpenDevice(outputDevice.index, false); - if(outputDevice.stream != nullptr) + if(midiOut.isPortOpen()) { - Pm_WriteShort(outputDevice.stream, Now(), 0xFA); // Start + std::vector message(1, 0xFA); // Start + midiOut.sendMessage(&message); } } @@ -316,9 +318,10 @@ //----------------------- { // Suspend MIDI I/O - if(outputDevice.stream != nullptr) + if(midiOut.isPortOpen()) { - Pm_WriteShort(outputDevice.stream, Now(), 0xFC); // Stop + std::vector message(1, 0xFC); // Stop + midiOut.sendMessage(&message); } CloseDevice(inputDevice); CloseDevice(outputDevice); @@ -330,11 +333,12 @@ void MidiInOut::PositionChanged() //------------------------------- { - if(outputDevice.stream != nullptr) + if(midiOut.isPortOpen()) { - const PtTimestamp now = Now(); - Pm_WriteShort(outputDevice.stream, now, 0xFC); // Stop - Pm_WriteShort(outputDevice.stream, now, 0xFA); // Start + std::vector message; + message.push_back(0xFC); // Stop + message.push_back(0xFA); // Start + midiOut.sendMessage(&message); } } @@ -343,27 +347,30 @@ bool MidiInOut::MidiSend(uint32 midiCode) //--------------------------------------- { - if(outputDevice.stream == nullptr || IsBypassed()) + if(!midiOut.isPortOpen() || IsBypassed()) { // We need an output device to send MIDI messages to. return true; } - Pm_WriteShort(outputDevice.stream, Now(), midiCode); + std::vector message(3, 0); + memcpy(&message[0], &midiCode, 3); + midiOut.sendMessage(&message); return true; } -bool MidiInOut::MidiSysexSend(const void *message, uint32 /*length*/) -//------------------------------------------------------------------- +bool MidiInOut::MidiSysexSend(const void *sysex, uint32 length) +//------------------------------------------------------------- { - if(outputDevice.stream == nullptr || IsBypassed()) + if(!midiOut.isPortOpen() || IsBypassed()) { // We need an output device to send MIDI messages to. return true; } - Pm_WriteSysEx(outputDevice.stream, Now(), const_cast(static_cast(message))); + std::vector message(static_cast(sysex), static_cast(sysex) + length); + midiOut.sendMessage(&message); return true; } @@ -405,20 +412,13 @@ } -static PmTimestamp PtTimeWrapper(void* /*time_info*/) -//--------------------------------------------------- -{ - return Pt_Time(); -} - - // Open a device for input or output. -void MidiInOut::OpenDevice(PmDeviceID newDevice, bool asInputDevice) -//------------------------------------------------------------------ +void MidiInOut::OpenDevice(MidiDevice::ID newDevice, bool asInputDevice) +//---------------------------------------------------------------------- { MidiDevice &device = asInputDevice ? inputDevice : outputDevice; - if(device.index == newDevice && device.stream != nullptr) + if(device.index == newDevice && device.stream.isPortOpen()) { // No need to re-open this device. return; @@ -427,46 +427,41 @@ CloseDevice(device); device.index = newDevice; + device.stream.closePort(); if(device.index == kNoDevice) { // Dummy device - device = MidiDevice(); + device.name = ""; return; } - PmError result = pmNoError; - if(m_isResumed) + device.name = device.GetPortName(newDevice); + //if(m_isResumed) { // Don't open MIDI devices if we're not processing. // This has to be done since we receive MIDI events in processReplacing(), // so if no processing is happening, some irrelevant events might be queued until the next processing happens... - MPT_LOCK_GUARD lock(mutex); - if(asInputDevice) + MPT_LOCK_GUARD lock(m_mutex); + + try { - result = Pm_OpenInput(&device.stream, newDevice, nullptr, 0, nullptr, nullptr); - } else + device.stream.openPort(newDevice); + if(asInputDevice) + { + midiIn.setCallback(InputCallback, this); + midiIn.ignoreTypes(false, true, true); + } + } catch(RtMidiError &error) { - if(latencyCompensation) + device.name = "Unavailable"; + MidiInOutEditor *editor = dynamic_cast(GetEditor()); + if(editor != nullptr) { - // buffer of 10000 events - result = Pm_OpenOutput(&device.stream, newDevice, nullptr, 10000, PtTimeWrapper, nullptr, Util::Round(1000.0 * GetOutputLatency())); - } else - { - result = Pm_OpenOutput(&device.stream, newDevice, nullptr, 0, nullptr, nullptr, 0); + Reporting::Error("MIDI device cannot be opened:" + error.getMessage(), "MIDI Input / Output", editor); } } } - - // Update current device name - device.name = GetDeviceName(device.index); - - MidiInOutEditor *editor = dynamic_cast(GetEditor()); - if(result != pmNoError && editor != nullptr) - { - // Display a warning if the editor is open. - Reporting::Error("MIDI device cannot be opened!", "MIDI Input / Output", editor); - } } @@ -474,60 +469,26 @@ void MidiInOut::CloseDevice(MidiDevice &device) //--------------------------------------------- { - if(device.stream != nullptr) + if(device.stream.isPortOpen()) { - MPT_LOCK_GUARD lock(mutex); - Pm_Close(device.stream); - device.stream = nullptr; + MPT_LOCK_GUARD lock(m_mutex); + device.stream.closePort(); } } // Get a device name -const char *MidiInOut::GetDeviceName(PmDeviceID index) const -//----------------------------------------------------------- +std::string MidiDevice::GetPortName(MidiDevice::ID port) +//------------------------------------------------------ { - const PmDeviceInfo *deviceInfo = Pm_GetDeviceInfo(index); - if(deviceInfo != nullptr) - return deviceInfo->name; - else - return "Unavailable"; + std::string portName = stream.getPortName(port); +#if MPT_OS_WINDOWS + // Remove auto-appended port number + if(portName.length() >= 2) + return portName.substr(0, portName.find_last_of(' ')); +#endif + return portName; } -bool MidiInOut::IsInputDevice(PmDeviceID index) const -//---------------------------------------------------- -{ - if(index == kNoDevice) - return true; - - const PmDeviceInfo *deviceInfo = Pm_GetDeviceInfo(index); - if(deviceInfo != nullptr) - return deviceInfo->input != 0; - else - return false; -} - - -bool MidiInOut::IsOutputDevice(PmDeviceID index) const -//---------------------------------------------------- -{ - if(index == kNoDevice) - return true; - - const PmDeviceInfo *deviceInfo = Pm_GetDeviceInfo(index); - if(deviceInfo != nullptr) - return deviceInfo->output != 0; - else - return false; -} - - -PtTimestamp MidiInOut::Now() const -//-------------------------------- -{ - return (latencyCompensation ? Pt_Time() : 0); -} - - OPENMPT_NAMESPACE_END Index: plugins/MidiInOut/MidiInOut.h =================================================================== --- plugins/MidiInOut/MidiInOut.h (revision 7555) +++ plugins/MidiInOut/MidiInOut.h (working copy) @@ -12,8 +12,7 @@ #include "../../common/mptMutex.h" #include "../../soundlib/plugins/PlugInterface.h" -#include -#include +#include "../../include/rtmidi/RtMidi.h" OPENMPT_NAMESPACE_BEGIN @@ -24,16 +23,20 @@ //============== { public: - PmDeviceID index; - PortMidiStream *stream; + typedef unsigned int ID; + + RtMidi &stream; std::string name; + ID index; public: - MidiDevice() - : index(-1) // MidiInOut::kNoDevice - , stream(nullptr) + MidiDevice(RtMidi &stream) + : stream(stream) , name("") + , index(ID(-1)) // MidiInOut::kNoDevice { } + + std::string GetPortName(ID port); }; @@ -56,18 +59,21 @@ kMaxDevices = 65536, // Should be a power of 2 to avoid rounding errors. }; - std::string chunkData; // Storage for GetChunk - std::vector bufferedMessage; // For receiving SysEx messages - mpt::mutex mutex; - double nextClock; + std::string m_chunkData; // Storage for GetChunk + std::vector m_bufferedMessage; // For receiving SysEx messages + mpt::mutex m_mutex; + double m_nextClock; // I/O device settings + RtMidiIn midiIn; + RtMidiOut midiOut; MidiDevice inputDevice; MidiDevice outputDevice; - bool latencyCompensation; + bool m_latencyCompensation; - CString programName; - static int numInstances; +#ifdef MODPLUG_TRACKER + CString m_programName; +#endif public: static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); @@ -75,13 +81,13 @@ ~MidiInOut(); // Translate a VST parameter to a PortMidi device ID - static PmDeviceID ParameterToDeviceID(float value) + static MidiDevice::ID ParameterToDeviceID(float value) { - return static_cast(value * static_cast(kMaxDevices)) - 1; + return static_cast(value * static_cast(kMaxDevices)) - 1; } // Translate a PortMidi device ID to a VST parameter - static float DeviceIDToParameter(PmDeviceID index) + static float DeviceIDToParameter(MidiDevice::ID index) { return static_cast(index + 1) / static_cast(kMaxDevices); } @@ -125,16 +131,12 @@ #ifdef MODPLUG_TRACKER virtual CString GetDefaultEffectName() { return _T("MIDI Input / Output"); } - // Cache a range of names, in case one-by-one retrieval would be slow (e.g. when using plugin bridge) - virtual void CacheProgramNames(int32, int32) { } - virtual void CacheParameterNames(int32, int32) { } - virtual CString GetParamName(PlugParamIndex param); virtual CString GetParamLabel(PlugParamIndex) { return CString(); } virtual CString GetParamDisplay(PlugParamIndex param); - virtual CString GetCurrentProgramName() { return programName; } - virtual void SetCurrentProgramName(const CString &name) { programName = name; } - virtual CString GetProgramName(int32) { return programName; } + virtual CString GetCurrentProgramName() { return m_programName; } + virtual void SetCurrentProgramName(const CString &name) { m_programName = name; } + virtual CString GetProgramName(int32) { return m_programName; } virtual CString GetPluginVendor() { return _T("OpenMPT Project"); } virtual bool HasEditor() const { return true; } @@ -155,18 +157,12 @@ protected: // Open a device for input or output. - void OpenDevice(PmDeviceID newDevice, bool asInputDevice); + void OpenDevice(MidiDevice::ID newDevice, bool asInputDevice); // Close an active device. void CloseDevice(MidiDevice &device); - // Get a device name - const char *GetDeviceName(PmDeviceID index) const; - // Check if the given device is an input device - bool IsInputDevice(PmDeviceID index) const; - // Check if the given device is an output device - bool IsOutputDevice(PmDeviceID index) const; - // Get current timestamp for sending - PtTimestamp Now() const; + static void InputCallback(double deltatime, std::vector *message, void *userData) { static_cast(userData)->InputCallback(deltatime, *message); } + void InputCallback(double deltatime, std::vector &message); }; Index: plugins/MidiInOut/MidiInOutEditor.cpp =================================================================== --- plugins/MidiInOut/MidiInOutEditor.cpp (revision 7555) +++ plugins/MidiInOut/MidiInOutEditor.cpp (working copy) @@ -14,6 +14,7 @@ #include "MidiInOutEditor.h" #include "../../mptrack/Mptrack.h" #include "../../mptrack/resource.h" +#include "../../include/rtmidi/RtMidi.h" OPENMPT_NAMESPACE_BEGIN @@ -51,7 +52,7 @@ //-------------------------------------------- { Create(IDD_MIDI_IO_PLUGIN, parent); - m_latencyCheck.SetCheck(static_cast(m_VstPlugin).latencyCompensation ? BST_CHECKED : BST_UNCHECKED); + m_latencyCheck.SetCheck(static_cast(m_VstPlugin).m_latencyCompensation ? BST_CHECKED : BST_UNCHECKED); PopulateLists(); return CAbstractVstEditor::OpenEditor(parent); } @@ -75,32 +76,38 @@ int selectOutputItem = 0; MidiInOut &plugin = static_cast(m_VstPlugin); - const PmDeviceInfo *device; - CString deviceName; - - // Go through all PortMidi devices - for(PmDeviceID i = 0; (device = Pm_GetDeviceInfo(i)) != nullptr; i++) + // Go through all RtMidi devices + unsigned int ports = plugin.midiIn.getPortCount(); + std::string portName; + for(unsigned int i = 0; i < ports; i++) { - if(device->input) + try { - // We can actually receive MIDI data on this device. - deviceName = theApp.GetFriendlyMIDIPortName(device->name, true) + _T(" [") + CString(device->interf) + _T("]"); - int result = m_inputCombo.AddString(deviceName); + portName = theApp.GetFriendlyMIDIPortName(plugin.inputDevice.GetPortName(i).c_str(), true); + int result = m_inputCombo.AddString(portName.c_str()); m_inputCombo.SetItemData(result, i); if(result != CB_ERR && i == plugin.inputDevice.index) selectInputItem = result; } + catch(RtMidiError &) + { + } + } - if(device->output) + ports = plugin.midiOut.getPortCount(); + for(unsigned int i = 0; i < ports; i++) + { + try { - // We can actually output MIDI data on this device. - deviceName = theApp.GetFriendlyMIDIPortName(device->name, false) + _T(" [") + CString(device->interf) + _T("]"); - int result = m_outputCombo.AddString(deviceName); + portName = theApp.GetFriendlyMIDIPortName(plugin.outputDevice.GetPortName(i).c_str(), false); + int result = m_outputCombo.AddString(portName.c_str()); m_outputCombo.SetItemData(result, i); if(result != CB_ERR && i == plugin.outputDevice.index) selectOutputItem = result; + } catch(RtMidiError &) + { } } @@ -113,13 +120,13 @@ // Refresh current input / output device in GUI -void MidiInOutEditor::SetCurrentDevice(CComboBox &combo, PmDeviceID device) -//------------------------------------------------------------------------- +void MidiInOutEditor::SetCurrentDevice(CComboBox &combo, MidiDevice::ID device) +//----------------------------------------------------------------------------- { int items = combo.GetCount(); for(int i = 0; i < items; i++) { - if(static_cast(combo.GetItemData(i)) == device) + if(static_cast(combo.GetItemData(i)) == device) { combo.SetCurSel(i); break; @@ -132,7 +139,7 @@ //------------------------------------------------------------------------------ { // Update device ID and notify plugin. - PmDeviceID newDevice = static_cast(combo.GetItemData(combo.GetCurSel())); + MidiDevice::ID newDevice = static_cast(combo.GetItemData(combo.GetCurSel())); plugin.SetParameter(param, MidiInOut::DeviceIDToParameter(newDevice)); plugin.AutomateParameter(param); } @@ -157,7 +164,7 @@ { MidiInOut &plugin = static_cast(m_VstPlugin); plugin.CloseDevice(plugin.outputDevice); - plugin.latencyCompensation = (m_latencyCheck.GetCheck() != BST_UNCHECKED); + plugin.m_latencyCompensation = (m_latencyCheck.GetCheck() != BST_UNCHECKED); plugin.OpenDevice(plugin.outputDevice.index, false); } Index: plugins/MidiInOut/MidiInOutEditor.h =================================================================== --- plugins/MidiInOut/MidiInOutEditor.h (revision 7555) +++ plugins/MidiInOut/MidiInOutEditor.h (working copy) @@ -13,7 +13,6 @@ #ifdef MODPLUG_TRACKER #include "../../mptrack/AbstractVstEditor.h" -#include OPENMPT_NAMESPACE_BEGIN @@ -32,7 +31,7 @@ MidiInOutEditor(MidiInOut &plugin); // Refresh current input / output device in GUI - void SetCurrentDevice(bool asInputDevice, PmDeviceID device) + void SetCurrentDevice(bool asInputDevice, MidiDevice::ID device) { CComboBox &combo = asInputDevice ? m_inputCombo : m_outputCombo; SetCurrentDevice(combo, device); @@ -47,7 +46,7 @@ // Update lists of available input / output devices void PopulateLists(); // Refresh current input / output device in GUI - void SetCurrentDevice(CComboBox &combo, PmDeviceID device); + void SetCurrentDevice(CComboBox &combo, MidiDevice::ID device); virtual void DoDataExchange(CDataExchange* pDX);