Audacity 3.2.0
TimeTrack.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 TimeTrack.cpp
6
7 Dr William Bland
8
9*******************************************************************//*******************************************************************/
15
16
17#include "TimeTrack.h"
18
19#include "ActiveProject.h"
20#include <cfloat>
21#include <wx/wxcrtvararg.h>
22#include <wx/dc.h>
23#include <wx/intl.h>
24#include "widgets/Ruler.h"
25#include "Envelope.h"
26#include "Mix.h"
27#include "Project.h"
28#include "ProjectRate.h"
29#include "ViewInfo.h"
30
31
32//TODO-MB: are these sensible values?
33#define TIMETRACK_MIN 0.01
34#define TIMETRACK_MAX 10.0
35
37 "timetrack",
39};
40
42{
43 return _("Time Track");
44}
45
47{
48 auto &tracks = TrackList::Get( project );
49 auto &viewInfo = ViewInfo::Get( project );
50 auto result = tracks.Add(std::make_shared<TimeTrack>(&viewInfo));
51 result->AttachedTrackObjects::BuildAll();
52 return result;
53}
54
56 Track()
57 , mZoomInfo(zoomInfo)
58{
59 CleanState();
60}
61
63{
64 mEnvelope = std::make_unique<BoundedEnvelope>(true, TIMETRACK_MIN, TIMETRACK_MAX, 1.0);
65
66 SetRangeLower( 0.9 );
67 SetRangeUpper( 1.1 );
68 mDisplayLog = false;
69
70 mEnvelope->SetTrackLen(DBL_MAX);
71 mEnvelope->SetOffset(0);
72
73 //Time track is always unique
75
76 mRuler = std::make_unique<Ruler>();
77 mRuler->SetUseZoomInfo(0, mZoomInfo);
78 mRuler->SetLabelEdges(false);
79 mRuler->SetFormat(Ruler::TimeFormat);
80}
81
83 double *pT0, double *pT1
84) : Track(orig, std::move(a))
85 , mZoomInfo(orig.mZoomInfo)
86{
87 Init(orig); // this copies the TimeTrack metadata (name, range, etc)
88
89 auto len = DBL_MAX;
90 if (pT0 && pT1) {
91 len = *pT1 - *pT0;
92 mEnvelope = std::make_unique<BoundedEnvelope>( *orig.mEnvelope, *pT0, *pT1 );
93 }
94 else
95 mEnvelope = std::make_unique<BoundedEnvelope>( *orig.mEnvelope );
96
99
100 mEnvelope->SetTrackLen( len );
101 mEnvelope->SetOffset(0);
102
104 mRuler = std::make_unique<Ruler>();
105 mRuler->SetUseZoomInfo(0, mZoomInfo);
106 mRuler->SetLabelEdges(false);
107 mRuler->SetFormat(Ruler::TimeFormat);
108}
109
110// Copy the track metadata but not the contents.
111void TimeTrack::Init(const TimeTrack &orig)
112{
113 Track::Init(orig);
114 SetName(orig.GetName());
116}
117
119{
120}
121
123{
124 return mEnvelope->GetRangeLower();
125}
126
128{
129 return mEnvelope->GetRangeUpper();
130}
131
132void TimeTrack::SetRangeLower(double lower)
133{
134 mEnvelope->SetRangeLower( lower );
135}
136
137void TimeTrack::SetRangeUpper(double upper)
138{
139 mEnvelope->SetRangeUpper( upper );
140}
141
143{
144 static const Track::TypeInfo info{
145 { "time", "time", XO("Time Track") }, true, &Track::ClassTypeInfo() };
146 return info;
147}
148
149auto TimeTrack::GetTypeInfo() const -> const TypeInfo &
150{
151 return typeInfo();
152}
153
155{
156 return typeInfo();
157}
158
160{
161 return false;
162}
163
165{
166 // Maintain uniqueness of the time track!
167 std::shared_ptr<TimeTrack> pNewTrack;
168 if( auto pTrack = *TrackList::Get( project ).Any<TimeTrack>().begin() )
169 pNewTrack = pTrack->SharedPointer<TimeTrack>();
170 else
171 pNewTrack = std::make_shared<TimeTrack>( &ViewInfo::Get( project ) );
172
173 // Should come here only for .aup3 import, not for paste (because the
174 // track is skipped in cut/copy commands)
175 // And for import we agree to replace the track contents completely
176 pNewTrack->CleanState();
177 pNewTrack->Init(*this);
178 pNewTrack->Paste(0.0, this);
179 pNewTrack->SetRangeLower(this->GetRangeLower());
180 pNewTrack->SetRangeUpper(this->GetRangeUpper());
181 return pNewTrack;
182}
183
184Track::Holder TimeTrack::Cut( double t0, double t1 )
185{
186 auto result = Copy( t0, t1, false );
187 Clear( t0, t1 );
188 return result;
189}
190
191Track::Holder TimeTrack::Copy( double t0, double t1, bool ) const
192{
193 auto result = std::make_shared<TimeTrack>(*this, ProtectedCreationArg{}, &t0, &t1);
194 result->Init(*this);
195 return result;
196}
197
198namespace {
199double GetRate() {
200 auto pProject = GetActiveProject().lock();
201 return pProject
202 ? ProjectRate::Get( *pProject ).GetRate()
203 : 44100.0;
204}
205}
206
207void TimeTrack::Clear(double t0, double t1)
208{
209 auto sampleTime = 1.0 / GetRate();
210 mEnvelope->CollapseRegion( t0, t1, sampleTime );
211}
212
213void TimeTrack::Paste(double t, const Track * src)
214{
215 bool bOk = src && src->TypeSwitch< bool >( [&] (const TimeTrack *tt) {
216 auto sampleTime = 1.0 / GetRate();
217 mEnvelope->PasteEnvelope
218 (t, tt->mEnvelope.get(), sampleTime);
219 return true;
220 } );
221
222 if (! bOk )
223 // THROW_INCONSISTENCY_EXCEPTION // ?
224 (void)0;// intentionally do nothing.
225}
226
227void TimeTrack::Silence(double WXUNUSED(t0), double WXUNUSED(t1))
228{
229}
230
231void TimeTrack::InsertSilence(double t, double len)
232{
233 mEnvelope->InsertSpace(t, len);
234}
235
237{
238 auto result = std::make_shared<TimeTrack>(*this, ProtectedCreationArg{});
239 result->Init(*this);
240 return result;
241}
242
244{
245 return mEnvelope->GetExponential();
246}
247
248void TimeTrack::SetInterpolateLog(bool interpolateLog) {
249 mEnvelope->SetExponential(interpolateLog);
250}
251
252bool TimeTrack::HandleXMLTag(const std::string_view& tag, const AttributesList &attrs)
253{
254 if (tag == "timetrack") {
255 mRescaleXMLValues = true; // will be set to false if upper/lower is found
256
257 long nValue;
258
259 for (auto pair : attrs)
260 {
261 auto attr = pair.first;
262 auto value = pair.second;
263
264 if (this->Track::HandleCommonXMLAttribute(attr, value))
265 ;
266 else if (attr == "rangelower")
267 {
268 SetRangeLower( value.Get(GetRangeLower()) );
269 mRescaleXMLValues = false;
270 }
271 else if (attr == "rangeupper")
272 {
273 SetRangeUpper( value.Get(GetRangeUpper()) );
274 mRescaleXMLValues = false;
275 }
276 else if (attr == "displaylog" && value.TryGet(nValue))
277 {
278 SetDisplayLog(nValue != 0);
279 //TODO-MB: This causes a graphical glitch, TrackPanel should probably be Refresh()ed after loading.
280 // I don't know where to do this though.
281 }
282 else if (attr == "interpolatelog" && value.TryGet(nValue))
283 {
284 SetInterpolateLog(nValue != 0);
285 }
286
287 } // while
289 mEnvelope->SetRange(0.0, 1.0); // this will be restored to the actual range later
290 return true;
291 }
292
293 return false;
294}
295
296void TimeTrack::HandleXMLEndTag(const std::string_view& WXUNUSED(tag))
297{
299 {
300 mRescaleXMLValues = false;
301 mEnvelope->RescaleValues(GetRangeLower(), GetRangeUpper());
303 }
304}
305
306XMLTagHandler *TimeTrack::HandleXMLChild(const std::string_view& tag)
307{
308 if (tag == "envelope")
309 return mEnvelope.get();
310
311 return NULL;
312}
313
314void TimeTrack::WriteXML(XMLWriter &xmlFile) const
315// may throw
316{
317 xmlFile.StartTag(wxT("timetrack"));
318 this->Track::WriteCommonXMLAttributes( xmlFile );
319
320 //xmlFile.WriteAttr(wxT("channel"), mChannel);
321 //xmlFile.WriteAttr(wxT("offset"), mOffset, 8);
322 xmlFile.WriteAttr(wxT("rangelower"), GetRangeLower(), 12);
323 xmlFile.WriteAttr(wxT("rangeupper"), GetRangeUpper(), 12);
324 xmlFile.WriteAttr(wxT("displaylog"), GetDisplayLog());
325 xmlFile.WriteAttr(wxT("interpolatelog"), GetInterpolateLog());
326
327 mEnvelope->WriteXML(xmlFile);
328
329 xmlFile.EndTag(wxT("timetrack"));
330}
331
333{
334 GetEnvelope()->Flatten(0.0);
335 GetEnvelope()->InsertOrReplace(0.0, 0.2);
336 GetEnvelope()->InsertOrReplace(5.0 - 0.001, 0.2);
337 GetEnvelope()->InsertOrReplace(5.0 + 0.001, 1.3);
338 GetEnvelope()->InsertOrReplace(10.0, 1.3);
339
340 double value1 = GetEnvelope()->Integral(2.0, 13.0);
341 double expected1 = (5.0 - 2.0) * 0.2 + (13.0 - 5.0) * 1.3;
342 double value2 = GetEnvelope()->IntegralOfInverse(2.0, 13.0);
343 double expected2 = (5.0 - 2.0) / 0.2 + (13.0 - 5.0) / 1.3;
344 if( fabs(value1 - expected1) > 0.01 )
345 {
346 wxPrintf( "TimeTrack: Integral failed! expected %f got %f\n", expected1, value1);
347 }
348 if( fabs(value2 - expected2) > 0.01 )
349 {
350 wxPrintf( "TimeTrack: IntegralOfInverse failed! expected %f got %f\n", expected2, value2);
351 }
352
353 /*double reqt0 = 10.0 - .1;
354 double reqt1 = 10.0 + .1;
355 double t0 = warp( reqt0 );
356 double t1 = warp( reqt1 );
357 if( t0 > t1 )
358 {
359 wxPrintf( "TimeTrack: Warping reverses an interval! [%.2f,%.2f] -> [%.2f,%.2f]\n",
360 reqt0, reqt1,
361 t0, t1 );
362 }*/
363}
364
366static Mixer::WarpOptions::DefaultWarp::Scope installer{
367[](const TrackList &list) -> const BoundedEnvelope*
368{
369 if (auto pTimeTrack = *list.Any<const TimeTrack>().begin())
370 return pTimeTrack->GetEnvelope();
371 else
372 return nullptr;
373} };
AUDACITY_DLL_API std::weak_ptr< AudacityProject > GetActiveProject()
Handle changing of active project and keep global project pointer.
#define XO(s)
Definition: Internat.h:31
#define _(s)
Definition: Internat.h:75
an object holding per-project preferred sample rate
static Mixer::WarpOptions::DefaultWarp::Scope installer
Installer of the time warper.
Definition: TimeTrack.cpp:366
static ProjectFileIORegistry::ObjectReaderEntry readerEntry
Definition: TimeTrack.cpp:36
#define TIMETRACK_MAX
Definition: TimeTrack.cpp:34
#define TIMETRACK_MIN
Definition: TimeTrack.cpp:33
static const Track::TypeInfo & typeInfo()
Definition: TimeTrack.cpp:142
std::vector< Attribute > AttributesList
Definition: XMLTagHandler.h:40
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:89
double Integral(double t0, double t1) const
Definition: Envelope.cpp:1166
int InsertOrReplace(double when, double value)
Add a point at a particular absolute time coordinate.
Definition: Envelope.h:173
double IntegralOfInverse(double t0, double t1) const
Definition: Envelope.cpp:1229
void Flatten(double value)
Definition: Envelope.cpp:132
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:28
double GetRate() const
Definition: ProjectRate.cpp:53
@ TimeFormat
Definition: Ruler.h:33
A kind of Track used to 'warp time'.
Definition: TimeTrack.h:24
static wxString GetDefaultName()
Definition: TimeTrack.cpp:41
void Paste(double t, const Track *src) override
Definition: TimeTrack.cpp:213
void WriteXML(XMLWriter &xmlFile) const override
Definition: TimeTrack.cpp:314
void SetInterpolateLog(bool interpolateLog)
Definition: TimeTrack.cpp:248
void HandleXMLEndTag(const std::string_view &tag) override
Definition: TimeTrack.cpp:296
TimeTrack(const ZoomInfo *zoomInfo)
Definition: TimeTrack.cpp:55
static const TypeInfo & ClassTypeInfo()
Definition: TimeTrack.cpp:154
bool mRescaleXMLValues
Definition: TimeTrack.h:112
void SetDisplayLog(bool displayLog)
Definition: TimeTrack.h:97
const ZoomInfo *const mZoomInfo
Definition: TimeTrack.h:108
std::unique_ptr< BoundedEnvelope > mEnvelope
Definition: TimeTrack.h:109
Holder Copy(double t0, double t1, bool forClipboard) const override
Definition: TimeTrack.cpp:191
Track::Holder Clone() const override
Definition: TimeTrack.cpp:236
bool GetInterpolateLog() const
Definition: TimeTrack.cpp:243
bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs) override
Definition: TimeTrack.cpp:252
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
Definition: TimeTrack.cpp:306
void CleanState()
Definition: TimeTrack.cpp:62
Holder Cut(double t0, double t1) override
Definition: TimeTrack.cpp:184
std::unique_ptr< Ruler > mRuler
Definition: TimeTrack.h:110
BoundedEnvelope * GetEnvelope()
Definition: TimeTrack.h:85
bool GetDisplayLog() const
Definition: TimeTrack.h:96
void InsertSilence(double t, double len) override
Definition: TimeTrack.cpp:231
bool mDisplayLog
Definition: TimeTrack.h:111
void testMe()
Definition: TimeTrack.cpp:332
const TypeInfo & GetTypeInfo() const override
Definition: TimeTrack.cpp:149
void SetRangeLower(double lower)
Definition: TimeTrack.cpp:132
virtual ~TimeTrack()
Definition: TimeTrack.cpp:118
void Silence(double t0, double t1) override
Definition: TimeTrack.cpp:227
static TimeTrack * New(AudacityProject &project)
Definition: TimeTrack.cpp:46
double GetRangeLower() const
Definition: TimeTrack.cpp:122
double GetRangeUpper() const
Definition: TimeTrack.cpp:127
Holder PasteInto(AudacityProject &) const override
Find or create the destination track for a paste, maybe in a different project.
Definition: TimeTrack.cpp:164
void Clear(double t0, double t1) override
Definition: TimeTrack.cpp:207
bool SupportsBasicEditing() const override
Whether this track type implements cut-copy-paste; by default, true.
Definition: TimeTrack.cpp:159
void Init(const TimeTrack &orig)
Copy the metadata from another track but not the points.
Definition: TimeTrack.cpp:111
void SetRangeUpper(double upper)
Definition: TimeTrack.cpp:137
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:225
static const TypeInfo & ClassTypeInfo()
Definition: Track.cpp:1247
R TypeSwitch(const Functions &...functions)
Use this function rather than testing track type explicitly and making down-casts.
Definition: Track.h:832
std::shared_ptr< Track > Holder
Definition: Track.h:368
bool HandleCommonXMLAttribute(const std::string_view &attr, const XMLAttributeValueView &valueView)
Definition: Track.cpp:1283
wxString GetName() const
Definition: Track.h:466
void Init(const Track &orig)
Definition: Track.cpp:64
void WriteCommonXMLAttributes(XMLWriter &xmlFile, bool includeNameAndSelected=true) const
Definition: Track.cpp:1270
void SetName(const wxString &n)
Definition: Track.cpp:79
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:1336
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:486
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:42
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:26
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150
STL namespace.
Empty argument passed to some public constructors.
Definition: Track.h:232