mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Midi: Use proper PImpl idiom in MidiInput and MidiOutput
This commit is contained in:
parent
fd8ba2deda
commit
c3849041ae
6 changed files with 152 additions and 124 deletions
|
|
@ -164,12 +164,16 @@ public:
|
|||
/** Deprecated. */
|
||||
static std::unique_ptr<MidiInput> openDevice (int, MidiInputCallback*);
|
||||
|
||||
/** @internal */
|
||||
class Pimpl;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
explicit MidiInput (const String&, const String&);
|
||||
|
||||
MidiDeviceInfo deviceInfo;
|
||||
void* internal = nullptr;
|
||||
|
||||
std::unique_ptr<Pimpl> internal;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInput)
|
||||
};
|
||||
|
|
@ -350,6 +354,9 @@ public:
|
|||
/** Deprecated. */
|
||||
static std::unique_ptr<MidiOutput> openDevice (int);
|
||||
|
||||
/** @internal */
|
||||
class Pimpl;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
struct PendingMessage
|
||||
|
|
@ -368,7 +375,9 @@ private:
|
|||
void run() override;
|
||||
|
||||
MidiDeviceInfo deviceInfo;
|
||||
void* internal = nullptr;
|
||||
|
||||
std::unique_ptr<Pimpl> internal;
|
||||
|
||||
CriticalSection lock;
|
||||
PendingMessage* firstMessage = nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -350,17 +350,17 @@ DECLARE_JNI_CLASS_WITH_MIN_SDK (JuceMidiPort, "com/rmsl/juce/JuceMidiSupport$Juc
|
|||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
//==============================================================================
|
||||
class AndroidMidiInput
|
||||
class MidiInput::Pimpl
|
||||
{
|
||||
public:
|
||||
AndroidMidiInput (MidiInput* midiInput, int deviceID, juce::MidiInputCallback* midiInputCallback, jobject deviceManager)
|
||||
Pimpl (MidiInput* midiInput, int deviceID, juce::MidiInputCallback* midiInputCallback, jobject deviceManager)
|
||||
: juceMidiInput (midiInput), callback (midiInputCallback), midiConcatenator (2048),
|
||||
javaMidiDevice (LocalRef<jobject>(getEnv()->CallObjectMethod (deviceManager, MidiDeviceManager.openMidiInputPortWithID,
|
||||
(jint) deviceID, (jlong) this)))
|
||||
{
|
||||
}
|
||||
|
||||
~AndroidMidiInput()
|
||||
~Pimpl()
|
||||
{
|
||||
if (jobject d = javaMidiDevice.get())
|
||||
{
|
||||
|
|
@ -416,7 +416,7 @@ public:
|
|||
static void handleReceive (JNIEnv*, jobject, jlong host, jbyteArray byteArray,
|
||||
jint offset, jint len, jlong timestamp)
|
||||
{
|
||||
auto* myself = reinterpret_cast<AndroidMidiInput*> (host);
|
||||
auto* myself = reinterpret_cast<Pimpl*> (host);
|
||||
|
||||
myself->handleMidi (byteArray, offset, len, timestamp);
|
||||
}
|
||||
|
|
@ -429,15 +429,15 @@ private:
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
class AndroidMidiOutput
|
||||
class MidiOutput::Pimpl
|
||||
{
|
||||
public:
|
||||
AndroidMidiOutput (const LocalRef<jobject>& midiDevice)
|
||||
Pimpl (const LocalRef<jobject>& midiDevice)
|
||||
: javaMidiDevice (midiDevice)
|
||||
{
|
||||
}
|
||||
|
||||
~AndroidMidiOutput()
|
||||
~Pimpl()
|
||||
{
|
||||
if (jobject d = javaMidiDevice.get())
|
||||
{
|
||||
|
|
@ -468,7 +468,7 @@ private:
|
|||
|
||||
//==============================================================================
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
||||
CALLBACK (AndroidMidiInput::handleReceive, "handleReceive", "(J[BIIJ)V" )
|
||||
CALLBACK (MidiInput::Pimpl::handleReceive, "handleReceive", "(J[BIIJ)V" )
|
||||
|
||||
DECLARE_JNI_CLASS_WITH_MIN_SDK (JuceMidiInputPort, "com/rmsl/juce/JuceMidiSupport$JuceMidiInputPort", 23)
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
|
@ -509,11 +509,11 @@ public:
|
|||
return {};
|
||||
}
|
||||
|
||||
AndroidMidiInput* openMidiInputPortWithID (int deviceID, MidiInput* juceMidiInput, juce::MidiInputCallback* callback)
|
||||
MidiInput::Pimpl* openMidiInputPortWithID (int deviceID, MidiInput* juceMidiInput, juce::MidiInputCallback* callback)
|
||||
{
|
||||
if (auto dm = deviceManager.get())
|
||||
{
|
||||
std::unique_ptr<AndroidMidiInput> androidMidiInput (new AndroidMidiInput (juceMidiInput, deviceID, callback, dm));
|
||||
auto androidMidiInput = std::make_unique<MidiInput::Pimpl> (juceMidiInput, deviceID, callback, dm);
|
||||
|
||||
if (androidMidiInput->isOpen())
|
||||
return androidMidiInput.release();
|
||||
|
|
@ -522,11 +522,11 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
AndroidMidiOutput* openMidiOutputPortWithID (int deviceID)
|
||||
MidiOutput::Pimpl* openMidiOutputPortWithID (int deviceID)
|
||||
{
|
||||
if (auto dm = deviceManager.get())
|
||||
if (auto javaMidiPort = getEnv()->CallObjectMethod (dm, MidiDeviceManager.openMidiOutputPortWithID, (jint) deviceID))
|
||||
return new AndroidMidiOutput (LocalRef<jobject>(javaMidiPort));
|
||||
return new MidiOutput::Pimpl (LocalRef<jobject>(javaMidiPort));
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -564,7 +564,7 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier
|
|||
|
||||
if (auto* port = manager.openMidiInputPortWithID (deviceIdentifier.getIntValue(), midiInput.get(), callback))
|
||||
{
|
||||
midiInput->internal = port;
|
||||
midiInput->internal.reset (port);
|
||||
midiInput->setName (port->getName());
|
||||
|
||||
return midiInput;
|
||||
|
|
@ -601,20 +601,17 @@ MidiInput::MidiInput (const String& deviceName, const String& deviceIdentifier)
|
|||
{
|
||||
}
|
||||
|
||||
MidiInput::~MidiInput()
|
||||
{
|
||||
delete reinterpret_cast<AndroidMidiInput*> (internal);
|
||||
}
|
||||
MidiInput::~MidiInput() = default;
|
||||
|
||||
void MidiInput::start()
|
||||
{
|
||||
if (auto* mi = reinterpret_cast<AndroidMidiInput*> (internal))
|
||||
if (auto* mi = internal.get())
|
||||
mi->start();
|
||||
}
|
||||
|
||||
void MidiInput::stop()
|
||||
{
|
||||
if (auto* mi = reinterpret_cast<AndroidMidiInput*> (internal))
|
||||
if (auto* mi = internal.get())
|
||||
mi->stop();
|
||||
}
|
||||
|
||||
|
|
@ -646,7 +643,7 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (const String& deviceIdentifi
|
|||
if (auto* port = manager.openMidiOutputPortWithID (deviceIdentifier.getIntValue()))
|
||||
{
|
||||
std::unique_ptr<MidiOutput> midiOutput (new MidiOutput ({}, deviceIdentifier));
|
||||
midiOutput->internal = port;
|
||||
midiOutput->internal.reset (port);
|
||||
midiOutput->setName (port->getName());
|
||||
|
||||
return midiOutput;
|
||||
|
|
@ -681,13 +678,11 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (int index)
|
|||
MidiOutput::~MidiOutput()
|
||||
{
|
||||
stopBackgroundThread();
|
||||
|
||||
delete reinterpret_cast<AndroidMidiOutput*> (internal);
|
||||
}
|
||||
|
||||
void MidiOutput::sendMessageNow (const MidiMessage& message)
|
||||
{
|
||||
if (auto* androidMidi = reinterpret_cast<AndroidMidiOutput*>(internal))
|
||||
if (auto* androidMidi = internal.get())
|
||||
{
|
||||
auto* env = getEnv();
|
||||
auto messageSize = message.getRawDataSize();
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ namespace juce
|
|||
{
|
||||
|
||||
//==============================================================================
|
||||
class BelaMidiInput
|
||||
class MidiInput::Pimpl
|
||||
{
|
||||
public:
|
||||
static Array<BelaMidiInput*> midiInputs;
|
||||
static Array<Pimpl*> midiInputs;
|
||||
|
||||
BelaMidiInput (const String& port, MidiInput* input, MidiInputCallback* callback)
|
||||
Pimpl (const String& port, MidiInput* input, MidiInputCallback* callback)
|
||||
: midiInput (input), midiPort (port), midiCallback (callback)
|
||||
{
|
||||
jassert (midiCallback != nullptr);
|
||||
|
|
@ -38,7 +38,7 @@ public:
|
|||
buffer.resize (32);
|
||||
}
|
||||
|
||||
~BelaMidiInput()
|
||||
~Pimpl()
|
||||
{
|
||||
stop();
|
||||
midiInputs.removeAllInstancesOf (this);
|
||||
|
|
@ -76,7 +76,7 @@ public:
|
|||
}
|
||||
|
||||
if (receivedBytes > 0)
|
||||
pushMidiData (receivedBytes);
|
||||
pushMidiData ((int) receivedBytes);
|
||||
}
|
||||
|
||||
static Array<MidiDeviceInfo> getDevices (bool input)
|
||||
|
|
@ -141,7 +141,7 @@ private:
|
|||
snd_rawmidi_info_t* info;
|
||||
snd_rawmidi_info_alloca (&info);
|
||||
|
||||
snd_rawmidi_info_set_device (info, device);
|
||||
snd_rawmidi_info_set_device (info, (unsigned int) device);
|
||||
snd_rawmidi_info_set_stream (info, input ? SND_RAWMIDI_STREAM_INPUT
|
||||
: SND_RAWMIDI_STREAM_OUTPUT);
|
||||
|
||||
|
|
@ -173,10 +173,10 @@ private:
|
|||
Midi midi;
|
||||
MidiDataConcatenator concatenator { 512 };
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BelaMidiInput)
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl)
|
||||
};
|
||||
|
||||
Array<BelaMidiInput*> BelaMidiInput::midiInputs;
|
||||
Array<MidiInput::Pimpl*> MidiInput::Pimpl::midiInputs;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -366,7 +366,7 @@ public:
|
|||
String getLastError() override { return lastError; }
|
||||
|
||||
//==============================================================================
|
||||
int getCurrentBufferSizeSamples() override { return actualBufferSize; }
|
||||
int getCurrentBufferSizeSamples() override { return (int) actualBufferSize; }
|
||||
double getCurrentSampleRate() override { return 44100.0; }
|
||||
int getCurrentBitDepth() override { return 16; }
|
||||
BigInteger getActiveOutputChannels() const override { BigInteger b; b.setRange (0, actualNumberOfOutputs, true); return b; }
|
||||
|
|
@ -384,8 +384,8 @@ private:
|
|||
bool setup (BelaContext& context)
|
||||
{
|
||||
actualBufferSize = context.audioFrames;
|
||||
actualNumberOfInputs = context.audioInChannels + context.analogInChannels;
|
||||
actualNumberOfOutputs = context.audioOutChannels + context.analogOutChannels;
|
||||
actualNumberOfInputs = (int) (context.audioInChannels + context.analogInChannels);
|
||||
actualNumberOfOutputs = (int) (context.audioOutChannels + context.analogOutChannels);
|
||||
isBelaOpen = true;
|
||||
firstCallback = true;
|
||||
|
||||
|
|
@ -405,7 +405,7 @@ private:
|
|||
ScopedLock lock (callbackLock);
|
||||
|
||||
// Check for and process and midi
|
||||
for (auto midiInput : BelaMidiInput::midiInputs)
|
||||
for (auto midiInput : MidiInput::Pimpl::midiInputs)
|
||||
midiInput->poll();
|
||||
|
||||
if (callback != nullptr)
|
||||
|
|
@ -413,27 +413,29 @@ private:
|
|||
jassert (context.audioFrames <= actualBufferSize);
|
||||
jassert ((context.flags & BELA_FLAG_INTERLEAVED) == 0);
|
||||
|
||||
using Frames = decltype (context.audioFrames);
|
||||
|
||||
// Setup channelInBuffers
|
||||
for (int ch = 0; ch < actualNumberOfInputs; ++ch)
|
||||
{
|
||||
if (ch < analogChannelStart)
|
||||
channelInBuffer[ch] = &context.audioIn[ch * context.audioFrames];
|
||||
channelInBuffer[ch] = &context.audioIn[(Frames) ch * context.audioFrames];
|
||||
else
|
||||
channelInBuffer[ch] = &context.analogIn[(ch - analogChannelStart) * context.analogFrames];
|
||||
channelInBuffer[ch] = &context.analogIn[(Frames) (ch - analogChannelStart) * context.analogFrames];
|
||||
}
|
||||
|
||||
// Setup channelOutBuffers
|
||||
for (int ch = 0; ch < actualNumberOfOutputs; ++ch)
|
||||
{
|
||||
if (ch < analogChannelStart)
|
||||
channelOutBuffer[ch] = &context.audioOut[ch * context.audioFrames];
|
||||
channelOutBuffer[ch] = &context.audioOut[(Frames) ch * context.audioFrames];
|
||||
else
|
||||
channelOutBuffer[ch] = &context.analogOut[(ch - analogChannelStart) * context.audioFrames];
|
||||
channelOutBuffer[ch] = &context.analogOut[(Frames) (ch - analogChannelStart) * context.audioFrames];
|
||||
}
|
||||
|
||||
callback->audioDeviceIOCallback (channelInBuffer.getData(), actualNumberOfInputs,
|
||||
channelOutBuffer.getData(), actualNumberOfOutputs,
|
||||
context.audioFrames);
|
||||
(int) context.audioFrames);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -527,13 +529,13 @@ MidiInput::MidiInput (const String& deviceName, const String& deviceID)
|
|||
{
|
||||
}
|
||||
|
||||
MidiInput::~MidiInput() { delete static_cast<BelaMidiInput*> (internal); }
|
||||
void MidiInput::start() { static_cast<BelaMidiInput*> (internal)->start(); }
|
||||
void MidiInput::stop() { static_cast<BelaMidiInput*> (internal)->stop(); }
|
||||
MidiInput::~MidiInput() = default;
|
||||
void MidiInput::start() { internal->start(); }
|
||||
void MidiInput::stop() { internal->stop(); }
|
||||
|
||||
Array<MidiDeviceInfo> MidiInput::getAvailableDevices()
|
||||
{
|
||||
return BelaMidiInput::getDevices (true);
|
||||
return Pimpl::getDevices (true);
|
||||
}
|
||||
|
||||
MidiDeviceInfo MidiInput::getDefaultDevice()
|
||||
|
|
@ -547,7 +549,7 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier
|
|||
return {};
|
||||
|
||||
std::unique_ptr<MidiInput> midiInput (new MidiInput (deviceIdentifier, deviceIdentifier));
|
||||
midiInput->internal = new BelaMidiInput (deviceIdentifier, midiInput.get(), callback);
|
||||
midiInput->internal = std::make_unique<Pimpl> (deviceIdentifier, midiInput.get(), callback);
|
||||
|
||||
return midiInput;
|
||||
}
|
||||
|
|
@ -581,7 +583,8 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (int index, MidiInputCallback*
|
|||
|
||||
//==============================================================================
|
||||
// TODO: Add Bela MidiOutput support
|
||||
MidiOutput::~MidiOutput() {}
|
||||
class MidiOutput::Pimpl {};
|
||||
MidiOutput::~MidiOutput() = default;
|
||||
void MidiOutput::sendMessageNow (const MidiMessage&) {}
|
||||
Array<MidiDeviceInfo> MidiOutput::getAvailableDevices() { return {}; }
|
||||
MidiDeviceInfo MidiOutput::getDefaultDevice() { return {}; }
|
||||
|
|
|
|||
|
|
@ -25,10 +25,6 @@ namespace juce
|
|||
|
||||
#if JUCE_ALSA
|
||||
|
||||
//==============================================================================
|
||||
namespace
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
class AlsaClient : public ReferenceCountedObject
|
||||
{
|
||||
|
|
@ -453,9 +449,23 @@ static AlsaClient::Port* iterateMidiDevices (bool forInput,
|
|||
return port;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
struct AlsaPortPtr
|
||||
{
|
||||
explicit AlsaPortPtr (AlsaClient::Port* p)
|
||||
: ptr (p) {}
|
||||
|
||||
~AlsaPortPtr() noexcept { AlsaClient::getInstance()->deletePort (ptr); }
|
||||
|
||||
AlsaClient::Port* ptr = nullptr;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class MidiInput::Pimpl : public AlsaPortPtr
|
||||
{
|
||||
public:
|
||||
using AlsaPortPtr::AlsaPortPtr;
|
||||
};
|
||||
|
||||
Array<MidiDeviceInfo> MidiInput::getAvailableDevices()
|
||||
{
|
||||
Array<MidiDeviceInfo> devices;
|
||||
|
|
@ -485,7 +495,7 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier
|
|||
std::unique_ptr<MidiInput> midiInput (new MidiInput (port->portName, deviceIdentifier));
|
||||
|
||||
port->setupInput (midiInput.get(), callback);
|
||||
midiInput->internal = port;
|
||||
midiInput->internal = std::make_unique<Pimpl> (port);
|
||||
|
||||
return midiInput;
|
||||
}
|
||||
|
|
@ -501,7 +511,7 @@ std::unique_ptr<MidiInput> MidiInput::createNewDevice (const String& deviceName,
|
|||
std::unique_ptr<MidiInput> midiInput (new MidiInput (deviceName, getFormattedPortIdentifier (client->getId(), port->portId)));
|
||||
|
||||
port->setupInput (midiInput.get(), callback);
|
||||
midiInput->internal = port;
|
||||
midiInput->internal = std::make_unique<Pimpl> (port);
|
||||
|
||||
return midiInput;
|
||||
}
|
||||
|
|
@ -536,20 +546,25 @@ MidiInput::MidiInput (const String& deviceName, const String& deviceIdentifier)
|
|||
MidiInput::~MidiInput()
|
||||
{
|
||||
stop();
|
||||
AlsaClient::getInstance()->deletePort (static_cast<AlsaClient::Port*> (internal));
|
||||
}
|
||||
|
||||
void MidiInput::start()
|
||||
{
|
||||
static_cast<AlsaClient::Port*> (internal)->enableCallback (true);
|
||||
internal->ptr->enableCallback (true);
|
||||
}
|
||||
|
||||
void MidiInput::stop()
|
||||
{
|
||||
static_cast<AlsaClient::Port*> (internal)->enableCallback (false);
|
||||
internal->ptr->enableCallback (false);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class MidiOutput::Pimpl : public AlsaPortPtr
|
||||
{
|
||||
public:
|
||||
using AlsaPortPtr::AlsaPortPtr;
|
||||
};
|
||||
|
||||
Array<MidiDeviceInfo> MidiOutput::getAvailableDevices()
|
||||
{
|
||||
Array<MidiDeviceInfo> devices;
|
||||
|
|
@ -577,7 +592,7 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (const String& deviceIdentifi
|
|||
std::unique_ptr<MidiOutput> midiOutput (new MidiOutput (port->portName, deviceIdentifier));
|
||||
|
||||
port->setupOutput();
|
||||
midiOutput->internal = port;
|
||||
midiOutput->internal = std::make_unique<Pimpl> (port);
|
||||
|
||||
return midiOutput;
|
||||
}
|
||||
|
|
@ -593,7 +608,7 @@ std::unique_ptr<MidiOutput> MidiOutput::createNewDevice (const String& deviceNam
|
|||
std::unique_ptr<MidiOutput> midiOutput (new MidiOutput (deviceName, getFormattedPortIdentifier (client->getId(), port->portId)));
|
||||
|
||||
port->setupOutput();
|
||||
midiOutput->internal = port;
|
||||
midiOutput->internal = std::make_unique<Pimpl> (port);
|
||||
|
||||
return midiOutput;
|
||||
}
|
||||
|
|
@ -623,12 +638,11 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (int index)
|
|||
MidiOutput::~MidiOutput()
|
||||
{
|
||||
stopBackgroundThread();
|
||||
AlsaClient::getInstance()->deletePort (static_cast<AlsaClient::Port*> (internal));
|
||||
}
|
||||
|
||||
void MidiOutput::sendMessageNow (const MidiMessage& message)
|
||||
{
|
||||
static_cast<AlsaClient::Port*> (internal)->sendMessageNow (message);
|
||||
internal->ptr->sendMessageNow (message);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -393,6 +393,12 @@ namespace CoreMidiHelpers
|
|||
}
|
||||
}
|
||||
|
||||
class MidiInput::Pimpl : public CoreMidiHelpers::MidiPortAndCallback
|
||||
{
|
||||
public:
|
||||
using MidiPortAndCallback::MidiPortAndCallback;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
Array<MidiDeviceInfo> MidiInput::getAvailableDevices()
|
||||
{
|
||||
|
|
@ -424,7 +430,7 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier
|
|||
if (CHECK_ERROR (MIDIObjectGetStringProperty (endpoint, kMIDIPropertyName, &cfName.cfString)))
|
||||
{
|
||||
MIDIPortRef port;
|
||||
auto mpc = std::make_unique<MidiPortAndCallback> (*callback);
|
||||
auto mpc = std::make_unique<Pimpl> (*callback);
|
||||
|
||||
if (CHECK_ERROR (MIDIInputPortCreate (client, cfName.cfString, midiInputProc, mpc.get(), &port)))
|
||||
{
|
||||
|
|
@ -435,10 +441,11 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier
|
|||
std::unique_ptr<MidiInput> midiInput (new MidiInput (endpointInfo.name, endpointInfo.identifier));
|
||||
|
||||
mpc->input = midiInput.get();
|
||||
midiInput->internal = mpc.get();
|
||||
auto* ptr = mpc.get();
|
||||
midiInput->internal = std::move (mpc);
|
||||
|
||||
const ScopedLock sl (callbackLock);
|
||||
activeCallbacks.add (mpc.release());
|
||||
activeCallbacks.add (ptr);
|
||||
|
||||
return midiInput;
|
||||
}
|
||||
|
|
@ -462,7 +469,7 @@ std::unique_ptr<MidiInput> MidiInput::createNewDevice (const String& deviceName,
|
|||
|
||||
if (auto client = getGlobalMidiClient())
|
||||
{
|
||||
auto mpc = std::make_unique<MidiPortAndCallback> (*callback);
|
||||
auto mpc = std::make_unique<Pimpl> (*callback);
|
||||
mpc->active = false;
|
||||
|
||||
MIDIEndpointRef endpoint;
|
||||
|
|
@ -491,10 +498,11 @@ std::unique_ptr<MidiInput> MidiInput::createNewDevice (const String& deviceName,
|
|||
std::unique_ptr<MidiInput> midiInput (new MidiInput (deviceName, String (deviceIdentifier)));
|
||||
|
||||
mpc->input = midiInput.get();
|
||||
midiInput->internal = mpc.get();
|
||||
auto* ptr = mpc.get();
|
||||
midiInput->internal = std::move (mpc);
|
||||
|
||||
const ScopedLock sl (callbackLock);
|
||||
activeCallbacks.add (mpc.release());
|
||||
activeCallbacks.add (ptr);
|
||||
|
||||
return midiInput;
|
||||
}
|
||||
|
|
@ -529,24 +537,27 @@ MidiInput::MidiInput (const String& deviceName, const String& deviceIdentifier)
|
|||
{
|
||||
}
|
||||
|
||||
MidiInput::~MidiInput()
|
||||
{
|
||||
delete static_cast<CoreMidiHelpers::MidiPortAndCallback*> (internal);
|
||||
}
|
||||
MidiInput::~MidiInput() = default;
|
||||
|
||||
void MidiInput::start()
|
||||
{
|
||||
const ScopedLock sl (CoreMidiHelpers::callbackLock);
|
||||
static_cast<CoreMidiHelpers::MidiPortAndCallback*> (internal)->active = true;
|
||||
internal->active = true;
|
||||
}
|
||||
|
||||
void MidiInput::stop()
|
||||
{
|
||||
const ScopedLock sl (CoreMidiHelpers::callbackLock);
|
||||
static_cast<CoreMidiHelpers::MidiPortAndCallback*> (internal)->active = false;
|
||||
internal->active = false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class MidiOutput::Pimpl : public CoreMidiHelpers::MidiPortAndEndpoint
|
||||
{
|
||||
public:
|
||||
using MidiPortAndEndpoint::MidiPortAndEndpoint;
|
||||
};
|
||||
|
||||
Array<MidiDeviceInfo> MidiOutput::getAvailableDevices()
|
||||
{
|
||||
return CoreMidiHelpers::findDevices (false);
|
||||
|
|
@ -581,7 +592,7 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (const String& deviceIdentifi
|
|||
if (CHECK_ERROR (MIDIOutputPortCreate (client, cfName.cfString, &port)))
|
||||
{
|
||||
std::unique_ptr<MidiOutput> midiOutput (new MidiOutput (endpointInfo.name, endpointInfo.identifier));
|
||||
midiOutput->internal = new MidiPortAndEndpoint (port, endpoint);
|
||||
midiOutput->internal = std::make_unique<Pimpl> (port, endpoint);
|
||||
|
||||
return midiOutput;
|
||||
}
|
||||
|
|
@ -622,7 +633,7 @@ std::unique_ptr<MidiOutput> MidiOutput::createNewDevice (const String& deviceNam
|
|||
if (CHECK_ERROR (MIDIObjectSetIntegerProperty (endpoint, kMIDIPropertyUniqueID, (SInt32) deviceIdentifier)))
|
||||
{
|
||||
std::unique_ptr<MidiOutput> midiOutput (new MidiOutput (deviceName, String (deviceIdentifier)));
|
||||
midiOutput->internal = new MidiPortAndEndpoint (0, endpoint);
|
||||
midiOutput->internal = std::make_unique<Pimpl> ((UInt32) 0, endpoint);
|
||||
|
||||
return midiOutput;
|
||||
}
|
||||
|
|
@ -655,8 +666,6 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (int index)
|
|||
MidiOutput::~MidiOutput()
|
||||
{
|
||||
stopBackgroundThread();
|
||||
|
||||
delete static_cast<CoreMidiHelpers::MidiPortAndEndpoint*> (internal);
|
||||
}
|
||||
|
||||
void MidiOutput::sendMessageNow (const MidiMessage& message)
|
||||
|
|
@ -715,7 +724,7 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
|
|||
return;
|
||||
}
|
||||
|
||||
static_cast<CoreMidiHelpers::MidiPortAndEndpoint*> (internal)->send (packetToSend);
|
||||
internal->send (packetToSend);
|
||||
}
|
||||
|
||||
#undef CHECK_ERROR
|
||||
|
|
|
|||
|
|
@ -29,37 +29,39 @@
|
|||
namespace juce
|
||||
{
|
||||
|
||||
class MidiInput::Pimpl
|
||||
{
|
||||
public:
|
||||
virtual ~Pimpl() noexcept = default;
|
||||
|
||||
virtual String getDeviceIdentifier() = 0;
|
||||
virtual String getDeviceName() = 0;
|
||||
|
||||
virtual void start() = 0;
|
||||
virtual void stop() = 0;
|
||||
};
|
||||
|
||||
class MidiOutput::Pimpl
|
||||
{
|
||||
public:
|
||||
virtual ~Pimpl() noexcept = default;
|
||||
|
||||
virtual String getDeviceIdentifier() = 0;
|
||||
virtual String getDeviceName() = 0;
|
||||
|
||||
virtual void sendMessageNow (const MidiMessage&) = 0;
|
||||
};
|
||||
|
||||
struct MidiServiceType
|
||||
{
|
||||
struct InputWrapper
|
||||
{
|
||||
virtual ~InputWrapper() {}
|
||||
|
||||
virtual String getDeviceIdentifier() = 0;
|
||||
virtual String getDeviceName() = 0;
|
||||
|
||||
virtual void start() = 0;
|
||||
virtual void stop() = 0;
|
||||
};
|
||||
|
||||
struct OutputWrapper
|
||||
{
|
||||
virtual ~OutputWrapper() {}
|
||||
|
||||
virtual String getDeviceIdentifier() = 0;
|
||||
virtual String getDeviceName() = 0;
|
||||
|
||||
virtual void sendMessageNow (const MidiMessage&) = 0;
|
||||
};
|
||||
|
||||
MidiServiceType() {}
|
||||
virtual ~MidiServiceType() {}
|
||||
MidiServiceType() = default;
|
||||
virtual ~MidiServiceType() noexcept = default;
|
||||
|
||||
virtual Array<MidiDeviceInfo> getAvailableDevices (bool) = 0;
|
||||
virtual MidiDeviceInfo getDefaultDevice (bool) = 0;
|
||||
|
||||
virtual InputWrapper* createInputWrapper (MidiInput&, const String&, MidiInputCallback&) = 0;
|
||||
virtual OutputWrapper* createOutputWrapper (const String&) = 0;
|
||||
virtual MidiInput::Pimpl* createInputWrapper (MidiInput&, const String&, MidiInputCallback&) = 0;
|
||||
virtual MidiOutput::Pimpl* createOutputWrapper (const String&) = 0;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiServiceType)
|
||||
};
|
||||
|
|
@ -82,12 +84,12 @@ struct Win32MidiService : public MidiServiceType,
|
|||
: Win32OutputWrapper::getDefaultDevice();
|
||||
}
|
||||
|
||||
InputWrapper* createInputWrapper (MidiInput& input, const String& deviceIdentifier, MidiInputCallback& callback) override
|
||||
MidiInput::Pimpl* createInputWrapper (MidiInput& input, const String& deviceIdentifier, MidiInputCallback& callback) override
|
||||
{
|
||||
return new Win32InputWrapper (*this, input, deviceIdentifier, callback);
|
||||
}
|
||||
|
||||
OutputWrapper* createOutputWrapper (const String& deviceIdentifier) override
|
||||
MidiOutput::Pimpl* createOutputWrapper (const String& deviceIdentifier) override
|
||||
{
|
||||
return new Win32OutputWrapper (*this, deviceIdentifier);
|
||||
}
|
||||
|
|
@ -384,7 +386,7 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
struct Win32InputWrapper : public InputWrapper,
|
||||
struct Win32InputWrapper : public MidiInput::Pimpl,
|
||||
public Win32MidiDeviceQuery<Win32InputWrapper>
|
||||
{
|
||||
Win32InputWrapper (Win32MidiService& parentService, MidiInput& midiInput, const String& deviceIdentifier, MidiInputCallback& c)
|
||||
|
|
@ -508,7 +510,7 @@ private:
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
struct Win32OutputWrapper : public OutputWrapper,
|
||||
struct Win32OutputWrapper : public MidiOutput::Pimpl,
|
||||
public Win32MidiDeviceQuery<Win32OutputWrapper>
|
||||
{
|
||||
Win32OutputWrapper (Win32MidiService& p, const String& deviceIdentifier)
|
||||
|
|
@ -763,12 +765,12 @@ public:
|
|||
: outputDeviceWatcher->getDefaultDevice();
|
||||
}
|
||||
|
||||
InputWrapper* createInputWrapper (MidiInput& input, const String& deviceIdentifier, MidiInputCallback& callback) override
|
||||
MidiInput::Pimpl* createInputWrapper (MidiInput& input, const String& deviceIdentifier, MidiInputCallback& callback) override
|
||||
{
|
||||
return new WinRTInputWrapper (*this, input, deviceIdentifier, callback);
|
||||
}
|
||||
|
||||
OutputWrapper* createOutputWrapper (const String& deviceIdentifier) override
|
||||
MidiOutput::Pimpl* createOutputWrapper (const String& deviceIdentifier) override
|
||||
{
|
||||
return new WinRTOutputWrapper (*this, deviceIdentifier);
|
||||
}
|
||||
|
|
@ -1554,7 +1556,7 @@ private:
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
struct WinRTInputWrapper final : public InputWrapper,
|
||||
struct WinRTInputWrapper final : public MidiInput::Pimpl,
|
||||
private WinRTIOWrapper<IMidiInPortStatics, IMidiInPort>
|
||||
|
||||
{
|
||||
|
|
@ -1708,7 +1710,7 @@ private:
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
struct WinRTOutputWrapper final : public OutputWrapper,
|
||||
struct WinRTOutputWrapper final : public MidiOutput::Pimpl,
|
||||
private WinRTIOWrapper <IMidiOutPortStatics, IMidiOutPort>
|
||||
{
|
||||
WinRTOutputWrapper (WinRTMidiService& service, const String& deviceIdentifier)
|
||||
|
|
@ -1865,7 +1867,7 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier
|
|||
return {};
|
||||
|
||||
std::unique_ptr<MidiInput> in (new MidiInput ({}, deviceIdentifier));
|
||||
std::unique_ptr<MidiServiceType::InputWrapper> wrapper;
|
||||
std::unique_ptr<Pimpl> wrapper;
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -1877,7 +1879,7 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier
|
|||
}
|
||||
|
||||
in->setName (wrapper->getDeviceName());
|
||||
in->internal = wrapper.release();
|
||||
in->internal = std::move (wrapper);
|
||||
|
||||
return in;
|
||||
}
|
||||
|
|
@ -1907,13 +1909,10 @@ MidiInput::MidiInput (const String& deviceName, const String& deviceIdentifier)
|
|||
{
|
||||
}
|
||||
|
||||
MidiInput::~MidiInput()
|
||||
{
|
||||
delete static_cast<MidiServiceType::InputWrapper*> (internal);
|
||||
}
|
||||
MidiInput::~MidiInput() = default;
|
||||
|
||||
void MidiInput::start() { static_cast<MidiServiceType::InputWrapper*> (internal)->start(); }
|
||||
void MidiInput::stop() { static_cast<MidiServiceType::InputWrapper*> (internal)->stop(); }
|
||||
void MidiInput::start() { internal->start(); }
|
||||
void MidiInput::stop() { internal->stop(); }
|
||||
|
||||
//==============================================================================
|
||||
Array<MidiDeviceInfo> MidiOutput::getAvailableDevices()
|
||||
|
|
@ -1931,7 +1930,7 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (const String& deviceIdentifi
|
|||
if (deviceIdentifier.isEmpty())
|
||||
return {};
|
||||
|
||||
std::unique_ptr<MidiServiceType::OutputWrapper> wrapper;
|
||||
std::unique_ptr<Pimpl> wrapper;
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -1945,7 +1944,7 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (const String& deviceIdentifi
|
|||
std::unique_ptr<MidiOutput> out;
|
||||
out.reset (new MidiOutput (wrapper->getDeviceName(), deviceIdentifier));
|
||||
|
||||
out->internal = wrapper.release();
|
||||
out->internal = std::move (wrapper);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
@ -1973,12 +1972,11 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (int index)
|
|||
MidiOutput::~MidiOutput()
|
||||
{
|
||||
stopBackgroundThread();
|
||||
delete static_cast<MidiServiceType::OutputWrapper*> (internal);
|
||||
}
|
||||
|
||||
void MidiOutput::sendMessageNow (const MidiMessage& message)
|
||||
{
|
||||
static_cast<MidiServiceType::OutputWrapper*> (internal)->sendMessageNow (message);
|
||||
internal->sendMessageNow (message);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue