Mercurial > mplayer.hg
comparison libao2/ao_sun.c @ 3095:981a9e5118ce
interface to libao2 changed ao_plugin added
author | anders |
---|---|
date | Sat, 24 Nov 2001 05:21:22 +0000 |
parents | 6da3b9428ff0 |
children | b9ee2d8d7279 |
comparison
equal
deleted
inserted
replaced
3094:4150aff2ac17 | 3095:981a9e5118ce |
---|---|
40 #define AUDIO_CHANNELS_MONO 1 | 40 #define AUDIO_CHANNELS_MONO 1 |
41 #define AUDIO_CHANNELS_STEREO 2 | 41 #define AUDIO_CHANNELS_STEREO 2 |
42 #endif | 42 #endif |
43 | 43 |
44 | 44 |
45 // there are some globals: | |
46 // ao_samplerate | |
47 // ao_channels | |
48 // ao_format | |
49 // ao_bps | |
50 // ao_outburst | |
51 // ao_buffersize | |
52 | |
53 static char *audio_dev = "/dev/audio"; | 45 static char *audio_dev = "/dev/audio"; |
54 static int queued_bursts = 0; | 46 static int queued_bursts = 0; |
55 static int queued_samples = 0; | 47 static int queued_samples = 0; |
56 static int bytes_per_sample = 0; | 48 static int bytes_per_sample = 0; |
49 static int byte_per_sec = 0; | |
57 static int convert_u8_s8; | 50 static int convert_u8_s8; |
58 static int audio_fd = -1; | 51 static int audio_fd = -1; |
59 static enum { | 52 static enum { |
60 RTSC_UNKNOWN = 0, | 53 RTSC_UNKNOWN = 0, |
61 RTSC_ENABLED, | 54 RTSC_ENABLED, |
228 // open & setup audio device | 221 // open & setup audio device |
229 // return: 1=success 0=fail | 222 // return: 1=success 0=fail |
230 static int init(int rate,int channels,int format,int flags){ | 223 static int init(int rate,int channels,int format,int flags){ |
231 | 224 |
232 audio_info_t info; | 225 audio_info_t info; |
233 int byte_per_sec; | |
234 int ok; | 226 int ok; |
235 | 227 |
236 if (ao_subdevice) audio_dev = ao_subdevice; | 228 if (ao_subdevice) audio_dev = ao_subdevice; |
237 | 229 |
238 if (enable_sample_timing == RTSC_UNKNOWN | 230 if (enable_sample_timing == RTSC_UNKNOWN |
250 } | 242 } |
251 | 243 |
252 ioctl(audio_fd, AUDIO_DRAIN, 0); | 244 ioctl(audio_fd, AUDIO_DRAIN, 0); |
253 | 245 |
254 AUDIO_INITINFO(&info); | 246 AUDIO_INITINFO(&info); |
255 info.play.encoding = oss2sunfmt(ao_format = format); | 247 info.play.encoding = oss2sunfmt(ao_data.format = format); |
256 info.play.precision = | 248 info.play.precision = |
257 (format==AFMT_S16_LE || format==AFMT_S16_BE | 249 (format==AFMT_S16_LE || format==AFMT_S16_BE |
258 ? AUDIO_PRECISION_16 | 250 ? AUDIO_PRECISION_16 |
259 : AUDIO_PRECISION_8); | 251 : AUDIO_PRECISION_8); |
260 info.play.channels = ao_channels = channels; | 252 info.play.channels = ao_data.channels = channels; |
261 info.play.sample_rate = ao_samplerate = rate; | 253 info.play.sample_rate = ao_data.samplerate = rate; |
262 convert_u8_s8 = 0; | 254 convert_u8_s8 = 0; |
263 ok = ioctl(audio_fd, AUDIO_SETINFO, &info) >= 0; | 255 ok = ioctl(audio_fd, AUDIO_SETINFO, &info) >= 0; |
264 if (!ok && info.play.encoding == AUDIO_ENCODING_LINEAR8) { | 256 if (!ok && info.play.encoding == AUDIO_ENCODING_LINEAR8) { |
265 /* sun audiocs hardware does not support U8 format, try S8... */ | 257 /* sun audiocs hardware does not support U8 format, try S8... */ |
266 info.play.encoding = AUDIO_ENCODING_LINEAR; | 258 info.play.encoding = AUDIO_ENCODING_LINEAR; |
276 return 0; | 268 return 0; |
277 } | 269 } |
278 | 270 |
279 bytes_per_sample = channels * info.play.precision / 8; | 271 bytes_per_sample = channels * info.play.precision / 8; |
280 byte_per_sec = bytes_per_sample * rate; | 272 byte_per_sec = bytes_per_sample * rate; |
281 ao_outburst = byte_per_sec > 100000 ? 16384 : 8192; | 273 ao_data.outburst = byte_per_sec > 100000 ? 16384 : 8192; |
282 | 274 |
283 #ifdef __not_used__ | 275 #ifdef __not_used__ |
284 /* | 276 /* |
285 * hmm, ao_buffersize is currently not used in this driver, do there's | 277 * hmm, ao_data.buffersize is currently not used in this driver, do there's |
286 * no need to measure it | 278 * no need to measure it |
287 */ | 279 */ |
288 if(ao_buffersize==-1){ | 280 if(ao_data.buffersize==-1){ |
289 // Measuring buffer size: | 281 // Measuring buffer size: |
290 void* data; | 282 void* data; |
291 ao_buffersize=0; | 283 ao_data.buffersize=0; |
292 #ifdef HAVE_AUDIO_SELECT | 284 #ifdef HAVE_AUDIO_SELECT |
293 data = malloc(ao_outburst); | 285 data = malloc(ao_data.outburst); |
294 memset(data, format==AFMT_U8 ? 0x80 : 0, ao_outburst); | 286 memset(data, format==AFMT_U8 ? 0x80 : 0, ao_data.outburst); |
295 while(ao_buffersize<0x40000){ | 287 while(ao_data.buffersize<0x40000){ |
296 fd_set rfds; | 288 fd_set rfds; |
297 struct timeval tv; | 289 struct timeval tv; |
298 FD_ZERO(&rfds); FD_SET(audio_fd,&rfds); | 290 FD_ZERO(&rfds); FD_SET(audio_fd,&rfds); |
299 tv.tv_sec=0; tv.tv_usec = 0; | 291 tv.tv_sec=0; tv.tv_usec = 0; |
300 if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) break; | 292 if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) break; |
301 write(audio_fd,data,ao_outburst); | 293 write(audio_fd,data,ao_data.outburst); |
302 ao_buffersize+=ao_outburst; | 294 ao_data.buffersize+=ao_data.outburst; |
303 } | 295 } |
304 free(data); | 296 free(data); |
305 if(ao_buffersize==0){ | 297 if(ao_data.buffersize==0){ |
306 printf("\n *** Your audio driver DOES NOT support select() ***\n"); | 298 printf("\n *** Your audio driver DOES NOT support select() ***\n"); |
307 printf("Recompile mplayer with #undef HAVE_AUDIO_SELECT in config.h !\n\n"); | 299 printf("Recompile mplayer with #undef HAVE_AUDIO_SELECT in config.h !\n\n"); |
308 return 0; | 300 return 0; |
309 } | 301 } |
310 #ifdef __svr4__ | 302 #ifdef __svr4__ |
311 // remove the 0 bytes from the above ao_buffersize measurement from the | 303 // remove the 0 bytes from the above ao_data.buffersize measurement from the |
312 // audio driver's STREAMS queue | 304 // audio driver's STREAMS queue |
313 ioctl(audio_fd, I_FLUSH, FLUSHW); | 305 ioctl(audio_fd, I_FLUSH, FLUSHW); |
314 #endif | 306 #endif |
315 ioctl(audio_fd, AUDIO_DRAIN, 0); | 307 ioctl(audio_fd, AUDIO_DRAIN, 0); |
316 #endif | 308 #endif |
350 } | 342 } |
351 | 343 |
352 ioctl(audio_fd, AUDIO_DRAIN, 0); | 344 ioctl(audio_fd, AUDIO_DRAIN, 0); |
353 | 345 |
354 AUDIO_INITINFO(&info); | 346 AUDIO_INITINFO(&info); |
355 info.play.encoding = oss2sunfmt(ao_format); | 347 info.play.encoding = oss2sunfmt(ao_data.format); |
356 info.play.precision = | 348 info.play.precision = |
357 (ao_format==AFMT_S16_LE || ao_format==AFMT_S16_BE | 349 (ao_data.format==AFMT_S16_LE || ao_data.format==AFMT_S16_BE |
358 ? AUDIO_PRECISION_16 | 350 ? AUDIO_PRECISION_16 |
359 : AUDIO_PRECISION_8); | 351 : AUDIO_PRECISION_8); |
360 info.play.channels = ao_channels; | 352 info.play.channels = ao_data.channels; |
361 info.play.sample_rate = ao_samplerate; | 353 info.play.sample_rate = ao_data.samplerate; |
362 info.play.samples = 0; | 354 info.play.samples = 0; |
363 info.play.eof = 0; | 355 info.play.eof = 0; |
364 info.play.error = 0; | 356 info.play.error = 0; |
365 ioctl (audio_fd, AUDIO_SETINFO, &info); | 357 ioctl (audio_fd, AUDIO_SETINFO, &info); |
366 queued_bursts = 0; | 358 queued_bursts = 0; |
386 } | 378 } |
387 | 379 |
388 | 380 |
389 // return: how many bytes can be played without blocking | 381 // return: how many bytes can be played without blocking |
390 static int get_space(){ | 382 static int get_space(){ |
391 int playsize = ao_outburst; | 383 int playsize = ao_data.outburst; |
392 audio_info_t info; | 384 audio_info_t info; |
393 | 385 |
394 // check buffer | 386 // check buffer |
395 #ifdef HAVE_AUDIO_SELECT | 387 #ifdef HAVE_AUDIO_SELECT |
396 { | 388 { |
406 | 398 |
407 ioctl(audio_fd, AUDIO_GETINFO, &info); | 399 ioctl(audio_fd, AUDIO_GETINFO, &info); |
408 if (queued_bursts - info.play.eof > 2) | 400 if (queued_bursts - info.play.eof > 2) |
409 return 0; | 401 return 0; |
410 | 402 |
411 return ao_outburst; | 403 return ao_data.outburst; |
412 } | 404 } |
413 | 405 |
414 // plays 'len' bytes of 'data' | 406 // plays 'len' bytes of 'data' |
415 // it should round it down to outburst*n | 407 // it should round it down to outburst*n |
416 // return: number of bytes played | 408 // return: number of bytes played |
419 int native_endian = AFMT_S16_BE; | 411 int native_endian = AFMT_S16_BE; |
420 #else | 412 #else |
421 int native_endian = AFMT_S16_LE; | 413 int native_endian = AFMT_S16_LE; |
422 #endif | 414 #endif |
423 | 415 |
424 if (len < ao_outburst) return 0; | 416 if (len < ao_data.outburst) return 0; |
425 len /= ao_outburst; | 417 len /= ao_data.outburst; |
426 len *= ao_outburst; | 418 len *= ao_data.outburst; |
427 | 419 |
428 /* 16-bit format using the 'wrong' byteorder? swap words */ | 420 /* 16-bit format using the 'wrong' byteorder? swap words */ |
429 if ((ao_format == AFMT_S16_LE || ao_format == AFMT_S16_BE) | 421 if ((ao_data.format == AFMT_S16_LE || ao_data.format == AFMT_S16_BE) |
430 && ao_format != native_endian) { | 422 && ao_data.format != native_endian) { |
431 static void *swab_buf; | 423 static void *swab_buf; |
432 static int swab_len; | 424 static int swab_len; |
433 if (len > swab_len) { | 425 if (len > swab_len) { |
434 if (swab_buf) | 426 if (swab_buf) |
435 swab_buf = realloc(swab_buf, len); | 427 swab_buf = realloc(swab_buf, len); |
438 swab_len = len; | 430 swab_len = len; |
439 if (swab_buf == NULL) return 0; | 431 if (swab_buf == NULL) return 0; |
440 } | 432 } |
441 swab(data, swab_buf, len); | 433 swab(data, swab_buf, len); |
442 data = swab_buf; | 434 data = swab_buf; |
443 } else if (ao_format == AFMT_U8 && convert_u8_s8) { | 435 } else if (ao_data.format == AFMT_U8 && convert_u8_s8) { |
444 int i; | 436 int i; |
445 unsigned char *p = data; | 437 unsigned char *p = data; |
446 | 438 |
447 for (i = 0, p = data; i < len; i++, p++) | 439 for (i = 0, p = data; i < len; i++, p++) |
448 *p ^= 0x80; | 440 *p ^= 0x80; |
458 } | 450 } |
459 return len; | 451 return len; |
460 } | 452 } |
461 | 453 |
462 | 454 |
463 // return: how many unplayed bytes are in the buffer | 455 // return: delay in seconds between first and last sample in buffer |
464 static int get_delay(){ | 456 static float get_delay(){ |
465 audio_info_t info; | 457 audio_info_t info; |
466 ioctl(audio_fd, AUDIO_GETINFO, &info); | 458 ioctl(audio_fd, AUDIO_GETINFO, &info); |
467 if (info.play.samples && enable_sample_timing == RTSC_ENABLED) | 459 if (info.play.samples && enable_sample_timing == RTSC_ENABLED) |
468 return (queued_samples - info.play.samples) * bytes_per_sample; | 460 return (float)(queued_samples - info.play.samples) / (float)byte_per_sec; |
469 else | 461 else |
470 return (queued_bursts - info.play.eof) * ao_outburst; | 462 return (flaot)((queued_bursts - info.play.eof) * ao_data.outburst) / (float)byte_per_sec; |
471 } | 463 } |
472 | 464 |