mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
MIDI: Get rid of InputHandler types that are no longer required
This commit is contained in:
parent
7dc906fa1b
commit
9a7e70ced3
4 changed files with 50 additions and 356 deletions
|
|
@ -66,8 +66,6 @@
|
|||
#include <juce_audio_basics/native/juce_AudioWorkgroup_mac.h>
|
||||
#include <juce_audio_basics/midi/juce_MidiDataConcatenator.h>
|
||||
#include <juce_audio_basics/midi/ump/juce_UMP.h>
|
||||
#include "midi_io/ump/juce_UMPBytestreamInputHandler.h"
|
||||
#include "midi_io/ump/juce_UMPU32InputHandler.h"
|
||||
#endif
|
||||
|
||||
#if JUCE_MAC
|
||||
|
|
|
|||
|
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/** @cond */
|
||||
namespace juce::universal_midi_packets
|
||||
{
|
||||
|
||||
/**
|
||||
A base class for classes which convert bytestream midi to other formats.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct BytestreamInputHandler
|
||||
{
|
||||
virtual ~BytestreamInputHandler() noexcept = default;
|
||||
|
||||
virtual void reset() = 0;
|
||||
virtual void pushMidiData (const void* data, int bytes, double time) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
Parses a continuous bytestream and emits complete MidiMessages whenever a full
|
||||
message is received.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct BytestreamToBytestreamHandler : public BytestreamInputHandler
|
||||
{
|
||||
BytestreamToBytestreamHandler (MidiInput& i, MidiInputCallback& c)
|
||||
: input (i), callback (c), concatenator (2048) {}
|
||||
|
||||
/**
|
||||
Provides an `operator()` which can create an input handler for a given
|
||||
MidiInput.
|
||||
|
||||
All handler classes should have a similar Factory to facilitate
|
||||
creation of handlers in generic contexts.
|
||||
*/
|
||||
class Factory
|
||||
{
|
||||
public:
|
||||
explicit Factory (MidiInputCallback* c)
|
||||
: callback (c) {}
|
||||
|
||||
std::unique_ptr<BytestreamToBytestreamHandler> operator() (MidiInput& i) const
|
||||
{
|
||||
if (callback != nullptr)
|
||||
return std::make_unique<BytestreamToBytestreamHandler> (i, *callback);
|
||||
|
||||
jassertfalse;
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
MidiInputCallback* callback = nullptr;
|
||||
};
|
||||
|
||||
void reset() override { concatenator.reset(); }
|
||||
|
||||
void pushMidiData (const void* data, int bytes, double time) override
|
||||
{
|
||||
concatenator.pushMidiData (data, bytes, time, &input, callback);
|
||||
}
|
||||
|
||||
MidiInput& input;
|
||||
MidiInputCallback& callback;
|
||||
MidiDataConcatenator concatenator;
|
||||
};
|
||||
|
||||
/**
|
||||
Parses a continuous MIDI 1.0 bytestream, and emits full messages in the requested
|
||||
UMP format.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct BytestreamToUMPHandler : public BytestreamInputHandler
|
||||
{
|
||||
BytestreamToUMPHandler (PacketProtocol protocol, Receiver& c)
|
||||
: recipient (c), dispatcher (0, protocol, 2048) {}
|
||||
|
||||
/**
|
||||
Provides an `operator()` which can create an input handler for a given
|
||||
MidiInput.
|
||||
|
||||
All handler classes should have a similar Factory to facilitate
|
||||
creation of handlers in generic contexts.
|
||||
*/
|
||||
class Factory
|
||||
{
|
||||
public:
|
||||
Factory (PacketProtocol p, Receiver& c)
|
||||
: protocol (p), callback (c) {}
|
||||
|
||||
std::unique_ptr<BytestreamToUMPHandler> operator() (MidiInput&) const
|
||||
{
|
||||
return std::make_unique<BytestreamToUMPHandler> (protocol, callback);
|
||||
}
|
||||
|
||||
private:
|
||||
PacketProtocol protocol;
|
||||
Receiver& callback;
|
||||
};
|
||||
|
||||
void reset() override { dispatcher.reset(); }
|
||||
|
||||
void pushMidiData (const void* data, int bytes, double time) override
|
||||
{
|
||||
const auto* ptr = static_cast<const std::byte*> (data);
|
||||
dispatcher.dispatch (Span { ptr, (size_t) bytes }, time, [&] (const View& v, double t)
|
||||
{
|
||||
recipient.packetReceived (v, t);
|
||||
});
|
||||
}
|
||||
|
||||
Receiver& recipient;
|
||||
BytestreamToUMPDispatcher dispatcher;
|
||||
};
|
||||
|
||||
} // juce::universal_midi_packets
|
||||
/** @endcond */
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/** @cond */
|
||||
namespace juce::universal_midi_packets
|
||||
{
|
||||
|
||||
/**
|
||||
A base class for classes which convert Universal MIDI Packets to other
|
||||
formats.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct U32InputHandler
|
||||
{
|
||||
virtual ~U32InputHandler() noexcept = default;
|
||||
|
||||
virtual void reset() = 0;
|
||||
virtual void pushMidiData (Span<const uint32_t>, double time) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
Parses a continuous stream of U32 words and emits complete MidiMessages whenever a full
|
||||
message is received.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct U32ToBytestreamHandler : public U32InputHandler
|
||||
{
|
||||
U32ToBytestreamHandler (MidiInput& i, MidiInputCallback& c)
|
||||
: input (i), callback (c), dispatcher (2048) {}
|
||||
|
||||
/**
|
||||
Provides an `operator()` which can create an input handler for a given
|
||||
MidiInput.
|
||||
|
||||
All handler classes should have a similar Factory to facilitate
|
||||
creation of handlers in generic contexts.
|
||||
*/
|
||||
class Factory
|
||||
{
|
||||
public:
|
||||
explicit Factory (MidiInputCallback* c)
|
||||
: callback (c) {}
|
||||
|
||||
std::unique_ptr<U32ToBytestreamHandler> operator() (MidiInput& i) const
|
||||
{
|
||||
if (callback != nullptr)
|
||||
return std::make_unique<U32ToBytestreamHandler> (i, *callback);
|
||||
|
||||
jassertfalse;
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
MidiInputCallback* callback = nullptr;
|
||||
};
|
||||
|
||||
void reset() override { dispatcher.reset(); }
|
||||
|
||||
void pushMidiData (Span<const uint32_t> words, double time) override
|
||||
{
|
||||
dispatcher.dispatch (words, time, [&] (const BytesOnGroup& roundTripped, double t)
|
||||
{
|
||||
callback.handleIncomingMidiMessage (&input, MidiMessage { roundTripped.bytes.data(), (int) roundTripped.bytes.size(), t });
|
||||
});
|
||||
}
|
||||
|
||||
MidiInput& input;
|
||||
MidiInputCallback& callback;
|
||||
ToBytestreamDispatcher dispatcher;
|
||||
};
|
||||
|
||||
/**
|
||||
Parses a continuous stream of U32 words and emits full messages in the requested
|
||||
UMP format.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct U32ToUMPHandler : public U32InputHandler
|
||||
{
|
||||
U32ToUMPHandler (PacketProtocol protocol, Receiver& c)
|
||||
: recipient (c), converter (protocol) {}
|
||||
|
||||
/**
|
||||
Provides an `operator()` which can create an input handler for a given
|
||||
MidiInput.
|
||||
|
||||
All handler classes should have a similar Factory to facilitate
|
||||
creation of handlers in generic contexts.
|
||||
*/
|
||||
class Factory
|
||||
{
|
||||
public:
|
||||
Factory (PacketProtocol p, Receiver& c)
|
||||
: protocol (p), callback (c) {}
|
||||
|
||||
std::unique_ptr<U32ToUMPHandler> operator() (MidiInput&) const
|
||||
{
|
||||
return std::make_unique<U32ToUMPHandler> (protocol, callback);
|
||||
}
|
||||
|
||||
private:
|
||||
PacketProtocol protocol;
|
||||
Receiver& callback;
|
||||
};
|
||||
|
||||
void reset() override
|
||||
{
|
||||
dispatcher.reset();
|
||||
converter.reset();
|
||||
}
|
||||
|
||||
void pushMidiData (Span<const uint32_t> words, double time) override
|
||||
{
|
||||
dispatcher.dispatch (words, time, [this] (const View& view, double thisTime)
|
||||
{
|
||||
converter.convert (view, [&] (const View& converted)
|
||||
{
|
||||
recipient.packetReceived (converted, thisTime);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Receiver& recipient;
|
||||
Dispatcher dispatcher;
|
||||
GenericUMPConverter converter;
|
||||
};
|
||||
|
||||
} // namespace juce::universal_midi_packets
|
||||
/** @endcond */
|
||||
|
|
@ -41,6 +41,12 @@ namespace juce
|
|||
|
||||
namespace CoreMidiHelpers
|
||||
{
|
||||
struct Consumer
|
||||
{
|
||||
virtual ~Consumer() = default;
|
||||
virtual void consume (ump::Iterator, ump::Iterator, double) = 0;
|
||||
};
|
||||
|
||||
static bool checkError (OSStatus err, [[maybe_unused]] int lineNum)
|
||||
{
|
||||
if (err == noErr)
|
||||
|
|
@ -627,12 +633,8 @@ namespace CoreMidiHelpers
|
|||
template <>
|
||||
struct Receiver<ImplementationStrategy::onlyNew>
|
||||
{
|
||||
Receiver (ump::PacketProtocol protocol, ump::Receiver& receiver)
|
||||
: u32InputHandler (std::make_unique<ump::U32ToUMPHandler> (protocol, receiver))
|
||||
{}
|
||||
|
||||
Receiver (MidiInput& input, MidiInputCallback& callback)
|
||||
: u32InputHandler (std::make_unique<ump::U32ToBytestreamHandler> (input, callback))
|
||||
explicit Receiver (Consumer& cb)
|
||||
: callback (cb)
|
||||
{}
|
||||
|
||||
void dispatch (const MIDIEventList* list, double time) const
|
||||
|
|
@ -644,45 +646,49 @@ namespace CoreMidiHelpers
|
|||
static_assert (sizeof (uint32_t) == sizeof (UInt32)
|
||||
&& alignof (uint32_t) == alignof (UInt32),
|
||||
"If this fails, the cast below will be broken too!");
|
||||
u32InputHandler->pushMidiData ({ reinterpret_cast<const uint32_t*> (packet->words),
|
||||
(size_t) packet->wordCount },
|
||||
time);
|
||||
|
||||
callback.consume (ump::Iterator { packet->words, packet->wordCount },
|
||||
ump::Iterator { packet->words + packet->wordCount, 0 },
|
||||
time);
|
||||
|
||||
packet = MIDIEventPacketNext (packet);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<ump::U32InputHandler> u32InputHandler;
|
||||
Consumer& callback;
|
||||
};
|
||||
|
||||
#if JUCE_HAS_OLD_COREMIDI_API
|
||||
template <>
|
||||
struct Receiver<ImplementationStrategy::onlyOld>
|
||||
{
|
||||
Receiver (ump::PacketProtocol protocol, ump::Receiver& receiver)
|
||||
: bytestreamInputHandler (std::make_unique<ump::BytestreamToUMPHandler> (protocol, receiver))
|
||||
{}
|
||||
explicit Receiver (Consumer& cb)
|
||||
: dispatcher (0, ump::PacketProtocol::MIDI_1_0, 4096), callback (cb) {}
|
||||
|
||||
Receiver (MidiInput& input, MidiInputCallback& callback)
|
||||
: bytestreamInputHandler (std::make_unique<ump::BytestreamToBytestreamHandler> (input, callback))
|
||||
{}
|
||||
|
||||
void dispatch (const MIDIPacketList* list, double time) const
|
||||
void dispatch (const MIDIPacketList* list, double time)
|
||||
{
|
||||
auto* packet = list->packet;
|
||||
|
||||
for (unsigned int i = 0; i < list->numPackets; ++i)
|
||||
{
|
||||
auto len = readUnaligned<decltype (packet->length)> (&(packet->length));
|
||||
bytestreamInputHandler->pushMidiData (packet->data, len, time);
|
||||
const auto* bytes = unalignedPointerCast<const std::byte*> (packet->data);
|
||||
const auto len = readUnaligned<decltype (packet->length)> (&(packet->length));
|
||||
|
||||
dispatcher.dispatch (Span (bytes, len), time, [this] (const ump::View& v, double t)
|
||||
{
|
||||
ump::Iterator b { v.data(), v.size() };
|
||||
auto e = std::next (b);
|
||||
callback.consume (b, e, t);
|
||||
});
|
||||
|
||||
packet = MIDIPacketNext (packet);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<ump::BytestreamInputHandler> bytestreamInputHandler;
|
||||
ump::BytestreamToUMPDispatcher dispatcher;
|
||||
Consumer& callback;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -690,20 +696,16 @@ namespace CoreMidiHelpers
|
|||
template <>
|
||||
struct Receiver<ImplementationStrategy::both>
|
||||
{
|
||||
Receiver (ump::PacketProtocol protocol, ump::Receiver& receiver)
|
||||
: newReceiver (protocol, receiver), oldReceiver (protocol, receiver)
|
||||
explicit Receiver (Consumer& cb)
|
||||
: newReceiver (cb), oldReceiver (cb)
|
||||
{}
|
||||
|
||||
Receiver (MidiInput& input, MidiInputCallback& callback)
|
||||
: newReceiver (input, callback), oldReceiver (input, callback)
|
||||
{}
|
||||
|
||||
void dispatch (const MIDIEventList* list, double time) const
|
||||
void dispatch (const MIDIEventList* list, double time)
|
||||
{
|
||||
newReceiver.dispatch (list, time);
|
||||
}
|
||||
|
||||
void dispatch (const MIDIPacketList* list, double time) const
|
||||
void dispatch (const MIDIPacketList* list, double time)
|
||||
{
|
||||
oldReceiver.dispatch (list, time);
|
||||
}
|
||||
|
|
@ -720,14 +722,14 @@ namespace CoreMidiHelpers
|
|||
CriticalSection callbackLock;
|
||||
Array<MidiPortAndCallback*> activeCallbacks;
|
||||
|
||||
class MidiPortAndCallback
|
||||
class MidiPortAndCallback : private Consumer
|
||||
{
|
||||
public:
|
||||
MidiPortAndCallback (MidiInput& inputIn, ReceiverToUse receiverIn)
|
||||
: input (&inputIn), receiver (std::move (receiverIn))
|
||||
MidiPortAndCallback (MidiInput& inputIn, MidiInputCallback& cb)
|
||||
: input (&inputIn), callback (cb), receiver (*this)
|
||||
{}
|
||||
|
||||
~MidiPortAndCallback()
|
||||
~MidiPortAndCallback() override
|
||||
{
|
||||
active = false;
|
||||
|
||||
|
|
@ -752,6 +754,7 @@ namespace CoreMidiHelpers
|
|||
}
|
||||
|
||||
MidiInput* input = nullptr;
|
||||
MidiInputCallback& callback;
|
||||
std::atomic<bool> active { false };
|
||||
|
||||
ReceiverToUse receiver;
|
||||
|
|
@ -759,6 +762,19 @@ namespace CoreMidiHelpers
|
|||
std::unique_ptr<MidiPortAndEndpoint> portAndEndpoint;
|
||||
|
||||
private:
|
||||
void consume (ump::Iterator b, ump::Iterator e, double t) override
|
||||
{
|
||||
for (auto view : makeRange (b, e))
|
||||
{
|
||||
bytestreamConverter.convert (view, t, [this] (ump::BytesOnGroup x, double time)
|
||||
{
|
||||
callback.handleIncomingMidiMessage (input, { x.bytes.data(), (int) x.bytes.size(), time });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ump::ToBytestreamConverter bytestreamConverter { 2048 };
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiPortAndCallback)
|
||||
};
|
||||
|
||||
|
|
@ -954,20 +970,13 @@ class MidiInput::Pimpl : public CoreMidiHelpers::MidiPortAndCallback
|
|||
public:
|
||||
using MidiPortAndCallback::MidiPortAndCallback;
|
||||
|
||||
static std::unique_ptr<Pimpl> makePimpl (MidiInput& midiInput,
|
||||
ump::PacketProtocol packetProtocol,
|
||||
ump::Receiver& umpReceiver)
|
||||
{
|
||||
return std::make_unique<Pimpl> (midiInput, CoreMidiHelpers::ReceiverToUse (packetProtocol, umpReceiver));
|
||||
}
|
||||
|
||||
static std::unique_ptr<Pimpl> makePimpl (MidiInput& midiInput,
|
||||
MidiInputCallback* midiInputCallback)
|
||||
{
|
||||
if (midiInputCallback == nullptr)
|
||||
return {};
|
||||
|
||||
return std::make_unique<Pimpl> (midiInput, CoreMidiHelpers::ReceiverToUse (midiInput, *midiInputCallback));
|
||||
return std::make_unique<Pimpl> (midiInput, *midiInputCallback);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue