mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Bela updates to support analog inputs
This commit is contained in:
parent
ada4bba910
commit
32a0208147
1 changed files with 57 additions and 105 deletions
|
|
@ -187,9 +187,6 @@ public:
|
|||
BelaAudioIODevice::belaTypeName)
|
||||
{
|
||||
Bela_defaultSettings (&defaultSettings);
|
||||
|
||||
if (includeAnalogSupport)
|
||||
analogInputs.resize (8);
|
||||
}
|
||||
|
||||
~BelaAudioIODevice()
|
||||
|
|
@ -198,8 +195,26 @@ public:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
StringArray getOutputChannelNames() override { return { "Out #1", "Out #2" }; }
|
||||
StringArray getInputChannelNames() override { return { "In #1", "In #2" }; }
|
||||
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; }
|
||||
|
|
@ -221,15 +236,27 @@ public:
|
|||
auto numIns = getNumContiguousSetBits (inputChannels);
|
||||
auto numOuts = getNumContiguousSetBits (outputChannels);
|
||||
|
||||
settings.useAnalog = includeAnalogSupport ? 1 : 0;
|
||||
settings.useDigital = 0;
|
||||
settings.numAudioInChannels = numIns;
|
||||
settings.numAudioOutChannels = numOuts;
|
||||
// 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 = 1;
|
||||
settings.interleave = 0;
|
||||
|
||||
if (bufferSizeSamples > 0)
|
||||
settings.periodSize = bufferSizeSamples;
|
||||
|
|
@ -248,10 +275,7 @@ public:
|
|||
actualNumberOfInputs = jmin (numIns, actualNumberOfInputs);
|
||||
actualNumberOfOutputs = jmin (numOuts, actualNumberOfOutputs);
|
||||
|
||||
audioInBuffer.setSize (actualNumberOfInputs, actualBufferSize);
|
||||
channelInBuffer.calloc (actualNumberOfInputs);
|
||||
|
||||
audioOutBuffer.setSize (actualNumberOfOutputs, actualBufferSize);
|
||||
channelOutBuffer.calloc (actualNumberOfOutputs);
|
||||
|
||||
return {};
|
||||
|
|
@ -273,10 +297,7 @@ public:
|
|||
actualNumberOfInputs = 0;
|
||||
actualNumberOfOutputs = 0;
|
||||
|
||||
audioInBuffer.setSize (0, 0);
|
||||
channelInBuffer.free();
|
||||
|
||||
audioOutBuffer.setSize (0, 0);
|
||||
channelOutBuffer.free();
|
||||
}
|
||||
}
|
||||
|
|
@ -306,9 +327,6 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
audioInBuffer.clear();
|
||||
audioOutBuffer.clear();
|
||||
|
||||
callback = newCallback;
|
||||
isRunning = (Bela_startAudio() == 0);
|
||||
|
||||
|
|
@ -350,7 +368,7 @@ public:
|
|||
//==============================================================================
|
||||
int getCurrentBufferSizeSamples() override { return actualBufferSize; }
|
||||
double getCurrentSampleRate() override { return 44100.0; }
|
||||
int getCurrentBitDepth() override { return 24; }
|
||||
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; }
|
||||
|
|
@ -366,8 +384,8 @@ private:
|
|||
bool setup (BelaContext& context)
|
||||
{
|
||||
actualBufferSize = context.audioFrames;
|
||||
actualNumberOfInputs = context.audioInChannels;
|
||||
actualNumberOfOutputs = context.audioOutChannels;
|
||||
actualNumberOfInputs = context.audioInChannels + context.analogInChannels;
|
||||
actualNumberOfOutputs = context.audioOutChannels + context.analogOutChannels;
|
||||
isBelaOpen = true;
|
||||
firstCallback = true;
|
||||
|
||||
|
|
@ -386,9 +404,6 @@ private:
|
|||
|
||||
ScopedLock lock (callbackLock);
|
||||
|
||||
if (includeAnalogSupport)
|
||||
updateAnalogInputs (context);
|
||||
|
||||
// Check for and process and midi
|
||||
for (auto midiInput : BelaMidiInput::midiInputs)
|
||||
midiInput->poll();
|
||||
|
|
@ -396,59 +411,29 @@ private:
|
|||
if (callback != nullptr)
|
||||
{
|
||||
jassert (context.audioFrames <= actualBufferSize);
|
||||
auto numSamples = jmin (context.audioFrames, actualBufferSize);
|
||||
auto interleaved = ((context.flags & BELA_FLAG_INTERLEAVED) != 0);
|
||||
auto numIns = jmin (actualNumberOfInputs, (int) context.audioInChannels);
|
||||
auto numOuts = jmin (actualNumberOfOutputs, (int) context.audioOutChannels);
|
||||
jassert ((context.flags & BELA_FLAG_INTERLEAVED) == 0);
|
||||
|
||||
int ch;
|
||||
|
||||
if (interleaved && context.audioInChannels > 1)
|
||||
// Setup channelInBuffers
|
||||
for (int ch = 0; ch < actualNumberOfInputs; ++ch)
|
||||
{
|
||||
for (ch = 0; ch < numIns; ++ch)
|
||||
{
|
||||
using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst>;
|
||||
using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved, AudioData::Const>;
|
||||
|
||||
channelInBuffer[ch] = audioInBuffer.getWritePointer (ch);
|
||||
DstSampleType dstData (audioInBuffer.getWritePointer (ch));
|
||||
SrcSampleType srcData (context.audioIn + ch, context.audioInChannels);
|
||||
dstData.convertSamples (srcData, numSamples);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (ch = 0; ch < numIns; ++ch)
|
||||
channelInBuffer[ch] = context.audioIn + (ch * numSamples);
|
||||
if (ch < analogChannelStart)
|
||||
channelInBuffer[ch] = &context.audioIn[ch * context.audioFrames];
|
||||
else
|
||||
channelInBuffer[ch] = &context.analogIn[(ch - analogChannelStart) * context.analogFrames];
|
||||
}
|
||||
|
||||
for (; ch < actualNumberOfInputs; ++ch)
|
||||
// Setup channelOutBuffers
|
||||
for (int ch = 0; ch < actualNumberOfOutputs; ++ch)
|
||||
{
|
||||
channelInBuffer[ch] = audioInBuffer.getWritePointer(ch);
|
||||
zeromem (audioInBuffer.getWritePointer (ch), sizeof (float) * numSamples);
|
||||
if (ch < analogChannelStart)
|
||||
channelOutBuffer[ch] = &context.audioOut[ch * context.audioFrames];
|
||||
else
|
||||
channelOutBuffer[ch] = &context.analogOut[(ch - analogChannelStart) * context.audioFrames];
|
||||
}
|
||||
|
||||
for (int i = 0; i < actualNumberOfOutputs; ++i)
|
||||
channelOutBuffer[i] = ((interleaved && context.audioOutChannels > 1) || static_cast<uint32_t> (i) >= context.audioOutChannels ? audioOutBuffer.getWritePointer (i)
|
||||
: context.audioOut + (i * numSamples));
|
||||
|
||||
callback->audioDeviceIOCallback (channelInBuffer.getData(), actualNumberOfInputs,
|
||||
channelOutBuffer.getData(), actualNumberOfOutputs,
|
||||
numSamples);
|
||||
|
||||
if (interleaved && context.audioOutChannels > 1)
|
||||
{
|
||||
for (int i = 0; i < numOuts; ++i)
|
||||
{
|
||||
using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved, AudioData::NonConst>;
|
||||
using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const>;
|
||||
|
||||
SrcSampleType srcData (channelOutBuffer[i]);
|
||||
DstSampleType dstData (context.audioOut + i, context.audioOutChannels);
|
||||
|
||||
dstData.convertSamples (srcData, numSamples);
|
||||
}
|
||||
}
|
||||
context.audioFrames);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -460,39 +445,7 @@ private:
|
|||
callback->audioDeviceStopped();
|
||||
}
|
||||
|
||||
void updateAnalogInputs (BelaContext& context)
|
||||
{
|
||||
for (size_t i = 0; i < 8; i++)
|
||||
{
|
||||
auto v = analogRead (&context, 0, static_cast<int> (i));
|
||||
|
||||
if (fabs (analogInputs[i].previousInput - v) > 1.0f/512.0f)
|
||||
{
|
||||
auto controlValue = int (v * 127.0);
|
||||
|
||||
if (analogInputs[i].previousControlValue != controlValue)
|
||||
{
|
||||
// Consider this to have moved
|
||||
analogInputs[i].previousInput = v;
|
||||
analogInputs[i].previousControlValue = controlValue;
|
||||
|
||||
auto message = MidiMessage::controllerEvent (1, 16 + i, controlValue);
|
||||
|
||||
for (auto midiInput : BelaMidiInput::midiInputs)
|
||||
midiInput->pushMidiMessage (message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AnalogInput
|
||||
{
|
||||
float previousInput = 0;
|
||||
int previousControlValue = 0;
|
||||
};
|
||||
|
||||
std::vector<AnalogInput> analogInputs;
|
||||
|
||||
const int analogChannelStart = 2;
|
||||
|
||||
//==============================================================================
|
||||
uint64_t expectedElapsedAudioSamples = 0;
|
||||
|
|
@ -535,11 +488,10 @@ private:
|
|||
uint32_t actualBufferSize = 0;
|
||||
int actualNumberOfInputs = 0, actualNumberOfOutputs = 0;
|
||||
|
||||
AudioBuffer<float> audioInBuffer, audioOutBuffer;
|
||||
HeapBlock<const float*> channelInBuffer;
|
||||
HeapBlock<float*> channelOutBuffer;
|
||||
|
||||
bool includeAnalogSupport = true;
|
||||
bool includeAnalogSupport;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BelaAudioIODevice)
|
||||
};
|
||||
|
|
@ -551,7 +503,6 @@ struct BelaAudioIODeviceType : public AudioIODeviceType
|
|||
{
|
||||
BelaAudioIODeviceType() : AudioIODeviceType ("Bela") {}
|
||||
|
||||
// TODO: support analog outputs
|
||||
StringArray getDeviceNames (bool) const override { return StringArray (BelaAudioIODevice::belaTypeName); }
|
||||
void scanForDevices() override {}
|
||||
int getDefaultDeviceIndex (bool) const override { return 0; }
|
||||
|
|
@ -560,6 +511,7 @@ struct BelaAudioIODeviceType : public AudioIODeviceType
|
|||
|
||||
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();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue