3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2008 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
41 /* master output volume */
42 sample_t ss_master_volume
= 0.5;
44 /* output accounting */
45 int ss_output_clipped
= 0;
46 sample_t ss_max
= 0.0;
48 /* optimal output volume */
49 sample_t ss_optimal_volume
;
55 usual channel mapping:
59 3 channel: left | right | center
60 quad: front left | front right | rear left | rear right
61 4 channel: left | center | right | surround
62 6 channel: left center | left | center | right center | right | surround
63 home cinema 5.1: front l | center | front r | real l | rear r | subwoofer
65 Converting from wav to 5.1 ac3:
67 ffmpeg -ac 6 -ab 192 -ar 44100 -i input.wav output.ac3
70 /* a copy of the output file name */
71 static const char *ss_output_file_name
= NULL
;
73 /* cue file name and track */
74 const char *ss_cue_file_name
= NULL
;
75 static int ss_cue_file_track
= -1;
80 void *ss_outdev_open(const char *drvname
, const char *file
, int freq
,
82 void ss_outdev_write(void *drv
, short int *frame
);
83 void *ss_outdev_close(void *drv
);
86 static void close_on_signal(int sig_num
)
87 /* SIGINT (and other) signal handler */
89 /* close output device */
90 outdev
= ss_outdev_close(outdev
);
98 * ss_output_open - Opens an output device.
99 * @name: name of the driver
100 * @filename: name of the file or device
102 * Opens an output device. @name contains the name of the driver
103 * (i.e. "oss" or "wav"), @filename contains the (optional) name
104 * of the output file or device (i.e. a filename
105 * "wav" or "/dev/dsp" for a direct audio device like "oss").
106 * @Name can be the special pseudo-driver "default"
107 * to select the most appropriate (usually a platform-specific
108 * direct output device, or "wav" if no one exists).
109 * @filename can also be NULL; in that case, a driver dependent,
110 * default value is used.
112 * Returns zero if the output device was correctly open, or
115 int ss_output_open(const char *drvname
, const char *filename
)
117 if (strcmp(drvname
, "default") == 0)
120 /* reset accounting */
121 ss_output_clipped
= 0;
124 /* close the device on unexpected signals */
125 signal(SIGINT
, close_on_signal
);
127 /* store a copy of the filename */
128 ss_output_file_name
= filename
;
130 return (outdev
= ss_outdev_open(drvname
,
131 filename
, ss_frequency
,
132 ss_nchannels
)) == NULL
;
137 * ss_output_init_frame - Inits a frame
140 * Inits a frame, setting all samples to zero.
142 void ss_output_init_frame(sample_t frame
[])
144 memset(frame
, '\0', sizeof(sample_t
) * SS_MAX_CHANNELS
);
149 * ss_output_write - Outputs a frame of samples.
150 * @frame: the frame of samples
152 * Outputs a frame of samples. Applies master volume, tests for
153 * maximum amplitudes and clips all saturating ones.
155 * Returns a negative value in case of error, or 0 otherwise.
157 int ss_output_write(sample_t frame
[])
161 short int is
[SS_MAX_CHANNELS
];
163 /* final corrections */
164 for (n
= 0; n
< ss_nchannels
; n
++) {
167 /* test maximum amplitudes, apply master
168 volume and clipping */
172 s
*= ss_master_volume
;
181 s
*= ss_master_volume
;
188 /* convert to 16 bit signed */
191 /* store in buffer */
192 is
[n
] = (short int) s
;
196 ss_outdev_write(outdev
, is
);
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 outdev
= ss_outdev_close(outdev
);
215 /* calculate optimal master volume for zero saturation */
217 ss_optimal_volume
= 1 / ss_max
;
221 static int cue_file_init(void)
222 /* inits the cue file, writing the first line */
226 if (ss_output_file_name
== NULL
227 || (f
= fopen(ss_cue_file_name
, "wb")) == NULL
)
230 /* write first line */
231 fprintf(f
, "FILE \"%s\" WAVE\n", ss_output_file_name
);
234 ss_cue_file_track
= 0;
240 int cue_file_song_info(int frame
, const char *author
, const char *name
)
245 if (ss_cue_file_name
== NULL
)
248 /* init if it's the first time */
249 if (ss_cue_file_track
== -1) {
250 /* can't open? fail */
251 if (cue_file_init() < 0) {
252 ss_cue_file_name
= NULL
;
258 if ((f
= fopen(ss_cue_file_name
, "a")) == NULL
)
261 s
= frame
/ ss_frequency
;
263 fprintf(f
, "TRACK %02d AUDIO\n", ss_cue_file_track
++);
264 fprintf(f
, " PERFORMER \"%s\"\n", author
);
265 fprintf(f
, " TITLE \"%s\"\n", name
);
266 fprintf(f
, " INDEX 01 %02d:%02d:00\n", s
/ 60, s
% 60);