Chromium Code Reviews| 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..46e4d2f80e069dd4276cfa2898cd7938354fe40f 100644 |
| --- a/third_party/WebKit/Source/platform/audio/Reverb.cpp |
| +++ b/third_party/WebKit/Source/platform/audio/Reverb.cpp |
| @@ -116,18 +116,21 @@ Reverb::Reverb(AudioBus* impulseResponse, |
| void Reverb::initialize(AudioBus* impulseResponseBuffer, |
| size_t renderSliceSize, |
| size_t maxFFTSize, |
| - size_t numberOfChannels, |
| + size_t numberOfResponseChannels, |
| bool useBackgroundThreads) { |
| m_impulseResponseLength = impulseResponseBuffer->length(); |
| + m_numberOfResponseChannels = numberOfResponseChannels; |
| // The reverb can handle a mono impulse response and still do stereo |
| - // processing |
| + // processing. |
| size_t numResponseChannels = impulseResponseBuffer->numberOfChannels(); |
|
hongchan
2017/03/28 19:01:44
How this |numResponseChannels| is different from |
Raymond Toy
2017/03/28 20:18:02
Good point. I don't think there is anymore and num
|
| - m_convolvers.reserveCapacity(numberOfChannels); |
| + size_t numConvolvers = std::max(numResponseChannels, static_cast<size_t>(2)); |
|
hongchan
2017/03/28 19:01:44
If |numResponseChannel| is unsigned we don't need
|
| + m_convolvers.reserveCapacity(numConvolvers); |
|
hongchan
2017/03/28 19:01:44
Then we can do .reserveCapacity(static_cast<size_t
Raymond Toy
2017/03/28 20:18:02
This is ok. Just means we also need more casting i
|
| int convolverRenderPhase = 0; |
| - for (size_t i = 0; i < numResponseChannels; ++i) { |
| - AudioChannel* channel = impulseResponseBuffer->channel(i); |
| + for (size_t i = 0; i < numConvolvers; ++i) { |
| + AudioChannel* channel = |
| + impulseResponseBuffer->channel(std::min(i, numResponseChannels - 1)); |
| std::unique_ptr<ReverbConvolver> convolver = WTF::wrapUnique( |
| new ReverbConvolver(channel, renderSliceSize, maxFFTSize, |
| @@ -173,11 +176,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 +219,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 +251,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 +273,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(); |
| } |
| } |