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