1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00

AudioPlayHead: Improve granularity of position info

This commit is contained in:
reuk 2022-06-13 19:37:49 +01:00
parent 891daf1332
commit 8fbd99c424
No known key found for this signature in database
GPG key ID: 9ADCD339CFC98A11
27 changed files with 924 additions and 572 deletions

View file

@ -293,14 +293,14 @@ public:
bool processBlock (AudioBuffer<float>& buffer,
AudioProcessor::Realtime realtime,
const AudioPlayHead::CurrentPositionInfo& positionInfo) noexcept override
const AudioPlayHead::PositionInfo& positionInfo) noexcept override
{
const auto numSamples = buffer.getNumSamples();
jassert (numSamples <= maximumSamplesPerBlock);
jassert (numChannels == buffer.getNumChannels());
jassert (realtime == AudioProcessor::Realtime::no || useBufferedAudioSourceReader);
const auto timeInSamples = positionInfo.timeInSamples;
const auto isPlaying = positionInfo.isPlaying;
const auto timeInSamples = positionInfo.getTimeInSamples().orFallback (0);
const auto isPlaying = positionInfo.getIsPlaying();
bool success = true;
bool didRenderAnyRegion = false;
@ -482,7 +482,7 @@ public:
bool processBlock (AudioBuffer<float>& buffer,
AudioProcessor::Realtime realtime,
const AudioPlayHead::CurrentPositionInfo& positionInfo) noexcept override
const AudioPlayHead::PositionInfo& positionInfo) noexcept override
{
ignoreUnused (realtime);
@ -491,7 +491,7 @@ public:
if (! locked)
return true;
if (positionInfo.isPlaying)
if (positionInfo.getIsPlaying())
return true;
if (const auto previewedRegion = previewState->previewedRegion.load())
@ -1075,12 +1075,11 @@ private:
void doResize()
{
auto* aph = getAudioPlayhead();
AudioPlayHead::CurrentPositionInfo positionInfo;
aph->getCurrentPosition (positionInfo);
const auto info = aph->getPosition();
if (positionInfo.isPlaying)
if (info.hasValue() && info->getIsPlaying())
{
const auto markerX = positionInfo.timeInSeconds * pixelPerSecond;
const auto markerX = info->getTimeInSeconds().orFallback (0) * pixelPerSecond;
const auto playheadLine = getLocalBounds().withTrimmedLeft ((int) (markerX - markerWidth / 2.0) - horizontalOffset)
.removeFromLeft ((int) markerWidth);
playheadMarker.setVisible (true);

View file

@ -321,12 +321,10 @@ public:
class SpinLockedPosInfo
{
public:
SpinLockedPosInfo() { info.resetToDefault(); }
// Wait-free, but setting new info may fail if the main thread is currently
// calling `get`. This is unlikely to matter in practice because
// we'll be calling `set` much more frequently than `get`.
void set (const AudioPlayHead::CurrentPositionInfo& newInfo)
void set (const AudioPlayHead::PositionInfo& newInfo)
{
const juce::SpinLock::ScopedTryLockType lock (mutex);
@ -334,7 +332,7 @@ public:
info = newInfo;
}
AudioPlayHead::CurrentPositionInfo get() const noexcept
AudioPlayHead::PositionInfo get() const noexcept
{
const juce::SpinLock::ScopedLockType lock (mutex);
return info;
@ -342,7 +340,7 @@ public:
private:
juce::SpinLock mutex;
AudioPlayHead::CurrentPositionInfo info;
AudioPlayHead::PositionInfo info;
};
//==============================================================================
@ -510,13 +508,13 @@ private:
}
// quick-and-dirty function to format a bars/beats string
static String quarterNotePositionToBarsBeatsString (double quarterNotes, int numerator, int denominator)
static String quarterNotePositionToBarsBeatsString (double quarterNotes, AudioPlayHead::TimeSignature sig)
{
if (numerator == 0 || denominator == 0)
if (sig.numerator == 0 || sig.denominator == 0)
return "1|1|000";
auto quarterNotesPerBar = (numerator * 4 / denominator);
auto beats = (fmod (quarterNotes, quarterNotesPerBar) / quarterNotesPerBar) * numerator;
auto quarterNotesPerBar = (sig.numerator * 4 / sig.denominator);
auto beats = (fmod (quarterNotes, quarterNotesPerBar) / quarterNotesPerBar) * sig.numerator;
auto bar = ((int) quarterNotes) / quarterNotesPerBar + 1;
auto beat = ((int) beats) + 1;
@ -526,21 +524,21 @@ private:
}
// Updates the text in our position label.
void updateTimecodeDisplay (AudioPlayHead::CurrentPositionInfo pos)
void updateTimecodeDisplay (const AudioPlayHead::PositionInfo& pos)
{
MemoryOutputStream displayText;
displayText << "[" << SystemStats::getJUCEVersion() << "] "
<< String (pos.bpm, 2) << " bpm, "
<< pos.timeSigNumerator << '/' << pos.timeSigDenominator
<< " - " << timeToTimecodeString (pos.timeInSeconds)
<< " - " << quarterNotePositionToBarsBeatsString (pos.ppqPosition,
pos.timeSigNumerator,
pos.timeSigDenominator);
const auto sig = pos.getTimeSignature().orFallback (AudioPlayHead::TimeSignature{});
if (pos.isRecording)
displayText << "[" << SystemStats::getJUCEVersion() << "] "
<< String (pos.getBpm().orFallback (120.0), 2) << " bpm, "
<< sig.numerator << '/' << sig.denominator
<< " - " << timeToTimecodeString (pos.getTimeInSeconds().orFallback (0.0))
<< " - " << quarterNotePositionToBarsBeatsString (pos.getPpqPosition().orFallback (0.0), sig);
if (pos.getIsRecording())
displayText << " (recording)";
else if (pos.isPlaying)
else if (pos.getIsPlaying())
displayText << " (playing)";
timecodeDisplayLabel.setText (displayText.toString(), dontSendNotification);
@ -647,17 +645,11 @@ private:
const auto newInfo = [&]
{
if (auto* ph = getPlayHead())
{
AudioPlayHead::CurrentPositionInfo result;
if (ph->getCurrentPosition (result))
return result;
}
if (auto result = ph->getPosition())
return *result;
// If the host fails to provide the current time, we'll just use default values
AudioPlayHead::CurrentPositionInfo result;
result.resetToDefault();
return result;
return AudioPlayHead::PositionInfo{};
}();
lastPosInfo.set (newInfo);