| Index: third_party/WebKit/Source/platform/audio/Reverb.cpp
|
| diff --git a/third_party/WebKit/Source/platform/audio/Reverb.cpp b/third_party/WebKit/Source/platform/audio/Reverb.cpp
|
| index 32c62acfe1903e73195d6d4b07786e82819630a9..ac49ad3818e1d9544e4a7c4f75789fed962a4734 100644
|
| --- a/third_party/WebKit/Source/platform/audio/Reverb.cpp
|
| +++ b/third_party/WebKit/Source/platform/audio/Reverb.cpp
|
| @@ -90,7 +90,6 @@ static float calculateNormalizationScale(AudioBus* response) {
|
| Reverb::Reverb(AudioBus* impulseResponse,
|
| size_t renderSliceSize,
|
| size_t maxFFTSize,
|
| - size_t numberOfChannels,
|
| bool useBackgroundThreads,
|
| bool normalize) {
|
| float scale = 1;
|
| @@ -102,7 +101,7 @@ Reverb::Reverb(AudioBus* impulseResponse,
|
| impulseResponse->scale(scale);
|
| }
|
|
|
| - initialize(impulseResponse, renderSliceSize, maxFFTSize, numberOfChannels,
|
| + initialize(impulseResponse, renderSliceSize, maxFFTSize,
|
| useBackgroundThreads);
|
|
|
| // Undo scaling since this shouldn't be a destructive operation on
|
| @@ -116,18 +115,19 @@ Reverb::Reverb(AudioBus* impulseResponse,
|
| void Reverb::initialize(AudioBus* impulseResponseBuffer,
|
| size_t renderSliceSize,
|
| size_t maxFFTSize,
|
| - size_t numberOfChannels,
|
| bool useBackgroundThreads) {
|
| m_impulseResponseLength = impulseResponseBuffer->length();
|
| + m_numberOfResponseChannels = impulseResponseBuffer->numberOfChannels();
|
|
|
| // The reverb can handle a mono impulse response and still do stereo
|
| - // processing
|
| - size_t numResponseChannels = impulseResponseBuffer->numberOfChannels();
|
| - m_convolvers.reserveCapacity(numberOfChannels);
|
| + // processing.
|
| + unsigned numConvolvers = std::max(m_numberOfResponseChannels, 2u);
|
| + m_convolvers.reserveCapacity(numConvolvers);
|
|
|
| int convolverRenderPhase = 0;
|
| - for (size_t i = 0; i < numResponseChannels; ++i) {
|
| - AudioChannel* channel = impulseResponseBuffer->channel(i);
|
| + for (unsigned i = 0; i < numConvolvers; ++i) {
|
| + AudioChannel* channel = impulseResponseBuffer->channel(
|
| + std::min(i, m_numberOfResponseChannels - 1));
|
|
|
| std::unique_ptr<ReverbConvolver> convolver = WTF::wrapUnique(
|
| new ReverbConvolver(channel, renderSliceSize, maxFFTSize,
|
| @@ -140,7 +140,7 @@ void Reverb::initialize(AudioBus* impulseResponseBuffer,
|
| // For "True" stereo processing we allocate a temporary buffer to avoid
|
| // repeatedly allocating it in the process() method. It can be bad to
|
| // allocate memory in a real-time thread.
|
| - if (numResponseChannels == 4)
|
| + if (m_numberOfResponseChannels == 4)
|
| m_tempBuffer = AudioBus::create(2, MaxFrameSize);
|
| }
|
|
|
| @@ -173,11 +173,42 @@ void Reverb::process(const AudioBus* sourceBus,
|
| // Handle input -> output matrixing...
|
| size_t numInputChannels = sourceBus->numberOfChannels();
|
| size_t numOutputChannels = destinationBus->numberOfChannels();
|
| - size_t numReverbChannels = m_convolvers.size();
|
| -
|
| - if (numInputChannels == 2 && numReverbChannels == 2 &&
|
| + size_t numberOfResponseChannels = m_numberOfResponseChannels;
|
| +
|
| + DCHECK_LE(numInputChannels, 2ul);
|
| + DCHECK_LE(numOutputChannels, 2ul);
|
| + DCHECK(numberOfResponseChannels == 1 || numberOfResponseChannels == 2 ||
|
| + numberOfResponseChannels == 4);
|
| +
|
| + // These are the possible combinations of number inputs, response
|
| + // channels and outputs channels that need to be supported:
|
| + //
|
| + // numInputChannels: 1 or 2
|
| + // numberOfResponseChannels: 1, 2, or 4
|
| + // numOutputChannels: 1 or 2
|
| + //
|
| + // Not all possible combinations are valid. numOutputChannels is
|
| + // one only if both numInputChannels and numberOfResponseChannels are 1.
|
| + // Otherwise numOutputChannels MUST be 2.
|
| + //
|
| + // The valid combinations are
|
| + //
|
| + // Case in -> resp -> out
|
| + // 1 1 -> 1 -> 1
|
| + // 2 1 -> 2 -> 2
|
| + // 3 1 -> 4 -> 2
|
| + // 4 2 -> 1 -> 2
|
| + // 5 2 -> 2 -> 2
|
| + // 6 2 -> 4 -> 2
|
| +
|
| + if (numInputChannels == 2 &&
|
| + (numberOfResponseChannels == 1 || numberOfResponseChannels == 2) &&
|
| numOutputChannels == 2) {
|
| - // 2 -> 2 -> 2
|
| + // Case 4 and 5: 2 -> 2 -> 2 or 2 -> 1 -> 2.
|
| + //
|
| + // These can be handled in the same way because in the latter
|
| + // case, two connvolvers are still created with the second being a
|
| + // copy of the first.
|
| const AudioChannel* sourceChannelR = sourceBus->channel(1);
|
| AudioChannel* destinationChannelR = destinationBus->channel(1);
|
| m_convolvers[0]->process(sourceChannelL, destinationChannelL,
|
| @@ -185,38 +216,21 @@ void Reverb::process(const AudioBus* sourceBus,
|
| m_convolvers[1]->process(sourceChannelR, destinationChannelR,
|
| framesToProcess);
|
| } else if (numInputChannels == 1 && numOutputChannels == 2 &&
|
| - numReverbChannels == 2) {
|
| - // 1 -> 2 -> 2
|
| + numberOfResponseChannels == 2) {
|
| + // Case 2: 1 -> 2 -> 2
|
| for (int i = 0; i < 2; ++i) {
|
| AudioChannel* destinationChannel = destinationBus->channel(i);
|
| m_convolvers[i]->process(sourceChannelL, destinationChannel,
|
| framesToProcess);
|
| }
|
| - } else if (numInputChannels == 1 && numReverbChannels == 1 &&
|
| - numOutputChannels == 2) {
|
| - // 1 -> 1 -> 2
|
| - m_convolvers[0]->process(sourceChannelL, destinationChannelL,
|
| - framesToProcess);
|
| -
|
| - // simply copy L -> R
|
| - AudioChannel* destinationChannelR = destinationBus->channel(1);
|
| - bool isCopySafe = destinationChannelL->data() &&
|
| - destinationChannelR->data() &&
|
| - destinationChannelL->length() >= framesToProcess &&
|
| - destinationChannelR->length() >= framesToProcess;
|
| - ASSERT(isCopySafe);
|
| - if (!isCopySafe)
|
| - return;
|
| - memcpy(destinationChannelR->mutableData(), destinationChannelL->data(),
|
| - sizeof(float) * framesToProcess);
|
| - } else if (numInputChannels == 1 && numReverbChannels == 1 &&
|
| - numOutputChannels == 1) {
|
| - // 1 -> 1 -> 1
|
| + } else if (numInputChannels == 1 && numberOfResponseChannels == 1) {
|
| + // Case 1: 1 -> 1 -> 1
|
| + DCHECK_EQ(numOutputChannels, 1ul);
|
| m_convolvers[0]->process(sourceChannelL, destinationChannelL,
|
| framesToProcess);
|
| - } else if (numInputChannels == 2 && numReverbChannels == 4 &&
|
| + } else if (numInputChannels == 2 && numberOfResponseChannels == 4 &&
|
| numOutputChannels == 2) {
|
| - // 2 -> 4 -> 2 ("True" stereo)
|
| + // Case 6: 2 -> 4 -> 2 ("True" stereo)
|
| const AudioChannel* sourceChannelR = sourceBus->channel(1);
|
| AudioChannel* destinationChannelR = destinationBus->channel(1);
|
|
|
| @@ -234,11 +248,11 @@ void Reverb::process(const AudioBus* sourceBus,
|
| m_convolvers[3]->process(sourceChannelR, tempChannelR, framesToProcess);
|
|
|
| destinationBus->sumFrom(*m_tempBuffer);
|
| - } else if (numInputChannels == 1 && numReverbChannels == 4 &&
|
| + } else if (numInputChannels == 1 && numberOfResponseChannels == 4 &&
|
| numOutputChannels == 2) {
|
| - // 1 -> 4 -> 2 (Processing mono with "True" stereo impulse response)
|
| - // This is an inefficient use of a four-channel impulse response, but we
|
| - // should handle the case.
|
| + // Case 3: 1 -> 4 -> 2 (Processing mono with "True" stereo impulse
|
| + // response) This is an inefficient use of a four-channel impulse
|
| + // response, but we should handle the case.
|
| AudioChannel* destinationChannelR = destinationBus->channel(1);
|
|
|
| AudioChannel* tempChannelL = m_tempBuffer->channel(0);
|
| @@ -256,8 +270,7 @@ void Reverb::process(const AudioBus* sourceBus,
|
|
|
| destinationBus->sumFrom(*m_tempBuffer);
|
| } else {
|
| - // Handle gracefully any unexpected / unsupported matrixing
|
| - // FIXME: add code for 5.1 support...
|
| + NOTREACHED();
|
| destinationBus->zero();
|
| }
|
| }
|
|
|