From 32a0208147e18fa0b7f271322bf2e78135a558de Mon Sep 17 00:00:00 2001 From: cesare Date: Sat, 12 Oct 2019 14:28:29 +0100 Subject: [PATCH] Bela updates to support analog inputs --- .../native/juce_linux_Bela.cpp | 162 ++++++------------ 1 file changed, 57 insertions(+), 105 deletions(-) diff --git a/modules/juce_audio_devices/native/juce_linux_Bela.cpp b/modules/juce_audio_devices/native/juce_linux_Bela.cpp index 8a111361af..b13eceb50e 100755 --- a/modules/juce_audio_devices/native/juce_linux_Bela.cpp +++ b/modules/juce_audio_devices/native/juce_linux_Bela.cpp @@ -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 getAvailableSampleRates() override { return { 44100.0 }; } Array 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; - using SrcSampleType = AudioData::Pointer; - - 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 (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; - using SrcSampleType = AudioData::Pointer; - - 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 (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 analogInputs; - + const int analogChannelStart = 2; //============================================================================== uint64_t expectedElapsedAudioSamples = 0; @@ -535,11 +488,10 @@ private: uint32_t actualBufferSize = 0; int actualNumberOfInputs = 0, actualNumberOfOutputs = 0; - AudioBuffer audioInBuffer, audioOutBuffer; HeapBlock channelInBuffer; HeapBlock 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();