8385ae8a86ef390a8943ca64cdf3445003e09fd4
3 * This file is part of DisOrder.
4 * Copyright (C) 2005 Richard Kettlewell
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
30 #include <ao/plugin.h>
32 /* extra declarations to help out lazy <ao/plugin.h> */
33 int ao_plugin_test(void);
34 ao_info
*ao_plugin_driver_info(void);
35 char *ao_plugin_file_extension(void);
37 /* private data structure for this driver */
39 int fd
; /* output file descriptor */
40 int exit_on_error
; /* exit on write error */
43 /* like write() but never returns EINTR/EAGAIN or short */
44 static int do_write(int fd
, const void *ptr
, size_t n
) {
49 memset(&ufd
, 0, sizeof ufd
);
53 ret
= write(fd
, (const char *)ptr
+ written
, n
- written
);
58 /* Someone sneakily gave us a nonblocking file descriptor, wait until
59 * we can write again */
60 ret
= poll(&ufd
, 1, -1);
61 if(ret
< 0 && errno
!= EINTR
) return -1;
72 /* return 1 if this driver can be opened */
73 int ao_plugin_test(void) {
77 /* return info about this driver */
78 ao_info
*ao_plugin_driver_info(void) {
79 static const char *options
[] = { "fd" };
80 static const ao_info info
= {
81 AO_TYPE_LIVE
, /* type */
82 (char *)"DisOrder format driver", /* name */
83 (char *)"disorder", /* short_name */
84 (char *)"http://www.greenend.org.uk/rjk/disorder/", /* comment */
85 (char *)"Richard Kettlewell", /* author */
86 AO_FMT_NATIVE
, /* preferred_byte_format */
88 (char **)options
, /* options */
91 return (ao_info
*)&info
;
94 /* initialize the private data structure */
95 int ao_plugin_device_init(ao_device
*device
) {
96 struct internal
*i
= malloc(sizeof (struct internal
));
100 memset(i
, 0, sizeof *i
);
101 if((e
= getenv("DISORDER_RAW_FD")))
105 device
->internal
= i
;
110 int ao_plugin_set_option(ao_device
*device
,
113 struct internal
*i
= device
->internal
;
115 if(!strcmp(key
, "fd"))
117 else if(!strcmp(key
, "fragile"))
118 i
->exit_on_error
= atoi(value
);
119 /* unknown options are required to be ignored */
123 /* open the device */
124 int ao_plugin_open(ao_device
*device
, ao_sample_format
*format
) {
125 struct internal
*i
= device
->internal
;
127 /* we would like native-order samples */
128 device
->driver_byte_format
= AO_FMT_NATIVE
;
129 if(do_write(i
->fd
, format
, sizeof *format
) < 0) {
130 if(i
->exit_on_error
) exit(-1);
136 /* play some samples */
137 int ao_plugin_play(ao_device
*device
, const char *output_samples
,
139 struct internal
*i
= device
->internal
;
141 if(do_write(i
->fd
, output_samples
, num_bytes
) < 0) {
142 if(i
->exit_on_error
) _exit(-1);
148 /* close the device */
149 int ao_plugin_close(ao_device
attribute((unused
)) *device
) {
153 /* delete private data structures */
154 void ao_plugin_device_clear(ao_device
*device
) {
155 free(device
->internal
);
156 device
->internal
= 0;
159 /* report preferred filename extension */
160 char *ao_plugin_file_extension(void) {
170 /* arch-tag:ru/Jqo0hseWMoSt/ba4Xlw */