mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
AudioPlayHead: Improve granularity of position info
This commit is contained in:
parent
891daf1332
commit
8fbd99c424
27 changed files with 924 additions and 572 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue