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