home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD2.bin
/
bbs
/
dev
/
cmanual-3.0.lha
/
CManual
/
Devices
/
AudioDevice
/
Example6.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-12
|
15KB
|
530 lines
/***********************************************************/
/* */
/* Amiga C Encyclopedia (ACE) V3.0 Amiga C Club (ACC) */
/* ------------------------------- ------------------ */
/* */
/* Book: ACM Devices Amiga C Club */
/* Chapter: AudioDevice Tulevagen 22 */
/* File: Example6.c 181 41 LIDINGO */
/* Author: Anders Bjerin SWEDEN */
/* Date: 92-04-24 */
/* 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 will play some notes (A to G#) with help */
/* of the Audio Device. It will use as many audio channels */
/* as possible, and we are modifying the hardware registers */
/* directly instead of using the special Audio Device */
/* commands. */
/* */
/* You are allowed to use the hardware registers directly */
/* if you make sure that no other task can steel them from */
/* you before you have cleared all necessary registers. */
#include <exec/types.h> /* STRPTR */
#include <exec/memory.h> /* MEMF_CHIP */
#include <devices/audio.h> /* Audio Device */
#include <hardware/custom.h> /* struct Custom */
#include <hardware/dmabits.h> /* DMAF_SETCLR */
/* 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 */
/* Some common notes (their frequencies are */
/* defined later on in this program): */
#define NOTE_A 0
#define NOTE_Ax 1
#define NOTE_B 2
#define NOTE_C 3
#define NOTE_Cx 4
#define NOTE_D 5
#define NOTE_Dx 6
#define NOTE_E 7
#define NOTE_F 8
#define NOTE_Fx 9
#define NOTE_G 10
#define NOTE_Gx 11
/* An octave consists of 12 notes: */
#define OCTAVE 12
/* Define min/max-volumes: */
#define MAXVOLUME 64
#define MINVOLUME 0
/* Our square waveform data consists of two samples: */
/* (Waveform data must alwyas be an even number of */
/* byte long.) */
#define SQUARE_DATA_LENGTH 2
/* Timer units (50 units / second): */
#define SECONDS *50
/* Declare a pointer to our reply port: */
struct MsgPort *replymp = NULL;
/* Declare a pointer to our audio request block: */
struct IOAudio *audio_req = NULL;
/* Declare a pointer to our lock: */
struct IOAudio *audio_lock = NULL;
/* Our list of preffered channel combinations: */
/* (We want as many channels as possible. The */
/* way I write it may look a bit strange, but */
/* it is actually easier to understand this */
/* code, than if we had removed all spaces.) */
UBYTE desired_channels[]=
{
LEFT0F | RIGHT0F | RIGHT1F | LEFT1F,
LEFT0F | RIGHT0F | RIGHT1F ,
LEFT0F | RIGHT0F | LEFT1F,
LEFT0F | RIGHT0F ,
LEFT0F | RIGHT1F | LEFT1F,
LEFT0F | RIGHT1F ,
LEFT0F | LEFT1F,
LEFT0F ,
RIGHT0F | RIGHT1F | LEFT1F,
RIGHT0F | RIGHT1F ,
RIGHT0F | LEFT1F,
RIGHT0F ,
RIGHT1F | LEFT1F,
RIGHT1F ,
LEFT1F,
};
/* Declare a pointer to some soundwave data: */
BYTE *square_wave = NULL;
/* The notes (defined above) frequencies. These frequencies */
/* represent notes which are one octave higher than the middle */
/* octave on a piano. To change octave, simply double/half these */
/* values. Ex, A=880, one octave lower A=440, one octave higher */
/* A=1760. */
/* */
/* Instead of changing the frequencies you can of course double */
/* or half the amount of samled waveform data. If you double the */
/* amount of sampled waveformdata you will move down one octave */
/* and vice versa. In this example when we caluculate the period */
/* value we use the length of the vaweform as one parameter. */
/* Therefore, if you change the length of the waveform the same */
/* frequencies will be used. */
UWORD note_frequency[ OCTAVE ]=
{
880.0, /* A */
932.3, /* A# */
987.8, /* B */
1046.5, /* C */
1108.7, /* C# */
1174.7, /* D */
1244.5, /* D# */
1318.5, /* E */
1396.9, /* F */
1480.0, /* F# */
1568.0, /* G */
1661.2 /* G# */
};
/* These structure are defined in the headerfile "hardware/custom.h" */
/* and are automatically connected to the hardware registers. We do */
/* therefore not need to initialize them. */
extern UWORD far dmacon; /* DMA control */
extern struct AudChannel far aud[]; /* Audio channels. */
/* Since the hardware data most certainly will not be within reach */
/* for normal (small) pointers, they must both be declared as far. */
/* Declare our functions: */
void main();
void clean_up( STRPTR text );
void main()
{
/* Error messages: */
BYTE error;
/* The channel we have received: */
UBYTE channels;
/* Current note: */
int note;
/* Pointer to the audio register: */
/* (If we have successfuly reserved */
/* the sound channel we initialize the */
/* corresponding pointer, else it */
/* remains NULL.) */
struct AudChannel *left0_audio_register = NULL;
struct AudChannel *left1_audio_register = NULL;
struct AudChannel *right0_audio_register = NULL;
struct AudChannel *right1_audio_register = NULL;
/* 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!" );
/* Allocate memory for the lock: */
audio_lock = (struct IOAudio *)
CreateExtIO( replymp, sizeof( struct IOAudio ) );
if( !audio_lock )
clean_up( "Not enough memory for the Lock!" );
/* Set sound priority: */
audio_req->ioa_Request.io_Message.mn_Node.ln_Pri = SOUND_EFFECT;
/* Give the audio structure our replyport: */
audio_req->ioa_Request.io_Message.mn_ReplyPort = replymp;
/* Tell the Audio Device which channels we preffere: */
audio_req->ioa_Data = desired_channels;
/* The size of our list of desired channels: */
audio_req->ioa_Length = sizeof( desired_channels );
/* Open the Audio Device and at the same time try to */
/* reserve the channel(s): */
error = OpenDevice( AUDIONAME, 0, audio_req, 0 );
if( error )
{
/* Clear the "io_Device" flag since we have not opened the device: