|
|
1.1 ! root 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: dma_t the_shm; ! 15: int snd_inited; ! 16: ! 17: static int tryrates[] = { 44100, 22050, 11025, 8000 }; ! 18: ! 19: extern int desired_speed; ! 20: extern int desired_bits; ! 21: extern int desired_num_channels; ! 22: ! 23: qboolean SNDDMA_Init(void) ! 24: { ! 25: ! 26: int rc; ! 27: int fmt; ! 28: int tmp; ! 29: int i; ! 30: char *s; ! 31: struct audio_buf_info info; ! 32: int caps; ! 33: ! 34: snd_inited = 0; ! 35: ! 36: // open /dev/dsp, confirm capability to mmap, and get size of dma buffer ! 37: ! 38: audio_fd = open("/dev/dsp", O_RDWR); ! 39: if (audio_fd < 0) ! 40: { ! 41: perror("/dev/dsp"); ! 42: Con_Printf("Could not open /dev/dsp\n"); ! 43: return 0; ! 44: } ! 45: ! 46: rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0); ! 47: if (rc < 0) ! 48: { ! 49: perror("/dev/dsp"); ! 50: Con_Printf("Could not reset /dev/dsp\n"); ! 51: close(audio_fd); ! 52: return 0; ! 53: } ! 54: ! 55: if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1) ! 56: { ! 57: perror("/dev/dsp"); ! 58: Con_Printf("Sound driver too old\n"); ! 59: close(audio_fd); ! 60: return 0; ! 61: } ! 62: ! 63: if (!(caps & DSP_CAP_TRIGGER) ! 64: || !(caps & DSP_CAP_MMAP)) ! 65: { ! 66: Con_Printf("Sorry but your soundcard can't do this\n"); ! 67: close(audio_fd); ! 68: // return dmasim_Init(); ! 69: return 0; ! 70: } ! 71: ! 72: if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1) ! 73: { ! 74: perror("GETOSPACE"); ! 75: Con_Printf("Um, can't do GETOSPACE?\n"); ! 76: close(audio_fd); ! 77: return 0; ! 78: } ! 79: ! 80: shm = &the_shm; ! 81: shm->splitbuffer = 0; ! 82: ! 83: // set sample bits & speed ! 84: ! 85: s = getenv("QUAKE_SOUND_SAMPLEBITS"); ! 86: if (s) shm->samplebits = atoi(s); ! 87: else ! 88: { ! 89: ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt); ! 90: if (fmt & AFMT_S16_LE) shm->samplebits = 16; ! 91: else if (fmt & AFMT_U8) shm->samplebits = 8; ! 92: } ! 93: ! 94: s = getenv("QUAKE_SOUND_SPEED"); ! 95: if (s) shm->speed = atoi(s); ! 96: else ! 97: { ! 98: shm->speed = desired_speed; ! 99: if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &shm->speed)) ! 100: { ! 101: for (i=0 ; i<sizeof(tryrates)/4 ; i++) ! 102: if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break; ! 103: shm->speed = tryrates[i]; ! 104: } ! 105: } ! 106: ! 107: s = getenv("QUAKE_SOUND_CHANNELS"); ! 108: if (s) shm->channels = atoi(s); ! 109: else shm->channels = 2; ! 110: ! 111: shm->samples = info.fragstotal * info.fragsize / (shm->samplebits/8); ! 112: shm->submission_chunk = 1; ! 113: ! 114: // memory map the dma buffer ! 115: ! 116: shm->buffer = (unsigned char *) mmap(NULL, info.fragstotal ! 117: * info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0); ! 118: if (!shm->buffer) ! 119: { ! 120: perror("/dev/dsp"); ! 121: Con_Printf("Could not mmap /dev/dsp\n"); ! 122: close(audio_fd); ! 123: return 0; ! 124: } ! 125: ! 126: rc = ioctl(audio_fd, SOUND_PCM_WRITE_CHANNELS, &shm->channels); ! 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: ! 135: rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &shm->speed); ! 136: if (rc < 0) ! 137: { ! 138: perror("/dev/dsp"); ! 139: Con_Printf("Could not set /dev/dsp speed to %d", shm->speed); ! 140: close(audio_fd); ! 141: return 0; ! 142: } ! 143: ! 144: if (shm->samplebits == 16) ! 145: { ! 146: rc = AFMT_S16_LE; ! 147: rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc); ! 148: if (rc < 0) ! 149: { ! 150: perror("/dev/dsp"); ! 151: Con_Printf("Could not support 16-bit data. Try 8-bit.\n"); ! 152: close(audio_fd); ! 153: return 0; ! 154: } ! 155: } ! 156: else if (shm->samplebits == 8) ! 157: { ! 158: rc = AFMT_U8; ! 159: rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc); ! 160: if (rc < 0) ! 161: { ! 162: perror("/dev/dsp"); ! 163: Con_Printf("Could not support 8-bit data.\n"); ! 164: close(audio_fd); ! 165: return 0; ! 166: } ! 167: } ! 168: else ! 169: { ! 170: perror("/dev/dsp"); ! 171: Con_Printf("%d-bit sound not supported.", shm->samplebits); ! 172: close(audio_fd); ! 173: return 0; ! 174: } ! 175: ! 176: // toggle the trigger & start her up ! 177: ! 178: tmp = 0; ! 179: ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); ! 180: tmp = PCM_ENABLE_OUTPUT; ! 181: ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); ! 182: ! 183: shm->samplepos = 0; ! 184: ! 185: snd_inited = 1; ! 186: return 1; ! 187: ! 188: } ! 189: ! 190: int SNDDMA_GetDMAPos(void) ! 191: { ! 192: ! 193: struct count_info count; ! 194: ! 195: if (!snd_inited) return 0; ! 196: ! 197: if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1) ! 198: { ! 199: perror("/dev/dsp"); ! 200: Con_Printf("Uh, sound dead.\n"); ! 201: close(audio_fd); ! 202: snd_inited = 0; ! 203: return 0; ! 204: } ! 205: // shm->samplepos = (count.bytes / (shm->samplebits / 8)) & (shm->samples-1); ! 206: // fprintf(stderr, "%d \r", count.ptr); ! 207: shm->samplepos = count.ptr / (shm->samplebits / 8); ! 208: ! 209: return shm->samplepos; ! 210: ! 211: } ! 212: ! 213: void SNDDMA_Shutdown(void) ! 214: { ! 215: if (snd_inited) ! 216: { ! 217: close(audio_fd); ! 218: snd_inited = 0; ! 219: } ! 220: } ! 221:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.