feat: show top tracks on artist profile with play/shuffle
- Adds extra=topTracks to artist/page API request - Embeds a List::Tracks widget at the top of ArtistView showing the artist's most popular tracks, with Play and Shuffle buttons - Bubbles playTrackRequested through MainContent up to MainWindow - Also adds the viz PCM ring buffer FFI infrastructure (for future spectrum widget) to the Rust backend Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,7 @@ const RING_BUFFER_SIZE: usize = 32 * 1024;
|
||||
|
||||
pub struct AudioOutput {
|
||||
ring_buf_producer: rb::Producer<f32>,
|
||||
viz_producer: Option<rb::Producer<f32>>,
|
||||
_stream: cpal::Stream,
|
||||
pub sample_rate: u32,
|
||||
pub channels: usize,
|
||||
@@ -51,12 +52,17 @@ impl AudioOutput {
|
||||
|
||||
Ok(Self {
|
||||
ring_buf_producer: producer,
|
||||
viz_producer: None,
|
||||
_stream: stream,
|
||||
sample_rate,
|
||||
channels,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_viz_producer(&mut self, producer: rb::Producer<f32>) {
|
||||
self.viz_producer = Some(producer);
|
||||
}
|
||||
|
||||
pub fn write(
|
||||
&mut self,
|
||||
decoded: AudioBufferRef<'_>,
|
||||
@@ -70,6 +76,11 @@ impl AudioOutput {
|
||||
sample_buf.copy_interleaved_ref(decoded);
|
||||
let samples: Vec<f32> = sample_buf.samples().iter().map(|s| s * volume).collect();
|
||||
|
||||
// Best-effort copy for visualizer (non-blocking, ok to drop samples)
|
||||
if let Some(ref mut viz) = self.viz_producer {
|
||||
let _ = viz.write(&samples);
|
||||
}
|
||||
|
||||
let mut remaining = &samples[..];
|
||||
while !remaining.is_empty() {
|
||||
if stop.load(Ordering::SeqCst) {
|
||||
|
||||
Reference in New Issue
Block a user