@@ -28,6 +28,9 @@ | |||
#define JUCE_SNAP_TO_ZERO(n) | |||
#endif | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
IIRFilterOld::IIRFilterOld() | |||
: active (false), v1 (0), v2 (0) | |||
@@ -237,3 +240,5 @@ void IIRFilterOld::setCoefficients (double c1, double c2, double c3, | |||
} | |||
#undef JUCE_SNAP_TO_ZERO | |||
} // namespace juce |
@@ -25,6 +25,8 @@ | |||
#ifndef __JUCE_IIRFILTER_OLD_JUCEHEADER__ | |||
#define __JUCE_IIRFILTER_OLD_JUCEHEADER__ | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -144,5 +146,6 @@ protected: | |||
JUCE_LEAK_DETECTOR (IIRFilterOld) | |||
}; | |||
} // namespace juce | |||
#endif // __JUCE_IIRFILTER_OLD_JUCEHEADER__ |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -46,14 +46,15 @@ public: | |||
/** Frame rate types. */ | |||
enum FrameRateType | |||
{ | |||
fps24 = 0, | |||
fps25 = 1, | |||
fps2997 = 2, | |||
fps30 = 3, | |||
fps2997drop = 4, | |||
fps30drop = 5, | |||
fps60 = 6, | |||
fps60drop = 7, | |||
fps23976 = 0, | |||
fps24 = 1, | |||
fps25 = 2, | |||
fps2997 = 3, | |||
fps30 = 4, | |||
fps2997drop = 5, | |||
fps30drop = 6, | |||
fps60 = 7, | |||
fps60drop = 8, | |||
fpsUnknown = 99 | |||
}; | |||
@@ -70,12 +71,12 @@ public: | |||
/** Time signature denominator, e.g. the 4 of a 3/4 time sig */ | |||
int timeSigDenominator; | |||
/** The current play position, in samples from the start of the edit. */ | |||
/** The current play position, in samples from the start of the timeline. */ | |||
int64 timeInSamples; | |||
/** The current play position, in seconds from the start of the edit. */ | |||
/** The current play position, in seconds from the start of the timeline. */ | |||
double timeInSeconds; | |||
/** For timecode, the position of the start of the edit, in seconds from 00:00:00:00. */ | |||
/** For timecode, the position of the start of the timeline, in seconds from 00:00:00:00. */ | |||
double editOriginTime; | |||
/** The current play position, in pulses-per-quarter-note. */ | |||
@@ -83,7 +84,7 @@ public: | |||
/** The position of the start of the last bar, in pulses-per-quarter-note. | |||
This is the time from the start of the edit to the start of the current | |||
This is the time from the start of the timeline to the start of the current | |||
bar, in ppq units. | |||
Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If | |||
@@ -150,3 +151,5 @@ public: | |||
/** Rewinds the audio. */ | |||
virtual void transportRewind() {} | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
AudioChannelSet::AudioChannelSet (uint32 c) : channels (c) {} | |||
AudioChannelSet::AudioChannelSet (const Array<ChannelType>& c) | |||
{ | |||
@@ -65,6 +68,8 @@ String AudioChannelSet::getChannelTypeName (AudioChannelSet::ChannelType type) | |||
case ambisonicX: return NEEDS_TRANS("Ambisonic X"); | |||
case ambisonicY: return NEEDS_TRANS("Ambisonic Y"); | |||
case ambisonicZ: return NEEDS_TRANS("Ambisonic Z"); | |||
case topSideLeft: return NEEDS_TRANS("Top Side Left"); | |||
case topSideRight: return NEEDS_TRANS("Top Side Right"); | |||
default: break; | |||
} | |||
@@ -105,6 +110,8 @@ String AudioChannelSet::getAbbreviatedChannelTypeName (AudioChannelSet::ChannelT | |||
case ambisonicX: return "X"; | |||
case ambisonicY: return "Y"; | |||
case ambisonicZ: return "Z"; | |||
case topSideLeft: return "Tsl"; | |||
case topSideRight: return "Tsr"; | |||
default: break; | |||
} | |||
@@ -144,6 +151,8 @@ AudioChannelSet::ChannelType AudioChannelSet::getChannelTypeFromAbbreviation (co | |||
if (abbr == "X") return ambisonicX; | |||
if (abbr == "Y") return ambisonicY; | |||
if (abbr == "Z") return ambisonicZ; | |||
if (abbr == "Tsl") return topSideLeft; | |||
if (abbr == "Tsr") return topSideRight; | |||
return unknown; | |||
} | |||
@@ -189,16 +198,18 @@ String AudioChannelSet::getDescription() const | |||
if (*this == createLRS()) return "LRS"; | |||
if (*this == createLCRS()) return "LCRS"; | |||
if (*this == create5point0()) return "5.0 Surround"; | |||
if (*this == create5point1()) return "5.1 Surround"; | |||
if (*this == create6point0()) return "6.0 Surround"; | |||
if (*this == create6point1()) return "6.1 Surround"; | |||
if (*this == create6point0Music()) return "6.0 (Music) Surround"; | |||
if (*this == create6point1Music()) return "6.1 (Music) Surround"; | |||
if (*this == create7point0()) return "7.0 Surround"; | |||
if (*this == create7point1()) return "7.1 Surround"; | |||
if (*this == create7point0SDDS()) return "7.0 Surround SDDS"; | |||
if (*this == create7point1SDDS()) return "7.1 Surround SDDS"; | |||
if (*this == create5point0()) return "5.0 Surround"; | |||
if (*this == create5point1()) return "5.1 Surround"; | |||
if (*this == create6point0()) return "6.0 Surround"; | |||
if (*this == create6point1()) return "6.1 Surround"; | |||
if (*this == create6point0Music()) return "6.0 (Music) Surround"; | |||
if (*this == create6point1Music()) return "6.1 (Music) Surround"; | |||
if (*this == create7point0()) return "7.0 Surround"; | |||
if (*this == create7point1()) return "7.1 Surround"; | |||
if (*this == create7point0SDDS()) return "7.0 Surround SDDS"; | |||
if (*this == create7point1SDDS()) return "7.1 Surround SDDS"; | |||
if (*this == create7point0point2()) return "7.0.2 Surround"; | |||
if (*this == create7point1point2()) return "7.1.2 Surround"; | |||
if (*this == quadraphonic()) return "Quadraphonic"; | |||
if (*this == pentagonal()) return "Pentagonal"; | |||
@@ -212,7 +223,7 @@ String AudioChannelSet::getDescription() const | |||
bool AudioChannelSet::isDiscreteLayout() const noexcept | |||
{ | |||
for (auto& speaker : getChannelTypes()) | |||
if (speaker <= ambisonicZ) | |||
if (speaker <= topSideRight) | |||
return false; | |||
return true; | |||
@@ -272,27 +283,29 @@ void AudioChannelSet::removeChannel (ChannelType newChannel) | |||
channels.clearBit (bit); | |||
} | |||
AudioChannelSet AudioChannelSet::disabled() { return {}; } | |||
AudioChannelSet AudioChannelSet::mono() { return AudioChannelSet (1u << centre); } | |||
AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ((1u << left) | (1u << right)); } | |||
AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre)); } | |||
AudioChannelSet AudioChannelSet::createLRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surround)); } | |||
AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surround)); } | |||
AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround)); } | |||
AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround)); } | |||
AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); } | |||
AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); } | |||
AudioChannelSet AudioChannelSet::create6point0Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); } | |||
AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); } | |||
AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); } | |||
AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); } | |||
AudioChannelSet AudioChannelSet::ambisonic() { return AudioChannelSet ((1u << ambisonicW) | (1u << ambisonicX) | (1u << ambisonicY) | (1u << ambisonicZ)); } | |||
AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround)); } | |||
AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << centreSurround) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround) | (1u << wideLeft) | (1u << wideRight)); } | |||
AudioChannelSet AudioChannelSet::disabled() { return {}; } | |||
AudioChannelSet AudioChannelSet::mono() { return AudioChannelSet (1u << centre); } | |||
AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ((1u << left) | (1u << right)); } | |||
AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre)); } | |||
AudioChannelSet AudioChannelSet::createLRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surround)); } | |||
AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surround)); } | |||
AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround)); } | |||
AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround)); } | |||
AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); } | |||
AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); } | |||
AudioChannelSet AudioChannelSet::create6point0Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); } | |||
AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); } | |||
AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); } | |||
AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); } | |||
AudioChannelSet AudioChannelSet::ambisonic() { return AudioChannelSet ((1u << ambisonicW) | (1u << ambisonicX) | (1u << ambisonicY) | (1u << ambisonicZ)); } | |||
AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround)); } | |||
AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << centreSurround) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround) | (1u << wideLeft) | (1u << wideRight)); } | |||
AudioChannelSet AudioChannelSet::create7point0point2() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << topSideLeft) | (1u << topSideRight)); } | |||
AudioChannelSet AudioChannelSet::create7point1point2() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << topSideLeft) | (1u << topSideRight)); } | |||
AudioChannelSet AudioChannelSet::discreteChannels (int numChannels) | |||
@@ -414,3 +427,5 @@ int32 AudioChannelSet::getWaveChannelMask() const noexcept | |||
return (channels.toInteger() >> 1); | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -194,6 +194,18 @@ public: | |||
*/ | |||
static AudioChannelSet JUCE_CALLTYPE create7point1SDDS(); | |||
/** Creates a set for Dolby Atmos 7.0.2 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight). | |||
Is equivalent to: n/a (VST), AAX_eStemFormat_7_0_2 (AAX), n/a (CoreAudio) | |||
*/ | |||
static AudioChannelSet JUCE_CALLTYPE create7point0point2(); | |||
/** Creates a set for Dolby Atmos 7.1.2 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, LFE, topSideLeft, topSideRight). | |||
Is equivalent to: k71_2 (VST), AAX_eStemFormat_7_1_2 (AAX), n/a (CoreAudio) | |||
*/ | |||
static AudioChannelSet JUCE_CALLTYPE create7point1point2(); | |||
//============================================================================== | |||
/** Creates a set for ambisonic surround setups (ambisonicW, ambisonicX, ambisonicY, ambisonicZ). | |||
@@ -289,6 +301,10 @@ public: | |||
ambisonicY = 26, | |||
ambisonicZ = 27, | |||
// Used by Dolby Atmos 7.0.2 and 7.1.2 | |||
topSideLeft = 28, // Lts (AAX), Tsl (VST) | |||
topSideRight = 29, // Rts (AAX), Tsr (VST) | |||
discreteChannel0 = 64 /**< Non-typed individual channels are indexed upwards from this value. */ | |||
}; | |||
@@ -305,7 +321,7 @@ public: | |||
//============================================================================== | |||
enum | |||
{ | |||
maxChannelsOfNamedLayout = 8 | |||
maxChannelsOfNamedLayout = 10 | |||
}; | |||
/** Adds a channel to the set. */ | |||
@@ -388,3 +404,5 @@ private: | |||
explicit AudioChannelSet (uint32); | |||
explicit AudioChannelSet (const Array<ChannelType>&); | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest, int numSamples, const int destBytesPerSample) | |||
{ | |||
const double maxVal = (double) 0x7fff; | |||
@@ -309,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 auto scale = 1.0f / (float) 0x7fffffff; | |||
const char* intData = static_cast<const char*> (source); | |||
if (source != (void*) dest || srcBytesPerSample >= 4) | |||
@@ -334,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 auto scale = 1.0f / (float) 0x7fffffff; | |||
const char* intData = static_cast<const char*> (source); | |||
if (source != (void*) dest || srcBytesPerSample >= 4) | |||
@@ -596,3 +599,5 @@ public: | |||
static AudioConversionTests audioConversionUnitTests; | |||
#endif | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -708,3 +708,5 @@ private: | |||
AudioDataConverters(); | |||
JUCE_DECLARE_NON_COPYABLE (AudioDataConverters) | |||
}; | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -184,11 +184,19 @@ public: | |||
: numChannels (other.numChannels), | |||
size (other.size), | |||
allocatedBytes (other.allocatedBytes), | |||
channels (other.channels), | |||
allocatedData (static_cast<HeapBlock<char, true>&&> (other.allocatedData)), | |||
isClear (other.isClear) | |||
{ | |||
memcpy (preallocatedChannelSpace, other.preallocatedChannelSpace, sizeof (preallocatedChannelSpace)); | |||
if (numChannels < (int) numElementsInArray (preallocatedChannelSpace)) | |||
{ | |||
channels = preallocatedChannelSpace; | |||
memcpy (preallocatedChannelSpace, other.channels, sizeof (preallocatedChannelSpace)); | |||
} | |||
else | |||
{ | |||
channels = other.channels; | |||
} | |||
other.numChannels = 0; | |||
other.size = 0; | |||
other.allocatedBytes = 0; | |||
@@ -200,10 +208,19 @@ public: | |||
numChannels = other.numChannels; | |||
size = other.size; | |||
allocatedBytes = other.allocatedBytes; | |||
channels = other.channels; | |||
allocatedData = static_cast<HeapBlock<char, true>&&> (other.allocatedData); | |||
isClear = other.isClear; | |||
memcpy (preallocatedChannelSpace, other.preallocatedChannelSpace, sizeof (preallocatedChannelSpace)); | |||
if (numChannels < (int) numElementsInArray (preallocatedChannelSpace)) | |||
{ | |||
channels = preallocatedChannelSpace; | |||
memcpy (preallocatedChannelSpace, other.channels, sizeof (preallocatedChannelSpace)); | |||
} | |||
else | |||
{ | |||
channels = other.channels; | |||
} | |||
other.numChannels = 0; | |||
other.size = 0; | |||
other.allocatedBytes = 0; | |||
@@ -332,7 +349,7 @@ public: | |||
auto numSamplesToCopy = (size_t) jmin (newNumSamples, size); | |||
auto newChannels = reinterpret_cast<Type**> (newData.getData()); | |||
auto newChannels = reinterpret_cast<Type**> (newData.get()); | |||
auto newChan = reinterpret_cast<Type*> (newData + channelListSize); | |||
for (int j = 0; j < newNumChannels; ++j) | |||
@@ -364,7 +381,7 @@ public: | |||
{ | |||
allocatedBytes = newTotalBytes; | |||
allocatedData.allocate (newTotalBytes, clearExtraSpace || isClear); | |||
channels = reinterpret_cast<Type**> (allocatedData.getData()); | |||
channels = reinterpret_cast<Type**> (allocatedData.get()); | |||
} | |||
auto* chan = reinterpret_cast<Type*> (allocatedData + channelListSize); | |||
@@ -629,7 +646,7 @@ public: | |||
jassert (isPositiveAndBelow (channel, numChannels)); | |||
jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size); | |||
const auto increment = (endGain - startGain) / numSamples; | |||
const auto increment = (endGain - startGain) / (float) numSamples; | |||
auto* d = channels[channel] + startSample; | |||
while (--numSamples >= 0) | |||
@@ -1051,7 +1068,7 @@ private: | |||
auto channelListSize = sizeof (Type*) * (size_t) (numChannels + 1); | |||
allocatedBytes = (size_t) numChannels * (size_t) size * sizeof (Type) + channelListSize + 32; | |||
allocatedData.malloc (allocatedBytes); | |||
channels = reinterpret_cast<Type**> (allocatedData.getData()); | |||
channels = reinterpret_cast<Type**> (allocatedData.get()); | |||
auto* chan = (Type*) (allocatedData + channelListSize); | |||
for (int i = 0; i < numChannels; ++i) | |||
@@ -1076,7 +1093,7 @@ private: | |||
else | |||
{ | |||
allocatedData.malloc ((size_t) numChannels + 1, sizeof (Type*)); | |||
channels = reinterpret_cast<Type**> (allocatedData.getData()); | |||
channels = reinterpret_cast<Type**> (allocatedData.get()); | |||
} | |||
for (int i = 0; i < numChannels; ++i) | |||
@@ -1105,3 +1122,5 @@ private: | |||
@see AudioBuffer | |||
*/ | |||
typedef AudioBuffer<float> AudioSampleBuffer; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
namespace FloatVectorHelpers | |||
{ | |||
#define JUCE_INCREMENT_SRC_DEST dest += (16 / sizeof (*dest)); src += (16 / sizeof (*dest)); | |||
@@ -874,7 +877,7 @@ void JUCE_CALLTYPE FloatVectorOperations::convertFixedToFloat (float* dest, cons | |||
vmulq_n_f32 (vcvtq_f32_s32 (vld1q_s32 (src)), multiplier), | |||
JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, ) | |||
#else | |||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, | |||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = (float) src[i] * multiplier, | |||
Mode::mul (mult, _mm_cvtepi32_ps (_mm_loadu_si128 ((const __m128i*) src))), | |||
JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, | |||
const Mode::ParallelType mult = Mode::load1 (multiplier);) | |||
@@ -1068,9 +1071,9 @@ public: | |||
#else | |||
// These tests deliberately operate on misaligned memory and will be flagged up by | |||
// checks for undefined behavior! | |||
ValueType* const data1 = addBytesToPointer (buffer1.getData(), random.nextInt (16)); | |||
ValueType* const data2 = addBytesToPointer (buffer2.getData(), random.nextInt (16)); | |||
int* const int1 = addBytesToPointer (buffer3.getData(), random.nextInt (16)); | |||
ValueType* const data1 = addBytesToPointer (buffer1.get(), random.nextInt (16)); | |||
ValueType* const data2 = addBytesToPointer (buffer2.get(), random.nextInt (16)); | |||
int* const int1 = addBytesToPointer (buffer3.get(), random.nextInt (16)); | |||
#endif | |||
fillRandomly (random, data1, num); | |||
@@ -1158,7 +1161,7 @@ public: | |||
static void convertFixed (float* d, const int* s, ValueType multiplier, int num) | |||
{ | |||
while (--num >= 0) | |||
*d++ = *s++ * multiplier; | |||
*d++ = (float) *s++ * multiplier; | |||
} | |||
static bool areAllValuesEqual (const ValueType* d, int num, ValueType target) | |||
@@ -1200,3 +1203,5 @@ public: | |||
static FloatVectorOperationsTests vectorOpTests; | |||
#endif | |||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
#if JUCE_INTEL | |||
#define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8f || n > 1.0e-8f)) n = 0; | |||
@@ -219,3 +220,35 @@ public: | |||
*/ | |||
static void JUCE_CALLTYPE disableDenormalisedNumberSupport() noexcept; | |||
}; | |||
//============================================================================== | |||
/** | |||
Helper class providing an RAII-based mechanism for temporarily disabling | |||
denormals on your CPU. | |||
*/ | |||
class ScopedNoDenormals | |||
{ | |||
public: | |||
inline ScopedNoDenormals() noexcept | |||
{ | |||
#if JUCE_USE_SSE_INTRINSICS | |||
mxcsr = _mm_getcsr(); | |||
_mm_setcsr (mxcsr | 0x8040); // add the DAZ and FZ bits | |||
#endif | |||
} | |||
inline ~ScopedNoDenormals() noexcept | |||
{ | |||
#if JUCE_USE_SSE_INTRINSICS | |||
_mm_setcsr (mxcsr); | |||
#endif | |||
} | |||
private: | |||
#if JUCE_USE_SSE_INTRINSICS | |||
unsigned int mxcsr; | |||
#endif | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
struct CatmullRomAlgorithm | |||
{ | |||
static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept | |||
@@ -58,3 +61,5 @@ int CatmullRomInterpolator::processAdding (double actualRatio, const float* in, | |||
{ | |||
return interpolateAdding<CatmullRomAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain); | |||
} | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
/** | |||
Interpolator for resampling a stream of floats using Catmull-Rom interpolation. | |||
@@ -84,3 +87,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CatmullRomInterpolator) | |||
}; | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -96,3 +96,5 @@ private: | |||
Decibels(); // This class can't be instantiated, it's just a holder for static methods.. | |||
JUCE_DECLARE_NON_COPYABLE (Decibels) | |||
}; | |||
} // namespace juce |
@@ -20,7 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
//============================================================================== | |||
namespace juce | |||
{ | |||
IIRCoefficients::IIRCoefficients() noexcept | |||
{ | |||
zeromem (coefficients, sizeof (coefficients)); | |||
@@ -335,3 +337,5 @@ void IIRFilter::processSamples (float* const samples, const int numSamples) noex | |||
} | |||
#undef JUCE_SNAP_TO_ZERO | |||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
class IIRFilter; | |||
@@ -205,3 +206,5 @@ protected: | |||
IIRFilter& operator= (const IIRFilter&); | |||
JUCE_LEAK_DETECTOR (IIRFilter) | |||
}; | |||
} // namespace juce |
@@ -28,6 +28,9 @@ | |||
#define JUCE_SNAP_TO_ZERO(n) | |||
#endif | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
IIRFilterOld::IIRFilterOld() | |||
: active (false), v1 (0), v2 (0) | |||
@@ -237,3 +240,5 @@ void IIRFilterOld::setCoefficients (double c1, double c2, double c3, | |||
} | |||
#undef JUCE_SNAP_TO_ZERO | |||
} // namespace juce |
@@ -26,6 +26,9 @@ | |||
#define __JUCE_IIRFILTER_OLD_JUCEHEADER__ | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
An IIR filter that can perform low, high, or band-pass filtering on an | |||
@@ -145,4 +148,6 @@ protected: | |||
}; | |||
} // namespace juce | |||
#endif // __JUCE_IIRFILTER_OLD_JUCEHEADER__ |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
namespace | |||
{ | |||
static forcedinline void pushInterpolationSample (float* lastInputSamples, const float newValue) noexcept | |||
@@ -196,3 +199,5 @@ int LagrangeInterpolator::processAdding (double actualRatio, const float* in, fl | |||
{ | |||
return interpolateAdding<LagrangeAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain); | |||
} | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
/** | |||
Interpolator for resampling a stream of floats using 4-point lagrange interpolation. | |||
@@ -84,3 +87,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LagrangeInterpolator) | |||
}; | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -182,3 +182,5 @@ private: | |||
FloatType currentValue = 0, target = 0, step = 0; | |||
int countdown = 0, stepsToTarget = 0; | |||
}; | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -316,3 +316,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Reverb) | |||
}; | |||
} // namespace juce |
@@ -76,9 +76,6 @@ | |||
#include <arm_neon.h> | |||
#endif | |||
namespace juce | |||
{ | |||
#include "buffers/juce_AudioDataConverters.cpp" | |||
#include "buffers/juce_FloatVectorOperations.cpp" | |||
#include "buffers/juce_AudioChannelSet.cpp" | |||
@@ -110,5 +107,3 @@ namespace juce | |||
#include "sources/juce_ReverbAudioSource.cpp" | |||
#include "sources/juce_ToneGeneratorAudioSource.cpp" | |||
#include "synthesisers/juce_Synthesiser.cpp" | |||
} |
@@ -31,7 +31,7 @@ | |||
ID: juce_audio_basics | |||
vendor: juce | |||
version: 5.1.1 | |||
version: 5.1.2 | |||
name: JUCE audio and MIDI data classes | |||
description: Classes for audio buffer manipulation, midi message handling, synthesis, etc. | |||
website: http://www.juce.com/juce | |||
@@ -51,9 +51,7 @@ | |||
#include <juce_core/juce_core.h> | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
#undef Complex // apparently some C libraries actually define these symbols (!) | |||
#undef Factor | |||
@@ -95,5 +93,3 @@ namespace juce | |||
#include "sources/juce_ToneGeneratorAudioSource.h" | |||
#include "synthesisers/juce_Synthesiser.h" | |||
#include "audio_play_head/juce_AudioPlayHead.h" | |||
} |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
namespace MidiBufferHelpers | |||
{ | |||
inline int getEventTime (const void* const d) noexcept | |||
@@ -34,7 +37,7 @@ namespace MidiBufferHelpers | |||
inline uint16 getEventTotalSize (const void* const d) noexcept | |||
{ | |||
return getEventDataSize (d) + sizeof (int32) + sizeof (uint16); | |||
return (uint16) (getEventDataSize (d) + sizeof (int32) + sizeof (uint16)); | |||
} | |||
static int findActualEventLength (const uint8* const data, const int maxBytes) noexcept | |||
@@ -225,3 +228,5 @@ bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result, int& samplePositio | |||
return true; | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -160,8 +160,8 @@ public: | |||
/** | |||
Used to iterate through the events in a MidiBuffer. | |||
Note that altering the buffer while an iterator is using it isn't a | |||
safe operation. | |||
Note that altering the buffer while an iterator is using it will produce | |||
undefined behaviour. | |||
@see MidiBuffer | |||
*/ | |||
@@ -172,6 +172,9 @@ public: | |||
/** Creates an Iterator for this MidiBuffer. */ | |||
Iterator (const MidiBuffer&) noexcept; | |||
/** Creates a copy of an iterator. */ | |||
Iterator (const Iterator&) noexcept = default; | |||
/** Destructor. */ | |||
~Iterator() noexcept; | |||
@@ -214,8 +217,6 @@ public: | |||
//============================================================================== | |||
const MidiBuffer& buffer; | |||
const uint8* data; | |||
JUCE_DECLARE_NON_COPYABLE (Iterator) | |||
}; | |||
/** The raw data holding this buffer. | |||
@@ -227,3 +228,5 @@ public: | |||
private: | |||
JUCE_LEAK_DETECTOR (MidiBuffer) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
namespace MidiFileHelpers | |||
{ | |||
static void writeVariableLengthInt (OutputStream& out, unsigned int v) | |||
@@ -443,3 +446,5 @@ bool MidiFile::writeTrack (OutputStream& mainOut, const int trackNum) | |||
return true; | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -178,3 +178,5 @@ private: | |||
JUCE_LEAK_DETECTOR (MidiFile) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
MidiKeyboardState::MidiKeyboardState() | |||
{ | |||
zerostruct (noteStates); | |||
@@ -179,3 +182,5 @@ void MidiKeyboardState::removeListener (MidiKeyboardStateListener* const listene | |||
const ScopedLock sl (lock); | |||
listeners.removeFirstMatchingValue (listener); | |||
} | |||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
class MidiKeyboardState; | |||
@@ -197,3 +198,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
namespace MidiHelpers | |||
{ | |||
inline uint8 initialByte (const int type, const int channel) noexcept | |||
@@ -1119,3 +1122,5 @@ const char* MidiMessage::getControllerName (const int n) | |||
return isPositiveAndBelow (n, numElementsInArray (names)) ? names[n] : nullptr; | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -936,3 +936,5 @@ private: | |||
inline uint8* getData() const noexcept { return isHeapAllocated() ? packedData.allocatedData : (uint8*) packedData.asBytes; } | |||
uint8* allocateSpace (int); | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
MidiMessageSequence::MidiEventHolder::MidiEventHolder (const MidiMessage& mm) : message (mm) {} | |||
MidiMessageSequence::MidiEventHolder::MidiEventHolder (MidiMessage&& mm) : message (static_cast<MidiMessage&&> (mm)) {} | |||
@@ -334,3 +336,5 @@ void MidiMessageSequence::createControllerUpdatesForTime (int channelNumber, dou | |||
} | |||
} | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -294,3 +294,5 @@ private: | |||
JUCE_LEAK_DETECTOR (MidiMessageSequence) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
MidiRPNDetector::MidiRPNDetector() noexcept | |||
{ | |||
} | |||
@@ -369,3 +372,5 @@ private: | |||
static MidiRPNGeneratorTests MidiRPNGeneratorUnitTests; | |||
#endif // JUCE_UNIT_TESTS | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** Represents a MIDI RPN (registered parameter number) or NRPN (non-registered | |||
@@ -144,3 +144,5 @@ public: | |||
bool isNRPN = false, | |||
bool use14BitValue = true); | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
namespace | |||
{ | |||
const uint8 noLSBValueReceived = 0xff; | |||
@@ -2148,3 +2151,5 @@ private: | |||
static MPEInstrumentTests MPEInstrumentUnitTests; | |||
#endif // JUCE_UNIT_TESTS | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/* | |||
@@ -374,3 +374,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPEInstrument) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
MidiBuffer MPEMessages::addZone (MPEZone zone) | |||
{ | |||
MidiBuffer buffer (MidiRPNGenerator::generate (zone.getFirstNoteChannel(), | |||
@@ -193,3 +196,5 @@ private: | |||
static MPEMessagesTests MPEMessagesUnitTests; | |||
#endif // JUCE_UNIT_TESTS | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -87,3 +87,5 @@ public: | |||
*/ | |||
static const int zoneLayoutMessagesRpnNumber = 6; | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
namespace | |||
{ | |||
uint16 generateNoteID (int midiChannel, int midiNoteNumber) noexcept | |||
@@ -128,3 +131,5 @@ private: | |||
static MPENoteTests MPENoteUnitTests; | |||
#endif // JUCE_UNIT_TESTS | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -172,3 +172,5 @@ struct JUCE_API MPENote | |||
/** Returns true if two notes are different notes, determined by their unique ID. */ | |||
bool operator!= (const MPENote& other) const noexcept; | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
MPESynthesiser::MPESynthesiser() | |||
{ | |||
} | |||
@@ -352,3 +355,5 @@ void MPESynthesiser::renderNextSubBlock (AudioBuffer<double>& buffer, int startS | |||
voice->renderNextBlock (buffer, startSample, numSamples); | |||
} | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -305,3 +305,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiser) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
MPESynthesiserBase::MPESynthesiserBase() | |||
: instrument (new MPEInstrument), | |||
sampleRate (0), | |||
@@ -178,3 +181,5 @@ void MPESynthesiserBase::setMinimumRenderingSubdivisionSize (int numSamples, boo | |||
minimumSubBlockSize = numSamples; | |||
subBlockSubdivisionIsStrict = shouldBeStrict; | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -204,3 +204,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiserBase) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
MPESynthesiserVoice::MPESynthesiserVoice() | |||
: currentSampleRate (0), noteStartTime (0) | |||
{ | |||
@@ -49,3 +52,5 @@ void MPESynthesiserVoice::clearCurrentNote() noexcept | |||
{ | |||
currentlyPlayingNote = MPENote(); | |||
} | |||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -183,3 +184,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiserVoice) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
MPEValue::MPEValue() noexcept : normalisedValue (8192) | |||
{ | |||
} | |||
@@ -166,3 +169,5 @@ private: | |||
static MPEValueTests MPEValueUnitTests; | |||
#endif // JUCE_UNIT_TESTS | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -88,3 +88,5 @@ private: | |||
MPEValue (int normalisedValue); | |||
int normalisedValue; | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
namespace | |||
{ | |||
void checkAndLimitZoneParameters (int minValue, | |||
@@ -312,3 +315,5 @@ private: | |||
static MPEZoneTests MPEZoneUnitTests; | |||
#endif // JUCE_UNIT_TESTS | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -138,3 +138,5 @@ private: | |||
int perNotePitchbendRange; | |||
int masterPitchbendRange; | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
MPEZoneLayout::MPEZoneLayout() noexcept | |||
{ | |||
} | |||
@@ -378,3 +381,5 @@ static MPEZoneLayoutTests MPEZoneLayoutUnitTests; | |||
#endif // JUCE_UNIT_TESTS | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -157,3 +157,5 @@ private: | |||
void processZoneLayoutRpnMessage (MidiRPNMessage); | |||
void processPitchbendRangeRpnMessage (MidiRPNMessage); | |||
}; | |||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
#if JUCE_MAC || JUCE_IOS | |||
@@ -304,3 +305,5 @@ private: | |||
}; | |||
#endif | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -173,3 +173,5 @@ public: | |||
*/ | |||
virtual void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) = 0; | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* s, | |||
TimeSliceThread& thread, | |||
const bool deleteSourceWhenDeleted, | |||
@@ -307,3 +310,5 @@ int BufferingAudioSource::useTimeSlice() | |||
{ | |||
return readNextBufferChunk() ? 1 : 100; | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -113,3 +113,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferingAudioSource) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
ChannelRemappingAudioSource::ChannelRemappingAudioSource (AudioSource* const source_, | |||
const bool deleteSourceWhenDeleted) | |||
: source (source_, deleteSourceWhenDeleted), | |||
@@ -180,3 +183,5 @@ void ChannelRemappingAudioSource::restoreFromXml (const XmlElement& e) | |||
remappedOutputs.add (outs[i].getIntValue()); | |||
} | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -135,3 +135,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChannelRemappingAudioSource) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
IIRFilterAudioSource::IIRFilterAudioSource (AudioSource* const inputSource, | |||
const bool deleteInputWhenDeleted) | |||
: input (inputSource, deleteInputWhenDeleted) | |||
@@ -73,3 +76,5 @@ void IIRFilterAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& buff | |||
->processSamples (bufferToFill.buffer->getWritePointer (i, bufferToFill.startSample), | |||
bufferToFill.numSamples); | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -62,3 +62,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (IIRFilterAudioSource) | |||
}; | |||
} // namespace juce |
@@ -20,7 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
//============================================================================== | |||
namespace juce | |||
{ | |||
MemoryAudioSource::MemoryAudioSource (AudioBuffer<float>& bufferToUse, bool copyMemory, bool shouldLoop) | |||
: isLooping (shouldLoop) | |||
{ | |||
@@ -64,3 +66,5 @@ void MemoryAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferT | |||
if (pos < m) | |||
dst.clear (bufferToFill.startSample + pos, m - pos); | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -59,3 +59,5 @@ private: | |||
//============================================================================== | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryAudioSource) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
MixerAudioSource::MixerAudioSource() | |||
: currentSampleRate (0.0), bufferSizeExpected (0) | |||
{ | |||
@@ -151,3 +154,5 @@ void MixerAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info) | |||
info.clearActiveBufferRegion(); | |||
} | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -93,3 +93,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MixerAudioSource) | |||
}; | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -70,3 +70,5 @@ public: | |||
/** Tells the source whether you'd like it to play in a loop. */ | |||
virtual void setLooping (bool shouldLoop) { ignoreUnused (shouldLoop); } | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
ResamplingAudioSource::ResamplingAudioSource (AudioSource* const inputSource, | |||
const bool deleteInputWhenDeleted, | |||
const int channels) | |||
@@ -259,3 +262,5 @@ void ResamplingAudioSource::applyFilter (float* samples, int num, FilterState& f | |||
*samples++ = (float) out; | |||
} | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -99,3 +99,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResamplingAudioSource) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
ReverbAudioSource::ReverbAudioSource (AudioSource* const inputSource, const bool deleteInputWhenDeleted) | |||
: input (inputSource, deleteInputWhenDeleted), | |||
bypass (false) | |||
@@ -76,3 +79,5 @@ void ReverbAudioSource::setBypassed (bool b) noexcept | |||
reverb.reset(); | |||
} | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -68,3 +68,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ReverbAudioSource) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
ToneGeneratorAudioSource::ToneGeneratorAudioSource() | |||
: frequency (1000.0), | |||
sampleRate (44100.0), | |||
@@ -71,3 +74,5 @@ void ToneGeneratorAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& | |||
info.buffer->setSample (j, info.startSample + i, sample); | |||
} | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -65,3 +65,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToneGeneratorAudioSource) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
SynthesiserSound::SynthesiserSound() {} | |||
SynthesiserSound::~SynthesiserSound() {} | |||
@@ -305,8 +308,8 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice, | |||
voice->noteOnTime = ++lastNoteOnCounter; | |||
voice->currentlyPlayingSound = sound; | |||
voice->setKeyDown (true); | |||
voice->sostenutoPedalDown = false; | |||
voice->sustainPedalDown = sustainPedalsDown[midiChannel]; | |||
voice->setSostenutoPedalDown (false); | |||
voice->setSustainPedalDown (sustainPedalsDown[midiChannel]); | |||
voice->startNote (midiNoteNumber, velocity, sound, | |||
lastPitchWheelValues [midiChannel - 1]); | |||
@@ -340,11 +343,11 @@ void Synthesiser::noteOff (const int midiChannel, | |||
if (sound->appliesToNote (midiNoteNumber) | |||
&& sound->appliesToChannel (midiChannel)) | |||
{ | |||
jassert (! voice->keyIsDown || voice->sustainPedalDown == sustainPedalsDown [midiChannel]); | |||
jassert (! voice->keyIsDown || voice->isSustainPedalDown() == sustainPedalsDown [midiChannel]); | |||
voice->setKeyDown (false); | |||
if (! (voice->sustainPedalDown || voice->sostenutoPedalDown)) | |||
if (! (voice->isSustainPedalDown() || voice->isSostenutoPedalDown())) | |||
stopVoice (voice, velocity, allowTailOff); | |||
} | |||
} | |||
@@ -421,7 +424,7 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown) | |||
for (auto* voice : voices) | |||
if (voice->isPlayingChannel (midiChannel) && voice->isKeyDown()) | |||
voice->sustainPedalDown = true; | |||
voice->setSustainPedalDown (true); | |||
} | |||
else | |||
{ | |||
@@ -429,7 +432,7 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown) | |||
{ | |||
if (voice->isPlayingChannel (midiChannel)) | |||
{ | |||
voice->sustainPedalDown = false; | |||
voice->setSustainPedalDown (false); | |||
if (! (voice->isKeyDown() || voice->isSostenutoPedalDown())) | |||
stopVoice (voice, 1.0f, true); | |||
@@ -450,8 +453,8 @@ void Synthesiser::handleSostenutoPedal (int midiChannel, bool isDown) | |||
if (voice->isPlayingChannel (midiChannel)) | |||
{ | |||
if (isDown) | |||
voice->sostenutoPedalDown = true; | |||
else if (voice->sostenutoPedalDown) | |||
voice->setSostenutoPedalDown (true); | |||
else if (voice->isSostenutoPedalDown()) | |||
stopVoice (voice, 1.0f, true); | |||
} | |||
} | |||
@@ -567,3 +570,5 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay, | |||
return low; | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -224,9 +224,15 @@ public: | |||
/** Returns true if the sustain pedal is currently active for this voice. */ | |||
bool isSustainPedalDown() const noexcept { return sustainPedalDown; } | |||
/** Modifies the sustain pedal flag. */ | |||
void setSustainPedalDown (bool isNowDown) noexcept { sustainPedalDown = isNowDown; } | |||
/** Returns true if the sostenuto pedal is currently active for this voice. */ | |||
bool isSostenutoPedalDown() const noexcept { return sostenutoPedalDown; } | |||
/** Modifies the sostenuto pedal flag. */ | |||
void setSostenutoPedalDown (bool isNowDown) noexcept { sostenutoPedalDown = isNowDown; } | |||
/** Returns true if a voice is sounding in its release phase **/ | |||
bool isPlayingButReleased() const noexcept | |||
{ | |||
@@ -514,15 +520,15 @@ public: | |||
with timestamps outside the specified region will be ignored. | |||
*/ | |||
inline void renderNextBlock (AudioBuffer<float>& outputAudio, | |||
const MidiBuffer& inputMidi, | |||
int startSample, | |||
int numSamples) | |||
const MidiBuffer& inputMidi, | |||
int startSample, | |||
int numSamples) | |||
{ processNextBlock (outputAudio, inputMidi, startSample, numSamples); } | |||
inline void renderNextBlock (AudioBuffer<double>& outputAudio, | |||
const MidiBuffer& inputMidi, | |||
int startSample, | |||
int numSamples) | |||
const MidiBuffer& inputMidi, | |||
int startSample, | |||
int numSamples) | |||
{ processNextBlock (outputAudio, inputMidi, startSample, numSamples); } | |||
/** Returns the current target sample rate at which rendering is being done. | |||
@@ -639,3 +645,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
AudioDeviceManager::AudioDeviceSetup::AudioDeviceSetup() | |||
: sampleRate (0), | |||
bufferSize (0), | |||
@@ -929,7 +932,7 @@ void AudioDeviceManager::LevelMeter::updateLevel (const float* const* channelDat | |||
for (int i = 0; i < numChannels; ++i) | |||
s += std::abs (channelData[i][j]); | |||
s /= numChannels; | |||
s /= (float) numChannels; | |||
const double decayFactor = 0.99992; | |||
@@ -1000,3 +1003,5 @@ double AudioDeviceManager::getCurrentOutputLevel() const noexcept { return out | |||
void AudioDeviceManager::enableInputLevelMeasurement (bool enable) noexcept { inputLevelMeter.setEnabled (enable); } | |||
void AudioDeviceManager::enableOutputLevelMeasurement (bool enable) noexcept { outputLevelMeter.setEnabled (enable); } | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -518,3 +518,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioDeviceManager) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
AudioIODevice::AudioIODevice (const String& deviceName, const String& deviceTypeName) | |||
: name (deviceName), typeName (deviceTypeName) | |||
{ | |||
@@ -30,6 +33,7 @@ AudioIODevice::~AudioIODevice() {} | |||
void AudioIODeviceCallback::audioDeviceError (const String&) {} | |||
bool AudioIODevice::setAudioPreprocessingEnabled (bool) { return false; } | |||
bool AudioIODevice::hasControlPanel() const { return false; } | |||
int AudioIODevice::getXRunCount() const noexcept { return -1; } | |||
bool AudioIODevice::showControlPanel() | |||
{ | |||
@@ -37,3 +41,5 @@ bool AudioIODevice::showControlPanel() | |||
// their hasControlPanel() method. | |||
return false; | |||
} | |||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
class AudioIODevice; | |||
@@ -292,6 +293,19 @@ public: | |||
*/ | |||
virtual bool setAudioPreprocessingEnabled (bool shouldBeEnabled); | |||
//============================================================================== | |||
/** Returns the number of under- or over runs reported by the OS since | |||
playback/recording has started. | |||
This number may be different than determining the Xrun count manually (by | |||
measuring the time spent in the audio callback) as the OS may be doing | |||
some buffering internally - especially on mobile devices. | |||
Returns -1 if playback/recording has not started yet or if getting the underrun | |||
count is not supported for this device (Android SDK 23 and lower). | |||
*/ | |||
virtual int getXRunCount() const noexcept; | |||
//============================================================================== | |||
protected: | |||
/** Creates a device, setting its name and type member variables. */ | |||
@@ -301,3 +315,5 @@ protected: | |||
/** @internal */ | |||
String name, typeName; | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
AudioIODeviceType::AudioIODeviceType (const String& name) | |||
: typeName (name) | |||
{ | |||
@@ -74,3 +77,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android() | |||
#if ! (JUCE_ANDROID && JUCE_USE_ANDROID_OPENSLES) | |||
AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() { return nullptr; } | |||
#endif | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -174,3 +174,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE (AudioIODeviceType) | |||
}; | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -53,3 +53,5 @@ private: | |||
SystemAudioVolume(); // Don't instantiate this class, just call its static fns. | |||
JUCE_DECLARE_NON_COPYABLE (SystemAudioVolume) | |||
}; | |||
} // namespace juce |
@@ -155,9 +155,6 @@ | |||
#endif | |||
namespace juce | |||
{ | |||
#include "audio_io/juce_AudioDeviceManager.cpp" | |||
#include "audio_io/juce_AudioIODevice.cpp" | |||
#include "audio_io/juce_AudioIODeviceType.cpp" | |||
@@ -214,14 +211,15 @@ namespace juce | |||
#if JUCE_USE_ANDROID_OPENSLES | |||
#include "native/juce_android_OpenSL.cpp" | |||
#endif | |||
#endif | |||
#if ! JUCE_SYSTEMAUDIOVOL_IMPLEMENTED | |||
// None of these methods are available. (On Windows you might need to enable WASAPI for this) | |||
float JUCE_CALLTYPE SystemAudioVolume::getGain() { jassertfalse; return 0.0f; } | |||
bool JUCE_CALLTYPE SystemAudioVolume::setGain (float) { jassertfalse; return false; } | |||
bool JUCE_CALLTYPE SystemAudioVolume::isMuted() { jassertfalse; return false; } | |||
bool JUCE_CALLTYPE SystemAudioVolume::setMuted (bool) { jassertfalse; return false; } | |||
#endif | |||
namespace juce | |||
{ | |||
// None of these methods are available. (On Windows you might need to enable WASAPI for this) | |||
float JUCE_CALLTYPE SystemAudioVolume::getGain() { jassertfalse; return 0.0f; } | |||
bool JUCE_CALLTYPE SystemAudioVolume::setGain (float) { jassertfalse; return false; } | |||
bool JUCE_CALLTYPE SystemAudioVolume::isMuted() { jassertfalse; return false; } | |||
bool JUCE_CALLTYPE SystemAudioVolume::setMuted (bool) { jassertfalse; return false; } | |||
} | |||
#endif |
@@ -31,7 +31,7 @@ | |||
ID: juce_audio_devices | |||
vendor: juce | |||
version: 5.1.1 | |||
version: 5.1.2 | |||
name: JUCE audio and MIDI I/O device classes | |||
description: Classes to play and record from audio and MIDI I/O devices | |||
website: http://www.juce.com/juce | |||
@@ -140,9 +140,6 @@ | |||
//============================================================================== | |||
namespace juce | |||
{ | |||
#include "midi_io/juce_MidiInput.h" | |||
#include "midi_io/juce_MidiMessageCollector.h" | |||
#include "midi_io/juce_MidiOutput.h" | |||
@@ -156,5 +153,3 @@ namespace juce | |||
#if JUCE_IOS | |||
#include "native/juce_ios_Audio.h" | |||
#endif | |||
} |
@@ -20,7 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
class MidiInput; | |||
@@ -171,3 +172,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInput) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
MidiMessageCollector::MidiMessageCollector() | |||
{ | |||
} | |||
@@ -151,3 +154,5 @@ void MidiMessageCollector::handleIncomingMidiMessage (MidiInput*, const MidiMess | |||
{ | |||
addMessageToQueue (message); | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -99,3 +99,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiMessageCollector) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
struct MidiOutput::PendingMessage | |||
{ | |||
PendingMessage (const void* const data, const int len, const double timeStamp) | |||
@@ -169,3 +172,5 @@ void MidiOutput::run() | |||
clearAllPendingMessages(); | |||
} | |||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -139,3 +139,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiOutput) | |||
}; | |||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
@@ -31,9 +32,8 @@ class MidiDataConcatenator | |||
{ | |||
public: | |||
//============================================================================== | |||
MidiDataConcatenator (const int initialBufferSize) | |||
: pendingData ((size_t) initialBufferSize), | |||
pendingDataTime (0), pendingBytes (0), runningStatus (0) | |||
MidiDataConcatenator (int initialBufferSize) | |||
: pendingData ((size_t) initialBufferSize) | |||
{ | |||
} | |||
@@ -181,9 +181,11 @@ private: | |||
} | |||
MemoryBlock pendingData; | |||
double pendingDataTime; | |||
int pendingBytes; | |||
uint8 runningStatus; | |||
double pendingDataTime = 0; | |||
int pendingBytes = 0; | |||
uint8 runningStatus = 0; | |||
JUCE_DECLARE_NON_COPYABLE (MidiDataConcatenator) | |||
}; | |||
} // namespace juce |
@@ -20,7 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
//============================================================================== | |||
namespace juce | |||
{ | |||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ | |||
STATICMETHOD (getMinBufferSize, "getMinBufferSize", "(III)I") \ | |||
STATICMETHOD (getNativeOutputSampleRate, "getNativeOutputSampleRate", "(I)I") \ | |||
@@ -48,6 +50,13 @@ DECLARE_JNI_CLASS (AudioTrack, "android/media/AudioTrack"); | |||
DECLARE_JNI_CLASS (AudioRecord, "android/media/AudioRecord"); | |||
#undef JNI_CLASS_MEMBERS | |||
//============================================================================== | |||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ | |||
STATICFIELD (SDK_INT, "SDK_INT", "I") \ | |||
DECLARE_JNI_CLASS (AndroidBuildVersion, "android/os/Build$VERSION"); | |||
#undef JNI_CLASS_MEMBERS | |||
//============================================================================== | |||
enum | |||
{ | |||
@@ -193,6 +202,9 @@ public: | |||
STREAM_MUSIC, sampleRate, CHANNEL_OUT_STEREO, ENCODING_PCM_16BIT, | |||
(jint) (minBufferSizeOut * numDeviceOutputChannels * static_cast<int> (sizeof (int16))), MODE_STREAM)); | |||
const bool supportsUnderrunCount = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 24); | |||
getUnderrunCount = supportsUnderrunCount ? env->GetMethodID (AudioTrack, "getUnderrunCount", "()I") : 0; | |||
int outputDeviceState = env->CallIntMethod (outputDevice, AudioTrack.getState); | |||
if (outputDeviceState > 0) | |||
{ | |||
@@ -279,6 +291,14 @@ public: | |||
String getLastError() override { return lastError; } | |||
bool isPlaying() override { return isRunning && callback != 0; } | |||
int getXRunCount() const noexcept override | |||
{ | |||
if (outputDevice != nullptr && getUnderrunCount != 0) | |||
return getEnv()->CallIntMethod (outputDevice, getUnderrunCount); | |||
return -1; | |||
} | |||
void start (AudioIODeviceCallback* newCallback) override | |||
{ | |||
if (isRunning && callback != newCallback) | |||
@@ -404,6 +424,7 @@ private: | |||
BigInteger activeOutputChans, activeInputChans; | |||
GlobalRef outputDevice, inputDevice; | |||
AudioSampleBuffer inputChannelBuffer, outputChannelBuffer; | |||
jmethodID getUnderrunCount = 0; | |||
void closeDevices() | |||
{ | |||
@@ -472,3 +493,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android() | |||
return new AndroidAudioIODeviceType(); | |||
} | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ | |||
METHOD (getJuceAndroidMidiInputDevices, "getJuceAndroidMidiInputDevices", "()[Ljava/lang/String;") \ | |||
METHOD (getJuceAndroidMidiOutputDevices, "getJuceAndroidMidiOutputDevices", "()[Ljava/lang/String;") \ | |||
@@ -89,9 +92,9 @@ public: | |||
jbyte* data = getEnv()->GetByteArrayElements (byteArray, nullptr); | |||
HeapBlock<uint8> buffer (static_cast<size_t> (len)); | |||
std::memcpy (buffer.getData(), data + offset, static_cast<size_t> (len)); | |||
std::memcpy (buffer.get(), data + offset, static_cast<size_t> (len)); | |||
midiConcatenator.pushMidiData (buffer.getData(), | |||
midiConcatenator.pushMidiData (buffer.get(), | |||
len, static_cast<double> (timestamp) * 1.0e-9, | |||
juceMidiInput, *callback); | |||
@@ -357,3 +360,5 @@ MidiInput::~MidiInput() | |||
{ | |||
delete reinterpret_cast<AndroidMidiInput*> (internal); | |||
} | |||
} // namespace juce |
@@ -20,12 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
//============================================================================== | |||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ | |||
STATICFIELD (SDK_INT, "SDK_INT", "I") \ | |||
DECLARE_JNI_CLASS (AndroidBuildVersion, "android/os/Build$VERSION"); | |||
#undef JNI_CLASS_MEMBERS | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
#ifndef SL_ANDROID_DATAFORMAT_PCM_EX | |||
@@ -289,12 +285,39 @@ public: | |||
nextBlock (0), numBlocksOut (0) | |||
{} | |||
~OpenSLQueueRunner() | |||
{ | |||
if (config != nullptr && javaProxy != nullptr) | |||
{ | |||
javaProxy.clear(); | |||
(*config)->ReleaseJavaProxy (config, SL_ANDROID_JAVA_PROXY_ROUTING); | |||
} | |||
} | |||
bool init() | |||
{ | |||
runner = crtp().createPlayerOrRecorder(); | |||
if (runner == nullptr) | |||
return false; | |||
const bool supportsJavaProxy = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 24); | |||
if (supportsJavaProxy) | |||
{ | |||
// may return nullptr on some platforms - that's ok | |||
config = SlRef<SLAndroidConfigurationItf_>::cast (runner); | |||
if (config != nullptr) | |||
{ | |||
jobject audioRoutingJni; | |||
auto status = (*config)->AcquireJavaProxy (config, SL_ANDROID_JAVA_PROXY_ROUTING, | |||
&audioRoutingJni); | |||
if (status == SL_RESULT_SUCCESS && audioRoutingJni != 0) | |||
javaProxy = GlobalRef (audioRoutingJni); | |||
} | |||
} | |||
queue = SlRef<SLAndroidSimpleBufferQueueItf_>::cast (runner); | |||
if (queue == nullptr) | |||
return false; | |||
@@ -308,7 +331,7 @@ public: | |||
nextBlock.set (0); | |||
numBlocksOut.set (0); | |||
zeromem (nativeBuffer.getData(), static_cast<size_t> (owner.bufferSize * numChannels * owner.numBuffers) * sizeof (T)); | |||
zeromem (nativeBuffer.get(), static_cast<size_t> (owner.bufferSize * numChannels * owner.numBuffers) * sizeof (T)); | |||
scratchBuffer.clear(); | |||
(*queue)->Clear (queue); | |||
} | |||
@@ -321,7 +344,7 @@ public: | |||
bool isBufferAvailable() const { return (numBlocksOut.get() < owner.numBuffers); } | |||
T* getNextBuffer() { nextBlock.set((nextBlock.get() + 1) % owner.numBuffers); return getCurrentBuffer(); } | |||
T* getCurrentBuffer() { return nativeBuffer.getData() + (static_cast<size_t> (nextBlock.get()) * getBufferSizeInSamples()); } | |||
T* getCurrentBuffer() { return nativeBuffer.get() + (static_cast<size_t> (nextBlock.get()) * getBufferSizeInSamples()); } | |||
size_t getBufferSizeInSamples() const { return static_cast<size_t> (owner.bufferSize * numChannels); } | |||
void finished (SLAndroidSimpleBufferQueueItf) | |||
@@ -345,6 +368,8 @@ public: | |||
SlRef<RunnerObjectType> runner; | |||
SlRef<SLAndroidSimpleBufferQueueItf_> queue; | |||
SlRef<SLAndroidConfigurationItf_> config; | |||
GlobalRef javaProxy; | |||
int numChannels; | |||
@@ -377,12 +402,12 @@ public: | |||
SLDataSource source = {&queueLocator, &dataFormat}; | |||
SLDataSink sink = {&outputMix, nullptr}; | |||
SLInterfaceID queueInterfaces[] = { &IntfIID<SLAndroidSimpleBufferQueueItf_>::iid }; | |||
SLboolean trueFlag = SL_BOOLEAN_TRUE; | |||
SLInterfaceID queueInterfaces[] = { &IntfIID<SLAndroidSimpleBufferQueueItf_>::iid, &IntfIID<SLAndroidConfigurationItf_>::iid }; | |||
SLboolean interfaceRequired[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_FALSE}; | |||
SLObjectItf obj = nullptr; | |||
SLresult status = (*Base::owner.engine)->CreateAudioPlayer (Base::owner.engine, &obj, &source, &sink, 1, queueInterfaces, &trueFlag); | |||
SLresult status = (*Base::owner.engine)->CreateAudioPlayer (Base::owner.engine, &obj, &source, &sink, 2, queueInterfaces, interfaceRequired); | |||
if (status != SL_RESULT_SUCCESS || obj == nullptr || (*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS) | |||
{ | |||
if (obj != nullptr) | |||
@@ -435,15 +460,12 @@ public: | |||
SlRef<SLRecordItf_> recorder = SlRef<SLRecordItf_>::cast (SlObjectRef (obj)); | |||
// may return nullptr on some platforms - that's ok | |||
config = SlRef<SLAndroidConfigurationItf_>::cast (recorder); | |||
return recorder; | |||
} | |||
bool setAudioPreprocessingEnabled (bool shouldEnable) | |||
{ | |||
if (config != nullptr) | |||
if (Base::config != nullptr) | |||
{ | |||
const bool supportsUnprocessed = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 25); | |||
const SLuint32 recordingPresetValue | |||
@@ -451,8 +473,8 @@ public: | |||
: (supportsUnprocessed ? SL_ANDROID_RECORDING_PRESET_UNPROCESSED | |||
: SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION)); | |||
SLresult status = (*config)->SetConfiguration (config, SL_ANDROID_KEY_RECORDING_PRESET, | |||
&recordingPresetValue, sizeof (recordingPresetValue)); | |||
SLresult status = (*Base::config)->SetConfiguration (Base::config, SL_ANDROID_KEY_RECORDING_PRESET, | |||
&recordingPresetValue, sizeof (recordingPresetValue)); | |||
return (status == SL_RESULT_SUCCESS); | |||
} | |||
@@ -461,8 +483,6 @@ public: | |||
} | |||
void setState (bool running) { (*Base::runner)->SetRecordState (Base::runner, running ? SL_RECORDSTATE_RECORDING : SL_RECORDSTATE_STOPPED); } | |||
SlRef<SLAndroidConfigurationItf_> config; | |||
}; | |||
//============================================================================== | |||
@@ -519,6 +539,7 @@ public: | |||
virtual void stop() { running = false; } | |||
virtual bool setAudioPreprocessingEnabled (bool shouldEnable) = 0; | |||
virtual bool supportsFloatingPoint() const noexcept = 0; | |||
virtual int getXRunCount() const noexcept = 0; | |||
void setCallback (AudioIODeviceCallback* callbackToUse) | |||
{ | |||
@@ -614,6 +635,9 @@ public: | |||
player = nullptr; | |||
return; | |||
} | |||
const bool supportsUnderrunCount = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 24); | |||
getUnderrunCount = supportsUnderrunCount ? getEnv()->GetMethodID (AudioTrack, "getUnderrunCount", "()I") : 0; | |||
} | |||
} | |||
} | |||
@@ -676,6 +700,14 @@ public: | |||
return true; | |||
} | |||
int getXRunCount() const noexcept override | |||
{ | |||
if (player != nullptr && player->javaProxy != nullptr && getUnderrunCount != 0) | |||
return getEnv()->CallIntMethod (player->javaProxy, getUnderrunCount); | |||
return -1; | |||
} | |||
bool supportsFloatingPoint() const noexcept override { return (BufferHelpers<T>::isFloatingPoint != 0); } | |||
void doSomeWorkOnAudioThread() | |||
@@ -726,6 +758,7 @@ public: | |||
ScopedPointer<OpenSLQueueRunnerPlayer<T> > player; | |||
ScopedPointer<OpenSLQueueRunnerRecorder<T> > recorder; | |||
Atomic<int> guard; | |||
jmethodID getUnderrunCount = 0; | |||
}; | |||
//============================================================================== | |||
@@ -890,6 +923,7 @@ public: | |||
BigInteger getActiveInputChannels() const override { return activeInputChans; } | |||
String getLastError() override { return lastError; } | |||
bool isPlaying() override { return callback != nullptr; } | |||
int getXRunCount() const noexcept override { return (session != nullptr ? session->getXRunCount() : -1); } | |||
int getDefaultBufferSize() override | |||
{ | |||
@@ -1203,11 +1237,11 @@ public: | |||
pthread_t startThread (void* (*entry) (void*), void* userPtr) | |||
{ | |||
memset (buffer.getData(), 0, static_cast<size_t> (sizeof (int16) * static_cast<size_t> (bufferSize * numBuffers))); | |||
memset (buffer.get(), 0, static_cast<size_t> (sizeof (int16) * static_cast<size_t> (bufferSize * numBuffers))); | |||
for (int i = 0; i < numBuffers; ++i) | |||
{ | |||
int16* dst = buffer.getData() + (bufferSize * i); | |||
int16* dst = buffer.get() + (bufferSize * i); | |||
(*queue)->Enqueue (queue, dst, static_cast<SLuint32> (static_cast<size_t> (bufferSize) * sizeof (int16))); | |||
} | |||
@@ -1283,3 +1317,5 @@ pthread_t juce_createRealtimeAudioThread (void* (*entry) (void*), void* userPtr) | |||
return threadID; | |||
} | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
class iOSAudioIODevice; | |||
static const char* const iOSAudioDeviceName = "iOS Audio"; | |||
@@ -183,6 +186,10 @@ bool getNotificationValueForKey (NSNotification* notification, NSString* key, NS | |||
@end | |||
//============================================================================== | |||
#if JUCE_MODULE_AVAILABLE_juce_graphics | |||
#include <juce_graphics/native/juce_mac_CoreGraphicsHelpers.h> | |||
#endif | |||
namespace juce { | |||
#ifndef JUCE_IOS_AUDIO_LOGGING | |||
@@ -206,10 +213,6 @@ static void logNSError (NSError* e) | |||
#define JUCE_NSERROR_CHECK(X) { NSError* error = nil; X; logNSError (error); } | |||
#if JUCE_MODULE_AVAILABLE_juce_graphics | |||
#include <juce_graphics/native/juce_mac_CoreGraphicsHelpers.h> | |||
#endif | |||
//============================================================================== | |||
struct iOSAudioIODevice::Pimpl : public AudioPlayHead, | |||
public AsyncUpdater | |||
@@ -310,6 +313,9 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead, | |||
{ | |||
close(); | |||
firstHostTime = true; | |||
lastNumFrames = 0; | |||
xrun = 0; | |||
lastError.clear(); | |||
preferredBufferSize = bufferSize <= 0 ? defaultBufferSize : bufferSize; | |||
@@ -711,6 +717,8 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead, | |||
{ | |||
OSStatus err = noErr; | |||
recordXruns (time, numFrames); | |||
if (audioInputIsAvailable && numInputChannels > 0) | |||
err = AudioUnitRender (audioUnit, flags, time, 1, numFrames, data); | |||
@@ -796,6 +804,26 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead, | |||
updateSampleRateAndAudioInput(); | |||
} | |||
void recordXruns (const AudioTimeStamp* time, UInt32 numFrames) | |||
{ | |||
if (time != nullptr && (time->mFlags & kAudioTimeStampSampleTimeValid) != 0) | |||
{ | |||
if (! firstHostTime) | |||
{ | |||
if ((time->mSampleTime - lastSampleTime) != lastNumFrames) | |||
xrun++; | |||
} | |||
else | |||
firstHostTime = false; | |||
lastSampleTime = time->mSampleTime; | |||
} | |||
else | |||
firstHostTime = true; | |||
lastNumFrames = numFrames; | |||
} | |||
//============================================================================== | |||
static OSStatus processStatic (void* client, AudioUnitRenderActionFlags* flags, const AudioTimeStamp* time, | |||
UInt32 /*busNumber*/, UInt32 numFrames, AudioBufferList* data) | |||
@@ -1060,6 +1088,11 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead, | |||
float* outputChannels[3]; | |||
bool monoInputChannelNumber, monoOutputChannelNumber; | |||
bool firstHostTime; | |||
Float64 lastSampleTime; | |||
unsigned int lastNumFrames; | |||
int xrun; | |||
JUCE_DECLARE_NON_COPYABLE (Pimpl) | |||
}; | |||
@@ -1105,6 +1138,7 @@ BigInteger iOSAudioIODevice::getActiveInputChannels() const { return pim | |||
int iOSAudioIODevice::getOutputLatencyInSamples() { return roundToInt (pimpl->sampleRate * [AVAudioSession sharedInstance].outputLatency); } | |||
int iOSAudioIODevice::getInputLatencyInSamples() { return roundToInt (pimpl->sampleRate * [AVAudioSession sharedInstance].inputLatency); } | |||
int iOSAudioIODevice::getXRunCount() const noexcept { return pimpl->xrun; } | |||
void iOSAudioIODevice::setMidiMessageCollector (MidiMessageCollector* collector) { pimpl->messageCollector = collector; } | |||
AudioPlayHead* iOSAudioIODevice::getAudioPlayHead() const { return pimpl; } | |||
@@ -1168,3 +1202,5 @@ void AudioSessionHolder::handleRouteChange (const char* reason) | |||
} | |||
#undef JUCE_NSERROR_CHECK | |||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||
============================================================================== | |||
*/ | |||
#pragma once | |||
namespace juce | |||
{ | |||
struct iOSAudioIODeviceType; | |||
@@ -61,6 +62,8 @@ public: | |||
int getOutputLatencyInSamples() override; | |||
int getInputLatencyInSamples() override; | |||
int getXRunCount() const noexcept override; | |||
//============================================================================== | |||
void setMidiMessageCollector (MidiMessageCollector*); | |||
AudioPlayHead* getAudioPlayHead() const; | |||
@@ -86,3 +89,5 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice) | |||
}; | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
namespace | |||
{ | |||
@@ -75,7 +78,7 @@ static void getDeviceNumChannels (snd_pcm_t* handle, unsigned int* minChans, uns | |||
JUCE_ALSA_LOG ("getDeviceNumChannels: " << (int) *minChans << " " << (int) *maxChans); | |||
// some virtual devices (dmix for example) report 10000 channels , we have to clamp these values | |||
*maxChans = jmin (*maxChans, 32u); | |||
*maxChans = jmin (*maxChans, 256u); | |||
*minChans = jmin (*minChans, *maxChans); | |||
} | |||
else | |||
@@ -155,7 +158,7 @@ public: | |||
isInput (forInput), | |||
isInterleaved (true) | |||
{ | |||
JUCE_ALSA_LOG ("snd_pcm_open (" << deviceID.toUTF8().getAddress() << ", forInput=" << forInput << ")"); | |||
JUCE_ALSA_LOG ("snd_pcm_open (" << deviceID.toUTF8().getAddress() << ", forInput=" << (int) forInput << ")"); | |||
int err = snd_pcm_open (&handle, deviceID.toUTF8(), | |||
forInput ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, | |||
@@ -241,7 +244,8 @@ public: | |||
(type & isFloatBit) != 0, | |||
(type & isLittleEndianBit) != 0, | |||
(type & onlyUseLower24Bits) != 0, | |||
numChannels); | |||
numChannels, | |||
isInterleaved); | |||
break; | |||
} | |||
} | |||
@@ -329,8 +333,14 @@ public: | |||
numDone = snd_pcm_writen (handle, (void**) data, (snd_pcm_uframes_t) numSamples); | |||
} | |||
if (numDone < 0 && JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) numDone, 1 /* silent */))) | |||
return false; | |||
if (numDone < 0) | |||
{ | |||
if (numDone == -(EPIPE)) | |||
underrunCount++; | |||
if (JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) numDone, 1 /* silent */))) | |||
return false; | |||
} | |||
if (numDone < numSamples) | |||
JUCE_ALSA_LOG ("Did not write all samples: numDone: " << numDone << ", numSamples: " << numSamples); | |||
@@ -350,8 +360,15 @@ public: | |||
snd_pcm_sframes_t num = snd_pcm_readi (handle, scratch.getData(), (snd_pcm_uframes_t) numSamples); | |||
if (num < 0 && JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) num, 1 /* silent */))) | |||
return false; | |||
if (num < 0) | |||
{ | |||
if (num == -(EPIPE)) | |||
overrunCount++; | |||
if (JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) num, 1 /* silent */))) | |||
return false; | |||
} | |||
if (num < numSamples) | |||
JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples); | |||
@@ -363,8 +380,14 @@ public: | |||
{ | |||
snd_pcm_sframes_t num = snd_pcm_readn (handle, (void**) data, (snd_pcm_uframes_t) numSamples); | |||
if (num < 0 && JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) num, 1 /* silent */))) | |||
return false; | |||
if (num < 0) | |||
{ | |||
if (num == -(EPIPE)) | |||
overrunCount++; | |||
if (JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) num, 1 /* silent */))) | |||
return false; | |||
} | |||
if (num < numSamples) | |||
JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples); | |||
@@ -380,6 +403,7 @@ public: | |||
snd_pcm_t* handle; | |||
String error; | |||
int bitDepth, numChannelsRunning, latency; | |||
int underrunCount = 0, overrunCount = 0; | |||
private: | |||
//============================================================================== | |||
@@ -393,44 +417,55 @@ private: | |||
template <class SampleType> | |||
struct ConverterHelper | |||
{ | |||
static AudioData::Converter* createConverter (const bool forInput, const bool isLittleEndian, const int numInterleavedChannels) | |||
static AudioData::Converter* createConverter (const bool forInput, const bool isLittleEndian, const int numInterleavedChannels, bool interleaved) | |||
{ | |||
if (interleaved) | |||
return create<AudioData::Interleaved> (forInput, isLittleEndian, numInterleavedChannels); | |||
return create<AudioData::NonInterleaved> (forInput, isLittleEndian, numInterleavedChannels); | |||
} | |||
private: | |||
template <class InterleavedType> | |||
static AudioData::Converter* create (const bool forInput, const bool isLittleEndian, const int numInterleavedChannels) | |||
{ | |||
if (forInput) | |||
{ | |||
typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> DestType; | |||
if (isLittleEndian) | |||
return new AudioData::ConverterInstance <AudioData::Pointer <SampleType, AudioData::LittleEndian, AudioData::Interleaved, AudioData::Const>, DestType> (numInterleavedChannels, 1); | |||
return new AudioData::ConverterInstance <AudioData::Pointer <SampleType, AudioData::LittleEndian, InterleavedType, AudioData::Const>, DestType> (numInterleavedChannels, 1); | |||
return new AudioData::ConverterInstance <AudioData::Pointer <SampleType, AudioData::BigEndian, AudioData::Interleaved, AudioData::Const>, DestType> (numInterleavedChannels, 1); | |||
return new AudioData::ConverterInstance <AudioData::Pointer <SampleType, AudioData::BigEndian, InterleavedType, AudioData::Const>, DestType> (numInterleavedChannels, 1); | |||
} | |||
typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> SourceType; | |||
if (isLittleEndian) | |||
return new AudioData::ConverterInstance <SourceType, AudioData::Pointer <SampleType, AudioData::LittleEndian, AudioData::Interleaved, AudioData::NonConst> > (1, numInterleavedChannels); | |||
return new AudioData::ConverterInstance <SourceType, AudioData::Pointer <SampleType, AudioData::LittleEndian, InterleavedType, AudioData::NonConst> > (1, numInterleavedChannels); | |||
return new AudioData::ConverterInstance <SourceType, AudioData::Pointer <SampleType, AudioData::BigEndian, AudioData::Interleaved, AudioData::NonConst> > (1, numInterleavedChannels); | |||
return new AudioData::ConverterInstance <SourceType, AudioData::Pointer <SampleType, AudioData::BigEndian, InterleavedType, AudioData::NonConst> > (1, numInterleavedChannels); | |||
} | |||
}; | |||
static AudioData::Converter* createConverter (bool forInput, int bitDepth, | |||
bool isFloat, bool isLittleEndian, bool useOnlyLower24Bits, | |||
int numInterleavedChannels) | |||
int numInterleavedChannels, | |||
bool interleaved) | |||
{ | |||
JUCE_ALSA_LOG ("format: bitDepth=" << bitDepth << ", isFloat=" << isFloat | |||
<< ", isLittleEndian=" << isLittleEndian << ", numChannels=" << numInterleavedChannels); | |||
JUCE_ALSA_LOG ("format: bitDepth=" << bitDepth << ", isFloat=" << (int) isFloat | |||
<< ", isLittleEndian=" << (int) isLittleEndian << ", numChannels=" << numInterleavedChannels); | |||
if (isFloat) return ConverterHelper <AudioData::Float32>::createConverter (forInput, isLittleEndian, numInterleavedChannels); | |||
if (bitDepth == 16) return ConverterHelper <AudioData::Int16> ::createConverter (forInput, isLittleEndian, numInterleavedChannels); | |||
if (bitDepth == 24) return ConverterHelper <AudioData::Int24> ::createConverter (forInput, isLittleEndian, numInterleavedChannels); | |||
if (isFloat) return ConverterHelper <AudioData::Float32>::createConverter (forInput, isLittleEndian, numInterleavedChannels, interleaved); | |||
if (bitDepth == 16) return ConverterHelper <AudioData::Int16> ::createConverter (forInput, isLittleEndian, numInterleavedChannels, interleaved); | |||
if (bitDepth == 24) return ConverterHelper <AudioData::Int24> ::createConverter (forInput, isLittleEndian, numInterleavedChannels, interleaved); | |||
jassert (bitDepth == 32); | |||
if (useOnlyLower24Bits) | |||
return ConverterHelper <AudioData::Int24in32>::createConverter (forInput, isLittleEndian, numInterleavedChannels); | |||
return ConverterHelper <AudioData::Int24in32>::createConverter (forInput, isLittleEndian, numInterleavedChannels, interleaved); | |||
return ConverterHelper <AudioData::Int32>::createConverter (forInput, isLittleEndian, numInterleavedChannels); | |||
return ConverterHelper <AudioData::Int32>::createConverter (forInput, isLittleEndian, numInterleavedChannels, interleaved); | |||
} | |||
//============================================================================== | |||
@@ -734,6 +769,19 @@ public: | |||
return 16; | |||
} | |||
int getXRunCount() const noexcept | |||
{ | |||
int result = 0; | |||
if (outputDevice != nullptr) | |||
result += outputDevice->underrunCount; | |||
if (inputDevice != nullptr) | |||
result += inputDevice->overrunCount; | |||
return result; | |||
} | |||
//============================================================================== | |||
String error; | |||
double sampleRate; | |||
@@ -893,6 +941,8 @@ public: | |||
int getOutputLatencyInSamples() override { return internal.outputLatency; } | |||
int getInputLatencyInSamples() override { return internal.inputLatency; } | |||
int getXRunCount() const noexcept override { return internal.getXRunCount(); } | |||
void start (AudioIODeviceCallback* callback) override | |||
{ | |||
if (! isOpen_) | |||
@@ -1037,7 +1087,7 @@ private: | |||
if ((isInput || isOutput) && rates.size() > 0) | |||
{ | |||
JUCE_ALSA_LOG ("testDevice: '" << id.toUTF8().getAddress() << "' -> isInput: " | |||
<< isInput << ", isOutput: " << isOutput); | |||
<< (int) isInput << ", isOutput: " << (int) isOutput); | |||
if (isInput) | |||
{ | |||
@@ -1128,7 +1178,8 @@ private: | |||
} | |||
JUCE_ALSA_LOG ("Soundcard ID: " << id << ", name: '" << name | |||
<< ", isInput:" << isInput << ", isOutput:" << isOutput << "\n"); | |||
<< ", isInput:" << (int) isInput | |||
<< ", isOutput:" << (int) isOutput << "\n"); | |||
if (isInput) | |||
{ | |||
@@ -1259,3 +1310,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA() | |||
{ | |||
return createAudioIODeviceType_ALSA_PCMDevices(); | |||
} | |||
} // namespace juce |
@@ -20,7 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
//============================================================================== | |||
namespace juce | |||
{ | |||
static void* juce_libjackHandle = nullptr; | |||
static void* juce_loadJackFunction (const char* const name) | |||
@@ -67,6 +69,7 @@ JUCE_DECL_JACK_FUNCTION (void*, jack_set_port_connect_callback, (jack_client_t* | |||
JUCE_DECL_JACK_FUNCTION (jack_port_t* , jack_port_by_id, (jack_client_t* client, jack_port_id_t port_id), (client, port_id)); | |||
JUCE_DECL_JACK_FUNCTION (int, jack_port_connected, (const jack_port_t* port), (port)); | |||
JUCE_DECL_JACK_FUNCTION (int, jack_port_connected_to, (const jack_port_t* port, const char* port_name), (port, port_name)); | |||
JUCE_DECL_JACK_FUNCTION (int, jack_set_xrun_callback, (jack_client_t* client, JackXRunCallback xrun_callback, void* arg), (client, xrun_callback, arg)); | |||
#if JUCE_DEBUG | |||
#define JACK_LOGGING_ENABLED 1 | |||
@@ -256,9 +259,11 @@ public: | |||
lastError.clear(); | |||
close(); | |||
xruns = 0; | |||
juce::jack_set_process_callback (client, processCallback, this); | |||
juce::jack_set_port_connect_callback (client, portConnectCallback, this); | |||
juce::jack_on_shutdown (client, shutdownCallback, this); | |||
juce::jack_set_xrun_callback (client, xrunCallback, this); | |||
juce::jack_activate (client); | |||
deviceIsOpen = true; | |||
@@ -300,6 +305,8 @@ public: | |||
if (client != nullptr) | |||
{ | |||
juce::jack_deactivate (client); | |||
juce::jack_set_xrun_callback (client, xrunCallback, nullptr); | |||
juce::jack_set_process_callback (client, processCallback, nullptr); | |||
juce::jack_set_port_connect_callback (client, portConnectCallback, nullptr); | |||
juce::jack_on_shutdown (client, shutdownCallback, nullptr); | |||
@@ -336,6 +343,7 @@ public: | |||
bool isPlaying() override { return callback != nullptr; } | |||
int getCurrentBitDepth() override { return 32; } | |||
String getLastError() override { return lastError; } | |||
int getXRunCount() const noexcept override { return xruns; } | |||
BigInteger getActiveOutputChannels() const override { return activeOutputChannels; } | |||
BigInteger getActiveInputChannels() const override { return activeInputChannels; } | |||
@@ -406,6 +414,14 @@ private: | |||
return 0; | |||
} | |||
static int xrunCallback (void* callbackArgument) | |||
{ | |||
if (callbackArgument != nullptr) | |||
((JackAudioIODevice*) callbackArgument)->xruns++; | |||
return 0; | |||
} | |||
void updateActivePorts() | |||
{ | |||
BigInteger newOutputChannels, newInputChannels; | |||
@@ -475,6 +491,8 @@ private: | |||
int totalNumberOfOutputChannels; | |||
Array<void*> inputPorts, outputPorts; | |||
BigInteger activeInputChannels, activeOutputChannels; | |||
int xruns; | |||
}; | |||
@@ -602,3 +620,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK() | |||
{ | |||
return new JackAudioIODeviceType(); | |||
} | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
#if JUCE_ALSA | |||
// You can define these strings in your app if you want to override the default names: | |||
@@ -137,7 +140,7 @@ public: | |||
numBytes -= numSent; | |||
data += numSent; | |||
snd_seq_ev_set_source (&event, portId); | |||
snd_seq_ev_set_source (&event, (unsigned char) portId); | |||
snd_seq_ev_set_subs (&event); | |||
snd_seq_ev_set_direct (&event); | |||
@@ -610,3 +613,5 @@ MidiInput* MidiInput::openDevice (int, MidiInputCallback*) { re | |||
MidiInput* MidiInput::createNewDevice (const String&, MidiInputCallback*) { return nullptr; } | |||
#endif | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
#if JUCE_COREAUDIO_LOGGING_ENABLED | |||
#define JUCE_COREAUDIOLOG(a) { String camsg ("CoreAudio: "); camsg << a; Logger::writeToLog (camsg); } | |||
#else | |||
@@ -228,7 +231,7 @@ public: | |||
for (int i = 0; i < numStreams; ++i) | |||
{ | |||
const ::AudioBuffer& b = bufList->mBuffers[i]; | |||
auto& b = bufList->mBuffers[i]; | |||
for (unsigned int j = 0; j < b.mNumberChannels; ++j) | |||
{ | |||
@@ -578,6 +581,8 @@ public: | |||
stop (false); | |||
updateDetailsFromDevice(); | |||
activeInputChans = inputChannels; | |||
activeInputChans.setRange (inChanNames.size(), | |||
activeInputChans.getHighestBit() + 1 - inChanNames.size(), | |||
@@ -733,7 +738,7 @@ public: | |||
} | |||
} | |||
callback->audioDeviceIOCallback (const_cast<const float**> (tempInputBuffers.getData()), | |||
callback->audioDeviceIOCallback (const_cast<const float**> (tempInputBuffers.get()), | |||
numInputChans, | |||
tempOutputBuffers, | |||
numOutputChans, | |||
@@ -791,6 +796,7 @@ public: | |||
int inputLatency = 0; | |||
int outputLatency = 0; | |||
int bitDepth = 32; | |||
int xruns = 0; | |||
BigInteger activeInputChans, activeOutputChans; | |||
StringArray inChanNames, outChanNames; | |||
Array<double> sampleRates; | |||
@@ -832,6 +838,9 @@ private: | |||
switch (pa->mSelector) | |||
{ | |||
case kAudioDeviceProcessorOverload: | |||
intern->xruns++; | |||
break; | |||
case kAudioDevicePropertyBufferSize: | |||
case kAudioDevicePropertyBufferFrameSize: | |||
case kAudioDevicePropertyNominalSampleRate: | |||
@@ -957,6 +966,7 @@ public: | |||
double getCurrentSampleRate() override { return internal->getSampleRate(); } | |||
int getCurrentBitDepth() override { return internal->bitDepth; } | |||
int getCurrentBufferSizeSamples() override { return internal->getBufferSize(); } | |||
int getXRunCount() const noexcept override { return internal->xruns; } | |||
int getDefaultBufferSize() override | |||
{ | |||
@@ -977,6 +987,7 @@ public: | |||
{ | |||
isOpen_ = true; | |||
internal->xruns = 0; | |||
if (bufferSizeSamples <= 0) | |||
bufferSizeSamples = getDefaultBufferSize(); | |||
@@ -2058,3 +2069,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio() | |||
} | |||
#undef JUCE_COREAUDIOLOG | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
#ifndef JUCE_LOG_COREMIDI_ERRORS | |||
#define JUCE_LOG_COREMIDI_ERRORS 1 | |||
#endif | |||
@@ -555,3 +558,5 @@ void MidiInput::stop() | |||
} | |||
#undef CHECK_ERROR | |||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
#undef WINDOWS | |||
/* The ASIO SDK *should* declare its callback functions as being __cdecl, but different versions seem | |||
@@ -406,6 +409,8 @@ public: | |||
Array<int> getAvailableBufferSizes() override { return bufferSizes; } | |||
int getDefaultBufferSize() override { return preferredBufferSize; } | |||
int getXRunCount() const noexcept override { return xruns; } | |||
String open (const BigInteger& inputChannels, | |||
const BigInteger& outputChannels, | |||
double sr, int bufferSizeSamples) override | |||
@@ -461,6 +466,9 @@ public: | |||
err = asioObject->getChannels (&totalNumInputChans, &totalNumOutputChans); | |||
jassert (err == ASE_OK); | |||
if (asioObject->future (kAsioCanReportOverload, nullptr) != ASE_OK) | |||
xruns = -1; | |||
inBuffers.calloc (totalNumInputChans + 8); | |||
outBuffers.calloc (totalNumOutputChans + 8); | |||
@@ -786,6 +794,7 @@ private: | |||
bool volatile littleEndian, postOutput, needToReset; | |||
bool volatile insideControlPanelModalLoop; | |||
bool volatile shouldUsePreferredSize; | |||
int xruns = 0; | |||
//============================================================================== | |||
static String convertASIOString (char* const text, int length) | |||
@@ -1177,6 +1186,7 @@ private: | |||
totalNumOutputChans = 0; | |||
numActiveInputChans = 0; | |||
numActiveOutputChans = 0; | |||
xruns = 0; | |||
currentCallback = nullptr; | |||
error.clear(); | |||
@@ -1346,7 +1356,7 @@ private: | |||
{ | |||
case kAsioSelectorSupported: | |||
if (value == kAsioResetRequest || value == kAsioEngineVersion || value == kAsioResyncRequest | |||
|| value == kAsioLatenciesChanged || value == kAsioSupportsInputMonitor) | |||
|| value == kAsioLatenciesChanged || value == kAsioSupportsInputMonitor || value == kAsioOverload) | |||
return 1; | |||
break; | |||
@@ -1357,7 +1367,8 @@ private: | |||
case kAsioEngineVersion: return 2; | |||
case kAsioSupportsTimeInfo: | |||
case kAsioSupportsTimeCode: return 0; | |||
case kAsioSupportsTimeCode: return 0; | |||
case kAsioOverload: xruns++; return 1; | |||
} | |||
return 0; | |||
@@ -1643,3 +1654,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO() | |||
{ | |||
return new ASIOAudioIODeviceType(); | |||
} | |||
} // namespace juce |