diff --git a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm index 693853c86d..359c238f7c 100644 --- a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm +++ b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm @@ -2293,43 +2293,43 @@ private: if (p != nullptr) *p = value; } - OSStatus getBeatAndTempo (Float64* outCurrentBeat, Float64* outCurrentTempo) const + /* If the AudioPlayHead is available, and has valid PositionInfo, this will return the result + of calling the specified getter on that PositionInfo. Otherwise, this will return a + default-constructed instance of the same type. + + For getters that return an Optional, this function will return a nullopt if the playhead or + position info is invalid. + + For getters that return a bool, this function will return false if the playhead or position + info is invalid. + */ + template + Result getFromPlayHead (Result (AudioPlayHead::PositionInfo::* member)() const) const { if (auto* ph = getPlayHead()) - { if (const auto pos = ph->getPosition()) - { - setIfNotNull (outCurrentBeat, pos->getPpqPosition().orFallback (0.0)); - setIfNotNull (outCurrentTempo, pos->getBpm().orFallback (0.0)); - return noErr; - } - } + return ((*pos).*member)(); - setIfNotNull (outCurrentBeat, 0); - setIfNotNull (outCurrentTempo, 120.0); + return {}; + } + + OSStatus getBeatAndTempo (Float64* outCurrentBeat, Float64* outCurrentTempo) const + { + setIfNotNull (outCurrentBeat, getFromPlayHead (&AudioPlayHead::PositionInfo::getPpqPosition).orFallback (0)); + setIfNotNull (outCurrentTempo, getFromPlayHead (&AudioPlayHead::PositionInfo::getBpm).orFallback (120.0)); return noErr; } OSStatus getMusicalTimeLocation (UInt32* outDeltaSampleOffsetToNextBeat, Float32* outTimeSig_Numerator, UInt32* outTimeSig_Denominator, Float64* outCurrentMeasureDownBeat) const { - if (auto* ph = getPlayHead()) - { - if (const auto pos = ph->getPosition()) - { - const auto signature = pos->getTimeSignature().orFallback (AudioPlayHead::TimeSignature{}); - setIfNotNull (outDeltaSampleOffsetToNextBeat, (UInt32) 0); //xxx - setIfNotNull (outTimeSig_Numerator, (UInt32) signature.numerator); - setIfNotNull (outTimeSig_Denominator, (UInt32) signature.denominator); - setIfNotNull (outCurrentMeasureDownBeat, pos->getPpqPositionOfLastBarStart().orFallback (0.0)); //xxx wrong - return noErr; - } - } + setIfNotNull (outDeltaSampleOffsetToNextBeat, (UInt32) 0); //xxx + setIfNotNull (outCurrentMeasureDownBeat, getFromPlayHead (&AudioPlayHead::PositionInfo::getPpqPositionOfLastBarStart).orFallback (0.0)); + + const auto signature = getFromPlayHead (&AudioPlayHead::PositionInfo::getTimeSignature).orFallback (AudioPlayHead::TimeSignature{}); + setIfNotNull (outTimeSig_Numerator, (UInt32) signature.numerator); + setIfNotNull (outTimeSig_Denominator, (UInt32) signature.denominator); - setIfNotNull (outDeltaSampleOffsetToNextBeat, (UInt32) 0); - setIfNotNull (outTimeSig_Numerator, (UInt32) 4); - setIfNotNull (outTimeSig_Denominator, (UInt32) 4); - setIfNotNull (outCurrentMeasureDownBeat, 0); return noErr; } @@ -2337,34 +2337,16 @@ private: Float64* outCurrentSampleInTimeLine, Boolean* outIsCycling, Float64* outCycleStartBeat, Float64* outCycleEndBeat) { - if (auto* ph = getPlayHead()) - { - AudioPlayHead::CurrentPositionInfo result; + const auto nowPlaying = getFromPlayHead (&AudioPlayHead::PositionInfo::getIsPlaying); + setIfNotNull (outIsPlaying, nowPlaying); + setIfNotNull (outTransportStateChanged, std::exchange (wasPlaying, nowPlaying) != nowPlaying); + setIfNotNull (outCurrentSampleInTimeLine, getFromPlayHead (&AudioPlayHead::PositionInfo::getTimeInSamples).orFallback (0)); + setIfNotNull (outIsCycling, getFromPlayHead (&AudioPlayHead::PositionInfo::getIsLooping)); - if (ph->getCurrentPosition (result)) - { - setIfNotNull (outIsPlaying, result.isPlaying); - - if (outTransportStateChanged != nullptr) - { - *outTransportStateChanged = result.isPlaying != wasPlaying; - wasPlaying = result.isPlaying; - } - - setIfNotNull (outCurrentSampleInTimeLine, result.timeInSamples); - setIfNotNull (outIsCycling, result.isLooping); - setIfNotNull (outCycleStartBeat, result.ppqLoopStart); - setIfNotNull (outCycleEndBeat, result.ppqLoopEnd); - return noErr; - } - } + const auto loopPoints = getFromPlayHead (&AudioPlayHead::PositionInfo::getLoopPoints).orFallback (AudioPlayHead::LoopPoints{}); + setIfNotNull (outCycleStartBeat, loopPoints.ppqStart); + setIfNotNull (outCycleEndBeat, loopPoints.ppqEnd); - setIfNotNull (outIsPlaying, false); - setIfNotNull (outTransportStateChanged, false); - setIfNotNull (outCurrentSampleInTimeLine, 0); - setIfNotNull (outIsCycling, false); - setIfNotNull (outCycleStartBeat, 0.0); - setIfNotNull (outCycleEndBeat, 0.0); return noErr; }