diff --git a/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp b/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp index dc1fdbe516..ef1284de92 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp +++ b/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp @@ -39,10 +39,9 @@ AudioSampleBuffer::AudioSampleBuffer (const AudioSampleBuffer& other) noexcept size (other.size) { allocateData(); - const size_t numBytes = sizeof (float) * (size_t) size; for (int i = 0; i < numChannels; ++i) - memcpy (channels[i], other.channels[i], numBytes); + FloatVectorOperations::copy (channels[i], other.channels[i], size); } void AudioSampleBuffer::allocateData() @@ -130,10 +129,8 @@ AudioSampleBuffer& AudioSampleBuffer::operator= (const AudioSampleBuffer& other) { setSize (other.getNumChannels(), other.getNumSamples(), false, false, false); - const size_t numBytes = sizeof (float) * (size_t) size; - for (int i = 0; i < numChannels; ++i) - memcpy (channels[i], other.channels[i], numBytes); + FloatVectorOperations::copy (channels[i], other.channels[i], size); } return *this; @@ -154,15 +151,17 @@ void AudioSampleBuffer::setSize (const int newNumChannels, if (newNumSamples != size || newNumChannels != numChannels) { - const size_t channelListSize = sizeof (float*) * (size_t) (newNumChannels + 1); - const size_t newTotalBytes = ((size_t) newNumChannels * (size_t) newNumSamples * sizeof (float)) + channelListSize + 32; + const size_t allocatedSamplesPerChannel = (newNumSamples + 3) & ~3; + const size_t channelListSize = ((sizeof (float*) * (size_t) (newNumChannels + 1)) + 15) & ~15; + const size_t newTotalBytes = ((size_t) newNumChannels * (size_t) allocatedSamplesPerChannel * sizeof (float)) + + channelListSize + 32; if (keepExistingContent) { HeapBlock newData; newData.allocate (newTotalBytes, clearExtraSpace); - const size_t numBytesToCopy = sizeof (float) * (size_t) jmin (newNumSamples, size); + const size_t numSamplesToCopy = jmin (newNumSamples, size); float** const newChannels = reinterpret_cast (newData.getData()); float* newChan = reinterpret_cast (newData + channelListSize); @@ -170,12 +169,12 @@ void AudioSampleBuffer::setSize (const int newNumChannels, for (int j = 0; j < newNumChannels; ++j) { newChannels[j] = newChan; - newChan += newNumSamples; + newChan += allocatedSamplesPerChannel; } const int numChansToCopy = jmin (numChannels, newNumChannels); for (int i = 0; i < numChansToCopy; ++i) - memcpy (newChannels[i], channels[i], numBytesToCopy); + FloatVectorOperations::copy (newChannels[i], channels[i], numSamplesToCopy); allocatedData.swapWith (newData); allocatedBytes = newTotalBytes; @@ -199,7 +198,7 @@ void AudioSampleBuffer::setSize (const int newNumChannels, for (int i = 0; i < newNumChannels; ++i) { channels[i] = chan; - chan += newNumSamples; + chan += allocatedSamplesPerChannel; } } @@ -212,7 +211,7 @@ void AudioSampleBuffer::setSize (const int newNumChannels, void AudioSampleBuffer::clear() noexcept { for (int i = 0; i < numChannels; ++i) - zeromem (channels[i], sizeof (float) * (size_t) size); + FloatVectorOperations::clear (channels[i], size); } void AudioSampleBuffer::clear (const int startSample, @@ -221,7 +220,7 @@ void AudioSampleBuffer::clear (const int startSample, jassert (startSample >= 0 && startSample + numSamples <= size); for (int i = 0; i < numChannels; ++i) - zeromem (channels [i] + startSample, sizeof (float) * (size_t) numSamples); + FloatVectorOperations::clear (channels[i] + startSample, numSamples); } void AudioSampleBuffer::clear (const int channel, @@ -231,7 +230,7 @@ void AudioSampleBuffer::clear (const int channel, jassert (isPositiveAndBelow (channel, numChannels)); jassert (startSample >= 0 && startSample + numSamples <= size); - zeromem (channels [channel] + startSample, sizeof (float) * (size_t) numSamples); + FloatVectorOperations::clear (channels [channel] + startSample, numSamples); } void AudioSampleBuffer::applyGain (const int channel, @@ -244,17 +243,12 @@ void AudioSampleBuffer::applyGain (const int channel, if (gain != 1.0f) { - float* d = channels [channel] + startSample; + float* const d = channels [channel] + startSample; if (gain == 0.0f) - { - zeromem (d, sizeof (float) * (size_t) numSamples); - } + FloatVectorOperations::clear (d, numSamples); else - { - while (--numSamples >= 0) - *d++ *= gain; - } + FloatVectorOperations::multiply (d, gain, numSamples); } } @@ -322,19 +316,13 @@ void AudioSampleBuffer::addFrom (const int destChannel, if (gain != 0.0f && numSamples > 0) { - float* d = channels [destChannel] + destStartSample; - const float* s = source.channels [sourceChannel] + sourceStartSample; + float* const d = channels [destChannel] + destStartSample; + const float* const s = source.channels [sourceChannel] + sourceStartSample; if (gain != 1.0f) - { - while (--numSamples >= 0) - *d++ += gain * *s++; - } + FloatVectorOperations::addWithMultiply (d, s, gain, numSamples); else - { - while (--numSamples >= 0) - *d++ += *s++; - } + FloatVectorOperations::add (d, s, numSamples); } } @@ -350,18 +338,12 @@ void AudioSampleBuffer::addFrom (const int destChannel, if (gain != 0.0f && numSamples > 0) { - float* d = channels [destChannel] + destStartSample; + float* const d = channels [destChannel] + destStartSample; if (gain != 1.0f) - { - while (--numSamples >= 0) - *d++ += gain * *source++; - } + FloatVectorOperations::addWithMultiply (d, source, gain, numSamples); else - { - while (--numSamples >= 0) - *d++ += *source++; - } + FloatVectorOperations::add (d, source, numSamples); } } @@ -378,11 +360,7 @@ void AudioSampleBuffer::addFromWithRamp (const int destChannel, if (startGain == endGain) { - addFrom (destChannel, - destStartSample, - source, - numSamples, - startGain); + addFrom (destChannel, destStartSample, source, numSamples, startGain); } else { @@ -415,9 +393,9 @@ void AudioSampleBuffer::copyFrom (const int destChannel, if (numSamples > 0) { - memcpy (channels [destChannel] + destStartSample, - source.channels [sourceChannel] + sourceStartSample, - sizeof (float) * (size_t) numSamples); + FloatVectorOperations::copy (channels [destChannel] + destStartSample, + source.channels [sourceChannel] + sourceStartSample, + numSamples); } } @@ -432,9 +410,9 @@ void AudioSampleBuffer::copyFrom (const int destChannel, if (numSamples > 0) { - memcpy (channels [destChannel] + destStartSample, - source, - sizeof (float) * (size_t) numSamples); + FloatVectorOperations::copy (channels [destChannel] + destStartSample, + source, + numSamples); } } @@ -455,18 +433,13 @@ void AudioSampleBuffer::copyFrom (const int destChannel, if (gain != 1.0f) { if (gain == 0) - { - zeromem (d, sizeof (float) * (size_t) numSamples); - } + FloatVectorOperations::clear (d, numSamples); else - { - while (--numSamples >= 0) - *d++ = gain * *source++; - } + FloatVectorOperations::copyWithMultiply (d, source, gain, numSamples); } else { - memcpy (d, source, sizeof (float) * (size_t) numSamples); + FloatVectorOperations::copy (d, source, numSamples); } } } @@ -484,11 +457,7 @@ void AudioSampleBuffer::copyFromWithRamp (const int destChannel, if (startGain == endGain) { - copyFrom (destChannel, - destStartSample, - source, - numSamples, - startGain); + copyFrom (destChannel, destStartSample, source, numSamples, startGain); } else { @@ -515,7 +484,8 @@ void AudioSampleBuffer::findMinMax (const int channel, jassert (isPositiveAndBelow (channel, numChannels)); jassert (startSample >= 0 && startSample + numSamples <= size); - findMinAndMax (channels [channel] + startSample, numSamples, minVal, maxVal); + FloatVectorOperations::findMinAndMax (channels [channel] + startSample, + numSamples, minVal, maxVal); } float AudioSampleBuffer::getMagnitude (const int channel, diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp new file mode 100644 index 0000000000..925330cbb0 --- /dev/null +++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp @@ -0,0 +1,234 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-11 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#if JUCE_USE_SSE_INTRINSICS + +namespace FloatVectorHelpers +{ + static bool sse2Present = false; + + static bool isSSE2Available() + { + if (sse2Present) + return true; + + sse2Present = SystemStats::hasSSE2(); + return sse2Present; + } + + inline static bool isAligned (const void* p) + { + return (((pointer_sized_int) p) & 15) == 0; + } +} + +#define JUCE_BEGIN_SSE_OP \ + if (FloatVectorHelpers::isSSE2Available()) \ + { \ + const int numLongOps = num / 4; + +#define JUCE_FINISH_SSE_OP(normalOp) \ + _mm_empty(); \ + num &= 3; \ + if (num == 0) return; \ + } \ + for (int i = 0; i < num; ++i) normalOp; + +#define JUCE_SSE_LOOP(sseOp, srcLoad, dstLoad, dstStore, locals, increment) \ + for (int i = 0; i < numLongOps; ++i) \ + { \ + locals (srcLoad, dstLoad); \ + dstStore (dest, sseOp); \ + increment; \ + } + +#define JUCE_INCREMENT_SRC_DEST dest += 4; src += 4; +#define JUCE_INCREMENT_DEST dest += 4; + +#define JUCE_LOAD_NONE(srcLoad, dstLoad) +#define JUCE_LOAD_DEST(srcLoad, dstLoad) const __m128 d = dstLoad (dest); +#define JUCE_LOAD_SRC(srcLoad, dstLoad) const __m128 s = srcLoad (src); +#define JUCE_LOAD_SRC_DEST(srcLoad, dstLoad) const __m128 d = dstLoad (dest); const __m128 s = srcLoad (src); + +#define JUCE_PERFORM_SSE_OP_DEST(normalOp, sseOp) \ + JUCE_BEGIN_SSE_OP \ + if (FloatVectorHelpers::isAligned (dest)) JUCE_SSE_LOOP (sseOp, dummy, _mm_load_ps, _mm_store_ps, JUCE_LOAD_DEST, JUCE_INCREMENT_DEST) \ + else JUCE_SSE_LOOP (sseOp, dummy, _mm_loadu_ps, _mm_storeu_ps, JUCE_LOAD_DEST, JUCE_INCREMENT_DEST) \ + JUCE_FINISH_SSE_OP (normalOp) + +#define JUCE_PERFORM_SSE_OP_SRC_DEST(normalOp, sseOp, locals, increment) \ + JUCE_BEGIN_SSE_OP \ + if (FloatVectorHelpers::isAligned (dest)) \ + { \ + if (FloatVectorHelpers::isAligned (src)) JUCE_SSE_LOOP (sseOp, _mm_load_ps, _mm_load_ps, _mm_store_ps, locals, increment) \ + else JUCE_SSE_LOOP (sseOp, _mm_loadu_ps, _mm_load_ps, _mm_store_ps, locals, increment) \ + }\ + else \ + { \ + if (FloatVectorHelpers::isAligned (src)) JUCE_SSE_LOOP (sseOp, _mm_load_ps, _mm_loadu_ps, _mm_storeu_ps, locals, increment) \ + else JUCE_SSE_LOOP (sseOp, _mm_loadu_ps, _mm_loadu_ps, _mm_storeu_ps, locals, increment) \ + } \ + JUCE_FINISH_SSE_OP (normalOp) + + +#else + #define JUCE_PERFORM_SSE_OP_DEST(normalOp, unused1) for (int i = 0; i < num; ++i) normalOp; + #define JUCE_PERFORM_SSE_OP_SRC_DEST(normalOp, sseOp, locals, increment) for (int i = 0; i < num; ++i) normalOp; +#endif + +void FloatVectorOperations::clear (float* dest, const int num) noexcept +{ + zeromem (dest, num * sizeof (float)); +} + +void FloatVectorOperations::copy (float* dest, const float* src, const int num) noexcept +{ + memcpy (dest, src, num * sizeof (float)); +} + +void FloatVectorOperations::copyWithMultiply (float* dest, const float* src, float multiplier, int num) noexcept +{ + #if JUCE_USE_SSE_INTRINSICS + const __m128 mult = _mm_load1_ps (&multiplier); + #endif + + JUCE_PERFORM_SSE_OP_SRC_DEST (dest[i] = src[i] * multiplier, + _mm_mul_ps (mult, s), + JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST) +} + +void FloatVectorOperations::add (float* dest, const float* src, int num) noexcept +{ + JUCE_PERFORM_SSE_OP_SRC_DEST (dest[i] += src[i], + _mm_add_ps (d, s), + JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST) +} + +void FloatVectorOperations::add (float* dest, float amount, int num) noexcept +{ + #if JUCE_USE_SSE_INTRINSICS + const __m128 amountToAdd = _mm_load1_ps (&amount); + #endif + + JUCE_PERFORM_SSE_OP_DEST (dest[i] += amount, + _mm_add_ps (d, amountToAdd)) +} + +void FloatVectorOperations::addWithMultiply (float* dest, const float* src, float multiplier, int num) noexcept +{ + #if JUCE_USE_SSE_INTRINSICS + const __m128 mult = _mm_load1_ps (&multiplier); + #endif + + JUCE_PERFORM_SSE_OP_SRC_DEST (dest[i] += src[i] * multiplier, + _mm_add_ps (d, _mm_mul_ps (mult, s)), + JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST) +} + +void FloatVectorOperations::multiply (float* dest, const float* src, int num) noexcept +{ + JUCE_PERFORM_SSE_OP_SRC_DEST (dest[i] *= src[i], + _mm_mul_ps (d, s), + JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST) +} + +void FloatVectorOperations::multiply (float* dest, float multiplier, int num) noexcept +{ + #if JUCE_USE_SSE_INTRINSICS + const __m128 mult = _mm_load1_ps (&multiplier); + #endif + + JUCE_PERFORM_SSE_OP_DEST (dest[i] *= multiplier, + _mm_mul_ps (d, mult)) +} + +void FloatVectorOperations::convertFixedToFloat (float* dest, const int* src, float multiplier, int num) noexcept +{ + #if JUCE_USE_SSE_INTRINSICS + const __m128 mult = _mm_load1_ps (&multiplier); + #endif + + JUCE_PERFORM_SSE_OP_SRC_DEST (dest[i] = src[i] * multiplier, + _mm_mul_ps (mult, _mm_movelh_ps (_mm_cvt_pi2ps (_mm_setzero_ps(), ((const __m64*) src)[0]), + _mm_cvt_pi2ps (_mm_setzero_ps(), ((const __m64*) src)[1]))), + JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST) +} + +void FloatVectorOperations::findMinAndMax (const float* src, int num, float& minResult, float& maxResult) noexcept +{ + #if JUCE_USE_SSE_INTRINSICS + const int numLongOps = num / 4; + + if (numLongOps > 1 && FloatVectorHelpers::isSSE2Available()) + { + __m128 mn, mx; + + #define JUCE_MINMAX_SSE_LOOP(loadOp) \ + mn = loadOp (src); \ + mx = mn; \ + src += 4; \ + for (int i = 1; i < numLongOps; ++i) \ + { \ + const __m128 s = loadOp (src); \ + mn = _mm_min_ps (mn, s); \ + mx = _mm_max_ps (mx, s); \ + src += 4; \ + } + + if (FloatVectorHelpers::isAligned (src)) { JUCE_MINMAX_SSE_LOOP (_mm_load_ps) } + else { JUCE_MINMAX_SSE_LOOP (_mm_loadu_ps) } + + float localMin, localMax; + + { + float mns[4], mxs[4]; + _mm_storeu_ps (mns, mn); + _mm_storeu_ps (mxs, mx); + _mm_empty(); + + localMin = jmin (mns[0], mns[1], mns[2], mns[3]); + localMax = jmax (mxs[0], mxs[1], mxs[2], mxs[3]); + } + + num &= 3; + + if (num != 0) + { + for (int i = 0; i < num; ++i) + { + const float s = src[i]; + localMin = jmin (localMin, s); + localMax = jmax (localMax, s); + } + } + + minResult = localMin; + maxResult = localMax; + return; + } + #endif + + juce::findMinAndMax (src, num, minResult, maxResult); +} diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h new file mode 100644 index 0000000000..28ba2a1248 --- /dev/null +++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h @@ -0,0 +1,69 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-11 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCE_FLOATVECTOROPERATIONS_JUCEHEADER__ +#define __JUCE_FLOATVECTOROPERATIONS_JUCEHEADER__ + + +//============================================================================== +/** +*/ +class JUCE_API FloatVectorOperations +{ +public: + //============================================================================== + /** Clears a vector of floats. */ + static void clear (float* dest, int numValues) noexcept; + + /** Copies a vector of floats. */ + static void copy (float* dest, const float* src, int numValues) noexcept; + + /** Copies a vector of floats, multiplying each value by a given multiplier */ + static void copyWithMultiply (float* dest, const float* src, float multiplier, int numValues) noexcept; + + /** Adds the source values to the destination values. */ + static void add (float* dest, const float* src, int numValues) noexcept; + + /** Adds a fixed value to the destination values. */ + static void add (float* dest, float amount, int numValues) noexcept; + + /** Multiplies each source value by the given multiplier, then adds it to the destination value. */ + static void addWithMultiply (float* dest, const float* src, float multiplier, int numValues) noexcept; + + /** Multiplies the destination values by the source values. */ + static void multiply (float* dest, const float* src, int numValues) noexcept; + + /** Multiplies each of the destination values by a fixed multiplier. */ + static void multiply (float* dest, float multiplier, int numValues) noexcept; + + /** Converts a stream of integers to floats, multiplying each one by the given multiplier. */ + static void convertFixedToFloat (float* dest, const int* src, float multiplier, int numValues) noexcept; + + /** Finds the miniumum and maximum values in the given array. */ + static void findMinAndMax (const float* src, int numValues, float& minResult, float& maxResult) noexcept; +}; + + +#endif // __JUCE_FLOATVECTOROPERATIONS_JUCEHEADER__ diff --git a/modules/juce_audio_basics/effects/juce_IIRFilter.cpp b/modules/juce_audio_basics/effects/juce_IIRFilter.cpp index 875e936a33..aecbbe8e64 100644 --- a/modules/juce_audio_basics/effects/juce_IIRFilter.cpp +++ b/modules/juce_audio_basics/effects/juce_IIRFilter.cpp @@ -38,7 +38,7 @@ IIRFilter::IIRFilter() IIRFilter::IIRFilter (const IIRFilter& other) : active (other.active), v1 (0), v2 (0) { - const ScopedLock sl (other.processLock); + const SpinLock::ScopedLockType sl (other.processLock); memcpy (coefficients, other.coefficients, sizeof (coefficients)); } @@ -49,7 +49,7 @@ IIRFilter::~IIRFilter() //============================================================================== void IIRFilter::reset() noexcept { - const ScopedLock sl (processLock); + const SpinLock::ScopedLockType sl (processLock); v1 = v2 = 0; } @@ -59,8 +59,8 @@ float IIRFilter::processSingleSampleRaw (const float in) noexcept JUCE_SNAP_TO_ZERO (out); - v1 = coefficients[1] * in - coefficients[4] * out + v2; - v2 = coefficients[2] * in - coefficients[5] * out; + v1 = coefficients[1] * in - coefficients[3] * out + v2; + v2 = coefficients[2] * in - coefficients[4] * out; return out; } @@ -68,23 +68,29 @@ float IIRFilter::processSingleSampleRaw (const float in) noexcept void IIRFilter::processSamples (float* const samples, const int numSamples) noexcept { - const ScopedLock sl (processLock); + const SpinLock::ScopedLockType sl (processLock); if (active) { + const float c0 = coefficients[0]; + const float c1 = coefficients[1]; + const float c2 = coefficients[2]; + const float c3 = coefficients[3]; + const float c4 = coefficients[4]; + float lv1 = v1, lv2 = v2; + for (int i = 0; i < numSamples; ++i) { const float in = samples[i]; - - float out = coefficients[0] * in + v1; - - JUCE_SNAP_TO_ZERO (out); - - v1 = coefficients[1] * in - coefficients[4] * out + v2; - v2 = coefficients[2] * in - coefficients[5] * out; - + const float out = c0 * in + lv1; samples[i] = out; + + lv1 = c1 * in - c3 * out + lv2; + lv2 = c2 * in - c4 * out; } + + JUCE_SNAP_TO_ZERO (lv1); v1 = lv1; + JUCE_SNAP_TO_ZERO (lv2); v2 = lv2; } } @@ -194,14 +200,14 @@ void IIRFilter::makeBandPass (const double sampleRate, void IIRFilter::makeInactive() noexcept { - const ScopedLock sl (processLock); + const SpinLock::ScopedLockType sl (processLock); active = false; } //============================================================================== void IIRFilter::copyCoefficientsFrom (const IIRFilter& other) noexcept { - const ScopedLock sl (processLock); + const SpinLock::ScopedLockType sl (processLock); memcpy (coefficients, other.coefficients, sizeof (coefficients)); active = other.active; @@ -219,14 +225,13 @@ void IIRFilter::setCoefficients (double c1, double c2, double c3, c5 *= a; c6 *= a; - const ScopedLock sl (processLock); + const SpinLock::ScopedLockType sl (processLock); coefficients[0] = (float) c1; coefficients[1] = (float) c2; coefficients[2] = (float) c3; - coefficients[3] = (float) c4; - coefficients[4] = (float) c5; - coefficients[5] = (float) c6; + coefficients[3] = (float) c5; + coefficients[4] = (float) c6; active = true; } diff --git a/modules/juce_audio_basics/effects/juce_IIRFilter.h b/modules/juce_audio_basics/effects/juce_IIRFilter.h index 21e3eb0179..93e5c36d2e 100644 --- a/modules/juce_audio_basics/effects/juce_IIRFilter.h +++ b/modules/juce_audio_basics/effects/juce_IIRFilter.h @@ -131,13 +131,13 @@ public: protected: //============================================================================== - CriticalSection processLock; + SpinLock processLock; void setCoefficients (double c1, double c2, double c3, double c4, double c5, double c6) noexcept; bool active; - float coefficients[6]; + float coefficients[5]; float v1, v2; // (use the copyCoefficientsFrom() method instead of this operator) diff --git a/modules/juce_audio_basics/juce_audio_basics.cpp b/modules/juce_audio_basics/juce_audio_basics.cpp index fe6fb1d465..53d9845ab5 100644 --- a/modules/juce_audio_basics/juce_audio_basics.cpp +++ b/modules/juce_audio_basics/juce_audio_basics.cpp @@ -35,15 +35,27 @@ // Your project must contain an AppConfig.h file with your project-specific settings in it, // and your header search path must make it accessible to the module's files. #include "AppConfig.h" - #include "juce_audio_basics.h" +#ifndef JUCE_USE_SSE_INTRINSICS + #define JUCE_USE_SSE_INTRINSICS 1 +#endif + +#if ! JUCE_INTEL + #define JUCE_USE_SSE_INTRINSICS 0 +#endif + +#if JUCE_USE_SSE_INTRINSICS + #include +#endif + namespace juce { // START_AUTOINCLUDE buffers/*.cpp, effects/*.cpp, midi/*.cpp, sources/*.cpp, synthesisers/*.cpp #include "buffers/juce_AudioDataConverters.cpp" #include "buffers/juce_AudioSampleBuffer.cpp" +#include "buffers/juce_FloatVectorOperations.cpp" #include "effects/juce_IIRFilter.cpp" #include "effects/juce_LagrangeInterpolator.cpp" #include "midi/juce_MidiBuffer.cpp" diff --git a/modules/juce_audio_basics/juce_audio_basics.h b/modules/juce_audio_basics/juce_audio_basics.h index ec8d788175..43ac33a0ef 100644 --- a/modules/juce_audio_basics/juce_audio_basics.h +++ b/modules/juce_audio_basics/juce_audio_basics.h @@ -39,6 +39,9 @@ namespace juce #ifndef __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ #include "buffers/juce_AudioSampleBuffer.h" #endif +#ifndef __JUCE_FLOATVECTOROPERATIONS_JUCEHEADER__ + #include "buffers/juce_FloatVectorOperations.h" +#endif #ifndef __JUCE_DECIBELS_JUCEHEADER__ #include "effects/juce_Decibels.h" #endif diff --git a/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp b/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp index 5b84c21a3d..50a9e01ae3 100644 --- a/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp +++ b/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp @@ -160,18 +160,29 @@ void AudioFormatReader::read (AudioSampleBuffer* buffer, } } +template +static inline void getChannelMinAndMax (SampleType* channel, const int numSamples, SampleType& mn, SampleType& mx) +{ + findMinAndMax (channel, numSamples, mn, mx); +} + +static inline void getChannelMinAndMax (float* channel, const int numSamples, float& mn, float& mx) +{ + FloatVectorOperations::findMinAndMax (channel, numSamples, mn, mx); +} + template static void getStereoMinAndMax (SampleType* const* channels, const int numChannels, const int numSamples, SampleType& lmin, SampleType& lmax, SampleType& rmin, SampleType& rmax) { SampleType bufMin, bufMax; - findMinAndMax (channels[0], numSamples, bufMin, bufMax); + getChannelMinAndMax (channels[0], numSamples, bufMin, bufMax); lmax = jmax (lmax, bufMax); lmin = jmin (lmin, bufMin); if (numChannels > 1) { - findMinAndMax (channels[1], numSamples, bufMin, bufMax); + getChannelMinAndMax (channels[1], numSamples, bufMin, bufMax); rmax = jmax (rmax, bufMax); rmin = jmin (rmin, bufMin); } diff --git a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_Wrapper.cpp b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_Wrapper.cpp index 4199b8ea18..87407915c6 100644 --- a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_Wrapper.cpp @@ -562,7 +562,7 @@ protected: if (juceFilter->isSuspended()) { for (int i = 0; i < numOut; ++i) - zeromem (outputs [i], sizeof (float) * numSamples); + FloatVectorOperations::clear (outputs [i], numSamples); } else { @@ -573,7 +573,7 @@ protected: channels[i] = outputs [i]; if (i < numIn && inputs != outputs) - memcpy (outputs [i], inputs[i], sizeof (float) * numSamples); + FloatVectorOperations::copy (outputs [i], inputs[i], numSamples); } for (; i < numIn; ++i) @@ -813,9 +813,9 @@ private: for (int i = fNumOutputs; --i >= 0;) { if (i < fNumInputs) - memcpy (outputs[i], inputs[i], numSamples * sizeof (float)); + FloatVectorOperations::copy (outputs[i], inputs[i], numSamples); else - zeromem (outputs[i], numSamples * sizeof (float)); + FloatVectorOperations::clear (outputs[i], numSamples); } } diff --git a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp index 0ac03b5a74..82e961e818 100644 --- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp @@ -526,7 +526,7 @@ public: if (filter->isSuspended()) { for (int i = 0; i < numOut; ++i) - zeromem (outputs[i], sizeof (float) * (size_t) numSamples); + FloatVectorOperations::clear (outputs[i], numSamples); } else { diff --git a/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp b/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp index de2f2b5bd6..b9b682941c 100644 --- a/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp +++ b/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp @@ -700,7 +700,7 @@ void AudioThumbnail::addBlock (const int64 startSample, const AudioSampleBuffer& { float low, high; const int start = i * samplesPerThumbSample; - findMinAndMax (sourceData + start, jmin (samplesPerThumbSample, numSamples - start), low, high); + FloatVectorOperations::findMinAndMax (sourceData + start, jmin (samplesPerThumbSample, numSamples - start), low, high); dest[i].setFloat (low, high); } }