home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
-
- A simple SAMP reader. This program reads in a SAMP format file using
- the dissidents requester.library for file name input and error message
- handling ( this library is not mandatory for using the samp.library,
- but since it's so @#$! easy to use, why not? ) This demonstrates the use
- of the EXTRAVector for obtaining various parameters of a wave, such as
- sample rate, size, loop points, etc. Other ways of obtaining this
- information are also shown, using the SampleHeader64 structure. Once the
- fields are obtained and Transpose Table(s) is/are setup, the program
- closes down. This guy does a lot of printf()'s, so you'll probably want
- to redirect the output to a file which you can examine at your leisure,
- as in:
-
- samp_readout > outfile
-
- by Jeff Glatt and Jim Fiore, dissidents.
-
- Not-so-fancy compile/link instructions:
-
- ( Manx 3.6 )
- cc +P samp_readout.c
- ln samp_readout.o SampInterface.o FileInterface.o -lcl32
-
- ( Lattice 5.0 )
- lc -b0 samp_readout.c
- blink lib:c.o samp_readout.o SampInterface.o FileInterface.o to samp_readout lib lib:lcnb.lib
-
- Note: SampInterface.o and FileInterface.o are not the same for Lattice/Manx.
- Create them by running SampInterface.asm and FileInterface.asm through your
- system's assembler. For non-Manx, make sure that you get rid of the
- far data far code reference at the top of the .asm files.
-
- *****************************************************************************/
-
- #ifdef AZTEC_C
- #define NARGS
- #define NO_PRAGMAS
- #endif
-
- #include "exec/types.h"
- #include "exec/memory.h"
- #include "libraries/dos.h"
- #include "libraries/dosextens.h"
-
- #include "graphics/gfx.h"
- #include "graphics/rastport.h"
-
- #ifdef LATTICE
- #include "proto/all.h"
- #else
- #include "functions.h"
- #endif
-
- /*============ Include files for dissidents' custom libraries ===========*/
-
- #include "FileIO.h"
- #include "SAMP.h"
-
- /*================== For dissidents requester.library =================*/
-
- struct RequesterBase *RequesterBase = 0L;
- struct FileIO *fileio_sup = 0L;
- UBYTE fileio_filename[260];
-
- /*==================== For dissidents samp.library =====================*/
-
- extern LONG SAMPError; /* This comes from SAMPInterface.asm */
- struct SAMPBase *SAMPBase = 0L;
- struct SAMPInfo *libSAMPinfo = 0L;
-
- #define playCHANS 4
- UBYTE play_map[ 128 * playCHANS ]; /* let NumOfChans = 4. You can change this if you desire */
- struct TransposeNode *T_List = 0L;
-
- /* Declare 32 SampleHeader64 structs for loading up to 32 waves in a SAMP */
- #define MAXSAMPLES 32L /* We arbitrarily load up to 32 waves */
- #define NAMESIZE 16 /* This is arbitrary */
-
- struct SampleHeader64 samp_head[ MAXSAMPLES ];
-
- UBYTE nameBuffers[ MAXSAMPLES ][ NAMESIZE ]; /* for the wave names */
-
-
- /*====================== The C Application begins here ==================*/
-
- #ifdef NARGS
- VOID open_all(), exit_all();
- BOOL ReadExtraVector();
- long main();
- #else
- VOID open_all( void ), exit_all( void );
- BOOL ReadExtraVector( ULONG, struct SampleHeader64 *, struct SAMPInfo *, struct waveHeader * );
- long main( long, char ** );
- #endif
-
- main( argc, argv )
- long argc;
- char *argv[];
- {
- ULONG totalWaves, p, period, wave_size, loop_start, loop_end, loop_length;
- LONG x;
- USHORT i;
- UBYTE *address;
-
- /* Open libs, get FileIO struct */
- open_all();
-
- /* choose the SAMP file to load via the requester.library */
- address = DoFileIOWindow( fileio_sup, 0L );
- if( address == fileio_filename )
- {
-
- /* Open the file and determine if it is a SAMP */
- if( !( libSAMPinfo = OpenSampRead( fileio_filename, 0L ) ) )
- {
- address = SAMPErrorMsg( SAMPError );
- puts( address );
- exit_all();
- }
-
- /* Before proceeding, set a few output fields of SAMPinfo, depending on need */
- libSAMPinfo->MaxChars = NAMESIZE; /* NOTE: Don't cast NAMESIZE as a LONG. This field is a WORD */
- libSAMPinfo->MemType = MEMF_PUBLIC; /* not using DMA playback */
-
- /* EXTRA Vector will allow us to examine the waveHeader structure, automatically */
- libSAMPinfo->EXTRA = (APTR)ReadExtraVector;
-
- /* Grab any needed input fields of SAMPinfo at this point */
- printf("Format = %d bits\n\n", libSAMPinfo->SampleFormat );
-
- /* Load up to 32 waves starting with the first wave in the SAMP (0)
- We'll load these into our samp_head and nameBuffers starting with
- the first member of each array. */
-
- if( !(totalWaves = ReadWaves( 0L, MAXSAMPLES, &nameBuffers[0][0], &samp_head[0] )) )
- {
- /* We didn't load ANY waves! Must be an empty SAMP. */
- CloseSamp();
- address = SAMPErrorMsg( SAMPError );
- puts( address );
- exit_all();
- }
-
-
- /* Print out the names of the waves in the file */
- for( i = 0; i < totalWaves; ++i )
- {
- printf("Name of wave %d is %s\n", i, &nameBuffers[i][0] );
- }
-
- /* The following function zeros out our playMap and transfers the loaded
- playMap to our passed playMap. It adjusts for difference in numOfChans
- between our program's playMap (4 chans) and the loaded playMap
- (0 to 4 chans). Also, it ensures that only those wave numbers that we
- loaded appear in our play_map. We pass an offset of 0 because we
- loaded from the first SampleHeader64 in our samp_head array.
-
- If you do not plan on playing back the wave data from the Amiga, or
- adjusting mapping, you do not need to deal with playMaps. This would
- be the case in a program which reads in the data and just draws it,
- or perhaps only performs some analysis of it. */
-
-
- LoadPlaymap( totalWaves, 4L, 0L, 0L, &play_map[0] );
-
- /* Let's verify the play_map */
- for( x = 0; x < 128*playCHANS; x += playCHANS )
- {
- printf("Loaded playmap[%d] %d %d %d %d\n",x, play_map[x], play_map[x+1], play_map[x+2], play_map[x+3] );
- }
-
- for( i = 0; i < totalWaves; i++ )
- {
- /* The SAMP library set the TransTable fields of each loaded
- SampleHeader64 struct to that wave's sample period in nSec. This is
- a simple convenience trick, since you need the period, and the
- TransTable field is unused until the Transpose Table is built.
- Alternately, we could get the period from the EXTRA Vector routine.
-
- Now we use this function to get all of the needed TransposeTables.
- This function links any new TranposeTable into our T_List and
- returns the address of that TransposeTable's ORIGINAL_PITCH. We'll
- simply restore this return in the SampleHeader64's TransTable field.
-
- We can grab data at this point as well, if desired. Although we
- are capable of finding parameters such as loop start and wave size
- in the SampleHeader64 structure, this material was simply copied
- over from the waveHeader structure by the library. Use of the
- EXTRA Vector to obtain this data is preferred ( see above ).
-
- Finally, note that if you don't plan on playing back a wave, you
- have no need to create a Transpose Table, and this whole section
- may be skipped. Two cases where you might not want a Transpose
- Table are when you prefer to 'roll your own' ( for example, for
- micro-tonal scales ), or in an application which simply analizes
- wave data ( for example, a data analysis package performing FFT
- or TDS type functions ). Note the comment above, concerning
- playMaps. In short, playMaps and Transpose Tables are musical
- performance oriented items. They are not part of the SAMP spec.
- They simply exist for the samp reader/writer library and
- contain only the information that a player program would need. */
-
- wave_size = samp_head[i].WaveSize;
- loop_length = (samp_head[i].LoopLength) * 2; /* was in WORDS */
- loop_end = (ULONG)(samp_head[i].OneShotEnd);
- loop_start = (ULONG)(samp_head[i].OneShotAddr);
- loop_start = loop_end - loop_start; /* one shot size */
- period = (ULONG)(samp_head[i].TransTable);
-
- printf("\nEquivalent data obtained from SampleHeader64 structure:\n");
- printf("Size %d, Loop Start %d, Loop Len %d, Period %d (nSec)\n\n", wave_size, loop_start, loop_length, period );
-
- /* Make a Transpose Table that is 6 steps up and down from the root
- pitch, 13 notes total. 6 steps is an arbitrary value for this
- example, but the routine MakeTransTable() supports only values of
- up to 12 for upper and lower ranges.
-
- It is important to note that after a load, the TransTable field
- of all SampleHeader64 structures must be converted to an
- ORIGINAL_PITCH address ( as in the MakeTransTable() call below ),
- or set to zero. Do not leave this field as the sampling period! */
-
- samp_head[i].TransTable = MakeTransTable( (ULONG)(samp_head[i].TransTable), 6L, 6L, &T_List );
-
- /* Let's verify the Transpose Table... Remember, 0 means out of range */
- for( x = -6; x <= 6; x++ )
- {
- printf("TransTable[%d] %d\n",x, samp_head[i].TransTable[x] );
- }
- }
-
- /* We are all done reading the SAMP file, so close samp */
-
- CloseSamp();
-
- /* At this point, we could do whatever we needed with the wave data.
- Since this program doesn't really _do_ anything, we just deallocate
- whatever was allocated during the read-in process, clean up, and exit */
-
-
- /* Free the sample memory (for "total" # of waves) */
- for( p=0; p<totalWaves; ++p )
- {
- FreeMem( samp_head[p].OneShotAddr, samp_head[p].WaveSize );
- }
-
- FreeTTables( &T_List );
-
- }
-
- exit_all();
-
- } /********** end of main() ********/
-
-
-
-
- /**************************** open_all() ***********************************
-
- General beginning routine which opens FileIO and SAMP libs, and sets up
- the fileio support structure.
-
- *****************************************************************************/
-
- VOID open_all()
- {
- /* Open the requester library and allocate/setup a FileIO structure */
- if( !(RequesterBase=(struct RequesterBase *)OpenLibrary("requester.library", 1L)) )
- {
- puts("Can't find requester.library\n");
- exit_all();
- }
-
- if( !(fileio_sup = GetFileIO()) )
- {
- puts("Can't get FileIO support\n");
- exit_all();
- }
-
- fileio_sup->X = 6;
- fileio_sup->Y = 11;
- fileio_sup->DrawMode = JAM2;
- fileio_sup->PenA = 0;
- fileio_sup->PenB = 1;
- fileio_sup->Buffer = (UBYTE *)fileio_filename;
-
- /* Open the SAMP reader/writer library */
- if( !(SAMPBase=(struct SAMPBase *)OpenLibrary("samp.library", 0L)) )
- {
- puts("Can't find samp.library\n");
- exit_all();
- }
- }
-
-
-
-
- /**************************** exit_all() ***********************************
-
- General clean up routine which closes FileIO and SAMP libs.
-
- *****************************************************************************/
-
- VOID exit_all()
- {
- if( fileio_sup ) ReleaseFileIO( fileio_sup );
- if( RequesterBase ) CloseLibrary( RequesterBase );
- if( SAMPBase ) CloseLibrary( SAMPBase );
- exit( FALSE );
- }
-
-
- /**************************** ReadExtraVector() ****************************
-
- This is the routine passed to the EXTRA field of the SAMPinfo structure,
- for reading SAMP files. This allows us to determine a variety of parameters
- describing the SAMP file and its waves. Here, we just print out a few
- of the generally desirable elements. This routine is automatically called
- by the library during ReadWaves() immediately before the sample data for
- the current wave is about to be read in. At this point, the library has
- already called all of your other vectors (i.e. ATAKvector, USERvector, etc)
-
- *****************************************************************************/
-
- BOOL ReadExtraVector( wave_number, sample_header, samp_info, wave_header )
- ULONG wave_number;
- struct SampleHeader64 *sample_header;
- struct SAMPInfo *samp_info;
- struct waveHeader *wave_header;
- {
-
- /* DON'T look at any fields of SampleHeader64 in here since the data has
- yet to be copied over from the waveHeader!! This will be garbage. */
-
- printf("READ EXTRA Vector results for wave %d :\n", wave_number );
-
- printf("Wave Size = %d bytes\n", wave_header->WaveSize );
- printf("Period = %d nanoseconds\n", wave_header->Period );
- printf("Sample Rate = %d Hz\n", wave_header->Rate );
- printf("Loop Start at %d byte offset\n", wave_header->LoopStart );
- printf("Loop End at %d byte offset\n", wave_header->LoopEnd );
- printf("Loop Type = %d ( 0 = forward, 1 = backward )\n\n", wave_header->LoopType );
-
- return( 0 ); /* continue, all good. A 1 would abort the load at this point. */
- }
-
- /*************************** DAT'S ALL FOLKS.... ****************************/
-