Skip to content

Commit 0f5ea52

Browse files
committed
Added information on demand-wake for the audio pipeline and fixed the wake-up sequence
1 parent 0812b03 commit 0f5ea52

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

source/MicroBitAudio.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ MicroBitAudio::MicroBitAudio(NRF52Pin &pin, NRF52Pin &speaker, NRF52ADC &adc, NR
6363
adc.setSamplePeriod( 1e6 / 22000 );
6464
mic->setGain(7,0);
6565

66+
// Implementers note: The order that the pipeline comes up here is quite senitive. If we connect up to splitters after starting to
67+
// listen for events from them, we'll see channel startup events (which are valid!) that we don't want. So roughly always follow
68+
// the following schema:
69+
//
70+
// 1. Create the splitter
71+
// 2. Attach any stages to the splitter
72+
// 3. Start listening for splitter events
73+
//
74+
// This prevents any cases where the pipeline stages cause a connect() message to be emitted, which then auto-activates the mic.
75+
6676
//Initialialise the microphone filter
6777
micFilter = new LowPassFilter(mic->output, 0.1f, true);
6878

@@ -72,6 +82,10 @@ MicroBitAudio::MicroBitAudio(NRF52Pin &pin, NRF52Pin &speaker, NRF52ADC &adc, NR
7282
//Initilise stream normalizer
7383
processor = new StreamNormalizer(*rawSplitter->createChannel(), 0.08f, true, DATASTREAM_FORMAT_8BIT_SIGNED, 10);
7484

85+
// Connect to the rawSplitter. This must come AFTER the processor, to prevent the processor's channel activation starting the microphone
86+
if(EventModel::defaultEventBus)
87+
EventModel::defaultEventBus->listen(rawSplitter->id, DEVICE_EVT_ANY, this, &MicroBitAudio::onSplitterEvent, MESSAGE_BUS_LISTENER_IMMEDIATE);
88+
7589
//Initilise stream splitter
7690
splitter = new StreamSplitter(processor->output, DEVICE_ID_SPLITTER);
7791

@@ -81,21 +95,22 @@ MicroBitAudio::MicroBitAudio(NRF52Pin &pin, NRF52Pin &speaker, NRF52ADC &adc, NR
8195
//Initilise level detector SPL and attach to splitter
8296
levelSPL = new LevelDetectorSPL(*rawSplitter->createChannel(), 85.0, 65.0, 16.0, 0, DEVICE_ID_MICROPHONE, false);
8397

84-
// Register listener for splitter events
85-
if(EventModel::defaultEventBus){
86-
EventModel::defaultEventBus->listen(rawSplitter->id, DEVICE_EVT_ANY, this, &MicroBitAudio::onSplitterEvent, MESSAGE_BUS_LISTENER_IMMEDIATE);
98+
// 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
99+
// we're going to follow the schema set out above, to be 100% sure.
100+
if(EventModel::defaultEventBus)
87101
EventModel::defaultEventBus->listen(DEVICE_ID_SPLITTER, DEVICE_EVT_ANY, this, &MicroBitAudio::onSplitterEvent, MESSAGE_BUS_LISTENER_IMMEDIATE);
88-
}
89102
}
90103

91104
/**
92105
* Handle events from splitter
93106
*/
94107
void MicroBitAudio::onSplitterEvent(MicroBitEvent e){
95-
if(e.value == SPLITTER_ACTIVATE_CHANNEL)
108+
if( e.value == SPLITTER_CHANNEL_CONNECT )
96109
activateMic();
97-
else if (e.value == SPLITTER_DEACTIVATE_CHANNEL)
98-
if( splitter->numberChannels <= 0 && rawSplitter->numberChannels <= 0 ) // Only deactivate if we have no more channels to serve!
110+
111+
// Note: The processor will always be present on the rawSplitter, hence the <= 1.
112+
else if( e.value == SPLITTER_CHANNEL_DISCONNECT )
113+
if( splitter->numberActiveChannels <= 0 && rawSplitter->numberActiveChannels <= 1 )
99114
deactivateMic();
100115
}
101116

0 commit comments

Comments
 (0)