rvsttd: hold-back last drain chunk for fade, same faded audio to Moonshine + WAV
This commit is contained in:
+21
-24
@@ -113,14 +113,6 @@ impl DebugRecorder {
|
|||||||
self.audio.extend_from_slice(samples);
|
self.audio.extend_from_slice(samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn audio_len(&self) -> usize {
|
|
||||||
self.audio.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn truncate_audio(&mut self, len: usize) {
|
|
||||||
self.audio.truncate(len);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn save(self) {
|
fn save(self) {
|
||||||
// Write log
|
// Write log
|
||||||
let log_path = self.dir.join("session.log");
|
let log_path = self.dir.join("session.log");
|
||||||
@@ -332,45 +324,50 @@ fn transcriber_loop(
|
|||||||
// Drain trailing audio from ALSA buffer (cpal stream still alive).
|
// Drain trailing audio from ALSA buffer (cpal stream still alive).
|
||||||
// Fixed 100ms window — cpal delivers every ~50ms (800 samples @ 16kHz),
|
// Fixed 100ms window — cpal delivers every ~50ms (800 samples @ 16kHz),
|
||||||
// so this captures 1-2 more callbacks worth of trailing audio.
|
// so this captures 1-2 more callbacks worth of trailing audio.
|
||||||
|
// Hold one chunk back so we can apply a fade-out to the very last one.
|
||||||
let drain_deadline = std::time::Instant::now() + Duration::from_millis(100);
|
let drain_deadline = std::time::Instant::now() + Duration::from_millis(100);
|
||||||
let mut drained: Vec<f32> = Vec::new();
|
let mut held_chunk: Option<Vec<f32>> = None;
|
||||||
while std::time::Instant::now() < drain_deadline {
|
while std::time::Instant::now() < drain_deadline {
|
||||||
match rx.recv_timeout(drain_deadline - std::time::Instant::now()) {
|
match rx.recv_timeout(drain_deadline - std::time::Instant::now()) {
|
||||||
Ok(chunk) => {
|
Ok(chunk) => {
|
||||||
|
// Feed previously held chunk to Moonshine + recorder (no fade)
|
||||||
|
if let Some(prev) = held_chunk.take() {
|
||||||
if let Some(ref mut r) = recorder {
|
if let Some(ref mut r) = recorder {
|
||||||
r.add_audio(&chunk);
|
r.add_audio(&prev);
|
||||||
}
|
}
|
||||||
drained.extend_from_slice(&chunk);
|
unsafe {
|
||||||
|
moonshine_transcribe_add_audio_to_stream(
|
||||||
|
handle, stream_handle,
|
||||||
|
prev.as_ptr(), prev.len() as u64,
|
||||||
|
SAMPLE_RATE, 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
held_chunk = Some(chunk);
|
||||||
}
|
}
|
||||||
Err(mpsc::RecvTimeoutError::Timeout) => break,
|
Err(mpsc::RecvTimeoutError::Timeout) => break,
|
||||||
Err(mpsc::RecvTimeoutError::Disconnected) => break,
|
Err(mpsc::RecvTimeoutError::Disconnected) => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply 5ms fade-out to the trailing edge of the drained audio.
|
// Apply 5ms fade-out to the last chunk, then feed to both Moonshine and recorder
|
||||||
// Both the debug WAV and Moonshine receive the same faded audio.
|
if let Some(mut chunk) = held_chunk.take() {
|
||||||
let fade_samples = (SAMPLE_RATE as usize * 5) / 1000;
|
let fade_samples = (SAMPLE_RATE as usize * 5) / 1000;
|
||||||
if drained.len() > fade_samples {
|
if chunk.len() > fade_samples {
|
||||||
let start = drained.len() - fade_samples;
|
let start = chunk.len() - fade_samples;
|
||||||
for i in 0..fade_samples {
|
for i in 0..fade_samples {
|
||||||
let t = 1.0 - (i as f32 / fade_samples as f32);
|
let t = 1.0 - (i as f32 / fade_samples as f32);
|
||||||
drained[start + i] *= t;
|
chunk[start + i] *= t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update recorder with the faded audio (replaces the raw versions added above)
|
|
||||||
if let Some(ref mut r) = recorder {
|
if let Some(ref mut r) = recorder {
|
||||||
// Remove the raw drained samples and re-add the faded ones
|
r.add_audio(&chunk);
|
||||||
let raw_drained_len = r.audio_len();
|
|
||||||
r.truncate_audio(raw_drained_len.saturating_sub(drained.len()));
|
|
||||||
r.add_audio(&drained);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !drained.is_empty() {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
moonshine_transcribe_add_audio_to_stream(
|
moonshine_transcribe_add_audio_to_stream(
|
||||||
handle, stream_handle,
|
handle, stream_handle,
|
||||||
drained.as_ptr(), drained.len() as u64,
|
chunk.as_ptr(), chunk.len() as u64,
|
||||||
SAMPLE_RATE, 0,
|
SAMPLE_RATE, 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user