123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /*
- * Gargle.cpp
- * ----------
- * Purpose: Implementation of the DMO Gargle DSP (for non-Windows platforms)
- * Notes : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
- #include "stdafx.h"
- #ifndef NO_PLUGINS
- #include "../../Sndfile.h"
- #include "Gargle.h"
- #endif // !NO_PLUGINS
- OPENMPT_NAMESPACE_BEGIN
- #ifndef NO_PLUGINS
- namespace DMO
- {
- IMixPlugin* Gargle::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct)
- {
- return new (std::nothrow) Gargle(factory, sndFile, mixStruct);
- }
- Gargle::Gargle(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct)
- : IMixPlugin(factory, sndFile, mixStruct)
- {
- m_param[kGargleRate] = 0.02f;
- m_param[kGargleWaveShape] = 0.0f;
- m_mixBuffer.Initialize(2, 2);
- InsertIntoFactoryList();
- }
- void Gargle::Process(float *pOutL, float *pOutR, uint32 numFrames)
- {
- if(!m_mixBuffer.Ok())
- return;
- const float *inL = m_mixBuffer.GetInputBuffer(0), *inR = m_mixBuffer.GetInputBuffer(1);
- float *outL = m_mixBuffer.GetOutputBuffer(0), *outR = m_mixBuffer.GetOutputBuffer(1);
- const bool triangle = m_param[kGargleWaveShape] < 1.0f;
- for(uint32 frame = numFrames; frame != 0;)
- {
- if(m_counter < m_periodHalf)
- {
- // First half of gargle period
- const uint32 remain = std::min(frame, m_periodHalf - m_counter);
- if(triangle)
- {
- const uint32 stop = m_counter + remain;
- const float factor = 1.0f / m_periodHalf;
- for(uint32 i = m_counter; i < stop; i++)
- {
- *outL++ = *inL++ * i * factor;
- *outR++ = *inR++ * i * factor;
- }
- } else
- {
- for(uint32 i = 0; i < remain; i++)
- {
- *outL++ = *inL++;
- *outR++ = *inR++;
- }
- }
- frame -= remain;
- m_counter += remain;
- } else
- {
- // Second half of gargle period
- const uint32 remain = std::min(frame, m_period - m_counter);
- if(triangle)
- {
- const uint32 stop = m_period - m_counter - remain;
- const float factor = 1.0f / m_periodHalf;
- for(uint32 i = m_period - m_counter; i > stop; i--)
- {
- *outL++ = *inL++ * i * factor;
- *outR++ = *inR++ * i * factor;
- }
- } else
- {
- for(uint32 i = 0; i < remain; i++)
- {
- *outL++ = 0;
- *outR++ = 0;
- }
- inL += remain;
- inR += remain;
- }
- frame -= remain;
- m_counter += remain;
- if(m_counter >= m_period) m_counter = 0;
- }
- }
- ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames);
- }
- PlugParamValue Gargle::GetParameter(PlugParamIndex index)
- {
- if(index < kGargleNumParameters)
- {
- return m_param[index];
- }
- return 0;
- }
- void Gargle::SetParameter(PlugParamIndex index, PlugParamValue value)
- {
- if(index < kGargleNumParameters)
- {
- value = mpt::safe_clamp(value, 0.0f, 1.0f);
- if(index == kGargleWaveShape)
- value = mpt::round(value);
- m_param[index] = value;
- RecalculateGargleParams();
- }
- }
- void Gargle::Resume()
- {
- RecalculateGargleParams();
- m_counter = 0;
- m_isResumed = true;
- }
- #ifdef MODPLUG_TRACKER
- CString Gargle::GetParamName(PlugParamIndex param)
- {
- switch(param)
- {
- case kGargleRate: return _T("Rate");
- case kGargleWaveShape: return _T("WaveShape");
- }
- return CString();
- }
- CString Gargle::GetParamLabel(PlugParamIndex param)
- {
- switch(param)
- {
- case kGargleRate: return _T("Hz");
- }
- return CString();
- }
- CString Gargle::GetParamDisplay(PlugParamIndex param)
- {
- CString s;
- switch(param)
- {
- case kGargleRate:
- s.Format(_T("%u"), RateInHertz());
- break;
- case kGargleWaveShape:
- return (m_param[param] < 0.5) ? _T("Triangle") : _T("Square");
- }
- return s;
- }
- #endif // MODPLUG_TRACKER
- uint32 Gargle::RateInHertz() const
- {
- return static_cast<uint32>(mpt::round(std::clamp(m_param[kGargleRate], 0.0f, 1.0f) * 999.0f)) + 1;
- }
- void Gargle::RecalculateGargleParams()
- {
- m_period = m_SndFile.GetSampleRate() / RateInHertz();
- if(m_period < 2) m_period = 2;
- m_periodHalf = m_period / 2;
- LimitMax(m_counter, m_period);
- }
- } // namespace DMO
- #else
- MPT_MSVC_WORKAROUND_LNK4221(Gargle)
- #endif // !NO_PLUGINS
- OPENMPT_NAMESPACE_END
|