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 namespace WebCore {
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 uninitialize();
52 }
53
initialize()54 void DefaultAudioDestinationNode::initialize()
55 {
56 ASSERT(isMainThread());
57 if (isInitialized())
58 return;
59
60 createDestination();
61 AudioNode::initialize();
62 }
63
uninitialize()64 void DefaultAudioDestinationNode::uninitialize()
65 {
66 ASSERT(isMainThread());
67 if (!isInitialized())
68 return;
69
70 m_destination->stop();
71 m_numberOfInputChannels = 0;
72
73 AudioNode::uninitialize();
74 }
75
createDestination()76 void DefaultAudioDestinationNode::createDestination()
77 {
78 float hardwareSampleRate = AudioDestination::hardwareSampleRate();
79 WTF_LOG(WebAudio, ">>>> hardwareSampleRate = %f\n", hardwareSampleRate);
80
81 m_destination = AudioDestination::create(*this, m_inputDeviceId, m_numberOfInputChannels, channelCount(), hardwareSampleRate);
82 }
83
startRendering()84 void DefaultAudioDestinationNode::startRendering()
85 {
86 ASSERT(isInitialized());
87 if (isInitialized())
88 m_destination->start();
89 }
90
maxChannelCount() const91 unsigned long DefaultAudioDestinationNode::maxChannelCount() const
92 {
93 return AudioDestination::maxChannelCount();
94 }
95
setChannelCount(unsigned long channelCount,ExceptionState & exceptionState)96 void DefaultAudioDestinationNode::setChannelCount(unsigned long channelCount, ExceptionState& exceptionState)
97 {
98 // The channelCount for the input to this node controls the actual number of channels we
99 // send to the audio hardware. It can only be set depending on the maximum number of
100 // channels supported by the hardware.
101
102 ASSERT(isMainThread());
103
104 if (!maxChannelCount() || channelCount > maxChannelCount()) {
105 exceptionState.throwDOMException(
106 IndexSizeError,
107 ExceptionMessages::indexOutsideRange<unsigned>("channel count", channelCount, 1, ExceptionMessages::InclusiveBound, maxChannelCount(), ExceptionMessages::InclusiveBound));
108 return;
109 }
110
111 unsigned long oldChannelCount = this->channelCount();
112 AudioNode::setChannelCount(channelCount, exceptionState);
113
114 if (!exceptionState.hadException() && this->channelCount() != oldChannelCount && isInitialized()) {
115 // Re-create destination.
116 m_destination->stop();
117 createDestination();
118 m_destination->start();
119 }
120 }
121
122 } // namespace WebCore
123
124 #endif // ENABLE(WEB_AUDIO)
125