/*************************************************************
 * writeAUHeader
 *------------------------------------------------------------
 * The folloing documentation about the AU header format has been
 * copied verbatim from www.wotsit.org (no copyright statement):
-------
 * [ From: [email protected] (Marshall Rose) ]
 * 
 * Audio data is encoded in three parts: a header, containing fields that
 * describe the audio encoding format; a variable-length information field,
 * in which, for instance, ASCII annotation may be stored; and, the actual
 * encoded audio.  The header and data fields are written using big-endian
 * ordering.
 * 
 * The header part consists of six 32-bit quantities, in this order:
 * 
 * longword	field		description
 * --------	-----		-----------
 *  0		magic number	the value 0x2e736e64 (ASCII ".snd")
 * 
 *  1		data offset	the offset, in octets, to the data part.
 * 				The minimum valid number is 24 (decimal).
 * 
 *  2		data size	the size in octets, of the data part.
 * 				If unknown, the value 0xffffffff should
 * 				be used.
 * 
 *  3		encoding	the data encoding format:
 * 				    value	format
 * 				      1		8-bit ISDN u-law
 * 				      2		8-bit linear PCM [REF-PCM]
 * 				      3		16-bit linear PCM
 * 				      4		24-bit linear PCM
 * 				      5		32-bit linear PCM
 * 				      6		32-bit IEEE floating point
 * 				      7		64-bit IEEE floating point
 * 				     23		8-bit ISDN u-law compressed
 * 						using the CCITT G.721 ADPCM
 * 						voice data encoding scheme.
 * 
 *  4		sample rate	the number of samples/second (e.g., 8000)
 * 
 *  5		channels	the number of interleaved channels (e.g., 1)
 * 
 * The information part, consists of 0 or more octets, and starts 24 octets
 * after the beginning of the header part. The length of the information
 * part is calculated by subtracting 24 (decimal) from the data offset
 * field in the header part.
 * --
 *  Bill Janssen      [email protected]      (415) 812-4763
 *  Xerox Palo Alto Research Center      FAX: (415) 812-4777
 *  3333 Coyote Hill Road, Palo Alto, California   94304
-----
 * The following approach was written by Dave Graff for the LDC
 */
void writeAUHeader( void )
{
    char *ordr = "10";  /* AU files use high-byte first */
    int dsize, nchan, enc;

    nchan = ( chanout < chancount ) ?  1 : chancount;
    hdrsize = 24;
    dsize = sampcount * nchan * sizeout;
    enc = ( sizeout == 1 ) ?  1 : 3;  /* either 8-bit u-law or 16-bit PCM */
    copycharr( ".snd", &hdr[0], 4 );
    copylong( hdrsize, &hdr[4], ordr );
    copylong( dsize, &hdr[8], ordr );
    copylong( enc, &hdr[12], ordr );
    copylong( samprate, &hdr[16], ordr );
    copylong( nchan, &hdr[20], ordr );

    if ( fwrite( hdr, 1, hdrsize, fpout ) != hdrsize ) {
	fprintf( stderr, "Failed to write AU header to %s\n", outname );
	exit(1);
    }
}
/*************************************************************
 * writeRIFFHeader
 *------------------------------------------------------------
 * The following documentation about the RIFF header format has been
 * copied verbatim from "wav.c" in sox-12.17; the copyright notice
 * contained in that source file is included, and applies to the
 * following commentary:

----- excerpt from sox-12.17/wav.c 
----- (available from http://home.sprynet.com/~cbagwell/sox.html)

 * Microsoft's WAVE sound format driver
 *
 * This source code is freely redistributable and may be used for
 * any purpose.  This copyright notice must be maintained. 
 * Lance Norskog And Sundry Contributors are not responsible for 
 * the consequences of using this software.
 *
 * ... [See note below.  -- DG/LDC]
 *
 * NOTE: Previous maintainers weren't very good at providing contact
 * information.
 *
 * Copyright 1992 Rick Richardson
 * Copyright 1991 Lance Norskog And Sundry Contributors
 *
 * ...
 *
 * Info for format tags can be found at:
 *   http://www.microsoft.com/asf/resources/draft-ietf-fleischman-codec-subtree-01.txt

... write .wav headers as follows:
 
bytes      variable      description
0  - 3     'RIFF'
4  - 7     wRiffLength   length of file minus the 8 byte riff header
8  - 11    'WAVE'
12 - 15    'fmt '
16 - 19    wFmtSize       length of format chunk minus 8 byte header 
20 - 21    wFormatTag     identifies PCM, ULAW, ALAW etc
22 - 23    wChannels      
24 - 27    wSamplesPerSecond   samples per second per channel
28 - 31    wAvgBytesPerSec     non-trivial for compressed formats
32 - 33    wBlockAlign         basic block size
34 - 35    wBitsPerSample      non-trivial for compressed formats

PCM formats then go straight to the data chunk:
36 - 39    'data'
40 - 43     wDataLength   length of data chunk minus 8 byte header
44 - (wDataLength + 43)    the data

non-PCM formats must write an extended format chunk and a fact chunk:

ULAW, ALAW formats:
36 - 37    wExtSize = 0  the length of the format extension
38 - 41    'fact'
42 - 45    wFactSize = 4  length of the fact chunk minus 8 byte header
46 - 49    wSamplesWritten   actual number of samples written out
50 - 53    'data'
54 - 57     wDataLength   length of data chunk minus 8 byte header
58 - (wDataLength + 57)    the data

...
----- end of excerpt

 * Note: The source code change history (and source code) was omitted;
 * Stan Brooks ([email protected]) and Chris Bagwell
 * ([email protected]) authored several recent improvements
 * to wav.c, including the documentation quoted above.
 *
 * The following approach, written by David Graff for the LDC,
 * supports output to stdout (this was not supported in sox-12.17,
 * probably because sox included support for various RIFF-based
 * forms of compression, which are not supported here).
 */
void writeRIFFHeader( void )
{
    char *ordr = "01";		/* RIFF header wants ints with low-byte first */
    int fsize, hsize, hoffs;
    short int nbyts, nchan, fmtyp;
  
    nchan = ( chanout < chancount ) ?  1 : chancount;
    nbyts = nchan * sizeout;
    fsize = sampcount * nbyts;
    if ( sizeout == 1 ) {  /* applies to ALAW and ULAW */
	hoffs = 18;
	hsize = 50;
	fmtyp = ( typeout == ALAW ) ?  0x0006 : 0x0007;
    } else {
	hoffs = 16;
	hsize = 36;
	fmtyp = 0x0001;
    }
    copycharr( "RIFF", &hdr[0], 4 );
    copylong( fsize + hsize, &hdr[4], ordr );
    copycharr( "WAVE", &hdr[8], 4 );
    copycharr( "fmt ", &hdr[12], 4 );
    copylong( hoffs, &hdr[16], ordr );
    copyshort( fmtyp, &hdr[20], ordr );
    copyshort( nchan, &hdr[22], ordr );
    copylong( samprate, &hdr[24], ordr );
    copylong( nbyts * samprate, &hdr[28], ordr );
    copyshort( nbyts, &hdr[32], ordr );
    copyshort( sizeout * 8, &hdr[34], ordr );
    if ( sizeout == 1 ) {  /* applies to ALAW and ULAW */
	copyshort( 0, &hdr[36], ordr );
	copycharr( "fact", &hdr[38], 4 );
	copylong( 4, &hdr[42], ordr );
	copylong( sampcount, &hdr[46], ordr );
    }
    hoffs = hsize;
    copycharr( "data", &hdr[hoffs], 4 );
    copylong( fsize, &hdr[hoffs+4], ordr );

    hsize += 8;	/* add in the first 8 bytes, which weren't included earlier */
    if ( fwrite( hdr, 1, hsize, fpout ) != hsize ) {
	fprintf( stderr, "Failed to write WAV header to %s\n", outname );
	exit(1);
    }
}
Exemple #3
0
int main(int argc, char **argv)
{
    FILE *fp, *fp2;
    char *p, buf[256];
    int i;

    _argv = argv;

    if (argc < 3 || !strncmp(argv[1],"-h",2) || !strncmp(argv[1],"--h",3))
    {
	printf(usage);
	exit(1);
    }

    switch(argv[1][0])
    {
    case 'c':		/* create library */
	fp = fopen(argv[2],"wb");
	if (! fp) {
	    fprintf(stderr,"ldrdf: could not open '%s'\n",argv[2]);
	    perror("ldrdf");
	    exit(1);
	}
	fclose(fp);
	break;

    case 'a':		/* add module */
	if (argc < 5) {
	    fprintf(stderr,"ldrdf: required parameter missing\n");
	    exit(1);
	}
	fp = fopen(argv[2],"ab");
	if (! fp)
	{
	    fprintf(stderr,"ldrdf: could not open '%s'\n",argv[2]);
	    perror("ldrdf");
	    exit(1);
	}
	
	fp2 = fopen(argv[3],"rb");
	if (! fp)
	{
	    fprintf(stderr,"ldrdf: could not open '%s'\n",argv[3]);
	    perror("ldrdf");
	    exit(1);
	}

	p = argv[4];
	do {
	    if ( fputc(*p,fp) == EOF ) {
		fprintf(stderr,"ldrdf: write error\n");
		exit(1);
	    }
	} while (*p++);

	while (! feof (fp2) ) {
	    i = fgetc (fp2);
	    if (i == EOF) {
		break;
	    }

	    if ( fputc(i, fp) == EOF ) {
		fprintf(stderr,"ldrdf: write error\n");
		exit(1);
	    }
	}
	fclose(fp2);
	fclose(fp);
	break;

    case 'x':
	if (argc < 5) {
	    fprintf(stderr,"ldrdf: required parameter missing\n");
	    exit(1);
	}

	fp = fopen(argv[2],"rb");
	if (! fp)
	{
	    fprintf(stderr,"ldrdf: could not open '%s'\n",argv[2]);
	    perror("ldrdf");
	    exit(1);
	}
	
	fp2 = NULL;
	while (! feof(fp) ) {
	    /* read name */
	    p = buf;
	    while( ( *(p++) = (char) fgetc(fp) ) )  
		if (feof(fp)) break;

	    if (feof(fp)) break;

	    /* check against desired name */
	    if (! strcmp(buf,argv[3]) )
	    {
		fp2 = fopen(argv[4],"wb");
		if (! fp2)
		{
		    fprintf(stderr,"ldrdf: could not open '%s'\n", argv[4]);
		    perror("ldrdf");
		    exit(1);
		}
	    }
	    else
		fp2 = NULL;

	    /* step over the RDOFF file, copying it if fp2 != NULL */
	    copybytes(fp,fp2,6);	/* magic number */
	    copybytes(fp,fp2, copylong(fp,fp2));	/* header */
	    copybytes(fp,fp2, copylong(fp,fp2));	/* text */
	    copybytes(fp,fp2, copylong(fp,fp2));	/* data */

	    if (fp2)
		break;
	}
	fclose(fp);
	if (fp2)
	    fclose(fp2);
	else
	{
	    fprintf(stderr,"ldrdf: module '%s' not found in '%s'\n",
		    argv[3],argv[2]);
	    exit(1);
	}
	break;

    default:
	fprintf(stderr,"ldrdf: command '%c' not recognised\n",
		argv[1][0]);
	exit(1);
    }
    return 0;
}