|
|
1.1 ! root 1: #include <dmedia/dmedia.h> ! 2: #include <dmedia/audio.h> ! 3: ! 4: #include "../client/client.h" ! 5: #include "../client/snd_loc.h" ! 6: ! 7: /* ! 8: ================== ! 9: SNDDM_Init ! 10: ! 11: Try to find a sound device to mix for. ! 12: Returns false if nothing is found. ! 13: Returns true and fills in the "dma" structure with information for the mixer. ! 14: ================== ! 15: */ ! 16: ! 17: // must be power of two! ! 18: #define QSND_SKID 2 ! 19: #define QSND_BUFFER_FRAMES 8192 ! 20: #define QSND_BUFFER_SIZE (QSND_BUFFER_FRAMES*2) ! 21: ! 22: #define UST_TO_BUFFPOS(ust) ((int)((ust) & (QSND_BUFFER_FRAMES - 1)) << 1) ! 23: ! 24: cvar_t *s_loadas8bit; ! 25: cvar_t *s_khz; ! 26: cvar_t *sndchannels; ! 27: ! 28: short int dma_buffer[QSND_BUFFER_SIZE]; ! 29: ALport sgisnd_aport = NULL; ! 30: long long sgisnd_startframe; ! 31: double sgisnd_frames_per_ns; ! 32: long long sgisnd_lastframewritten = 0; ! 33: ! 34: qboolean SNDDMA_Init(void) ! 35: { ! 36: ALconfig ac = NULL; ! 37: ALpv pvbuf[2]; ! 38: ! 39: s_loadas8bit = Cvar_Get("s_loadas8bit", "16", CVAR_ARCHIVE); ! 40: if ((int)s_loadas8bit->value) ! 41: dma.samplebits = 8; ! 42: else ! 43: dma.samplebits = 16; ! 44: ! 45: if (dma.samplebits != 16) { ! 46: Com_Printf("Don't currently support %i-bit data. Forcing 16-bit.\n", ! 47: dma.samplebits); ! 48: dma.samplebits = 16; ! 49: Cvar_SetValue( "s_loadas8bit", false ); ! 50: } ! 51: ! 52: s_khz = Cvar_Get("s_khz", "0", CVAR_ARCHIVE); ! 53: switch ((int)s_khz->value) { ! 54: case 48: ! 55: dma.speed = AL_RATE_48000; ! 56: break; ! 57: case 44: ! 58: dma.speed = AL_RATE_44100; ! 59: break; ! 60: case 32: ! 61: dma.speed = AL_RATE_32000; ! 62: break; ! 63: case 22: ! 64: dma.speed = AL_RATE_22050; ! 65: break; ! 66: case 16: ! 67: dma.speed = AL_RATE_16000; ! 68: break; ! 69: case 11: ! 70: dma.speed = AL_RATE_11025; ! 71: break; ! 72: case 8: ! 73: dma.speed = AL_RATE_8000; ! 74: break; ! 75: default: ! 76: dma.speed = AL_RATE_22050; ! 77: Com_Printf("Don't currently support %i kHz sample rate. Using %i.\n", ! 78: (int)s_khz->value, (int)(dma.speed/1000)); ! 79: } ! 80: ! 81: sndchannels = Cvar_Get("sndchannels", "2", CVAR_ARCHIVE); ! 82: dma.channels = (int)sndchannels->value; ! 83: if (dma.channels != 2) ! 84: Com_Printf("Don't currently support %i sound channels. Try 2.\n", ! 85: sndchannels); ! 86: ! 87: /***********************/ ! 88: ! 89: ac = alNewConfig(); ! 90: alSetChannels( ac, AL_STEREO ); ! 91: alSetSampFmt( ac, AL_SAMPFMT_TWOSCOMP ); ! 92: alSetQueueSize( ac, QSND_BUFFER_FRAMES ); ! 93: if (dma.samplebits == 8) ! 94: alSetWidth( ac, AL_SAMPLE_8 ); ! 95: else ! 96: alSetWidth( ac, AL_SAMPLE_16 ); ! 97: ! 98: sgisnd_aport = alOpenPort( "Quake", "w", ac ); ! 99: if (!sgisnd_aport) ! 100: { ! 101: printf( "failed to open audio port!\n" ); ! 102: } ! 103: ! 104: // set desired sample rate ! 105: pvbuf[0].param = AL_MASTER_CLOCK; ! 106: pvbuf[0].value.i = AL_CRYSTAL_MCLK_TYPE; ! 107: pvbuf[1].param = AL_RATE; ! 108: pvbuf[1].value.ll = alIntToFixed( dma.speed ); ! 109: alSetParams( alGetResource( sgisnd_aport ), pvbuf, 2 ); ! 110: if (pvbuf[1].sizeOut < 0) ! 111: printf( "illegal sample rate %d\n", dma.speed ); ! 112: ! 113: sgisnd_frames_per_ns = dma.speed * 1.0e-9; ! 114: ! 115: dma.samples = sizeof(dma_buffer)/(dma.samplebits/8); ! 116: dma.submission_chunk = 1; ! 117: ! 118: dma.buffer = (unsigned char *)dma_buffer; ! 119: ! 120: dma.samplepos = 0; ! 121: ! 122: alFreeConfig( ac ); ! 123: return true; ! 124: } ! 125: ! 126: ! 127: /* ! 128: ============== ! 129: SNDDMA_GetDMAPos ! 130: ! 131: return the current sample position (in mono samples, not stereo) ! 132: inside the recirculating dma buffer, so the mixing code will know ! 133: how many sample are required to fill it up. ! 134: =============== ! 135: */ ! 136: int SNDDMA_GetDMAPos(void) ! 137: { ! 138: long long ustFuture, ustNow; ! 139: if (!sgisnd_aport) return( 0 ); ! 140: alGetFrameTime( sgisnd_aport, &sgisnd_startframe, &ustFuture ); ! 141: dmGetUST( (unsigned long long *)&ustNow ); ! 142: sgisnd_startframe -= (long long)((ustFuture - ustNow) * sgisnd_frames_per_ns); ! 143: sgisnd_startframe += 100; ! 144: //printf( "frame %ld pos %d\n", frame, UST_TO_BUFFPOS( sgisnd_startframe ) ); ! 145: return( UST_TO_BUFFPOS( sgisnd_startframe ) ); ! 146: } ! 147: ! 148: /* ! 149: ============== ! 150: SNDDMA_Shutdown ! 151: ! 152: Reset the sound device for exiting ! 153: =============== ! 154: */ ! 155: void SNDDMA_Shutdown(void) ! 156: { ! 157: if (sgisnd_aport) alClosePort( sgisnd_aport ), sgisnd_aport = NULL; ! 158: return; ! 159: } ! 160: ! 161: /* ! 162: ============== ! 163: SNDDMA_Submit ! 164: ! 165: Send sound to device if buffer isn't really the dma buffer ! 166: =============== ! 167: */ ! 168: ! 169: extern int soundtime; ! 170: ! 171: void SNDDMA_Submit(void) ! 172: { ! 173: int nFillable, nFilled, nPos; ! 174: int nFrames, nFramesLeft; ! 175: unsigned endtime; ! 176: ! 177: if (!sgisnd_aport) return; ! 178: ! 179: nFillable = alGetFillable( sgisnd_aport ); ! 180: nFilled = QSND_BUFFER_FRAMES - nFillable; ! 181: ! 182: nFrames = dma.samples >> (dma.channels - 1); ! 183: ! 184: if (paintedtime - soundtime < nFrames) ! 185: nFrames = paintedtime - soundtime; ! 186: ! 187: if (nFrames <= QSND_SKID) return; ! 188: ! 189: nPos = UST_TO_BUFFPOS( sgisnd_startframe ); ! 190: ! 191: // dump re-written contents of the buffer ! 192: if (sgisnd_lastframewritten > sgisnd_startframe) ! 193: { ! 194: alDiscardFrames( sgisnd_aport, sgisnd_lastframewritten - sgisnd_startframe ); ! 195: } ! 196: else if ((int)(sgisnd_startframe - sgisnd_lastframewritten) >= QSND_BUFFER_FRAMES) ! 197: { ! 198: // blow away everything if we've underflowed ! 199: alDiscardFrames( sgisnd_aport, QSND_BUFFER_FRAMES ); ! 200: } ! 201: ! 202: // don't block ! 203: if (nFrames > nFillable) nFrames = nFillable; ! 204: ! 205: // account for stereo ! 206: nFramesLeft = nFrames; ! 207: if (nPos + nFrames * dma.channels > QSND_BUFFER_SIZE) ! 208: { ! 209: int nFramesAtEnd = (QSND_BUFFER_SIZE - nPos) >> (dma.channels - 1); ! 210: ! 211: alWriteFrames( sgisnd_aport, &dma_buffer[nPos], nFramesAtEnd ); ! 212: nPos = 0; ! 213: nFramesLeft -= nFramesAtEnd; ! 214: } ! 215: alWriteFrames( sgisnd_aport, &dma_buffer[nPos], nFramesLeft ); ! 216: ! 217: sgisnd_lastframewritten = sgisnd_startframe + nFrames; ! 218: } ! 219: ! 220: void SNDDMA_BeginPainting (void) ! 221: { ! 222: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.