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 MoveTo(double o) = 0;
300
307
310 virtual size_t NChannels() const = 0;
311
313
319 template<typename ChannelType = Channel>
320 std::shared_ptr<ChannelType> GetChannel(size_t iChannel)
321 {
322 return
323 std::dynamic_pointer_cast<ChannelType>(DoGetChannel(iChannel));
324 }
325
329 template<typename ChannelType = const Channel>
330 auto GetChannel(size_t iChannel) const
331 -> std::enable_if_t<std::is_const_v<ChannelType>,
332 std::shared_ptr<ChannelType>>
333 {
334 return std::dynamic_pointer_cast<ChannelType>(
335 const_cast<ChannelGroup*>(this)->DoGetChannel(iChannel));
336 }
337
340 template<typename ChannelType>
342 : public ValueIterator<
343 std::shared_ptr<ChannelType>, std::bidirectional_iterator_tag
344 >
345 {
346 using GroupType = std::conditional_t<std::is_const_v<ChannelType>,
348 public:
349 ChannelIterator() = default;
350 ChannelIterator(GroupType *pGroup, size_t index)
351 : mpGroup{ pGroup }, mIndex{ index }
352 {}
353
354 std::shared_ptr<ChannelType> operator *() const
355 {
356 if (!mpGroup || mIndex >= mpGroup->NChannels())
357 return {};
358 return mpGroup->template GetChannel<ChannelType>(mIndex);
359 }
360
361 ChannelIterator &operator ++() { ++mIndex; return *this; }
362 ChannelIterator operator ++(int)
363 { auto copy{ *this }; operator ++(); return copy; }
364
365 ChannelIterator &operator --() { --mIndex; return *this; }
366 ChannelIterator operator --(int)
367 { auto copy{ *this }; operator --(); return copy; }
368
370 { return a.mpGroup == b.mpGroup && a.mIndex == b.mIndex; }
372 { return !(a == b); }
373
374 private:
375 GroupType *mpGroup{};
376 size_t mIndex{};
377 };
378
380 template<typename ChannelType = Channel>
382 {
383 return { { this, 0 }, { this, NChannels() } };
384 }
385
387 template<typename ChannelType = const Channel>
388 auto Channels() const
389 -> std::enable_if_t<std::is_const_v<ChannelType>,
391 >
392 {
393 return { { this, 0 }, { this, NChannels() } };
394 }
395
396 std::shared_ptr<Channel> NthChannel(size_t nChannel)
397 {
398 auto iter = Channels().begin();
399 std::advance(iter, nChannel);
400 return *iter;
401 }
402
403 std::shared_ptr<const Channel> NthChannel(size_t nChannel) const
404 {
405 auto iter = Channels().begin();
406 std::advance(iter, nChannel);
407 return *iter;
408 }
409
417
419 virtual size_t NIntervals() const = 0;
420
422
426 template<typename IntervalType = Interval>
427 std::shared_ptr<IntervalType> GetInterval(size_t iInterval)
428 {
429 return
430 std::dynamic_pointer_cast<IntervalType>(DoGetInterval(iInterval));
431 }
432
436 template<typename IntervalType = const Interval>
437 auto GetInterval(size_t iInterval) const
438 -> std::enable_if_t<std::is_const_v<IntervalType>,
439 std::shared_ptr<IntervalType>>
440 {
441 return std::dynamic_pointer_cast<IntervalType>(
442 const_cast<ChannelGroup*>(this)->DoGetInterval(iInterval));
443 }
444
447
451 template<typename IntervalType>
453 : public ValueIterator<
454 std::shared_ptr<IntervalType>, std::bidirectional_iterator_tag
455 >
456 {
457 using GroupType = std::conditional_t<std::is_const_v<IntervalType>,
459 public:
460 IntervalIterator() = default;
461 IntervalIterator(GroupType *pGroup, size_t index)
462 : mpGroup{ pGroup }, mIndex{ index }
463 {}
464
465 std::shared_ptr<IntervalType> operator *() const
466 {
467 if (!mpGroup || mIndex >= mpGroup->NIntervals())
468 return {};
469 return mpGroup->template GetInterval<IntervalType>(mIndex);
470 }
471
472 IntervalIterator &operator ++() { ++mIndex; return *this; }
473 IntervalIterator operator ++(int)
474 { auto copy{ *this }; operator ++(); return copy; }
475
476 IntervalIterator &operator --() { --mIndex; return *this; }
477 IntervalIterator operator --(int)
478 { auto copy{ *this }; operator --(); return copy; }
479
481 { return a.mpGroup == b.mpGroup && a.mIndex == b.mIndex; }
483 { return !(a == b); }
484
485 private:
486 GroupType *mpGroup{};
487 size_t mIndex{};
488 };
489
491 template<typename IntervalType = Interval>
493 {
494 return { { this, 0 }, { this, NIntervals() } };
495 }
496
498 template<typename IntervalType = const Interval>
499 auto Intervals() const
500 -> std::enable_if_t<std::is_const_v<IntervalType>,
501 IteratorRange<IntervalIterator<IntervalType>>
502 >
503 {
504 return { { this, 0 }, { this, NIntervals() } };
505 }
506
512 enum class LinkType : int {
513 None = 0,
514 // 1 - reserved for backward compatibility with projects generated by
515 // older versions of Audacity
516 Group = 2,
518 Aligned,
519 };
520
521protected:
525
528 virtual std::shared_ptr<Channel> DoGetChannel(size_t iChannel) = 0;
529
531
534 virtual std::shared_ptr<Interval> DoGetInterval(size_t iInterval) = 0;
535};
536
537inline size_t Channel::NIntervals() const
538{
539 return GetChannelGroup().NIntervals();
540}
541
542template<typename IntervalType>
543std::shared_ptr<IntervalType> Channel::GetInterval(size_t iInterval)
544{
545 return DoGetChannelGroup().GetInterval(iInterval)
546 ->template GetChannel<IntervalType>(GetChannelIndex());
547}
548
549template<typename IntervalType>
550auto Channel::GetInterval(size_t iInterval) const
551 -> std::enable_if_t<std::is_const_v<IntervalType>,
552 std::shared_ptr<IntervalType>>
553{
554 return DoGetChannelGroup().GetInterval(iInterval)
555 ->template GetChannel<IntervalType>(GetChannelIndex());
556}
557#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 EffectReverbSettings &a, const EffectReverbSettings &b)
Definition: Reverb.cpp:632
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:347
ChannelIterator(GroupType *pGroup, size_t index)
Definition: Channel.h:350
std::conditional_t< std::is_const_v< IntervalType >, const ChannelGroup, ChannelGroup > GroupType
Definition: Channel.h:458
IntervalIterator(GroupType *pGroup, size_t index)
Definition: Channel.h:461
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:388
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:499
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:512
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:381
auto GetChannel(size_t iChannel) const -> std::enable_if_t< std::is_const_v< ChannelType >, std::shared_ptr< ChannelType > >
Definition: Channel.h:330
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:437
IteratorRange< IntervalIterator< IntervalType > > Intervals()
Get range of intervals with mutative access.
Definition: Channel.h:492
std::shared_ptr< IntervalType > GetInterval(size_t iInterval)
Retrieve an interval, cast to the given type.
Definition: Channel.h:427
std::shared_ptr< const Channel > NthChannel(size_t nChannel) const
Definition: Channel.h:403
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:320
virtual std::shared_ptr< Channel > DoGetChannel(size_t iChannel)=0
std::shared_ptr< Channel > NthChannel(size_t nChannel)
Definition: Channel.h:396
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:537
std::shared_ptr< IntervalType > GetInterval(size_t iInterval)
Retrieve an interval, cast to the given type.
Definition: Channel.h:543
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