diff --git a/source/common/audio/sound/i_sound.cpp b/source/common/audio/sound/i_sound.cpp index 90fda4be2..5f9fdda18 100644 --- a/source/common/audio/sound/i_sound.cpp +++ b/source/common/audio/sound/i_sound.cpp @@ -131,7 +131,7 @@ public: void SetMusicVolume (float volume) { } - SoundHandle LoadSound(uint8_t *sfxdata, int length) + SoundHandle LoadSound(uint8_t *sfxdata, int length, int def_loop_start, int def_loop_end) { SoundHandle retval = { NULL }; return retval; diff --git a/source/common/audio/sound/i_sound.h b/source/common/audio/sound/i_sound.h index b2f281f29..080515494 100644 --- a/source/common/audio/sound/i_sound.h +++ b/source/common/audio/sound/i_sound.h @@ -105,7 +105,7 @@ public: virtual bool IsNull() { return false; } virtual void SetSfxVolume (float volume) = 0; virtual void SetMusicVolume (float volume) = 0; - virtual SoundHandle LoadSound(uint8_t *sfxdata, int length) = 0; + virtual SoundHandle LoadSound(uint8_t *sfxdata, int length, int def_loop_start, int def_loop_end) = 0; SoundHandle LoadSoundVoc(uint8_t *sfxdata, int length); virtual SoundHandle LoadSoundRaw(uint8_t *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1) = 0; virtual void UnloadSound (SoundHandle sfx) = 0; // unloads a sound from memory diff --git a/source/common/audio/sound/oalsound.cpp b/source/common/audio/sound/oalsound.cpp index 81ec4cae7..6f6e4e3ee 100644 --- a/source/common/audio/sound/oalsound.cpp +++ b/source/common/audio/sound/oalsound.cpp @@ -1096,7 +1096,7 @@ SoundHandle OpenALSoundRenderer::LoadSoundRaw(uint8_t *sfxdata, int length, int return retval; } -SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length) +SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length, int def_loop_start, int def_loop_end) { SoundHandle retval = { NULL }; ALenum format = AL_NONE; @@ -1106,7 +1106,16 @@ SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length) uint32_t loop_start = 0, loop_end = ~0u; zmusic_bool startass = false, endass = false; - FindLoopTags(sfxdata, length, &loop_start, &startass, &loop_end, &endass); + if (def_loop_start < 0) + { + FindLoopTags(sfxdata, length, &loop_start, &startass, &loop_end, &endass); + } + else + { + loop_start = def_loop_start; + loop_end = def_loop_end; + startass = endass = true; + } auto decoder = CreateDecoder(sfxdata, length, true); if (!decoder) return retval; diff --git a/source/common/audio/sound/oalsound.h b/source/common/audio/sound/oalsound.h index 90cb8c8bd..4b277bc25 100644 --- a/source/common/audio/sound/oalsound.h +++ b/source/common/audio/sound/oalsound.h @@ -34,7 +34,7 @@ public: virtual void SetSfxVolume(float volume); virtual void SetMusicVolume(float volume); - virtual SoundHandle LoadSound(uint8_t *sfxdata, int length); + virtual SoundHandle LoadSound(uint8_t *sfxdata, int length, int def_loop_start, int def_loop_end); virtual SoundHandle LoadSoundRaw(uint8_t *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1); virtual void UnloadSound(SoundHandle sfx); virtual unsigned int GetMSLength(SoundHandle sfx); diff --git a/source/common/audio/sound/s_sound.cpp b/source/common/audio/sound/s_sound.cpp index 11c598f04..f3b0fb412 100644 --- a/source/common/audio/sound/s_sound.cpp +++ b/source/common/audio/sound/s_sound.cpp @@ -382,7 +382,7 @@ static float CalcPitch(int pitchmask, float defpitch, float defpitchmax) { if (defpitchmax > 0.0 && defpitch != defpitchmax) { - defpitch = pr_soundpitch.GenRand_Real1() * (defpitchmax - defpitch) + defpitch; + defpitch = (float)pr_soundpitch.GenRand_Real1() * (defpitchmax - defpitch) + defpitch; } return defpitch; } @@ -769,7 +769,7 @@ sfxinfo_t *SoundEngine::LoadSound(sfxinfo_t *sfx) // If that fails, let the sound system try and figure it out. else { - sfx->data = GSnd->LoadSound(sfxdata.Data(), size); + sfx->data = GSnd->LoadSound(sfxdata.Data(), size, sfx->LoopStart, sfx->LoopEnd); } } diff --git a/source/common/audio/sound/s_soundinternal.h b/source/common/audio/sound/s_soundinternal.h index 81a740313..3f5f92373 100644 --- a/source/common/audio/sound/s_soundinternal.h +++ b/source/common/audio/sound/s_soundinternal.h @@ -102,6 +102,7 @@ constexpr FSoundID INVALID_SOUND = FSoundID::fromInt(-1); int RawRate = 0; // Sample rate to use when bLoadRAW is true int LoopStart = -1; // -1 means no specific loop defined + int LoopEnd = -1; // -1 means no specific loop defined FSoundID link = NO_LINK; constexpr static FSoundID NO_LINK = FSoundID::fromInt(-1); diff --git a/source/core/music/s_advsound.cpp b/source/core/music/s_advsound.cpp index 9e5229b61..fa6d87431 100644 --- a/source/core/music/s_advsound.cpp +++ b/source/core/music/s_advsound.cpp @@ -62,6 +62,7 @@ enum SICommands SI_PitchSet, SI_PitchSetDuke, SI_DukeFlags, + SI_Loop, }; @@ -95,6 +96,7 @@ static const char *SICommandStrings[] = "$pitchset", "$pitchsetduke", "$dukeflags", + "$loop", NULL }; @@ -380,6 +382,19 @@ static void S_AddSNDINFO (int lump) } + case SI_Loop: { + // dukesound + // Sets loop points for the given sound in samples. Only really useful for WAV - for Ogg and FLAC use the metadata they can contain. + sc.MustGetString(); + auto sfxid = soundEngine->FindSoundTentative(sc.String, DEFAULT_LIMIT); + auto sfx = soundEngine->GetWritableSfx(sfxid); + sc.MustGetNumber(); + sfx->LoopStart = sc.Number; + if (sc.CheckNumber()) + sfx->LoopEnd = sc.Number; + break; + } + default: { // Got a logical sound mapping diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index 5e2b7e884..a17f231cc 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -526,7 +526,7 @@ int S_PlaySound3D(FSoundID soundid, DDukeActor* actor, const DVector3& pos, int { if (explosion && underwater) { - pitch = chan->Pitch? chan->Pitch * (0.55 / 128) : 0.55; // todo: fix pitch storage in backend. + pitch = float(chan->Pitch? chan->Pitch * (0.55 / 128) : 0.55); // todo: fix pitch storage in backend. soundEngine->SetPitch(chan, pitch); } chan->UserData = (currentCommentarySound != NO_SOUND);