/*----------------------------------------------------------------------------- © 1999, Steinberg Soft und Hardware GmbH, All Rights Reserved -----------------------------------------------------------------------------*/ #include #include #include "ADelay.hpp" #include "AEffEditor.hpp" //----------------------------------------------------------------------------- ADelayProgram::ADelayProgram () { fDelay = 0.5; fFeedBack = 0.5; fOut = 0.75; strcpy (name, "Init"); } //----------------------------------------------------------------------------- ADelay::ADelay (audioMasterCallback audioMaster) : AudioEffectX (audioMaster, 16, kNumParams) { size = 44100; buffer = new float[size]; programs = new ADelayProgram[numPrograms]; fDelay = fFeedBack = fOut = vu = 0; delay = inPos = outPos = 0; if (programs) setProgram (0); setNumInputs (1); setNumOutputs (2); hasVu (); canProcessReplacing (); setUniqueID ('ADly'); suspend (); // flush buffer } //------------------------------------------------------------------------ ADelay::~ADelay () { if (buffer) delete[] buffer; if (programs) delete[] programs; } //------------------------------------------------------------------------ void ADelay::setProgram (long program) { ADelayProgram * ap = &programs[program]; curProgram = program; setParameter (kDelay, ap->fDelay); setParameter (kFeedBack, ap->fFeedBack); setParameter (kOut, ap->fOut); } //------------------------------------------------------------------------ void ADelay::setDelay (float fdelay) { long oi; fDelay = fdelay; delay = (long)(fdelay * (float)(size - 1)); programs[curProgram].fDelay = fdelay; oi = inPos - delay; if (oi < 0) oi += size; outPos = oi; } //------------------------------------------------------------------------ void ADelay::setProgramName (char *name) { strcpy (programs[curProgram].name, name); } //------------------------------------------------------------------------ void ADelay::getProgramName (char *name) { if (!strcmp (programs[curProgram].name, "Init")) sprintf (name, "%s %d", programs[curProgram].name, curProgram + 1); else strcpy (name, programs[curProgram].name); } //------------------------------------------------------------------------ void ADelay::suspend () { memset (buffer, 0, size * sizeof (float)); } //------------------------------------------------------------------------ float ADelay::getVu () { float cvu = vu; vu = 0; return cvu; } //------------------------------------------------------------------------ void ADelay::setParameter (long index, float value) { ADelayProgram * ap = &programs[curProgram]; switch (index) { case kDelay : setDelay (value); break; case kFeedBack : fFeedBack = ap->fFeedBack = value; break; case kOut : fOut = ap->fOut = value; break; } if (editor) editor->postUpdate (); } //------------------------------------------------------------------------ float ADelay::getParameter (long index) { float v = 0; switch (index) { case kDelay : v = fDelay; break; case kFeedBack : v = fFeedBack; break; case kOut : v = fOut; break; } return v; } //------------------------------------------------------------------------ void ADelay::getParameterName (long index, char *label) { switch (index) { case kDelay : strcpy (label, " Delay "); break; case kFeedBack : strcpy (label, "FeedBack"); break; case kOut : strcpy (label, " Volume "); break; } } //------------------------------------------------------------------------ void ADelay::getParameterDisplay (long index, char *text) { switch (index) { case kDelay : long2string (delay, text); break; case kFeedBack : float2string (fFeedBack, text); break; case kOut : dB2string (fOut, text); break; } } //------------------------------------------------------------------------ void ADelay::getParameterLabel (long index, char *label) { switch (index) { case kDelay : strcpy (label, "samples "); break; case kFeedBack : strcpy (label, " amount "); break; case kOut : strcpy (label, " dB "); break; } } //----------------------------------------------------------------------------- void ADelay::subProcess (float *in, float *out1, float *out2, float *dest, float *del, long sampleframes) { float d, feed = fFeedBack, vol = fOut, xn; float o1, o2, cvu = vu; while (--sampleframes >= 0) { xn = *in++; o1 = *out1; // get current buss value o2 = *out2; d = *del++ * vol; if (d > cvu) // positive only... cvu = d; xn += d / feed; o1 += d; // add to buss o2 += d; *dest++ = xn; *out1++ = o1; // store to buss *out2++ = o2; } vu = cvu; } //------------------------------------------------------------------------ void ADelay::process (float **inputs, float **outputs, long sampleframes) { float *in = *inputs; float *out1 = outputs[0]; float *out2 = outputs[1]; long frames, remain; remain = sampleframes; while (remain > 0) { if (size - inPos < remain || size - outPos < remain) { if (size - inPos < size - outPos) frames = size - inPos; else frames = size - outPos; } else frames = remain; subProcess (in, out1, out2, buffer + inPos, buffer + outPos, frames); in += frames; out1 += frames; out2 += frames; inPos += frames; if (inPos >= size) inPos -= size; outPos += frames; if (outPos >= size) outPos -= size; remain -= frames; } } //----------------------------------------------------------------------------- // replacing void ADelay::subProcessReplacing (float *in, float *out1, float *out2, float *dest, float *del, long sampleframes) { float d, feed = fFeedBack, vol = fOut, xn; float cvu = vu; while (--sampleframes >= 0) { xn = *in++; d = *del++ * vol; if (d > cvu) // positive only... cvu = d; xn += d / feed; *dest++ = xn; *out1++ = d; // store to buss *out2++ = d; } vu = cvu; } //--------------------------------------------------------------------------- void ADelay::processReplacing (float **inputs, float **outputs, long sampleframes) { float *in = *inputs; float *out1 = outputs[0]; float *out2 = outputs[1]; long frames, remain; remain = sampleframes; while (remain > 0) { if (size - inPos < remain || size - outPos < remain) { if (size - inPos < size - outPos) frames = size - inPos; else frames = size - outPos; } else frames = remain; subProcessReplacing (in, out1, out2, buffer + inPos, buffer + outPos, frames); in += frames; out1 += frames; out2 += frames; inPos += frames; if (inPos >= size) inPos -= size; outPos += frames; if (outPos >= size) outPos -= size; remain -= frames; } }