- converted Blood's sound system to the OpenAL sound engine.

Now, this code was one big mess of strange design, let's hope it sounds better with a real 3D mixer now.
This commit is contained in:
Christoph Oelckers 2019-12-17 19:37:05 +01:00
parent 4d5755ca67
commit 706157d623
21 changed files with 353 additions and 713 deletions

View file

@ -94,7 +94,6 @@ static FORCE_INLINE int FX_GetReverseStereo(void) { return MV_GetReverseStereo()
static FORCE_INLINE void FX_SetReverb_(int reverb) { MV_SetReverb(reverb); }
static FORCE_INLINE int FX_GetMaxReverbDelay(void) { return MV_GetMaxReverbDelay(); }
static FORCE_INLINE int FX_GetReverbDelay(void) { return MV_GetReverbDelay(); }
static FORCE_INLINE void FX_SetReverbDelay(int delay) { MV_SetReverbDelay(delay); }
static FORCE_INLINE int FX_VoiceAvailable(int priority) { return MV_VoiceAvailable(priority); }
static FORCE_INLINE int FX_PauseVoice(int handle, int pause) { return FX_CheckMVErr(MV_PauseVoice(handle, pause)); }
static FORCE_INLINE int FX_EndLooping(int handle) { return FX_CheckMVErr(MV_EndLooping(handle)); }

View file

@ -48,6 +48,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "endgame.h"
#include "view.h"
#include "tile.h"
#include "sound/s_soundinternal.h"
BEGIN_BLD_NS
static void genDudeAttack1(int, int);
@ -902,6 +903,7 @@ bool playGenDudeSound(spritetype* pSprite, int mode, bool forceInterrupt) {
// let's check if there same sounds already played by other dudes
// so we won't get a lot of annoying screams in the same time and ensure sound played in it's full length (if not interruptable)
if (pExtra->sndPlaying && !sndInfo->interruptable) {
#if 0
for (int i = 0; i < 256; i++) {
if (Bonkle[i].atc <= 0) continue;
for (int a = 0; a < rand; a++) {
@ -915,6 +917,7 @@ bool playGenDudeSound(spritetype* pSprite, int mode, bool forceInterrupt) {
}
}
}
#endif
pExtra->sndPlaying = false;
@ -928,7 +931,7 @@ bool playGenDudeSound(spritetype* pSprite, int mode, bool forceInterrupt) {
int maxRetries = 5;
while (maxRetries-- > 0) {
int random = Random(rand);
if (!gSoundRes.Lookup(sndId + random, "SFX")) continue;
if (!soundEngine->FindSoundByResID(sndId + random)) continue;
sndId = sndId + random;
gotSnd = true;
break;
@ -938,7 +941,7 @@ bool playGenDudeSound(spritetype* pSprite, int mode, bool forceInterrupt) {
if (gotSnd == false) {
int maxSndId = sndId + rand;
while (sndId++ <= maxSndId) {
if (!gSoundRes.Lookup(sndId, "SFX")) continue;
if (!soundEngine->FindSoundByResID(sndId)) continue;
gotSnd = true;
break;
}

View file

@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "player.h"
#include "resource.h"
#include "sound.h"
#include "sound/s_soundinternal.h"
BEGIN_BLD_NS
@ -40,13 +41,9 @@ BEGIN_BLD_NS
struct AMB_CHANNEL
{
int at0;
int at4;
int at8;
DICTNODE *atc;
char *at10;
int at14;
int at18;
FSoundID soundID;
int distance;
int check;
};
AMB_CHANNEL ambChannels[kMaxAmbChannel];
@ -75,22 +72,31 @@ void ambProcess(void)
dz >>= 8;
int nDist = ksqrt(dx*dx+dy*dy+dz*dz);
int vs = mulscale16(pXSprite->data4, pXSprite->busy);
ambChannels[pSprite->owner].at4 += ClipRange(scale(nDist, pXSprite->data1, pXSprite->data2, vs, 0), 0, vs);
ambChannels[pSprite->owner].distance += ClipRange(scale(nDist, pXSprite->data1, pXSprite->data2, vs, 0), 0, vs);
}
}
}
AMB_CHANNEL *pChannel = ambChannels;
for (int i = 0; i < nAmbChannels; i++, pChannel++)
{
if (pChannel->at0 > 0)
FX_SetPan(pChannel->at0, pChannel->at4, pChannel->at4, pChannel->at4);
else
if (soundEngine->IsSourcePlayingSomething(SOURCE_Ambient, pChannel, CHAN_BODY, -1))
{
int end = ClipLow(pChannel->at14-1, 0);
pChannel->at0 = FX_PlayLoopedRaw(pChannel->at10, pChannel->at14, pChannel->at10, pChannel->at10+end, sndGetRate(pChannel->at18), 0,
pChannel->at4, pChannel->at4, pChannel->at4, pChannel->at4, 1.f, (intptr_t)&pChannel->at0);
if (pChannel->distance > 0)
{
soundEngine->ChangeSoundVolume(SOURCE_Ambient, pChannel, CHAN_BODY, pChannel->distance / 255.f);
}
else
{
// Stop the sound if it cannot be heard so that it doesn't occupy a physical channel.
soundEngine->StopSound(SOURCE_Ambient, pChannel, CHAN_BODY);
}
}
pChannel->at4 = 0;
else if (pChannel->distance > 0)
{
FVector3 pt{};
soundEngine->StartSound(SOURCE_Ambient, pChannel, &pt, CHAN_BODY, CHANF_LOOP, pChannel->soundID, pChannel->distance / 255.f, ATTN_NONE);
}
pChannel->distance = 0;
}
}
@ -99,16 +105,8 @@ void ambKillAll(void)
AMB_CHANNEL *pChannel = ambChannels;
for (int i = 0; i < nAmbChannels; i++, pChannel++)
{
if (pChannel->at0 > 0)
{
FX_EndLooping(pChannel->at0);
FX_StopSound(pChannel->at0);
}
if (pChannel->atc)
{
gSoundRes.Unlock(pChannel->atc);
pChannel->atc = NULL;
}
soundEngine->StopSound(SOURCE_Ambient, pChannel, CHAN_BODY);
pChannel->soundID = 0;
}
nAmbChannels = 0;
}
@ -125,7 +123,7 @@ void ambInit(void)
int i; AMB_CHANNEL *pChannel = ambChannels;
for (i = 0; i < nAmbChannels; i++, pChannel++)
if (pXSprite->data3 == pChannel->at8) break;
if (pXSprite->data3 == pChannel->check) break;
if (i == nAmbChannels) {
@ -135,30 +133,17 @@ void ambInit(void)
}
int nSFX = pXSprite->data3;
DICTNODE *pSFXNode = gSoundRes.Lookup(nSFX, "SFX");
if (!pSFXNode) {
auto snd = soundEngine->FindSoundByResID(nSFX);
if (!snd) {
//ThrowError("Missing sound #%d used in ambient sound generator %d\n", nSFX);
viewSetSystemMessage("Missing sound #%d used in ambient sound generator #%d\n", nSFX);
continue;
}
SFX *pSFX = (SFX*)gSoundRes.Load(pSFXNode);
DICTNODE *pRAWNode = gSoundRes.Lookup(pSFX->rawName, "RAW");
if (!pRAWNode) {
//ThrowError("Missing RAW sound \"%s\" used in ambient sound generator %d\n", pSFX->rawName, nSFX);
viewSetSystemMessage("Missing RAW sound \"%s\" used in ambient sound generator %d\n", pSFX->rawName, nSFX);
continue;
}
if (pRAWNode->Size() > 0) {
pChannel->at14 = pRAWNode->Size();
pChannel->at8 = nSFX;
pChannel->atc = pRAWNode;
pChannel->at14 = pRAWNode->Size();
pChannel->at10 = (char*)gSoundRes.Lock(pRAWNode);
pChannel->at18 = pSFX->format;
nAmbChannels++;
}
pChannel->soundID = FSoundID(snd);
pChannel->check = nSFX;
pChannel->distance = 0;
nAmbChannels++;
}

View file

@ -172,7 +172,7 @@ void ShutDown(void)
if (!in3dmode())
return;
netDeinitialize();
sndTerm();
//sndTerm();
sfxTerm();
scrUnInit();
// PORT_TODO: Check argument
@ -915,7 +915,6 @@ void ProcessFrame(void)
actProcessSprites();
actPostProcess();
viewCorrectPrediction();
sndProcess();
ambProcess();
viewUpdateDelirium();
viewUpdateShake();
@ -1198,7 +1197,6 @@ int GameInterface::app_main()
viewResizeView(gViewSize);
initprintf("Initializing sound system\n");
sndInit();
sfxInit();
gChoke.sub_83ff0(518, sub_84230);
if (bAddUserMap)
{

View file

@ -238,13 +238,13 @@ void credPlaySmk(const char *_pzSMK, const char *_pzWAV, int nWav)
nScale = divscale16(200, nHeight);
if (nWav)
sndStartWavID(nWav, snd_fxvolume);
sndStartWavID(nWav, 255);
else
{
auto nHandleWAV = credKOpen4Load(pzWAV);
if (nHandleWAV.isOpen())
{
sndStartWavDisk(pzWAV, snd_fxvolume);
sndStartWavDisk(pzWAV, 255);
}
}

View file

@ -220,7 +220,7 @@ void CSecretMgr::Found(int nType)
} else at8++;
if (gGameOptions.nGameType == 0) {
viewSetMessage(GStrings(FStringf("TXT_SECRET%d", Random(2))), 0, MESSAGE_PRIORITY_SECRET);
viewSetMessage(GStrings(FStringf("TXTB_SECRET%d", Random(2))), 0, MESSAGE_PRIORITY_SECRET);
}
}

View file

@ -270,20 +270,6 @@ static int osdcmd_noclip(osdcmdptr_t UNUSED(parm))
return OSDCMD_OK;
}
/*
static int osdcmd_restartsound(osdcmdptr_t UNUSED(parm))
{
UNREFERENCED_CONST_PARAMETER(parm);
sfxTerm();
sndTerm();
sndInit();
sfxInit();
return OSDCMD_OK;
}
*/
void onvideomodechange(int32_t newmode)
{
UNREFERENCED_PARAMETER(newmode);

View file

@ -39,6 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "actor.h"
#include "tile.h"
#include "view.h"
#include "sound/s_soundinternal.h"
BEGIN_BLD_NS
@ -327,8 +328,13 @@ void SEQINST::Update(ACTIVE *pActive)
};
int sndId = surfSfxMove[surf][Random(2)];
DICTNODE * hRes = gSoundRes.Lookup(sndId, "SFX"); SFX * pEffect = (SFX*)gSoundRes.Load(hRes);
sfxPlay3DSoundCP(pSprite, sndId, -1, 0, 0, (surfSfxMove[surf][2] != pEffect->relVol) ? pEffect->relVol : surfSfxMove[surf][3]);
auto snd = soundEngine->FindSoundByResID(sndId);
if (snd > 0)
{
auto udata = (int*)soundEngine->GetUserData(snd);
int relVol = udata ? udata[2] : 255;
sfxPlay3DSoundCP(pSprite, sndId, -1, 0, 0, (surfSfxMove[surf][2] != relVol) ? relVol : surfSfxMove[surf][3]);
}
}

View file

@ -35,338 +35,175 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "sfx.h"
#include "sound.h"
#include "trig.h"
#include "sound/s_soundinternal.h"
BEGIN_BLD_NS
POINT2D earL, earR, earL0, earR0; // Ear position
VECTOR2D earVL, earVR; // Ear velocity ?
int lPhase, rPhase, lVol, rVol, lPitch, rPitch;
class BloodSoundEngine : public SoundEngine
{
// client specific parts of the sound engine go in this class.
void CalcPosVel(int type, const void* source, const float pt[3], int channum, int chanflags, FSoundID chanSound, FVector3* pos, FVector3* vel) override;
TArray<uint8_t> ReadSound(int lumpnum);
BONKLE Bonkle[256];
BONKLE *BonkleCache[256];
int nBonkles;
public:
BloodSoundEngine()
{
S_Rolloff.RolloffType = ROLLOFF_Doom;
S_Rolloff.MinDistance = 170; // these are the numbers I got when uncrunching the original sound code.
S_Rolloff.MaxDistance = 850;
}
};
void sfxInit(void)
{
for (int i = 0; i < 256; i++)
BonkleCache[i] = &Bonkle[i];
nBonkles = 0;
soundEngine = new BloodSoundEngine;
}
void sfxTerm()
{
}
int Vol3d(int angle, int dist)
//==========================================================================
//
//
//
//==========================================================================
TArray<uint8_t> BloodSoundEngine::ReadSound(int lumpnum)
{
return dist - mulscale16(dist, 0x2000 - mulscale30(0x2000, Cos(angle)));
auto wlump = fileSystem.OpenFileReader(lumpnum);
return wlump.Read();
}
void Calc3DValues(BONKLE *pBonkle)
void BloodSoundEngine::CalcPosVel(int type, const void* source, const float pt[3], int channum, int chanflags, FSoundID chanSound, FVector3* pos, FVector3* vel)
{
int dx = pBonkle->at20.x - gMe->pSprite->x;
int dy = pBonkle->at20.y - gMe->pSprite->y;
int dz = pBonkle->at20.z - gMe->pSprite->z;
int angle = getangle(dx, dy);
dx >>= 4;
dy >>= 4;
dz >>= 8;
int distance = ksqrt(dx*dx + dy * dy + dz * dz);
distance = ClipLow((distance >> 2) + (distance >> 3), 64);
int v14, v18;
v14 = v18 = scale(pBonkle->at1c, 80, distance);
int sinVal = Sin(angle);
int cosVal = Cos(angle);
int v8 = dmulscale30r(cosVal, pBonkle->at20.x - pBonkle->at2c.x, sinVal, pBonkle->at20.y - pBonkle->at2c.y);
if (pos != nullptr && type != SOURCE_None)
{
FVector3 camera;
if (gMe && gMe->pSprite) camera = GetSoundPos(&gMe->pSprite->pos);
else camera = { 0, 0, 0 }; // don't crash if there is no player.
int distanceL = approxDist(pBonkle->at20.x - earL.x, pBonkle->at20.y - earL.y);
lVol = Vol3d(angle - (gMe->pSprite->ang - 85), v18);
int phaseLeft = mulscale16r(distanceL, pBonkle->at3c == 1 ? 4114 : 8228);
lPitch = scale(pBonkle->at18, dmulscale30r(cosVal, earVL.dx, sinVal, earVL.dy) + 5853, v8 + 5853);
if (vel) vel->Zero();
int distanceR = approxDist(pBonkle->at20.x - earR.x, pBonkle->at20.y - earR.y);
rVol = Vol3d(angle - (gMe->pSprite->ang + 85), v14);
int phaseRight = mulscale16r(distanceR, pBonkle->at3c == 1 ? 4114 : 8228);
rPitch = scale(pBonkle->at18, dmulscale30r(cosVal, earVR.dx, sinVal, earVR.dy) + 5853, v8 + 5853);
if (type == SOURCE_Unattached)
{
pos->X = pt[0];
pos->Y = pt[1];
pos->Z = pt[2];
}
else if (type == SOURCE_Actor)
{
auto actor = (spritetype*)source;
assert(actor != nullptr);
size_t index = actor - sprite;
// Engine expects velocity in units per second, not units per tic.
if (vel) *vel = { xvel[index] * (30 / 65536.f), zvel[index] * (-30 / 65536.f), yvel[index] * (-30 / 65536.f) };
*pos = GetSoundPos(&actor->pos);
}
else if (type == SOURCE_Ambient)
{
*pos = camera; // just to be safe. Ambient sounds are in the world but unpositioned
}
if ((chanflags & CHANF_LISTENERZ))
{
pos->Y = camera.Y;
}
}
}
int phaseMin = ClipHigh(phaseLeft, phaseRight);
lPhase = phaseRight - phaseMin;
rPhase = phaseLeft - phaseMin;
void sfxUpdate3DSounds(void)
{
SoundListener listener;
listener.angle = -(float)gMe->pSprite->ang * pi::pi() / 1024; // Build uses a period of 2048.
listener.velocity.Zero();
listener.position = GetSoundPos(&gMe->pSprite->pos);
listener.underwater = false;
// This should probably use a real environment instead of the pitch hacking in S_PlaySound3D.
// listenactor->waterlevel == 3;
//assert(primaryLevel->Zones.Size() > listenactor->Sector->ZoneNumber);
listener.Environment = 0;// primaryLevel->Zones[listenactor->Sector->ZoneNumber].Environment;
listener.valid = true;
listener.ListenerObject = gMe->pSprite;
soundEngine->SetListener(listener);
soundEngine->UpdateSounds((int)totalclock);
}
FSoundID getSfx(FSoundID soundId, float &attenuation, int &pitch, int relvol)
{
auto udata = (int*)soundEngine->GetUserData(soundId);
if (pitch < 0) pitch = udata ? udata[0] : 0x10000;
if (relvol < 0) relvol = udata && udata[2] ? udata[2] : 80;
if (relvol > 255) relvol = 255;
attenuation = relvol > 0 ? 80.f / relvol : 1.f;
return soundId;
}
void sfxPlay3DSound(int x, int y, int z, int soundId, int nSector)
{
if (!SoundEnabled() || soundId < 0) return;
DICTNODE *hRes = gSoundRes.Lookup(soundId, "SFX");
if (!hRes)return;
auto sid = soundEngine->FindSoundByResID(soundId);
if (sid == 0) return;
SFX *pEffect = (SFX*)gSoundRes.Load(hRes);
hRes = gSoundRes.Lookup(pEffect->rawName, "RAW");
if (!hRes) return;
vec3_t xyz = { x, y, z };
auto svec = GetSoundPos(&xyz);
float attenuation;
int pitch = -1;
sid = getSfx(sid, attenuation, pitch, -1);
soundEngine->StartSound(SOURCE_Unattached, nullptr, &svec, -1, CHANF_OVERLAP, sid, 0.8f, attenuation, nullptr, pitch / 65536.f);
int v1c, v18;
v1c = v18 = mulscale16(pEffect->pitch, sndGetRate(pEffect->format));
if (nBonkles >= 256)
return;
BONKLE *pBonkle = BonkleCache[nBonkles++];
pBonkle->at10 = NULL;
pBonkle->at20.x = x;
pBonkle->at20.y = y;
pBonkle->at20.z = z;
pBonkle->at38 = nSector;
FindSector(x, y, z, &pBonkle->at38);
pBonkle->at2c = pBonkle->at20;
pBonkle->atc = soundId;
pBonkle->at8 = hRes;
pBonkle->at1c = pEffect->relVol;
pBonkle->at18 = v18;
pBonkle->at3c = pEffect->format;
int size = hRes->Size();
char *pData = (char*)gSoundRes.Lock(hRes);
Calc3DValues(pBonkle);
int priority = 1;
if (priority < lVol)
priority = lVol;
if (priority < rVol)
priority = rVol;
if (snd_doppler)
{
MV_Lock();
pBonkle->at0 = FX_PlayRaw(pData + lPhase, size - lPhase, lPitch, 0, lVol, lVol, 0, priority, 1.f, (intptr_t)&pBonkle->at0);
pBonkle->at4 = FX_PlayRaw(pData + rPhase, size - rPhase, rPitch, 0, rVol, 0, rVol, priority, 1.f, (intptr_t)&pBonkle->at4);
MV_Unlock();
}
else
{
pBonkle->at0 = FX_PlayRaw(pData + lPhase, size - lPhase, v1c, 0, lVol, lVol, rVol, priority, 1.f, (intptr_t)&pBonkle->at0);
pBonkle->at4 = 0;
}
}
void sfxPlay3DSound(spritetype *pSprite, int soundId, int a3, int a4)
enum EPlayFlags
{
if (!SoundEnabled())
return;
if (!pSprite)
return;
if (soundId < 0)
return;
DICTNODE *hRes = gSoundRes.Lookup(soundId, "SFX");
if (!hRes)
return;
FX_GlobalChannel = 1,
FX_SoundMatch = 2,
FX_ChannelMatch = 4,
};
SFX *pEffect = (SFX*)gSoundRes.Load(hRes);
hRes = gSoundRes.Lookup(pEffect->rawName, "RAW");
if (!hRes)
return;
int size = hRes->Size();
if (size <= 0)
return;
int v14;
v14 = mulscale16(pEffect->pitch, sndGetRate(pEffect->format));
BONKLE *pBonkle = NULL;
if (a3 >= 0)
{
int i;
for (i = 0; i < nBonkles; i++)
{
pBonkle = BonkleCache[i];
if (pBonkle->at14 == a3 && (pBonkle->at10 == pSprite || (a4 & 1) != 0))
{
if ((a4 & 4) != 0 && pBonkle->at14 == a3)
return;
if ((a4 & 2) != 0 && pBonkle->atc == soundId)
return;
if (pBonkle->at0 > 0)
FX_StopSound(pBonkle->at0);
if (pBonkle->at4 > 0)
FX_StopSound(pBonkle->at4);
if (pBonkle->at8)
{
gSoundRes.Unlock(pBonkle->at8);
pBonkle->at8 = NULL;
}
break;
}
}
if (i == nBonkles)
{
if (nBonkles >= 256)
return;
pBonkle = BonkleCache[nBonkles++];
}
pBonkle->at10 = pSprite;
pBonkle->at14 = a3;
}
else
{
if (nBonkles >= 256)
return;
pBonkle = BonkleCache[nBonkles++];
pBonkle->at10 = NULL;
}
pBonkle->at20.x = pSprite->x;
pBonkle->at20.y = pSprite->y;
pBonkle->at20.z = pSprite->z;
pBonkle->at38 = pSprite->sectnum;
pBonkle->at2c = pBonkle->at20;
pBonkle->atc = soundId;
pBonkle->at8 = hRes;
pBonkle->at1c = pEffect->relVol;
pBonkle->at18 = v14;
Calc3DValues(pBonkle);
int priority = 1;
if (priority < lVol)
priority = lVol;
if (priority < rVol)
priority = rVol;
int loopStart = pEffect->loopStart;
int loopEnd = ClipLow(size - 1, 0);
if (a3 < 0)
loopStart = -1;
MV_Lock();
char *pData = (char*)gSoundRes.Lock(hRes);
if (loopStart >= 0)
{
if (snd_doppler)
{
pBonkle->at0 = FX_PlayLoopedRaw(pData + lPhase, size - lPhase, pData + loopStart, pData + loopEnd, lPitch, 0, lVol, lVol, 0, priority, 1.f, (intptr_t)&pBonkle->at0);
pBonkle->at4 = FX_PlayLoopedRaw(pData + rPhase, size - rPhase, pData + loopStart, pData + loopEnd, rPitch, 0, rVol, 0, rVol, priority, 1.f, (intptr_t)&pBonkle->at4);
}
else
{
pBonkle->at0 = FX_PlayLoopedRaw(pData + lPhase, size - lPhase, pData + loopStart, pData + loopEnd, v14, 0, lVol, lVol, rVol, priority, 1.f, (intptr_t)&pBonkle->at0);
pBonkle->at4 = 0;
}
}
else
{
pData = (char*)gSoundRes.Lock(pBonkle->at8);
if (snd_doppler)
{
pBonkle->at0 = FX_PlayRaw(pData + lPhase, size - lPhase, lPitch, 0, lVol, lVol, 0, priority, 1.f, (intptr_t)&pBonkle->at0);
pBonkle->at4 = FX_PlayRaw(pData + rPhase, size - rPhase, rPitch, 0, rVol, 0, rVol, priority, 1.f, (intptr_t)&pBonkle->at4);
}
else
{
pBonkle->at0 = FX_PlayRaw(pData + lPhase, size - lPhase, v14, 0, lVol, lVol, rVol, priority, 1.f, (intptr_t)&pBonkle->at0);
pBonkle->at4 = 0;
}
}
MV_Unlock();
}
// By NoOne: same as previous, but allows to set custom pitch for sound AND volume. Used by SFX gen now.
void sfxPlay3DSoundCP(spritetype* pSprite, int soundId, int a3, int a4, int pitch, int volume)
{
if (!SoundEnabled() || !pSprite || soundId < 0) return;
DICTNODE* hRes = gSoundRes.Lookup(soundId, "SFX");
if (!hRes) return;
if (!SoundEnabled() || soundId < 0 || !pSprite) return;
auto sid = soundEngine->FindSoundByResID(soundId);
if (sid == 0) return;
SFX* pEffect = (SFX*)gSoundRes.Load(hRes);
hRes = gSoundRes.Lookup(pEffect->rawName, "RAW");
if (!hRes) return;
int size = hRes->Size();
if (size <= 0) return;
if (pitch <= 0) pitch = pEffect->pitch;
else pitch -= Random(pEffect->pitchRange);
auto svec = GetSoundPos(&pSprite->pos);
float attenuation;
sid = getSfx(sid, attenuation, pitch, volume);
int v14;
v14 = mulscale16(pitch, sndGetRate(pEffect->format));
BONKLE * pBonkle = NULL;
if (a3 >= 0)
{
int i;
for (i = 0; i < nBonkles; i++)
{
pBonkle = BonkleCache[i];
if (pBonkle->at14 == a3 && (pBonkle->at10 == pSprite || (a4 & 1) != 0))
a3++; // This is to make 0 a valid channel value.
if (soundEngine->EnumerateChannels([=](FSoundChan* chan) -> int
{
if ((a4 & 4) != 0 && pBonkle->at14 == a3)
return;
if ((a4 & 2) != 0 && pBonkle->atc == soundId)
return;
if (pBonkle->at0 > 0)
FX_StopSound(pBonkle->at0);
if (pBonkle->at4 > 0)
FX_StopSound(pBonkle->at4);
if (pBonkle->at8)
if (chan->SourceType != SOURCE_Actor) return false; // other source types are not our business.
if (chan->EntChannel == a3 && (chan->Source == pSprite || (a4 & FX_GlobalChannel) != 0))
{
gSoundRes.Unlock(pBonkle->at8);
pBonkle->at8 = NULL;
if ((a4 & FX_ChannelMatch) != 0 && chan->EntChannel == a3)
return true;
if ((a4 & FX_SoundMatch) != 0 && chan->OrgID == sid)
return true;
soundEngine->StopChannel(chan);
return -1;
}
break;
}
}
if (i == nBonkles)
{
if (nBonkles >= 256)
return;
pBonkle = BonkleCache[nBonkles++];
}
pBonkle->at10 = pSprite;
pBonkle->at14 = a3;
return false;
})) return;
}
else
{
if (nBonkles >= 256)
return;
pBonkle = BonkleCache[nBonkles++];
pBonkle->at10 = NULL;
}
pBonkle->at20.x = pSprite->x;
pBonkle->at20.y = pSprite->y;
pBonkle->at20.z = pSprite->z;
pBonkle->at38 = pSprite->sectnum;
pBonkle->at2c = pBonkle->at20;
pBonkle->atc = soundId;
pBonkle->at8 = hRes;
pBonkle->at1c = ((volume == 0) ? pEffect->relVol : ((volume == -1) ? 0 : ((volume > 255) ? 255 : volume)));
pBonkle->at18 = v14;
Calc3DValues(pBonkle);
int priority = 1;
if (priority < lVol)
priority = lVol;
if (priority < rVol)
priority = rVol;
int loopStart = pEffect->loopStart;
int loopEnd = ClipLow(size - 1, 0);
if (a3 < 0)
loopStart = -1;
MV_Lock();
char* pData = (char*)gSoundRes.Lock(hRes);
if (loopStart >= 0)
{
if (snd_doppler)
{
pBonkle->at0 = FX_PlayLoopedRaw(pData + lPhase, size - lPhase, pData + loopStart, pData + loopEnd, lPitch, 0, lVol, lVol, 0, priority, 1.f, (intptr_t)& pBonkle->at0);
pBonkle->at4 = FX_PlayLoopedRaw(pData + rPhase, size - rPhase, pData + loopStart, pData + loopEnd, rPitch, 0, rVol, 0, rVol, priority, 1.f, (intptr_t)& pBonkle->at4);
}
else
{
pBonkle->at0 = FX_PlayLoopedRaw(pData + lPhase, size - lPhase, pData + loopStart, pData + loopEnd, v14, 0, lVol, lVol, rVol, priority, 1.f, (intptr_t)& pBonkle->at0);
pBonkle->at4 = 0;
}
}
else
{
pData = (char*)gSoundRes.Lock(pBonkle->at8);
if (snd_doppler)
{
pBonkle->at0 = FX_PlayRaw(pData + lPhase, size - lPhase, lPitch, 0, lVol, lVol, 0, priority, 1.f, (intptr_t)& pBonkle->at0);
pBonkle->at4 = FX_PlayRaw(pData + rPhase, size - rPhase, rPitch, 0, rVol, 0, rVol, priority, 1.f, (intptr_t)& pBonkle->at4);
}
else
{
pBonkle->at0 = FX_PlayRaw(pData + lPhase, size - lPhase, v14, 0, lVol, lVol, rVol, priority, 1.f, (intptr_t)& pBonkle->at0);
pBonkle->at4 = 0;
}
}
MV_Unlock();
soundEngine->StartSound(SOURCE_Actor, pSprite, &svec, a3, a3 == -1? CHANF_OVERLAP : CHANF_NONE , sid, 0.8f, attenuation, nullptr, pitch / 65536.f);
}
void sfxPlay3DSound(spritetype* pSprite, int soundId, int a3, int a4)
{
sfxPlay3DSoundCP(pSprite, soundId, a3, a4, -1, -1);
}
@ -374,136 +211,48 @@ void sfxKill3DSound(spritetype *pSprite, int a2, int a3)
{
if (!pSprite)
return;
for (int i = nBonkles - 1; i >= 0; i--)
{
BONKLE *pBonkle = BonkleCache[i];
if (pBonkle->at10 == pSprite && (a2 < 0 || a2 == pBonkle->at14) && (a3 < 0 || a3 == pBonkle->atc))
if (a2 >= 0) a2++;
soundEngine->EnumerateChannels([=](FSoundChan* channel)
{
if (pBonkle->at0 > 0)
if (channel->SourceType == SOURCE_Actor && channel->Source == pSprite && (a2 < 0 || a2 == channel->EntChannel) && (a3 < 0 || a3 == channel->OrgID))
{
FX_EndLooping(pBonkle->at0);
FX_StopSound(pBonkle->at0);
soundEngine->StopChannel(channel);
}
if (pBonkle->at4 > 0)
{
FX_EndLooping(pBonkle->at4);
FX_StopSound(pBonkle->at4);
}
if (pBonkle->at8)
{
gSoundRes.Unlock(pBonkle->at8);
pBonkle->at8 = NULL;
}
BonkleCache[i] = BonkleCache[--nBonkles];
BonkleCache[nBonkles] = pBonkle;
break;
}
}
return false;
});
}
void sfxKillAllSounds(void)
{
for (int i = nBonkles - 1; i >= 0; i--)
soundEngine->EnumerateChannels([](FSoundChan* channel)
{
BONKLE *pBonkle = BonkleCache[i];
if (pBonkle->at0 > 0)
{
FX_EndLooping(pBonkle->at0);
FX_StopSound(pBonkle->at0);
}
if (pBonkle->at4 > 0)
{
FX_EndLooping(pBonkle->at4);
FX_StopSound(pBonkle->at4);
}
if (pBonkle->at8)
{
gSoundRes.Unlock(pBonkle->at8);
pBonkle->at8 = NULL;
}
BonkleCache[i] = BonkleCache[--nBonkles];
BonkleCache[nBonkles] = pBonkle;
}
if (channel->SourceType == SOURCE_Actor || channel->SourceType == SOURCE_Unattached) soundEngine->StopChannel(channel);
return false;
});
}
void sfxUpdate3DSounds(void)
{
int dx = mulscale30(Cos(gMe->pSprite->ang + 512), 43);
earL0 = earL;
int dy = mulscale30(Sin(gMe->pSprite->ang + 512), 43);
earR0 = earR;
earL.x = gMe->pSprite->x - dx;
earL.y = gMe->pSprite->y - dy;
earR.x = gMe->pSprite->x + dx;
earR.y = gMe->pSprite->y + dy;
earVL.dx = earL.x - earL0.x;
earVL.dy = earL.y - earL0.y;
earVR.dx = earR.x - earR0.x;
earVR.dy = earR.y - earR0.y;
for (int i = nBonkles - 1; i >= 0; i--)
{
BONKLE *pBonkle = BonkleCache[i];
if (pBonkle->at0 > 0 || pBonkle->at4 > 0)
{
if (!pBonkle->at8)
continue;
if (pBonkle->at10)
{
pBonkle->at2c = pBonkle->at20;
pBonkle->at20.x = pBonkle->at10->x;
pBonkle->at20.y = pBonkle->at10->y;
pBonkle->at20.z = pBonkle->at10->z;
pBonkle->at38 = pBonkle->at10->sectnum;
}
Calc3DValues(pBonkle);
MV_Lock();
if (pBonkle->at0 > 0)
{
if (pBonkle->at4 > 0)
{
FX_SetPan(pBonkle->at0, lVol, lVol, 0);
FX_SetFrequency(pBonkle->at0, lPitch);
}
else
FX_SetPan(pBonkle->at0, lVol, lVol, rVol);
}
if (pBonkle->at4 > 0)
{
FX_SetPan(pBonkle->at4, rVol, 0, rVol);
FX_SetFrequency(pBonkle->at4, rPitch);
}
MV_Unlock();
}
else
{
gSoundRes.Unlock(pBonkle->at8);
pBonkle->at8 = NULL;
BonkleCache[i] = BonkleCache[--nBonkles];
BonkleCache[nBonkles] = pBonkle;
}
}
}
void sfxSetReverb(bool toggle)
{
if (toggle)
{
FX_SetReverb_(128);
FX_SetReverb(128);
FX_SetReverbDelay(10);
}
else
FX_SetReverb_(0);
FX_SetReverb(0);
}
void sfxSetReverb2(bool toggle)
{
if (toggle)
{
FX_SetReverb_(128);
FX_SetReverb(128);
FX_SetReverbDelay(20);
}
else
FX_SetReverb_(0);
FX_SetReverb(0);
}
END_BLD_NS

View file

@ -25,30 +25,24 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_BLD_NS
#if 0
struct BONKLE
{
int at0;
int at4;
DICTNODE* at8;
int atc;
spritetype* at10;
int at14;
int at18;
int at1c;
POINT3D at20;
POINT3D at2c;
//int at20;
//int at24;
//int at28;
//int at2c;
//int at30;
//int at34;
int at38;
int at3c;
int left;
int right;
DICTNODE* data;
int soundId;
spritetype* origin;
int channel;
int pitch;
int relVol;
POINT3D originPt;
POINT3D oldOriginPt;
};
extern BONKLE Bonkle[256];
extern BONKLE* BonkleCache[256];
#endif
void sfxInit(void);
void sfxTerm(void);

View file

@ -35,6 +35,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "al_midi.h"
#include "openaudio.h"
#include "z_music.h"
#include "sfx.h"
#include "sound/s_soundinternal.h"
BEGIN_BLD_NS
@ -57,6 +59,72 @@ int soundRates[13] = {
};
#define kChannelMax 32
//==========================================================================
//
// S_AddBloodSFX
//
// Registers a new sound with the name "<lumpname>.sfx"
// Actual sound data is searched for in the ns_bloodraw namespace.
//
//==========================================================================
static void S_AddBloodSFX(int lumpnum)
{
auto sfxlump = fileSystem.ReadFile(lumpnum);
const SFX* sfx = (SFX*)sfxlump.GetMem();
FStringf rawname("%s.raw", sfx->rawName);
auto rawlump = fileSystem.FindFile(rawname);
int sfxnum;
if (rawlump != -1)
{
auto& S_sfx = soundEngine->GetSounds();
sfxnum = soundEngine->AddSoundLump(sfx->rawName, rawlump, 0, fileSystem.GetResourceId(lumpnum), 6);
if (sfx->format < 5 || sfx->format > 12)
{ // [0..4] + invalid formats
S_sfx[sfxnum].RawRate = 11025;
}
else if (sfx->format < 9)
{ // [5..8]
S_sfx[sfxnum].RawRate = 22050;
}
else
{ // [9..12]
S_sfx[sfxnum].RawRate = 44100;
}
S_sfx[sfxnum].bLoadRAW = true;
S_sfx[sfxnum].LoopStart = LittleLong(sfx->loopStart);
//S_sfx[sfxnum].Volume = sfx->relVol / 255.f; This cannot be done because this volume setting is optional.
S_sfx[sfxnum].UserData.Resize(8);
int* udata = (int*)S_sfx[sfxnum].UserData.Data();
udata[0] = sfx->pitch;
udata[1] = sfx->pitchRange;
udata[2] = sfx->relVol; }
}
void sndInit(void)
{
sfxInit();
for (int i = fileSystem.GetNumEntries() - 1; i >= 0; i--)
{
auto type = fileSystem.GetResourceType(i);
if (type == NAME_SFX)
{
if (soundEngine->FindSoundByResID(fileSystem.GetResourceId(i)) == 0)
S_AddBloodSFX(i);
}
else if (type == NAME_WAV || type == NAME_OGG || type == NAME_FLAC || type == NAME_VOC)
{
soundEngine->AddSoundLump(fileSystem.GetFileName(i), i, 0, fileSystem.GetResourceId(i)| 0x40000000, 6); // mark the resource ID as special.
}
}
soundEngine->HashSounds();
}
int sndGetRate(int format)
{
if (format < 13)
@ -64,22 +132,6 @@ int sndGetRate(int format)
return 11025;
}
SAMPLE2D Channel[kChannelMax];
SAMPLE2D * FindChannel(void)
{
for (int i = kChannelMax - 1; i >= 0; i--)
if (Channel[i].at5 == 0) return &Channel[i];
consoleSysMsg("No free channel available for sample");
//ThrowError("No free channel available for sample");
return NULL;
}
void sndSetFXVolume(int nVolume)
{
snd_fxvolume = nVolume;
FX_SetVolume(nVolume);
}
void SoundCallback(intptr_t val)
@ -88,8 +140,6 @@ void SoundCallback(intptr_t val)
pChannel->at0 = 0;
}
void sndKillSound(SAMPLE2D *pChannel);
void sndStartSample(const char *pzSound, int nVolume, int nChannel)
{
if (!SoundEnabled())
@ -97,19 +147,11 @@ void sndStartSample(const char *pzSound, int nVolume, int nChannel)
if (!strlen(pzSound))
return;
dassert(nChannel >= -1 && nChannel < kChannelMax);
SAMPLE2D *pChannel;
if (nChannel == -1)
pChannel = FindChannel();
else
pChannel = &Channel[nChannel];
if (pChannel->at0 > 0)
sndKillSound(pChannel);
pChannel->at5 = gSoundRes.Lookup(pzSound, "RAW");
if (!pChannel->at5)
return;
int nSize = pChannel->at5->Size();
char *pData = (char*)gSoundRes.Lock(pChannel->at5);
pChannel->at0 = FX_PlayRaw(pData, nSize, sndGetRate(1), 0, nVolume, nVolume, nVolume, nVolume, 1.f, (intptr_t)&pChannel->at0);
auto snd = soundEngine->FindSound(pzSound);
if (snd > 0)
{
soundEngine->StartSound(SOURCE_None, nullptr, nullptr, nChannel + 1, 0, snd, nVolume / 255.f, ATTN_NONE);
}
}
void sndStartSample(unsigned int nSound, int nVolume, int nChannel, bool bLoop)
@ -117,193 +159,35 @@ void sndStartSample(unsigned int nSound, int nVolume, int nChannel, bool bLoop)
if (!SoundEnabled())
return;
dassert(nChannel >= -1 && nChannel < kChannelMax);
DICTNODE *hSfx = gSoundRes.Lookup(nSound, "SFX");
if (!hSfx)
return;
SFX *pEffect = (SFX*)gSoundRes.Lock(hSfx);
dassert(pEffect != NULL);
SAMPLE2D *pChannel;
if (nChannel == -1)
pChannel = FindChannel();
else
pChannel = &Channel[nChannel];
if (pChannel->at0 > 0)
sndKillSound(pChannel);
pChannel->at5 = gSoundRes.Lookup(pEffect->rawName, "RAW");
if (!pChannel->at5)
return;
if (nVolume < 0)
nVolume = pEffect->relVol;
int nSize = pChannel->at5->Size();
int nLoopEnd = nSize - 1;
if (nLoopEnd < 0)
nLoopEnd = 0;
if (nSize <= 0)
return;
char *pData = (char*)gSoundRes.Lock(pChannel->at5);
if (nChannel < 0)
bLoop = false;
if (bLoop)
if (nChannel >= 7) nChannel = -1;
auto snd = soundEngine->FindSoundByResID(nSound);
if (snd > 0)
{
pChannel->at0 = FX_PlayLoopedRaw(pData, nSize, pData + pEffect->loopStart, pData + nLoopEnd, sndGetRate(pEffect->format),
0, nVolume, nVolume, nVolume, nVolume, 1.f, (intptr_t)&pChannel->at0);
pChannel->at4 |= 1;
}
else
{
pChannel->at0 = FX_PlayRaw(pData, nSize, sndGetRate(pEffect->format), 0, nVolume, nVolume, nVolume, nVolume, 1.f, (intptr_t)&pChannel->at0);
pChannel->at4 &= ~1;
if (nVolume < 0)
{
auto udata = (int*)soundEngine->GetUserData(snd);
if (udata) nVolume = udata[2];
else nVolume = 255;
}
soundEngine->StartSound(SOURCE_None, nullptr, nullptr, (nChannel + 1), (bLoop? CHANF_LOOP : EChanFlags::FromInt(0)), snd, nVolume / 255.f, ATTN_NONE);
}
}
void sndStartWavID(unsigned int nSound, int nVolume, int nChannel)
{
if (!SoundEnabled())
return;
dassert(nChannel >= -1 && nChannel < kChannelMax);
SAMPLE2D *pChannel;
if (nChannel == -1)
pChannel = FindChannel();
else
pChannel = &Channel[nChannel];
if (pChannel->at0 > 0)
sndKillSound(pChannel);
pChannel->at5 = gSoundRes.Lookup(nSound, "WAV");
if (!pChannel->at5)
return;
char *pData = (char*)gSoundRes.Lock(pChannel->at5);
pChannel->at0 = FX_Play(pData, pChannel->at5->Size(), 0, -1, 0, nVolume, nVolume, nVolume, nVolume, 1.f, (intptr_t)&pChannel->at0);
}
void sndKillSound(SAMPLE2D *pChannel)
{
if (pChannel->at4 & 1)
{
FX_EndLooping(pChannel->at0);
pChannel->at4 &= ~1;
}
FX_StopSound(pChannel->at0);
return sndStartSample(nSound | 0x40000000, nVolume, nChannel);
}
void sndStartWavDisk(const char *pzFile, int nVolume, int nChannel)
{
dassert(nChannel >= -1 && nChannel < kChannelMax);
SAMPLE2D *pChannel;
if (nChannel == -1)
pChannel = FindChannel();
else
pChannel = &Channel[nChannel];
if (pChannel->at0 > 0)
sndKillSound(pChannel);
auto hFile = fileSystem.OpenFileReader(pzFile, 0);
if (!hFile.isOpen())
return;
int nLength = hFile.GetLength();
char* pData = nullptr;
cacheAllocateBlock((intptr_t*)pData, nLength, nullptr); // use this obsolete call to indicate that some work is needed here!
if (!pData)
{
return;
}
hFile.Read(pData, nLength);
pChannel->at5 = (DICTNODE*)pData;
pChannel->at4 |= 2;
pChannel->at0 = FX_Play(pData, nLength, 0, -1, 0, nVolume, nVolume, nVolume, nVolume, 1.f, (intptr_t)&pChannel->at0);
return sndStartSample(pzFile, nVolume, nChannel);
}
void sndKillAllSounds(void)
{
for (int i = 0; i < kChannelMax; i++)
{
SAMPLE2D *pChannel = &Channel[i];
if (pChannel->at0 > 0)
sndKillSound(pChannel);
if (pChannel->at5)
{
if (pChannel->at4 & 2)
{
pChannel->at4 &= ~2;
}
else // This 'else' needs to be removed once the file system is up (when cacheAllocateBlock gets replaced.)
{
gSoundRes.Unlock(pChannel->at5);
}
pChannel->at5 = 0;
}
}
}
void sndProcess(void)
{
for (int i = 0; i < kChannelMax; i++)
{
if (Channel[i].at0 <= 0 && Channel[i].at5)
{
if (Channel[i].at4 & 2)
{
Channel[i].at4 &= ~2;
}
else // This 'else' needs to be removed once the file system is up (when cacheAllocateBlock gets replaced.)
{
gSoundRes.Unlock(Channel[i].at5);
}
Channel[i].at5 = 0;
}
}
}
void InitSoundDevice(void)
{
#ifdef MIXERTYPEWIN
void *initdata = (void *)win_gethwnd(); // used for DirectSound
#else
void *initdata = NULL;
#endif
int nStatus;
nStatus = FX_Init(snd_numvoices, snd_numchannels, snd_mixrate, initdata);
if (nStatus != 0)
{
initprintf("InitSoundDevice: %s\n", FX_ErrorString(nStatus));
return;
}
snd_reversestereo.Callback();
snd_fxvolume.Callback();
FX_SetCallBack(SoundCallback);
}
void DeinitSoundDevice(void)
{
int nStatus = FX_Shutdown();
if (nStatus != 0)
ThrowError(FX_ErrorString(nStatus));
soundEngine->StopSound(CHAN_AUTO);
}
bool sndActive = false;
void sndTerm(void)
{
if (!sndActive)
return;
sndActive = false;
Mus_Stop();
DeinitSoundDevice();
//DeinitMusicDevice();
}
extern char *pUserSoundRFF;
void sndInit(void)
{
memset(Channel, 0, sizeof(Channel));
#if 0
pSongPtr = NULL;
nSongSize = 0;
bWaveMusic = false;
nWaveMusicHandle = -1;
#endif
InitSoundDevice();
//InitMusicDevice();
//atexit(sndTerm);
sndActive = true;
}
END_BLD_NS

View file

@ -45,7 +45,6 @@ struct SFX
};
int sndGetRate(int format);
void sndSetFXVolume(int nVolume);
void sndStartSample(const char *pzSound, int nVolume, int nChannel = -1);
void sndStartSample(unsigned int nSound, int nVolume, int nChannel = -1, bool bLoop = false);
void sndStartWavID(unsigned int nSound, int nVolume, int nChannel = -1);

View file

@ -1300,6 +1300,16 @@ static inline void maybe_grow_buffer(char ** const buffer, int32_t * const buffe
#include "fix16.h"
#include "libdivide.h"
#include "clockticks.hpp"
#include "vectors.h"
inline FVector3 GetSoundPos(const vec3_t *pos)
{
// converts a Build coordinate to a sound system coordinate
const float xmul = 1 / 16.f;
const float ymul = -1 / 16.f;
const float zmul = -1 / 256.f;
return { pos->x* xmul, pos->z* zmul, pos->y* ymul };
}
/* End dependence on compat.o object. */

View file

@ -550,6 +550,15 @@ int FileSystem::GetResourceId(int lump) const
return FileInfo[lump].lump->ResourceId;
}
FName FileSystem::GetResourceType(int lump) const
{
if ((size_t)lump >= NumEntries)
return NAME_None;
else
return FileInfo[lump].lump->LumpName[FResourceLump::ExtensionType];
}
//==========================================================================
//
// GetLumpFile

View file

@ -164,6 +164,7 @@ public:
bool IsEncryptedFile(int file) const noexcept;
int GetResourceId(int file) const;
FName GetResourceType(int file) const;
int GetNumResourceFiles() const { return NumFiles; }
int GetNumEntries () const { return NumEntries; }

View file

@ -22,6 +22,7 @@ enum EChanFlag
CHANF_PICKUP = CHANF_MAYBE_LOCAL,
CHANF_NONE = 0,
CHANF_IS3D = 1, // internal: Sound is 3D.
CHANF_EVICTED = 2, // internal: Sound was evicted.
CHANF_FORGETTABLE = 4, // internal: Forget channel data when sound stops.

View file

@ -727,7 +727,8 @@ sfxinfo_t *SoundEngine::LoadSound(sfxinfo_t *sfx, FSoundLoadBuffer *pBuffer)
// then set this one up as a link, and don't load the sound again.
for (i = 0; i < S_sfx.Size(); i++)
{
if (S_sfx[i].data.isValid() && S_sfx[i].link == sfxinfo_t::NO_LINK && S_sfx[i].lumpnum == sfx->lumpnum)
if (S_sfx[i].data.isValid() && S_sfx[i].link == sfxinfo_t::NO_LINK && S_sfx[i].lumpnum == sfx->lumpnum &&
(!sfx->bLoadRAW || (sfx->RawRate == S_sfx[i].RawRate))) // Raw sounds with different sample rates may not share buffers, even if they use the same source data.
{
//DPrintf (DMSG_NOTIFY, "Linked %s to %s (%d)\n", sfx->name.GetChars(), S_sfx[i].name.GetChars(), i);
sfx->link = i;
@ -803,7 +804,7 @@ void SoundEngine::LoadSound3D(sfxinfo_t *sfx, FSoundLoadBuffer *pBuffer)
{
snd = GSnd->LoadSoundBuffered(pBuffer, true);
}
else if (sfx->lumpnum >= 0)
else
{
auto sfxdata = ReadSound(sfx->lumpnum);
int size = sfxdata.Size();
@ -1555,6 +1556,14 @@ int SoundEngine::AddSoundLump(const char* logicalname, int lump, int CurrentPitc
return (int)S_sfx.Size()-1;
}
int SoundEngine::AddSfx(sfxinfo_t &sfx)
{
S_sfx.Push(sfx);
if (sfx.ResourceId >= 0) ResIdMap[sfx.ResourceId] = S_sfx.Size() - 1;
return (int)S_sfx.Size() - 1;
}
//==========================================================================
//
// S_FindSoundTentative

View file

@ -95,8 +95,8 @@ enum
ROLLOFF_Custom // Lookup volume from SNDCURVE
};
int S_FindSound(const char *logicalname);
int S_FindSoundByResID(int snd_id);
int S_FindSoundByResID(int ndx);
int S_FindSound(const char* name);
// An index into the S_sfx[] array.
class FSoundID
@ -173,11 +173,8 @@ struct FSoundChan : public FISoundChannel
int16_t NearLimit;
uint8_t SourceType;
float LimitRange;
union
{
const void *Source;
float Point[3]; // Sound is not attached to any source.
};
const void *Source;
float Point[3]; // Sound is not attached to any source.
};
@ -217,8 +214,7 @@ 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_Actor, // Sound is coming from an actor.
SOURCE_Sector, // Sound is coming from a sector.
SOURCE_Polyobj, // Sound is coming from a polyobject.
SOURCE_Ambient, // Sound is coming from a blood ambient definition.
SOURCE_Unattached, // Sound is not attached to any particular emitter.
};
@ -383,7 +379,8 @@ public:
{
for (FSoundChan* chan = Channels; chan; chan = chan->NextChan)
{
if (callback(chan)) return true;
int res = callback(chan);
if (res) return res > 0;
}
return false;
}
@ -406,6 +403,7 @@ public:
int FindSoundNoHash(const char* logicalname);
int FindSoundByLump(int lump);
int AddSoundLump(const char* logicalname, int lump, int CurrentPitchMask, int resid = -1, int nearlimit = 2);
int AddSfx(sfxinfo_t &sfx);
int FindSoundTentative(const char* name);
void CacheRandomSound(sfxinfo_t* sfx);
unsigned int GetMSLength(FSoundID sound);
@ -433,4 +431,18 @@ inline void FX_StopAllSounds(void)
inline void FX_SetReverb(int strength)
{
// todo: investigate how this works and set a proper environment.
}
}
inline void FX_SetReverbDelay(int delay)
{
}
inline int S_FindSoundByResID(int ndx)
{
return soundEngine->FindSoundByResID(ndx);
}
inline int S_FindSound(const char* name)
{
return soundEngine->FindSound(name);
}

View file

@ -14,6 +14,10 @@ xx(SEQ)
xx(SFX)
xx(RAW)
xx(MAP)
xx(WAV)
xx(OGG)
xx(FLAC)
xx(VOC)
xx(Controlmessage)
xx(MainMenu)

View file

@ -30,10 +30,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_DUKE_NS
// Coordinate factors to map Build coordinate space to sound system coordinate space.
const float xmul = 1 / 16.f;
const float ymul = -1 / 16.f;
const float zmul = -1 / 256.f;
class DukeSoundEngine : public SoundEngine
{
@ -211,8 +207,8 @@ static int S_CalcDistAndAng(int spriteNum, int soundNum, int sectNum,
if (sndPos)
{
FVector3 sndorg = { pos->x * xmul, pos->z * zmul, pos->y * ymul };
FVector3 campos = { cam->x * xmul, cam->z * zmul, cam->y * ymul };
FVector3 sndorg = GetSoundPos(pos);
FVector3 campos = GetSoundPos(cam);
// Now calculate the virtual position in sound system coordinates.
FVector3 sndvec = sndorg - campos;
if (orgsndist > 0)
@ -325,7 +321,7 @@ void S_Update(void)
{
listener.angle = -(float)ca * pi::pi() / 1024; // Build uses a period of 2048.
listener.velocity.Zero();
listener.position = { c->x * xmul, c->z * zmul, c->y * ymul };
listener.position = GetSoundPos(c);
listener.underwater = false;
// This should probably use a real environment instead of the pitch hacking in S_PlaySound3D.
// listenactor->waterlevel == 3;

View file

@ -30,11 +30,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_RR_NS
// Coordinate factors to map Build coordinate space to sound system coordinate space.
const float xmul = 1 / 16.f;
const float ymul = -1 / 16.f;
const float zmul = -1 / 256.f;
class DukeSoundEngine : public SoundEngine
{
// client specific parts of the sound engine go in this class.
@ -211,8 +206,8 @@ static int S_CalcDistAndAng(int spriteNum, int soundNum, int sectNum,
if (sndPos)
{
FVector3 sndorg = { pos->x * xmul, pos->z * zmul, pos->y * ymul };
FVector3 campos = { cam->x * xmul, cam->z * zmul, cam->y * ymul };
FVector3 sndorg = GetSoundPos(pos);
FVector3 campos = GetSoundPos(cam);
// Now calculate the virtual position in sound system coordinates.
FVector3 sndvec = sndorg - campos;
if (orgsndist > 0)
@ -330,7 +325,7 @@ void S_Update(void)
{
listener.angle = -(float)ca * pi::pi() / 1024; // Build uses a period of 2048.
listener.velocity.Zero();
listener.position = { c->x * xmul, c->z * zmul, c->y * ymul };
listener.position = GetSoundPos(c);
listener.underwater = false;
// This should probably use a real environment instead of the pitch hacking in S_PlaySound3D.
// listenactor->waterlevel == 3;