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

  1. /***************************************************************************
  2.     Set your editor's TAB width to 3.
  3.  
  4.     This is an example C application using the dissidents' SAMP library.
  5.     It uses the dissidents' requester.library to allow the user to choose a
  6.     SAMP file to load. It then loads the SAMP file, and plays back all of the 
  7.     midi notes (0 to 127) of the PlayMap using the audio device. We only look at 
  8.     the first PlayMap byte if NumOfChans > 1 (i.e. MULTI PlayMode). This example 
  9.     is in the public domain, and may be used by any other program.
  10.  
  11.     Written by Jim Fiore and Jeff Glatt, dissidents
  12.  
  13.     Quicky make instructions:
  14.     
  15.     Manx 3.6
  16.     
  17.     cc +P Exam.c
  18.     ln Exam.o SampInterface.o FileInterface.o -lcl32
  19.     
  20.     Lattice 5.0
  21.     
  22.     lc -b0 Exam.c
  23.     blink lib:c.o Exam.o SampInterface.o FileInterface.o to Exam lib lib:lcnb.lib lib:amiga.lib
  24.     ( Note, proto doesn't seem to contain BeginIO, which is why amiga.lib is added. )
  25.  
  26.  
  27. ****************************************************************************/
  28.  
  29. #ifdef AZTEC_C
  30. #define NARGS
  31. #define NO_PRAGMAS
  32. #endif
  33.  
  34. #include "exec/types.h"
  35. #include "exec/tasks.h"
  36. #include "exec/memory.h"
  37. #include "hardware/custom.h"
  38. #include "hardware/dmabits.h"
  39. #include "libraries/dos.h"
  40. #include "libraries/dosextens.h"
  41. #include "devices/audio.h"
  42.  
  43. #ifdef AZTEC_C
  44. #include "functions.h"
  45. #else
  46. #include "proto/all.h"
  47. #endif
  48.  
  49. #include "intuition/intuition.h"
  50. #include "intuition/intuitionbase.h"
  51.  
  52. #include "graphics/gfx.h"
  53. #include "graphics/gfxbase.h"
  54. #include "graphics/rastport.h"
  55. #include "graphics/gfxmacros.h"
  56. #include "graphics/view.h"
  57. #include "graphics/text.h"
  58.  
  59. /*=============== Include files for dissidents' custom libraries ===========*/
  60. #include "FileIO.h"
  61. #include "SAMP.h"
  62.  
  63. /*=================== For audio.device playback of wave ==================*/
  64. struct IOAudio ioaudio = {0}, ioaudio2 = {0};
  65. struct MsgPort *audPort = 0L;
  66. UBYTE  audio_gub = 0;
  67. UBYTE  anychan[4] = {1,2,4,8};
  68.  
  69. /*================== For dissidents requester.library =================*/
  70. struct RequesterBase          *RequesterBase = 0L;
  71. struct FileIO                 *fileio_sup = 0L;
  72. UBYTE  fileio_filename[260];
  73.  
  74. /*==================== For dissidents samp.library =====================*/
  75. extern LONG SAMPError;            /* This comes from SAMPInterface.asm */
  76. struct SAMPBase               *SAMPBase = 0L;
  77. struct SAMPInfo                    *libSAMPinfo = 0L;
  78. #define playCHANS 4
  79. UBYTE  play_map[128 * playCHANS];  /* let NumOfChans = 4 */
  80. struct TransposeNode          *T_List = 0L;
  81.  
  82. /* Declare 32 SampleHeader64 structs for loading up to 32 waves in a SAMP */
  83. #define  MAXSAMPLES 32L
  84. #define  NAMESIZE   16
  85.  
  86. struct SampleHeader64 samp_head[MAXSAMPLES];
  87.  
  88. UBYTE  nameBuffers[MAXSAMPLES][NAMESIZE];  /* for the wave names */
  89.  
  90.  
  91. /*====================== The C Application begins here ==================*/
  92.  
  93. #ifdef NARGS
  94. VOID open_all(), exit_all();
  95. #else
  96. VOID open_all( void ), exit_all( void );
  97. long main( long, char ** );
  98. #endif
  99.  
  100. main( argc, argv )
  101. long argc;
  102. char *argv[];
  103. {
  104.     ULONG    totalWaves, err, p;
  105.     LONG  transposeAmount;
  106.     USHORT waveNum, i;
  107.     UBYTE *address, b;
  108.  
  109.     /* Open libs, initialize audio dev and structures, get FileIO struct */
  110.     open_all();
  111.  
  112.     /* choose the SAMP file to load via the requester.library */
  113.     address = DoFileIOWindow(fileio_sup, 0L);
  114.     if( address == fileio_filename )
  115.     {
  116.  
  117.         /* Open the file and determine if it is a SAMP */
  118.         if( !(libSAMPinfo = OpenSampRead( fileio_filename, 0L )) )
  119.         {
  120.             address = SAMPErrorMsg( SAMPError );
  121.             puts( address );
  122.             exit_all();
  123.         }
  124.         libSAMPinfo->MaxChars = NAMESIZE;
  125.  
  126.         /* Load up to 32 waves starting with the first wave in the SAMP (0)
  127.             We'll load these into our samp_head and nameBuffers starting with
  128.             the first member of each array. */
  129.         if( !(totalWaves = ReadWaves( 0L, MAXSAMPLES, &nameBuffers[0][0], &samp_head[0] )) )
  130.         {
  131.             /* We didn't load ANY waves! Must be an empty SAMP. */
  132.             CloseSamp();
  133.             address = SAMPErrorMsg( SAMPError );
  134.             puts( address );
  135.             exit_all();
  136.         }
  137.  
  138.         /* This zeros out our playMap and transfers the loaded playMap to our
  139.             passed playMap. It adjusts for difference in numOfChans between our
  140.             program's playMap (4 chans) and the loaded playMap (0 to 4 chans).
  141.             Also, it ensures that only those wave numbers that we loaded appear
  142.             in our play_map. We pass an offset of 0 because we loaded from the
  143.             first SampleHeader64 in our samp_head array. */
  144.         LoadPlaymap( totalWaves, 4L, 0L, 0L, &play_map[0] );
  145.  
  146.         for( i=0; i<totalWaves; ++i )
  147.        {
  148.             /* The SAMP library set the TransTable fields of each loaded
  149.                 SampleHeader64 struct to that wave's samplePeriod. Now we use this
  150.                 function to get all of the needed TransposeTables. This function
  151.                 links any new TranposeTable into our T_List and returns the
  152.                 address of that TransposeTable's ORIGINAL_PITCH. We'll simply
  153.                 restore this return in the SampleHeader64's TransTable field. */
  154.             samp_head[i].TransTable = MakeTransTable( (ULONG)(samp_head[i].TransTable), 6L, 6L, &T_List );
  155.         }
  156.  
  157.         CloseSamp();
  158.  
  159.  
  160.     /* playback the wave using audio.device. Do multi playMode (i.e. only use
  161.        the 1st byte for each midi note in the playMap). */
  162.         ioaudio.ioa_Volume = 64;    /* Play everything with MAX volume and forget velocity table */
  163.         ioaudio2.ioa_Volume = 64;
  164.         ioaudio.ioa_Request.io_Command = CMD_WRITE;
  165.         ioaudio2.ioa_Request.io_Command = CMD_WRITE;
  166.  
  167.         for( i=0; i<128; ++i ) 
  168.         {                       /* play all 128 midi notes */
  169.             waveNum = i*playCHANS;
  170.             if( b = play_map[waveNum] )
  171.            {
  172.                 --b;                        /* To adjust wave number from 0 instead of 1 */
  173.                 waveNum = (USHORT)b;    /* Recast the PlayMap UBYTE as a USHORT */
  174.  
  175.                 /* show the user the name of the wave playing back */
  176.                 puts("\nPlaying...");
  177.                 puts( &nameBuffers[b][0] );
  178.  
  179.                 /* Play the OneShot portion */
  180.                 ioaudio.ioa_Data = (UBYTE *)samp_head[waveNum].OneShotAddr;
  181.                 ioaudio.ioa_Length = samp_head[waveNum].OneShotEnd - samp_head[waveNum].OneShotAddr;
  182.                 ioaudio.ioa_Request.io_Flags = ADIOF_PERVOL;
  183.                 ioaudio.ioa_Cycles = 1;
  184.                 if( samp_head[waveNum].TransTable )
  185.                {
  186.                     transposeAmount = (LONG)i - (LONG)(samp_head[waveNum].RootNote);
  187.                     ioaudio.ioa_Period = *(samp_head[waveNum].TransTable + transposeAmount); /* transposeAmount automatically x4 */
  188.                 }
  189.                 else
  190.                     /* Actually, we could've saved the original sample rate so that
  191.                         we could play it back at its original pitch if the loaded
  192.                         MHDR numOfChans = 0, or if we couldn't make a transpose table. */
  193.                     break;
  194.  
  195.                 if( ioaudio.ioa_Period )    /* A zero means out of range */
  196.                 {
  197.                     ioaudio2.ioa_Data = (UBYTE *)samp_head[waveNum].OneShotEnd;
  198.                     ioaudio2.ioa_Request.io_Flags = 0;
  199.                     ioaudio2.ioa_Cycles = 1;        /* only play the loop once. */
  200.                     ioaudio2.ioa_Period = ioaudio.ioa_Period;
  201.                     BeginIO( (struct IORequest *)(&ioaudio) );
  202.  
  203.                     if( ioaudio2.ioa_Length = samp_head[waveNum].LoopLength * 2 )
  204.                         BeginIO( (struct IORequest *)(&ioaudio2) );
  205.                     err = WaitIO( (struct IORequest *)(&ioaudio) );
  206.                     GetMsg( audPort );
  207.                     if( ioaudio2.ioa_Length )
  208.                     {
  209.                         err = WaitIO( (struct IORequest *)(&ioaudio2) );
  210.                         GetMsg( audPort );
  211.                     }
  212.                 }
  213.                 else
  214.                     puts( "Period out of range of audio hardware" );
  215.             }
  216.         }
  217.  
  218.     /* Free the sample memory (for "total" # of waves) */
  219.         for( p=0; p<totalWaves; ++p )
  220.        {
  221.             FreeMem( samp_head[p].OneShotAddr, samp_head[p].WaveSize );
  222.         }
  223.  
  224.     /* Free the TransposeTables */
  225.         FreeTTables( &T_List );
  226.  
  227.     /* Now close down and get some food, Laurey's is almost closed... */
  228.         exit_all();
  229.     }
  230.  
  231. }   /********** end of main() ********/
  232.  
  233.  
  234.  
  235. /*---------- Opens audio dev, audio port, SAMP and FileIO libs ---------*/
  236.  
  237. VOID open_all()
  238. {
  239.     /* Open the requester library and allocate/setup a FileIO structure */
  240.     if( !(RequesterBase=(struct RequesterBase *)OpenLibrary("requester.library", 1L)) )
  241.     {
  242.         puts("need requester.library, Not ARP");
  243.         exit_all();
  244.     }
  245.  
  246.     if( !(fileio_sup = GetFileIO()) )
  247.     {
  248.         puts("Can't get FileIO support");
  249.         exit_all();
  250.     }
  251.  
  252.     fileio_sup->X = 6;
  253.     fileio_sup->Y = 11;
  254.     fileio_sup->DrawMode = JAM2;
  255.     fileio_sup->PenA = 0;
  256.     fileio_sup->PenB = 1;
  257.     fileio_sup->Buffer = (UBYTE *)fileio_filename;
  258.  
  259.     /* Open the SAMP reader/writer library */
  260.     if( !(SAMPBase=(struct SAMPBase *)OpenLibrary("samp.library", 0L)) )
  261.     {
  262.         puts("need samp.library, ratface");
  263.         exit_all();
  264.     }
  265.  
  266.     /* Open audio.device and allocate a channel */
  267.  
  268.     if( !(audPort = CreatePort( "SAMP_Port", 0 )) )
  269.     {
  270.         puts("no audio port");
  271.         exit_all();
  272.     }
  273.  
  274.     ioaudio.ioa_Request.io_Message.mn_ReplyPort = audPort;
  275.  
  276.     ioaudio.ioa_Request.io_Command = ADCMD_ALLOCATE;
  277.     ioaudio.ioa_Data = (UBYTE *)anychan;
  278.     ioaudio.ioa_Length = 4;
  279.     ioaudio.ioa_Request.io_Flags = ADIOF_NOWAIT | IOF_QUICK;
  280.     if( OpenDevice("audio.device", 0, (struct IORequest *)(&ioaudio), 0 ) )
  281.     {
  282.         puts("audio device open error");
  283.         exit_all();
  284.     }
  285.  
  286.     if( !(ioaudio.ioa_Request.io_Flags & IOF_QUICK ) )
  287.         GetMsg( audPort );
  288.  
  289.     audio_gub = 1;
  290.     
  291.     ioaudio2 = ioaudio;
  292.  
  293. }
  294.  
  295.  
  296.  
  297.  
  298. /*-----------closes audio dev, audio port, FileIO and SAMP libs---------*/
  299.  
  300. VOID exit_all()
  301. {
  302.     if( audio_gub )     CloseDevice( (struct IORequest *)(&ioaudio) );
  303.     if( audPort )       DeletePort( audPort );
  304.     if( fileio_sup )    ReleaseFileIO( fileio_sup );
  305.     if( RequesterBase ) CloseLibrary( RequesterBase );
  306.     if( SAMPBase )      CloseLibrary( SAMPBase );
  307.     exit( FALSE );
  308.  
  309. }
  310.  
  311. /* ************************* DAT'S ALL FOLKS ***************************** */
  312.