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.
return new Promise((resolve, reject) => {
try {
+ console.log("Resolving audio");
+ console.log(audioContainer.input);
resolve(audioContainer.input);
record = false;
} catch (e) {
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) {
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;
// 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.
// 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.
--- /dev/null
+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
--- /dev/null
+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
+ }
+}
+
+
+
+