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
35 #include "ss_output.h"
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
;
58 usual channel mapping:
62 3 channel: left | right | center
63 quad: front left | front right | rear left | rear right
64 4 channel: left | center | right | surround
65 6 channel: left center | left | center | right center | right | surround
72 void * ss_outdev_open(char * drvname
, char * file
, int freq
, int n_channels
);
73 void ss_outdev_write(void * drv
, short int * frame
);
74 void ss_outdev_close(void * drv
);
77 * ss_output_open - Opens an output device.
78 * @name: name of the driver
79 * @filename: name of the file or device
81 * Opens an output device. @name contains the name of the driver
82 * (i.e. "raw" or "wav"), @filename contains the (optional) name
83 * of the output file or device (i.e. a filename for "raw" or
84 * "wav" or "/dev/dsp" for a direct audio device like "oss").
85 * @Name can be the special pseudo-driver "default"
86 * to select the most appropriate (usually a platform-specific
87 * direct output device, or "wav" if no one exists).
88 * @filename can also be NULL; in that case, a driver dependent,
89 * default value is used.
91 * The ss_nchannels global variable can be changed on output if
92 * the driver doesn't support so much channels.
94 * Returns a negative number in case of error, or zero otherwise.
96 int ss_output_open(char * drvname
, char * filename
)
98 if(strcmp(drvname
, "default") == 0)
101 /* reset accounting */
102 ss_output_frames
=ss_output_clipped
=0;
103 ss_output_lowest
=ss_output_highest
=0.0;
105 return((outdev
=ss_outdev_open(drvname
,
106 filename
, ss_frequency
, ss_nchannels
)) == NULL
);
110 void ss_output_init_frame(float samples
[])
114 for(n
=0;n
< SS_MAX_CHANNELS
;n
++)
120 * ss_output_write - Outputs a frame of samples.
121 * @samples: the frame of samples
123 * Outputs a frame of samples. The output samples are
124 * intermixed if needed, have the master volume applied and trimmed
125 * before being sent to the output driver itself.
127 * If the maximum number of channels the output driver supports
128 * is lower than the global ss_nchannels, they are sequentially intermixed
129 * (for example, when outputting 4 channel data to a stereo device,
130 * 0 and 2 channels will go to left and 1 and 3 to right).
132 * Returns a negative value in case of error, or 0 otherwise.
134 int ss_output_write(float samples
[])
138 short int is
[SS_MAX_CHANNELS
];
140 /* final corrections */
141 for(n
=clip
=0;n
< ss_nchannels
;n
++)
145 /* store the lowest and highest
146 amplitude seen before master volume */
147 if(s
< ss_output_lowest
)
150 if(s
> ss_output_highest
)
153 /* apply master volume */
154 s
*= ss_master_volume
;
156 /* clip samples to signed 16 bit boundaries */
169 /* store in buffer */
173 /* update accounting */
180 ss_outdev_write(outdev
, is
);
187 * ss_output_close - Closes the output device.
189 * Closes the output driver.
191 int ss_output_close(void)
195 ss_outdev_close(outdev
);
197 /* calculate optimal master volume for
199 ss_output_lowest
=fabs(ss_output_lowest
);
201 ss_optimal_volume
= ss_output_lowest
> ss_output_highest
?
202 32768.0 / ss_output_lowest
:
203 32767.0 / ss_output_highest
;