1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include <assert.h>
6 #include <ao/ao.h>
7
8 #include "uadeconstants.h"
9 #include "audio.h"
10 #include "uade123.h"
11
12 ao_sample_format format;
13
14 static ao_device *libao_device = NULL;
15
16 static ao_option *options = NULL;
17
audio_close(void)18 void audio_close(void)
19 {
20 if (libao_device) {
21
22 /* Work-around libao/alsa, sleep 10ms to drain audio stream. */
23 if (uade_output_file_name[0] == 0)
24 usleep(10000);
25
26 ao_close(libao_device);
27 }
28 }
29
process_config_options(const struct uade_config * uc)30 void process_config_options(const struct uade_config *uc)
31 {
32 char *s;
33 char *key;
34 char *value;
35
36 if (uc->buffer_time > 0) {
37 char val[32];
38 /* buffer_time is given in milliseconds, so convert to microseconds */
39 snprintf(val, sizeof val, "%d", 1000 * uc->buffer_time);
40 ao_append_option(&options, "buffer_time", val);
41 }
42
43 format.bits = UADE_BYTES_PER_SAMPLE * 8;
44 format.channels = UADE_CHANNELS;
45 format.rate = uc->frequency;
46 format.byte_format = AO_FMT_NATIVE;
47
48 s = (char *) uc->ao_options.o;
49 while (s != NULL && *s != 0) {
50 key = s;
51
52 s = strchr(s, '\n');
53 if (s == NULL)
54 break;
55 *s = 0;
56 s++;
57
58 value = strchr(key, ':');
59 if (value == NULL) {
60 fprintf(stderr, "uade: Invalid ao option: %s\n", key);
61 continue;
62 }
63 *value = 0;
64 value++;
65
66 ao_append_option(&options, key, value);
67 }
68 }
69
audio_init(const struct uade_config * uc)70 int audio_init(const struct uade_config *uc)
71 {
72 int driver;
73
74 if (uade_no_audio_output)
75 return 1;
76
77 process_config_options(uc);
78
79 ao_initialize();
80
81 if (uade_output_file_name[0]) {
82 driver = ao_driver_id(uade_output_file_format[0] ? uade_output_file_format : "wav");
83 if (driver < 0) {
84 fprintf(stderr, "Invalid libao driver\n");
85 return 0;
86 }
87 libao_device = ao_open_file(driver, uade_output_file_name, 1, &format, NULL);
88 } else {
89 driver = ao_default_driver_id();
90 libao_device = ao_open_live(driver, &format, options);
91 }
92
93 if (libao_device == NULL) {
94 fprintf(stderr, "Can not open ao device: %d\n", errno);
95 return 0;
96 }
97
98 return 1;
99 }
100
101
audio_play(unsigned char * samples,int bytes)102 int audio_play(unsigned char *samples, int bytes)
103 {
104 if (libao_device == NULL)
105 return bytes;
106
107 /* ao_play returns 0 on failure */
108 return ao_play(libao_device, (char *) samples, bytes);
109 }
110