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 >
C/C++ Source or Header  |  1993-10-12  |  15KB  |  530 lines

  1. /***********************************************************/
  2. /*                                                         */
  3. /* Amiga C Encyclopedia (ACE) V3.0      Amiga C Club (ACC) */
  4. /* -------------------------------      ------------------ */
  5. /*                                                         */
  6. /* Book:    ACM Devices                 Amiga C Club       */
  7. /* Chapter: AudioDevice                 Tulevagen 22       */
  8. /* File:    Example6.c                  181 41  LIDINGO    */
  9. /* Author:  Anders Bjerin               SWEDEN             */
  10. /* Date:    92-04-24                                       */
  11. /* Version: 1.00                                           */
  12. /*                                                         */
  13. /*   Copyright 1992, Anders Bjerin - Amiga C Club (ACC)    */
  14. /*                                                         */
  15. /* Registered members may use this program freely in their */
  16. /*     own commercial/noncommercial programs/articles.     */
  17. /*                                                         */
  18. /***********************************************************/
  19.  
  20. /* This program will play some notes (A to G#) with help    */
  21. /* of the Audio Device. It will use as many audio channels  */
  22. /* as possible, and we are modifying the hardware registers */
  23. /* directly instead of using the special Audio Device       */
  24. /* commands.                                                */ 
  25. /*                                                          */
  26. /* You are allowed to use the hardware registers directly   */
  27. /* if you make sure that no other task can steel them from  */
  28. /* you before you have cleared all necessary registers.     */
  29.  
  30.  
  31.  
  32. #include <exec/types.h>        /* STRPTR         */
  33. #include <exec/memory.h>       /* MEMF_CHIP      */
  34. #include <devices/audio.h>     /* Audio Device   */
  35. #include <hardware/custom.h>   /* struct Custom  */
  36. #include <hardware/dmabits.h>  /* DMAF_SETCLR    */
  37.  
  38.  
  39.  
  40. /* The audio channels: (Sadly these constants */
  41. /* have not been defined in any header file.) */ 
  42.  
  43. /* Values: */
  44. #define LEFT0B   0
  45. #define RIGHT0B  1
  46. #define RIGHT1B  2
  47. #define LEFT1B   3
  48.  
  49. /* Bit fields: */
  50. #define LEFT0F   (1<<LEFT0B)
  51. #define RIGHT0F  (1<<RIGHT0B)
  52. #define RIGHT1F  (1<<RIGHT1B)
  53. #define LEFT1F   (1<<LEFT1B)
  54.  
  55. /* Sound priorities: */
  56. #define SOUND_UNSTOPPABLE  127
  57. #define SOUND_EMERGENCIES   95
  58. #define SOUND_ATTENTION     85
  59. #define SOUND_SPEECH        75
  60. #define SOUND_INFORMATION   60
  61. #define SOUND_MUSIC          0
  62. #define SOUND_EFFECT       -35
  63. #define SOUND_BACKGROUND   -90
  64. #define SOUND_SILENCE     -128
  65.  
  66. /* The clock constant: */
  67. #define NTSC_CLOCK    3579545 /* American Amigas - 60Hz */
  68. #define PAL_CLOCK     3546895 /* European Amigas - 50Hz */
  69.  
  70. /* Some common notes (their frequencies are */
  71. /* defined later on in this program):       */
  72. #define NOTE_A   0
  73. #define NOTE_Ax  1
  74. #define NOTE_B   2
  75. #define NOTE_C   3
  76. #define NOTE_Cx  4
  77. #define NOTE_D   5
  78. #define NOTE_Dx  6
  79. #define NOTE_E   7
  80. #define NOTE_F   8
  81. #define NOTE_Fx  9
  82. #define NOTE_G  10
  83. #define NOTE_Gx 11
  84.  
  85. /* An octave consists of 12 notes: */
  86. #define OCTAVE  12
  87.  
  88. /* Define min/max-volumes: */
  89. #define MAXVOLUME  64
  90. #define MINVOLUME   0
  91.  
  92. /* Our square waveform data consists of two samples: */
  93. /* (Waveform data must alwyas be an even number of   */
  94. /* byte long.)                                       */
  95. #define SQUARE_DATA_LENGTH       2
  96.  
  97. /* Timer units (50 units / second): */
  98. #define SECONDS *50
  99.  
  100.  
  101.  
  102. /* Declare a pointer to our reply port: */
  103. struct MsgPort *replymp = NULL;
  104.  
  105. /* Declare a pointer to our audio request block: */
  106. struct IOAudio *audio_req = NULL;
  107.  
  108. /* Declare a pointer to our lock: */
  109. struct IOAudio *audio_lock = NULL;
  110.  
  111.  
  112.  
  113. /* Our list of preffered channel combinations: */
  114. /* (We want as many channels as possible. The  */
  115. /* way I write it may look a bit strange, but  */
  116. /* it is actually easier to understand this    */
  117. /* code, than if we had removed all spaces.)   */
  118.  
  119. UBYTE desired_channels[]=
  120. {
  121.   LEFT0F | RIGHT0F | RIGHT1F | LEFT1F,
  122.   LEFT0F | RIGHT0F | RIGHT1F         ,
  123.   LEFT0F | RIGHT0F           | LEFT1F,
  124.   LEFT0F | RIGHT0F                   ,
  125.   LEFT0F           | RIGHT1F | LEFT1F,
  126.   LEFT0F           | RIGHT1F         ,
  127.   LEFT0F                     | LEFT1F,
  128.   LEFT0F                             ,
  129.            RIGHT0F | RIGHT1F | LEFT1F,
  130.            RIGHT0F | RIGHT1F         ,
  131.            RIGHT0F           | LEFT1F,
  132.            RIGHT0F                   ,
  133.                      RIGHT1F | LEFT1F,
  134.                      RIGHT1F         ,
  135.                                LEFT1F,
  136. };
  137.  
  138.  
  139.  
  140. /* Declare a pointer to some soundwave data: */
  141. BYTE *square_wave = NULL;
  142.  
  143.  
  144.  
  145. /* The notes (defined above) frequencies. These frequencies      */
  146. /* represent notes which are one octave higher than the middle   */
  147. /* octave on a piano. To change octave, simply double/half these */
  148. /* values. Ex, A=880, one octave lower A=440, one octave higher  */
  149. /* A=1760.                                                       */
  150. /*                                                               */
  151. /* Instead of changing the frequencies you can of course double  */
  152. /* or half the amount of samled waveform data. If you double the */
  153. /* amount of sampled waveformdata you will move down one octave  */
  154. /* and vice versa. In this example when we caluculate the period */
  155. /* value we use the length of the vaweform as one parameter.     */
  156. /* Therefore, if you change the length of the waveform the same  */
  157. /* frequencies will be used.                                     */ 
  158.  
  159. UWORD note_frequency[ OCTAVE ]=
  160. {
  161.    880.0, /* A  */
  162.    932.3, /* A# */
  163.    987.8, /* B  */
  164.   1046.5, /* C  */
  165.   1108.7, /* C# */
  166.   1174.7, /* D  */
  167.   1244.5, /* D# */
  168.   1318.5, /* E  */
  169.   1396.9, /* F  */
  170.   1480.0, /* F# */
  171.   1568.0, /* G  */
  172.   1661.2  /* G# */
  173. };
  174.  
  175.  
  176.  
  177. /* These structure are defined in the headerfile "hardware/custom.h" */
  178. /* and are automatically connected to the hardware registers. We do  */
  179. /* therefore not need to initialize them.                            */
  180.  
  181. extern UWORD far dmacon;            /* DMA control     */
  182. extern struct AudChannel far aud[]; /* Audio channels. */
  183.  
  184. /* Since the hardware data most certainly will not be within reach  */
  185. /* for normal (small) pointers, they must both be declared as far.  */
  186.  
  187.  
  188.  
  189. /* Declare our functions: */
  190. void main();
  191. void clean_up( STRPTR text );
  192.  
  193.  
  194.  
  195. void main()
  196. {
  197.   /* Error messages: */
  198.   BYTE error;
  199.  
  200.   /* The channel we have received: */
  201.   UBYTE channels;
  202.  
  203.   /* Current note: */
  204.   int note;
  205.  
  206.   /* Pointer to the audio register:      */
  207.   /* (If we have successfuly reserved    */
  208.   /* the sound channel we initialize the */
  209.   /* corresponding pointer, else it      */
  210.   /* remains NULL.)                      */
  211.   struct AudChannel *left0_audio_register = NULL;
  212.   struct AudChannel *left1_audio_register = NULL;
  213.   struct AudChannel *right0_audio_register = NULL;
  214.   struct AudChannel *right1_audio_register = NULL;
  215.  
  216.  
  217.  
  218.   /* Get a reply port: (No name, priority 0) */
  219.   replymp = (struct MsgPort *)
  220.     CreatePort( NULL, 0 );
  221.   if( !replymp )
  222.     clean_up( "Could not create the reply port!" );
  223.  
  224.  
  225.  
  226.   /* Allocate and preinitialize an audio request block: */
  227.   audio_req = (struct IOAudio *)
  228.     CreateExtIO( replymp, sizeof( struct IOAudio ) );
  229.   if( !audio_req )
  230.     clean_up( "Not enough memory for the IOAudio structure!" );
  231.  
  232.  
  233.  
  234.   /* Allocate memory for the lock: */
  235.   audio_lock = (struct IOAudio *)
  236.     CreateExtIO( replymp, sizeof( struct IOAudio ) );
  237.   if( !audio_lock )
  238.     clean_up( "Not enough memory for the Lock!" );
  239.  
  240.  
  241.  
  242.   /* Set sound priority: */
  243.   audio_req->ioa_Request.io_Message.mn_Node.ln_Pri = SOUND_EFFECT;
  244.  
  245.   /* Give the audio structure our replyport: */
  246.   audio_req->ioa_Request.io_Message.mn_ReplyPort = replymp;
  247.  
  248.   /* Tell the Audio Device which channels we preffere: */
  249.   audio_req->ioa_Data = desired_channels;
  250.  
  251.   /* The size of our list of desired channels: */
  252.   audio_req->ioa_Length = sizeof( desired_channels );
  253.  
  254.  
  255.  
  256.   /* Open the Audio Device and at the same time try to */
  257.   /* reserve the channel(s):                           */
  258.   error = OpenDevice( AUDIONAME, 0, audio_req, 0 );
  259.   if( error )
  260.   {
  261.     /* Clear the "io_Device" flag since we have not opened the device: