Optimize for IPP in DirectConvolver::process()
[WebKit-https.git] / Source / WebCore / platform / audio / DirectConvolver.cpp
index 39f3e5c3b711d3f302cac77209b95f4257337716..f2906ebcd1100e95bc48a06dcd43299d783ebf3d 100644 (file)
@@ -40,14 +40,15 @@ using namespace VectorMath;
     
 DirectConvolver::DirectConvolver(size_t inputBlockSize)
     : m_inputBlockSize(inputBlockSize)
-    , m_inputBuffer(inputBlockSize * 2)
+#if USE(WEBAUDIO_IPP)
+    , m_overlayBuffer(inputBlockSize)
+#endif // USE(WEBAUDIO_IPP)
+    , m_buffer(inputBlockSize * 2)
 {
 }
 
 void DirectConvolver::process(AudioFloatArray* convolutionKernel, const float* sourceP, float* destP, size_t framesToProcess)
 {
-    // FIXME: Optimize for IPP, reverb function in IPP library can be used here.
-    // https://bugs.webkit.org/show_bug.cgi?id=80255
     // FIXME: Optimize for DARWIN, conv() function in Accelerate.framework can be used here.
     // https://bugs.webkit.org/show_bug.cgi?id=80256
 
@@ -63,14 +64,27 @@ void DirectConvolver::process(AudioFloatArray* convolutionKernel, const float* s
 
     float* kernelP = convolutionKernel->data();
 
-    float* inputP = m_inputBuffer.data() + m_inputBlockSize;
-
     // Sanity check
-    bool isCopyGood = kernelP && sourceP && destP && m_inputBuffer.data();
+    bool isCopyGood = kernelP && sourceP && destP && m_buffer.data();
     ASSERT(isCopyGood);
     if (!isCopyGood)
         return;
 
+#if USE(WEBAUDIO_IPP)
+    float* outputBuffer = m_buffer.data();
+    float* overlayBuffer = m_overlayBuffer.data();
+    bool isCopyGood2 = overlayBuffer && m_overlayBuffer.size() >= kernelSize && m_buffer.size() == m_inputBlockSize * 2;
+    ASSERT(isCopyGood2);
+    if (!isCopyGood2)
+        return;
+
+    ippsConv_32f(static_cast<const Ipp32f*>(sourceP), framesToProcess, static_cast<Ipp32f*>(kernelP), kernelSize, static_cast<Ipp32f*>(outputBuffer));
+
+    vadd(outputBuffer, 1, overlayBuffer, 1, destP, 1, framesToProcess);
+    memcpy(overlayBuffer, outputBuffer + m_inputBlockSize, sizeof(float) * kernelSize);
+#else
+    float* inputP = m_buffer.data() + m_inputBlockSize;
+
     // Copy samples to 2nd half of input buffer.
     memcpy(inputP, sourceP, sizeof(float) * framesToProcess);
 
@@ -345,12 +359,16 @@ void DirectConvolver::process(AudioFloatArray* convolutionKernel, const float* s
     }
 
     // Copy 2nd half of input buffer to 1st half.
-    memcpy(m_inputBuffer.data(), inputP, sizeof(float) * framesToProcess);
+    memcpy(m_buffer.data(), inputP, sizeof(float) * framesToProcess);
+#endif
 }
 
 void DirectConvolver::reset()
 {
-    m_inputBuffer.zero();
+    m_buffer.zero();
+#if USE(WEBAUDIO_IPP)
+    m_overlayBuffer.zero();
+#endif // USE(WEBAUDIO_IPP)
 }
 
 } // namespace WebCore