mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
Bela: Drop support
This commit is contained in:
parent
d64b9e7782
commit
9a7ac1f743
8 changed files with 12 additions and 651 deletions
|
|
@ -331,7 +331,6 @@ void AudioDeviceManager::createAudioDeviceTypes (OwnedArray<AudioIODeviceType>&
|
|||
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ASIO());
|
||||
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_CoreAudio());
|
||||
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_iOSAudio());
|
||||
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Bela());
|
||||
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ALSA());
|
||||
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_JACK());
|
||||
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Oboe());
|
||||
|
|
|
|||
|
|
@ -106,12 +106,6 @@ void AudioIODeviceType::callDeviceChangeListeners()
|
|||
AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK() { return nullptr; }
|
||||
#endif
|
||||
|
||||
#if JUCE_LINUX && JUCE_BELA
|
||||
AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Bela() { return new BelaAudioIODeviceType(); }
|
||||
#else
|
||||
AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Bela() { return nullptr; }
|
||||
#endif
|
||||
|
||||
#if JUCE_ANDROID
|
||||
AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -176,8 +176,6 @@ public:
|
|||
static AudioIODeviceType* createAudioIODeviceType_OpenSLES();
|
||||
/** Creates an Oboe device type if it's available on this platform, or returns null. */
|
||||
static AudioIODeviceType* createAudioIODeviceType_Oboe();
|
||||
/** Creates a Bela device type if it's available on this platform, or returns null. */
|
||||
static AudioIODeviceType* createAudioIODeviceType_Bela();
|
||||
|
||||
/** @cond */
|
||||
[[deprecated ("You should call the method which takes a WASAPIDeviceMode instead.")]]
|
||||
|
|
|
|||
|
|
@ -176,23 +176,23 @@
|
|||
#include "native/juce_ALSA_linux.cpp"
|
||||
#endif
|
||||
|
||||
#if (JUCE_LINUX && JUCE_BELA)
|
||||
/* Got an include error here? If so, you've either not got the bela headers
|
||||
installed, or you've not got your paths set up correctly to find its header
|
||||
files.
|
||||
#if JUCE_JACK
|
||||
/* Got an include error here? If so, you've either not got jack-audio-connection-kit
|
||||
installed, or you've not got your paths set up correctly to find its header files.
|
||||
|
||||
The package you need to install to get JACK support is "libjack-dev".
|
||||
|
||||
If you don't have the jack-audio-connection-kit library and don't want to build
|
||||
JUCE with low latency audio support, just set the JUCE_JACK flag to 0.
|
||||
*/
|
||||
#include <Bela.h>
|
||||
#include <Midi.h>
|
||||
#include <juce_audio_basics/midi/juce_MidiDataConcatenator.h>
|
||||
#include "native/juce_Bela_linux.cpp"
|
||||
#include <jack/jack.h>
|
||||
#include "native/juce_JackAudio_linux.cpp"
|
||||
#endif
|
||||
|
||||
#undef SIZEOF
|
||||
|
||||
#if ! JUCE_BELA
|
||||
#include <juce_audio_basics/midi/juce_MidiDataConcatenator.h>
|
||||
#include "native/juce_Midi_linux.cpp"
|
||||
#endif
|
||||
#include <juce_audio_basics/midi/juce_MidiDataConcatenator.h>
|
||||
#include "native/juce_Midi_linux.cpp"
|
||||
|
||||
//==============================================================================
|
||||
#elif JUCE_ANDROID
|
||||
|
|
|
|||
|
|
@ -127,13 +127,6 @@
|
|||
#define JUCE_JACK 0
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_BELA
|
||||
Enables Bela audio devices on Bela boards.
|
||||
*/
|
||||
#ifndef JUCE_BELA
|
||||
#define JUCE_BELA 0
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_USE_ANDROID_OBOE
|
||||
Enables Oboe devices (Android only).
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,612 +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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
class MidiInput::Pimpl
|
||||
{
|
||||
public:
|
||||
static Array<Pimpl*> midiInputs;
|
||||
|
||||
Pimpl (const String& port, MidiInput* input, MidiInputCallback* callback)
|
||||
: midiInput (input), midiPort (port), midiCallback (callback)
|
||||
{
|
||||
jassert (midiCallback != nullptr);
|
||||
midiInputs.add (this);
|
||||
|
||||
buffer.resize (32);
|
||||
}
|
||||
|
||||
~Pimpl()
|
||||
{
|
||||
stop();
|
||||
midiInputs.removeAllInstancesOf (this);
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
midi.readFrom (midiPort.toRawUTF8());
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
midi.enableParser (false);
|
||||
}
|
||||
|
||||
void poll()
|
||||
{
|
||||
size_t receivedBytes = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
auto data = midi.getInput();
|
||||
|
||||
if (data < 0)
|
||||
break;
|
||||
|
||||
buffer[receivedBytes] = (uint8) data;
|
||||
receivedBytes++;
|
||||
|
||||
if (receivedBytes == buffer.size())
|
||||
{
|
||||
pushMidiData (static_cast<int> (receivedBytes));
|
||||
receivedBytes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (receivedBytes > 0)
|
||||
pushMidiData ((int) receivedBytes);
|
||||
}
|
||||
|
||||
static Array<MidiDeviceInfo> getDevices (bool input)
|
||||
{
|
||||
Array<MidiDeviceInfo> devices;
|
||||
|
||||
for (auto& card : findAllALSACardIDs())
|
||||
findMidiDevices (devices, input, card);
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
void pushMidiMessage (juce::MidiMessage& message)
|
||||
{
|
||||
concatenator.pushMidiData (message.getRawData(), message.getRawDataSize(), Time::getMillisecondCounter() * 0.001, midiInput, *midiCallback);
|
||||
}
|
||||
|
||||
private:
|
||||
void pushMidiData (int length)
|
||||
{
|
||||
concatenator.pushMidiData (buffer.data(), length, Time::getMillisecondCounter() * 0.001, midiInput, *midiCallback);
|
||||
}
|
||||
|
||||
std::vector<uint8> buffer;
|
||||
|
||||
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 (Array<MidiDeviceInfo>& 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, (unsigned int) 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 (size_t sub = 0; sub < subCount; ++sub)
|
||||
{
|
||||
snd_rawmidi_info_set_subdevice (info, sub);
|
||||
|
||||
status = snd_ctl_rawmidi_info (ctl, info);
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
String deviceName ("hw:" + String (cardNum) + "," + String (device) + "," + String (sub));
|
||||
devices.add (MidiDeviceInfo (deviceName, deviceName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snd_ctl_close (ctl);
|
||||
}
|
||||
|
||||
MidiInput* const midiInput;
|
||||
String midiPort;
|
||||
MidiInputCallback* const midiCallback;
|
||||
|
||||
Midi midi;
|
||||
MidiDataConcatenator concatenator { 512 };
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl)
|
||||
};
|
||||
|
||||
Array<MidiInput::Pimpl*> MidiInput::Pimpl::midiInputs;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class BelaAudioIODevice final : public AudioIODevice
|
||||
{
|
||||
public:
|
||||
BelaAudioIODevice() : AudioIODevice (BelaAudioIODevice::belaTypeName,
|
||||
BelaAudioIODevice::belaTypeName)
|
||||
{
|
||||
Bela_defaultSettings (&defaultSettings);
|
||||
}
|
||||
|
||||
~BelaAudioIODevice()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
StringArray getOutputChannelNames() override
|
||||
{
|
||||
StringArray result;
|
||||
|
||||
for (int i = 1; i <= actualNumberOfOutputs; i++)
|
||||
result.add ("Out #" + std::to_string (i));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
StringArray getInputChannelNames() override
|
||||
{
|
||||
StringArray result;
|
||||
|
||||
for (int i = 1; i <= actualNumberOfInputs; i++)
|
||||
result.add ("In #" + std::to_string (i));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Array<double> getAvailableSampleRates() override { return { 44100.0 }; }
|
||||
Array<int> getAvailableBufferSizes() override { /* TODO: */ return { getDefaultBufferSize() }; }
|
||||
int getDefaultBufferSize() override { return defaultSettings.periodSize; }
|
||||
|
||||
//==============================================================================
|
||||
String open (const BigInteger& inputChannels,
|
||||
const BigInteger& outputChannels,
|
||||
double sampleRate,
|
||||
int bufferSizeSamples) override
|
||||
{
|
||||
if (sampleRate != 44100.0 && sampleRate != 0.0)
|
||||
{
|
||||
lastError = "Bela audio outputs only support 44.1 kHz sample rate";
|
||||
return lastError;
|
||||
}
|
||||
|
||||
settings = defaultSettings;
|
||||
|
||||
auto numIns = getNumContiguousSetBits (inputChannels);
|
||||
auto numOuts = getNumContiguousSetBits (outputChannels);
|
||||
|
||||
// Input and Output channels are numbered as follows
|
||||
//
|
||||
// 0 .. 1 - audio
|
||||
// 2 .. 9 - analog
|
||||
|
||||
if (numIns > 2 || numOuts > 2)
|
||||
{
|
||||
settings.useAnalog = true;
|
||||
settings.numAnalogInChannels = std::max (numIns - 2, 8);
|
||||
settings.numAnalogOutChannels = std::max (numOuts - 2, 8);
|
||||
settings.uniformSampleRate = true;
|
||||
}
|
||||
|
||||
settings.numAudioInChannels = std::max (numIns, 2);
|
||||
settings.numAudioOutChannels = std::max (numOuts, 2);
|
||||
|
||||
settings.detectUnderruns = 1;
|
||||
settings.setup = setupCallback;
|
||||
settings.render = renderCallback;
|
||||
settings.cleanup = cleanupCallback;
|
||||
settings.interleave = 0;
|
||||
|
||||
if (bufferSizeSamples > 0)
|
||||
settings.periodSize = bufferSizeSamples;
|
||||
|
||||
isBelaOpen = false;
|
||||
isRunning = false;
|
||||
callback = nullptr;
|
||||
underruns = 0;
|
||||
|
||||
if (Bela_initAudio (&settings, this) != 0 || ! isBelaOpen)
|
||||
{
|
||||
lastError = "Bela_initAutio failed";
|
||||
return lastError;
|
||||
}
|
||||
|
||||
actualNumberOfInputs = jmin (numIns, actualNumberOfInputs);
|
||||
actualNumberOfOutputs = jmin (numOuts, actualNumberOfOutputs);
|
||||
|
||||
channelInBuffer.calloc (actualNumberOfInputs);
|
||||
channelOutBuffer.calloc (actualNumberOfOutputs);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void close() override
|
||||
{
|
||||
stop();
|
||||
|
||||
if (isBelaOpen)
|
||||
{
|
||||
Bela_cleanupAudio();
|
||||
|
||||
isBelaOpen = false;
|
||||
callback = nullptr;
|
||||
underruns = 0;
|
||||
|
||||
actualBufferSize = 0;
|
||||
actualNumberOfInputs = 0;
|
||||
actualNumberOfOutputs = 0;
|
||||
|
||||
channelInBuffer.free();
|
||||
channelOutBuffer.free();
|
||||
}
|
||||
}
|
||||
|
||||
bool isOpen() override { return isBelaOpen; }
|
||||
|
||||
void start (AudioIODeviceCallback* newCallback) override
|
||||
{
|
||||
if (! isBelaOpen)
|
||||
return;
|
||||
|
||||
if (isRunning)
|
||||
{
|
||||
if (newCallback != callback)
|
||||
{
|
||||
if (newCallback != nullptr)
|
||||
newCallback->audioDeviceAboutToStart (this);
|
||||
|
||||
{
|
||||
ScopedLock lock (callbackLock);
|
||||
std::swap (callback, newCallback);
|
||||
}
|
||||
|
||||
if (newCallback != nullptr)
|
||||
newCallback->audioDeviceStopped();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
callback = newCallback;
|
||||
isRunning = (Bela_startAudio() == 0);
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
if (isRunning)
|
||||
{
|
||||
callback->audioDeviceAboutToStart (this);
|
||||
}
|
||||
else
|
||||
{
|
||||
lastError = "Bela_StartAudio failed";
|
||||
callback->audioDeviceError (lastError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stop() override
|
||||
{
|
||||
AudioIODeviceCallback* oldCallback = nullptr;
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
ScopedLock lock (callbackLock);
|
||||
std::swap (callback, oldCallback);
|
||||
}
|
||||
|
||||
isRunning = false;
|
||||
Bela_stopAudio();
|
||||
|
||||
if (oldCallback != nullptr)
|
||||
oldCallback->audioDeviceStopped();
|
||||
}
|
||||
|
||||
bool isPlaying() override { return isRunning; }
|
||||
String getLastError() override { return lastError; }
|
||||
|
||||
//==============================================================================
|
||||
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; }
|
||||
BigInteger getActiveInputChannels() const override { BigInteger b; b.setRange (0, actualNumberOfInputs, true); return b; }
|
||||
int getOutputLatencyInSamples() override { /* TODO */ return 0; }
|
||||
int getInputLatencyInSamples() override { /* TODO */ return 0; }
|
||||
int getXRunCount() const noexcept override { return underruns; }
|
||||
|
||||
//==============================================================================
|
||||
static const char* const belaTypeName;
|
||||
|
||||
private:
|
||||
|
||||
//==============================================================================
|
||||
bool setup (BelaContext& context)
|
||||
{
|
||||
actualBufferSize = context.audioFrames;
|
||||
actualNumberOfInputs = (int) (context.audioInChannels + context.analogInChannels);
|
||||
actualNumberOfOutputs = (int) (context.audioOutChannels + context.analogOutChannels);
|
||||
isBelaOpen = true;
|
||||
firstCallback = true;
|
||||
|
||||
ScopedLock lock (callbackLock);
|
||||
|
||||
if (callback != nullptr)
|
||||
callback->audioDeviceAboutToStart (this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void render (BelaContext& context)
|
||||
{
|
||||
// check for xruns
|
||||
calculateXruns (context.audioFramesElapsed, context.audioFrames);
|
||||
|
||||
ScopedLock lock (callbackLock);
|
||||
|
||||
// Check for and process and midi
|
||||
for (auto midiInput : MidiInput::Pimpl::midiInputs)
|
||||
midiInput->poll();
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
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[(Frames) ch * context.audioFrames];
|
||||
else
|
||||
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[(Frames) ch * context.audioFrames];
|
||||
else
|
||||
channelOutBuffer[ch] = &context.analogOut[(Frames) (ch - analogChannelStart) * context.audioFrames];
|
||||
}
|
||||
|
||||
callback->audioDeviceIOCallbackWithContext (channelInBuffer.getData(),
|
||||
actualNumberOfInputs,
|
||||
channelOutBuffer.getData(),
|
||||
actualNumberOfOutputs,
|
||||
(int) context.audioFrames,
|
||||
{});
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup (BelaContext&)
|
||||
{
|
||||
ScopedLock lock (callbackLock);
|
||||
|
||||
if (callback != nullptr)
|
||||
callback->audioDeviceStopped();
|
||||
}
|
||||
|
||||
const int analogChannelStart = 2;
|
||||
|
||||
//==============================================================================
|
||||
uint64_t expectedElapsedAudioSamples = 0;
|
||||
int underruns = 0;
|
||||
bool firstCallback = false;
|
||||
|
||||
void calculateXruns (uint64_t audioFramesElapsed, uint32_t numSamples)
|
||||
{
|
||||
if (audioFramesElapsed > expectedElapsedAudioSamples && ! firstCallback)
|
||||
++underruns;
|
||||
|
||||
firstCallback = false;
|
||||
expectedElapsedAudioSamples = audioFramesElapsed + numSamples;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static int getNumContiguousSetBits (const BigInteger& value) noexcept
|
||||
{
|
||||
int bit = 0;
|
||||
|
||||
while (value[bit])
|
||||
++bit;
|
||||
|
||||
return bit;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static bool setupCallback (BelaContext* context, void* userData) noexcept { return static_cast<BelaAudioIODevice*> (userData)->setup (*context); }
|
||||
static void renderCallback (BelaContext* context, void* userData) noexcept { static_cast<BelaAudioIODevice*> (userData)->render (*context); }
|
||||
static void cleanupCallback (BelaContext* context, void* userData) noexcept { static_cast<BelaAudioIODevice*> (userData)->cleanup (*context); }
|
||||
|
||||
//==============================================================================
|
||||
BelaInitSettings defaultSettings, settings;
|
||||
bool isBelaOpen = false, isRunning = false;
|
||||
|
||||
CriticalSection callbackLock;
|
||||
AudioIODeviceCallback* callback = nullptr;
|
||||
|
||||
String lastError;
|
||||
uint32_t actualBufferSize = 0;
|
||||
int actualNumberOfInputs = 0, actualNumberOfOutputs = 0;
|
||||
|
||||
HeapBlock<const float*> channelInBuffer;
|
||||
HeapBlock<float*> channelOutBuffer;
|
||||
|
||||
bool includeAnalogSupport;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BelaAudioIODevice)
|
||||
};
|
||||
|
||||
const char* const BelaAudioIODevice::belaTypeName = "Bela Analog";
|
||||
|
||||
//==============================================================================
|
||||
struct BelaAudioIODeviceType final : public AudioIODeviceType
|
||||
{
|
||||
BelaAudioIODeviceType() : AudioIODeviceType ("Bela") {}
|
||||
|
||||
StringArray getDeviceNames (bool) const override { return StringArray (BelaAudioIODevice::belaTypeName); }
|
||||
void scanForDevices() override {}
|
||||
int getDefaultDeviceIndex (bool) const override { return 0; }
|
||||
int getIndexOfDevice (AudioIODevice* device, bool) const override { return device != nullptr ? 0 : -1; }
|
||||
bool hasSeparateInputsAndOutputs() const override { return false; }
|
||||
|
||||
AudioIODevice* createDevice (const String& outputName, const String& inputName) override
|
||||
{
|
||||
// TODO: switching whether to support analog/digital with possible multiple Bela device types?
|
||||
if (outputName == BelaAudioIODevice::belaTypeName || inputName == BelaAudioIODevice::belaTypeName)
|
||||
return new BelaAudioIODevice();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BelaAudioIODeviceType)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
MidiInput::MidiInput (const String& deviceName, const String& deviceID)
|
||||
: deviceInfo (deviceName, deviceID)
|
||||
{
|
||||
}
|
||||
|
||||
MidiInput::~MidiInput() = default;
|
||||
void MidiInput::start() { internal->start(); }
|
||||
void MidiInput::stop() { internal->stop(); }
|
||||
|
||||
Array<MidiDeviceInfo> MidiInput::getAvailableDevices()
|
||||
{
|
||||
return Pimpl::getDevices (true);
|
||||
}
|
||||
|
||||
MidiDeviceInfo MidiInput::getDefaultDevice()
|
||||
{
|
||||
return getAvailableDevices().getFirst();
|
||||
}
|
||||
|
||||
std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier, MidiInputCallback* callback)
|
||||
{
|
||||
if (deviceIdentifier.isEmpty())
|
||||
return {};
|
||||
|
||||
std::unique_ptr<MidiInput> midiInput (new MidiInput (deviceIdentifier, deviceIdentifier));
|
||||
midiInput->internal = std::make_unique<Pimpl> (deviceIdentifier, midiInput.get(), callback);
|
||||
|
||||
return midiInput;
|
||||
}
|
||||
|
||||
std::unique_ptr<MidiInput> MidiInput::createNewDevice (const String&, MidiInputCallback*)
|
||||
{
|
||||
// N/A on Bela
|
||||
jassertfalse;
|
||||
return {};
|
||||
}
|
||||
|
||||
StringArray MidiInput::getDevices()
|
||||
{
|
||||
StringArray deviceNames;
|
||||
|
||||
for (auto& d : getAvailableDevices())
|
||||
deviceNames.add (d.name);
|
||||
|
||||
return deviceNames;
|
||||
}
|
||||
|
||||
int MidiInput::getDefaultDeviceIndex()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<MidiInput> MidiInput::openDevice (int index, MidiInputCallback* callback)
|
||||
{
|
||||
return openDevice (getAvailableDevices()[index].identifier, callback);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// TODO: Add Bela MidiOutput support
|
||||
class MidiOutput::Pimpl {};
|
||||
MidiOutput::~MidiOutput() = default;
|
||||
void MidiOutput::sendMessageNow (const MidiMessage&) {}
|
||||
Array<MidiDeviceInfo> MidiOutput::getAvailableDevices() { return {}; }
|
||||
MidiDeviceInfo MidiOutput::getDefaultDevice() { return {}; }
|
||||
std::unique_ptr<MidiOutput> MidiOutput::openDevice (const String&) { return {}; }
|
||||
std::unique_ptr<MidiOutput> MidiOutput::createNewDevice (const String&) { return {}; }
|
||||
StringArray MidiOutput::getDevices() { return {}; }
|
||||
int MidiOutput::getDefaultDeviceIndex() { return 0;}
|
||||
std::unique_ptr<MidiOutput> MidiOutput::openDevice (int) { return {}; }
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -32,10 +32,6 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
#if JUCE_BELA
|
||||
extern "C" int cobalt_thread_mode();
|
||||
#endif
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
|
|
@ -384,14 +380,7 @@ int64 Time::getHighResolutionTicks() noexcept
|
|||
{
|
||||
timespec t;
|
||||
|
||||
#if JUCE_BELA
|
||||
if (cobalt_thread_mode() == 0x200 /*XNRELAX*/)
|
||||
clock_gettime (CLOCK_MONOTONIC, &t);
|
||||
else
|
||||
__wrap_clock_gettime (CLOCK_MONOTONIC, &t);
|
||||
#else
|
||||
clock_gettime (CLOCK_MONOTONIC, &t);
|
||||
#endif
|
||||
|
||||
return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / 1000);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue