Annotation of quake2/linux/snd_linux.c, revision 1.1.1.2

1.1.1.2 ! root        1: /*
        !             2: Copyright (C) 1997-2001 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: */
1.1       root       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: 
                     31: #include "../client/client.h"
                     32: #include "../client/snd_loc.h"
                     33: 
                     34: int audio_fd;
                     35: int snd_inited;
                     36: 
                     37: cvar_t *sndbits;
                     38: cvar_t *sndspeed;
                     39: cvar_t *sndchannels;
                     40: cvar_t *snddevice;
                     41: 
                     42: static int tryrates[] = { 11025, 22051, 44100, 8000 };
                     43: 
                     44: qboolean SNDDMA_Init(void)
                     45: {
                     46: 
                     47:        int rc;
                     48:     int fmt;
                     49:        int tmp;
                     50:     int i;
                     51:     char *s;
                     52:        struct audio_buf_info info;
                     53:        int caps;
                     54:        extern uid_t saved_euid;
                     55: 
                     56:        if (snd_inited)
                     57:                return;
                     58: 
                     59:        if (!snddevice) {
                     60:                sndbits = Cvar_Get("sndbits", "16", CVAR_ARCHIVE);
                     61:                sndspeed = Cvar_Get("sndspeed", "0", CVAR_ARCHIVE);
                     62:                sndchannels = Cvar_Get("sndchannels", "2", CVAR_ARCHIVE);
                     63:                snddevice = Cvar_Get("snddevice", "/dev/dsp", CVAR_ARCHIVE);
                     64:        }
                     65: 
                     66: // open /dev/dsp, confirm capability to mmap, and get size of dma buffer
                     67: 
                     68:        if (!audio_fd) {
                     69:                seteuid(saved_euid);
                     70: 
                     71:                audio_fd = open(snddevice->string, O_RDWR);
                     72: 
                     73:                seteuid(getuid());
                     74: 
                     75:                if (audio_fd < 0)
                     76:                {
                     77:                        perror(snddevice->string);
                     78:                        Com_Printf("Could not open %s\n", snddevice->string);
                     79:                        return 0;
                     80:                }
                     81:        }
                     82: 
                     83:     rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
                     84:     if (rc < 0)
                     85:        {
                     86:                perror(snddevice->string);
                     87:                Com_Printf("Could not reset %s\n", snddevice->string);
                     88:                close(audio_fd);
                     89:                return 0;
                     90:        }
                     91: 
                     92:        if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1)
                     93:        {
                     94:                perror(snddevice->string);
                     95:         Com_Printf("Sound driver too old\n");
                     96:                close(audio_fd);
                     97:                return 0;
                     98:        }
                     99: 
                    100:        if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP))
                    101:        {
                    102:                Com_Printf("Sorry but your soundcard can't do this\n");
                    103:                close(audio_fd);
                    104:                return 0;
                    105:        }
                    106: 
                    107:     if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1)
                    108:     {   
                    109:         perror("GETOSPACE");
                    110:                Com_Printf("Um, can't do GETOSPACE?\n");
                    111:                close(audio_fd);
                    112:                return 0;
                    113:     }
                    114:     
                    115: // set sample bits & speed
                    116: 
                    117:     dma.samplebits = (int)sndbits->value;
                    118:        if (dma.samplebits != 16 && dma.samplebits != 8)
                    119:     {
                    120:         ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt);
                    121:         if (fmt & AFMT_S16_LE) dma.samplebits = 16;
                    122:         else if (fmt & AFMT_U8) dma.samplebits = 8;
                    123:     }
                    124: 
                    125:        dma.speed = (int)sndspeed->value;
                    126:        if (!dma.speed) {
                    127:         for (i=0 ; i<sizeof(tryrates)/4 ; i++)
                    128:             if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break;
                    129:         dma.speed = tryrates[i];
                    130:     }
                    131: 
                    132:        dma.channels = (int)sndchannels->value;
                    133:        if (dma.channels < 1 || dma.channels > 2)
                    134:                dma.channels = 2;
                    135:        
                    136:        dma.samples = info.fragstotal * info.fragsize / (dma.samplebits/8);
                    137:        dma.submission_chunk = 1;
                    138: 
                    139: // memory map the dma buffer
                    140: 
                    141:        if (!dma.buffer)
                    142:                dma.buffer = (unsigned char *) mmap(NULL, info.fragstotal
                    143:                        * info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0);
                    144:        if (!dma.buffer)
                    145:        {
                    146:                perror(snddevice->string);
                    147:                Com_Printf("Could not mmap %s\n", snddevice->string);
                    148:                close(audio_fd);
                    149:                return 0;
                    150:        }
                    151: 
                    152:        tmp = 0;
                    153:        if (dma.channels == 2)
                    154:                tmp = 1;
                    155:     rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
                    156:     if (rc < 0)
                    157:     {
                    158:                perror(snddevice->string);
                    159:         Com_Printf("Could not set %s to stereo=%d", snddevice->string, dma.channels);
                    160:                close(audio_fd);
                    161:         return 0;
                    162:     }
                    163:        if (tmp)
                    164:                dma.channels = 2;
                    165:        else
                    166:                dma.channels = 1;
                    167: 
                    168:     rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &dma.speed);
                    169:     if (rc < 0)
                    170:     {
                    171:                perror(snddevice->string);
                    172:         Com_Printf("Could not set %s speed to %d", snddevice->string, dma.speed);
                    173:                close(audio_fd);
                    174:         return 0;
                    175:     }
                    176: 
                    177:     if (dma.samplebits == 16)
                    178:     {
                    179:         rc = AFMT_S16_LE;
                    180:         rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
                    181:         if (rc < 0)
                    182:                {
                    183:                        perror(snddevice->string);
                    184:                        Com_Printf("Could not support 16-bit data.  Try 8-bit.\n");
                    185:                        close(audio_fd);
                    186:                        return 0;
                    187:                }
                    188:     }
                    189:     else if (dma.samplebits == 8)
                    190:     {
                    191:         rc = AFMT_U8;
                    192:         rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
                    193:         if (rc < 0)
                    194:                {
                    195:                        perror(snddevice->string);
                    196:                        Com_Printf("Could not support 8-bit data.\n");
                    197:                        close(audio_fd);
                    198:                        return 0;
                    199:                }
                    200:     }
                    201:        else
                    202:        {
                    203:                perror(snddevice->string);
                    204:                Com_Printf("%d-bit sound not supported.", dma.samplebits);
                    205:                close(audio_fd);
                    206:                return 0;
                    207:        }
                    208: 
                    209: // toggle the trigger & start her up
                    210: 
                    211:     tmp = 0;
                    212:     rc  = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
                    213:        if (rc < 0)
                    214:        {
                    215:                perror(snddevice->string);
                    216:                Com_Printf("Could not toggle.\n");
                    217:                close(audio_fd);
                    218:                return 0;
                    219:        }
                    220:     tmp = PCM_ENABLE_OUTPUT;
                    221:     rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
                    222:        if (rc < 0)
                    223:        {
                    224:                perror(snddevice->string);
                    225:                Com_Printf("Could not toggle.\n");
                    226:                close(audio_fd);
                    227:                return 0;
                    228:        }
                    229: 
                    230:        dma.samplepos = 0;
                    231: 
                    232:        snd_inited = 1;
                    233:        return 1;
                    234: 
                    235: }
                    236: 
                    237: int SNDDMA_GetDMAPos(void)
                    238: {
                    239: 
                    240:        struct count_info count;
                    241: 
                    242:        if (!snd_inited) return 0;
                    243: 
                    244:        if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1)
                    245:        {
                    246:                perror(snddevice->string);
                    247:                Com_Printf("Uh, sound dead.\n");
                    248:                close(audio_fd);
                    249:                snd_inited = 0;
                    250:                return 0;
                    251:        }
                    252: //     dma.samplepos = (count.bytes / (dma.samplebits / 8)) & (dma.samples-1);
                    253: //     fprintf(stderr, "%d    \r", count.ptr);
                    254:        dma.samplepos = count.ptr / (dma.samplebits / 8);
                    255: 
                    256:        return dma.samplepos;
                    257: 
                    258: }
                    259: 
                    260: void SNDDMA_Shutdown(void)
                    261: {
                    262: #if 0
                    263:        if (snd_inited)
                    264:        {
                    265:                close(audio_fd);
                    266:                snd_inited = 0;
                    267:        }
                    268: #endif
                    269: }
                    270: 
                    271: /*
                    272: ==============
                    273: SNDDMA_Submit
                    274: 
                    275: Send sound to device if buffer isn't really the dma buffer
                    276: ===============
                    277: */
                    278: void SNDDMA_Submit(void)
                    279: {
                    280: }
                    281: 
                    282: void SNDDMA_BeginPainting (void)
                    283: {
                    284: }
                    285: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.