aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-08-12 00:20:16 +0000
committerDavid Robillard <d@drobilla.net>2008-08-12 00:20:16 +0000
commit102e899c331bd2ed9902467a077164e209c918f9 (patch)
treeb7fe5ec873582cc8a0fc0862f9da045d12b2259a /src
parent2b679f152e1c3104ac178b6c78ac0b1edf954ff6 (diff)
downloadmda.lv2-102e899c331bd2ed9902467a077164e209c918f9.tar.gz
mda.lv2-102e899c331bd2ed9902467a077164e209c918f9.tar.bz2
mda.lv2-102e899c331bd2ed9902467a077164e209c918f9.zip
VSTUI X11 port and embeddable GTK wrapper.
Build mdaSpecMeter and GUI. git-svn-id: http://svn.drobilla.net/lad/mda-lv2@1340 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/mdaSpecMeter.cpp482
-rw-r--r--src/mdaSpecMeter.h19
-rw-r--r--src/mdaSpecMeterGUI.cpp390
-rw-r--r--src/mdaSpecMeterGUI.h36
-rw-r--r--src/mdaspecmeter.cpp416
5 files changed, 718 insertions, 625 deletions
diff --git a/src/mdaSpecMeter.cpp b/src/mdaSpecMeter.cpp
new file mode 100644
index 0000000..7aae786
--- /dev/null
+++ b/src/mdaSpecMeter.cpp
@@ -0,0 +1,482 @@
+//
+// Plug-in: "MDA SpecMeter"
+//
+// Copyright(c)2002 Paul Kellett (maxim digital audio)
+//
+
+
+#include <stdio.h>
+#include <string.h>
+#include <float.h>
+#include <math.h>
+
+#include "mdaSpecMeter.h"
+//#include "mdaSpecMeterGUI.h"
+//#include "AEffEditor.hpp"
+
+AudioEffect *
+createEffectInstance (audioMasterCallback audioMaster)
+{
+ return new mdaSpecMeter (audioMaster);
+}
+
+mdaSpecMeterProgram::mdaSpecMeterProgram ()
+{
+ param[_PARAM0] = 1.0;
+ strcpy (name, "MDA SpecMeter");
+}
+
+
+mdaSpecMeter::mdaSpecMeter (audioMasterCallback audioMaster):AudioEffectX (audioMaster, 1,
+ NPARAMS)
+{
+ //editor = new mdaSpecMeterGUI(this);
+
+ programs = new mdaSpecMeterProgram[numPrograms];
+ if (programs) {
+ setProgram (0);
+ }
+
+ setNumInputs (2);
+ setNumOutputs (2);
+ DECLARE_LVZ_DEPRECATED (canMono) ();
+ setUniqueID ("mdaSpecMeter");
+ canProcessReplacing ();
+
+ //initialise...
+ K = counter = 0;
+ kmax = 2048;
+ topband = 11;
+ iK = 1.0f / (float) kmax;
+ den = 1.0e-8f;
+
+ //buffer = new float[44100];
+
+ suspend ();
+}
+
+bool
+mdaSpecMeter::getProductString (char *text)
+{
+ strcpy (text, "MDA SpecMeter");
+ return true;
+}
+
+bool
+mdaSpecMeter::getVendorString (char *text)
+{
+ strcpy (text, "mda");
+ return true;
+}
+
+bool
+mdaSpecMeter::getEffectName (char *name)
+{
+ strcpy (name, "SpecMeter");
+ return true;
+}
+
+void
+mdaSpecMeter::suspend ()
+{
+ Lpeak = Rpeak = Lrms = Rrms = Corr = 0.0f;
+ lpeak = rpeak = lrms = rrms = corr = 0.0f;
+ Lhold = Rhold = 0.0f;
+ Lmin = Rmin = 0.0000001f;
+ for (long i = 0; i < 16; i++) {
+ band[0][i] = band[1][i] = 0.0f;
+ for (long j = 0; j < 6; j++)
+ lpp[j][i] = rpp[j][i] = 0.0f;
+ }
+
+ //memset(buffer, 0, size * sizeof (float));
+}
+
+void
+mdaSpecMeter::setSampleRate (float rate)
+{
+ AudioEffectX::setSampleRate (rate);
+ if (rate > 64000) {
+ topband = 12;
+ kmax = 4096;
+ } else {
+ topband = 11;
+ kmax = 2048;
+ }
+ iK = 1.0f / (float) kmax;
+}
+
+
+mdaSpecMeter::~mdaSpecMeter ()
+{
+ //if(buffer) delete [] buffer;
+ if (programs)
+ delete[]programs;
+}
+
+
+void
+mdaSpecMeter::setProgramName (char *name)
+{
+ strcpy (programs[curProgram].name, name);
+}
+
+void
+mdaSpecMeter::getProgramName (char *name)
+{
+ strcpy (name, programs[curProgram].name);
+}
+
+float
+mdaSpecMeter::getParameter (LvzInt32 index)
+{
+ return param[index];
+}
+
+void
+mdaSpecMeter::setProgram (LvzInt32 program)
+{
+ mdaSpecMeterProgram *p = &programs[program];
+ curProgram = program;
+ setProgramName (p->name);
+ for (long i = 0; i < NPARAMS; i++)
+ setParameter (i, p->param[i]);
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+
+void
+mdaSpecMeter::setParameter (LvzInt32 index, float value)
+{
+ mdaSpecMeterProgram *p = &programs[curProgram];
+ param[index] = p->param[index] = value;
+
+ switch (index) {
+ case _PARAM0:
+ gain = (float) pow (10.0f, 2.0f * param[index] - 1.0f);
+ break;
+
+ default:
+ break;
+ }
+
+ //if(editor) editor->postUpdate();
+}
+
+
+void
+mdaSpecMeter::getParameterName (LvzInt32 index, char *label)
+{
+ switch (index) {
+ case _PARAM0:
+ strcpy (label, "Gain");
+ break;
+ default:
+ strcpy (label, "");
+ }
+}
+
+
+void
+mdaSpecMeter::getParameterDisplay (LvzInt32 index, char *text)
+{
+ char string[16];
+
+ switch (index) {
+ case _PARAM0:
+ sprintf (string, "%.1f", 40.0f * param[index] - 20.0f);
+ break;
+ default:
+ sprintf (string, "%.0f", 0.0f * param[index]);
+ }
+ string[8] = 0;
+ strcpy (text, (char *) string);
+}
+
+
+void
+mdaSpecMeter::getParameterLabel (LvzInt32 index, char *label)
+{
+ switch (index) {
+ case _PARAM0:
+ strcpy (label, "Gain");
+ break;
+ default:
+ strcpy (label, "");
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+
+void
+mdaSpecMeter::process (float **inputs, float **outputs, LvzInt32 sampleFrames)
+{
+ float *in1 = inputs[0];
+ float *in2 = inputs[1];
+ float *out1 = outputs[0];
+ float *out2 = outputs[1];
+
+ den = -den;
+ float l, r, p, q, iN = iK;
+ long k = K, j0 = topband, mask, j;
+
+ while (--sampleFrames >= 0) {
+ l = *in1++;
+ r = *in2++;
+ *out1++ += l;
+ *out2++ += r;
+
+ l += den; //anti-denormal
+ r += den;
+
+ lrms += l * l; //RMS integrate
+ rrms += r * r;
+
+ p = (float) fabs (l);
+ if (p > lpeak)
+ lpeak = p; //peak detect
+ q = (float) fabs (r);
+ if (q > rpeak)
+ rpeak = q;
+ /*
+ if(p > 1.0e-8f && p < lmin) lmin = p; //'trough' detect
+ if(q > 1.0e-8f && q < rmin) rmin = q;
+ */
+ if ((l * r) > 0.0f)
+ corr += iN; //measure correlation
+
+ j = j0;
+ mask = k << 1;
+
+ do { //polyphase filter bank
+ p = lpp[0][j] + 0.208f * l;
+ lpp[0][j] = lpp[1][j];
+ lpp[1][j] = l - 0.208f * p;
+
+ q = lpp[2][j] + lpp[4][j] * 0.682f;
+ lpp[2][j] = lpp[3][j];
+ lpp[3][j] = lpp[4][j] - 0.682f * q;
+ lpp[4][j] = l;
+ lpp[5][j] += (float) fabs (p - q); //top octave
+ l = p + q; //lower octaves
+
+ p = rpp[0][j] + 0.208f * r;
+ rpp[0][j] = rpp[1][j];
+ rpp[1][j] = r - 0.208f * p;
+
+ q = rpp[2][j] + rpp[4][j] * 0.682f;
+ rpp[2][j] = rpp[3][j];
+ rpp[3][j] = rpp[4][j] - 0.682f * q;
+ rpp[4][j] = r;
+ rpp[5][j] += (float) fabs (p - q); //top octave
+ r = p + q; //lower octaves
+
+ j--;
+ mask >>= 1;
+ } while (mask & 1);
+
+ if (++k == kmax) {
+ k = 0;
+ counter++; //editor waits for this to change
+
+ if (lpeak == 0.0f)
+ Lpeak = Lrms = 0.0f;
+ else { ///add limits here!
+ if (lpeak > 2.0f)
+ lpeak = 2.0f;
+ if (lpeak >= Lpeak) {
+ Lpeak = lpeak;
+ Lhold = 2.0f * Lpeak;
+ } else {
+ Lhold *= 0.95f;
+ if (Lhold < Lpeak)
+ Lpeak = Lhold;
+ }
+ Lmin = lmin;
+ lmin *= 1.01f;
+ Lrms += 0.2f * (iN * lrms - Lrms);
+ }
+
+ if (rpeak == 0.0f)
+ Rpeak = Rrms = 0.0f;
+ else {
+ if (rpeak > 2.0f)
+ rpeak = 2.0f;
+ if (rpeak >= Rpeak) {
+ Rpeak = rpeak;
+ Rhold = 2.0f * Rpeak;
+ } else {
+ Rhold *= 0.95f;
+ if (Rhold < Rpeak)
+ Rpeak = Rhold;
+ }
+ Rmin = rmin;
+ rmin *= 1.01f;
+ Rrms += 0.2f * (iN * rrms - Rrms);
+ }
+
+ rpeak = lpeak = lrms = rrms = 0.0f;
+ Corr += 0.1f * (corr - Corr); //correlation
+ corr = SILENCE;
+
+ float dec = 0.08f;
+ for (j = 0; j < 13; j++) { //spectrum output
+ band[0][j] += dec * (iN * lpp[5][j] - band[0][j]);
+ if (band[0][j] > 2.0f)
+ band[0][j] = 2.0f;
+ else if (band[0][j] < 0.014f)
+ band[0][j] = 0.014f;
+
+ band[1][j] += dec * (iN * rpp[5][j] - band[1][j]);
+ if (band[1][j] > 2.0f)
+ band[1][j] = 2.0f;
+ else if (band[1][j] < 0.014f)
+ band[1][j] = 0.014f;
+
+ rpp[5][j] = lpp[5][j] = SILENCE;
+ dec = dec * 1.1f;
+ }
+ }
+ }
+
+ K = k;
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+
+void
+mdaSpecMeter::processReplacing (float **inputs, float **outputs,
+ LvzInt32 sampleFrames)
+{
+ float *in1 = inputs[0];
+ float *in2 = inputs[1];
+ float *out1 = outputs[0];
+ float *out2 = outputs[1];
+
+ den = -den;
+ float l, r, p, q, iN = iK;
+ long k = K, j0 = topband, mask, j;
+
+ while (--sampleFrames >= 0) {
+ l = *in1++;
+ r = *in2++;
+ *out1++ = l;
+ *out2++ = r;
+
+ l += den; //anti-denormal
+ r += den;
+
+ lrms += l * l; //RMS integrate
+ rrms += r * r;
+
+ p = (float) fabs (l);
+ if (p > lpeak)
+ lpeak = p; //peak detect
+ q = (float) fabs (r);
+ if (q > rpeak)
+ rpeak = q;
+ /*
+ if(p > 1.0e-8f && p < lmin) lmin = p; //'trough' detect
+ if(q > 1.0e-8f && q < rmin) rmin = q;
+ */
+ if ((l * r) > 0.0f)
+ corr += iN; //measure correlation
+
+ j = j0;
+ mask = k << 1;
+
+ do { //polyphase filter bank
+ p = lpp[0][j] + 0.208f * l;
+ lpp[0][j] = lpp[1][j];
+ lpp[1][j] = l - 0.208f * p;
+
+ q = lpp[2][j] + lpp[4][j] * 0.682f;
+ lpp[2][j] = lpp[3][j];
+ lpp[3][j] = lpp[4][j] - 0.682f * q;
+ lpp[4][j] = l;
+ lpp[5][j] += (float) fabs (p - q); //top octave
+ l = p + q; //lower octaves
+
+ p = rpp[0][j] + 0.208f * r;
+ rpp[0][j] = rpp[1][j];
+ rpp[1][j] = r - 0.208f * p;
+
+ q = rpp[2][j] + rpp[4][j] * 0.682f;
+ rpp[2][j] = rpp[3][j];
+ rpp[3][j] = rpp[4][j] - 0.682f * q;
+ rpp[4][j] = r;
+ rpp[5][j] += (float) fabs (p - q); //top octave
+ r = p + q; //lower octaves
+
+ j--;
+ mask >>= 1;
+ } while (mask & 1);
+
+ if (++k == kmax) {
+ k = 0;
+ //counter++; //editor waits for this to change
+
+ if (lpeak == 0.0f)
+ Lpeak = Lrms = 0.0f;
+ else { ///add limits here!
+ if (lpeak > 2.0f)
+ lpeak = 2.0f;
+ if (lpeak >= Lpeak) {
+ Lpeak = lpeak;
+ Lhold = 2.0f * Lpeak;
+ } else {
+ Lhold *= 0.95f;
+ if (Lhold < Lpeak)
+ Lpeak = Lhold;
+ }
+ Lmin = lmin;
+ lmin *= 1.01f;
+ Lrms += 0.2f * (iN * lrms - Lrms);
+ }
+
+ if (rpeak == 0.0f)
+ Rpeak = Rrms = 0.0f;
+ else {
+ if (rpeak > 2.0f)
+ rpeak = 2.0f;
+ if (rpeak >= Rpeak) {
+ Rpeak = rpeak;
+ Rhold = 2.0f * Rpeak;
+ } else {
+ Rhold *= 0.95f;
+ if (Rhold < Rpeak)
+ Rpeak = Rhold;
+ }
+ Rmin = rmin;
+ rmin *= 1.01f;
+ Rrms += 0.2f * (iN * rrms - Rrms);
+ }
+
+ rpeak = lpeak = lrms = rrms = 0.0f;
+ Corr += 0.1f * (corr - Corr); //correlation
+ corr = SILENCE;
+
+ float dec = 0.08f;
+ for (j = 0; j < 13; j++) { //spectrum output
+ band[0][j] += dec * (iN * lpp[5][j] - band[0][j]);
+ if (band[0][j] > 2.0f)
+ band[0][j] = 2.0f;
+ else if (band[0][j] < 0.014f)
+ band[0][j] = 0.014f;
+
+ band[1][j] += dec * (iN * rpp[5][j] - band[1][j]);
+ if (band[1][j] > 2.0f)
+ band[1][j] = 2.0f;
+ else if (band[1][j] < 0.014f)
+ band[1][j] = 0.014f;
+
+ rpp[5][j] = lpp[5][j] = SILENCE;
+ dec = dec * 1.1f;
+ }
+
+ counter++; //editor waits for this to change
+ }
+ }
+
+ K = k;
+}
diff --git a/src/mdaSpecMeter.h b/src/mdaSpecMeter.h
index 31573ed..5ce88ee 100644
--- a/src/mdaSpecMeter.h
+++ b/src/mdaSpecMeter.h
@@ -1,21 +1,18 @@
-//see associated .cpp file for copyright and other info
+//
+// Plug-in: "MDA SpecMeter"
+//
+// Copyright(c)1999-2000 Paul Kellett (maxim digital audio)
+// Copyright (C) 2008 Dave Robillard
+//
#include "audioeffectx.h"
#include <string.h>
-#define NPROGS 4 //can hide decay settings in programs! fast...slow...peak hold
#define SILENCE 0.00000001f
-
-
-enum
-{
- _PARAM0, //peak decay
- _PARAM1, //RMS speed
- _PARAM2, //spectrum speed
- _PARAM3, //peak reset?
-
+enum {
+ _PARAM0, // gain
NPARAMS
};
diff --git a/src/mdaSpecMeterGUI.cpp b/src/mdaSpecMeterGUI.cpp
index 08bc5a3..d36622d 100644
--- a/src/mdaSpecMeterGUI.cpp
+++ b/src/mdaSpecMeterGUI.cpp
@@ -1,179 +1,211 @@
-#include "mdaSpecMeterGUI.h"
-#include "mdaSpecMeter.h"
-
-#include <math.h>
-
-
-mdaSpecMeterGUI::mdaSpecMeterGUI(AudioEffect *effect) : AEffGUIEditor(effect)
-{
- background = new CBitmap(128);
-
- rect.left = 0;
- rect.top = 0;
- rect.right = (LvzInt16)background->getWidth();
- rect.bottom = (LvzInt16)background->getHeight();
-}
-
-
-mdaSpecMeterGUI::~mdaSpecMeterGUI()
-{
- delete background;
-}
-
-
-bool mdaSpecMeterGUI::open(void *ptr)
-{
- AEffGUIEditor::open(ptr);
-
- CPoint offs(0, 0);
- CRect size(0, 0, background->getWidth(), background->getHeight());
- frame = new CFrame(size, ptr, this);
-
- size.offset(0, 0);
- draw = new CDraw(size, 0.0f, background);
- frame->addView(draw);
-
- return true;
-}
-
-
-void mdaSpecMeterGUI::close()
-{
- delete frame;
- frame = 0;
-}
-
-
-void mdaSpecMeterGUI::idle()
-{
- long xnow = ((mdaSpecMeter *)effect)->counter;
- if(xnow != xtimer)
- {
- xtimer = xnow;
-
- //if(draw) temp = draw->temp;
- //if(label) label->setLabel(xtimer);
-
- if(draw) //copy data from effect (this can't be the best way!)
- {
- draw->Lpeak = ((mdaSpecMeter *)effect)->Lpeak;
- draw->Lmin = ((mdaSpecMeter *)effect)->Lmin;
- draw->Lrms = ((mdaSpecMeter *)effect)->Lrms;
- draw->Rpeak = ((mdaSpecMeter *)effect)->Rpeak;
- draw->Rmin = ((mdaSpecMeter *)effect)->Rmin;
- draw->Rrms = ((mdaSpecMeter *)effect)->Rrms;
- draw->Corr = ((mdaSpecMeter *)effect)->Corr;
- for(long i=0; i<13; i++)
- {
- draw->band[0][i] = ((mdaSpecMeter *)effect)->band[0][i];
- draw->band[1][i] = ((mdaSpecMeter *)effect)->band[1][i];
- }
- draw->setDirty(true); //trigger redraw
- }
- }
-
- AEffGUIEditor::idle();
-}
-
-
-CDraw::CDraw(CRect &size, float value, CBitmap *background) : CControl(size)
-{
- bitmap = background;
-
- Lpeak = Lmin = Lrms = Rpeak = Rmin = Rrms = Corr = 0.0f;
- for(long i=0; i<16; i++) band[0][i] = band[1][i] = 0.0f;
-
- setValue(value);
-}
-
-CDraw::~CDraw()
-{
-
-}
-
-void CDraw::draw(CDrawContext *pContext)
-{
- long r, p;
- CRect block;
- CRect rect(0, 0, bitmap->getWidth(), bitmap->getHeight());
-
- bitmap->draw(pContext, rect);
-/*
- pContext->setFillColor(kGreenCColor);
-
- p = x2pix(Lmin);
- block(p - 3, 10, p - 1, 18);
- pContext->fillRect(block);
-
- p = x2pix(Rmin);
- block(p - 3, 18, p - 1, 26);
- pContext->fillRect(block);
-*/
- pContext->setFillColor(kBlackCColor);
-
- r = x22pix(Lrms); if(r > 454) r = 454;
- p = x2pix(Lpeak); if(p > 454) p = 454;
- block = CRect(r - 1, 10, p - 1, 18);
- pContext->fillRect(block);
- block = CRect(p - 1, 10, 478, 18);
- if(p < 454) pContext->fillRect(block);
-
- r = x22pix(Rrms); if(r > 454) r = 454;
- p = x2pix(Rpeak); if(p > 454) p = 454;
- block = CRect(r - 1, 18, p - 1, 26);
- pContext->fillRect(block);
- block = CRect(p - 1, 18, 478, 26);
- if(p < 454) pContext->fillRect(block);
-
- //block(x2pix(Rpeak), 18, 478, 26);
- //buf->fillRect(block);
-
- block = CRect(235, 42, 244, 134 - (long)(90 * Corr));
- pContext->fillRect(block);
-
- long i, x1=2, x2=256; //octave bands
- float dB;
- for(i=0; i<13; i++)
- {
- dB = band[0][i];
- block = CRect(x1, 42, x1+18, 49 - (long)(20.0 * log(dB)));
- pContext->fillRect(block);
- x1 += 17;
-
- dB = band[1][i];
- block = CRect(x2, 42, x2+18, 49 - (long)(20.0 * log(dB)));
- pContext->fillRect(block);
- x2 += 17;
- }
-}
-
-
-long CDraw::x2pix(float x)
-{
- float dB = x;
- long p = 478;
-
- if(x > 0.00000005f) dB = 8.6858896f * (float)log(x); else dB = -146.0f;
- if(dB < -20.0)
- p = 293 + (long)(2.0f * dB);
- else
- p = 453 + (long)(10.0f * dB);
-
- return p;
-}
-
-
-long CDraw::x22pix(float x) //power version for squared summed
-{
- float dB = x;
- long p = 478;
-
- if(x > 0.00000005f) dB = 4.3429448f * (float)log(x); else dB = -146.0f;
- if(dB < -20.0)
- p = 293 + (long)(2.0f * dB);
- else
- if(dB < 0.0f) p = 453 + (long)(10.0f * dB);
-
- return p;
-}
-
+#include "mdaSpecMeterGUI.h"
+#include "mdaSpecMeter.h"
+#include "mdaSpecMeter.xpm"
+#include <X11/Xlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+
+#include <math.h>
+
+mdaSpecMeterGUI::mdaSpecMeterGUI(AudioEffect * effect)
+ : AEffGUIEditor(effect)
+ , background(NULL)
+{
+}
+
+
+mdaSpecMeterGUI::~mdaSpecMeterGUI()
+{
+ delete background;
+}
+
+
+bool
+mdaSpecMeterGUI::open(void *ptr)
+{
+ if (background == NULL) {
+ background = new CBitmap(*this, "mdaSpecMeter.png");
+ rect.right = (LvzInt16) background->getWidth();
+ rect.bottom = (LvzInt16) background->getHeight();
+ }
+
+ AEffGUIEditor::open(ptr);
+
+ CPoint offs(0, 0);
+ CRect size(0, 0, background->getWidth(), background->getHeight());
+ frame = new CFrame(size, ptr, this);
+
+ size.offset(0, 0);
+ draw = new CDraw(size, 0.0f, background);
+ frame->addView(draw);
+
+ return true;
+}
+
+
+void
+mdaSpecMeterGUI::close()
+{
+ delete frame;
+ frame = 0;
+}
+
+
+void
+mdaSpecMeterGUI::idle()
+{
+ long xnow = ((mdaSpecMeter *) effect)->counter;
+ if (xnow != xtimer) {
+ xtimer = xnow;
+
+ if (draw) { // copy data from effect (this can't be the best way!)
+ draw->Lpeak = ((mdaSpecMeter *) effect)->Lpeak;
+ draw->Lmin = ((mdaSpecMeter *) effect)->Lmin;
+ draw->Lrms = ((mdaSpecMeter *) effect)->Lrms;
+ draw->Rpeak = ((mdaSpecMeter *) effect)->Rpeak;
+ draw->Rmin = ((mdaSpecMeter *) effect)->Rmin;
+ draw->Rrms = ((mdaSpecMeter *) effect)->Rrms;
+ draw->Corr = ((mdaSpecMeter *) effect)->Corr;
+ for (long i = 0; i < 13; i++) {
+ draw->band[0][i] = ((mdaSpecMeter *) effect)->band[0][i];
+ draw->band[1][i] = ((mdaSpecMeter *) effect)->band[1][i];
+ }
+ draw->setDirty(true); // trigger redraw
+ }
+ }
+
+ AEffGUIEditor::idle();
+}
+
+
+CDraw::CDraw(CRect & size, float value, CBitmap * background):
+ CControl(size)
+{
+ bitmap = background;
+
+ Lpeak = Lmin = Lrms = Rpeak = Rmin = Rrms = Corr = 0.0f;
+ for (long i = 0; i < 16; i++)
+ band[0][i] = band[1][i] = 0.0f;
+
+ setValue(value);
+}
+
+CDraw::~CDraw()
+{
+}
+
+void
+CDraw::draw(CDrawContext * pContext)
+{
+ long r, p;
+ CRect block;
+ CRect rect(0, 0, bitmap->getWidth(), bitmap->getHeight());
+
+ bitmap->draw(pContext, rect);
+
+ /*
+ pContext->setFillColor(kGreenCColor);
+
+ p = x2pix(Lmin);
+ block(p - 3, 10, p - 1, 18);
+ pContext->fillRect(block);
+
+ p = x2pix(Rmin);
+ block(p - 3, 18, p - 1, 26);
+ pContext->fillRect(block);
+ */
+
+ pContext->setFillColor(kBlackCColor);
+
+ r = x22pix(Lrms);
+ if (r > 454)
+ r = 454;
+
+ p = x2pix(Lpeak);
+ if (p > 454)
+ p = 454;
+
+ block = CRect(r - 1, 10, p - 1, 18);
+ pContext->fillRect(block);
+
+ block = CRect(p - 1, 10, 478, 18);
+ if (p < 454)
+ pContext->fillRect(block);
+
+ r = x22pix(Rrms);
+ if (r > 454)
+ r = 454;
+
+ p = x2pix(Rpeak);
+ if (p > 454)
+ p = 454;
+
+ block = CRect(r - 1, 18, p - 1, 26);
+ pContext->fillRect(block);
+
+ block = CRect(p - 1, 18, 478, 26);
+ if (p < 454)
+ pContext->fillRect(block);
+
+ //block(x2pix(Rpeak), 18, 478, 26);
+ //buf->fillRect(block);
+
+ block = CRect(235, 42, 244, 134 - (long)(90 * Corr));
+ pContext->fillRect(block);
+
+ long i, x1 = 2, x2 = 256; // octave bands
+ for (i = 0; i < 13; i++) {
+ float dB = band[0][i];
+ block = CRect(x1, 42, x1 + 18, 49 - (long)(20.0 * log(dB)));
+ pContext->fillRect(block);
+ x1 += 17;
+
+ dB = band[1][i];
+ block = CRect(x2, 42, x2 + 18, 49 - (long)(20.0 * log(dB)));
+ pContext->fillRect(block);
+ x2 += 17;
+ }
+}
+
+
+long
+CDraw::x2pix(float x)
+{
+ float dB = x;
+ long p = 478;
+
+ if (x > 0.00000005f)
+ dB = 8.6858896f * (float)log(x);
+ else
+ dB = -146.0f;
+
+ if (dB < -20.0)
+ p = 293 + (long)(2.0f * dB);
+ else
+ p = 453 + (long)(10.0f * dB);
+
+ return p;
+}
+
+
+long
+CDraw::x22pix(float x) // power version for squared summed
+{
+ float dB = x;
+ long p = 478;
+
+ if (x > 0.00000005f)
+ dB = 4.3429448f * (float)log(x);
+ else
+ dB = -146.0f;
+
+ if (dB < -20.0)
+ p = 293 + (long)(2.0f * dB);
+ else if (dB < 0.0f)
+ p = 453 + (long)(10.0f * dB);
+
+ return p;
+}
+
diff --git a/src/mdaSpecMeterGUI.h b/src/mdaSpecMeterGUI.h
index b4541f1..263a20b 100644
--- a/src/mdaSpecMeterGUI.h
+++ b/src/mdaSpecMeterGUI.h
@@ -1,45 +1,43 @@
#ifndef _mdaSpecMeterGUI_h_
#define _mdaSpecMeterGUI_h_
-#include "lvzgui.h"
+#include "vstgui.h"
-//a drawing control
class CDraw : public CControl
{
public:
- CDraw(CRect &size, float x, CBitmap *background);
- ~CDraw();
+ CDraw(CRect& size, float x, CBitmap* background);
+ ~CDraw();
- void draw(CDrawContext *pContext);
+ void draw(CDrawContext* pContext);
long x2pix(float x);
long x22pix(float x);
- float Lpeak, Lrms, Lmin, Rpeak, Rrms, Rmin, Corr;
- float band[2][16];
- long temp;
+ float Lpeak, Lrms, Lmin, Rpeak, Rrms, Rmin, Corr;
+ float band[2][16];
protected:
- CBitmap *bitmap;
+ CBitmap* bitmap;
};
class mdaSpecMeterGUI : public AEffGUIEditor
{
public:
- mdaSpecMeterGUI(AudioEffect *effect);
- ~mdaSpecMeterGUI();
-
- bool open(void *ptr);
- void idle();
- void close();
+ mdaSpecMeterGUI(AudioEffect* effect);
+ ~mdaSpecMeterGUI();
+
+ bool open(void* ptr);
+ void idle();
+ void close();
private:
- CDraw *draw;
- CBitmap *background;
- long xtimer;
+ CDraw* draw;
+ CBitmap* background;
+ long xtimer;
};
-#endif //_mdaSpecMeterGUI_h_
+#endif // _mdaSpecMeterGUI_h_
diff --git a/src/mdaspecmeter.cpp b/src/mdaspecmeter.cpp
deleted file mode 100644
index 475a7c5..0000000
--- a/src/mdaspecmeter.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-//
-// Plug-in: "MDA Template" v1.0
-//
-// Copyright(c)2002 Paul Kellett (maxim digital audio)
-//
-
-
-#include <stdio.h>
-#include <string.h>
-#include <float.h>
-#include <math.h>
-
-#include "mdaSpecMeter.h"
-#include "mdaSpecMeterGUI.h"
-//#include "AEffEditor.hpp"
-
-AudioEffect *createEffectInstance(audioMasterCallback audioMaster)
-{
- return new mdaSpecMeter(audioMaster);
-}
-
-mdaSpecMeterProgram::mdaSpecMeterProgram()
-{
- param[_PARAM0] = 0.5;
- param[_PARAM1] = 0.5;
- param[_PARAM2] = 0.75;
- strcpy (name, "default");
-}
-
-
-mdaSpecMeter::mdaSpecMeter(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, 1, NPARAMS)
-{
- editor = new mdaSpecMeterGUI(this);
-
- programs = new mdaSpecMeterProgram[numPrograms];
- if(programs)
- {
- setProgram(0);
- }
-
- setNumInputs(2);
- setNumOutputs(2);
- DECLARE_LVZ_DEPRECATED(canMono) ();
- setUniqueID("mdaSpecMeter");
- canProcessReplacing();
-
- //initialise...
- K = counter = 0;
- kmax = 2048;
- topband = 11;
- iK = 1.0f / (float)kmax;
- den = 1.0e-8f;
-
- //buffer = new float[44100];
-
- suspend();
-}
-
-bool mdaSpecMeter::getProductString(char* text) { strcpy(text, "MDA SpecMeter"); return true; }
-bool mdaSpecMeter::getVendorString(char* text) { strcpy(text, "mda"); return true; }
-bool mdaSpecMeter::getEffectName(char* name) { strcpy(name, "SpecMeter"); return true; }
-
-void mdaSpecMeter::suspend()
-{
- Lpeak = Rpeak = Lrms = Rrms = Corr = 0.0f;
- lpeak = rpeak = lrms = rrms = corr = 0.0f;
- Lhold = Rhold = 0.0f;
- Lmin = Rmin = 0.0000001f;
- for(long i=0; i<16; i++)
- {
- band[0][i] = band[1][i] = 0.0f;
- for(long j=0; j<6; j++) lpp[j][i] = rpp[j][i] = 0.0f;
- }
-
- //memset(buffer, 0, size * sizeof (float));
-}
-
-void mdaSpecMeter::setSampleRate(float sampleRate)
-{
- AudioEffectX::setSampleRate(sampleRate);
- if(sampleRate > 64000) { topband = 12; kmax = 4096; }
- else { topband = 11; kmax = 2048; }
- iK = 1.0f / (float)kmax;
-}
-
-
-mdaSpecMeter::~mdaSpecMeter()
-{
- //if(buffer) delete [] buffer;
- if(programs) delete [] programs;
-}
-
-
-void mdaSpecMeter::setProgramName(char *name) { strcpy(programs[curProgram].name, name); }
-void mdaSpecMeter::getProgramName(char *name) { strcpy(name, programs[curProgram].name); }
-float mdaSpecMeter::getParameter(LvzInt32 index) { return param[index]; }
-
-void mdaSpecMeter::setProgram(LvzInt32 program)
-{
- mdaSpecMeterProgram *p = &programs[program];
- curProgram = program;
- setProgramName(p->name);
- for(long i=0; i<NPARAMS; i++) setParameter(i, p->param[i]);
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-
-void mdaSpecMeter::setParameter(LvzInt32 index, float value)
-{
- mdaSpecMeterProgram *p = &programs[curProgram];
- param[index] = p->param[index] = value;
-
- switch(index)
- {
- case _PARAM0: gain = (float)pow(10.0f, 2.0f * param[index] - 1.0f); break;
-
- default: break;
- }
-
- //if(editor) editor->postUpdate();
-}
-
-
-void mdaSpecMeter::getParameterName(LvzInt32 index, char *label)
-{
- switch (index)
- {
- case _PARAM0: strcpy (label, ""); break;
- default : strcpy (label, "");
- }
-}
-
-
-void mdaSpecMeter::getParameterDisplay(LvzInt32 index, char *text)
-{
- char string[16];
-
- switch (index)
- {
- case _PARAM0: sprintf(string, "%.1f", 40.0f * param[index] - 20.0f); break;
- case _PARAM1: strcpy (string, ""); break;
- default : sprintf(string, "%.0f", 100.0f * param[index]);
- }
- string[8] = 0;
- strcpy(text, (char *)string);
-}
-
-
-void mdaSpecMeter::getParameterLabel(LvzInt32 index, char *label)
-{
- switch (index)
- {
- case _PARAM0: strcpy(label, ""); break;
- default : strcpy(label, "");
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-
-void mdaSpecMeter::process (float **inputs, float **outputs, LvzInt32 sampleFrames)
-{
- float *in1 = inputs[0];
- float *in2 = inputs[1];
- float *out1 = outputs[0];
- float *out2 = outputs[1];
-
- den = -den;
- float l, r, p, q, iN = iK;
- long k=K, j0=topband, mask, j;
-
- while(--sampleFrames >= 0)
- {
- l = *in1++;
- r = *in2++;
- *out1++ += l;
- *out2++ += r;
-
- l += den; //anti-denormal
- r += den;
-
- lrms += l * l; //RMS integrate
- rrms += r * r;
-
- p = (float)fabs(l); if(p > lpeak) lpeak = p; //peak detect
- q = (float)fabs(r); if(q > rpeak) rpeak = q;
-/*
- if(p > 1.0e-8f && p < lmin) lmin = p; //'trough' detect
- if(q > 1.0e-8f && q < rmin) rmin = q;
-*/
- if((l * r) > 0.0f) corr += iN; //measure correlation
-
- j = j0;
- mask = k << 1;
-
- do //polyphase filter bank
- {
- p = lpp[0][j] + 0.208f * l;
- lpp[0][j] = lpp[1][j];
- lpp[1][j] = l - 0.208f * p;
-
- q = lpp[2][j] + lpp[4][j] * 0.682f;
- lpp[2][j] = lpp[3][j];
- lpp[3][j] = lpp[4][j] - 0.682f * q;
- lpp[4][j] = l;
- lpp[5][j] += (float)fabs(p - q); //top octave
- l = p + q; //lower octaves
-
- p = rpp[0][j] + 0.208f * r;
- rpp[0][j] = rpp[1][j];
- rpp[1][j] = r - 0.208f * p;
-
- q = rpp[2][j] + rpp[4][j] * 0.682f;
- rpp[2][j] = rpp[3][j];
- rpp[3][j] = rpp[4][j] - 0.682f * q;
- rpp[4][j] = r;
- rpp[5][j] += (float)fabs(p - q); //top octave
- r = p + q; //lower octaves
-
- j--;
- mask >>= 1;
- } while(mask & 1);
-
- if(++k == kmax)
- {
- k = 0;
- counter++; //editor waits for this to change
-
- if(lpeak == 0.0f) Lpeak = Lrms = 0.0f; else ///add limits here!
- {
- if(lpeak > 2.0f) lpeak = 2.0f;
- if(lpeak >= Lpeak)
- {
- Lpeak = lpeak;
- Lhold = 2.0f * Lpeak;
- }
- else
- {
- Lhold *= 0.95f;
- if(Lhold < Lpeak) Lpeak = Lhold;
- }
- Lmin = lmin;
- lmin *= 1.01f;
- Lrms += 0.2f * (iN * lrms - Lrms);
- }
-
- if(rpeak == 0.0f) Rpeak = Rrms = 0.0f; else
- {
- if(rpeak > 2.0f) rpeak = 2.0f;
- if(rpeak >= Rpeak)
- {
- Rpeak = rpeak;
- Rhold = 2.0f * Rpeak;
- }
- else
- {
- Rhold *= 0.95f;
- if(Rhold < Rpeak) Rpeak = Rhold;
- }
- Rmin = rmin;
- rmin *= 1.01f;
- Rrms += 0.2f * (iN * rrms - Rrms);
- }
-
- rpeak = lpeak = lrms = rrms = 0.0f;
- Corr += 0.1f * (corr - Corr); //correlation
- corr = SILENCE;
-
- float dec = 0.08f;
- for(j=0; j<13; j++) //spectrum output
- {
- band[0][j] += dec * (iN * lpp[5][j] - band[0][j]);
- if(band[0][j] > 2.0f) band[0][j] = 2.0f;
- else if(band[0][j] < 0.014f) band[0][j] = 0.014f;
-
- band[1][j] += dec * (iN * rpp[5][j] - band[1][j]);
- if(band[1][j] > 2.0f) band[1][j] = 2.0f;
- else if(band[1][j] < 0.014f) band[1][j] = 0.014f;
-
- rpp[5][j] = lpp[5][j] = SILENCE;
- dec = dec * 1.1f;
- }
- }
- }
-
- K = k;
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-
-void mdaSpecMeter::processReplacing (float **inputs, float **outputs, LvzInt32 sampleFrames)
-{
- float *in1 = inputs[0];
- float *in2 = inputs[1];
- float *out1 = outputs[0];
- float *out2 = outputs[1];
-
- den = -den;
- float l, r, p, q, iN = iK;
- long k=K, j0=topband, mask, j;
-
- while(--sampleFrames >= 0)
- {
- l = *in1++;
- r = *in2++;
- *out1++ = l;
- *out2++ = r;
-
- l += den; //anti-denormal
- r += den;
-
- lrms += l * l; //RMS integrate
- rrms += r * r;
-
- p = (float)fabs(l); if(p > lpeak) lpeak = p; //peak detect
- q = (float)fabs(r); if(q > rpeak) rpeak = q;
-/*
- if(p > 1.0e-8f && p < lmin) lmin = p; //'trough' detect
- if(q > 1.0e-8f && q < rmin) rmin = q;
-*/
- if((l * r) > 0.0f) corr += iN; //measure correlation
-
- j = j0;
- mask = k << 1;
-
- do //polyphase filter bank
- {
- p = lpp[0][j] + 0.208f * l;
- lpp[0][j] = lpp[1][j];
- lpp[1][j] = l - 0.208f * p;
-
- q = lpp[2][j] + lpp[4][j] * 0.682f;
- lpp[2][j] = lpp[3][j];
- lpp[3][j] = lpp[4][j] - 0.682f * q;
- lpp[4][j] = l;
- lpp[5][j] += (float)fabs(p - q); //top octave
- l = p + q; //lower octaves
-
- p = rpp[0][j] + 0.208f * r;
- rpp[0][j] = rpp[1][j];
- rpp[1][j] = r - 0.208f * p;
-
- q = rpp[2][j] + rpp[4][j] * 0.682f;
- rpp[2][j] = rpp[3][j];
- rpp[3][j] = rpp[4][j] - 0.682f * q;
- rpp[4][j] = r;
- rpp[5][j] += (float)fabs(p - q); //top octave
- r = p + q; //lower octaves
-
- j--;
- mask >>= 1;
- } while(mask & 1);
-
- if(++k == kmax)
- {
- k = 0;
- counter++; //editor waits for this to change
-
- if(lpeak == 0.0f) Lpeak = Lrms = 0.0f; else ///add limits here!
- {
- if(lpeak > 2.0f) lpeak = 2.0f;
- if(lpeak >= Lpeak)
- {
- Lpeak = lpeak;
- Lhold = 2.0f * Lpeak;
- }
- else
- {
- Lhold *= 0.95f;
- if(Lhold < Lpeak) Lpeak = Lhold;
- }
- Lmin = lmin;
- lmin *= 1.01f;
- Lrms += 0.2f * (iN * lrms - Lrms);
- }
-
- if(rpeak == 0.0f) Rpeak = Rrms = 0.0f; else
- {
- if(rpeak > 2.0f) rpeak = 2.0f;
- if(rpeak >= Rpeak)
- {
- Rpeak = rpeak;
- Rhold = 2.0f * Rpeak;
- }
- else
- {
- Rhold *= 0.95f;
- if(Rhold < Rpeak) Rpeak = Rhold;
- }
- Rmin = rmin;
- rmin *= 1.01f;
- Rrms += 0.2f * (iN * rrms - Rrms);
- }
-
- rpeak = lpeak = lrms = rrms = 0.0f;
- Corr += 0.1f * (corr - Corr); //correlation
- corr = SILENCE;
-
- float dec = 0.08f;
- for(j=0; j<13; j++) //spectrum output
- {
- band[0][j] += dec * (iN * lpp[5][j] - band[0][j]);
- if(band[0][j] > 2.0f) band[0][j] = 2.0f;
- else if(band[0][j] < 0.014f) band[0][j] = 0.014f;
-
- band[1][j] += dec * (iN * rpp[5][j] - band[1][j]);
- if(band[1][j] > 2.0f) band[1][j] = 2.0f;
- else if(band[1][j] < 0.014f) band[1][j] = 0.014f;
-
- rpp[5][j] = lpp[5][j] = SILENCE;
- dec = dec * 1.1f;
- }
- }
- }
-
- K = k;
-}