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

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_LaunchQuantisation.cpp
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
12namespace tracktion { inline namespace engine
13{
14
16{
17 return { NEEDS_TRANS("None"),
18 NEEDS_TRANS("8 Bars"),
19 NEEDS_TRANS("4 Bars"),
20 NEEDS_TRANS("2 Bars"),
21 NEEDS_TRANS("1 Bar"),
22 NEEDS_TRANS("1/2 T"),
23 NEEDS_TRANS("1/2"),
24 NEEDS_TRANS("1/2 D"),
25 NEEDS_TRANS("1/4 T"),
26 NEEDS_TRANS("1/4"),
27 NEEDS_TRANS("1/4 D"),
28 NEEDS_TRANS("1/8 T"),
29 NEEDS_TRANS("1/8"),
30 NEEDS_TRANS("1/8 D"),
31 NEEDS_TRANS("1/16 T"),
32 NEEDS_TRANS("1/16"),
33 NEEDS_TRANS("1/16 D"),
34 NEEDS_TRANS("1/32 T"),
35 NEEDS_TRANS("1/32"),
36 NEEDS_TRANS("1/32 D"),
37 NEEDS_TRANS("1/64 T"),
38 NEEDS_TRANS("1/64"),
39 NEEDS_TRANS("1/64 D") };
40}
41
43{
44 auto index = getLaunchQTypeChoices().indexOf (name);
45
46 if (juce::isPositiveAndNotGreaterThan (index, static_cast<int> (LaunchQType::sixtyFourthD)))
47 return static_cast<LaunchQType> (index);
48
49 return {};
50}
51
52juce::String getName (LaunchQType t)
53{
54 assert (t >= LaunchQType::none || t <= LaunchQType::sixtyFourthD);
55 return getLaunchQTypeChoices()[static_cast<int> (t)];
56}
57
58double toBarFraction (LaunchQType q) noexcept
59{
60 assert (q >= LaunchQType::none || q <= LaunchQType::sixtyFourthD);
61
62 constexpr auto dot = 1.5;
63 constexpr auto triplet = 2.0 / 3.0;
64
65 switch (q)
66 {
67 case LaunchQType::eightBars: return 8.0;
68 case LaunchQType::fourBars: return 4.0;
69 case LaunchQType::twoBars: return 2.0;
70 case LaunchQType::bar: return 1.0;
71 case LaunchQType::halfT: return 1.0 / 2.0 * triplet;
72 case LaunchQType::half: return 1.0 / 2.0;
73 case LaunchQType::halfD: return 1.0 / 2.0 * dot;
74 case LaunchQType::quarterT: return 1.0 / 4.0 * triplet;
75 case LaunchQType::quarter: return 1.0 / 4.0;
76 case LaunchQType::quarterD: return 1.0 / 4.0 * dot;
77 case LaunchQType::eighthT: return 1.0 / 8.0 * triplet;
78 case LaunchQType::eighth: return 1.0 / 8.0;
79 case LaunchQType::eighthD: return 1.0 / 8.0 * dot;
80 case LaunchQType::sixteenthT: return 1.0 / 16.0 * triplet;
81 case LaunchQType::sixteenth: return 1.0 / 16.0;
82 case LaunchQType::sixteenthD: return 1.0 / 16.0 * dot;
83 case LaunchQType::thirtySecondT: return 1.0 / 32.0 * triplet;
84 case LaunchQType::thirtySecond: return 1.0 / 32.0;
85 case LaunchQType::thirtySecondD: return 1.0 / 32.0 * dot;
86 case LaunchQType::sixtyFourthT: return 1.0 / 64.0 * triplet;
87 case LaunchQType::sixtyFourth: return 1.0 / 64.0;
88 case LaunchQType::sixtyFourthD: return 1.0 / 64.0 * dot;
89 case LaunchQType::none: return 0.0;
90 }
91
92 assert (false);
93 return 1.0;
94}
95
96LaunchQType fromBarFraction (double f) noexcept
97{
98 auto ret = LaunchQType::bar;
99
100 magic_enum::enum_for_each<LaunchQType> ([f, &ret] (auto t)
101 {
103 {
104 ret = t;
105 return;
106 }
107 });
108
109 return ret;
110}
111
112BeatPosition getNext (LaunchQType q, const tempo::Sequence& ts, BeatPosition pos) noexcept
113{
114 constexpr auto adjustment = 1.0 - 1.0e-10; // Round up adjustment
115
116 if (q == LaunchQType::none)
117 return pos;
118
119 const auto qFraction = toBarFraction (q);
120 auto barsBeats = ts.toBarsAndBeats (ts.toTime (pos));
121
122 if (q <= LaunchQType::bar)
123 {
124 auto barsPlusBeats = barsBeats.bars + (barsBeats.beats.inBeats() / barsBeats.numerator);
125
126 barsBeats.bars = static_cast<int> (qFraction * (int) std::floor (barsPlusBeats / qFraction + adjustment));
127 barsBeats.beats = {};
128 }
129
130 // Fractional bars
131 barsBeats.beats = BeatDuration::fromBeats (qFraction * std::floor ((barsBeats.beats.inBeats() / qFraction) + adjustment));
132
133 return ts.toBeats (barsBeats);
134}
135
136BeatPosition getNext (LaunchQType q, const TempoSequence& ts, BeatPosition pos) noexcept
137{
138 return getNext (q, ts.getInternalSequence(), pos);
139}
140
141
142//==============================================================================
143//==============================================================================
145 : edit (e)
146{
147 type.referTo (v, IDs::launchQuantisation, &e.getUndoManager(), LaunchQType::bar);
148}
149
151{
152 return engine::getNext (type, edit.tempoSequence, p);
153}
154
155}} // namespace tracktion { inline namespace engine
assert
void referTo(ValueTree &tree, const Identifier &property, UndoManager *um)
int indexOf(StringRef stringToLookFor, bool ignoreCase=false, int startIndex=0) const
The Tracktion Edit class!
juce::UndoManager & getUndoManager() noexcept
Returns the juce::UndoManager used for this Edit.
LaunchQuantisation(juce::ValueTree &, Edit &)
Creates a LaunchQuantisation property on a given state tree.
BeatPosition getNext(BeatPosition) const noexcept
Returns the next beat quantised to the current type.
juce::CachedValue< LaunchQType > type
The current type property.
Holds a list of TempoSetting objects, to form a sequence of tempo changes.
T floor(T... args)
#define NEEDS_TRANS(stringLiteral)
typedef int
constexpr bool approximatelyEqual(Type a, Type b, Tolerance< Type > tolerance=Tolerance< Type >{} .withAbsolute(std::numeric_limits< Type >::min()) .withRelative(std::numeric_limits< Type >::epsilon()))
bool isPositiveAndNotGreaterThan(Type1 valueToTest, Type2 upperLimit) noexcept
juce::String getName(LaunchQType t)
Retuns the name of a LaunchQType for display purposes.
double toBarFraction(LaunchQType q) noexcept
Returns the fraction of a bar to be used for a given rate type.
BeatPosition getNext(LaunchQType q, const tempo::Sequence &ts, BeatPosition pos) noexcept
Returns the next quantised position.
std::optional< LaunchQType > launchQTypeFromName(const juce::String &name)
Returns a the launch Q from a string returned from getLaunchQTypeChoices().
LaunchQType fromBarFraction(double f) noexcept
Returns the fraction of a bar to be used for a given rate type.
juce::StringArray getLaunchQTypeChoices()
Returns a list of quantisation type options in the order of LaunchQType.
Represents a position in beats.