Browse Source

Added support for Bela MIDI input

tags/2021-05-28
jules 7 years ago
parent
commit
4d505346cd
4 changed files with 194 additions and 4 deletions
  1. +4
    -2
      modules/juce_audio_devices/juce_audio_devices.cpp
  2. +1
    -1
      modules/juce_audio_devices/native/juce_MidiDataConcatenator.h
  3. +1
    -1
      modules/juce_audio_devices/native/juce_linux_ALSA.cpp
  4. +188
    -0
      modules/juce_audio_devices/native/juce_linux_Bela.cpp

+ 4
- 2
modules/juce_audio_devices/juce_audio_devices.cpp View File

@@ -148,7 +148,9 @@
installed, or you've not got your paths set up correctly to find its header
files.
*/
#include <rtdk.h>
#include <Bela.h>
#include <Midi.h>
#endif
#undef SIZEOF
@@ -210,14 +212,14 @@
#include "native/juce_linux_ALSA.cpp"
#endif
#include "native/juce_linux_Midi.cpp"
#if JUCE_JACK
#include "native/juce_linux_JackAudio.cpp"
#endif
#if JUCE_BELA
#include "native/juce_linux_Bela.cpp"
#else
#include "native/juce_linux_Midi.cpp"
#endif
//==============================================================================


+ 1
- 1
modules/juce_audio_devices/native/juce_MidiDataConcatenator.h View File

@@ -171,7 +171,7 @@ private:
}
}
uint8 currentMessage[3] = {};
uint8 currentMessage[3];
int currentMessageLen = 0;
MemoryBlock pendingSysexData;


+ 1
- 1
modules/juce_audio_devices/native/juce_linux_ALSA.cpp View File

@@ -1115,7 +1115,7 @@ private:
if (cardNum < 0)
break;
if (JUCE_CHECKED_RESULT (snd_ctl_open (&handle, ("hw:" + String (cardNum)).toUTF8(), SND_CTL_NONBLOCK)) >= 0)
if (JUCE_CHECKED_RESULT (snd_ctl_open (&handle, ("hw:" + String (cardNum)).toRawUTF8(), SND_CTL_NONBLOCK)) >= 0)
{
if (JUCE_CHECKED_RESULT (snd_ctl_card_info (handle, info)) >= 0)
{


+ 188
- 0
modules/juce_audio_devices/native/juce_linux_Bela.cpp View File

@@ -23,6 +23,136 @@
namespace juce
{
//==============================================================================
class BelaMidiInput
{
public:
static Array<BelaMidiInput*> midiInputs;
BelaMidiInput (const String& port, MidiInput* input, MidiInputCallback* callback)
: midiInput (input), midiPort (port), midiCallback (callback)
{
jassert (midiCallback != nullptr);
midiInputs.add (this);
}
~BelaMidiInput()
{
stop();
midiInputs.removeAllInstancesOf (this);
}
void start()
{
midi.readFrom (midiPort.toRawUTF8());
}
void stop()
{
midi.enableParser (false);
}
void poll()
{
for (;;)
{
auto data = midi.getInput();
if (data < 0)
break;
auto byte = (uint8) data;
concatenator.pushMidiData (&byte, 1, 0.0, midiInput, *midiCallback);
}
}
static StringArray getDevices (bool input)
{
StringArray devices;
for (auto& card : findAllALSACardIDs())
findMidiDevices (devices, input, card);
return devices;
}
private:
static Array<int> findAllALSACardIDs()
{
Array<int> cards;
int card = -1;
for (;;)
{
auto status = snd_card_next (&card);
if (status != 0 || card < 0)
break;
cards.add (card);
}
return cards;
}
// Adds all midi devices to the devices array of the given input/output type on the given card
static void findMidiDevices (StringArray& devices, bool input, int cardNum)
{
snd_ctl_t* ctl = nullptr;
auto status = snd_ctl_open (&ctl, ("hw:" + String (cardNum)).toRawUTF8(), 0);
if (status < 0)
return;
int device = -1;
for (;;)
{
status = snd_ctl_rawmidi_next_device (ctl, &device);
if (status < 0 || device < 0)
break;
snd_rawmidi_info_t* info;
snd_rawmidi_info_alloca (&info);
snd_rawmidi_info_set_device (info, device);
snd_rawmidi_info_set_stream (info, input ? SND_RAWMIDI_STREAM_INPUT
: SND_RAWMIDI_STREAM_OUTPUT);
snd_ctl_rawmidi_info (ctl, info);
auto subCount = snd_rawmidi_info_get_subdevices_count (info);
for (int sub = 0; sub < subCount; ++sub)
{
snd_rawmidi_info_set_subdevice (info, sub);
status = snd_ctl_rawmidi_info (ctl, info);
if (status == 0)
devices.add ("hw:" + String (cardNum) + ","
+ String (device) + ","
+ String (sub));
}
}
snd_ctl_close (ctl);
}
String midiPort;
MidiInput* const midiInput;
MidiInputCallback* const midiCallback;
Midi midi;
MidiDataConcatenator concatenator { 512 };
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BelaMidiInput)
};
Array<BelaMidiInput*> BelaMidiInput::midiInputs;
//==============================================================================
class BelaAudioIODevice : public AudioIODevice
{
@@ -226,6 +356,10 @@ private:
ScopedLock lock (callbackLock);
// Check for and process and midi
for (auto midiInput : BelaMidiInput::midiInputs)
midiInput->poll();
if (callback != nullptr)
{
jassert (context.audioFrames <= actualBufferSize);
@@ -373,4 +507,58 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Bela()
return new BelaAudioIODeviceType();
}
//==============================================================================
// TODO: Add Bela MidiOutput support
StringArray MidiOutput::getDevices() { return {}; }
int MidiOutput::getDefaultDeviceIndex() { return 0; }
MidiOutput* MidiOutput::openDevice (int) { return {}; }
MidiOutput* MidiOutput::createNewDevice (const String&) { return {}; }
MidiOutput::~MidiOutput() {}
void MidiOutput::sendMessageNow (const MidiMessage&) {}
//==============================================================================
MidiInput::MidiInput (const String& nm) : name (nm) {}
MidiInput::~MidiInput()
{
delete static_cast<BelaMidiInput*> (internal);
}
void MidiInput::start() { static_cast<BelaMidiInput*> (internal)->start(); }
void MidiInput::stop() { static_cast<BelaMidiInput*> (internal)->stop(); }
int MidiInput::getDefaultDeviceIndex()
{
return 0;
}
StringArray MidiInput::getDevices()
{
return BelaMidiInput::getDevices (true);
}
MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
{
auto devices = getDevices();
if (index >= 0 && index < devices.size())
{
auto deviceName = devices[index];
auto result = new MidiInput (deviceName);
result->internal = new BelaMidiInput (deviceName, result, callback);
return result;
}
return {};
}
MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallback* callback)
{
jassertfalse; // N/A on Bela
return {};
}
} // namespace juce

Loading…
Cancel
Save