Add vsma in VectorMath to handle vector scale multiply and add and use it in AudioBus

https://bugs.webkit.org/show_bug.cgi?id=75835

When summing a audio bus, the source is multiplied with the scale and
then summed into the destination bus. Add this function to fulfill it.

Patch by Wei James <james.wei@intel.com> on 2012-01-12
Reviewed by Kenneth Russell.

* platform/audio/AudioBus.cpp:
* platform/audio/VectorMath.cpp:
(WebCore::VectorMath::vsma):
* platform/audio/VectorMath.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@104893 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 6dc0d0b1
2012-01-12 Wei James <james.wei@intel.com>
Add vsma in VectorMath to handle vector scale multiply and add and use it in AudioBus
https://bugs.webkit.org/show_bug.cgi?id=75835
When summing a audio bus, the source is multiplied with the scale and
then summed into the destination bus. Add this function to fulfill it.
Reviewed by Kenneth Russell.
* platform/audio/AudioBus.cpp:
* platform/audio/VectorMath.cpp:
(WebCore::VectorMath::vsma):
* platform/audio/VectorMath.h:
2012-01-12 James Simonsen <simonjam@chromium.org>
Web Inspector: [Chomium] Resources loaded with 304 status code have receiving time of 15000 days in network panel.
......@@ -252,10 +252,11 @@ void AudioBus::sumFrom(const AudioBus &sourceBus)
*destinationR++ = sumR; \
}
// FIXME: this can be optimized with additional VectorMath functions.
#define STEREO_SUM_V \
for (; k < framesToProcess; ++k) \
STEREO_SUM
{ \
vsma(sourceL, 1, &gain, destinationL, 1, framesToProcess - k); \
vsma(sourceR, 1, &gain, destinationR, 1, framesToProcess - k); \
}
// Mono -> stereo (mix equally into L and R)
// FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center...
......@@ -269,8 +270,10 @@ void AudioBus::sumFrom(const AudioBus &sourceBus)
}
#define MONO2STEREO_SUM_V \
for (; k < framesToProcess; ++k) \
MONO2STEREO_SUM
{ \
vsma(sourceL, 1, &gain, destinationL, 1, framesToProcess - k); \
vsma(sourceL, 1, &gain, destinationR, 1, framesToProcess - k); \
}
#define MONO_SUM \
{ \
......@@ -279,8 +282,9 @@ void AudioBus::sumFrom(const AudioBus &sourceBus)
}
#define MONO_SUM_V \
for (; k < framesToProcess; ++k) \
MONO_SUM
{ \
vsma(sourceL, 1, &gain, destinationL, 1, framesToProcess - k); \
}
#define STEREO_NO_SUM \
{ \
......
......@@ -90,8 +90,69 @@ void zvmul(const float* real1P, const float* imag1P, const float* real2P, const
#endif
}
void vsma(const float* sourceP, int sourceStride, const float* scale, float* destP, int destStride, size_t framesToProcess)
{
vDSP_vsma(sourceP, sourceStride, scale, destP, destStride, destP, destStride, framesToProcess);
}
#else
void vsma(const float* sourceP, int sourceStride, const float* scale, float* destP, int destStride, size_t framesToProcess)
{
int n = framesToProcess;
#ifdef __SSE2__
if ((sourceStride == 1) && (destStride == 1)) {
float k = *scale;
// If the sourceP address is not 16-byte aligned, the first several frames (at most three) should be processed seperately.
while ((reinterpret_cast<uintptr_t>(sourceP) & 0x0F) && n) {
*destP += k * *sourceP;
sourceP++;
destP++;
n--;
}
// Now the sourceP address aligned and start to apply SSE.
int tailFrames = n % 4;
float* endP = destP + n - tailFrames;
__m128 pSource;
__m128 dest;
__m128 temp;
__m128 mScale = _mm_set_ps1(k);
bool destAligned = !(reinterpret_cast<uintptr_t>(destP) & 0x0F);
#define SSE2_MULT_ADD(loadInstr, storeInstr) \
while (destP < endP) \
{ \
pSource = _mm_load_ps(sourceP); \
temp = _mm_mul_ps(pSource, mScale); \
dest = _mm_##loadInstr##_ps(destP); \
dest = _mm_add_ps(dest, temp); \
_mm_##storeInstr##_ps(destP, dest); \
sourceP += 4; \
destP += 4; \
}
if (destAligned)
SSE2_MULT_ADD(load, store)
else
SSE2_MULT_ADD(loadu, storeu)
n = tailFrames;
}
#endif
while (n) {
*destP += *sourceP * *scale;
sourceP += sourceStride;
destP += destStride;
n--;
}
}
void vsmul(const float* sourceP, int sourceStride, const float* scale, float* destP, int destStride, size_t framesToProcess)
{
#ifdef __SSE2__
......
......@@ -31,6 +31,9 @@ namespace WebCore {
namespace VectorMath {
// Vector scalar multiply and then add.
void vsma(const float* sourceP, int sourceStride, const float* scale, float* destP, int destStride, size_t framesToProcess);
void vsmul(const float* sourceP, int sourceStride, const float* scale, float* destP, int destStride, size_t framesToProcess);
void vadd(const float* source1P, int sourceStride1, const float* source2P, int sourceStride2, float* destP, int destStride, size_t framesToProcess);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment