OpenShot Audio Library | OpenShotAudio  0.6.0
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 
23 namespace juce
24 {
25 
26 //==============================================================================
38 class JUCE_API AudioPlayHead
39 {
40 protected:
41  //==============================================================================
42  AudioPlayHead() = default;
43 
44 public:
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 
578  virtual Optional<PositionInfo> getPosition() const = 0;
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< FrameRate > getFrameRate() const
void setHostTimeNs(Optional< uint64_t > hostTimeNsIn)
void setLoopPoints(Optional< LoopPoints > loopPointsIn)
void setPpqPositionOfLastBarStart(Optional< double > positionIn)
Optional< uint64_t > getHostTimeNs() const
void setBarCount(Optional< int64_t > barCountIn)
void setPpqPosition(Optional< double > ppqPositionIn)
Optional< TimeSignature > getTimeSignature() const
void setTimeInSeconds(Optional< double > timeInSecondsIn)
Optional< double > getBpm() const
Optional< double > getPpqPosition() const
Optional< LoopPoints > getLoopPoints() const
Optional< int64_t > getBarCount() const
Optional< int64_t > getTimeInSamples() const
Optional< double > getTimeInSeconds() const
Optional< double > getPpqPositionOfLastBarStart() const
void setTimeSignature(Optional< TimeSignature > timeSignatureIn)
void setFrameRate(Optional< FrameRate > frameRateIn)
void setEditOriginTime(Optional< double > editOriginTimeIn)
Optional< double > getEditOriginTime() const
virtual Optional< PositionInfo > getPosition() const =0
bool getCurrentPosition(CurrentPositionInfo &result)