Mercurial > mplayer.hg
annotate libao2/ao_alsa1x.c @ 2100:6f6eb4f8e7a0
finished mov header and index processing
author | arpi |
---|---|
date | Fri, 05 Oct 2001 23:13:26 +0000 |
parents | 3c390543302c |
children | a59f952fad34 |
rev | line source |
---|---|
1050 | 1 /* |
2 ao_alsa9 - ALSA-0.9.x output plugin for MPlayer | |
3 | |
4 (C) Alex Beregszaszi <alex@naxine.org> | |
1180 | 5 |
6 Don't use this buggy driver, ALSA-0.9.x emulates OSS very well... | |
1050 | 7 */ |
8 | |
9 #include <errno.h> | |
10 #include <sys/asoundlib.h> | |
11 | |
12 #include "../config.h" | |
13 | |
14 #include "audio_out.h" | |
15 #include "audio_out_internal.h" | |
1058 | 16 #include "afmt.h" |
1050 | 17 |
18 extern int verbose; | |
19 | |
20 static ao_info_t info = | |
21 { | |
22 "ALSA-0.9.x audio output", | |
23 "alsa9", | |
24 "Alex Beregszaszi <alex@naxine.org>", | |
25 "under developement" | |
26 }; | |
27 | |
28 LIBAO_EXTERN(alsa9) | |
29 | |
30 /* global variables: | |
31 ao_samplerate | |
32 ao_channels | |
33 ao_format | |
34 ao_bps | |
35 ao_outburst | |
36 ao_buffersize | |
37 */ | |
38 | |
39 static snd_pcm_t *alsa_handler; | |
40 static snd_pcm_format_t alsa_format; | |
41 static snd_pcm_hw_params_t *alsa_hwparams; | |
42 static snd_pcm_sw_params_t *alsa_swparams; | |
43 static char *alsa_device; | |
2059 | 44 #define ALSA_DEVICE_SIZE 48 /* war 48 */ |
1050 | 45 |
2059 | 46 static int alsa_fragsize = 8192; /* 4096 war 8192*/ |
47 static int alsa_fragcount = 8; /* war 8 */ | |
1128 | 48 |
1050 | 49 /* to set/get/query special features/parameters */ |
50 static int control(int cmd, int arg) | |
51 { | |
52 switch(cmd) | |
53 { | |
54 case AOCONTROL_GET_DEVICE: | |
1146
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
55 return((char *)alsa_device); /* egy kicsit brutalis, dehat :) */ |
1050 | 56 case AOCONTROL_SET_DEVICE: |
1146
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
57 { |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
58 int ret; |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
59 |
1050 | 60 strncpy(alsa_device, (char *)arg, ALSA_DEVICE_SIZE); |
1146
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
61 uninit(); |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
62 ret = init(ao_samplerate, ao_channels, ao_format, 0); |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
63 if (ret == 0) |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
64 return(CONTROL_ERROR); |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
65 else |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
66 return(CONTROL_OK); |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
67 } |
1050 | 68 } |
69 return(CONTROL_UNKNOWN); | |
70 } | |
71 | |
2059 | 72 #undef start /* war undef */ |
73 #define buffersize | |
74 #undef buffertime /* war undef? */ | |
1128 | 75 #define set_period |
2059 | 76 #define sw_params /* war undef */ |
77 #undef set_start_mode /* war undef */ | |
1128 | 78 |
1050 | 79 /* |
80 open & setup audio device | |
81 return: 1=success 0=fail | |
82 */ | |
83 static int init(int rate_hz, int channels, int format, int flags) | |
84 { | |
85 int err; | |
86 int cards = -1; | |
87 snd_pcm_info_t *alsa_info; | |
1180 | 88 |
2059 | 89 printf("alsa-init: Don't use this buggy driver, ALSA-0.9.x emulates OSS very well... modified by me\n"); |
1050 | 90 |
91 printf("alsa-init: requested format: %d Hz, %d channels, %s\n", rate_hz, | |
92 channels, audio_out_format_name(format)); | |
93 | |
94 alsa_handler = NULL; | |
95 | |
96 if (verbose) | |
2059 | 97 printf("alsa-init: compiled for ALSA-%s\n", SND_LIB_VERSION_STR); |
1050 | 98 |
99 if ((err = snd_card_next(&cards)) < 0 || cards < 0) | |
100 { | |
101 printf("alsa-init: no soundcards found: %s\n", snd_strerror(err)); | |
102 return(0); | |
103 } | |
104 | |
2059 | 105 ao_samplerate = rate_hz; /*war rate_hz */ |
1128 | 106 ao_bps = channels; /* really this is bytes per frame so bad varname */ |
2059 | 107 /* ao_bps = channels */ |
1050 | 108 ao_format = format; |
1128 | 109 ao_channels = channels; |
1050 | 110 ao_outburst = OUTBURST; |
111 ao_buffersize = 16384; | |
112 | |
113 switch (format) | |
114 { | |
115 case AFMT_S8: | |
116 alsa_format = SND_PCM_FORMAT_S8; | |
117 break; | |
118 case AFMT_U8: | |
119 alsa_format = SND_PCM_FORMAT_U8; | |
120 break; | |
121 case AFMT_U16_LE: | |
122 alsa_format = SND_PCM_FORMAT_U16_LE; | |
123 break; | |
124 case AFMT_U16_BE: | |
125 alsa_format = SND_PCM_FORMAT_U16_BE; | |
126 break; | |
127 case AFMT_S16_LE: | |
128 alsa_format = SND_PCM_FORMAT_S16_LE; | |
129 break; | |
130 case AFMT_S16_BE: | |
131 alsa_format = SND_PCM_FORMAT_S16_BE; | |
132 break; | |
133 default: | |
134 alsa_format = SND_PCM_FORMAT_MPEG; | |
135 break; | |
136 } | |
137 | |
138 switch(alsa_format) | |
139 { | |
140 case SND_PCM_FORMAT_S16_LE: | |
141 case SND_PCM_FORMAT_U16_LE: | |
142 ao_bps *= 2; | |
143 break; | |
144 case -1: | |
145 printf("alsa-init: invalid format (%s) requested - output disabled\n", | |
146 audio_out_format_name(format)); | |
147 return(0); | |
1115
a16b569f2702
-Wall style cleanups, TEST IT, it can be working by others
al3x
parents:
1058
diff
changeset
|
148 default: |
a16b569f2702
-Wall style cleanups, TEST IT, it can be working by others
al3x
parents:
1058
diff
changeset
|
149 break; |
1050 | 150 } |
1128 | 151 |
1050 | 152 if ((err = snd_pcm_info_malloc(&alsa_info)) < 0) |
153 { | |
154 printf("alsa-init: memory allocation error: %s\n", snd_strerror(err)); | |
155 return(0); | |
156 } | |
157 | |
1207 | 158 if (ao_subdevice != NULL) |
159 alsa_device = ao_subdevice; | |
160 | |
1146
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
161 if (alsa_device == NULL) |
1050 | 162 { |
1146
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
163 if ((alsa_device = malloc(ALSA_DEVICE_SIZE)) == NULL) |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
164 { |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
165 printf("alsa-init: memory allocation error: %s\n", strerror(errno)); |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
166 return(0); |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
167 } |
1050 | 168 |
1146
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
169 snprintf(alsa_device, ALSA_DEVICE_SIZE, "hw:%d,%d", |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
170 snd_pcm_info_get_device(alsa_info), |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
171 snd_pcm_info_get_subdevice(alsa_info)); |
1050 | 172 |
1146
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
173 snd_pcm_info_free(alsa_info); |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
174 } |
1050 | 175 |
176 printf("alsa-init: %d soundcard%s found, using: %s\n", cards+1, | |
177 (cards >= 0) ? "" : "s", alsa_device); | |
178 | |
179 if ((err = snd_pcm_open(&alsa_handler, alsa_device, SND_PCM_STREAM_PLAYBACK, | |
180 0)) < 0) | |
181 { | |
182 printf("alsa-init: playback open error: %s\n", snd_strerror(err)); | |
183 return(0); | |
184 } | |
185 | |
186 snd_pcm_hw_params_malloc(&alsa_hwparams); | |
187 snd_pcm_sw_params_malloc(&alsa_swparams); | |
188 | |
189 if ((err = snd_pcm_hw_params_any(alsa_handler, alsa_hwparams)) < 0) | |
190 { | |
191 printf("alsa-init: unable to get initial parameters: %s\n", | |
192 snd_strerror(err)); | |
193 return(0); | |
194 } | |
195 | |
196 if ((err = snd_pcm_hw_params_set_access(alsa_handler, alsa_hwparams, | |
197 SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) | |
198 { | |
199 printf("alsa-init: unable to set access type: %s\n", | |
200 snd_strerror(err)); | |
201 return(0); | |
202 } | |
203 | |
204 if ((err = snd_pcm_hw_params_set_format(alsa_handler, alsa_hwparams, | |
205 alsa_format)) < 0) | |
206 { | |
207 printf("alsa-init: unable to set format: %s\n", | |
208 snd_strerror(err)); | |
209 return(0); | |
210 } | |
211 | |
212 if ((err = snd_pcm_hw_params_set_channels(alsa_handler, alsa_hwparams, | |
213 ao_channels)) < 0) | |
214 { | |
215 printf("alsa-init: unable to set channels: %s\n", | |
216 snd_strerror(err)); | |
217 return(0); | |
218 } | |
219 | |
2059 | 220 if ((err = snd_pcm_hw_params_set_rate_near(alsa_handler, alsa_hwparams, ao_samplerate, 0)) < 0) |
221 /* war nur snd_pcm_hw_params_set_rate */ | |
222 { | |
223 printf("alsa-init: unable to set samplerate-2: %s\n", | |
224 snd_strerror(err)); | |
225 //snd_pcm_hw_params_dump(alsa_hwparams, errlog); | |
226 return(0); | |
227 } | |
1050 | 228 |
1128 | 229 #ifdef set_period |
1115
a16b569f2702
-Wall style cleanups, TEST IT, it can be working by others
al3x
parents:
1058
diff
changeset
|
230 { |
1128 | 231 if ((err = snd_pcm_hw_params_set_period_size(alsa_handler, alsa_hwparams, alsa_fragsize / 4, 0)) < 0) |
232 { | |
233 printf("alsa-init: unable to set periodsize: %s\n", | |
234 snd_strerror(err)); | |
235 return(0); | |
236 } | |
237 if ((err = snd_pcm_hw_params_set_periods(alsa_handler, alsa_hwparams, alsa_fragcount, 0)) < 0) | |
238 { | |
239 printf("alsa-init: unable to set periods: %s\n", | |
240 snd_strerror(err)); | |
241 return(0); | |
242 } | |
1115
a16b569f2702
-Wall style cleanups, TEST IT, it can be working by others
al3x
parents:
1058
diff
changeset
|
243 } |
1128 | 244 #endif |
1050 | 245 #ifdef buffersize |
246 if ((err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams)) < 0) | |
247 { | |
248 printf("alsa-init: unable to get buffer size: %s\n", | |
249 snd_strerror(err)); | |
250 return(0); | |
251 } else | |
1128 | 252 { |
1050 | 253 ao_buffersize = err; |
1146
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
254 if (verbose) |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
255 printf("alsa-init: got buffersize %i\n", ao_buffersize); |
1128 | 256 } |
1050 | 257 #endif |
258 | |
259 #ifdef buffertime | |
260 { | |
2059 | 261 int alsa_buffer_time = 60; /* war 60 */ |
1050 | 262 |
2059 | 263 if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa_handler, alsa_hwparams, alsa_buffer_time, 0)) < 0) |
1050 | 264 { |
265 printf("alsa-init: unable to set buffer time near: %s\n", | |
266 snd_strerror(err)); | |
267 return(0); | |
268 } else | |
269 alsa_buffer_time = err; | |
270 | |
2059 | 271 if ((err = snd_pcm_hw_params_set_period_time_near(alsa_handler, alsa_hwparams, alsa_buffer_time/ao_bps, 0)) < 0) |
272 /* war alsa_buffer_time/ao_bps */ | |
1050 | 273 { |
274 printf("alsa-init: unable to set period time: %s\n", | |
275 snd_strerror(err)); | |
276 return(0); | |
277 } | |
1128 | 278 printf("alsa-init: buffer_time: %d, period_time :%d\n", |
279 alsa_buffer_time, err); | |
1050 | 280 } |
281 #endif | |
282 | |
283 if ((err = snd_pcm_hw_params(alsa_handler, alsa_hwparams)) < 0) | |
284 { | |
285 printf("alsa-init: unable to set parameters: %s\n", | |
286 snd_strerror(err)); | |
287 return(0); | |
288 } | |
1128 | 289 |
290 #ifdef sw_params | |
1050 | 291 if ((err = snd_pcm_sw_params_current(alsa_handler, alsa_swparams)) < 0) |
292 { | |
293 printf("alsa-init: unable to get parameters: %s\n", | |
294 snd_strerror(err)); | |
295 return(0); | |
296 } | |
297 | |
1128 | 298 #ifdef set_start_mode |
1050 | 299 if ((err = snd_pcm_sw_params_set_start_mode(alsa_handler, alsa_swparams, |
300 SND_PCM_START_DATA)) < 0) | |
301 { | |
302 printf("alsa-init: unable to set start mode: %s\n", | |
303 snd_strerror(err)); | |
304 return(0); | |
305 } | |
1128 | 306 #endif |
1050 | 307 |
308 if ((err = snd_pcm_sw_params(alsa_handler, alsa_swparams)) < 0) | |
309 { | |
310 printf("alsa-init: unable to set parameters: %s\n", | |
311 snd_strerror(err)); | |
312 return(0); | |
313 } | |
314 | |
1128 | 315 // snd_pcm_sw_params_default(alsa_handler, alsa_swparams); |
316 #endif | |
1050 | 317 if ((err = snd_pcm_prepare(alsa_handler)) < 0) |
318 { | |
319 printf("alsa-init: pcm prepare error: %s\n", snd_strerror(err)); | |
320 return(0); | |
321 } | |
322 | |
1115
a16b569f2702
-Wall style cleanups, TEST IT, it can be working by others
al3x
parents:
1058
diff
changeset
|
323 #ifdef start |
1050 | 324 if ((err = snd_pcm_start(alsa_handler)) < 0) |
325 { | |
326 printf("alsa-init: pcm start error: %s\n", snd_strerror(err)); | |
327 if (err != -EPIPE) | |
328 return(0); | |
329 if ((err = snd_pcm_start(alsa_handler)) < 0) | |
330 { | |
331 printf("alsa-init: pcm start error: %s\n", snd_strerror(err)); | |
332 return(0); | |
333 } | |
334 } | |
1115
a16b569f2702
-Wall style cleanups, TEST IT, it can be working by others
al3x
parents:
1058
diff
changeset
|
335 #endif |
1128 | 336 printf("AUDIO: %d Hz/%d channels/%d bpf/%d bytes buffer/%s\n", |
337 ao_samplerate, ao_channels, ao_bps, ao_buffersize, | |
1050 | 338 snd_pcm_format_description(alsa_format)); |
339 return(1); | |
340 } | |
341 | |
342 /* close audio device */ | |
343 static void uninit() | |
344 { | |
345 int err; | |
346 | |
347 if (alsa_device != NULL) | |
348 free(alsa_device); | |
349 | |
350 snd_pcm_hw_params_free(alsa_hwparams); | |
351 snd_pcm_sw_params_free(alsa_swparams); | |
352 | |
353 if ((err = snd_pcm_drain(alsa_handler)) < 0) | |
354 { | |
355 printf("alsa-uninit: pcm drain error: %s\n", snd_strerror(err)); | |
356 return; | |
357 } | |
358 | |
1129 | 359 #ifdef start |
1050 | 360 if ((err = snd_pcm_reset(alsa_handler)) < 0) |
361 { | |
362 printf("alsa-uninit: pcm reset error: %s\n", snd_strerror(err)); | |
363 return; | |
364 } | |
1129 | 365 #endif |
1050 | 366 |
367 if ((err = snd_pcm_close(alsa_handler)) < 0) | |
368 { | |
369 printf("alsa-uninit: pcm close error: %s\n", snd_strerror(err)); | |
370 return; | |
371 } | |
372 } | |
373 | |
374 static void audio_pause() | |
375 { | |
376 int err; | |
377 | |
378 if ((err = snd_pcm_drain(alsa_handler)) < 0) | |
379 { | |
380 printf("alsa-pause: pcm drain error: %s\n", snd_strerror(err)); | |
381 return; | |
382 } | |
383 | |
1129 | 384 #ifdef reset |
1050 | 385 if ((err = snd_pcm_reset(alsa_handler)) < 0) |
386 { | |
387 printf("alsa-pause: pcm reset error: %s\n", snd_strerror(err)); | |
388 return; | |
389 } | |
1129 | 390 #endif |
1050 | 391 } |
392 | |
393 static void audio_resume() | |
394 { | |
395 int err; | |
396 | |
397 if ((err = snd_pcm_prepare(alsa_handler)) < 0) | |
398 { | |
399 printf("alsa-resume: pcm prepare error: %s\n", snd_strerror(err)); | |
400 return; | |
401 } | |
402 | |
1129 | 403 #ifdef start |
1050 | 404 if ((err = snd_pcm_start(alsa_handler)) < 0) |
405 { | |
406 printf("alsa-resume: pcm start error: %s\n", snd_strerror(err)); | |
407 return; | |
408 } | |
1129 | 409 #endif |
1050 | 410 } |
411 | |
412 /* stop playing and empty buffers (for seeking/pause) */ | |
413 static void reset() | |
414 { | |
415 int err; | |
416 | |
417 if ((err = snd_pcm_drain(alsa_handler)) < 0) | |
418 { | |
419 printf("alsa-reset: pcm drain error: %s\n", snd_strerror(err)); | |
420 return; | |
421 } | |
422 | |
1129 | 423 #ifdef start |
1050 | 424 if ((err = snd_pcm_reset(alsa_handler)) < 0) |
425 { | |
426 printf("alsa-reset: pcm reset error: %s\n", snd_strerror(err)); | |
427 return; | |
428 } | |
1129 | 429 #endif |
1050 | 430 |
431 if ((err = snd_pcm_prepare(alsa_handler)) < 0) | |
432 { | |
433 printf("alsa-reset: pcm prepare error: %s\n", snd_strerror(err)); | |
434 return; | |
435 } | |
436 | |
1129 | 437 #ifdef start |
1050 | 438 if ((err = snd_pcm_start(alsa_handler)) < 0) |
439 { | |
440 printf("alsa-reset: pcm start error: %s\n", snd_strerror(err)); | |
441 return; | |
442 } | |
1129 | 443 #endif |
1050 | 444 } |
445 | |
446 /* | |
447 plays 'len' bytes of 'data' | |
448 returns: number of bytes played | |
449 */ | |
450 static int play(void* data, int len, int flags) | |
451 { | |
1115
a16b569f2702
-Wall style cleanups, TEST IT, it can be working by others
al3x
parents:
1058
diff
changeset
|
452 int got_len; |
a16b569f2702
-Wall style cleanups, TEST IT, it can be working by others
al3x
parents:
1058
diff
changeset
|
453 |
2059 | 454 got_len = snd_pcm_writei(alsa_handler, data, len / 4); |
455 | |
456 // war: if ((got_len = snd_pcm_writei(alsa_handler, data, (len/ao_bps))) != (len/ao_bps)) { | |
457 | |
1115
a16b569f2702
-Wall style cleanups, TEST IT, it can be working by others
al3x
parents:
1058
diff
changeset
|
458 if (got_len == -EPIPE) /* underrun? */ |
1050 | 459 { |
460 printf("alsa-play: alsa underrun, resetting stream\n"); | |
1128 | 461 if ((got_len = snd_pcm_prepare(alsa_handler)) < 0) |
1050 | 462 { |
1128 | 463 printf("alsa-play: playback prepare error: %s\n", snd_strerror(got_len)); |
1050 | 464 return(0); |
465 } | |
1128 | 466 if ((got_len = snd_pcm_writei(alsa_handler, data, (len/ao_bps))) != (len/ao_bps)) |
1050 | 467 { |
468 printf("alsa-play: write error after reset: %s - giving up\n", | |
1128 | 469 snd_strerror(got_len)); |
1050 | 470 return(0); |
471 } | |
472 return(len); /* 2nd write was ok */ | |
473 } | |
474 return(len); | |
475 } | |
476 | |
477 /* how many byes are free in the buffer */ | |
478 static int get_space() | |
479 { | |
480 snd_pcm_status_t *status; | |
481 int ret; | |
482 | |
483 if ((ret = snd_pcm_status_malloc(&status)) < 0) | |
484 { | |
485 printf("alsa-space: memory allocation error: %s\n", snd_strerror(ret)); | |
486 return(0); | |
487 } | |
488 | |
489 if ((ret = snd_pcm_status(alsa_handler, status)) < 0) | |
490 { | |
491 printf("alsa-space: cannot get pcm status: %s\n", snd_strerror(ret)); | |
492 return(0); | |
493 } | |
494 | |
495 switch(snd_pcm_status_get_state(status)) | |
496 { | |
497 case SND_PCM_STATE_OPEN: | |
498 case SND_PCM_STATE_PREPARED: | |
499 case SND_PCM_STATE_RUNNING: | |
500 ret = snd_pcm_status_get_avail(status) * ao_bps; | |
501 break; | |
502 default: | |
503 ret = 0; | |
504 } | |
505 | |
506 snd_pcm_status_free(status); | |
1129 | 507 |
508 if (ret < 0) | |
509 ret = 0; | |
1050 | 510 return(ret); |
511 } | |
512 | |
513 /* how many unplayed bytes are in the buffer */ | |
514 static int get_delay() | |
515 { | |
516 snd_pcm_status_t *status; | |
517 int ret; | |
518 | |
519 if ((ret = snd_pcm_status_malloc(&status)) < 0) | |
520 { | |
521 printf("alsa-delay: memory allocation error: %s\n", snd_strerror(ret)); | |
522 return(0); | |
523 } | |
524 | |
525 if ((ret = snd_pcm_status(alsa_handler, status)) < 0) | |
526 { | |
527 printf("alsa-delay: cannot get pcm status: %s\n", snd_strerror(ret)); | |
528 return(0); | |
529 } | |
530 | |
531 switch(snd_pcm_status_get_state(status)) | |
532 { | |
533 case SND_PCM_STATE_OPEN: | |
534 case SND_PCM_STATE_PREPARED: | |
535 case SND_PCM_STATE_RUNNING: | |
536 ret = snd_pcm_status_get_delay(status) * ao_bps; | |
537 break; | |
538 default: | |
539 ret = 0; | |
540 } | |
541 | |
542 snd_pcm_status_free(status); | |
1129 | 543 |
544 if (ret < 0) | |
545 ret = 0; | |
1050 | 546 return(ret); |
547 } |