refactor: resync with qbqt baseline and restore genre browser
Some checks failed
Build for Windows / build-windows (push) Has been cancelled
Some checks failed
Build for Windows / build-windows (push) Has been cancelled
This commit is contained in:
@@ -141,7 +141,7 @@ fn player_loop(rx: std::sync::mpsc::Receiver<PlayerCommand>, status: PlayerStatu
|
||||
match rx.recv_timeout(Duration::from_millis(100)) {
|
||||
Ok(PlayerCommand::Play(info)) => break info,
|
||||
Ok(PlayerCommand::QueueNext(info)) => {
|
||||
// If completely idle and get QueueNext, treat as Play
|
||||
// If we are completely idle and get QueueNext, treat as Play
|
||||
break info;
|
||||
}
|
||||
Ok(PlayerCommand::Stop) => {
|
||||
@@ -155,7 +155,7 @@ fn player_loop(rx: std::sync::mpsc::Receiver<PlayerCommand>, status: PlayerStatu
|
||||
Ok(PlayerCommand::SetVolume(v)) => {
|
||||
status.volume.store(v, Ordering::Relaxed);
|
||||
}
|
||||
Ok(_) => {}
|
||||
Ok(_) => {} // Ignore Pause/Resume when idle
|
||||
Err(RecvTimeoutError::Timeout) => {}
|
||||
Err(RecvTimeoutError::Disconnected) => break 'outer,
|
||||
}
|
||||
@@ -176,9 +176,11 @@ fn player_loop(rx: std::sync::mpsc::Receiver<PlayerCommand>, status: PlayerStatu
|
||||
status.position_secs.store(0, Ordering::Relaxed);
|
||||
paused.store(false, Ordering::SeqCst);
|
||||
|
||||
// TrackInfo now directly passes the prefetch_data (if it exists) to the decoder
|
||||
match decoder::play_track_inline(info, &status, &paused, &mut audio_output, &rx) {
|
||||
Ok(Some(NextAction::Play(next_track))) => {
|
||||
pending_action = Some(NextAction::Play(next_track));
|
||||
// Interrupted by a manual play, no need to tell C++ to advance the queue
|
||||
}
|
||||
Ok(Some(NextAction::Transition(next_track))) => {
|
||||
pending_action = Some(NextAction::Play(next_track));
|
||||
|
||||
@@ -3,7 +3,7 @@ use cpal::{
|
||||
traits::{DeviceTrait, HostTrait, StreamTrait},
|
||||
StreamConfig,
|
||||
};
|
||||
use rb::{RbConsumer, RbProducer, SpscRb, RB};
|
||||
use rb::{RbConsumer, RbInspector, RbProducer, SpscRb, RB};
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
@@ -13,6 +13,7 @@ use symphonia::core::audio::AudioBufferRef;
|
||||
const RING_BUFFER_SIZE: usize = 32 * 1024;
|
||||
|
||||
pub struct AudioOutput {
|
||||
_ring: SpscRb<f32>,
|
||||
ring_buf_producer: rb::Producer<f32>,
|
||||
_stream: cpal::Stream,
|
||||
pub sample_rate: u32,
|
||||
@@ -50,6 +51,7 @@ impl AudioOutput {
|
||||
stream.play()?;
|
||||
|
||||
Ok(Self {
|
||||
_ring: ring,
|
||||
ring_buf_producer: producer,
|
||||
_stream: stream,
|
||||
sample_rate,
|
||||
@@ -87,4 +89,13 @@ impl AudioOutput {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn flush(&self) {
|
||||
// Wait until the ring buffer is fully emptied by cpal
|
||||
while !self._ring.is_empty() {
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
}
|
||||
// Give the physical DAC an extra 100ms to output the last samples
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user