Add Russian translation provided by Валерий Крувялис <valkru@mail.ru>
[xiph-mirror.git] / squishyball / audio.c
blob5e635ff5d7cd41e2e705f5bcb08d739e9d8e2ca8
1 /*
3 * squishyball
5 * Copyright (C) 2010-2013 Xiph.Org
7 * squishyball is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
12 * squishyball is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with rtrecord; see the file COPYING. If not, write to the
19 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 #define _GNU_SOURCE
25 #define _LARGEFILE_SOURCE
26 #define _LARGEFILE64_SOURCE
27 #define _FILE_OFFSET_BITS 64
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <math.h>
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <unistd.h>
35 #include <ao/ao.h>
36 #include "main.h"
38 /* sample formatting helpers ********************************************************/
40 static inline int host_is_big_endian() {
41 union {
42 int32_t pattern;
43 unsigned char bytewise[4];
44 } m;
45 m.pattern = 0xfeedface; /* deadbeef */
46 if (m.bytewise[0] == 0xfe) return 1;
47 return 0;
50 static float get_clamp(pcm_t *pcm){
51 if(pcm->nativebits>=0 && pcm->nativebits<24)
52 return 1.f - 1.f/(1<<(pcm->nativebits-1));
53 else
54 return 1.f - 1.f/2147483648.f;
57 float check_warn_clipping(pcm_t *pcm, int no_normalize){
58 int i,j;
59 int cpf = pcm->ch;
60 int s = pcm->size/sizeof(float);
61 float clamp;
62 float min,max;
63 int flag[cpf];
64 size_t count=0;
65 float *d = (float *)pcm->data;
67 memset(flag,0,sizeof(flag));
69 if(sb_verbose)
70 fprintf(stderr,"\rLoading %s: checking for clipping...",pcm->name);
72 clamp = max = get_clamp(pcm);
73 min=-1.f;
75 for(i=0;i<s;i+=pcm->ch)
76 for(j=0;j<pcm->ch;j++){
77 if(d[i+j]<-1.f){
78 if(d[i+j]<min)min=d[i+j];
79 flag[j]++;
80 }else if(d[i+j]>clamp){
81 if(d[i+j]>max)max=d[i+j];
82 flag[j]++;
83 }else{
84 if(flag[j]>1)count+=flag[j];
85 flag[j]=0;
88 for(j=0;j<cpf;j++)
89 if(flag[j]>1)count+=flag[j];
91 if(count){
92 if(sb_verbose)
93 fprintf(stderr,"\n");
94 if(pcm->nativebits>0){
95 fprintf(stderr,"CLIPPING WARNING: %ld probably clipped samples in %s;\n",(long)count,pcm->name);
96 fprintf(stderr," (can't be repaired with normalization)\n");
97 }else{
98 if(no_normalize){
99 fprintf(stderr,"CLIPPING WARNING: %ld clipped samples in %s;\n",(long)count,pcm->name);
100 fprintf(stderr," normalization disabled on command line.\n");
101 }else{
102 float att = -1./min;
103 if(clamp/max < att) att=clamp/max;
104 if(sb_verbose){
105 fprintf(stderr,"%ld overrange samples after decoding %s (peak %+0.1fdB)\n",(long)count,pcm->name,todB(1./att));
107 return att;
110 }else{
111 if(sb_verbose)
112 fprintf(stderr,"\rLoading %s: done. \n",pcm->name);
115 return 1.;
118 /* input must be float */
119 float convert_to_mono(pcm_t *pcm){
120 int i,j,k;
121 int cpf = pcm->ch;
122 int s = pcm->size/sizeof(float);
123 float *d = (float *)pcm->data;
124 float max=0;
125 float min=0;
126 float att=1.f;
127 float clamp = get_clamp(pcm);
129 if(pcm->currentbits!=-32){
130 fprintf(stderr,"Internal error; non-float PCM passed to convert_to_mono.\n");
131 exit(10);
134 if(sb_verbose)
135 fprintf(stderr,"Downmixing to mono... ");
137 k=0;
138 for(i=0;i<s;i+=cpf){
139 float acc=0.f;
140 for(j=0;j<cpf;j++)
141 acc+=d[i+j];
142 if(acc>max)max=acc;
143 if(acc<min)min=acc;
144 d[k++]=acc;
148 pcm->size/=cpf;
149 pcm->ch=1;
150 if(pcm->matrix)free(pcm->matrix);
151 pcm->matrix=strdup("M");
152 if(min<-1.f) att=-1./min;
153 if(clamp/max < att) att=clamp/max;
155 if(sb_verbose){
156 if(att<1.){
157 fprintf(stderr,"done. peak: %+0.1fdB\n",todB(1./att));
158 }else{
159 fprintf(stderr,"done.\n");
162 return att;
165 /* non-normalized */
166 static const float left_mix[33]={
167 1., /* A: M */
168 1., /* B: L */
169 0., /* C: R */
170 0.707, /* D: C */
171 0.707, /* E: LFE */
172 0.866, /* F: BL */
173 0.5, /* G: BR */
174 0.791, /* H: CL */
175 0.612, /* I: CR */
176 0.612, /* J: BC */
177 0.866, /* K: SL */
178 0.5, /* L: SR */
182 static const float right_mix[33]={
183 1., /* A: M */
184 0., /* B: L */
185 1., /* C: R */
186 0.707, /* D: C */
187 0.707, /* E: LFE */
188 0.5, /* F: BL */
189 0.866, /* G: BR */
190 0.612, /* H: CL */
191 0.791, /* I: CR */
192 0.612, /* J: BC */
193 0.5, /* K: SL */
194 0.866, /* L: SR */
198 /* input must be float */
199 float convert_to_stereo(pcm_t *pcm){
200 int i,j,k;
201 int cpf = pcm->ch;
202 int s = pcm->size/sizeof(float);
203 float *d = (float *)pcm->data;
204 float max=0;
205 float min=0;
206 float att=1.f;
207 float clamp = get_clamp(pcm);
209 float *lmix,*rmix;
211 if(pcm->currentbits!=-32){
212 fprintf(stderr,"Internal error; non-float PCM passed to convert_to_mono.\n");
213 exit(10);
215 if(pcm->ch<2){
216 fprintf(stderr,"Internal error; can't downmix mono to stereo.\n");
217 exit(10);
220 if(sb_verbose)
221 fprintf(stderr,"Downmixing to stereo... ");
223 lmix=calloc(cpf,sizeof(*lmix));
224 rmix=calloc(cpf,sizeof(*rmix));
225 for(j=0;j<cpf;j++){
226 lmix[j] = left_mix[pcm->mix[j]-'A'];
227 rmix[j] = right_mix[pcm->mix[j]-'A'];
230 k=0;
231 for(i=0;i<s;i+=cpf){
232 float L=0.f,R=0.f;
234 for(j=0;j<cpf;j++){
235 L+=d[i+j]*lmix[j];
236 R+=d[i+j]*rmix[j];
239 if(L>max)max=L;
240 if(L<min)min=L;
241 if(R>max)max=R;
242 if(R<min)min=R;
243 d[k++]=L;
244 d[k++]=R;
247 pcm->size=pcm->size/cpf*2;
248 pcm->ch=2;
249 if(pcm->matrix)free(pcm->matrix);
250 pcm->matrix=strdup("L,R");
252 if(min<-1.f) att=-1./min;
253 if(clamp/max < att) att=clamp/max;
255 if(sb_verbose){
256 if(att<1.f){
257 fprintf(stderr,"done. peak: %+0.1fdB\n",todB(1./att));
258 }else{
259 fprintf(stderr,"done.\n");
262 return att;
265 static inline float triangle_ditherval(float *save){
266 float r = rand()/(float)RAND_MAX-.5f;
267 float ret = *save-r;
268 *save = r;
269 return ret;
272 void convert_to_32(pcm_t *pcm){
273 unsigned char *d = pcm->data;
274 float *f = (float *)pcm->data;
275 off_t j;
276 if(sb_verbose)
277 fprintf(stderr,"\rConverting %s to 32 bit... ",pcm->name);
278 for(j=0;j<pcm->size/sizeof(float);j++){
279 float val = rint(f[j]*2147483648.f);
280 int iv;
281 if(val<-2147483648.f) val = -2147483648.f;
282 if(val> 2147483647.f) val = 2147483647.f;
283 iv=(int)val;
284 d[j*4]=iv&0xff;
285 d[j*4+1]=(iv>>8)&0xff;
286 d[j*4+2]=(iv>>16)&0xff;
287 d[j*4+3]=(iv>>24)&0xff;
289 if(sb_verbose)
290 fprintf(stderr,"done.\n");
291 pcm->currentbits=32;
292 pcm->size/=sizeof(float);
293 pcm->size*=4;
296 void convert_to_24(pcm_t *pcm){
297 unsigned char *d = pcm->data;
298 float *f = (float *)pcm->data;
299 off_t j;
300 if(sb_verbose)
301 fprintf(stderr,"\rConverting %s to 24 bit... ",pcm->name);
302 for(j=0;j<pcm->size/sizeof(float);j++){
303 float val = rint(f[j]*8388608.f);
304 int iv;
305 if(val<-8388608.f) val = -8388608.f;
306 if(val> 8388607.f) val = 8388607.f;
307 iv=(int)val;
308 d[j*3]=iv&0xff;
309 d[j*3+1]=(iv>>8)&0xff;
310 d[j*3+2]=(iv>>16)&0xff;
312 if(sb_verbose)
313 fprintf(stderr,"done.\n");
314 pcm->currentbits=24;
315 pcm->size/=sizeof(float);
316 pcm->size*=3;
319 void convert_to_16(pcm_t *pcm, int dither){
320 unsigned char *d = pcm->data;
321 float *f = (float *)pcm->data;
322 off_t j;
323 float t[pcm->ch];
324 int ch=0;
325 memset(t,0,sizeof(t));
327 if(sb_verbose)
328 fprintf(stderr,"\r%s %s to 16 bit... ",
329 dither?"Dithering":"Down-converting",pcm->name);
331 for(j=0;j<pcm->size/sizeof(float);j++){
332 float val;
333 if(dither){
334 val = rint(f[j]*32768.f + triangle_ditherval(t+ch));
335 ch++;
336 if(ch>pcm->ch)ch=0;
337 }else{
338 val = rint(f[j]*32768.f);
341 if(val>=32767.f){
342 d[j*2]=0xff;
343 d[j*2+1]=0x7f;
344 }else if(val<=-32768.f){
345 d[j*2]=0x00;
346 d[j*2+1]=0x80;
347 }else{
348 int iv = (int)val;
349 d[j*2]=iv&0xff;
350 d[j*2+1]=(iv>>8)&0xff;
354 if(sb_verbose)
355 fprintf(stderr,"done.\n");
357 pcm->currentbits=16;
358 pcm->size/=sizeof(float);
359 pcm->size*=2;
362 /* Channel map reconciliation helpers *********************************/
364 static const char *chlist[]={"X","M","L","R","C","LFE","SL","SR","BC","BL","BR","CL","CR",NULL};
366 static void tokenize_channels(char *matrix,int *out,int n){
367 int i=0;
368 char *copy = strdup(matrix);
369 char *t=strtok(copy,",");
370 memset(out,0,sizeof(*out)*n);
372 while(t){
373 int j=0;
374 while(chlist[j]){
375 if(!strcmp(chlist[j],t))break;
376 j++;
378 out[i]=j;
379 i++;
380 t=strtok(NULL,",");
382 free(copy);
385 /* pre-permute sample ordering so that playback incurs ~equal
386 CPU/memory/etc load during playback */
387 /* A and B must have machine sample formats */
388 void reconcile_channel_maps(pcm_t *A, pcm_t *B){
389 /* arbitrary; match B to A */
390 int ai[A->ch],bi[A->ch];
391 int i,j,k;
392 off_t o;
393 int bps = (B->currentbits+7)/8;
394 int bpf = B->ch*bps;
395 int p[bpf];
396 unsigned char temp[bpf];
397 unsigned char *d;
399 tokenize_channels(A->matrix,ai,A->ch);
400 tokenize_channels(B->matrix,bi,A->ch);
402 if(sb_verbose){
403 fprintf(stderr,"remapping channels in %s: ",B->name);
404 for(i=0;i<B->ch;i++)
405 fprintf(stderr,"%d%s",bi[i],i+1==B->ch?"":", ");
406 fprintf(stderr," -> ");
407 for(i=0;i<A->ch;i++)
408 fprintf(stderr,"%d%s",ai[i],i+1==A->ch?"":", ");
409 fprintf(stderr,"\n");
412 for(i=0;i<A->ch;i++){
413 for(k=0;k<bps;k++)
414 p[i*bps+k]=i*bps+k; /* failsafe */
415 for(j=0;j<A->ch;j++){
416 if(bi[i]==ai[j]){
417 for(k=0;k<bps;k++)
418 p[i*bps+k]=j*bps+k;
419 break;
424 d=B->data;
425 for(o=0;o<B->size;o+=bpf){
426 for(i=0;i<bpf;i++)
427 temp[p[i]]=d[i];
428 memcpy(d,temp,bpf);
429 d+=bpf;
432 free(B->matrix);
433 B->matrix = strdup(A->matrix);
436 /* fade and beep function generation **************************************/
438 void put_val(unsigned char *d,int bps,float v){
439 int i = rint(v);
440 d[0]=i&0xff;
441 d[1]=(i>>8)&0xff;
442 if(bps==3)
443 d[2]=(i>>16)&0xff;
446 float get_val(unsigned char *d, int bps){
447 if(bps==2){
448 short i = d[0] | (d[1]<<8);
449 return (float)i;
450 }else{
451 int32_t i = ((d[0]<<8) | (d[1]<<16) | (d[2]<<24))>>8;
452 return (float)i;
456 int setup_windows(pcm_t **pcm, int test_files,
457 float **fw1, float **fw2, float **fw3,
458 float **b1, float **b2){
459 int i;
460 int fragsamples = pcm[0]->rate/10; /* 100ms */
461 float mul = (pcm[0]->currentbits==24 ? 8388608.f : 32768.f) * .0625;
462 int bps=(pcm[0]->currentbits+7)/8;
463 int ch=pcm[0]->ch;
464 int bpf=ch*bps;
465 int maxsamples = pcm[0]->size / bpf;
466 if (fragsamples * 3 > maxsamples)
467 fragsamples = maxsamples / 3;
468 /* precompute the fades/beeps */
469 float *fadewindow1 = *fw1 = calloc(fragsamples,sizeof(*fadewindow1));
470 float *fadewindow2 = *fw2 = calloc(fragsamples,sizeof(*fadewindow2));
471 float *fadewindow3 = *fw3 = calloc(fragsamples,sizeof(*fadewindow3));
472 float *beep1 = *b1 = calloc(fragsamples,sizeof(*beep1));
473 float *beep2 = *b2 = calloc(fragsamples,sizeof(*beep2));
475 if(!fadewindow1 ||
476 !fadewindow2 ||
477 !fadewindow3 ||
478 !beep1 ||
479 !beep2)
480 exit(9);
482 /* fadewindow1 is a larger simple crossfade */
483 for(i=0;i<fragsamples;i++){
484 float val = cosf(M_PI*.5f*(i+.5f)/fragsamples);
485 fadewindow1[i] = val*val;
488 /* fadewindow2 goes to silence and back */
489 for(i=0;i<fragsamples/3;i++){
490 float val = cosf(M_PI*1.5f*(i+.5f)/fragsamples);
491 fadewindow2[i] = val*val;
493 for(;i<fragsamples;i++)
494 fadewindow2[i] = 0.f;
496 /* fadewindow3 is like fadewindow 2 but with briefer silence */
497 for(i=0;i<fragsamples/2;i++){
498 float val = cosf(M_PI*(i+.5f)/fragsamples);
499 fadewindow3[i] = val*val;
501 for(;i<fragsamples;i++)
502 fadewindow3[i] = 0.f;
504 /* Single beep for flipping */
505 for(i=0;i<fragsamples/4;i++){
506 beep1[i]=0.f;
507 beep1[fragsamples-i-1]=0.f;
509 float base = 3.14159f*2.f*1000./pcm[0]->rate;
510 for(;i<fragsamples*3/4;i++){
511 float f = i-fragsamples/4+.5f;
512 float w = cosf(3.14159f*f/fragsamples);
513 float b =
514 sinf(f*base)+
515 sinf(f*base*3)*.33f+
516 sinf(f*base*5)*.2f+
517 sinf(f*base*7)*.14f+
518 sinf(f*base*9)*.11f;
519 w*=w;
520 beep1[i] = w*b*mul;
523 /* Double beep for selection */
524 for(i=0;i<fragsamples/4;i++){
525 beep2[i]=0.f;
526 beep2[fragsamples-i-1]=0.f;
528 for(;i<fragsamples/2;i++){
529 float f = i-fragsamples/4+.5f;
530 float w = cosf(3.14159f*2.f*f/fragsamples);
531 float b =
532 sinf(f*base)+
533 sinf(f*base*3)*.33f+
534 sinf(f*base*5)*.2f+
535 sinf(f*base*7)*.14f+
536 sinf(f*base*9)*.11f;
537 w*=w;
538 beep2[i] = w*b*mul;
540 base = 3.14159f*2.f*1500./pcm[0]->rate;
541 for(;i<fragsamples*3/4;i++){
542 float f = i-fragsamples/2+.5f;
543 float w = cosf(3.14159f*2.f*f/fragsamples);
544 float b =
545 sinf(f*base)+
546 sinf(f*base*3)*.33f+
547 sinf(f*base*5)*.2f+
548 sinf(f*base*7)*.14f+
549 sinf(f*base*9)*.11f;
550 w*=w;
551 beep2[i] = w*b*mul*2;
554 return fragsamples;
557 /* fragment is filled such that a crossloop never begins after
558 pcm->size-fragsize, and it always begins from the start of the
559 window, even if that means starting a crossloop late because the
560 endpos moved. */
561 void fill_fragment1(unsigned char *out, pcm_t *pcm, off_t start, off_t *pos, off_t end, int *loop,
562 int fragsamples, float *fadewindow){
563 int bps = (pcm->currentbits+7)/8;
564 int cpf = pcm->ch;
565 int bpf = bps*cpf;
566 int fragsize = fragsamples*bpf;
568 /* guard limits here */
569 if(end<fragsize*3)end=fragsize*3;
570 if(end>pcm->size)end=pcm->size;
571 if(start<0)start=0;
572 if(start>pcm->size-fragsize*3)start=pcm->size-fragsize*3;
574 /* we fill a fragment from the data buffer of the passed in pcm_t.
575 It's possible we'll need to crossloop from the end of the sample,
576 and the start/end markers may have moved so that the cursor is
577 outside the strict sample bounds. */
579 /* if *loop>0, we're in the process of crosslapping at pos ><
580 start+(fragsize-*loop*bpf). Stay the course. */
581 if(*loop){
582 int lp = *loop;
583 int i,j;
584 unsigned char *A = pcm->data+*pos;
585 unsigned char *B = pcm->data+start+(fragsamples-lp)*bpf;
586 for(i=0;i<fragsamples;i++){
587 if(lp){
588 float w = fadewindow[--lp];
589 for(j=0;j<cpf;j++){
590 float val = get_val(A,bps)*(1.f-w) + get_val(B,bps)*w;
591 put_val(out,bps,val);
592 A+=bps;
593 B+=bps;
594 out+=bps;
596 }else{
597 /* crossloop finished, the rest is B */
598 memcpy(out,B,bpf);
599 B+=bpf;
600 out+=bpf;
603 *loop=0;
604 *pos=B-pcm->data;
605 }else{
606 /* no crossloop in progress... should one be? If the cursor is
607 before start, do nothing. If it's past end-fragsize, begin a
608 crossloop immediately. If the current fragment will extend
609 beyond end-fragsize, begin the crossloop at end-fragsize */
610 if(*pos>pcm->size-fragsize){
611 /* Error condition; should not be possible */
612 fprintf(stderr,"Internal error; %ld>%ld, Monty fucked up.\n",(long)*pos,(long)pcm->size-fragsize);
613 exit(100);
614 }else if(*pos+fragsize>end-fragsize){
615 int i,j;
616 unsigned char *A = pcm->data+*pos;
617 unsigned char *B = pcm->data+start;
618 int lp = (end-*pos)/bpf;
619 if(lp<fragsamples)lp=fragsamples; /* If we're late, start immediately, but use full window */
621 for(i=0;i<fragsamples;i++){
622 if(--lp>=fragsamples){
623 /* still before crossloop begins */
624 memcpy(out,A,bpf);
625 A+=bpf;
626 out+=bpf;
627 }else{
628 /* crosslooping */
629 float w = fadewindow[lp];
630 for(j=0;j<cpf;j++){
631 float val = get_val(A,bps)*(1.f-w) + get_val(B,bps)*w;
632 put_val(out,bps,val);
633 A+=bps;
634 B+=bps;
635 out+=bps;
639 *loop=(lp<0?0:lp);
640 *pos=(lp<=0?B-pcm->data:A-pcm->data);
641 }else{
642 /* no crossloop */
643 unsigned char *A = pcm->data+*pos;
644 memcpy(out,A,fragsize);
645 *loop=0;
646 *pos+=fragsize;
651 /* fragment is filled such that a crossloop is always 'exactly on
652 schedule' even if that means beginning partway through the window. */
653 void fill_fragment2(unsigned char *out, pcm_t *pcm, off_t start, off_t *pos, off_t end, int *loop,
654 int fragsamples, float *fadewindow){
655 int bps = (pcm->currentbits+7)/8;
656 int cpf = pcm->ch;
657 int bpf = bps*cpf;
658 int fragsize=fragsamples*bpf;
660 /* guard limits here */
661 if(end<fragsize*3)end=fragsize*3;
662 if(end>pcm->size)end=pcm->size;
663 if(start<0)start=0;
664 if(start>pcm->size-fragsize*3)start=pcm->size-fragsize*3;
666 /* loop is never in progress for a fill_fragment2; called only during a seek crosslap */
667 unsigned char *A = pcm->data+*pos;
668 if(end-*pos>=fragsize*2){
669 /* no crosslap */
670 memcpy(out,A,fragsize);
671 *loop=0;
672 *pos=A-pcm->data+fragsize;
673 }else{
674 /* just before crossloop, in the middle of a crossloop, or just after crossloop */
675 int i,j;
676 int lp = (end-*pos)/bpf;
677 unsigned char *B = pcm->data+start;
678 if(lp<fragsamples)B+=(fragsamples-lp)*bpf;
680 for(i=0;i<fragsamples;i++){
681 --lp;
682 if(lp>=fragsamples){
683 /* not yet crosslooping */
684 memcpy(out,A,bpf);
685 A+=bpf;
686 out+=bpf;
687 }else if (lp>=0){
688 /* now crosslooping */
689 float w = fadewindow[lp];
690 for(j=0;j<cpf;j++){
691 float val = get_val(A,bps)*(1.-w) + get_val(B,bps)*w;
692 put_val(out,val,bps);
693 A+=bps;
694 B+=bps;
695 out+=bps;
697 }else{
698 /* after crosslap */
699 memcpy(out,B,bpf);
700 B+=bpf;
701 out+=bpf;
704 *loop=(lp>0?(lp<fragsamples?lp:fragsamples):0);
705 *pos=(lp>0?A-pcm->data:B-pcm->data);
709 /* playback ******************************************************/
711 ao_device *setup_playback(int rate, int ch, int bits, char *matrix, char *device){
712 ao_option aoe={0,0,0};
713 ao_device *ret=NULL;
714 ao_sample_format sf;
715 char *aname="";
716 sf.rate=rate;
717 sf.channels=ch;
718 sf.bits=bits;
719 sf.byte_format=AO_FMT_LITTLE;
720 sf.matrix=(ch>2?matrix:0);
721 aoe.key="quiet";
723 if(!device){
724 /* if we don't have an explicit device, defaults make this easy */
725 int id = ao_default_driver_id();
726 ao_info *ai;
727 if(id<0)
728 return NULL;
729 ai=ao_driver_info(id);
730 if(!ai)
731 return NULL;
732 aname=ai->short_name;
733 if(sb_verbose)
734 fprintf(stderr,"Opening [%s] %s for %d/%d and %d channel[s]...",aname,"default",bits,rate,ch);
735 ret=ao_open_live(id, &sf, &aoe);
736 if(sb_verbose){
737 if(!ret){
738 fprintf(stderr," errno %d\n",errno);
739 }else{
740 fprintf(stderr," ok!\n");
743 }else{
744 /* Otherwise... there's some hunting to do. */
745 /* Is the passed device a number or a name? */
746 char *test;
747 int count;
748 ao_info **info_list=ao_driver_info_list(&count);
749 int number=strtol(device,&test,10);
750 int i;
752 if(!device[0] || test[0]) number=-1;
753 if(sb_verbose)
754 fprintf(stderr,"Scanning for a device driver that recognizes '%s'...\n",device);
756 /* driver info list is sorted by priority */
757 for(i=0;i<count;i++){
758 int j;
759 ao_info *info=info_list[i];
760 ao_option ao={0,0,0};
761 int id = ao_driver_id(info->short_name);
762 char buf[80];
764 sprintf(buf,"%d",number);
765 ao.key=(number>=0?"id":"dev");
766 ao.value=(number>=0?buf:device);
767 ao.next=&aoe;
768 aname=info->short_name;
770 /* don't try to open the driver if it doesn't have the device/id
771 option; it will ignore the option and try to open its default */
772 for(j=0;j<info->option_count;j++)
773 if(!strcmp(info->options[j],ao.key))break;
774 if(j<info->option_count){
775 if(sb_verbose)
776 fprintf(stderr," ...trying to open [%s] %s for %d/%d and %d channel[s]...",aname,device,bits,rate,ch);
777 if((ret=ao_open_live(id,&sf,&ao))){
778 if(sb_verbose)
779 fprintf(stderr," ok!\n");
780 break;
782 if(sb_verbose)
783 fprintf(stderr," errno %d\n",errno);
787 if(ret && sb_verbose)
788 fprintf(stderr,"Opened %s%s audio device %s%sfor %d bit %d channel %d Hz...\n",
789 (device?"":"default "),aname,
790 (device?device:""),(device?" ":""),bits,ch,rate);
792 return ret;