chiark / gitweb /
disobedience, playrtp: Have `playrtp' handle volume control.
[disorder] / lib / timeval.h
1 /*
2  * This file is part of DisOrder.
3  * Copyright (C) 2007-2009, 2013 Richard Kettlewell
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 /** @file lib/timeval.h
19  * @brief Arithmetic on timeval structures
20  */
21 #ifndef TIMEVAL_H
22 #define TIMEVAL_H
23
24 #include <time.h>
25 #include <sys/time.h>
26 #include <math.h>
27
28 static inline struct timeval tvsub(const struct timeval a,
29                                    const struct timeval b) {
30   struct timeval r;
31
32   r.tv_sec = a.tv_sec - b.tv_sec;
33   r.tv_usec = a.tv_usec - b.tv_usec;
34   if(r.tv_usec < 0) {
35     r.tv_usec += 1000000;
36     r.tv_sec--;
37   }
38   if(r.tv_usec > 999999) {
39     r.tv_usec -= 1000000;
40     r.tv_sec++;
41   }
42   return r;
43 }
44
45 static inline struct timeval tvadd(const struct timeval a,
46                                    const struct timeval b) {
47   struct timeval r;
48
49   r.tv_sec = a.tv_sec + b.tv_sec;
50   r.tv_usec = a.tv_usec + b.tv_usec;
51   if(r.tv_usec < 0) {
52     r.tv_usec += 1000000;
53     r.tv_sec--;
54   }
55   if(r.tv_usec > 999999) {
56     r.tv_usec -= 1000000;
57     r.tv_sec++;
58   }
59   return r;
60 }
61
62 static inline double tvdouble(const struct timeval a) {
63   return a.tv_sec + a.tv_usec / 1000000.0;
64 }
65
66 static inline int64_t tvsub_us(const struct timeval a,
67                                const struct timeval b) {
68   return (((uint64_t)a.tv_sec * 1000000 + a.tv_usec)
69           - ((uint64_t)b.tv_sec * 1000000 + b.tv_usec));
70 }
71
72 /** @brief Great-than comparison for timevals */
73 static inline int tvgt(const struct timeval *a, const struct timeval *b) {
74   if(a->tv_sec > b->tv_sec)
75     return 1;
76   if(a->tv_sec == b->tv_sec
77      && a->tv_usec > b->tv_usec)
78     return 1;
79   return 0;
80 }
81
82 /** @brief Less-than
83     comparison for timevals */
84 static inline int tvlt(const struct timeval *a, const struct timeval *b) {
85   if(a->tv_sec < b->tv_sec)
86     return 1;
87   if(a->tv_sec == b->tv_sec
88      && a->tv_usec < b->tv_usec)
89     return 1;
90   return 0;
91 }
92
93 /** @brief Greater-than-or-equal comparison for timevals */
94 static inline int tvge(const struct timeval *a, const struct timeval *b) {
95   return !tvlt(a, b);
96 }
97
98 /** @brief Less-than-or-equal comparison for timevals */
99 static inline int tvle(const struct timeval *a, const struct timeval *b) {
100   return !tvgt(a, b);
101 }
102
103 /** @brief Return the sum of two timespecs */
104 static inline struct timespec tsadd(const struct timespec a,
105                                     const struct timespec b) {
106   struct timespec r;
107
108   r.tv_sec = a.tv_sec + b.tv_sec;
109   r.tv_nsec = a.tv_nsec + b.tv_nsec;
110   if(r.tv_nsec < 0) {
111     r.tv_nsec += 1000000;
112     r.tv_sec--;
113   }
114   if(r.tv_nsec > 999999) {
115     r.tv_nsec -= 1000000;
116     r.tv_sec++;
117   }
118   return r;
119 }
120
121 /** @brief Subtract one timespec from another */
122 static inline struct timespec tssub(const struct timespec a,
123                                     const struct timespec b) {
124   struct timespec r;
125
126   r.tv_sec = a.tv_sec - b.tv_sec;
127   r.tv_nsec = a.tv_nsec - b.tv_nsec;
128   if(r.tv_nsec < 0) {
129     r.tv_nsec += 1000000;
130     r.tv_sec--;
131   }
132   if(r.tv_nsec > 999999) {
133     r.tv_nsec -= 1000000;
134     r.tv_sec++;
135   }
136   return r;
137 }
138
139 /** @brief Convert a timespec to a double */
140 static inline double ts_to_double(const struct timespec ts) {
141   return ts.tv_sec + ts.tv_nsec / 1000000000.0;
142 }
143
144 /** @brief Convert a double to a timespec */
145 static inline struct timespec double_to_ts(double n) {
146   double i, f;
147   struct timespec r;
148   f = modf(n, &i);
149   r.tv_sec = i;
150   r.tv_nsec = 1000000000 * f;
151   return r;
152 }
153
154 #endif /* TIMEVAL_H */
155
156 /*
157 Local Variables:
158 c-basic-offset:2
159 comment-column:40
160 fill-column:79
161 indent-tabs-mode:nil
162 End:
163 */