The output system has been adapted to the new ss_outdev architecture. The
[ahxm.git] / ss_output.c
blobb1ae9a60598b0b5f33db69a801db778ec78cfca9
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 "ss_core.h"
35 #include "ss_output.h"
38 /*******************
39 Data
40 ********************/
42 /* master output volume */
43 float ss_master_volume=1.0;
45 /* output accounting */
46 int ss_output_frames=0;
47 int ss_output_clipped=0;
48 float ss_output_lowest=0;
49 float ss_output_highest=0;
51 /* optimal output volume */
52 float ss_optimal_volume;
54 /* output filehandle */
55 static int ss_of;
57 /*******************
58 Code
59 ********************/
61 int ss_outdev(char * drv, char * file, int freq, int n_channels);
63 /**
64 * ss_output_open - Opens an output device.
65 * @name: name of the driver
66 * @filename: name of the file or device
68 * Opens an output device. @name contains the name of the driver
69 * (i.e. "raw" or "wav"), @filename contains the (optional) name
70 * of the output file or device (i.e. a filename for "raw" or
71 * "wav" or "/dev/dsp" for a direct audio device like "oss").
72 * @Name can be the special pseudo-driver "default"
73 * to select the most appropriate (usually a platform-specific
74 * direct output device, or "wav" if no one exists).
75 * @filename can also be NULL; in that case, a driver dependent,
76 * default value is used.
78 * The _n_channels global variable can be changed on output if
79 * the driver doesn't support so much channels.
81 * Returns a negative number in case of error, or zero otherwise.
83 int ss_output_open(char * drvname, char * filename)
85 if(strcmp(drvname, "default") == 0)
86 drvname=NULL;
88 /* reset accounting */
89 ss_output_frames=ss_output_clipped=0;
90 ss_output_lowest=ss_output_highest=0.0;
92 ss_of=ss_outdev(drvname, filename, ss_frequency, ss_nchannels);
94 return(0);
98 void ss_output_init_frame(float samples[])
100 int n;
102 for(n=0;n < SS_MAX_CHANNELS;n++)
103 samples[n] = 0.0;
108 * ss_output_write - Outputs a frame of samples.
109 * @samples: the frame of samples
111 * Outputs a frame of samples. The output samples are
112 * intermixed if needed, have the master volume applied and trimmed
113 * before being sent to the output driver itself.
115 * If the maximum number of channels the output driver supports
116 * is lower than the global _n_channels, they are sequentially intermixed
117 * (for example, when outputting 4 channel data to a stereo device,
118 * 0 and 2 channels will go to left and 1 and 3 to right).
120 * Returns a negative value in case of error, or 0 otherwise.
122 int ss_output_write(float samples[])
124 int n, clip, ret=0;
125 float s, fs[SS_MAX_CHANNELS];
126 short int is[SS_MAX_CHANNELS];
128 /* clean samples first */
129 for(n=0;n < ss_nchannels;n++)
130 fs[n]=0.0;
132 /* move samples, 'down-channeling' if needed */
133 for(n=0;n < SS_MAX_CHANNELS;n++)
134 fs[n % ss_nchannels] += samples[n];
136 /* final corrections */
137 for(n=clip=0;n < ss_nchannels;n++)
139 s=fs[n];
141 /* store the lowest and highest
142 amplitude seen before master volume */
143 if(s < ss_output_lowest)
144 ss_output_lowest=s;
146 if(s > ss_output_highest)
147 ss_output_highest=s;
149 /* apply master volume */
150 s *= ss_master_volume;
152 /* clip samples to signed 16 bit boundaries */
153 if(s < -32768)
155 s=-32768;
156 clip++;
159 if(s > 32767)
161 s=32767;
162 clip++;
165 /* store in buffer */
166 is[n]=(short int) s;
169 /* update accounting */
170 ss_output_frames++;
172 if(clip)
173 ss_output_clipped++;
175 /* finally write */
176 /* write(ss_of, is, ss_nchannels * sizeof(short int));*/
177 write(ss_of, is, 256);
179 return(ret);
184 * ss_output_close - Closes the output device.
186 * Closes the output driver.
188 int ss_output_close(void)
190 int r;
192 close(ss_of);
194 /* calculate optimal master volume for
195 zero saturation */
196 ss_output_lowest=fabs(ss_output_lowest);
198 ss_optimal_volume = ss_output_lowest > ss_output_highest ?
199 32768.0 / ss_output_lowest :
200 32767.0 / ss_output_highest;
202 return(r);