- this sound system is too insane to be ported.

This commit is contained in:
Christoph Oelckers 2019-12-12 21:42:58 +01:00
parent c5c2873223
commit 773c480940
3 changed files with 284 additions and 316 deletions

View file

@ -916,13 +916,35 @@ bool SoundEngine::CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_
// //
//========================================================================== //==========================================================================
void SoundEngine::StopSound (int channel) void SoundEngine::StopSoundID(int sound_id)
{
FSoundChan* chan = Channels;
while (chan != NULL)
{
FSoundChan* next = chan->NextChan;
if (sound_id == chan->SoundID)
{
StopChannel(chan);
}
chan = next;
}
}
//==========================================================================
//
// S_StopSound
//
// Stops an unpositioned sound from playing on a specific channel.
//
//==========================================================================
void SoundEngine::StopSound (int channel, int sound_id)
{ {
FSoundChan *chan = Channels; FSoundChan *chan = Channels;
while (chan != NULL) while (chan != NULL)
{ {
FSoundChan *next = chan->NextChan; FSoundChan *next = chan->NextChan;
if (chan->SourceType == SOURCE_None) if (chan->SourceType == SOURCE_None && (sound_id == -1 || sound_id == chan->SoundID))
{ {
StopChannel(chan); StopChannel(chan);
} }
@ -938,7 +960,7 @@ void SoundEngine::StopSound (int channel)
// //
//========================================================================== //==========================================================================
void SoundEngine::StopSound(int sourcetype, const void* actor, int channel) void SoundEngine::StopSound(int sourcetype, const void* actor, int channel, int sound_id)
{ {
FSoundChan* chan = Channels; FSoundChan* chan = Channels;
while (chan != NULL) while (chan != NULL)
@ -946,7 +968,7 @@ void SoundEngine::StopSound(int sourcetype, const void* actor, int channel)
FSoundChan* next = chan->NextChan; FSoundChan* next = chan->NextChan;
if (chan->SourceType == sourcetype && if (chan->SourceType == sourcetype &&
chan->Source == actor && chan->Source == actor &&
(chan->EntChannel == channel || channel < 0)) (sound_id == -1? (chan->EntChannel == channel || channel < 0) : (chan->SoundID == sound_id)))
{ {
StopChannel(chan); StopChannel(chan);
} }
@ -1050,13 +1072,13 @@ void SoundEngine::ChangeSoundVolume(int sourcetype, const void *source, int chan
// //
//========================================================================== //==========================================================================
void SoundEngine::ChangeSoundPitch(int sourcetype, const void *source, int channel, double pitch) void SoundEngine::ChangeSoundPitch(int sourcetype, const void *source, int channel, double pitch, int sound_id)
{ {
for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan) for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan)
{ {
if (chan->SourceType == sourcetype && if (chan->SourceType == sourcetype &&
chan->Source == source && chan->Source == source &&
chan->EntChannel == channel) (sound_id == -1? (chan->EntChannel == channel) : (chan->SoundID == sound_id)))
{ {
SetPitch(chan, (float)pitch); SetPitch(chan, (float)pitch);
return; return;
@ -1085,9 +1107,9 @@ bool SoundEngine::GetSoundPlayingInfo (int sourcetype, const void *source, int s
{ {
for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan) for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan)
{ {
if (chan->OrgID == sound_id && if (chan->OrgID == sound_id && (sourcetype == SOURCE_Any ||
chan->SourceType == sourcetype && (chan->SourceType == sourcetype &&
chan->Source == source) chan->Source == source)))
{ {
return true; return true;
} }

View file

@ -43,6 +43,8 @@ struct sfxinfo_t
unsigned bPlayerReserve : 1; unsigned bPlayerReserve : 1;
unsigned bPlayerCompat : 1; unsigned bPlayerCompat : 1;
unsigned bPlayerSilent:1; // This player sound is intentionally silent. unsigned bPlayerSilent:1; // This player sound is intentionally silent.
unsigned userFlags;
int userdata;
int RawRate; // Sample rate to use when bLoadRAW is true int RawRate; // Sample rate to use when bLoadRAW is true
@ -208,6 +210,7 @@ enum
enum // This cannot be remain as this, but for now it has to suffice. enum // This cannot be remain as this, but for now it has to suffice.
{ {
SOURCE_Any = -1, // Input for check functions meaning 'any source'
SOURCE_None, // Sound is always on top of the listener. SOURCE_None, // Sound is always on top of the listener.
SOURCE_Actor, // Sound is coming from an actor. SOURCE_Actor, // Sound is coming from an actor.
SOURCE_Sector, // Sound is coming from a sector. SOURCE_Sector, // Sound is coming from a sector.
@ -300,12 +303,13 @@ public:
const FVector3* pt, int channel, FSoundID sound_id, float volume, float attenuation, FRolloffInfo* rolloff = nullptr, float spitch = 0.0f); const FVector3* pt, int channel, FSoundID sound_id, float volume, float attenuation, FRolloffInfo* rolloff = nullptr, float spitch = 0.0f);
// Stops an origin-less sound from playing from this channel. // Stops an origin-less sound from playing from this channel.
void StopSound(int channel); void StopSoundID(int sound_id);
void StopSound(int sourcetype, const void* actor, int channel); void StopSound(int channel, int sound_id = -1);
void StopSound(int sourcetype, const void* actor, int channel, int sound_id = -1);
void RelinkSound(int sourcetype, const void* from, const void* to, const FVector3* optpos); void RelinkSound(int sourcetype, const void* from, const void* to, const FVector3* optpos);
void ChangeSoundVolume(int sourcetype, const void* source, int channel, double dvolume); void ChangeSoundVolume(int sourcetype, const void* source, int channel, double dvolume);
void ChangeSoundPitch(int sourcetype, const void* source, int channel, double pitch); void ChangeSoundPitch(int sourcetype, const void* source, int channel, double pitch, int sound_id = -1);
bool IsSourcePlayingSomething(int sourcetype, const void* actor, int channel, int sound_id); bool IsSourcePlayingSomething(int sourcetype, const void* actor, int channel, int sound_id);
// Stop and resume music, during game PAUSE. // Stop and resume music, during game PAUSE.
@ -365,6 +369,18 @@ public:
{ {
S_rnd.Clear(); S_rnd.Clear();
} }
int GetUserFlags(int snd)
{
return S_sfx[snd].userFlags;
}
int GetUserData(int snd)
{
return S_sfx[snd].userdata;
}
bool isValidSoundId(int id)
{
return id > 0 && id < (int)S_sfx.Size();
}
void ChannelVirtualChanged(FISoundChannel* ichan, bool is_virtual); void ChannelVirtualChanged(FISoundChannel* ichan, bool is_virtual);
FString ListSoundChannels(); FString ListSoundChannels();

View file

@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "openaudio.h" #include "openaudio.h"
#include "z_music.h" #include "z_music.h"
#include "mapinfo.h" #include "mapinfo.h"
#include "sound/s_soundinternal.h"
#include <atomic> #include <atomic>
BEGIN_DUKE_NS BEGIN_DUKE_NS
@ -269,277 +270,6 @@ static inline int S_GetAngle(int ang, const vec3_t *cam, const vec3_t *pos)
return (2048 + ang - getangle(cam->x - pos->x, cam->y - pos->y)) & 2047; return (2048 + ang - getangle(cam->x - pos->x, cam->y - pos->y)) & 2047;
} }
static int S_CalcDistAndAng(int spriteNum, int soundNum, int sectNum, int angle,
const vec3_t *cam, const vec3_t *pos, int *distPtr, int *angPtr)
{
int sndang = 0, sndist = 0, explosion = 0;
if (PN(spriteNum) == APLAYER && P_Get(spriteNum) == screenpeek)
goto sound_further_processing;
sndang = S_GetAngle(angle, cam, pos);
sndist = FindDistance3D(cam->x-pos->x, cam->y-pos->y, (cam->z-pos->z));
if ((g_sounds[soundNum].m & (SF_GLOBAL|SF_DTAG)) != SF_GLOBAL && S_IsAmbientSFX(spriteNum) && (sector[SECT(spriteNum)].lotag&0xff) < 9) // ST_9_SLIDING_ST_DOOR
sndist = divscale14(sndist, SHT(spriteNum)+1);
sound_further_processing:
sndist += g_sounds[soundNum].vo;
if (sndist < 0)
sndist = 0;
if (!FURY && sectNum > -1 && sndist && PN(spriteNum) != MUSICANDSFX
&& !cansee(cam->x, cam->y, cam->z - (24 << 8), sectNum, SX(spriteNum), SY(spriteNum), SZ(spriteNum) - (24 << 8), SECT(spriteNum)))
sndist += sndist>>5;
if ((g_sounds[soundNum].m & (SF_GLOBAL|SF_DTAG)) == (SF_GLOBAL|SF_DTAG))
{
boost:
int const sdist = g_sounds[soundNum].vo > 0 ? g_sounds[soundNum].vo : 6144;
explosion = true;
if (sndist > sdist)
sndist = sdist;
}
else if (!FURY)
{
switch (DYNAMICSOUNDMAP(soundNum))
{
case PIPEBOMB_EXPLODE__STATIC:
case LASERTRIP_EXPLODE__STATIC:
case RPG_EXPLODE__STATIC:
goto boost;
}
}
if ((g_sounds[soundNum].m & (SF_GLOBAL|SF_DTAG)) == SF_GLOBAL || sndist < ((255-LOUDESTVOLUME) << 6))
sndist = ((255-LOUDESTVOLUME) << 6);
*distPtr = sndist;
*angPtr = sndang;
return explosion;
}
int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos)
{
int32_t j = VM_OnEventWithReturn(EVENT_SOUND, spriteNum, screenpeek, num);
if ((j == -1 && num != -1) || !SoundEnabled()) // check that the user returned -1, but only if -1 wasn't playing already (in which case, warn)
return -1;
int const sndNum = j;
sound_t & snd = g_sounds[sndNum];
if (EDUKE32_PREDICT_FALSE((unsigned) sndNum > (unsigned) g_highestSoundIdx || snd.filename == NULL || snd.ptr == NULL))
{
OSD_Printf("WARNING: invalid sound #%d\n", num);
return -1;
}
auto const pPlayer = g_player[myconnectindex].ps;
if (((snd.m & SF_ADULT) && adult_lockout) || (unsigned)spriteNum >= MAXSPRITES || (pPlayer->gm & MODE_MENU) || !FX_VoiceAvailable(snd.pr)
|| (pPlayer->timebeforeexit > 0 && pPlayer->timebeforeexit <= GAMETICSPERSEC * 3))
return -1;
// Duke talk
if (snd.m & SF_TALK)
{
if ((g_netServer || ud.multimode > 1) && PN(spriteNum) == APLAYER && P_Get(spriteNum) != screenpeek) // other player sound
{
if ((snd_speech & 4) != 4)
return -1;
}
else if ((snd_speech & 1) != 1)
return -1;
// don't play if any Duke talk sounds are already playing
for (j = 0; j <= g_highestSoundIdx; ++j)
if ((g_sounds[j].m & SF_TALK) && g_sounds[j].num > 0)
return -1;
}
else if ((snd.m & (SF_DTAG|SF_GLOBAL)) == SF_DTAG) // Duke-Tag sound
{
int const voice = S_PlaySound(sndNum);
if (voice <= FX_Ok)
return -1;
j = 0;
while (j < MAXSOUNDINSTANCES && snd.voices[j].id != voice)
j++;
snd.voices[j].owner = spriteNum;
return voice;
}
int32_t sndist, sndang;
int const explosionp = S_CalcDistAndAng(spriteNum, sndNum, CAMERA(sect), fix16_to_int(CAMERA(q16ang)), &CAMERA(pos), pos, &sndist, &sndang);
int pitch = S_GetPitch(sndNum);
auto const pOther = g_player[screenpeek].ps;
if (pOther->sound_pitch)
pitch += pOther->sound_pitch;
if (explosionp)
{
if (pOther->cursectnum > -1 && sector[pOther->cursectnum].lotag == ST_2_UNDERWATER)
pitch -= 1024;
}
else
{
if (sndist > 32767 && PN(spriteNum) != MUSICANDSFX && (snd.m & (SF_LOOP|SF_MSFX)) == 0)
return -1;
if (pOther->cursectnum > -1 && sector[pOther->cursectnum].lotag == ST_2_UNDERWATER
&& (snd.m & SF_TALK) == 0)
pitch = -768;
}
if (snd.num > 0 && PN(spriteNum) != MUSICANDSFX)
S_StopEnvSound(sndNum, spriteNum);
int const sndSlot = S_GetSlot(sndNum);
if (sndSlot >= MAXSOUNDINSTANCES)
{
return -1;
}
int const repeatp = (snd.m & SF_LOOP);
if (repeatp && (snd.m & SF_ONEINST_INTERNAL) && snd.num > 0)
{
return -1;
}
int const voice = FX_Play3D(snd.ptr, snd.siz, repeatp ? FX_LOOP : FX_ONESHOT, pitch, sndang >> 4, sndist >> 6,
snd.pr, snd.volume, (sndNum * MAXSOUNDINSTANCES) + sndSlot);
if (voice <= FX_Ok)
{
return -1;
}
snd.num++;
S_SetProperties(&snd.voices[sndSlot], spriteNum, voice, sndist >> 6, 0);
return voice;
}
int S_PlaySound(int num)
{
int sndnum = VM_OnEventWithReturn(EVENT_SOUND, g_player[screenpeek].ps->i, screenpeek, num);
if ((sndnum == -1 && num != -1) || !SoundEnabled()) // check that the user returned -1, but only if -1 wasn't playing already (in which case, warn)
return -1;
num = sndnum;
sound_t & snd = g_sounds[num];
if (EDUKE32_PREDICT_FALSE((unsigned)num > (unsigned)g_highestSoundIdx || snd.filename == NULL || snd.ptr == NULL))
{
OSD_Printf("WARNING: invalid sound #%d\n",num);
return -1;
}
if ((!(snd_speech & 1) && (snd.m & SF_TALK)) || ((snd.m & SF_ADULT) && adult_lockout) || !FX_VoiceAvailable(snd.pr))
return -1;
int const pitch = S_GetPitch(num);
sndnum = S_GetSlot(num);
if (sndnum >= MAXSOUNDINSTANCES)
{
return -1;
}
int const voice = (snd.m & SF_LOOP) ? FX_Play(snd.ptr, snd.siz, 0, -1, pitch, LOUDESTVOLUME, LOUDESTVOLUME,
LOUDESTVOLUME, snd.siz, snd.volume, (num * MAXSOUNDINSTANCES) + sndnum)
: FX_Play3D(snd.ptr, snd.siz, FX_ONESHOT, pitch, 0, 255 - LOUDESTVOLUME, snd.pr, snd.volume,
(num * MAXSOUNDINSTANCES) + sndnum);
if (voice <= FX_Ok)
{
return -1;
}
snd.num++;
S_SetProperties(&snd.voices[sndnum], -1, voice, 255-LOUDESTVOLUME, 0);
return voice;
}
int A_PlaySound(int soundNum, int spriteNum)
{
if (EDUKE32_PREDICT_FALSE((unsigned)soundNum > (unsigned)g_highestSoundIdx))
return -1;
return (unsigned)spriteNum >= MAXSPRITES ? S_PlaySound(soundNum) :
S_PlaySound3D(soundNum, spriteNum, &sprite[spriteNum].pos);
}
void S_StopEnvSound(int sndNum, int sprNum)
{
if (EDUKE32_PREDICT_FALSE((unsigned)sndNum > (unsigned)g_highestSoundIdx) || g_sounds[sndNum].num <= 0)
return;
int j;
do
{
for (j=0; j<MAXSOUNDINSTANCES; ++j)
{
S_Cleanup();
auto &voice = g_sounds[sndNum].voices[j];
if ((sprNum == -1 && voice.id > FX_Ok) || (sprNum != -1 && voice.owner == sprNum))
{
if (voice.id > FX_Ok)
{
if (FX_SoundActive(voice.id))
FX_StopSound(voice.id);
break;
}
}
}
}
while (j < MAXSOUNDINSTANCES);
}
// Do not remove this or make it inline.
void S_StopAllSounds(void)
{
FX_StopAllSounds();
}
void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset)
{
if ((unsigned)soundNum > (unsigned)g_highestSoundIdx || g_sounds[soundNum].num <= 0)
return;
for (auto &voice : g_sounds[soundNum].voices)
{
if ((spriteNum == -1 && voice.id > FX_Ok) || (spriteNum != -1 && voice.owner == spriteNum))
{
if (EDUKE32_PREDICT_FALSE(spriteNum >= 0 && voice.id <= FX_Ok))
initprintf(OSD_ERROR "S_ChangeSoundPitch(): bad voice %d for sound ID %d!\n", voice.id, soundNum);
else if (voice.id > FX_Ok && FX_SoundActive(voice.id))
FX_SetPitch(voice.id, pitchoffset);
break;
}
}
}
void S_Update(void) void S_Update(void)
{ {
if ((g_player[myconnectindex].ps->gm & (MODE_GAME|MODE_DEMO)) == 0) if ((g_player[myconnectindex].ps->gm & (MODE_GAME|MODE_DEMO)) == 0)
@ -605,53 +335,248 @@ void S_Update(void)
} while (++sndnum <= highest); } while (++sndnum <= highest);
} }
// S_Callback() can be called from either the audio thread when a sound ends, or the main thread //==========================================================================
// when playing back a new sound needs an existing sound to be stopped first //
void S_Callback(intptr_t num) // With OpenAL we are only interested in how this function alters
{ // the distance to calculate attenuation.
if ((int32_t)num == MUSIC_ID) //
return; //==========================================================================
mutex_lock(&m_callback); static int S_CalcDistAndAng(int spriteNum, int soundNum, int sectNum, int angle, int* distPtr)
unative_t const ldnum = dnum; {
dq[ldnum & (DQSIZE - 1)] = (uint32_t)num; int sndang = 0, sndist = 0, explosion = 0;
dnum++;
mutex_unlock(&m_callback); if (PN(spriteNum) == APLAYER && P_Get(spriteNum) == screenpeek)
goto sound_further_processing;
sndang = S_GetAngle(angle, cam, pos);
sndist = FindDistance3D(cam->x - pos->x, cam->y - pos->y, (cam->z - pos->z));
if ((g_sounds[soundNum].m & (SF_GLOBAL | SF_DTAG)) != SF_GLOBAL && S_IsAmbientSFX(spriteNum) && (sector[SECT(spriteNum)].lotag & 0xff) < 9) // ST_9_SLIDING_ST_DOOR
sndist = divscale14(sndist, SHT(spriteNum) + 1);
sound_further_processing:
sndist += g_sounds[soundNum].vo;
if (sndist < 0)
sndist = 0;
if (!FURY && sectNum > -1 && sndist && PN(spriteNum) != MUSICANDSFX
&& !cansee(cam->x, cam->y, cam->z - (24 << 8), sectNum, SX(spriteNum), SY(spriteNum), SZ(spriteNum) - (24 << 8), SECT(spriteNum)))
sndist += sndist >> 5;
if ((g_sounds[soundNum].m & (SF_GLOBAL | SF_DTAG)) == (SF_GLOBAL | SF_DTAG))
{
boost:
int const sdist = g_sounds[soundNum].vo > 0 ? g_sounds[soundNum].vo : 6144;
explosion = true;
if (sndist > sdist)
sndist = sdist;
}
else if (!FURY)
{
switch (DYNAMICSOUNDMAP(soundNum))
{
case PIPEBOMB_EXPLODE__STATIC:
case LASERTRIP_EXPLODE__STATIC:
case RPG_EXPLODE__STATIC:
goto boost;
}
}
if ((g_sounds[soundNum].m & (SF_GLOBAL | SF_DTAG)) == SF_GLOBAL || sndist < ((255 - LOUDESTVOLUME) << 6))
sndist = ((255 - LOUDESTVOLUME) << 6);
*distPtr = sndist;
*angPtr = sndang;
return explosion;
} }
//==========================================================================
//
//
//
//==========================================================================
int S_PlaySound3D(int num, int spriteNum, const vec3_t* pos)
{
int32_t j = VM_OnEventWithReturn(EVENT_SOUND, spriteNum, screenpeek, num);
int sndnum = VM_OnEventWithReturn(EVENT_SOUND, spriteNum, screenpeek, num);
auto const pPlayer = g_player[myconnectindex].ps;
if (!soundEngine->isValidSoundId(sndnum) || !SoundEnabled() || (unsigned)spriteNum >= MAXSPRITES || (pPlayer->gm & MODE_MENU) ||
(pPlayer->timebeforeexit > 0 && pPlayer->timebeforeexit <= GAMETICSPERSEC * 3)) return -1;
int userflags = soundEngine->GetUserFlags(sndnum);
if ((!(snd_speech & 1) && (userflags & SF_TALK)) || ((userflags & SF_ADULT) && adult_lockout))
return -1;
// Duke talk
if (userflags & SF_TALK)
{
if ((g_netServer || ud.multimode > 1) && PN(spriteNum) == APLAYER && P_Get(spriteNum) != screenpeek) // other player sound
{
if ((snd_speech & 4) != 4)
return -1;
}
else if ((snd_speech & 1) != 1)
return -1;
// don't play if any Duke talk sounds are already playing
for (j = 0; j <= g_highestSoundIdx; ++j)
if ((g_sounds[j].m & SF_TALK) && g_sounds[j].num > 0)
return -1;
}
else if ((userflags & (SF_DTAG | SF_GLOBAL)) == SF_DTAG) // Duke-Tag sound
{
return S_PlaySound(sndnum);
}
int32_t sndist, sndang;
int const explosionp = S_CalcDistAndAng(spriteNum, sndnum, CAMERA(sect), fix16_to_int(CAMERA(q16ang)), &CAMERA(pos), pos, &sndist, &sndang);
int pitch = S_GetPitch(sndnum);
auto const pOther = g_player[screenpeek].ps;
if (pOther->sound_pitch)
pitch += pOther->sound_pitch;
if (explosionp)
{
if (pOther->cursectnum > -1 && sector[pOther->cursectnum].lotag == ST_2_UNDERWATER)
pitch -= 1024;
}
else
{
if (sndist > 32767 && PN(spriteNum) != MUSICANDSFX && (userflags & (SF_LOOP | SF_MSFX)) == 0)
return -1;
if (pOther->cursectnum > -1 && sector[pOther->cursectnum].lotag == ST_2_UNDERWATER
&& (userflags & SF_TALK) == 0)
pitch = -768;
}
if (snd.num > 0 && PN(spriteNum) != MUSICANDSFX)
S_StopEnvSound(sndNum, spriteNum);
int const sndSlot = S_GetSlot(sndNum);
if (sndSlot >= MAXSOUNDINSTANCES)
{
return -1;
}
int const repeatp = (snd.m & SF_LOOP);
if (repeatp && (snd.m & SF_ONEINST_INTERNAL) && snd.num > 0)
{
return -1;
}
int const voice = FX_Play3D(snd.ptr, snd.siz, repeatp ? FX_LOOP : FX_ONESHOT, pitch, sndang >> 4, sndist >> 6,
snd.pr, snd.volume, (sndNum * MAXSOUNDINSTANCES) + sndSlot);
if (voice <= FX_Ok)
{
return -1;
}
snd.num++;
S_SetProperties(&snd.voices[sndSlot], spriteNum, voice, sndist >> 6, 0);
return voice;
}
//==========================================================================
//
//
//
//==========================================================================
int S_PlaySound(int num)
{
int sndnum = VM_OnEventWithReturn(EVENT_SOUND, g_player[screenpeek].ps->i, screenpeek, num);
if (!soundEngine->isValidSoundId(sndnum) || !SoundEnabled()) return -1;
int userflags = soundEngine->GetUserFlags(sndnum);
if ((!(snd_speech & 1) && (userflags & SF_TALK)) || ((userflags & SF_ADULT) && adult_lockout))
return -1;
int const pitch = S_GetPitch(num);
double expitch = pow(2, pitch / 1200.); // I hope I got this right that ASS uses a linear scale where 1200 is a full octave.
soundEngine->StartSound(SOURCE_None, nullptr, nullptr, (userflags & SF_LOOP)? CHAN_AUTO|CHAN_LOOP : CHAN_AUTO, sndnum, 1.f, ATTN_NONE, nullptr, expitch);
/* for reference. May still be needed for balancing later.
: FX_Play3D(snd.ptr, snd.siz, FX_ONESHOT, pitch, 0, 255 - LOUDESTVOLUME, snd.pr, snd.volume,
(num * MAXSOUNDINSTANCES) + sndnum);
*/
return 0;
}
//==========================================================================
//
//
//
//==========================================================================
int A_PlaySound(int soundNum, int spriteNum)
{
return (unsigned)spriteNum >= MAXSPRITES ? S_PlaySound(soundNum) :
S_PlaySound3D(soundNum, spriteNum, &sprite[spriteNum].pos);
}
void S_StopEnvSound(int sndNum, int sprNum)
{
if (sprNum < -1 || sprNum >= MAXSPRITES) return;
if (sprNum == -1) soundEngine->StopSoundID(sndNum);
else soundEngine->StopSound(SOURCE_Actor, &sprite[sprNum], -1, sndNum);
}
void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset)
{
if (spriteNum < -1 || spriteNum >= MAXSPRITES) return;
double expitch = pow(2, pitchoffset / 1200.); // I hope I got this right that ASS uses a linear scale where 1200 is a full octave.
if (spriteNum == -1)
{
soundEngine->ChangeSoundPitch(SOURCE_Unattached, nullptr, CHAN_AUTO, expitch, soundNum);
}
else
{
soundEngine->ChangeSoundPitch(SOURCE_Actor, &sprite[spriteNum], CHAN_AUTO, expitch, soundNum);
}
}
//==========================================================================
//
//
//
//==========================================================================
int A_CheckSoundPlaying(int spriteNum, int soundNum) int A_CheckSoundPlaying(int spriteNum, int soundNum)
{ {
if (EDUKE32_PREDICT_FALSE((unsigned)soundNum > (unsigned)g_highestSoundIdx)) return 0; if (spriteNum == -1) return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundNum);
if ((unsigned)spriteNum >= MAXSPRITES) return false;
if (g_sounds[soundNum].num > 0 && spriteNum >= 0) return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, &sprite[spriteNum], CHAN_AUTO, soundNum);
{
for (auto &voice : g_sounds[soundNum].voices)
if (voice.owner == spriteNum)
return 1;
}
return (spriteNum == -1) ? (g_sounds[soundNum].num != 0) : 0;
} }
// Check if actor <i> is playing any sound. // Check if actor <i> is playing any sound.
int A_CheckAnySoundPlaying(int spriteNum) int A_CheckAnySoundPlaying(int spriteNum)
{ {
int const msp = g_highestSoundIdx; if ((unsigned)spriteNum >= MAXSPRITES) return false;
return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, &sprite[spriteNum], CHAN_AUTO, 0);
for (int j = 0; j <= msp; ++j)
{
for (auto &voice : g_sounds[j].voices)
if (voice.owner == spriteNum)
return 1;
}
return 0;
} }
int S_CheckSoundPlaying(int soundNum) int S_CheckSoundPlaying(int soundNum)
{ {
if (EDUKE32_PREDICT_FALSE((unsigned)soundNum > (unsigned)g_highestSoundIdx)) return false; return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundNum);
return (g_sounds[soundNum].num != 0);
} }
//========================================================================== //==========================================================================
@ -673,6 +598,11 @@ void S_MenuSound(void)
S_PlaySound(s); S_PlaySound(s);
} }
//==========================================================================
//
// Music
//
//==========================================================================
static void S_SetMusicIndex(unsigned int m) static void S_SetMusicIndex(unsigned int m)
{ {