home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / SOUNDUTILS / mm1_tracker.lzh / TRACKER4.6 / Sparc / audio.c next >
Text File  |  1994-11-24  |  7KB  |  322 lines

  1. /* sparc/audio.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: audio.c,v 4.2 1994/01/13 09:19:08 espie Exp espie $
  6.  * $Log: audio.c,v $
  7.  * Revision 4.2  1994/01/13  09:19:08  espie
  8.  * Forgotten something.
  9.  *
  10.  * Revision 4.0  1994/01/11  18:16:36  espie
  11.  * New release.
  12.  *
  13.  * Revision 1.2  1993/12/26  18:54:21  Espie
  14.  * Handle errors better.
  15.  *
  16.  * Revision 1.1  1993/12/26  00:55:53  Espie
  17.  * Initial revision
  18.  *
  19.  * Revision 3.14  1993/12/04  16:12:50  espie
  20.  * BOOL -> boolean.
  21.  *
  22.  * Revision 3.13  1993/12/02  15:45:33  espie
  23.  * Merged ss10/solaris.
  24.  *
  25.  * Revision 3.12  1993/11/27  17:07:33  espie
  26.  * Merged support for solaris together.
  27.  *
  28.  * Revision 3.11  1993/11/17  15:31:16  espie
  29.  * *** empty log message ***
  30.  *
  31.  *
  32.  * Revision 3.9  1993/07/14  16:33:41  espie
  33.  * Fixed /16 bug.
  34.  *
  35.  * Revision 3.8  1993/05/09  14:06:03  espie
  36.  * Corrected mix problem.
  37.  *
  38.  * Revision 3.6  1992/12/03  15:00:50  espie
  39.  * restore stty.
  40.  *
  41.  * Revision 3.4  1992/11/24  10:51:19  espie
  42.  * Sync pseudo call.
  43.  *
  44.  * Revision 3.3  1992/11/22  17:20:01  espie
  45.  * Added update_frequency call, mostly unchecked
  46.  *
  47.  * Revision 3.2  1992/11/20  14:53:32  espie
  48.  * Added finetune.
  49.  *
  50.  * Revision 3.1  1992/11/19  20:44:47  espie
  51.  * Protracker commands.
  52.  *
  53.  * Revision 3.0  1992/11/18  16:08:05  espie
  54.  * New release.
  55.  *
  56.  * Revision 1.3  1992/11/17  15:38:00  espie
  57.  * discard_buffer() call for snappier interface calls.
  58.  * - Unified support for all sparcs.
  59.  * - moved down to level 2 io.
  60.  */
  61.  
  62. #include <stdio.h>
  63. #include "defs.h"
  64. #include "extern.h"
  65. #ifdef SOLARIS
  66. #include <sys/audio.io.h>
  67. #else
  68. #include <sun/audioio.h>
  69. #endif
  70. #include <sys/ioctl.h>
  71. #include <fcntl.h>
  72. #include <stropts.h>
  73. #include <malloc.h>
  74.      
  75. /* things that aren't defined in all sun/audioio.h */
  76.  
  77. #ifndef AUDIO_ENCODING_LINEAR
  78. #define AUDIO_ENCODING_LINEAR (3)
  79. #endif
  80. #ifndef AUDIO_GETDEV
  81. #define AUDIO_GETDEV    _IOR(A, 4, int)
  82. #endif
  83. #ifndef AUDIO_DEV_UNKNOWN
  84. #define AUDIO_DEV_UNKNOWN (0)
  85. #endif
  86. #ifndef AUDIO_DEV_AMD
  87. #define AUDIO_DEV_AMD (1)
  88. #endif
  89.  
  90. ID("$Id: audio.c,v 4.2 1994/01/13 09:19:08 espie Exp espie $")
  91.  
  92. LOCAL int audio;
  93.  
  94. LOCAL struct audio_info ainfo;
  95. LOCAL char *buffer;
  96. LOCAL short *sbuffer;
  97. LOCAL int index;
  98. LOCAL int dsize;
  99.  
  100. LOCAL int stereo;
  101. LOCAL int primary, secondary;
  102.  
  103. void set_mix(percent)
  104. int percent;
  105.     {
  106.     percent *= 256;
  107.     percent /= 100;
  108.     primary = percent;
  109.     secondary = 512 - percent;
  110.     }
  111.  
  112. #define abs(x) ((x) < 0 ? -(x) : (x))
  113.  
  114. LOCAL int available(f)
  115. int f;
  116.     {
  117.     static int possible[] = { 8000, 9600, 11025, 16000, 18900, 22050, 32000,
  118.         37800, 44100, 48000, 0};
  119.     int best = 0;
  120.     int i;
  121.  
  122.     for (i = 0; possible[i]; i++)
  123.         if (abs(possible[i] - f) < abs(best - f))
  124.             best = possible[i];
  125.     return best;
  126.     }
  127.  
  128. int open_audio(f, s)
  129. int f;
  130. int s;
  131.     {
  132.     int type;
  133. #ifdef SOLARIS
  134.     audio_device_t dev;
  135.  
  136.     audio = open("/dev/audio", O_WRONLY);
  137. #else
  138.     audio = open("/dev/audio", O_WRONLY|O_NDELAY);
  139. #endif
  140.     if (audio == -1)
  141.         end_all("Error: could not open audio");
  142.     if (f == 0)
  143.         f = 22050;
  144.         /* round frequency to acceptable value */
  145.     f = available(f);
  146.  
  147.         /* check whether we know about AUDIO_ENCODING_LINEAR */
  148. #ifdef SOLARIS
  149.     ioctl(audio, AUDIO_GETDEV, &dev);
  150.     if (strcmp(dev.name, "SUNW,dbri") != 0)
  151. #else
  152.     if (ioctl(audio, AUDIO_GETDEV, &type) ||
  153.     type == AUDIO_DEV_UNKNOWN || type == AUDIO_DEV_AMD)
  154. #endif
  155.         {
  156.             /* not a new ss5/10/20 -> revert to base quality audio */
  157.         stereo = 0;
  158.         dsize = 1;
  159.         ainfo.play.sample_rate = 8000;
  160.         ainfo.play.encoding = AUDIO_ENCODING_ULAW;
  161.         ainfo.play.channels = 1;
  162.         }
  163.     else
  164.         {
  165.             /* tentative set up */
  166.         stereo = s;
  167.         AUDIO_INITINFO(&ainfo);
  168.         ainfo.play.sample_rate = f;
  169.         ainfo.play.precision = 16;
  170.         dsize = 2;
  171.         if (stereo)
  172.             {
  173.             ainfo.play.channels = 2;
  174.             }
  175.         else
  176.             ainfo.play.channels = 1;
  177.             /* try it */
  178.         ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
  179.         if (ioctl(audio, AUDIO_SETINFO, &ainfo) != 0)
  180.             /* didn't work: fatal problem */
  181.             end_all("Error: AUDIO_SETINFO");
  182.         }
  183.     index = 0;
  184.     buffer = (char *)malloc(dsize * ainfo.play.channels * ainfo.play.sample_rate);
  185.     sbuffer = (short *) buffer;
  186.     if (!buffer)
  187.         end_all("Error: could not allocate buffer");
  188.     return ainfo.play.sample_rate;
  189.     }
  190.  
  191. void set_synchro(s)
  192. int s;
  193.     {
  194.     }
  195.  
  196. int update_frequency()
  197.     {
  198.     int oldfreq;
  199.  
  200.     oldfreq = ainfo.play.sample_rate;
  201.     if (ioctl(audio, AUDIO_GETINFO, &ainfo) == 0)
  202.         {
  203.         if (oldfreq != ainfo.play.sample_rate)
  204.             {
  205.             buffer = realloc(buffer, 
  206.                 dsize * ainfo.play.channels * ainfo.play.sample_rate);
  207.             sbuffer = (short *)buffer;
  208.             return ainfo.play.sample_rate;
  209.             }
  210.         }
  211.     return 0;
  212.     }
  213.  
  214.  
  215. LOCAL int sign(x)
  216. unsigned char x;
  217.     {
  218.     return x;
  219.     }
  220.  
  221. /************************************************************************/
  222. /*      For routine 'cvt' only                                          */
  223. /************************************************************************/
  224. /*      Copyright 1989 by Rich Gopstein and Harris Corporation          */
  225. /************************************************************************/
  226.  
  227. LOCAL unsigned int cvt(ch)
  228. int ch;
  229.     {
  230.     int mask;
  231.  
  232.     if (ch < 0)
  233.         {
  234.         ch = -ch;
  235.         mask = 0x7f;
  236.         }
  237.     else
  238.         mask = 0xff;
  239.  
  240.     if (ch < 32)
  241.         {
  242.         ch = 0xF0 | 15 - (ch / 2);
  243.         }
  244.     else if (ch < 96)
  245.         {
  246.         ch = 0xE0 | 15 - (ch - 32) / 4;
  247.         }
  248.     else if (ch < 224)
  249.         {
  250.         ch = 0xD0 | 15 - (ch - 96) / 8;
  251.         }
  252.     else if (ch < 480)
  253.         {
  254.         ch = 0xC0 | 15 - (ch - 224) / 16;
  255.         }
  256.     else if (ch < 992)
  257.         {
  258.         ch = 0xB0 | 15 - (ch - 480) / 32;
  259.         }
  260.     else if (ch < 2016)
  261.         {
  262.         ch = 0xA0 | 15 - (ch - 992) / 64;
  263.         }
  264.     else if (ch < 4064)
  265.         {
  266.         ch = 0x90 | 15 - (ch - 2016) / 128;
  267.         }
  268.     else if (ch < 8160)
  269.         {
  270.         ch = 0x80 | 15 - (ch - 4064) /  256;
  271.         }
  272.     else
  273.         {
  274.         ch = 0x80;
  275.         }
  276.     return (mask & ch);
  277.     }
  278.  
  279.  
  280. void output_samples(left, right)
  281. int left, right;
  282.     {
  283.     if (stereo)
  284.         {
  285.         sbuffer[index++] = (left * primary + right * secondary)/256;
  286.         sbuffer[index++] = (right * primary + left * secondary)/256;
  287.         }
  288.     else
  289.         switch(ainfo.play.encoding)
  290.             {
  291.         case AUDIO_ENCODING_LINEAR:
  292.             sbuffer[index++] = left + right;
  293.             break;
  294.         case AUDIO_ENCODING_ULAW:
  295.             buffer[index++] = cvt((left + right) /4);
  296.             break;
  297.             }
  298.     }
  299.  
  300. void flush_buffer()
  301.     {
  302.     int actual;
  303.  
  304.     actual = write(audio, buffer, dsize * index);
  305.     if (actual == -1)
  306.         notice("Write to audio failed");
  307.     else if (actual != dsize * index)
  308.         notice("Short write to audio");
  309.     index = 0;
  310.     }
  311.  
  312. void discard_buffer()
  313.     {
  314.     ioctl(audio, I_FLUSH, FLUSHW);
  315.     }
  316.  
  317. void close_audio()
  318.     {
  319.     free(buffer);
  320.     close(audio);
  321.     }
  322.