Struct spectrusty_audio::carousel::AudioFrameConsumer
source · pub struct AudioFrameConsumer<T> { /* private fields */ }
Expand description
Relays AudioBuffer samples to the audio framework output buffers.
Implementations§
source§impl<T> AudioFrameConsumer<T>
impl<T> AudioFrameConsumer<T>
sourcepub fn new(
buffer: AudioBuffer<T>,
producer_tx: Sender<AudioBuffer<T>>,
consumer_rx: Receiver<AudioBuffer<T>>
) -> Self
pub fn new(
buffer: AudioBuffer<T>,
producer_tx: Sender<AudioBuffer<T>>,
consumer_rx: Receiver<AudioBuffer<T>>
) -> Self
Creates a new instance of AudioFrameConsumer
.
Prefer to use create_carousel instead.
Examples found in repository?
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
pub fn create_carousel<T>(latency: usize, sample_frames: usize, channels: u8) ->
(AudioFrameProducer<T>, AudioFrameConsumer<T>)
where T: 'static + AudioSample + Send
{
// let sample_frames = (sample_rate as f64 * frame_duration).ceil() as usize;
let buffer = AudioBuffer::<T>::new(sample_frames, channels);
let (producer_tx, producer_rx) = channel::<AudioBuffer<T>>();
let (consumer_tx, consumer_rx) = channel::<AudioBuffer<T>>();
// if latency > 0 {
// Add some frame buffers into circulation
// for _ in 0..latency {
producer_tx.send(buffer.clone()).unwrap(); // infallible
// }
for _ in 0..latency {
consumer_tx.send(buffer.clone()).unwrap(); // infallible
}
// }
// }
let producer = AudioFrameProducer::new(buffer.clone(), consumer_tx, producer_rx);
let consumer = AudioFrameConsumer::new(buffer, producer_tx, consumer_rx);
(producer, consumer)
}
sourcepub fn reset_cursor(&mut self)
pub fn reset_cursor(&mut self)
Resets the audio buffer sample cursor.
source§impl<T: 'static + Copy + Send> AudioFrameConsumer<T>
impl<T: 'static + Copy + Send> AudioFrameConsumer<T>
sourcepub fn next_frame(&mut self) -> AudioFrameResult<bool>
pub fn next_frame(&mut self) -> AudioFrameResult<bool>
Attempts to receive the next audio frame from the AudioFrameProducer.
When Ok(true)
is returned replaces the current frame buffer with the one received
and sends back the current one.
If there is no new buffer waiting in the message queue returns Ok(false)
.
Returns Err(AudioFrameError)
only when sending or receiving buffers failed,
which is possible only when the remote end has disconnected.
Examples found in repository?
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
pub fn fill_buffer<'a>(
&mut self,
mut target_buffer: &'a mut[T],
ignore_missing: bool
) -> AudioFrameResult<&'a mut[T]>
{
let mut cursor = self.cursor;
while !target_buffer.is_empty() {
if cursor >= self.buffer.sampled_size() {
if !(self.next_frame()? || ignore_missing) {
break
}
cursor = 0;
}
// print!("{:?} ", self.buffer.as_ptr());
let copied_size = self.buffer.copy_to(target_buffer, cursor);
cursor += copied_size;
target_buffer = &mut target_buffer[copied_size..];
}
self.cursor = cursor;
Ok(target_buffer)
}
sourcepub fn current_frame(&self) -> &[T] ⓘ
pub fn current_frame(&self) -> &[T] ⓘ
Exposes the last received frame buffer as a slice of samples.
sourcepub fn fill_buffer<'a>(
&mut self,
target_buffer: &'a mut [T],
ignore_missing: bool
) -> AudioFrameResult<&'a mut [T]>
pub fn fill_buffer<'a>(
&mut self,
target_buffer: &'a mut [T],
ignore_missing: bool
) -> AudioFrameResult<&'a mut [T]>
Fills the target_buffer
with the received audio frame samples.
Attempts to receive new frame buffers when necessary, repeating the process until the whole buffer is filled or when there are no more buffers waiting in the incoming queue.
Returns the unfilled part of the target buffer in case there were no more frames to receive
and ignore_missing
was false
.
Returns an empty slice if the whole buffer has been filled.
In case ignore_missing
is true
the last audio frame will be rendered again if there are
no more new buffers in the queue.
Returns Err(AudioFrameError)
only when sending or receiving buffers failed,
which is possible only when the remote end has disconnected.
Examples found in repository?
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
fn callback(&mut self, out: &mut [T]) {
match self.0.fill_buffer(out, false) {
Ok(unfilled) => {
if !unfilled.is_empty() {
for t in unfilled {
*t = T::SILENCE
}
debug!("missing buffer");
}
}
Err(_) => {
error!("fatal: producer terminated");
}
}
}
More examples
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
pub fn create_with_device_and_config(
device: &cpal::Device,
config: &cpal::StreamConfig,
frame_duration_nanos: u32,
latency: usize,
) -> Result<Self, AudioHandleError>
{
let channels: u8 = config.channels.try_into()
.map_err(|_| (format!("number of channels: {} exceed the maximum value of 255", config.channels),
AudioHandleErrorKind::InvalidArguments))?;
let sample_rate = config.sample_rate.0;
let frame_duration_secs = Duration::from_nanos(frame_duration_nanos.into()).as_secs_f64();
let audio_frame_samples = (sample_rate as f64 * frame_duration_secs).ceil() as usize;
debug!("audio specs: {:?}", config);
debug!("audio frame samples: {} latency: {}", audio_frame_samples, latency);
let (producer, mut consumer) = create_carousel::<T>(latency, audio_frame_samples, channels);
let data_fn = move |out: &mut [T], _: &_| match consumer.fill_buffer(out, false) {
Ok(unfilled) => {
if !unfilled.is_empty() {
for t in unfilled {
*t = T::silence()
}
debug!("missing buffer");
}
}
Err(_) => {
error!("fatal: producer terminated");
}
};
let err_fn = |err| error!("an error occurred on stream: {}", err);
let stream = device.build_output_stream(config, data_fn, err_fn)?;
Ok(AudioHandle {
sample_rate,
channels,
producer,
stream
})
}
Trait Implementations§
Auto Trait Implementations§
impl<T> RefUnwindSafe for AudioFrameConsumer<T>where
T: RefUnwindSafe,
impl<T> Send for AudioFrameConsumer<T>where
T: Send,
impl<T> !Sync for AudioFrameConsumer<T>
impl<T> Unpin for AudioFrameConsumer<T>where
T: Unpin,
impl<T> UnwindSafe for AudioFrameConsumer<T>where
T: UnwindSafe,
Blanket Implementations§
source§impl<S, T> IntoSample<S> for Twhere
S: FromSample<T>,
impl<S, T> IntoSample<S> for Twhere
S: FromSample<T>,
source§fn into_sample(self) -> S
fn into_sample(self) -> S
S
a sample type from self
.