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

Side by Side Diff: third_party/WebKit/Source/platform/audio/ReverbConvolver.cpp

Issue 2384073002: reflow comments in platform/audio (Closed)
Patch Set: comments (heh!) 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 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 26 matching lines...) Expand all
37 #include "public/platform/WebTraceLocation.h" 37 #include "public/platform/WebTraceLocation.h"
38 #include "wtf/PtrUtil.h" 38 #include "wtf/PtrUtil.h"
39 #include <memory> 39 #include <memory>
40 40
41 namespace blink { 41 namespace blink {
42 42
43 using namespace VectorMath; 43 using namespace VectorMath;
44 44
45 const int InputBufferSize = 8 * 16384; 45 const int InputBufferSize = 8 * 16384;
46 46
47 // We only process the leading portion of the impulse response in the real-time thread. We don't exceed this length. 47 // We only process the leading portion of the impulse response in the real-time
48 // It turns out then, that the background thread has about 278msec of scheduling slop. 48 // thread. We don't exceed this length. It turns out then, that the
49 // Empirically, this has been found to be a good compromise between giving enoug h time for scheduling slop, 49 // background thread has about 278msec of scheduling slop. Empirically, this
50 // while still minimizing the amount of processing done in the primary (high-pri ority) thread. 50 // has been found to be a good compromise between giving enough time for
51 // This was found to be a good value on Mac OS X, and may work well on other pla tforms as well, assuming 51 // scheduling slop, while still minimizing the amount of processing done in the
52 // the very rough scheduling latencies are similar on these time-scales. Of cou rse, this code may need to be 52 // primary (high-priority) thread. This was found to be a good value on Mac OS
53 // tuned for individual platforms if this assumption is found to be incorrect. 53 // X, and may work well on other platforms as well, assuming the very rough
54 // scheduling latencies are similar on these time-scales. Of course, this code
55 // may need to be tuned for individual platforms if this assumption is found to
56 // be incorrect.
54 const size_t RealtimeFrameLimit = 8192 + 4096; // ~278msec @ 44.1KHz 57 const size_t RealtimeFrameLimit = 8192 + 4096; // ~278msec @ 44.1KHz
55 58
56 const size_t MinFFTSize = 128; 59 const size_t MinFFTSize = 128;
57 const size_t MaxRealtimeFFTSize = 2048; 60 const size_t MaxRealtimeFFTSize = 2048;
58 61
59 ReverbConvolver::ReverbConvolver(AudioChannel* impulseResponse, 62 ReverbConvolver::ReverbConvolver(AudioChannel* impulseResponse,
60 size_t renderSliceSize, 63 size_t renderSliceSize,
61 size_t maxFFTSize, 64 size_t maxFFTSize,
62 size_t convolverRenderPhase, 65 size_t convolverRenderPhase,
63 bool useBackgroundThreads) 66 bool useBackgroundThreads)
64 : m_impulseResponseLength(impulseResponse->length()), 67 : m_impulseResponseLength(impulseResponse->length()),
65 m_accumulationBuffer(impulseResponse->length() + renderSliceSize), 68 m_accumulationBuffer(impulseResponse->length() + renderSliceSize),
66 m_inputBuffer(InputBufferSize), 69 m_inputBuffer(InputBufferSize),
67 m_minFFTSize( 70 m_minFFTSize(MinFFTSize), // First stage will have this size - successive
68 MinFFTSize) // First stage will have this size - successive stages wi ll double in size each time 71 // stages will double in size each time
69 , 72 m_maxFFTSize(maxFFTSize) // until we hit m_maxFFTSize
70 m_maxFFTSize(maxFFTSize) // until we hit m_maxFFTSize
71 { 73 {
72 // If we are using background threads then don't exceed this FFT size for the 74 // If we are using background threads then don't exceed this FFT size for the
73 // stages which run in the real-time thread. This avoids having only one or t wo 75 // stages which run in the real-time thread. This avoids having only one or
74 // large stages (size 16384 or so) at the end which take a lot of time every s everal 76 // two large stages (size 16384 or so) at the end which take a lot of time
75 // processing slices. This way we amortize the cost over more processing slic es. 77 // every several processing slices. This way we amortize the cost over more
78 // processing slices.
76 m_maxRealtimeFFTSize = MaxRealtimeFFTSize; 79 m_maxRealtimeFFTSize = MaxRealtimeFFTSize;
77 80
78 const float* response = impulseResponse->data(); 81 const float* response = impulseResponse->data();
79 size_t totalResponseLength = impulseResponse->length(); 82 size_t totalResponseLength = impulseResponse->length();
80 83
81 // The total latency is zero because the direct-convolution is used in the lea ding portion. 84 // The total latency is zero because the direct-convolution is used in the
85 // leading portion.
82 size_t reverbTotalLatency = 0; 86 size_t reverbTotalLatency = 0;
83 87
84 size_t stageOffset = 0; 88 size_t stageOffset = 0;
85 int i = 0; 89 int i = 0;
86 size_t fftSize = m_minFFTSize; 90 size_t fftSize = m_minFFTSize;
87 while (stageOffset < totalResponseLength) { 91 while (stageOffset < totalResponseLength) {
88 size_t stageSize = fftSize / 2; 92 size_t stageSize = fftSize / 2;
89 93
90 // For the last stage, it's possible that stageOffset is such that we're str addling the end 94 // For the last stage, it's possible that stageOffset is such that we're
91 // of the impulse response buffer (if we use stageSize), so reduce the last stage's length... 95 // straddling the end of the impulse response buffer (if we use stageSize),
96 // so reduce the last stage's length...
92 if (stageSize + stageOffset > totalResponseLength) 97 if (stageSize + stageOffset > totalResponseLength)
93 stageSize = totalResponseLength - stageOffset; 98 stageSize = totalResponseLength - stageOffset;
94 99
95 // This "staggers" the time when each FFT happens so they don't all happen a t the same time 100 // This "staggers" the time when each FFT happens so they don't all happen
101 // at the same time
96 int renderPhase = convolverRenderPhase + i * renderSliceSize; 102 int renderPhase = convolverRenderPhase + i * renderSliceSize;
97 103
98 bool useDirectConvolver = !stageOffset; 104 bool useDirectConvolver = !stageOffset;
99 105
100 std::unique_ptr<ReverbConvolverStage> stage = 106 std::unique_ptr<ReverbConvolverStage> stage =
101 wrapUnique(new ReverbConvolverStage( 107 wrapUnique(new ReverbConvolverStage(
102 response, totalResponseLength, reverbTotalLatency, stageOffset, 108 response, totalResponseLength, reverbTotalLatency, stageOffset,
103 stageSize, fftSize, renderPhase, renderSliceSize, 109 stageSize, fftSize, renderPhase, renderSliceSize,
104 &m_accumulationBuffer, useDirectConvolver)); 110 &m_accumulationBuffer, useDirectConvolver));
105 111
(...skipping 15 matching lines...) Expand all
121 } 127 }
122 128
123 if (useBackgroundThreads && !isBackgroundStage && 129 if (useBackgroundThreads && !isBackgroundStage &&
124 fftSize > m_maxRealtimeFFTSize) 130 fftSize > m_maxRealtimeFFTSize)
125 fftSize = m_maxRealtimeFFTSize; 131 fftSize = m_maxRealtimeFFTSize;
126 if (fftSize > m_maxFFTSize) 132 if (fftSize > m_maxFFTSize)
127 fftSize = m_maxFFTSize; 133 fftSize = m_maxFFTSize;
128 } 134 }
129 135
130 // Start up background thread 136 // Start up background thread
131 // FIXME: would be better to up the thread priority here. It doesn't need to be real-time, but higher than the default... 137 // FIXME: would be better to up the thread priority here. It doesn't need to
138 // be real-time, but higher than the default...
132 if (useBackgroundThreads && m_backgroundStages.size() > 0) 139 if (useBackgroundThreads && m_backgroundStages.size() > 0)
133 m_backgroundThread = wrapUnique(Platform::current()->createThread( 140 m_backgroundThread = wrapUnique(Platform::current()->createThread(
134 "Reverb convolution background thread")); 141 "Reverb convolution background thread"));
135 } 142 }
136 143
137 ReverbConvolver::~ReverbConvolver() { 144 ReverbConvolver::~ReverbConvolver() {
138 // Wait for background thread to stop 145 // Wait for background thread to stop
139 m_backgroundThread.reset(); 146 m_backgroundThread.reset();
140 } 147 }
141 148
142 void ReverbConvolver::processInBackground() { 149 void ReverbConvolver::processInBackground() {
143 // Process all of the stages until their read indices reach the input buffer's write index 150 // Process all of the stages until their read indices reach the input buffer's
151 // write index
144 int writeIndex = m_inputBuffer.writeIndex(); 152 int writeIndex = m_inputBuffer.writeIndex();
145 153
146 // Even though it doesn't seem like every stage needs to maintain its own vers ion of readIndex 154 // Even though it doesn't seem like every stage needs to maintain its own
147 // we do this in case we want to run in more than one background thread. 155 // version of readIndex we do this in case we want to run in more than one
156 // background thread.
148 int readIndex; 157 int readIndex;
149 158
150 while ((readIndex = m_backgroundStages[0]->inputReadIndex()) != 159 while ((readIndex = m_backgroundStages[0]->inputReadIndex()) !=
151 writeIndex) { // FIXME: do better to detect buffer overrun... 160 writeIndex) { // FIXME: do better to detect buffer overrun...
152 // The ReverbConvolverStages need to process in amounts which evenly divide half the FFT size 161 // The ReverbConvolverStages need to process in amounts which evenly divide
162 // half the FFT size
153 const int SliceSize = MinFFTSize / 2; 163 const int SliceSize = MinFFTSize / 2;
154 164
155 // Accumulate contributions from each stage 165 // Accumulate contributions from each stage
156 for (size_t i = 0; i < m_backgroundStages.size(); ++i) 166 for (size_t i = 0; i < m_backgroundStages.size(); ++i)
157 m_backgroundStages[i]->processInBackground(this, SliceSize); 167 m_backgroundStages[i]->processInBackground(this, SliceSize);
158 } 168 }
159 } 169 }
160 170
161 void ReverbConvolver::process(const AudioChannel* sourceChannel, 171 void ReverbConvolver::process(const AudioChannel* sourceChannel,
162 AudioChannel* destinationChannel, 172 AudioChannel* destinationChannel,
(...skipping 15 matching lines...) Expand all
178 // Feed input buffer (read by all threads) 188 // Feed input buffer (read by all threads)
179 m_inputBuffer.write(source, framesToProcess); 189 m_inputBuffer.write(source, framesToProcess);
180 190
181 // Accumulate contributions from each stage 191 // Accumulate contributions from each stage
182 for (size_t i = 0; i < m_stages.size(); ++i) 192 for (size_t i = 0; i < m_stages.size(); ++i)
183 m_stages[i]->process(source, framesToProcess); 193 m_stages[i]->process(source, framesToProcess);
184 194
185 // Finally read from accumulation buffer 195 // Finally read from accumulation buffer
186 m_accumulationBuffer.readAndClear(destination, framesToProcess); 196 m_accumulationBuffer.readAndClear(destination, framesToProcess);
187 197
188 // Now that we've buffered more input, post another task to the background thr ead. 198 // Now that we've buffered more input, post another task to the background
199 // thread.
189 if (m_backgroundThread) 200 if (m_backgroundThread)
190 m_backgroundThread->getWebTaskRunner()->postTask( 201 m_backgroundThread->getWebTaskRunner()->postTask(
191 BLINK_FROM_HERE, crossThreadBind(&ReverbConvolver::processInBackground, 202 BLINK_FROM_HERE, crossThreadBind(&ReverbConvolver::processInBackground,
192 crossThreadUnretained(this))); 203 crossThreadUnretained(this)));
193 } 204 }
194 205
195 void ReverbConvolver::reset() { 206 void ReverbConvolver::reset() {
196 for (size_t i = 0; i < m_stages.size(); ++i) 207 for (size_t i = 0; i < m_stages.size(); ++i)
197 m_stages[i]->reset(); 208 m_stages[i]->reset();
198 209
199 for (size_t i = 0; i < m_backgroundStages.size(); ++i) 210 for (size_t i = 0; i < m_backgroundStages.size(); ++i)
200 m_backgroundStages[i]->reset(); 211 m_backgroundStages[i]->reset();
201 212
202 m_accumulationBuffer.reset(); 213 m_accumulationBuffer.reset();
203 m_inputBuffer.reset(); 214 m_inputBuffer.reset();
204 } 215 }
205 216
206 size_t ReverbConvolver::latencyFrames() const { 217 size_t ReverbConvolver::latencyFrames() const {
207 return 0; 218 return 0;
208 } 219 }
209 220
210 } // namespace blink 221 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698