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
41 /* master output volume */
42 float _master_volume
=1.0;
44 /* output accounting */
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
[] = {
74 static struct _output_driver
* drv
=NULL
;
77 static short int * _out_buffer
=NULL
;
78 static int _out_buffer_size
=0;
79 static int _out_buffer_index
=0;
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
)
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)
119 if(_drivers
[n
] == NULL
)
122 if(_drivers
[n
]->open
!= NULL
)
134 if(_drivers
[n
] == NULL
)
137 if(strcmp(name
, _drivers
[n
]->name
) == 0 &&
138 _drivers
[n
]->open
!= NULL
)
149 /* if filename is NULL, take the default one */
151 filename
=drv
->default_file
;
154 if((n
= drv
->open(filename
)) < 0)
160 /* if the driver requests a buffer, assign; otherwise,
161 alloc a minimal buffer to write a frame */
165 _out_buffer_size
=_n_channels
;
167 /* free previously allocated buffer, in any */
168 if(_out_buffer
!= NULL
)
171 /* alloc output buffer */
172 if((_out_buffer
= (short *)
173 malloc(_out_buffer_size
* sizeof(short int))) == NULL
)
179 /* reset accounting */
180 _output_frames
=_output_clipped
=0;
181 _output_lowest
=_output_highest
=0.0;
189 void output_init_frame(float samples
[])
193 for(n
=0;n
< CHANNELS
;n
++)
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
[])
218 /* clean samples first */
219 for(n
=0;n
< _n_channels
;n
++)
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
)
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 */
253 /* store in buffer */
254 _out_buffer
[_out_buffer_index
++]=(short int) s
[n
];
257 /* update accounting */
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
);
275 * output_close - Closes the output device.
277 * Closes the output driver.
279 int output_close(void)
284 if(_out_buffer_index
)
285 drv
->write(_out_buffer
, _out_buffer_index
);
290 /* calculate optimal master volume for
292 _output_lowest
=fabs(_output_lowest
);
294 _optimal_volume
= _output_lowest
> _output_highest
?
295 32768.0 / _output_lowest
:
296 32767.0 / _output_highest
;