| @@ -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 | |||||