From ee706331210325c1c951ea8572cc7d0f3de777ce Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 16 May 2013 19:30:41 -0400 Subject: [PATCH] Bug 836599 - Part 9: Implement the DOM binding for OfflineAudioContext; r=roc --- content/events/public/nsEventNameList.h | 5 +++ content/media/webaudio/AudioContext.cpp | 37 +++++++++++++-- content/media/webaudio/AudioContext.h | 21 ++++++++- content/media/webaudio/Makefile.in | 1 + .../webaudio/OfflineAudioCompletionEvent.cpp | 38 ++++++++++++++++ .../webaudio/OfflineAudioCompletionEvent.h | 45 +++++++++++++++++++ content/media/webaudio/moz.build | 1 + dom/bindings/Bindings.conf | 11 +++++ dom/webidl/OfflineAudioCompletionEvent.webidl | 19 ++++++++ dom/webidl/OfflineAudioContext.webidl | 24 ++++++++++ dom/webidl/WebIDL.mk | 2 + widget/nsGUIEvent.h | 1 + 12 files changed, 200 insertions(+), 5 deletions(-) create mode 100644 content/media/webaudio/OfflineAudioCompletionEvent.cpp create mode 100644 content/media/webaudio/OfflineAudioCompletionEvent.h create mode 100644 dom/webidl/OfflineAudioCompletionEvent.webidl create mode 100644 dom/webidl/OfflineAudioContext.webidl diff --git a/content/events/public/nsEventNameList.h b/content/events/public/nsEventNameList.h index 98fcc04075e1..fe6de76e06d9 100644 --- a/content/events/public/nsEventNameList.h +++ b/content/events/public/nsEventNameList.h @@ -853,6 +853,11 @@ NON_IDL_EVENT(audioprocess, EventNameType_None, NS_EVENT) +NON_IDL_EVENT(complete, + NS_AUDIO_COMPLETE, + EventNameType_None, + NS_EVENT) + #ifdef DEFINED_FORWARDED_EVENT #undef DEFINED_FORWARDED_EVENT #undef FORWARDED_EVENT diff --git a/content/media/webaudio/AudioContext.cpp b/content/media/webaudio/AudioContext.cpp index c01ea2c582b5..1d3302b734b7 100644 --- a/content/media/webaudio/AudioContext.cpp +++ b/content/media/webaudio/AudioContext.cpp @@ -8,6 +8,8 @@ #include "nsContentUtils.h" #include "nsPIDOMWindow.h" #include "mozilla/ErrorResult.h" +#include "mozilla/dom/AudioContextBinding.h" +#include "mozilla/dom/OfflineAudioContextBinding.h" #include "MediaStreamGraph.h" #include "mozilla/dom/AnalyserNode.h" #include "AudioDestinationNode.h" @@ -44,8 +46,9 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper) static uint8_t gWebAudioOutputKey; -AudioContext::AudioContext(nsPIDOMWindow* aWindow) +AudioContext::AudioContext(nsPIDOMWindow* aWindow, bool aIsOffline) : mDestination(new AudioDestinationNode(this, MediaStreamGraph::GetInstance())) + , mIsOffline(aIsOffline) { // Actually play audio mDestination->Stream()->AddAudioOutput(&gWebAudioOutputKey); @@ -64,7 +67,11 @@ AudioContext::~AudioContext() JSObject* AudioContext::WrapObject(JSContext* aCx, JS::Handle aScope) { - return AudioContextBinding::Wrap(aCx, aScope, this); + if (mIsOffline) { + return OfflineAudioContextBinding::Wrap(aCx, aScope, this); + } else { + return AudioContextBinding::Wrap(aCx, aScope, this); + } } /* static */ already_AddRefed @@ -76,7 +83,31 @@ AudioContext::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv) return nullptr; } - nsRefPtr object = new AudioContext(window); + nsRefPtr object = new AudioContext(window, false); + window->AddAudioContext(object); + return object.forget(); +} + +/* static */ already_AddRefed +AudioContext::Constructor(const GlobalObject& aGlobal, + uint32_t aNumberOfChannels, + uint32_t aLength, + float aSampleRate, + ErrorResult& aRv) +{ + nsCOMPtr window = do_QueryInterface(aGlobal.Get()); + if (!window) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } + + if (aSampleRate != IdealAudioRate()) { + // TODO: Add support for running OfflineAudioContext at other sampling rates + aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); + return nullptr; + } + + nsRefPtr object = new AudioContext(window, true); window->AddAudioContext(object); return object.forget(); } diff --git a/content/media/webaudio/AudioContext.h b/content/media/webaudio/AudioContext.h index 403435757a13..162e87af7b1c 100644 --- a/content/media/webaudio/AudioContext.h +++ b/content/media/webaudio/AudioContext.h @@ -50,6 +50,7 @@ class DelayNode; class DynamicsCompressorNode; class GainNode; class GlobalObject; +class OfflineRenderSuccessCallback; class PannerNode; class ScriptProcessorNode; class WaveShaperNode; @@ -57,8 +58,8 @@ class WaveShaperNode; class AudioContext MOZ_FINAL : public nsDOMEventTargetHelper, public EnableWebAudioCheck { - explicit AudioContext(nsPIDOMWindow* aParentWindow); - ~AudioContext(); + explicit AudioContext(nsPIDOMWindow* aParentWindow, bool aIsOffline); + virtual ~AudioContext(); public: NS_DECL_ISUPPORTS_INHERITED @@ -77,9 +78,20 @@ public: virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aScope) MOZ_OVERRIDE; + // Constructor for regular AudioContext static already_AddRefed Constructor(const GlobalObject& aGlobal, ErrorResult& aRv); + // Constructor for offline AudioContext + static already_AddRefed + Constructor(const GlobalObject& aGlobal, + uint32_t aNumberOfChannels, + uint32_t aLength, + float aSampleRate, + ErrorResult& aRv); + + // AudioContext methods + AudioDestinationNode* Destination() const { return mDestination; @@ -164,6 +176,10 @@ public: DecodeSuccessCallback& aSuccessCallback, const Optional >& aFailureCallback); + // OfflineAudioContext methods + void StartRendering() {} + IMPL_EVENT_HANDLER(complete) + uint32_t GetRate() const { return IdealAudioRate(); } MediaStreamGraph* Graph() const; @@ -193,6 +209,7 @@ private: // Hashset containing all ScriptProcessorNodes in order to stop them. // These are all weak pointers. nsTHashtable > mScriptProcessorNodes; + bool mIsOffline; }; } diff --git a/content/media/webaudio/Makefile.in b/content/media/webaudio/Makefile.in index f3171104b479..9b1cc1365bf0 100644 --- a/content/media/webaudio/Makefile.in +++ b/content/media/webaudio/Makefile.in @@ -33,6 +33,7 @@ CPPSRCS := \ EnableWebAudioCheck.cpp \ GainNode.cpp \ MediaBufferDecoder.cpp \ + OfflineAudioCompletionEvent.cpp \ PannerNode.cpp \ ScriptProcessorNode.cpp \ ThreeDPoint.cpp \ diff --git a/content/media/webaudio/OfflineAudioCompletionEvent.cpp b/content/media/webaudio/OfflineAudioCompletionEvent.cpp new file mode 100644 index 000000000000..7df0f664c44f --- /dev/null +++ b/content/media/webaudio/OfflineAudioCompletionEvent.cpp @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "OfflineAudioCompletionEvent.h" +#include "mozilla/dom/OfflineAudioCompletionEventBinding.h" + +namespace mozilla { +namespace dom { + +NS_IMPL_CYCLE_COLLECTION_INHERITED_1(OfflineAudioCompletionEvent, nsDOMEvent, + mRenderedBuffer) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(OfflineAudioCompletionEvent) +NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent) + +NS_IMPL_ADDREF_INHERITED(OfflineAudioCompletionEvent, nsDOMEvent) +NS_IMPL_RELEASE_INHERITED(OfflineAudioCompletionEvent, nsDOMEvent) + +OfflineAudioCompletionEvent::OfflineAudioCompletionEvent(AudioContext* aOwner, + nsPresContext* aPresContext, + nsEvent* aEvent) + : nsDOMEvent(aOwner, aPresContext, aEvent) +{ + SetIsDOMBinding(); +} + +JSObject* +OfflineAudioCompletionEvent::WrapObject(JSContext* aCx, JS::Handle aScope) +{ + return OfflineAudioCompletionEventBinding::Wrap(aCx, aScope, this); +} + +} +} + diff --git a/content/media/webaudio/OfflineAudioCompletionEvent.h b/content/media/webaudio/OfflineAudioCompletionEvent.h new file mode 100644 index 000000000000..7671016c31cb --- /dev/null +++ b/content/media/webaudio/OfflineAudioCompletionEvent.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef OfflineAudioCompletionEvent_h_ +#define OfflineAudioCompletionEvent_h_ + +#include "nsDOMEvent.h" +#include "AudioBuffer.h" +#include "AudioContext.h" + +namespace mozilla { +namespace dom { + +class OfflineAudioCompletionEvent : public nsDOMEvent, + public EnableWebAudioCheck +{ +public: + OfflineAudioCompletionEvent(AudioContext* aOwner, + nsPresContext *aPresContext, + nsEvent *aEvent); + + NS_DECL_ISUPPORTS_INHERITED + NS_FORWARD_TO_NSDOMEVENT + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(OfflineAudioCompletionEvent, nsDOMEvent) + + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aScope) MOZ_OVERRIDE; + + AudioBuffer* RenderedBuffer() + { + return mRenderedBuffer; + } + +private: + nsRefPtr mRenderedBuffer; +}; + +} +} + +#endif + diff --git a/content/media/webaudio/moz.build b/content/media/webaudio/moz.build index 72a6d1f969b4..4150fa97bed1 100644 --- a/content/media/webaudio/moz.build +++ b/content/media/webaudio/moz.build @@ -34,6 +34,7 @@ EXPORTS.mozilla.dom += [ 'DynamicsCompressorNode.h', 'EnableWebAudioCheck.h', 'GainNode.h', + 'OfflineAudioCompletionEvent.h', 'PannerNode.h', 'ScriptProcessorNode.h', 'WaveShaperNode.h', diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 09c6e1dc3b35..64d238191b41 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -675,6 +675,17 @@ DOMInterfaces = { 'nativeType': 'nsDOMNotifyAudioAvailableEvent', }, +'OfflineAudioCompletionEvent': { + 'resultNotAddRefed': [ 'renderedBuffer' ], +}, + +'OfflineAudioContext': { + 'nativeType': 'mozilla::dom::AudioContext', + 'implicitJSContext': [ 'createBuffer' ], + 'nativeOwnership': 'refcounted', + 'resultNotAddRefed': [ 'destination', 'listener' ], +}, + 'PaintRequest': { 'nativeType': 'nsPaintRequest', }, diff --git a/dom/webidl/OfflineAudioCompletionEvent.webidl b/dom/webidl/OfflineAudioCompletionEvent.webidl new file mode 100644 index 000000000000..f0717c87985c --- /dev/null +++ b/dom/webidl/OfflineAudioCompletionEvent.webidl @@ -0,0 +1,19 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + +[PrefControlled] +interface OfflineAudioCompletionEvent : Event { + + readonly attribute AudioBuffer renderedBuffer; + +}; + diff --git a/dom/webidl/OfflineAudioContext.webidl b/dom/webidl/OfflineAudioContext.webidl new file mode 100644 index 000000000000..189f1b581e01 --- /dev/null +++ b/dom/webidl/OfflineAudioContext.webidl @@ -0,0 +1,24 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + +callback OfflineRenderSuccessCallback = void (AudioBuffer renderedData); + +[Constructor(unsigned long numberOfChannels, unsigned long length, float sampleRate), + PrefControlled] +interface OfflineAudioContext : AudioContext { + + void startRendering(); + + [SetterThrows] + attribute EventHandler oncomplete; + +}; diff --git a/dom/webidl/WebIDL.mk b/dom/webidl/WebIDL.mk index 458df864e98f..0cfa72177b06 100644 --- a/dom/webidl/WebIDL.mk +++ b/dom/webidl/WebIDL.mk @@ -178,6 +178,8 @@ webidl_files = \ Notification.webidl \ NotifyAudioAvailableEvent.webidl \ NotifyPaintEvent.webidl \ + OfflineAudioCompletionEvent.webidl \ + OfflineAudioContext.webidl \ PaintRequest.webidl \ PaintRequestList.webidl \ PannerNode.webidl \ diff --git a/widget/nsGUIEvent.h b/widget/nsGUIEvent.h index f683c8ce5d8d..5aaa9ae4fbc5 100644 --- a/widget/nsGUIEvent.h +++ b/widget/nsGUIEvent.h @@ -401,6 +401,7 @@ enum nsEventStructType { #define NS_WEBAUDIO_EVENT_START 4350 #define NS_AUDIO_PROCESS (NS_WEBAUDIO_EVENT_START) +#define NS_AUDIO_COMPLETE (NS_WEBAUDIO_EVENT_START + 1) // script notification events #define NS_NOTIFYSCRIPT_START 4500