Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: Source/modules/webaudio/StereoPannerNode.cpp

Issue 691143007: Implement StereoPannerNode for robust stereo panning (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6
7 #if ENABLE(WEB_AUDIO)
8
9 #include "modules/webaudio/StereoPannerNode.h"
10
11 #include "bindings/core/v8/ExceptionMessages.h"
12 #include "bindings/core/v8/ExceptionState.h"
13 #include "core/dom/ExecutionContext.h"
14 #include "modules/webaudio/AudioContext.h"
15 #include "modules/webaudio/AudioNodeInput.h"
16 #include "modules/webaudio/AudioNodeOutput.h"
17 #include "platform/audio/StereoPanner.h"
18 #include "wtf/MathExtras.h"
19
20 namespace blink {
21
22 StereoPannerNode::StereoPannerNode(AudioContext* context, float sampleRate)
23 : AudioNode(context, sampleRate)
24 , m_sampleAccuratePanValues(AudioNode::ProcessingSizeInFrames)
25 {
26 m_pan = AudioParam::create(context, 0);
27
28 addInput();
29 addOutput(AudioNodeOutput::create(this, 2));
30
31 // The node-specific default mixing rules declare that StereoPannerNode
32 // can handle mono to stereo and stereo to stereo conversion.
33 m_channelCount = 2;
34 m_channelCountMode = ClampedMax;
35 m_channelInterpretation = AudioBus::Speakers;
36
37 setNodeType(NodeTypeStereoPanner);
38
39 initialize();
40 }
41
42 StereoPannerNode::~StereoPannerNode()
43 {
44 ASSERT(!isInitialized());
45 }
46
47 void StereoPannerNode::dispose()
48 {
49 uninitialize();
50 AudioNode::dispose();
51 }
52
53 void StereoPannerNode::process(size_t framesToProcess)
54 {
55 AudioBus* outputBus = output(0)->bus();
56
57 if (!isInitialized() || !input(0)->isConnected() || !m_stereoPanner.get()) {
58 outputBus->zero();
59 return;
60 }
61
62 AudioBus* inputBus = input(0)->bus();
63 if (!inputBus) {
64 outputBus->zero();
65 return;
66 }
67
68 if (pan()->hasSampleAccurateValues()) {
69 // Apply sample-accurate panning specified by AudioParam automation.
70 ASSERT(framesToProcess <= m_sampleAccuratePanValues.size());
71 if (framesToProcess <= m_sampleAccuratePanValues.size()) {
72 float* panValues = m_sampleAccuratePanValues.data();
73 pan()->calculateSampleAccurateValues(panValues, framesToProcess);
74 m_stereoPanner->panWithSampleAccurateValues(inputBus, outputBus, pan Values, framesToProcess);
75 }
76 } else {
77 m_stereoPanner->panToTargetValue(inputBus, outputBus, pan()->value(), fr amesToProcess);
78 }
79 }
80
81 void StereoPannerNode::initialize()
82 {
83 if (isInitialized())
84 return;
85
86 m_stereoPanner = Spatializer::create(Spatializer::PanningModelEqualPower, sa mpleRate());
87
88 AudioNode::initialize();
89 }
90
91 void StereoPannerNode::uninitialize()
92 {
93 if (!isInitialized())
94 return;
95
96 m_stereoPanner.clear();
97
98 AudioNode::uninitialize();
99 }
100
101 void StereoPannerNode::setChannelCount(unsigned long channelCount, ExceptionStat e& exceptionState)
102 {
103 ASSERT(isMainThread());
104 AudioContext::AutoLocker locker(context());
105
106 // A PannerNode only supports 1 or 2 channels
107 if (channelCount > 0 && channelCount <= 2) {
108 if (m_channelCount != channelCount) {
109 m_channelCount = channelCount;
110 if (m_channelCountMode != Max)
111 updateChannelsForInputs();
112 }
113 } else {
114 exceptionState.throwDOMException(
115 NotSupportedError,
116 ExceptionMessages::indexOutsideRange<unsigned long>(
117 "channelCount",
118 channelCount,
119 1,
120 ExceptionMessages::InclusiveBound,
121 2,
122 ExceptionMessages::InclusiveBound));
123 }
124 }
125
126 void StereoPannerNode::setChannelCountMode(const String& mode, ExceptionState& e xceptionState)
127 {
128 ASSERT(isMainThread());
129 AudioContext::AutoLocker locker(context());
130
131 ChannelCountMode oldMode = m_channelCountMode;
132
133 if (mode == "clamped-max") {
134 m_newChannelCountMode = ClampedMax;
135 } else if (mode == "explicit") {
136 m_newChannelCountMode = Explicit;
137 } else if (mode == "max") {
138 // This is not supported for a StereoPannerNode, which can only handle
139 // 1 or 2 channels.
140 exceptionState.throwDOMException(
141 NotSupportedError,
142 ExceptionMessages::failedToSet(
143 "channelCountMode",
144 "StereoPannerNode",
145 "'max' is not allowed"));
146 m_newChannelCountMode = oldMode;
147 } else {
148 // Do nothing for other invalid values.
149 m_newChannelCountMode = oldMode;
150 }
151
152 if (m_newChannelCountMode != oldMode)
153 context()->addChangedChannelCountMode(this);
154 }
155
156 void StereoPannerNode::trace(Visitor* visitor)
157 {
158 visitor->trace(m_stereoPanner);
159 visitor->trace(m_pan);
160 AudioNode::trace(visitor);
161 }
162
163 } // namespace blink
164
165 #endif // ENABLE(WEB_AUDIO)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698