Skip to content

Commit

Permalink
update fallback mechanism while getting audio
Browse files Browse the repository at this point in the history
  • Loading branch information
Mahmoudz committed May 18, 2024
1 parent 073f41b commit 3e63b66
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 64 deletions.
17 changes: 12 additions & 5 deletions src/core/AiAssistantEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class AiAssistantEngine extends EventEmitter {
}

// Control the primary user input method, if one fails it will fallback to the others and retry
this.userInputMethod = UserInputMethod.SPEECH_RECOGNIZER;
this.userInputMethod = UserInputMethod.AUDIO_RECORDER;
this.sdkVersion = pkg.version;
this.apiKey = apiKey;
this.apiUrl = apiUrl;
Expand Down Expand Up @@ -142,18 +142,25 @@ class AiAssistantEngine extends EventEmitter {
? await this.audioRecorder.startRecording()
: await this.speechToText.startListening();
} catch (err) {
this.getingtUserInput = false;
if (retries >= 2) {
throw new Error('Failed to get user input after 2 retries');
Logger.error(err);
if (retries >= 3) {
Logger.log(
'Both methods to getUserAudioInput failed. Stopping further attempts.',
);
throw new Error(
'Failed to get user input after trying both methods.',
);
}
Logger.error('Error getting user input, switching method:', err);

this.getingtUserInput = false;
this.userInputMethod =
this.userInputMethod === UserInputMethod.AUDIO_RECORDER
? UserInputMethod.SPEECH_RECOGNIZER
: UserInputMethod.AUDIO_RECORDER;
Logger.log(
`--[SISTA]-- FALLBACK: Switching "User Input Method" To = ${this.userInputMethod}`,
);

return this._getUserAudioInput(retries + 1);
}
}
Expand Down
91 changes: 53 additions & 38 deletions src/core/AudioRecorder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,52 +22,67 @@ class AudioRecorder {
this.handleStop = this.handleStop.bind(this);
}

public async startRecording(): Promise<Blob> {
if (this.mediaRecorder && this.mediaRecorder.state === 'recording') {
console.error('Recording is already in progress');
throw new Error('Recording is already in progress');
}

const stream = await this.getMediaStream();
const possibleTypes = [
'audio/mp4',
'audio/ogg; codecs=opus',
'audio/webm; codecs=opus',
'audio/wav',
'audio/mpeg',
];

let options = { mimeType: 'audio/wav' };
let supportedType = possibleTypes.find((type) =>
MediaRecorder.isTypeSupported(type),
);

if (!supportedType) {
console.error('No supported audio type found');
throw new Error('No supported audio type found');
}

options.mimeType = supportedType;

this.mediaRecorder = new MediaRecorder(stream, options);
this.mediaRecorder.ondataavailable = this.handleDataAvailable;
this.mediaRecorder.onstop = this.handleStop;
this.mediaRecorder.start();

this.setupAudioAnalysis(stream);
public async test_startRecording(): Promise<Blob> {
return new Promise((resolve, reject) => {
reject(new Error('TEST Error starting recording...'));
});
}

setTimeout(() => {
public async startRecording(): Promise<Blob> {
try {
if (
this.mediaRecorder &&
this.mediaRecorder.state === 'recording'
) {
this.stopRecording();
console.error('Recording is already in progress');
throw new Error('Recording is already in progress');
}
}, this.maxRecordingTime);

return new Promise<Blob>((resolve) => {
this.resolveRecording = resolve;
});
const stream = await this.getMediaStream();
const possibleTypes = [
'audio/mp4',
'audio/ogg; codecs=opus',
'audio/webm; codecs=opus',
'audio/wav',
'audio/mpeg',
];

let options = { mimeType: 'audio/wav' };
let supportedType = possibleTypes.find((type) =>
MediaRecorder.isTypeSupported(type),
);

if (!supportedType) {
console.error('No supported audio type found');
throw new Error('No supported audio type found');
}

options.mimeType = supportedType;

this.mediaRecorder = new MediaRecorder(stream, options);
this.mediaRecorder.ondataavailable = this.handleDataAvailable;
this.mediaRecorder.onstop = this.handleStop;
this.mediaRecorder.start();

this.setupAudioAnalysis(stream);

setTimeout(() => {
if (
this.mediaRecorder &&
this.mediaRecorder.state === 'recording'
) {
this.stopRecording();
}
}, this.maxRecordingTime);

return new Promise<Blob>((resolve) => {
this.resolveRecording = resolve;
});
} catch (error) {
Logger.error('AudioRecorder Error starting recording:', error);
throw new Error('Error starting recording');
}
}

private async getMediaStream(): Promise<MediaStream> {
Expand Down
54 changes: 33 additions & 21 deletions src/core/SpeechRecognizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,32 +65,44 @@ class SpeechRecognizer {
};
}

public async startListening(): Promise<string> {
public async test_startListening(): Promise<string> {
return new Promise((resolve, reject) => {
if (this.recognition.continuous) {
reject('Recognition is already in progress');
return;
}
reject(new Error('TEST Error starting listening...'));
});
}

this.finalTranscript = '';
public async startListening(): Promise<string> {
try {
return new Promise((resolve, reject) => {
if (this.recognition.continuous) {
console.error('Recognition is already in progress');
throw new Error('Recognition is already in progress');
}

this.recognition.onend = () => {
Logger.log('--[SISTA]-- Speech recognition service has ended.');
resolve(this.finalTranscript);
this.isListening = false;
};
this.finalTranscript = '';

this.recognition.onerror = (event: SpeechRecognitionEvent) => {
Logger.error(
`--[SISTA]-- Speech recognition error: ${event.error}`,
);
reject(new Error(event.error));
this.isListening = false;
};
this.recognition.onend = () => {
Logger.log(
'--[SISTA]-- Speech recognition service has ended.',
);
resolve(this.finalTranscript);
this.isListening = false;
};

this.recognition.start();
Logger.log('--[SISTA]-- Speech recognition started.');
});
this.recognition.onerror = (event: SpeechRecognitionEvent) => {
Logger.error(
`--[SISTA]-- Speech recognition error: ${event.error}`,
);
throw new Error(event.error);
};

this.recognition.start();
Logger.log('--[SISTA]-- Speech recognition started.');
});
} catch (error) {
Logger.error('SpeechRecognizer Error starting listening:', error);
throw new Error('Error starting listening');
}
}
}

Expand Down

0 comments on commit 3e63b66

Please sign in to comment.