mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
Added A_SoundPitch and an optional pitch parameter to A_PlaySound and S_Sound.
- Note: Because sound channels are not in zscript, there's no way to modify a sound made by S_Sound.
This commit is contained in:
parent
9d66a5105a
commit
15eabfd055
10 changed files with 144 additions and 30 deletions
|
@ -142,6 +142,15 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_StopSound, NativeStopSound)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_SoundPitch, S_ChangeSoundPitch)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(channel);
|
||||
PARAM_FLOAT(pitch);
|
||||
S_ChangeSoundPitch(self, channel, pitch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_SoundVolume, S_ChangeSoundVolume)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
|
@ -160,7 +169,8 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_PlaySound, A_PlaySound)
|
|||
PARAM_BOOL(looping);
|
||||
PARAM_FLOAT(attenuation);
|
||||
PARAM_BOOL(local);
|
||||
A_PlaySound(self, soundid, channel, volume, looping, attenuation, local);
|
||||
PARAM_FLOAT(pitch);
|
||||
A_PlaySound(self, soundid, channel, volume, looping, attenuation, local, pitch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -158,6 +158,9 @@ public:
|
|||
void ChannelVolume(FISoundChannel *, float)
|
||||
{
|
||||
}
|
||||
void ChannelPitch(FISoundChannel *, float)
|
||||
{
|
||||
}
|
||||
|
||||
// Streaming sounds.
|
||||
SoundStream *CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata)
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "i_soundinternal.h"
|
||||
|
||||
class FileReader;
|
||||
struct FSoundChan;
|
||||
|
||||
enum ECodecType
|
||||
{
|
||||
|
@ -130,6 +131,9 @@ public:
|
|||
// Changes a channel's volume.
|
||||
virtual void ChannelVolume (FISoundChannel *chan, float volume) = 0;
|
||||
|
||||
// Changes a channel's pitch.
|
||||
virtual void ChannelPitch(FISoundChannel *chan, float volume) = 0;
|
||||
|
||||
// Marks a channel's start time without actually playing it.
|
||||
virtual void MarkStartTime (FISoundChannel *chan) = 0;
|
||||
|
||||
|
|
|
@ -109,6 +109,7 @@ struct FISoundChannel
|
|||
float DistanceScale;
|
||||
float DistanceSqr;
|
||||
bool ManualRolloff;
|
||||
int ChanFlags;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1870,6 +1870,20 @@ void OpenALSoundRenderer::ChannelVolume(FISoundChannel *chan, float volume)
|
|||
alSourcef(source, AL_GAIN, SfxVolume * volume);
|
||||
}
|
||||
|
||||
void OpenALSoundRenderer::ChannelPitch(FISoundChannel *chan, float pitch)
|
||||
{
|
||||
if (chan == NULL || chan->SysChannel == NULL)
|
||||
return;
|
||||
|
||||
alDeferUpdatesSOFT();
|
||||
|
||||
ALuint source = GET_PTRID(chan->SysChannel);
|
||||
if (WasInWater && !(chan->ChanFlags & CHAN_UI))
|
||||
alSourcef(source, AL_PITCH, MAX(pitch, 0.0001f)*PITCH_MULT);
|
||||
else
|
||||
alSourcef(source, AL_PITCH, MAX(pitch, 0.0001f));
|
||||
}
|
||||
|
||||
void OpenALSoundRenderer::FreeSource(ALuint source)
|
||||
{
|
||||
alSourceRewind(source);
|
||||
|
@ -2118,7 +2132,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
|
|||
|
||||
const_cast<ReverbContainer*>(env)->Modified = false;
|
||||
}
|
||||
|
||||
|
||||
// NOTE: Moving into and out of water will undo pitch variations on sounds.
|
||||
if(listener->underwater || env->SoftwareWater)
|
||||
{
|
||||
|
@ -2138,20 +2152,33 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
|
|||
alFilterf(EnvFilters[1], AL_LOWPASS_GAINHF, 1.f);
|
||||
|
||||
// Apply the updated filters on the sources
|
||||
for(uint32_t i = 0;i < ReverbSfx.Size();++i)
|
||||
FSoundChan *schan = Channels;
|
||||
while (schan)
|
||||
{
|
||||
alSourcei(ReverbSfx[i], AL_DIRECT_FILTER, EnvFilters[0]);
|
||||
alSource3i(ReverbSfx[i], AL_AUXILIARY_SEND_FILTER, EnvSlot, 0, EnvFilters[1]);
|
||||
ALuint source = GET_PTRID(schan->SysChannel);
|
||||
if (source && !(schan->ChanFlags & CHAN_UI))
|
||||
{
|
||||
alSourcei(source, AL_DIRECT_FILTER, EnvFilters[0]);
|
||||
alSource3i(source, AL_AUXILIARY_SEND_FILTER, EnvSlot, 0, EnvFilters[1]);
|
||||
}
|
||||
schan = schan->NextChan;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32_t i = 0;i < ReverbSfx.Size();++i)
|
||||
alSourcef(ReverbSfx[i], AL_PITCH, PITCH_MULT);
|
||||
FSoundChan *schan = Channels;
|
||||
while (schan)
|
||||
{
|
||||
ALuint source = GET_PTRID(schan->SysChannel);
|
||||
if (source && !(schan->ChanFlags & CHAN_UI))
|
||||
alSourcef(source, AL_PITCH, schan->Pitch / 128.0f * PITCH_MULT);
|
||||
schan = schan->NextChan;
|
||||
}
|
||||
getALError();
|
||||
}
|
||||
}
|
||||
else if(WasInWater)
|
||||
{
|
||||
|
||||
WasInWater = false;
|
||||
|
||||
if(EnvSlot != 0)
|
||||
|
@ -2162,15 +2189,28 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
|
|||
alFilterf(EnvFilters[0], AL_LOWPASS_GAINHF, 1.f);
|
||||
alFilterf(EnvFilters[1], AL_LOWPASS_GAIN, 1.f);
|
||||
alFilterf(EnvFilters[1], AL_LOWPASS_GAINHF, 1.f);
|
||||
for(uint32_t i = 0;i < ReverbSfx.Size();++i)
|
||||
|
||||
FSoundChan *schan = Channels;
|
||||
while (schan)
|
||||
{
|
||||
alSourcei(ReverbSfx[i], AL_DIRECT_FILTER, EnvFilters[0]);
|
||||
alSource3i(ReverbSfx[i], AL_AUXILIARY_SEND_FILTER, EnvSlot, 0, EnvFilters[1]);
|
||||
ALuint source = GET_PTRID(schan->SysChannel);
|
||||
if (source && !(schan->ChanFlags & CHAN_UI))
|
||||
{
|
||||
alSourcei(source, AL_DIRECT_FILTER, EnvFilters[0]);
|
||||
alSource3i(source, AL_AUXILIARY_SEND_FILTER, EnvSlot, 0, EnvFilters[1]);
|
||||
}
|
||||
schan = schan->NextChan;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32_t i = 0;i < ReverbSfx.Size();++i)
|
||||
alSourcef(ReverbSfx[i], AL_PITCH, 1.f);
|
||||
FSoundChan *schan = Channels;
|
||||
while (schan)
|
||||
{
|
||||
ALuint source = GET_PTRID(schan->SysChannel);
|
||||
if (source && !(schan->ChanFlags & CHAN_UI))
|
||||
alSourcef(source, AL_PITCH, schan->Pitch / 128.0f);
|
||||
schan = schan->NextChan;
|
||||
}
|
||||
getALError();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,6 +144,9 @@ public:
|
|||
// Changes a channel's volume.
|
||||
virtual void ChannelVolume(FISoundChannel *chan, float volume);
|
||||
|
||||
// Changes a channel's pitch.
|
||||
virtual void ChannelPitch(FISoundChannel *chan, float pitch);
|
||||
|
||||
// Stops a sound channel.
|
||||
virtual void StopChannel(FISoundChannel *chan);
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, co
|
|||
static void CalcSectorSoundOrg(const DVector3 &listenpos, const sector_t *sec, int channum, FVector3 &res);
|
||||
static void CalcPolyobjSoundOrg(const DVector3 &listenpos, const FPolyObj *poly, FVector3 &res);
|
||||
static FSoundChan *S_StartSound(AActor *mover, const sector_t *sec, const FPolyObj *poly,
|
||||
const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation, FRolloffInfo *rolloff);
|
||||
const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation, FRolloffInfo *rolloff, float spitch);
|
||||
static void S_SetListener(SoundListener &listener, AActor *listenactor);
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
@ -929,7 +929,7 @@ static void CalcPolyobjSoundOrg(const DVector3 &listenpos, const FPolyObj *poly,
|
|||
|
||||
static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyObj *poly,
|
||||
const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation,
|
||||
FRolloffInfo *forcedrolloff=NULL)
|
||||
FRolloffInfo *forcedrolloff=NULL, float spitch = 0.0f)
|
||||
{
|
||||
sfxinfo_t *sfx;
|
||||
int chanflags;
|
||||
|
@ -1235,6 +1235,10 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
|
|||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (spitch > 0.0)
|
||||
S_SetPitch(chan, spitch);
|
||||
|
||||
return chan;
|
||||
}
|
||||
|
||||
|
@ -1318,9 +1322,14 @@ void S_RestartSound(FSoundChan *chan)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_Sound (int channel, FSoundID sound_id, float volume, float attenuation)
|
||||
void S_SoundPitch(int channel, FSoundID sound_id, float volume, float attenuation, float pitch)
|
||||
{
|
||||
S_StartSound (NULL, NULL, NULL, NULL, channel, sound_id, volume, attenuation);
|
||||
S_StartSound(NULL, NULL, NULL, NULL, channel, sound_id, volume, attenuation, 0, pitch);
|
||||
}
|
||||
|
||||
void S_Sound(int channel, FSoundID sound_id, float volume, float attenuation)
|
||||
{
|
||||
S_StartSound (NULL, NULL, NULL, NULL, channel, sound_id, volume, attenuation, 0, 0.f);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DObject, S_Sound)
|
||||
|
@ -1330,7 +1339,8 @@ DEFINE_ACTION_FUNCTION(DObject, S_Sound)
|
|||
PARAM_INT(channel);
|
||||
PARAM_FLOAT(volume);
|
||||
PARAM_FLOAT(attn);
|
||||
S_Sound(channel, id, static_cast<float>(volume), static_cast<float>(attn));
|
||||
PARAM_FLOAT(pitch);
|
||||
S_SoundPitch(channel, id, static_cast<float>(volume), static_cast<float>(attn), static_cast<float>(pitch));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1339,14 +1349,17 @@ DEFINE_ACTION_FUNCTION(DObject, S_Sound)
|
|||
// S_Sound - An actor is source
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_Sound (AActor *ent, int channel, FSoundID sound_id, float volume, float attenuation)
|
||||
void S_SoundPitchActor(AActor *ent, int channel, FSoundID sound_id, float volume, float attenuation, float pitch)
|
||||
{
|
||||
if (ent == nullptr || ent->Sector->Flags & SECF_SILENT || ent->Level != primaryLevel)
|
||||
return;
|
||||
S_StartSound (ent, nullptr, nullptr, nullptr, channel, sound_id, volume, attenuation);
|
||||
S_StartSound (ent, nullptr, nullptr, nullptr, channel, sound_id, volume, attenuation, 0, pitch);
|
||||
}
|
||||
|
||||
void S_Sound(AActor *ent, int channel, FSoundID sound_id, float volume, float attenuation)
|
||||
{
|
||||
S_SoundPitchActor(ent, channel, sound_id, volume, attenuation, 0.f);
|
||||
}
|
||||
//==========================================================================
|
||||
//
|
||||
// S_SoundMinMaxDist - An actor is source
|
||||
|
@ -1414,38 +1427,43 @@ void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, fl
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_PlaySound(AActor *a, int chan, FSoundID sid, float vol, float atten, bool local)
|
||||
void S_PlaySoundPitch(AActor *a, int chan, FSoundID sid, float vol, float atten, bool local, float pitch)
|
||||
{
|
||||
if (a == nullptr || a->Sector->Flags & SECF_SILENT || a->Level != primaryLevel)
|
||||
return;
|
||||
|
||||
if (!local)
|
||||
{
|
||||
S_Sound(a, chan, sid, vol, atten);
|
||||
S_SoundPitchActor(a, chan, sid, vol, atten, pitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a->CheckLocalView())
|
||||
{
|
||||
S_Sound(chan, sid, vol, ATTN_NONE);
|
||||
S_SoundPitch(chan, sid, vol, ATTN_NONE, pitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void A_PlaySound(AActor *self, int soundid, int channel, double volume, int looping, double attenuation, int local)
|
||||
void S_PlaySound(AActor *a, int chan, FSoundID sid, float vol, float atten, bool local)
|
||||
{
|
||||
S_PlaySoundPitch(a, chan, sid, vol, atten, local, 0.f);
|
||||
}
|
||||
|
||||
void A_PlaySound(AActor *self, int soundid, int channel, double volume, int looping, double attenuation, int local, double pitch)
|
||||
{
|
||||
if (!looping)
|
||||
{
|
||||
if (!(channel & CHAN_NOSTOP) || !S_IsActorPlayingSomething(self, channel & 7, soundid))
|
||||
{
|
||||
S_PlaySound(self, channel, soundid, (float)volume, (float)attenuation, local);
|
||||
S_PlaySoundPitch(self, channel, soundid, (float)volume, (float)attenuation, local, (float)pitch);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!S_IsActorPlayingSomething(self, channel & 7, soundid))
|
||||
{
|
||||
S_PlaySound(self, channel | CHAN_LOOP, soundid, (float)volume, (float)attenuation, local);
|
||||
S_PlaySoundPitch(self, channel | CHAN_LOOP, soundid, (float)volume, (float)attenuation, local, (float)pitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1843,6 +1861,33 @@ void S_ChangeSoundVolume(AActor *actor, int channel, double dvolume)
|
|||
return;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_ChangeSoundPitch
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_ChangeSoundPitch(AActor *actor, int channel, double pitch)
|
||||
{
|
||||
for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan)
|
||||
{
|
||||
if (chan->SourceType == SOURCE_Actor &&
|
||||
chan->Actor == actor &&
|
||||
chan->EntChannel == channel)
|
||||
{
|
||||
S_SetPitch(chan, (float)pitch);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void S_SetPitch(FSoundChan *chan, float pitch)
|
||||
{
|
||||
GSnd->ChannelPitch(chan, MAX(0.0001f, pitch));
|
||||
chan->Pitch = MAX(1, int(float(NORM_PITCH) * pitch));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_GetSoundPlayingInfo
|
||||
|
|
|
@ -179,7 +179,6 @@ struct FSoundChan : public FISoundChannel
|
|||
FSoundID SoundID; // Sound ID of playing sound.
|
||||
FSoundID OrgID; // Sound ID of sound used to start this channel.
|
||||
float Volume;
|
||||
int ChanFlags;
|
||||
int16_t Pitch; // Pitch variation.
|
||||
uint8_t EntChannel; // Actor's sound channel.
|
||||
int8_t Priority;
|
||||
|
@ -231,8 +230,12 @@ void S_Sound (const FPolyObj *poly, int channel, FSoundID sfxid, float volume, f
|
|||
void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, float attenuation);
|
||||
void S_Sound(FLevelLocals *Level, const DVector3 &pos, int channel, FSoundID sfxid, float volume, float attenuation);
|
||||
|
||||
void S_SoundPitch (int channel, FSoundID sfxid, float volume, float attenuation, float pitch);
|
||||
void S_SoundPitchActor (AActor *ent, int channel, FSoundID sfxid, float volume, float attenuation, float pitch);
|
||||
|
||||
// [Nash] Used by ACS and DECORATE
|
||||
void S_PlaySound(AActor *a, int chan, FSoundID sid, float vol, float atten, bool local);
|
||||
void S_PlaySoundPitch(AActor *a, int chan, FSoundID sid, float vol, float atten, bool local, float pitch);
|
||||
|
||||
// sound channels
|
||||
// channel 0 never willingly overrides
|
||||
|
@ -310,6 +313,10 @@ bool S_IsActorPlayingSomething (AActor *actor, int channel, int sound_id);
|
|||
// Change a playing sound's volume
|
||||
void S_ChangeSoundVolume(AActor *actor, int channel, double volume);
|
||||
|
||||
// Change a playing sound's pitch
|
||||
void S_ChangeSoundPitch(AActor *actor, int channel, double pitch);
|
||||
void S_SetPitch(FSoundChan *chan, float dpitch);
|
||||
|
||||
// Moves all sounds from one mobj to another
|
||||
void S_RelinkSound (AActor *from, AActor *to);
|
||||
|
||||
|
@ -372,7 +379,7 @@ sfxinfo_t *S_LoadSound(sfxinfo_t *sfx, FSoundLoadBuffer *pBuffer = nullptr);
|
|||
unsigned int S_GetMSLength(FSoundID sound);
|
||||
void S_ParseMusInfo();
|
||||
bool S_ParseTimeTag(const char *tag, bool *as_samples, unsigned int *time);
|
||||
void A_PlaySound(AActor *self, int soundid, int channel, double volume, int looping, double attenuation, int local);
|
||||
void A_PlaySound(AActor *self, int soundid, int channel, double volume, int looping, double attenuation, int local, double pitch);
|
||||
|
||||
// [RH] Prints sound debug info to the screen.
|
||||
// Modelled after Hexen's noise cheat.
|
||||
|
|
|
@ -1052,8 +1052,9 @@ class Actor : Thinker native
|
|||
|
||||
deprecated("2.3") native void A_BulletAttack();
|
||||
native void A_WolfAttack(int flags = 0, sound whattoplay = "weapons/pistol", double snipe = 1.0, int maxdamage = 64, int blocksize = 128, int pointblank = 2, int longrange = 4, double runspeed = 160.0, class<Actor> pufftype = "BulletPuff");
|
||||
native clearscope void A_PlaySound(sound whattoplay = "weapons/pistol", int slot = CHAN_BODY, double volume = 1.0, bool looping = false, double attenuation = ATTN_NORM, bool local = false);
|
||||
native clearscope void A_PlaySound(sound whattoplay = "weapons/pistol", int slot = CHAN_BODY, double volume = 1.0, bool looping = false, double attenuation = ATTN_NORM, bool local = false, double pitch = 0.0);
|
||||
native void A_SoundVolume(int slot, double volume);
|
||||
native void A_SoundPitch(int slot, double pitch);
|
||||
deprecated("2.3") void A_PlayWeaponSound(sound whattoplay) { A_PlaySound(whattoplay, CHAN_WEAPON); }
|
||||
native void A_StopSound(int slot = CHAN_VOICE); // Bad default but that's what is originally was...
|
||||
deprecated("2.3") native void A_PlaySoundEx(sound whattoplay, name slot, bool looping = false, int attenuation = 0);
|
||||
|
|
|
@ -442,7 +442,7 @@ class Object native
|
|||
{
|
||||
return level.PickPlayerStart(pnum, flags);
|
||||
}
|
||||
native static void S_Sound (Sound sound_id, int channel, float volume = 1, float attenuation = ATTN_NORM);
|
||||
native static void S_Sound (Sound sound_id, int channel, float volume = 1, float attenuation = ATTN_NORM, float pitch = 0.0);
|
||||
native static void S_PauseSound (bool notmusic, bool notsfx);
|
||||
native static void S_ResumeSound (bool notsfx);
|
||||
native static bool S_ChangeMusic(String music_name, int order = 0, bool looping = true, bool force = false);
|
||||
|
|
Loading…
Reference in a new issue