1 /* 2 * I3DL2Reverb.h 3 * ------------- 4 * Purpose: Implementation of the DMO I3DL2Reverb DSP (for non-Windows platforms) 5 * Notes : (currently none) 6 * Authors: OpenMPT Devs 7 * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. 8 */ 9 10 11 #pragma once 12 13 #include "openmpt/all/BuildSettings.hpp" 14 15 #ifndef NO_PLUGINS 16 17 #include "../PlugInterface.h" 18 19 OPENMPT_NAMESPACE_BEGIN 20 21 namespace DMO 22 { 23 24 class I3DL2Reverb final : public IMixPlugin 25 { 26 protected: 27 enum Parameters 28 { 29 kI3DL2ReverbRoom = 0, 30 kI3DL2ReverbRoomHF, 31 kI3DL2ReverbRoomRolloffFactor, // Doesn't actually do anything :) 32 kI3DL2ReverbDecayTime, 33 kI3DL2ReverbDecayHFRatio, 34 kI3DL2ReverbReflections, 35 kI3DL2ReverbReflectionsDelay, 36 kI3DL2ReverbReverb, 37 kI3DL2ReverbReverbDelay, 38 kI3DL2ReverbDiffusion, 39 kI3DL2ReverbDensity, 40 kI3DL2ReverbHFReference, 41 kI3DL2ReverbQuality, 42 kI3DL2ReverbNumParameters 43 }; 44 45 enum QualityFlags 46 { 47 kMoreDelayLines = 0x01, 48 kFullSampleRate = 0x02, 49 }; 50 51 class DelayLine : private std::vector<float> 52 { 53 int32 m_length; 54 int32 m_position; 55 int32 m_delayPosition; 56 57 public: 58 void Init(int32 ms, int32 padding, uint32 sampleRate, int32 delayTap = 0); 59 void SetDelayTap(int32 delayTap); 60 void Advance(); 61 void Set(float value); 62 float Get(int32 offset) const; 63 float Get() const; 64 }; 65 66 float m_param[kI3DL2ReverbNumParameters]; 67 int32 m_program = 0; 68 69 // Calculated parameters 70 uint32 m_quality; 71 float m_effectiveSampleRate; 72 float m_diffusion; 73 float m_roomFilter; 74 float m_ERLevel; 75 float m_ReverbLevelL; 76 float m_ReverbLevelR; 77 78 int32 m_delayTaps[15]; // 6*L + 6*R + LR + Early L + Early R 79 int32 m_earlyTaps[2][6]; 80 float m_delayCoeffs[13][2]; 81 82 // State 83 DelayLine m_delayLines[19]; 84 float m_filterHist[19]; 85 86 // Remaining frame for downsampled reverb 87 float m_prevL; 88 float m_prevR; 89 bool m_remain = false; 90 91 bool m_ok = false, m_recalcParams = true; 92 93 public: 94 static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); 95 I3DL2Reverb(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); 96 Release()97 void Release() override { delete this; } GetUID()98 int32 GetUID() const override { return 0xEF985E71; } GetVersion()99 int32 GetVersion() const override { return 0; } Idle()100 void Idle() override { } GetLatency()101 uint32 GetLatency() const override { return 0; } 102 103 void Process(float *pOutL, float *pOutR, uint32 numFrames) override; 104 RenderSilence(uint32)105 float RenderSilence(uint32) override { return 0.0f; } 106 107 int32 GetNumPrograms() const override; GetCurrentProgram()108 int32 GetCurrentProgram() override { return m_program; } 109 // cppcheck-suppress virtualCallInConstructor 110 void SetCurrentProgram(int32) override; 111 GetNumParameters()112 PlugParamIndex GetNumParameters() const override { return kI3DL2ReverbNumParameters; } 113 PlugParamValue GetParameter(PlugParamIndex index) override; 114 void SetParameter(PlugParamIndex index, PlugParamValue value) override; 115 116 void Resume() override; Suspend()117 void Suspend() override { m_isResumed = false; } 118 void PositionChanged() override; IsInstrument()119 bool IsInstrument() const override { return false; } CanRecieveMidiEvents()120 bool CanRecieveMidiEvents() override { return false; } ShouldProcessSilence()121 bool ShouldProcessSilence() override { return true; } 122 123 #ifdef MODPLUG_TRACKER GetDefaultEffectName()124 CString GetDefaultEffectName() override { return _T("I3DL2Reverb"); } 125 126 CString GetParamName(PlugParamIndex param) override; 127 CString GetParamLabel(PlugParamIndex) override; 128 CString GetParamDisplay(PlugParamIndex param) override; 129 130 CString GetCurrentProgramName() override; SetCurrentProgramName(const CString &)131 void SetCurrentProgramName(const CString &) override { } 132 CString GetProgramName(int32 program) override; 133 HasEditor()134 bool HasEditor() const override { return false; } 135 #endif 136 BeginSetProgram(int32)137 void BeginSetProgram(int32) override { } EndSetProgram()138 void EndSetProgram() override { } 139 GetNumInputChannels()140 int GetNumInputChannels() const override { return 2; } GetNumOutputChannels()141 int GetNumOutputChannels() const override { return 2; } 142 143 protected: Room()144 float Room() const { return -10000.0f + m_param[kI3DL2ReverbRoom] * 10000.0f; } RoomHF()145 float RoomHF() const { return -10000.0f + m_param[kI3DL2ReverbRoomHF] * 10000.0f; } RoomRolloffFactor()146 float RoomRolloffFactor() const { return m_param[kI3DL2ReverbRoomRolloffFactor] * 10.0f; } DecayTime()147 float DecayTime() const { return 0.1f + m_param[kI3DL2ReverbDecayTime] * 19.9f; } DecayHFRatio()148 float DecayHFRatio() const { return 0.1f + m_param[kI3DL2ReverbDecayHFRatio] * 1.9f; } Reflections()149 float Reflections() const { return -10000.0f + m_param[kI3DL2ReverbReflections] * 11000.0f; } ReflectionsDelay()150 float ReflectionsDelay() const { return m_param[kI3DL2ReverbReflectionsDelay] * 0.3f; } Reverb()151 float Reverb() const { return -10000.0f + m_param[kI3DL2ReverbReverb] * 12000.0f; } ReverbDelay()152 float ReverbDelay() const { return m_param[kI3DL2ReverbReverbDelay] * 0.1f; } Diffusion()153 float Diffusion() const { return m_param[kI3DL2ReverbDiffusion] * 100.0f; } Density()154 float Density() const { return m_param[kI3DL2ReverbDensity] * 100.0f; } HFReference()155 float HFReference() const { return 20.0f + m_param[kI3DL2ReverbHFReference] * 19980.0f; } Quality()156 uint32 Quality() const { return mpt::saturate_round<uint32>(m_param[kI3DL2ReverbQuality] * 3.0f); } 157 158 void RecalculateI3DL2ReverbParams(); 159 160 void SetDelayTaps(); 161 void SetDecayCoeffs(); 162 float CalcDecayCoeffs(int32 index); 163 }; 164 165 } // namespace DMO 166 167 OPENMPT_NAMESPACE_END 168 169 #endif // !NO_PLUGINS 170