home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************/
- /* */
- /* Amiga C Encyclopedia (ACE) V3.0 Amiga C Club (ACC) */
- /* ------------------------------- ------------------ */
- /* */
- /* Book: ACM Sound Amiga C Club */
- /* Chapter: IncludeSound Tulevagen 22 */
- /* File: PrintSound.c 181 41 LIDINGO */
- /* Author: Anders Bjerin SWEDEN */
- /* Date: 92-05-01 */
- /* Version: 1.10 */
- /* */
- /* Copyright 1992, Anders Bjerin - Amiga C Club (ACC) */
- /* */
- /* Registered members may use this program freely in their */
- /* own commercial/noncommercial programs/articles. */
- /* */
- /***********************************************************/
-
- /* PrintSound() loads a sampled sound file (IFF or FutureSound) and */
- /* prints the sound data as a large array. This array can then simply */
- /* be included in your own programs together with the IncludeSound */
- /* file. The advantage to this compared to EasySound is that you do */
- /* not need to have to load the sound data when you run your program. */
- /* This is both much faster and more convinient. */
- /* */
- /* NOTE! Do not try to print too large samples. Even a short sample */
- /* can result in several pages of data! (However, once the file has */
- /* been compiled it will not use more memory than normal. The program */
- /* itself will also be some kilo bytes shorter since you do not need */
- /* to include any routines to load the sound.) */
- /* */
- /* Sounds that have been prepared with PrintSound can also be used with */
- /* EasySound. Note that the sound should then NOT be prepared NOR should */
- /* it be removed. Everything else is as normal. */
- /* */
- /* */
- /* */
- /* I N S T R U C T I O N S */
- /* ----------------------- */
- /* */
- /* PrintSound > "output file" "sound file" "name of array" */
- /* */
- /* Example: "PrintSound > RAM:Data Explosion.snd Bang" */
- /* */
- /* PrintSound will load file "Explosion.snd", and print the sound */
- /* data in file "RAM:Data". The SoundInfo structure will be called */
- /* "Bang". */
-
-
-
- /* Include some important header files: */
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <devices/audio.h>
- #include <stdio.h>
-
-
- #define CLOCK_CONSTANT 3579545
- #define MUSIC_PRIORITY 0
-
-
-
- /* Structure containing all necessary information about the sound: */
- struct SoundInfo
- {
- BYTE *SoundBuffer; /* WaveForm Buffers */
- UWORD RecordRate; /* Record Rate */
- ULONG FileLength; /* WaveForm Lengths */
- };
-
-
- /* An IOAudio pointer to each sound channel: */
- struct IOAudio *IOA[ 4 ] = { NULL, NULL, NULL, NULL };
-
-
- typedef LONG Fixed;
- typedef struct
- {
- ULONG oneShotHiSamples; /* #samples in the high octave 1-shot part */
- ULONG repeatHiSamples; /* #samples in the high octave repeat part */
- ULONG samplesPerHiCycle; /* #samples/cycle in high octave, else 0 */
- UWORD samplesPerSec; /* Data sampling rate */
- UBYTE ctOctave; /* Number of octaves of waveforms */
- UBYTE sCompression; /* Data compression technique used */
- Fixed volume; /* Playback volume from 0 to 0x10000 */
- } Voice8Header;
-
-
- /* Declare the functions we are going to use: */
- void main();
- BOOL PrintSound();
- UWORD LoadSound();
- ULONG GetSize();
- ULONG SizeIFF();
- UWORD ReadIFF();
- BOOL MoveTo();
-
-
- /* PrintSound <sound file> <name of array> */
- void main( argc, argv )
- int argc;
- char *argv[];
- {
- /* Two arguments + program name: */
- if( argc == 3 )
- {
- if( !PrintSound( argv[ 1 ], argv[ 2 ] ) )
- {
- printf( "ERROR!" );
- }
- }
- else
- {
- /* Not enough or to many arguments. */
-
- /* Print instructions: */
- printf( "PrintSound > \"output file\" \"sound file\" \"name of array\"\n" );
- printf( "Example: \"PrintSound > RAM:Data Explosion.snd Bang\"\n" );
- printf( " PrintSound will load file \"Explosion.snd\",\n" );
- printf( " and print the sound data in file \"RAM:Data\".\n" );
- printf( " The SoundInfo structure will be called \"Bang\".\n" );
- }
- }
-
-
- /* PrintSound() */
- /* PrintSound() loads a sampled sound file (IFF or FutureSound) and */
- /* prints the sound data as a large array. This array can then simply */
- /* be included in your own programs together with the IncludeSound */
- /* file. The advantage to this compared to EasySound is that you do */
- /* not need to have to load the sound data when you run your program. */
- /* This is both much faster and more convinient. */
- /* NOTE! Do not try to print too large samples. Even a short sample */
- /* can result in several pages of data! (However, once the file has */
- /* been compiled it will not use more memory than normal. The proram */
- /* itself will also be some kilo bytes shorter since you do not need */
- /* to include any routines to load the sound.) */
- /* */
- /* Synopsis: result = PrintSound( filename, name ); */
- /* result: (BOOL) If PrintSound has successfully loaded and printed */
- /* the sound data it will return TRUE, else FALSE. */
- /* filename: (STRPTR) Name of the sound file. */
- /* name: (STRPTR) Name of the sound data array. */
-
- BOOL PrintSound( file, name )
- STRPTR file, name;
- {
- BYTE *pointer;
- ULONG position;
- BOOL result = FALSE;
-
-
- /* Declare a pointer to a SoundInfo structure: */
- struct SoundInfo *info;
-
- /* Allocate memory for a SoundInfo structure: (The memory can be of */
- /* any type, and should be cleared. */
- info = (struct SoundInfo *) AllocMem( sizeof( struct SoundInfo ),
- MEMF_PUBLIC|MEMF_CLEAR );
-
-
- if( info )
- {
- /* The memory have been successfully allocated. */
-
- /* Get the size of the file, and store it in the SoundInfo struct.: */
- if( info->FileLength = GetSize( file ) )
- {
- /* Allocate enough memory for the sampled sound, and store a */
- /* pointer to the buffer in the SoundInfo structure: */
- info->SoundBuffer = (BYTE *) AllocMem( info->FileLength,
- MEMF_CHIP|MEMF_CLEAR );
-
- if( info->SoundBuffer )
- {
- /* The memory have been successfully allocated. */
-
- /* Load the sound, and store the record rate in the SoundInfo */
- /* structure. If the sound could not be loaded, 0 is returned: */
- if( info->RecordRate = LoadSound( file, info ) )
- {
- /* OK! The sound has successfully been loaded. */
-
- /* Old FutureSound files were saved in kHz. If the record rate */
- /* is less than one hundered, we know it is an old FutureSound */
- /* file, and simply multiply the rate with one thousand: */
- if( info->RecordRate < 100 )
- info->RecordRate *= 1000;
-
- pointer = info->SoundBuffer;
-
- printf( "#include \"IncludeSound.h\"\n\n" );
- printf( "\n/************************************/\n" );
- printf( "/* SoundData prepared by PrintSound */\n" );
- printf( "/* Anders Bjerin Amiga C Club */\n" );
- printf( "/* */\n" );
- printf( "/* File name: %19s */\n", file );
- printf( "/* Record Rate: %19d */\n", info->RecordRate );
- printf( "/* File Length: %19d */\n", info->FileLength );
- printf( "/************************************/\n\n" );
-
- /* NOTE! This data must be in "Chip Memory"! */
- printf( "BYTE chip %s_data[]=\n{", name );
- for( position = 0; position < info->FileLength; position++ )
- {
- /* New line after each ten values: */
- if( position % 10 == 0 )
- printf( "\n " );
-
- /* Print a sample (one byte): */
- printf( "%d%s",
- pointer[ position ],
- position < info->FileLength - 1 ? "," : " " );
- }
- printf( "\n};\n\n" );
-
- printf( "struct SoundInfo %s=\n{\n", name );
- printf( " %s_data, /* WaveForm Buffers */\n", name );
- printf( " %8d, /* Record Rate */\n", info->RecordRate );
- printf( " %8d /* WaveForm Length */\n};\n\n", info->FileLength );
-
- printf( "/************************************/\n" );
- printf( "/* End of sound: %18s */\n", file );
- printf( "/************************************/\n\n" );
-
- result = TRUE;
- }
-
- /* Deallocate the memory for the sound buffer: */
- FreeMem( info->SoundBuffer, info->FileLength );
- }
- }
- /* Deallocate the memory the SoundInfo structure: */
- FreeMem( info, sizeof( struct SoundInfo ) );
- }
-
- return( result );
- }
-
-
-
- /* LoadSound() */
- /* LoadSound() will load sampled sound that was either saved in IFF or */
- /* FutureSound format. */
- /* */
- /* Synopsis: rate = LoadSound( filename, pointer ); */
- /* rate: (UWORD) The record rate is returned if the sound was */
- /* successfully loaded, else 0. */
- /* filename: (STRPTR) Pointer to a string containing the name of the */
- /* sound file. For example "df0:Explosion.snd". */
- /* pointer: (struct SoundInfo *info) Pointer to a SoundInfo structure.*/
-
- UWORD LoadSound( filename, info )
- STRPTR filename;
- struct SoundInfo *info;
- {
- FILE *file_ptr; /* Pointer to a file. */
- ULONG length; /* Data Length. */
- UWORD record_rate; /* Record rate. */
-
-
- /* Check if it is an IFF File: */
- if( SizeIFF( filename ) )
- {
- /* Yes, it is an IFF file. Read it: */
- return( ReadIFF( filename, info ) );
- }
- else
- {
- /* No, then it is probably a FutureSound file. */
- /* Open the file so we can read it: */
- if( (file_ptr = fopen( filename, "r" )) == 0 )
- return( 0 ); /* ERROR! Could not open the file! */
-
- /* Read the data length: */
- if( fread( (char *) &length, sizeof( ULONG ), 1, file_ptr ) == 0 )
- {
- /* ERROR! Could not read the data length! */
- /* Close the file, and return zero: */
- fclose( file_ptr );
- return( 0 );
- }
-
- /* Read the record rate: */
- if( fread( (char *) &record_rate, sizeof( UWORD ), 1, file_ptr ) == 0 )
- {
- /* ERROR! Could not read the record rate! */
- /* Close the file, and return zero: */
- fclose( file_ptr );
- return( 0 );
- }
-
- /* Read the sampled sound data into the buffer: */
- if( fread( (char *) info->SoundBuffer, length, 1, file_ptr ) == 0 )
- {
- /* ERROR! Could not read the data! */
- /* Close the file, and return zero: */
- fclose( file_ptr );
- return( 0 );
- }
-
- /* Close the file: */
- fclose( file_ptr );
-
- /* Return the record rate: */
- return( record_rate );
- }
- }
-
-
-
-
- /* GetSize() */
- /* GetSize() returns the size of the file which was saved in either */
- /* IFF or FutureSound format. */
- /* */
- /* Synopsis: length = GetSize( filename ); */
- /* length: (ULONG) Data length. */
- /* filename: (STRPTR) Pointer to a string containing the name of the */
- /* sound file. For example "df0:Explosion.snd". */
-
- ULONG GetSize( filename )
- STRPTR filename;
- {
- FILE *file_ptr; /* Pointer to a file. */
- ULONG length; /* Data length. */
-
-
- /* Check if it is an IFF File: */
- if( ( length = SizeIFF( filename ) ) == 0 )
- {
- /* No, then it is probably a FutureSound file. */
- /* Open the file so we can read it: */
- if( ( file_ptr = fopen( filename, "r" ) ) == 0 )
- return( 0 ); /* ERROR! Could not open the file! */
-
- /* Read the data length: */
- if( fread( (char *) &length, sizeof( ULONG ), 1, file_ptr ) == 0)
- {
- /* ERROR! Could not read the data length! */
- /* Close the file, and return zero: */
- fclose( file_ptr );
- return( 0 );
- }
-
- /* Close the file: */
- fclose( file_ptr );
- }
- return( length );
- }
-
-
-
- /* SizeIFF() */
- /* SizeIFF() returns the size of an IFF file, or zero if something */
- /* went wrong (for example, It was not an IFF file). */
- /* */
- /* Synopsis: length = SizeIFF( filename ); */
- /* length: (ULONG) Data length. */
- /* filename: (STRPTR) Pointer to a string containing the name of the */
- /* IFF file. For example "df0:Explosion.snd". */
-
- ULONG SizeIFF( filename )
- STRPTR filename;
- {
- FILE *file_ptr; /* Pointer to a file. */
- STRPTR empty_string = " "; /* Four spaces. */
- LONG dummy; /* A dummy variable. */
- Voice8Header Header; /* Voice8Header structure. */
-
-
- /* Try to open the file: */
- if( file_ptr = fopen( filename, "r" ) )
- {
- fread( (char *) empty_string, 4, 1, file_ptr );
- if( strcmp( empty_string, "FORM" ) == 0)
- {
- /* Read twice: */
- fread( (char *) empty_string, 4, 1, file_ptr );
- fread( (char *) empty_string, 4, 1, file_ptr );
-
- /* Check if it is a "8SVX" file, or not: */
- if( strcmp( empty_string, "8SVX" ) == 0 )
- {
- MoveTo( "VHDR", file_ptr );
- fread( (char *) &dummy, sizeof( LONG ), 1, file_ptr );
- fread( (char *) &Header, sizeof( Header ), 1, file_ptr );
-
- /* Close the file, and return the length: */
- fclose( file_ptr );
- return( Header.oneShotHiSamples + Header.repeatHiSamples );
- }
- }
- /* Close the file: */
- fclose( file_ptr );
- }
- /* Return zero: (ERROR) */
- return( 0 );
- }
-
-
-
- /* ReadIFF() */
- /* ReadIFF() reads an IFF file into the buffer, and returns the record */
- /* rate. */
- /* */
- /* Synopsis: rate = ReadIFF( filename, pointer ); */
- /* rate: (UWORD) The record rate is returned if the sound was */
- /* successfully loaded, else 0. */
- /* filename: (STRPTR) Pointer to a string containing the name of the */
- /* sound file. For example "df0:Explosion.snd". */
- /* pointer: (struct SoundInfo *info) Pointer to a SoundInfo structure.*/
-
- UWORD ReadIFF( filename, info )
- STRPTR filename;
- struct SoundInfo *info;
- {
- FILE *file_ptr; /* Pointer to a file. */
- STRPTR empty_string = " "; /* Four spaces. */
- LONG dummy; /* A dummy variable. */
- Voice8Header Header; /* Voice8Header structure. */
-
-
- /* Try to open the file: */
- if( file_ptr = fopen( filename, "r" ) )
- {
- fread( (char *) empty_string, 4, 1, file_ptr );
- if( strcmp( empty_string, "FORM" ) == 0 )
- {
- /* Read twice: */
- fread( (char *) empty_string, 4, 1, file_ptr );
- fread( (char *) empty_string, 4, 1, file_ptr );
-
- /* Check if it is a "8SVX" file, or not: */
- if( strcmp( empty_string, "8SVX" ) == 0 )
- {
- MoveTo( "VHDR", file_ptr );
- fread( (char *) &dummy, sizeof( LONG ), 1, file_ptr );
- fread( (char *) &Header, sizeof( Header ), 1, file_ptr );
-
- MoveTo( "BODY", file_ptr );
- fread( (char *) &dummy, sizeof( LONG ), 1, file_ptr );
- fread( (char *) info->SoundBuffer, Header.oneShotHiSamples +
- Header.repeatHiSamples, 1, file_ptr );
-
- /* Close the file, and return the record rate: */
- fclose( file_ptr );
- return( Header.samplesPerSec );
- }
- }
- /* Close the file: */
- fclose( file_ptr );
- }
- /* Return zero: (ERROR) */
- return( 0 );
- }
-
-
-
- /* MoveTo() */
- /* MoveTo() walks through an IFF file, and looks for chunks. */
- /* */
- /* Synopsis: MoveTo( chunk, file_ptr ); */
- /* chunk: (STRPTR) The chunk we want to get to. */
- /* file_ptr: (FILE *) Pointer to an already opened file. */
-
- BOOL MoveTo( check_string, file_ptr )
- STRPTR check_string;
- FILE *file_ptr;
- {
- STRPTR empty_string = " "; /* Four spaces. */
- int skip, loop; /* How much data should be skiped. */
- LONG dummy; /* A dummy variable. */
-
-
- /* As long as we have not reached the EOF, continue: */
- while( !feof( file_ptr ) )
- {
- fread( (char *) empty_string, 4, 1, file_ptr);
-
- /* Have we found the right chunk? */
- if( strcmp( check_string, empty_string ) ==0 )
- return( 0 ); /* YES! Return nothing. */
-
- /* Move foreward: */
- fread( (char *) &skip, sizeof( LONG ), 1, file_ptr );
- for( loop = 0; loop < skip; loop++ )
- fread( (char *) &dummy, 1, 1, file_ptr);
- }
- }
-