comparison src/vamp-sdk/RealTime.cpp @ 227:6b30e064cab7 distinct-libraries

* more moving
author cannam
date Thu, 06 Nov 2008 14:13:12 +0000
parents src/RealTime.cpp@14029eb08472
children 5ee166dccfff
comparison
equal deleted inserted replaced
226:14029eb08472 227:6b30e064cab7
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Vamp
5
6 An API for audio analysis and feature extraction plugins.
7
8 Centre for Digital Music, Queen Mary, University of London.
9 Copyright 2006 Chris Cannam.
10
11 Permission is hereby granted, free of charge, to any person
12 obtaining a copy of this software and associated documentation
13 files (the "Software"), to deal in the Software without
14 restriction, including without limitation the rights to use, copy,
15 modify, merge, publish, distribute, sublicense, and/or sell copies
16 of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be
20 included in all copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 Except as contained in this notice, the names of the Centre for
31 Digital Music; Queen Mary, University of London; and Chris Cannam
32 shall not be used in advertising or otherwise to promote the sale,
33 use or other dealings in this Software without prior written
34 authorization.
35 */
36
37 /*
38 This is a modified version of a source file from the
39 Rosegarden MIDI and audio sequencer and notation editor.
40 This file copyright 2000-2006 Chris Cannam.
41 Relicensed by the author as detailed above.
42 */
43
44 #include <iostream>
45
46 #if (__GNUC__ < 3)
47 #include <strstream>
48 #define stringstream strstream
49 #else
50 #include <sstream>
51 #endif
52
53 using std::cerr;
54 using std::endl;
55
56 #include "RealTime.h"
57
58 #ifndef _WIN32
59 #include <sys/time.h>
60 #endif
61
62 namespace Vamp {
63
64 // A RealTime consists of two ints that must be at least 32 bits each.
65 // A signed 32-bit int can store values exceeding +/- 2 billion. This
66 // means we can safely use our lower int for nanoseconds, as there are
67 // 1 billion nanoseconds in a second and we need to handle double that
68 // because of the implementations of addition etc that we use.
69 //
70 // The maximum valid RealTime on a 32-bit system is somewhere around
71 // 68 years: 999999999 nanoseconds longer than the classic Unix epoch.
72
73 #define ONE_BILLION 1000000000
74
75 RealTime::RealTime(int s, int n) :
76 sec(s), nsec(n)
77 {
78 if (sec == 0) {
79 while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; }
80 while (nsec >= ONE_BILLION) { nsec -= ONE_BILLION; ++sec; }
81 } else if (sec < 0) {
82 while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; }
83 while (nsec > 0) { nsec -= ONE_BILLION; ++sec; }
84 } else {
85 while (nsec >= ONE_BILLION) { nsec -= ONE_BILLION; ++sec; }
86 while (nsec < 0) { nsec += ONE_BILLION; --sec; }
87 }
88 }
89
90 RealTime
91 RealTime::fromSeconds(double sec)
92 {
93 return RealTime(int(sec), int((sec - int(sec)) * ONE_BILLION + 0.5));
94 }
95
96 RealTime
97 RealTime::fromMilliseconds(int msec)
98 {
99 return RealTime(msec / 1000, (msec % 1000) * 1000000);
100 }
101
102 #ifndef _WIN32
103 RealTime
104 RealTime::fromTimeval(const struct timeval &tv)
105 {
106 return RealTime(tv.tv_sec, tv.tv_usec * 1000);
107 }
108 #endif
109
110 std::ostream &operator<<(std::ostream &out, const RealTime &rt)
111 {
112 if (rt < RealTime::zeroTime) {
113 out << "-";
114 } else {
115 out << " ";
116 }
117
118 int s = (rt.sec < 0 ? -rt.sec : rt.sec);
119 int n = (rt.nsec < 0 ? -rt.nsec : rt.nsec);
120
121 out << s << ".";
122
123 int nn(n);
124 if (nn == 0) out << "00000000";
125 else while (nn < (ONE_BILLION / 10)) {
126 out << "0";
127 nn *= 10;
128 }
129
130 out << n << "R";
131 return out;
132 }
133
134 std::string
135 RealTime::toString() const
136 {
137 std::stringstream out;
138 out << *this;
139
140 #if (__GNUC__ < 3)
141 out << std::ends;
142 #endif
143
144 std::string s = out.str();
145
146 // remove trailing R
147 return s.substr(0, s.length() - 1);
148 }
149
150 std::string
151 RealTime::toText(bool fixedDp) const
152 {
153 if (*this < RealTime::zeroTime) return "-" + (-*this).toText();
154
155 std::stringstream out;
156
157 if (sec >= 3600) {
158 out << (sec / 3600) << ":";
159 }
160
161 if (sec >= 60) {
162 out << (sec % 3600) / 60 << ":";
163 }
164
165 if (sec >= 10) {
166 out << ((sec % 60) / 10);
167 }
168
169 out << (sec % 10);
170
171 int ms = msec();
172
173 if (ms != 0) {
174 out << ".";
175 out << (ms / 100);
176 ms = ms % 100;
177 if (ms != 0) {
178 out << (ms / 10);
179 ms = ms % 10;
180 } else if (fixedDp) {
181 out << "0";
182 }
183 if (ms != 0) {
184 out << ms;
185 } else if (fixedDp) {
186 out << "0";
187 }
188 } else if (fixedDp) {
189 out << ".000";
190 }
191
192 #if (__GNUC__ < 3)
193 out << std::ends;
194 #endif
195
196 std::string s = out.str();
197
198 return s;
199 }
200
201
202 RealTime
203 RealTime::operator/(int d) const
204 {
205 int secdiv = sec / d;
206 int secrem = sec % d;
207
208 double nsecdiv = (double(nsec) + ONE_BILLION * double(secrem)) / d;
209
210 return RealTime(secdiv, int(nsecdiv + 0.5));
211 }
212
213 double
214 RealTime::operator/(const RealTime &r) const
215 {
216 double lTotal = double(sec) * ONE_BILLION + double(nsec);
217 double rTotal = double(r.sec) * ONE_BILLION + double(r.nsec);
218
219 if (rTotal == 0) return 0.0;
220 else return lTotal/rTotal;
221 }
222
223 long
224 RealTime::realTime2Frame(const RealTime &time, unsigned int sampleRate)
225 {
226 if (time < zeroTime) return -realTime2Frame(-time, sampleRate);
227 double s = time.sec + double(time.nsec + 1) / 1000000000.0;
228 return long(s * sampleRate);
229 }
230
231 RealTime
232 RealTime::frame2RealTime(long frame, unsigned int sampleRate)
233 {
234 if (frame < 0) return -frame2RealTime(-frame, sampleRate);
235
236 RealTime rt;
237 rt.sec = frame / long(sampleRate);
238 frame -= rt.sec * long(sampleRate);
239 rt.nsec = (int)(((double(frame) * 1000000.0) / sampleRate) * 1000.0);
240 return rt;
241 }
242
243 const RealTime RealTime::zeroTime(0,0);
244
245 }