Skip to content

Commit 77b5a3c

Browse files
committed
improved handling of audio play + mic release events
1 parent 37a88dc commit 77b5a3c

File tree

3 files changed

+58
-34
lines changed

3 files changed

+58
-34
lines changed

www/scripts/sepiaFW.audioRecorder.js

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ function sepiaFW_build_audio_recorder(){
44

55
//Debug modules and interfaces?
66
AudioRecorder.debugInterfaces = false;
7-
8-
//Parameters and states
9-
AudioRecorder.isRecording = false;
107

118
//set default parameters for audio recorder
129
AudioRecorder.setup = function(successCallback, errorCallback){
@@ -15,21 +12,12 @@ function sepiaFW_build_audio_recorder(){
1512

1613
//---- broadcasting -----
1714

18-
function broadcastRecorderRequested(){
19-
//console.log('broadcastRecorderRequested');
20-
}
21-
function broadcastRecorderStopRequested(){
22-
//console.log('broadcastRecorderStopRequested');
23-
}
24-
function broadcastRecorderClosed(){
25-
//console.log('broadcastRecorderClosed');
26-
}
27-
function broadcastRecorderStarted(){
28-
//console.log('broadcastRecorderStarted');
29-
}
30-
function broadcastRecorderStopped(){
31-
//console.log('broadcastRecorderStopped');
32-
}
15+
//TODO: do we still need these events? (check below: 'dispatchRecorderEvent')
16+
function broadcastRecorderRequested(){}
17+
function broadcastRecorderStopRequested(){}
18+
function broadcastRecorderClosed(){}
19+
function broadcastRecorderStarted(){}
20+
function broadcastRecorderStopped(){}
3321
function broadcastRecorderError(e){
3422
//console.log('broadcastRecorderError');
3523
}
@@ -39,8 +27,22 @@ function sepiaFW_build_audio_recorder(){
3927
if (SepiaFW.webAudio.defaultProcessorOptions){
4028
SepiaFW.webAudio.defaultProcessorOptions.moduleFolder = "audio-modules";
4129
}
30+
31+
//event dispatcher
32+
function dispatchRecorderEvent(data){
33+
//console.error("WebAudio recorder event", data); //DEBUG
34+
document.dispatchEvent(new CustomEvent('sepia_web_audio_recorder', { detail: data}));
35+
}
36+
37+
//The one and ONLY recorder instance:
4238
var sepiaWebAudioProcessor;
4339

40+
//should run parallel to AudioPlayer output?
41+
AudioRecorder.mayMicRunParallelToAudioOut = function(){
42+
return !SepiaFW.ui.isMobile; //mobile is ATM usually not good with Input + Output at same time
43+
//NOTE: for wake-word we check 'WakeTriggers.allowWakeWordDuringStream' and user can force this
44+
}
45+
4446
var activeAudioModules = [];
4547
var activeAudioModuleCapabilities = {}; //e.g.: resample, wakeWordDetection, vad, waveEncoding, volume, speechRecognition
4648
AudioRecorder.webAudioHasCapability = function(testCap){
@@ -131,12 +133,6 @@ function sepiaFW_build_audio_recorder(){
131133
if (useLegacyMicInterface) micAudioRecorderOptions.sourceType = "scriptProcessor";
132134
//var legacyScriptProcessorBufferSize = 512; //use 'micAudioRecorderOptions.processorBufferSize'
133135

134-
//event dispatcher
135-
function dispatchRecorderEvent(data){
136-
//console.error("WebAudio recorder event", data); //DEBUG
137-
document.dispatchEvent(new CustomEvent('sepia_web_audio_recorder', { detail: data}));
138-
}
139-
140136
function defaultOnProcessorReady(sepiaWebAudioProcessor, msg){
141137
SepiaFW.debug.info("AudioRecorder - onProcessorReady", sepiaWebAudioProcessor, msg); //DEBUG
142138
}
@@ -167,11 +163,6 @@ function sepiaFW_build_audio_recorder(){
167163
return (!!sepiaWebAudioProcessor && sepiaWebAudioProcessor.isInitialized() && sepiaWebAudioProcessor.isProcessing());
168164
}
169165
AudioRecorder.startWebAudioRecorder = function(successCallback, noopCallback, errorCallback){
170-
/*if (AudioRecorder.isRecording){
171-
SepiaFW.debug.err("AudioRecorder error: Tried to capture audio but was already running!");
172-
errorCallback({name: "AudioRecorder: not started!", message: "Audio capture was already running."});
173-
return;
174-
}*/
175166
if (sepiaWebAudioProcessor){
176167
sepiaWebAudioProcessor.start(successCallback, noopCallback, errorCallback);
177168
}else{

www/scripts/sepiaFW.speechAudioProcessor.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ function sepiaFW_build_speech_audio_proc(){
186186
var maxVadTime = 10000;
187187

188188
var isWaitingToRecord = false; //use for..?
189+
var isReleasing = false;
189190
//var recognizerWaitingForResult = false; //TODO: implement?
190191

191192
var asrModuleGateIsOpen = false; //equivalent to: 'isRecording'
@@ -359,6 +360,7 @@ function sepiaFW_build_speech_audio_proc(){
359360
_asrLogCallback('ASR ERROR - ABORT');
360361
//reset states
361362
isWaitingToRecord = false;
363+
isReleasing = false;
362364
asrModuleGateIsOpen = false; //TODO: can we trust this?
363365

364366
if (Recognizer.onerror){
@@ -424,6 +426,7 @@ function sepiaFW_build_speech_audio_proc(){
424426
SpeechRecognition.recognitionModule = buildWebSocketAsrModule();
425427

426428
//states set 2 - start
429+
isReleasing = false;
427430
abortRecognition = false;
428431
asrModuleGateIsOpen = false;
429432

@@ -481,6 +484,7 @@ function sepiaFW_build_speech_audio_proc(){
481484
//STATE: audioend
482485
onAudioEnd(); //trigger or not?
483486
//TODO: just wait for result? release after certain time? what if errorCallback triggers?
487+
//NOTE: releasing the recorder will kill all pending results (use idle event?)
484488
});
485489
}
486490
}
@@ -492,17 +496,29 @@ function sepiaFW_build_speech_audio_proc(){
492496
//NOTE: expected to send END event - should be triggered by stop
493497
}
494498

499+
//a release function - currently just used to prevent multiple calls to release
500+
function releaseThisRecorder(callback){
501+
if (!isReleasing && SpeechRecognition.recognitionModule){
502+
isReleasing = true;
503+
SepiaFW.audioRecorder.stopAndReleaseIfActive(function(){
504+
if (callback) callback();
505+
//... the rest is below in event handler
506+
});
507+
}
508+
}
509+
495510
//listen to global events to make sure state is updated correctly
496511
document.addEventListener("sepia_web_audio_recorder", recoderEventListener);
497512
function recoderEventListener(e){
498513
var data = e.detail;
499514
if (!data || !data.event) return;
500515

501516
//TODO: is this correct?
502-
if (data.event == "release" && (asrModuleGateIsOpen || isWaitingToRecord)){
517+
if (data.event == "release" && SpeechRecognition.recognitionModule){
503518
//reset state
504519
asrModuleGateIsOpen = false;
505520
isWaitingToRecord = false;
521+
isReleasing = false;
506522
SpeechRecognition.recognitionModule = undefined;
507523

508524
}else if (data.event == "audioend" && (asrModuleGateIsOpen || isWaitingToRecord)){
@@ -512,6 +528,23 @@ function sepiaFW_build_speech_audio_proc(){
512528
isWaitingToRecord = false;
513529
}
514530
}
531+
document.addEventListener('sepia_audio_player_event', audioPlayerEventListener, true);
532+
function audioPlayerEventListener(e){
533+
var data = e.detail;
534+
if (!data || !data.action) return;
535+
//console.error("SpeechRecognition Processor - sepia_audio_player_event", data, "exists?", !!SpeechRecognition.recognitionModule); //DEBUG
536+
if (SpeechRecognition.recognitionModule){
537+
//Audio player start
538+
if (data.action == "prepare" || data.action == "start" || data.action == "resume"){
539+
//make sure the recorder is released when audio out is running
540+
if (!SepiaFW.audioRecorder.mayMicRunParallelToAudioOut()){
541+
releaseThisRecorder(function(){
542+
SepiaFW.debug.info("SpeechRecognition Processor - Released due to audio player '" + data.action + "' event");
543+
});
544+
}
545+
}
546+
}
547+
}
515548

516549
return SpeechRecognition;
517550
}

www/scripts/sepiaFW.wakeTriggers.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,13 @@ function sepiaFW_build_wake_triggers() {
8989
hasAudioPlayerEventListeners = true;
9090
document.addEventListener('sepia_audio_player_event', function(e){
9191
if (e.detail){
92-
//console.error(e.detail);
92+
//console.error("WakeTriggers - sepia_audio_player_event", e.detail); //DEBUG
9393
if (WakeTriggers.useWakeWord && WakeTriggers.engineLoaded){
9494
//Audio player start
95-
if (e.detail.action == "start" || e.detail.action == "resume"){
96-
if (WakeTriggers.isListening() && !WakeTriggers.allowWakeWordDuringStream){
95+
if (e.detail.action == "prepare" || e.detail.action == "start" || e.detail.action == "resume"){
96+
if (!isStopping && WakeTriggers.isListening() && !WakeTriggers.allowWakeWordDuringStream){
9797
SepiaFW.debug.info("WakeTriggers - Stopping wake-word listener due to audio player '" + e.detail.action + "' event");
98-
WakeTriggers.stopListeningToWakeWords();
98+
WakeTriggers.stopListeningToWakeWords(); //note without 'keepalive' this is RELEASE
9999
}
100100
//Audio player stop
101101
}else if (e.detail.action == "stop" || e.detail.action == "pause"){

0 commit comments

Comments
 (0)