home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / SOUNDUTILS / tracker.4.6.lzh / TRACKER4.6 / Hpux / low_audio.c < prev   
Text File  |  1994-11-24  |  5KB  |  217 lines

  1. /* hplow_audio.c 
  2.     vi:se ts=3 sw=3:
  3.  */
  4.  
  5. /* Driver for HP9000 series 710/7x5 with HP-UX 9.01 */
  6. /* Using low-level audio calls */
  7. /* Copyright 1993 Marc Espie   (Marc.Espie@ens.fr)  */
  8. /* Copyright 1993 Markus Gyger (mgyger@itr.ch) */
  9.  
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <fcntl.h>
  13. #include <unistd.h>
  14. #include <sys/audio.h>
  15. #include "defs.h"
  16. #include "extern.h"
  17.  
  18. ID("$Id$")
  19. #ifndef DEFAULT_SAMPLE_RATE
  20. #define DEFAULT_SAMPLE_RATE  22050
  21. #endif
  22.  
  23. #ifndef AUDIO_NAME
  24. #define AUDIO_NAME           "/dev/audio"
  25. #endif
  26. #ifndef AUDIO_CTL_NAME
  27. #define AUDIO_CTL_NAME       "/dev/audioCtl"
  28. #endif
  29.  
  30. LOCAL int audio;
  31. LOCAL int audio_ctl;
  32.  
  33. LOCAL struct audio_describe ainfo;
  34. LOCAL char *buffer;
  35. LOCAL short *sbuffer;
  36. LOCAL int index;
  37. LOCAL int sample_rate;
  38. LOCAL int channels;
  39. LOCAL int min_samples;
  40.  
  41. LOCAL int stereo;
  42. LOCAL int primary, secondary;
  43.  
  44. void set_mix(percent)
  45. int percent;
  46.     {
  47.     percent *= 256;
  48.     percent /= 100;
  49.     primary = percent;
  50.     secondary = 512 - percent;
  51.     }
  52.  
  53. LOCAL int available(f)
  54. int f;
  55.     {
  56.     int best = 0;
  57.     int i;
  58.  
  59.     for (i = 0; i < ainfo.nrates; i++)
  60.     if (abs(ainfo.sample_rate[i] - f) < abs(best - f))
  61.         best = ainfo.sample_rate[i];
  62.     return best;
  63.     }
  64.  
  65. int open_audio(f, s)
  66. int f;
  67. int s;
  68.     {
  69.     int type;
  70.  
  71.     audio_ctl = open(AUDIO_CTL_NAME, O_WRONLY | O_NDELAY);
  72.     if (audio_ctl == -1)
  73.         {
  74.         end_all("No audio control device");
  75.         }
  76.  
  77.     if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
  78.         {
  79.     end_all("No audio info");
  80.         }
  81.  
  82.     if (f == 0)
  83.         f = DEFAULT_SAMPLE_RATE;
  84.         /* round frequency to acceptable value */
  85.     sample_rate = available(f);
  86.  
  87.         /* check whether we have stereo device */
  88.     if (ainfo.nchannels < 2)
  89.         {
  90.             /* a 710 or 425 -> revert to base quality audio */
  91.         stereo = 0;
  92.         channels = 1;
  93.         }
  94.     else
  95.         {
  96.             /* 7x5 set up */
  97.         stereo = s;
  98.         if (stereo)
  99.             {
  100.             channels = 2;
  101.             set_mix(30);
  102.             }
  103.         else
  104.             channels = 1;
  105.         }
  106.  
  107.         /* write a minimum of samples to avoid underflows on 715 (???) */
  108.     switch (ainfo.audio_id)
  109.         {
  110.         case AUDIO_ID_CS4215:
  111.             /* empirically found values */
  112.             min_samples = 12288;
  113.             if (channels < 2) min_samples = 8192;
  114.             if (sample_rate <= 11025) min_samples = 6144;
  115.             if (sample_rate <= 8000) min_samples = 4096;
  116.             break;
  117.  
  118.         case AUDIO_ID_PSB2160:
  119.         default:
  120.             min_samples = 0;
  121.             break;
  122.         }
  123.  
  124.     if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_LINEAR16BIT) == -1)
  125.         {
  126.           end_all("Linear format not available");
  127.         }
  128.     if (ioctl(audio_ctl, AUDIO_SET_CHANNELS, channels) == -1)
  129.         {
  130.           end_all("Could not set # of audio channels");
  131.         }
  132.     if (ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, sample_rate) == -1)
  133.         {
  134.           end_all("Could not set audio sample rate");
  135.         }
  136.  
  137.     audio = open(AUDIO_NAME, O_WRONLY | O_NDELAY);
  138.     if (audio == -1)
  139.         {
  140.           end_all("Could not open audio device");
  141.         }
  142.  
  143. #ifdef SET_OUTPUT
  144.         /* ensure we hear something */
  145.     if (ioctl(audio_ctl, AUDIO_SET_OUTPUT,
  146.         ((SET_OUTPUT & 1) ? AUDIO_OUT_INTERNAL : 0) |   /* speaker */
  147.         ((SET_OUTPUT & 2) ? AUDIO_OUT_EXTERNAL : 0) |   /* phones  */
  148.         ((SET_OUTPUT & 4) ? AUDIO_OUT_LINE : 0) |   /* line    */
  149.         ((SET_OUTPUT & 7) ? 0 : AUDIO_OUT_NONE)) == -1)
  150.           notice("Warning: could not set audio output");
  151. #endif
  152.  
  153.     index = 0;
  154.     sbuffer = (short *)malloc(2 * channels * sample_rate);
  155.     buffer = (char *)sbuffer;
  156.     if (!buffer)
  157.         end_all("Could not allocate buffer");
  158.     return sample_rate;
  159.     }
  160.  
  161. void set_synchro(s)
  162. int s;
  163.     {
  164.     }
  165.  
  166. int update_frequency()
  167.     {
  168.     int oldfreq;
  169.  
  170.     oldfreq = sample_rate;
  171.     if (ioctl(audio, AUDIO_GET_SAMPLE_RATE, &sample_rate) != -1)
  172.         {
  173.         if (oldfreq != sample_rate)
  174.             {
  175.             sbuffer = (short *)realloc(sbuffer, 2 * channels * sample_rate);
  176.             buffer = (char *)sbuffer;
  177.             return sample_rate;
  178.             }
  179.         }
  180.     return 0;
  181.     }
  182.  
  183. void output_samples(left, right)
  184. int left, right;
  185.     {
  186.     if (stereo)
  187.         {
  188.         sbuffer[index++] = (left * primary + right * secondary)/256;
  189.         sbuffer[index++] = (right * primary + left * secondary)/256;
  190.         }
  191.     else
  192.         sbuffer[index++] = left + right;
  193.     }
  194.  
  195. void flush_buffer()
  196.     {
  197.     if (index >= min_samples)
  198.         {
  199.         write(audio, buffer, 2 * index);
  200.         index = 0;
  201.         }
  202.     }
  203.  
  204. void discard_buffer()
  205.     {
  206.     if (ioctl(audio, AUDIO_RESET, RESET_TX_BUF) == -1)
  207.         notice("Warning: could not discard audio buffer");
  208.     }
  209.  
  210. void close_audio()
  211.     {
  212.     free(buffer);
  213.     close(audio);
  214.     close(audio_ctl);
  215.     }
  216.  
  217.