Mercurial > mplayer.hg
annotate libao2/ao_esd.c @ 16805:50fb26acbcba
processing audio is sometimes essential for a/v sync, so 1000l to
whoever made rawvideo muxer disable audio!!
with this patch, audio is processed but simply thrown away by the
muxer. various 'error' conditions in rawvideo muxer are removed to
make it work. feel free to re-add them if they can be done without
breaking anything, but do not use printf !!!!
btw old behavior can be obtained by manually specifying -nosound.
author | rfelker |
---|---|
date | Wed, 19 Oct 2005 05:44:27 +0000 |
parents | cae0dbeb44bb |
children | f580a7755ac5 |
rev | line source |
---|---|
8572 | 1 /* |
2 * ao_esd - EsounD audio output driver for MPlayer | |
3 * | |
4 * Juergen Keil <jk@tools.de> | |
5 * | |
6 * This driver is distributed under the terms of the GPL | |
7 * | |
8 * TODO / known problems: | |
9 * - does not work well when the esd daemon has autostandby disabled | |
10 * (workaround: run esd with option "-as 2" - fortunatelly this is | |
11 * the default) | |
12 * - plays noise on a linux 2.4.4 kernel with a SB16PCI card, when using | |
13 * a local tcp connection to the esd daemon; there is no noise when using | |
14 * a unix domain socket connection. | |
15 * (there are EIO errors reported by the sound card driver, so this is | |
16 * most likely a linux sound card driver problem) | |
17 */ | |
18 | |
19 #include <sys/types.h> | |
20 #include <sys/time.h> | |
21 #include <sys/socket.h> | |
22 #include <stdio.h> | |
23 #include <string.h> | |
24 #include <unistd.h> | |
25 #include <errno.h> | |
26 #include <fcntl.h> | |
8623
440301fef3fe
Added/reordered #includes to silence warnings about "implicit declaration".
rathann
parents:
8572
diff
changeset
|
27 #include <time.h> |
8572 | 28 #ifdef __svr4__ |
29 #include <stropts.h> | |
30 #endif | |
31 #include <esd.h> | |
32 | |
14479 | 33 #include "config.h" |
8572 | 34 #include "audio_out.h" |
35 #include "audio_out_internal.h" | |
14245 | 36 #include "libaf/af_format.h" |
14123 | 37 #include "mp_msg.h" |
38 #include "help_mp.h" | |
8572 | 39 |
40 | |
41 #undef ESD_DEBUG | |
42 | |
43 #if ESD_DEBUG | |
44 #define dprintf(...) printf(__VA_ARGS__) | |
45 #else | |
46 #define dprintf(...) /**/ | |
47 #endif | |
48 | |
49 | |
50 #define ESD_CLIENT_NAME "MPlayer" | |
51 #define ESD_MAX_DELAY (1.0f) /* max amount of data buffered in esd (#sec) */ | |
52 | |
53 static ao_info_t info = | |
54 { | |
55 "EsounD audio output", | |
56 "esd", | |
57 "Juergen Keil <jk@tools.de>", | |
58 "" | |
59 }; | |
60 | |
61 LIBAO_EXTERN(esd) | |
62 | |
63 static int esd_fd = -1; | |
64 static int esd_play_fd = -1; | |
65 static esd_server_info_t *esd_svinfo; | |
66 static int esd_latency; | |
67 static int esd_bytes_per_sample; | |
68 static unsigned long esd_samples_written; | |
69 static struct timeval esd_play_start; | |
10213
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
70 extern float audio_delay; |
8572 | 71 |
72 /* | |
73 * to set/get/query special features/parameters | |
74 */ | |
9633
12b1790038b0
64bit libao2 fix by Jens Axboe <mplayer-dev@kernel.dk>
alex
parents:
8623
diff
changeset
|
75 static int control(int cmd, void *arg) |
8572 | 76 { |
77 esd_player_info_t *esd_pi; | |
78 esd_info_t *esd_i; | |
79 time_t now; | |
80 static time_t vol_cache_time; | |
81 static ao_control_vol_t vol_cache; | |
82 | |
83 switch (cmd) { | |
84 case AOCONTROL_GET_VOLUME: | |
85 time(&now); | |
86 if (now == vol_cache_time) { | |
87 *(ao_control_vol_t *)arg = vol_cache; | |
88 return CONTROL_OK; | |
89 } | |
90 | |
91 dprintf("esd: get vol\n"); | |
92 if ((esd_i = esd_get_all_info(esd_fd)) == NULL) | |
93 return CONTROL_ERROR; | |
94 | |
95 for (esd_pi = esd_i->player_list; esd_pi != NULL; esd_pi = esd_pi->next) | |
96 if (strcmp(esd_pi->name, ESD_CLIENT_NAME) == 0) | |
97 break; | |
98 | |
99 if (esd_pi != NULL) { | |
100 ao_control_vol_t *vol = (ao_control_vol_t *)arg; | |
101 vol->left = esd_pi->left_vol_scale * 100 / ESD_VOLUME_BASE; | |
102 vol->right = esd_pi->right_vol_scale * 100 / ESD_VOLUME_BASE; | |
103 | |
104 vol_cache = *vol; | |
105 vol_cache_time = now; | |
106 } | |
107 esd_free_all_info(esd_i); | |
108 | |
109 return CONTROL_OK; | |
110 | |
111 case AOCONTROL_SET_VOLUME: | |
112 dprintf("esd: set vol\n"); | |
113 if ((esd_i = esd_get_all_info(esd_fd)) == NULL) | |
114 return CONTROL_ERROR; | |
115 | |
116 for (esd_pi = esd_i->player_list; esd_pi != NULL; esd_pi = esd_pi->next) | |
117 if (strcmp(esd_pi->name, ESD_CLIENT_NAME) == 0) | |
118 break; | |
119 | |
120 if (esd_pi != NULL) { | |
121 ao_control_vol_t *vol = (ao_control_vol_t *)arg; | |
122 esd_set_stream_pan(esd_fd, esd_pi->source_id, | |
123 vol->left * ESD_VOLUME_BASE / 100, | |
124 vol->right * ESD_VOLUME_BASE / 100); | |
125 | |
126 vol_cache = *vol; | |
127 time(&vol_cache_time); | |
128 } | |
129 esd_free_all_info(esd_i); | |
130 return CONTROL_OK; | |
131 | |
132 default: | |
133 return CONTROL_UNKNOWN; | |
134 } | |
135 } | |
136 | |
137 | |
138 /* | |
139 * open & setup audio device | |
140 * return: 1=success 0=fail | |
141 */ | |
142 static int init(int rate_hz, int channels, int format, int flags) | |
143 { | |
144 esd_format_t esd_fmt; | |
145 int bytes_per_sample; | |
146 int fl; | |
10213
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
147 char *server = ao_subdevice; /* NULL for localhost */ |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
148 float lag_seconds, lag_net, lag_serv; |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
149 struct timeval proto_start, proto_end; |
8572 | 150 |
151 if (esd_fd < 0) { | |
10213
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
152 esd_fd = esd_open_sound(server); |
8572 | 153 if (esd_fd < 0) { |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12145
diff
changeset
|
154 mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ESD_CantOpenSound, |
8572 | 155 strerror(errno)); |
156 return 0; | |
157 } | |
158 | |
10213
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
159 /* get server info, and measure network latency */ |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
160 gettimeofday(&proto_start, NULL); |
8572 | 161 esd_svinfo = esd_get_server_info(esd_fd); |
10213
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
162 if(server) { |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
163 gettimeofday(&proto_end, NULL); |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
164 lag_net = (proto_end.tv_sec - proto_start.tv_sec) + |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
165 (proto_end.tv_usec - proto_start.tv_usec) / 1000000.0; |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
166 lag_net /= 2.0; /* round trip -> one way */ |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
167 } else |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
168 lag_net = 0.0; /* no network lag */ |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
169 |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
170 /* |
8572 | 171 if (esd_svinfo) { |
172 mp_msg(MSGT_AO, MSGL_INFO, "AO: [esd] server info:\n"); | |
173 esd_print_server_info(esd_svinfo); | |
174 } | |
10213
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
175 */ |
8572 | 176 } |
177 | |
178 esd_fmt = ESD_STREAM | ESD_PLAY; | |
179 | |
180 #if ESD_RESAMPLES | |
181 /* let the esd daemon convert sample rate */ | |
182 #else | |
183 /* let mplayer's audio filter convert the sample rate */ | |
184 if (esd_svinfo != NULL) | |
185 rate_hz = esd_svinfo->rate; | |
186 #endif | |
187 ao_data.samplerate = rate_hz; | |
188 | |
189 /* EsounD can play mono or stereo */ | |
190 switch (channels) { | |
191 case 1: | |
192 esd_fmt |= ESD_MONO; | |
193 ao_data.channels = bytes_per_sample = 1; | |
194 break; | |
195 default: | |
196 esd_fmt |= ESD_STEREO; | |
197 ao_data.channels = bytes_per_sample = 2; | |
198 break; | |
199 } | |
200 | |
201 /* EsounD can play 8bit unsigned and 16bit signed native */ | |
202 switch (format) { | |
14245 | 203 case AF_FORMAT_S8: |
204 case AF_FORMAT_U8: | |
8572 | 205 esd_fmt |= ESD_BITS8; |
14245 | 206 ao_data.format = AF_FORMAT_U8; |
8572 | 207 break; |
208 default: | |
209 esd_fmt |= ESD_BITS16; | |
14245 | 210 ao_data.format = AF_FORMAT_S16_NE; |
8572 | 211 bytes_per_sample *= 2; |
212 break; | |
213 } | |
214 | |
10213
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
215 /* modify audio_delay depending on esd_latency |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
216 * latency is number of samples @ 44.1khz stereo 16 bit |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
217 * adjust according to rate_hz & bytes_per_sample |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
218 */ |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
219 #ifdef HAVE_ESD_LATENCY |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
220 esd_latency = esd_get_latency(esd_fd); |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
221 #else |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
222 esd_latency = ((channels == 1 ? 2 : 1) * ESD_DEFAULT_RATE * |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
223 (ESD_BUF_SIZE + 64 * (4.0f / bytes_per_sample)) |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
224 ) / rate_hz; |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
225 esd_latency += ESD_BUF_SIZE * 2; |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
226 #endif |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
227 if(esd_latency > 0) { |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
228 lag_serv = (esd_latency * 4.0f) / (bytes_per_sample * rate_hz); |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
229 lag_seconds = lag_net + lag_serv; |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
230 audio_delay += lag_seconds; |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12145
diff
changeset
|
231 mp_msg(MSGT_AO, MSGL_INFO,MSGTR_AO_ESD_LatencyInfo, |
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12145
diff
changeset
|
232 lag_serv, lag_net, lag_seconds); |
10213
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
233 } |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
234 |
8572 | 235 esd_play_fd = esd_play_stream_fallback(esd_fmt, rate_hz, |
10213
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
236 server, ESD_CLIENT_NAME); |
8572 | 237 if (esd_play_fd < 0) { |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12145
diff
changeset
|
238 mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ESD_CantOpenPBStream, strerror(errno)); |
8572 | 239 return 0; |
240 } | |
241 | |
242 /* enable non-blocking i/o on the socket connection to the esd server */ | |
243 if ((fl = fcntl(esd_play_fd, F_GETFL)) >= 0) | |
244 fcntl(esd_play_fd, F_SETFL, O_NDELAY|fl); | |
245 | |
246 #if ESD_DEBUG | |
247 { | |
248 int sbuf, rbuf, len; | |
249 len = sizeof(sbuf); | |
250 getsockopt(esd_play_fd, SOL_SOCKET, SO_SNDBUF, &sbuf, &len); | |
251 len = sizeof(rbuf); | |
252 getsockopt(esd_play_fd, SOL_SOCKET, SO_RCVBUF, &rbuf, &len); | |
253 dprintf("esd: send/receive socket buffer space %d/%d bytes\n", | |
254 sbuf, rbuf); | |
255 } | |
256 #endif | |
257 | |
258 ao_data.bps = bytes_per_sample * rate_hz; | |
259 ao_data.outburst = ao_data.bps > 100000 ? 4*ESD_BUF_SIZE : 2*ESD_BUF_SIZE; | |
260 | |
261 esd_play_start.tv_sec = 0; | |
262 esd_samples_written = 0; | |
263 esd_bytes_per_sample = bytes_per_sample; | |
264 | |
265 return 1; | |
266 } | |
267 | |
268 | |
269 /* | |
270 * close audio device | |
271 */ | |
12145 | 272 static void uninit(int immed) |
8572 | 273 { |
274 if (esd_play_fd >= 0) { | |
275 esd_close(esd_play_fd); | |
276 esd_play_fd = -1; | |
277 } | |
278 | |
279 if (esd_svinfo) { | |
280 esd_free_server_info(esd_svinfo); | |
281 esd_svinfo = NULL; | |
282 } | |
283 | |
284 if (esd_fd >= 0) { | |
285 esd_close(esd_fd); | |
286 esd_fd = -1; | |
287 } | |
288 } | |
289 | |
290 | |
291 /* | |
292 * plays 'len' bytes of 'data' | |
293 * it should round it down to outburst*n | |
294 * return: number of bytes played | |
295 */ | |
296 static int play(void* data, int len, int flags) | |
297 { | |
298 int offs; | |
299 int nwritten; | |
300 int nsamples; | |
301 int remainder, n; | |
302 int saved_fl; | |
303 | |
304 /* round down buffersize to a multiple of ESD_BUF_SIZE bytes */ | |
305 len = len / ESD_BUF_SIZE * ESD_BUF_SIZE; | |
306 if (len <= 0) | |
307 return 0; | |
308 | |
309 #define SINGLE_WRITE 0 | |
310 #if SINGLE_WRITE | |
311 nwritten = write(esd_play_fd, data, len); | |
312 #else | |
11619
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
313 for (offs = 0, nwritten=0; offs + ESD_BUF_SIZE <= len; offs += ESD_BUF_SIZE) { |
8572 | 314 /* |
315 * note: we're writing to a non-blocking socket here. | |
316 * A partial write means, that the socket buffer is full. | |
317 */ | |
11619
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
318 n = write(esd_play_fd, (char*)data + offs, ESD_BUF_SIZE); |
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
319 if ( n < 0 ) { |
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
320 if ( errno != EAGAIN ) |
8572 | 321 dprintf("esd play: write failed: %s\n", strerror(errno)); |
322 break; | |
11619
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
323 } else if ( n != ESD_BUF_SIZE ) { |
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
324 nwritten += n; |
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
325 break; |
8572 | 326 } else |
327 nwritten += n; | |
328 } | |
11619
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
329 #endif |
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
330 |
8572 | 331 if (nwritten > 0) { |
332 if (!esd_play_start.tv_sec) | |
333 gettimeofday(&esd_play_start, NULL); | |
334 nsamples = nwritten / esd_bytes_per_sample; | |
335 esd_samples_written += nsamples; | |
336 | |
337 dprintf("esd play: %d %lu\n", nsamples, esd_samples_written); | |
338 } else { | |
339 dprintf("esd play: blocked / %lu\n", esd_samples_written); | |
340 } | |
341 | |
342 return nwritten; | |
343 } | |
344 | |
345 | |
346 /* | |
347 * stop playing, keep buffers (for pause) | |
348 */ | |
349 static void audio_pause() | |
350 { | |
351 /* | |
352 * not possible with esd. the esd daemom will continue playing | |
353 * buffered data (not more than ESD_MAX_DELAY seconds of samples) | |
354 */ | |
355 } | |
356 | |
357 | |
358 /* | |
359 * resume playing, after audio_pause() | |
360 */ | |
361 static void audio_resume() | |
362 { | |
363 /* | |
364 * not possible with esd. | |
365 * | |
366 * Let's hope the pause was long enough that the esd ran out of | |
367 * buffered data; we restart our time based delay computation | |
368 * for an audio resume. | |
369 */ | |
370 esd_play_start.tv_sec = 0; | |
371 esd_samples_written = 0; | |
372 } | |
373 | |
374 | |
375 /* | |
376 * stop playing and empty buffers (for seeking/pause) | |
377 */ | |
378 static void reset() | |
379 { | |
380 #ifdef __svr4__ | |
381 /* throw away data buffered in the esd connection */ | |
382 if (ioctl(esd_play_fd, I_FLUSH, FLUSHW)) | |
383 perror("I_FLUSH"); | |
384 #endif | |
385 } | |
386 | |
387 | |
388 /* | |
389 * return: how many bytes can be played without blocking | |
390 */ | |
391 static int get_space() | |
392 { | |
393 struct timeval tmout; | |
394 fd_set wfds; | |
395 float current_delay; | |
396 int space; | |
397 | |
398 /* | |
399 * Don't buffer too much data in the esd daemon. | |
400 * | |
401 * If we send too much, esd will block in write()s to the sound | |
402 * device, and the consequence is a huge slow down for things like | |
403 * esd_get_all_info(). | |
404 */ | |
405 if ((current_delay = get_delay()) >= ESD_MAX_DELAY) { | |
406 dprintf("esd get_space: too much data buffered\n"); | |
407 return 0; | |
408 } | |
409 | |
410 FD_ZERO(&wfds); | |
411 FD_SET(esd_play_fd, &wfds); | |
412 tmout.tv_sec = 0; | |
413 tmout.tv_usec = 0; | |
414 | |
415 if (select(esd_play_fd + 1, NULL, &wfds, NULL, &tmout) != 1) | |
416 return 0; | |
417 | |
418 if (!FD_ISSET(esd_play_fd, &wfds)) | |
419 return 0; | |
420 | |
421 /* try to fill 50% of the remaining "free" buffer space */ | |
422 space = (ESD_MAX_DELAY - current_delay) * ao_data.bps * 0.5f; | |
423 | |
424 /* round up to next multiple of ESD_BUF_SIZE */ | |
425 space = (space + ESD_BUF_SIZE-1) / ESD_BUF_SIZE * ESD_BUF_SIZE; | |
426 | |
427 dprintf("esd get_space: %d\n", space); | |
428 return space; | |
429 } | |
430 | |
431 | |
432 /* | |
433 * return: delay in seconds between first and last sample in buffer | |
434 */ | |
435 static float get_delay() | |
436 { | |
437 struct timeval now; | |
438 double buffered_samples_time; | |
439 double play_time; | |
440 | |
441 if (!esd_play_start.tv_sec) | |
442 return 0; | |
443 | |
444 buffered_samples_time = (float)esd_samples_written / ao_data.samplerate; | |
445 gettimeofday(&now, NULL); | |
446 play_time = now.tv_sec - esd_play_start.tv_sec; | |
447 play_time += (now.tv_usec - esd_play_start.tv_usec) / 1000000.; | |
448 | |
449 /* dprintf("esd delay: %f %f\n", play_time, buffered_samples_time); */ | |
450 | |
451 if (play_time > buffered_samples_time) { | |
452 dprintf("esd: underflow\n"); | |
453 esd_play_start.tv_sec = 0; | |
454 esd_samples_written = 0; | |
455 return 0; | |
456 } | |
457 | |
458 dprintf("esd: get_delay %f\n", buffered_samples_time - play_time); | |
459 return buffered_samples_time - play_time; | |
460 } |