From: Andrew Gundersen Date: Tue, 25 May 2021 20:21:57 +0000 (-0500) Subject: minor changes X-Git-Url: https://andrewgundersen.net/repos?a=commitdiff_plain;h=c561e11839061b23950227d492e7b5dde9a8726c;p=mime-chat minor changes --- diff --git a/src/background/audio.ts b/src/background/audio.ts index 0a98206..97a1576 100644 --- a/src/background/audio.ts +++ b/src/background/audio.ts @@ -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) { diff --git a/src/background/init.ts b/src/background/init.ts index f251246..b206393 100644 --- a/src/background/init.ts +++ b/src/background/init.ts @@ -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. diff --git a/src/background/initAudio.ts b/src/background/initAudio.ts new file mode 100644 index 0000000..27cc11b --- /dev/null +++ b/src/background/initAudio.ts @@ -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(); + }); + +} \ No newline at end of file diff --git a/src/components/message.vue b/src/components/message.vue index e69f29c..c701155 100644 --- a/src/components/message.vue +++ b/src/components/message.vue @@ -47,7 +47,7 @@
? diff --git a/src/modules/audio.ts b/src/modules/audio.ts new file mode 100644 index 0000000..853243a --- /dev/null +++ b/src/modules/audio.ts @@ -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 + } +} + + + +