annotate libao2/ao_esd.c @ 8763:19e96e60a3d0

Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
author anders
date Sat, 04 Jan 2003 06:19:25 +0000
parents 440301fef3fe
children 12b1790038b0
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
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
55 static ao_info_t info =
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
56 {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
57 "EsounD audio output",
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
58 "esd",
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
59 "Juergen Keil <jk@tools.de>",
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
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
63 LIBAO_EXTERN(esd)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
64
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
65 static int esd_fd = -1;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
66 static int esd_play_fd = -1;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
67 static esd_server_info_t *esd_svinfo;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
68 static int esd_latency;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
69 static int esd_bytes_per_sample;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
70 static unsigned long esd_samples_written;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
71 static struct timeval esd_play_start;
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 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
75 * to set/get/query special features/parameters
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
76 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
77 static int control(int cmd, int arg)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
78 {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
79 esd_player_info_t *esd_pi;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
80 esd_info_t *esd_i;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
81 time_t now;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
82 static time_t vol_cache_time;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
83 static ao_control_vol_t vol_cache;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
84
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
85 switch (cmd) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
86 case AOCONTROL_GET_VOLUME:
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
87 time(&now);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
88 if (now == vol_cache_time) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
89 *(ao_control_vol_t *)arg = vol_cache;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
90 return CONTROL_OK;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
91 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
92
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
93 dprintf("esd: get vol\n");
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
94 if ((esd_i = esd_get_all_info(esd_fd)) == NULL)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
95 return CONTROL_ERROR;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
96
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
97 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
98 if (strcmp(esd_pi->name, ESD_CLIENT_NAME) == 0)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
99 break;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
100
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
101 if (esd_pi != NULL) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
102 ao_control_vol_t *vol = (ao_control_vol_t *)arg;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
103 vol->left = esd_pi->left_vol_scale * 100 / ESD_VOLUME_BASE;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
104 vol->right = esd_pi->right_vol_scale * 100 / ESD_VOLUME_BASE;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
105
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
106 vol_cache = *vol;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
107 vol_cache_time = now;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
108 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
109 esd_free_all_info(esd_i);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
110
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
111 return CONTROL_OK;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
112
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
113 case AOCONTROL_SET_VOLUME:
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
114 dprintf("esd: set vol\n");
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
115 if ((esd_i = esd_get_all_info(esd_fd)) == NULL)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
116 return CONTROL_ERROR;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
117
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
118 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
119 if (strcmp(esd_pi->name, ESD_CLIENT_NAME) == 0)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
120 break;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
121
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
122 if (esd_pi != NULL) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
123 ao_control_vol_t *vol = (ao_control_vol_t *)arg;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
124 esd_set_stream_pan(esd_fd, esd_pi->source_id,
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
125 vol->left * ESD_VOLUME_BASE / 100,
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
126 vol->right * ESD_VOLUME_BASE / 100);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
127
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
128 vol_cache = *vol;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
129 time(&vol_cache_time);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
130 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
131 esd_free_all_info(esd_i);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
132 return CONTROL_OK;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
133
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
134 default:
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
135 return CONTROL_UNKNOWN;
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 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
141 * open & setup audio device
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
142 * return: 1=success 0=fail
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
143 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
144 static int init(int rate_hz, int channels, int format, int flags)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
145 {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
146 esd_format_t esd_fmt;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
147 int bytes_per_sample;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
148 int fl;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
149
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
150 if (esd_fd < 0) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
151 esd_fd = esd_open_sound(NULL);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
152 if (esd_fd < 0) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
153 mp_msg(MSGT_AO, MSGL_ERR, "AO: [esd] esd_open_sound failed: %s\n",
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
154 strerror(errno));
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
155 return 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
156 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
157
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
158 esd_svinfo = esd_get_server_info(esd_fd);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
159 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
160 if (esd_svinfo) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
161 mp_msg(MSGT_AO, MSGL_INFO, "AO: [esd] server info:\n");
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
162 esd_print_server_info(esd_svinfo);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
163 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
164 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
165
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
166 esd_latency = esd_get_latency(esd_fd);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
167 /* mp_msg(MSGT_AO, MSGL_INFO, "AO: [esd] latency: %d\n", esd_latency); */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
168 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
169
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
170 esd_fmt = ESD_STREAM | ESD_PLAY;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
171
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
172 #if ESD_RESAMPLES
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
173 /* let the esd daemon convert sample rate */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
174 #else
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
175 /* let mplayer's audio filter convert the sample rate */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
176 if (esd_svinfo != NULL)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
177 rate_hz = esd_svinfo->rate;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
178 #endif
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
179 ao_data.samplerate = rate_hz;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
180
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
181
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
182 /* EsounD can play mono or stereo */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
183 switch (channels) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
184 case 1:
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
185 esd_fmt |= ESD_MONO;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
186 ao_data.channels = bytes_per_sample = 1;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
187 break;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
188 default:
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
189 esd_fmt |= ESD_STEREO;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
190 ao_data.channels = bytes_per_sample = 2;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
191 break;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
192 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
193
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
194 /* EsounD can play 8bit unsigned and 16bit signed native */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
195 switch (format) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
196 case AFMT_S8:
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
197 case AFMT_U8:
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
198 esd_fmt |= ESD_BITS8;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
199 ao_data.format = AFMT_U8;
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 default:
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
202 esd_fmt |= ESD_BITS16;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
203 ao_data.format = AFMT_S16_NE;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
204 bytes_per_sample *= 2;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
205 break;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
206 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
207
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
208 esd_play_fd = esd_play_stream_fallback(esd_fmt, rate_hz,
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
209 NULL, ESD_CLIENT_NAME);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
210 if (esd_play_fd < 0) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
211 mp_msg(MSGT_AO, MSGL_ERR,
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
212 "AO: [esd] failed to open esd playback stream: %s\n",
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
213 strerror(errno));
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
214 return 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
215 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
216
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
217 /* enable non-blocking i/o on the socket connection to the esd server */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
218 if ((fl = fcntl(esd_play_fd, F_GETFL)) >= 0)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
219 fcntl(esd_play_fd, F_SETFL, O_NDELAY|fl);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
220
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
221 #if ESD_DEBUG
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
222 {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
223 int sbuf, rbuf, len;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
224 len = sizeof(sbuf);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
225 getsockopt(esd_play_fd, SOL_SOCKET, SO_SNDBUF, &sbuf, &len);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
226 len = sizeof(rbuf);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
227 getsockopt(esd_play_fd, SOL_SOCKET, SO_RCVBUF, &rbuf, &len);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
228 dprintf("esd: send/receive socket buffer space %d/%d bytes\n",
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
229 sbuf, rbuf);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
230 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
231 #endif
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
232
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
233 ao_data.bps = bytes_per_sample * rate_hz;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
234 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
235
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
236 esd_play_start.tv_sec = 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
237 esd_samples_written = 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
238 esd_bytes_per_sample = bytes_per_sample;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
239
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
240 return 1;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
241 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
242
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
243
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
244 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
245 * close audio device
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
246 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
247 static void uninit()
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
248 {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
249 if (esd_play_fd >= 0) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
250 esd_close(esd_play_fd);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
251 esd_play_fd = -1;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
252 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
253
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
254 if (esd_svinfo) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
255 esd_free_server_info(esd_svinfo);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
256 esd_svinfo = NULL;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
257 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
258
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
259 if (esd_fd >= 0) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
260 esd_close(esd_fd);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
261 esd_fd = -1;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
262 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
263 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
264
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
265
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
266 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
267 * plays 'len' bytes of 'data'
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
268 * it should round it down to outburst*n
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
269 * return: number of bytes played
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
270 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
271 static int play(void* data, int len, int flags)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
272 {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
273 int offs;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
274 int nwritten;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
275 int nsamples;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
276 int remainder, n;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
277 int saved_fl;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
278
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
279 /* round down buffersize to a multiple of ESD_BUF_SIZE bytes */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
280 len = len / ESD_BUF_SIZE * ESD_BUF_SIZE;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
281 if (len <= 0)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
282 return 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
283
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
284 #define SINGLE_WRITE 0
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
285 #if SINGLE_WRITE
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
286 nwritten = write(esd_play_fd, data, len);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
287 #else
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
288 for (offs = 0; offs + ESD_BUF_SIZE <= len; offs += ESD_BUF_SIZE) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
289 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
290 * note: we're writing to a non-blocking socket here.
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
291 * A partial write means, that the socket buffer is full.
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
292 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
293 nwritten = write(esd_play_fd, (char*)data + offs, ESD_BUF_SIZE);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
294 if (nwritten != ESD_BUF_SIZE) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
295 if (nwritten < 0 && errno != EAGAIN) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
296 dprintf("esd play: write failed: %s\n", strerror(errno));
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
297 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
298 break;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
299 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
300 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
301 nwritten = offs;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
302 #endif
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
303
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
304 if (nwritten > 0 && nwritten % ESD_BUF_SIZE != 0) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
305
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
306 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
307 * partial write of an audio block of ESD_BUF_SIZE bytes.
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
308 *
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
309 * Send the remainder of that block as well; this avoids a busy
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
310 * polling loop in the esd daemon, which waits for the rest of
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
311 * the incomplete block using reads from a non-blocking
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
312 * socket. This busy polling loop wastes CPU cycles on the
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
313 * esd server machine, and we're trying to avoid that.
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
314 * (esd 0.2.28+ has the busy polling read loop, 0.2.22 inserts
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
315 * 0 samples which is bad as well)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
316 *
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
317 * Let's hope the blocking write does not consume too much time.
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
318 *
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
319 * (fortunatelly, this piece of code is not used when playing
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
320 * sound on the local machine - on solaris at least)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
321 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
322 remainder = ESD_BUF_SIZE - nwritten % ESD_BUF_SIZE;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
323 dprintf("esd play: partial audio block written, remainder %d \n",
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
324 remainder);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
325
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
326 /* blocking write of remaining bytes for the partial audio block */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
327 saved_fl = fcntl(esd_play_fd, F_GETFL);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
328 fcntl(esd_play_fd, F_SETFL, saved_fl & ~O_NDELAY);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
329 n = write(esd_play_fd, (char *)data + nwritten, remainder);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
330 fcntl(esd_play_fd, F_SETFL, saved_fl);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
331
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
332 if (n != remainder) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
333 mp_msg(MSGT_AO, MSGL_ERR,
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
334 "AO: [esd] send remainer of audio block failed, %d/%d\n",
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
335 n, remainder);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
336 } else
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
337 nwritten += n;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
338 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
339
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
340 if (nwritten > 0) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
341 if (!esd_play_start.tv_sec)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
342 gettimeofday(&esd_play_start, NULL);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
343 nsamples = nwritten / esd_bytes_per_sample;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
344 esd_samples_written += nsamples;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
345
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
346 dprintf("esd play: %d %lu\n", nsamples, esd_samples_written);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
347 } else {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
348 dprintf("esd play: blocked / %lu\n", esd_samples_written);
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 return nwritten;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
352 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
353
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
354
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
355 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
356 * stop playing, keep buffers (for pause)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
357 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
358 static void audio_pause()
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 * not possible with esd. the esd daemom will continue playing
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
362 * buffered data (not more than ESD_MAX_DELAY seconds of samples)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
363 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
364 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
365
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
366
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
367 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
368 * resume playing, after audio_pause()
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
369 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
370 static void audio_resume()
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
371 {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
372 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
373 * not possible with esd.
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
374 *
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
375 * 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
376 * buffered data; we restart our time based delay computation
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
377 * for an audio resume.
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
378 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
379 esd_play_start.tv_sec = 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
380 esd_samples_written = 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
381 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
382
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
383
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
384 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
385 * stop playing and empty buffers (for seeking/pause)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
386 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
387 static void reset()
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
388 {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
389 #ifdef __svr4__
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
390 /* throw away data buffered in the esd connection */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
391 if (ioctl(esd_play_fd, I_FLUSH, FLUSHW))
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
392 perror("I_FLUSH");
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
393 #endif
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
394 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
395
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
396
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
397 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
398 * return: how many bytes can be played without blocking
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
399 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
400 static int get_space()
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
401 {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
402 struct timeval tmout;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
403 fd_set wfds;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
404 float current_delay;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
405 int space;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
406
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
407 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
408 * Don't buffer too much data in the esd daemon.
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 we send too much, esd will block in write()s to the sound
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
411 * device, and the consequence is a huge slow down for things like
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
412 * esd_get_all_info().
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
413 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
414 if ((current_delay = get_delay()) >= ESD_MAX_DELAY) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
415 dprintf("esd get_space: too much data buffered\n");
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
416 return 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
417 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
418
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
419 FD_ZERO(&wfds);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
420 FD_SET(esd_play_fd, &wfds);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
421 tmout.tv_sec = 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
422 tmout.tv_usec = 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
423
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
424 if (select(esd_play_fd + 1, NULL, &wfds, NULL, &tmout) != 1)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
425 return 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
426
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
427 if (!FD_ISSET(esd_play_fd, &wfds))
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
428 return 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
429
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
430 /* try to fill 50% of the remaining "free" buffer space */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
431 space = (ESD_MAX_DELAY - current_delay) * ao_data.bps * 0.5f;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
432
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
433 /* round up to next multiple of ESD_BUF_SIZE */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
434 space = (space + ESD_BUF_SIZE-1) / ESD_BUF_SIZE * ESD_BUF_SIZE;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
435
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
436 dprintf("esd get_space: %d\n", space);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
437 return space;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
438 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
439
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
440
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
441 /*
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
442 * return: delay in seconds between first and last sample in buffer
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
443 */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
444 static float get_delay()
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
445 {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
446 struct timeval now;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
447 double buffered_samples_time;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
448 double play_time;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
449
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
450 if (!esd_play_start.tv_sec)
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
451 return 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
452
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
453 buffered_samples_time = (float)esd_samples_written / ao_data.samplerate;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
454 gettimeofday(&now, NULL);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
455 play_time = now.tv_sec - esd_play_start.tv_sec;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
456 play_time += (now.tv_usec - esd_play_start.tv_usec) / 1000000.;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
457
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
458 /* dprintf("esd delay: %f %f\n", play_time, buffered_samples_time); */
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
459
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
460 if (play_time > buffered_samples_time) {
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
461 dprintf("esd: underflow\n");
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
462 esd_play_start.tv_sec = 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
463 esd_samples_written = 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
464 return 0;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
465 }
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
466
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
467 dprintf("esd: get_delay %f\n", buffered_samples_time - play_time);
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
468 return buffered_samples_time - play_time;
46dbfa8c1999 new EsounD audio driver (-ao esd)
jkeil
parents:
diff changeset
469 }