394 lines
12 KiB
C++
394 lines
12 KiB
C++
//-------------------------------------------------------------------------------------------------------
|
|
// VST Plug-Ins SDK
|
|
// Version 1.0
|
|
// © 2003 Steinberg Media Technologies, All Rights Reserved
|
|
//
|
|
// you should not have to edit this file
|
|
// use override methods instead
|
|
//-------------------------------------------------------------------------------------------------------
|
|
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
#ifndef __AudioEffect__
|
|
#include "AudioEffect.hpp"
|
|
#endif
|
|
|
|
#ifndef __AEffEditor__
|
|
#include "AEffEditor.hpp"
|
|
#endif
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
long dispatchEffectClass (AEffect *e, long opCode, long index, long value, void *ptr, float opt)
|
|
{
|
|
AudioEffect *ae = (AudioEffect*)(e->object);
|
|
|
|
if (opCode == effClose)
|
|
{
|
|
ae->dispatcher (opCode, index, value, ptr, opt);
|
|
delete ae;
|
|
return 1;
|
|
}
|
|
|
|
return ae->dispatcher (opCode, index, value, ptr, opt);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
float getParameterClass (AEffect *e, long index)
|
|
{
|
|
AudioEffect *ae = (AudioEffect*)(e->object);
|
|
return ae->getParameter (index);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void setParameterClass (AEffect *e, long index, float value)
|
|
{
|
|
AudioEffect *ae = (AudioEffect*)(e->object);
|
|
ae->setParameter (index, value);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void processClass (AEffect *e, float **inputs, float **outputs, long sampleFrames)
|
|
{
|
|
AudioEffect *ae = (AudioEffect*)(e->object);
|
|
ae->process (inputs, outputs, sampleFrames);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void processClassReplacing (AEffect *e, float **inputs, float **outputs, long sampleFrames)
|
|
{
|
|
AudioEffect *ae = (AudioEffect*)(e->object);
|
|
ae->processReplacing (inputs, outputs, sampleFrames);
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
// AudioEffect Implementation
|
|
//-------------------------------------------------------------------------------------------------------
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
AudioEffect::AudioEffect (AudioMasterCallback audioMaster, long numPrograms, long numParams)
|
|
{
|
|
this->audioMaster = audioMaster;
|
|
editor = 0;
|
|
this->numPrograms = numPrograms;
|
|
this->numParams = numParams;
|
|
curProgram = 0;
|
|
|
|
memset(&cEffect, 0, sizeof (cEffect));
|
|
cEffect.magic = kEffectMagic;
|
|
cEffect.dispatcher = dispatchEffectClass;
|
|
cEffect.process = processClass;
|
|
cEffect.setParameter = setParameterClass;
|
|
cEffect.getParameter = getParameterClass;
|
|
cEffect.numPrograms = numPrograms;
|
|
cEffect.numParams = numParams;
|
|
cEffect.numInputs = 1;
|
|
cEffect.numOutputs = 2;
|
|
cEffect.flags = 0;
|
|
cEffect.resvd1 = 0;
|
|
cEffect.resvd2 = 0;
|
|
cEffect.initialDelay = 0;
|
|
cEffect.realQualities = 0;
|
|
cEffect.offQualities = 0;
|
|
cEffect.ioRatio = 1.f;
|
|
cEffect.object = this;
|
|
cEffect.user = 0;
|
|
cEffect.uniqueID = CCONST ('N', 'o', 'E', 'f'); // you must set this!
|
|
cEffect.version = 1;
|
|
cEffect.processReplacing = processClassReplacing;
|
|
|
|
sampleRate = 44100.f;
|
|
blockSize = 1024L;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
AudioEffect::~AudioEffect ()
|
|
{
|
|
if (editor)
|
|
delete editor;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
long AudioEffect::dispatcher (long opCode, long index, long value, void *ptr, float opt)
|
|
{
|
|
long v = 0;
|
|
|
|
switch (opCode)
|
|
{
|
|
case effOpen: open (); break;
|
|
case effClose: close (); break;
|
|
case effSetProgram: if (value < numPrograms) setProgram (value); break;
|
|
case effGetProgram: v = getProgram (); break;
|
|
case effSetProgramName: setProgramName ((char *)ptr); break;
|
|
case effGetProgramName: getProgramName ((char *)ptr); break;
|
|
case effGetParamLabel: getParameterLabel (index, (char *)ptr); break;
|
|
case effGetParamDisplay: getParameterDisplay (index, (char *)ptr); break;
|
|
case effGetParamName: getParameterName (index, (char *)ptr); break;
|
|
|
|
case effSetSampleRate: setSampleRate (opt); break;
|
|
case effSetBlockSize: setBlockSize (value); break;
|
|
case effMainsChanged: if (!value) suspend (); else resume (); break;
|
|
case effGetVu: v = (long)(getVu () * 32767.); break;
|
|
|
|
|
|
// Editor
|
|
case effEditGetRect: if (editor) v = editor->getRect ((ERect **)ptr); break;
|
|
case effEditOpen: if (editor) v = editor->open (ptr); break;
|
|
case effEditClose: if (editor) editor->close (); break;
|
|
case effEditIdle: if (editor) editor->idle (); break;
|
|
|
|
#if MAC
|
|
case effEditDraw: if (editor) editor->draw ((ERect *)ptr); break;
|
|
case effEditMouse: if (editor) v = editor->mouse (index, value); break;
|
|
case effEditKey: if (editor) v = editor->key (value); break;
|
|
case effEditTop: if (editor) editor->top (); break;
|
|
case effEditSleep: if (editor) editor->sleep (); break;
|
|
#endif
|
|
|
|
case effIdentify: v = CCONST ('N', 'v', 'E', 'f'); break;
|
|
case effGetChunk: v = getChunk ((void**)ptr, index ? true : false); break;
|
|
case effSetChunk: v = setChunk (ptr, value, index ? true : false); break;
|
|
}
|
|
return v;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
long AudioEffect::getMasterVersion ()
|
|
{
|
|
long version = 1;
|
|
if (audioMaster)
|
|
{
|
|
version = audioMaster (&cEffect, audioMasterVersion, 0, 0, 0, 0);
|
|
if (!version) // old
|
|
version = 1;
|
|
}
|
|
return version;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
long AudioEffect::getCurrentUniqueId ()
|
|
{
|
|
long id = 0;
|
|
if (audioMaster)
|
|
id = audioMaster (&cEffect, audioMasterCurrentId, 0, 0, 0, 0);
|
|
return id;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::masterIdle ()
|
|
{
|
|
if (audioMaster)
|
|
audioMaster (&cEffect, audioMasterIdle, 0, 0, 0, 0);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
bool AudioEffect::isInputConnected (long input)
|
|
{
|
|
long ret = 0;
|
|
if (audioMaster)
|
|
ret = audioMaster (&cEffect, audioMasterPinConnected, input, 0, 0, 0);
|
|
return ret ? false : true; // return value is 0 for true
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
bool AudioEffect::isOutputConnected (long output)
|
|
{
|
|
long ret = 0;
|
|
if (audioMaster)
|
|
ret = audioMaster (&cEffect, audioMasterPinConnected, output, 1, 0, 0);
|
|
return ret ? false : true; // return value is 0 for true
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::setParameterAutomated (long index, float value)
|
|
{
|
|
setParameter (index, value);
|
|
if (audioMaster)
|
|
audioMaster (&cEffect, audioMasterAutomate, index, 0, 0, value); // value is in opt
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
// Flags
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::hasVu (bool state)
|
|
{
|
|
if (state)
|
|
cEffect.flags |= effFlagsHasVu;
|
|
else
|
|
cEffect.flags &= ~effFlagsHasVu;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::hasClip (bool state)
|
|
{
|
|
if (state)
|
|
cEffect.flags |= effFlagsHasClip;
|
|
else
|
|
cEffect.flags &= ~effFlagsHasClip;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::canMono (bool state)
|
|
{
|
|
if (state)
|
|
cEffect.flags |= effFlagsCanMono;
|
|
else
|
|
cEffect.flags &= ~effFlagsCanMono;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::canProcessReplacing (bool state)
|
|
{
|
|
if (state)
|
|
cEffect.flags |= effFlagsCanReplacing;
|
|
else
|
|
cEffect.flags &= ~effFlagsCanReplacing;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::programsAreChunks (bool state)
|
|
{
|
|
if (state)
|
|
cEffect.flags |= effFlagsProgramChunks;
|
|
else
|
|
cEffect.flags &= ~effFlagsProgramChunks;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::setRealtimeQualities (long qualities)
|
|
{
|
|
cEffect.realQualities = qualities;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::setOfflineQualities (long qualities)
|
|
{
|
|
cEffect.offQualities = qualities;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::setInitialDelay (long delay)
|
|
{
|
|
cEffect.initialDelay = delay;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
// Strings Conversion
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::dB2string (float value, char *text)
|
|
{
|
|
if (value <= 0)
|
|
#if MAC
|
|
strcpy (text, "-°");
|
|
#else
|
|
strcpy (text, "-oo");
|
|
#endif
|
|
else
|
|
float2string ((float)(20. * log10 (value)), text);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::Hz2string (float samples, char *text)
|
|
{
|
|
float sampleRate = getSampleRate ();
|
|
if (!samples)
|
|
float2string (0, text);
|
|
else
|
|
float2string (sampleRate / samples, text);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::ms2string (float samples, char *text)
|
|
{
|
|
float2string ((float)(samples * 1000. / getSampleRate ()), text);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::float2string (float value, char *text)
|
|
{
|
|
long c = 0, neg = 0;
|
|
char string[32];
|
|
char *s;
|
|
double v, integ, i10, mantissa, m10, ten = 10.;
|
|
|
|
v = (double)value;
|
|
if (v < 0)
|
|
{
|
|
neg = 1;
|
|
value = -value;
|
|
v = -v;
|
|
c++;
|
|
if (v > 9999999.)
|
|
{
|
|
strcpy (string, "Huge!");
|
|
return;
|
|
}
|
|
}
|
|
else if( v > 99999999.)
|
|
{
|
|
strcpy (string, "Huge!");
|
|
return;
|
|
}
|
|
|
|
s = string + 31;
|
|
*s-- = 0;
|
|
*s-- = '.';
|
|
c++;
|
|
|
|
integ = floor (v);
|
|
i10 = fmod (integ, ten);
|
|
*s-- = (char)((long)i10 + '0');
|
|
integ /= ten;
|
|
c++;
|
|
while (integ >= 1. && c < 8)
|
|
{
|
|
i10 = fmod (integ, ten);
|
|
*s-- = (char)((long)i10 + '0');
|
|
integ /= ten;
|
|
c++;
|
|
}
|
|
if (neg)
|
|
*s-- = '-';
|
|
strcpy (text, s + 1);
|
|
if (c >= 8)
|
|
return;
|
|
|
|
s = string + 31;
|
|
*s-- = 0;
|
|
mantissa = fmod (v, 1.);
|
|
mantissa *= pow (ten, (double)(8 - c));
|
|
while (c < 8)
|
|
{
|
|
if (mantissa <= 0)
|
|
*s-- = '0';
|
|
else
|
|
{
|
|
m10 = fmod (mantissa, ten);
|
|
*s-- = (char)((long)m10 + '0');
|
|
mantissa /= 10.;
|
|
}
|
|
c++;
|
|
}
|
|
strcat (text, s + 1);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
void AudioEffect::long2string (long value, char *text)
|
|
{
|
|
char string[32];
|
|
|
|
if (value >= 100000000)
|
|
{
|
|
strcpy (text, "Huge!");
|
|
return;
|
|
}
|
|
sprintf (string, "%7d", (int)value);
|
|
string[8] = 0;
|
|
strcpy (text, (char *)string);
|
|
}
|
|
//-------------------------------------------------------------------------------------------------------
|
|
//-------------------------------------------------------------------------------------------------------
|