| OLD | NEW |
| 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 void FFTConvolver::process(FFTFrame* fftKernel, | 43 void FFTConvolver::process(FFTFrame* fftKernel, |
| 44 const float* sourceP, | 44 const float* sourceP, |
| 45 float* destP, | 45 float* destP, |
| 46 size_t framesToProcess) { | 46 size_t framesToProcess) { |
| 47 size_t halfSize = fftSize() / 2; | 47 size_t halfSize = fftSize() / 2; |
| 48 | 48 |
| 49 // framesToProcess must be an exact multiple of halfSize, | 49 // framesToProcess must be an exact multiple of halfSize, |
| 50 // or halfSize is a multiple of framesToProcess when halfSize > | 50 // or halfSize is a multiple of framesToProcess when halfSize > |
| 51 // framesToProcess. | 51 // framesToProcess. |
| 52 bool isGood = !(halfSize % framesToProcess && framesToProcess % halfSize); | 52 bool isGood = !(halfSize % framesToProcess && framesToProcess % halfSize); |
| 53 ASSERT(isGood); | 53 DCHECK(isGood); |
| 54 if (!isGood) | 54 if (!isGood) |
| 55 return; | 55 return; |
| 56 | 56 |
| 57 size_t numberOfDivisions = | 57 size_t numberOfDivisions = |
| 58 halfSize <= framesToProcess ? (framesToProcess / halfSize) : 1; | 58 halfSize <= framesToProcess ? (framesToProcess / halfSize) : 1; |
| 59 size_t divisionSize = numberOfDivisions == 1 ? framesToProcess : halfSize; | 59 size_t divisionSize = numberOfDivisions == 1 ? framesToProcess : halfSize; |
| 60 | 60 |
| 61 for (size_t i = 0; i < numberOfDivisions; | 61 for (size_t i = 0; i < numberOfDivisions; |
| 62 ++i, sourceP += divisionSize, destP += divisionSize) { | 62 ++i, sourceP += divisionSize, destP += divisionSize) { |
| 63 // Copy samples to input buffer (note contraint above!) | 63 // Copy samples to input buffer (note contraint above!) |
| 64 float* inputP = m_inputBuffer.data(); | 64 float* inputP = m_inputBuffer.data(); |
| 65 | 65 |
| 66 // Sanity check | 66 // Sanity check |
| 67 bool isCopyGood1 = sourceP && inputP && | 67 bool isCopyGood1 = sourceP && inputP && |
| 68 m_readWriteIndex + divisionSize <= m_inputBuffer.size(); | 68 m_readWriteIndex + divisionSize <= m_inputBuffer.size(); |
| 69 ASSERT(isCopyGood1); | 69 DCHECK(isCopyGood1); |
| 70 if (!isCopyGood1) | 70 if (!isCopyGood1) |
| 71 return; | 71 return; |
| 72 | 72 |
| 73 memcpy(inputP + m_readWriteIndex, sourceP, sizeof(float) * divisionSize); | 73 memcpy(inputP + m_readWriteIndex, sourceP, sizeof(float) * divisionSize); |
| 74 | 74 |
| 75 // Copy samples from output buffer | 75 // Copy samples from output buffer |
| 76 float* outputP = m_outputBuffer.data(); | 76 float* outputP = m_outputBuffer.data(); |
| 77 | 77 |
| 78 // Sanity check | 78 // Sanity check |
| 79 bool isCopyGood2 = destP && outputP && | 79 bool isCopyGood2 = destP && outputP && |
| 80 m_readWriteIndex + divisionSize <= m_outputBuffer.size(); | 80 m_readWriteIndex + divisionSize <= m_outputBuffer.size(); |
| 81 ASSERT(isCopyGood2); | 81 DCHECK(isCopyGood2); |
| 82 if (!isCopyGood2) | 82 if (!isCopyGood2) |
| 83 return; | 83 return; |
| 84 | 84 |
| 85 memcpy(destP, outputP + m_readWriteIndex, sizeof(float) * divisionSize); | 85 memcpy(destP, outputP + m_readWriteIndex, sizeof(float) * divisionSize); |
| 86 m_readWriteIndex += divisionSize; | 86 m_readWriteIndex += divisionSize; |
| 87 | 87 |
| 88 // Check if it's time to perform the next FFT | 88 // Check if it's time to perform the next FFT |
| 89 if (m_readWriteIndex == halfSize) { | 89 if (m_readWriteIndex == halfSize) { |
| 90 // The input buffer is now filled (get frequency-domain version) | 90 // The input buffer is now filled (get frequency-domain version) |
| 91 m_frame.doFFT(m_inputBuffer.data()); | 91 m_frame.doFFT(m_inputBuffer.data()); |
| 92 m_frame.multiply(*fftKernel); | 92 m_frame.multiply(*fftKernel); |
| 93 m_frame.doInverseFFT(m_outputBuffer.data()); | 93 m_frame.doInverseFFT(m_outputBuffer.data()); |
| 94 | 94 |
| 95 // Overlap-add 1st half from previous time | 95 // Overlap-add 1st half from previous time |
| 96 vadd(m_outputBuffer.data(), 1, m_lastOverlapBuffer.data(), 1, | 96 vadd(m_outputBuffer.data(), 1, m_lastOverlapBuffer.data(), 1, |
| 97 m_outputBuffer.data(), 1, halfSize); | 97 m_outputBuffer.data(), 1, halfSize); |
| 98 | 98 |
| 99 // Finally, save 2nd half of result | 99 // Finally, save 2nd half of result |
| 100 bool isCopyGood3 = m_outputBuffer.size() == 2 * halfSize && | 100 bool isCopyGood3 = m_outputBuffer.size() == 2 * halfSize && |
| 101 m_lastOverlapBuffer.size() == halfSize; | 101 m_lastOverlapBuffer.size() == halfSize; |
| 102 ASSERT(isCopyGood3); | 102 DCHECK(isCopyGood3); |
| 103 if (!isCopyGood3) | 103 if (!isCopyGood3) |
| 104 return; | 104 return; |
| 105 | 105 |
| 106 memcpy(m_lastOverlapBuffer.data(), m_outputBuffer.data() + halfSize, | 106 memcpy(m_lastOverlapBuffer.data(), m_outputBuffer.data() + halfSize, |
| 107 sizeof(float) * halfSize); | 107 sizeof(float) * halfSize); |
| 108 | 108 |
| 109 // Reset index back to start for next time | 109 // Reset index back to start for next time |
| 110 m_readWriteIndex = 0; | 110 m_readWriteIndex = 0; |
| 111 } | 111 } |
| 112 } | 112 } |
| 113 } | 113 } |
| 114 | 114 |
| 115 void FFTConvolver::reset() { | 115 void FFTConvolver::reset() { |
| 116 m_lastOverlapBuffer.zero(); | 116 m_lastOverlapBuffer.zero(); |
| 117 m_readWriteIndex = 0; | 117 m_readWriteIndex = 0; |
| 118 } | 118 } |
| 119 | 119 |
| 120 } // namespace blink | 120 } // namespace blink |
| OLD | NEW |