// Load a SFX chunk into memory and ensure that it is locked. static dboolean LockSound(sfxinfo_t *sfxinfo) { // If the sound isn't loaded, load it now if (!GetAllocatedSoundBySfxInfoAndPitch(sfxinfo, NORM_PITCH)) if (!CacheSFX(sfxinfo)) return false; LockAllocatedSound(GetAllocatedSoundBySfxInfoAndPitch(sfxinfo, NORM_PITCH)); return true; }
// // Starting a sound means adding it // to the current list of active sounds // in the internal channels. // As the SFX info struct contains // e.g. a pointer to the raw data, // it is ignored. // As our sound handling does not handle // priority, it is ignored. // Pitching (that is, increased speed of playback) // is set, but currently not used by mixing. // int I_SDL_StartSound(sfxinfo_t *sfxinfo, int channel, int vol, int sep, int pitch) { allocated_sound_t *snd; if (!sound_initialized || channel < 0 || channel >= NUM_CHANNELS) return -1; // Release a sound effect if there is already one playing // on this channel ReleaseSoundOnChannel(channel); // Get the sound data if (!LockSound(sfxinfo)) return -1; snd = GetAllocatedSoundBySfxInfoAndPitch(sfxinfo, pitch); if (!snd) { allocated_sound_t *newsnd; // fetch the base sound effect, un-pitch-shifted snd = GetAllocatedSoundBySfxInfoAndPitch(sfxinfo, NORM_PITCH); if (!snd) return -1; if (s_randompitch) { newsnd = PitchShift(snd, pitch); if (newsnd) { LockAllocatedSound(newsnd); UnlockAllocatedSound(snd); snd = newsnd; } } } else LockAllocatedSound(snd); // play sound Mix_PlayChannel(channel, &snd->chunk, 0); channels_playing[channel] = snd; // set separation, etc. I_SDL_UpdateSoundParams(channel, vol, sep); return channel; }
static boolean CacheSFX(sfxinfo_t *sfxinfo) { int lumpnum; unsigned int lumplen; int samplerate; unsigned int length; byte *data; // need to load the sound lumpnum = sfxinfo->lumpnum; data = W_CacheLumpNum(lumpnum, PU_STATIC); lumplen = W_LumpLength(lumpnum); // Check the header, and ensure this is a valid sound if (lumplen < 8 || data[0] != 0x03 || data[1] != 0x00) { // Invalid sound return false; } // 16 bit sample rate field, 32 bit length field samplerate = (data[3] << 8) | data[2]; length = (data[7] << 24) | (data[6] << 16) | (data[5] << 8) | data[4]; // If the header specifies that the length of the sound is greater than // the length of the lump itself, this is an invalid sound lump // We also discard sound lumps that are less than 49 samples long, // as this is how DMX behaves - although the actual cut-off length // seems to vary slightly depending on the sample rate. This needs // further investigation to better understand the correct // behavior. if (length > lumplen - 8 || length <= 48) { return false; } // The DMX sound library seems to skip the first 16 and last 16 // bytes of the lump - reason unknown. data += 16; length -= 32; // Sample rate conversion if (!ExpandSoundData(sfxinfo, data + 8, samplerate, length)) { return false; } #ifdef DEBUG_DUMP_WAVS { char filename[16]; allocated_sound_t * snd; M_snprintf(filename, sizeof(filename), "%s.wav", DEH_String(sfxinfo->name)); snd = GetAllocatedSoundBySfxInfoAndPitch(sfxinfo, NORM_PITCH); WriteWAV(filename, snd->chunk.abuf, snd->chunk.alen,mixer_freq); } #endif // don't need the original lump any more W_ReleaseLumpNum(lumpnum); return true; }