154 lines
3.5 KiB
C++
154 lines
3.5 KiB
C++
#include "DistrhoPlugin.hpp"
|
|
#include "synth.h"
|
|
|
|
START_NAMESPACE_DISTRHO
|
|
|
|
class ShepPlug : public Plugin
|
|
{
|
|
public:
|
|
ShepPlug()
|
|
: Plugin(kParameterCount, 0, 0),
|
|
sampleRate(getSampleRate()),
|
|
synth(sampleRate),
|
|
fParameters { 0 }
|
|
{
|
|
}
|
|
|
|
protected:
|
|
const char* getLabel() const override { return "yaw-shep"; }
|
|
const char* getDescription() const override { return "Generalized Shepard tone, mouse UI"; }
|
|
const char* getMaker() const override { return "yaw-audio"; }
|
|
const char* getHomePage() const override { return "https://yaw.man/plugins/yaw-shep"; }
|
|
const char* getLicense() const override { return "Fuck You Pay Me"; }
|
|
uint32_t getVersion() const override { return d_version(1, 0, 0); }
|
|
int64_t getUniqueId() const override { return d_cconst('y', 's', 'p', 'm'); }
|
|
|
|
|
|
void initParameter(uint32_t index, Parameter& parameter) override
|
|
{
|
|
parameter.hints = kParameterIsAutomatable;
|
|
parameter.ranges.def = 0.0f;
|
|
parameter.ranges.min = 0.0f;
|
|
parameter.ranges.max = 1.0f;
|
|
|
|
switch (index)
|
|
{
|
|
case kHz:
|
|
parameter.name = "hz";
|
|
parameter.symbol = "hz";
|
|
parameter.hints = kParameterIsOutput;
|
|
parameter.ranges.def = 55.0f;
|
|
parameter.ranges.min = 55.0f;
|
|
parameter.ranges.max = 880.0f;
|
|
case kMouseX:
|
|
parameter.name = "x";
|
|
parameter.symbol = "x";
|
|
break;
|
|
case kMouseY:
|
|
parameter.name = "y";
|
|
parameter.symbol = "y";
|
|
break;
|
|
case kVolume:
|
|
parameter.name = "Volume";
|
|
parameter.symbol = "vol";
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sampleRateChanged(double newRate) override
|
|
{
|
|
synth.setSampleRate(sampleRate, newRate);
|
|
sampleRate = newRate;
|
|
}
|
|
|
|
float getParameterValue(uint32_t index) const override
|
|
{
|
|
return fParameters[index];
|
|
}
|
|
|
|
void setParameterValue(uint32_t idx, float val) override
|
|
{
|
|
fParameters[idx] = val;
|
|
switch (idx) {
|
|
case kMouseX:
|
|
synth.setPhaseVelocity(val);
|
|
break;
|
|
case kMouseY:
|
|
synth.setTone(val);
|
|
break;
|
|
case kVolume:
|
|
synth.setVolume(val);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void run(const float** inputs, float** outputs, uint32_t frames,
|
|
const MidiEvent* midiEvents, uint32_t midiEventCount) override
|
|
{
|
|
|
|
uint32_t currentFrame = 0;
|
|
if( midiEventCount > 1 )
|
|
{
|
|
currentFrame = 0;
|
|
}
|
|
|
|
for (uint32_t i = 0; i < midiEventCount; ++i)
|
|
{
|
|
if (midiEvents[i].size <= 3)
|
|
{
|
|
|
|
uint8_t status = midiEvents[i].data[0];
|
|
uint8_t data = midiEvents[i].data[1] & 127;
|
|
uint8_t velocity = midiEvents[i].data[2] & 127;
|
|
|
|
float vol = velocity / 127.0f;
|
|
|
|
switch (status & 0xf0)
|
|
{
|
|
//Controller change.
|
|
case 0xb0:
|
|
//Channel Volume.
|
|
if( data == 7 ) setParameterValue(kVolume, vol);
|
|
//Breath Control.
|
|
if( data == 2 ) setParameterValue(kVolume, vol);
|
|
break;
|
|
//Aftertouch.
|
|
case 0xd0:
|
|
setParameterValue(kVolume, vol);
|
|
break;
|
|
//Note On.
|
|
case 0x90:
|
|
synth.setNote(data);
|
|
/* fall through */
|
|
//Note Off.
|
|
case 0x80:
|
|
setParameterValue(kVolume, vol);
|
|
break;
|
|
|
|
}
|
|
|
|
synth.process(*outputs, midiEvents[i].frame - currentFrame);
|
|
currentFrame = midiEvents[i].frame;
|
|
}
|
|
}
|
|
|
|
synth.process(*outputs, frames - currentFrame);
|
|
fParameters[kHz] = synth.hzFund;
|
|
}
|
|
|
|
private:
|
|
float fParameters[kParameterCount];
|
|
double sampleRate;
|
|
bool parity = false;
|
|
|
|
Synth synth;
|
|
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ShepPlug)
|
|
};
|
|
|
|
Plugin* createPlugin()
|
|
{
|
|
return new ShepPlug();
|
|
}
|
|
|
|
END_NAMESPACE_DISTRHO
|