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