- Library code update
- project update (added Eigen) git-svn-id: http://moon:8086/svn/software/trunk/projects/mpsk_rx_gui@94 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
|
||||
{
|
||||
const double maxVal = (double) 0x7fff;
|
||||
char* intData = static_cast <char*> (dest);
|
||||
char* intData = static_cast<char*> (dest);
|
||||
|
||||
if (dest != (void*) source || destBytesPerSample <= 4)
|
||||
{
|
||||
@@ -50,7 +50,7 @@ void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest
|
||||
void AudioDataConverters::convertFloatToInt16BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
|
||||
{
|
||||
const double maxVal = (double) 0x7fff;
|
||||
char* intData = static_cast <char*> (dest);
|
||||
char* intData = static_cast<char*> (dest);
|
||||
|
||||
if (dest != (void*) source || destBytesPerSample <= 4)
|
||||
{
|
||||
@@ -75,7 +75,7 @@ void AudioDataConverters::convertFloatToInt16BE (const float* source, void* dest
|
||||
void AudioDataConverters::convertFloatToInt24LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
|
||||
{
|
||||
const double maxVal = (double) 0x7fffff;
|
||||
char* intData = static_cast <char*> (dest);
|
||||
char* intData = static_cast<char*> (dest);
|
||||
|
||||
if (dest != (void*) source || destBytesPerSample <= 4)
|
||||
{
|
||||
@@ -100,7 +100,7 @@ void AudioDataConverters::convertFloatToInt24LE (const float* source, void* dest
|
||||
void AudioDataConverters::convertFloatToInt24BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
|
||||
{
|
||||
const double maxVal = (double) 0x7fffff;
|
||||
char* intData = static_cast <char*> (dest);
|
||||
char* intData = static_cast<char*> (dest);
|
||||
|
||||
if (dest != (void*) source || destBytesPerSample <= 4)
|
||||
{
|
||||
@@ -125,7 +125,7 @@ void AudioDataConverters::convertFloatToInt24BE (const float* source, void* dest
|
||||
void AudioDataConverters::convertFloatToInt32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
|
||||
{
|
||||
const double maxVal = (double) 0x7fffffff;
|
||||
char* intData = static_cast <char*> (dest);
|
||||
char* intData = static_cast<char*> (dest);
|
||||
|
||||
if (dest != (void*) source || destBytesPerSample <= 4)
|
||||
{
|
||||
@@ -150,7 +150,7 @@ void AudioDataConverters::convertFloatToInt32LE (const float* source, void* dest
|
||||
void AudioDataConverters::convertFloatToInt32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
|
||||
{
|
||||
const double maxVal = (double) 0x7fffffff;
|
||||
char* intData = static_cast <char*> (dest);
|
||||
char* intData = static_cast<char*> (dest);
|
||||
|
||||
if (dest != (void*) source || destBytesPerSample <= 4)
|
||||
{
|
||||
@@ -176,7 +176,7 @@ void AudioDataConverters::convertFloatToFloat32LE (const float* source, void* de
|
||||
{
|
||||
jassert (dest != (void*) source || destBytesPerSample <= 4); // This op can't be performed on in-place data!
|
||||
|
||||
char* d = static_cast <char*> (dest);
|
||||
char* d = static_cast<char*> (dest);
|
||||
|
||||
for (int i = 0; i < numSamples; ++i)
|
||||
{
|
||||
@@ -194,7 +194,7 @@ void AudioDataConverters::convertFloatToFloat32BE (const float* source, void* de
|
||||
{
|
||||
jassert (dest != (void*) source || destBytesPerSample <= 4); // This op can't be performed on in-place data!
|
||||
|
||||
char* d = static_cast <char*> (dest);
|
||||
char* d = static_cast<char*> (dest);
|
||||
|
||||
for (int i = 0; i < numSamples; ++i)
|
||||
{
|
||||
@@ -212,7 +212,7 @@ void AudioDataConverters::convertFloatToFloat32BE (const float* source, void* de
|
||||
void AudioDataConverters::convertInt16LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
|
||||
{
|
||||
const float scale = 1.0f / 0x7fff;
|
||||
const char* intData = static_cast <const char*> (source);
|
||||
const char* intData = static_cast<const char*> (source);
|
||||
|
||||
if (source != (void*) dest || srcBytesPerSample >= 4)
|
||||
{
|
||||
@@ -237,7 +237,7 @@ void AudioDataConverters::convertInt16LEToFloat (const void* const source, float
|
||||
void AudioDataConverters::convertInt16BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
|
||||
{
|
||||
const float scale = 1.0f / 0x7fff;
|
||||
const char* intData = static_cast <const char*> (source);
|
||||
const char* intData = static_cast<const char*> (source);
|
||||
|
||||
if (source != (void*) dest || srcBytesPerSample >= 4)
|
||||
{
|
||||
@@ -262,7 +262,7 @@ void AudioDataConverters::convertInt16BEToFloat (const void* const source, float
|
||||
void AudioDataConverters::convertInt24LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
|
||||
{
|
||||
const float scale = 1.0f / 0x7fffff;
|
||||
const char* intData = static_cast <const char*> (source);
|
||||
const char* intData = static_cast<const char*> (source);
|
||||
|
||||
if (source != (void*) dest || srcBytesPerSample >= 4)
|
||||
{
|
||||
@@ -287,7 +287,7 @@ void AudioDataConverters::convertInt24LEToFloat (const void* const source, float
|
||||
void AudioDataConverters::convertInt24BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
|
||||
{
|
||||
const float scale = 1.0f / 0x7fffff;
|
||||
const char* intData = static_cast <const char*> (source);
|
||||
const char* intData = static_cast<const char*> (source);
|
||||
|
||||
if (source != (void*) dest || srcBytesPerSample >= 4)
|
||||
{
|
||||
@@ -312,7 +312,7 @@ void AudioDataConverters::convertInt24BEToFloat (const void* const source, float
|
||||
void AudioDataConverters::convertInt32LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
|
||||
{
|
||||
const float scale = 1.0f / 0x7fffffff;
|
||||
const char* intData = static_cast <const char*> (source);
|
||||
const char* intData = static_cast<const char*> (source);
|
||||
|
||||
if (source != (void*) dest || srcBytesPerSample >= 4)
|
||||
{
|
||||
@@ -337,7 +337,7 @@ void AudioDataConverters::convertInt32LEToFloat (const void* const source, float
|
||||
void AudioDataConverters::convertInt32BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
|
||||
{
|
||||
const float scale = 1.0f / 0x7fffffff;
|
||||
const char* intData = static_cast <const char*> (source);
|
||||
const char* intData = static_cast<const char*> (source);
|
||||
|
||||
if (source != (void*) dest || srcBytesPerSample >= 4)
|
||||
{
|
||||
@@ -361,7 +361,7 @@ void AudioDataConverters::convertInt32BEToFloat (const void* const source, float
|
||||
|
||||
void AudioDataConverters::convertFloat32LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
|
||||
{
|
||||
const char* s = static_cast <const char*> (source);
|
||||
const char* s = static_cast<const char*> (source);
|
||||
|
||||
for (int i = 0; i < numSamples; ++i)
|
||||
{
|
||||
@@ -378,7 +378,7 @@ void AudioDataConverters::convertFloat32LEToFloat (const void* const source, flo
|
||||
|
||||
void AudioDataConverters::convertFloat32BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
|
||||
{
|
||||
const char* s = static_cast <const char*> (source);
|
||||
const char* s = static_cast<const char*> (source);
|
||||
|
||||
for (int i = 0; i < numSamples; ++i)
|
||||
{
|
||||
|
||||
@@ -91,7 +91,7 @@ AudioSampleBuffer::AudioSampleBuffer (float* const* dataToReferTo,
|
||||
allocatedBytes (0)
|
||||
{
|
||||
jassert (dataToReferTo != nullptr);
|
||||
jassert (numChans >= 0);
|
||||
jassert (numChans >= 0 && numSamples >= 0);
|
||||
allocateChannels (dataToReferTo, 0);
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ AudioSampleBuffer::AudioSampleBuffer (float* const* dataToReferTo,
|
||||
isClear (false)
|
||||
{
|
||||
jassert (dataToReferTo != nullptr);
|
||||
jassert (numChans >= 0);
|
||||
jassert (numChans >= 0 && startSample >= 0 && numSamples >= 0);
|
||||
allocateChannels (dataToReferTo, startSample);
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ void AudioSampleBuffer::setDataToReferTo (float** dataToReferTo,
|
||||
const int newNumSamples) noexcept
|
||||
{
|
||||
jassert (dataToReferTo != nullptr);
|
||||
jassert (newNumChannels >= 0);
|
||||
jassert (newNumChannels >= 0 && newNumSamples >= 0);
|
||||
|
||||
allocatedBytes = 0;
|
||||
allocatedData.free();
|
||||
@@ -128,6 +128,8 @@ void AudioSampleBuffer::setDataToReferTo (float** dataToReferTo,
|
||||
|
||||
void AudioSampleBuffer::allocateChannels (float* const* const dataToReferTo, int offset)
|
||||
{
|
||||
jassert (offset >= 0);
|
||||
|
||||
// (try to avoid doing a malloc here, as that'll blow up things like Pro-Tools)
|
||||
if (numChannels < (int) numElementsInArray (preallocatedChannelSpace))
|
||||
{
|
||||
@@ -163,6 +165,8 @@ AudioSampleBuffer& AudioSampleBuffer::operator= (const AudioSampleBuffer& other)
|
||||
}
|
||||
else
|
||||
{
|
||||
isClear = false;
|
||||
|
||||
for (int i = 0; i < numChannels; ++i)
|
||||
FloatVectorOperations::copy (channels[i], other.channels[i], size);
|
||||
}
|
||||
|
||||
@@ -24,8 +24,9 @@
|
||||
|
||||
namespace FloatVectorHelpers
|
||||
{
|
||||
#define JUCE_INCREMENT_SRC_DEST dest += (16 / sizeof (*dest)); src += (16 / sizeof (*dest));
|
||||
#define JUCE_INCREMENT_DEST dest += (16 / sizeof (*dest));
|
||||
#define JUCE_INCREMENT_SRC_DEST dest += (16 / sizeof (*dest)); src += (16 / sizeof (*dest));
|
||||
#define JUCE_INCREMENT_SRC1_SRC2_DEST dest += (16 / sizeof (*dest)); src1 += (16 / sizeof (*dest)); src2 += (16 / sizeof (*dest));
|
||||
#define JUCE_INCREMENT_DEST dest += (16 / sizeof (*dest));
|
||||
|
||||
#if JUCE_USE_SSE_INTRINSICS
|
||||
static bool sse2Present = false;
|
||||
@@ -122,6 +123,17 @@ namespace FloatVectorHelpers
|
||||
} \
|
||||
JUCE_FINISH_VEC_OP (normalOp)
|
||||
|
||||
#define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST(normalOp, vecOp, locals, increment, setupOp) \
|
||||
JUCE_BEGIN_VEC_OP \
|
||||
setupOp \
|
||||
{ \
|
||||
Mode::ParallelType (&loadSrc1) (const Mode::Type* v) = FloatVectorHelpers::isAligned (src1) ? Mode::loadA : Mode::loadU; \
|
||||
Mode::ParallelType (&loadSrc2) (const Mode::Type* v) = FloatVectorHelpers::isAligned (src2) ? Mode::loadA : Mode::loadU; \
|
||||
void (&storeDst) (Mode::Type* dest, Mode::ParallelType a) = FloatVectorHelpers::isAligned (dest) ? Mode::storeA : Mode::storeU; \
|
||||
JUCE_VEC_LOOP_TWO_SOURCES (vecOp, loadSrc1, loadSrc2, storeDst, locals, increment); \
|
||||
} \
|
||||
JUCE_FINISH_VEC_OP (normalOp)
|
||||
|
||||
//==============================================================================
|
||||
#elif JUCE_USE_ARM_NEON
|
||||
|
||||
@@ -193,6 +205,12 @@ namespace FloatVectorHelpers
|
||||
JUCE_VEC_LOOP (vecOp, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \
|
||||
JUCE_FINISH_VEC_OP (normalOp)
|
||||
|
||||
#define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST(normalOp, vecOp, locals, increment, setupOp) \
|
||||
JUCE_BEGIN_VEC_OP \
|
||||
setupOp \
|
||||
JUCE_VEC_LOOP_TWO_SOURCES (vecOp, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \
|
||||
JUCE_FINISH_VEC_OP (normalOp)
|
||||
|
||||
//==============================================================================
|
||||
#else
|
||||
#define JUCE_PERFORM_VEC_OP_DEST(normalOp, vecOp, locals, setupOp) \
|
||||
@@ -201,6 +219,8 @@ namespace FloatVectorHelpers
|
||||
#define JUCE_PERFORM_VEC_OP_SRC_DEST(normalOp, vecOp, locals, increment, setupOp) \
|
||||
for (int i = 0; i < num; ++i) normalOp;
|
||||
|
||||
#define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST(normalOp, vecOp, locals, increment, setupOp) \
|
||||
for (int i = 0; i < num; ++i) normalOp;
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
@@ -212,10 +232,19 @@ namespace FloatVectorHelpers
|
||||
increment; \
|
||||
}
|
||||
|
||||
#define JUCE_VEC_LOOP_TWO_SOURCES(vecOp, src1Load, src2Load, dstStore, locals, increment) \
|
||||
for (int i = 0; i < numLongOps; ++i) \
|
||||
{ \
|
||||
locals (src1Load, src2Load); \
|
||||
dstStore (dest, vecOp); \
|
||||
increment; \
|
||||
}
|
||||
|
||||
#define JUCE_LOAD_NONE(srcLoad, dstLoad)
|
||||
#define JUCE_LOAD_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest);
|
||||
#define JUCE_LOAD_SRC(srcLoad, dstLoad) const Mode::ParallelType s = srcLoad (src);
|
||||
#define JUCE_LOAD_SRC_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest), s = srcLoad (src);
|
||||
#define JUCE_LOAD_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest);
|
||||
#define JUCE_LOAD_SRC(srcLoad, dstLoad) const Mode::ParallelType s = srcLoad (src);
|
||||
#define JUCE_LOAD_SRC1_SRC2(src1Load, src2Load) const Mode::ParallelType s1 = src1Load (src1), s2 = src2Load (src2);
|
||||
#define JUCE_LOAD_SRC_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest), s = srcLoad (src);
|
||||
|
||||
#if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON
|
||||
template<int typeSize> struct ModeType { typedef BasicOps32 Mode; };
|
||||
@@ -229,7 +258,7 @@ namespace FloatVectorHelpers
|
||||
|
||||
static Type findMinOrMax (const Type* src, int num, const bool isMinimum) noexcept
|
||||
{
|
||||
const int numLongOps = num / Mode::numParallel;
|
||||
int numLongOps = num / Mode::numParallel;
|
||||
|
||||
#if JUCE_USE_SSE_INTRINSICS
|
||||
if (numLongOps > 1 && isSSE2Available())
|
||||
@@ -246,7 +275,7 @@ namespace FloatVectorHelpers
|
||||
|
||||
if (isMinimum)
|
||||
{
|
||||
for (int i = 1; i < numLongOps; ++i)
|
||||
while (--numLongOps > 0)
|
||||
{
|
||||
src += Mode::numParallel;
|
||||
val = Mode::min (val, Mode::loadA (src));
|
||||
@@ -254,7 +283,7 @@ namespace FloatVectorHelpers
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 1; i < numLongOps; ++i)
|
||||
while (--numLongOps > 0)
|
||||
{
|
||||
src += Mode::numParallel;
|
||||
val = Mode::max (val, Mode::loadA (src));
|
||||
@@ -268,7 +297,7 @@ namespace FloatVectorHelpers
|
||||
|
||||
if (isMinimum)
|
||||
{
|
||||
for (int i = 1; i < numLongOps; ++i)
|
||||
while (--numLongOps > 0)
|
||||
{
|
||||
src += Mode::numParallel;
|
||||
val = Mode::min (val, Mode::loadU (src));
|
||||
@@ -276,7 +305,7 @@ namespace FloatVectorHelpers
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 1; i < numLongOps; ++i)
|
||||
while (--numLongOps > 0)
|
||||
{
|
||||
src += Mode::numParallel;
|
||||
val = Mode::max (val, Mode::loadU (src));
|
||||
@@ -288,6 +317,7 @@ namespace FloatVectorHelpers
|
||||
: Mode::max (val);
|
||||
|
||||
num &= (Mode::numParallel - 1);
|
||||
src += Mode::numParallel;
|
||||
|
||||
for (int i = 0; i < num; ++i)
|
||||
result = isMinimum ? jmin (result, src[i])
|
||||
@@ -302,7 +332,7 @@ namespace FloatVectorHelpers
|
||||
|
||||
static Range<Type> findMinAndMax (const Type* src, int num) noexcept
|
||||
{
|
||||
const int numLongOps = num / Mode::numParallel;
|
||||
int numLongOps = num / Mode::numParallel;
|
||||
|
||||
#if JUCE_USE_SSE_INTRINSICS
|
||||
if (numLongOps > 1 && isSSE2Available())
|
||||
@@ -318,7 +348,7 @@ namespace FloatVectorHelpers
|
||||
mn = Mode::loadA (src);
|
||||
mx = mn;
|
||||
|
||||
for (int i = 1; i < numLongOps; ++i)
|
||||
while (--numLongOps > 0)
|
||||
{
|
||||
src += Mode::numParallel;
|
||||
const ParallelType v = Mode::loadA (src);
|
||||
@@ -332,7 +362,7 @@ namespace FloatVectorHelpers
|
||||
mn = Mode::loadU (src);
|
||||
mx = mn;
|
||||
|
||||
for (int i = 1; i < numLongOps; ++i)
|
||||
while (--numLongOps > 0)
|
||||
{
|
||||
src += Mode::numParallel;
|
||||
const ParallelType v = Mode::loadU (src);
|
||||
@@ -344,7 +374,9 @@ namespace FloatVectorHelpers
|
||||
Range<Type> result (Mode::min (mn),
|
||||
Mode::max (mx));
|
||||
|
||||
num &= 3;
|
||||
num &= (Mode::numParallel - 1);
|
||||
src += Mode::numParallel;
|
||||
|
||||
for (int i = 0; i < num; ++i)
|
||||
result = result.getUnionWith (src[i]);
|
||||
|
||||
@@ -409,7 +441,7 @@ void JUCE_CALLTYPE FloatVectorOperations::copy (double* dest, const double* src,
|
||||
void JUCE_CALLTYPE FloatVectorOperations::copyWithMultiply (float* dest, const float* src, float multiplier, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vsmul (src, 1, &multiplier, dest, 1, num);
|
||||
vDSP_vsmul (src, 1, &multiplier, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, Mode::mul (mult, s),
|
||||
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
|
||||
@@ -420,7 +452,7 @@ void JUCE_CALLTYPE FloatVectorOperations::copyWithMultiply (float* dest, const f
|
||||
void JUCE_CALLTYPE FloatVectorOperations::copyWithMultiply (double* dest, const double* src, double multiplier, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vsmulD (src, 1, &multiplier, dest, 1, num);
|
||||
vDSP_vsmulD (src, 1, &multiplier, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, Mode::mul (mult, s),
|
||||
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
|
||||
@@ -440,10 +472,32 @@ void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, double amount, int
|
||||
const Mode::ParallelType amountToAdd = Mode::load1 (amount);)
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, float* src, float amount, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vsadd (src, 1, &amount, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] + amount, Mode::add (am, s),
|
||||
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
|
||||
const Mode::ParallelType am = Mode::load1 (amount);)
|
||||
#endif
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, double* src, double amount, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vsaddD (src, 1, &amount, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] + amount, Mode::add (am, s),
|
||||
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
|
||||
const Mode::ParallelType am = Mode::load1 (amount);)
|
||||
#endif
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, const float* src, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vadd (src, 1, dest, 1, dest, 1, num);
|
||||
vDSP_vadd (src, 1, dest, 1, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i], Mode::add (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
|
||||
#endif
|
||||
@@ -452,16 +506,34 @@ void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, const float* src, in
|
||||
void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, const double* src, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vaddD (src, 1, dest, 1, dest, 1, num);
|
||||
vDSP_vaddD (src, 1, dest, 1, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i], Mode::add (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
|
||||
#endif
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, const float* src1, const float* src2, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vadd (src1, 1, src2, 1, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] + src2[i], Mode::add (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, )
|
||||
#endif
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, const double* src1, const double* src2, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vaddD (src1, 1, src2, 1, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] + src2[i], Mode::add (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, )
|
||||
#endif
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::subtract (float* dest, const float* src, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vsub (src, 1, dest, 1, dest, 1, num);
|
||||
vDSP_vsub (src, 1, dest, 1, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i], Mode::sub (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
|
||||
#endif
|
||||
@@ -470,12 +542,30 @@ void JUCE_CALLTYPE FloatVectorOperations::subtract (float* dest, const float* sr
|
||||
void JUCE_CALLTYPE FloatVectorOperations::subtract (double* dest, const double* src, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vsubD (src, 1, dest, 1, dest, 1, num);
|
||||
vDSP_vsubD (src, 1, dest, 1, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i], Mode::sub (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
|
||||
#endif
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::subtract (float* dest, const float* src1, const float* src2, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vsub (src2, 1, src1, 1, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] - src2[i], Mode::sub (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, )
|
||||
#endif
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::subtract (double* dest, const double* src1, const double* src2, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vsubD (src2, 1, src1, 1, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] - src2[i], Mode::sub (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, )
|
||||
#endif
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (float* dest, const float* src, float multiplier, int num) noexcept
|
||||
{
|
||||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i] * multiplier, Mode::add (d, Mode::mul (mult, s)),
|
||||
@@ -493,7 +583,7 @@ void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (double* dest, const d
|
||||
void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* src, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vmul (src, 1, dest, 1, dest, 1, num);
|
||||
vDSP_vmul (src, 1, dest, 1, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] *= src[i], Mode::mul (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
|
||||
#endif
|
||||
@@ -502,16 +592,34 @@ void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* sr
|
||||
void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, const double* src, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vmulD (src, 1, dest, 1, dest, 1, num);
|
||||
vDSP_vmulD (src, 1, dest, 1, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] *= src[i], Mode::mul (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
|
||||
#endif
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* src1, const float* src2, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vmul (src1, 1, src2, 1, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] * src2[i], Mode::mul (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, )
|
||||
#endif
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, const double* src1, const double* src2, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vmulD (src1, 1, src2, 1, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] * src2[i], Mode::mul (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, )
|
||||
#endif
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, float multiplier, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vsmul (dest, 1, &multiplier, dest, 1, num);
|
||||
vDSP_vsmul (dest, 1, &multiplier, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_DEST (dest[i] *= multiplier, Mode::mul (d, mult), JUCE_LOAD_DEST,
|
||||
const Mode::ParallelType mult = Mode::load1 (multiplier);)
|
||||
@@ -521,13 +629,27 @@ void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, float multiplie
|
||||
void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, double multiplier, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
vDSP_vsmulD (dest, 1, &multiplier, dest, 1, num);
|
||||
vDSP_vsmulD (dest, 1, &multiplier, dest, 1, (vDSP_Length) num);
|
||||
#else
|
||||
JUCE_PERFORM_VEC_OP_DEST (dest[i] *= multiplier, Mode::mul (d, mult), JUCE_LOAD_DEST,
|
||||
const Mode::ParallelType mult = Mode::load1 (multiplier);)
|
||||
#endif
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* src, float multiplier, int num) noexcept
|
||||
{
|
||||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, Mode::mul (mult, s),
|
||||
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
|
||||
const Mode::ParallelType mult = Mode::load1 (multiplier);)
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, const double* src, double multiplier, int num) noexcept
|
||||
{
|
||||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, Mode::mul (mult, s),
|
||||
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
|
||||
const Mode::ParallelType mult = Mode::load1 (multiplier);)
|
||||
}
|
||||
|
||||
void FloatVectorOperations::negate (float* dest, const float* src, int num) noexcept
|
||||
{
|
||||
#if JUCE_USE_VDSP_FRAMEWORK
|
||||
@@ -640,8 +762,8 @@ public:
|
||||
const int range = random.nextBool() ? 500 : 10;
|
||||
const int num = random.nextInt (range) + 1;
|
||||
|
||||
HeapBlock<ValueType> buffer1 (num + 16), buffer2 (num + 16);
|
||||
HeapBlock<int> buffer3 (num + 16);
|
||||
HeapBlock<ValueType> buffer1 ((size_t) num + 16), buffer2 ((size_t) num + 16);
|
||||
HeapBlock<int> buffer3 ((size_t) num + 16);
|
||||
|
||||
#if JUCE_ARM
|
||||
ValueType* const data1 = buffer1;
|
||||
|
||||
@@ -65,18 +65,36 @@ public:
|
||||
/** Adds a fixed value to the destination values. */
|
||||
static void JUCE_CALLTYPE add (double* dest, double amountToAdd, int numValues) noexcept;
|
||||
|
||||
/** Adds a fixed value to each source value and stores it in the destination array. */
|
||||
static void JUCE_CALLTYPE add (float* dest, float* src, float amount, int numValues) noexcept;
|
||||
|
||||
/** Adds a fixed value to each source value and stores it in the destination array. */
|
||||
static void JUCE_CALLTYPE add (double* dest, double* src, double amount, int numValues) noexcept;
|
||||
|
||||
/** Adds the source values to the destination values. */
|
||||
static void JUCE_CALLTYPE add (float* dest, const float* src, int numValues) noexcept;
|
||||
|
||||
/** Adds the source values to the destination values. */
|
||||
static void JUCE_CALLTYPE add (double* dest, const double* src, int numValues) noexcept;
|
||||
|
||||
/** Adds each source1 value to the corresponding source2 value and stores the result in the destination array. */
|
||||
static void JUCE_CALLTYPE add (float* dest, const float* src1, const float* src2, int num) noexcept;
|
||||
|
||||
/** Adds each source1 value to the corresponding source2 value and stores the result in the destination array. */
|
||||
static void JUCE_CALLTYPE add (double* dest, const double* src1, const double* src2, int num) noexcept;
|
||||
|
||||
/** Subtracts the source values from the destination values. */
|
||||
static void JUCE_CALLTYPE subtract (float* dest, const float* src, int numValues) noexcept;
|
||||
|
||||
/** Subtracts the source values from the destination values. */
|
||||
static void JUCE_CALLTYPE subtract (double* dest, const double* src, int numValues) noexcept;
|
||||
|
||||
/** Subtracts each source2 value from the corresponding source1 value and stores the result in the destination array. */
|
||||
static void JUCE_CALLTYPE subtract (float* dest, const float* src1, const float* src2, int num) noexcept;
|
||||
|
||||
/** Subtracts each source2 value from the corresponding source1 value and stores the result in the destination array. */
|
||||
static void JUCE_CALLTYPE subtract (double* dest, const double* src1, const double* src2, int num) noexcept;
|
||||
|
||||
/** Multiplies each source value by the given multiplier, then adds it to the destination value. */
|
||||
static void JUCE_CALLTYPE addWithMultiply (float* dest, const float* src, float multiplier, int numValues) noexcept;
|
||||
|
||||
@@ -89,12 +107,24 @@ public:
|
||||
/** Multiplies the destination values by the source values. */
|
||||
static void JUCE_CALLTYPE multiply (double* dest, const double* src, int numValues) noexcept;
|
||||
|
||||
/** Multiplies each source1 value by the correspinding source2 value, then stores it in the destination array. */
|
||||
static void JUCE_CALLTYPE multiply (float* dest, const float* src1, const float* src2, int numValues) noexcept;
|
||||
|
||||
/** Multiplies each source1 value by the correspinding source2 value, then stores it in the destination array. */
|
||||
static void JUCE_CALLTYPE multiply (double* dest, const double* src1, const double* src2, int numValues) noexcept;
|
||||
|
||||
/** Multiplies each of the destination values by a fixed multiplier. */
|
||||
static void JUCE_CALLTYPE multiply (float* dest, float multiplier, int numValues) noexcept;
|
||||
|
||||
/** Multiplies each of the destination values by a fixed multiplier. */
|
||||
static void JUCE_CALLTYPE multiply (double* dest, double multiplier, int numValues) noexcept;
|
||||
|
||||
/** Multiplies each of the source values by a fixed multiplier and stores the result in the destination array. */
|
||||
static void JUCE_CALLTYPE multiply (float* dest, const float* src, float multiplier, int num) noexcept;
|
||||
|
||||
/** Multiplies each of the source values by a fixed multiplier and stores the result in the destination array. */
|
||||
static void JUCE_CALLTYPE multiply (double* dest, const double* src, double multiplier, int num) noexcept;
|
||||
|
||||
/** Copies a source vector to a destination, negating each value. */
|
||||
static void JUCE_CALLTYPE negate (float* dest, const float* src, int numValues) noexcept;
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ public:
|
||||
for (int j = 0; j < numAllPasses; ++j) // run the allpass filters in series
|
||||
output = allPass[0][j].process (output);
|
||||
|
||||
samples[i] = output * wet1 + input * dry;
|
||||
samples[i] = output * wet1 + samples[i] * dry;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,9 @@
|
||||
#endif
|
||||
|
||||
#if (JUCE_MAC || JUCE_IOS) && JUCE_USE_VDSP_FRAMEWORK
|
||||
#define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers)
|
||||
#include <Accelerate/Accelerate.h>
|
||||
#undef Point
|
||||
#else
|
||||
#undef JUCE_USE_VDSP_FRAMEWORK
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "juce_audio_basics",
|
||||
"name": "JUCE audio and midi data classes",
|
||||
"version": "3.0.5",
|
||||
"version": "3.0.8",
|
||||
"description": "Classes for audio buffer manipulation, midi message handling, synthesis, etc",
|
||||
"website": "http://www.juce.com/juce",
|
||||
"license": "GPL/Commercial",
|
||||
|
||||
@@ -210,7 +210,7 @@ bool MidiBuffer::Iterator::getNextEvent (const uint8* &midiData, int& numBytes,
|
||||
const int itemSize = MidiBufferHelpers::getEventDataSize (data);
|
||||
numBytes = itemSize;
|
||||
midiData = data + sizeof (int32) + sizeof (uint16);
|
||||
data += sizeof (int32) + sizeof (uint16) + itemSize;
|
||||
data += sizeof (int32) + sizeof (uint16) + (size_t) itemSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result, int& samplePositio
|
||||
samplePosition = MidiBufferHelpers::getEventTime (data);
|
||||
const int itemSize = MidiBufferHelpers::getEventDataSize (data);
|
||||
result = MidiMessage (data + sizeof (int32) + sizeof (uint16), itemSize, samplePosition);
|
||||
data += sizeof (int32) + sizeof (uint16) + itemSize;
|
||||
data += sizeof (int32) + sizeof (uint16) + (size_t) itemSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -186,9 +186,10 @@ public:
|
||||
|
||||
/** Retrieves a copy of the next event from the buffer.
|
||||
|
||||
@param result on return, this will be the message (the MidiMessage's timestamp
|
||||
is not set)
|
||||
@param samplePosition on return, this will be the position of the event
|
||||
@param result on return, this will be the message. The MidiMessage's timestamp
|
||||
is set to the same value as samplePosition.
|
||||
@param samplePosition on return, this will be the position of the event, as a
|
||||
sample index in the buffer
|
||||
@returns true if an event was found, or false if the iterator has reached
|
||||
the end of the buffer
|
||||
*/
|
||||
@@ -203,7 +204,8 @@ public:
|
||||
temporarily until the MidiBuffer is altered.
|
||||
@param numBytesOfMidiData on return, this is the number of bytes of data used by the
|
||||
midi message
|
||||
@param samplePosition on return, this will be the position of the event
|
||||
@param samplePosition on return, this will be the position of the event, as a
|
||||
sample index in the buffer
|
||||
@returns true if an event was found, or false if the iterator has reached
|
||||
the end of the buffer
|
||||
*/
|
||||
|
||||
@@ -129,7 +129,7 @@ MidiMessage::MidiMessage (const MidiMessage& other)
|
||||
{
|
||||
if (other.allocatedData != nullptr)
|
||||
{
|
||||
allocatedData.malloc (size);
|
||||
allocatedData.malloc ((size_t) size);
|
||||
memcpy (allocatedData, other.allocatedData, (size_t) size);
|
||||
}
|
||||
else
|
||||
@@ -143,7 +143,7 @@ MidiMessage::MidiMessage (const MidiMessage& other, const double newTimeStamp)
|
||||
{
|
||||
if (other.allocatedData != nullptr)
|
||||
{
|
||||
allocatedData.malloc (size);
|
||||
allocatedData.malloc ((size_t) size);
|
||||
memcpy (allocatedData, other.allocatedData, (size_t) size);
|
||||
}
|
||||
else
|
||||
@@ -255,7 +255,7 @@ MidiMessage& MidiMessage::operator= (const MidiMessage& other)
|
||||
|
||||
if (other.allocatedData != nullptr)
|
||||
{
|
||||
allocatedData.malloc (size);
|
||||
allocatedData.malloc ((size_t) size);
|
||||
memcpy (allocatedData, other.allocatedData, (size_t) size);
|
||||
}
|
||||
else
|
||||
@@ -297,7 +297,7 @@ uint8* MidiMessage::allocateSpace (int bytes)
|
||||
{
|
||||
if (bytes > 4)
|
||||
{
|
||||
allocatedData.malloc (bytes);
|
||||
allocatedData.malloc ((size_t) bytes);
|
||||
return allocatedData;
|
||||
}
|
||||
|
||||
@@ -661,7 +661,7 @@ String MidiMessage::getTextFromTextMetaEvent() const
|
||||
|
||||
MidiMessage MidiMessage::textMetaEvent (int type, StringRef text)
|
||||
{
|
||||
jassert (type > 0 && type < 16)
|
||||
jassert (type > 0 && type < 16);
|
||||
|
||||
MidiMessage result;
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ MidiMessageSequence::MidiMessageSequence()
|
||||
MidiMessageSequence::MidiMessageSequence (const MidiMessageSequence& other)
|
||||
{
|
||||
list.addCopiesOf (other.list);
|
||||
updateMatchedPairs();
|
||||
}
|
||||
|
||||
MidiMessageSequence& MidiMessageSequence::operator= (const MidiMessageSequence& other)
|
||||
@@ -52,17 +53,17 @@ void MidiMessageSequence::clear()
|
||||
list.clear();
|
||||
}
|
||||
|
||||
int MidiMessageSequence::getNumEvents() const
|
||||
int MidiMessageSequence::getNumEvents() const noexcept
|
||||
{
|
||||
return list.size();
|
||||
}
|
||||
|
||||
MidiMessageSequence::MidiEventHolder* MidiMessageSequence::getEventPointer (const int index) const
|
||||
MidiMessageSequence::MidiEventHolder* MidiMessageSequence::getEventPointer (const int index) const noexcept
|
||||
{
|
||||
return list [index];
|
||||
}
|
||||
|
||||
double MidiMessageSequence::getTimeOfMatchingKeyUp (const int index) const
|
||||
double MidiMessageSequence::getTimeOfMatchingKeyUp (const int index) const noexcept
|
||||
{
|
||||
if (const MidiEventHolder* const meh = list [index])
|
||||
if (meh->noteOffObject != nullptr)
|
||||
@@ -71,7 +72,7 @@ double MidiMessageSequence::getTimeOfMatchingKeyUp (const int index) const
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
int MidiMessageSequence::getIndexOfMatchingKeyUp (const int index) const
|
||||
int MidiMessageSequence::getIndexOfMatchingKeyUp (const int index) const noexcept
|
||||
{
|
||||
if (const MidiEventHolder* const meh = list [index])
|
||||
return list.indexOf (meh->noteOffObject);
|
||||
@@ -79,12 +80,12 @@ int MidiMessageSequence::getIndexOfMatchingKeyUp (const int index) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
int MidiMessageSequence::getIndexOf (MidiEventHolder* const event) const
|
||||
int MidiMessageSequence::getIndexOf (MidiEventHolder* const event) const noexcept
|
||||
{
|
||||
return list.indexOf (event);
|
||||
}
|
||||
|
||||
int MidiMessageSequence::getNextIndexAtTime (const double timeStamp) const
|
||||
int MidiMessageSequence::getNextIndexAtTime (const double timeStamp) const noexcept
|
||||
{
|
||||
const int numEvents = list.size();
|
||||
|
||||
@@ -97,17 +98,17 @@ int MidiMessageSequence::getNextIndexAtTime (const double timeStamp) const
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
double MidiMessageSequence::getStartTime() const
|
||||
double MidiMessageSequence::getStartTime() const noexcept
|
||||
{
|
||||
return getEventTime (0);
|
||||
}
|
||||
|
||||
double MidiMessageSequence::getEndTime() const
|
||||
double MidiMessageSequence::getEndTime() const noexcept
|
||||
{
|
||||
return getEventTime (list.size() - 1);
|
||||
}
|
||||
|
||||
double MidiMessageSequence::getEventTime (const int index) const
|
||||
double MidiMessageSequence::getEventTime (const int index) const noexcept
|
||||
{
|
||||
if (const MidiEventHolder* const meh = list [index])
|
||||
return meh->message.getTimeStamp();
|
||||
@@ -181,13 +182,13 @@ void MidiMessageSequence::addSequence (const MidiMessageSequence& other,
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MidiMessageSequence::sort()
|
||||
void MidiMessageSequence::sort() noexcept
|
||||
{
|
||||
MidiMessageSequenceSorter sorter;
|
||||
list.sort (sorter, true);
|
||||
}
|
||||
|
||||
void MidiMessageSequence::updateMatchedPairs()
|
||||
void MidiMessageSequence::updateMatchedPairs() noexcept
|
||||
{
|
||||
for (int i = 0; i < list.size(); ++i)
|
||||
{
|
||||
@@ -226,7 +227,7 @@ void MidiMessageSequence::updateMatchedPairs()
|
||||
}
|
||||
}
|
||||
|
||||
void MidiMessageSequence::addTimeToMessages (const double delta)
|
||||
void MidiMessageSequence::addTimeToMessages (const double delta) noexcept
|
||||
{
|
||||
for (int i = list.size(); --i >= 0;)
|
||||
{
|
||||
|
||||
@@ -91,47 +91,47 @@ public:
|
||||
void clear();
|
||||
|
||||
/** Returns the number of events in the sequence. */
|
||||
int getNumEvents() const;
|
||||
int getNumEvents() const noexcept;
|
||||
|
||||
/** Returns a pointer to one of the events. */
|
||||
MidiEventHolder* getEventPointer (int index) const;
|
||||
MidiEventHolder* getEventPointer (int index) const noexcept;
|
||||
|
||||
/** Returns the time of the note-up that matches the note-on at this index.
|
||||
If the event at this index isn't a note-on, it'll just return 0.
|
||||
@see MidiMessageSequence::MidiEventHolder::noteOffObject
|
||||
*/
|
||||
double getTimeOfMatchingKeyUp (int index) const;
|
||||
double getTimeOfMatchingKeyUp (int index) const noexcept;
|
||||
|
||||
/** Returns the index of the note-up that matches the note-on at this index.
|
||||
If the event at this index isn't a note-on, it'll just return -1.
|
||||
@see MidiMessageSequence::MidiEventHolder::noteOffObject
|
||||
*/
|
||||
int getIndexOfMatchingKeyUp (int index) const;
|
||||
int getIndexOfMatchingKeyUp (int index) const noexcept;
|
||||
|
||||
/** Returns the index of an event. */
|
||||
int getIndexOf (MidiEventHolder* event) const;
|
||||
int getIndexOf (MidiEventHolder* event) const noexcept;
|
||||
|
||||
/** Returns the index of the first event on or after the given timestamp.
|
||||
If the time is beyond the end of the sequence, this will return the
|
||||
number of events.
|
||||
*/
|
||||
int getNextIndexAtTime (double timeStamp) const;
|
||||
int getNextIndexAtTime (double timeStamp) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the timestamp of the first event in the sequence.
|
||||
@see getEndTime
|
||||
*/
|
||||
double getStartTime() const;
|
||||
double getStartTime() const noexcept;
|
||||
|
||||
/** Returns the timestamp of the last event in the sequence.
|
||||
@see getStartTime
|
||||
*/
|
||||
double getEndTime() const;
|
||||
double getEndTime() const noexcept;
|
||||
|
||||
/** Returns the timestamp of the event at a given index.
|
||||
If the index is out-of-range, this will return 0.0
|
||||
*/
|
||||
double getEventTime (int index) const;
|
||||
double getEventTime (int index) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Inserts a midi message into the sequence.
|
||||
@@ -185,13 +185,13 @@ public:
|
||||
will scan the list and make sure all the note-offs in the MidiEventHolder
|
||||
structures are pointing at the correct ones.
|
||||
*/
|
||||
void updateMatchedPairs();
|
||||
void updateMatchedPairs() noexcept;
|
||||
|
||||
/** Forces a sort of the sequence.
|
||||
You may need to call this if you've manually modified the timestamps of some
|
||||
events such that the overall order now needs updating.
|
||||
*/
|
||||
void sort();
|
||||
void sort() noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Copies all the messages for a particular midi channel to another sequence.
|
||||
@@ -224,7 +224,7 @@ public:
|
||||
/** Adds an offset to the timestamps of all events in the sequence.
|
||||
@param deltaTime the amount to add to each timestamp.
|
||||
*/
|
||||
void addTimeToMessages (double deltaTime);
|
||||
void addTimeToMessages (double deltaTime) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Scans through the sequence to determine the state of any midi controllers at
|
||||
|
||||
@@ -47,23 +47,28 @@ void ResamplingAudioSource::setResamplingRatio (const double samplesInPerOutputS
|
||||
ratio = jmax (0.0, samplesInPerOutputSample);
|
||||
}
|
||||
|
||||
void ResamplingAudioSource::prepareToPlay (int samplesPerBlockExpected,
|
||||
double sampleRate)
|
||||
void ResamplingAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
|
||||
{
|
||||
const SpinLock::ScopedLockType sl (ratioLock);
|
||||
|
||||
input->prepareToPlay (samplesPerBlockExpected, sampleRate);
|
||||
|
||||
buffer.setSize (numChannels, roundToInt (samplesPerBlockExpected * ratio) + 32);
|
||||
buffer.clear();
|
||||
sampsInBuffer = 0;
|
||||
bufferPos = 0;
|
||||
subSampleOffset = 0.0;
|
||||
|
||||
filterStates.calloc ((size_t) numChannels);
|
||||
srcBuffers.calloc ((size_t) numChannels);
|
||||
destBuffers.calloc ((size_t) numChannels);
|
||||
createLowPass (ratio);
|
||||
|
||||
flushBuffers();
|
||||
}
|
||||
|
||||
void ResamplingAudioSource::flushBuffers()
|
||||
{
|
||||
buffer.clear();
|
||||
bufferPos = 0;
|
||||
sampsInBuffer = 0;
|
||||
subSampleOffset = 0.0;
|
||||
resetFilters();
|
||||
}
|
||||
|
||||
@@ -225,7 +230,8 @@ void ResamplingAudioSource::setFilterCoefficients (double c1, double c2, double
|
||||
|
||||
void ResamplingAudioSource::resetFilters()
|
||||
{
|
||||
filterStates.clear ((size_t) numChannels);
|
||||
if (filterStates != nullptr)
|
||||
filterStates.clear ((size_t) numChannels);
|
||||
}
|
||||
|
||||
void ResamplingAudioSource::applyFilter (float* samples, int num, FilterState& fs)
|
||||
|
||||
@@ -66,6 +66,9 @@ public:
|
||||
*/
|
||||
double getResamplingRatio() const noexcept { return ratio; }
|
||||
|
||||
/** Clears any buffers and filters that the resampler is using. */
|
||||
void flushBuffers();
|
||||
|
||||
//==============================================================================
|
||||
void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override;
|
||||
void releaseResources() override;
|
||||
|
||||
@@ -163,10 +163,7 @@ void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBu
|
||||
: numSamples;
|
||||
|
||||
if (numThisTime > 0)
|
||||
{
|
||||
for (int i = voices.size(); --i >= 0;)
|
||||
voices.getUnchecked (i)->renderNextBlock (outputBuffer, startSample, numThisTime);
|
||||
}
|
||||
renderVoices (outputBuffer, startSample, numThisTime);
|
||||
|
||||
if (useEvent)
|
||||
handleMidiEvent (m);
|
||||
@@ -176,6 +173,12 @@ void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBu
|
||||
}
|
||||
}
|
||||
|
||||
void Synthesiser::renderVoices (AudioSampleBuffer& buffer, int startSample, int numSamples)
|
||||
{
|
||||
for (int i = voices.size(); --i >= 0;)
|
||||
voices.getUnchecked (i)->renderNextBlock (buffer, startSample, numSamples);
|
||||
}
|
||||
|
||||
void Synthesiser::handleMidiEvent (const MidiMessage& m)
|
||||
{
|
||||
if (m.isNoteOn())
|
||||
@@ -184,7 +187,7 @@ void Synthesiser::handleMidiEvent (const MidiMessage& m)
|
||||
}
|
||||
else if (m.isNoteOff())
|
||||
{
|
||||
noteOff (m.getChannel(), m.getNoteNumber(), true);
|
||||
noteOff (m.getChannel(), m.getNoteNumber(), m.getFloatVelocity(), true);
|
||||
}
|
||||
else if (m.isAllNotesOff() || m.isAllSoundOff())
|
||||
{
|
||||
@@ -230,10 +233,10 @@ void Synthesiser::noteOn (const int midiChannel,
|
||||
|
||||
if (voice->getCurrentlyPlayingNote() == midiNoteNumber
|
||||
&& voice->isPlayingChannel (midiChannel))
|
||||
stopVoice (voice, true);
|
||||
stopVoice (voice, 1.0f, true);
|
||||
}
|
||||
|
||||
startVoice (findFreeVoice (sound, shouldStealNotes),
|
||||
startVoice (findFreeVoice (sound, midiChannel, midiNoteNumber, shouldStealNotes),
|
||||
sound, midiChannel, midiNoteNumber, velocity);
|
||||
}
|
||||
}
|
||||
@@ -248,7 +251,7 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice,
|
||||
if (voice != nullptr && sound != nullptr)
|
||||
{
|
||||
if (voice->currentlyPlayingSound != nullptr)
|
||||
voice->stopNote (false);
|
||||
voice->stopNote (0.0f, false);
|
||||
|
||||
voice->startNote (midiNoteNumber, velocity, sound,
|
||||
lastPitchWheelValues [midiChannel - 1]);
|
||||
@@ -261,11 +264,11 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice,
|
||||
}
|
||||
}
|
||||
|
||||
void Synthesiser::stopVoice (SynthesiserVoice* voice, const bool allowTailOff)
|
||||
void Synthesiser::stopVoice (SynthesiserVoice* voice, float velocity, const bool allowTailOff)
|
||||
{
|
||||
jassert (voice != nullptr);
|
||||
|
||||
voice->stopNote (allowTailOff);
|
||||
voice->stopNote (velocity, allowTailOff);
|
||||
|
||||
// the subclass MUST call clearCurrentNote() if it's not tailing off! RTFM for stopNote()!
|
||||
jassert (allowTailOff || (voice->getCurrentlyPlayingNote() < 0 && voice->getCurrentlyPlayingSound() == 0));
|
||||
@@ -273,6 +276,7 @@ void Synthesiser::stopVoice (SynthesiserVoice* voice, const bool allowTailOff)
|
||||
|
||||
void Synthesiser::noteOff (const int midiChannel,
|
||||
const int midiNoteNumber,
|
||||
const float velocity,
|
||||
const bool allowTailOff)
|
||||
{
|
||||
const ScopedLock sl (lock);
|
||||
@@ -291,7 +295,7 @@ void Synthesiser::noteOff (const int midiChannel,
|
||||
voice->keyIsDown = false;
|
||||
|
||||
if (! (sustainPedalsDown [midiChannel] || voice->sostenutoPedalDown))
|
||||
stopVoice (voice, allowTailOff);
|
||||
stopVoice (voice, velocity, allowTailOff);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -307,7 +311,7 @@ void Synthesiser::allNotesOff (const int midiChannel, const bool allowTailOff)
|
||||
SynthesiserVoice* const voice = voices.getUnchecked (i);
|
||||
|
||||
if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))
|
||||
voice->stopNote (allowTailOff);
|
||||
voice->stopNote (1.0f, allowTailOff);
|
||||
}
|
||||
|
||||
sustainPedalsDown.clear();
|
||||
@@ -379,7 +383,7 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown)
|
||||
SynthesiserVoice* const voice = voices.getUnchecked (i);
|
||||
|
||||
if (voice->isPlayingChannel (midiChannel) && ! voice->keyIsDown)
|
||||
stopVoice (voice, true);
|
||||
stopVoice (voice, 1.0f, true);
|
||||
}
|
||||
|
||||
sustainPedalsDown.clearBit (midiChannel);
|
||||
@@ -400,7 +404,7 @@ void Synthesiser::handleSostenutoPedal (int midiChannel, bool isDown)
|
||||
if (isDown)
|
||||
voice->sostenutoPedalDown = true;
|
||||
else if (voice->sostenutoPedalDown)
|
||||
stopVoice (voice, true);
|
||||
stopVoice (voice, 1.0f, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -412,7 +416,9 @@ void Synthesiser::handleSoftPedal (int midiChannel, bool /*isDown*/)
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay, const bool stealIfNoneAvailable) const
|
||||
SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay,
|
||||
int midiChannel, int midiNoteNumber,
|
||||
const bool stealIfNoneAvailable) const
|
||||
{
|
||||
const ScopedLock sl (lock);
|
||||
|
||||
@@ -425,25 +431,68 @@ SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay, con
|
||||
}
|
||||
|
||||
if (stealIfNoneAvailable)
|
||||
return findVoiceToSteal (soundToPlay);
|
||||
return findVoiceToSteal (soundToPlay, midiChannel, midiNoteNumber);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay) const
|
||||
struct VoiceAgeSorter
|
||||
{
|
||||
// currently this just steals the one that's been playing the longest, but could be made a bit smarter..
|
||||
SynthesiserVoice* oldest = nullptr;
|
||||
static int compareElements (SynthesiserVoice* v1, SynthesiserVoice* v2) noexcept
|
||||
{
|
||||
return v1->wasStartedBefore (*v2) ? 1 : (v2->wasStartedBefore (*v1) ? -1 : 0);
|
||||
}
|
||||
};
|
||||
|
||||
SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
|
||||
int /*midiChannel*/, int midiNoteNumber) const
|
||||
{
|
||||
SynthesiserVoice* bottom = nullptr;
|
||||
SynthesiserVoice* top = nullptr;
|
||||
|
||||
// this is a list of voices we can steal, sorted by how long they've been running
|
||||
Array<SynthesiserVoice*> usableVoices;
|
||||
usableVoices.ensureStorageAllocated (voices.size());
|
||||
|
||||
for (int i = 0; i < voices.size(); ++i)
|
||||
{
|
||||
SynthesiserVoice* const voice = voices.getUnchecked (i);
|
||||
|
||||
if (voice->canPlaySound (soundToPlay)
|
||||
&& (oldest == nullptr || voice->wasStartedBefore (*oldest)))
|
||||
oldest = voice;
|
||||
if (voice->canPlaySound (soundToPlay))
|
||||
{
|
||||
VoiceAgeSorter sorter;
|
||||
usableVoices.addSorted (sorter, voice);
|
||||
|
||||
const int note = voice->getCurrentlyPlayingNote();
|
||||
|
||||
if (bottom == nullptr || note < bottom->getCurrentlyPlayingNote())
|
||||
bottom = voice;
|
||||
|
||||
if (top == nullptr || note > top->getCurrentlyPlayingNote())
|
||||
top = voice;
|
||||
}
|
||||
}
|
||||
|
||||
jassert (oldest != nullptr);
|
||||
return oldest;
|
||||
jassert (bottom != nullptr && top != nullptr);
|
||||
|
||||
// The oldest note that's playing with the target pitch playing is ideal..
|
||||
for (int i = 0; i < usableVoices.size(); ++i)
|
||||
{
|
||||
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
|
||||
|
||||
if (voice->getCurrentlyPlayingNote() == midiNoteNumber)
|
||||
return voice;
|
||||
}
|
||||
|
||||
// ..otherwise, look for the oldest note that isn't the top or bottom note..
|
||||
for (int i = 0; i < usableVoices.size(); ++i)
|
||||
{
|
||||
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
|
||||
|
||||
if (voice != bottom && voice != top)
|
||||
return voice;
|
||||
}
|
||||
|
||||
// ..otherwise, there's only one or two voices to choose from - we'll return the top one..
|
||||
return top;
|
||||
}
|
||||
|
||||
@@ -55,14 +55,14 @@ public:
|
||||
The Synthesiser will use this information when deciding which sounds to trigger
|
||||
for a given note.
|
||||
*/
|
||||
virtual bool appliesToNote (const int midiNoteNumber) = 0;
|
||||
virtual bool appliesToNote (int midiNoteNumber) = 0;
|
||||
|
||||
/** Returns true if the sound should be triggered by midi events on a given channel.
|
||||
|
||||
The Synthesiser will use this information when deciding which sounds to trigger
|
||||
for a given note.
|
||||
*/
|
||||
virtual bool appliesToChannel (const int midiChannel) = 0;
|
||||
virtual bool appliesToChannel (int midiChannel) = 0;
|
||||
|
||||
/** The class is reference-counted, so this is a handy pointer class for it. */
|
||||
typedef ReferenceCountedObjectPtr<SynthesiserSound> Ptr;
|
||||
@@ -127,6 +127,8 @@ public:
|
||||
|
||||
This will be called during the rendering callback, so must be fast and thread-safe.
|
||||
|
||||
The velocity indicates how quickly the note was released - 0 is slowly, 1 is quickly.
|
||||
|
||||
If allowTailOff is false or the voice doesn't want to tail-off, then it must stop all
|
||||
sound immediately, and must call clearCurrentNote() to reset the state of this voice
|
||||
and allow the synth to reassign it another sound.
|
||||
@@ -136,7 +138,7 @@ public:
|
||||
finishes playing (during the rendering callback), it must make sure that it calls
|
||||
clearCurrentNote().
|
||||
*/
|
||||
virtual void stopNote (bool allowTailOff) = 0;
|
||||
virtual void stopNote (float velocity, bool allowTailOff) = 0;
|
||||
|
||||
/** Called to let the voice know that the pitch wheel has been moved.
|
||||
This will be called during the rendering callback, so must be fast and thread-safe.
|
||||
@@ -173,13 +175,6 @@ public:
|
||||
int startSample,
|
||||
int numSamples) = 0;
|
||||
|
||||
/** Returns true if the voice is currently playing a sound which is mapped to the given
|
||||
midi channel.
|
||||
|
||||
If it's not currently playing, this will return false.
|
||||
*/
|
||||
bool isPlayingChannel (int midiChannel) const;
|
||||
|
||||
/** Changes the voice's reference sample rate.
|
||||
|
||||
The rate is set so that subclasses know the output rate and can set their pitch
|
||||
@@ -188,7 +183,19 @@ public:
|
||||
This method is called by the synth, and subclasses can access the current rate with
|
||||
the currentSampleRate member.
|
||||
*/
|
||||
void setCurrentPlaybackSampleRate (double newRate);
|
||||
virtual void setCurrentPlaybackSampleRate (double newRate);
|
||||
|
||||
/** Returns the current target sample rate at which rendering is being done.
|
||||
Subclasses may need to know this so that they can pitch things correctly.
|
||||
*/
|
||||
double getSampleRate() const noexcept { return currentSampleRate; }
|
||||
|
||||
/** Returns true if the voice is currently playing a sound which is mapped to the given
|
||||
midi channel.
|
||||
|
||||
If it's not currently playing, this will return false.
|
||||
*/
|
||||
bool isPlayingChannel (int midiChannel) const;
|
||||
|
||||
/** Returns true if the key that triggered this voice is still held down.
|
||||
Note that the voice may still be playing after the key was released (e.g because the
|
||||
@@ -203,13 +210,6 @@ public:
|
||||
bool wasStartedBefore (const SynthesiserVoice& other) const noexcept;
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** Returns the current target sample rate at which rendering is being done.
|
||||
|
||||
This is available for subclasses so they can pitch things correctly.
|
||||
*/
|
||||
double getSampleRate() const { return currentSampleRate; }
|
||||
|
||||
/** Resets the state of this voice after a sound has finished playing.
|
||||
|
||||
The subclass must call this when it finishes playing a note and becomes available
|
||||
@@ -235,6 +235,11 @@ private:
|
||||
SynthesiserSound::Ptr currentlyPlayingSound;
|
||||
bool keyIsDown, sostenutoPedalDown;
|
||||
|
||||
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE
|
||||
// Note the new parameters for this method.
|
||||
virtual int stopNote (bool) { return 0; }
|
||||
#endif
|
||||
|
||||
JUCE_LEAK_DETECTOR (SynthesiserVoice)
|
||||
};
|
||||
|
||||
@@ -268,8 +273,7 @@ class JUCE_API Synthesiser
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a new synthesiser.
|
||||
|
||||
You'll need to add some sounds and voices before it'll make any sound..
|
||||
You'll need to add some sounds and voices before it'll make any sound.
|
||||
*/
|
||||
Synthesiser();
|
||||
|
||||
@@ -365,6 +369,7 @@ public:
|
||||
*/
|
||||
virtual void noteOff (int midiChannel,
|
||||
int midiNoteNumber,
|
||||
float velocity,
|
||||
bool allowTailOff);
|
||||
|
||||
/** Turns off all notes.
|
||||
@@ -444,7 +449,7 @@ public:
|
||||
This value is propagated to the voices so that they can use it to render the correct
|
||||
pitches.
|
||||
*/
|
||||
void setCurrentPlaybackSampleRate (double sampleRate);
|
||||
virtual void setCurrentPlaybackSampleRate (double sampleRate);
|
||||
|
||||
/** Creates the next block of audio output.
|
||||
|
||||
@@ -463,6 +468,11 @@ public:
|
||||
int startSample,
|
||||
int numSamples);
|
||||
|
||||
/** Returns the current target sample rate at which rendering is being done.
|
||||
Subclasses may need to know this so that they can pitch things correctly.
|
||||
*/
|
||||
double getSampleRate() const noexcept { return sampleRate; }
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** This is used to control access to the rendering callback and the note trigger methods. */
|
||||
@@ -474,21 +484,34 @@ protected:
|
||||
/** The last pitch-wheel values for each midi channel. */
|
||||
int lastPitchWheelValues [16];
|
||||
|
||||
/** Searches through the voices to find one that's not currently playing, and which
|
||||
can play the given sound.
|
||||
/** Renders the voices for the given range.
|
||||
By default this just calls renderNextBlock() on each voice, but you may need
|
||||
to override it to handle custom cases.
|
||||
*/
|
||||
virtual void renderVoices (AudioSampleBuffer& outputAudio,
|
||||
int startSample, int numSamples);
|
||||
|
||||
/** Searches through the voices to find one that's not currently playing, and
|
||||
which can play the given sound.
|
||||
|
||||
Returns nullptr if all voices are busy and stealing isn't enabled.
|
||||
|
||||
This can be overridden to implement custom voice-stealing algorithms.
|
||||
To implement a custom note-stealing algorithm, you can either override this
|
||||
method, or (preferably) override findVoiceToSteal().
|
||||
*/
|
||||
virtual SynthesiserVoice* findFreeVoice (SynthesiserSound* soundToPlay,
|
||||
const bool stealIfNoneAvailable) const;
|
||||
int midiChannel,
|
||||
int midiNoteNumber,
|
||||
bool stealIfNoneAvailable) const;
|
||||
|
||||
/** Chooses a voice that is most suitable for being re-used.
|
||||
The default method returns the one that has been playing for the longest, but
|
||||
you may want to override this and do something more cunning instead.
|
||||
The default method will attempt to find the oldest voice that isn't the
|
||||
bottom or top note being played. If that's not suitable for your synth,
|
||||
you can override this method and do something more cunning instead.
|
||||
*/
|
||||
virtual SynthesiserVoice* findVoiceToSteal (SynthesiserSound* soundToPlay) const;
|
||||
virtual SynthesiserVoice* findVoiceToSteal (SynthesiserSound* soundToPlay,
|
||||
int midiChannel,
|
||||
int midiNoteNumber) const;
|
||||
|
||||
/** Starts a specified voice playing a particular sound.
|
||||
|
||||
@@ -511,11 +534,14 @@ private:
|
||||
bool shouldStealNotes;
|
||||
BigInteger sustainPedalsDown;
|
||||
|
||||
void stopVoice (SynthesiserVoice*, bool allowTailOff);
|
||||
void stopVoice (SynthesiserVoice*, float velocity, bool allowTailOff);
|
||||
|
||||
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE
|
||||
// Note the new parameters for this method.
|
||||
// Note the new parameters for these methods.
|
||||
virtual int findFreeVoice (const bool) const { return 0; }
|
||||
virtual int noteOff (int, int, int) { return 0; }
|
||||
virtual int findFreeVoice (SynthesiserSound*, const bool) { return 0; }
|
||||
virtual int findVoiceToSteal (SynthesiserSound*) const { return 0; }
|
||||
#endif
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser)
|
||||
|
||||
Reference in New Issue
Block a user