/*-------------- Telecommunications & Signal Processing Lab --------------- McGill University Routine: ConcatAudio [options] AFileA AfileB ... AFileO Purpose: Concatenate samples from audio files Description: This program copies input audio file(s) to an output audio file. The samples in the output file are the concatenation of the scaled samples from the individual input files, taken in the order in which they appear on the command line. The default data format for the output file is chosen according to a data format promotion rule based on the data types of the input files. For single input files, the output data format will be the same as the input data format as long as that data format is compatible with the output file type. Options: The command line specifies options and file names. The last file name is that of the output file. The other file names specify input files. -s SFREQ, --srate=SFREQ Sampling frequency for the output file, default from the input audio file(s). This option only changes the sampling frequency field in the output header; the audio data itself is unaffected. -D DFORMAT, --data_format=DFORMAT Data format for the output file. "mu-law8" - 8-bit mu-law data "A-law8" - 8-bit A-law data "unsigned8" - offset-binary 8-bit integer data "integer8" - two's-complement 8-bit integer data "integer16" - two's-complement 16-bit integer data "float32" - 32-bit IEEE floating-point data "text" - text data The data formats available depend on the output file type. AFsp (Sun) audio files: mu-law, A-law, 8-bit integer, 16-bit integer, float RIFF WAVE files: mu-law, A-law, offset-binary 8-bit integer, 16-bit integer AIFF-C audio files: mu-law, A-law, 8-bit integer, 16-bit integer Headerless files: all data formats -F FTYPE, --file_type=FTYPE File type, default "AFsp". "AFsp", "Sun" or "sun" - AFsp (Sun) audio file "WAVE" or "wave" - RIFF WAVE file "AIFF-C" - AIFF-C audio file "raw" or "raw_native" - Headerless file (native byte order) "raw_swap" - Headerless file (byte swapped) "raw_big-endian" - Headerless file (big-endian byte order) "raw_little-endian" - Headerless file (little-endian byte order) -g GAIN, --gain=GAIN A gain factor applied to all input samples. The default value is one. -P PARMS, --parameters=PARMS Parameters to be used for headerless input files. This option may be given more than once. Each invokation applies to the files that follow the option. See the description of the environment variable RAWAUDIOFILE below for the format of the parameter specification. -I INFO, --info=INFO Header information string. -h, --help Print a list of options and exit. -v, --version Print the version number and exit. For AFsp output files, the audio file header contains an information string. Standard Header Information: date:1994/01/25 19:19:39 UTC date user:kabal@aldebaran user program:ConcatAudio program name This information can be changed with the header information string which is specified as one of the command line options. Structured information records should adhere to the above format with a named field terminated by a colon, followed by numeric data or text. Comments can follow as unstructured information. For the purpose of this program, records are terminated by newline characters. However in the header itself, the newline characters are replaced by nulls. To place a newline character into the header, escape the newline character by preceding it with a '\' character. If the first character of the user supplied header information string is a newline character, the header information string is appended to the standard header information. If not, the user supplied header information string replaces the standard header information. Environment variables: RAWAUDIOFILE: This environment variable defines the data format for headerless or non-standard input audio files. The string consists of a list of parameters separated by commas. The form of the list is "Format, Start, Sfreq, Swapb, Nchan, ScaleF" Format: File data format The lowercase versions of these format specifiers cause a headerless file to be accepted only after checking for standard file headers; the uppercase versions cause a headerless file to be accepted without checking the file header. "undefined" - Headerless files will be rejected "mu-law8" or "MU-LAW8" - 8-bit mu-law data "A-law8" or "A-LAW8" - 8-bit A-law data "unsigned8" or "UNSIGNED8" - offset-binary 8-bit integer data "integer8" or "INTEGER8" - two's-complement 8-bit integer data "integer16" or "INTEGER16" - two's-complement 16-bit integer data "float32" or "FLOAT32" - 32-bit floating-point data "text" or "TEXT" - text data Start: byte offset to the start of data (integer value) Sfreq: sampling frequency in Hz (floating point number) Swapb: Data byte swap parameter "native" - no byte swapping "little-endian" - file data is in little-endian byte order "big-endian" - file data is in big-endian byte order "swap" - swap the data bytes as the data is read Nchan: number of channels The data consists of interleaved samples from Nchan channels ScaleF: Scale factor Scale factor applied to the data from the file The default values for the audio file parameters correspond to the following string. "undefined, 0, 8000., native, 1, 1.0" AUDIOPATH: This environment variable specifies a list of directories to be searched when opening the input audio files. Directories in the list are separated by colons (semicolons for MS-DOS). Author / version: P. Kabal / v1r3 1996/08/12 Copyright (C) 1996 -------------------------------------------------------------------------*/ static char rcsid[] = "$Id: ConcatAudio.c 1.11 1996/08/16 AFsp-V2R1 $"; #include #include #include #include #include "ConcatAudio.h" #include "AO.h" #ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 /* Normally in stdlib.h */ #endif #define ICEILV(n, m) (((n) + ((m) - 1)) / (m)) /* int n,m >= 0 */ int main (argc, argv) int argc; const char *argv[]; { int DformatI[MAXIFILE], Fformat; long int Lim[MAXIFILE][2]; const char *NHparms[MAXIFILE]; const char *Hinfo; int Nfiles, Nifiles; long int Nsamp, NchanI, Nchan; const char *Fname[MAXFILE]; const char *FnameO; char Fn[FILENAME_MAX+1]; AFILE *AFp[MAXIFILE], *AFpO; float Sfreq[MAXIFILE], SfreqO; int Sfdiff; float Sf; int i; float Gain; /* Get the input parameters */ CCoptions (argc, argv, &Fformat, &SfreqO, NHparms, &Hinfo, &Gain, Fname, &Nfiles); /* Open the input files */ Nifiles = Nfiles - 1; NchanI = 0; for (i = 0; i < Nifiles; ++i) { if (NHparms[i] != NULL) AFsetNH (NHparms[i]); else AFsetNH ("$RAWAUDIOFILE"); FLpathList (Fname[i], "$AUDIOPATH", Fn); AFp[i] = AFopenRead (Fn, &Nsamp, &Nchan, &Sfreq[i], stdout); if (NchanI != 0 && NchanI != Nchan) UThalt ("%s: Different numbers of input channels", PROGRAM); NchanI = Nchan; Lim[i][0] = 0L; Lim[i][1] = Nchan * ICEILV (Nsamp, Nchan) - 1; DformatI[i] = AFp[i]->Format; } printf ("\n"); /* Sampling frequency */ Sfdiff = 0; Sf = Sfreq[0]; for (i = 1; i < Nifiles; ++i) { if (Sfreq[i] != Sfreq[i-1]) Sfdiff = 1; Sf = Sf + Sfreq[i]; } if (Sfdiff) UTwarn ("%s - Input sampling frequencies differ", PROGRAM); Sf = Sf / Nifiles; if (SfreqO == 0.0) SfreqO = Sf; /* Open the output file */ if (Hinfo != NULL) AFsetHinfo (Hinfo); FnameO = Fname[Nfiles-1]; FLbackup (FnameO); Fformat = AOsetDFormat (Fformat, DformatI, Nifiles); AFpO = AFopenWrite (FnameO, Fformat, Nchan, (double) SfreqO, stdout); /* Concatenate the samples from the input files */ for (i = 0; i < Nifiles; ++i) { CCcopySamp (AFp[i], Lim[i], Gain, AFpO); AFclose (AFp[i]); } AFclose (AFpO); return EXIT_SUCCESS; }