home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************/
- /* */
- /* Amiga C Encyclopedia (ACE) V3.0 Amiga C Club (ACC) */
- /* ------------------------------- ------------------ */
- /* */
- /* Book: ACM Devices Amiga C Club */
- /* Chapter: AudioDevice Tulevagen 22 */
- /* File: Example3.c 181 41 LIDINGO */
- /* Author: Anders Bjerin SWEDEN */
- /* Date: 92-04-21 */
- /* Version: 1.00 */
- /* */
- /* Copyright 1992, Anders Bjerin - Amiga C Club (ACC) */
- /* */
- /* Registered members may use this program freely in their */
- /* own commercial/noncommercial programs/articles. */
- /* */
- /***********************************************************/
-
- /* This program demonstrates how you can play some sampled */
- /* data. Remeber that sampled data is just a more complicatd */
- /* waveform. */
- /* */
- /* The sampled sound has been converted into numbers by */
- /* "PrintSound", a utilitiy included in the "Sound" manual. */
-
-
-
- #include <exec/types.h> /* STRPTR */
- #include <exec/memory.h> /* MEMF_CHIP */
- #include <devices/audio.h> /* Audio Device */
-
-
-
- /* The audio channels: (Sadly these constants */
- /* have not been defined in any header file.) */
-
- /* Values: */
- #define LEFT0B 0
- #define RIGHT0B 1
- #define RIGHT1B 2
- #define LEFT1B 3
-
- /* Bit fields: */
- #define LEFT0F (1<<LEFT0B)
- #define RIGHT0F (1<<RIGHT0B)
- #define RIGHT1F (1<<RIGHT1B)
- #define LEFT1F (1<<LEFT1B)
-
- /* Sound priorities: */
- #define SOUND_UNSTOPPABLE 127
- #define SOUND_EMERGENCIES 95
- #define SOUND_ATTENTION 85
- #define SOUND_SPEECH 75
- #define SOUND_INFORMATION 60
- #define SOUND_MUSIC 0
- #define SOUND_EFFECT -35
- #define SOUND_BACKGROUND -90
- #define SOUND_SILENCE -128
-
- /* The clock constant: */
- #define NTSC_CLOCK 3579545 /* American Amigas - 60Hz */
- #define PAL_CLOCK 3546895 /* European Amigas - 50Hz */
-
- /* Define min/max-volumes: */
- #define MAXVOLUME 64
- #define MINVOLUME 0
-
-
-
- /* Declare a pointer to our reply port: */
- struct MsgPort *replymp = NULL;
-
- /* Declare a pointer to our audio request block: */
- struct IOAudio *audio_req = NULL;
-
-
-
- /* Our list of preffered channel combinations: */
- /* (First we try to reserve the first channel, */
- /* then the second, third and finally fourth */
- /* audio channel.) */
- UBYTE allocation_array[]=
- {
- LEFT0F,
- RIGHT0F,
- RIGHT1F,
- LEFT1F
- };
-
-
-
- /* Declare a pointer to some soundwave data: */
- BYTE *beep_wave = NULL;
-
- /* This is some sampled sound data which will be copied */
- /* into some chip memory before we try to play it: */
- /* (This data was converted to numbers by PrintSound.) */
-
- /************************************/
- /* SoundData prepared by PrintSound */
- /* Anders Bjerin Amiga C Club */
- /* */
- /* File name: Beep.snd */
- /* Record Rate: 10100 */
- /* File Length: 602 */
- /************************************/
-
- BYTE chip beep_data[]=
- {
- 4,11,9,0,-11,-9,3,15,17,-6,-34,
- -31,22,93,63,-20,-106,-85,0,104,84,-9,
- -98,-68,17,114,57,-42,-109,-33,61,101,9,
- -88,-95,7,101,46,-39,-109,-33,60,114,14,
- -79,-79,19,112,46,-53,-111,-20,73,104,3,
- -95,-80,22,111,36,-57,-111,-19,84,96,-11,
- -103,-63,34,114,23,-71,-107,-7,90,82,-15,
- -106,-55,47,119,22,-69,-103,-4,98,87,-20,
- -107,-53,46,117,20,-77,-103,1,100,73,-25,
- -111,-47,58,122,17,-77,-96,6,111,66,-26,
- -107,-39,60,122,22,-79,-93,19,117,53,-39,
- -109,-23,82,115,3,-90,-74,30,122,41,-57,
- -111,-14,85,100,-6,-103,-68,42,123,28,-61,
- -109,-11,93,101,-9,-103,-61,41,123,28,-68,
- -106,-3,96,92,-11,-107,-58,52,123,19,-73,
- -100,0,104,87,-20,-109,-49,55,119,12,-85,
- -96,11,111,73,-25,-114,-41,68,115,4,-88,
- -85,15,119,65,-38,-114,-30,73,112,4,-93,
- -87,23,119,50,-42,-111,-25,79,114,3,-92,
- -82,22,120,47,-52,-114,-19,82,107,-1,-100,
- -73,38,122,28,-66,-101,-6,100,92,-25,-111,
- -46,58,119,9,-88,-92,14,114,63,-36,-115,
- -33,76,109,-4,-96,-76,23,127,58,-44,-115,
- -26,76,103,0,-96,-85,19,119,57,-38,-114,
- -34,74,103,-4,-96,-77,25,122,44,-57,-112,
- -14,88,84,-19,-109,-61,47,123,23,-74,-103,
- 6,109,57,-44,-117,-33,69,111,6,-95,-88,
- 25,117,39,-53,-119,-25,85,100,-7,-104,-74,
- 33,123,36,-61,-115,-9,93,84,-15,-111,-63,
- 52,122,19,-73,-106,6,111,61,-33,-114,-38,
- 68,114,7,-84,-88,23,117,44,-50,-114,-17,
- 88,93,-4,-101,-76,41,120,28,-60,-107,-6,
- 103,80,-19,-109,-58,50,122,23,-71,-101,7,
- 109,68,-22,-111,-52,65,119,12,-79,-88,19,
- 120,58,-41,-114,-28,80,101,-1,-98,-73,42,
- 122,30,-61,-107,-4,106,77,-26,-106,-39,71,
- 109,7,-88,-88,30,119,42,-49,-109,-14,100,
- 92,-11,-101,-66,47,119,33,-63,-107,-1,103,
- 73,-22,-106,-49,69,109,11,-80,-90,22,111,
- 49,-46,-106,-22,84,88,-4,-92,-68,52,107,
- 23,-63,-95,3,101,66,-28,-98,-36,69,95,
- 7,-79,-69,38,100,31,-53,-87,-3,85,63,
- -26,-88,-38,58,88,14,-68,-73,20,87,41,
- -38,-80,-17,68,63,-14,-73,-42,42,79,22,
- -50,-63,11,73,44,-25,-68,-22,53,65,0,
- -58,-44,26,69,28,-41,-61,-3,58,46,-15,
- -65,-38,34,65,17,-42,-53,3,57,38,-23,
- -55,-17,41,49,-1,-52,-41,25,61,22,-38,
- -58,-6,60,53,-7,-60,-39,31,68,25,-39,
- -65,-4,57,47,-11,-60,-36,34,57,11,-44,
- -58,-1,55,41,-12,-55,-31,30,53,17,-33,
- -50,-4,44,39,-3,-42,-30,19,41,12,-26,
- -36,-3,34,31,-3,-34,-28,7,42,20,-12,
- -28,-9,17,22,1,-19,-15,3,15,7,-9,
- -14,-3,9,9,-1,-7,-4,3
- };
-
- /* To sample sound you have to use a sound sampler. If */
- /* you do not have any I can help you and do it for */
- /* you, free of charge. (Registered members only.) */
-
-
-
-
- /* Declare our functions: */
- void main();
- void clean_up( STRPTR text );
-
-
-
- void main()
- {
- /* Error messages: */
- BYTE error;
-
- /* The channel we have received: */
- UBYTE channel;
-
- /* Used in the loops: */
- int loop;
-
-
-
- /* Get a reply port: (No name, priority 0) */
- replymp = (struct MsgPort *)
- CreatePort( NULL, 0 );
- if( !replymp )
- clean_up( "Could not create the reply port!" );
-
-
-
- /* Allocate and preinitialize an audio request block: */
- audio_req = (struct IOAudio *)
- CreateExtIO( replymp, sizeof( struct IOAudio ) );
- if( !audio_req )
- clean_up( "Not enough memory for the IOAudio structure!" );
-
-
-
- /* Open the Audio Device: (We will try to */
- /* reserve a sound channel later on.) */
- error = OpenDevice( AUDIONAME, 0, audio_req, 0 );
- if( error )
- {
- /* Clear the "io_Device" flag since we have not opened the device: */
- audio_req->ioa_Request.io_Device = NULL;
-
- /* Quit: */
- clean_up( "Could not open the Audio Device!" );
- }
-
-
-
- /* Try to reserve a channel: */
- audio_req->ioa_Request.io_Command = ADCMD_ALLOCATE;
-
- /* Set sound priority: (We are going to play a sound effect.) */
- audio_req->ioa_Request.io_Message.mn_Node.ln_Pri = SOUND_EFFECT;
-
- /* Do not wait for any channels to be free, */
- /* return immediately, successfully or not: */
- audio_req->ioa_Request.io_Flags = ADIOF_NOWAIT;
-
- /* Give the request block a pointer to our allocation array: */
- audio_req->ioa_Data = allocation_array;
-
- /* Set the length of the allocation array: */
- audio_req->ioa_Length = sizeof( allocation_array );
-
- /* Do our request: */
- BeginIO( audio_req );
-
- /* Wait for the request to be completed: */
- error = WaitIO( audio_req );
-
- /* Everything OK? */
- if( error )
- clean_up( "No channel available!" );
-
-
-
- /* Check which channel we received: */
- channel = (UBYTE) audio_req->ioa_Request.io_Unit;
-
- /* Check which channel we received: */
- channel = (UBYTE) audio_req->ioa_Request.io_Unit;
-
- if( channel & LEFT0F )
- printf( "First left channel!\n" );
-
- if( channel & RIGHT0F )
- printf( "First right channel!\n" );
-
- if( channel & RIGHT1F )
- printf( "Second right channel!\n" );
-
- if( channel & LEFT1F )
- printf( "Second left channel!\n" );
-
-
-
- /* Allocate some memory where we can store the waveform we */
- /* want to use. Note that it must be Chip memory, and placed */
- /* on a word boundary! */
- beep_wave = (BYTE *) AllocMem( sizeof( beep_data ), MEMF_CHIP );
- if( !beep_wave )
- clean_up( "Could not allocate enough memory for the beep wave!" );
-
- /* Copy the beep data to some chip memory: */
- for( loop = 0; loop < sizeof( beep_data ); loop++ )
- beep_wave[ loop ] = beep_data[ loop ];
-
-
-
- /* Give the request block a pointer to the waveform: */
- audio_req->ioa_Data = beep_wave;
-
- /* Set the length of the waveform: */
- /* (Must be an even number of bytes.) */
- audio_req->ioa_Length = sizeof( beep_data );
-
- /* Play the waveform 1 time: */
- audio_req->ioa_Cycles = 1;
-
- /* Going to play a tune: */
- audio_req->ioa_Request.io_Command = CMD_WRITE;
-
- /* Use the volume and period fields of the request block: */
- /* (If we do not set this flag the previous volume and */
- /* period values will be used.) */
- audio_req->ioa_Request.io_Flags = ADIOF_PERVOL;
-
- /* Medium volume: */
- audio_req->ioa_Volume = 32;
-
- /* Set the period: (The period value can be calculated */
- /* by dividing the clock constant with the record rate. */
- /* The record rate is also printed by PrintSound, */
- /* together with the sample data values.) */
- audio_req->ioa_Period = PAL_CLOCK / 10100;
-
-
-
- /* Tell the user to be prepared: */
- printf( "\"The machine that goes Bing!\"\n" );
-
- /* Start to play the sound: */
- BeginIO( audio_req );
-
- /* Wait for the soiund to be completed: */
- error = WaitIO( audio_req );
-
- /* Was the note successfully played? */
- if( error )
- clean_up( "Error while playing!" );
-
-
-
- /* Clean up and quit: */
- clean_up( "The End!" );
- }
-
-
-
- /* Close and return everything that has been */
- /* opened and allocated before we quit: */
-
- void clean_up( STRPTR text )
- {
- /* If we have a request block and it does not contain */
- /* any errors we know that a channel has been allocated */
- /* and must be deallocated: */
- if( audio_req && !(audio_req->ioa_Request.io_Error) )
- {
- /* Free the channel: */
- audio_req->ioa_Request.io_Command = ADCMD_FREE;
-
- /* We are allowed to use the function DoIO() for */
- /* this request since it will not change any */
- /* values that are vital for us: */
- DoIO( audio_req );
-
- /* The lock is automatically unlocked when we */
- /* free the audio channel. */
- }
-
- /* Empty the reply port: */
- while( GetMsg( replymp ) )
- printf( "Collected a message at the reply port.\n" );
-
- /* If we have a request block and the "io_Device" field */
- /* is not zero, we know that the device has successfully */
- /* been opened and must now be closed: */
- if( audio_req && audio_req->ioa_Request.io_Device )
- CloseDevice( audio_req );
-
- /* Remove the replyport: */
- if( replymp )
- DeletePort( replymp);
-
- /* Dealocate the IOAudio structure: */
- if( audio_req )
- DeleteExtIO( audio_req, sizeof( struct IOAudio ) );
-
- /* Dealocate the beep waveform: */
- if( beep_wave )
- FreeMem( beep_wave, sizeof( beep_data ) );
-
- /* Print the last message: */
- printf( "%s\n", text );
-
- /* Quit: */
- exit( 0 );
- }
-
-
-