diff options
author | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2018-08-30 09:13:57 +0200 |
---|---|---|
committer | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2018-09-11 10:38:56 +0200 |
commit | f423ede07f79dbaf7cc2ec41795a7a8d76d98501 (patch) | |
tree | e60af9739fd4648d7e6571a34471a22609074b00 /components | |
parent | 795e7f60029ec8d6be23bbac007ac2100abdabe1 (diff) | |
download | servo-f423ede07f79dbaf7cc2ec41795a7a8d76d98501.tar.gz servo-f423ede07f79dbaf7cc2ec41795a7a8d76d98501.zip |
Add support for multichannel decoded audio
Diffstat (limited to 'components')
-rw-r--r-- | components/script/dom/audiobuffer.rs | 7 | ||||
-rw-r--r-- | components/script/dom/baseaudiocontext.rs | 28 | ||||
-rw-r--r-- | components/script/dom/offlineaudiocontext.rs | 4 |
3 files changed, 26 insertions, 13 deletions
diff --git a/components/script/dom/audiobuffer.rs b/components/script/dom/audiobuffer.rs index 8cf3bb6648f..761bcde404b 100644 --- a/components/script/dom/audiobuffer.rs +++ b/components/script/dom/audiobuffer.rs @@ -64,7 +64,7 @@ impl AudioBuffer { number_of_channels: u32, length: u32, sample_rate: f32, - initial_data: Option<&[f32]>, + initial_data: Option<&[Vec<f32>]>, ) -> DomRoot<AudioBuffer> { let buffer = AudioBuffer::new_inherited(number_of_channels, length, sample_rate); let buffer = reflect_dom_object(Box::new(buffer), global, AudioBufferBinding::Wrap); @@ -93,20 +93,19 @@ impl AudioBuffer { } #[allow(unsafe_code)] - pub fn set_channels(&self, initial_data: Option<&[f32]>) { + pub fn set_channels(&self, initial_data: Option<&[Vec<f32>]>) { let global = self.global(); let cx = global.get_cx(); let _ac = JSAutoCompartment::new(cx, global.reflector().get_jsobject().get()); let chans = self.js_channels.borrow_mut(); for channel in 0..self.number_of_channels { rooted!(in (cx) let mut array = ptr::null_mut::<JSObject>()); - let offset = (channel * self.length) as usize; match initial_data { Some(data) => { let _ = unsafe { Float32Array::create( cx, - CreateWith::Slice(&data[offset..offset + (self.length as usize) - 1]), + CreateWith::Slice(data[channel as usize].as_slice()), array.handle_mut(), ) }; diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index 8cd9afa00ce..dbd821b64fe 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -405,6 +405,7 @@ impl BaseAudioContextMethods for BaseAudioContext { let audio_data = audio_data.to_vec(); let decoded_audio = Arc::new(Mutex::new(Vec::new())); let decoded_audio_ = decoded_audio.clone(); + let decoded_audio__ = decoded_audio.clone(); let this = Trusted::new(self); let this_ = this.clone(); let task_source = window.dom_manipulation_task_source(); @@ -412,15 +413,30 @@ impl BaseAudioContextMethods for BaseAudioContext { let canceller = window.task_canceller(TaskSourceName::DOMManipulation); let canceller_ = window.task_canceller(TaskSourceName::DOMManipulation); let callbacks = AudioDecoderCallbacks::new() + .ready(move |channel_count| { + decoded_audio + .lock() + .unwrap() + .resize(channel_count as usize, Vec::new()); + }) + .progress(move |buffer, channel| { + let mut decoded_audio = decoded_audio_.lock().unwrap(); + decoded_audio[(channel - 1) as usize].extend_from_slice((*buffer).as_ref()); + }) .eos(move || { let _ = task_source.queue_with_canceller( task!(audio_decode_eos: move || { let this = this.root(); - let decoded_audio = decoded_audio.lock().unwrap(); + let decoded_audio = decoded_audio__.lock().unwrap(); + let length = if decoded_audio.len() >= 1 { + decoded_audio[0].len() + } else { + 0 + }; let buffer = AudioBuffer::new( &this.global().as_window(), - 1, // XXX servo-media should provide this info - decoded_audio.len() as u32, + decoded_audio.len() as u32 /* number of channels */, + length as u32, this.sample_rate, Some(decoded_audio.as_slice())); let mut resolvers = this.decode_resolvers.borrow_mut(); @@ -451,12 +467,6 @@ impl BaseAudioContextMethods for BaseAudioContext { &canceller_, ); }) - .progress(move |buffer| { - decoded_audio_ - .lock() - .unwrap() - .extend_from_slice((*buffer).as_ref()); - }) .build(); self.audio_context_impl .decode_audio_data(audio_data, callbacks); diff --git a/components/script/dom/offlineaudiocontext.rs b/components/script/dom/offlineaudiocontext.rs index 4490d5df6f9..21376c11a4d 100644 --- a/components/script/dom/offlineaudiocontext.rs +++ b/components/script/dom/offlineaudiocontext.rs @@ -144,6 +144,10 @@ impl OfflineAudioContextMethods for OfflineAudioContext { task!(resolve: move || { let this = this.root(); let processed_audio = processed_audio.lock().unwrap(); + let processed_audio: Vec<_> = processed_audio + .chunks(this.length as usize) + .map(|channel| channel.to_vec()) + .collect(); let buffer = AudioBuffer::new( &this.global().as_window(), this.channel_count, |