static void ReleaseSoundOnChannel(int channel) { sfxinfo_t *sfxinfo = channels_playing[channel]; if (sfxinfo == NULL) { return; } channels_playing[channel] = NULL; UnlockAllocatedSound(sfxinfo->driver_data); }
// // 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; }
// When a sound stops, check if it is still playing. If it is not, // we can mark the sound data as CACHE to be freed back for other // means. static void ReleaseSoundOnChannel(int channel) { allocated_sound_t *snd = channels_playing[channel]; if (!snd) return; channels_playing[channel] = NULL; UnlockAllocatedSound(snd); // if the sound is a pitch-shift and it's not in use, immediately free it if (snd->pitch != NORM_PITCH && snd->use_count <= 0) FreeAllocatedSound(snd); }