void SND_setup() { sndBuffer *p, *q; cvar_t * cv; int scs; cv = Cvar_Get("com_soundMegs", DEF_COMSOUNDMEGS, CVAR_LATCH | CVAR_ARCHIVE); scs = (cv->integer * 1536); buffer = (sndBuffer *)malloc(scs * sizeof(sndBuffer)); // allocate the stack based hunk allocator sfxScratchBuffer = (short *)malloc(SND_CHUNK_SIZE * sizeof(short) * 4); //Hunk_Alloc(SND_CHUNK_SIZE * sizeof(short) * 4); sfxScratchPointer = NULL; inUse = scs * sizeof(sndBuffer); p = buffer;; q = p + scs; while (--q > p) { *(sndBuffer **)q = q - 1; } *(sndBuffer **)q = NULL; freelist = p + scs - 1; Com_Printf("Sound memory manager started\n"); }
/* * ================ * ResampleSfx * * resample / decimate to the current source rate * ================ */ static void ResampleSfx(sfx_t *sfx, int inrate, int inwidth, byte *data, bool compressed) { int outcount; int srcsample; float stepscale; int i; int sample, samplefrac, fracstep; int part; sndBuffer *chunk; stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2 outcount = sfx->soundLength / stepscale; sfx->soundLength = outcount; samplefrac = 0; fracstep = stepscale * 256; chunk = sfx->soundData; for (i = 0; i < outcount; i++) { srcsample = samplefrac >> 8; samplefrac += fracstep; if (inwidth == 2) { sample = LittleShort(((short *)data)[srcsample]); } else { sample = (int)((unsigned char)(data[srcsample]) - 128) << 8; } part = (i & (SND_CHUNK_SIZE - 1)); if (part == 0) { sndBuffer *newchunk; newchunk = SND_malloc(); if (chunk == NULL) { sfx->soundData = newchunk; } else { chunk->next = newchunk; } chunk = newchunk; } chunk->sndChunk[part] = sample; } }
//============================================================================= /* * ============== * S_LoadSound * * The filename may be different than sfx->name in the case * of a forced fallback of a player specific sound * ============== */ bool S_LoadSound(sfx_t *sfx) { byte * data; short * samples; wavinfo_t info; int size; // player specific sounds are never directly loaded if (sfx->soundName[0] == '*') { return(false); } // load it in size = FS_ReadFile(sfx->soundName, (void **)&data); if (!data) { return(false); } info = GetWavinfo(sfx->soundName, data, size); if (info.channels != 1) { Com_Printf("%s is a stereo wav file\n", sfx->soundName); FS_FreeFile(data); return(false); } if (info.width == 1) { Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is a 8 bit wav file\n", sfx->soundName); } if (info.rate != 22050) { Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is not a 22kHz wav file\n", sfx->soundName); } samples = (short *)Hunk_AllocateTempMemory(info.samples * sizeof(short) * 2); sfx->lastTimeUsed = Com_Milliseconds() + 1; // each of these compression schemes works just fine // but the 16bit quality is much nicer and with a local // install assured we can rely upon the sound memory // manager to do the right thing for us and page // sound in as needed if (sfx->soundCompressed == true) { sfx->soundCompressionMethod = 1; sfx->soundData = NULL; sfx->soundLength = ResampleSfxRaw(samples, info.rate, info.width, info.samples, (data + info.dataofs)); S_AdpcmEncodeSound(sfx, samples); } else { sfx->soundCompressionMethod = 0; sfx->soundLength = info.samples; sfx->soundData = NULL; ResampleSfx(sfx, info.rate, info.width, data + info.dataofs, false); } Hunk_FreeTempMemory(samples); FS_FreeFile(data); return(true); }