Example #1
0
// 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;
}
Example #2
0
//
// 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;
}
Example #3
0
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;
}