1 /* 2 * Copyright (C) 2010, Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25 #ifndef JavaScriptAudioNode_h 26 #define JavaScriptAudioNode_h 27 28 #include "ActiveDOMObject.h" 29 #include "AudioNode.h" 30 #include "EventListener.h" 31 #include "EventTarget.h" 32 #include <wtf/PassRefPtr.h> 33 #include <wtf/RefPtr.h> 34 #include <wtf/Vector.h> 35 36 namespace WebCore { 37 38 class AudioBuffer; 39 class AudioContext; 40 class AudioProcessingEvent; 41 class Float32Array; 42 43 // JavaScriptAudioNode is an AudioNode which allows for arbitrary synthesis or processing directly using JavaScript. 44 // The API allows for a variable number of inputs and outputs, although it must have at least one input or output. 45 // This basic implementation supports no more than one input and output. 46 // The "onaudioprocess" attribute is an event listener which will get called periodically with an AudioProcessingEvent which has 47 // AudioBuffers for each input and output. 48 49 class JavaScriptAudioNode : public AudioNode, public EventTarget { 50 public: 51 // bufferSize must be one of the following values: 256, 512, 1024, 2048, 4096, 8192, 16384. 52 // This value controls how frequently the onaudioprocess event handler is called and how many sample-frames need to be processed each call. 53 // Lower numbers for bufferSize will result in a lower (better) latency. Higher numbers will be necessary to avoid audio breakup and glitches. 54 // The value chosen must carefully balance between latency and audio quality. 55 static PassRefPtr<JavaScriptAudioNode> create(AudioContext*, double sampleRate, size_t bufferSize, unsigned numberOfInputs = 1, unsigned numberOfOutputs = 1); 56 57 virtual ~JavaScriptAudioNode(); 58 59 // AudioNode 60 virtual void process(size_t framesToProcess); 61 virtual void reset(); 62 virtual void initialize(); 63 virtual void uninitialize(); 64 65 // EventTarget 66 virtual ScriptExecutionContext* scriptExecutionContext() const; 67 virtual JavaScriptAudioNode* toJavaScriptAudioNode(); 68 virtual EventTargetData* eventTargetData() { return &m_eventTargetData; } 69 virtual EventTargetData* ensureEventTargetData() { return &m_eventTargetData; } 70 71 size_t bufferSize() const { return m_bufferSize; } 72 73 DEFINE_ATTRIBUTE_EVENT_LISTENER(audioprocess); 74 75 // Reconcile ref/deref which are defined both in AudioNode and EventTarget. 76 using AudioNode::ref; 77 using AudioNode::deref; 78 79 private: 80 JavaScriptAudioNode(AudioContext*, double sampleRate, size_t bufferSize, unsigned numberOfInputs, unsigned numberOfOutputs); 81 82 static void fireProcessEventDispatch(void* userData); 83 void fireProcessEvent(); 84 85 // Double buffering 86 unsigned doubleBufferIndex() const { return m_doubleBufferIndex; } 87 void swapBuffers() { m_doubleBufferIndex = 1 - m_doubleBufferIndex; } 88 unsigned m_doubleBufferIndex; 89 unsigned m_doubleBufferIndexForEvent; 90 Vector<RefPtr<AudioBuffer> > m_inputBuffers; 91 Vector<RefPtr<AudioBuffer> > m_outputBuffers; 92 93 virtual void refEventTarget() { ref(); } 94 virtual void derefEventTarget() { deref(); } 95 EventTargetData m_eventTargetData; 96 97 size_t m_bufferSize; 98 unsigned m_bufferReadWriteIndex; 99 volatile bool m_isRequestOutstanding; 100 }; 101 102 } // namespace WebCore 103 104 #endif // JavaScriptAudioNode_h 105