diff options
author | David Robillard <d@drobilla.net> | 2008-08-12 00:20:16 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2008-08-12 00:20:16 +0000 |
commit | 102e899c331bd2ed9902467a077164e209c918f9 (patch) | |
tree | b7fe5ec873582cc8a0fc0862f9da045d12b2259a /src | |
parent | 2b679f152e1c3104ac178b6c78ac0b1edf954ff6 (diff) | |
download | mda.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.cpp | 482 | ||||
-rw-r--r-- | src/mdaSpecMeter.h | 19 | ||||
-rw-r--r-- | src/mdaSpecMeterGUI.cpp | 390 | ||||
-rw-r--r-- | src/mdaSpecMeterGUI.h | 36 | ||||
-rw-r--r-- | src/mdaspecmeter.cpp | 416 |
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; -} |