Mark compilation.
[ahxm.git] / output.c
blob8b6658f7669dc576c31e56d6fd23eca873b31ab2
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003 Angel Ortega <angel@triptico.com>
6 output.c - Output Interface
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 http://www.triptico.com
26 #include "config.h"
28 #include <stdio.h>
29 #include <string.h>
30 #include <math.h>
32 #include "core.h"
33 #include "output.h"
36 /*******************
37 Data
38 ********************/
40 /* master output volume */
41 float _master_volume=1.0;
43 /* output accounting */
44 int _output_frames=0;
45 int _output_clipped=0;
46 float _output_lowest=0;
47 float _output_highest=0;
49 /* optimal output volume */
50 float _optimal_volume;
53 /* the output drivers */
55 extern struct _output_driver _out_driver_oss;
56 extern struct _output_driver _out_driver_sgi;
57 extern struct _output_driver _out_driver_wav;
58 extern struct _output_driver _out_driver_raw;
59 extern struct _output_driver _out_driver_pipe;
60 extern struct _output_driver _out_driver_esd;
62 static struct _output_driver _out_driver_eof=
63 { NULL, NULL, NULL, NULL, NULL };
65 static struct _output_driver * _drivers[] = {
66 &_out_driver_oss,
67 &_out_driver_sgi,
68 &_out_driver_wav,
69 &_out_driver_raw,
70 &_out_driver_pipe,
71 &_out_driver_esd,
72 &_out_driver_eof
75 /* driver in use */
76 static struct _output_driver * drv=NULL;
79 /*******************
80 Code
81 ********************/
83 /**
84 * output_open - Opens an output device.
85 * @name: name of the driver
86 * @filename: name of the file or device
88 * Opens an output device. @name contains the name of the driver
89 * (i.e. "raw" or "wav"), @filename contains the (optional) name
90 * of the output file or device (i.e. a filename for "raw" or
91 * "wav" or "/dev/dsp" for a direct audio device like "oss").
92 * @Name can be the special pseudo-driver "default"
93 * to select the most appropriate (usually a platform-specific
94 * direct output device, or "wav" if no supported one exists).
95 * @filename can also be NULL; in that case, a driver dependent,
96 * default value is used.
98 * Returns the number of channels accepted by the output
99 * driver, than can be less than the global _n_channels (in that
100 * case, output will be intermixed).
102 int output_open(char * name, char * filename)
104 int n;
106 if(drv != NULL)
107 return(-1);
109 /* if driver name is 'default', open the first usable driver
110 (supposedly the best for the current platform) */
111 if(strcmp(name, "default") == 0)
113 for(n=0;;n++)
115 if(_drivers[n]->name == NULL)
116 return(-2);
118 if(_drivers[n]->open != NULL)
120 drv=_drivers[n];
121 break;
125 else
127 for(n=0;;n++)
129 if(_drivers[n]->name == NULL)
130 return(-2);
132 if(strcmp(name, _drivers[n]->name) == 0)
134 drv=_drivers[n];
135 break;
140 if(drv == NULL)
141 return(-2);
143 /* if filename is NULL, take the default one */
144 if(filename == NULL)
145 filename=drv->default_file;
147 /* the output driver must acknowledge the requested
148 number of channels or return the maximum supported */
149 _n_channels = drv->open(filename);
151 /* unassign driver if opening fails */
152 if(_n_channels <= 0)
153 drv=NULL;
155 /* reset accounting */
156 _output_frames=_output_clipped=0;
157 _output_lowest=_output_highest=0.0;
159 return(_n_channels);
163 void output_init_frame(float samples[])
165 int n;
167 for(n=0;n < CHANNELS;n++)
168 samples[n] = 0.0;
173 * output_write - Outputs a frame of samples.
174 * @samples: the frame of samples
176 * Outputs a frame of samples. The output samples are
177 * intermixed if needed, have the master volume applied and trimmed
178 * before being sent to the output driver itself.
180 * If the maximum number of channels the output driver supports
181 * is lower than the global _n_channels, they are sequentially intermixed
182 * (for example, when outputting 4 channel data to a stereo device,
183 * 0 and 2 channels will go to left and 1 and 3 to right).
185 * Returns a negative value in case of error, or 0 otherwise.
187 int output_write(float samples[])
189 int n,clip;
190 float s[CHANNELS];
192 /* clean samples first */
193 for(n=0;n < _n_channels;n++)
194 s[n]=0.0;
196 /* move samples, 'down-channeling' if needed */
197 for(n=0;n < CHANNELS;n++)
198 s[n % _n_channels] += samples[n];
200 /* final corrections */
201 for(n=clip=0;n < _n_channels;n++)
203 /* store the lowest and highest
204 amplitude seen before master volume */
205 if(s[n] < _output_lowest)
206 _output_lowest=s[n];
208 if(s[n] > _output_highest)
209 _output_highest=s[n];
211 /* apply master volume */
212 s[n] *= _master_volume;
214 /* clip samples to signed 16 bit boundaries */
215 if(s[n] < -32768)
217 s[n]=-32768;
218 clip++;
221 if(s[n] > 32767)
223 s[n]=32767;
224 clip++;
228 /* update accounting */
229 _output_frames++;
231 if(clip)
232 _output_clipped++;
234 return(drv->write(s));
239 * output_close - Closes the output device.
241 * Closes the output driver.
243 int output_close(void)
245 int r;
247 r=drv->close();
248 drv=NULL;
250 /* calculate optimal master volume for
251 zero saturation */
252 _output_lowest=fabs(_output_lowest);
254 _optimal_volume = _output_lowest > _output_highest ?
255 32768.0 / _output_lowest :
256 32767.0 / _output_highest;
258 return(r);