Finally, delete wav.c, as it's no longer needed. It has served us well
[ahxm.git] / ss_output.c
blob3d960cdb536f1324e53ab362ad76f0642fb8f3b5
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2005 Angel Ortega <angel@triptico.com>
6 ss_output.c - Softsynth 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 <unistd.h>
31 #include <string.h>
32 #include <math.h>
34 #include <signal.h>
36 #include "annhell.h"
38 /*******************
39 Data
40 ********************/
42 /* master output volume */
43 float ss_master_volume=0.5;
45 /* output accounting */
46 int ss_output_clipped=0;
47 float ss_output_lowest=0;
48 float ss_output_highest=0;
50 /* optimal output volume */
51 float ss_optimal_volume;
53 /* driver data */
54 static void * outdev;
57 usual channel mapping:
59 mono: all
60 stereo: left | right
61 3 channel: left | right | center
62 quad: front left | front right | rear left | rear right
63 4 channel: left | center | right | surround
64 6 channel: left center | left | center | right center | right | surround
67 /*******************
68 Code
69 ********************/
71 void * ss_outdev_open(char * drvname, char * file, int freq, int n_channels);
72 void ss_outdev_write(void * drv, short int * frame);
73 void ss_outdev_close(void * drv);
76 static void close_on_signal(int sig_num)
77 /* SIGINT (and other) signal handler */
79 /* close output device if still open */
80 if(outdev != NULL)
81 ss_outdev_close(outdev);
83 /* exit */
84 exit(0);
88 /**
89 * ss_output_open - Opens an output device.
90 * @name: name of the driver
91 * @filename: name of the file or device
93 * Opens an output device. @name contains the name of the driver
94 * (i.e. "oss" or "wav"), @filename contains the (optional) name
95 * of the output file or device (i.e. a filename
96 * "wav" or "/dev/dsp" for a direct audio device like "oss").
97 * @Name can be the special pseudo-driver "default"
98 * to select the most appropriate (usually a platform-specific
99 * direct output device, or "wav" if no one exists).
100 * @filename can also be NULL; in that case, a driver dependent,
101 * default value is used.
103 * Returns zero if the output device was correctly open, or
104 * nonzero otherwise.
106 int ss_output_open(char * drvname, char * filename)
108 if(strcmp(drvname, "default") == 0)
109 drvname=NULL;
111 /* reset accounting */
112 ss_output_clipped=0;
113 ss_output_lowest=ss_output_highest=0.0;
115 /* close the device on unexpected signals */
116 signal(SIGINT, close_on_signal);
118 return((outdev=ss_outdev_open(drvname,
119 filename, ss_frequency, ss_nchannels)) == NULL);
124 * ss_output_init_frame - Inits a frame
125 * @frame: the frame
127 * Inits a frame, setting all samples to zero.
129 void ss_output_init_frame(float frame[])
131 int n;
133 for(n=0;n < SS_MAX_CHANNELS;n++)
134 frame[n] = 0.0;
139 * ss_output_write - Outputs a frame of samples.
140 * @frame: the frame of samples
142 * Outputs a frame of samples. The output samples are
143 * intermixed if needed, have the master volume applied and trimmed
144 * before being sent to the output driver itself.
146 * If the maximum number of channels the output driver supports
147 * is lower than the global ss_nchannels, they are sequentially intermixed
148 * (for example, when outputting 4 channel data to a stereo device,
149 * 0 and 2 channels will go to left and 1 and 3 to right).
151 * Returns a negative value in case of error, or 0 otherwise.
153 int ss_output_write(float frame[])
155 int n, clip, ret=0;
156 float s;
157 short int is[SS_MAX_CHANNELS];
159 /* final corrections */
160 for(n=clip=0;n < ss_nchannels;n++)
162 s=frame[n];
164 /* store the lowest and highest
165 amplitude seen before master volume */
166 if(s < ss_output_lowest)
167 ss_output_lowest=s;
169 if(s > ss_output_highest)
170 ss_output_highest=s;
172 /* apply master volume */
173 s *= ss_master_volume;
175 /* clip samples to signed 16 bit boundaries */
176 if(s < -32768)
178 s=-32768;
179 clip++;
182 if(s > 32767)
184 s=32767;
185 clip++;
188 /* store in buffer */
189 is[n]=(short int) s;
192 if(clip)
193 ss_output_clipped++;
195 /* finally write */
196 ss_outdev_write(outdev, is);
198 return(ret);
203 * ss_output_close - Closes the output device.
205 * Closes the output driver.
207 void ss_output_close(void)
209 /* back to default signal behaviour */
210 signal(SIGINT, SIG_DFL);
212 /* close the device */
213 ss_outdev_close(outdev);
214 outdev=NULL;
216 /* calculate optimal master volume for
217 zero saturation */
218 ss_output_lowest=fabs(ss_output_lowest);
220 ss_optimal_volume = ss_output_lowest > ss_output_highest ?
221 32768.0 / ss_output_lowest :
222 32767.0 / ss_output_highest;