Audacity 3.2.0
SnappingTest.cpp
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*!********************************************************************
3
4 Audacity: A Digital Audio Editor
5
6 SnappingTest.cpp
7
8 Dmitry Vedenko
9
10**********************************************************************/
11
12#include <catch2/catch.hpp>
13
14#include "SnapUtils.h"
15
16#include "Project.h"
18
19#include "MockedAudio.h"
20#include "MockedPrefs.h"
21
22void TimeCase(const AudacityProject& project, const char* format, double time, double expected, bool nearest)
23{
24 REQUIRE(SnapFunctionsRegistry::Snap(format, project, time, nearest).snapped);
25 REQUIRE(
26 SnapFunctionsRegistry::Snap(format, project, time, nearest).time ==
27 Approx(expected));
28}
29
31 AudacityProject& project, const char* format, double time, double expected,
32 bool nearest, int upper, int lower)
33{
34 auto& timeSignature = ProjectTimeSignature::Get(project);
35
36 timeSignature.SetTempo(60.0);
37 timeSignature.SetUpperTimeSignature(upper);
38 timeSignature.SetLowerTimeSignature(lower);
39
40 REQUIRE(
41 SnapFunctionsRegistry::Snap(format, project, time, nearest).snapped);
42
43 REQUIRE(
44 SnapFunctionsRegistry::Snap(format, project, time, nearest).time ==
45 Approx(expected));
46}
47
49 const AudacityProject& project, const char* format, double time,
50 double expected, bool upwards, bool successful)
51{
52 REQUIRE(
54 .snapped == successful);
55
56 REQUIRE(
57 SnapFunctionsRegistry::SingleStep(format, project, time, upwards).time ==
58 Approx(expected));
59}
60
62 AudacityProject& project, const char* format, double time,
63 double expected, bool upwards)
64{
65 auto& timeSignature = ProjectTimeSignature::Get(project);
66
67 timeSignature.SetTempo(60.0);
68 timeSignature.SetUpperTimeSignature(4);
69 timeSignature.SetLowerTimeSignature(4);
70
71 REQUIRE(SnapFunctionsRegistry::SingleStep(format, project, time, upwards)
72 .snapped);
73
74 REQUIRE(
75 SnapFunctionsRegistry::SingleStep(format, project, time, upwards).time ==
76 Approx(expected));
77}
78
79TEST_CASE("Snapping", "")
80{
81 MockedPrefs mockedPrefs;
82 MockedAudio mockedAudio;
83
85
86 REQUIRE(!SnapFunctionsRegistry::Snap("foo", *project, 1.0, true).snapped);
87
88
89 TimeCase(*project, "seconds", 1.0, 1.0, true);
90 TimeCase(*project, "seconds", 1.0, 1.0, false);
91 TimeCase(*project, "seconds", 1.1, 1.0, true);
92 TimeCase(*project, "seconds", 1.1, 1.0, false);
93 TimeCase(*project, "seconds", 1.9, 2.0, true);
94 TimeCase(*project, "seconds", 1.9, 1.0, false);
95
96 TimeCase(*project, "deciseconds", 1.0, 1.0, true);
97 TimeCase(*project, "deciseconds", 1.0, 1.0, false);
98 TimeCase(*project, "deciseconds", 1.1, 1.1, true);
99 TimeCase(*project, "deciseconds", 1.1, 1.1, false);
100 TimeCase(*project, "deciseconds", 1.91, 1.9, true);
101 TimeCase(*project, "deciseconds", 1.91, 1.9, false);
102 TimeCase(*project, "deciseconds", 1.99, 2.0, true);
103 TimeCase(*project, "deciseconds", 1.99, 1.9, false);
104
105 TimeCase(*project, "centiseconds", 1.0, 1.0, true);
106 TimeCase(*project, "centiseconds", 1.0, 1.0, false);
107 TimeCase(*project, "centiseconds", 1.1, 1.1, true);
108 TimeCase(*project, "centiseconds", 1.1, 1.1, false);
109 TimeCase(*project, "centiseconds", 1.91, 1.91, true);
110 TimeCase(*project, "centiseconds", 1.91, 1.91, false);
111 TimeCase(*project, "centiseconds", 1.911, 1.91, true);
112 TimeCase(*project, "centiseconds", 1.911, 1.91, false);
113 TimeCase(*project, "centiseconds", 1.999, 2.0, true);
114 TimeCase(*project, "centiseconds", 1.999, 1.99, false);
115
116 TimeCase(*project, "milliseconds", 1.0, 1.0, true);
117 TimeCase(*project, "milliseconds", 1.0, 1.0, false);
118 TimeCase(*project, "milliseconds", 1.1, 1.1, true);
119 TimeCase(*project, "milliseconds", 1.1, 1.1, false);
120 TimeCase(*project, "milliseconds", 1.91, 1.91, true);
121 TimeCase(*project, "milliseconds", 1.91, 1.91, false);
122 TimeCase(*project, "milliseconds", 1.911, 1.911, true);
123 TimeCase(*project, "milliseconds", 1.911, 1.911, false);
124 TimeCase(*project, "milliseconds", 1.999, 1.999, true);
125 TimeCase(*project, "milliseconds", 1.999, 1.999, false);
126 TimeCase(*project, "milliseconds", 1.9991, 1.999, true);
127 TimeCase(*project, "milliseconds", 1.9991, 1.999, false);
128 TimeCase(*project, "milliseconds", 1.9996, 2.0, true);
129 TimeCase(*project, "milliseconds", 1.9996, 1.999, false);
130
131 TimeCase(*project, "samples", 1.0, 1.0, true);
132 TimeCase(*project, "samples", 1.0, 1.0, false);
133 TimeCase(*project, "samples", 1.0 / 44100, 1.0 / 44100, true);
134 TimeCase(*project, "samples", 1.0 / 44100, 1.0 / 44100, false);
135 TimeCase(*project, "samples", 1.1 / 44100, 1.0 / 44100, true);
136 TimeCase(*project, "samples", 1.1 / 44100, 1.0 / 44100, false);
137 TimeCase(*project, "samples", 1.6 / 44100, 2.0 / 44100, true);
138 TimeCase(*project, "samples", 1.6 / 44100, 1.0 / 44100, false);
139
140 TimeStepCase(*project, "seconds", 1.0, 2.0, true, true);
141 TimeStepCase(*project, "seconds", 1.0, 0.0, false, true);
142 TimeStepCase(*project, "seconds", 0.5, 0.0, false, false);
143 TimeStepCase(*project, "seconds", 0.4, 1.0, true, true);
144 TimeStepCase(*project, "deciseconds", 1.0, 1.1, true, true);
145 TimeStepCase(*project, "deciseconds", 1.0, 0.9, false, true);
146 TimeStepCase(*project, "samples", 1.0, 1.0 + 1.0 / 44100, true, true);
147 TimeStepCase(*project, "samples", 1.0, 1.0 - 1.0 / 44100, false, true);
148
149 BeatsCase(*project, "bar", 1.0, 0.0, true, 3, 4);
150 BeatsCase(*project, "bar", 1.0, 0.0, false, 3, 4);
151 BeatsCase(*project, "bar", 2.0, 3.0, true, 3, 4);
152 BeatsCase(*project, "bar", 2.0, 0.0, false, 3, 4);
153
154 BeatsCase(*project, "bar", 2.0, 4.0, true, 4, 4);
155 BeatsCase(*project, "bar", 2.0, 0.0, false, 4, 4);
156 BeatsCase(*project, "bar", 3.0, 3.0, true, 3, 4);
157 BeatsCase(*project, "bar", 3.0, 3.0, false, 3, 4);
158
159 BeatsCase(*project, "bar_1_2", 0.0, 0.0, true, 3, 4);
160 BeatsCase(*project, "bar_1_2", 0.5, 0.0, true, 3, 4);
161 BeatsCase(*project, "bar_1_2", 1.0, 2.0, true, 3, 4);
162 BeatsCase(*project, "bar_1_2", 2.0, 2.0, true, 3, 4);
163 BeatsCase(*project, "bar_1_2", 3.0, 4.0, true, 3, 4);
164
165 BeatsCase(*project, "bar_1_2", 0.0, 0.0, true, 4, 4);
166 BeatsCase(*project, "bar_1_2", 0.5, 0.0, true, 4, 4);
167 BeatsCase(*project, "bar_1_2", 1.0, 2.0, true, 4, 4);
168 BeatsCase(*project, "bar_1_2", 2.0, 2.0, true, 4, 4);
169 BeatsCase(*project, "bar_1_2", 3.0, 4.0, true, 4, 4);
170
171 BeatsCase(*project, "bar_1_4", 0.0, 0.0, true, 3, 4);
172 BeatsCase(*project, "bar_1_4", 0.5, 1.0, true, 3, 4);
173 BeatsCase(*project, "bar_1_4", 1.0, 1.0, true, 3, 4);
174 BeatsCase(*project, "bar_1_4", 2.0, 2.0, true, 3, 4);
175 BeatsCase(*project, "bar_1_4", 3.0, 3.0, true, 3, 4);
176 BeatsCase(*project, "bar_1_4", 4.0, 4.0, true, 3, 4);
177
178 BeatsCase(*project, "bar_1_4", 0.0, 0.0, true, 4, 4);
179 BeatsCase(*project, "bar_1_4", 0.5, 1.0, true, 4, 4);
180 BeatsCase(*project, "bar_1_4", 1.0, 1.0, true, 4, 4);
181 BeatsCase(*project, "bar_1_4", 2.0, 2.0, true, 4, 4);
182 BeatsCase(*project, "bar_1_4", 3.0, 3.0, true, 4, 4);
183 BeatsCase(*project, "bar_1_4", 4.0, 4.0, true, 4, 4);
184
185 BeatsCase(*project, "bar_1_8", 0.0, 0.0, true, 3, 4);
186 BeatsCase(*project, "bar_1_8", 0.1, 0.0, true, 3, 4);
187 BeatsCase(*project, "bar_1_8", 0.5, 0.5, true, 3, 4);
188 BeatsCase(*project, "bar_1_8", 0.6, 0.5, true, 3, 4);
189 BeatsCase(*project, "bar_1_8", 0.8, 1.0, true, 3, 4);
190 BeatsCase(*project, "bar_1_8", 1.0, 1.0, true, 3, 4);
191 BeatsCase(*project, "bar_1_8", 1.6, 1.5, true, 3, 4);
192 BeatsCase(*project, "bar_1_8", 1.8, 2.0, true, 3, 4);
193
194 BeatsCase(*project, "bar_1_8", 0.0, 0.0, true, 4, 4);
195 BeatsCase(*project, "bar_1_8", 0.1, 0.0, true, 4, 4);
196 BeatsCase(*project, "bar_1_8", 0.5, 0.5, true, 4, 4);
197 BeatsCase(*project, "bar_1_8", 0.6, 0.5, true, 4, 4);
198 BeatsCase(*project, "bar_1_8", 0.8, 1.0, true, 4, 4);
199 BeatsCase(*project, "bar_1_8", 1.0, 1.0, true, 4, 4);
200 BeatsCase(*project, "bar_1_8", 1.6, 1.5, true, 4, 4);
201 BeatsCase(*project, "bar_1_8", 1.8, 2.0, true, 4, 4);
202
203 BeatsCase(*project, "triplet_1_2", 0.0, 0.0, true, 3, 4);
204 BeatsCase(*project, "triplet_1_2", 0.5, 0.0, true, 3, 4);
205 BeatsCase(*project, "triplet_1_2", 1.0, 1 + 1.0 / 3.0, true, 3, 4);
206 BeatsCase(*project, "triplet_1_2", 2.0, 2.0 + 2.0 / 3.0, true, 3, 4);
207 BeatsCase(*project, "triplet_1_2", 3.0, 2.0 + 2.0 / 3.0, true, 3, 4);
208
209 BeatsCase(*project, "triplet_1_2", 0.0, 0.0, true, 4, 4);
210 BeatsCase(*project, "triplet_1_2", 0.5, 0.0, true, 4, 4);
211 BeatsCase(*project, "triplet_1_2", 1.0, 1 + 1.0 / 3.0, true, 4, 4);
212 BeatsCase(*project, "triplet_1_2", 2.0, 2.0 + 2.0 / 3.0, true, 4, 4);
213 BeatsCase(*project, "triplet_1_2", 3.0, 2.0 + 2.0 / 3.0, true, 4, 4);
214 BeatsCase(*project, "triplet_1_2", 4.0, 4.0, true, 4, 4);
215
216 BeatsCase(*project, "triplet_1_4", 0.0, 0.0, true, 4, 4);
217 BeatsCase(*project, "triplet_1_4", 1.0, 1 + 1.0 / 3.0, true, 4, 4);
218 BeatsCase(*project, "triplet_1_4", 2.0, 2.0, true, 4, 4);
219 BeatsCase(*project, "triplet_1_4", 4.0, 4.0, true, 4, 4);
220
221 BarStepCase(*project, "bar", 0.0, 4.0, true);
222 BarStepCase(*project, "bar", 4.0, 0.0, false);
223 BarStepCase(*project, "bar_1_4", 0.0, 1.0, true);
224 BarStepCase(*project, "bar_1_4", 4.0, 3.0, false);
225}
TEST_CASE("Snapping", "")
void TimeStepCase(const AudacityProject &project, const char *format, double time, double expected, bool upwards, bool successful)
void BeatsCase(AudacityProject &project, const char *format, double time, double expected, bool nearest, int upper, int lower)
void BarStepCase(AudacityProject &project, const char *format, double time, double expected, bool upwards)
void TimeCase(const AudacityProject &project, const char *format, double time, double expected, bool nearest)
const auto project
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static std::shared_ptr< AudacityProject > Create()
Use this factory function.
Definition: Project.cpp:78
static ProjectTimeSignature & Get(AudacityProject &project)
static SnapResult Snap(const Identifier &id, const AudacityProject &project, double time, bool nearest)
Definition: SnapUtils.cpp:146
static SnapResult SingleStep(const Identifier &id, const AudacityProject &project, double time, bool upwards)
Definition: SnapUtils.cpp:158