Audacity 3.2.0
BeatsFormat.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 BeatsFormat.cpp
6
7 Michael Papadopoulos
8
9**********************************************************************/
10
11#include "BeatsFormat.h"
12
14 double units, double& major, double& minor, double &minorMinor,
15 int& mDigits
16) const
17{
18 // Check that all data is positive
19 if (!(mBpm > 0 && mTimeSigUpper > 0 && mTimeSigLower > 0)) return;
20 // Also check that the lower time signature is valid (power of 2)
21 if(mTimeSigLower & (mTimeSigLower - 1)) return;
22
23 const auto lower = static_cast<double>(mTimeSigLower);
24 if (units < .025 * (60 / mBpm) * (4 / lower))
25 {
26 // measures
27 major = (60 * mTimeSigUpper) / (mBpm * (lower / 4));
28 // thirtysecondth notes (label every quarter note)
29 minor = 60 / (mBpm * (lower * 2));
30 // hundredtwentyeighth notes
31 minorMinor = 60 / (mBpm * (lower * 8));
32 }
33 else if (units < .05 * (60 / mBpm) * (4 / lower))
34 {
35 // measures
36 major = (60 * mTimeSigUpper) / (mBpm * (lower / 4));
37 // sixteenth notes (label every quarter note)
38 minor = 60 / (mBpm * (lower));
39 // sixtyfourth notes
40 minorMinor = 60 / (mBpm * (lower * 4));
41 }
42 else if (units < .1 * (60 / mBpm) * (4 / lower))
43 {
44 // measures
45 major = (60 * mTimeSigUpper) / (mBpm * (lower / 4));
46 // eigth notes (label every quarter note)
47 minor = 60 / (mBpm * (lower / 2));
48 // thirtysecondth notes
49 minorMinor = 60 / (mBpm * (lower * 2));
50 }
51 else if (units < .4 * (60 / mBpm) * (4 / lower))
52 {
53 // measures
54 major = (60 * mTimeSigUpper) / (mBpm * (lower / 4));
55 // eigth notes (label every quarter note)
56 minor = 60 / (mBpm * (lower / 2));
57 // sixteenth notes
58 minorMinor = 60 / (mBpm * (lower));
59 }
60 else if (units < .8 * (60 / mBpm) * (4 / lower))
61 {
62 // measures
63 major = (60 * mTimeSigUpper) / (mBpm * (lower / 4));
64 // quarter notes
65 minor = 60 / (mBpm * (lower / 4));
66 // sixteenth notes
67 minorMinor = 60 / (mBpm * (lower));
68 }
69 else if (units < 4 * (60 / mBpm) * (4 / lower))
70 {
71 // measures
72 major = (60 * mTimeSigUpper) / (mBpm * (lower / 4));
73 // quarter notes
74 minorMinor = 60 / (mBpm * (lower / 4));
75 }
76 else if (units < 8 * (60 / mBpm) * (4 / lower))
77 {
78 // four-measures
79 major = (60 * mTimeSigUpper) / (mBpm * (lower / 16));
80 // measures
81 minor = 60 / (mBpm * (lower / 16));
82 // half measures
83 minorMinor = 60 / (mBpm * (lower / 8));
84 }
85 else {
86 int factor = pow(2, std::floor(log2(std::ceil(units) * (mBpm / 60) * (mTimeSigLower / 4))) - 2);
87 major = (60 * mTimeSigUpper) / (mBpm * (lower / (16 * factor)));
88 minorMinor = 60 / (mBpm * (lower / (8 * factor)));
89 }
90
91 mDigits = 0;
92}
93
95 wxString& s, double d, double units, double minor, int mDigits, TickType tickType
96) const
97{
98 if (d < 0) {
99 return;
100 }
101
102 const auto lower = static_cast<double>(mTimeSigLower);
103 double val = (mBpm * (lower / 4) * d) / (60 * mTimeSigUpper);
104 double beatApprox = (val - floor(val)) * mTimeSigUpper + 1;
105 int beat = round(beatApprox);
106
107 // Don't add decimal if it's a major tick or is on the beat
108 // Segment by distance with units
109 if (units < .4 * (60 / mBpm)* (4 / lower))
110 {
111 if (tickType == RulerFormat::t_major) {
112 s.Printf(wxT("%d"), (int)round(val + 1));
113 }
114 else if (tickType == RulerFormat::t_minor && abs(beat - beatApprox) < 1.0e-5f) {
115 s.Printf(wxT("%d.%d"), (int)floor(val + 1), (int)beat);
116 }
117 }
118 else if (units < .8 * (60 / mBpm) * (4 / lower))
119 {
120 if (tickType == RulerFormat::t_major) {
121 s.Printf(wxT("%d"), (int)round(val + 1));
122 }
123 else if (tickType == RulerFormat::t_minor && beat != 1) {
124 s.Printf(wxT("%d.%d"), (int)floor(val + 1), (int)beat);
125 }
126 }
127 else {
128 if (tickType == RulerFormat::t_major) {
129 s.Printf(wxT("%d"), (int)round(val + 1));
130 }
131 }
132}
133
134BeatsFormat::~BeatsFormat() = default;
wxT("CloseDown"))
void SetLabelString(wxString &s, double d, double units, double minor, int mDigits, TickType tickType) const override
Definition: BeatsFormat.cpp:94
~BeatsFormat() override
double mBpm
Definition: BeatsFormat.h:38
int mTimeSigLower
Definition: BeatsFormat.h:40
int mTimeSigUpper
Definition: BeatsFormat.h:39
void SetTickSizes(double units, double &major, double &minor, double &minorMinor, int &mDigits) const override
Definition: BeatsFormat.cpp:13
fastfloat_really_inline void round(adjusted_mantissa &am, callback cb) noexcept
Definition: fast_float.h:2512