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

Side by Side Diff: Source/platform/audio/StereoPanner.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
« no previous file with comments | « Source/platform/audio/StereoPanner.h ('k') | Source/platform/blink_platform.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "platform/audio/StereoPanner.h"
10
11 #include "platform/audio/AudioBus.h"
12 #include "platform/audio/AudioUtilities.h"
13 #include "wtf/MathExtras.h"
14 #include <algorithm>
15
16 // Use a 50ms smoothing / de-zippering time-constant.
17 const float SmoothingTimeConstant = 0.050f;
18
19 namespace blink {
20
21 StereoPanner::StereoPanner(float sampleRate) : Spatializer(PanningModelEqualPowe r)
22 , m_isFirstRender(true)
23 , m_gainL(0.5)
24 , m_gainR(0.5)
25 {
26 m_smoothingConstant = AudioUtilities::discreteTimeConstantForSampleRate(Smoo thingTimeConstant, sampleRate);
27 }
28
29 void StereoPanner::panWithSampleAccurateValues(const AudioBus* inputBus, AudioBu s* outputBus, const float* panValues, size_t framesToProcess)
30 {
31 bool isInputSafe = inputBus
32 && (inputBus->numberOfChannels() == 1 || inputBus->numberOfChannels() == 2)
33 && framesToProcess <= inputBus->length();
34 ASSERT(isInputSafe);
35 if (!isInputSafe)
36 return;
37
38 unsigned numberOfInputChannels = inputBus->numberOfChannels();
39
40 bool isOutputSafe = outputBus
41 && outputBus->numberOfChannels() == 2
42 && framesToProcess <= outputBus->length();
43 ASSERT(isOutputSafe);
44 if (!isOutputSafe)
45 return;
46
47 const float* sourceL = inputBus->channel(0)->data();
48 const float* sourceR = numberOfInputChannels > 1 ? inputBus->channel(1)->dat a() : sourceL;
49 float* destinationL = outputBus->channelByType(AudioBus::ChannelLeft)->mutab leData();
50 float* destinationR = outputBus->channelByType(AudioBus::ChannelRight)->muta bleData();
51
52 if (!sourceL || !sourceR || !destinationL || !destinationR)
53 return;
54
55 // Cache in local variables.
56 double gainL = m_gainL;
57 double gainR = m_gainR;
58
59 int n = framesToProcess;
60
61 if (numberOfInputChannels == 1) { // For mono source case.
62 while (n--) {
63 float inputL = *sourceL++;
64 float panValue = clampTo(*panValues++, -1.0, 1.0);
65 float panPosition = (panValue * 0.5 + 0.5) * piOverTwoDouble;
66 gainL = std::cos(panPosition);
67 gainR = std::sin(panPosition);
68 *destinationL++ = static_cast<float>(inputL * gainL);
69 *destinationR++ = static_cast<float>(inputL * gainR);
70 }
71 } else { // For stereo source case.
72 while (n--) {
73 float inputL = *sourceL++;
74 float inputR = *sourceR++;
75 float panValue = clampTo(*panValues++, -1.0, 1.0);
76 float panPosition = (panValue * 0.5 + 0.5) * piOverTwoDouble;
77 gainL = std::cos(panPosition);
78 gainR = std::sin(panPosition);
79 *destinationL++ = static_cast<float>(inputL * gainL);
80 *destinationR++ = static_cast<float>(inputR * gainR);
81 }
82 }
83
84 m_gainL = gainL;
85 m_gainR = gainR;
86 }
87
88 void StereoPanner::panToTargetValue(const AudioBus* inputBus, AudioBus* outputBu s, float panValue, size_t framesToProcess)
89 {
90 bool isInputSafe = inputBus
91 && (inputBus->numberOfChannels() == 1 || inputBus->numberOfChannels() == 2)
92 && framesToProcess <= inputBus->length();
93 ASSERT(isInputSafe);
94 if (!isInputSafe)
95 return;
96
97 unsigned numberOfInputChannels = inputBus->numberOfChannels();
98
99 bool isOutputSafe = outputBus
100 && outputBus->numberOfChannels() == 2
101 && framesToProcess <= outputBus->length();
102 ASSERT(isOutputSafe);
103 if (!isOutputSafe)
104 return;
105
106 const float* sourceL = inputBus->channel(0)->data();
107 const float* sourceR = numberOfInputChannels > 1 ? inputBus->channel(1)->dat a() : sourceL;
108 float* destinationL = outputBus->channelByType(AudioBus::ChannelLeft)->mutab leData();
109 float* destinationR = outputBus->channelByType(AudioBus::ChannelRight)->muta bleData();
110
111 if (!sourceL || !sourceR || !destinationL || !destinationR)
112 return;
113
114 float panValueClamped = clampTo(panValue, -1.0, 1.0);
115 double targetGainL = std::cos(piOverTwoDouble * (panValueClamped * 0.5 + 0.5 ));
116 double targetGainR = std::sin(piOverTwoDouble * (panValueClamped * 0.5 + 0.5 ));
117
118 // Don't de-zipper on first render call.
119 if (m_isFirstRender) {
120 m_isFirstRender = false;
121 m_gainL = targetGainL;
122 m_gainR = targetGainR;
123 }
124
125 // Cache in local variables.
126 double gainL = m_gainL;
127 double gainR = m_gainR;
128
129 // Get local copy of smoothing constant.
130 const double SmoothingConstant = m_smoothingConstant;
131
132 int n = framesToProcess;
133
134 if (numberOfInputChannels == 1) { // For mono source case.
135 while (n--) {
136 float inputL = *sourceL++;
137 gainL += (targetGainL - gainL) * SmoothingConstant;
138 gainR += (targetGainR - gainR) * SmoothingConstant;
139 *destinationL++ = static_cast<float>(inputL * gainL);
140 *destinationR++ = static_cast<float>(inputL * gainR);
141 }
142 } else { // For stereo source case.
143 while (n--) {
144 float inputL = *sourceL++;
145 float inputR = *sourceR++;
146 gainL += (targetGainL - gainL) * SmoothingConstant;
147 gainR += (targetGainR - gainR) * SmoothingConstant;
148 *destinationL++ = static_cast<float>(inputL * gainL);
149 *destinationR++ = static_cast<float>(inputR * gainR);
150 }
151 }
152
153 m_gainL = gainL;
154 m_gainR = gainR;
155 }
156
157 } // namespace blink
158
159 #endif // ENABLE(WEB_AUDIO)
OLDNEW
« no previous file with comments | « Source/platform/audio/StereoPanner.h ('k') | Source/platform/blink_platform.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698