home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 14 / MA_Cover_14.iso / source / c / q1source_amy / qw / client / snd_linux.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-07  |  5.0 KB  |  251 lines

  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <stdlib.h>
  4. #include <sys/types.h>
  5. #include <sys/ioctl.h>
  6. #include <sys/mman.h>
  7. #include <sys/shm.h>
  8. #include <sys/wait.h>
  9. #include <linux/soundcard.h>
  10. #include <stdio.h>
  11. #include "quakedef.h"
  12.  
  13. int audio_fd;
  14. int snd_inited;
  15.  
  16. static int tryrates[] = { 11025, 22051, 44100, 8000 };
  17.  
  18. qboolean SNDDMA_Init(void)
  19. {
  20.  
  21.     int rc;
  22.     int fmt;
  23.     int tmp;
  24.     int i;
  25.     char *s;
  26.     struct audio_buf_info info;
  27.     int caps;
  28.  
  29.     snd_inited = 0;
  30.  
  31. // open /dev/dsp, confirm capability to mmap, and get size of dma buffer
  32.  
  33.     audio_fd = open("/dev/dsp", O_RDWR);
  34.     if (audio_fd < 0)
  35.     {
  36.         perror("/dev/dsp");
  37.         Con_Printf("Could not open /dev/dsp\n");
  38.         return 0;
  39.     }
  40.  
  41.     rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
  42.     if (rc < 0)
  43.     {
  44.         perror("/dev/dsp");
  45.         Con_Printf("Could not reset /dev/dsp\n");
  46.         close(audio_fd);
  47.         return 0;
  48.     }
  49.  
  50.     if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1)
  51.     {
  52.         perror("/dev/dsp");
  53.         Con_Printf("Sound driver too old\n");
  54.         close(audio_fd);
  55.         return 0;
  56.     }
  57.  
  58.     if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP))
  59.     {
  60.         Con_Printf("Sorry but your soundcard can't do this\n");
  61.         close(audio_fd);
  62.         return 0;
  63.     }
  64.  
  65.     if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1)
  66.     {   
  67.         perror("GETOSPACE");
  68.         Con_Printf("Um, can't do GETOSPACE?\n");
  69.         close(audio_fd);
  70.         return 0;
  71.     }
  72.     
  73.     shm = &sn;
  74.     shm->splitbuffer = 0;
  75.  
  76. // set sample bits & speed
  77.  
  78.     s = getenv("QUAKE_SOUND_SAMPLEBITS");
  79.     if (s) shm->samplebits = atoi(s);
  80.     else if ((i = COM_CheckParm("-sndbits")) != 0)
  81.         shm->samplebits = atoi(com_argv[i+1]);
  82.     if (shm->samplebits != 16 && shm->samplebits != 8)
  83.     {
  84.         ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt);
  85.         if (fmt & AFMT_S16_LE) shm->samplebits = 16;
  86.         else if (fmt & AFMT_U8) shm->samplebits = 8;
  87.     }
  88.  
  89.     s = getenv("QUAKE_SOUND_SPEED");
  90.     if (s) shm->speed = atoi(s);
  91.     else if ((i = COM_CheckParm("-sndspeed")) != 0)
  92.         shm->speed = atoi(com_argv[i+1]);
  93.     else
  94.     {
  95.         for (i=0 ; i<sizeof(tryrates)/4 ; i++)
  96.             if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break;
  97.         shm->speed = tryrates[i];
  98.     }
  99.  
  100.     s = getenv("QUAKE_SOUND_CHANNELS");
  101.     if (s) shm->channels = atoi(s);
  102.     else if ((i = COM_CheckParm("-sndmono")) != 0)
  103.         shm->channels = 1;
  104.     else if ((i = COM_CheckParm("-sndstereo")) != 0)
  105.         shm->channels = 2;
  106.     else shm->channels = 2;
  107.  
  108.     shm->samples = info.fragstotal * info.fragsize / (shm->samplebits/8);
  109.     shm->submission_chunk = 1;
  110.  
  111. // memory map the dma buffer
  112.  
  113.     shm->buffer = (unsigned char *) mmap(NULL, info.fragstotal
  114.         * info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0);
  115.     if (!shm->buffer)
  116.     {
  117.         perror("/dev/dsp");
  118.         Con_Printf("Could not mmap /dev/dsp\n");
  119.         close(audio_fd);
  120.         return 0;
  121.     }
  122.  
  123.     tmp = 0;
  124.     if (shm->channels == 2)
  125.         tmp = 1;
  126.     rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
  127.     if (rc < 0)
  128.     {
  129.         perror("/dev/dsp");
  130.         Con_Printf("Could not set /dev/dsp to stereo=%d", shm->channels);
  131.         close(audio_fd);
  132.         return 0;
  133.     }
  134.     if (tmp)
  135.         shm->channels = 2;
  136.     else
  137.         shm->channels = 1;
  138.  
  139.     rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &shm->speed);
  140.     if (rc < 0)
  141.     {
  142.         perror("/dev/dsp");
  143.         Con_Printf("Could not set /dev/dsp speed to %d", shm->speed);
  144.         close(audio_fd);
  145.         return 0;
  146.     }
  147.  
  148.     if (shm->samplebits == 16)
  149.     {
  150.         rc = AFMT_S16_LE;
  151.         rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
  152.         if (rc < 0)
  153.         {
  154.             perror("/dev/dsp");
  155.             Con_Printf("Could not support 16-bit data.  Try 8-bit.\n");
  156.             close(audio_fd);
  157.             return 0;
  158.         }
  159.     }
  160.     else if (shm->samplebits == 8)
  161.     {
  162.         rc = AFMT_U8;
  163.         rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
  164.         if (rc < 0)
  165.         {
  166.             perror("/dev/dsp");
  167.             Con_Printf("Could not support 8-bit data.\n");
  168.             close(audio_fd);
  169.             return 0;
  170.         }
  171.     }
  172.     else
  173.     {
  174.         perror("/dev/dsp");
  175.         Con_Printf("%d-bit sound not supported.", shm->samplebits);
  176.         close(audio_fd);
  177.         return 0;
  178.     }
  179.  
  180. // toggle the trigger & start her up
  181.  
  182.     tmp = 0;
  183.     rc  = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
  184.     if (rc < 0)
  185.     {
  186.         perror("/dev/dsp");
  187.         Con_Printf("Could not toggle.\n");
  188.         close(audio_fd);
  189.         return 0;
  190.     }
  191.     tmp = PCM_ENABLE_OUTPUT;
  192.     rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
  193.     if (rc < 0)
  194.     {
  195.         perror("/dev/dsp");
  196.         Con_Printf("Could not toggle.\n");
  197.         close(audio_fd);
  198.         return 0;
  199.     }
  200.  
  201.     shm->samplepos = 0;
  202.  
  203.     snd_inited = 1;
  204.     return 1;
  205.  
  206. }
  207.  
  208. int SNDDMA_GetDMAPos(void)
  209. {
  210.  
  211.     struct count_info count;
  212.  
  213.     if (!snd_inited) return 0;
  214.  
  215.     if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1)
  216.     {
  217.         perror("/dev/dsp");
  218.         Con_Printf("Uh, sound dead.\n");
  219.         close(audio_fd);
  220.         snd_inited = 0;
  221.         return 0;
  222.     }
  223. //    shm->samplepos = (count.bytes / (shm->samplebits / 8)) & (shm->samples-1);
  224. //    fprintf(stderr, "%d    \r", count.ptr);
  225.     shm->samplepos = count.ptr / (shm->samplebits / 8);
  226.  
  227.     return shm->samplepos;
  228.  
  229. }
  230.  
  231. void SNDDMA_Shutdown(void)
  232. {
  233.     if (snd_inited)
  234.     {
  235.         close(audio_fd);
  236.         snd_inited = 0;
  237.     }
  238. }
  239.  
  240. /*
  241. ==============
  242. SNDDMA_Submit
  243.  
  244. Send sound to device if buffer isn't really the dma buffer
  245. ===============
  246. */
  247. void SNDDMA_Submit(void)
  248. {
  249. }
  250.  
  251.