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

Side by Side Diff: third_party/WebKit/Source/modules/webaudio/RealtimeAnalyser.cpp

Issue 2389253002: reflow comments in modules/{webaudio,vr} (Closed)
Patch Set: . Created 4 years, 2 months 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
1 /* 1 /*
2 * Copyright (C) 2010, Google Inc. All rights reserved. 2 * Copyright (C) 2010, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 22 matching lines...) Expand all
33 #include <complex> 33 #include <complex>
34 #include <limits.h> 34 #include <limits.h>
35 35
36 namespace blink { 36 namespace blink {
37 37
38 const double RealtimeAnalyser::DefaultSmoothingTimeConstant = 0.8; 38 const double RealtimeAnalyser::DefaultSmoothingTimeConstant = 0.8;
39 const double RealtimeAnalyser::DefaultMinDecibels = -100; 39 const double RealtimeAnalyser::DefaultMinDecibels = -100;
40 const double RealtimeAnalyser::DefaultMaxDecibels = -30; 40 const double RealtimeAnalyser::DefaultMaxDecibels = -30;
41 41
42 const unsigned RealtimeAnalyser::DefaultFFTSize = 2048; 42 const unsigned RealtimeAnalyser::DefaultFFTSize = 2048;
43 // All FFT implementations are expected to handle power-of-two sizes MinFFTSize <= size <= MaxFFTSize. 43 // All FFT implementations are expected to handle power-of-two sizes
44 // MinFFTSize <= size <= MaxFFTSize.
44 const unsigned RealtimeAnalyser::MinFFTSize = 32; 45 const unsigned RealtimeAnalyser::MinFFTSize = 32;
45 const unsigned RealtimeAnalyser::MaxFFTSize = 32768; 46 const unsigned RealtimeAnalyser::MaxFFTSize = 32768;
46 const unsigned RealtimeAnalyser::InputBufferSize = 47 const unsigned RealtimeAnalyser::InputBufferSize =
47 RealtimeAnalyser::MaxFFTSize * 2; 48 RealtimeAnalyser::MaxFFTSize * 2;
48 49
49 RealtimeAnalyser::RealtimeAnalyser() 50 RealtimeAnalyser::RealtimeAnalyser()
50 : m_inputBuffer(InputBufferSize), 51 : m_inputBuffer(InputBufferSize),
51 m_writeIndex(0), 52 m_writeIndex(0),
52 m_downMixBus(AudioBus::create(1, AudioUtilities::kRenderQuantumFrames)), 53 m_downMixBus(AudioBus::create(1, AudioUtilities::kRenderQuantumFrames)),
53 m_fftSize(DefaultFFTSize), 54 m_fftSize(DefaultFFTSize),
(...skipping 10 matching lines...) Expand all
64 65
65 // Only allow powers of two. 66 // Only allow powers of two.
66 unsigned log2size = static_cast<unsigned>(log2(size)); 67 unsigned log2size = static_cast<unsigned>(log2(size));
67 bool isPOT(1UL << log2size == size); 68 bool isPOT(1UL << log2size == size);
68 69
69 if (!isPOT || size > MaxFFTSize || size < MinFFTSize) 70 if (!isPOT || size > MaxFFTSize || size < MinFFTSize)
70 return false; 71 return false;
71 72
72 if (m_fftSize != size) { 73 if (m_fftSize != size) {
73 m_analysisFrame = wrapUnique(new FFTFrame(size)); 74 m_analysisFrame = wrapUnique(new FFTFrame(size));
74 // m_magnitudeBuffer has size = fftSize / 2 because it contains floats reduc ed from complex values in m_analysisFrame. 75 // m_magnitudeBuffer has size = fftSize / 2 because it contains floats
76 // reduced from complex values in m_analysisFrame.
75 m_magnitudeBuffer.allocate(size / 2); 77 m_magnitudeBuffer.allocate(size / 2);
76 m_fftSize = size; 78 m_fftSize = size;
77 } 79 }
78 80
79 return true; 81 return true;
80 } 82 }
81 83
82 void RealtimeAnalyser::writeInput(AudioBus* bus, size_t framesToProcess) { 84 void RealtimeAnalyser::writeInput(AudioBus* bus, size_t framesToProcess) {
83 bool isBusGood = bus && bus->numberOfChannels() > 0 && 85 bool isBusGood = bus && bus->numberOfChannels() > 0 &&
84 bus->channel(0)->length() >= framesToProcess; 86 bus->channel(0)->length() >= framesToProcess;
85 DCHECK(isBusGood); 87 DCHECK(isBusGood);
86 if (!isBusGood) 88 if (!isBusGood)
87 return; 89 return;
88 90
89 // FIXME : allow to work with non-FFTSize divisible chunking 91 // FIXME : allow to work with non-FFTSize divisible chunking
90 bool isDestinationGood = 92 bool isDestinationGood =
91 m_writeIndex < m_inputBuffer.size() && 93 m_writeIndex < m_inputBuffer.size() &&
92 m_writeIndex + framesToProcess <= m_inputBuffer.size(); 94 m_writeIndex + framesToProcess <= m_inputBuffer.size();
93 DCHECK(isDestinationGood); 95 DCHECK(isDestinationGood);
94 if (!isDestinationGood) 96 if (!isDestinationGood)
95 return; 97 return;
96 98
97 // Perform real-time analysis 99 // Perform real-time analysis
98 float* dest = m_inputBuffer.data() + m_writeIndex; 100 float* dest = m_inputBuffer.data() + m_writeIndex;
99 101
100 // Clear the bus and downmix the input according to the down mixing rules. Th en save the result 102 // Clear the bus and downmix the input according to the down mixing rules.
101 // in the m_inputBuffer at the appropriate place. 103 // Then save the result in the m_inputBuffer at the appropriate place.
102 m_downMixBus->zero(); 104 m_downMixBus->zero();
103 m_downMixBus->sumFrom(*bus); 105 m_downMixBus->sumFrom(*bus);
104 memcpy(dest, m_downMixBus->channel(0)->data(), 106 memcpy(dest, m_downMixBus->channel(0)->data(),
105 framesToProcess * sizeof(*dest)); 107 framesToProcess * sizeof(*dest));
106 108
107 m_writeIndex += framesToProcess; 109 m_writeIndex += framesToProcess;
108 if (m_writeIndex >= InputBufferSize) 110 if (m_writeIndex >= InputBufferSize)
109 m_writeIndex = 0; 111 m_writeIndex = 0;
110 } 112 }
111 113
(...skipping 14 matching lines...) Expand all
126 a0 - a1 * cos(twoPiDouble * x) + a2 * cos(twoPiDouble * 2.0 * x); 128 a0 - a1 * cos(twoPiDouble * x) + a2 * cos(twoPiDouble * 2.0 * x);
127 p[i] *= float(window); 129 p[i] *= float(window);
128 } 130 }
129 } 131 }
130 132
131 } // namespace 133 } // namespace
132 134
133 void RealtimeAnalyser::doFFTAnalysis() { 135 void RealtimeAnalyser::doFFTAnalysis() {
134 DCHECK(isMainThread()); 136 DCHECK(isMainThread());
135 137
136 // Unroll the input buffer into a temporary buffer, where we'll apply an analy sis window followed by an FFT. 138 // Unroll the input buffer into a temporary buffer, where we'll apply an
139 // analysis window followed by an FFT.
137 size_t fftSize = this->fftSize(); 140 size_t fftSize = this->fftSize();
138 141
139 AudioFloatArray temporaryBuffer(fftSize); 142 AudioFloatArray temporaryBuffer(fftSize);
140 float* inputBuffer = m_inputBuffer.data(); 143 float* inputBuffer = m_inputBuffer.data();
141 float* tempP = temporaryBuffer.data(); 144 float* tempP = temporaryBuffer.data();
142 145
143 // Take the previous fftSize values from the input buffer and copy into the te mporary buffer. 146 // Take the previous fftSize values from the input buffer and copy into the
147 // temporary buffer.
144 unsigned writeIndex = m_writeIndex; 148 unsigned writeIndex = m_writeIndex;
145 if (writeIndex < fftSize) { 149 if (writeIndex < fftSize) {
146 memcpy(tempP, inputBuffer + writeIndex - fftSize + InputBufferSize, 150 memcpy(tempP, inputBuffer + writeIndex - fftSize + InputBufferSize,
147 sizeof(*tempP) * (fftSize - writeIndex)); 151 sizeof(*tempP) * (fftSize - writeIndex));
148 memcpy(tempP + fftSize - writeIndex, inputBuffer, 152 memcpy(tempP + fftSize - writeIndex, inputBuffer,
149 sizeof(*tempP) * writeIndex); 153 sizeof(*tempP) * writeIndex);
150 } else { 154 } else {
151 memcpy(tempP, inputBuffer + writeIndex - fftSize, sizeof(*tempP) * fftSize); 155 memcpy(tempP, inputBuffer + writeIndex - fftSize, sizeof(*tempP) * fftSize);
152 } 156 }
153 157
154 // Window the input samples. 158 // Window the input samples.
155 applyWindow(tempP, fftSize); 159 applyWindow(tempP, fftSize);
156 160
157 // Do the analysis. 161 // Do the analysis.
158 m_analysisFrame->doFFT(tempP); 162 m_analysisFrame->doFFT(tempP);
159 163
160 float* realP = m_analysisFrame->realData(); 164 float* realP = m_analysisFrame->realData();
161 float* imagP = m_analysisFrame->imagData(); 165 float* imagP = m_analysisFrame->imagData();
162 166
163 // Blow away the packed nyquist component. 167 // Blow away the packed nyquist component.
164 imagP[0] = 0; 168 imagP[0] = 0;
165 169
166 // Normalize so than an input sine wave at 0dBfs registers as 0dBfs (undo FFT scaling factor). 170 // Normalize so than an input sine wave at 0dBfs registers as 0dBfs (undo FFT
171 // scaling factor).
167 const double magnitudeScale = 1.0 / fftSize; 172 const double magnitudeScale = 1.0 / fftSize;
168 173
169 // A value of 0 does no averaging with the previous result. Larger values pro duce slower, but smoother changes. 174 // A value of 0 does no averaging with the previous result. Larger values
175 // produce slower, but smoother changes.
170 double k = m_smoothingTimeConstant; 176 double k = m_smoothingTimeConstant;
171 k = std::max(0.0, k); 177 k = std::max(0.0, k);
172 k = std::min(1.0, k); 178 k = std::min(1.0, k);
173 179
174 // Convert the analysis data from complex to magnitude and average with the pr evious result. 180 // Convert the analysis data from complex to magnitude and average with the
181 // previous result.
175 float* destination = magnitudeBuffer().data(); 182 float* destination = magnitudeBuffer().data();
176 size_t n = magnitudeBuffer().size(); 183 size_t n = magnitudeBuffer().size();
177 for (size_t i = 0; i < n; ++i) { 184 for (size_t i = 0; i < n; ++i) {
178 std::complex<double> c(realP[i], imagP[i]); 185 std::complex<double> c(realP[i], imagP[i]);
179 double scalarMagnitude = abs(c) * magnitudeScale; 186 double scalarMagnitude = abs(c) * magnitudeScale;
180 destination[i] = float(k * destination[i] + (1 - k) * scalarMagnitude); 187 destination[i] = float(k * destination[i] + (1 - k) * scalarMagnitude);
181 } 188 }
182 } 189 }
183 190
184 void RealtimeAnalyser::convertFloatToDb(DOMFloat32Array* destinationArray) { 191 void RealtimeAnalyser::convertFloatToDb(DOMFloat32Array* destinationArray) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 : 1 / (m_maxDecibels - m_minDecibels); 231 : 1 / (m_maxDecibels - m_minDecibels);
225 const double minDecibels = m_minDecibels; 232 const double minDecibels = m_minDecibels;
226 233
227 const float* source = magnitudeBuffer().data(); 234 const float* source = magnitudeBuffer().data();
228 unsigned char* destination = destinationArray->data(); 235 unsigned char* destination = destinationArray->data();
229 236
230 for (unsigned i = 0; i < len; ++i) { 237 for (unsigned i = 0; i < len; ++i) {
231 float linearValue = source[i]; 238 float linearValue = source[i];
232 double dbMag = AudioUtilities::linearToDecibels(linearValue); 239 double dbMag = AudioUtilities::linearToDecibels(linearValue);
233 240
234 // The range m_minDecibels to m_maxDecibels will be scaled to byte values from 0 to UCHAR_MAX. 241 // The range m_minDecibels to m_maxDecibels will be scaled to byte values
242 // from 0 to UCHAR_MAX.
235 double scaledValue = UCHAR_MAX * (dbMag - minDecibels) * rangeScaleFactor; 243 double scaledValue = UCHAR_MAX * (dbMag - minDecibels) * rangeScaleFactor;
236 244
237 // Clip to valid range. 245 // Clip to valid range.
238 if (scaledValue < 0) 246 if (scaledValue < 0)
239 scaledValue = 0; 247 scaledValue = 0;
240 if (scaledValue > UCHAR_MAX) 248 if (scaledValue > UCHAR_MAX)
241 scaledValue = UCHAR_MAX; 249 scaledValue = UCHAR_MAX;
242 250
243 destination[i] = static_cast<unsigned char>(scaledValue); 251 destination[i] = static_cast<unsigned char>(scaledValue);
244 } 252 }
245 } 253 }
246 } 254 }
247 255
248 void RealtimeAnalyser::getByteFrequencyData(DOMUint8Array* destinationArray, 256 void RealtimeAnalyser::getByteFrequencyData(DOMUint8Array* destinationArray,
249 double currentTime) { 257 double currentTime) {
250 DCHECK(isMainThread()); 258 DCHECK(isMainThread());
251 DCHECK(destinationArray); 259 DCHECK(destinationArray);
252 260
253 if (currentTime <= m_lastAnalysisTime) { 261 if (currentTime <= m_lastAnalysisTime) {
254 // FIXME: Is it worth caching the data so we don't have to do the conversion every time? 262 // FIXME: Is it worth caching the data so we don't have to do the conversion
255 // Perhaps not, since we expect many calls in the same rendering quantum. 263 // every time? Perhaps not, since we expect many calls in the same
264 // rendering quantum.
256 convertToByteData(destinationArray); 265 convertToByteData(destinationArray);
257 return; 266 return;
258 } 267 }
259 268
260 // Time has advanced since the last call; update the FFT data. 269 // Time has advanced since the last call; update the FFT data.
261 m_lastAnalysisTime = currentTime; 270 m_lastAnalysisTime = currentTime;
262 doFFTAnalysis(); 271 doFFTAnalysis();
263 272
264 convertToByteData(destinationArray); 273 convertToByteData(destinationArray);
265 } 274 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 scaledValue = 0; 333 scaledValue = 0;
325 if (scaledValue > UCHAR_MAX) 334 if (scaledValue > UCHAR_MAX)
326 scaledValue = UCHAR_MAX; 335 scaledValue = UCHAR_MAX;
327 336
328 destination[i] = static_cast<unsigned char>(scaledValue); 337 destination[i] = static_cast<unsigned char>(scaledValue);
329 } 338 }
330 } 339 }
331 } 340 }
332 341
333 } // namespace blink 342 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698