Merge pull request #395 from mitchmindtree/callback_info

Add a `CallbackInfo` argument to the stream data callback
This commit is contained in:
mitchmindtree 2020-04-27 14:32:37 +02:00 committed by GitHub
commit f032557fb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 123 additions and 109 deletions

View File

@ -4,11 +4,11 @@ on: [push, pull_request]
jobs:
clippy-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Update apt
run: sudo apt update
- name: Install alsa
run: sudo apt-get install libasound2-dev
- name: Install stable
@ -27,7 +27,7 @@ jobs:
rustfmt-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Install stable
uses: actions-rs/toolchain@v1
with:
@ -42,16 +42,14 @@ jobs:
args: --all -- --check
cargo-publish:
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
env:
CRATESIO_TOKEN: ${{ secrets.CRATESIO_TOKEN }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Update apt
run: sudo apt update
- name: Install alsa
run: sudo apt-get install libasound2-dev
- name: Run cargo publish for cpal
@ -68,11 +66,11 @@ jobs:
[ $empty -eq 1 ] || grep -q "is already uploaded" < $CPAL_TMP
ubuntu-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Update apt
run: sudo apt update
- name: Install alsa
run: sudo apt-get install libasound2-dev
- name: Install stable
@ -93,15 +91,12 @@ jobs:
args: --all --all-features --verbose
asmjs-wasm32-test:
strategy:
matrix:
target: [asmjs-unknown-emscripten, wasm32-unknown-emscripten]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Install emscripten
run: sudo apt-get install emscripten
- name: Install stable
@ -114,15 +109,12 @@ jobs:
run: cargo build --example beep --target ${{ matrix.target }}
windows-test:
strategy:
matrix:
version: [x86_64, i686]
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Install ASIO SDK
env:
LINK: https://www.steinberg.net/asiosdk
@ -150,9 +142,8 @@ jobs:
macos-test:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Install llvm and clang
run: brew install llvm
- name: Install stable

View File

@ -17,6 +17,8 @@
- Added `build_input/output_stream_raw` methods allowing for dynamically
handling sample format type.
- Added support for DragonFly platform.
- Add `InputCallbackInfo` and `OutputCallbackInfo` types and update expected
user data callback function signature to provide these.
# Version 0.11.0 (2019-12-11)

View File

@ -37,7 +37,9 @@ where
let stream = device.build_output_stream(
config,
move |data: &mut [T]| write_data(data, channels, &mut next_value),
move |data: &mut [T], _: &cpal::OutputCallbackInfo| {
write_data(data, channels, &mut next_value)
},
err_fn,
)?;
stream.play()?;

View File

@ -46,7 +46,7 @@ fn main() -> Result<(), anyhow::Error> {
producer.push(0.0).unwrap();
}
let input_data_fn = move |data: &[f32]| {
let input_data_fn = move |data: &[f32], _: &cpal::InputCallbackInfo| {
let mut output_fell_behind = false;
for &sample in data {
if producer.push(sample).is_err() {
@ -58,7 +58,7 @@ fn main() -> Result<(), anyhow::Error> {
}
};
let output_data_fn = move |data: &mut [f32]| {
let output_data_fn = move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
let mut input_fell_behind = None;
for sample in data {
*sample = match consumer.pop() {

View File

@ -43,17 +43,17 @@ fn main() -> Result<(), anyhow::Error> {
let stream = match config.sample_format() {
cpal::SampleFormat::F32 => device.build_input_stream(
&config.into(),
move |data| write_input_data::<f32, f32>(data, &writer_2),
move |data, _: &_| write_input_data::<f32, f32>(data, &writer_2),
err_fn,
)?,
cpal::SampleFormat::I16 => device.build_input_stream(
&config.into(),
move |data| write_input_data::<i16, i16>(data, &writer_2),
move |data, _: &_| write_input_data::<i16, i16>(data, &writer_2),
err_fn,
)?,
cpal::SampleFormat::U16 => device.build_input_stream(
&config.into(),
move |data| write_input_data::<u16, i16>(data, &writer_2),
move |data, _: &_| write_input_data::<u16, i16>(data, &writer_2),
err_fn,
)?,
};

View File

@ -4,9 +4,9 @@ extern crate libc;
use self::alsa::poll::Descriptors;
use crate::{
BackendSpecificError, BuildStreamError, ChannelCount, Data, DefaultStreamConfigError,
DeviceNameError, DevicesError, PauseStreamError, PlayStreamError, SampleFormat, SampleRate,
StreamConfig, StreamError, SupportedStreamConfig, SupportedStreamConfigRange,
SupportedStreamConfigsError,
DeviceNameError, DevicesError, InputCallbackInfo, OutputCallbackInfo, PauseStreamError,
PlayStreamError, SampleFormat, SampleRate, StreamConfig, StreamError, SupportedStreamConfig,
SupportedStreamConfigRange, SupportedStreamConfigsError,
};
use std::sync::Arc;
use std::thread::{self, JoinHandle};
@ -90,7 +90,7 @@ impl DeviceTrait for Device {
error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&Data) + Send + 'static,
D: FnMut(&Data, &InputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
let stream_inner =
@ -107,7 +107,7 @@ impl DeviceTrait for Device {
error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&mut Data) + Send + 'static,
D: FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
let stream_inner =
@ -464,7 +464,7 @@ struct StreamWorkerContext {
fn input_stream_worker(
rx: TriggerReceiver,
stream: &StreamInner,
data_callback: &mut (dyn FnMut(&Data) + Send + 'static),
data_callback: &mut (dyn FnMut(&Data, &InputCallbackInfo) + Send + 'static),
error_callback: &mut (dyn FnMut(StreamError) + Send + 'static),
) {
let mut ctxt = StreamWorkerContext::default();
@ -499,7 +499,7 @@ fn input_stream_worker(
fn output_stream_worker(
rx: TriggerReceiver,
stream: &StreamInner,
data_callback: &mut (dyn FnMut(&mut Data) + Send + 'static),
data_callback: &mut (dyn FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static),
error_callback: &mut (dyn FnMut(StreamError) + Send + 'static),
) {
let mut ctxt = StreamWorkerContext::default();
@ -636,14 +636,15 @@ fn poll_descriptors_and_prepare_buffer(
fn process_input(
stream: &StreamInner,
buffer: &mut [u8],
data_callback: &mut (dyn FnMut(&Data) + Send + 'static),
data_callback: &mut (dyn FnMut(&Data, &InputCallbackInfo) + Send + 'static),
) -> Result<(), BackendSpecificError> {
stream.channel.io().readi(buffer)?;
let sample_format = stream.sample_format;
let data = buffer.as_mut_ptr() as *mut ();
let len = buffer.len() / sample_format.sample_size();
let data = unsafe { Data::from_parts(data, len, sample_format) };
data_callback(&data);
let info = crate::InputCallbackInfo {};
data_callback(&data, &info);
Ok(())
}
@ -655,7 +656,7 @@ fn process_output(
stream: &StreamInner,
buffer: &mut [u8],
available_frames: usize,
data_callback: &mut (dyn FnMut(&mut Data) + Send + 'static),
data_callback: &mut (dyn FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static),
error_callback: &mut dyn FnMut(StreamError),
) {
{
@ -664,7 +665,8 @@ fn process_output(
let data = buffer.as_mut_ptr() as *mut ();
let len = buffer.len() / sample_format.sample_size();
let mut data = unsafe { Data::from_parts(data, len, sample_format) };
data_callback(&mut data);
let info = crate::OutputCallbackInfo {};
data_callback(&mut data, &info);
}
loop {
match stream.channel.io().writei(buffer) {
@ -700,7 +702,7 @@ impl Stream {
mut error_callback: E,
) -> Stream
where
D: FnMut(&Data) + Send + 'static,
D: FnMut(&Data, &InputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
let (tx, rx) = trigger();
@ -722,7 +724,7 @@ impl Stream {
mut error_callback: E,
) -> Stream
where
D: FnMut(&mut Data) + Send + 'static,
D: FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
let (tx, rx) = trigger();

View File

@ -3,8 +3,8 @@ extern crate parking_lot;
use crate::{
BuildStreamError, Data, DefaultStreamConfigError, DeviceNameError, DevicesError,
PauseStreamError, PlayStreamError, SampleFormat, StreamConfig, StreamError,
SupportedStreamConfig, SupportedStreamConfigsError,
InputCallbackInfo, OutputCallbackInfo, PauseStreamError, PlayStreamError, SampleFormat,
StreamConfig, StreamError, SupportedStreamConfig, SupportedStreamConfigsError,
};
use traits::{DeviceTrait, HostTrait, StreamTrait};
@ -90,7 +90,7 @@ impl DeviceTrait for Device {
error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&Data) + Send + 'static,
D: FnMut(&Data, &InputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
Device::build_input_stream_raw(self, config, sample_format, data_callback, error_callback)
@ -104,7 +104,7 @@ impl DeviceTrait for Device {
error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&mut Data) + Send + 'static,
D: FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
Device::build_output_stream_raw(self, config, sample_format, data_callback, error_callback)

View File

@ -4,19 +4,14 @@ extern crate num_traits;
use self::num_traits::PrimInt;
use super::parking_lot::Mutex;
use super::Device;
use crate::{
BackendSpecificError, BuildStreamError, Data, InputCallbackInfo, OutputCallbackInfo,
PauseStreamError, PlayStreamError, Sample, SampleFormat, StreamConfig, StreamError,
SupportedStreamConfig,
};
use std;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use BackendSpecificError;
use BuildStreamError;
use Data;
use PauseStreamError;
use PlayStreamError;
use Sample;
use SampleFormat;
use StreamConfig;
use StreamError;
use SupportedStreamConfig;
/// Sample types whose constant silent value is known.
trait Silence {
@ -66,7 +61,7 @@ impl Device {
_error_callback: E,
) -> Result<Stream, BuildStreamError>
where
D: FnMut(&Data) + Send + 'static,
D: FnMut(&Data, &InputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
let stream_type = self.driver.input_data_type().map_err(build_stream_err)?;
@ -116,7 +111,7 @@ impl Device {
) where
A: AsioSample,
B: Sample,
D: FnMut(&Data) + Send + 'static,
D: FnMut(&Data, &InputCallbackInfo) + Send + 'static,
F: Fn(A) -> A,
{
// 1. Write the ASIO channels to the CPAL buffer.
@ -133,7 +128,8 @@ impl Device {
let data = interleaved.as_mut_ptr() as *mut ();
let len = interleaved.len();
let data = Data::from_parts(data, len, B::FORMAT);
callback(&data);
let info = InputCallbackInfo {};
callback(&data, &info);
}
match (&stream_type, sample_format) {
@ -233,7 +229,7 @@ impl Device {
_error_callback: E,
) -> Result<Stream, BuildStreamError>
where
D: FnMut(&mut Data) + Send + 'static,
D: FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
let stream_type = self.driver.output_data_type().map_err(build_stream_err)?;
@ -307,7 +303,7 @@ impl Device {
) where
A: Sample,
B: AsioSample,
D: FnMut(&mut Data) + Send + 'static,
D: FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static,
F: Fn(B) -> B,
{
// 1. Render interleaved buffer from callback.
@ -315,7 +311,8 @@ impl Device {
let data = interleaved.as_mut_ptr() as *mut ();
let len = interleaved.len();
let mut data = Data::from_parts(data, len, A::FORMAT);
callback(&mut data);
let info = OutputCallbackInfo {};
callback(&mut data, &info);
// 2. Silence ASIO channels if necessary.
let n_channels = interleaved.len() / asio_stream.buffer_size as usize;

View File

@ -21,9 +21,9 @@ use self::coreaudio::sys::{
use crate::traits::{DeviceTrait, HostTrait, StreamTrait};
use crate::{
BackendSpecificError, BuildStreamError, ChannelCount, Data, DefaultStreamConfigError,
DeviceNameError, DevicesError, PauseStreamError, PlayStreamError, SampleFormat, SampleRate,
StreamConfig, StreamError, SupportedStreamConfig, SupportedStreamConfigRange,
SupportedStreamConfigsError,
DeviceNameError, DevicesError, InputCallbackInfo, OutputCallbackInfo, PauseStreamError,
PlayStreamError, SampleFormat, SampleRate, StreamConfig, StreamError, SupportedStreamConfig,
SupportedStreamConfigRange, SupportedStreamConfigsError,
};
use std::cell::RefCell;
use std::ffi::CStr;
@ -111,7 +111,7 @@ impl DeviceTrait for Device {
error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&Data) + Send + 'static,
D: FnMut(&Data, &InputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
Device::build_input_stream_raw(self, config, sample_format, data_callback, error_callback)
@ -125,7 +125,7 @@ impl DeviceTrait for Device {
error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&mut Data) + Send + 'static,
D: FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
Device::build_output_stream_raw(self, config, sample_format, data_callback, error_callback)
@ -486,7 +486,7 @@ impl Device {
_error_callback: E,
) -> Result<Stream, BuildStreamError>
where
D: FnMut(&Data) + Send + 'static,
D: FnMut(&Data, &InputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
// The scope and element for working with a device's input stream.
@ -653,7 +653,8 @@ impl Device {
let data = data as *mut ();
let len = (data_byte_size as usize / bytes_per_channel) as usize;
let data = Data::from_parts(data, len, sample_format);
data_callback(&data);
let info = InputCallbackInfo {};
data_callback(&data, &info);
Ok(())
})?;
@ -674,7 +675,7 @@ impl Device {
_error_callback: E,
) -> Result<Stream, BuildStreamError>
where
D: FnMut(&mut Data) + Send + 'static,
D: FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
let mut audio_unit = audio_unit_from_device(self, false)?;
@ -704,7 +705,8 @@ impl Device {
let data = data as *mut ();
let len = (data_byte_size as usize / bytes_per_channel) as usize;
let mut data = Data::from_parts(data, len, sample_format);
data_callback(&mut data);
let info = OutputCallbackInfo {};
data_callback(&mut data, &info);
Ok(())
})?;

View File

@ -9,8 +9,9 @@ use stdweb::Reference;
use crate::{
BuildStreamError, Data, DefaultStreamConfigError, DeviceNameError, DevicesError,
PauseStreamError, PlayStreamError, SampleFormat, StreamConfig, StreamError,
SupportedStreamConfig, SupportedStreamConfigRange, SupportedStreamConfigsError,
InputCallbackInfo, OutputCallbackInfo, PauseStreamError, PlayStreamError, SampleFormat,
StreamConfig, StreamError, SupportedStreamConfig, SupportedStreamConfigRange,
SupportedStreamConfigsError,
};
use traits::{DeviceTrait, HostTrait, StreamTrait};
@ -160,7 +161,7 @@ impl DeviceTrait for Device {
_error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&Data) + Send + 'static,
D: FnMut(&Data, &InputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
unimplemented!()
@ -174,7 +175,7 @@ impl DeviceTrait for Device {
error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&mut Data) + Send + 'static,
D: FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
assert_eq!(
@ -224,7 +225,7 @@ impl StreamTrait for Stream {
// and to the `callback` parameter that was passed to `run`.
fn audio_callback_fn<D, E>(user_data_ptr: *mut c_void)
where
D: FnMut(&mut Data) + Send + 'static,
D: FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
unsafe {
@ -241,7 +242,8 @@ where
let data = temporary_buffer.as_mut_ptr() as *mut ();
let sample_format = SampleFormat::F32;
let mut data = Data::from_parts(data, len, sample_format);
data_cb(&mut data);
let info = OutputCallbackInfo {};
data_cb(&mut data, &info);
}
// TODO: directly use a TypedArray<f32> once this is supported by stdweb

View File

@ -1,7 +1,8 @@
use crate::{
BuildStreamError, Data, DefaultStreamConfigError, DeviceNameError, DevicesError,
PauseStreamError, PlayStreamError, SampleFormat, StreamConfig, StreamError,
SupportedStreamConfig, SupportedStreamConfigRange, SupportedStreamConfigsError,
InputCallbackInfo, OutputCallbackInfo, PauseStreamError, PlayStreamError, SampleFormat,
StreamConfig, StreamError, SupportedStreamConfig, SupportedStreamConfigRange,
SupportedStreamConfigsError,
};
use traits::{DeviceTrait, HostTrait, StreamTrait};
@ -74,7 +75,7 @@ impl DeviceTrait for Device {
_error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&Data) + Send + 'static,
D: FnMut(&Data, &InputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
unimplemented!()
@ -89,7 +90,7 @@ impl DeviceTrait for Device {
_error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&mut Data) + Send + 'static,
D: FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
unimplemented!()

View File

@ -1,7 +1,8 @@
use crate::{
BackendSpecificError, Data, DefaultStreamConfigError, DeviceNameError, DevicesError,
SampleFormat, SampleRate, StreamConfig, SupportedStreamConfig, SupportedStreamConfigRange,
SupportedStreamConfigsError, COMMON_SAMPLE_RATES,
InputCallbackInfo, OutputCallbackInfo, SampleFormat, SampleRate, StreamConfig,
SupportedStreamConfig, SupportedStreamConfigRange, SupportedStreamConfigsError,
COMMON_SAMPLE_RATES,
};
use std;
use std::ffi::OsString;
@ -104,7 +105,7 @@ impl DeviceTrait for Device {
error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&Data) + Send + 'static,
D: FnMut(&Data, &InputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
let stream_inner = self.build_input_stream_raw_inner(config, sample_format)?;
@ -123,7 +124,7 @@ impl DeviceTrait for Device {
error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&mut Data) + Send + 'static,
D: FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
let stream_inner = self.build_output_stream_raw_inner(config, sample_format)?;

View File

@ -8,7 +8,8 @@ use super::winapi::um::winbase;
use super::winapi::um::winnt;
use crate::traits::StreamTrait;
use crate::{
BackendSpecificError, Data, PauseStreamError, PlayStreamError, SampleFormat, StreamError,
BackendSpecificError, Data, InputCallbackInfo, OutputCallbackInfo, PauseStreamError,
PlayStreamError, SampleFormat, StreamError,
};
use std::mem;
use std::ptr;
@ -83,7 +84,7 @@ impl Stream {
mut error_callback: E,
) -> Stream
where
D: FnMut(&Data) + Send + 'static,
D: FnMut(&Data, &InputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
let pending_scheduled_event =
@ -112,7 +113,7 @@ impl Stream {
mut error_callback: E,
) -> Stream
where
D: FnMut(&mut Data) + Send + 'static,
D: FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
let pending_scheduled_event =
@ -277,7 +278,7 @@ fn stream_error_from_hresult(hresult: winnt::HRESULT) -> Result<(), StreamError>
fn run_input(
mut run_ctxt: RunContext,
data_callback: &mut dyn FnMut(&Data),
data_callback: &mut dyn FnMut(&Data, &InputCallbackInfo),
error_callback: &mut dyn FnMut(StreamError),
) {
loop {
@ -304,7 +305,7 @@ fn run_input(
fn run_output(
mut run_ctxt: RunContext,
data_callback: &mut dyn FnMut(&mut Data),
data_callback: &mut dyn FnMut(&mut Data, &OutputCallbackInfo),
error_callback: &mut dyn FnMut(StreamError),
) {
loop {
@ -370,7 +371,7 @@ fn process_commands_and_await_signal(
fn process_input(
stream: &StreamInner,
capture_client: *mut audioclient::IAudioCaptureClient,
data_callback: &mut dyn FnMut(&Data),
data_callback: &mut dyn FnMut(&Data, &InputCallbackInfo),
error_callback: &mut dyn FnMut(StreamError),
) -> ControlFlow {
let mut frames_available = 0;
@ -409,7 +410,8 @@ fn process_input(
let len = frames_available as usize * stream.bytes_per_frame as usize
/ stream.sample_format.sample_size();
let data = Data::from_parts(data, len, stream.sample_format);
data_callback(&data);
let info = InputCallbackInfo {};
data_callback(&data, &info);
// Release the buffer.
let hresult = (*capture_client).ReleaseBuffer(frames_available);
@ -425,7 +427,7 @@ fn process_input(
fn process_output(
stream: &StreamInner,
render_client: *mut audioclient::IAudioRenderClient,
data_callback: &mut dyn FnMut(&mut Data),
data_callback: &mut dyn FnMut(&mut Data, &OutputCallbackInfo),
error_callback: &mut dyn FnMut(StreamError),
) -> ControlFlow {
// The number of frames available for writing.
@ -453,7 +455,8 @@ fn process_output(
let len = frames_available as usize * stream.bytes_per_frame as usize
/ stream.sample_format.sample_size();
let mut data = Data::from_parts(data, len, stream.sample_format);
data_callback(&mut data);
let info = OutputCallbackInfo {};
data_callback(&mut data, &info);
let hresult = (*render_client).ReleaseBuffer(frames_available as u32, 0);
if let Err(err) = stream_error_from_hresult(hresult) {

View File

@ -63,7 +63,7 @@
//! # let config = device.default_output_config().unwrap().into();
//! let stream = device.build_output_stream(
//! &config,
//! move |data: &mut [f32]| {
//! move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
//! // react to stream events and read or write stream data here.
//! },
//! move |err| {
@ -102,7 +102,7 @@
//! SampleFormat::U16 => device.build_output_stream(&config, write_silence::<u16>, err_fn),
//! }.unwrap();
//!
//! fn write_silence<T: Sample>(data: &mut [T]) {
//! fn write_silence<T: Sample>(data: &mut [T], _: &cpal::OutputCallbackInfo) {
//! for sample in data.iter_mut() {
//! *sample = Sample::from(&0.0);
//! }
@ -119,7 +119,7 @@
//! # let supported_config = device.default_output_config().unwrap();
//! # let sample_format = supported_config.sample_format();
//! # let config = supported_config.into();
//! # let data_fn = move |_data: &mut cpal::Data| {};
//! # let data_fn = move |_data: &mut cpal::Data, _: &cpal::OutputCallbackInfo| {};
//! # let err_fn = move |_err| {};
//! # let stream = device.build_output_stream_raw(&config, sample_format, data_fn, err_fn).unwrap();
//! stream.play().unwrap();
@ -135,7 +135,7 @@
//! # let supported_config = device.default_output_config().unwrap();
//! # let sample_format = supported_config.sample_format();
//! # let config = supported_config.into();
//! # let data_fn = move |_data: &mut cpal::Data| {};
//! # let data_fn = move |_data: &mut cpal::Data, _: &cpal::OutputCallbackInfo| {};
//! # let err_fn = move |_err| {};
//! # let stream = device.build_output_stream_raw(&config, sample_format, data_fn, err_fn).unwrap();
//! stream.pause().unwrap();
@ -220,6 +220,14 @@ pub struct Data {
sample_format: SampleFormat,
}
/// Information relevant to a single call to the user's output stream data callback.
#[derive(Debug, Clone, PartialEq)]
pub struct OutputCallbackInfo {}
/// Information relevant to a single call to the user's input stream data callback.
#[derive(Debug, Clone, PartialEq)]
pub struct InputCallbackInfo {}
impl SupportedStreamConfig {
pub fn channels(&self) -> ChannelCount {
self.channels

View File

@ -263,7 +263,7 @@ macro_rules! impl_platform_host {
error_callback: E,
) -> Result<Self::Stream, crate::BuildStreamError>
where
D: FnMut(&crate::Data) + Send + 'static,
D: FnMut(&crate::Data, &crate::InputCallbackInfo) + Send + 'static,
E: FnMut(crate::StreamError) + Send + 'static,
{
match self.0 {
@ -289,7 +289,7 @@ macro_rules! impl_platform_host {
error_callback: E,
) -> Result<Self::Stream, crate::BuildStreamError>
where
D: FnMut(&mut crate::Data) + Send + 'static,
D: FnMut(&mut crate::Data, &crate::OutputCallbackInfo) + Send + 'static,
E: FnMut(crate::StreamError) + Send + 'static,
{
match self.0 {

View File

@ -1,9 +1,10 @@
//! The suite of traits allowing CPAL to abstract over hosts, devices, event loops and stream IDs.
use {
BuildStreamError, Data, DefaultStreamConfigError, DeviceNameError, DevicesError, InputDevices,
OutputDevices, PauseStreamError, PlayStreamError, Sample, SampleFormat, StreamConfig,
StreamError, SupportedStreamConfig, SupportedStreamConfigRange, SupportedStreamConfigsError,
BuildStreamError, Data, DefaultStreamConfigError, DeviceNameError, DevicesError,
InputCallbackInfo, InputDevices, OutputCallbackInfo, OutputDevices, PauseStreamError,
PlayStreamError, Sample, SampleFormat, StreamConfig, StreamError, SupportedStreamConfig,
SupportedStreamConfigRange, SupportedStreamConfigsError,
};
/// A **Host** provides access to the available audio devices on the system.
@ -122,16 +123,17 @@ pub trait DeviceTrait {
) -> Result<Self::Stream, BuildStreamError>
where
T: Sample,
D: FnMut(&[T]) + Send + 'static,
D: FnMut(&[T], &InputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
self.build_input_stream_raw(
config,
T::FORMAT,
move |data| {
move |data, info| {
data_callback(
data.as_slice()
.expect("host supplied incorrect sample type"),
info,
)
},
error_callback,
@ -147,16 +149,17 @@ pub trait DeviceTrait {
) -> Result<Self::Stream, BuildStreamError>
where
T: Sample,
D: FnMut(&mut [T]) + Send + 'static,
D: FnMut(&mut [T], &OutputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static,
{
self.build_output_stream_raw(
config,
T::FORMAT,
move |data| {
move |data, info| {
data_callback(
data.as_slice_mut()
.expect("host supplied incorrect sample type"),
info,
)
},
error_callback,
@ -172,7 +175,7 @@ pub trait DeviceTrait {
error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&Data) + Send + 'static,
D: FnMut(&Data, &InputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static;
/// Create a dynamically typed output stream.
@ -184,7 +187,7 @@ pub trait DeviceTrait {
error_callback: E,
) -> Result<Self::Stream, BuildStreamError>
where
D: FnMut(&mut Data) + Send + 'static,
D: FnMut(&mut Data, &OutputCallbackInfo) + Send + 'static,
E: FnMut(StreamError) + Send + 'static;
}