Skip to content

Commit

Permalink
Merge pull request #101 from HEnquist/noblock
Browse files Browse the repository at this point in the history
Noblock
  • Loading branch information
HEnquist authored Apr 8, 2021
2 parents 5ffd961 + bc14de6 commit 9736ae9
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ New features:
- Add `debug` feature for extra logging.
- Improve validation of filters.
- Setting to enable retry on reads from Alsa capture devices.
- Avoid blocking reads on Alsa capture devices (helps avoiding driver bugs for some devices).

Bugfixes:
- Don't block playback for CoreAudio/Wasapi if there is no data in time.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "camilladsp"
version = "0.5.0"
version = "0.5.0-beta5"
authors = ["Henrik Enquist <[email protected]>"]
description = "A flexible tool for processing audio"

Expand Down
49 changes: 46 additions & 3 deletions src/alsadevice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,58 @@ fn play_buffer(
Ok(())
}

/// Play a buffer.
/// Capture a buffer.
fn capture_buffer(
buffer: &mut [u8],
pcmdevice: &alsa::PCM,
io: &alsa::pcm::IO<u8>,
retry: bool,
samplerate: usize,
frames_to_read: usize,
) -> Res<CaptureResult> {
let capture_state = pcmdevice.state();
if capture_state == State::XRun {
warn!("prepare capture");
warn!("Prepare capture device");
pcmdevice.prepare()?;
} else if capture_state != State::Running {
debug!("Starting capture");
pcmdevice.start()?;
}
let available = pcmdevice.avail();
match available {
Ok(frames) => {
if (frames as usize) < frames_to_read {
trace!(
"Not enough frames available: {}, need: {}, waiting...",
frames,
frames_to_read
);
// Let's wait for more frames, with 10% plus 1 ms of margin
thread::sleep(Duration::from_millis(
(1 + (1100 * (frames_to_read - frames as usize)) / samplerate) as u64,
));
if (pcmdevice.avail().unwrap_or(0) as usize) < frames_to_read {
// Still not enough,
warn!("Capture timed out, will try again");
return Ok(CaptureResult::RecoverableError);
}
}
}
Err(err) => {
if retry {
warn!("Capture failed while querying for available frames, error: {}, will try again.", err);
thread::sleep(Duration::from_millis(
(1000 * frames_to_read as u64) / samplerate as u64,
));
return Ok(CaptureResult::RecoverableError);
} else {
warn!(
"Capture failed while querying for available frames, error: {}",
err
);
return Err(Box::new(err));
}
}
}
let _frames = match io.readi(buffer) {
Ok(frames) => frames,
Expand All @@ -151,7 +192,7 @@ fn capture_buffer(
warn!("Capture failed with error: {}, will try again.", err);
return Ok(CaptureResult::RecoverableError);
} else {
warn!("Capture failed, error: {}", err);
warn!("Capture failed with error: {}", err);
return Err(Box::new(err));
}
}
Expand Down Expand Up @@ -397,6 +438,8 @@ fn capture_loop_bytes(
pcmdevice,
&io,
params.retry_on_error,
params.capture_samplerate,
capture_bytes / (params.channels * params.store_bytes_per_sample),
);
match capture_res {
Ok(CaptureResult::Normal) => {
Expand Down

0 comments on commit 9736ae9

Please sign in to comment.