@@ -20,8 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
@@ -46,14 +46,15 @@ public: | |||||
/** Frame rate types. */ | /** Frame rate types. */ | ||||
enum FrameRateType | 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 | fpsUnknown = 99 | ||||
}; | }; | ||||
@@ -70,12 +71,12 @@ public: | |||||
/** Time signature denominator, e.g. the 4 of a 3/4 time sig */ | /** Time signature denominator, e.g. the 4 of a 3/4 time sig */ | ||||
int timeSigDenominator; | 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; | 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; | 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; | double editOriginTime; | ||||
/** The current play position, in pulses-per-quarter-note. */ | /** 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. | /** 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. | bar, in ppq units. | ||||
Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If | Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If | ||||
@@ -150,3 +151,5 @@ public: | |||||
/** Rewinds the audio. */ | /** Rewinds the audio. */ | ||||
virtual void transportRewind() {} | virtual void transportRewind() {} | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
AudioChannelSet::AudioChannelSet (uint32 c) : channels (c) {} | AudioChannelSet::AudioChannelSet (uint32 c) : channels (c) {} | ||||
AudioChannelSet::AudioChannelSet (const Array<ChannelType>& 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 ambisonicX: return NEEDS_TRANS("Ambisonic X"); | ||||
case ambisonicY: return NEEDS_TRANS("Ambisonic Y"); | case ambisonicY: return NEEDS_TRANS("Ambisonic Y"); | ||||
case ambisonicZ: return NEEDS_TRANS("Ambisonic Z"); | 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; | default: break; | ||||
} | } | ||||
@@ -105,6 +110,8 @@ String AudioChannelSet::getAbbreviatedChannelTypeName (AudioChannelSet::ChannelT | |||||
case ambisonicX: return "X"; | case ambisonicX: return "X"; | ||||
case ambisonicY: return "Y"; | case ambisonicY: return "Y"; | ||||
case ambisonicZ: return "Z"; | case ambisonicZ: return "Z"; | ||||
case topSideLeft: return "Tsl"; | |||||
case topSideRight: return "Tsr"; | |||||
default: break; | default: break; | ||||
} | } | ||||
@@ -144,6 +151,8 @@ AudioChannelSet::ChannelType AudioChannelSet::getChannelTypeFromAbbreviation (co | |||||
if (abbr == "X") return ambisonicX; | if (abbr == "X") return ambisonicX; | ||||
if (abbr == "Y") return ambisonicY; | if (abbr == "Y") return ambisonicY; | ||||
if (abbr == "Z") return ambisonicZ; | if (abbr == "Z") return ambisonicZ; | ||||
if (abbr == "Tsl") return topSideLeft; | |||||
if (abbr == "Tsr") return topSideRight; | |||||
return unknown; | return unknown; | ||||
} | } | ||||
@@ -189,16 +198,18 @@ String AudioChannelSet::getDescription() const | |||||
if (*this == createLRS()) return "LRS"; | if (*this == createLRS()) return "LRS"; | ||||
if (*this == createLCRS()) return "LCRS"; | 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 == quadraphonic()) return "Quadraphonic"; | ||||
if (*this == pentagonal()) return "Pentagonal"; | if (*this == pentagonal()) return "Pentagonal"; | ||||
@@ -212,7 +223,7 @@ String AudioChannelSet::getDescription() const | |||||
bool AudioChannelSet::isDiscreteLayout() const noexcept | bool AudioChannelSet::isDiscreteLayout() const noexcept | ||||
{ | { | ||||
for (auto& speaker : getChannelTypes()) | for (auto& speaker : getChannelTypes()) | ||||
if (speaker <= ambisonicZ) | |||||
if (speaker <= topSideRight) | |||||
return false; | return false; | ||||
return true; | return true; | ||||
@@ -272,27 +283,29 @@ void AudioChannelSet::removeChannel (ChannelType newChannel) | |||||
channels.clearBit (bit); | 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) | AudioChannelSet AudioChannelSet::discreteChannels (int numChannels) | ||||
@@ -414,3 +427,5 @@ int32 AudioChannelSet::getWaveChannelMask() const noexcept | |||||
return (channels.toInteger() >> 1); | return (channels.toInteger() >> 1); | ||||
} | } | ||||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
@@ -194,6 +194,18 @@ public: | |||||
*/ | */ | ||||
static AudioChannelSet JUCE_CALLTYPE create7point1SDDS(); | 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). | /** Creates a set for ambisonic surround setups (ambisonicW, ambisonicX, ambisonicY, ambisonicZ). | ||||
@@ -289,6 +301,10 @@ public: | |||||
ambisonicY = 26, | ambisonicY = 26, | ||||
ambisonicZ = 27, | 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. */ | discreteChannel0 = 64 /**< Non-typed individual channels are indexed upwards from this value. */ | ||||
}; | }; | ||||
@@ -305,7 +321,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
enum | enum | ||||
{ | { | ||||
maxChannelsOfNamedLayout = 8 | |||||
maxChannelsOfNamedLayout = 10 | |||||
}; | }; | ||||
/** Adds a channel to the set. */ | /** Adds a channel to the set. */ | ||||
@@ -388,3 +404,5 @@ private: | |||||
explicit AudioChannelSet (uint32); | explicit AudioChannelSet (uint32); | ||||
explicit AudioChannelSet (const Array<ChannelType>&); | 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) | void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest, int numSamples, const int destBytesPerSample) | ||||
{ | { | ||||
const double maxVal = (double) 0x7fff; | 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) | 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); | const char* intData = static_cast<const char*> (source); | ||||
if (source != (void*) dest || srcBytesPerSample >= 4) | 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) | 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); | const char* intData = static_cast<const char*> (source); | ||||
if (source != (void*) dest || srcBytesPerSample >= 4) | if (source != (void*) dest || srcBytesPerSample >= 4) | ||||
@@ -596,3 +599,5 @@ public: | |||||
static AudioConversionTests audioConversionUnitTests; | static AudioConversionTests audioConversionUnitTests; | ||||
#endif | #endif | ||||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
@@ -708,3 +708,5 @@ private: | |||||
AudioDataConverters(); | AudioDataConverters(); | ||||
JUCE_DECLARE_NON_COPYABLE (AudioDataConverters) | JUCE_DECLARE_NON_COPYABLE (AudioDataConverters) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
@@ -184,11 +184,19 @@ public: | |||||
: numChannels (other.numChannels), | : numChannels (other.numChannels), | ||||
size (other.size), | size (other.size), | ||||
allocatedBytes (other.allocatedBytes), | allocatedBytes (other.allocatedBytes), | ||||
channels (other.channels), | |||||
allocatedData (static_cast<HeapBlock<char, true>&&> (other.allocatedData)), | allocatedData (static_cast<HeapBlock<char, true>&&> (other.allocatedData)), | ||||
isClear (other.isClear) | 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.numChannels = 0; | ||||
other.size = 0; | other.size = 0; | ||||
other.allocatedBytes = 0; | other.allocatedBytes = 0; | ||||
@@ -200,10 +208,19 @@ public: | |||||
numChannels = other.numChannels; | numChannels = other.numChannels; | ||||
size = other.size; | size = other.size; | ||||
allocatedBytes = other.allocatedBytes; | allocatedBytes = other.allocatedBytes; | ||||
channels = other.channels; | |||||
allocatedData = static_cast<HeapBlock<char, true>&&> (other.allocatedData); | allocatedData = static_cast<HeapBlock<char, true>&&> (other.allocatedData); | ||||
isClear = other.isClear; | 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.numChannels = 0; | ||||
other.size = 0; | other.size = 0; | ||||
other.allocatedBytes = 0; | other.allocatedBytes = 0; | ||||
@@ -332,7 +349,7 @@ public: | |||||
auto numSamplesToCopy = (size_t) jmin (newNumSamples, size); | 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); | auto newChan = reinterpret_cast<Type*> (newData + channelListSize); | ||||
for (int j = 0; j < newNumChannels; ++j) | for (int j = 0; j < newNumChannels; ++j) | ||||
@@ -364,7 +381,7 @@ public: | |||||
{ | { | ||||
allocatedBytes = newTotalBytes; | allocatedBytes = newTotalBytes; | ||||
allocatedData.allocate (newTotalBytes, clearExtraSpace || isClear); | allocatedData.allocate (newTotalBytes, clearExtraSpace || isClear); | ||||
channels = reinterpret_cast<Type**> (allocatedData.getData()); | |||||
channels = reinterpret_cast<Type**> (allocatedData.get()); | |||||
} | } | ||||
auto* chan = reinterpret_cast<Type*> (allocatedData + channelListSize); | auto* chan = reinterpret_cast<Type*> (allocatedData + channelListSize); | ||||
@@ -629,7 +646,7 @@ public: | |||||
jassert (isPositiveAndBelow (channel, numChannels)); | jassert (isPositiveAndBelow (channel, numChannels)); | ||||
jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size); | 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; | auto* d = channels[channel] + startSample; | ||||
while (--numSamples >= 0) | while (--numSamples >= 0) | ||||
@@ -1051,7 +1068,7 @@ private: | |||||
auto channelListSize = sizeof (Type*) * (size_t) (numChannels + 1); | auto channelListSize = sizeof (Type*) * (size_t) (numChannels + 1); | ||||
allocatedBytes = (size_t) numChannels * (size_t) size * sizeof (Type) + channelListSize + 32; | allocatedBytes = (size_t) numChannels * (size_t) size * sizeof (Type) + channelListSize + 32; | ||||
allocatedData.malloc (allocatedBytes); | allocatedData.malloc (allocatedBytes); | ||||
channels = reinterpret_cast<Type**> (allocatedData.getData()); | |||||
channels = reinterpret_cast<Type**> (allocatedData.get()); | |||||
auto* chan = (Type*) (allocatedData + channelListSize); | auto* chan = (Type*) (allocatedData + channelListSize); | ||||
for (int i = 0; i < numChannels; ++i) | for (int i = 0; i < numChannels; ++i) | ||||
@@ -1076,7 +1093,7 @@ private: | |||||
else | else | ||||
{ | { | ||||
allocatedData.malloc ((size_t) numChannels + 1, sizeof (Type*)); | 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) | for (int i = 0; i < numChannels; ++i) | ||||
@@ -1105,3 +1122,5 @@ private: | |||||
@see AudioBuffer | @see AudioBuffer | ||||
*/ | */ | ||||
typedef AudioBuffer<float> AudioSampleBuffer; | typedef AudioBuffer<float> AudioSampleBuffer; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
namespace FloatVectorHelpers | namespace FloatVectorHelpers | ||||
{ | { | ||||
#define JUCE_INCREMENT_SRC_DEST dest += (16 / sizeof (*dest)); src += (16 / sizeof (*dest)); | #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), | vmulq_n_f32 (vcvtq_f32_s32 (vld1q_s32 (src)), multiplier), | ||||
JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, ) | JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, ) | ||||
#else | #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))), | Mode::mul (mult, _mm_cvtepi32_ps (_mm_loadu_si128 ((const __m128i*) src))), | ||||
JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, | JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, | ||||
const Mode::ParallelType mult = Mode::load1 (multiplier);) | const Mode::ParallelType mult = Mode::load1 (multiplier);) | ||||
@@ -1068,9 +1071,9 @@ public: | |||||
#else | #else | ||||
// These tests deliberately operate on misaligned memory and will be flagged up by | // These tests deliberately operate on misaligned memory and will be flagged up by | ||||
// checks for undefined behavior! | // 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 | #endif | ||||
fillRandomly (random, data1, num); | fillRandomly (random, data1, num); | ||||
@@ -1158,7 +1161,7 @@ public: | |||||
static void convertFixed (float* d, const int* s, ValueType multiplier, int num) | static void convertFixed (float* d, const int* s, ValueType multiplier, int num) | ||||
{ | { | ||||
while (--num >= 0) | while (--num >= 0) | ||||
*d++ = *s++ * multiplier; | |||||
*d++ = (float) *s++ * multiplier; | |||||
} | } | ||||
static bool areAllValuesEqual (const ValueType* d, int num, ValueType target) | static bool areAllValuesEqual (const ValueType* d, int num, ValueType target) | ||||
@@ -1200,3 +1203,5 @@ public: | |||||
static FloatVectorOperationsTests vectorOpTests; | static FloatVectorOperationsTests vectorOpTests; | ||||
#endif | #endif | ||||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
#if JUCE_INTEL | #if JUCE_INTEL | ||||
#define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8f || n > 1.0e-8f)) n = 0; | #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; | 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 | struct CatmullRomAlgorithm | ||||
{ | { | ||||
static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept | 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); | 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. | Interpolator for resampling a stream of floats using Catmull-Rom interpolation. | ||||
@@ -84,3 +87,5 @@ private: | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CatmullRomInterpolator) | 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.. | Decibels(); // This class can't be instantiated, it's just a holder for static methods.. | ||||
JUCE_DECLARE_NON_COPYABLE (Decibels) | JUCE_DECLARE_NON_COPYABLE (Decibels) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,7 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
//============================================================================== | |||||
namespace juce | |||||
{ | |||||
IIRCoefficients::IIRCoefficients() noexcept | IIRCoefficients::IIRCoefficients() noexcept | ||||
{ | { | ||||
zeromem (coefficients, sizeof (coefficients)); | zeromem (coefficients, sizeof (coefficients)); | ||||
@@ -335,3 +337,5 @@ void IIRFilter::processSamples (float* const samples, const int numSamples) noex | |||||
} | } | ||||
#undef JUCE_SNAP_TO_ZERO | #undef JUCE_SNAP_TO_ZERO | ||||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
class IIRFilter; | class IIRFilter; | ||||
@@ -205,3 +206,5 @@ protected: | |||||
IIRFilter& operator= (const IIRFilter&); | IIRFilter& operator= (const IIRFilter&); | ||||
JUCE_LEAK_DETECTOR (IIRFilter) | JUCE_LEAK_DETECTOR (IIRFilter) | ||||
}; | }; | ||||
} // namespace juce |
@@ -28,6 +28,9 @@ | |||||
#define JUCE_SNAP_TO_ZERO(n) | #define JUCE_SNAP_TO_ZERO(n) | ||||
#endif | #endif | ||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
IIRFilterOld::IIRFilterOld() | IIRFilterOld::IIRFilterOld() | ||||
: active (false), v1 (0), v2 (0) | : active (false), v1 (0), v2 (0) | ||||
@@ -237,3 +240,5 @@ void IIRFilterOld::setCoefficients (double c1, double c2, double c3, | |||||
} | } | ||||
#undef JUCE_SNAP_TO_ZERO | #undef JUCE_SNAP_TO_ZERO | ||||
} // namespace juce |
@@ -26,6 +26,9 @@ | |||||
#define __JUCE_IIRFILTER_OLD_JUCEHEADER__ | #define __JUCE_IIRFILTER_OLD_JUCEHEADER__ | ||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
An IIR filter that can perform low, high, or band-pass filtering on an | 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__ | #endif // __JUCE_IIRFILTER_OLD_JUCEHEADER__ |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
namespace | namespace | ||||
{ | { | ||||
static forcedinline void pushInterpolationSample (float* lastInputSamples, const float newValue) noexcept | 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); | 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. | 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) | 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; | FloatType currentValue = 0, target = 0, step = 0; | ||||
int countdown = 0, stepsToTarget = 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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Reverb) | ||||
}; | }; | ||||
} // namespace juce |
@@ -76,9 +76,6 @@ | |||||
#include <arm_neon.h> | #include <arm_neon.h> | ||||
#endif | #endif | ||||
namespace juce | |||||
{ | |||||
#include "buffers/juce_AudioDataConverters.cpp" | #include "buffers/juce_AudioDataConverters.cpp" | ||||
#include "buffers/juce_FloatVectorOperations.cpp" | #include "buffers/juce_FloatVectorOperations.cpp" | ||||
#include "buffers/juce_AudioChannelSet.cpp" | #include "buffers/juce_AudioChannelSet.cpp" | ||||
@@ -110,5 +107,3 @@ namespace juce | |||||
#include "sources/juce_ReverbAudioSource.cpp" | #include "sources/juce_ReverbAudioSource.cpp" | ||||
#include "sources/juce_ToneGeneratorAudioSource.cpp" | #include "sources/juce_ToneGeneratorAudioSource.cpp" | ||||
#include "synthesisers/juce_Synthesiser.cpp" | #include "synthesisers/juce_Synthesiser.cpp" | ||||
} |
@@ -31,7 +31,7 @@ | |||||
ID: juce_audio_basics | ID: juce_audio_basics | ||||
vendor: juce | vendor: juce | ||||
version: 5.1.1 | |||||
version: 5.1.2 | |||||
name: JUCE audio and MIDI data classes | name: JUCE audio and MIDI data classes | ||||
description: Classes for audio buffer manipulation, midi message handling, synthesis, etc. | description: Classes for audio buffer manipulation, midi message handling, synthesis, etc. | ||||
website: http://www.juce.com/juce | website: http://www.juce.com/juce | ||||
@@ -51,9 +51,7 @@ | |||||
#include <juce_core/juce_core.h> | #include <juce_core/juce_core.h> | ||||
namespace juce | |||||
{ | |||||
//============================================================================== | |||||
#undef Complex // apparently some C libraries actually define these symbols (!) | #undef Complex // apparently some C libraries actually define these symbols (!) | ||||
#undef Factor | #undef Factor | ||||
@@ -95,5 +93,3 @@ namespace juce | |||||
#include "sources/juce_ToneGeneratorAudioSource.h" | #include "sources/juce_ToneGeneratorAudioSource.h" | ||||
#include "synthesisers/juce_Synthesiser.h" | #include "synthesisers/juce_Synthesiser.h" | ||||
#include "audio_play_head/juce_AudioPlayHead.h" | #include "audio_play_head/juce_AudioPlayHead.h" | ||||
} |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
namespace MidiBufferHelpers | namespace MidiBufferHelpers | ||||
{ | { | ||||
inline int getEventTime (const void* const d) noexcept | inline int getEventTime (const void* const d) noexcept | ||||
@@ -34,7 +37,7 @@ namespace MidiBufferHelpers | |||||
inline uint16 getEventTotalSize (const void* const d) noexcept | 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 | 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; | 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. | 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 | @see MidiBuffer | ||||
*/ | */ | ||||
@@ -172,6 +172,9 @@ public: | |||||
/** Creates an Iterator for this MidiBuffer. */ | /** Creates an Iterator for this MidiBuffer. */ | ||||
Iterator (const MidiBuffer&) noexcept; | Iterator (const MidiBuffer&) noexcept; | ||||
/** Creates a copy of an iterator. */ | |||||
Iterator (const Iterator&) noexcept = default; | |||||
/** Destructor. */ | /** Destructor. */ | ||||
~Iterator() noexcept; | ~Iterator() noexcept; | ||||
@@ -214,8 +217,6 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
const MidiBuffer& buffer; | const MidiBuffer& buffer; | ||||
const uint8* data; | const uint8* data; | ||||
JUCE_DECLARE_NON_COPYABLE (Iterator) | |||||
}; | }; | ||||
/** The raw data holding this buffer. | /** The raw data holding this buffer. | ||||
@@ -227,3 +228,5 @@ public: | |||||
private: | private: | ||||
JUCE_LEAK_DETECTOR (MidiBuffer) | JUCE_LEAK_DETECTOR (MidiBuffer) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
namespace MidiFileHelpers | namespace MidiFileHelpers | ||||
{ | { | ||||
static void writeVariableLengthInt (OutputStream& out, unsigned int v) | static void writeVariableLengthInt (OutputStream& out, unsigned int v) | ||||
@@ -443,3 +446,5 @@ bool MidiFile::writeTrack (OutputStream& mainOut, const int trackNum) | |||||
return true; | return true; | ||||
} | } | ||||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
@@ -178,3 +178,5 @@ private: | |||||
JUCE_LEAK_DETECTOR (MidiFile) | JUCE_LEAK_DETECTOR (MidiFile) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
MidiKeyboardState::MidiKeyboardState() | MidiKeyboardState::MidiKeyboardState() | ||||
{ | { | ||||
zerostruct (noteStates); | zerostruct (noteStates); | ||||
@@ -179,3 +182,5 @@ void MidiKeyboardState::removeListener (MidiKeyboardStateListener* const listene | |||||
const ScopedLock sl (lock); | const ScopedLock sl (lock); | ||||
listeners.removeFirstMatchingValue (listener); | listeners.removeFirstMatchingValue (listener); | ||||
} | } | ||||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
class MidiKeyboardState; | class MidiKeyboardState; | ||||
@@ -197,3 +198,5 @@ private: | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
namespace MidiHelpers | namespace MidiHelpers | ||||
{ | { | ||||
inline uint8 initialByte (const int type, const int channel) noexcept | 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; | 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; } | inline uint8* getData() const noexcept { return isHeapAllocated() ? packedData.allocatedData : (uint8*) packedData.asBytes; } | ||||
uint8* allocateSpace (int); | uint8* allocateSpace (int); | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
MidiMessageSequence::MidiEventHolder::MidiEventHolder (const MidiMessage& mm) : message (mm) {} | MidiMessageSequence::MidiEventHolder::MidiEventHolder (const MidiMessage& mm) : message (mm) {} | ||||
MidiMessageSequence::MidiEventHolder::MidiEventHolder (MidiMessage&& mm) : message (static_cast<MidiMessage&&> (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) | JUCE_LEAK_DETECTOR (MidiMessageSequence) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
MidiRPNDetector::MidiRPNDetector() noexcept | MidiRPNDetector::MidiRPNDetector() noexcept | ||||
{ | { | ||||
} | } | ||||
@@ -369,3 +372,5 @@ private: | |||||
static MidiRPNGeneratorTests MidiRPNGeneratorUnitTests; | static MidiRPNGeneratorTests MidiRPNGeneratorUnitTests; | ||||
#endif // JUCE_UNIT_TESTS | #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 | /** Represents a MIDI RPN (registered parameter number) or NRPN (non-registered | ||||
@@ -144,3 +144,5 @@ public: | |||||
bool isNRPN = false, | bool isNRPN = false, | ||||
bool use14BitValue = true); | bool use14BitValue = true); | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
namespace | namespace | ||||
{ | { | ||||
const uint8 noLSBValueReceived = 0xff; | const uint8 noLSBValueReceived = 0xff; | ||||
@@ -2148,3 +2151,5 @@ private: | |||||
static MPEInstrumentTests MPEInstrumentUnitTests; | static MPEInstrumentTests MPEInstrumentUnitTests; | ||||
#endif // JUCE_UNIT_TESTS | #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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPEInstrument) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
MidiBuffer MPEMessages::addZone (MPEZone zone) | MidiBuffer MPEMessages::addZone (MPEZone zone) | ||||
{ | { | ||||
MidiBuffer buffer (MidiRPNGenerator::generate (zone.getFirstNoteChannel(), | MidiBuffer buffer (MidiRPNGenerator::generate (zone.getFirstNoteChannel(), | ||||
@@ -193,3 +196,5 @@ private: | |||||
static MPEMessagesTests MPEMessagesUnitTests; | static MPEMessagesTests MPEMessagesUnitTests; | ||||
#endif // JUCE_UNIT_TESTS | #endif // JUCE_UNIT_TESTS | ||||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
@@ -87,3 +87,5 @@ public: | |||||
*/ | */ | ||||
static const int zoneLayoutMessagesRpnNumber = 6; | static const int zoneLayoutMessagesRpnNumber = 6; | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
namespace | namespace | ||||
{ | { | ||||
uint16 generateNoteID (int midiChannel, int midiNoteNumber) noexcept | uint16 generateNoteID (int midiChannel, int midiNoteNumber) noexcept | ||||
@@ -128,3 +131,5 @@ private: | |||||
static MPENoteTests MPENoteUnitTests; | static MPENoteTests MPENoteUnitTests; | ||||
#endif // JUCE_UNIT_TESTS | #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. */ | /** Returns true if two notes are different notes, determined by their unique ID. */ | ||||
bool operator!= (const MPENote& other) const noexcept; | bool operator!= (const MPENote& other) const noexcept; | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
MPESynthesiser::MPESynthesiser() | MPESynthesiser::MPESynthesiser() | ||||
{ | { | ||||
} | } | ||||
@@ -352,3 +355,5 @@ void MPESynthesiser::renderNextSubBlock (AudioBuffer<double>& buffer, int startS | |||||
voice->renderNextBlock (buffer, startSample, numSamples); | 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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiser) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
MPESynthesiserBase::MPESynthesiserBase() | MPESynthesiserBase::MPESynthesiserBase() | ||||
: instrument (new MPEInstrument), | : instrument (new MPEInstrument), | ||||
sampleRate (0), | sampleRate (0), | ||||
@@ -178,3 +181,5 @@ void MPESynthesiserBase::setMinimumRenderingSubdivisionSize (int numSamples, boo | |||||
minimumSubBlockSize = numSamples; | minimumSubBlockSize = numSamples; | ||||
subBlockSubdivisionIsStrict = shouldBeStrict; | 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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiserBase) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
MPESynthesiserVoice::MPESynthesiserVoice() | MPESynthesiserVoice::MPESynthesiserVoice() | ||||
: currentSampleRate (0), noteStartTime (0) | : currentSampleRate (0), noteStartTime (0) | ||||
{ | { | ||||
@@ -49,3 +52,5 @@ void MPESynthesiserVoice::clearCurrentNote() noexcept | |||||
{ | { | ||||
currentlyPlayingNote = MPENote(); | 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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiserVoice) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
MPEValue::MPEValue() noexcept : normalisedValue (8192) | MPEValue::MPEValue() noexcept : normalisedValue (8192) | ||||
{ | { | ||||
} | } | ||||
@@ -166,3 +169,5 @@ private: | |||||
static MPEValueTests MPEValueUnitTests; | static MPEValueTests MPEValueUnitTests; | ||||
#endif // JUCE_UNIT_TESTS | #endif // JUCE_UNIT_TESTS | ||||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
@@ -88,3 +88,5 @@ private: | |||||
MPEValue (int normalisedValue); | MPEValue (int normalisedValue); | ||||
int normalisedValue; | int normalisedValue; | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
namespace | namespace | ||||
{ | { | ||||
void checkAndLimitZoneParameters (int minValue, | void checkAndLimitZoneParameters (int minValue, | ||||
@@ -312,3 +315,5 @@ private: | |||||
static MPEZoneTests MPEZoneUnitTests; | static MPEZoneTests MPEZoneUnitTests; | ||||
#endif // JUCE_UNIT_TESTS | #endif // JUCE_UNIT_TESTS | ||||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
@@ -138,3 +138,5 @@ private: | |||||
int perNotePitchbendRange; | int perNotePitchbendRange; | ||||
int masterPitchbendRange; | int masterPitchbendRange; | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
MPEZoneLayout::MPEZoneLayout() noexcept | MPEZoneLayout::MPEZoneLayout() noexcept | ||||
{ | { | ||||
} | } | ||||
@@ -378,3 +381,5 @@ static MPEZoneLayoutTests MPEZoneLayoutUnitTests; | |||||
#endif // JUCE_UNIT_TESTS | #endif // JUCE_UNIT_TESTS | ||||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
@@ -157,3 +157,5 @@ private: | |||||
void processZoneLayoutRpnMessage (MidiRPNMessage); | void processZoneLayoutRpnMessage (MidiRPNMessage); | ||||
void processPitchbendRangeRpnMessage (MidiRPNMessage); | void processPitchbendRangeRpnMessage (MidiRPNMessage); | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
#if JUCE_MAC || JUCE_IOS | #if JUCE_MAC || JUCE_IOS | ||||
@@ -304,3 +305,5 @@ private: | |||||
}; | }; | ||||
#endif | #endif | ||||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
@@ -173,3 +173,5 @@ public: | |||||
*/ | */ | ||||
virtual void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) = 0; | virtual void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) = 0; | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* s, | BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* s, | ||||
TimeSliceThread& thread, | TimeSliceThread& thread, | ||||
const bool deleteSourceWhenDeleted, | const bool deleteSourceWhenDeleted, | ||||
@@ -307,3 +310,5 @@ int BufferingAudioSource::useTimeSlice() | |||||
{ | { | ||||
return readNextBufferChunk() ? 1 : 100; | 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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferingAudioSource) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
ChannelRemappingAudioSource::ChannelRemappingAudioSource (AudioSource* const source_, | ChannelRemappingAudioSource::ChannelRemappingAudioSource (AudioSource* const source_, | ||||
const bool deleteSourceWhenDeleted) | const bool deleteSourceWhenDeleted) | ||||
: source (source_, deleteSourceWhenDeleted), | : source (source_, deleteSourceWhenDeleted), | ||||
@@ -180,3 +183,5 @@ void ChannelRemappingAudioSource::restoreFromXml (const XmlElement& e) | |||||
remappedOutputs.add (outs[i].getIntValue()); | 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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChannelRemappingAudioSource) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
IIRFilterAudioSource::IIRFilterAudioSource (AudioSource* const inputSource, | IIRFilterAudioSource::IIRFilterAudioSource (AudioSource* const inputSource, | ||||
const bool deleteInputWhenDeleted) | const bool deleteInputWhenDeleted) | ||||
: input (inputSource, deleteInputWhenDeleted) | : input (inputSource, deleteInputWhenDeleted) | ||||
@@ -73,3 +76,5 @@ void IIRFilterAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& buff | |||||
->processSamples (bufferToFill.buffer->getWritePointer (i, bufferToFill.startSample), | ->processSamples (bufferToFill.buffer->getWritePointer (i, bufferToFill.startSample), | ||||
bufferToFill.numSamples); | 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) | 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) | MemoryAudioSource::MemoryAudioSource (AudioBuffer<float>& bufferToUse, bool copyMemory, bool shouldLoop) | ||||
: isLooping (shouldLoop) | : isLooping (shouldLoop) | ||||
{ | { | ||||
@@ -64,3 +66,5 @@ void MemoryAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferT | |||||
if (pos < m) | if (pos < m) | ||||
dst.clear (bufferToFill.startSample + pos, m - pos); | 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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryAudioSource) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
MixerAudioSource::MixerAudioSource() | MixerAudioSource::MixerAudioSource() | ||||
: currentSampleRate (0.0), bufferSizeExpected (0) | : currentSampleRate (0.0), bufferSizeExpected (0) | ||||
{ | { | ||||
@@ -151,3 +154,5 @@ void MixerAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info) | |||||
info.clearActiveBufferRegion(); | 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) | 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. */ | /** Tells the source whether you'd like it to play in a loop. */ | ||||
virtual void setLooping (bool shouldLoop) { ignoreUnused (shouldLoop); } | virtual void setLooping (bool shouldLoop) { ignoreUnused (shouldLoop); } | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
ResamplingAudioSource::ResamplingAudioSource (AudioSource* const inputSource, | ResamplingAudioSource::ResamplingAudioSource (AudioSource* const inputSource, | ||||
const bool deleteInputWhenDeleted, | const bool deleteInputWhenDeleted, | ||||
const int channels) | const int channels) | ||||
@@ -259,3 +262,5 @@ void ResamplingAudioSource::applyFilter (float* samples, int num, FilterState& f | |||||
*samples++ = (float) out; | *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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResamplingAudioSource) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
ReverbAudioSource::ReverbAudioSource (AudioSource* const inputSource, const bool deleteInputWhenDeleted) | ReverbAudioSource::ReverbAudioSource (AudioSource* const inputSource, const bool deleteInputWhenDeleted) | ||||
: input (inputSource, deleteInputWhenDeleted), | : input (inputSource, deleteInputWhenDeleted), | ||||
bypass (false) | bypass (false) | ||||
@@ -76,3 +79,5 @@ void ReverbAudioSource::setBypassed (bool b) noexcept | |||||
reverb.reset(); | 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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ReverbAudioSource) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
ToneGeneratorAudioSource::ToneGeneratorAudioSource() | ToneGeneratorAudioSource::ToneGeneratorAudioSource() | ||||
: frequency (1000.0), | : frequency (1000.0), | ||||
sampleRate (44100.0), | sampleRate (44100.0), | ||||
@@ -71,3 +74,5 @@ void ToneGeneratorAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& | |||||
info.buffer->setSample (j, info.startSample + i, sample); | 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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToneGeneratorAudioSource) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
SynthesiserSound::SynthesiserSound() {} | SynthesiserSound::SynthesiserSound() {} | ||||
SynthesiserSound::~SynthesiserSound() {} | SynthesiserSound::~SynthesiserSound() {} | ||||
@@ -305,8 +308,8 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice, | |||||
voice->noteOnTime = ++lastNoteOnCounter; | voice->noteOnTime = ++lastNoteOnCounter; | ||||
voice->currentlyPlayingSound = sound; | voice->currentlyPlayingSound = sound; | ||||
voice->setKeyDown (true); | voice->setKeyDown (true); | ||||
voice->sostenutoPedalDown = false; | |||||
voice->sustainPedalDown = sustainPedalsDown[midiChannel]; | |||||
voice->setSostenutoPedalDown (false); | |||||
voice->setSustainPedalDown (sustainPedalsDown[midiChannel]); | |||||
voice->startNote (midiNoteNumber, velocity, sound, | voice->startNote (midiNoteNumber, velocity, sound, | ||||
lastPitchWheelValues [midiChannel - 1]); | lastPitchWheelValues [midiChannel - 1]); | ||||
@@ -340,11 +343,11 @@ void Synthesiser::noteOff (const int midiChannel, | |||||
if (sound->appliesToNote (midiNoteNumber) | if (sound->appliesToNote (midiNoteNumber) | ||||
&& sound->appliesToChannel (midiChannel)) | && sound->appliesToChannel (midiChannel)) | ||||
{ | { | ||||
jassert (! voice->keyIsDown || voice->sustainPedalDown == sustainPedalsDown [midiChannel]); | |||||
jassert (! voice->keyIsDown || voice->isSustainPedalDown() == sustainPedalsDown [midiChannel]); | |||||
voice->setKeyDown (false); | voice->setKeyDown (false); | ||||
if (! (voice->sustainPedalDown || voice->sostenutoPedalDown)) | |||||
if (! (voice->isSustainPedalDown() || voice->isSostenutoPedalDown())) | |||||
stopVoice (voice, velocity, allowTailOff); | stopVoice (voice, velocity, allowTailOff); | ||||
} | } | ||||
} | } | ||||
@@ -421,7 +424,7 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown) | |||||
for (auto* voice : voices) | for (auto* voice : voices) | ||||
if (voice->isPlayingChannel (midiChannel) && voice->isKeyDown()) | if (voice->isPlayingChannel (midiChannel) && voice->isKeyDown()) | ||||
voice->sustainPedalDown = true; | |||||
voice->setSustainPedalDown (true); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -429,7 +432,7 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown) | |||||
{ | { | ||||
if (voice->isPlayingChannel (midiChannel)) | if (voice->isPlayingChannel (midiChannel)) | ||||
{ | { | ||||
voice->sustainPedalDown = false; | |||||
voice->setSustainPedalDown (false); | |||||
if (! (voice->isKeyDown() || voice->isSostenutoPedalDown())) | if (! (voice->isKeyDown() || voice->isSostenutoPedalDown())) | ||||
stopVoice (voice, 1.0f, true); | stopVoice (voice, 1.0f, true); | ||||
@@ -450,8 +453,8 @@ void Synthesiser::handleSostenutoPedal (int midiChannel, bool isDown) | |||||
if (voice->isPlayingChannel (midiChannel)) | if (voice->isPlayingChannel (midiChannel)) | ||||
{ | { | ||||
if (isDown) | if (isDown) | ||||
voice->sostenutoPedalDown = true; | |||||
else if (voice->sostenutoPedalDown) | |||||
voice->setSostenutoPedalDown (true); | |||||
else if (voice->isSostenutoPedalDown()) | |||||
stopVoice (voice, 1.0f, true); | stopVoice (voice, 1.0f, true); | ||||
} | } | ||||
} | } | ||||
@@ -567,3 +570,5 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay, | |||||
return low; | 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. */ | /** Returns true if the sustain pedal is currently active for this voice. */ | ||||
bool isSustainPedalDown() const noexcept { return sustainPedalDown; } | 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. */ | /** Returns true if the sostenuto pedal is currently active for this voice. */ | ||||
bool isSostenutoPedalDown() const noexcept { return sostenutoPedalDown; } | 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 **/ | /** Returns true if a voice is sounding in its release phase **/ | ||||
bool isPlayingButReleased() const noexcept | bool isPlayingButReleased() const noexcept | ||||
{ | { | ||||
@@ -514,15 +520,15 @@ public: | |||||
with timestamps outside the specified region will be ignored. | with timestamps outside the specified region will be ignored. | ||||
*/ | */ | ||||
inline void renderNextBlock (AudioBuffer<float>& outputAudio, | 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); } | { processNextBlock (outputAudio, inputMidi, startSample, numSamples); } | ||||
inline void renderNextBlock (AudioBuffer<double>& outputAudio, | 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); } | { processNextBlock (outputAudio, inputMidi, startSample, numSamples); } | ||||
/** Returns the current target sample rate at which rendering is being done. | /** 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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
AudioDeviceManager::AudioDeviceSetup::AudioDeviceSetup() | AudioDeviceManager::AudioDeviceSetup::AudioDeviceSetup() | ||||
: sampleRate (0), | : sampleRate (0), | ||||
bufferSize (0), | bufferSize (0), | ||||
@@ -929,7 +932,7 @@ void AudioDeviceManager::LevelMeter::updateLevel (const float* const* channelDat | |||||
for (int i = 0; i < numChannels; ++i) | for (int i = 0; i < numChannels; ++i) | ||||
s += std::abs (channelData[i][j]); | s += std::abs (channelData[i][j]); | ||||
s /= numChannels; | |||||
s /= (float) numChannels; | |||||
const double decayFactor = 0.99992; | 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::enableInputLevelMeasurement (bool enable) noexcept { inputLevelMeter.setEnabled (enable); } | ||||
void AudioDeviceManager::enableOutputLevelMeasurement (bool enable) noexcept { outputLevelMeter.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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioDeviceManager) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
AudioIODevice::AudioIODevice (const String& deviceName, const String& deviceTypeName) | AudioIODevice::AudioIODevice (const String& deviceName, const String& deviceTypeName) | ||||
: name (deviceName), typeName (deviceTypeName) | : name (deviceName), typeName (deviceTypeName) | ||||
{ | { | ||||
@@ -30,6 +33,7 @@ AudioIODevice::~AudioIODevice() {} | |||||
void AudioIODeviceCallback::audioDeviceError (const String&) {} | void AudioIODeviceCallback::audioDeviceError (const String&) {} | ||||
bool AudioIODevice::setAudioPreprocessingEnabled (bool) { return false; } | bool AudioIODevice::setAudioPreprocessingEnabled (bool) { return false; } | ||||
bool AudioIODevice::hasControlPanel() const { return false; } | bool AudioIODevice::hasControlPanel() const { return false; } | ||||
int AudioIODevice::getXRunCount() const noexcept { return -1; } | |||||
bool AudioIODevice::showControlPanel() | bool AudioIODevice::showControlPanel() | ||||
{ | { | ||||
@@ -37,3 +41,5 @@ bool AudioIODevice::showControlPanel() | |||||
// their hasControlPanel() method. | // their hasControlPanel() method. | ||||
return false; | return false; | ||||
} | } | ||||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
class AudioIODevice; | class AudioIODevice; | ||||
@@ -292,6 +293,19 @@ public: | |||||
*/ | */ | ||||
virtual bool setAudioPreprocessingEnabled (bool shouldBeEnabled); | 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: | protected: | ||||
/** Creates a device, setting its name and type member variables. */ | /** Creates a device, setting its name and type member variables. */ | ||||
@@ -301,3 +315,5 @@ protected: | |||||
/** @internal */ | /** @internal */ | ||||
String name, typeName; | String name, typeName; | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
AudioIODeviceType::AudioIODeviceType (const String& name) | AudioIODeviceType::AudioIODeviceType (const String& name) | ||||
: typeName (name) | : typeName (name) | ||||
{ | { | ||||
@@ -74,3 +77,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android() | |||||
#if ! (JUCE_ANDROID && JUCE_USE_ANDROID_OPENSLES) | #if ! (JUCE_ANDROID && JUCE_USE_ANDROID_OPENSLES) | ||||
AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() { return nullptr; } | AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() { return nullptr; } | ||||
#endif | #endif | ||||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
@@ -174,3 +174,5 @@ private: | |||||
JUCE_DECLARE_NON_COPYABLE (AudioIODeviceType) | 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. | SystemAudioVolume(); // Don't instantiate this class, just call its static fns. | ||||
JUCE_DECLARE_NON_COPYABLE (SystemAudioVolume) | JUCE_DECLARE_NON_COPYABLE (SystemAudioVolume) | ||||
}; | }; | ||||
} // namespace juce |
@@ -155,9 +155,6 @@ | |||||
#endif | #endif | ||||
namespace juce | |||||
{ | |||||
#include "audio_io/juce_AudioDeviceManager.cpp" | #include "audio_io/juce_AudioDeviceManager.cpp" | ||||
#include "audio_io/juce_AudioIODevice.cpp" | #include "audio_io/juce_AudioIODevice.cpp" | ||||
#include "audio_io/juce_AudioIODeviceType.cpp" | #include "audio_io/juce_AudioIODeviceType.cpp" | ||||
@@ -214,14 +211,15 @@ namespace juce | |||||
#if JUCE_USE_ANDROID_OPENSLES | #if JUCE_USE_ANDROID_OPENSLES | ||||
#include "native/juce_android_OpenSL.cpp" | #include "native/juce_android_OpenSL.cpp" | ||||
#endif | #endif | ||||
#endif | #endif | ||||
#if ! JUCE_SYSTEMAUDIOVOL_IMPLEMENTED | #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 | ID: juce_audio_devices | ||||
vendor: juce | vendor: juce | ||||
version: 5.1.1 | |||||
version: 5.1.2 | |||||
name: JUCE audio and MIDI I/O device classes | name: JUCE audio and MIDI I/O device classes | ||||
description: Classes to play and record from audio and MIDI I/O devices | description: Classes to play and record from audio and MIDI I/O devices | ||||
website: http://www.juce.com/juce | website: http://www.juce.com/juce | ||||
@@ -140,9 +140,6 @@ | |||||
//============================================================================== | //============================================================================== | ||||
namespace juce | |||||
{ | |||||
#include "midi_io/juce_MidiInput.h" | #include "midi_io/juce_MidiInput.h" | ||||
#include "midi_io/juce_MidiMessageCollector.h" | #include "midi_io/juce_MidiMessageCollector.h" | ||||
#include "midi_io/juce_MidiOutput.h" | #include "midi_io/juce_MidiOutput.h" | ||||
@@ -156,5 +153,3 @@ namespace juce | |||||
#if JUCE_IOS | #if JUCE_IOS | ||||
#include "native/juce_ios_Audio.h" | #include "native/juce_ios_Audio.h" | ||||
#endif | #endif | ||||
} |
@@ -20,7 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
class MidiInput; | class MidiInput; | ||||
@@ -171,3 +172,5 @@ private: | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInput) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInput) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
MidiMessageCollector::MidiMessageCollector() | MidiMessageCollector::MidiMessageCollector() | ||||
{ | { | ||||
} | } | ||||
@@ -151,3 +154,5 @@ void MidiMessageCollector::handleIncomingMidiMessage (MidiInput*, const MidiMess | |||||
{ | { | ||||
addMessageToQueue (message); | 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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiMessageCollector) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
struct MidiOutput::PendingMessage | struct MidiOutput::PendingMessage | ||||
{ | { | ||||
PendingMessage (const void* const data, const int len, const double timeStamp) | PendingMessage (const void* const data, const int len, const double timeStamp) | ||||
@@ -169,3 +172,5 @@ void MidiOutput::run() | |||||
clearAllPendingMessages(); | clearAllPendingMessages(); | ||||
} | } | ||||
} // namespace juce |
@@ -20,8 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
@@ -139,3 +139,5 @@ private: | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiOutput) | 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: | 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; | MemoryBlock pendingData; | ||||
double pendingDataTime; | |||||
int pendingBytes; | |||||
uint8 runningStatus; | |||||
double pendingDataTime = 0; | |||||
int pendingBytes = 0; | |||||
uint8 runningStatus = 0; | |||||
JUCE_DECLARE_NON_COPYABLE (MidiDataConcatenator) | JUCE_DECLARE_NON_COPYABLE (MidiDataConcatenator) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,7 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
//============================================================================== | |||||
namespace juce | |||||
{ | |||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ | #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ | ||||
STATICMETHOD (getMinBufferSize, "getMinBufferSize", "(III)I") \ | STATICMETHOD (getMinBufferSize, "getMinBufferSize", "(III)I") \ | ||||
STATICMETHOD (getNativeOutputSampleRate, "getNativeOutputSampleRate", "(I)I") \ | STATICMETHOD (getNativeOutputSampleRate, "getNativeOutputSampleRate", "(I)I") \ | ||||
@@ -48,6 +50,13 @@ DECLARE_JNI_CLASS (AudioTrack, "android/media/AudioTrack"); | |||||
DECLARE_JNI_CLASS (AudioRecord, "android/media/AudioRecord"); | DECLARE_JNI_CLASS (AudioRecord, "android/media/AudioRecord"); | ||||
#undef JNI_CLASS_MEMBERS | #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 | enum | ||||
{ | { | ||||
@@ -193,6 +202,9 @@ public: | |||||
STREAM_MUSIC, sampleRate, CHANNEL_OUT_STEREO, ENCODING_PCM_16BIT, | STREAM_MUSIC, sampleRate, CHANNEL_OUT_STEREO, ENCODING_PCM_16BIT, | ||||
(jint) (minBufferSizeOut * numDeviceOutputChannels * static_cast<int> (sizeof (int16))), MODE_STREAM)); | (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); | int outputDeviceState = env->CallIntMethod (outputDevice, AudioTrack.getState); | ||||
if (outputDeviceState > 0) | if (outputDeviceState > 0) | ||||
{ | { | ||||
@@ -279,6 +291,14 @@ public: | |||||
String getLastError() override { return lastError; } | String getLastError() override { return lastError; } | ||||
bool isPlaying() override { return isRunning && callback != 0; } | 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 | void start (AudioIODeviceCallback* newCallback) override | ||||
{ | { | ||||
if (isRunning && callback != newCallback) | if (isRunning && callback != newCallback) | ||||
@@ -404,6 +424,7 @@ private: | |||||
BigInteger activeOutputChans, activeInputChans; | BigInteger activeOutputChans, activeInputChans; | ||||
GlobalRef outputDevice, inputDevice; | GlobalRef outputDevice, inputDevice; | ||||
AudioSampleBuffer inputChannelBuffer, outputChannelBuffer; | AudioSampleBuffer inputChannelBuffer, outputChannelBuffer; | ||||
jmethodID getUnderrunCount = 0; | |||||
void closeDevices() | void closeDevices() | ||||
{ | { | ||||
@@ -472,3 +493,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android() | |||||
return new AndroidAudioIODeviceType(); | return new AndroidAudioIODeviceType(); | ||||
} | } | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ | #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ | ||||
METHOD (getJuceAndroidMidiInputDevices, "getJuceAndroidMidiInputDevices", "()[Ljava/lang/String;") \ | METHOD (getJuceAndroidMidiInputDevices, "getJuceAndroidMidiInputDevices", "()[Ljava/lang/String;") \ | ||||
METHOD (getJuceAndroidMidiOutputDevices, "getJuceAndroidMidiOutputDevices", "()[Ljava/lang/String;") \ | METHOD (getJuceAndroidMidiOutputDevices, "getJuceAndroidMidiOutputDevices", "()[Ljava/lang/String;") \ | ||||
@@ -89,9 +92,9 @@ public: | |||||
jbyte* data = getEnv()->GetByteArrayElements (byteArray, nullptr); | jbyte* data = getEnv()->GetByteArrayElements (byteArray, nullptr); | ||||
HeapBlock<uint8> buffer (static_cast<size_t> (len)); | 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, | len, static_cast<double> (timestamp) * 1.0e-9, | ||||
juceMidiInput, *callback); | juceMidiInput, *callback); | ||||
@@ -357,3 +360,5 @@ MidiInput::~MidiInput() | |||||
{ | { | ||||
delete reinterpret_cast<AndroidMidiInput*> (internal); | 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 | #ifndef SL_ANDROID_DATAFORMAT_PCM_EX | ||||
@@ -289,12 +285,39 @@ public: | |||||
nextBlock (0), numBlocksOut (0) | nextBlock (0), numBlocksOut (0) | ||||
{} | {} | ||||
~OpenSLQueueRunner() | |||||
{ | |||||
if (config != nullptr && javaProxy != nullptr) | |||||
{ | |||||
javaProxy.clear(); | |||||
(*config)->ReleaseJavaProxy (config, SL_ANDROID_JAVA_PROXY_ROUTING); | |||||
} | |||||
} | |||||
bool init() | bool init() | ||||
{ | { | ||||
runner = crtp().createPlayerOrRecorder(); | runner = crtp().createPlayerOrRecorder(); | ||||
if (runner == nullptr) | if (runner == nullptr) | ||||
return false; | 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); | queue = SlRef<SLAndroidSimpleBufferQueueItf_>::cast (runner); | ||||
if (queue == nullptr) | if (queue == nullptr) | ||||
return false; | return false; | ||||
@@ -308,7 +331,7 @@ public: | |||||
nextBlock.set (0); | nextBlock.set (0); | ||||
numBlocksOut.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(); | scratchBuffer.clear(); | ||||
(*queue)->Clear (queue); | (*queue)->Clear (queue); | ||||
} | } | ||||
@@ -321,7 +344,7 @@ public: | |||||
bool isBufferAvailable() const { return (numBlocksOut.get() < owner.numBuffers); } | bool isBufferAvailable() const { return (numBlocksOut.get() < owner.numBuffers); } | ||||
T* getNextBuffer() { nextBlock.set((nextBlock.get() + 1) % owner.numBuffers); return getCurrentBuffer(); } | 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); } | size_t getBufferSizeInSamples() const { return static_cast<size_t> (owner.bufferSize * numChannels); } | ||||
void finished (SLAndroidSimpleBufferQueueItf) | void finished (SLAndroidSimpleBufferQueueItf) | ||||
@@ -345,6 +368,8 @@ public: | |||||
SlRef<RunnerObjectType> runner; | SlRef<RunnerObjectType> runner; | ||||
SlRef<SLAndroidSimpleBufferQueueItf_> queue; | SlRef<SLAndroidSimpleBufferQueueItf_> queue; | ||||
SlRef<SLAndroidConfigurationItf_> config; | |||||
GlobalRef javaProxy; | |||||
int numChannels; | int numChannels; | ||||
@@ -377,12 +402,12 @@ public: | |||||
SLDataSource source = {&queueLocator, &dataFormat}; | SLDataSource source = {&queueLocator, &dataFormat}; | ||||
SLDataSink sink = {&outputMix, nullptr}; | 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; | 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 (status != SL_RESULT_SUCCESS || obj == nullptr || (*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS) | ||||
{ | { | ||||
if (obj != nullptr) | if (obj != nullptr) | ||||
@@ -435,15 +460,12 @@ public: | |||||
SlRef<SLRecordItf_> recorder = SlRef<SLRecordItf_>::cast (SlObjectRef (obj)); | SlRef<SLRecordItf_> recorder = SlRef<SLRecordItf_>::cast (SlObjectRef (obj)); | ||||
// may return nullptr on some platforms - that's ok | |||||
config = SlRef<SLAndroidConfigurationItf_>::cast (recorder); | |||||
return recorder; | return recorder; | ||||
} | } | ||||
bool setAudioPreprocessingEnabled (bool shouldEnable) | bool setAudioPreprocessingEnabled (bool shouldEnable) | ||||
{ | { | ||||
if (config != nullptr) | |||||
if (Base::config != nullptr) | |||||
{ | { | ||||
const bool supportsUnprocessed = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 25); | const bool supportsUnprocessed = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 25); | ||||
const SLuint32 recordingPresetValue | const SLuint32 recordingPresetValue | ||||
@@ -451,8 +473,8 @@ public: | |||||
: (supportsUnprocessed ? SL_ANDROID_RECORDING_PRESET_UNPROCESSED | : (supportsUnprocessed ? SL_ANDROID_RECORDING_PRESET_UNPROCESSED | ||||
: SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION)); | : 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); | 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); } | 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 void stop() { running = false; } | ||||
virtual bool setAudioPreprocessingEnabled (bool shouldEnable) = 0; | virtual bool setAudioPreprocessingEnabled (bool shouldEnable) = 0; | ||||
virtual bool supportsFloatingPoint() const noexcept = 0; | virtual bool supportsFloatingPoint() const noexcept = 0; | ||||
virtual int getXRunCount() const noexcept = 0; | |||||
void setCallback (AudioIODeviceCallback* callbackToUse) | void setCallback (AudioIODeviceCallback* callbackToUse) | ||||
{ | { | ||||
@@ -614,6 +635,9 @@ public: | |||||
player = nullptr; | player = nullptr; | ||||
return; | 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; | 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); } | bool supportsFloatingPoint() const noexcept override { return (BufferHelpers<T>::isFloatingPoint != 0); } | ||||
void doSomeWorkOnAudioThread() | void doSomeWorkOnAudioThread() | ||||
@@ -726,6 +758,7 @@ public: | |||||
ScopedPointer<OpenSLQueueRunnerPlayer<T> > player; | ScopedPointer<OpenSLQueueRunnerPlayer<T> > player; | ||||
ScopedPointer<OpenSLQueueRunnerRecorder<T> > recorder; | ScopedPointer<OpenSLQueueRunnerRecorder<T> > recorder; | ||||
Atomic<int> guard; | Atomic<int> guard; | ||||
jmethodID getUnderrunCount = 0; | |||||
}; | }; | ||||
//============================================================================== | //============================================================================== | ||||
@@ -890,6 +923,7 @@ public: | |||||
BigInteger getActiveInputChannels() const override { return activeInputChans; } | BigInteger getActiveInputChannels() const override { return activeInputChans; } | ||||
String getLastError() override { return lastError; } | String getLastError() override { return lastError; } | ||||
bool isPlaying() override { return callback != nullptr; } | bool isPlaying() override { return callback != nullptr; } | ||||
int getXRunCount() const noexcept override { return (session != nullptr ? session->getXRunCount() : -1); } | |||||
int getDefaultBufferSize() override | int getDefaultBufferSize() override | ||||
{ | { | ||||
@@ -1203,11 +1237,11 @@ public: | |||||
pthread_t startThread (void* (*entry) (void*), void* userPtr) | 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) | 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))); | (*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; | return threadID; | ||||
} | } | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
class iOSAudioIODevice; | class iOSAudioIODevice; | ||||
static const char* const iOSAudioDeviceName = "iOS Audio"; | static const char* const iOSAudioDeviceName = "iOS Audio"; | ||||
@@ -183,6 +186,10 @@ bool getNotificationValueForKey (NSNotification* notification, NSString* key, NS | |||||
@end | @end | ||||
//============================================================================== | //============================================================================== | ||||
#if JUCE_MODULE_AVAILABLE_juce_graphics | |||||
#include <juce_graphics/native/juce_mac_CoreGraphicsHelpers.h> | |||||
#endif | |||||
namespace juce { | namespace juce { | ||||
#ifndef JUCE_IOS_AUDIO_LOGGING | #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); } | #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, | struct iOSAudioIODevice::Pimpl : public AudioPlayHead, | ||||
public AsyncUpdater | public AsyncUpdater | ||||
@@ -310,6 +313,9 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead, | |||||
{ | { | ||||
close(); | close(); | ||||
firstHostTime = true; | |||||
lastNumFrames = 0; | |||||
xrun = 0; | |||||
lastError.clear(); | lastError.clear(); | ||||
preferredBufferSize = bufferSize <= 0 ? defaultBufferSize : bufferSize; | preferredBufferSize = bufferSize <= 0 ? defaultBufferSize : bufferSize; | ||||
@@ -711,6 +717,8 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead, | |||||
{ | { | ||||
OSStatus err = noErr; | OSStatus err = noErr; | ||||
recordXruns (time, numFrames); | |||||
if (audioInputIsAvailable && numInputChannels > 0) | if (audioInputIsAvailable && numInputChannels > 0) | ||||
err = AudioUnitRender (audioUnit, flags, time, 1, numFrames, data); | err = AudioUnitRender (audioUnit, flags, time, 1, numFrames, data); | ||||
@@ -796,6 +804,26 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead, | |||||
updateSampleRateAndAudioInput(); | 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, | static OSStatus processStatic (void* client, AudioUnitRenderActionFlags* flags, const AudioTimeStamp* time, | ||||
UInt32 /*busNumber*/, UInt32 numFrames, AudioBufferList* data) | UInt32 /*busNumber*/, UInt32 numFrames, AudioBufferList* data) | ||||
@@ -1060,6 +1088,11 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead, | |||||
float* outputChannels[3]; | float* outputChannels[3]; | ||||
bool monoInputChannelNumber, monoOutputChannelNumber; | bool monoInputChannelNumber, monoOutputChannelNumber; | ||||
bool firstHostTime; | |||||
Float64 lastSampleTime; | |||||
unsigned int lastNumFrames; | |||||
int xrun; | |||||
JUCE_DECLARE_NON_COPYABLE (Pimpl) | 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::getOutputLatencyInSamples() { return roundToInt (pimpl->sampleRate * [AVAudioSession sharedInstance].outputLatency); } | ||||
int iOSAudioIODevice::getInputLatencyInSamples() { return roundToInt (pimpl->sampleRate * [AVAudioSession sharedInstance].inputLatency); } | 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; } | void iOSAudioIODevice::setMidiMessageCollector (MidiMessageCollector* collector) { pimpl->messageCollector = collector; } | ||||
AudioPlayHead* iOSAudioIODevice::getAudioPlayHead() const { return pimpl; } | AudioPlayHead* iOSAudioIODevice::getAudioPlayHead() const { return pimpl; } | ||||
@@ -1168,3 +1202,5 @@ void AudioSessionHolder::handleRouteChange (const char* reason) | |||||
} | } | ||||
#undef JUCE_NSERROR_CHECK | #undef JUCE_NSERROR_CHECK | ||||
} // namespace juce |
@@ -20,7 +20,8 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
#pragma once | |||||
namespace juce | |||||
{ | |||||
struct iOSAudioIODeviceType; | struct iOSAudioIODeviceType; | ||||
@@ -61,6 +62,8 @@ public: | |||||
int getOutputLatencyInSamples() override; | int getOutputLatencyInSamples() override; | ||||
int getInputLatencyInSamples() override; | int getInputLatencyInSamples() override; | ||||
int getXRunCount() const noexcept override; | |||||
//============================================================================== | //============================================================================== | ||||
void setMidiMessageCollector (MidiMessageCollector*); | void setMidiMessageCollector (MidiMessageCollector*); | ||||
AudioPlayHead* getAudioPlayHead() const; | AudioPlayHead* getAudioPlayHead() const; | ||||
@@ -86,3 +89,5 @@ private: | |||||
JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice) | JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice) | ||||
}; | }; | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
namespace | namespace | ||||
{ | { | ||||
@@ -75,7 +78,7 @@ static void getDeviceNumChannels (snd_pcm_t* handle, unsigned int* minChans, uns | |||||
JUCE_ALSA_LOG ("getDeviceNumChannels: " << (int) *minChans << " " << (int) *maxChans); | JUCE_ALSA_LOG ("getDeviceNumChannels: " << (int) *minChans << " " << (int) *maxChans); | ||||
// some virtual devices (dmix for example) report 10000 channels , we have to clamp these values | // 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); | *minChans = jmin (*minChans, *maxChans); | ||||
} | } | ||||
else | else | ||||
@@ -155,7 +158,7 @@ public: | |||||
isInput (forInput), | isInput (forInput), | ||||
isInterleaved (true) | 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(), | int err = snd_pcm_open (&handle, deviceID.toUTF8(), | ||||
forInput ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, | forInput ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, | ||||
@@ -241,7 +244,8 @@ public: | |||||
(type & isFloatBit) != 0, | (type & isFloatBit) != 0, | ||||
(type & isLittleEndianBit) != 0, | (type & isLittleEndianBit) != 0, | ||||
(type & onlyUseLower24Bits) != 0, | (type & onlyUseLower24Bits) != 0, | ||||
numChannels); | |||||
numChannels, | |||||
isInterleaved); | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
@@ -329,8 +333,14 @@ public: | |||||
numDone = snd_pcm_writen (handle, (void**) data, (snd_pcm_uframes_t) numSamples); | 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) | if (numDone < numSamples) | ||||
JUCE_ALSA_LOG ("Did not write all samples: numDone: " << numDone << ", numSamples: " << 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); | 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) | if (num < numSamples) | ||||
JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << 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); | 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) | if (num < numSamples) | ||||
JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples); | JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples); | ||||
@@ -380,6 +403,7 @@ public: | |||||
snd_pcm_t* handle; | snd_pcm_t* handle; | ||||
String error; | String error; | ||||
int bitDepth, numChannelsRunning, latency; | int bitDepth, numChannelsRunning, latency; | ||||
int underrunCount = 0, overrunCount = 0; | |||||
private: | private: | ||||
//============================================================================== | //============================================================================== | ||||
@@ -393,44 +417,55 @@ private: | |||||
template <class SampleType> | template <class SampleType> | ||||
struct ConverterHelper | 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) | if (forInput) | ||||
{ | { | ||||
typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> DestType; | typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> DestType; | ||||
if (isLittleEndian) | 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; | typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> SourceType; | ||||
if (isLittleEndian) | 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, | static AudioData::Converter* createConverter (bool forInput, int bitDepth, | ||||
bool isFloat, bool isLittleEndian, bool useOnlyLower24Bits, | 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); | jassert (bitDepth == 32); | ||||
if (useOnlyLower24Bits) | 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; | 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; | String error; | ||||
double sampleRate; | double sampleRate; | ||||
@@ -893,6 +941,8 @@ public: | |||||
int getOutputLatencyInSamples() override { return internal.outputLatency; } | int getOutputLatencyInSamples() override { return internal.outputLatency; } | ||||
int getInputLatencyInSamples() override { return internal.inputLatency; } | int getInputLatencyInSamples() override { return internal.inputLatency; } | ||||
int getXRunCount() const noexcept override { return internal.getXRunCount(); } | |||||
void start (AudioIODeviceCallback* callback) override | void start (AudioIODeviceCallback* callback) override | ||||
{ | { | ||||
if (! isOpen_) | if (! isOpen_) | ||||
@@ -1037,7 +1087,7 @@ private: | |||||
if ((isInput || isOutput) && rates.size() > 0) | if ((isInput || isOutput) && rates.size() > 0) | ||||
{ | { | ||||
JUCE_ALSA_LOG ("testDevice: '" << id.toUTF8().getAddress() << "' -> isInput: " | JUCE_ALSA_LOG ("testDevice: '" << id.toUTF8().getAddress() << "' -> isInput: " | ||||
<< isInput << ", isOutput: " << isOutput); | |||||
<< (int) isInput << ", isOutput: " << (int) isOutput); | |||||
if (isInput) | if (isInput) | ||||
{ | { | ||||
@@ -1128,7 +1178,8 @@ private: | |||||
} | } | ||||
JUCE_ALSA_LOG ("Soundcard ID: " << id << ", name: '" << name | JUCE_ALSA_LOG ("Soundcard ID: " << id << ", name: '" << name | ||||
<< ", isInput:" << isInput << ", isOutput:" << isOutput << "\n"); | |||||
<< ", isInput:" << (int) isInput | |||||
<< ", isOutput:" << (int) isOutput << "\n"); | |||||
if (isInput) | if (isInput) | ||||
{ | { | ||||
@@ -1259,3 +1310,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA() | |||||
{ | { | ||||
return createAudioIODeviceType_ALSA_PCMDevices(); | return createAudioIODeviceType_ALSA_PCMDevices(); | ||||
} | } | ||||
} // namespace juce |
@@ -20,7 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
//============================================================================== | |||||
namespace juce | |||||
{ | |||||
static void* juce_libjackHandle = nullptr; | static void* juce_libjackHandle = nullptr; | ||||
static void* juce_loadJackFunction (const char* const name) | 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 (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, (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_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 | #if JUCE_DEBUG | ||||
#define JACK_LOGGING_ENABLED 1 | #define JACK_LOGGING_ENABLED 1 | ||||
@@ -256,9 +259,11 @@ public: | |||||
lastError.clear(); | lastError.clear(); | ||||
close(); | close(); | ||||
xruns = 0; | |||||
juce::jack_set_process_callback (client, processCallback, this); | juce::jack_set_process_callback (client, processCallback, this); | ||||
juce::jack_set_port_connect_callback (client, portConnectCallback, this); | juce::jack_set_port_connect_callback (client, portConnectCallback, this); | ||||
juce::jack_on_shutdown (client, shutdownCallback, this); | juce::jack_on_shutdown (client, shutdownCallback, this); | ||||
juce::jack_set_xrun_callback (client, xrunCallback, this); | |||||
juce::jack_activate (client); | juce::jack_activate (client); | ||||
deviceIsOpen = true; | deviceIsOpen = true; | ||||
@@ -300,6 +305,8 @@ public: | |||||
if (client != nullptr) | if (client != nullptr) | ||||
{ | { | ||||
juce::jack_deactivate (client); | juce::jack_deactivate (client); | ||||
juce::jack_set_xrun_callback (client, xrunCallback, nullptr); | |||||
juce::jack_set_process_callback (client, processCallback, nullptr); | juce::jack_set_process_callback (client, processCallback, nullptr); | ||||
juce::jack_set_port_connect_callback (client, portConnectCallback, nullptr); | juce::jack_set_port_connect_callback (client, portConnectCallback, nullptr); | ||||
juce::jack_on_shutdown (client, shutdownCallback, nullptr); | juce::jack_on_shutdown (client, shutdownCallback, nullptr); | ||||
@@ -336,6 +343,7 @@ public: | |||||
bool isPlaying() override { return callback != nullptr; } | bool isPlaying() override { return callback != nullptr; } | ||||
int getCurrentBitDepth() override { return 32; } | int getCurrentBitDepth() override { return 32; } | ||||
String getLastError() override { return lastError; } | String getLastError() override { return lastError; } | ||||
int getXRunCount() const noexcept override { return xruns; } | |||||
BigInteger getActiveOutputChannels() const override { return activeOutputChannels; } | BigInteger getActiveOutputChannels() const override { return activeOutputChannels; } | ||||
BigInteger getActiveInputChannels() const override { return activeInputChannels; } | BigInteger getActiveInputChannels() const override { return activeInputChannels; } | ||||
@@ -406,6 +414,14 @@ private: | |||||
return 0; | return 0; | ||||
} | } | ||||
static int xrunCallback (void* callbackArgument) | |||||
{ | |||||
if (callbackArgument != nullptr) | |||||
((JackAudioIODevice*) callbackArgument)->xruns++; | |||||
return 0; | |||||
} | |||||
void updateActivePorts() | void updateActivePorts() | ||||
{ | { | ||||
BigInteger newOutputChannels, newInputChannels; | BigInteger newOutputChannels, newInputChannels; | ||||
@@ -475,6 +491,8 @@ private: | |||||
int totalNumberOfOutputChannels; | int totalNumberOfOutputChannels; | ||||
Array<void*> inputPorts, outputPorts; | Array<void*> inputPorts, outputPorts; | ||||
BigInteger activeInputChannels, activeOutputChannels; | BigInteger activeInputChannels, activeOutputChannels; | ||||
int xruns; | |||||
}; | }; | ||||
@@ -602,3 +620,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK() | |||||
{ | { | ||||
return new JackAudioIODeviceType(); | return new JackAudioIODeviceType(); | ||||
} | } | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
#if JUCE_ALSA | #if JUCE_ALSA | ||||
// You can define these strings in your app if you want to override the default names: | // You can define these strings in your app if you want to override the default names: | ||||
@@ -137,7 +140,7 @@ public: | |||||
numBytes -= numSent; | numBytes -= numSent; | ||||
data += 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_subs (&event); | ||||
snd_seq_ev_set_direct (&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; } | MidiInput* MidiInput::createNewDevice (const String&, MidiInputCallback*) { return nullptr; } | ||||
#endif | #endif | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
#if JUCE_COREAUDIO_LOGGING_ENABLED | #if JUCE_COREAUDIO_LOGGING_ENABLED | ||||
#define JUCE_COREAUDIOLOG(a) { String camsg ("CoreAudio: "); camsg << a; Logger::writeToLog (camsg); } | #define JUCE_COREAUDIOLOG(a) { String camsg ("CoreAudio: "); camsg << a; Logger::writeToLog (camsg); } | ||||
#else | #else | ||||
@@ -228,7 +231,7 @@ public: | |||||
for (int i = 0; i < numStreams; ++i) | 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) | for (unsigned int j = 0; j < b.mNumberChannels; ++j) | ||||
{ | { | ||||
@@ -578,6 +581,8 @@ public: | |||||
stop (false); | stop (false); | ||||
updateDetailsFromDevice(); | |||||
activeInputChans = inputChannels; | activeInputChans = inputChannels; | ||||
activeInputChans.setRange (inChanNames.size(), | activeInputChans.setRange (inChanNames.size(), | ||||
activeInputChans.getHighestBit() + 1 - 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, | numInputChans, | ||||
tempOutputBuffers, | tempOutputBuffers, | ||||
numOutputChans, | numOutputChans, | ||||
@@ -791,6 +796,7 @@ public: | |||||
int inputLatency = 0; | int inputLatency = 0; | ||||
int outputLatency = 0; | int outputLatency = 0; | ||||
int bitDepth = 32; | int bitDepth = 32; | ||||
int xruns = 0; | |||||
BigInteger activeInputChans, activeOutputChans; | BigInteger activeInputChans, activeOutputChans; | ||||
StringArray inChanNames, outChanNames; | StringArray inChanNames, outChanNames; | ||||
Array<double> sampleRates; | Array<double> sampleRates; | ||||
@@ -832,6 +838,9 @@ private: | |||||
switch (pa->mSelector) | switch (pa->mSelector) | ||||
{ | { | ||||
case kAudioDeviceProcessorOverload: | |||||
intern->xruns++; | |||||
break; | |||||
case kAudioDevicePropertyBufferSize: | case kAudioDevicePropertyBufferSize: | ||||
case kAudioDevicePropertyBufferFrameSize: | case kAudioDevicePropertyBufferFrameSize: | ||||
case kAudioDevicePropertyNominalSampleRate: | case kAudioDevicePropertyNominalSampleRate: | ||||
@@ -957,6 +966,7 @@ public: | |||||
double getCurrentSampleRate() override { return internal->getSampleRate(); } | double getCurrentSampleRate() override { return internal->getSampleRate(); } | ||||
int getCurrentBitDepth() override { return internal->bitDepth; } | int getCurrentBitDepth() override { return internal->bitDepth; } | ||||
int getCurrentBufferSizeSamples() override { return internal->getBufferSize(); } | int getCurrentBufferSizeSamples() override { return internal->getBufferSize(); } | ||||
int getXRunCount() const noexcept override { return internal->xruns; } | |||||
int getDefaultBufferSize() override | int getDefaultBufferSize() override | ||||
{ | { | ||||
@@ -977,6 +987,7 @@ public: | |||||
{ | { | ||||
isOpen_ = true; | isOpen_ = true; | ||||
internal->xruns = 0; | |||||
if (bufferSizeSamples <= 0) | if (bufferSizeSamples <= 0) | ||||
bufferSizeSamples = getDefaultBufferSize(); | bufferSizeSamples = getDefaultBufferSize(); | ||||
@@ -2058,3 +2069,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio() | |||||
} | } | ||||
#undef JUCE_COREAUDIOLOG | #undef JUCE_COREAUDIOLOG | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
#ifndef JUCE_LOG_COREMIDI_ERRORS | #ifndef JUCE_LOG_COREMIDI_ERRORS | ||||
#define JUCE_LOG_COREMIDI_ERRORS 1 | #define JUCE_LOG_COREMIDI_ERRORS 1 | ||||
#endif | #endif | ||||
@@ -555,3 +558,5 @@ void MidiInput::stop() | |||||
} | } | ||||
#undef CHECK_ERROR | #undef CHECK_ERROR | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
#undef WINDOWS | #undef WINDOWS | ||||
/* The ASIO SDK *should* declare its callback functions as being __cdecl, but different versions seem | /* 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; } | Array<int> getAvailableBufferSizes() override { return bufferSizes; } | ||||
int getDefaultBufferSize() override { return preferredBufferSize; } | int getDefaultBufferSize() override { return preferredBufferSize; } | ||||
int getXRunCount() const noexcept override { return xruns; } | |||||
String open (const BigInteger& inputChannels, | String open (const BigInteger& inputChannels, | ||||
const BigInteger& outputChannels, | const BigInteger& outputChannels, | ||||
double sr, int bufferSizeSamples) override | double sr, int bufferSizeSamples) override | ||||
@@ -461,6 +466,9 @@ public: | |||||
err = asioObject->getChannels (&totalNumInputChans, &totalNumOutputChans); | err = asioObject->getChannels (&totalNumInputChans, &totalNumOutputChans); | ||||
jassert (err == ASE_OK); | jassert (err == ASE_OK); | ||||
if (asioObject->future (kAsioCanReportOverload, nullptr) != ASE_OK) | |||||
xruns = -1; | |||||
inBuffers.calloc (totalNumInputChans + 8); | inBuffers.calloc (totalNumInputChans + 8); | ||||
outBuffers.calloc (totalNumOutputChans + 8); | outBuffers.calloc (totalNumOutputChans + 8); | ||||
@@ -786,6 +794,7 @@ private: | |||||
bool volatile littleEndian, postOutput, needToReset; | bool volatile littleEndian, postOutput, needToReset; | ||||
bool volatile insideControlPanelModalLoop; | bool volatile insideControlPanelModalLoop; | ||||
bool volatile shouldUsePreferredSize; | bool volatile shouldUsePreferredSize; | ||||
int xruns = 0; | |||||
//============================================================================== | //============================================================================== | ||||
static String convertASIOString (char* const text, int length) | static String convertASIOString (char* const text, int length) | ||||
@@ -1177,6 +1186,7 @@ private: | |||||
totalNumOutputChans = 0; | totalNumOutputChans = 0; | ||||
numActiveInputChans = 0; | numActiveInputChans = 0; | ||||
numActiveOutputChans = 0; | numActiveOutputChans = 0; | ||||
xruns = 0; | |||||
currentCallback = nullptr; | currentCallback = nullptr; | ||||
error.clear(); | error.clear(); | ||||
@@ -1346,7 +1356,7 @@ private: | |||||
{ | { | ||||
case kAsioSelectorSupported: | case kAsioSelectorSupported: | ||||
if (value == kAsioResetRequest || value == kAsioEngineVersion || value == kAsioResyncRequest | if (value == kAsioResetRequest || value == kAsioEngineVersion || value == kAsioResyncRequest | ||||
|| value == kAsioLatenciesChanged || value == kAsioSupportsInputMonitor) | |||||
|| value == kAsioLatenciesChanged || value == kAsioSupportsInputMonitor || value == kAsioOverload) | |||||
return 1; | return 1; | ||||
break; | break; | ||||
@@ -1357,7 +1367,8 @@ private: | |||||
case kAsioEngineVersion: return 2; | case kAsioEngineVersion: return 2; | ||||
case kAsioSupportsTimeInfo: | case kAsioSupportsTimeInfo: | ||||
case kAsioSupportsTimeCode: return 0; | |||||
case kAsioSupportsTimeCode: return 0; | |||||
case kAsioOverload: xruns++; return 1; | |||||
} | } | ||||
return 0; | return 0; | ||||
@@ -1643,3 +1654,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO() | |||||
{ | { | ||||
return new ASIOAudioIODeviceType(); | return new ASIOAudioIODeviceType(); | ||||
} | } | ||||
} // namespace juce |
@@ -20,8 +20,6 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
} // (juce namespace) | |||||
extern "C" | extern "C" | ||||
{ | { | ||||
// Declare just the minimum number of interfaces for the DSound objects that we need.. | // Declare just the minimum number of interfaces for the DSound objects that we need.. | ||||
@@ -268,6 +266,10 @@ public: | |||||
pDirectSound = nullptr; | pDirectSound = nullptr; | ||||
pOutputBuffer = nullptr; | pOutputBuffer = nullptr; | ||||
writeOffset = 0; | writeOffset = 0; | ||||
xruns = 0; | |||||
firstPlayTime = true; | |||||
lastPlayTime = 0; | |||||
String error; | String error; | ||||
HRESULT hr = E_NOINTERFACE; | HRESULT hr = E_NOINTERFACE; | ||||
@@ -278,6 +280,7 @@ public: | |||||
if (SUCCEEDED (hr)) | if (SUCCEEDED (hr)) | ||||
{ | { | ||||
bytesPerBuffer = (bufferSizeSamples * (bitDepth >> 2)) & ~15; | bytesPerBuffer = (bufferSizeSamples * (bitDepth >> 2)) & ~15; | ||||
ticksPerBuffer = bytesPerBuffer * Time::getHighResolutionTicksPerSecond() / (sampleRate * (bitDepth >> 2)); | |||||
totalBytesPerBuffer = (blocksPerOverallBuffer * bytesPerBuffer) & ~15; | totalBytesPerBuffer = (blocksPerOverallBuffer * bytesPerBuffer) & ~15; | ||||
const int numChannels = 2; | const int numChannels = 2; | ||||
@@ -399,6 +402,18 @@ public: | |||||
return true; | return true; | ||||
} | } | ||||
auto currentPlayTime = Time::getHighResolutionTicks (); | |||||
if (! firstPlayTime) | |||||
{ | |||||
auto expectedBuffers = (currentPlayTime - lastPlayTime) / ticksPerBuffer; | |||||
playCursor += static_cast<DWORD> (expectedBuffers * bytesPerBuffer); | |||||
} | |||||
else | |||||
firstPlayTime = false; | |||||
lastPlayTime = currentPlayTime; | |||||
int playWriteGap = (int) (writeCursor - playCursor); | int playWriteGap = (int) (writeCursor - playCursor); | ||||
if (playWriteGap < 0) | if (playWriteGap < 0) | ||||
playWriteGap += totalBytesPerBuffer; | playWriteGap += totalBytesPerBuffer; | ||||
@@ -411,6 +426,9 @@ public: | |||||
{ | { | ||||
writeOffset = writeCursor; | writeOffset = writeCursor; | ||||
bytesEmpty = totalBytesPerBuffer - playWriteGap; | bytesEmpty = totalBytesPerBuffer - playWriteGap; | ||||
// buffer underflow | |||||
xruns++; | |||||
} | } | ||||
if (bytesEmpty >= bytesPerBuffer) | if (bytesEmpty >= bytesPerBuffer) | ||||
@@ -482,7 +500,7 @@ public: | |||||
} | } | ||||
} | } | ||||
int bitDepth; | |||||
int bitDepth, xruns; | |||||
bool doneFlag; | bool doneFlag; | ||||
private: | private: | ||||
@@ -498,6 +516,9 @@ private: | |||||
int totalBytesPerBuffer, bytesPerBuffer; | int totalBytesPerBuffer, bytesPerBuffer; | ||||
unsigned int lastPlayCursor; | unsigned int lastPlayCursor; | ||||
bool firstPlayTime; | |||||
int64 lastPlayTime, ticksPerBuffer; | |||||
static inline int convertInputValues (const float l, const float r) noexcept | static inline int convertInputValues (const float l, const float r) noexcept | ||||
{ | { | ||||
return jlimit (-32768, 32767, roundToInt (32767.0f * r)) << 16 | return jlimit (-32768, 32767, roundToInt (32767.0f * r)) << 16 | ||||
@@ -856,6 +877,11 @@ public: | |||||
bool isPlaying() override { return isStarted && isOpen_ && isThreadRunning(); } | bool isPlaying() override { return isStarted && isOpen_ && isThreadRunning(); } | ||||
String getLastError() override { return lastError; } | String getLastError() override { return lastError; } | ||||
int getXRunCount () const noexcept override | |||||
{ | |||||
return (outChans[0] != nullptr ? outChans[0]->xruns : -1); | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
StringArray inChannels, outChannels; | StringArray inChannels, outChannels; | ||||
int outputDeviceIndex, inputDeviceIndex; | int outputDeviceIndex, inputDeviceIndex; | ||||
@@ -1271,3 +1297,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound() | |||||
{ | { | ||||
return new DSoundAudioIODeviceType(); | return new DSoundAudioIODeviceType(); | ||||
} | } | ||||
} // namespace juce |
@@ -20,6 +20,9 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
namespace juce | |||||
{ | |||||
struct MidiServiceType | struct MidiServiceType | ||||
{ | { | ||||
struct InputWrapper | struct InputWrapper | ||||
@@ -27,7 +30,6 @@ struct MidiServiceType | |||||
virtual ~InputWrapper() {} | virtual ~InputWrapper() {} | ||||
virtual String getDeviceName() = 0; | virtual String getDeviceName() = 0; | ||||
virtual void start() = 0; | virtual void start() = 0; | ||||
virtual void stop() = 0; | virtual void stop() = 0; | ||||
}; | }; | ||||
@@ -37,7 +39,6 @@ struct MidiServiceType | |||||
virtual ~OutputWrapper() {} | virtual ~OutputWrapper() {} | ||||
virtual String getDeviceName() = 0; | virtual String getDeviceName() = 0; | ||||
virtual void sendMessageNow (const MidiMessage&) = 0; | virtual void sendMessageNow (const MidiMessage&) = 0; | ||||
}; | }; | ||||
@@ -47,10 +48,8 @@ struct MidiServiceType | |||||
virtual StringArray getDevices (bool) = 0; | virtual StringArray getDevices (bool) = 0; | ||||
virtual int getDefaultDeviceIndex (bool) = 0; | virtual int getDefaultDeviceIndex (bool) = 0; | ||||
virtual InputWrapper* createInputWrapper (MidiInput* const, | |||||
const int, | |||||
MidiInputCallback* const callback) = 0; | |||||
virtual OutputWrapper* createOutputWrapper (const int) = 0; | |||||
virtual InputWrapper* createInputWrapper (MidiInput*, int, MidiInputCallback*) = 0; | |||||
virtual OutputWrapper* createOutputWrapper (int) = 0; | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiServiceType) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiServiceType) | ||||
}; | }; | ||||
@@ -510,14 +509,12 @@ public: | |||||
: WindowsOutputWrapper::getDefaultDeviceIndex(); | : WindowsOutputWrapper::getDefaultDeviceIndex(); | ||||
} | } | ||||
InputWrapper* createInputWrapper (MidiInput* const input, | |||||
const int index, | |||||
MidiInputCallback* const callback) override | |||||
InputWrapper* createInputWrapper (MidiInput* input, int index, MidiInputCallback* callback) override | |||||
{ | { | ||||
return new WindowsInputWrapper (*this, input, index, callback); | return new WindowsInputWrapper (*this, input, index, callback); | ||||
} | } | ||||
OutputWrapper* createOutputWrapper (const int index) override | |||||
OutputWrapper* createOutputWrapper (int index) override | |||||
{ | { | ||||
return new WindowsOutputWrapper (*this, index); | return new WindowsOutputWrapper (*this, index); | ||||
} | } | ||||
@@ -1001,7 +998,7 @@ private: | |||||
if (bufferFactory == nullptr) | if (bufferFactory == nullptr) | ||||
throw std::runtime_error ("Failed to create output buffer factory"); | throw std::runtime_error ("Failed to create output buffer factory"); | ||||
HRESULT hr = bufferFactory->Create (static_cast<UINT32> (256), buffer.resetAndGetPointerAddress()); | |||||
HRESULT hr = bufferFactory->Create (static_cast<UINT32> (65536), buffer.resetAndGetPointerAddress()); | |||||
if (FAILED (hr)) | if (FAILED (hr)) | ||||
throw std::runtime_error ("Failed to create output buffer"); | throw std::runtime_error ("Failed to create output buffer"); | ||||
@@ -1081,14 +1078,12 @@ public: | |||||
: outputDeviceWatcher->getDefaultDeviceIndex(); | : outputDeviceWatcher->getDefaultDeviceIndex(); | ||||
} | } | ||||
InputWrapper* createInputWrapper (MidiInput* const input, | |||||
const int index, | |||||
MidiInputCallback* const callback) override | |||||
InputWrapper* createInputWrapper (MidiInput* input, int index, MidiInputCallback* callback) override | |||||
{ | { | ||||
return new WinRTInputWrapper (*this, input, index, *callback); | return new WinRTInputWrapper (*this, input, index, *callback); | ||||
} | } | ||||
OutputWrapper* createOutputWrapper (const int index) override | |||||
OutputWrapper* createOutputWrapper (int index) override | |||||
{ | { | ||||
return new WinRTOutputWrapper (*this, index); | return new WinRTOutputWrapper (*this, index); | ||||
} | } | ||||
@@ -1169,8 +1164,9 @@ MidiInput* MidiInput::openDevice (const int index, MidiInputCallback* const call | |||||
if (callback == nullptr) | if (callback == nullptr) | ||||
return nullptr; | return nullptr; | ||||
ScopedPointer<MidiInput> in (new MidiInput ("")); | |||||
ScopedPointer<MidiInput> in (new MidiInput ({})); | |||||
ScopedPointer<MidiServiceType::InputWrapper> wrapper; | ScopedPointer<MidiServiceType::InputWrapper> wrapper; | ||||
try | try | ||||
{ | { | ||||
wrapper = MidiService::getInstance()->getService()->createInputWrapper (in, index, callback); | wrapper = MidiService::getInstance()->getService()->createInputWrapper (in, index, callback); | ||||
@@ -1207,6 +1203,7 @@ int MidiOutput::getDefaultDeviceIndex() | |||||
MidiOutput* MidiOutput::openDevice (const int index) | MidiOutput* MidiOutput::openDevice (const int index) | ||||
{ | { | ||||
ScopedPointer<MidiServiceType::OutputWrapper> wrapper; | ScopedPointer<MidiServiceType::OutputWrapper> wrapper; | ||||
try | try | ||||
{ | { | ||||
wrapper = MidiService::getInstance()->getService()->createOutputWrapper (index); | wrapper = MidiService::getInstance()->getService()->createOutputWrapper (index); | ||||
@@ -1229,6 +1226,7 @@ MidiOutput::~MidiOutput() | |||||
void MidiOutput::sendMessageNow (const MidiMessage& message) | void MidiOutput::sendMessageNow (const MidiMessage& message) | ||||
{ | { | ||||
auto* const wrapper = static_cast<MidiServiceType::OutputWrapper*> (internal); | |||||
wrapper->sendMessageNow (message); | |||||
static_cast<MidiServiceType::OutputWrapper*> (internal)->sendMessageNow (message); | |||||
} | } | ||||
} // namespace juce |