~ubuntu-branches/ubuntu/trusty/libao/trusty

« back to all changes in this revision

Viewing changes to src/audio_out.c

  • Committer: Bazaar Package Importer
  • Author(s): John Francesco Ferlito
  • Date: 2010-04-11 11:04:30 UTC
  • mfrom: (5.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20100411110430-wldc1w7ll1j6c4yc
Tags: 1.0.0-4
Actually depend on libao.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 *  along with GNU Make; see the file COPYING.  If not, write to
23
23
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24
24
 *
25
 
 */
 
25
 ********************************************************************
 
26
 
 
27
 last mod: $Id: audio_out.c 17008 2010-03-24 03:12:16Z xiphmont $
 
28
 
 
29
 ********************************************************************/
26
30
 
27
31
#include <stdlib.h>
28
32
#include <stdio.h>
29
33
#include <string.h>
 
34
#include <ctype.h>
30
35
#include <limits.h>
31
36
#if defined HAVE_DLFCN_H && defined HAVE_DLOPEN
32
37
# include <dlfcn.h>
101
106
static ao_info **info_table = NULL;
102
107
static int driver_count = 0;
103
108
 
 
109
/* uses the device messaging and option infrastructure */
 
110
static ao_device *ao_global_dummy;
 
111
static ao_device ao_global_dummy_storage;
 
112
static ao_option *ao_global_options=NULL;
 
113
 
104
114
/* ---------- Helper functions ---------- */
105
115
 
106
116
/* Clear out all of the library configuration options and set them to
107
117
   defaults.   The defaults should match the initializer above. */
108
118
static void _clear_config()
109
119
{
 
120
        memset(ao_global_dummy,0,sizeof(*ao_global_dummy));
 
121
        ao_global_dummy = NULL;
 
122
        ao_free_options(ao_global_options);
 
123
        ao_global_options = NULL;
 
124
 
110
125
        free(config.default_driver);
111
126
        config.default_driver = NULL;
112
127
}
116
131
   struct. */
117
132
static driver_list *_get_plugin(char *plugin_file)
118
133
{
 
134
        ao_device *device = ao_global_dummy;
119
135
        driver_list *dt;
120
136
        void *handle;
 
137
        char *prompt="";
121
138
 
122
139
        handle = dlopen(plugin_file, DLOPEN_FLAG /* See ao_private.h */);
123
140
 
124
141
        if (handle) {
125
 
                dt = (driver_list *)malloc(sizeof(driver_list));
 
142
                prompt="calloc() failed";
 
143
                dt = (driver_list *)calloc(1,sizeof(driver_list));
126
144
                if (!dt) return NULL;
127
145
 
128
146
                dt->handle = handle;
129
 
                
130
 
                dt->functions = (ao_functions *)malloc(sizeof(ao_functions));
 
147
 
 
148
                dt->functions = (ao_functions *)calloc(1,sizeof(ao_functions));
131
149
                if (!(dt->functions)) {
132
150
                        free(dt);
133
151
                        return NULL;
134
152
                }
135
153
 
 
154
                prompt="ao_plugin_test() missing";
136
155
                dt->functions->test = dlsym(dt->handle, "ao_plugin_test");
137
156
                if (!(dt->functions->test)) goto failed;
138
157
 
139
 
                dt->functions->driver_info = 
 
158
                prompt="ao_plugin_driver_info() missing";
 
159
                dt->functions->driver_info =
140
160
                  dlsym(dt->handle, "ao_plugin_driver_info");
141
161
                if (!(dt->functions->driver_info)) goto failed;
142
162
 
143
 
                dt->functions->device_init = 
 
163
                prompt="ao_plugin_device_list() missing";
 
164
                dt->functions->device_init =
144
165
                  dlsym(dt->handle, "ao_plugin_device_init");
145
166
                if (!(dt->functions->device_init )) goto failed;
146
167
 
147
 
                dt->functions->set_option = 
 
168
                prompt="ao_plugin_set_option() missing";
 
169
                dt->functions->set_option =
148
170
                  dlsym(dt->handle, "ao_plugin_set_option");
149
171
                if (!(dt->functions->set_option)) goto failed;
150
172
 
 
173
                prompt="ao_plugin_open() missing";
151
174
                dt->functions->open = dlsym(dt->handle, "ao_plugin_open");
152
175
                if (!(dt->functions->open)) goto failed;
153
176
 
 
177
                prompt="ao_plugin_play() missing";
154
178
                dt->functions->play = dlsym(dt->handle, "ao_plugin_play");
155
179
                if (!(dt->functions->play)) goto failed;
156
180
 
 
181
                prompt="ao_plugin_close() missing";
157
182
                dt->functions->close = dlsym(dt->handle, "ao_plugin_close");
158
183
                if (!(dt->functions->close)) goto failed;
159
184
 
160
 
                dt->functions->device_clear = 
 
185
                prompt="ao_plugin_clear() missing";
 
186
                dt->functions->device_clear =
161
187
                  dlsym(dt->handle, "ao_plugin_device_clear");
162
188
                if (!(dt->functions->device_clear)) goto failed;
163
189
 
164
190
 
165
191
        } else {
166
 
                return NULL;
 
192
          aerror("Failed to load plugin %s => dlopen() failed\n",plugin_file);
 
193
          return NULL;
167
194
        }
168
195
 
 
196
        adebug("Loaded driver %s\n",dt->functions->driver_info()->short_name);
169
197
        return dt;
170
198
 
171
199
 failed:
 
200
        aerror("Failed to load plugin %s => %s\n",plugin_file,prompt);
172
201
        free(dt->functions);
173
202
        free(dt);
174
203
        return NULL;
182
211
        int def_id;
183
212
        int id;
184
213
        ao_info *info;
185
 
        driver_list *driver = driver_head;
 
214
        driver_list *dl = driver_head;
 
215
        ao_device *device = ao_global_dummy;
186
216
 
 
217
        adebug("Testing drivers to find playback default...\n");
187
218
        if ( name == NULL || (def_id = ao_driver_id(name)) < 0 ) {
188
219
                /* No default specified. Find one among available drivers. */
189
220
                def_id = -1;
190
 
                
 
221
 
191
222
                id = 0;
192
 
                while (driver != NULL) {
193
 
 
194
 
                        info = driver->functions->driver_info();
195
 
 
196
 
                        if ( info->type == AO_TYPE_LIVE && 
 
223
                while (dl != NULL) {
 
224
 
 
225
                        info = dl->functions->driver_info();
 
226
                        adebug("...testing %s\n",info->short_name);
 
227
                        if ( info->type == AO_TYPE_LIVE &&
197
228
                             info->priority > 0 && /* Skip static drivers */
198
 
                             driver->functions->test() ) {
 
229
                             dl->functions->test() ) {
199
230
                                def_id = id; /* Found a usable driver */
 
231
                                adebug("OK, using driver %s\n",info->short_name);
200
232
                                break;
201
233
                        }
202
234
 
203
 
                        driver = driver->next;
 
235
                        dl = dl->next;
204
236
                        id++;
205
237
                }
206
238
        }
209
241
}
210
242
 
211
243
 
212
 
/* Convert the static drivers table into a linked list of drivers. */ 
 
244
/* Convert the static drivers table into a linked list of drivers. */
213
245
static driver_list* _load_static_drivers(driver_list **end)
214
246
{
 
247
        ao_device *device = ao_global_dummy;
215
248
        driver_list *head;
216
249
        driver_list *driver;
217
250
        int i;
218
 
       
 
251
 
219
252
        /* insert first driver */
220
 
        head = driver = malloc(sizeof(driver_list));
 
253
        head = driver = calloc(1,sizeof(driver_list));
221
254
        if (driver != NULL) {
222
255
                driver->functions = static_drivers[0];
223
256
                driver->handle = NULL;
224
257
                driver->next = NULL;
 
258
                adebug("Loaded driver %s (built-in)\n",driver->functions->driver_info()->short_name);
225
259
 
226
260
                i = 1;
227
261
                while (static_drivers[i] != NULL) {
228
 
                        driver->next = malloc(sizeof(driver_list));
 
262
                  driver->next = calloc(1,sizeof(driver_list));
229
263
                        if (driver->next == NULL)
230
264
                                break;
231
265
 
232
266
                        driver->next->functions = static_drivers[i];
233
267
                        driver->next->handle = NULL;
234
268
                        driver->next->next = NULL;
235
 
                        
 
269
 
236
270
                        driver = driver->next;
 
271
                        adebug("Loaded driver %s (built-in)\n",driver->functions->driver_info()->short_name);
237
272
                        i++;
238
273
                }
239
274
        }
253
288
        struct dirent *plugin_dirent;
254
289
        char *ext;
255
290
        struct stat statbuf;
256
 
        char fullpath[PATH_MAX];
257
291
        DIR *plugindir;
258
292
        driver_list *plugin;
259
293
        driver_list *driver = end;
 
294
        ao_device *device = ao_global_dummy;
260
295
 
261
296
        /* now insert any plugins we find */
262
297
        plugindir = opendir(AO_PLUGIN_PATH);
 
298
        adebug("Loading driver plugins from %s...\n",AO_PLUGIN_PATH);
263
299
        if (plugindir != NULL) {
264
 
                while ((plugin_dirent = readdir(plugindir)) != NULL) {
265
 
                        snprintf(fullpath, PATH_MAX, "%s/%s", 
266
 
                                 AO_PLUGIN_PATH, plugin_dirent->d_name);
267
 
                        if (!stat(fullpath, &statbuf) && 
268
 
                            S_ISREG(statbuf.st_mode) && 
269
 
                         (ext = strrchr(plugin_dirent->d_name, '.')) != NULL) {
270
 
                                if (strcmp(ext, SHARED_LIB_EXT) == 0) {
271
 
                                        plugin = _get_plugin(fullpath);
272
 
                                        if (plugin) {
273
 
                                                driver->next = plugin;
274
 
                                                plugin->next = NULL;
275
 
                                                driver = driver->next;
276
 
                                        }
277
 
                                }
278
 
                        }
279
 
                }
280
 
                
281
 
                closedir(plugindir);
 
300
          while ((plugin_dirent = readdir(plugindir)) != NULL) {
 
301
            char fullpath[strlen(AO_PLUGIN_PATH) + 1 + strlen(plugin_dirent->d_name) + 1];
 
302
            snprintf(fullpath, sizeof(fullpath), "%s/%s",
 
303
                     AO_PLUGIN_PATH, plugin_dirent->d_name);
 
304
            if (!stat(fullpath, &statbuf) &&
 
305
                S_ISREG(statbuf.st_mode) &&
 
306
                (ext = strrchr(plugin_dirent->d_name, '.')) != NULL) {
 
307
              if (strcmp(ext, SHARED_LIB_EXT) == 0) {
 
308
                plugin = _get_plugin(fullpath);
 
309
                if (plugin) {
 
310
                  driver->next = plugin;
 
311
                  plugin->next = NULL;
 
312
                  driver = driver->next;
 
313
                }
 
314
              }
 
315
            }
 
316
          }
 
317
 
 
318
          closedir(plugindir);
282
319
        }
283
320
#endif
284
321
}
285
322
 
286
323
 
287
 
/* Compare two drivers based on priority 
 
324
/* Compare two drivers based on priority
288
325
   Used as compar function for qsort() in _make_info_table() */
289
 
static int _compar_driver_priority (const driver_list **a, 
 
326
static int _compar_driver_priority (const driver_list **a,
290
327
                                    const driver_list **b)
291
328
{
292
329
        return memcmp(&((*b)->functions->driver_info()->priority),
313
350
                list = list->next;
314
351
        }
315
352
 
316
 
        
 
353
 
317
354
        /* Sort driver_list */
318
355
        drivers_table = (driver_list **) calloc(i, sizeof(driver_list *));
319
356
        if (drivers_table == NULL)
322
359
        *driver_count = i;
323
360
        for (i = 0; i < *driver_count; i++, list = list->next)
324
361
                drivers_table[i] = list;
325
 
        qsort(drivers_table, i, sizeof(driver_list *), 
 
362
        qsort(drivers_table, i, sizeof(driver_list *),
326
363
                        (int(*)(const void *, const void *))
327
364
                        _compar_driver_priority);
328
365
        *head = drivers_table[0];
357
394
                driver = driver->next;
358
395
        }
359
396
 
360
 
        if (i == driver_id) 
 
397
        if (i == driver_id)
361
398
                return driver;
362
399
 
363
400
        return NULL;
376
413
                driver = driver->next;
377
414
                i++;
378
415
        }
379
 
        
 
416
 
380
417
        if (i == (driver_id + 1))
381
418
                return 1;
382
419
 
383
420
        return 0;
384
 
}       
 
421
}
385
422
 
386
423
 
387
424
/* helper function to convert a byte_format of AO_FMT_NATIVE to the
404
441
                                 ao_sample_format *format, FILE *file)
405
442
{
406
443
        ao_device *device;
407
 
        
408
 
        device = malloc(sizeof(ao_device));
409
 
        
410
 
        if (device != NULL) {           
 
444
 
 
445
        device = calloc(1,sizeof(ao_device));
 
446
 
 
447
        if (device != NULL) {
411
448
                device->type = driver->functions->driver_info()->type;
412
449
                device->driver_id = driver_id;
413
450
                device->funcs = driver->functions;
414
451
                device->file = file;
415
 
                device->machine_byte_format = 
 
452
                device->machine_byte_format =
416
453
                  ao_is_big_endian() ? AO_FMT_BIG : AO_FMT_LITTLE;
417
454
                device->client_byte_format =
418
455
                  _real_byte_format(format->byte_format);
419
456
                device->swap_buffer = NULL;
420
457
                device->swap_buffer_size = 0;
421
458
                device->internal = NULL;
 
459
                device->output_channels = format->channels;
 
460
                device->inter_permute = NULL;
 
461
                device->output_matrix = NULL;
422
462
        }
423
463
 
424
464
        return device;
444
484
}
445
485
 
446
486
 
 
487
static void _buffer_zero(char *target,int och,int bytewidth,int ochannels,int bytes){
 
488
  int i = och*bytewidth;
 
489
  int stride = bytewidth*ochannels;
 
490
  switch(bytewidth){
 
491
  case 1:
 
492
    while(i<bytes){
 
493
      ((unsigned char *)target)[i] = 128; /* 8 bit PCM is unsigned in libao */
 
494
      i+=stride;
 
495
    }
 
496
    break;
 
497
  case 2:
 
498
    while(i<bytes){
 
499
      target[i] = 0;
 
500
      target[i+1] = 0;
 
501
      i+=stride;
 
502
    }
 
503
    break;
 
504
  case 3:
 
505
    while(i<bytes){
 
506
      target[i] = 0;
 
507
      target[i+1] = 0;
 
508
      target[i+2] = 0;
 
509
      i+=stride;
 
510
    }
 
511
    break;
 
512
  case 4:
 
513
    while(i<bytes){
 
514
      target[i] = 0;
 
515
      target[i+1] = 0;
 
516
      target[i+2] = 0;
 
517
      target[i+3] = 0;
 
518
      i+=stride;
 
519
    }
 
520
    break;
 
521
  }
 
522
}
 
523
 
 
524
static void _buffer_permute_swap(char *target,int och,int bytewidth,int ochannels,int bytes,
 
525
                                 char *source,int ich, int ichannels){
 
526
  int o = och*bytewidth;
 
527
  int i = ich*bytewidth;
 
528
  int ostride = bytewidth*ochannels;
 
529
  int istride = bytewidth*ichannels;
 
530
  switch(bytewidth){
 
531
  case 2:
 
532
    while(o<bytes){
 
533
      target[o] = source[i+1];
 
534
      target[o+1] = source[i];
 
535
      o+=ostride;
 
536
      i+=istride;
 
537
    }
 
538
    break;
 
539
  case 3:
 
540
    while(o<bytes){
 
541
      target[o] = source[i+2];
 
542
      target[o+1] = source[i+1];
 
543
      target[o+2] = source[i];
 
544
      o+=ostride;
 
545
      i+=istride;
 
546
    }
 
547
    break;
 
548
  case 4:
 
549
    while(o<bytes){
 
550
      target[o] = source[i+3];
 
551
      target[o+1] = source[i+2];
 
552
      target[o+2] = source[i+1];
 
553
      target[o+3] = source[i];
 
554
      o+=ostride;
 
555
      i+=istride;
 
556
    }
 
557
    break;
 
558
  }
 
559
}
 
560
 
 
561
static void _buffer_permute(char *target,int och,int bytewidth,int ochannels,int bytes,
 
562
                            char *source,int ich, int ichannels){
 
563
  int o = och*bytewidth;
 
564
  int i = ich*bytewidth;
 
565
  int ostride = bytewidth*ochannels;
 
566
  int istride = bytewidth*ichannels;
 
567
  switch(bytewidth){
 
568
  case 1:
 
569
    while(o<bytes){
 
570
      target[o] = source[i];
 
571
      o+=ostride;
 
572
      i+=istride;
 
573
    }
 
574
    break;
 
575
  case 2:
 
576
    while(o<bytes){
 
577
      target[o] = source[i];
 
578
      target[o+1] = source[i+1];
 
579
      o+=ostride;
 
580
      i+=istride;
 
581
    }
 
582
    break;
 
583
  case 3:
 
584
    while(o<bytes){
 
585
      target[o] = source[i];
 
586
      target[o+1] = source[i+1];
 
587
      target[o+2] = source[i+2];
 
588
      o+=ostride;
 
589
      i+=istride;
 
590
    }
 
591
    break;
 
592
  case 4:
 
593
    while(o<bytes){
 
594
      target[o] = source[i];
 
595
      target[o+1] = source[i+1];
 
596
      target[o+2] = source[i+2];
 
597
      target[o+3] = source[i+3];
 
598
      o+=ostride;
 
599
      i+=istride;
 
600
    }
 
601
    break;
 
602
  }
 
603
}
 
604
 
 
605
 
447
606
/* Swap and copy the byte order of samples from the source buffer to
448
607
   the target buffer. */
449
608
static void _swap_samples(char *target_buffer, char* source_buffer,
456
615
                target_buffer[i+1] = source_buffer[i];
457
616
        }
458
617
}
459
 
                
 
618
 
 
619
/* the channel locations we know right now. code below assumes U is in slot 0, X in 1, M in 2 */
 
620
static char *mnemonics[]={
 
621
  "X",
 
622
  "M",
 
623
  "L","C","R","CL","CR","SL","SR","BL","BC","BR","LFE",
 
624
  "A1","A2","A3","A4","A5","A6","A7","A8","A9","A10",
 
625
  "A11","A12","A13","A14","A15","A16","A17","A18","A19","A20",
 
626
  "A21","A22","A23","A24","A25","A26","A27","A28","A29","A30",
 
627
  "A31","A32",NULL
 
628
};
 
629
 
 
630
/* Check the requested matrix string for syntax and mnemonics */
 
631
static char *_sanitize_matrix(int maxchannels, char *matrix, ao_device *device){
 
632
  if(matrix){
 
633
    char *ret = calloc(strlen(matrix)+1,1); /* can only get smaller */
 
634
    char *p=matrix;
 
635
    int count=0;
 
636
    while(count<maxchannels){
 
637
      char *h,*t;
 
638
      int m=0;
 
639
 
 
640
      /* trim leading space */
 
641
      while(*p && isspace(*p))p++;
 
642
 
 
643
      /* search for seperator */
 
644
      h=p;
 
645
      while(*h && *h!=',')h++;
 
646
 
 
647
      /* trim trailing space */
 
648
      t=h;
 
649
      while(t>p && isspace(*(t-1)))t--;
 
650
 
 
651
      while(mnemonics[m]){
 
652
        if(t-p && !strncmp(mnemonics[m],p,t-p) &&
 
653
           strlen(mnemonics[m])==t-p){
 
654
          if(count)strcat(ret,",");
 
655
          strcat(ret,mnemonics[m]);
 
656
          break;
 
657
        }
 
658
        m++;
 
659
      }
 
660
      if(!mnemonics[m]){
 
661
        /* unrecognized channel mnemonic */
 
662
        {
 
663
          int i;
 
664
          aerror("Unrecognized channel name \"");
 
665
          for(i=0;i<t-p;i++)fputc(p[i],stderr);
 
666
          fprintf(stderr,"\" in channel matrix \"%s\"\n",matrix);
 
667
        }
 
668
        free(ret);
 
669
        return NULL;
 
670
      }else
 
671
        count++;
 
672
      if(!*h)break;
 
673
      p=h+1;
 
674
    }
 
675
    return ret;
 
676
  }else
 
677
    return NULL;
 
678
}
 
679
 
 
680
static int _find_channel(int needle, char *haystack){
 
681
  char *p=haystack;
 
682
  int count=0;
 
683
 
 
684
  /* X does not map to anything, including X! */
 
685
  if(needle==0) return -1;
 
686
 
 
687
  while(1){
 
688
    char *h;
 
689
    int m=0;
 
690
 
 
691
    /* search for seperator */
 
692
    h=p;
 
693
    while(*h && *h!=',')h++;
 
694
 
 
695
    while(mnemonics[m]){
 
696
      if(!strncmp(mnemonics[needle],p,h-p) &&
 
697
         strlen(mnemonics[needle])==h-p)break;
 
698
      m++;
 
699
    }
 
700
    if(mnemonics[m])
 
701
      return count;
 
702
    count++;
 
703
    if(!*h)break;
 
704
    p=h+1;
 
705
  }
 
706
  return -1;
 
707
}
 
708
 
 
709
static char **_tokenize_matrix(char *matrix){
 
710
  char **ret=NULL;
 
711
  char *p=matrix;
 
712
  int count=0;
 
713
  while(1){
 
714
    char *h,*t;
 
715
 
 
716
    /* trim leading space */
 
717
    while(*p && isspace(*p))p++;
 
718
 
 
719
    /* search for seperator */
 
720
    h=p;
 
721
    while(*h && *h!=',')h++;
 
722
 
 
723
    /* trim trailing space */
 
724
    t=h;
 
725
    while(t>p && isspace(*(t-1)))t--;
 
726
 
 
727
    count++;
 
728
    if(!*h)break;
 
729
    p=h+1;
 
730
  }
 
731
 
 
732
  ret = calloc(count+1,sizeof(*ret));
 
733
 
 
734
  p=matrix;
 
735
  count=0;
 
736
  while(1){
 
737
    char *h,*t;
 
738
 
 
739
    /* trim leading space */
 
740
    while(*p && isspace(*p))p++;
 
741
 
 
742
    /* search for seperator */
 
743
    h=p;
 
744
    while(*h && *h!=',')h++;
 
745
 
 
746
    /* trim trailing space */
 
747
    t=h;
 
748
    while(t>p && isspace(*(t-1)))t--;
 
749
 
 
750
    ret[count] = calloc(t-p+1,1);
 
751
    memcpy(ret[count],p,t-p);
 
752
    count++;
 
753
    if(!*h)break;
 
754
    p=h+1;
 
755
  }
 
756
 
 
757
  return ret;
 
758
 
 
759
}
 
760
 
 
761
static void _free_map(char **m){
 
762
  char **in=m;
 
763
  while(m && *m){
 
764
    free(*m);
 
765
    m++;
 
766
  }
 
767
  if(in)free(in);
 
768
}
 
769
 
 
770
static unsigned int _matrix_to_channelmask(int ch, char *matrix, char *premap, int **mout){
 
771
  unsigned int ret=0;
 
772
  char *p=matrix;
 
773
  int *perm=(*mout=malloc(ch*sizeof(*mout)));
 
774
  int i;
 
775
  char **map = _tokenize_matrix(premap);
 
776
 
 
777
  for(i=0;i<ch;i++) perm[i] = -1;
 
778
  i=0;
 
779
 
 
780
  while(1){
 
781
    char *h=p;
 
782
    int m=0;
 
783
 
 
784
    /* search for seperator */
 
785
    while(*h && *h!=',')h++;
 
786
 
 
787
    while(map[m]){
 
788
      if(h-p && !strncmp(map[m],p,h-p) &&
 
789
         strlen(map[m])==h-p)
 
790
        break;
 
791
      m++;
 
792
    }
 
793
    /* X is a placeholder, X does not map to X */
 
794
    if(map[m] && strcmp(map[m],"X")){
 
795
      ret |= (1<<m);
 
796
      perm[i] = m;
 
797
    }
 
798
    if(!*h)break;
 
799
    p=h+1;
 
800
    i++;
 
801
  }
 
802
 
 
803
  _free_map(map);
 
804
  return ret;
 
805
}
 
806
 
 
807
static char *_channelmask_to_matrix(unsigned int mask, char *premap){
 
808
  int m=0;
 
809
  int count=0;
 
810
  char buffer[257]={0};
 
811
  char **map = _tokenize_matrix(premap);
 
812
 
 
813
  while(map[m]){
 
814
    if(mask & (1<<m)){
 
815
      if(count)
 
816
        strcat(buffer,",");
 
817
      strcat(buffer,map[m]);
 
818
      count++;
 
819
    }
 
820
    m++;
 
821
  }
 
822
  _free_map(map);
 
823
  return strdup(buffer);
 
824
}
 
825
 
 
826
static int _channelmask_bits(unsigned int mask){
 
827
  int count=0;
 
828
  while(mask){
 
829
    if(mask&1)count++;
 
830
    mask/=2;
 
831
  }
 
832
  return count;
 
833
}
 
834
 
 
835
static int _channelmask_maxbit(unsigned int mask){
 
836
  int count=0;
 
837
  int max=-1;
 
838
  while(mask){
 
839
    if(mask&1)max=count;
 
840
    mask/=2;
 
841
    count++;
 
842
  }
 
843
  return max;
 
844
}
 
845
 
 
846
static char *_matrix_intersect(char *matrix,char *premap){
 
847
  char *p=matrix;
 
848
  char buffer[257]={0};
 
849
  int count=0;
 
850
  char **map = _tokenize_matrix(premap);
 
851
 
 
852
  while(1){
 
853
    char *h=p;
 
854
    int m=0;
 
855
 
 
856
    /* search for seperator */
 
857
    while(*h && *h!=',')h++;
 
858
 
 
859
    while(map[m]){
 
860
      if(h-p && !strncmp(map[m],p,h-p) &&
 
861
         strlen(map[m])==h-p)
 
862
        break;
 
863
      m++;
 
864
    }
 
865
    /* X is a placeholder, X does not map to X */
 
866
    if(map[m] && strcmp(map[m],"X")){
 
867
      if(count)
 
868
        strcat(buffer,",");
 
869
      strcat(buffer,map[m]);
 
870
      count++;
 
871
    }
 
872
 
 
873
    if(!*h)break;
 
874
    p=h+1;
 
875
  }
 
876
 
 
877
  _free_map(map);
 
878
  return strdup(buffer);
 
879
}
 
880
 
 
881
static int ao_global_load_options(ao_option *options){
 
882
  while (options != NULL) {
 
883
    if(!strcmp(options->key,"debug")){
 
884
      ao_global_dummy->verbose=2;
 
885
    }else if(!strcmp(options->key,"verbose")){
 
886
      if(ao_global_dummy->verbose<1)ao_global_dummy->verbose=1;
 
887
    }else if(!strcmp(options->key,"quiet")){
 
888
      ao_global_dummy->verbose=-1;
 
889
    }
 
890
 
 
891
    options = options->next;
 
892
  }
 
893
 
 
894
  return 0;
 
895
 
 
896
}
 
897
 
 
898
static int ao_device_load_options(ao_device *device, ao_option *options){
 
899
 
 
900
  while (options != NULL) {
 
901
    if(!strcmp(options->key,"matrix")){
 
902
      /* If a driver has a static channel mapping mechanism
 
903
         (physically constant channel mapping, or at least an
 
904
         unvarying set of constants for mapping channels), the
 
905
         output_matrix is already set.  An app/user specified
 
906
         output mapping trumps. */
 
907
      if(device->output_matrix)
 
908
        free(device->output_matrix);
 
909
      /* explicitly set the output matrix to the requested
 
910
         string; devices must not override. */
 
911
      device->output_matrix = _sanitize_matrix(32, options->value, device);
 
912
      if(!device->output_matrix){
 
913
        aerror("Empty or inavlid output matrix\n");
 
914
        return AO_EBADOPTION;
 
915
      }
 
916
      adebug("Sanitized device output matrix: %s\n",device->output_matrix);
 
917
    }else if(!strcmp(options->key,"debug")){
 
918
      device->verbose=2;
 
919
    }else if(!strcmp(options->key,"verbose")){
 
920
      if(device->verbose<1)device->verbose=1;
 
921
    }else if(!strcmp(options->key,"quiet")){
 
922
      device->verbose=-1;
 
923
    }else{
 
924
      if (!device->funcs->set_option(device, options->key, options->value)) {
 
925
        /* Problem setting options */
 
926
        return AO_EOPENDEVICE;
 
927
      }
 
928
    }
 
929
 
 
930
    options = options->next;
 
931
  }
 
932
 
 
933
  return 0;
 
934
}
460
935
 
461
936
/* Open a device.  If this is a live device, file == NULL. */
462
 
static ao_device* _open_device(int driver_id, ao_sample_format *format, 
 
937
static ao_device* _open_device(int driver_id, ao_sample_format *format,
463
938
                               ao_option *options, FILE *file)
464
939
{
465
940
        ao_functions *funcs;
466
941
        driver_list *driver;
467
 
        ao_device *device;
 
942
        ao_device *device=NULL;
468
943
        int result;
469
 
        
 
944
        ao_sample_format sformat=*format;
 
945
        sformat.matrix=NULL;
 
946
 
470
947
        /* Get driver id */
471
948
        if ( (driver = _get_driver(driver_id)) == NULL ) {
472
949
                errno = AO_ENODRIVER;
473
 
                return NULL; /* No driver exists */
 
950
                goto error;
474
951
        }
475
952
 
476
953
        funcs = driver->functions;
477
954
 
478
955
        /* Check the driver type */
479
 
        if (file == NULL && 
 
956
        if (file == NULL &&
480
957
            funcs->driver_info()->type != AO_TYPE_LIVE) {
481
958
 
482
959
                errno = AO_ENOTLIVE;
483
 
                return NULL;
484
 
        } else if (file != NULL && 
 
960
                goto error;
 
961
        } else if (file != NULL &&
485
962
                   funcs->driver_info()->type != AO_TYPE_FILE) {
486
963
 
487
964
                errno = AO_ENOTFILE;
488
 
                return NULL;
 
965
                goto error;
489
966
        }
490
 
        
 
967
 
491
968
        /* Make a new device structure */
492
 
        if ( (device = _create_device(driver_id, driver, 
 
969
        if ( (device = _create_device(driver_id, driver,
493
970
                                      format, file)) == NULL ) {
494
971
                errno = AO_EFAIL;
495
 
                return NULL; /* Couldn't alloc device */
 
972
                goto error;
496
973
        }
497
 
                
498
 
        /* Initialize the device memory */
 
974
 
 
975
        /* Initialize the device memory; get static channel mapping */
499
976
        if (!funcs->device_init(device)) {
500
 
                free(device);
501
977
                errno = AO_EFAIL;
502
 
                return NULL; /* Couldn't init internal memory */
 
978
                goto error;
503
979
        }
504
 
        
 
980
 
505
981
        /* Load options */
506
 
        while (options != NULL) {
507
 
                if (!funcs->set_option(device, options->key, options->value)) {
508
 
                        /* Problem setting options */
509
 
                        free(device);
510
 
                        errno = AO_EOPENDEVICE;
511
 
                        return NULL;
512
 
                }
513
 
                        
514
 
                options = options->next;
515
 
        }
 
982
        errno = ao_device_load_options(device,ao_global_options);
 
983
        if(errno) goto error;
 
984
        errno = ao_device_load_options(device,options);
 
985
        if(errno) goto error;
 
986
 
 
987
        /* also sanitize the format input channel matrix */
 
988
        if(format->matrix){
 
989
          sformat.matrix = _sanitize_matrix(format->channels, format->matrix, device);
 
990
          if(!sformat.matrix)
 
991
            awarn("Input channel matrix invalid; ignoring.\n");
 
992
 
 
993
          /* special-case handling of 'M'. */
 
994
          if(sformat.channels==1 && sformat.matrix && !strcmp(sformat.matrix,"M")){
 
995
            free(sformat.matrix);
 
996
            sformat.matrix=NULL;
 
997
          }
 
998
        }
 
999
 
 
1000
        /* If device init was able to declare a static channel mapping
 
1001
           mechanism, reconcile it to the input now.  Odd drivers that
 
1002
           need to communicate with a backend device to determine
 
1003
           channel mapping strategy can still bypass this mechanism
 
1004
           entirely.  Also, drivers like ALSA may need to adjust
 
1005
           strategy depending on what device is successfully opened,
 
1006
           etc, but this still saves work later. */
 
1007
 
 
1008
        if(device->output_matrix && sformat.matrix){
 
1009
          switch(device->output_matrix_order){
 
1010
          case AO_OUTPUT_MATRIX_FIXED:
 
1011
            /* Backend channel ordering is immutable and unused
 
1012
               channels must still be sent.  Look for the highest
 
1013
               channel number we are able to map from the input
 
1014
               matrix. */
 
1015
            {
 
1016
              unsigned int mask = _matrix_to_channelmask(sformat.channels,sformat.matrix,
 
1017
                                                         device->output_matrix,
 
1018
                                                         &device->input_map);
 
1019
              int max = _channelmask_maxbit(mask);
 
1020
              if(max<0){
 
1021
                aerror("Unable to map any channels from input matrix to output");
 
1022
                errno = AO_EBADFORMAT;
 
1023
                goto error;
 
1024
              }
 
1025
              device->output_channels = max+1;
 
1026
              device->output_mask = mask;
 
1027
              device->inter_matrix = strdup(device->output_matrix);
 
1028
            }
 
1029
            break;
 
1030
 
 
1031
          case AO_OUTPUT_MATRIX_COLLAPSIBLE:
 
1032
            /* the ordering of channels submitted to the backend is
 
1033
               fixed, but only the channels in use should be present
 
1034
               in the audio stream */
 
1035
            {
 
1036
              unsigned int mask = _matrix_to_channelmask(sformat.channels,sformat.matrix,
 
1037
                                                         device->output_matrix,
 
1038
                                                         &device->input_map);
 
1039
              int channels = _channelmask_bits(mask);
 
1040
              if(channels<0){
 
1041
                aerror("Unable to map any channels from input matrix to output");
 
1042
                errno = AO_EBADFORMAT;
 
1043
                goto error;
 
1044
              }
 
1045
              device->output_channels = channels;
 
1046
              device->output_mask = mask;
 
1047
              device->inter_matrix = _channelmask_to_matrix(mask,device->output_matrix);
 
1048
            }
 
1049
            break;
 
1050
 
 
1051
          case AO_OUTPUT_MATRIX_PERMUTABLE:
 
1052
            /* The ordering of channels is freeform.  Only the
 
1053
               channels in use should be sent, and they may be sent in
 
1054
               any order.  If possible, leave the input ordering
 
1055
               unchanged */
 
1056
            {
 
1057
              unsigned int mask = _matrix_to_channelmask(sformat.channels,sformat.matrix,
 
1058
                                                         device->output_matrix,
 
1059
                                                         &device->input_map);
 
1060
              int channels = _channelmask_bits(mask);
 
1061
              if(channels<0){
 
1062
                aerror("Unable to map any channels from input matrix to output");
 
1063
                errno = AO_EBADFORMAT;
 
1064
                goto error;
 
1065
              }
 
1066
              device->output_channels = channels;
 
1067
              device->output_mask = mask;
 
1068
              device->inter_matrix = _matrix_intersect(sformat.matrix,device->output_matrix);
 
1069
            }
 
1070
            break;
 
1071
 
 
1072
          default:
 
1073
            aerror("Driver backend failed to set output ordering.\n");
 
1074
            errno = AO_EFAIL;
 
1075
            goto error;
 
1076
          }
 
1077
 
 
1078
        }else{
 
1079
          device->output_channels = sformat.channels;
 
1080
        }
 
1081
 
 
1082
        /* other housekeeping */
 
1083
        device->input_channels = sformat.channels;
 
1084
        device->bytewidth = (sformat.bits+7)>>3;
 
1085
        device->rate = sformat.rate;
516
1086
 
517
1087
        /* Open the device */
518
 
        result = funcs->open(device, format);
 
1088
        result = funcs->open(device, &sformat);
519
1089
        if (!result) {
520
 
                funcs->device_clear(device);
521
 
                free(device);
522
 
                errno = AO_EOPENDEVICE;
523
 
                return NULL; /* Couldn't open device */
 
1090
          errno = AO_EOPENDEVICE;
 
1091
          goto error;
524
1092
        }
525
 
                
 
1093
 
 
1094
        /* set up permutation based on finalized inter_matrix mapping */
 
1095
        /* The only way device->output_channels could be zero here is
 
1096
           if the driver has opted to ouput no channels (eg, the null
 
1097
           driver). */
 
1098
        if(sformat.matrix){
 
1099
          if(!device->inter_matrix){
 
1100
            awarn("Driver %s does not support automatic channel mapping;\n"
 
1101
                 "\tRouting only L/R channels to output.\n\n",
 
1102
                 info_table[device->driver_id]->short_name);
 
1103
            device->inter_matrix=strdup("L,R");
 
1104
          }
 
1105
          {
 
1106
 
 
1107
            /* walk thorugh the inter matrix, match channels */
 
1108
            char *op=device->inter_matrix;
 
1109
            int count=0;
 
1110
            device->inter_permute = calloc(device->output_channels,sizeof(int));
 
1111
 
 
1112
            adebug("\n");
 
1113
 
 
1114
            while(count<device->output_channels){
 
1115
              int m=0,mm;
 
1116
              char *h=op;
 
1117
 
 
1118
              if(*op){
 
1119
                /* find mnemonic offset of inter channel */
 
1120
                while(*h && *h!=',')h++;
 
1121
                while(mnemonics[m]){
 
1122
                  if(!strncmp(mnemonics[m],op,h-op))
 
1123
                    break;
 
1124
                  m++;
 
1125
                }
 
1126
                mm=m;
 
1127
 
 
1128
                /* find match in input if any */
 
1129
                device->inter_permute[count] = _find_channel(m,sformat.matrix);
 
1130
                if(device->inter_permute[count] == -1 && sformat.channels == 1){
 
1131
                  device->inter_permute[count] = _find_channel(1,sformat.matrix);
 
1132
                  mm=1;
 
1133
                }
 
1134
              }else
 
1135
                device->inter_permute[count] = -1;
 
1136
 
 
1137
              /* display resulting mapping for now */
 
1138
              if(device->inter_permute[count]>=0){
 
1139
                adebug("input %d (%s)\t -> backend %d (%s)\n",
 
1140
                       device->inter_permute[count], mnemonics[mm],
 
1141
                       count,mnemonics[m]);
 
1142
              }else{
 
1143
                adebug("             \t    backend %d (%s)\n",
 
1144
                       count,mnemonics[m]);
 
1145
              }
 
1146
              count++;
 
1147
              op=h;
 
1148
              if(*h)op++;
 
1149
            }
 
1150
            {
 
1151
              char **inch = _tokenize_matrix(sformat.matrix);
 
1152
              int i,j;
 
1153
              int unflag=0;
 
1154
              for(j=0;j<sformat.channels;j++){
 
1155
                for(i=0;i<device->output_channels;i++)
 
1156
                  if(device->inter_permute[i]==j)break;
 
1157
                if(i==device->output_channels){
 
1158
                  adebug("input %d (%s)\t -> none\n",
 
1159
                         j,inch[j]);
 
1160
                  unflag=1;
 
1161
                }
 
1162
              }
 
1163
              _free_map(inch);
 
1164
              if(unflag)
 
1165
                awarn("Some input channels are unmapped and will not be used.\n");
 
1166
            }
 
1167
            averbose("\n");
 
1168
 
 
1169
          }
 
1170
        }
 
1171
 
 
1172
        /* if there's no actual permutation to do, release the permutation vector */
 
1173
        if(device->inter_permute && device->output_channels == device->input_channels){
 
1174
          int i;
 
1175
          for(i=0;i<device->output_channels;i++)
 
1176
            if(device->inter_permute[i]!=i)break;
 
1177
          if(i==device->output_channels){
 
1178
            free(device->inter_permute);
 
1179
            device->inter_permute=NULL;
 
1180
          }
 
1181
        }
 
1182
 
526
1183
        /* Resolve actual driver byte format */
527
 
        device->driver_byte_format = 
 
1184
        device->driver_byte_format =
528
1185
                _real_byte_format(device->driver_byte_format);
529
 
        
530
 
        /* Only create swap buffer for 16 bit samples if needed */
531
 
        if (format->bits == 16 &&
532
 
            device->client_byte_format != device->driver_byte_format) {
533
 
 
534
 
          fprintf(stderr,
535
 
                  "n\n\n\n-------------------------\n"
536
 
                  "big : %d\n"
537
 
                  "device->client_byte_format:%d\n"
538
 
                  "device->driver_byte_format:%d\n"
539
 
                  "--------------------------\n",
540
 
                  ao_is_big_endian(),device->client_byte_format,device->driver_byte_format);
541
 
                
542
 
                result = _realloc_swap_buffer(device, DEF_SWAP_BUF_SIZE);
543
 
                
544
 
                if (!result) {
545
 
                        
546
 
                        device->funcs->close(device);
547
 
                        device->funcs->device_clear(device);
548
 
                        free(device);
549
 
                        errno = AO_EFAIL;
550
 
                        return NULL; /* Couldn't alloc swap buffer */
551
 
                }
 
1186
 
 
1187
        /* Only create swap buffer if needed */
 
1188
        if (device->bytewidth>1 &&
 
1189
            device->client_byte_format != device->driver_byte_format){
 
1190
          adebug("swap buffer required:\n");
 
1191
          adebug("  machine endianness: %d\n",ao_is_big_endian());
 
1192
          adebug("  device->client_byte_format:%d\n",device->client_byte_format);
 
1193
          adebug("  device->driver_byte_format:%d\n",device->driver_byte_format);
 
1194
        }
 
1195
 
 
1196
        if ( (device->bytewidth>1 &&
 
1197
              device->client_byte_format != device->driver_byte_format) ||
 
1198
             device->inter_permute){
 
1199
 
 
1200
          result = _realloc_swap_buffer(device, DEF_SWAP_BUF_SIZE);
 
1201
 
 
1202
          if (!result) {
 
1203
 
 
1204
            if(sformat.matrix)free(sformat.matrix);
 
1205
            device->funcs->close(device);
 
1206
            device->funcs->device_clear(device);
 
1207
            free(device);
 
1208
            errno = AO_EFAIL;
 
1209
            return NULL; /* Couldn't alloc swap buffer */
 
1210
          }
552
1211
        }
553
 
        
 
1212
 
554
1213
        /* If we made it this far, everything is OK. */
555
 
        return device; 
 
1214
        if(sformat.matrix)free(sformat.matrix);
 
1215
        return device;
 
1216
 
 
1217
 error:
 
1218
        {
 
1219
          int errtemp = errno;
 
1220
          if(sformat.matrix)
 
1221
            free(sformat.matrix);
 
1222
          ao_close(device);
 
1223
          errno=errtemp;
 
1224
        }
 
1225
        return NULL;
556
1226
}
557
1227
 
558
1228
 
560
1230
 
561
1231
/* -- Library Setup/Teardown -- */
562
1232
 
 
1233
static ao_info ao_dummy_info=
 
1234
  { 0,0,0,0,0,0,0,0,0 };
 
1235
static ao_info *ao_dummy_driver_info(void){
 
1236
  return &ao_dummy_info;
 
1237
}
 
1238
static ao_functions ao_dummy_funcs=
 
1239
  { 0, &ao_dummy_driver_info, 0,0,0,0,0,0,0};
 
1240
 
563
1241
void ao_initialize(void)
564
1242
{
565
1243
        driver_list *end;
 
1244
        ao_global_dummy = &ao_global_dummy_storage;
 
1245
        ao_global_dummy->funcs = &ao_dummy_funcs;
566
1246
 
567
1247
        /* Read config files */
568
 
        read_config_files(&config);
 
1248
        ao_read_config_files(&config);
 
1249
        ao_global_load_options(ao_global_options);
569
1250
 
570
1251
        if (driver_head == NULL) {
571
1252
                driver_head = _load_static_drivers(&end);
576
1257
        info_table = _make_info_table(&driver_head, &driver_count);
577
1258
}
578
1259
 
579
 
 
580
1260
void ao_shutdown(void)
581
1261
{
582
1262
        driver_list *driver = driver_head;
603
1283
 
604
1284
 
605
1285
/* -- Device Setup/Playback/Teardown -- */
606
 
 
607
1286
int ao_append_option(ao_option **options, const char *key, const char *value)
608
1287
{
609
1288
        ao_option *op, *list;
610
1289
 
611
 
        op = malloc(sizeof(ao_option));
 
1290
        op = calloc(1,sizeof(ao_option));
612
1291
        if (op == NULL) return 0;
613
1292
 
614
1293
        op->key = strdup(key);
615
 
        op->value = strdup(value);
 
1294
        op->value = strdup(value?value:"");
616
1295
        op->next = NULL;
617
1296
 
618
1297
        if ((list = *options) != NULL) {
627
1306
        return 1;
628
1307
}
629
1308
 
 
1309
int ao_append_global_option(const char *key, const char *value)
 
1310
{
 
1311
  return ao_append_option(&ao_global_options,key,value);
 
1312
}
630
1313
 
631
1314
void ao_free_options(ao_option *options)
632
1315
{
642
1325
}
643
1326
 
644
1327
 
645
 
ao_device *ao_open_live (int driver_id, ao_sample_format *format, 
 
1328
ao_device *ao_open_live (int driver_id, ao_sample_format *format,
646
1329
                        ao_option *options)
647
1330
{
648
 
        return _open_device(driver_id, format, options, NULL);          
 
1331
        return _open_device(driver_id, format, options, NULL);
649
1332
}
650
1333
 
651
1334
 
652
 
ao_device *ao_open_file (int driver_id, const char *filename, int overwrite, 
 
1335
ao_device *ao_open_file (int driver_id, const char *filename, int overwrite,
653
1336
                         ao_sample_format *format, ao_option *options)
654
1337
{
655
1338
        FILE *file;
678
1361
                errno = AO_EOPENFILE;
679
1362
                return NULL;
680
1363
        }
681
 
                
 
1364
 
682
1365
        device = _open_device(driver_id, format, options, file);
683
 
        
 
1366
 
684
1367
        if (device == NULL) {
685
1368
                fclose(file);
686
1369
                /* errno already set by _open_device() */
698
1381
        if (device == NULL)
699
1382
          return 0;
700
1383
 
701
 
#if 1
702
1384
        if (device->swap_buffer != NULL) {
703
 
                if (_realloc_swap_buffer(device, num_bytes)) {
704
 
                        _swap_samples(device->swap_buffer, 
705
 
                                      output_samples, num_bytes);
706
 
                        playback_buffer = device->swap_buffer;
707
 
                } else
708
 
                        return 0; /* Could not expand swap buffer */
 
1385
          int out_bytes = num_bytes*device->output_channels/device->input_channels;
 
1386
          if (_realloc_swap_buffer(device, out_bytes)) {
 
1387
            int i;
 
1388
            int swap = (device->bytewidth>1 &&
 
1389
                        device->client_byte_format != device->driver_byte_format);
 
1390
            for(i=0;i<device->output_channels;i++){
 
1391
              int ic = device->inter_permute ? device->inter_permute[i] : i;
 
1392
              if(ic==-1){
 
1393
                _buffer_zero(device->swap_buffer,i,device->bytewidth,device->output_channels,
 
1394
                             out_bytes);
 
1395
              }else if(swap){
 
1396
                _buffer_permute_swap(device->swap_buffer,i,device->bytewidth,device->output_channels,
 
1397
                                     out_bytes, output_samples, ic, device->input_channels);
 
1398
              }else{
 
1399
                _buffer_permute(device->swap_buffer,i,device->bytewidth,device->output_channels,
 
1400
                                out_bytes, output_samples, ic, device->input_channels);
 
1401
              }
 
1402
            }
 
1403
            playback_buffer = device->swap_buffer;
 
1404
            num_bytes = out_bytes;
 
1405
          } else
 
1406
            return 0; /* Could not expand swap buffer */
709
1407
        } else
710
 
#endif
711
 
                playback_buffer = output_samples;
 
1408
          playback_buffer = output_samples;
712
1409
 
713
1410
        return device->funcs->play(device, playback_buffer, num_bytes);
714
1411
}
731
1428
 
732
1429
                if (device->swap_buffer != NULL)
733
1430
                        free(device->swap_buffer);
734
 
 
 
1431
                if (device->output_matrix != NULL)
 
1432
                        free(device->output_matrix);
 
1433
                if (device->input_map != NULL)
 
1434
                        free(device->input_map);
 
1435
                if (device->inter_matrix != NULL)
 
1436
                        free(device->inter_matrix);
 
1437
                if (device->inter_permute != NULL)
 
1438
                        free(device->inter_permute);
735
1439
                free(device);
736
1440
        }
737
1441
 
748
1452
 
749
1453
        i = 0;
750
1454
        while (driver) {
751
 
                if (strcmp(short_name, 
 
1455
                if (strcmp(short_name,
752
1456
                           driver->functions->driver_info()->short_name) == 0)
753
1457
                        return i;
754
1458
                driver = driver->next;
755
1459
                i++;
756
1460
        }
757
 
        
 
1461
 
758
1462
        return -1; /* No driver by that name */
759
1463
}
760
1464
 
762
1466
int ao_default_driver_id (void)
763
1467
{
764
1468
        /* Find the default driver in the list of loaded drivers */
765
 
  
 
1469
 
766
1470
        return _find_default_driver_id(config.default_driver);
767
1471
}
768
1472
 
788
1492
/* -- Miscellaneous -- */
789
1493
 
790
1494
/* Stolen from Vorbis' lib/vorbisfile.c */
791
 
int ao_is_big_endian(void) 
 
1495
int ao_is_big_endian(void)
792
1496
{
793
1497
        static uint_16 pattern = 0xbabe;
794
1498
        return 0[(volatile unsigned char *)&pattern] == 0xba;