Skip to content

Commit

Permalink
Fix buffer underrun soon after starting Alsa playback
Browse files Browse the repository at this point in the history
  • Loading branch information
HEnquist committed Sep 16, 2020
1 parent cf17ed5 commit c9fb5c8
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ New features:
Bugfixes:
- Fix websocket `exit` command.
- Correct response of `setconfigname` websocket command.
- Fix buffer underrun soon after starting Alsa playback.


## 0.3.1
Expand Down
21 changes: 14 additions & 7 deletions src/alsadevice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,22 +92,28 @@ struct PlaybackParams {
}

/// Play a buffer.
fn play_buffer(buffer: &[u8], pcmdevice: &alsa::PCM, io: &alsa::pcm::IO<u8>) -> Res<()> {
fn play_buffer(
buffer: &[u8],
pcmdevice: &alsa::PCM,
io: &alsa::pcm::IO<u8>,
target_delay: u64,
) -> Res<()> {
let playback_state = pcmdevice.state();
trace!("playback state {:?}", playback_state);
if playback_state == State::XRun {
warn!("Prepare playback");
warn!("Prepare playback after buffer underrun");
pcmdevice.prepare()?;
let delay = Duration::from_millis(5);
thread::sleep(delay);
thread::sleep(Duration::from_millis(target_delay));
} else if playback_state == State::Prepared {
warn!("Starting playback from Prepared state");
thread::sleep(Duration::from_millis(target_delay));
}
let _frames = match io.writei(&buffer[..]) {
Ok(frames) => frames,
Err(err) => {
warn!("Retrying playback, error: {}", err);
pcmdevice.prepare()?;
let delay = Duration::from_millis(5);
thread::sleep(delay);
thread::sleep(Duration::from_millis(target_delay));
io.writei(&buffer[..])?
}
};
Expand Down Expand Up @@ -204,6 +210,7 @@ fn playback_loop_bytes(
let mut speed;
let mut diff: isize;
let adjust = params.adjust_period > 0.0 && params.adjust_enabled;
let target_delay = 1000 * (params.target_level as u64) / srate as u64;
loop {
match channels.audio.recv() {
Ok(AudioMessage::Audio(chunk)) => {
Expand Down Expand Up @@ -245,7 +252,7 @@ fn playback_loop_bytes(
.unwrap();
}

let playback_res = play_buffer(&buffer, pcmdevice, &io);
let playback_res = play_buffer(&buffer, pcmdevice, &io, target_delay);
match playback_res {
Ok(_) => {}
Err(msg) => {
Expand Down

0 comments on commit c9fb5c8

Please sign in to comment.