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

unix.superglobalmegacorp.com

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