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

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

Issue 2159403002: Replace ASSERT with DCHECK in WebAudio (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 4 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 , m_smoothingTimeConstant(DefaultSmoothingTimeConstant) 53 , m_smoothingTimeConstant(DefaultSmoothingTimeConstant)
54 , m_minDecibels(DefaultMinDecibels) 54 , m_minDecibels(DefaultMinDecibels)
55 , m_maxDecibels(DefaultMaxDecibels) 55 , m_maxDecibels(DefaultMaxDecibels)
56 , m_lastAnalysisTime(-1) 56 , m_lastAnalysisTime(-1)
57 { 57 {
58 m_analysisFrame = wrapUnique(new FFTFrame(DefaultFFTSize)); 58 m_analysisFrame = wrapUnique(new FFTFrame(DefaultFFTSize));
59 } 59 }
60 60
61 bool RealtimeAnalyser::setFftSize(size_t size) 61 bool RealtimeAnalyser::setFftSize(size_t size)
62 { 62 {
63 ASSERT(isMainThread()); 63 DCHECK(isMainThread());
64 64
65 // Only allow powers of two. 65 // Only allow powers of two.
66 unsigned log2size = static_cast<unsigned>(log2(size)); 66 unsigned log2size = static_cast<unsigned>(log2(size));
67 bool isPOT(1UL << log2size == size); 67 bool isPOT(1UL << log2size == size);
68 68
69 if (!isPOT || size > MaxFFTSize || size < MinFFTSize) 69 if (!isPOT || size > MaxFFTSize || size < MinFFTSize)
70 return false; 70 return false;
71 71
72 if (m_fftSize != size) { 72 if (m_fftSize != size) {
73 m_analysisFrame = wrapUnique(new FFTFrame(size)); 73 m_analysisFrame = wrapUnique(new FFTFrame(size));
74 // m_magnitudeBuffer has size = fftSize / 2 because it contains floats r educed from complex values in m_analysisFrame. 74 // m_magnitudeBuffer has size = fftSize / 2 because it contains floats r educed from complex values in m_analysisFrame.
75 m_magnitudeBuffer.allocate(size / 2); 75 m_magnitudeBuffer.allocate(size / 2);
76 m_fftSize = size; 76 m_fftSize = size;
77 } 77 }
78 78
79 return true; 79 return true;
80 } 80 }
81 81
82 void RealtimeAnalyser::writeInput(AudioBus* bus, size_t framesToProcess) 82 void RealtimeAnalyser::writeInput(AudioBus* bus, size_t framesToProcess)
83 { 83 {
84 bool isBusGood = bus && bus->numberOfChannels() > 0 && bus->channel(0)->leng th() >= framesToProcess; 84 bool isBusGood = bus && bus->numberOfChannels() > 0 && bus->channel(0)->leng th() >= framesToProcess;
85 ASSERT(isBusGood); 85 DCHECK(isBusGood);
86 if (!isBusGood) 86 if (!isBusGood)
87 return; 87 return;
88 88
89 // FIXME : allow to work with non-FFTSize divisible chunking 89 // FIXME : allow to work with non-FFTSize divisible chunking
90 bool isDestinationGood = m_writeIndex < m_inputBuffer.size() && m_writeIndex + framesToProcess <= m_inputBuffer.size(); 90 bool isDestinationGood = m_writeIndex < m_inputBuffer.size() && m_writeIndex + framesToProcess <= m_inputBuffer.size();
91 ASSERT(isDestinationGood); 91 DCHECK(isDestinationGood);
92 if (!isDestinationGood) 92 if (!isDestinationGood)
93 return; 93 return;
94 94
95 // Perform real-time analysis 95 // Perform real-time analysis
96 float* dest = m_inputBuffer.data() + m_writeIndex; 96 float* dest = m_inputBuffer.data() + m_writeIndex;
97 97
98 // Clear the bus and downmix the input according to the down mixing rules. Then save the result 98 // Clear the bus and downmix the input according to the down mixing rules. Then save the result
99 // in the m_inputBuffer at the appropriate place. 99 // in the m_inputBuffer at the appropriate place.
100 m_downMixBus->zero(); 100 m_downMixBus->zero();
101 m_downMixBus->sumFrom(*bus); 101 m_downMixBus->sumFrom(*bus);
102 memcpy(dest, m_downMixBus->channel(0)->data(), framesToProcess * sizeof(*des t)); 102 memcpy(dest, m_downMixBus->channel(0)->data(), framesToProcess * sizeof(*des t));
103 103
104 m_writeIndex += framesToProcess; 104 m_writeIndex += framesToProcess;
105 if (m_writeIndex >= InputBufferSize) 105 if (m_writeIndex >= InputBufferSize)
106 m_writeIndex = 0; 106 m_writeIndex = 0;
107 } 107 }
108 108
109 namespace { 109 namespace {
110 110
111 void applyWindow(float* p, size_t n) 111 void applyWindow(float* p, size_t n)
112 { 112 {
113 ASSERT(isMainThread()); 113 DCHECK(isMainThread());
114 114
115 // Blackman window 115 // Blackman window
116 double alpha = 0.16; 116 double alpha = 0.16;
117 double a0 = 0.5 * (1 - alpha); 117 double a0 = 0.5 * (1 - alpha);
118 double a1 = 0.5; 118 double a1 = 0.5;
119 double a2 = 0.5 * alpha; 119 double a2 = 0.5 * alpha;
120 120
121 for (unsigned i = 0; i < n; ++i) { 121 for (unsigned i = 0; i < n; ++i) {
122 double x = static_cast<double>(i) / static_cast<double>(n); 122 double x = static_cast<double>(i) / static_cast<double>(n);
123 double window = a0 - a1 * cos(twoPiDouble * x) + a2 * cos(twoPiDouble * 2.0 * x); 123 double window = a0 - a1 * cos(twoPiDouble * x) + a2 * cos(twoPiDouble * 2.0 * x);
124 p[i] *= float(window); 124 p[i] *= float(window);
125 } 125 }
126 } 126 }
127 127
128 } // namespace 128 } // namespace
129 129
130 void RealtimeAnalyser::doFFTAnalysis() 130 void RealtimeAnalyser::doFFTAnalysis()
131 { 131 {
132 ASSERT(isMainThread()); 132 DCHECK(isMainThread());
133 133
134 // Unroll the input buffer into a temporary buffer, where we'll apply an ana lysis window followed by an FFT. 134 // Unroll the input buffer into a temporary buffer, where we'll apply an ana lysis window followed by an FFT.
135 size_t fftSize = this->fftSize(); 135 size_t fftSize = this->fftSize();
136 136
137 AudioFloatArray temporaryBuffer(fftSize); 137 AudioFloatArray temporaryBuffer(fftSize);
138 float* inputBuffer = m_inputBuffer.data(); 138 float* inputBuffer = m_inputBuffer.data();
139 float* tempP = temporaryBuffer.data(); 139 float* tempP = temporaryBuffer.data();
140 140
141 // Take the previous fftSize values from the input buffer and copy into the temporary buffer. 141 // Take the previous fftSize values from the input buffer and copy into the temporary buffer.
142 unsigned writeIndex = m_writeIndex; 142 unsigned writeIndex = m_writeIndex;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 for (unsigned i = 0; i < len; ++i) { 189 for (unsigned i = 0; i < len; ++i) {
190 float linearValue = source[i]; 190 float linearValue = source[i];
191 double dbMag = AudioUtilities::linearToDecibels(linearValue); 191 double dbMag = AudioUtilities::linearToDecibels(linearValue);
192 destination[i] = float(dbMag); 192 destination[i] = float(dbMag);
193 } 193 }
194 } 194 }
195 } 195 }
196 196
197 void RealtimeAnalyser::getFloatFrequencyData(DOMFloat32Array* destinationArray, double currentTime) 197 void RealtimeAnalyser::getFloatFrequencyData(DOMFloat32Array* destinationArray, double currentTime)
198 { 198 {
199 ASSERT(isMainThread()); 199 DCHECK(isMainThread());
200 ASSERT(destinationArray); 200 DCHECK(destinationArray);
201 201
202 if (currentTime <= m_lastAnalysisTime) { 202 if (currentTime <= m_lastAnalysisTime) {
203 convertFloatToDb(destinationArray); 203 convertFloatToDb(destinationArray);
204 return; 204 return;
205 } 205 }
206 206
207 // Time has advanced since the last call; update the FFT data. 207 // Time has advanced since the last call; update the FFT data.
208 m_lastAnalysisTime = currentTime; 208 m_lastAnalysisTime = currentTime;
209 doFFTAnalysis(); 209 doFFTAnalysis();
210 210
(...skipping 25 matching lines...) Expand all
236 if (scaledValue > UCHAR_MAX) 236 if (scaledValue > UCHAR_MAX)
237 scaledValue = UCHAR_MAX; 237 scaledValue = UCHAR_MAX;
238 238
239 destination[i] = static_cast<unsigned char>(scaledValue); 239 destination[i] = static_cast<unsigned char>(scaledValue);
240 } 240 }
241 } 241 }
242 } 242 }
243 243
244 void RealtimeAnalyser::getByteFrequencyData(DOMUint8Array* destinationArray, dou ble currentTime) 244 void RealtimeAnalyser::getByteFrequencyData(DOMUint8Array* destinationArray, dou ble currentTime)
245 { 245 {
246 ASSERT(isMainThread()); 246 DCHECK(isMainThread());
247 ASSERT(destinationArray); 247 DCHECK(destinationArray);
248 248
249 if (currentTime <= m_lastAnalysisTime) { 249 if (currentTime <= m_lastAnalysisTime) {
250 // FIXME: Is it worth caching the data so we don't have to do the conver sion every time? 250 // FIXME: Is it worth caching the data so we don't have to do the conver sion every time?
251 // Perhaps not, since we expect many calls in the same rendering quantum . 251 // Perhaps not, since we expect many calls in the same rendering quantum .
252 convertToByteData(destinationArray); 252 convertToByteData(destinationArray);
253 return; 253 return;
254 } 254 }
255 255
256 // Time has advanced since the last call; update the FFT data. 256 // Time has advanced since the last call; update the FFT data.
257 m_lastAnalysisTime = currentTime; 257 m_lastAnalysisTime = currentTime;
258 doFFTAnalysis(); 258 doFFTAnalysis();
259 259
260 convertToByteData(destinationArray); 260 convertToByteData(destinationArray);
261 } 261 }
262 262
263 void RealtimeAnalyser::getFloatTimeDomainData(DOMFloat32Array* destinationArray) 263 void RealtimeAnalyser::getFloatTimeDomainData(DOMFloat32Array* destinationArray)
264 { 264 {
265 ASSERT(isMainThread()); 265 DCHECK(isMainThread());
266 ASSERT(destinationArray); 266 DCHECK(destinationArray);
267 267
268 unsigned fftSize = this->fftSize(); 268 unsigned fftSize = this->fftSize();
269 size_t len = std::min(fftSize, destinationArray->length()); 269 size_t len = std::min(fftSize, destinationArray->length());
270 if (len > 0) { 270 if (len > 0) {
271 bool isInputBufferGood = m_inputBuffer.size() == InputBufferSize && m_in putBuffer.size() > fftSize; 271 bool isInputBufferGood = m_inputBuffer.size() == InputBufferSize && m_in putBuffer.size() > fftSize;
272 ASSERT(isInputBufferGood); 272 DCHECK(isInputBufferGood);
273 if (!isInputBufferGood) 273 if (!isInputBufferGood)
274 return; 274 return;
275 275
276 float* inputBuffer = m_inputBuffer.data(); 276 float* inputBuffer = m_inputBuffer.data();
277 float* destination = destinationArray->data(); 277 float* destination = destinationArray->data();
278 278
279 unsigned writeIndex = m_writeIndex; 279 unsigned writeIndex = m_writeIndex;
280 280
281 for (unsigned i = 0; i < len; ++i) { 281 for (unsigned i = 0; i < len; ++i) {
282 // Buffer access is protected due to modulo operation. 282 // Buffer access is protected due to modulo operation.
283 float value = inputBuffer[(i + writeIndex - fftSize + InputBufferSiz e) % InputBufferSize]; 283 float value = inputBuffer[(i + writeIndex - fftSize + InputBufferSiz e) % InputBufferSize];
284 284
285 destination[i] = value; 285 destination[i] = value;
286 } 286 }
287 } 287 }
288 } 288 }
289 289
290 void RealtimeAnalyser::getByteTimeDomainData(DOMUint8Array* destinationArray) 290 void RealtimeAnalyser::getByteTimeDomainData(DOMUint8Array* destinationArray)
291 { 291 {
292 ASSERT(isMainThread()); 292 DCHECK(isMainThread());
293 ASSERT(destinationArray); 293 DCHECK(destinationArray);
294 294
295 unsigned fftSize = this->fftSize(); 295 unsigned fftSize = this->fftSize();
296 size_t len = std::min(fftSize, destinationArray->length()); 296 size_t len = std::min(fftSize, destinationArray->length());
297 if (len > 0) { 297 if (len > 0) {
298 bool isInputBufferGood = m_inputBuffer.size() == InputBufferSize && m_in putBuffer.size() > fftSize; 298 bool isInputBufferGood = m_inputBuffer.size() == InputBufferSize && m_in putBuffer.size() > fftSize;
299 ASSERT(isInputBufferGood); 299 DCHECK(isInputBufferGood);
300 if (!isInputBufferGood) 300 if (!isInputBufferGood)
301 return; 301 return;
302 302
303 float* inputBuffer = m_inputBuffer.data(); 303 float* inputBuffer = m_inputBuffer.data();
304 unsigned char* destination = destinationArray->data(); 304 unsigned char* destination = destinationArray->data();
305 305
306 unsigned writeIndex = m_writeIndex; 306 unsigned writeIndex = m_writeIndex;
307 307
308 for (unsigned i = 0; i < len; ++i) { 308 for (unsigned i = 0; i < len; ++i) {
309 // Buffer access is protected due to modulo operation. 309 // Buffer access is protected due to modulo operation.
310 float value = inputBuffer[(i + writeIndex - fftSize + InputBufferSiz e) % InputBufferSize]; 310 float value = inputBuffer[(i + writeIndex - fftSize + InputBufferSiz e) % InputBufferSize];
311 311
312 // Scale from nominal -1 -> +1 to unsigned byte. 312 // Scale from nominal -1 -> +1 to unsigned byte.
313 double scaledValue = 128 * (value + 1); 313 double scaledValue = 128 * (value + 1);
314 314
315 // Clip to valid range. 315 // Clip to valid range.
316 if (scaledValue < 0) 316 if (scaledValue < 0)
317 scaledValue = 0; 317 scaledValue = 0;
318 if (scaledValue > UCHAR_MAX) 318 if (scaledValue > UCHAR_MAX)
319 scaledValue = UCHAR_MAX; 319 scaledValue = UCHAR_MAX;
320 320
321 destination[i] = static_cast<unsigned char>(scaledValue); 321 destination[i] = static_cast<unsigned char>(scaledValue);
322 } 322 }
323 } 323 }
324 } 324 }
325 325
326 } // namespace blink 326 } // namespace blink
327 327
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698