1
0
Fork 0
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:
cesare 2019-10-12 14:28:29 +01:00
parent ada4bba910
commit 32a0208147

View file

@ -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();