1 /* Simple example of using SoX libraries
3 * Copyright (c) 2009 robs@users.sourceforge.net
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 * Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 /* Concatenate audio files. Note that the files must have the same number
24 * of channels and the same sample rate.
26 * Usage: example4 input-1 input-2 [... input-n] output
29 #define check(x) do if (!(x)) { \
30 fprintf(stderr, "check failed: %s\n", #x); goto error; } while (0)
32 int main(int argc
, char * argv
[])
34 sox_format_t
* output
= NULL
;
37 check(argc
>= 1 + 2 + 1); /* Need at least 2 input files + 1 output file. */
38 check(sox_init() == SOX_SUCCESS
);
40 /* Defer openning the output file as we want to set its characteristics
41 * based on those of the input files. */
43 for (i
= 1; i
< argc
- 1; ++i
) { /* For each input file... */
45 static sox_signalinfo_t signal
; /* static quashes `uninitialised' warning.*/
47 /* The (maximum) number of samples that we shall read/write at a time;
48 * chosen as a rough match to typical operating system I/O buffer size: */
49 #define MAX_SAMPLES (size_t)2048
50 sox_sample_t samples
[MAX_SAMPLES
]; /* Temporary store whilst copying. */
53 /* Open this input file: */
54 check(input
= sox_open_read(argv
[i
], NULL
, NULL
, NULL
));
56 if (i
== 1) { /* If this is the first input file... */
58 /* Open the output file using the same signal and encoding character-
59 * istics as the first input file. Note that here, input->signal.length
60 * will not be equal to the output file length so we are relying on
61 * libSoX to set the output length correctly (i.e. non-seekable output
62 * is not catered for); an alternative would be to first calculate the
63 * output length by summing the lengths of the input files and modifying
64 * the second parameter to sox_open_write accordingly. */
65 check(output
= sox_open_write(argv
[argc
- 1],
66 &input
->signal
, &input
->encoding
, NULL
, NULL
, NULL
));
68 /* Also, we'll store the signal characteristics of the first file
69 * so that we can check that these match those of the other inputs: */
70 signal
= input
->signal
;
72 else { /* Second or subsequent input file... */
74 /* Check that this input file's signal matches that of the first file: */
75 check(input
->signal
.channels
== signal
.channels
);
76 check(input
->signal
.rate
== signal
.rate
);
79 /* Copy all of the audio from this input file to the output file: */
80 while ((number_read
= sox_read(input
, samples
, MAX_SAMPLES
)))
81 check(sox_write(output
, samples
, number_read
) == number_read
);
83 check(sox_close(input
) == SOX_SUCCESS
); /* Finished with this input file.*/
86 check(sox_close(output
) == SOX_SUCCESS
); /* Finished with the output file. */
88 check(sox_quit() == SOX_SUCCESS
);
91 error
: /* Truncate output file on error: */
95 if ((f
= fopen(argv
[argc
- 1], "w"))) fclose(f
);