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