Files
Work/vst/AudioEffect.cpp
2024-08-07 09:16:27 -04:00

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);
}
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------