Skip to content

Commit

Permalink
Resampling (#2)
Browse files Browse the repository at this point in the history
* minor(audio::input): use qualified path with imported Sample interface references

* deps(audio::input): add rubato for resampling input

* feat(cli): add subcommand to list input devices

* feat(audio::input): automatically resample input

Whisper wants an array of f32 encoding raw PCM data at a 16K sample rate.

* refactor(whisper): remove unnecessary conversion from i16, include job metadata in output
  • Loading branch information
dev-msp committed Apr 15, 2024
1 parent 6935796 commit 1762c60
Show file tree
Hide file tree
Showing 7 changed files with 361 additions and 113 deletions.
86 changes: 86 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ log = "0.4.21"
crossbeam = "0.8.4"
serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.115"
rubato = "0.15.0"
2 changes: 1 addition & 1 deletion run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ model_path="$2"
# The Unix socket the program will read and write to.
socket_path="$3"

./voice \
./voice run-daemon \
--socket-path "$socket_path" \
--model "$model_path" \
--device-name "$device_name"
29 changes: 16 additions & 13 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ use sttx::{IteratorExt, Timing};

use crate::app::input::iter::alpha_only;
use crate::audio::input::{controlled_recording, Recording};
use crate::sync;
use crate::{socket::receive_instructions, whisper, App};
use crate::whisper::TranscriptionJob;
use crate::{socket::receive_instructions, sync, whisper, DaemonInit};

use self::command::{CmdStream, Command};
use self::input::iter;
use self::response::Response;
use self::state::{Chat, Mode};

pub struct Daemon {
app: App,
config: DaemonInit,
input_device: Option<Device>,
state: state::State,
}
Expand Down Expand Up @@ -139,9 +139,9 @@ fn handle_hey_robot(content: &str) -> Option<Command> {
}

impl Daemon {
pub fn new(app: App, input_device: Option<Device>) -> Self {
pub fn new(config: DaemonInit, input_device: Option<Device>) -> Self {
Self {
app,
config,
input_device,
state: state::State::default(),
}
Expand All @@ -150,23 +150,22 @@ impl Daemon {
/// Runs the main application loop.
///
pub fn run_loop(&mut self) -> Result<bool, anyhow::Error> {
let model = self.app.model.clone();
let model = self.config.model.clone();
let device = self
.input_device
.as_ref()
.ok_or_else(|| anyhow!("No input device"))?;

let (to_whisper, from_recordings) = unbounded();
let (whisper_output, tx_worker) =
whisper::transcription_worker(&model, self.app.strategy(), from_recordings)?;
let (whisper_output, tx_worker) = whisper::transcription_worker(&model, from_recordings)?;

let ((rcmds, scmds), resps, listener) = receive_instructions(&self.app.socket_path)?;
let ((rcmds, scmds), resps, listener) = receive_instructions(&self.config.socket_path)?;
let mut commands = CmdStream::new(rcmds);

#[allow(unused_assignments)]
let mut exit_code = 0_u8;

let mut rec: Option<Recording<_, Vec<i16>>> = None;
let mut rec: Option<Recording<_, Vec<f32>>> = None;

for result in commands.run_state_machine(&mut self.state) {
let (ref command, ref new_state) = match result {
Expand Down Expand Up @@ -204,8 +203,12 @@ impl Daemon {
assert!(rec.is_some());
assert!(!new_state.running());

let audio = rec.take().unwrap().stop()?;
to_whisper.send(audio)?;
let (metadata, audio) = rec.take().unwrap().stop()?;
to_whisper.send(TranscriptionJob::new(
audio,
self.config.strategy(),
metadata.sample_rate.0 as i32,
))?;
let now = std::time::Instant::now();

let transcription = whisper_output
Expand Down Expand Up @@ -276,7 +279,7 @@ impl Daemon {
listener.join().unwrap()?;

// remove socket
std::fs::remove_file(&self.app.socket_path)?;
std::fs::remove_file(&self.config.socket_path)?;
Ok(false)
}
}
Loading

0 comments on commit 1762c60

Please sign in to comment.