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

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

Issue 1214463003: Split "Online" and "Offline" AudioContext processing (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 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 | Annotate | Revision Log
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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 // Empirically, this has been found to be a good compromise between giving enoug h time for scheduling slop, 50 // Empirically, this has been found to be a good compromise between giving enoug h time for scheduling slop,
51 // while still minimizing the amount of processing done in the primary (high-pri ority) thread. 51 // while still minimizing the amount of processing done in the primary (high-pri ority) thread.
52 // This was found to be a good value on Mac OS X, and may work well on other pla tforms as well, assuming 52 // This was found to be a good value on Mac OS X, and may work well on other pla tforms as well, assuming
53 // the very rough scheduling latencies are similar on these time-scales. Of cou rse, this code may need to be 53 // the very rough scheduling latencies are similar on these time-scales. Of cou rse, this code may need to be
54 // tuned for individual platforms if this assumption is found to be incorrect. 54 // tuned for individual platforms if this assumption is found to be incorrect.
55 const size_t RealtimeFrameLimit = 8192 + 4096; // ~278msec @ 44.1KHz 55 const size_t RealtimeFrameLimit = 8192 + 4096; // ~278msec @ 44.1KHz
56 56
57 const size_t MinFFTSize = 128; 57 const size_t MinFFTSize = 128;
58 const size_t MaxRealtimeFFTSize = 2048; 58 const size_t MaxRealtimeFFTSize = 2048;
59 59
60 ReverbConvolver::ReverbConvolver(AudioChannel* impulseResponse, size_t renderSli ceSize, size_t maxFFTSize, size_t convolverRenderPhase, bool useBackgroundThread s) 60 ReverbConvolver::ReverbConvolver(AudioChannel* impulseResponse, size_t renderSli ceSize, size_t maxFFTSize, size_t convolverRenderPhase, bool hasRealtimeConstrai nt)
61 : m_impulseResponseLength(impulseResponse->length()) 61 : m_impulseResponseLength(impulseResponse->length())
62 , m_accumulationBuffer(impulseResponse->length() + renderSliceSize) 62 , m_accumulationBuffer(impulseResponse->length() + renderSliceSize)
63 , m_inputBuffer(InputBufferSize) 63 , m_inputBuffer(InputBufferSize)
64 , m_minFFTSize(MinFFTSize) // First stage will have this size - successive s tages will double in size each time 64 , m_minFFTSize(MinFFTSize) // First stage will have this size - successive s tages will double in size each time
65 , m_maxFFTSize(maxFFTSize) // until we hit m_maxFFTSize 65 , m_maxFFTSize(maxFFTSize) // until we hit m_maxFFTSize
66 { 66 {
67 // If we are using background threads then don't exceed this FFT size for th e 67 // If we are using background threads then don't exceed this FFT size for th e
68 // stages which run in the real-time thread. This avoids having only one or two 68 // stages which run in the real-time thread. This avoids having only one or two
69 // large stages (size 16384 or so) at the end which take a lot of time every several 69 // large stages (size 16384 or so) at the end which take a lot of time every several
70 // processing slices. This way we amortize the cost over more processing sl ices. 70 // processing slices. This way we amortize the cost over more processing sl ices.
71 m_maxRealtimeFFTSize = MaxRealtimeFFTSize; 71 m_maxRealtimeFFTSize = MaxRealtimeFFTSize;
72 72
73 // For the moment, a good way to know if we have real-time constraint is to check if we're using background threads.
74 // Otherwise, assume we're being run from a command-line tool.
75 bool hasRealtimeConstraint = useBackgroundThreads;
76
77 const float* response = impulseResponse->data(); 73 const float* response = impulseResponse->data();
78 size_t totalResponseLength = impulseResponse->length(); 74 size_t totalResponseLength = impulseResponse->length();
79 75
80 // The total latency is zero because the direct-convolution is used in the l eading portion. 76 // The total latency is zero because the direct-convolution is used in the l eading portion.
81 size_t reverbTotalLatency = 0; 77 size_t reverbTotalLatency = 0;
82 78
83 size_t stageOffset = 0; 79 size_t stageOffset = 0;
84 int i = 0; 80 int i = 0;
85 size_t fftSize = m_minFFTSize; 81 size_t fftSize = m_minFFTSize;
86 while (stageOffset < totalResponseLength) { 82 while (stageOffset < totalResponseLength) {
87 size_t stageSize = fftSize / 2; 83 size_t stageSize = fftSize / 2;
88 84
89 // For the last stage, it's possible that stageOffset is such that we're straddling the end 85 // For the last stage, it's possible that stageOffset is such that we're straddling the end
90 // of the impulse response buffer (if we use stageSize), so reduce the l ast stage's length... 86 // of the impulse response buffer (if we use stageSize), so reduce the l ast stage's length...
91 if (stageSize + stageOffset > totalResponseLength) 87 if (stageSize + stageOffset > totalResponseLength)
92 stageSize = totalResponseLength - stageOffset; 88 stageSize = totalResponseLength - stageOffset;
93 89
94 // This "staggers" the time when each FFT happens so they don't all happ en at the same time 90 // This "staggers" the time when each FFT happens so they don't all happ en at the same time
95 int renderPhase = convolverRenderPhase + i * renderSliceSize; 91 int renderPhase = convolverRenderPhase + i * renderSliceSize;
96 92
97 bool useDirectConvolver = !stageOffset; 93 bool useDirectConvolver = !stageOffset;
98 94
99 OwnPtr<ReverbConvolverStage> stage = adoptPtr(new ReverbConvolverStage(r esponse, totalResponseLength, reverbTotalLatency, stageOffset, stageSize, fftSiz e, renderPhase, renderSliceSize, &m_accumulationBuffer, useDirectConvolver)); 95 OwnPtr<ReverbConvolverStage> stage = adoptPtr(new ReverbConvolverStage(r esponse, totalResponseLength, reverbTotalLatency, stageOffset, stageSize, fftSiz e, renderPhase, renderSliceSize, &m_accumulationBuffer, useDirectConvolver));
100 96
101 bool isBackgroundStage = false; 97 bool isBackgroundStage = false;
102 98
103 if (useBackgroundThreads && stageOffset > RealtimeFrameLimit) { 99 if (hasRealtimeConstraint && stageOffset > RealtimeFrameLimit) {
104 m_backgroundStages.append(stage.release()); 100 m_backgroundStages.append(stage.release());
105 isBackgroundStage = true; 101 isBackgroundStage = true;
106 } else 102 } else
107 m_stages.append(stage.release()); 103 m_stages.append(stage.release());
108 104
109 stageOffset += stageSize; 105 stageOffset += stageSize;
110 ++i; 106 ++i;
111 107
112 if (!useDirectConvolver) { 108 if (!useDirectConvolver) {
113 // Figure out next FFT size 109 // Figure out next FFT size
114 fftSize *= 2; 110 fftSize *= 2;
115 } 111 }
116 112
117 if (hasRealtimeConstraint && !isBackgroundStage && fftSize > m_maxRealti meFFTSize) 113 if (hasRealtimeConstraint && !isBackgroundStage && fftSize > m_maxRealti meFFTSize)
118 fftSize = m_maxRealtimeFFTSize; 114 fftSize = m_maxRealtimeFFTSize;
119 if (fftSize > m_maxFFTSize) 115 if (fftSize > m_maxFFTSize)
120 fftSize = m_maxFFTSize; 116 fftSize = m_maxFFTSize;
121 } 117 }
122 118
123 // Start up background thread 119 // Start up background thread
124 // FIXME: would be better to up the thread priority here. It doesn't need t o be real-time, but higher than the default... 120 // FIXME: would be better to up the thread priority here. It doesn't need t o be real-time, but higher than the default...
125 if (useBackgroundThreads && m_backgroundStages.size() > 0) 121 if (hasRealtimeConstraint && m_backgroundStages.size() > 0)
126 m_backgroundThread = adoptPtr(Platform::current()->createThread("Reverb convolution background thread")); 122 m_backgroundThread = adoptPtr(Platform::current()->createThread("Reverb convolution background thread"));
127 } 123 }
128 124
129 ReverbConvolver::~ReverbConvolver() 125 ReverbConvolver::~ReverbConvolver()
130 { 126 {
131 // Wait for background thread to stop 127 // Wait for background thread to stop
132 m_backgroundThread.clear(); 128 m_backgroundThread.clear();
133 } 129 }
134 130
135 void ReverbConvolver::processInBackground() 131 void ReverbConvolver::processInBackground()
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 } 189 }
194 190
195 size_t ReverbConvolver::latencyFrames() const 191 size_t ReverbConvolver::latencyFrames() const
196 { 192 {
197 return 0; 193 return 0;
198 } 194 }
199 195
200 } // namespace blink 196 } // namespace blink
201 197
202 #endif // ENABLE(WEB_AUDIO) 198 #endif // ENABLE(WEB_AUDIO)
OLDNEW
« Source/platform/audio/Reverb.h ('K') | « Source/platform/audio/ReverbConvolver.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698