annotate libao2/ao_esd.c @ 12022:293141b57c01

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