home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 390.lha / SampLibrary / samp_readout.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-01  |  12.1 KB  |  349 lines

  1. /****************************************************************************
  2.  
  3.     A simple SAMP reader. This program reads in a SAMP format file using
  4.     the dissidents requester.library for file name input and error message
  5.     handling ( this library is not mandatory for    using the samp.library, 
  6.     but since it's so @#$! easy to use, why not? ) This demonstrates the use
  7.     of the EXTRAVector for obtaining various parameters of a wave, such as 
  8.     sample rate, size, loop points, etc. Other ways of obtaining this 
  9.     information are also shown, using the SampleHeader64 structure. Once the
  10.     fields are obtained and Transpose Table(s) is/are setup, the program 
  11.     closes down. This guy does a lot of printf()'s, so you'll probably want
  12.     to redirect the output to a file which you can examine at your leisure, 
  13.     as in:
  14.  
  15.     samp_readout > outfile
  16.  
  17.     by Jeff Glatt and Jim Fiore, dissidents.
  18.  
  19.     Not-so-fancy compile/link instructions:
  20.  
  21.     ( Manx 3.6 )
  22.     cc +P samp_readout.c
  23.     ln samp_readout.o SampInterface.o FileInterface.o -lcl32
  24.  
  25.     ( Lattice 5.0 )
  26.     lc -b0 samp_readout.c
  27.     blink lib:c.o samp_readout.o SampInterface.o FileInterface.o to samp_readout lib lib:lcnb.lib
  28.  
  29.     Note: SampInterface.o and FileInterface.o are not the same for Lattice/Manx.
  30.     Create them by running SampInterface.asm and FileInterface.asm through your
  31.     system's assembler. For non-Manx, make sure that you get rid of the
  32.     far data  far code   reference at the top of the .asm files.
  33.  
  34. *****************************************************************************/
  35.  
  36. #ifdef AZTEC_C
  37. #define NARGS
  38. #define NO_PRAGMAS
  39. #endif
  40.  
  41. #include "exec/types.h"
  42. #include "exec/memory.h"
  43. #include "libraries/dos.h"
  44. #include "libraries/dosextens.h"
  45.  
  46. #include "graphics/gfx.h"
  47. #include "graphics/rastport.h"
  48.  
  49. #ifdef LATTICE
  50. #include "proto/all.h"
  51. #else  
  52. #include "functions.h"
  53. #endif
  54.  
  55. /*============ Include files for dissidents' custom libraries ===========*/
  56.  
  57. #include "FileIO.h"
  58. #include "SAMP.h"
  59.  
  60. /*================== For dissidents requester.library =================*/
  61.  
  62. struct    RequesterBase            *RequesterBase = 0L;
  63. struct    FileIO                    *fileio_sup = 0L;
  64. UBYTE        fileio_filename[260];
  65.  
  66. /*==================== For dissidents samp.library =====================*/
  67.  
  68. extern    LONG SAMPError;            /* This comes from SAMPInterface.asm */
  69. struct    SAMPBase                    *SAMPBase = 0L;
  70. struct     SAMPInfo                    *libSAMPinfo = 0L;
  71.  
  72. #define playCHANS 4
  73. UBYTE        play_map[ 128 * playCHANS ];  /* let NumOfChans = 4. You can change this if you desire */
  74. struct    TransposeNode            *T_List = 0L;
  75.  
  76. /* Declare 32 SampleHeader64 structs for loading up to 32 waves in a SAMP */
  77. #define    MAXSAMPLES    32L        /* We arbitrarily load up to 32 waves */
  78. #define    NAMESIZE        16            /* This is arbitrary */
  79.  
  80. struct SampleHeader64 samp_head[ MAXSAMPLES ];
  81.  
  82. UBYTE        nameBuffers[ MAXSAMPLES ][ NAMESIZE ];    /* for the wave names */
  83.  
  84.  
  85. /*====================== The C Application begins here ==================*/
  86.  
  87. #ifdef NARGS
  88. VOID open_all(), exit_all();
  89. BOOL ReadExtraVector();
  90. long main();
  91. #else
  92. VOID open_all( void ), exit_all( void );
  93. BOOL ReadExtraVector( ULONG, struct SampleHeader64 *, struct SAMPInfo *, struct waveHeader * );
  94. long main( long, char ** );
  95. #endif
  96.  
  97. main( argc, argv )
  98. long argc;
  99. char *argv[];
  100. {
  101.     ULONG    totalWaves, p, period, wave_size, loop_start, loop_end, loop_length;
  102.     LONG  x;
  103.     USHORT i;
  104.     UBYTE *address;
  105.  
  106.     /* Open libs, get FileIO struct */
  107.     open_all();
  108.  
  109.     /* choose the SAMP file to load via the requester.library */
  110.     address = DoFileIOWindow( fileio_sup, 0L );
  111.     if( address == fileio_filename )
  112.     {
  113.  
  114.         /* Open the file and determine if it is a SAMP */
  115.         if( !( libSAMPinfo = OpenSampRead( fileio_filename, 0L ) ) )
  116.         {
  117.             address = SAMPErrorMsg( SAMPError );
  118.             puts( address );
  119.             exit_all();
  120.         }
  121.  
  122.         /* Before proceeding, set a few output fields of SAMPinfo, depending on need */
  123.         libSAMPinfo->MaxChars = NAMESIZE;    /* NOTE: Don't cast NAMESIZE as a LONG. This field is a WORD */
  124.         libSAMPinfo->MemType = MEMF_PUBLIC;  /* not using DMA playback */
  125.  
  126.         /* EXTRA Vector will allow us to examine the waveHeader structure, automatically */
  127.         libSAMPinfo->EXTRA = (APTR)ReadExtraVector;
  128.  
  129.         /* Grab any needed input fields of SAMPinfo at this point */
  130.         printf("Format = %d bits\n\n", libSAMPinfo->SampleFormat );
  131.  
  132.         /* Load up to 32 waves starting with the first wave in the SAMP (0)
  133.             We'll load these into our samp_head and nameBuffers starting with
  134.             the first member of each array. */
  135.  
  136.         if( !(totalWaves = ReadWaves( 0L, MAXSAMPLES, &nameBuffers[0][0], &samp_head[0] )) )
  137.         {
  138.             /* We didn't load ANY waves! Must be an empty SAMP. */
  139.             CloseSamp();
  140.             address = SAMPErrorMsg( SAMPError );
  141.             puts( address );
  142.             exit_all();
  143.         }
  144.  
  145.  
  146.         /* Print out the names of the waves in the file */
  147.         for( i = 0; i < totalWaves; ++i )
  148.        {
  149.             printf("Name of wave %d is %s\n", i, &nameBuffers[i][0] );
  150.         }
  151.  
  152.         /* The following function zeros out our playMap and transfers the loaded
  153.               playMap to our    passed playMap. It adjusts for difference in numOfChans
  154.            between our    program's playMap (4 chans) and the loaded playMap 
  155.             (0 to 4 chans). Also, it ensures that only those wave numbers that we 
  156.             loaded appear in our play_map. We pass an offset of 0 because we 
  157.             loaded from the first SampleHeader64 in our samp_head array. 
  158.  
  159.             If you do not plan on playing back the wave data from the Amiga, or
  160.             adjusting mapping, you do not need to deal with playMaps. This would
  161.             be the case in a program which reads in the data and just draws it, 
  162.             or perhaps only performs some analysis of it. */
  163.  
  164.  
  165.         LoadPlaymap( totalWaves, 4L, 0L, 0L, &play_map[0] );
  166.  
  167.         /* Let's verify the play_map */
  168.         for( x = 0; x < 128*playCHANS; x += playCHANS )
  169.         {
  170.             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] );
  171.         }
  172.  
  173.         for( i = 0; i < totalWaves; i++ )
  174.        {
  175.             /* The SAMP library set the TransTable fields of each loaded
  176.                 SampleHeader64 struct to that wave's sample period in nSec. This is
  177.                 a simple convenience trick, since you need the period, and the
  178.                 TransTable field is unused until the Transpose Table is built.
  179.                 Alternately, we could get the period from the EXTRA Vector routine.
  180.  
  181.                 Now we use this function to get all of the needed TransposeTables.
  182.                This function links any new TranposeTable into our T_List and 
  183.                 returns the address of that TransposeTable's ORIGINAL_PITCH. We'll
  184.                simply restore this return in the SampleHeader64's TransTable field.
  185.  
  186.                We can grab data at this point as well, if desired. Although we
  187.               are capable of finding parameters such as loop start and wave size
  188.                 in the SampleHeader64 structure, this material was simply copied
  189.                 over from the waveHeader structure by the library. Use of the
  190.                 EXTRA Vector to obtain this data is preferred ( see above ).
  191.  
  192.                Finally, note that if you don't plan on playing back a wave, you
  193.                 have no need to create a Transpose Table, and this whole section
  194.                 may be skipped. Two cases where you might not want a Transpose 
  195.                 Table are when you prefer to 'roll your own' ( for example, for
  196.                 micro-tonal scales ), or in an application which simply analizes
  197.                 wave data ( for example, a data analysis package performing FFT
  198.                 or TDS type functions ). Note the comment above, concerning 
  199.                 playMaps. In short, playMaps and Transpose Tables are musical
  200.                 performance oriented items. They are not part of the SAMP spec.
  201.                 They simply exist for the samp reader/writer library and
  202.                 contain only the information that a player program would need. */
  203.  
  204.             wave_size = samp_head[i].WaveSize;
  205.             loop_length = (samp_head[i].LoopLength) * 2;   /* was in WORDS */
  206.             loop_end = (ULONG)(samp_head[i].OneShotEnd);
  207.             loop_start = (ULONG)(samp_head[i].OneShotAddr);
  208.             loop_start = loop_end - loop_start;            /* one shot size */
  209.             period = (ULONG)(samp_head[i].TransTable);
  210.  
  211.             printf("\nEquivalent data obtained from SampleHeader64 structure:\n");
  212.             printf("Size %d,  Loop Start %d, Loop Len %d, Period %d (nSec)\n\n", wave_size, loop_start, loop_length, period );
  213.  
  214.             /* Make a Transpose Table that is 6 steps up and down from the root 
  215.                 pitch, 13 notes total. 6 steps is an arbitrary value for this
  216.                 example, but the routine MakeTransTable() supports only values of
  217.                 up to 12 for upper and lower ranges.
  218.                 
  219.                 It is important to note that after a load, the TransTable field
  220.                 of all SampleHeader64 structures must be converted to an
  221.                 ORIGINAL_PITCH address ( as in the MakeTransTable() call below ), 
  222.                 or set to zero. Do not leave this field as the sampling period! */
  223.  
  224.             samp_head[i].TransTable = MakeTransTable( (ULONG)(samp_head[i].TransTable), 6L, 6L, &T_List );
  225.  
  226.             /* Let's verify the Transpose Table... Remember, 0 means out of range */
  227.             for( x = -6; x <= 6; x++ )
  228.             {
  229.                 printf("TransTable[%d] %d\n",x, samp_head[i].TransTable[x] );
  230.             }
  231.         }
  232.  
  233.         /* We are all done reading the SAMP file, so close samp */
  234.  
  235.         CloseSamp();
  236.  
  237.         /* At this point, we could do whatever we needed with the wave data.
  238.             Since this program doesn't really _do_ anything, we just deallocate
  239.            whatever was allocated during the read-in process, clean up, and exit */
  240.  
  241.  
  242.         /* Free the sample memory (for "total" # of waves) */
  243.         for( p=0; p<totalWaves; ++p )
  244.        {
  245.             FreeMem( samp_head[p].OneShotAddr, samp_head[p].WaveSize );
  246.         }
  247.  
  248.         FreeTTables( &T_List );
  249.  
  250.     }
  251.  
  252.     exit_all();
  253.  
  254. }   /********** end of main() ********/
  255.  
  256.  
  257.  
  258.  
  259. /****************************  open_all() ***********************************
  260.  
  261.     General beginning routine which opens FileIO and SAMP libs, and sets up
  262.     the fileio support structure.
  263.  
  264. *****************************************************************************/
  265.  
  266. VOID open_all()
  267. {
  268.    /* Open the requester library and allocate/setup a FileIO structure */
  269.     if( !(RequesterBase=(struct RequesterBase *)OpenLibrary("requester.library", 1L)) )
  270.     {
  271.         puts("Can't find requester.library\n");
  272.         exit_all();
  273.     }
  274.  
  275.     if( !(fileio_sup = GetFileIO()) )
  276.     {
  277.         puts("Can't get FileIO support\n");
  278.         exit_all();
  279.     }
  280.  
  281.     fileio_sup->X = 6;
  282.     fileio_sup->Y = 11;
  283.     fileio_sup->DrawMode = JAM2;
  284.     fileio_sup->PenA = 0;
  285.     fileio_sup->PenB = 1;
  286.     fileio_sup->Buffer = (UBYTE *)fileio_filename;
  287.  
  288.    /* Open the SAMP reader/writer library */
  289.     if( !(SAMPBase=(struct SAMPBase *)OpenLibrary("samp.library", 0L)) )
  290.     {
  291.         puts("Can't find samp.library\n");
  292.         exit_all();
  293.     }
  294. }
  295.  
  296.  
  297.  
  298.  
  299. /****************************  exit_all() ***********************************
  300.  
  301.     General clean up routine which closes FileIO and SAMP libs.
  302.  
  303. *****************************************************************************/
  304.  
  305. VOID exit_all()
  306. {
  307.     if( fileio_sup )    ReleaseFileIO( fileio_sup );
  308.     if( RequesterBase ) CloseLibrary( RequesterBase );
  309.     if( SAMPBase )      CloseLibrary( SAMPBase );
  310.     exit( FALSE );
  311. }
  312.  
  313.  
  314. /****************************  ReadExtraVector() ****************************
  315.  
  316.     This is the routine passed to the EXTRA field of the SAMPinfo structure,
  317.     for reading SAMP files. This allows us to determine a variety of parameters
  318.     describing the SAMP file and its waves. Here, we just print out a few
  319.     of the generally desirable elements. This routine is automatically called
  320.     by the library during ReadWaves() immediately before the sample data for
  321.     the current wave is about to be read in. At this point, the library has
  322.     already called all of your other vectors (i.e. ATAKvector, USERvector, etc)
  323.  
  324. *****************************************************************************/
  325.  
  326. BOOL ReadExtraVector( wave_number, sample_header, samp_info, wave_header )
  327. ULONG wave_number;
  328. struct SampleHeader64 *sample_header;
  329. struct SAMPInfo *samp_info;
  330. struct waveHeader *wave_header;
  331. {
  332.  
  333.     /* DON'T look at any fields of SampleHeader64 in here since the data has
  334.     yet to be copied over from the waveHeader!! This will be garbage. */
  335.  
  336.     printf("READ EXTRA Vector results for wave %d :\n", wave_number );
  337.  
  338.     printf("Wave Size = %d bytes\n", wave_header->WaveSize );
  339.     printf("Period = %d nanoseconds\n", wave_header->Period );
  340.     printf("Sample Rate = %d Hz\n", wave_header->Rate );
  341.     printf("Loop Start at %d byte offset\n", wave_header->LoopStart );
  342.     printf("Loop End at %d byte offset\n", wave_header->LoopEnd );
  343.     printf("Loop Type = %d ( 0 = forward, 1 = backward )\n\n", wave_header->LoopType );
  344.  
  345.     return( 0 ); /* continue, all good.  A 1 would abort the load at this point. */
  346. }
  347.  
  348. /*************************** DAT'S ALL FOLKS.... ****************************/
  349.