• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011, 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 #include "config.h"
26 
27 #if ENABLE(WEB_AUDIO)
28 
29 #include "modules/webaudio/DefaultAudioDestinationNode.h"
30 
31 #include "bindings/v8/ExceptionMessages.h"
32 #include "bindings/v8/ExceptionState.h"
33 #include "core/dom/ExceptionCode.h"
34 #include "platform/Logging.h"
35 #include "wtf/MainThread.h"
36 
37 const unsigned EnabledInputChannels = 2;
38 
39 namespace WebCore {
40 
DefaultAudioDestinationNode(AudioContext * context)41 DefaultAudioDestinationNode::DefaultAudioDestinationNode(AudioContext* context)
42     : AudioDestinationNode(context, AudioDestination::hardwareSampleRate())
43     , m_numberOfInputChannels(0)
44 {
45     // Node-specific default mixing rules.
46     m_channelCount = 2;
47     m_channelCountMode = Explicit;
48     m_channelInterpretation = AudioBus::Speakers;
49 }
50 
~DefaultAudioDestinationNode()51 DefaultAudioDestinationNode::~DefaultAudioDestinationNode()
52 {
53     uninitialize();
54 }
55 
initialize()56 void DefaultAudioDestinationNode::initialize()
57 {
58     ASSERT(isMainThread());
59     if (isInitialized())
60         return;
61 
62     createDestination();
63     AudioNode::initialize();
64 }
65 
uninitialize()66 void DefaultAudioDestinationNode::uninitialize()
67 {
68     ASSERT(isMainThread());
69     if (!isInitialized())
70         return;
71 
72     m_destination->stop();
73     m_numberOfInputChannels = 0;
74 
75     AudioNode::uninitialize();
76 }
77 
createDestination()78 void DefaultAudioDestinationNode::createDestination()
79 {
80     float hardwareSampleRate = AudioDestination::hardwareSampleRate();
81     WTF_LOG(WebAudio, ">>>> hardwareSampleRate = %f\n", hardwareSampleRate);
82 
83     m_destination = AudioDestination::create(*this, m_inputDeviceId, m_numberOfInputChannels, channelCount(), hardwareSampleRate);
84 }
85 
enableInput(const String & inputDeviceId)86 void DefaultAudioDestinationNode::enableInput(const String& inputDeviceId)
87 {
88     ASSERT(isMainThread());
89     if (m_numberOfInputChannels != EnabledInputChannels) {
90         m_numberOfInputChannels = EnabledInputChannels;
91         m_inputDeviceId = inputDeviceId;
92 
93         if (isInitialized()) {
94             // Re-create destination.
95             m_destination->stop();
96             createDestination();
97             m_destination->start();
98         }
99     }
100 }
101 
startRendering()102 void DefaultAudioDestinationNode::startRendering()
103 {
104     ASSERT(isInitialized());
105     if (isInitialized())
106         m_destination->start();
107 }
108 
maxChannelCount() const109 unsigned long DefaultAudioDestinationNode::maxChannelCount() const
110 {
111     return AudioDestination::maxChannelCount();
112 }
113 
setChannelCount(unsigned long channelCount,ExceptionState & exceptionState)114 void DefaultAudioDestinationNode::setChannelCount(unsigned long channelCount, ExceptionState& exceptionState)
115 {
116     // The channelCount for the input to this node controls the actual number of channels we
117     // send to the audio hardware. It can only be set depending on the maximum number of
118     // channels supported by the hardware.
119 
120     ASSERT(isMainThread());
121 
122     if (!maxChannelCount() || channelCount > maxChannelCount()) {
123         exceptionState.throwDOMException(
124             IndexSizeError,
125             ExceptionMessages::failedToSet(
126                 "channelCount",
127                 "AudioDestinationNode",
128                 "channel count (" + String::number(channelCount)
129                 + ") must be between 1 and "
130                 + String::number(maxChannelCount()) + "."));
131         return;
132     }
133 
134     unsigned long oldChannelCount = this->channelCount();
135     AudioNode::setChannelCount(channelCount, exceptionState);
136 
137     if (!exceptionState.hadException() && this->channelCount() != oldChannelCount && isInitialized()) {
138         // Re-create destination.
139         m_destination->stop();
140         createDestination();
141         m_destination->start();
142     }
143 }
144 
145 } // namespace WebCore
146 
147 #endif // ENABLE(WEB_AUDIO)
148