home *** CD-ROM | disk | FTP | other *** search
/ Inside Multimedia 1995 August / IMM0895.ISO01.iso / share / os2 / track061 / soundbla.c < prev    next >
Text File  |  1992-11-01  |  6KB  |  194 lines

  1. /* soundblaster_audio.c */
  2.  
  3. /* modified by David Nichols for this PM MOD player */
  4.  
  5. /* MODIFIED BY Michael Fulbright (MSF) to work with os/2 device driver */
  6.  
  7. /* $Author: steve $
  8.  * $Id: soundblaster_audio.c,v 1.1 1992/06/24 06:24:17 steve Exp steve $
  9.  * $Revision: 1.1 $
  10.  * $Log: soundblaster_audio.c,v $
  11.  * Revision 1.1  1992/06/24  06:24:17  steve
  12.  * Initial revision
  13.  */
  14.  
  15. #define INCL_DOS
  16.  
  17. #include <os2.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include "sblast_user.h"
  21. #include "defs.h"
  22.  
  23. struct sb_mixer_levels sbLevels;
  24. struct sb_mixer_params sbParams;
  25.  
  26. unsigned char *buffer;        /* buffer for ready-to-play samples */
  27.  
  28. static int buf_index;
  29.  
  30. HFILE hAudio;      /* audio handle */
  31.  
  32. int fixparams = 0;
  33. int filterout;
  34. int filterin;
  35. int filterhi;
  36.  
  37. /* 256th of primary/secondary source for that side. */
  38. static int primary, secondary;
  39.  
  40. void restoreparams()
  41. {
  42.    ULONG parlen, datlen;
  43.  
  44.    if (fixparams)
  45.    {
  46.       parlen = 0;
  47.       datlen = sizeof(struct sb_mixer_params);
  48.       DosDevIOCtl(hAudio, DSP_CAT, MIXER_IOCTL_READ_PARAMS,
  49.              NULL, 0, &parlen, &sbParams, datlen, &datlen);
  50.       sbParams.hifreq_filter = filterhi;
  51.       sbParams.filter_output = filterout;
  52.       sbParams.filter_input = filterin;
  53.       parlen = 0;
  54.       datlen = sizeof(struct sb_mixer_params);
  55.       DosDevIOCtl(hAudio, DSP_CAT, MIXER_IOCTL_SET_PARAMS,
  56.               NULL, 0, &parlen, &sbParams, datlen, &datlen);
  57.    }
  58. }
  59.  
  60. void set_mix (int percent)
  61. {
  62.   percent *= 256;
  63.   percent /= 100;
  64.   primary = percent;
  65.   secondary = 512 - percent;
  66. }
  67.  
  68. int open_audio(int frequency, unsigned short DMAbuffersize)
  69. {
  70.   USHORT status, freq;
  71.   USHORT   flag;
  72.   ULONG  datlen, parlen, action, temp;
  73.  
  74.   /* MSF - open SBDSP for output */
  75.   status = DosOpen( "SBDSP$", &hAudio, &action, 0, FILE_NORMAL, FILE_OPEN,
  76.    OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE |
  77.    OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_NOINHERIT |
  78.    OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_FAIL_ON_ERROR, NULL );
  79.  
  80.   if (status != 0) trackerror(1, "Error opening audio device SBDSP$", FATAL_ERROR);
  81.  
  82.   /* see if we are on a SBREG or SBPRO */
  83.   status = DosOpen( "SBMIX$", &temp, &action, 0, FILE_NORMAL, FILE_OPEN,
  84.    OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE |
  85.    OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_NOINHERIT | 
  86.    OPEN_FLAGS_NO_CACHE, NULL );
  87.  
  88.   if (status !=0) pref.stereo=FALSE;
  89.   else
  90.    {
  91.       fixparams = TRUE;
  92.       parlen = 0;
  93.       datlen = sizeof(struct sb_mixer_params);
  94.       DosDevIOCtl(hAudio, DSP_CAT, MIXER_IOCTL_READ_PARAMS,
  95.              NULL, 0, &parlen, &sbParams, datlen, &datlen);
  96.       filterhi = sbParams.hifreq_filter;
  97.       filterout = sbParams.filter_output;
  98.       filterin = sbParams.filter_input;
  99.       sbParams.hifreq_filter = TRUE;
  100.       sbParams.filter_output = FALSE;
  101.       sbParams.filter_input = TRUE;
  102.       parlen = 0;
  103.       datlen = sizeof(struct sb_mixer_params);
  104.       DosDevIOCtl(hAudio, DSP_CAT, MIXER_IOCTL_SET_PARAMS,
  105.                NULL, 0, &parlen, &sbParams, datlen, &datlen);
  106.       datlen=1;
  107.       parlen=0;
  108.       flag=pref.stereo;
  109.       status=DosDevIOCtl(hAudio, DSP_CAT, DSP_IOCTL_STEREO,
  110.              NULL, 0, &parlen, &flag, 1, &datlen);
  111.       if (status != 0)    trackerror (1, "Error setting stereo/mono", FATAL_ERROR);
  112.       datlen = 1;
  113.       flag = DMAbuffersize * 1024;
  114.       DMAbuffersize = flag;
  115.       status=DosDevIOCtl(hAudio, DSP_CAT, DSP_IOCTL_BUFSIZE,
  116.                     NULL, 0, &parlen, &DMAbuffersize, datlen, &datlen);
  117.       if (status != 0)trackerror(1, "Error setting DMA buffer size", FATAL_ERROR);
  118.    }
  119.  
  120.   if (pref.stereo) frequency *= 2;  /* XXX Stereo takes twice the speed */
  121.  
  122.   if (frequency == 0) frequency = -1;  /* read current frequency from driver */
  123.  
  124.   /* set speed */
  125.   datlen=2;
  126.   parlen=0;
  127.   freq = (USHORT) frequency;
  128.   status=DosDevIOCtl(hAudio, DSP_CAT, DSP_IOCTL_SPEED,
  129.              NULL, 0, &parlen, &freq, 2, &datlen);
  130.   frequency=freq;
  131.   if (status!=0) trackerror(1, "Error setting frequency", FATAL_ERROR);
  132.  
  133.   buffer = malloc (sizeof (SAMPLE) * frequency);    /* Stereo makes x2 */
  134.   buf_index = 0;
  135.  
  136.   if (pref.stereo) return (frequency / 2);
  137.   else return (frequency);
  138. }
  139.  
  140. void output_samples (int left, int right)
  141. {
  142.   if (pref.stereo)
  143.     {
  144.       buffer[buf_index++] = (((left * primary + right * secondary) / 256) + (1 << 15)) >> 8;
  145.       buffer[buf_index++] = (((right * primary + left * secondary) / 256) + (1 << 15)) >> 8;
  146.     }
  147.   else buffer[buf_index++] = (left + right + (1 << 15)) >> 8;
  148. }
  149.  
  150. void flush_buffer (void)
  151. {
  152.   ULONG numread, status;
  153.  
  154.   status = DosWrite(hAudio, buffer, buf_index, &numread);
  155.    if (status != 0)
  156.    {
  157.       char buf[80];
  158.  
  159.       sprintf(buf, "Error writing to audio device: %d, tried to write: %d, wrote: %d", status, buf_index, numread);
  160.       trackerror (1, buf, FATAL_ERROR);
  161.    }
  162.   if (numread != buf_index)
  163.    {
  164.       char buf[80];
  165.  
  166.       sprintf(buf, "DosWrite mismatch, buf_index: %d, numread: %d", buf_index, numread);
  167.       trackerror(1, buf, NONFATAL_ERROR);
  168.    }      
  169.   buf_index = 0;
  170. }
  171.  
  172. void flush_DMA_buffers()
  173. {
  174.   ULONG status, datlen, parlen;
  175.  
  176.   /* now tell device driver to flush out internal buffers */
  177.   parlen=0;
  178.   datlen=0;
  179.   status=DosDevIOCtl(hAudio, DSP_CAT, DSP_IOCTL_FLUSH,
  180.                     NULL, 0, &parlen, NULL, 0, &datlen);
  181.    if (status != 0)
  182.    {
  183.       char buf[80];
  184.  
  185.       sprintf(buf, "Error flushing DMA buffers: %d", status);
  186.       trackerror(1, buf, NONFATAL_ERROR);
  187.    }
  188. }
  189.  
  190. void close_audio (void)
  191. {
  192.    DosClose(hAudio);
  193. }
  194.