home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / tracker-4.13.lha / tracker / Arch / NeXT / audio.c next >
Encoding:
C/C++ Source or Header  |  1995-02-08  |  3.4 KB  |  184 lines

  1. /* NeXT/audio.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: audio.c,v 1.2 1995/02/08 13:16:22 espie Exp espie $
  6.  * $Log: audio.c,v $
  7.  * Revision 1.2  1995/02/08  13:16:22  espie
  8.  * *** empty log message ***
  9.  *
  10.  * Revision 1.1  1995/02/01  16:43:47  espie
  11.  * Initial revision
  12.  *
  13.  */
  14.  
  15. #include "defs.h"
  16. #include <sound/sound.h>
  17. #include "extern.h"
  18. /*
  19. #include <sys/ioctl.h>
  20. #include <fcntl.h>
  21. #include <stropts.h>
  22. */
  23.  
  24. ID("$Id: audio.c,v 1.2 1995/02/08 13:16:22 espie Exp espie $")
  25.  
  26. #define SND_PLAY_PRIO   5
  27.  
  28. LOCAL SNDSoundStruct ainfo;
  29. LOCAL struct {
  30.     SNDSoundStruct snd;
  31.     char data;
  32. } *snd;
  33. LOCAL int tag;
  34. unsigned int play_ahead;
  35. LOCAL char *buffer;
  36. LOCAL short *sbuffer;
  37. LOCAL int idx;
  38.  
  39. /* ###
  40. LOCAL int dsize;
  41. */
  42. #define DATASIZE 40960 /* 176400 */
  43. LOCAL int stereo;
  44. LOCAL int primary, secondary;    /* mix factor */
  45.  
  46. void
  47. set_mix(int percent)
  48. {
  49.     percent *= 256;
  50.     percent /= 100;
  51.     primary = percent;
  52.     secondary = 512 - percent;
  53. }
  54.  
  55. #define abs(x) ((x) < 0 ? -(x) : (x))
  56.  
  57. LOCAL int
  58. available(int f)
  59. {
  60.     static int possible[] = { 8012, 22050, 44100, 0};
  61.     int best = 0;
  62.     int i;
  63.  
  64.     for (i = 0; possible[i]; i++)
  65.     if (abs(possible[i] - f) < abs(best - f))
  66.         best = possible[i];
  67.     return best;
  68. }
  69.  
  70. int
  71. open_audio(int f, int s)
  72. {
  73.     if (f == 0)
  74.     f = 22050;
  75.     /* round frequency to acceptable value */
  76.     f = available(f);
  77.  
  78.     stereo = s;
  79.     ainfo.samplingRate = f;
  80. /*    dsize = 2; ###*/
  81.     if (stereo)
  82.     ainfo.channelCount = 2;
  83.     else
  84.     ainfo.channelCount = 1;
  85.     if(f!=8012)
  86.     ainfo.dataFormat = SND_FORMAT_LINEAR_16;
  87.     else
  88.     {
  89.     ainfo.dataFormat = SND_FORMAT_MULAW_8;
  90.     if (stereo)
  91.         notice("Warning: Your hardware may not be fast enough for mulaw-stereo.");
  92.     }
  93.     
  94.     idx = 0;
  95.     if (SNDAlloc((SNDSoundStruct **)&snd, DATASIZE, ainfo.dataFormat,
  96.          ainfo.samplingRate, ainfo.channelCount, 4))
  97.     end_all("Sound allocation error.");
  98.     
  99.     buffer = &snd->data;
  100.     sbuffer = (short *)&snd->data;
  101.     tag = 1;
  102.     play_ahead = 5;
  103.     return f;
  104. }
  105.  
  106. void
  107. set_synchro(int s)
  108. {
  109.     /* not implemented */
  110. }
  111.  
  112. int
  113. update_frequency()
  114. {
  115.     /* frequency can't change */
  116.     return 0;
  117. }
  118.  
  119. void
  120. output_samples(int left, int right)
  121. {
  122.     if (ainfo.dataFormat == SND_FORMAT_LINEAR_16)
  123.     {
  124.     if (stereo)
  125.     {
  126.         sbuffer[idx++] = (left * primary + right * secondary)/65536;
  127.         sbuffer[idx++] = (right * primary + left * secondary)/65536;
  128.     }
  129.     else
  130.         sbuffer[idx++] = left + right;
  131.     
  132.     if (idx >= DATASIZE/2)
  133.         flush_buffer();
  134.     }
  135.     else
  136.     {
  137.     if (stereo)
  138.     {
  139.         buffer[idx++] = SNDMulaw((left*primary + right*secondary)/65536);
  140.         buffer[idx++] = SNDMulaw((right*primary + left*secondary)/65536);
  141.     }
  142.     else
  143.         buffer[idx++] = SNDMulaw((left + right)/256);
  144.  
  145.     if (idx >= DATASIZE)
  146.         flush_buffer();
  147.     }
  148. }
  149.  
  150. void
  151. flush_buffer(void)
  152. {
  153. /*    snd->snd.dataSize = (idx * ainfo.channelCount *
  154.              ((ainfo.dataFormat == SND_FORMAT_LINEAR_16)?2:1)); */
  155.     if(tag>play_ahead)
  156.     SNDWait(tag-play_ahead);
  157.     if(SNDStartPlaying(&snd->snd, tag++, SND_PLAY_PRIO, 0,
  158.                NULL, (SNDNotificationFun)SNDFree))
  159.     notice("Sound playing error.");    /* ### end_all? */
  160.  
  161.     idx = 0;
  162.     if (SNDAlloc((SNDSoundStruct **)&snd, DATASIZE, ainfo.dataFormat,
  163.          ainfo.samplingRate, ainfo.channelCount, 4))
  164.     end_all("Sound allocation error.");
  165.     buffer = &snd->data;
  166.     sbuffer = (short *)&snd->data;
  167. }
  168.  
  169. void
  170. discard_buffer(void)
  171. {
  172.     int i;
  173.     
  174.     for(i=1; i<=play_ahead; i++)
  175.     SNDStop(tag-i);
  176. }
  177.  
  178. void
  179. close_audio(void)
  180. {
  181.     SNDFree(&snd->snd);
  182.     SNDWait(0);
  183. }
  184.