1 /*
2 esd: audio output for ESounD (highly untested nowadays (?))
3
4 copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
5 see COPYING and AUTHORS files in distribution or http://mpg123.org
6 initially written by Eric B. Mitchell ("esd port" should be this file...)
7 */
8
9 /* First the common header, including config.h
10 ...this is important for stuff like _FILE_OFFSET_BITS */
11 #include "out123_int.h"
12
13 #include <esd.h>
14 #include <errno.h>
15 #include <assert.h>
16
17 #ifdef SOLARIS
18 #include <stropts.h>
19 #include <sys/conf.h>
20 #endif
21 #ifdef NETBSD
22 #include <sys/ioctl.h>
23 #include <sys/audioio.h>
24 #endif
25 #include "debug.h"
26
27 static unsigned esd_rate = 0, esd_format = 0, esd_channels = 0;
28
29
open_esound(out123_handle * ao)30 static int open_esound(out123_handle *ao)
31 {
32 esd_format_t format = ESD_STREAM | ESD_PLAY;
33
34 if (!esd_rate)
35 {
36 int esd;
37 esd_server_info_t *info;
38 esd_format_t fmt;
39
40 if ((esd = esd_open_sound(NULL)) >= 0)
41 {
42 info = esd_get_server_info(esd);
43 esd_rate = info->rate;
44 fmt = info->format;
45 esd_free_server_info(info);
46 esd_close(esd);
47 }
48 else
49 {
50 esd_rate = esd_audio_rate;
51 fmt = esd_audio_format;
52 }
53 esd_format = MPG123_ENC_UNSIGNED_8;
54
55 if ((fmt & ESD_MASK_BITS) == ESD_BITS16)
56 esd_format |= MPG123_ENC_SIGNED_16;
57 esd_channels = fmt & ESD_MASK_CHAN;
58 }
59
60 if (ao->format == -1)
61 ao->format = esd_format;
62 else if (!(ao->format & esd_format))
63 {
64 if(!AOQUIET)
65 error1("Unsupported audio format: %d\n", ao->format);
66 errno = EINVAL;
67 return -1;
68 }
69
70
71 if (ao->format & MPG123_ENC_SIGNED_16)
72 format |= ESD_BITS16;
73 else if (ao->format & MPG123_ENC_UNSIGNED_8)
74 format |= ESD_BITS8;
75 else assert(0);
76
77 if (ao->channels == -1) ao->channels = 2;
78 else if (ao->channels <= 0 || ao->channels > esd_channels)
79 {
80 if(!AOQUIET)
81 error1("Unsupported no of channels: %d\n", ao->channels);
82 errno = EINVAL;
83 return -1;
84 }
85 if (ao->channels == 1)
86 format |= ESD_MONO;
87 else if (ao->channels == 2)
88 format |= ESD_STEREO;
89 else assert(0);
90
91 if (ao->rate == -1) ao->rate = esd_rate;
92 else if (ao->rate > esd_rate)
93 return -1;
94
95 ao->fn = esd_play_stream_fallback(format, ao->rate, ao->device, "mpg123");
96 return (ao->fn);
97 }
98
get_formats_esound(out123_handle * ao)99 static int get_formats_esound (out123_handle *ao)
100 {
101 if (0 < ao->channels && ao->channels <= esd_channels
102 && 0 < ao->rate && ao->rate <= esd_rate)
103 {
104 return esd_format;
105 } else {
106 return -1;
107 }
108 }
109
write_esound(out123_handle * ao,unsigned char * buf,int len)110 static int write_esound(out123_handle *ao,unsigned char *buf,int len)
111 {
112 return write(ao->fn,buf,len);
113 }
114
close_esound(out123_handle * ao)115 static int close_esound(out123_handle *ao)
116 {
117 close (ao->fn);
118 return 0;
119 }
120
121 #ifdef SOLARIS
flush_esound(out123_handle * ao)122 static void flush_esound (out123_handle *ao)
123 {
124 ioctl (ao->fn, I_FLUSH, FLUSHRW);
125 }
126 #else
127 #ifdef NETBSD
flush_esound(out123_handle * ao)128 static void flush_esound (out123_handle *ao)
129 {
130 ioctl (ao->fn, AUDIO_FLUSH, 0);
131 }
132 #else
133 /* Dunno what to do on Linux and Cygwin, but the func must be at least defined! */
flush_esound(out123_handle * ao)134 static void flush_esound (out123_handle *ao)
135 {
136 }
137 #endif
138 #endif
139
140
init_esound(out123_handle * ao)141 static int init_esound(out123_handle* ao)
142 {
143 if (ao==NULL) return -1;
144
145 /* Set callbacks */
146 ao->open = open_esound;
147 ao->flush = flush_esound;
148 ao->write = write_esound;
149 ao->get_formats = get_formats_esound;
150 ao->close = close_esound;
151
152 /* Success */
153 return 0;
154 }
155
156
157
158 /*
159 Module information data structure
160 */
161 mpg123_module_t mpg123_output_module_info = {
162 /* api_version */ MPG123_MODULE_API_VERSION,
163 /* name */ "esd",
164 /* description */ "Output audio using ESounD (The Enlightened Sound Daemon).",
165 /* revision */ "$Rev: 3915 $",
166 /* handle */ NULL,
167
168 /* init_output */ init_esound,
169 };
170