Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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