Mercurial > mplayer.hg
annotate libao2/ao_esd.c @ 36892:f50427ad9ff6
Internally map item 'potmeter' onto 'hpotmeter'.
Former version of the GUI treated a potmeter very similar to a hpotmeter
(the Win32 GUI still does so) and lots of skins are solely using
potmeters instead of hpotmeters, although this doesn't make sense at
all.
The current version of the GUI is treating a potmeter differently, but
in order to not break old skins, restore the old behaviour.
For the X11/GTK GUI, a potmeter is now simply a hpotmeter with
button=NULL and (button)width=(button)height=0. For the Win32 GUI
(where skins unfortunately are handled a bit differently and things
are more complicated) a potmeter is now a hpotmeter without button
but (button)width=(widget)width and (button)height=(widget)height.
Additionally, print a legacy information, because the item 'potmeter' is
obsolete now and oughtn't be used any longer.
author | ib |
---|---|
date | Mon, 10 Mar 2014 17:32:29 +0000 |
parents | 6ec928ab8112 |
children |
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 |
10213
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
168 esd_fd = esd_open_sound(server); |
8572 | 169 if (esd_fd < 0) { |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12145
diff
changeset
|
170 mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ESD_CantOpenSound, |
8572 | 171 strerror(errno)); |
172 return 0; | |
173 } | |
174 | |
10213
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
175 /* 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
|
176 gettimeofday(&proto_start, NULL); |
8572 | 177 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
|
178 if(server) { |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
179 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
|
180 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
|
181 (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
|
182 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
|
183 } else |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
184 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
|
185 |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
186 /* |
8572 | 187 if (esd_svinfo) { |
188 mp_msg(MSGT_AO, MSGL_INFO, "AO: [esd] server info:\n"); | |
189 esd_print_server_info(esd_svinfo); | |
190 } | |
10213
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
191 */ |
8572 | 192 |
193 esd_fmt = ESD_STREAM | ESD_PLAY; | |
194 | |
195 #if ESD_RESAMPLES | |
196 /* let the esd daemon convert sample rate */ | |
197 #else | |
198 /* let mplayer's audio filter convert the sample rate */ | |
199 if (esd_svinfo != NULL) | |
200 rate_hz = esd_svinfo->rate; | |
201 #endif | |
202 ao_data.samplerate = rate_hz; | |
203 | |
204 /* EsounD can play mono or stereo */ | |
205 switch (channels) { | |
206 case 1: | |
207 esd_fmt |= ESD_MONO; | |
208 ao_data.channels = bytes_per_sample = 1; | |
209 break; | |
210 default: | |
211 esd_fmt |= ESD_STEREO; | |
212 ao_data.channels = bytes_per_sample = 2; | |
213 break; | |
214 } | |
215 | |
216 /* EsounD can play 8bit unsigned and 16bit signed native */ | |
217 switch (format) { | |
14245 | 218 case AF_FORMAT_S8: |
219 case AF_FORMAT_U8: | |
8572 | 220 esd_fmt |= ESD_BITS8; |
14245 | 221 ao_data.format = AF_FORMAT_U8; |
8572 | 222 break; |
223 default: | |
224 esd_fmt |= ESD_BITS16; | |
14245 | 225 ao_data.format = AF_FORMAT_S16_NE; |
8572 | 226 bytes_per_sample *= 2; |
227 break; | |
228 } | |
229 | |
10213
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
230 /* 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
|
231 * 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
|
232 * 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
|
233 */ |
27387
eb7bdbd98210
Rename some audio-output-related preprocessor directives.
diego
parents:
18976
diff
changeset
|
234 #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
|
235 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
|
236 #else |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
237 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
|
238 (ESD_BUF_SIZE + 64 * (4.0f / bytes_per_sample)) |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
239 ) / rate_hz; |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
240 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
|
241 #endif |
5e15ff3261ff
esd:server and esd latency support by Andrew Williams <andrew.s.williams@adelaide.edu.au>
alex
parents:
9633
diff
changeset
|
242 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
|
243 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
|
244 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
|
245 audio_delay += lag_seconds; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
246 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
|
247 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
|
248 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
249 |
8572 | 250 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
|
251 server, ESD_CLIENT_NAME); |
8572 | 252 if (esd_play_fd < 0) { |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12145
diff
changeset
|
253 mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ESD_CantOpenPBStream, strerror(errno)); |
8572 | 254 return 0; |
255 } | |
256 | |
257 /* enable non-blocking i/o on the socket connection to the esd server */ | |
258 if ((fl = fcntl(esd_play_fd, F_GETFL)) >= 0) | |
259 fcntl(esd_play_fd, F_SETFL, O_NDELAY|fl); | |
260 | |
261 #if ESD_DEBUG | |
262 { | |
263 int sbuf, rbuf, len; | |
264 len = sizeof(sbuf); | |
265 getsockopt(esd_play_fd, SOL_SOCKET, SO_SNDBUF, &sbuf, &len); | |
266 len = sizeof(rbuf); | |
267 getsockopt(esd_play_fd, SOL_SOCKET, SO_RCVBUF, &rbuf, &len); | |
268 dprintf("esd: send/receive socket buffer space %d/%d bytes\n", | |
269 sbuf, rbuf); | |
270 } | |
271 #endif | |
272 | |
273 ao_data.bps = bytes_per_sample * rate_hz; | |
274 ao_data.outburst = ao_data.bps > 100000 ? 4*ESD_BUF_SIZE : 2*ESD_BUF_SIZE; | |
275 | |
276 esd_play_start.tv_sec = 0; | |
277 esd_samples_written = 0; | |
278 esd_bytes_per_sample = bytes_per_sample; | |
279 | |
280 return 1; | |
281 } | |
282 | |
283 | |
284 /* | |
285 * close audio device | |
286 */ | |
12145 | 287 static void uninit(int immed) |
8572 | 288 { |
289 if (esd_play_fd >= 0) { | |
290 esd_close(esd_play_fd); | |
291 esd_play_fd = -1; | |
292 } | |
293 | |
294 if (esd_svinfo) { | |
295 esd_free_server_info(esd_svinfo); | |
296 esd_svinfo = NULL; | |
297 } | |
298 | |
299 if (esd_fd >= 0) { | |
300 esd_close(esd_fd); | |
301 esd_fd = -1; | |
302 } | |
303 } | |
304 | |
305 | |
306 /* | |
307 * plays 'len' bytes of 'data' | |
308 * it should round it down to outburst*n | |
309 * return: number of bytes played | |
310 */ | |
311 static int play(void* data, int len, int flags) | |
312 { | |
313 int offs; | |
314 int nwritten; | |
315 int nsamples; | |
18976
6a08d0dabca8
Remove unused variables, patch by Stefan Huehner, stefan ##at## huehner org.
diego
parents:
17566
diff
changeset
|
316 int n; |
8572 | 317 |
318 /* round down buffersize to a multiple of ESD_BUF_SIZE bytes */ | |
319 len = len / ESD_BUF_SIZE * ESD_BUF_SIZE; | |
320 if (len <= 0) | |
321 return 0; | |
322 | |
323 #define SINGLE_WRITE 0 | |
324 #if SINGLE_WRITE | |
325 nwritten = write(esd_play_fd, data, len); | |
326 #else | |
11619
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
327 for (offs = 0, nwritten=0; offs + ESD_BUF_SIZE <= len; offs += ESD_BUF_SIZE) { |
8572 | 328 /* |
329 * note: we're writing to a non-blocking socket here. | |
330 * A partial write means, that the socket buffer is full. | |
331 */ | |
11619
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
332 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
|
333 if ( n < 0 ) { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
334 if ( errno != EAGAIN ) |
8572 | 335 dprintf("esd play: write failed: %s\n", strerror(errno)); |
336 break; | |
11619
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
337 } else if ( n != ESD_BUF_SIZE ) { |
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
338 nwritten += n; |
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
339 break; |
8572 | 340 } else |
341 nwritten += n; | |
342 } | |
11619
179138947307
This patch contains bugfixes for the esd audio output driver that I
attila
parents:
10213
diff
changeset
|
343 #endif |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
344 |
8572 | 345 if (nwritten > 0) { |
346 if (!esd_play_start.tv_sec) | |
347 gettimeofday(&esd_play_start, NULL); | |
348 nsamples = nwritten / esd_bytes_per_sample; | |
349 esd_samples_written += nsamples; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
350 |
8572 | 351 dprintf("esd play: %d %lu\n", nsamples, esd_samples_written); |
352 } else { | |
353 dprintf("esd play: blocked / %lu\n", esd_samples_written); | |
354 } | |
355 | |
356 return nwritten; | |
357 } | |
358 | |
359 | |
360 /* | |
361 * stop playing, keep buffers (for pause) | |
362 */ | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
14479
diff
changeset
|
363 static void audio_pause(void) |
8572 | 364 { |
365 /* | |
366 * not possible with esd. the esd daemom will continue playing | |
367 * buffered data (not more than ESD_MAX_DELAY seconds of samples) | |
368 */ | |
369 } | |
370 | |
371 | |
372 /* | |
373 * resume playing, after audio_pause() | |
374 */ | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
14479
diff
changeset
|
375 static void audio_resume(void) |
8572 | 376 { |
377 /* | |
378 * not possible with esd. | |
379 * | |
380 * Let's hope the pause was long enough that the esd ran out of | |
381 * buffered data; we restart our time based delay computation | |
382 * for an audio resume. | |
383 */ | |
384 esd_play_start.tv_sec = 0; | |
385 esd_samples_written = 0; | |
386 } | |
387 | |
388 | |
389 /* | |
390 * stop playing and empty buffers (for seeking/pause) | |
391 */ | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
14479
diff
changeset
|
392 static void reset(void) |
8572 | 393 { |
394 #ifdef __svr4__ | |
395 /* throw away data buffered in the esd connection */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
396 if (ioctl(esd_play_fd, I_FLUSH, FLUSHW)) |
8572 | 397 perror("I_FLUSH"); |
398 #endif | |
399 } | |
400 | |
401 | |
402 /* | |
403 * return: how many bytes can be played without blocking | |
404 */ | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
14479
diff
changeset
|
405 static int get_space(void) |
8572 | 406 { |
407 struct timeval tmout; | |
408 fd_set wfds; | |
409 float current_delay; | |
410 int space; | |
411 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
412 /* |
8572 | 413 * Don't buffer too much data in the esd daemon. |
414 * | |
415 * If we send too much, esd will block in write()s to the sound | |
416 * device, and the consequence is a huge slow down for things like | |
417 * esd_get_all_info(). | |
418 */ | |
419 if ((current_delay = get_delay()) >= ESD_MAX_DELAY) { | |
420 dprintf("esd get_space: too much data buffered\n"); | |
421 return 0; | |
422 } | |
423 | |
424 FD_ZERO(&wfds); | |
425 FD_SET(esd_play_fd, &wfds); | |
426 tmout.tv_sec = 0; | |
427 tmout.tv_usec = 0; | |
428 | |
429 if (select(esd_play_fd + 1, NULL, &wfds, NULL, &tmout) != 1) | |
430 return 0; | |
431 | |
432 if (!FD_ISSET(esd_play_fd, &wfds)) | |
433 return 0; | |
434 | |
435 /* try to fill 50% of the remaining "free" buffer space */ | |
436 space = (ESD_MAX_DELAY - current_delay) * ao_data.bps * 0.5f; | |
437 | |
438 /* round up to next multiple of ESD_BUF_SIZE */ | |
439 space = (space + ESD_BUF_SIZE-1) / ESD_BUF_SIZE * ESD_BUF_SIZE; | |
440 | |
441 dprintf("esd get_space: %d\n", space); | |
442 return space; | |
443 } | |
444 | |
445 | |
446 /* | |
447 * return: delay in seconds between first and last sample in buffer | |
448 */ | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
14479
diff
changeset
|
449 static float get_delay(void) |
8572 | 450 { |
451 struct timeval now; | |
452 double buffered_samples_time; | |
453 double play_time; | |
454 | |
455 if (!esd_play_start.tv_sec) | |
456 return 0; | |
457 | |
458 buffered_samples_time = (float)esd_samples_written / ao_data.samplerate; | |
459 gettimeofday(&now, NULL); | |
460 play_time = now.tv_sec - esd_play_start.tv_sec; | |
461 play_time += (now.tv_usec - esd_play_start.tv_usec) / 1000000.; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
462 |
8572 | 463 /* dprintf("esd delay: %f %f\n", play_time, buffered_samples_time); */ |
464 | |
465 if (play_time > buffered_samples_time) { | |
466 dprintf("esd: underflow\n"); | |
467 esd_play_start.tv_sec = 0; | |
468 esd_samples_written = 0; | |
469 return 0; | |
470 } | |
471 | |
472 dprintf("esd: get_delay %f\n", buffered_samples_time - play_time); | |
473 return buffered_samples_time - play_time; | |
474 } |