Update emscripten backend for removal of `UnknownTypeBuffer`
This commit is contained in:
parent
05b62bb1c0
commit
6fc2185c99
|
@ -7,18 +7,22 @@ use stdweb::unstable::TryInto;
|
||||||
use stdweb::web::TypedArray;
|
use stdweb::web::TypedArray;
|
||||||
use stdweb::web::set_timeout;
|
use stdweb::web::set_timeout;
|
||||||
|
|
||||||
use BuildStreamError;
|
use crate::{
|
||||||
use DefaultFormatError;
|
BuildStreamError,
|
||||||
use DeviceNameError;
|
DefaultFormatError,
|
||||||
use DevicesError;
|
DeviceNameError,
|
||||||
use Format;
|
DevicesError,
|
||||||
use PauseStreamError;
|
Format,
|
||||||
use PlayStreamError;
|
InputData,
|
||||||
use SupportedFormatsError;
|
OutputData,
|
||||||
use StreamData;
|
PauseStreamError,
|
||||||
use StreamError;
|
PlayStreamError,
|
||||||
use SupportedFormat;
|
Sample,
|
||||||
use UnknownTypeOutputBuffer;
|
SampleFormat,
|
||||||
|
StreamError,
|
||||||
|
SupportedFormat,
|
||||||
|
SupportedFormatsError,
|
||||||
|
};
|
||||||
use traits::{DeviceTrait, HostTrait, StreamTrait};
|
use traits::{DeviceTrait, HostTrait, StreamTrait};
|
||||||
|
|
||||||
// The emscripten backend currently works by instantiating an `AudioContext` object per `Stream`.
|
// The emscripten backend currently works by instantiating an `AudioContext` object per `Stream`.
|
||||||
|
@ -156,29 +160,33 @@ impl DeviceTrait for Device {
|
||||||
Device::default_output_format(self)
|
Device::default_output_format(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_input_stream<D, E>(
|
fn build_input_stream<T, D, E>(
|
||||||
&self,
|
&self,
|
||||||
_format: &Format,
|
_format: &Format,
|
||||||
_data_callback: D,
|
_data_callback: D,
|
||||||
_error_callback: E,
|
_error_callback: E,
|
||||||
) -> Result<Self::Stream, BuildStreamError>
|
) -> Result<Self::Stream, BuildStreamError>
|
||||||
where
|
where
|
||||||
D: FnMut(StreamData) + Send + 'static,
|
T: Sample,
|
||||||
|
D: FnMut(InputData<T>) + Send + 'static,
|
||||||
E: FnMut(StreamError) + Send + 'static,
|
E: FnMut(StreamError) + Send + 'static,
|
||||||
{
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_output_stream<D, E>(
|
fn build_output_stream<T, D, E>(
|
||||||
&self,
|
&self,
|
||||||
_format: &Format,
|
_format: &Format,
|
||||||
data_callback: D,
|
data_callback: D,
|
||||||
error_callback: E,
|
error_callback: E,
|
||||||
) -> Result<Self::Stream, BuildStreamError>
|
) -> Result<Self::Stream, BuildStreamError>
|
||||||
where
|
where
|
||||||
D: FnMut(StreamData) + Send + 'static,
|
T: Sample,
|
||||||
|
D: FnMut(OutputData<T>) + Send + 'static,
|
||||||
E: FnMut(StreamError) + Send + 'static,
|
E: FnMut(StreamError) + Send + 'static,
|
||||||
{
|
{
|
||||||
|
assert_eq!(T::FORMAT, SampleFormat::F32, "emscripten backend only supports `f32` data");
|
||||||
|
|
||||||
// Create the stream.
|
// Create the stream.
|
||||||
let audio_ctxt_ref = js!(return new AudioContext()).into_reference().unwrap();
|
let audio_ctxt_ref = js!(return new AudioContext()).into_reference().unwrap();
|
||||||
let stream = Stream { audio_ctxt_ref };
|
let stream = Stream { audio_ctxt_ref };
|
||||||
|
@ -193,7 +201,7 @@ impl DeviceTrait for Device {
|
||||||
//
|
//
|
||||||
// See also: The call to `set_timeout` at the end of the `audio_callback_fn` which creates
|
// See also: The call to `set_timeout` at the end of the `audio_callback_fn` which creates
|
||||||
// the loop.
|
// the loop.
|
||||||
set_timeout(|| audio_callback_fn::<D, E>(user_data_ptr as *mut c_void), 10);
|
set_timeout(|| audio_callback_fn::<T, D, E>(user_data_ptr as *mut c_void), 10);
|
||||||
|
|
||||||
Ok(stream)
|
Ok(stream)
|
||||||
}
|
}
|
||||||
|
@ -215,9 +223,10 @@ impl StreamTrait for Stream {
|
||||||
|
|
||||||
// The first argument of the callback function (a `void*`) is a casted pointer to `self`
|
// The first argument of the callback function (a `void*`) is a casted pointer to `self`
|
||||||
// and to the `callback` parameter that was passed to `run`.
|
// and to the `callback` parameter that was passed to `run`.
|
||||||
fn audio_callback_fn<D, E>(user_data_ptr: *mut c_void)
|
fn audio_callback_fn<T, D, E>(user_data_ptr: *mut c_void)
|
||||||
where
|
where
|
||||||
D: FnMut(StreamData) + Send + 'static,
|
T: Sample,
|
||||||
|
D: FnMut(OutputData<T>) + Send + 'static,
|
||||||
E: FnMut(StreamError) + Send + 'static,
|
E: FnMut(StreamError) + Send + 'static,
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -227,11 +236,11 @@ where
|
||||||
let audio_ctxt = &stream.audio_ctxt_ref;
|
let audio_ctxt = &stream.audio_ctxt_ref;
|
||||||
|
|
||||||
// TODO: We should be re-using a buffer.
|
// TODO: We should be re-using a buffer.
|
||||||
let mut temporary_buffer = vec![0.0; 44100 * 2 / 3];
|
let mut temporary_buffer: Vec<_> = (0..44100 * 2 / 3).map(|_| T::from(&0.0)).collect();
|
||||||
|
|
||||||
{
|
{
|
||||||
let buffer = UnknownTypeOutputBuffer::F32(::OutputBuffer { buffer: &mut temporary_buffer });
|
let buffer = &mut temporary_buffer;
|
||||||
let data = StreamData::Output { buffer: buffer };
|
let data = OutputData { buffer };
|
||||||
data_cb(data);
|
data_cb(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +281,7 @@ where
|
||||||
// TODO: handle latency better ; right now we just use setInterval with the amount of sound
|
// TODO: handle latency better ; right now we just use setInterval with the amount of sound
|
||||||
// data that is in each buffer ; this is obviously bad, and also the schedule is too tight
|
// data that is in each buffer ; this is obviously bad, and also the schedule is too tight
|
||||||
// and there may be underflows
|
// and there may be underflows
|
||||||
set_timeout(|| audio_callback_fn::<D, E>(user_data_ptr), 330);
|
set_timeout(|| audio_callback_fn::<T, D, E>(user_data_ptr), 330);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue