OpenShot Audio Library | OpenShotAudio 0.4.0
Loading...
Searching...
No Matches
juce_AudioPlayHead.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26//==============================================================================
38class JUCE_API AudioPlayHead
39{
40protected:
41 //==============================================================================
42 AudioPlayHead() = default;
43
44public:
45 virtual ~AudioPlayHead() = default;
46
47 //==============================================================================
50 {
51 fps23976 = 0,
52 fps24 = 1,
53 fps25 = 2,
54 fps2997 = 3,
55 fps30 = 4,
56 fps2997drop = 5,
57 fps30drop = 6,
58 fps60 = 7,
59 fps60drop = 8,
60 fpsUnknown = 99
61 };
62
64 class JUCE_API FrameRate
65 {
66 public:
68 FrameRate() = default;
69
71 FrameRate (FrameRateType type) : FrameRate (fromType (type)) {}
72
79 {
80 switch (base)
81 {
82 case 24: return pulldown ? fps23976 : fps24;
83 case 25: return fps25;
84 case 30: return pulldown ? (drop ? fps2997drop : fps2997)
85 : (drop ? fps30drop : fps30);
86 case 60: return drop ? fps60drop : fps60;
87 }
88
89 return fpsUnknown;
90 }
91
93 int getBaseRate() const { return base; }
94
96 bool isDrop() const { return drop; }
97
99 bool isPullDown() const { return pulldown; }
100
102 double getEffectiveRate() const { return pulldown ? (double) base / 1.001 : (double) base; }
103
105 [[nodiscard]] FrameRate withBaseRate (int x) const { return with (&FrameRate::base, x); }
106
108 [[nodiscard]] FrameRate withDrop (bool x = true) const { return with (&FrameRate::drop, x); }
109
111 [[nodiscard]] FrameRate withPullDown (bool x = true) const { return with (&FrameRate::pulldown, x); }
112
114 bool operator== (const FrameRate& other) const
115 {
116 const auto tie = [] (const FrameRate& x) { return std::tie (x.base, x.drop, x.pulldown); };
117 return tie (*this) == tie (other);
118 }
119
121 bool operator!= (const FrameRate& other) const { return ! (*this == other); }
122
123 private:
124 static FrameRate fromType (FrameRateType type)
125 {
126 switch (type)
127 {
128 case fps23976: return FrameRate().withBaseRate (24).withPullDown();
129 case fps24: return FrameRate().withBaseRate (24);
130 case fps25: return FrameRate().withBaseRate (25);
131 case fps2997: return FrameRate().withBaseRate (30).withPullDown();
132 case fps30: return FrameRate().withBaseRate (30);
133 case fps2997drop: return FrameRate().withBaseRate (30).withDrop().withPullDown();
134 case fps30drop: return FrameRate().withBaseRate (30).withDrop();
135 case fps60: return FrameRate().withBaseRate (60);
136 case fps60drop: return FrameRate().withBaseRate (60).withDrop();
137 case fpsUnknown: break;
138 }
139
140 return {};
141 }
142
143 template <typename Member, typename Value>
144 FrameRate with (Member&& member, Value&& value) const
145 {
146 auto copy = *this;
147 copy.*member = std::forward<Value> (value);
148 return copy;
149 }
150
151 int base = 0;
152 bool drop = false, pulldown = false;
153 };
154
159 struct JUCE_API TimeSignature
160 {
162 int numerator = 4;
163
165 int denominator = 4;
166
167 bool operator== (const TimeSignature& other) const
168 {
169 const auto tie = [] (auto& x) { return std::tie (x.numerator, x.denominator); };
170 return tie (*this) == tie (other);
171 }
172
173 bool operator!= (const TimeSignature& other) const
174 {
175 return ! operator== (other);
176 }
177 };
178
183 struct JUCE_API LoopPoints
184 {
186 double ppqStart = 0;
187
189 double ppqEnd = 0;
190
191 bool operator== (const LoopPoints& other) const
192 {
193 const auto tie = [] (auto& x) { return std::tie (x.ppqStart, x.ppqEnd); };
194 return tie (*this) == tie (other);
195 }
196
197 bool operator!= (const LoopPoints& other) const
198 {
199 return ! operator== (other);
200 }
201 };
202
203 //==============================================================================
210 struct JUCE_API CurrentPositionInfo
211 {
213 double bpm = 120.0;
214
216 int timeSigNumerator = 4;
217
219 int timeSigDenominator = 4;
220
222 int64 timeInSamples = 0;
224 double timeInSeconds = 0;
225
227 double editOriginTime = 0;
228
230 double ppqPosition = 0;
231
240 double ppqPositionOfLastBarStart = 0;
241
243 FrameRate frameRate = FrameRateType::fps23976;
244
246 bool isPlaying = false;
247
252 bool isRecording = false;
253
258 double ppqLoopStart = 0;
259
264 double ppqLoopEnd = 0;
265
267 bool isLooping = false;
268
269 //==============================================================================
270 bool operator== (const CurrentPositionInfo& other) const noexcept
271 {
272 const auto tie = [] (const CurrentPositionInfo& i)
273 {
274 return std::tie (i.timeInSamples,
275 i.ppqPosition,
276 i.editOriginTime,
277 i.ppqPositionOfLastBarStart,
278 i.frameRate,
279 i.isPlaying,
280 i.isRecording,
281 i.bpm,
282 i.timeSigNumerator,
283 i.timeSigDenominator,
284 i.ppqLoopStart,
285 i.ppqLoopEnd,
286 i.isLooping);
287 };
288
289 return tie (*this) == tie (other);
290 }
291
292 bool operator!= (const CurrentPositionInfo& other) const noexcept
293 {
294 return ! operator== (other);
295 }
296
297 void resetToDefault()
298 {
299 *this = CurrentPositionInfo{};
300 }
301 };
302
303 //==============================================================================
318 {
319 public:
321 Optional<int64_t> getTimeInSamples() const { return getOptional (flagTimeSamples, timeInSamples); }
322
324 void setTimeInSamples (Optional<int64_t> timeInSamplesIn) { setOptional (flagTimeSamples, timeInSamples, timeInSamplesIn); }
325
327 Optional<double> getTimeInSeconds() const { return getOptional (flagTimeSeconds, timeInSeconds); }
328
330 void setTimeInSeconds (Optional<double> timeInSecondsIn) { setOptional (flagTimeSeconds, timeInSeconds, timeInSecondsIn); }
331
333 Optional<double> getBpm() const { return getOptional (flagTempo, tempoBpm); }
334
336 void setBpm (Optional<double> bpmIn) { setOptional (flagTempo, tempoBpm, bpmIn); }
337
339 Optional<TimeSignature> getTimeSignature() const { return getOptional (flagTimeSignature, timeSignature); }
340
342 void setTimeSignature (Optional<TimeSignature> timeSignatureIn) { setOptional (flagTimeSignature, timeSignature, timeSignatureIn); }
343
345 Optional<LoopPoints> getLoopPoints() const { return getOptional (flagLoopPoints, loopPoints); }
346
348 void setLoopPoints (Optional<LoopPoints> loopPointsIn) { setOptional (flagLoopPoints, loopPoints, loopPointsIn); }
349
354 Optional<int64_t> getBarCount() const { return getOptional (flagBarCount, barCount); }
355
357 void setBarCount (Optional<int64_t> barCountIn) { setOptional (flagBarCount, barCount, barCountIn); }
358
366 Optional<double> getPpqPositionOfLastBarStart() const { return getOptional (flagLastBarStartPpq, lastBarStartPpq); }
367
369 void setPpqPositionOfLastBarStart (Optional<double> positionIn) { setOptional (flagLastBarStartPpq, lastBarStartPpq, positionIn); }
370
372 Optional<FrameRate> getFrameRate() const { return getOptional (flagFrameRate, frame); }
373
375 void setFrameRate (Optional<FrameRate> frameRateIn) { setOptional (flagFrameRate, frame, frameRateIn); }
376
378 Optional<double> getPpqPosition() const { return getOptional (flagPpqPosition, positionPpq); }
379
381 void setPpqPosition (Optional<double> ppqPositionIn) { setOptional (flagPpqPosition, positionPpq, ppqPositionIn); }
382
384 Optional<double> getEditOriginTime() const { return getOptional (flagOriginTime, originTime); }
385
387 void setEditOriginTime (Optional<double> editOriginTimeIn) { setOptional (flagOriginTime, originTime, editOriginTimeIn); }
388
390 Optional<uint64_t> getHostTimeNs() const { return getOptional (flagHostTimeNs, hostTimeNs); }
391
393 void setHostTimeNs (Optional<uint64_t> hostTimeNsIn) { setOptional (flagHostTimeNs, hostTimeNs, hostTimeNsIn); }
394
396 bool getIsPlaying() const { return getFlag (flagIsPlaying); }
397
399 void setIsPlaying (bool isPlayingIn) { setFlag (flagIsPlaying, isPlayingIn); }
400
405 bool getIsRecording() const { return getFlag (flagIsRecording); }
406
408 void setIsRecording (bool isRecordingIn) { setFlag (flagIsRecording, isRecordingIn); }
409
411 bool getIsLooping() const { return getFlag (flagIsLooping); }
412
414 void setIsLooping (bool isLoopingIn) { setFlag (flagIsLooping, isLoopingIn); }
415
416 bool operator== (const PositionInfo& other) const noexcept
417 {
418 const auto tie = [] (const PositionInfo& i)
419 {
420 return std::make_tuple (i.getTimeInSamples(),
421 i.getTimeInSeconds(),
422 i.getPpqPosition(),
423 i.getEditOriginTime(),
424 i.getPpqPositionOfLastBarStart(),
425 i.getFrameRate(),
426 i.getBarCount(),
427 i.getTimeSignature(),
428 i.getBpm(),
429 i.getLoopPoints(),
430 i.getHostTimeNs(),
431 i.getIsPlaying(),
432 i.getIsRecording(),
433 i.getIsLooping());
434 };
435
436 return tie (*this) == tie (other);
437 }
438
439 bool operator!= (const PositionInfo& other) const noexcept
440 {
441 return ! operator== (other);
442 }
443
444 private:
445 bool getFlag (int64_t flagToCheck) const
446 {
447 return (flagToCheck & flags) != 0;
448 }
449
450 void setFlag (int64_t flagToCheck, bool value)
451 {
452 flags = (value ? flags | flagToCheck : flags & ~flagToCheck);
453 }
454
455 template <typename Value>
456 Optional<Value> getOptional (int64_t flagToCheck, Value value) const
457 {
458 return getFlag (flagToCheck) ? makeOptional (std::move (value)) : nullopt;
459 }
460
461 template <typename Value>
462 void setOptional (int64_t flagToCheck, Value& value, Optional<Value> opt)
463 {
464 if (opt.hasValue())
465 value = *opt;
466
467 setFlag (flagToCheck, opt.hasValue());
468 }
469
470 enum
471 {
472 flagTimeSignature = 1 << 0,
473 flagLoopPoints = 1 << 1,
474 flagFrameRate = 1 << 2,
475 flagTimeSeconds = 1 << 3,
476 flagLastBarStartPpq = 1 << 4,
477 flagPpqPosition = 1 << 5,
478 flagOriginTime = 1 << 6,
479 flagTempo = 1 << 7,
480 flagTimeSamples = 1 << 8,
481 flagBarCount = 1 << 9,
482 flagHostTimeNs = 1 << 10,
483 flagIsPlaying = 1 << 11,
484 flagIsRecording = 1 << 12,
485 flagIsLooping = 1 << 13
486 };
487
488 TimeSignature timeSignature;
489 LoopPoints loopPoints;
490 FrameRate frame = FrameRateType::fps23976;
491 double timeInSeconds = 0.0;
492 double lastBarStartPpq = 0.0;
493 double positionPpq = 0.0;
494 double originTime = 0.0;
495 double tempoBpm = 0.0;
496 int64_t timeInSamples = 0;
497 int64_t barCount = 0;
498 uint64_t hostTimeNs = 0;
499 int64_t flags = 0;
500 };
501
502 //==============================================================================
515 [[deprecated ("Use getPosition instead. Not all hosts are able to provide all time position information; getPosition differentiates clearly between set and unset fields.")]]
517 {
518 if (const auto pos = getPosition())
519 {
520 result.resetToDefault();
521
522 if (const auto sig = pos->getTimeSignature())
523 {
524 result.timeSigNumerator = sig->numerator;
525 result.timeSigDenominator = sig->denominator;
526 }
527
528 if (const auto loop = pos->getLoopPoints())
529 {
530 result.ppqLoopStart = loop->ppqStart;
531 result.ppqLoopEnd = loop->ppqEnd;
532 }
533
534 if (const auto frame = pos->getFrameRate())
535 result.frameRate = *frame;
536
537 if (const auto timeInSeconds = pos->getTimeInSeconds())
538 result.timeInSeconds = *timeInSeconds;
539
540 if (const auto lastBarStartPpq = pos->getPpqPositionOfLastBarStart())
541 result.ppqPositionOfLastBarStart = *lastBarStartPpq;
542
543 if (const auto ppqPosition = pos->getPpqPosition())
544 result.ppqPosition = *ppqPosition;
545
546 if (const auto originTime = pos->getEditOriginTime())
547 result.editOriginTime = *originTime;
548
549 if (const auto bpm = pos->getBpm())
550 result.bpm = *bpm;
551
552 if (const auto timeInSamples = pos->getTimeInSamples())
553 result.timeInSamples = *timeInSamples;
554
555 result.isPlaying = pos->getIsPlaying();
556 result.isRecording = pos->getIsRecording();
557 result.isLooping = pos->getIsLooping();
558
559 return true;
560 }
561
562 return false;
563 }
564
579
581 virtual bool canControlTransport();
582
584 virtual void transportPlay (bool shouldStartPlaying);
585
587 virtual void transportRecord (bool shouldStartRecording);
588
590 virtual void transportRewind();
591};
592
593} // namespace juce
FrameRate withPullDown(bool x=true) const
FrameRate withDrop(bool x=true) const
FrameRate withBaseRate(int x) const
void setBpm(Optional< double > bpmIn)
void setIsRecording(bool isRecordingIn)
void setTimeInSamples(Optional< int64_t > timeInSamplesIn)
Optional< double > getBpm() const
Optional< int64_t > getTimeInSamples() const
void setHostTimeNs(Optional< uint64_t > hostTimeNsIn)
void setLoopPoints(Optional< LoopPoints > loopPointsIn)
Optional< double > getPpqPositionOfLastBarStart() const
void setPpqPositionOfLastBarStart(Optional< double > positionIn)
void setBarCount(Optional< int64_t > barCountIn)
void setPpqPosition(Optional< double > ppqPositionIn)
void setTimeInSeconds(Optional< double > timeInSecondsIn)
Optional< uint64_t > getHostTimeNs() const
Optional< double > getPpqPosition() const
Optional< TimeSignature > getTimeSignature() const
Optional< LoopPoints > getLoopPoints() const
Optional< double > getTimeInSeconds() const
void setTimeSignature(Optional< TimeSignature > timeSignatureIn)
void setFrameRate(Optional< FrameRate > frameRateIn)
void setEditOriginTime(Optional< double > editOriginTimeIn)
Optional< double > getEditOriginTime() const
Optional< int64_t > getBarCount() const
Optional< FrameRate > getFrameRate() const
virtual Optional< PositionInfo > getPosition() const =0
bool getCurrentPosition(CurrentPositionInfo &result)