Skip to content

Commit

Permalink
core: Add simple stereo mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
jpochyla committed Nov 27, 2021
1 parent a572cce commit a774653
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
6 changes: 6 additions & 0 deletions psst-core/src/audio/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl AudioOutput {
move |this| Stream::open(device, config, callback_recv, this).unwrap()
});
let sink = AudioSink {
channel_count: supported.channels(),
sample_rate: supported.sample_rate(),
stream_send: handle.sender(),
callback_send,
Expand Down Expand Up @@ -75,12 +76,17 @@ impl AudioOutput {

#[derive(Clone)]
pub struct AudioSink {
channel_count: cpal::ChannelCount,
sample_rate: cpal::SampleRate,
callback_send: Sender<CallbackMsg>,
stream_send: Sender<StreamMsg>,
}

impl AudioSink {
pub fn channel_count(&self) -> usize {
self.channel_count as usize
}

pub fn sample_rate(&self) -> u32 {
self.sample_rate.0
}
Expand Down
45 changes: 45 additions & 0 deletions psst-core/src/audio/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,48 @@ impl AudioSource for Empty {
0
}
}

pub struct StereoMapper<S> {
source: S,
input_channels: usize,
output_channels: usize,
buffer: Vec<f32>,
}

impl<S> StereoMapper<S> {
pub fn new(
source: S,
input_channels: usize,
output_channels: usize,
max_input_size: usize,
) -> Self {
Self {
source,
input_channels,
output_channels,
buffer: vec![0.0; (max_input_size / input_channels) * output_channels],
}
}

fn input_size(&mut self, output_size: usize) -> usize {
(output_size / self.output_channels) * self.input_channels
}
}

impl<S> AudioSource for StereoMapper<S>
where
S: AudioSource,
{
fn write(&mut self, output: &mut [f32]) -> usize {
let input_max = self.input_size(output.len()).min(self.buffer.len());
let written = self.source.write(&mut self.buffer[..input_max]);
let input = &self.buffer[..written];
let input_frames = input.chunks_exact(self.input_channels);
let output_frames = output.chunks_exact_mut(self.output_channels);
for (i, o) in input_frames.zip(output_frames) {
o[0] = i[0];
o[1] = i[1];
}
output.len()
}
}
13 changes: 9 additions & 4 deletions psst-core/src/player/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::{
decode::AudioDecoder,
output::AudioSink,
resample::{AudioResampler, ResamplingQuality, ResamplingSpec},
source::AudioSource,
source::{AudioSource, StereoMapper},
},
error::Error,
};
Expand All @@ -47,9 +47,14 @@ impl PlaybackManager {

pub fn play(&mut self, loaded: LoadedPlaybackItem) {
let path = loaded.file.path();
let source = DecoderSource::new(loaded, self.event_send.clone(), self.sink.sample_rate());
self.current = Some((path, source.actor.sender()));
self.sink.play(source);
let decoder = DecoderSource::new(loaded, self.event_send.clone(), self.sink.sample_rate());
self.current = Some((path, decoder.actor.sender()));
self.sink.play(StereoMapper::new(
decoder,
2,
self.sink.channel_count(),
8 * 1024,
));
self.sink.resume();
}

Expand Down

0 comments on commit a774653

Please sign in to comment.