From ea1d2e10118d6a1a779462dfb606ded3e2722c97 Mon Sep 17 00:00:00 2001 From: Joe Finney Date: Fri, 1 Nov 2024 16:29:26 +0000 Subject: [PATCH 1/4] Remove legacy code relater to runtime reconfiguration of audio pipeline --- inc/MicroBitAudio.h | 6 ------ source/MicroBitAudio.cpp | 18 ------------------ 2 files changed, 24 deletions(-) diff --git a/inc/MicroBitAudio.h b/inc/MicroBitAudio.h index 60ca6087..f3623767 100644 --- a/inc/MicroBitAudio.h +++ b/inc/MicroBitAudio.h @@ -97,12 +97,6 @@ namespace codal */ static void requestActivation(); - /** - * Catch events from the splitter - * @param MicroBitEvent - */ - void onSplitterEvent(MicroBitEvent); - /** * Activate Mic */ diff --git a/source/MicroBitAudio.cpp b/source/MicroBitAudio.cpp index fd8b0ff1..4e30a31f 100644 --- a/source/MicroBitAudio.cpp +++ b/source/MicroBitAudio.cpp @@ -81,26 +81,8 @@ MicroBitAudio::MicroBitAudio(NRF52Pin &pin, NRF52Pin &speaker, NRF52ADC &adc, NR //levelSPL = new LevelDetectorSPL(*rawSplitter->createChannel(), 85.0, 65.0, 16.0, 0, DEVICE_ID_MICROPHONE, false); levelSPL = new LevelDetectorSPL(*rawSplitter->createChannel(), 85.0, 65.0, 16.0, 52.0, DEVICE_ID_SYSTEM_LEVEL_DETECTOR, false); - // Connect to the rawSplitter. This must come AFTER the processor, to prevent the processor's channel activation starting the microphone - if(EventModel::defaultEventBus) - EventModel::defaultEventBus->listen(rawSplitter->id, DEVICE_EVT_ANY, this, &MicroBitAudio::onSplitterEvent, MESSAGE_BUS_LISTENER_IMMEDIATE); - //Initilise stream splitter splitter = new StreamSplitter(processor->output, DEVICE_ID_SPLITTER); - - // Connect to the splitter - this COULD come after we create it, before we add any stages, as these are dynamic and will only connect on-demand, but just in case - // we're going to follow the schema set out above, to be 100% sure. - if(EventModel::defaultEventBus) { - EventModel::defaultEventBus->listen(DEVICE_ID_SPLITTER, DEVICE_EVT_ANY, this, &MicroBitAudio::onSplitterEvent, MESSAGE_BUS_LISTENER_IMMEDIATE); - EventModel::defaultEventBus->listen(DEVICE_ID_NOTIFY, mic->output.emitFlowEvents(), this, &MicroBitAudio::onSplitterEvent, MESSAGE_BUS_LISTENER_IMMEDIATE); - } -} - -void MicroBitAudio::onSplitterEvent(MicroBitEvent e){ - if( mic->output.isFlowing() || (e.value == SPLITTER_ACTIVATE || e.value == SPLITTER_CHANNEL_CONNECT) ) - activateMic(); - else - deactivateMic(); } void MicroBitAudio::activateMic(){ From 8345d464d68c03772ae28e48aeb98f7916f51d85 Mon Sep 17 00:00:00 2001 From: Joe Finney Date: Tue, 26 Nov 2024 13:21:05 +0000 Subject: [PATCH 2/4] Chnages ito support audio-refactor. Not yet tested. --- inc/MicroBitAudio.h | 4 +++- source/MicroBitAudio.cpp | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/inc/MicroBitAudio.h b/inc/MicroBitAudio.h index f3623767..baed2d1b 100644 --- a/inc/MicroBitAudio.h +++ b/inc/MicroBitAudio.h @@ -55,7 +55,7 @@ namespace codal public: static MicroBitAudio *instance; // Primary instance of MicroBitAudio, on demand activated. Mixer2 mixer; // Multi channel audio mixer - NRF52ADCChannel *mic; // Microphone ADC Channel from uBit.IO + NRF52ADCChannel *mic; // Microphone ADC Channel from uBit.IO StreamNormalizer *processor; // Stream Normaliser instance StreamSplitter *splitter; // Stream Splitter instance (8bit normalized output) StreamSplitter *rawSplitter; // Stream Splitter instance (raw input) @@ -184,6 +184,8 @@ namespace codal * Puts the component in (or out of) sleep (low power) mode. */ virtual int setSleep(bool doSleep) override; + + virtual void periodicCallback(); }; } diff --git a/source/MicroBitAudio.cpp b/source/MicroBitAudio.cpp index 4e30a31f..23aaa2ea 100644 --- a/source/MicroBitAudio.cpp +++ b/source/MicroBitAudio.cpp @@ -55,6 +55,9 @@ MicroBitAudio::MicroBitAudio(NRF52Pin &pin, NRF52Pin &speaker, NRF52ADC &adc, NR if (MicroBitAudio::instance == NULL) MicroBitAudio::instance = this; + // Request a periodic callback + status |= DEVICE_COMPONENT_STATUS_SYSTEM_TICK; + synth.allowEmptyBuffers(true); mic = adc.getChannel(microphone, false); @@ -85,6 +88,15 @@ MicroBitAudio::MicroBitAudio(NRF52Pin &pin, NRF52Pin &speaker, NRF52ADC &adc, NR splitter = new StreamSplitter(processor->output, DEVICE_ID_SPLITTER); } +void MicroBitAudio::periodicCallback() +{ + if (mic->isEnabled() && !micEnabled) + activateMic(); + + if (!mic->isEnabled() && micEnabled) + deactivateMic(); +} + void MicroBitAudio::activateMic(){ runmic.setDigitalValue(1); runmic.setHighDrive(true); From cdb033ac2bb614806c46f768362bcf69c7816b72 Mon Sep 17 00:00:00 2001 From: Joe Finney Date: Thu, 28 Nov 2024 17:01:37 +0000 Subject: [PATCH 3/4] Bugfix minor errors in pipeline --- model/MicroBit.cpp | 1 - source/MicroBitAudio.cpp | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/model/MicroBit.cpp b/model/MicroBit.cpp index 7ebc8738..36195368 100644 --- a/model/MicroBit.cpp +++ b/model/MicroBit.cpp @@ -301,7 +301,6 @@ int MicroBit::init() // before any user code begins running. sleep(10); - return DEVICE_OK; } diff --git a/source/MicroBitAudio.cpp b/source/MicroBitAudio.cpp index 23aaa2ea..dee0695a 100644 --- a/source/MicroBitAudio.cpp +++ b/source/MicroBitAudio.cpp @@ -91,10 +91,16 @@ MicroBitAudio::MicroBitAudio(NRF52Pin &pin, NRF52Pin &speaker, NRF52ADC &adc, NR void MicroBitAudio::periodicCallback() { if (mic->isEnabled() && !micEnabled) + { + DMESG("MicroBitAudio::periodicCallback: activateMic()..."); activateMic(); + } if (!mic->isEnabled() && micEnabled) + { + DMESG("MicroBitAudio::periodicCallback: deactivateMic()..."); deactivateMic(); + } } void MicroBitAudio::activateMic(){ @@ -106,7 +112,6 @@ void MicroBitAudio::activateMic(){ void MicroBitAudio::deactivateMic(){ this->micEnabled = false; - //mic->disable(); runmic.setDigitalValue(0); runmic.setHighDrive(false); } From 8b28130f933dde4572a5e0f31a29145107f6d1a6 Mon Sep 17 00:00:00 2001 From: Joe Finney Date: Mon, 2 Dec 2024 17:59:38 +0000 Subject: [PATCH 4/4] bugfix --- model/MicroBit.cpp | 2 +- source/MicroBitAudio.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/model/MicroBit.cpp b/model/MicroBit.cpp index 36195368..ff4d45ad 100644 --- a/model/MicroBit.cpp +++ b/model/MicroBit.cpp @@ -364,7 +364,7 @@ void MicroBit::onListenerRegisteredEvent(Event evt) // The level detector uses lazy instantiation, we just need to read the data once to start it running. //audio.level->getValue(); // The level detector requires that we enable constant listening, otherwise no events will be emitted. - audio.levelSPL->activateForEvents( true ); + audio.levelSPL->listenerAdded(); break; case DEVICE_ID_MICROPHONE: diff --git a/source/MicroBitAudio.cpp b/source/MicroBitAudio.cpp index dee0695a..75898801 100644 --- a/source/MicroBitAudio.cpp +++ b/source/MicroBitAudio.cpp @@ -64,6 +64,8 @@ MicroBitAudio::MicroBitAudio(NRF52Pin &pin, NRF52Pin &speaker, NRF52ADC &adc, NR adc.setSamplePeriod( 1e6 / CONFIG_MIXER_DEFAULT_CHANNEL_SAMPLERATE ); mic->setGain(7, 0); + activateMic(); + // Implementers note: The order that the pipeline comes up here is quite sensitive. If we connect up to splitters after starting to // listen for events from them, we'll see channel startup events (which are valid!) that we don't want. So roughly always follow // the following schema: @@ -82,7 +84,7 @@ MicroBitAudio::MicroBitAudio(NRF52Pin &pin, NRF52Pin &speaker, NRF52ADC &adc, NR //Initilise level detector SPL and attach to splitter //levelSPL = new LevelDetectorSPL(*rawSplitter->createChannel(), 85.0, 65.0, 16.0, 0, DEVICE_ID_MICROPHONE, false); - levelSPL = new LevelDetectorSPL(*rawSplitter->createChannel(), 85.0, 65.0, 16.0, 52.0, DEVICE_ID_SYSTEM_LEVEL_DETECTOR, false); + levelSPL = new LevelDetectorSPL(*rawSplitter->createChannel(), 85.0, 65.0, 16.0, 52.0, DEVICE_ID_SYSTEM_LEVEL_DETECTOR); //Initilise stream splitter splitter = new StreamSplitter(processor->output, DEVICE_ID_SPLITTER);