import { sendAudio } from './session'
import { ipcMain } from "electron";
+import { backgroundMitt } from './emitter';
const portAudio = require('naudiodon');
-let ai: typeof portAudio.AudioIO;
-let ao: typeof portAudio.AudioIO;
+let ai: typeof portAudio.AudioIO | null = null;
+let ao: typeof portAudio.AudioIO | null = null;
let audioInput: Buffer[] = [];
const encoding = "base64";
const audioOptions = {
closeOnError: false,
}
-// main function run by run.ts module.
+backgroundMitt.once('window-active', (state: boolean) => {
+ if(!state) {
+ stopStream();
+ }
+});
+
+// main audio function run by run.ts module.
export function initAudioIO(): void {
- // init portAudio readable stream once.
- if (!ai) {
- ai = new portAudio.AudioIO({ inOptions: audioOptions });
- // base64 encoding needed for google speech to text.
- ai.setEncoding(encoding);
+ if (ai != null) {
+ ai.quit();
+ audioInput = [];
+ }
- // pause the portAudio data flow as soon as stream is initiated.
- ai.start();
- ai.pause();
+ ai = new portAudio.AudioIO({ inOptions: audioOptions });
- ai.on('error', (e: Error) => {
- console.log('Error recording audio', + e);
- });
- ai.on('data', (chunk: string) => {
- // turn string base64 data into buffer object.
- console.log('received string chunk of length', chunk.length)
- const buf = Buffer.from(chunk, encoding);
- audioInput.push(buf);
- });
- }
+ // base64 encoding needed for google speech to text.
+ ai.setEncoding(encoding);
- // init portAudio writable stream once.
- if (!ao) {
- ao = new portAudio.AudioIO({ outOptions: audioOptions });
- ao.start();
- }
+ // pause the portAudio data flow as soon as stream is initiated.
+ ai.start();
+ ai.pause();
+
+ ai.on('data', (chunk: string) => {
+ // turn string base64 data into buffer object.
+ const buf = Buffer.from(chunk, encoding);
+ audioInput.push(buf);
+ });
+
+ if (ao != null) {
+ ao.end();
+ }
+ ao = new portAudio.AudioIO({ outOptions: audioOptions });
+ ao.start();
}
-// run this function on space bar key up and down.
+// callback run on space bar key up and down.
const updateRecorder = (_event, record: boolean): void => {
if (record) {
// resume mic data flow on space bar key down.
+ while(audioInput.length) { audioInput.pop() }
ai.resume();
} else {
// stop mic data flow on space bar key up.
const audio = Buffer.concat(audioInput);
sendAudio(audio);
// clear audioInput.
- while(audioInput.length) { audioInput.pop()}
+ while(audioInput.length) { audioInput.pop() }
}
}
}
}
+function stopStream() {
+ if(ai != null) {
+ ai.quit();
+ ai = null;
+ }
+ if (ao != null) {
+ ao.quit();
+ ao = null;
+ }
+}
+
// utility function used by play func.
function bufSplit(input: Array<Buffer>): Array<Buffer> {
- let result: Buffer[] = [];
+ const result: Buffer[] = [];
input.forEach((b: Buffer) => {
// split buffer into two.
result.push(b.slice(0, b.length / 2), b.slice(b.length / 2, b.length));