tracktion-engine 3.0-10-g034fdde4aa5
Tracktion Engine — High level data model for audio applications

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_PlayHeadState.h
Go to the documentation of this file.
1 /*
2 ,--. ,--. ,--. ,--.
3 ,-' '-.,--.--.,--,--.,---.| |,-.,-' '-.`--' ,---. ,--,--, Copyright 2024
4 '-. .-'| .--' ,-. | .--'| /'-. .-',--.| .-. || \ Tracktion Software
5 | | | | \ '-' \ `--.| \ \ | | | |' '-' '| || | Corporation
6 `---' `--' `--`--'`---'`--'`--' `---' `--' `---' `--''--' www.tracktion.com
7
8 Tracktion Engine uses a GPL/commercial licence - see LICENCE.md for details.
9*/
10
11#pragma once
12
13
14namespace tracktion { inline namespace graph
15{
16
17//==============================================================================
18//==============================================================================
24{
25public:
27 : playHead (ph)
28 {
29 }
30
34 void update (juce::Range<int64_t> referenceSampleRange);
35
37 inline bool isContiguousWithPreviousBlock() noexcept { return ! (didPlayheadJump() || isFirstBlockOfLoop()); }
38
40 inline bool didPlayheadJump() noexcept { return playheadJumped; }
41
43 inline bool isFirstBlockOfLoop() noexcept { return firstBlockOfLoop; }
44
46 inline bool isLastBlockOfLoop() noexcept { return lastBlockOfLoop; }
47
48 PlayHead& playHead;
49
51 bool isPlayHeadRunning = false, playheadJumped = false, lastBlockOfLoop = false, firstBlockOfLoop = false;
52
53private:
54 std::chrono::system_clock::time_point lastUserInteractionTime;
55};
56
57
58//==============================================================================
59inline void PlayHeadState::update (juce::Range<int64_t> referenceSampleRange)
60{
61 const bool isPlayingNow = playHead.isPlaying();
62 bool jumped = false;
63
64 if (lastUserInteractionTime != playHead.getLastUserInteractionTime())
65 {
66 lastUserInteractionTime = playHead.getLastUserInteractionTime();
67 jumped = true;
68 }
69
70 if (isPlayingNow != isPlayHeadRunning)
71 {
72 isPlayHeadRunning = isPlayingNow;
73 jumped = jumped || isPlayHeadRunning;
74 }
75
76 playheadJumped = jumped;
77
78 // Next check if this is the start or end of a loop range
79 if (playHead.isLooping())
80 {
81 const auto timelineLoopRange = playHead.getLoopRange();
82 const auto startTimelinePos = playHead.referenceSamplePositionToTimelinePosition (referenceSampleRange.getStart());
83 const auto endTimelinePos = playHead.referenceSamplePositionToTimelinePosition (referenceSampleRange.getEnd() - 1) + 1;
84 // The -1/+1 is here to avoid the last sample being wrapped to the beginning of the loop range
85
86 if (playHead.isRollingIntoLoop())
87 firstBlockOfLoop = false;
88 else
89 firstBlockOfLoop = startTimelinePos == timelineLoopRange.getStart();
90
91 lastBlockOfLoop = endTimelinePos == timelineLoopRange.getEnd();
92 }
93 else
94 {
95 firstBlockOfLoop = false;
96 lastBlockOfLoop = false;
97 }
98}
99
100}}
constexpr ValueType getStart() const noexcept
constexpr ValueType getEnd() const noexcept
Determines how this block releates to other previous render blocks and if the play head has jumped in...
bool isLastBlockOfLoop() noexcept
Returns true if this is the last block of a loop.
bool isContiguousWithPreviousBlock() noexcept
Returns true if the play head did not jump and this block is contiguous with the previous block.
bool isFirstBlockOfLoop() noexcept
Returns true if this is the first block of a loop.
void update(juce::Range< int64_t > referenceSampleRange)
Call once per block to update the jumped state.
bool didPlayheadJump() noexcept
Returns true if the play head jumped.
Converts a monotonically increasing reference range in to a timeline range.
std::chrono::system_clock::time_point getLastUserInteractionTime() const
Returns the time of the last user interaction, either a setPosition or setUserIsDragging call.
bool isRollingIntoLoop() const noexcept
Returns true is the play head is looping but playing before the loop start position.
int64_t referenceSamplePositionToTimelinePosition(int64_t referenceSamplePosition) const
Converts a reference sample position to a timeline position.
juce::Range< int64_t > getLoopRange() const noexcept
Returns the looped playback range.
bool isPlaying() const noexcept
Returns true is the play head is currently playing.
bool isLooping() const noexcept
Returns true is the play head is in loop mode.