home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / snd_sun.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-17  |  4.5 KB  |  219 lines

  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 <stdio.h>
  29. #include <sys/audioio.h>
  30. #include <errno.h>
  31. #include "quakedef.h"
  32.  
  33. int audio_fd;
  34. int snd_inited;
  35.  
  36. static int bufpos;
  37. static int wbufp;
  38. static audio_info_t info;
  39.  
  40. #define BUFFER_SIZE   8192
  41.  
  42. unsigned char dma_buffer[BUFFER_SIZE];
  43. unsigned char pend_buffer[BUFFER_SIZE];
  44. int pending;
  45.  
  46. static int lastwrite = 0;
  47.  
  48. qboolean SNDDMA_Init(void)
  49. {
  50.   int rc;
  51.   int fmt;
  52.   int tmp;
  53.   int i;
  54.   char *s;
  55.   int caps;
  56.  
  57.   if (snd_inited) {
  58.     printf("Sound already init'd\n");
  59.     return;
  60.   }
  61.  
  62.   shm = &sn;
  63.   shm->splitbuffer = 0;
  64.  
  65.   audio_fd = open("/dev/audio", O_WRONLY|O_NDELAY);
  66.  
  67.   if (audio_fd < 0) {
  68.     if (errno == EBUSY) {
  69.       Con_Printf("Audio device is being used by another process\n");
  70.     }
  71.     perror("/dev/audio");
  72.     Con_Printf("Could not open /dev/audio\n");
  73.     return (0);
  74.   }
  75.  
  76.   if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) {
  77.     perror("/dev/audio");
  78.     Con_Printf("Could not communicate with audio device.\n");
  79.     close(audio_fd);
  80.     return 0;
  81.   }
  82.  
  83.   //
  84.   // set to nonblock
  85.   //
  86.   if (fcntl(audio_fd, F_SETFL, O_NONBLOCK) < 0) {
  87.     perror("/dev/audio");
  88.     close(audio_fd);
  89.     return 0;
  90.   }
  91.  
  92.   AUDIO_INITINFO(&info);
  93.  
  94.   shm->speed = 11025;
  95.  
  96.   // try 16 bit stereo
  97.   info.play.encoding = AUDIO_ENCODING_LINEAR;
  98.   info.play.sample_rate = 11025;
  99.   info.play.channels = 2;
  100.   info.play.precision = 16;
  101.  
  102.   if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) {
  103.     info.play.encoding = AUDIO_ENCODING_LINEAR;
  104.     info.play.sample_rate = 11025;
  105.     info.play.channels = 1;
  106.     info.play.precision = 16;
  107.     if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) {
  108.       Con_Printf("Incapable sound hardware.\n");
  109.       close(audio_fd);
  110.       return 0;
  111.     }
  112.     Con_Printf("16 bit mono sound initialized\n");
  113.     shm->samplebits = 16;
  114.     shm->channels = 1;
  115.   } else { // 16 bit stereo
  116.     Con_Printf("16 bit stereo sound initialized\n");
  117.     shm->samplebits = 16;
  118.     shm->channels = 2;
  119.   }
  120.  
  121.   shm->soundalive = true;
  122.   shm->samples = sizeof(dma_buffer) / (shm->samplebits/8);
  123.   shm->samplepos = 0;
  124.   shm->submission_chunk = 1;
  125.   shm->buffer = (unsigned char *)dma_buffer;
  126.  
  127.   snd_inited = 1;
  128.  
  129.   return 1;
  130. }
  131.  
  132. int SNDDMA_GetDMAPos(void)
  133. {
  134.   if (!snd_inited)
  135.     return (0);
  136.  
  137.   if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) {
  138.     perror("/dev/audio");
  139.     Con_Printf("Could not communicate with audio device.\n");
  140.     close(audio_fd);
  141.     snd_inited = 0;
  142.     return (0);
  143.   }
  144.  
  145.   return ((info.play.samples*shm->channels) % shm->samples);
  146. }
  147.  
  148. int SNDDMA_GetSamples(void)
  149. {
  150.   if (!snd_inited)
  151.     return (0);
  152.  
  153.   if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) {
  154.     perror("/dev/audio");
  155.     Con_Printf("Could not communicate with audio device.\n");
  156.     close(audio_fd);
  157.     snd_inited = 0;
  158.     return (0);
  159.   }
  160.  
  161.   return info.play.samples;
  162. }
  163.  
  164. void SNDDMA_Shutdown(void)
  165. {
  166.   if (snd_inited) {
  167.     close(audio_fd);
  168.     snd_inited = 0;
  169.   }
  170. }
  171.  
  172. /*
  173. ==============
  174. SNDDMA_Submit
  175.  
  176. Send sound to device if buffer isn't really the dma buffer
  177. ===============
  178. */
  179. void SNDDMA_Submit(void)
  180. {
  181.   int samps;
  182.   int bsize;
  183.   int bytes, b;
  184.   static unsigned char writebuf[1024];
  185.   unsigned char *p;
  186.   int idx;
  187.   int stop = paintedtime;
  188.   extern int soundtime;
  189.  
  190.   if (paintedtime < wbufp)
  191.     wbufp = 0; // reset
  192.  
  193.   bsize = shm->channels * (shm->samplebits/8);
  194.   bytes = (paintedtime - wbufp) * bsize;
  195.  
  196.   if (!bytes)
  197.     return;
  198.  
  199.   if (bytes > sizeof(writebuf)) {
  200.     bytes = sizeof(writebuf);
  201.     stop = wbufp + bytes/bsize;
  202.   }
  203.  
  204.   p = writebuf;
  205.   idx = (wbufp*bsize) & (BUFFER_SIZE - 1);
  206.  
  207.   for (b = bytes; b; b--) {
  208.     *p++ = dma_buffer[idx];
  209.     idx = (idx + 1) & (BUFFER_SIZE - 1);
  210.   }
  211.  
  212.   wbufp = stop;
  213.  
  214.   if (write(audio_fd, writebuf, bytes) < bytes)
  215.     printf("audio can't keep up!\n");
  216.  
  217. }
  218.  
  219.