2 * Copyright 2006 Johannes Weißl
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 * <ao/ao.h> uses FILE but doesn't include stdio.h.
27 * Also we use snprintf().
32 static ao_device
*libao_device
;
33 static char *wav_dir
= NULL
;
34 static int wav_counter
= 1;
35 static int is_wav
= 0;
38 static char *libao_driver
= NULL
;
39 static int libao_buffer_space
= 8192;
42 static int op_ao_init(void)
44 /* ignore config value */
51 static int op_ao_exit(void)
58 static int op_ao_open(sample_format_t sf
)
60 ao_sample_format format
;
63 if (libao_driver
== NULL
) {
64 driver
= ao_default_driver_id();
66 driver
= ao_driver_id(libao_driver
);
67 is_wav
= strcasecmp(libao_driver
, "wav") == 0;
71 return -OP_ERROR_ERRNO
;
74 format
.bits
= sf_get_bits(sf
);
75 format
.rate
= sf_get_rate(sf
);
76 format
.channels
= sf_get_channels(sf
);
77 format
.byte_format
= sf_get_bigendian(sf
) ? AO_FMT_BIG
: AO_FMT_LITTLE
;
83 wav_dir
= xstrdup(home_dir
);
84 snprintf(file
, sizeof(file
), "%s/%02d.wav", wav_dir
, wav_counter
);
85 libao_device
= ao_open_file(driver
, file
, 0, &format
, NULL
);
87 libao_device
= ao_open_live(driver
, &format
, NULL
);
90 if (libao_device
== NULL
) {
97 return -OP_ERROR_ERRNO
;
100 return -OP_ERROR_ERRNO
;
103 return -OP_ERROR_ERRNO
;
106 return -OP_ERROR_ERRNO
;
109 return -OP_ERROR_INTERNAL
;
115 static int op_ao_close(void)
117 ao_close(libao_device
);
123 static int op_ao_write(const char *buffer
, int count
)
125 if (ao_play(libao_device
, (void *)buffer
, count
) == 0)
130 static int op_ao_buffer_space(void)
134 return libao_buffer_space
;
137 static int op_ao_set_option(int key
, const char *val
)
143 if (str_to_int(val
, &ival
) || ival
< 4096) {
145 return -OP_ERROR_ERRNO
;
147 libao_buffer_space
= ival
;
153 libao_driver
= xstrdup(val
);
156 if (str_to_int(val
, &ival
)) {
158 return -OP_ERROR_ERRNO
;
164 wav_dir
= xstrdup(val
);
167 return -OP_ERROR_NOT_OPTION
;
172 static int op_ao_get_option(int key
, char **val
)
176 *val
= xnew(char, 22);
177 snprintf(*val
, 22, "%d", libao_buffer_space
);
181 *val
= xstrdup(libao_driver
);
184 *val
= xnew(char, 22);
185 snprintf(*val
, 22, "%d", wav_counter
);
189 wav_dir
= xstrdup(home_dir
);
190 *val
= xstrdup(wav_dir
);
193 return -OP_ERROR_NOT_OPTION
;
198 const struct output_plugin_ops op_pcm_ops
= {
202 .close
= op_ao_close
,
203 .write
= op_ao_write
,
204 .buffer_space
= op_ao_buffer_space
,
205 .set_option
= op_ao_set_option
,
206 .get_option
= op_ao_get_option
209 const char * const op_pcm_options
[] = {
217 const int op_priority
= 3;