minor changes
This commit is contained in:
parent
17e4b06948
commit
c561e11839
5 changed files with 166 additions and 11 deletions
|
|
@ -20,10 +20,10 @@ const audioContainer = {
|
|||
|
||||
const audioOptions = {
|
||||
channelCount: 1,
|
||||
sampleFormat: 16,
|
||||
sampleRate: 16000,
|
||||
sampleRate: 44100,
|
||||
sampleFormat: portAudio.SampleFormat16Bit,
|
||||
deviceId: -1,
|
||||
closeOnError: false,
|
||||
closeOnError: false
|
||||
}
|
||||
|
||||
// Toggles record to true to begin capturing chunks.
|
||||
|
|
@ -39,6 +39,8 @@ const onRecordingEnd = async (_event: any, payload: any) => {
|
|||
return new Promise((resolve, reject) => {
|
||||
|
||||
try {
|
||||
console.log("Resolving audio");
|
||||
console.log(audioContainer.input);
|
||||
resolve(audioContainer.input);
|
||||
record = false;
|
||||
} catch (e) {
|
||||
|
|
@ -143,15 +145,21 @@ export function play(input: string): void {
|
|||
let i = 0;
|
||||
|
||||
do {
|
||||
|
||||
chunk = audio[i];
|
||||
|
||||
// On last chunk
|
||||
if (i === audio.length - 1) {
|
||||
// write last chunk.
|
||||
ao.write(chunk, null, callback);
|
||||
} else {
|
||||
}
|
||||
|
||||
else {
|
||||
// check for backpreassure.
|
||||
ok = ao.write(chunk, null);
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
} while (i < audio.length && ok);
|
||||
|
||||
if (i < audio.length) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import { app, dialog } from "electron";
|
||||
import { createWindow } from './window';
|
||||
import { initSession } from './session';
|
||||
import { initAudioIO, stopStream } from './audio';
|
||||
import initAudioIO from './initAudio';
|
||||
import { backgroundMitt } from '@/modules/emitter';
|
||||
|
||||
let win: boolean;
|
||||
|
|
@ -45,12 +45,12 @@ async function main(dev: boolean) {
|
|||
// Must wait til window is created.
|
||||
await createWindow();
|
||||
|
||||
// Instantiate socket session with crimata-platorm.
|
||||
initSession(dev);
|
||||
|
||||
// Begin audio stream.
|
||||
initAudioIO();
|
||||
|
||||
// Instantiate socket session with crimata-platorm.
|
||||
initSession(dev);
|
||||
|
||||
}
|
||||
|
||||
// Root function of app.
|
||||
|
|
@ -64,7 +64,7 @@ export function initApp(dev: boolean): void {
|
|||
|
||||
// Must keep to ensure app doesn't quit on close.
|
||||
app.on("before-quit", async () => {
|
||||
await stopStream();
|
||||
// await stopStream();
|
||||
});
|
||||
|
||||
// Must keep to ensure app doesn't quit on close.
|
||||
|
|
|
|||
18
src/background/initAudio.ts
Normal file
18
src/background/initAudio.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { ipcMain } from "electron";
|
||||
import audioInterface from "@/modules/audio";
|
||||
|
||||
export default function initAudioIO () {
|
||||
console.log('[AUDIO]initializing audio');
|
||||
|
||||
// initialize the audio interface
|
||||
const { read, stopRead, write, shutdown } = audioInterface();
|
||||
|
||||
ipcMain.on("start-recording", read);
|
||||
|
||||
ipcMain.on("shutdown-audio", shutdown);
|
||||
|
||||
ipcMain.handle("stop-recording", () => {
|
||||
return stopRead();
|
||||
});
|
||||
|
||||
}
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
<!-- Show question mark if transcription comes back as unknown. -->
|
||||
<div
|
||||
v-else-if="message.content.text === false"
|
||||
v-else-if="message.content.text == false"
|
||||
class="questionMark"
|
||||
>
|
||||
?
|
||||
|
|
|
|||
129
src/modules/audio.ts
Normal file
129
src/modules/audio.ts
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
const portAudio = require('naudiodon');
|
||||
const stream = require('stream');
|
||||
const fs = require('fs');
|
||||
|
||||
|
||||
// current config
|
||||
let currentHost: number;
|
||||
let currentInputDevice: number;
|
||||
let currentOutputDevice: number;
|
||||
|
||||
// audio streams
|
||||
let ai: any;
|
||||
let ao: any;
|
||||
|
||||
// write audio here
|
||||
const path = 'rawAudio.raw'
|
||||
let writable = fs.createWriteStream(path);
|
||||
|
||||
// get info for given host api
|
||||
const getHostInfo = (id: number) => {
|
||||
return portAudio.getHostAPIs().HostAPIs.filter(host =>
|
||||
host.id === id)[0];
|
||||
}
|
||||
|
||||
// get info for given device
|
||||
const getDeviceInfo = (id: number) => {
|
||||
return portAudio.getDevices().filter(device =>
|
||||
device.id === id)[0];
|
||||
};
|
||||
|
||||
// constructor to start audio streams
|
||||
const setup = () => {
|
||||
|
||||
currentHost = portAudio.getHostAPIs().defaultHostAPI;
|
||||
const hostInfo = getHostInfo(currentHost);
|
||||
|
||||
if (currentInputDevice !== hostInfo.defaultInput) {
|
||||
currentInputDevice = hostInfo.defaultInput;
|
||||
ai = setInputStream();
|
||||
ai.start();
|
||||
}
|
||||
|
||||
if (currentOutputDevice !== hostInfo.defaultOutput) {
|
||||
currentOutputDevice = hostInfo.defaultOutput;
|
||||
ao = setOutputStream()
|
||||
ao.start();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// init and start input stream
|
||||
const setInputStream = () => {
|
||||
|
||||
const inputDeviceInfo = getDeviceInfo(currentInputDevice);
|
||||
|
||||
return new portAudio.AudioIO({
|
||||
inOptions: {
|
||||
channelCount: inputDeviceInfo.maxInputChannels,
|
||||
sampleFormat: portAudio.SampleFormat16Bit,
|
||||
sampleRate: inputDeviceInfo.defaultSampleRate,
|
||||
deviceId: inputDeviceInfo.id,
|
||||
closeOnError: false
|
||||
}
|
||||
})
|
||||
.on('error', () => console.log("input stream error"))
|
||||
|
||||
}
|
||||
|
||||
// init and start output stream
|
||||
const setOutputStream = () => {
|
||||
|
||||
const outputDeviceInfo = getDeviceInfo(currentOutputDevice);
|
||||
|
||||
return new portAudio.AudioIO({
|
||||
outOptions: {
|
||||
channelCount: outputDeviceInfo.maxOutputChannels,
|
||||
sampleFormat: portAudio.SampleFormat16Bit,
|
||||
sampleRate: outputDeviceInfo.defaultSampleRate,
|
||||
deviceId: outputDeviceInfo.id,
|
||||
closeOnError: false
|
||||
}
|
||||
})
|
||||
.on('error', () => console.log("output stream error"))
|
||||
|
||||
}
|
||||
|
||||
// pipe ai to writable
|
||||
const read = () => {
|
||||
if (ai) {
|
||||
ai.pipe(writable);
|
||||
}
|
||||
};
|
||||
|
||||
// remove pipe and return audio contents
|
||||
const stopRead = () => {
|
||||
if (ai) {
|
||||
ai.unpipe(writable);
|
||||
return fs.readFileSync(path);
|
||||
};
|
||||
};
|
||||
|
||||
// write a buffer of audio to stream
|
||||
const write = (chunks: Buffer) => {
|
||||
const readable = new stream.Readable()
|
||||
readable.pipe(ao);
|
||||
chunks.forEach(item => readable.push(item))
|
||||
};
|
||||
|
||||
// quit both streams
|
||||
const shutdown = () => {
|
||||
if (ao) ao.quit();
|
||||
if (ai) ai.quit();
|
||||
};
|
||||
|
||||
|
||||
// run in loop and return controls
|
||||
export default function audioInterface () {
|
||||
setInterval(setup, 2000);
|
||||
return {
|
||||
read,
|
||||
stopRead,
|
||||
write,
|
||||
shutdown
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in a new issue