Audacity 3.2.0
Channel.h
Go to the documentation of this file.
1/*!********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file Channel.h
6 @brief Abstract class ChannelGroup with two discrete iterable dimensions,
7 channels and intervals; subclasses associate information with those and
8 their intersections
9
10 Dominic Mazzoni
11
12 Paul Licameli split from Track.h
13
14**********************************************************************/
15#ifndef __AUDACITY_CHANNEL__
16#define __AUDACITY_CHANNEL__
17
18#include <cassert>
19#include <optional>
20#include <vector>
21
22#include "ClientData.h"
23#include "IteratorX.h"
24
26
29class CHANNEL_API ChannelGroupInterval {
30public:
32
34
36 virtual double Start() const = 0;
38 virtual double End() const = 0;
39};
40
42class CHANNEL_API ChannelInterval {
43public:
45};
46
47class ChannelGroup;
48
51
57public:
59
61
64 virtual size_t NChannels() const = 0;
65
67
73 template<typename IntervalType = ChannelInterval>
74 std::shared_ptr<IntervalType> GetChannel(size_t iChannel)
75 {
76 return
77 std::dynamic_pointer_cast<IntervalType>(DoGetChannel(iChannel));
78 }
79
83 template<typename IntervalType = const ChannelInterval>
84 auto GetChannel(size_t iChannel) const
85 -> std::enable_if_t<std::is_const_v<IntervalType>,
86 std::shared_ptr<IntervalType>>
87 {
88 return std::dynamic_pointer_cast<IntervalType>(
89 const_cast<WideChannelGroupInterval*>(this)->DoGetChannel(iChannel));
90 }
91
94 template<typename IntervalType>
96 : public ValueIterator<
97 std::shared_ptr<IntervalType>, std::bidirectional_iterator_tag
98 >
99 {
100 using GroupType = std::conditional_t<std::is_const_v<IntervalType>,
102 public:
103 ChannelIterator() = default;
104 ChannelIterator(GroupType *pGroup, size_t index)
105 : mpGroup{ pGroup }, mIndex{ index }
106 {}
107
108 std::shared_ptr<IntervalType> operator *() const
109 {
110 if (!mpGroup || mIndex >= mpGroup->NChannels())
111 return {};
112 return mpGroup->template GetChannel<IntervalType>(mIndex);
113 }
114
115 ChannelIterator &operator ++() { ++mIndex; return *this; }
116 ChannelIterator operator ++(int)
117 { auto copy{ *this }; operator ++(); return copy; }
118
119 ChannelIterator &operator --() { --mIndex; return *this; }
120 ChannelIterator operator --(int)
121 { auto copy{ *this }; operator --(); return copy; }
122
124 { return a.mpGroup == b.mpGroup && a.mIndex == b.mIndex; }
126 { return !(a == b); }
127
128 private:
129 GroupType *mpGroup{};
130 size_t mIndex{};
131 };
132
134 template<typename IntervalType = ChannelInterval>
136 {
137 return { { this, 0 }, { this, NChannels() } };
138 }
139
141 template<typename IntervalType = const ChannelInterval>
142 auto Channels() const
143 -> std::enable_if_t<std::is_const_v<IntervalType>,
144 IteratorRange<ChannelIterator<IntervalType>>
145 >
146 {
147 return { { this, 0 }, { this, NChannels() } };
148 }
149
150protected:
152
155 virtual std::shared_ptr<ChannelInterval> DoGetChannel(size_t iChannel) = 0;
156};
157
158class CHANNEL_API Channel
159{
160public:
161 virtual ~Channel();
162
164 ChannelGroup &GetChannelGroup();
168 const ChannelGroup &GetChannelGroup() const;
169
173 size_t GetChannelIndex() const;
174
181
183 size_t NIntervals() const;
184
186
190 template<typename IntervalType = Interval>
191 std::shared_ptr<IntervalType> GetInterval(size_t iInterval);
192
196 template<typename IntervalType = const Interval>
197 auto GetInterval(size_t iInterval) const
198 -> std::enable_if_t<std::is_const_v<IntervalType>,
199 std::shared_ptr<IntervalType>>;
200
203
207 template<typename IntervalType>
209 : public ValueIterator<
210 std::shared_ptr<IntervalType>, std::bidirectional_iterator_tag
211 >
212 {
213 using ChannelType = std::conditional_t<std::is_const_v<IntervalType>,
214 const Channel, Channel>;
215 public:
216 IntervalIterator() = default;
217 IntervalIterator(ChannelType *pChannel, size_t index)
218 : mpChannel{ pChannel }, mIndex{ index }
219 {}
220
221 std::shared_ptr<IntervalType> operator *() const
222 {
223 if (!mpChannel || mIndex >= mpChannel->NIntervals())
224 return {};
225 return mpChannel->template GetInterval<IntervalType>(mIndex);
226 }
227
228 IntervalIterator &operator ++() { ++mIndex; return *this; }
229 IntervalIterator operator ++(int)
230 { auto copy{ *this }; operator ++(); return copy; }
231
232 IntervalIterator &operator --() { --mIndex; return *this; }
233 IntervalIterator operator --(int)
234 { auto copy{ *this }; operator --(); return copy; }
235
237 { return a.mpChannel == b.mpChannel && a.mIndex == b.mIndex; }
239 { return !(a == b); }
240
241 private:
242 ChannelType *mpChannel{};
243 size_t mIndex{};
244 };
245
247 template<typename IntervalType = Interval>
249 {
250 return { { this, 0 }, { this, NIntervals() } };
251 }
252
254 template<typename IntervalType = const Interval>
255 auto Intervals() const
256 -> std::enable_if_t<std::is_const_v<IntervalType>,
257 IteratorRange<IntervalIterator<IntervalType>>
258 >
259 {
260 return { { this, 0 }, { this, NIntervals() } };
261 }
262
267protected:
269
273 virtual ChannelGroup &DoGetChannelGroup() const = 0;
274
275private:
276};
277
281>;
282
283class CHANNEL_API ChannelGroup : public ChannelGroupAttachments
284{
285public:
287
288 virtual ~ChannelGroup();
289
291 double GetStartTime() const;
293 double GetEndTime() const;
294
296 void ShiftBy(double t) { MoveTo(GetStartTime() + t); }
297
299 virtual void ShiftBy(double t0, double delta) = 0;
300
302 virtual void MoveTo(double o) = 0;
303
310
313 virtual size_t NChannels() const = 0;
314
316
322 template<typename ChannelType = Channel>
323 std::shared_ptr<ChannelType> GetChannel(size_t iChannel)
324 {
325 return
326 std::dynamic_pointer_cast<ChannelType>(DoGetChannel(iChannel));
327 }
328
332 template<typename ChannelType = const Channel>
333 auto GetChannel(size_t iChannel) const
334 -> std::enable_if_t<std::is_const_v<ChannelType>,
335 std::shared_ptr<ChannelType>>
336 {
337 return std::dynamic_pointer_cast<ChannelType>(
338 const_cast<ChannelGroup*>(this)->DoGetChannel(iChannel));
339 }
340
343 template<typename ChannelType>
345 : public ValueIterator<
346 std::shared_ptr<ChannelType>, std::bidirectional_iterator_tag
347 >
348 {
349 using GroupType = std::conditional_t<std::is_const_v<ChannelType>,
351 public:
352 ChannelIterator() = default;
353 ChannelIterator(GroupType *pGroup, size_t index)
354 : mpGroup{ pGroup }, mIndex{ index }
355 {}
356
357 std::shared_ptr<ChannelType> operator *() const
358 {
359 if (!mpGroup || mIndex >= mpGroup->NChannels())
360 return {};
361 return mpGroup->template GetChannel<ChannelType>(mIndex);
362 }
363
364 ChannelIterator &operator ++() { ++mIndex; return *this; }
365 ChannelIterator operator ++(int)
366 { auto copy{ *this }; operator ++(); return copy; }
367
368 ChannelIterator &operator --() { --mIndex; return *this; }
369 ChannelIterator operator --(int)
370 { auto copy{ *this }; operator --(); return copy; }
371
373 { return a.mpGroup == b.mpGroup && a.mIndex == b.mIndex; }
375 { return !(a == b); }
376
377 private:
378 GroupType *mpGroup{};
379 size_t mIndex{};
380 };
381
383 template<typename ChannelType = Channel>
385 {
386 return { { this, 0 }, { this, NChannels() } };
387 }
388
390 template<typename ChannelType = const Channel>
391 auto Channels() const
392 -> std::enable_if_t<std::is_const_v<ChannelType>,
394 >
395 {
396 return { { this, 0 }, { this, NChannels() } };
397 }
398
399 std::shared_ptr<Channel> NthChannel(size_t nChannel)
400 {
401 auto iter = Channels().begin();
402 std::advance(iter, nChannel);
403 return *iter;
404 }
405
406 std::shared_ptr<const Channel> NthChannel(size_t nChannel) const
407 {
408 auto iter = Channels().begin();
409 std::advance(iter, nChannel);
410 return *iter;
411 }
412
420
422 virtual size_t NIntervals() const = 0;
423
425
429 template<typename IntervalType = Interval>
430 std::shared_ptr<IntervalType> GetInterval(size_t iInterval)
431 {
432 return
433 std::dynamic_pointer_cast<IntervalType>(DoGetInterval(iInterval));
434 }
435
439 template<typename IntervalType = const Interval>
440 auto GetInterval(size_t iInterval) const
441 -> std::enable_if_t<std::is_const_v<IntervalType>,
442 std::shared_ptr<IntervalType>>
443 {
444 return std::dynamic_pointer_cast<IntervalType>(
445 const_cast<ChannelGroup*>(this)->DoGetInterval(iInterval));
446 }
447
450
454 template<typename IntervalType>
456 : public ValueIterator<
457 std::shared_ptr<IntervalType>, std::bidirectional_iterator_tag
458 >
459 {
460 using GroupType = std::conditional_t<std::is_const_v<IntervalType>,
462 public:
463 IntervalIterator() = default;
464 IntervalIterator(GroupType *pGroup, size_t index)
465 : mpGroup{ pGroup }, mIndex{ index }
466 {}
467
468 std::shared_ptr<IntervalType> operator *() const
469 {
470 if (!mpGroup || mIndex >= mpGroup->NIntervals())
471 return {};
472 return mpGroup->template GetInterval<IntervalType>(mIndex);
473 }
474
475 IntervalIterator &operator ++() { ++mIndex; return *this; }
476 IntervalIterator operator ++(int)
477 { auto copy{ *this }; operator ++(); return copy; }
478
479 IntervalIterator &operator --() { --mIndex; return *this; }
480 IntervalIterator operator --(int)
481 { auto copy{ *this }; operator --(); return copy; }
482
484 { return a.mpGroup == b.mpGroup && a.mIndex == b.mIndex; }
486 { return !(a == b); }
487
488 private:
489 GroupType *mpGroup{};
490 size_t mIndex{};
491 };
492
494 template<typename IntervalType = Interval>
496 {
497 return { { this, 0 }, { this, NIntervals() } };
498 }
499
501 template<typename IntervalType = const Interval>
502 auto Intervals() const
503 -> std::enable_if_t<std::is_const_v<IntervalType>,
504 IteratorRange<IntervalIterator<IntervalType>>
505 >
506 {
507 return { { this, 0 }, { this, NIntervals() } };
508 }
509
515 enum class LinkType : int {
516 None = 0,
517 // 1 - reserved for backward compatibility with projects generated by
518 // older versions of Audacity
519 Group = 2,
521 Aligned,
522 };
523
524protected:
528
531 virtual std::shared_ptr<Channel> DoGetChannel(size_t iChannel) = 0;
532
534
537 virtual std::shared_ptr<Interval> DoGetInterval(size_t iInterval) = 0;
538};
539
540inline size_t Channel::NIntervals() const
541{
542 return GetChannelGroup().NIntervals();
543}
544
545template<typename IntervalType>
546std::shared_ptr<IntervalType> Channel::GetInterval(size_t iInterval)
547{
548 return DoGetChannelGroup().GetInterval(iInterval)
549 ->template GetChannel<IntervalType>(GetChannelIndex());
550}
551
552template<typename IntervalType>
553auto Channel::GetInterval(size_t iInterval) const
554 -> std::enable_if_t<std::is_const_v<IntervalType>,
555 std::shared_ptr<IntervalType>>
556{
557 return DoGetChannelGroup().GetInterval(iInterval)
558 ->template GetChannel<IntervalType>(GetChannelIndex());
559}
560#endif
ClientData::Site< ChannelGroup, ClientData::Cloneable<>, ClientData::DeepCopying > ChannelGroupAttachments
Hosting of objects attached by higher level code.
Definition: Channel.h:281
Utility ClientData::Site to register hooks into a host class that attach client data.
auto operator*(PffftAlignedCount x, Integral y) -> std::enable_if_t< std::is_unsigned_v< Integral > &&sizeof(Integral)<=sizeof(size_t), PffftAlignedCount >
bool operator==(const WaveTrackLocation &a, const WaveTrackLocation &b)
bool operator!=(const WaveTrackLocation &a, const WaveTrackLocation &b)
IntervalIterator(ChannelType *pChannel, size_t index)
Definition: Channel.h:217
ChannelType * mpChannel
Definition: Channel.h:242
std::conditional_t< std::is_const_v< IntervalType >, const Channel, Channel > ChannelType
Definition: Channel.h:214
std::conditional_t< std::is_const_v< ChannelType >, const ChannelGroup, ChannelGroup > GroupType
Definition: Channel.h:350
ChannelIterator(GroupType *pGroup, size_t index)
Definition: Channel.h:353
std::conditional_t< std::is_const_v< IntervalType >, const ChannelGroup, ChannelGroup > GroupType
Definition: Channel.h:461
IntervalIterator(GroupType *pGroup, size_t index)
Definition: Channel.h:464
auto Channels() const -> std::enable_if_t< std::is_const_v< ChannelType >, IteratorRange< ChannelIterator< ChannelType > > >
Get range of channels with read-only access.
Definition: Channel.h:391
auto Intervals() const -> std::enable_if_t< std::is_const_v< IntervalType >, IteratorRange< IntervalIterator< IntervalType > > >
Get range of intervals with read-only access.
Definition: Channel.h:502
virtual void MoveTo(double o)=0
Change start time to given time point.
LinkType
For two tracks describes the type of the linkage.
Definition: Channel.h:515
virtual size_t NIntervals() const =0
Report the number of intervals.
IteratorRange< ChannelIterator< ChannelType > > Channels()
Get range of channels with mutative access.
Definition: Channel.h:384
auto GetChannel(size_t iChannel) const -> std::enable_if_t< std::is_const_v< ChannelType >, std::shared_ptr< ChannelType > >
Definition: Channel.h:333
void ShiftBy(double t)
Change start time by given duration.
Definition: Channel.h:296
virtual std::shared_ptr< Interval > DoGetInterval(size_t iInterval)=0
Retrieve an interval.
auto GetInterval(size_t iInterval) const -> std::enable_if_t< std::is_const_v< IntervalType >, std::shared_ptr< IntervalType > >
Definition: Channel.h:440
IteratorRange< IntervalIterator< IntervalType > > Intervals()
Get range of intervals with mutative access.
Definition: Channel.h:495
std::shared_ptr< IntervalType > GetInterval(size_t iInterval)
Retrieve an interval, cast to the given type.
Definition: Channel.h:430
std::shared_ptr< const Channel > NthChannel(size_t nChannel) const
Definition: Channel.h:406
virtual void ShiftBy(double t0, double delta)=0
Shift all intervals that starts after t0 by delta seconds.
virtual size_t NChannels() const =0
Report the number of channels.
std::shared_ptr< ChannelType > GetChannel(size_t iChannel)
Retrieve a channel, cast to the given type.
Definition: Channel.h:323
virtual std::shared_ptr< Channel > DoGetChannel(size_t iChannel)=0
std::shared_ptr< Channel > NthChannel(size_t nChannel)
Definition: Channel.h:399
virtual ~ChannelGroup()
A start and an end time, and whatever else subclasses associate with them.
Definition: Channel.h:29
virtual ~ChannelGroupInterval()
virtual double Start() const =0
ChannelGroupInterval()=default
virtual double End() const =0
auto Intervals() const -> std::enable_if_t< std::is_const_v< IntervalType >, IteratorRange< IntervalIterator< IntervalType > > >
Get range of intervals with read-only access.
Definition: Channel.h:255
size_t NIntervals() const
Report the number of intervals.
Definition: Channel.h:540
std::shared_ptr< IntervalType > GetInterval(size_t iInterval)
Retrieve an interval, cast to the given type.
Definition: Channel.h:546
virtual ~Channel()
IteratorRange< IntervalIterator< IntervalType > > Intervals()
Get range of intervals with mutative access.
Definition: Channel.h:248
ChannelGroup & GetChannelGroup()
Channel object's lifetime is assumed to be nested in its Track's.
Definition: Channel.cpp:43
virtual ChannelGroup & DoGetChannelGroup() const =0
Subclass must override.
size_t GetChannelIndex() const
Definition: Channel.cpp:25
The intersection of a Channel and a WideChannelGroupInterval.
Definition: Channel.h:42
virtual ~ChannelInterval()
Utility to register hooks into a host class that attach client data.
Definition: ClientData.h:229
std::conditional_t< std::is_const_v< IntervalType >, const WideChannelGroupInterval, WideChannelGroupInterval > GroupType
Definition: Channel.h:101
ChannelIterator(GroupType *pGroup, size_t index)
Definition: Channel.h:104
IteratorRange< ChannelIterator< IntervalType > > Channels()
Get range of ChannelInterval objects with mutative access.
Definition: Channel.h:135
virtual size_t NChannels() const =0
Report the number of channels.
auto GetChannel(size_t iChannel) const -> std::enable_if_t< std::is_const_v< IntervalType >, std::shared_ptr< IntervalType > >
Definition: Channel.h:84
~WideChannelGroupInterval() override
auto Channels() const -> std::enable_if_t< std::is_const_v< IntervalType >, IteratorRange< ChannelIterator< IntervalType > > >
Get range of channels with read-only access.
Definition: Channel.h:142
std::shared_ptr< IntervalType > GetChannel(size_t iChannel)
Retrieve a channel, cast to the given type.
Definition: Channel.h:74
virtual std::shared_ptr< ChannelInterval > DoGetChannel(size_t iChannel)=0
Retrieve a channel.
ChannelType
Mutually exclusive channel classifications.
@ DeepCopying
point to new sub-objects; these must define a Clone() member; won't compile for std::weak_ptr
MenuRegistry::GroupItem< MenuRegistry::Traits > Group
Definition: MenuHelper.h:11
void copy(const T *src, T *dst, int32_t n)
Definition: VectorOps.h:40
STL namespace.
A convenient base class defining abstract virtual Clone() for a given kind of pointer.
Definition: ClientData.h:50
A convenience for use with range-for.
Definition: IteratorX.h:39
A convenience for defining iterators that return rvalue types, so that they cooperate correctly with ...
Definition: IteratorX.h:25