#include "../game/q_shared.h"
#include "../qcommon/qcommon.h"
#include "snd_public.h"
Include dependency graph for snd_local.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
|
|
Definition at line 142 of file snd_local.h. Referenced by S_ChannelSetup(), and S_ClearSoundBuffer(). |
|
|
Definition at line 155 of file snd_local.h. Referenced by S_PaintChannels(), S_RawSamples(), and S_UpdateBackgroundTrack(). |
|
|
Definition at line 193 of file snd_local.h. |
|
|
Definition at line 29 of file snd_local.h. |
|
|
Definition at line 189 of file snd_local.h. |
|
|
Definition at line 188 of file snd_local.h. |
|
|
Definition at line 31 of file snd_local.h. Referenced by encodeMuLaw(), encodeWavelet(), ResampleSfx(), S_LoadSound(), S_PaintChannelFrom16(), S_PaintChannelFromADPCM(), S_PaintChannelFromMuLaw(), S_PaintChannelFromWavelet(), and SND_setup(). |
|
|
Definition at line 33 of file snd_local.h. Referenced by S_AdpcmEncodeSound(), and S_AdpcmGetSamples(). |
|
|
Definition at line 32 of file snd_local.h. Referenced by S_PaintChannelFromWavelet(). |
|
|
Definition at line 73 of file snd_local.h. |
|
|
Definition at line 106 of file snd_local.h. |
|
|
Referenced by S_AdpcmEncodeSound(), S_AdpcmGetSamples(), and S_AdpcmMemoryNeeded(). |
|
|
Referenced by S_AddLoopSounds(), and S_ClearSoundBuffer(). |
|
|
|
||||||||||||
|
Definition at line 173 of file snd_wavelet.c. References byte, i, mulawToShort, sndBuffer_s::size, sndBuffer, sndBuffer_s::sndChunk, and wt1(). Referenced by S_PaintChannelFromWavelet(). 00173 {
00174 float wksp[4097];
00175 int i;
00176 byte *out;
00177
00178 int size = chunk->size;
00179
00180 out = (byte *)chunk->sndChunk;
00181 for(i=0;i<size;i++) {
00182 wksp[i] = mulawToShort[out[i]];
00183 }
00184
00185 wt1(wksp, size, -1);
00186
00187 if (!to) return;
00188
00189 for(i=0; i<size; i++) {
00190 to[i] = wksp[i];
00191 }
00192 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 195 of file snd_wavelet.c. References byte, i, madeTable, MuLawDecode(), MuLawEncode(), mulawToShort, sndBuffer_s::next, sfx_t, sndBuffer_s::size, SND_CHUNK_SIZE, SND_malloc(), sndBuffer, sndBuffer_s::sndChunk, sfx_s::soundData, and sfx_s::soundLength. Referenced by S_LoadSound(). 00195 {
00196 int i, samples, size, grade, poop;
00197 sndBuffer *newchunk, *chunk;
00198 byte *out;
00199
00200 if (!madeTable) {
00201 for (i=0;i<256;i++) {
00202 mulawToShort[i] = (float)MuLawDecode((byte)i);
00203 }
00204 madeTable = qtrue;
00205 }
00206
00207 chunk = NULL;
00208 samples = sfx->soundLength;
00209 grade = 0;
00210
00211 while(samples>0) {
00212 size = samples;
00213 if (size>(SND_CHUNK_SIZE*2)) {
00214 size = (SND_CHUNK_SIZE*2);
00215 }
00216
00217 newchunk = SND_malloc();
00218 if (sfx->soundData == NULL) {
00219 sfx->soundData = newchunk;
00220 } else {
00221 chunk->next = newchunk;
00222 }
00223 chunk = newchunk;
00224 out = (byte *)chunk->sndChunk;
00225 for(i=0; i<size; i++) {
00226 poop = packets[0]+grade;
00227 if (poop>32767) {
00228 poop = 32767;
00229 } else if (poop<-32768) {
00230 poop = -32768;
00231 }
00232 out[i] = MuLawEncode((short)poop);
00233 grade = poop - mulawToShort[out[i]];
00234 packets++;
00235 }
00236 chunk->size = size;
00237 samples -= size;
00238 }
00239 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 123 of file snd_wavelet.c. References byte, i, madeTable, MuLawDecode(), MuLawEncode(), mulawToShort, sndBuffer_s::next, sfx_t, sndBuffer_s::size, SND_CHUNK_SIZE, SND_malloc(), sndBuffer, sndBuffer_s::sndChunk, sfx_s::soundData, sfx_s::soundLength, and wt1(). Referenced by S_LoadSound(). 00123 {
00124 float wksp[4097], temp;
00125 int i, samples, size;
00126 sndBuffer *newchunk, *chunk;
00127 byte *out;
00128
00129 if (!madeTable) {
00130 for (i=0;i<256;i++) {
00131 mulawToShort[i] = (float)MuLawDecode((byte)i);
00132 }
00133 madeTable = qtrue;
00134 }
00135 chunk = NULL;
00136
00137 samples = sfx->soundLength;
00138 while(samples>0) {
00139 size = samples;
00140 if (size>(SND_CHUNK_SIZE*2)) {
00141 size = (SND_CHUNK_SIZE*2);
00142 }
00143
00144 if (size<4) {
00145 size = 4;
00146 }
00147
00148 newchunk = SND_malloc();
00149 if (sfx->soundData == NULL) {
00150 sfx->soundData = newchunk;
00151 } else {
00152 chunk->next = newchunk;
00153 }
00154 chunk = newchunk;
00155 for(i=0; i<size; i++) {
00156 wksp[i] = *packets;
00157 packets++;
00158 }
00159 wt1(wksp, size, 1);
00160 out = (byte *)chunk->sndChunk;
00161
00162 for(i=0;i<size;i++) {
00163 temp = wksp[i];
00164 if (temp > 32767) temp = 32767; else if (temp<-32768) temp = -32768;
00165 out[i] = MuLawEncode((short)temp);
00166 }
00167
00168 chunk->size = size;
00169 samples -= size;
00170 }
00171 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 290 of file snd_adpcm.c. References sndBuffer_s::adpcm, adpcm_state_t, byte, count, adpcm_state::index, n, sndBuffer_s::next, S_AdpcmEncode(), adpcm_state::sample, sfx_t, SND_CHUNK_SIZE_BYTE, SND_malloc(), sndBuffer, sndBuffer_s::sndChunk, sfx_s::soundData, sfx_s::soundLength, and state. Referenced by S_LoadSound(). 00290 {
00291 adpcm_state_t state;
00292 int inOffset;
00293 int count;
00294 int n;
00295 sndBuffer *newchunk, *chunk;
00296 byte *out;
00297
00298 inOffset = 0;
00299 count = sfx->soundLength;
00300 state.index = 0;
00301 state.sample = samples[0];
00302
00303 chunk = NULL;
00304 while( count ) {
00305 n = count;
00306 if( n > SND_CHUNK_SIZE_BYTE*2 ) {
00307 n = SND_CHUNK_SIZE_BYTE*2;
00308 }
00309
00310 newchunk = SND_malloc();
00311 if (sfx->soundData == NULL) {
00312 sfx->soundData = newchunk;
00313 } else {
00314 chunk->next = newchunk;
00315 }
00316 chunk = newchunk;
00317
00318 // output the header
00319 chunk->adpcm.index = state.index;
00320 chunk->adpcm.sample = state.sample;
00321
00322 out = (byte *)chunk->sndChunk;
00323
00324 // encode the samples
00325 S_AdpcmEncode( samples + inOffset, out, n, &state );
00326
00327 inOffset += n;
00328 count -= n;
00329 }
00330 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 271 of file snd_adpcm.c. References sndBuffer_s::adpcm, adpcm_state_t, byte, adpcm_state::index, S_AdpcmDecode(), adpcm_state::sample, SND_CHUNK_SIZE_BYTE, sndBuffer, sndBuffer_s::sndChunk, and state. Referenced by S_PaintChannelFromADPCM(), and S_PaintChannelFromWavelet(). 00271 {
00272 adpcm_state_t state;
00273 byte *out;
00274
00275 // get the starting state from the block header
00276 state.index = chunk->adpcm.index;
00277 state.sample = chunk->adpcm.sample;
00278
00279 out = (byte *)chunk->sndChunk;
00280 // get samples
00281 S_AdpcmDecode( out, to, SND_CHUNK_SIZE_BYTE*2, &state );
00282 }
|
Here is the call graph for this function:

|
|
Definition at line 237 of file snd_adpcm.c. References adpcm_state_t, dma, wavinfo_t::rate, wavinfo_t::samples, and dma_t::speed. 00237 {
00238 float scale;
00239 int scaledSampleCount;
00240 int sampleMemory;
00241 int blockCount;
00242 int headerMemory;
00243
00244 // determine scale to convert from input sampling rate to desired sampling rate
00245 scale = (float)info->rate / dma.speed;
00246
00247 // calc number of samples at playback sampling rate
00248 scaledSampleCount = info->samples / scale;
00249
00250 // calc memory need to store those samples using ADPCM at 4 bits per sample
00251 sampleMemory = scaledSampleCount / 2;
00252
00253 // calc number of sample blocks needed of PAINTBUFFER_SIZE
00254 blockCount = scaledSampleCount / PAINTBUFFER_SIZE;
00255 if( scaledSampleCount % PAINTBUFFER_SIZE ) {
00256 blockCount++;
00257 }
00258
00259 // calc memory needed to store the block headers
00260 headerMemory = blockCount * sizeof(adpcm_state_t);
00261
00262 return sampleMemory + headerMemory;
00263 }
|
|
|
Definition at line 1608 of file snd_dma.c. References buffer, Com_DPrintf(), Com_Milliseconds(), i, sfx_s::inMemory, sfx_s::lastTimeUsed, sndBuffer_s::next, s_knownSfx, sfx_t, SND_free(), sndBuffer, sfx_s::soundData, and sfx_s::soundName. Referenced by SND_malloc(). 01608 {
01609 int i, oldest, used;
01610 sfx_t *sfx;
01611 sndBuffer *buffer, *nbuffer;
01612
01613 oldest = Com_Milliseconds();
01614 used = 0;
01615
01616 for (i=1 ; i < s_numSfx ; i++) {
01617 sfx = &s_knownSfx[i];
01618 if (sfx->inMemory && sfx->lastTimeUsed<oldest) {
01619 used = i;
01620 oldest = sfx->lastTimeUsed;
01621 }
01622 }
01623
01624 sfx = &s_knownSfx[used];
01625
01626 Com_DPrintf("S_FreeOldestSound: freeing sound %s\n", sfx->soundName);
01627
01628 buffer = sfx->soundData;
01629 while(buffer != NULL) {
01630 nbuffer = buffer->next;
01631 SND_free(buffer);
01632 buffer = nbuffer;
01633 }
01634 sfx->inMemory = qfalse;
01635 sfx->soundData = NULL;
01636 }
|
Here is the call graph for this function:

|
|
Definition at line 941 of file snd_dma.c. 00941 {
00942 return s_rawsamples;
00943 }
|
|
|
Definition at line 329 of file snd_mem.c. References byte, wavinfo_t::channels, Com_DPrintf(), Com_Milliseconds(), Com_Printf(), data, wavinfo_t::dataofs, encodeMuLaw(), encodeWavelet(), FS_FreeFile(), FS_ReadFile(), GetWavinfo(), Hunk_AllocateTempMemory(), Hunk_FreeTempMemory(), sfx_s::lastTimeUsed, qboolean, qfalse, wavinfo_t::rate, ResampleSfx(), ResampleSfxRaw(), S_AdpcmEncodeSound(), S_COLOR_YELLOW, wavinfo_t::samples, sfx_t, SND_CHUNK_SIZE, sfx_s::soundCompressed, sfx_s::soundCompressionMethod, sfx_s::soundData, sfx_s::soundLength, sfx_s::soundName, and wavinfo_t::width. Referenced by S_memoryLoad(). 00330 {
00331 byte *data;
00332 short *samples;
00333 wavinfo_t info;
00334 int size;
00335
00336 // player specific sounds are never directly loaded
00337 if ( sfx->soundName[0] == '*') {
00338 return qfalse;
00339 }
00340
00341 // load it in
00342 size = FS_ReadFile( sfx->soundName, (void **)&data );
00343 if ( !data ) {
00344 return qfalse;
00345 }
00346
00347 info = GetWavinfo( sfx->soundName, data, size );
00348 if ( info.channels != 1 ) {
00349 Com_Printf ("%s is a stereo wav file\n", sfx->soundName);
00350 FS_FreeFile (data);
00351 return qfalse;
00352 }
00353
00354 if ( info.width == 1 ) {
00355 Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is a 8 bit wav file\n", sfx->soundName);
00356 }
00357
00358 if ( info.rate != 22050 ) {
00359 Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is not a 22kHz wav file\n", sfx->soundName);
00360 }
00361
00362 samples = Hunk_AllocateTempMemory(info.samples * sizeof(short) * 2);
00363
00364 sfx->lastTimeUsed = Com_Milliseconds()+1;
00365
00366 // each of these compression schemes works just fine
00367 // but the 16bit quality is much nicer and with a local
00368 // install assured we can rely upon the sound memory
00369 // manager to do the right thing for us and page
00370 // sound in as needed
00371
00372 if( sfx->soundCompressed == qtrue) {
00373 sfx->soundCompressionMethod = 1;
00374 sfx->soundData = NULL;
00375 sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, (data + info.dataofs) );
00376 S_AdpcmEncodeSound(sfx, samples);
00377 #if 0
00378 } else if (info.samples>(SND_CHUNK_SIZE*16) && info.width >1) {
00379 sfx->soundCompressionMethod = 3;
00380 sfx->soundData = NULL;
00381 sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, (data + info.dataofs) );
00382 encodeMuLaw( sfx, samples);
00383 } else if (info.samples>(SND_CHUNK_SIZE*6400) && info.width >1) {
00384 sfx->soundCompressionMethod = 2;
00385 sfx->soundData = NULL;
00386 sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, (data + info.dataofs) );
00387 encodeWavelet( sfx, samples);
00388 #endif
00389 } else {
00390 sfx->soundCompressionMethod = 0;
00391 sfx->soundLength = info.samples;
00392 sfx->soundData = NULL;
00393 ResampleSfx( sfx, info.rate, info.width, data + info.dataofs, qfalse );
00394 }
00395
00396 Hunk_FreeTempMemory(samples);
00397 FS_FreeFile( data );
00398
00399 return qtrue;
00400 }
|
Here is the call graph for this function:

|
|
Definition at line 427 of file snd_dma.c. References sfx_s::defaultSound, sfx_s::inMemory, S_LoadSound(), and sfx_t. Referenced by S_AddLoopingSound(), S_AddRealLoopingSound(), S_RegisterSound(), and S_StartSound(). 00427 {
00428 // load the sound file
00429 if ( !S_LoadSound ( sfx ) ) {
00430 // Com_Printf( S_COLOR_YELLOW "WARNING: couldn't load sound: %s\n", sfx->soundName );
00431 sfx->defaultSound = qtrue;
00432 }
00433 sfx->inMemory = qtrue;
00434 }
|
Here is the call graph for this function:

|
|
Definition at line 562 of file snd_mix.c. References ch, Com_Memset(), count, i, portable_samplepair_t::left, channel_t::leftvol, MAX_RAW_SAMPLES, NULL, paintbuffer, portable_samplepair_t::right, channel_t::rightvol, s, S_PaintChannelFrom16(), S_PaintChannelFromADPCM(), S_PaintChannelFromMuLaw(), S_PaintChannelFromWavelet(), s_paintedtime, s_rawend, s_rawsamples, S_TransferPaintBuffer(), s_volume, sfx_t, snd_vol, sfx_s::soundCompressionMethod, sfx_s::soundData, sfx_s::soundLength, channel_t::startSample, channel_t::thesfx, and cvar_s::value. Referenced by S_Update_(). 00562 {
00563 int i;
00564 int end;
00565 channel_t *ch;
00566 sfx_t *sc;
00567 int ltime, count;
00568 int sampleOffset;
00569
00570
00571 snd_vol = s_volume->value*255;
00572
00573 //Com_Printf ("%i to %i\n", s_paintedtime, endtime);
00574 while ( s_paintedtime < endtime ) {
00575 // if paintbuffer is smaller than DMA buffer
00576 // we may need to fill it multiple times
00577 end = endtime;
00578 if ( endtime - s_paintedtime > PAINTBUFFER_SIZE ) {
00579 end = s_paintedtime + PAINTBUFFER_SIZE;
00580 }
00581
00582 // clear the paint buffer to either music or zeros
00583 if ( s_rawend < s_paintedtime ) {
00584 if ( s_rawend ) {
00585 //Com_DPrintf ("background sound underrun\n");
00586 }
00587 Com_Memset(paintbuffer, 0, (end - s_paintedtime) * sizeof(portable_samplepair_t));
00588 } else {
00589 // copy from the streaming sound source
00590 int s;
00591 int stop;
00592
00593 stop = (end < s_rawend) ? end : s_rawend;
00594
00595 for ( i = s_paintedtime ; i < stop ; i++ ) {
00596 s = i&(MAX_RAW_SAMPLES-1);
00597 paintbuffer[i-s_paintedtime] = s_rawsamples[s];
00598 }
00599 // if (i != end)
00600 // Com_Printf ("partial stream\n");
00601 // else
00602 // Com_Printf ("full stream\n");
00603 for ( ; i < end ; i++ ) {
00604 paintbuffer[i-s_paintedtime].left =
00605 paintbuffer[i-s_paintedtime].right = 0;
00606 }
00607 }
00608
00609 // paint in the channels.
00610 ch = s_channels;
00611 for ( i = 0; i < MAX_CHANNELS ; i++, ch++ ) {
00612 if ( !ch->thesfx || (ch->leftvol<0.25 && ch->rightvol<0.25 )) {
00613 continue;
00614 }
00615
00616 ltime = s_paintedtime;
00617 sc = ch->thesfx;
00618
00619 sampleOffset = ltime - ch->startSample;
00620 count = end - ltime;
00621 if ( sampleOffset + count > sc->soundLength ) {
00622 count = sc->soundLength - sampleOffset;
00623 }
00624
00625 if ( count > 0 ) {
00626 if( sc->soundCompressionMethod == 1) {
00627 S_PaintChannelFromADPCM (ch, sc, count, sampleOffset, ltime - s_paintedtime);
00628 } else if( sc->soundCompressionMethod == 2) {
00629 S_PaintChannelFromWavelet (ch, sc, count, sampleOffset, ltime - s_paintedtime);
00630 } else if( sc->soundCompressionMethod == 3) {
00631 S_PaintChannelFromMuLaw (ch, sc, count, sampleOffset, ltime - s_paintedtime);
00632 } else {
00633 S_PaintChannelFrom16 (ch, sc, count, sampleOffset, ltime - s_paintedtime);
00634 }
00635 }
00636 }
00637
00638 // paint in the looped channels.
00639 ch = loop_channels;
00640 for ( i = 0; i < numLoopChannels ; i++, ch++ ) {
00641 if ( !ch->thesfx || (!ch->leftvol && !ch->rightvol )) {
00642 continue;
00643 }
00644
00645 ltime = s_paintedtime;
00646 sc = ch->thesfx;
00647
00648 if (sc->soundData==NULL || sc->soundLength==0) {
00649 continue;
00650 }
00651 // we might have to make two passes if it
00652 // is a looping sound effect and the end of
00653 // the sample is hit
00654 do {
00655 sampleOffset = (ltime % sc->soundLength);
00656
00657 count = end - ltime;
00658 if ( sampleOffset + count > sc->soundLength ) {
00659 count = sc->soundLength - sampleOffset;
00660 }
00661
00662 if ( count > 0 ) {
00663 if( sc->soundCompressionMethod == 1) {
00664 S_PaintChannelFromADPCM (ch, sc, count, sampleOffset, ltime - s_paintedtime);
00665 } else if( sc->soundCompressionMethod == 2) {
00666 S_PaintChannelFromWavelet (ch, sc, count, sampleOffset, ltime - s_paintedtime);
00667 } else if( sc->soundCompressionMethod == 3) {
00668 S_PaintChannelFromMuLaw (ch, sc, count, sampleOffset, ltime - s_paintedtime);
00669 } else {
00670 S_PaintChannelFrom16 (ch, sc, count, sampleOffset, ltime - s_paintedtime);
00671 }
00672 ltime += count;
00673 }
00674 } while ( ltime < end);
00675 }
00676
00677 // transfer out according to DMA format
00678 S_TransferPaintBuffer( end );
00679 s_paintedtime = end;
00680 }
00681 }
|
Here is the call graph for this function:

|
|
|
|
|
Definition at line 53 of file snd_mem.c. References freelist, inUse, sndBuffer, and v. Referenced by S_FreeOldestSound(). 00053 {
00054 *(sndBuffer **)v = freelist;
00055 freelist = (sndBuffer*)v;
00056 inUse += sizeof(sndBuffer);
00057 }
|
|
|
Definition at line 59 of file snd_mem.c. References freelist, inUse, sndBuffer_s::next, S_FreeOldestSound(), sndBuffer, totalInUse, and v. Referenced by encodeMuLaw(), encodeWavelet(), ResampleSfx(), S_AdpcmEncodeSound(), and S_DefaultSound(). 00059 {
00060 sndBuffer *v;
00061 redo:
00062 if (freelist == NULL) {
00063 S_FreeOldestSound();
00064 goto redo;
00065 }
00066
00067 inUse -= sizeof(sndBuffer);
00068 totalInUse += sizeof(sndBuffer);
00069
00070 v = freelist;
00071 freelist = *(sndBuffer **)freelist;
00072 v->next = NULL;
00073 return v;
00074 }
|
Here is the call graph for this function:

|
|
Definition at line 76 of file snd_mem.c. References buffer, Com_Printf(), CVAR_ARCHIVE, Cvar_Get(), CVAR_LATCH, cvar_t, DEF_COMSOUNDMEGS, freelist, cvar_s::integer, inUse, malloc(), p, q, sfxScratchBuffer, sfxScratchPointer, SND_CHUNK_SIZE, and sndBuffer. Referenced by S_BeginRegistration(). 00076 {
00077 sndBuffer *p, *q;
00078 cvar_t *cv;
00079 int scs;
00080
00081 cv = Cvar_Get( "com_soundMegs", DEF_COMSOUNDMEGS, CVAR_LATCH | CVAR_ARCHIVE );
00082
00083 scs = (cv->integer*1536);
00084
00085 buffer = malloc(scs*sizeof(sndBuffer) );
00086 // allocate the stack based hunk allocator
00087 sfxScratchBuffer = malloc(SND_CHUNK_SIZE * sizeof(short) * 4); //Hunk_Alloc(SND_CHUNK_SIZE * sizeof(short) * 4);
00088 sfxScratchPointer = NULL;
00089
00090 inUse = scs*sizeof(sndBuffer);
00091 p = buffer;;
00092 q = p + scs;
00093 while (--q > p)
00094 *(sndBuffer **)q = q-1;
00095
00096 *(sndBuffer **)q = NULL;
00097 freelist = p + scs - 1;
00098
00099 Com_Printf("Sound memory manager started\n");
00100 }
|
Here is the call graph for this function:

|
|
Definition at line 315 of file macosx_sndcore.m. References dma_t::buffer, Com_Printf(), dma, DSoundError(), DWORD, gSndBufSize, HRESULT(), locksize, pDSBuf, and S_Shutdown(). Referenced by S_ClearSoundBuffer(), S_Update_(), and SNDDMA_InitDS(). 00315 {
00316 }
|
Here is the call graph for this function:

|
|
Definition at line 274 of file macosx_sndcore.m. References dma, DWORD, pDSBuf, s, and dma_t::samples. Referenced by S_GetSoundtime(). 00275 {
00276 return s_chunkCount * dma.submission_chunk;
00277 }
|
|
|
Definition at line 143 of file macosx_sndcore.m. References Com_DPrintf(), dma, dsound_init, memset(), NULL, qboolean, and SNDDMA_InitDS(). Referenced by S_Init(). 00144 {
00145 cvar_t *bufferSize;
00146 cvar_t *chunkSize;
00147 OSStatus status;
00148 UInt32 propertySize, bufferByteCount;
00149
00150 if (s_isRunning)
00151 return qtrue;
00152
00153 chunkSize = ri.Cvar_Get( "s_chunksize", "2048", CVAR_ARCHIVE );
00154 bufferSize = ri.Cvar_Get( "s_buffersize", "16384", CVAR_ARCHIVE );
00155 Com_Printf(" Chunk size = %d\n", chunkSize->integer);
00156 Com_Printf("Buffer size = %d\n", bufferSize->integer);
00157
00158 if (!chunkSize->integer)
00159 ri.Error(ERR_FATAL, "s_chunksize must be non-zero\n");
00160 if (!bufferSize->integer)
00161 ri.Error(ERR_FATAL, "s_buffersize must be non-zero\n");
00162 if (chunkSize->integer >= bufferSize->integer)
00163 ri.Error(ERR_FATAL, "s_chunksize must be less than s_buffersize\n");
00164 if (bufferSize->integer % chunkSize->integer)
00165 ri.Error(ERR_FATAL, "s_buffersize must be an even multiple of s_chunksize\n");
00166
00167 // Get the output device
00168 propertySize = sizeof(outputDeviceID);
00169 status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &propertySize, &outputDeviceID);
00170 if (status) {
00171 Com_Printf("AudioHardwareGetProperty returned %d\n", status);
00172 return qfalse;
00173 }
00174
00175 if (outputDeviceID == kAudioDeviceUnknown) {
00176 Com_Printf("AudioHardwareGetProperty: outputDeviceID is kAudioDeviceUnknown\n");
00177 return qfalse;
00178 }
00179
00180 // Configure the output device
00181 propertySize = sizeof(bufferByteCount);
00182 bufferByteCount = chunkSize->integer * sizeof(float);
00183 status = AudioDeviceSetProperty(outputDeviceID, NULL, 0, NO, kAudioDevicePropertyBufferSize, propertySize, &bufferByteCount);
00184 if (status) {
00185 Com_Printf("AudioDeviceSetProperty: returned %d when setting kAudioDevicePropertyBufferSize to %d\n", status, chunkSize->integer);
00186 return qfalse;
00187 }
00188
00189 propertySize = sizeof(bufferByteCount);
00190 status = AudioDeviceGetProperty(outputDeviceID, 0, NO, kAudioDevicePropertyBufferSize, &propertySize, &bufferByteCount);
00191 if (status) {
00192 Com_Printf("AudioDeviceGetProperty: returned %d when setting kAudioDevicePropertyBufferSize\n", status);
00193 return qfalse;
00194 }
00195
00196 // Print out the device status
00197 propertySize = sizeof(outputStreamBasicDescription);
00198 status = AudioDeviceGetProperty(outputDeviceID, 0, NO, kAudioDevicePropertyStreamFormat, &propertySize, &outputStreamBasicDescription);
00199 if (status) {
00200 Com_Printf("AudioDeviceGetProperty: returned %d when getting kAudioDevicePropertyStreamFormat\n", status);
00201 return qfalse;
00202 }
00203
00204 Com_Printf("Hardware format:\n");
00205 Com_Printf(" %f mSampleRate\n", outputStreamBasicDescription.mSampleRate);
00206 Com_Printf(" %c%c%c%c mFormatID\n",
00207 (outputStreamBasicDescription.mFormatID & 0xff000000) >> 24,
00208 (outputStreamBasicDescription.mFormatID & 0x00ff0000) >> 16,
00209 (outputStreamBasicDescription.mFormatID & 0x0000ff00) >> 8,
00210 (outputStreamBasicDescription.mFormatID & 0x000000ff) >> 0);
00211 Com_Printf(" %5d mBytesPerPacket\n", outputStreamBasicDescription.mBytesPerPacket);
00212 Com_Printf(" %5d mFramesPerPacket\n", outputStreamBasicDescription.mFramesPerPacket);
00213 Com_Printf(" %5d mBytesPerFrame\n", outputStreamBasicDescription.mBytesPerFrame);
00214 Com_Printf(" %5d mChannelsPerFrame\n", outputStreamBasicDescription.mChannelsPerFrame);
00215 Com_Printf(" %5d mBitsPerChannel\n", outputStreamBasicDescription.mBitsPerChannel);
00216
00217 if(outputStreamBasicDescription.mFormatID != kAudioFormatLinearPCM) {
00218 Com_Printf("Default Audio Device doesn't support Linear PCM!");
00219 return qfalse;
00220 }
00221
00222 // Start sound running
00223 status = AudioDeviceAddIOProc(outputDeviceID, audioDeviceIOProc, NULL);
00224 if (status) {
00225 Com_Printf("AudioDeviceAddIOProc: returned %d\n", status);
00226 return qfalse;
00227 }
00228
00229 submissionChunk = chunkSize->integer;
00230 if (outputStreamBasicDescription.mSampleRate == 44100) {
00231 submissionChunk = chunkSize->integer/2;
00232 }
00233 maxMixedSamples = bufferSize->integer;
00234 s_mixedSamples = calloc(1, sizeof(*s_mixedSamples) * maxMixedSamples);
00235 Com_Printf("Chunk Count = %d\n", (maxMixedSamples / submissionChunk));
00236
00237 // Tell the main app what we expect from it
00238 |