1 /* Sysdep esound sound dsp driver
2
3 Copyright 2000 Hans de Goede
4
5 This file and the acompanying files in this directory are free software;
6 you can redistribute them and/or modify them under the terms of the GNU
7 Library General Public License as published by the Free Software Foundation;
8 either version 2 of the License, or (at your option) any later version.
9
10 These files are distributed in the hope that they will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with these files; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20 /* Changelog
21 Version 0.1, January 2000
22 -initial release, based on the driver submitted by riq <riq@ciudad.com.ar>,
23 amongst others (Hans de Goede)
24 */
25 #ifdef SYSDEP_DSP_ESOUND
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <sys/ioctl.h>
30 #include <esd.h>
31 #include "sysdep/sysdep_dsp.h"
32 #include "sysdep/sysdep_dsp_priv.h"
33 #include "sysdep/plugin_manager.h"
34
35 /* #define ESOUND_DEBUG */
36
37 /* our per instance private data struct */
38 struct esound_dsp_priv_data {
39 int fd;
40 };
41
42 /* public methods prototypes (static but exported through the sysdep_dsp or
43 plugin struct) */
44 static void *esound_dsp_create(const void *flags);
45 static void esound_dsp_destroy(struct sysdep_dsp_struct *dsp);
46 static int esound_dsp_write(struct sysdep_dsp_struct *dsp, unsigned char *data,
47 int count);
48
49 /* public variables */
50 const struct plugin_struct sysdep_dsp_esound = {
51 "esound",
52 "sysdep_dsp",
53 "Esound DSP plugin",
54 NULL, /* no options */
55 NULL, /* no init */
56 NULL, /* no exit */
57 esound_dsp_create,
58 2 /* lower priority as direct device access */
59 };
60
61 /* private variables */
62 static int esound_dsp_bytes_per_sample[4] = SYSDEP_DSP_BYTES_PER_SAMPLE;
63
64 /* public methods (static but exported through the sysdep_dsp or plugin
65 struct) */
esound_dsp_create(const void * flags)66 static void *esound_dsp_create(const void *flags)
67 {
68 #ifdef ESOUND_DEBUG
69 int server_fd;
70 esd_server_info_t *info = NULL;
71 #endif
72 struct esound_dsp_priv_data *priv = NULL;
73 struct sysdep_dsp_struct *dsp = NULL;
74 const struct sysdep_dsp_create_params *params = flags;
75 esd_format_t esd_format;
76
77 /* allocate the dsp struct */
78 if (!(dsp = calloc(1, sizeof(struct sysdep_dsp_struct))))
79 {
80 fprintf(stderr,
81 "error malloc failed for struct sysdep_dsp_struct\n");
82 return NULL;
83 }
84
85 /* alloc private data */
86 if(!(priv = calloc(1, sizeof(struct esound_dsp_priv_data))))
87 {
88 fprintf(stderr,
89 "error malloc failed for struct esound_dsp_priv_data\n");
90 esound_dsp_destroy(dsp);
91 return NULL;
92 }
93
94 /* fill in the functions and some data */
95 priv->fd = -1;
96 dsp->_priv = priv;
97 dsp->write = esound_dsp_write;
98 dsp->destroy = esound_dsp_destroy;
99 dsp->hw_info.type = params->type;
100 dsp->hw_info.samplerate = params->samplerate;
101
102 /* open the sound device */
103 esd_format = ESD_STREAM | ESD_PLAY ;
104 esd_format |= (dsp->hw_info.type & SYSDEP_DSP_16BIT)?
105 ESD_BITS16 : ESD_BITS8;
106 esd_format |= (dsp->hw_info.type & SYSDEP_DSP_STEREO)?
107 ESD_STEREO : ESD_MONO;
108
109 #ifdef ESOUND_DEBUG
110 if((server_fd = esd_open_sound(params->device)) < 0)
111 {
112 fprintf(stderr, "error: esound server open failed\n");
113 esound_dsp_destroy(dsp);
114 return NULL;
115 }
116
117 if(!(info = esd_get_server_info(server_fd)))
118 {
119 fprintf(stderr, "error: esound get server info failed\n");
120 esd_close(server_fd);
121 esound_dsp_destroy(dsp);
122 return NULL;
123 }
124
125 esd_print_server_info(info);
126 esd_free_server_info(info);
127 esd_close(server_fd);
128 #endif
129
130 if((priv->fd = esd_play_stream(esd_format, dsp->hw_info.samplerate,
131 params->device, "mame esound")) < 0)
132 {
133 fprintf(stderr, "error: esound open stream failed\n");
134 esound_dsp_destroy(dsp);
135 return NULL;
136 }
137
138 /* set non-blocking mode if selected */
139 if(params->flags & SYSDEP_DSP_O_NONBLOCK)
140 {
141 long flags = fcntl(priv->fd, F_GETFL);
142 if((flags < 0) || (fcntl(priv->fd, F_SETFL, flags|O_NONBLOCK) < 0))
143 {
144 perror("Esound-driver, error: fnctl");
145 esound_dsp_destroy(dsp);
146 return NULL;
147 }
148 }
149
150 return dsp;
151 }
152
esound_dsp_destroy(struct sysdep_dsp_struct * dsp)153 static void esound_dsp_destroy(struct sysdep_dsp_struct *dsp)
154 {
155 struct esound_dsp_priv_data *priv = dsp->_priv;
156
157 if(priv)
158 {
159 if(priv->fd >= 0)
160 close(priv->fd);
161
162 free(priv);
163 }
164 free(dsp);
165 }
166
esound_dsp_write(struct sysdep_dsp_struct * dsp,unsigned char * data,int count)167 static int esound_dsp_write(struct sysdep_dsp_struct *dsp, unsigned char *data,
168 int count)
169 {
170 int result;
171 struct esound_dsp_priv_data *priv = dsp->_priv;
172
173 result = write(priv->fd, data, count *
174 esound_dsp_bytes_per_sample[dsp->hw_info.type]);
175
176 if (result < 0)
177 {
178 fprintf(stderr, "error: esound write to stream failed\n");
179 return -1;
180 }
181
182 return result / esound_dsp_bytes_per_sample[dsp->hw_info.type];
183 }
184
185 #endif /* ifdef SYSDEP_DSP_ESOUND */
186