Fix Lancer-patched libvorbis-aoTuV so it builds with GCC.
[vorbis-lancer-gcc.git] / vorbis-tools-1.2.0 / ogg123 / callbacks.c
blob4dc3276c5d855fd6115aee7d4180835bdab66d20
1 /********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE Ogg123 SOURCE CODE IS (C) COPYRIGHT 2000-2001 *
9 * by Stan Seibert <volsung@xiph.org> AND OTHER CONTRIBUTORS *
10 * http://www.xiph.org/ *
11 * *
12 ********************************************************************
14 last mod: $Id: callbacks.c,v 1.9 2003/09/05 19:25:30 volsung Exp $
16 ********************************************************************/
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
22 #include <stdio.h>
23 #include <string.h>
25 #include "callbacks.h"
26 #include "i18n.h"
28 #define WARNING_VERBOSITY 2
29 #define INFO_VERBOSITY 3
31 /* Audio callbacks */
33 int audio_play_callback (void *ptr, int nbytes, int eos, void *arg)
35 audio_play_arg_t *play_arg = (audio_play_arg_t *) arg;
36 int ret;
38 ret = audio_devices_write(play_arg->devices, ptr, nbytes);
40 return ret ? nbytes : 0;
43 void audio_reopen_action (buf_t *buf, void *arg)
45 audio_reopen_arg_t *reopen_arg = (audio_reopen_arg_t *) arg;
46 audio_device_t *current;
47 ao_sample_format format;
49 close_audio_devices (reopen_arg->devices);
51 /* Record audio device settings and open the devices */
52 format.rate = reopen_arg->format->rate;
53 format.channels = reopen_arg->format->channels;
54 format.bits = reopen_arg->format->word_size * 8;
55 format.byte_format = reopen_arg->format->big_endian ?
56 AO_FMT_BIG : AO_FMT_LITTLE;
58 current = reopen_arg->devices;
60 while (current != NULL) {
61 ao_info *info = ao_driver_info(current->driver_id);
63 if (current->filename == NULL)
64 current->device = ao_open_live(current->driver_id, &format,
65 current->options);
66 else
67 current->device = ao_open_file(current->driver_id, current->filename,
68 1 /*overwrite*/, &format,
69 current->options);
71 /* Report errors */
72 if (current->device == NULL) {
73 switch (errno) {
74 case AO_ENODRIVER:
75 status_error(_("Error: Device not available.\n"));
76 break;
77 case AO_ENOTLIVE:
78 status_error(_("Error: %s requires an output filename to be specified with -f.\n"), info->short_name);
79 break;
80 case AO_EBADOPTION:
81 status_error(_("Error: Unsupported option value to %s device.\n"),
82 info->short_name);
83 break;
84 case AO_EOPENDEVICE:
85 status_error(_("Error: Cannot open device %s.\n"),
86 info->short_name);
87 break;
88 case AO_EFAIL:
89 status_error(_("Error: Device %s failure.\n"), info->short_name);
90 break;
91 case AO_ENOTFILE:
92 status_error(_("Error: An output file cannot be given for %s device.\n"), info->short_name);
93 break;
94 case AO_EOPENFILE:
95 status_error(_("Error: Cannot open file %s for writing.\n"),
96 current->filename);
97 break;
98 case AO_EFILEEXISTS:
99 status_error(_("Error: File %s already exists.\n"), current->filename);
100 break;
101 default:
102 status_error(_("Error: This error should never happen (%d). Panic!\n"), errno);
103 break;
106 /* We cannot recover from any of these errors */
107 exit(1);
110 current = current->next_device;
113 /* Cleanup argument */
114 free(reopen_arg->format);
115 free(reopen_arg);
119 audio_reopen_arg_t *new_audio_reopen_arg (audio_device_t *devices,
120 audio_format_t *fmt)
122 audio_reopen_arg_t *arg;
124 if ( (arg = malloc(sizeof(audio_reopen_arg_t))) == NULL ) {
125 status_error(_("Error: Out of memory in new_audio_reopen_arg().\n"));
126 exit(1);
129 if ( (arg->format = malloc(sizeof(audio_format_t))) == NULL ) {
130 status_error(_("Error: Out of memory in new_audio_reopen_arg().\n"));
131 exit(1);
134 arg->devices = devices;
135 /* Copy format in case fmt is recycled later */
136 *arg->format = *fmt;
138 return arg;
142 /* Statistics callbacks */
144 void print_statistics_action (buf_t *buf, void *arg)
146 print_statistics_arg_t *stats_arg = (print_statistics_arg_t *) arg;
147 buffer_stats_t *buffer_stats;
149 if (buf != NULL)
150 buffer_stats = buffer_statistics(buf);
151 else
152 buffer_stats = NULL;
154 status_print_statistics(stats_arg->stat_format,
155 buffer_stats,
156 stats_arg->data_source_statistics,
157 stats_arg->decoder_statistics);
159 free(stats_arg->data_source_statistics);
160 free(stats_arg->decoder_statistics);
161 free(stats_arg);
162 free(buffer_stats);
166 print_statistics_arg_t *new_print_statistics_arg (
167 stat_format_t *stat_format,
168 data_source_stats_t *data_source_statistics,
169 decoder_stats_t *decoder_statistics)
171 print_statistics_arg_t *arg;
173 if ( (arg = malloc(sizeof(print_statistics_arg_t))) == NULL ) {
174 status_error(_("Error: Out of memory in new_print_statistics_arg().\n"));
175 exit(1);
178 arg->stat_format = stat_format;
179 arg->data_source_statistics = data_source_statistics;
180 arg->decoder_statistics = decoder_statistics;
182 return arg;
186 /* Decoder callbacks */
188 void decoder_error_callback (void *arg, int severity, char *message, ...)
190 va_list ap;
192 va_start(ap, message);
193 switch (severity) {
194 case ERROR:
195 vstatus_error(message, ap);
196 break;
197 case WARNING:
198 vstatus_message(WARNING_VERBOSITY, message, ap);
199 break;
200 case INFO:
201 vstatus_message(INFO_VERBOSITY, message, ap);
202 break;
204 va_end(ap);
208 void decoder_metadata_callback (void *arg, int verbosity, char *message, ...)
210 va_list ap;
212 va_start(ap, message);
213 vstatus_message(verbosity, message, ap);
214 va_end(ap);
218 /* ---------------------------------------------------------------------- */
220 /* These actions are just wrappers for vstatus_message() and vstatus_error() */
222 typedef struct status_message_arg_t {
223 int verbosity;
224 char *message;
225 } status_message_arg_t;
228 status_message_arg_t *new_status_message_arg (int verbosity)
230 status_message_arg_t *arg;
232 if ( (arg = malloc(sizeof(status_message_arg_t))) == NULL ) {
233 status_error(_("Error: Out of memory in new_status_message_arg().\n"));
234 exit(1);
237 arg->verbosity = verbosity;
239 return arg;
243 void status_error_action (buf_t *buf, void *arg)
245 status_message_arg_t *myarg = (status_message_arg_t *) arg;
247 status_error("%s", myarg->message);
249 free(myarg->message);
250 free(myarg);
254 void status_message_action (buf_t *buf, void *arg)
256 status_message_arg_t *myarg = (status_message_arg_t *) arg;
258 status_message(myarg->verbosity, "%s", myarg->message);
260 free(myarg->message);
261 free(myarg);
264 /* -------------------------------------------------------------- */
266 void decoder_buffered_error_callback (void *arg, int severity,
267 char *message, ...)
269 va_list ap;
270 buf_t *buf = (buf_t *)arg;
271 status_message_arg_t *sm_arg = new_status_message_arg(0);
272 int n, size = 80; /* Guess we need no more than 80 bytes. */
275 /* Preformat the string and allocate space for it. This code taken
276 straight from the vsnprintf() man page. We do this here because
277 we might need to reinit ap several times. */
278 if ((sm_arg->message = malloc (size)) == NULL) {
279 status_error(_("Error: Out of memory in decoder_buffered_metadata_callback().\n"));
280 exit(1);
283 while (1) {
284 /* Try to print in the allocated space. */
285 va_start(ap, message);
286 n = vsnprintf (sm_arg->message, size, message, ap);
287 va_end(ap);
289 /* If that worked, return the string. */
290 if (n > -1 && n < size)
291 break;
292 /* Else try again with more space. */
293 if (n > -1) /* glibc 2.1 */
294 size = n+1; /* precisely what is needed */
295 else /* glibc 2.0 */
296 size *= 2; /* twice the old size */
297 if ((sm_arg->message = realloc (sm_arg->message, size)) == NULL) {
298 status_error(_("Error: Out of memory in decoder_buffered_metadata_callback().\n"));
299 exit(1);
304 switch (severity) {
305 case ERROR:
306 buffer_append_action_at_end(buf, &status_error_action, sm_arg);
307 break;
308 case WARNING:
309 sm_arg->verbosity = WARNING_VERBOSITY;
310 buffer_append_action_at_end(buf, &status_message_action, sm_arg);
311 break;
312 case INFO:
313 sm_arg->verbosity = INFO_VERBOSITY;
314 buffer_append_action_at_end(buf, &status_message_action, sm_arg);
315 break;
322 void decoder_buffered_metadata_callback (void *arg, int verbosity,
323 char *message, ...)
325 va_list ap;
326 buf_t *buf = (buf_t *)arg;
327 status_message_arg_t *sm_arg = new_status_message_arg(0);
328 int n, size = 80; /* Guess we need no more than 80 bytes. */
331 /* Preformat the string and allocate space for it. This code taken
332 straight from the vsnprintf() man page. We do this here because
333 we might need to reinit ap several times. */
334 if ((sm_arg->message = malloc (size)) == NULL) {
335 status_error(_("Error: Out of memory in decoder_buffered_metadata_callback().\n"));
336 exit(1);
339 while (1) {
340 /* Try to print in the allocated space. */
341 va_start(ap, message);
342 n = vsnprintf (sm_arg->message, size, message, ap);
343 va_end(ap);
345 /* If that worked, return the string. */
346 if (n > -1 && n < size)
347 break;
348 /* Else try again with more space. */
349 if (n > -1) /* glibc 2.1 */
350 size = n+1; /* precisely what is needed */
351 else /* glibc 2.0 */
352 size *= 2; /* twice the old size */
353 if ((sm_arg->message = realloc (sm_arg->message, size)) == NULL) {
354 status_error(_("Error: Out of memory in decoder_buffered_metadata_callback().\n"));
355 exit(1);
359 sm_arg->verbosity = verbosity;
360 buffer_append_action_at_end(buf, &status_message_action, sm_arg);