home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / atari / atari800-0.8.6 / nas.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-05-10  |  5.3 KB  |  238 lines

  1. #include <audio/audiolib.h>
  2.  
  3. static char *rcsid = "$Id: nas.c,v 1.6 1998/02/21 14:55:43 david Exp $";
  4.  
  5. #define FALSE 0
  6. #define TRUE 1
  7.  
  8. #define SAMPLE_RATE 8000
  9.  
  10. static nasbug = FALSE;            /* Debug Flag */
  11. static sound_enabled = FALSE;
  12.  
  13. static AuServer *au_server;
  14. static AuDeviceID *au_device;
  15. static AuFlowID au_channel[4];
  16.  
  17. static int waveform = AuWaveFormSquare;
  18. static int au_channel_clock[4] =
  19. {64000, 64000, 64000, 64000};
  20. static int M[4] =
  21. {1, 1, 1, 1};
  22.  
  23. static int AUDCTL = 0x00;
  24. static int AUDF[4] =
  25. {0, 0, 0, 0};
  26. static int AUDC[4] =
  27. {0, 0, 0, 0};
  28.  
  29. void NAS_Initialise(int *argc, char *argv[])
  30. {
  31.     int i, j;
  32.  
  33.     for (i = j = 1; i < *argc; i++) {
  34.         if (strcmp(argv[i], "-sound") == 0)
  35.             sound_enabled = TRUE;
  36.         else if (strcmp(argv[i], "-squarewave") == 0)
  37.             waveform = AuWaveFormSquare;
  38.         else if (strcmp(argv[i], "-sinewave") == 0)
  39.             waveform = AuWaveFormSine;
  40.         else if (strcmp(argv[i], "-nasbug") == 0)
  41.             nasbug = TRUE;
  42.         else {
  43.             if (strcmp(argv[i], "-help") == 0) {
  44.                 printf("\t-sound        Enable NAS sound support\n");
  45.                 printf("\t-squarewave   Generate sound with a square wave\n");
  46.                 printf("\t-sinewave     Generate sound with a sine wave\n");
  47.                 printf("\t-nasbug       Enable debug code in nas.c\n");
  48.             }
  49.             argv[j++] = argv[i];
  50.         }
  51.     }
  52.  
  53.     *argc = j;
  54.  
  55.     if (sound_enabled) {
  56.         au_server = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL);
  57.         if (!au_server) {
  58.             printf("Unable to open audio server\n");
  59.             exit(1);
  60.         }
  61.         for (au_device = NULL, i = 0; i < AuServerNumDevices(au_server); i++) {
  62.             if ((AuDeviceKind(AuServerDevice(au_server, i)) ==
  63.                  AuComponentKindPhysicalOutput) &&
  64.                 AuDeviceNumTracks(AuServerDevice(au_server, i)) == 1) {
  65.                 au_device = (AuDeviceID *) AuDeviceIdentifier(AuServerDevice(au_server, i));
  66.                 break;
  67.             }
  68.         }
  69.  
  70.         au_channel[0] = AuCreateFlow(au_server, NULL);
  71.         au_channel[1] = AuCreateFlow(au_server, NULL);
  72.         au_channel[2] = AuCreateFlow(au_server, NULL);
  73.         au_channel[3] = AuCreateFlow(au_server, NULL);
  74.  
  75.         for (i = 0; i < 4; i++) {
  76.             AuElement elements[3];
  77.             int freq = 0;
  78.             int volume = AuFixedPointFromFraction(0, 100);
  79.  
  80.             AuMakeElementImportWaveForm(&elements[0], SAMPLE_RATE,
  81.                                         waveform,
  82.                                         AuUnlimitedSamples,
  83.                                         freq,
  84.                                         0, NULL);
  85.             AuMakeElementMultiplyConstant(&elements[1], 0, volume);
  86.             AuMakeElementExportDevice(&elements[2], 1, (int) au_device, SAMPLE_RATE,
  87.                                       AuUnlimitedSamples, 0, NULL);
  88.  
  89.             AuSetElements(au_server, au_channel[i], AuTrue, 3, elements, NULL);
  90.             AuStartFlow(au_server, au_channel[i], NULL);
  91.         }
  92.     }
  93. }
  94.  
  95. void NAS_Exit(void)
  96. {
  97.     if (sound_enabled) {
  98.         int i;
  99.  
  100.         for (i = 0; i < 4; i++) {
  101.             AuStopFlow(au_server, au_channel[i], NULL);
  102.         }
  103.  
  104.         AuCloseServer(au_server);
  105.     }
  106. }
  107.  
  108. NAS_SetFrequency(int channel, int frequency)
  109. {
  110.     if (frequency < 8000) {
  111.         static AuElementParameters parms;
  112.  
  113.         parms.flow = channel;
  114.         parms.element_num = 0;
  115.         parms.num_parameters = AuParmsImportWaveForm;
  116.         parms.parameters[AuParmsImportWaveFormFrequency] = frequency;
  117.         parms.parameters[AuParmsImportWaveFormNumSamples] = AuUnlimitedSamples;
  118.         AuSetElementParameters(au_server, 1, &parms, NULL);
  119.     }
  120. }
  121.  
  122. NAS_SetVolume(int channel, int volume)
  123. {
  124.     static AuElementParameters parms;
  125.  
  126.     parms.flow = channel;
  127.     parms.element_num = 1;
  128.     parms.num_parameters = AuParmsMultiplyConstant;
  129.     parms.parameters[AuParmsMultiplyConstantConstant] = volume;
  130.     AuSetElementParameters(au_server, 1, &parms, NULL);
  131. }
  132.  
  133. static int join12 = FALSE;
  134. static int join34 = FALSE;
  135.  
  136. void NAS_UpdateSound(void)
  137. {
  138.     if (sound_enabled) {
  139.         int i;
  140.  
  141.         for (i = 0; i < 4; i++) {
  142.             int freqtmp;
  143.             int flag = FALSE;
  144.  
  145.             if ((i < 2) && join12) {
  146.                 if (i == 1) {
  147.                     int N = ((AUDF[1] << 8) | AUDF[0]) + M[0];
  148.  
  149.                     if (nasbug)
  150.                         printf("join12: N=%d\n", N);
  151.  
  152.                     freqtmp = au_channel_clock[0] / (N + N);
  153.  
  154.                     flag = TRUE;
  155.                 }
  156.             }
  157.             else if ((i >= 2) && join34) {
  158.                 if (i == 3) {
  159.                     int N = ((AUDF[3] << 8) | AUDF[2]) + M[2];
  160.  
  161.                     if (nasbug)
  162.                         printf("join34: N=%d\n", N);
  163.  
  164.                     freqtmp = au_channel_clock[2] / (N + N);
  165.  
  166.                     flag = TRUE;
  167.                 }
  168.             }
  169.             else {
  170.                 int N = AUDF[i] + M[i];
  171.  
  172.                 freqtmp = au_channel_clock[i] / (N + N);
  173.  
  174.                 flag = TRUE;
  175.             }
  176.  
  177.             if (flag) {
  178.                 int distortion = AUDC[i] & 0xf0;
  179.                 int voltmp;
  180.  
  181.                 if ((distortion == 0xa0) || (distortion == 0xd0))
  182.                     voltmp = AuFixedPointFromFraction((AUDC[i] & 0x0f), 30);
  183.                 else
  184.                     voltmp = AuFixedPointFromFraction(0, 30);
  185.  
  186.                 NAS_SetFrequency(au_channel[i], freqtmp);
  187.                 NAS_SetVolume(au_channel[i], voltmp);
  188.             }
  189.         }
  190.  
  191.         AuFlush(au_server);
  192.     }
  193. }
  194.  
  195. void Atari_AUDC(int channel, int byte)
  196. {
  197.     AUDC[channel - 1] = byte;
  198. }
  199.  
  200. void Atari_AUDF(int channel, int byte)
  201. {
  202.     AUDF[channel - 1] = byte;
  203. }
  204.  
  205. void Atari_AUDCTL(int byte)
  206. {
  207.     AUDCTL = byte;
  208.  
  209.     if (byte & 0x01) {
  210.         au_channel_clock[0] = 15000;
  211.         au_channel_clock[1] = 15000;
  212.         au_channel_clock[2] = 15000;
  213.         au_channel_clock[3] = 15000;
  214.     }
  215.     else {
  216.         au_channel_clock[0] = 64000;
  217.         au_channel_clock[1] = 64000;
  218.         au_channel_clock[2] = 64000;
  219.         au_channel_clock[3] = 64000;
  220.     }
  221.  
  222.     M[0] = M[1] = M[2] = M[3] = 1;
  223.  
  224.     join34 = (byte & 0x08) ? TRUE : FALSE;    /* Clock channel 4 with channel 3 */
  225.     join12 = (byte & 0x10) ? TRUE : FALSE;    /* Clock channel 2 with channel 1 */
  226.  
  227.     if (byte & 0x20) {
  228.         au_channel_clock[2] = 1790000;    /* Clock channel 3 with 1.79 MHZ */
  229.         M[2] = (join34) ? 7 : 4;
  230.     }
  231.     if (byte & 0x40) {
  232.         au_channel_clock[0] = 1790000;    /* Clock channel 1 with 1.79 MHZ */
  233.         M[0] = (join12) ? 7 : 4;
  234.     }
  235.     if (nasbug && (byte & 0xfe))
  236.         printf("AUDCTL: %02x\n", byte);
  237. }
  238.