openMSX
EmuDuration.hh
Go to the documentation of this file.
1 #ifndef EMUDURATION_HH
2 #define EMUDURATION_HH
3 
4 #include "serialize.hh"
5 #include <cassert>
6 #include <cstdint>
7 
8 namespace openmsx {
9 
10 // constants
11 static const uint64_t MAIN_FREQ = 3579545ULL * 960;
12 static const unsigned MAIN_FREQ32 = MAIN_FREQ;
13 static_assert(MAIN_FREQ < (1ull << 32), "must fit in 32 bit");
14 
15 
17 {
18 public:
19  // This is only a very small class (one 64-bit member). On 64-bit CPUs
20  // it's cheaper to pass this by value. On 32-bit CPUs pass-by-reference
21  // is cheaper.
22 #ifdef __x86_64
23  using param = const EmuDuration;
24 #else
25  using param = const EmuDuration&;
26 #endif
27 
28  // friends
29  friend class EmuTime;
30 
31  // constructors
32  EmuDuration() = default;
33  explicit EmuDuration(uint64_t n) : time(n) {}
34  explicit EmuDuration(double duration)
35  : time(uint64_t(duration * MAIN_FREQ)) {}
36 
37  static EmuDuration sec(unsigned x)
38  { return EmuDuration(x * MAIN_FREQ); }
39  static EmuDuration msec(unsigned x)
40  { return EmuDuration(x * MAIN_FREQ / 1000); }
41  static EmuDuration usec(unsigned x)
42  { return EmuDuration(x * MAIN_FREQ / 1000000); }
43  static EmuDuration hz(unsigned x)
44  { return EmuDuration(MAIN_FREQ / x); }
45 
46  // conversions
47  double toDouble() const { return double(time) / MAIN_FREQ32; }
48  uint64_t length() const { return time; }
49 
50  // comparison operators
52  { return time == d.time; }
54  { return time != d.time; }
56  { return time < d.time; }
58  { return time <= d.time; }
60  { return time > d.time; }
62  { return time >= d.time; }
63 
64  // arithmetic operators
66  { return EmuDuration(time % d.time); }
68  { return EmuDuration(time + d.time); }
69  EmuDuration operator*(unsigned fact) const
70  { return EmuDuration(time * fact); }
71  EmuDuration operator/(unsigned fact) const
72  { return EmuDuration(time / fact); }
73  EmuDuration divRoundUp(unsigned fact) const
74  { return EmuDuration((time + fact - 1) / fact); }
75  unsigned operator/(EmuDuration::param d) const
76  {
77  uint64_t result = time / d.time;
78 #ifdef DEBUG
79  // we don't even want this overhead in devel builds
80  assert(result == unsigned(result));
81 #endif
82  return unsigned(result);
83  }
84  unsigned divUp(EmuDuration::param d) const {
85  uint64_t result = (time + d.time - 1) / d.time;
86 #ifdef DEBUG
87  assert(result == unsigned(result));
88 #endif
89  return unsigned(result);
90  }
91  double div(EmuDuration::param d) const
92  { return double(time) / d.time; }
93 
94  EmuDuration& operator*=(unsigned fact)
95  { time *= fact; return *this; }
96  EmuDuration& operator*=(double fact)
97  { time = uint64_t(time * fact); return *this; }
98  EmuDuration& operator/=(double fact)
99  { time = uint64_t(time / fact); return *this; }
100 
101  // ticks
102  // TODO: Used in WavAudioInput. Keep or use DynamicClock instead?
103  unsigned getTicksAt(unsigned freq) const
104  {
105  uint64_t result = time / (MAIN_FREQ32 / freq);
106 #ifdef DEBUG
107  // we don't even want this overhead in devel builds
108  assert(result == unsigned(result));
109 #endif
110  return unsigned(result);
111  }
112 
113  template<typename Archive>
114  void serialize(Archive& ar, unsigned version);
115 
116  static const EmuDuration zero;
117  static const EmuDuration infinity;
118 
119 private:
120  uint64_t time = 0;
121 };
122 
123 template<> struct SerializeAsMemcpy<EmuDuration> : std::true_type {};
124 
125 } // namespace openmsx
126 
127 #endif
unsigned divUp(EmuDuration::param d) const
Definition: EmuDuration.hh:84
static EmuDuration sec(unsigned x)
Definition: EmuDuration.hh:37
static EmuDuration hz(unsigned x)
Definition: EmuDuration.hh:43
static EmuDuration msec(unsigned x)
Definition: EmuDuration.hh:39
EmuDuration operator/(unsigned fact) const
Definition: EmuDuration.hh:71
bool operator>=(EmuDuration::param d) const
Definition: EmuDuration.hh:61
bool operator>(EmuDuration::param d) const
Definition: EmuDuration.hh:59
bool operator!=(EmuDuration::param d) const
Definition: EmuDuration.hh:53
EmuDuration operator%(EmuDuration::param d) const
Definition: EmuDuration.hh:65
EmuDuration & operator/=(double fact)
Definition: EmuDuration.hh:98
double toDouble() const
Definition: EmuDuration.hh:47
EmuDuration & operator*=(double fact)
Definition: EmuDuration.hh:96
EmuDuration & operator*=(unsigned fact)
Definition: EmuDuration.hh:94
EmuDuration(double duration)
Definition: EmuDuration.hh:34
static const EmuDuration zero
Definition: EmuDuration.hh:116
uint64_t length() const
Definition: EmuDuration.hh:48
bool operator<(EmuDuration::param d) const
Definition: EmuDuration.hh:55
static const EmuDuration infinity
Definition: EmuDuration.hh:117
double div(EmuDuration::param d) const
Definition: EmuDuration.hh:91
friend class EmuTime
Definition: EmuDuration.hh:29
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
static EmuDuration usec(unsigned x)
Definition: EmuDuration.hh:41
EmuDuration operator+(EmuDuration::param d) const
Definition: EmuDuration.hh:67
EmuDuration divRoundUp(unsigned fact) const
Definition: EmuDuration.hh:73
unsigned getTicksAt(unsigned freq) const
Definition: EmuDuration.hh:103
unsigned operator/(EmuDuration::param d) const
Definition: EmuDuration.hh:75
EmuDuration operator*(unsigned fact) const
Definition: EmuDuration.hh:69
bool operator<=(EmuDuration::param d) const
Definition: EmuDuration.hh:57
void serialize(Archive &ar, unsigned version)
Definition: EmuDuration.cc:10
EmuDuration(uint64_t n)
Definition: EmuDuration.hh:33
bool operator==(EmuDuration::param d) const
Definition: EmuDuration.hh:51