/************************************************************* * 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); } }
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; }