00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <iostream>
00022
00023 #if (__GNUC__ < 3)
00024 #include <strstream>
00025 #define stringstream strstream
00026 #else
00027 #include <sstream>
00028 #endif
00029
00030 using std::cerr;
00031 using std::endl;
00032
00033 #include "RealTime.h"
00034 #include "sys/time.h"
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #define ONE_BILLION 1000000000
00046
00047 RealTime::RealTime(int s, int n) :
00048 sec(s), nsec(n)
00049 {
00050 if (sec == 0) {
00051 while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; }
00052 while (nsec >= ONE_BILLION) { nsec -= ONE_BILLION; ++sec; }
00053 } else if (sec < 0) {
00054 while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; }
00055 while (nsec > 0) { nsec -= ONE_BILLION; ++sec; }
00056 } else {
00057 while (nsec >= ONE_BILLION) { nsec -= ONE_BILLION; ++sec; }
00058 while (nsec < 0) { nsec += ONE_BILLION; --sec; }
00059 }
00060 }
00061
00062 RealTime
00063 RealTime::fromSeconds(double sec)
00064 {
00065 return RealTime(int(sec), int((sec - int(sec)) * ONE_BILLION + 0.5));
00066 }
00067
00068 RealTime
00069 RealTime::fromMilliseconds(int msec)
00070 {
00071 return RealTime(msec / 1000, (msec % 1000) * 1000000);
00072 }
00073
00074 RealTime
00075 RealTime::fromTimeval(const struct timeval &tv)
00076 {
00077 return RealTime(tv.tv_sec, tv.tv_usec * 1000);
00078 }
00079
00080 std::ostream &operator<<(std::ostream &out, const RealTime &rt)
00081 {
00082 if (rt < RealTime::zeroTime) {
00083 out << "-";
00084 } else {
00085 out << " ";
00086 }
00087
00088 int s = (rt.sec < 0 ? -rt.sec : rt.sec);
00089 int n = (rt.nsec < 0 ? -rt.nsec : rt.nsec);
00090
00091 out << s << ".";
00092
00093 int nn(n);
00094 if (nn == 0) out << "00000000";
00095 else while (nn < (ONE_BILLION / 10)) {
00096 out << "0";
00097 nn *= 10;
00098 }
00099
00100 out << n << "R";
00101 return out;
00102 }
00103
00104 std::string
00105 RealTime::toString(bool align) const
00106 {
00107 std::stringstream out;
00108 out << *this;
00109
00110 #if (__GNUC__ < 3)
00111 out << std::ends;
00112 #endif
00113
00114 std::string s = out.str();
00115
00116 if (!align && *this >= RealTime::zeroTime) {
00117
00118 s = s.substr(1, s.length() - 1);
00119 }
00120
00121
00122 return s.substr(0, s.length() - 1);
00123 }
00124
00125 RealTime
00126 RealTime::fromString(std::string s)
00127 {
00128 bool negative = false;
00129 bool faulty = false;
00130 bool section = 0;
00131 std::string ssec, snsec;
00132
00133 for (size_t i = 0; i < s.length(); ++i) {
00134
00135 char c = s[i];
00136 if (isspace(c)) continue;
00137
00138 if (section == 0) {
00139
00140 if (c == '-') negative = true;
00141 else if (isdigit(c)) { section = 1; ssec += c; }
00142 else if (c == '.') section = 2;
00143 else break;
00144
00145 } else if (section == 1) {
00146
00147 if (c == '.') section = 2;
00148 else if (isdigit(c)) ssec += c;
00149 else break;
00150
00151 } else if (section == 2) {
00152
00153 if (isdigit(c)) snsec += c;
00154 else break;
00155 }
00156 }
00157
00158 while (snsec.length() < 8) snsec += '0';
00159
00160 int sec = atoi(ssec.c_str());
00161 int nsec = atoi(snsec.c_str());
00162 if (negative) sec = -sec;
00163
00164 std::cerr << "RealTime::fromString: string " << s << " -> "
00165 << sec << " sec, " << nsec << " nsec" << std::endl;
00166
00167 return RealTime(sec, nsec);
00168 }
00169
00170 std::string
00171 RealTime::toText(bool fixedDp) const
00172 {
00173 if (*this < RealTime::zeroTime) return "-" + (-*this).toText(fixedDp);
00174
00175 std::stringstream out;
00176
00177 if (sec >= 3600) {
00178 out << (sec / 3600) << ":";
00179 }
00180
00181 if (sec >= 60) {
00182 out << (sec % 3600) / 60 << ":";
00183 }
00184
00185 if (sec >= 10) {
00186 out << ((sec % 60) / 10);
00187 }
00188
00189 out << (sec % 10);
00190
00191 int ms = msec();
00192
00193 if (ms != 0) {
00194 out << ".";
00195 out << (ms / 100);
00196 ms = ms % 100;
00197 if (ms != 0) {
00198 out << (ms / 10);
00199 ms = ms % 10;
00200 } else if (fixedDp) {
00201 out << "0";
00202 }
00203 if (ms != 0) {
00204 out << ms;
00205 } else if (fixedDp) {
00206 out << "0";
00207 }
00208 } else if (fixedDp) {
00209 out << ".000";
00210 }
00211
00212 #if (__GNUC__ < 3)
00213 out << std::ends;
00214 #endif
00215
00216 std::string s = out.str();
00217
00218 return s;
00219 }
00220
00221 std::string
00222 RealTime::toSecText() const
00223 {
00224 if (*this < RealTime::zeroTime) return "-" + (-*this).toSecText();
00225
00226 std::stringstream out;
00227
00228 if (sec >= 3600) {
00229 out << (sec / 3600) << ":";
00230 }
00231
00232 if (sec >= 60) {
00233 out << (sec % 3600) / 60 << ":";
00234 }
00235
00236 if (sec >= 10) {
00237 out << ((sec % 60) / 10);
00238 }
00239
00240 out << (sec % 10);
00241
00242 if (sec < 60) {
00243 out << "s";
00244 }
00245
00246
00247 #if (__GNUC__ < 3)
00248 out << std::ends;
00249 #endif
00250
00251 std::string s = out.str();
00252
00253 return s;
00254 }
00255
00256 RealTime
00257 RealTime::operator*(int m) const
00258 {
00259 double t = (double(nsec) / ONE_BILLION) * m;
00260 t += sec * m;
00261 return fromSeconds(t);
00262 }
00263
00264 RealTime
00265 RealTime::operator/(int d) const
00266 {
00267 int secdiv = sec / d;
00268 int secrem = sec % d;
00269
00270 double nsecdiv = (double(nsec) + ONE_BILLION * double(secrem)) / d;
00271
00272 return RealTime(secdiv, int(nsecdiv + 0.5));
00273 }
00274
00275 RealTime
00276 RealTime::operator*(double m) const
00277 {
00278 double t = (double(nsec) / ONE_BILLION) * m;
00279 t += sec * m;
00280 return fromSeconds(t);
00281 }
00282
00283 RealTime
00284 RealTime::operator/(double d) const
00285 {
00286 double t = (double(nsec) / ONE_BILLION) / d;
00287 t += sec / d;
00288 return fromSeconds(t);
00289 }
00290
00291 double
00292 RealTime::operator/(const RealTime &r) const
00293 {
00294 double lTotal = double(sec) * ONE_BILLION + double(nsec);
00295 double rTotal = double(r.sec) * ONE_BILLION + double(r.nsec);
00296
00297 if (rTotal == 0) return 0.0;
00298 else return lTotal/rTotal;
00299 }
00300
00301 long
00302 RealTime::realTime2Frame(const RealTime &time, unsigned int sampleRate)
00303 {
00304 if (time < zeroTime) return -realTime2Frame(-time, sampleRate);
00305
00306
00307
00308
00309 long frame =
00310 time.sec * sampleRate +
00311 (time.msec() * sampleRate) / 1000 +
00312 ((time.usec() - 1000 * time.msec()) * sampleRate) / 1000000 +
00313 ((time.nsec - 1000 * time.usec()) * sampleRate) / 1000000000;
00314
00315 return frame;
00316 }
00317
00318 RealTime
00319 RealTime::frame2RealTime(long frame, unsigned int sampleRate)
00320 {
00321 if (frame < 0) return -frame2RealTime(-frame, sampleRate);
00322
00323 RealTime rt;
00324 rt.sec = frame / long(sampleRate);
00325 frame -= rt.sec * long(sampleRate);
00326 rt.nsec = (int)(((float(frame) * 1000000) / long(sampleRate)) * 1000);
00327 return rt;
00328 }
00329
00330 const RealTime RealTime::zeroTime(0,0);
00331