diff --git a/Client/mods/deathmatch/logic/CBassAudio.cpp b/Client/mods/deathmatch/logic/CBassAudio.cpp index 2f31d863242..a2ff7e55a9a 100644 --- a/Client/mods/deathmatch/logic/CBassAudio.cpp +++ b/Client/mods/deathmatch/logic/CBassAudio.cpp @@ -843,6 +843,16 @@ void CBassAudio::ApplyFxEffects() } } +BOOL CBassAudio::SetFxParameters(uint iFxEffect, void* params) +{ + return BASS_FXSetParameters(m_FxEffects[iFxEffect], params); +} + +BOOL CBassAudio::GetFxParameters(uint iFxEffect, void* params) +{ + return BASS_FXGetParameters(m_FxEffects[iFxEffect], params); +} + // // Must be call every frame // diff --git a/Client/mods/deathmatch/logic/CBassAudio.h b/Client/mods/deathmatch/logic/CBassAudio.h index 9d26bd85d77..65a4280996f 100644 --- a/Client/mods/deathmatch/logic/CBassAudio.h +++ b/Client/mods/deathmatch/logic/CBassAudio.h @@ -1,14 +1,13 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 - * (Shared logic for modifications) + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory - * FILE: - * PURPOSE: + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ * *****************************************************************************/ -#define CUT_OFF 5.0f //Cut off point at which volume is regarded as 0 in the function e^-x +#define CUT_OFF 5.0f // Cut off point at which volume is regarded as 0 in the function e^-x enum eSoundEventType { @@ -76,6 +75,8 @@ class CBassAudio bool GetPanEnabled() { return m_bPan; }; void SetPanEnabled(bool bPan) { m_bPan = bPan; }; void SetFxEffects(int* pEnabledEffects, uint iNumElements); + BOOL SetFxParameters(uint iFxEffect, void* params); + BOOL GetFxParameters(uint iFxEffect, void* params); SString GetMetaTags(const SString& strFormat); uint GetReachedEndCount(); bool IsFreed(); diff --git a/Client/mods/deathmatch/logic/CClientPlayerVoice.h b/Client/mods/deathmatch/logic/CClientPlayerVoice.h index 39ce38121d7..d89b0b2baa0 100644 --- a/Client/mods/deathmatch/logic/CClientPlayerVoice.h +++ b/Client/mods/deathmatch/logic/CClientPlayerVoice.h @@ -72,6 +72,7 @@ class CClientPlayerVoice bool SetFxEffect(uint uiFxEffect, bool bEnable); bool IsFxEffectEnabled(uint uiFxEffect); + bool IsActive() { return m_bVoiceActive; } private: diff --git a/Client/mods/deathmatch/logic/CClientSound.cpp b/Client/mods/deathmatch/logic/CClientSound.cpp index d6a214d8e6d..dc10132e4ba 100644 --- a/Client/mods/deathmatch/logic/CClientSound.cpp +++ b/Client/mods/deathmatch/logic/CClientSound.cpp @@ -13,7 +13,7 @@ CClientSound::CClientSound(CClientManager* pManager, ElementID ID) : ClassInit(this), CClientEntity(ID) { m_pSoundManager = pManager->GetSoundManager(); - m_pAudio = NULL; + m_pAudio = nullptr; SetTypeName("sound"); @@ -26,7 +26,7 @@ CClientSound::CClientSound(CClientManager* pManager, ElementID ID) : ClassInit(t m_bPan = true; m_fPan = 0.0f; - m_pBuffer = NULL; + m_pBuffer = nullptr; m_uiFrameNumberCreated = g_pClientGame->GetFrameCount(); } @@ -643,6 +643,30 @@ bool CClientSound::IsFxEffectEnabled(uint uiFxEffect) return m_EnabledEffects[uiFxEffect] ? true : false; } +bool CClientSound::SetFxEffectParameters(uint uiFxEffect, void* params) +{ + if (uiFxEffect >= NUMELMS(m_EnabledEffects)) + return false; + + if (m_pAudio) + if (m_pAudio->SetFxParameters(uiFxEffect, params)) + return true; + + return false; +} + +bool CClientSound::GetFxEffectParameters(uint uiFxEffect, void* params) +{ + if (uiFxEffect >= NUMELMS(m_EnabledEffects)) + return false; + + if (m_pAudio) + if (m_pAudio->GetFxParameters(uiFxEffect, params)) + return true; + + return false; +} + //////////////////////////////////////////////////////////// // // CClientSound::Process3D @@ -726,7 +750,7 @@ void CClientSound::Process3D(const CVector& vecPlayerPosition, const CVector& ve } else if (eventInfo.type == SOUND_EVENT_STREAM_RESULT) { - // Call onClientSoundStream LUA event + // Call onClientSoundStream Lua event CLuaArguments Arguments; Arguments.PushBoolean(eventInfo.bBool); Arguments.PushNumber(eventInfo.dNumber); diff --git a/Client/mods/deathmatch/logic/CClientSound.h b/Client/mods/deathmatch/logic/CClientSound.h index a1b51fbf216..0b960497b5d 100644 --- a/Client/mods/deathmatch/logic/CClientSound.h +++ b/Client/mods/deathmatch/logic/CClientSound.h @@ -82,6 +82,9 @@ class CClientSound final : public CClientEntity bool SetFxEffect(uint uiFxEffect, bool bEnable); bool IsFxEffectEnabled(uint uiFxEffect); + + bool SetFxEffectParameters(uint uiFxEffect, void* params); + bool GetFxEffectParameters(uint uiFxEffect, void* params); void Unlink(){}; diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index c8a95274b57..d4d17a8c691 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -667,6 +667,97 @@ ADD_ENUM(eClientModelType::OBJECT, "object") ADD_ENUM(eClientModelType::VEHICLE, "vehicle") IMPLEMENT_ENUM_CLASS_END("client-model-type") +// Sound effects +IMPLEMENT_ENUM_BEGIN(eSoundEffectType) +ADD_ENUM(BASS_FX_DX8_CHORUS, "chorus") +ADD_ENUM(BASS_FX_DX8_COMPRESSOR, "compressor") +ADD_ENUM(BASS_FX_DX8_DISTORTION, "distortion") +ADD_ENUM(BASS_FX_DX8_ECHO, "echo") +ADD_ENUM(BASS_FX_DX8_FLANGER, "flanger") +ADD_ENUM(BASS_FX_DX8_GARGLE, "gargle") +ADD_ENUM(BASS_FX_DX8_I3DL2REVERB, "i3dl2reverb") +ADD_ENUM(BASS_FX_DX8_PARAMEQ, "parameq") +ADD_ENUM(BASS_FX_DX8_REVERB, "reverb") +IMPLEMENT_ENUM_END("soundeffect-type") + +IMPLEMENT_ENUM_CLASS_BEGIN(eSoundEffectParams::Chorus) +ADD_ENUM(eSoundEffectParams::Chorus::WET_DRY_MIX, "wetDryMix") +ADD_ENUM(eSoundEffectParams::Chorus::DEPTH, "depth") +ADD_ENUM(eSoundEffectParams::Chorus::FEEDBACK, "feedback") +ADD_ENUM(eSoundEffectParams::Chorus::FREQUENCY, "frequency") +ADD_ENUM(eSoundEffectParams::Chorus::WAVEFORM, "waveform") +ADD_ENUM(eSoundEffectParams::Chorus::DELAY, "delay") +ADD_ENUM(eSoundEffectParams::Chorus::PHASE, "phase") +IMPLEMENT_ENUM_CLASS_END("soundeffect-params-chorus") + +IMPLEMENT_ENUM_CLASS_BEGIN(eSoundEffectParams::Compressor) +ADD_ENUM(eSoundEffectParams::Compressor::GAIN, "gain") +ADD_ENUM(eSoundEffectParams::Compressor::ATTACK, "attack") +ADD_ENUM(eSoundEffectParams::Compressor::RELEASE, "release") +ADD_ENUM(eSoundEffectParams::Compressor::THRESHOLD, "threshold") +ADD_ENUM(eSoundEffectParams::Compressor::RATIO, "ratio") +ADD_ENUM(eSoundEffectParams::Compressor::PREDELAY, "predelay") +IMPLEMENT_ENUM_CLASS_END("soundeffect-params-compressor") + +IMPLEMENT_ENUM_CLASS_BEGIN(eSoundEffectParams::Distortion) +ADD_ENUM(eSoundEffectParams::Distortion::GAIN, "gain") +ADD_ENUM(eSoundEffectParams::Distortion::EDGE, "edge") +ADD_ENUM(eSoundEffectParams::Distortion::POST_EQ_CENTER_FREQUENCY, "postEQCenterFrequency") +ADD_ENUM(eSoundEffectParams::Distortion::POST_EQ_BANDWIDTH, "postEQBandwidth") +ADD_ENUM(eSoundEffectParams::Distortion::PRE_LOWPASS_CUTOFF, "preLowpassCutoff") +IMPLEMENT_ENUM_CLASS_END("soundeffect-params-distortion") + +IMPLEMENT_ENUM_CLASS_BEGIN(eSoundEffectParams::Echo) +ADD_ENUM(eSoundEffectParams::Echo::WET_DRY_MIX, "wetDryMix") +ADD_ENUM(eSoundEffectParams::Echo::FEEDBACK, "feedback") +ADD_ENUM(eSoundEffectParams::Echo::LEFT_DELAY, "leftDelay") +ADD_ENUM(eSoundEffectParams::Echo::RIGHT_DELAY, "rightDelay") +ADD_ENUM(eSoundEffectParams::Echo::PAN_DELAY, "panDelay") +IMPLEMENT_ENUM_CLASS_END("soundeffect-params-echo") + +IMPLEMENT_ENUM_CLASS_BEGIN(eSoundEffectParams::Flanger) +ADD_ENUM(eSoundEffectParams::Flanger::WET_DRY_MIX, "wetDryMix") +ADD_ENUM(eSoundEffectParams::Flanger::DEPTH, "depth") +ADD_ENUM(eSoundEffectParams::Flanger::FEEDBACK, "feedback") +ADD_ENUM(eSoundEffectParams::Flanger::FREQUENCY, "frequency") +ADD_ENUM(eSoundEffectParams::Flanger::WAVEFORM, "waveform") +ADD_ENUM(eSoundEffectParams::Flanger::DELAY, "delay") +ADD_ENUM(eSoundEffectParams::Flanger::PHASE, "phase") +IMPLEMENT_ENUM_CLASS_END("soundeffect-params-flanger") + +IMPLEMENT_ENUM_CLASS_BEGIN(eSoundEffectParams::Gargle) +ADD_ENUM(eSoundEffectParams::Gargle::RATE_HZ, "rateHz") +ADD_ENUM(eSoundEffectParams::Gargle::WAVE_SHAPE, "waveShape") +IMPLEMENT_ENUM_CLASS_END("soundeffect-params-gargle") + +IMPLEMENT_ENUM_CLASS_BEGIN(eSoundEffectParams::I3DL2Reverb) +ADD_ENUM(eSoundEffectParams::I3DL2Reverb::ROOM, "room") +ADD_ENUM(eSoundEffectParams::I3DL2Reverb::ROOM_HF, "roomHF") +ADD_ENUM(eSoundEffectParams::I3DL2Reverb::ROOM_ROLLOFF_FACTOR, "roomRolloffFactor") +ADD_ENUM(eSoundEffectParams::I3DL2Reverb::DECAY_TIME, "decayTime") +ADD_ENUM(eSoundEffectParams::I3DL2Reverb::DECAY_HF_RATIO, "decayHFRatio") +ADD_ENUM(eSoundEffectParams::I3DL2Reverb::REFLECTIONS, "reflections") +ADD_ENUM(eSoundEffectParams::I3DL2Reverb::REFLECTIONS_DELAY, "reflectionsDelay") +ADD_ENUM(eSoundEffectParams::I3DL2Reverb::REVERB, "reverb") +ADD_ENUM(eSoundEffectParams::I3DL2Reverb::REVERB_DELAY, "reverbDelay") +ADD_ENUM(eSoundEffectParams::I3DL2Reverb::DIFFUSION, "diffusion") +ADD_ENUM(eSoundEffectParams::I3DL2Reverb::DENSITY, "density") +ADD_ENUM(eSoundEffectParams::I3DL2Reverb::HF_REFERENCE, "HFReference") +IMPLEMENT_ENUM_CLASS_END("soundeffect-params-i3dl2reverb") + +IMPLEMENT_ENUM_CLASS_BEGIN(eSoundEffectParams::ParamEq) +ADD_ENUM(eSoundEffectParams::ParamEq::CENTER, "center") +ADD_ENUM(eSoundEffectParams::ParamEq::BANDWIDTH, "bandwidth") +ADD_ENUM(eSoundEffectParams::ParamEq::GAIN, "gain") +IMPLEMENT_ENUM_CLASS_END("soundeffect-params-parameq") + +IMPLEMENT_ENUM_CLASS_BEGIN(eSoundEffectParams::Reverb) +ADD_ENUM(eSoundEffectParams::Reverb::IN_GAIN, "inGain") +ADD_ENUM(eSoundEffectParams::Reverb::REVERB_MIX, "reverbMix") +ADD_ENUM(eSoundEffectParams::Reverb::REVERB_TIME, "reverbTime") +ADD_ENUM(eSoundEffectParams::Reverb::HIGH_FREQ_RT_RATIO, "highFreqRTRatio") +IMPLEMENT_ENUM_CLASS_END("soundeffect-params-reverb") + // // Get best guess at name of userdata type // diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h index 4a1fba0f7ca..a83faf4b597 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -66,6 +66,16 @@ DECLARE_ENUM(eSurfaceWheelEffect); DECLARE_ENUM(eSurfaceSkidMarkType); DECLARE_ENUM(eSurfaceAdhesionGroup); DECLARE_ENUM_CLASS(eClientModelType); +DECLARE_ENUM(eSoundEffectType); +DECLARE_ENUM_CLASS(eSoundEffectParams::Chorus); +DECLARE_ENUM_CLASS(eSoundEffectParams::Compressor); +DECLARE_ENUM_CLASS(eSoundEffectParams::Distortion); +DECLARE_ENUM_CLASS(eSoundEffectParams::Echo); +DECLARE_ENUM_CLASS(eSoundEffectParams::Flanger); +DECLARE_ENUM_CLASS(eSoundEffectParams::Gargle); +DECLARE_ENUM_CLASS(eSoundEffectParams::I3DL2Reverb); +DECLARE_ENUM_CLASS(eSoundEffectParams::ParamEq); +DECLARE_ENUM_CLASS(eSoundEffectParams::Reverb); class CRemoteCall; @@ -455,6 +465,46 @@ inline SString GetClassByTypeName(eObjectGroup::BreakMode*) { return "objectgroup-breakmode"; } +inline SString GetClassTypeName(eSoundEffectType*) +{ + return "soundeffect-type"; +} +inline SString GetClassTypeName(eSoundEffectParams::Chorus*) +{ + return "soundeffect-params-chorus"; +} +inline SString GetClassTypeName(eSoundEffectParams::Compressor*) +{ + return "soundeffect-params-compressor"; +} +inline SString GetClassTypeName(eSoundEffectParams::Distortion*) +{ + return "soundeffect-params-distortion"; +} +inline SString GetClassTypeName(eSoundEffectParams::Echo*) +{ + return "soundeffect-params-echo"; +} +inline SString GetClassTypeName(eSoundEffectParams::Flanger*) +{ + return "soundeffect-params-flanger"; +} +inline SString GetClassTypeName(eSoundEffectParams::Gargle*) +{ + return "soundeffect-params-gargle"; +} +inline SString GetClassTypeName(eSoundEffectParams::I3DL2Reverb*) +{ + return "soundeffect-params-i3dl2reverb"; +} +inline SString GetClassTypeName(eSoundEffectParams::ParamEq*) +{ + return "soundeffect-params-parameq"; +} +inline SString GetClassTypeName(eSoundEffectParams::Reverb*) +{ + return "soundeffect-params-reverb"; +} inline SString GetClassByTypeName(eClientModelType) { diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp index 9e1c5c4312e..bfe0f515b57 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp @@ -58,6 +58,8 @@ void CLuaAudioDefs::LoadFunctions() {"getSoundMetaTags", GetSoundMetaTags}, {"setSoundEffectEnabled", SetSoundEffectEnabled}, {"getSoundEffects", GetSoundEffects}, + {"setSoundEffectParameter", SetSoundEffectParameter}, + {"getSoundEffectParameters", GetSoundEffectParameters}, {"setSoundPan", SetSoundPan}, {"getSoundPan", GetSoundPan}, @@ -87,6 +89,7 @@ void CLuaAudioDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "isPaused", "isSoundPaused"); lua_classfunction(luaVM, "setEffectEnabled", "setSoundEffectEnabled"); + lua_classfunction(luaVM, "setEffectParameter", "setSoundEffectParameter"); lua_classfunction(luaVM, "setPlaybackPosition", "setSoundPosition"); lua_classfunction(luaVM, "setSpeed", "setSoundSpeed"); lua_classfunction(luaVM, "setVolume", "setSoundVolume"); @@ -105,6 +108,7 @@ void CLuaAudioDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "getWaveData", "getSoundWaveData"); lua_classfunction(luaVM, "getLevelData", "getSoundLevelData"); lua_classfunction(luaVM, "getEffects", "getSoundEffects"); + lua_classfunction(luaVM, "getEffectParameters", "getSoundEffectParameters"); lua_classfunction(luaVM, "getPlaybackPosition", "getSoundPosition"); lua_classfunction(luaVM, "getSpeed", "getSoundSpeed"); lua_classfunction(luaVM, "getVolume", "getSoundVolume"); @@ -429,7 +433,7 @@ int CLuaAudioDefs::GetSoundLength(lua_State* luaVM) int CLuaAudioDefs::GetSoundBufferLength(lua_State* luaVM) { - CClientSound* pSound; + CClientSound* pSound; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pSound); @@ -1389,6 +1393,747 @@ int CLuaAudioDefs::GetSoundEffects(lua_State* luaVM) return 1; } +int CLuaAudioDefs::SetSoundEffectParameter(lua_State* luaVM) +{ + // bool setSoundEffectParameter ( sound sound, string effectName, string effectParameter, var effectParameterValue ) + CClientSound* pSound = nullptr; + eSoundEffectType eEffectType; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(pSound); + argStream.ReadEnumString(eEffectType); + + if (argStream.HasErrors()) + return luaL_error(luaVM, argStream.GetFullErrorMessage()); + + if (pSound->IsFxEffectEnabled(eEffectType)) + { + using namespace eSoundEffectParams; + switch (eEffectType) + { + case BASS_FX_DX8_CHORUS: + { + BASS_DX8_CHORUS params; + pSound->GetFxEffectParameters(eEffectType, ¶ms); + + Chorus eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) + { + case Chorus::WET_DRY_MIX: + { + argStream.ReadNumber(params.fWetDryMix); + break; + } + case Chorus::DEPTH: + { + argStream.ReadNumber(params.fDepth); + break; + } + case Chorus::FEEDBACK: + { + argStream.ReadNumber(params.fFeedback); + break; + } + case Chorus::FREQUENCY: + { + argStream.ReadNumber(params.fFrequency); + break; + } + case Chorus::WAVEFORM: + { + argStream.ReadNumber(params.lWaveform); + break; + } + case Chorus::DELAY: + { + argStream.ReadNumber(params.fDelay); + break; + } + case Chorus::PHASE: + { + argStream.ReadNumber(params.lPhase); + break; + } + } + + if (argStream.HasErrors()) + break; + + if (pSound->SetFxEffectParameters(eEffectType, ¶ms)) + { + lua_pushboolean(luaVM, true); + return 1; + } + break; + } + case BASS_FX_DX8_COMPRESSOR: + { + BASS_DX8_COMPRESSOR params; + pSound->GetFxEffectParameters(eEffectType, ¶ms); + + Compressor eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) + { + case Compressor::GAIN: + { + argStream.ReadNumber(params.fGain); + break; + } + case Compressor::ATTACK: + { + argStream.ReadNumber(params.fAttack); + break; + } + case Compressor::RELEASE: + { + argStream.ReadNumber(params.fRelease); + break; + } + case Compressor::THRESHOLD: + { + argStream.ReadNumber(params.fThreshold); + break; + } + case Compressor::RATIO: + { + argStream.ReadNumber(params.fRatio); + break; + } + case Compressor::PREDELAY: + { + argStream.ReadNumber(params.fPredelay); + break; + } + } + + if (argStream.HasErrors()) + break; + + if (pSound->SetFxEffectParameters(eEffectType, ¶ms)) + { + lua_pushboolean(luaVM, true); + return 1; + } + break; + } + case BASS_FX_DX8_DISTORTION: + { + BASS_DX8_DISTORTION params; + pSound->GetFxEffectParameters(eEffectType, ¶ms); + + Distortion eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) + { + case Distortion::GAIN: + { + argStream.ReadNumber(params.fGain); + break; + } + case Distortion::EDGE: + { + argStream.ReadNumber(params.fEdge); + break; + } + case Distortion::POST_EQ_CENTER_FREQUENCY: + { + argStream.ReadNumber(params.fPostEQCenterFrequency); + break; + } + case Distortion::POST_EQ_BANDWIDTH: + { + argStream.ReadNumber(params.fPostEQBandwidth); + break; + } + case Distortion::PRE_LOWPASS_CUTOFF: + { + argStream.ReadNumber(params.fPreLowpassCutoff); + break; + } + } + + if (argStream.HasErrors()) + break; + + if (pSound->SetFxEffectParameters(eEffectType, ¶ms)) + { + lua_pushboolean(luaVM, true); + return 1; + } + break; + } + case BASS_FX_DX8_ECHO: + { + BASS_DX8_ECHO params; + pSound->GetFxEffectParameters(eEffectType, ¶ms); + + Echo eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) + { + case Echo::WET_DRY_MIX: + { + argStream.ReadNumber(params.fWetDryMix); + break; + } + case Echo::FEEDBACK: + { + argStream.ReadNumber(params.fFeedback); + break; + } + case Echo::LEFT_DELAY: + { + argStream.ReadNumber(params.fLeftDelay); + break; + } + case Echo::RIGHT_DELAY: + { + argStream.ReadNumber(params.fRightDelay); + break; + } + case Echo::PAN_DELAY: + { + bool bPanDelay; + argStream.ReadBool(bPanDelay); + params.lPanDelay = bPanDelay; + break; + } + } + + if (argStream.HasErrors()) + break; + + if (pSound->SetFxEffectParameters(eEffectType, ¶ms)) + { + lua_pushboolean(luaVM, true); + return 1; + } + break; + } + case BASS_FX_DX8_FLANGER: + { + BASS_DX8_FLANGER params; + pSound->GetFxEffectParameters(eEffectType, ¶ms); + + Flanger eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) + { + case Flanger::WET_DRY_MIX: + { + argStream.ReadNumber(params.fWetDryMix); + break; + } + case Flanger::DEPTH: + { + argStream.ReadNumber(params.fDepth); + break; + } + case Flanger::FEEDBACK: + { + argStream.ReadNumber(params.fFeedback); + break; + } + case Flanger::FREQUENCY: + { + argStream.ReadNumber(params.fFrequency); + break; + } + case Flanger::WAVEFORM: + { + argStream.ReadNumber(params.lWaveform); + break; + } + case Flanger::DELAY: + { + argStream.ReadNumber(params.fDelay); + break; + } + case Flanger::PHASE: + { + argStream.ReadNumber(params.lPhase); + break; + } + } + + if (argStream.HasErrors()) + break; + + if (pSound->SetFxEffectParameters(eEffectType, ¶ms)) + { + lua_pushboolean(luaVM, true); + return 1; + } + break; + } + case BASS_FX_DX8_GARGLE: + { + BASS_DX8_GARGLE params; + pSound->GetFxEffectParameters(eEffectType, ¶ms); + + Gargle eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) + { + case Gargle::RATE_HZ: + { + argStream.ReadNumber(params.dwRateHz); + break; + } + case Gargle::WAVE_SHAPE: + { + argStream.ReadNumber(params.dwWaveShape); + break; + } + } + + if (argStream.HasErrors()) + break; + + if (pSound->SetFxEffectParameters(eEffectType, ¶ms)) + { + lua_pushboolean(luaVM, true); + return 1; + } + break; + } + case BASS_FX_DX8_I3DL2REVERB: + { + BASS_DX8_I3DL2REVERB params; + pSound->GetFxEffectParameters(eEffectType, ¶ms); + + I3DL2Reverb eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) + { + case I3DL2Reverb::ROOM: + { + argStream.ReadNumber(params.lRoom); + break; + } + case I3DL2Reverb::ROOM_HF: + { + argStream.ReadNumber(params.lRoomHF); + break; + } + case I3DL2Reverb::ROOM_ROLLOFF_FACTOR: + { + argStream.ReadNumber(params.flRoomRolloffFactor); + break; + } + case I3DL2Reverb::DECAY_TIME: + { + argStream.ReadNumber(params.flDecayTime); + break; + } + case I3DL2Reverb::DECAY_HF_RATIO: + { + argStream.ReadNumber(params.flDecayHFRatio); + break; + } + case I3DL2Reverb::REFLECTIONS: + { + argStream.ReadNumber(params.lReflections); + break; + } + case I3DL2Reverb::REFLECTIONS_DELAY: + { + argStream.ReadNumber(params.flReflectionsDelay); + break; + } + case I3DL2Reverb::REVERB: + { + argStream.ReadNumber(params.lReverb); + break; + } + case I3DL2Reverb::REVERB_DELAY: + { + argStream.ReadNumber(params.flReverbDelay); + break; + } + case I3DL2Reverb::DIFFUSION: + { + argStream.ReadNumber(params.flDiffusion); + break; + } + case I3DL2Reverb::DENSITY: + { + argStream.ReadNumber(params.flDensity); + break; + } + case I3DL2Reverb::HF_REFERENCE: + { + argStream.ReadNumber(params.flHFReference); + break; + } + } + + if (argStream.HasErrors()) + break; + + if (pSound->SetFxEffectParameters(eEffectType, ¶ms)) + { + lua_pushboolean(luaVM, true); + return 1; + } + break; + } + case BASS_FX_DX8_PARAMEQ: + { + BASS_DX8_PARAMEQ params; + pSound->GetFxEffectParameters(eEffectType, ¶ms); + + ParamEq eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) + { + case ParamEq::CENTER: + { + argStream.ReadNumber(params.fCenter); + break; + } + case ParamEq::BANDWIDTH: + { + argStream.ReadNumber(params.fBandwidth); + break; + } + case ParamEq::GAIN: + { + argStream.ReadNumber(params.fGain); + break; + } + } + + if (argStream.HasErrors()) + break; + + if (pSound->SetFxEffectParameters(eEffectType, ¶ms)) + { + lua_pushboolean(luaVM, true); + return 1; + } + break; + } + case BASS_FX_DX8_REVERB: + { + BASS_DX8_REVERB params; + pSound->GetFxEffectParameters(eEffectType, ¶ms); + + Reverb eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) + { + case Reverb::IN_GAIN: + { + argStream.ReadNumber(params.fInGain); + break; + } + case Reverb::REVERB_MIX: + { + argStream.ReadNumber(params.fReverbMix); + break; + } + case Reverb::REVERB_TIME: + { + argStream.ReadNumber(params.fReverbTime); + break; + } + case Reverb::HIGH_FREQ_RT_RATIO: + { + argStream.ReadNumber(params.fHighFreqRTRatio); + break; + } + } + + if (argStream.HasErrors()) + break; + + if (pSound->SetFxEffectParameters(eEffectType, ¶ms)) + { + lua_pushboolean(luaVM, true); + return 1; + } + break; + } + } + + return luaL_error(luaVM, argStream.GetFullErrorMessage()); + } + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaAudioDefs::GetSoundEffectParameters(lua_State* luaVM) +{ + // table getSoundEffectParameters ( sound sound, string effectName ) + CClientSound* pSound = nullptr; + eSoundEffectType eEffectType; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(pSound); + argStream.ReadEnumString(eEffectType); + + if (argStream.HasErrors()) + return luaL_error(luaVM, argStream.GetFullErrorMessage()); + + if (pSound->IsFxEffectEnabled(eEffectType)) + { + using namespace eSoundEffectParams; + switch (eEffectType) + { + case BASS_FX_DX8_CHORUS: + { + BASS_DX8_CHORUS fxChorusParams; + if (pSound->GetFxEffectParameters(eEffectType, &fxChorusParams)) + { + lua_createtable(luaVM, 0, 7); + + lua_pushnumber(luaVM, fxChorusParams.fWetDryMix); + lua_setfield(luaVM, -2, EnumToString(Chorus::WET_DRY_MIX)); + + lua_pushnumber(luaVM, fxChorusParams.fDepth); + lua_setfield(luaVM, -2, EnumToString(Chorus::DEPTH)); + + lua_pushnumber(luaVM, fxChorusParams.fFeedback); + lua_setfield(luaVM, -2, EnumToString(Chorus::FEEDBACK)); + + lua_pushnumber(luaVM, fxChorusParams.fFrequency); + lua_setfield(luaVM, -2, EnumToString(Chorus::FREQUENCY)); + + lua_pushnumber(luaVM, fxChorusParams.lWaveform); + lua_setfield(luaVM, -2, EnumToString(Chorus::WAVEFORM)); + + lua_pushnumber(luaVM, fxChorusParams.fDelay); + lua_setfield(luaVM, -2, EnumToString(Chorus::DELAY)); + + lua_pushnumber(luaVM, fxChorusParams.lPhase); + lua_setfield(luaVM, -2, EnumToString(Chorus::PHASE)); + return 1; + } + break; + } + case BASS_FX_DX8_COMPRESSOR: + { + BASS_DX8_COMPRESSOR fxCompressorParams; + if (pSound->GetFxEffectParameters(eEffectType, &fxCompressorParams)) + { + lua_createtable(luaVM, 0, 6); + + lua_pushnumber(luaVM, fxCompressorParams.fGain); + lua_setfield(luaVM, -2, EnumToString(Compressor::GAIN)); + + lua_pushnumber(luaVM, fxCompressorParams.fAttack); + lua_setfield(luaVM, -2, EnumToString(Compressor::ATTACK)); + + lua_pushnumber(luaVM, fxCompressorParams.fRelease); + lua_setfield(luaVM, -2, EnumToString(Compressor::RELEASE)); + + lua_pushnumber(luaVM, fxCompressorParams.fThreshold); + lua_setfield(luaVM, -2, EnumToString(Compressor::THRESHOLD)); + + lua_pushnumber(luaVM, fxCompressorParams.fRatio); + lua_setfield(luaVM, -2, EnumToString(Compressor::RATIO)); + + lua_pushnumber(luaVM, fxCompressorParams.fPredelay); + lua_setfield(luaVM, -2, EnumToString(Compressor::PREDELAY)); + return 1; + } + break; + } + case BASS_FX_DX8_DISTORTION: + { + BASS_DX8_DISTORTION fxDistortionParams; + if (pSound->GetFxEffectParameters(eEffectType, &fxDistortionParams)) + { + lua_createtable(luaVM, 0, 5); + + lua_pushnumber(luaVM, fxDistortionParams.fGain); + lua_setfield(luaVM, -2, EnumToString(Distortion::GAIN)); + + lua_pushnumber(luaVM, fxDistortionParams.fEdge); + lua_setfield(luaVM, -2, EnumToString(Distortion::EDGE)); + + lua_pushnumber(luaVM, fxDistortionParams.fPostEQCenterFrequency); + lua_setfield(luaVM, -2, EnumToString(Distortion::POST_EQ_CENTER_FREQUENCY)); + + lua_pushnumber(luaVM, fxDistortionParams.fPostEQBandwidth); + lua_setfield(luaVM, -2, EnumToString(Distortion::POST_EQ_BANDWIDTH)); + + lua_pushnumber(luaVM, fxDistortionParams.fPreLowpassCutoff); + lua_setfield(luaVM, -2, EnumToString(Distortion::PRE_LOWPASS_CUTOFF)); + return 1; + } + break; + } + case BASS_FX_DX8_ECHO: + { + BASS_DX8_ECHO fxEchoParams; + if (pSound->GetFxEffectParameters(eEffectType, &fxEchoParams)) + { + lua_createtable(luaVM, 0, 5); + + lua_pushnumber(luaVM, fxEchoParams.fWetDryMix); + lua_setfield(luaVM, -2, EnumToString(Echo::WET_DRY_MIX)); + + lua_pushnumber(luaVM, fxEchoParams.fFeedback); + lua_setfield(luaVM, -2, EnumToString(Echo::FEEDBACK)); + + lua_pushnumber(luaVM, fxEchoParams.fLeftDelay); + lua_setfield(luaVM, -2, EnumToString(Echo::LEFT_DELAY)); + + lua_pushnumber(luaVM, fxEchoParams.fRightDelay); + lua_setfield(luaVM, -2, EnumToString(Echo::RIGHT_DELAY)); + + lua_pushboolean(luaVM, fxEchoParams.lPanDelay); + lua_setfield(luaVM, -2, EnumToString(Echo::PAN_DELAY)); + return 1; + } + break; + } + case BASS_FX_DX8_FLANGER: + { + BASS_DX8_FLANGER fxFlangerParams; + if (pSound->GetFxEffectParameters(eEffectType, &fxFlangerParams)) + { + lua_createtable(luaVM, 0, 7); + + lua_pushnumber(luaVM, fxFlangerParams.fWetDryMix); + lua_setfield(luaVM, -2, EnumToString(Flanger::WET_DRY_MIX)); + + lua_pushnumber(luaVM, fxFlangerParams.fDepth); + lua_setfield(luaVM, -2, EnumToString(Flanger::DEPTH)); + + lua_pushnumber(luaVM, fxFlangerParams.fFeedback); + lua_setfield(luaVM, -2, EnumToString(Flanger::FEEDBACK)); + + lua_pushnumber(luaVM, fxFlangerParams.fFrequency); + lua_setfield(luaVM, -2, EnumToString(Flanger::FREQUENCY)); + + lua_pushnumber(luaVM, fxFlangerParams.lWaveform); + lua_setfield(luaVM, -2, EnumToString(Flanger::WAVEFORM)); + + lua_pushnumber(luaVM, fxFlangerParams.fDelay); + lua_setfield(luaVM, -2, EnumToString(Flanger::DELAY)); + + lua_pushnumber(luaVM, fxFlangerParams.lPhase); + lua_setfield(luaVM, -2, EnumToString(Flanger::PHASE)); + return 1; + } + break; + } + case BASS_FX_DX8_GARGLE: + { + BASS_DX8_GARGLE fxGargleParams; + if (pSound->GetFxEffectParameters(eEffectType, &fxGargleParams)) + { + lua_createtable(luaVM, 0, 2); + + lua_pushnumber(luaVM, fxGargleParams.dwRateHz); + lua_setfield(luaVM, -2, EnumToString(Gargle::RATE_HZ)); + + lua_pushnumber(luaVM, fxGargleParams.dwWaveShape); + lua_setfield(luaVM, -2, EnumToString(Gargle::WAVE_SHAPE)); + return 1; + } + break; + } + case BASS_FX_DX8_I3DL2REVERB: + { + BASS_DX8_I3DL2REVERB fxI3DL2ReverbParams; + if (pSound->GetFxEffectParameters(eEffectType, &fxI3DL2ReverbParams)) + { + lua_createtable(luaVM, 0, 12); + + lua_pushnumber(luaVM, fxI3DL2ReverbParams.lRoom); + lua_setfield(luaVM, -2, EnumToString(I3DL2Reverb::ROOM)); + + lua_pushnumber(luaVM, fxI3DL2ReverbParams.lRoomHF); + lua_setfield(luaVM, -2, EnumToString(I3DL2Reverb::ROOM_HF)); + + lua_pushnumber(luaVM, fxI3DL2ReverbParams.flRoomRolloffFactor); + lua_setfield(luaVM, -2, EnumToString(I3DL2Reverb::ROOM_ROLLOFF_FACTOR)); + + lua_pushnumber(luaVM, fxI3DL2ReverbParams.flDecayTime); + lua_setfield(luaVM, -2, EnumToString(I3DL2Reverb::DECAY_TIME)); + + lua_pushnumber(luaVM, fxI3DL2ReverbParams.flDecayHFRatio); + lua_setfield(luaVM, -2, EnumToString(I3DL2Reverb::DECAY_HF_RATIO)); + + lua_pushnumber(luaVM, fxI3DL2ReverbParams.lReflections); + lua_setfield(luaVM, -2, EnumToString(I3DL2Reverb::REFLECTIONS)); + + lua_pushnumber(luaVM, fxI3DL2ReverbParams.flReflectionsDelay); + lua_setfield(luaVM, -2, EnumToString(I3DL2Reverb::REFLECTIONS_DELAY)); + + lua_pushnumber(luaVM, fxI3DL2ReverbParams.lReverb); + lua_setfield(luaVM, -2, EnumToString(I3DL2Reverb::REVERB)); + + lua_pushnumber(luaVM, fxI3DL2ReverbParams.flReverbDelay); + lua_setfield(luaVM, -2, EnumToString(I3DL2Reverb::REVERB_DELAY)); + + lua_pushnumber(luaVM, fxI3DL2ReverbParams.flDiffusion); + lua_setfield(luaVM, -2, EnumToString(I3DL2Reverb::DIFFUSION)); + + lua_pushnumber(luaVM, fxI3DL2ReverbParams.flDensity); + lua_setfield(luaVM, -2, EnumToString(I3DL2Reverb::DENSITY)); + + lua_pushnumber(luaVM, fxI3DL2ReverbParams.flHFReference); + lua_setfield(luaVM, -2, EnumToString(I3DL2Reverb::HF_REFERENCE)); + return 1; + } + break; + } + case BASS_FX_DX8_PARAMEQ: + { + BASS_DX8_PARAMEQ fxParameqParams; + if (pSound->GetFxEffectParameters(eEffectType, &fxParameqParams)) + { + lua_createtable(luaVM, 0, 3); + + lua_pushnumber(luaVM, fxParameqParams.fCenter); + lua_setfield(luaVM, -2, EnumToString(ParamEq::CENTER)); + + lua_pushnumber(luaVM, fxParameqParams.fBandwidth); + lua_setfield(luaVM, -2, EnumToString(ParamEq::BANDWIDTH)); + + lua_pushnumber(luaVM, fxParameqParams.fGain); + lua_setfield(luaVM, -2, EnumToString(ParamEq::GAIN)); + return 1; + } + break; + } + case BASS_FX_DX8_REVERB: + { + BASS_DX8_REVERB fxReverbParams; + if (pSound->GetFxEffectParameters(eEffectType, &fxReverbParams)) + { + lua_createtable(luaVM, 0, 4); + + lua_pushnumber(luaVM, fxReverbParams.fInGain); + lua_setfield(luaVM, -2, EnumToString(Reverb::IN_GAIN)); + + lua_pushnumber(luaVM, fxReverbParams.fReverbMix); + lua_setfield(luaVM, -2, EnumToString(Reverb::REVERB_MIX)); + + lua_pushnumber(luaVM, fxReverbParams.fReverbTime); + lua_setfield(luaVM, -2, EnumToString(Reverb::REVERB_TIME)); + + lua_pushnumber(luaVM, fxReverbParams.fHighFreqRTRatio); + lua_setfield(luaVM, -2, EnumToString(Reverb::HIGH_FREQ_RT_RATIO)); + return 1; + } + break; + } + } + } + + lua_pushboolean(luaVM, false); + return 1; +} + int CLuaAudioDefs::PlaySoundFrontEnd(lua_State* luaVM) { CClientSound* pSound = NULL; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.h index d49d3bfe056..57ad6929db9 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.h @@ -59,6 +59,8 @@ class CLuaAudioDefs : public CLuaDefs LUA_DECLARE(GetSoundMetaTags); LUA_DECLARE(SetSoundEffectEnabled); LUA_DECLARE(GetSoundEffects); + LUA_DECLARE(SetSoundEffectParameter); + LUA_DECLARE(GetSoundEffectParameters); LUA_DECLARE(SetSoundPan); LUA_DECLARE(GetSoundPan); diff --git a/Client/sdk/game/Common.h b/Client/sdk/game/Common.h index 5b3051fac4e..740ffd716d3 100644 --- a/Client/sdk/game/Common.h +++ b/Client/sdk/game/Common.h @@ -1637,3 +1637,95 @@ namespace eObjectGroup SMASHABLE, }; } + +enum eSoundEffectType; + +namespace eSoundEffectParams +{ + enum class Chorus + { + WET_DRY_MIX, + DEPTH, + FEEDBACK, + FREQUENCY, + WAVEFORM, + DELAY, + PHASE, + }; + + enum class Compressor + { + GAIN, + ATTACK, + RELEASE, + THRESHOLD, + RATIO, + PREDELAY, + }; + + enum class Distortion + { + GAIN, + EDGE, + POST_EQ_CENTER_FREQUENCY, + POST_EQ_BANDWIDTH, + PRE_LOWPASS_CUTOFF, + }; + + enum class Echo + { + WET_DRY_MIX, + FEEDBACK, + LEFT_DELAY, + RIGHT_DELAY, + PAN_DELAY, + }; + + enum class Flanger + { + WET_DRY_MIX, + DEPTH, + FEEDBACK, + FREQUENCY, + WAVEFORM, + DELAY, + PHASE, + }; + + enum class Gargle + { + RATE_HZ, + WAVE_SHAPE, + }; + + enum class I3DL2Reverb + { + ROOM, + ROOM_HF, + ROOM_ROLLOFF_FACTOR, + DECAY_TIME, + DECAY_HF_RATIO, + REFLECTIONS, + REFLECTIONS_DELAY, + REVERB, + REVERB_DELAY, + DIFFUSION, + DENSITY, + HF_REFERENCE, + }; + + enum class ParamEq + { + CENTER, + BANDWIDTH, + GAIN, + }; + + enum class Reverb + { + IN_GAIN, + REVERB_MIX, + REVERB_TIME, + HIGH_FREQ_RT_RATIO, + }; +}