Added named block and file insertion code to lexer/parser.
[ahxm.git] / output.c
blobff176dc3cd34091986d4e350371b7e376e25a9e3
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2004 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 <stdlib.h>
30 #include <string.h>
31 #include <math.h>
33 #include "core.h"
34 #include "output.h"
37 /*******************
38 Data
39 ********************/
41 /* master output volume */
42 float _master_volume=1.0;
44 /* output accounting */
45 int _output_frames=0;
46 int _output_clipped=0;
47 float _output_lowest=0;
48 float _output_highest=0;
50 /* optimal output volume */
51 float _optimal_volume;
54 /* the output drivers */
56 extern struct _output_driver _out_driver_oss;
57 extern struct _output_driver _out_driver_sgi;
58 extern struct _output_driver _out_driver_wav;
59 extern struct _output_driver _out_driver_raw;
60 extern struct _output_driver _out_driver_pipe;
61 extern struct _output_driver _out_driver_esd;
63 static struct _output_driver * _drivers[] = {
64 &_out_driver_oss,
65 &_out_driver_sgi,
66 &_out_driver_wav,
67 &_out_driver_raw,
68 &_out_driver_pipe,
69 &_out_driver_esd,
70 NULL
73 /* driver in use */
74 static struct _output_driver * drv=NULL;
76 /* buffer */
77 static short int * _out_buffer=NULL;
78 static int _out_buffer_size=0;
79 static int _out_buffer_index=0;
82 /*******************
83 Code
84 ********************/
86 /**
87 * output_open - Opens an output device.
88 * @name: name of the driver
89 * @filename: name of the file or device
91 * Opens an output device. @name contains the name of the driver
92 * (i.e. "raw" or "wav"), @filename contains the (optional) name
93 * of the output file or device (i.e. a filename for "raw" or
94 * "wav" or "/dev/dsp" for a direct audio device like "oss").
95 * @Name can be the special pseudo-driver "default"
96 * to select the most appropriate (usually a platform-specific
97 * direct output device, or "wav" if no one exists).
98 * @filename can also be NULL; in that case, a driver dependent,
99 * default value is used.
101 * The _n_channels global variable can be changed on output if
102 * the driver doesn't support so much channels.
104 * Returns a negative number in case of error, or zero otherwise.
106 int output_open(char * name, char * filename)
108 int n;
110 if(drv != NULL)
111 return(-1);
113 /* if driver name is 'default', open the first usable driver
114 (supposedly the best for the current platform) */
115 if(strcmp(name, "default") == 0)
117 for(n=0;;n++)
119 if(_drivers[n] == NULL)
120 return(-2);
122 if(_drivers[n]->open != NULL)
124 drv=_drivers[n];
125 break;
129 else
131 /* find by name */
132 for(n=0;;n++)
134 if(_drivers[n] == NULL)
135 return(-2);
137 if(strcmp(name, _drivers[n]->name) == 0 &&
138 _drivers[n]->open != NULL)
140 drv=_drivers[n];
141 break;
146 if(drv == NULL)
147 return(-2);
149 /* if filename is NULL, take the default one */
150 if(filename == NULL)
151 filename=drv->default_file;
153 /* open driver */
154 if((n = drv->open(filename)) < 0)
156 drv=NULL;
157 return(n);
160 /* if the driver requests a buffer, assign; otherwise,
161 alloc a minimal buffer to write a frame */
162 if(n)
163 _out_buffer_size=n;
164 else
165 _out_buffer_size=_n_channels;
167 /* free previously allocated buffer, in any */
168 if(_out_buffer != NULL)
169 free(_out_buffer);
171 /* alloc output buffer */
172 if((_out_buffer = (short *)
173 malloc(_out_buffer_size * sizeof(short int))) == NULL)
175 drv=NULL;
176 return(-3);
179 /* reset accounting */
180 _output_frames=_output_clipped=0;
181 _output_lowest=_output_highest=0.0;
183 _out_buffer_index=0;
185 return(0);
189 void output_init_frame(float samples[])
191 int n;
193 for(n=0;n < CHANNELS;n++)
194 samples[n] = 0.0;
199 * output_write - Outputs a frame of samples.
200 * @samples: the frame of samples
202 * Outputs a frame of samples. The output samples are
203 * intermixed if needed, have the master volume applied and trimmed
204 * before being sent to the output driver itself.
206 * If the maximum number of channels the output driver supports
207 * is lower than the global _n_channels, they are sequentially intermixed
208 * (for example, when outputting 4 channel data to a stereo device,
209 * 0 and 2 channels will go to left and 1 and 3 to right).
211 * Returns a negative value in case of error, or 0 otherwise.
213 int output_write(float samples[])
215 int n,clip,ret=0;
216 float s[CHANNELS];
218 /* clean samples first */
219 for(n=0;n < _n_channels;n++)
220 s[n]=0.0;
222 /* move samples, 'down-channeling' if needed */
223 for(n=0;n < CHANNELS;n++)
224 s[n % _n_channels] += samples[n];
226 /* final corrections */
227 for(n=clip=0;n < _n_channels;n++)
229 /* store the lowest and highest
230 amplitude seen before master volume */
231 if(s[n] < _output_lowest)
232 _output_lowest=s[n];
234 if(s[n] > _output_highest)
235 _output_highest=s[n];
237 /* apply master volume */
238 s[n] *= _master_volume;
240 /* clip samples to signed 16 bit boundaries */
241 if(s[n] < -32768)
243 s[n]=-32768;
244 clip++;
247 if(s[n] > 32767)
249 s[n]=32767;
250 clip++;
253 /* store in buffer */
254 _out_buffer[_out_buffer_index++]=(short int) s[n];
257 /* update accounting */
258 _output_frames++;
260 if(clip)
261 _output_clipped++;
263 /* really write if buffer full */
264 if(_out_buffer_index >= _out_buffer_size - _n_channels)
266 ret=drv->write(_out_buffer, _out_buffer_index);
267 _out_buffer_index=0;
270 return(ret);
275 * output_close - Closes the output device.
277 * Closes the output driver.
279 int output_close(void)
281 int r;
283 /* flush buffer */
284 if(_out_buffer_index)
285 drv->write(_out_buffer, _out_buffer_index);
287 r=drv->close();
288 drv=NULL;
290 /* calculate optimal master volume for
291 zero saturation */
292 _output_lowest=fabs(_output_lowest);
294 _optimal_volume = _output_lowest > _output_highest ?
295 32768.0 / _output_lowest :
296 32767.0 / _output_highest;
298 return(r);