Merge pull request #395 from mitchmindtree/callback_info
Add a `CallbackInfo` argument to the stream data callback
This commit is contained in:
commit
f032557fb4
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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()?;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
)?,
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(())
|
||||
})?;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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!()
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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) {
|
||||
|
|
16
src/lib.rs
16
src/lib.rs
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue