source: roaraudio/libroar/time.c @ 5068:f11a0c0bacdd

Last change on this file since 5068:f11a0c0bacdd was 5068:f11a0c0bacdd, checked in by phi, 11 years ago

Support non-blocking latency request in VS API (Closes: #97)

File size: 4.5 KB
Line 
1//time.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2011
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38int roar_time_to_msg(struct roar_message * mes,  struct roar_time    * time) {
39 uint64_t * data;
40
41 if ( mes == NULL || time == NULL ) {
42  roar_err_set(ROAR_ERROR_FAULT);
43  return -1;
44 }
45
46 memset(mes, 0, sizeof(struct roar_message));
47
48 data = (uint64_t*)mes->data;
49
50 data[0] = ROAR_HOST2NET64(0);
51 data[1] = ROAR_HOST2NET64(time->t_sec);
52 data[2] = ROAR_HOST2NET64(time->t_ssec);
53 data[3] = ROAR_HOST2NET64(time->c_freq);
54 data[4] = ROAR_HOST2NET64(time->c_drift);
55
56 mes->datalen = 5*8;
57
58 if ( time->c_drift == 0 ) {
59  mes->datalen -= 8;
60  if ( time->c_freq == 0 ) {
61   mes->datalen -= 8;
62   if ( time->t_ssec == 0 ) {
63    mes->datalen -= 8;
64   }
65  }
66 }
67
68 return 0;
69}
70
71int roar_time_from_msg(struct roar_time  * time, struct roar_message * mes) {
72 uint64_t * data;
73
74 if ( mes == NULL || time == NULL ) {
75  roar_err_set(ROAR_ERROR_FAULT);
76  return -1;
77 }
78
79 data = (uint64_t*)mes->data;
80
81 if ( mes->datalen < 8 ) {
82  roar_err_set(ROAR_ERROR_BADMSG);
83  return -1;
84 }
85
86 if ( mes->datalen % 8 ) {
87  roar_err_set(ROAR_ERROR_BADMSG);
88  return -1;
89 }
90
91 if ( ROAR_NET2HOST64(data[0]) != 0 ) {
92  roar_err_set(ROAR_ERROR_NSVERSION);
93  return -1;
94 }
95
96 memset(time, 0, sizeof(struct roar_time));
97
98 if ( mes->datalen >= 16 ) {
99  time->t_sec = ROAR_NET2HOST64(data[1]);
100  if ( mes->datalen >= 24 ) {
101   time->t_ssec = ROAR_NET2HOST64(data[2]);
102   if ( mes->datalen >= 32 ) {
103    time->c_freq = ROAR_NET2HOST64(data[3]);
104    if ( mes->datalen >= 40 ) {
105     time->c_drift = ROAR_NET2HOST64(data[4]);
106    }
107   }
108  }
109 }
110
111 return 0;
112}
113
114int roar_get_time  (struct roar_connection * con, struct roar_time * time) {
115 struct roar_message mes;
116
117 if ( con == NULL || time == NULL ) {
118  roar_err_set(ROAR_ERROR_FAULT);
119  return -1;
120 }
121
122 memset(&mes, 0, sizeof(mes));
123
124 mes.cmd     = ROAR_CMD_GETTIMEOFDAY;
125 mes.stream  = -1;
126 mes.datalen = 8; /* 64 bit */
127 // mes.data is already cleared.
128
129 if ( roar_req(con, &mes, NULL) == -1 )
130  return -1;
131
132 if ( mes.cmd != ROAR_CMD_OK ) {
133  return -1;
134 }
135
136 if ( roar_time_from_msg(time, &mes) == -1 )
137  return -1;
138
139 return 0;
140}
141
142int roar_clock_gettime(struct roar_time * rt, int clock) {
143#ifdef ROAR_HAVE_GETTIMEOFDAY
144 struct timeval tv;
145#elif defined(ROAR_HAVE_TIME)
146 time_t now;
147#endif
148
149 ROAR_DBG("roar_clock_gettime(rt=%p, clock=%i) = ?", rt, clock);
150
151 if ( rt == NULL ) {
152  roar_err_set(ROAR_ERROR_FAULT);
153  return -1;
154 }
155
156 memset(rt, 0, sizeof(struct roar_time));
157
158 if ( clock == ROAR_CLOCK_DEFAULT )
159  clock = ROAR_CLOCK_REALTIME;
160
161 switch (clock) {
162  case ROAR_CLOCK_REALTIME:
163    ROAR_DBG("roar_clock_gettime(rt=%p, clock=(%i)ROAR_CLOCK_REALTIME) = -1", rt, clock);
164#ifdef ROAR_HAVE_GETTIMEOFDAY
165    if ( gettimeofday(&tv, NULL) == -1 ) {
166     roar_err_from_errno();
167     return -1;
168    }
169    rt->t_sec  = tv.tv_sec;
170    rt->t_ssec = (uint64_t)tv.tv_usec * (uint64_t)18446744073709ULL;
171    rt->c_freq = 1000000LLU*1000000000LLU;
172#elif defined(ROAR_HAVE_TIME)
173    now = time(NULL);
174    rt->t_sec  = now;
175    rt->c_freq = 1000000000LLU;
176#else
177    roar_err_set(ROAR_ERROR_NOTSUP);
178    return -1;
179#endif
180    return 0;
181   break;
182 }
183
184 ROAR_DBG("roar_clock_gettime(rt=%p, clock=%i) = -1 // error=NOTSUP", rt, clock);
185 roar_err_set(ROAR_ERROR_NOTSUP);
186 return -1;
187}
188
189//ll
Note: See TracBrowser for help on using the repository browser.