home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d3xx
/
d307
/
samp.lha
/
Samp
/
Exam.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-13
|
8KB
|
285 lines
/***************************************************************************
Set your editor's TAB width to 3.
This is an example C application using the dissidents' SAMP library.
It uses the dissidents' requester.library to allow the user to choose a
SAMP file to load. It then loads the SAMP file, and plays back all of the midi
notes (0 to 127) of the PlayMap using the audio device. This example is in the
public domain, and may be used by any other program.
Written by Jim Fiore and Jeff Glatt, dissidents
****************************************************************************/
#include "exec/types.h"
#include "exec/memory.h"
#include "hardware/custom.h"
#include "hardware/dmabits.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"
#include "devices/audio.h"
#include "functions.h"
#include "exec/tasks.h"
#include "intuition/intuition.h"
#include "intuition/intuitionbase.h"
#include "graphics/gfx.h"
#include "graphics/gfxbase.h"
#include "graphics/rastport.h"
#include "graphics/gfxmacros.h"
#include "graphics/view.h"
#include "graphics/text.h"
/*=============== Include files for dissidents' custom libraries ===========*/
#include "FileIO.h"
#include "SAMP.h"
/*=================== For audio.device playback of wave ==================*/
struct IOAudio ioaudio = {0}, ioaudio2 = {0};
struct MsgPort *audPort = 0L;
UBYTE audio_gub = 0;
UBYTE anychan[4] = {1,2,4,8};
/*================== 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 */
struct TransposeNode *T_List = 0L;
/* Declare 32 SampleHeader64 structs for loading up to 32 waves in a SAMP */
#define MAXSAMPLES 32
#define NAMESIZE 16
struct SampleHeader64 samp_head[MAXSAMPLES];
UBYTE nameBuffers[NAMESIZE*MAXSAMPLES]; /* for the wave names */
/*====================== The C Application begins here ==================*/
VOID open_all(), exit_all();
main()
{
ULONG totalWaves, err, p;
LONG transposeAmount;
USHORT waveNum, i;
UBYTE *address, b;
struct TransposeNode *transL, *transL2;
/* Open libs, initialize audio dev and structures, 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();
}
libSAMPinfo->MaxChars = NAMESIZE;
/* 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, 32L , &nameBuffers[0], &samp_head[0] )) )
{
/* We didn't load ANY waves! Must be an empty SAMP. */
CloseSamp();
address = SAMPErrorMsg( SAMPError );
puts( address );
exit_all();
}
/* This 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. */
LoadPlaymap(totalWaves, 4L, 0L, 0L, &play_map[0]);
for(i=0; i<totalWaves; ++i)
{
/* The SAMP library set the TransposeTable fields of each loaded
SampleHeader64 struct to that wave's sampleRate. 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. */
samp_head[i].TransTable = MakeTransTable( samp_head[i].TransTable, 6L, 6L, &T_List );
}
CloseSamp();
/* playback the wave using audio.device. Do multi playMode (i.e. only use
the 1st byte for each midi note in the playMap). */
ioaudio.ioa_Volume = 64; /* Play everything with MAX volume and forget velocity table */
ioaudio2.ioa_Volume = 64;
ioaudio.ioa_Request.io_Command = CMD_WRITE;
ioaudio2.ioa_Request.io_Command = CMD_WRITE;
for( i=0; i<128; ++i )
{ /* play all 128 midi notes */
waveNum = i*4;
if( b = play_map[waveNum] )
{
--b;
waveNum = (USHORT)b; /* to adjust wave number from 0 instead of 1 */
puts("\nPlaying...");
puts(&nameBuffers[b*NAMESIZE]);
ioaudio.ioa_Data = (UBYTE *)samp_head[waveNum].OneShotAddr;
ioaudio.ioa_Length = samp_head[waveNum].OneShotEnd - samp_head[waveNum].OneShotAddr;
ioaudio.ioa_Request.io_Flags = ADIOF_PERVOL;
ioaudio.ioa_Cycles = 1;
if( samp_head[waveNum].TransTable )
{
transposeAmount = (LONG)i - (LONG)(samp_head[waveNum].RootNote);
ioaudio.ioa_Period = *(samp_head[waveNum].TransTable + transposeAmount); /* transposeAmount automatically x2 */
}
else
/* Actually, we could've saved the original sample rate so that
we could play it back at its original pitch if the loaded
MHDR numOfChans = 0, or we can't make a transpose table. */
break;
ioaudio2.ioa_Data = (UBYTE *)samp_head[waveNum].OneShotEnd;
ioaudio2.ioa_Request.io_Flags = 0;
ioaudio2.ioa_Cycles = 1; /* only play the loop once. */
ioaudio2.ioa_Period = ioaudio.ioa_Period;
BeginIO( &ioaudio );
if( ioaudio2.ioa_Length = samp_head[waveNum].LoopLength * 2 )
BeginIO( &ioaudio2 );
err = WaitIO( &ioaudio );
GetMsg( audPort );
if(ioaudio2.ioa_Length)
{
err = WaitIO( &ioaudio2 );
GetMsg( audPort );
}
}
}
/* Free the sample memory (for "total" # of waves) */
for(p=0; p<totalWaves; ++p)
{
FreeMem(samp_head[p].OneShotAddr,samp_head[p].WaveSize);
}
/* Free the TransposeTables */
if( (transL = T_List) != 0 )
{
while( transL )
{
transL2 = transL->Next;
FreeMem( transL, transL->TSize );
transL = transL2;
}
}
/* Now close down and get some food */
exit_all();
}
} /********** end of main() ********/
/*---------- Opens audio dev, audio port, SAMP and FileIO libs ---------*/
VOID open_all()
{
ULONG err,x,total;
/* Open the requester library and allocate/setup a FileIO structure */
if( !(RequesterBase=(struct RequesterBase *)OpenLibrary("requester.library", 1L)) )
{
puts("need requester.library, Not ARP\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("need samp.library you knuckle-head\n");
exit_all();
}
/* Open audio.device and allocate a channel */
if( !(audPort = CreatePort( "SAMP_Port", 0 )) )
{
puts("no audio port");
exit_all();
}
ioaudio.ioa_Request.io_Message.mn_ReplyPort = audPort;
ioaudio.ioa_Request.io_Command = ADCMD_ALLOCATE;
ioaudio.ioa_Data = (UBYTE *)anychan;
ioaudio.ioa_Length = 4;
ioaudio.ioa_Request.io_Flags = ADIOF_NOWAIT | IOF_QUICK;
if( OpenDevice("audio.device", 0, &ioaudio, 0 ) )
{
puts("audio device open error\n");
exit_all();
}
if( !(ioaudio.ioa_Request.io_Flags & IOF_QUICK ) )
GetMsg( audPort );
audio_gub = 1;
ioaudio2 = ioaudio;
/* initialize the AudioIO for the looping portion */
}
/*-----------closes audio dev, audio port, FileIO and SAMP libs---------*/
VOID exit_all()
{
if( audio_gub ) CloseDevice( &ioaudio );
if( audPort ) DeletePort( audPort );
if( fileio_sup ) ReleaseFileIO( fileio_sup );
if( RequesterBase ) CloseLibrary( RequesterBase );
if( SAMPBase ) CloseLibrary( SAMPBase );
exit( FALSE );
}