@@ -40,6 +40,7 @@ mandir = @mandir@ | |||
HEADERS = ../SpiralPlugin.h \ | |||
../SpiralPluginGUI.h \ | |||
../../ChannelHandler.h \ | |||
../Widgets/Fl_DragBar.H \ | |||
../Widgets/Fl_SevenSeg.H \ | |||
../Widgets/Fl_VU_Meter.h \ | |||
@@ -48,6 +49,7 @@ HEADERS = ../SpiralPlugin.h \ | |||
MeterPluginGUI.h | |||
SOURCES = ../SpiralPlugin.C \ | |||
../SpiralPluginGUI.C \ | |||
../../ChannelHandler.C \ | |||
../Widgets/Fl_DragBar.cxx \ | |||
../Widgets/Fl_SevenSeg.cxx \ | |||
../Widgets/Fl_VU_Meter.cxx \ | |||
@@ -56,6 +58,7 @@ SOURCES = ../SpiralPlugin.C \ | |||
MeterPluginGUI.C | |||
OBJECTS = ../SpiralPlugin.o \ | |||
../SpiralPluginGUI.o \ | |||
../../ChannelHandler.o \ | |||
../Widgets/Fl_DragBar.o \ | |||
../Widgets/Fl_SevenSeg.o \ | |||
../Widgets/Fl_VU_Meter.o \ | |||
@@ -169,3 +172,5 @@ MeterPluginGUI.o: MeterPluginGUI.C \ | |||
../../Sample.h \ | |||
../SpiralPluginGUI.h | |||
../../ChannelHandler.o: ../../ChannelHandler.C \ | |||
../../ChannelHandler.h |
@@ -20,42 +20,66 @@ | |||
#include "SpiralIcon.xpm" | |||
extern "C" { | |||
SpiralPlugin* CreateInstance() { return new MeterPlugin; } | |||
char** GetIcon() { return SpiralIcon_xpm; } | |||
int GetID() { return 123; } | |||
} | |||
/////////////////////////////////////////////////////// | |||
} | |||
MeterPlugin::MeterPlugin() { | |||
m_PluginInfo.Name = "Meter"; | |||
m_PluginInfo.Width = 230; | |||
m_PluginInfo.Height = 108; | |||
m_PluginInfo.NumInputs = 1; | |||
m_PluginInfo.NumOutputs = 1; | |||
m_PluginInfo.PortTips.push_back ("Input"); | |||
m_PluginInfo.PortTips.push_back ("Output"); | |||
m_PluginInfo.Name = "Meter"; | |||
m_PluginInfo.Width = 230; | |||
m_PluginInfo.Height = 128; | |||
m_PluginInfo.NumInputs = 1; | |||
m_PluginInfo.NumOutputs = 1; | |||
m_PluginInfo.PortTips.push_back ("Input"); | |||
m_PluginInfo.PortTips.push_back ("Output"); | |||
m_Data = NULL; | |||
} | |||
MeterPlugin::~MeterPlugin() { | |||
if (m_Data != NULL) delete m_Data; | |||
} | |||
PluginInfo &MeterPlugin::Initialise (const HostInfo *Host) { | |||
PluginInfo& Info = SpiralPlugin::Initialise (Host); | |||
return Info; | |||
PluginInfo& Info = SpiralPlugin::Initialise (Host); | |||
m_Data = new float[Host->BUFSIZE]; | |||
m_AudioCH->RegisterData ("AudioData", ChannelHandler::OUTPUT, m_Data, Host->BUFSIZE * sizeof (float)); | |||
return Info; | |||
} | |||
SpiralGUIType *MeterPlugin::CreateGUI() { | |||
m_GUI = new MeterPluginGUI (m_PluginInfo.Width, m_PluginInfo.Height, this, m_HostInfo); | |||
m_GUI->hide(); | |||
return m_GUI; | |||
return new MeterPluginGUI (m_PluginInfo.Width, m_PluginInfo.Height, this, m_AudioCH, m_HostInfo); | |||
} | |||
void MeterPlugin::Execute() { | |||
// Just copy the data through. | |||
if (GetOutputBuf (0)) GetOutputBuf (0)->Zero(); | |||
if (GetInput (0)) GetOutputBuf (0)->Mix (*GetInput(0), 0); | |||
m_GUI->redraw(); | |||
// Just copy the data through. | |||
if (GetOutputBuf (0)) GetOutputBuf (0)->Zero(); | |||
if (GetInput (0)) { | |||
GetOutputBuf (0)->Mix (*GetInput(0), 0); | |||
memcpy (m_Data, GetInput (0)->GetBuffer (), m_HostInfo->BUFSIZE * sizeof (float)); | |||
} | |||
} | |||
void MeterPlugin::ExecuteCommands () { | |||
if (m_AudioCH->IsCommandWaiting ()) { | |||
switch (m_AudioCH->GetCommand()) { | |||
case (SETVU) : m_VUMode = true; | |||
break; | |||
case (SETMM) : m_VUMode = false; | |||
break; | |||
} | |||
} | |||
} | |||
void MeterPlugin::StreamOut (ostream &s) { | |||
s << m_Version << " " << m_VUMode << " "; | |||
} | |||
void MeterPlugin::StreamIn (istream &s) { | |||
int Version; | |||
s >> Version >> m_VUMode; | |||
} |
@@ -14,25 +14,28 @@ | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
*/ | |||
*/ | |||
#ifndef METERPLUGIN | |||
#define METERPLUGIN | |||
#include "../SpiralPlugin.h" | |||
#include <FL/Fl_Pixmap.H> | |||
class MeterPlugin : public SpiralPlugin { | |||
public: | |||
MeterPlugin(); | |||
virtual ~MeterPlugin(); | |||
virtual PluginInfo& Initialise (const HostInfo *Host); | |||
virtual SpiralGUIType* CreateGUI(); | |||
virtual void Execute(); | |||
virtual void StreamOut (ostream &s) {} | |||
virtual void StreamIn (istream &s) {} | |||
// has to be defined in the plugin | |||
virtual void UpdateGUI() { Fl::check(); } | |||
public: | |||
MeterPlugin(); | |||
virtual ~MeterPlugin(); | |||
virtual PluginInfo& Initialise (const HostInfo *Host); | |||
virtual SpiralGUIType* CreateGUI(); | |||
virtual void Execute(); | |||
virtual void ExecuteCommands(); | |||
virtual void StreamOut (ostream &s); | |||
virtual void StreamIn (istream &s); | |||
int GetVUMode (void) { return m_VUMode; } | |||
enum GUICommands {NONE, SETVU, SETMM}; | |||
private: | |||
float *m_Data; | |||
bool m_VUMode; // This value isn't USED for anything, it's here so we can save/load it | |||
}; | |||
#endif |
@@ -1,19 +0,0 @@ | |||
HEADERS = ../SpiralPlugin.h \ | |||
../SpiralPluginGUI.h \ | |||
../Widgets/Fl_DragBar.H \ | |||
../Widgets/Fl_VU_Meter.h \ | |||
../Widgets/Fl_SevenSeg.H \ | |||
../../Sample.h \ | |||
MeterPlugin.h \ | |||
MeterPluginGUI.h | |||
SOURCES = ../SpiralPlugin.C \ | |||
../SpiralPluginGUI.C \ | |||
../Widgets/Fl_DragBar.cxx \ | |||
../Widgets/Fl_VU_Meter.cxx \ | |||
../Widgets/Fl_SevenSeg.cxx \ | |||
../../Sample.C \ | |||
MeterPlugin.C \ | |||
MeterPluginGUI.C | |||
TARGET = MeterPlugin.so |
@@ -25,102 +25,160 @@ static const int GUIBG2_COLOUR = 145; | |||
char label_buf[10]; | |||
MeterPluginGUI::MeterPluginGUI(int w, int h, MeterPlugin *o, const HostInfo *Info) : | |||
SpiralPluginGUI (w, h, o), | |||
m_Bypass(0) { | |||
m_Plugin=o; | |||
Bypass = new Fl_Button (175, 2, 40, 16, "Bypass"); | |||
Bypass -> labelsize (10); | |||
Bypass -> type (1); | |||
Bypass -> callback ((Fl_Callback*)cb_Bypass); | |||
add (Bypass); | |||
for (int display=0; display<8; display++) { | |||
Digits[display] = new Fl_SevenSeg ((display*28)+2, 20, 28, 40); | |||
Digits[display] -> bar_width (4); | |||
Digits[display] -> color (FL_WHITE); | |||
Digits[display] -> color2 (GUI_COLOUR); | |||
add (Digits[display]); | |||
} | |||
MinBox = new Fl_Output (2, 84, 84, 20); | |||
MinBox -> box (FL_ENGRAVED_BOX); | |||
MinBox -> color (16); | |||
MinBox -> set_output(); | |||
add (MinBox); | |||
Reset = new Fl_Button (88, 84, 54, 20, "Reset"); | |||
Reset -> labelsize (10); | |||
Reset -> type (0); | |||
Reset -> callback ((Fl_Callback*)cb_Reset); | |||
add (Reset); | |||
MaxBox = new Fl_Output (144, 84, 84, 20); | |||
MaxBox->set_output(); | |||
MaxBox->box (FL_ENGRAVED_BOX); | |||
MaxBox->color (16); | |||
add (MaxBox); | |||
Meter = new Fl_VU_Meter (2, 62, 226, 20); | |||
Meter->color (FL_BLACK); | |||
cb_Reset_i (Reset, NULL); | |||
add (Reset); | |||
end(); | |||
} | |||
void MeterPluginGUI::Display (const float *data) { | |||
if (! m_Bypass) { | |||
snprintf (label_buf, 64, "%1.5f", *data); | |||
if (Meter->minimum() > *data) SetMin (*data); | |||
if (Meter->maximum() < *data) SetMax (*data); | |||
Meter->value (*data); | |||
Meter->redraw(); | |||
char* c = label_buf; | |||
for (int display=0; display<8; display++) { | |||
Digits[display] -> dp (off); | |||
if (*c == 0) Digits[display] -> value (0); | |||
else { | |||
if (*c == '.') { | |||
Digits[display] -> dp (point); | |||
c++; | |||
} | |||
int val; | |||
if (*c == '-') val = -1; else val = (int)*c - (int)'0'; | |||
Digits[display] -> value (val); | |||
c++; | |||
} | |||
} | |||
} | |||
MeterPluginGUI::MeterPluginGUI (int w, int h, MeterPlugin *o, ChannelHandler *ch, const HostInfo *Info) : | |||
SpiralPluginGUI (w, h, o, ch), | |||
m_Bypass (false) | |||
{ | |||
// If I'm only going to use the first value from this, is it worth doing all this | |||
m_BufSize = Info->BUFSIZE; | |||
m_Data = new float[m_BufSize]; | |||
// Create the widgets and stuff! | |||
Bypass = new Fl_Button (2, 18, 54, 20, "Bypass"); | |||
Bypass -> labelsize (10); | |||
Bypass -> type (1); | |||
Bypass -> callback ((Fl_Callback*)cb_Bypass); | |||
add (Bypass); | |||
VUMode = new Fl_Check_Button (86, 18, 54, 20, "VU"); | |||
VUMode->type (FL_RADIO_BUTTON); | |||
VUMode->down_box (FL_DIAMOND_DOWN_BOX); | |||
VUMode->selection_color (GUI_COLOUR); | |||
VUMode->callback ((Fl_Callback*)cb_Mode); | |||
VUMode->set(); | |||
add (VUMode); | |||
MMMode = new Fl_Check_Button (142, 18, 54, 20, "Min/Max"); | |||
MMMode->type (FL_RADIO_BUTTON); | |||
MMMode->down_box (FL_DIAMOND_DOWN_BOX); | |||
MMMode->selection_color (GUI_COLOUR); | |||
MMMode->callback ((Fl_Callback*)cb_Mode); | |||
add (MMMode); | |||
for (int display=0; display<8; display++) { | |||
Digits[display] = new Fl_SevenSeg ((display*28)+2, 40, 28, 40); | |||
Digits[display] -> bar_width (4); | |||
Digits[display] -> color (FL_WHITE); | |||
Digits[display] -> color2 (GUI_COLOUR); | |||
add (Digits[display]); | |||
} | |||
MinBox = new Fl_Output (2, 104, 84, 20); | |||
MinBox -> box (FL_ENGRAVED_BOX); | |||
MinBox -> color (16); | |||
MinBox -> set_output(); | |||
add (MinBox); | |||
Reset = new Fl_Button (88, 104, 54, 20, "Reset"); | |||
Reset -> labelsize (10); | |||
Reset -> type (0); | |||
Reset -> callback ((Fl_Callback*)cb_Reset); | |||
add (Reset); | |||
MaxBox = new Fl_Output (144, 104, 84, 20); | |||
MaxBox->set_output(); | |||
MaxBox->box (FL_ENGRAVED_BOX); | |||
MaxBox->color (16); | |||
add (MaxBox); | |||
Meter = new Fl_VU_Meter (2, 82, 226, 20); | |||
Meter->color (FL_BLACK); | |||
cb_Reset_i (Reset, NULL); | |||
add (Reset); | |||
end (); | |||
DoReset (); | |||
} | |||
void MeterPluginGUI::draw() { | |||
SpiralGUIType::draw(); | |||
if (m_Plugin->GetInput(0) != NULL) { | |||
Display (m_Plugin->GetInput(0)->GetBuffer()); | |||
} | |||
SpiralGUIType::draw (); | |||
if (! m_Bypass) { | |||
m_GUICH->GetData ("AudioData", m_Data); | |||
// The min and max values are based on the whole buffer | |||
for (int c=0; c<m_BufSize; c++) { | |||
if (VUMode->value ()) m_Data[c] = fabs (m_Data[c]); | |||
if (m_Data[c] < m_Min) m_Min=m_Data[c]; | |||
if (m_Data[c] > m_Max) m_Max=m_Data[c]; | |||
} | |||
SetMinMax (m_Min, m_Max); | |||
// The meter displays the first datum in the buffer (it's a quick average) | |||
Meter->value (*m_Data); | |||
Meter->redraw(); | |||
snprintf (label_buf, 64, "%1.5f", *m_Data); | |||
char* c = label_buf; | |||
for (int display=0; display<8; display++) { | |||
Digits[display] -> dp (off); | |||
if (*c == 0) Digits[display] -> value (0); | |||
else { | |||
if (*c == '.') { | |||
Digits[display] -> dp (point); | |||
c++; | |||
} | |||
int val; | |||
if (*c == '-') val = -1; else val = (int)*c - (int)'0'; | |||
Digits[display] -> value (val); | |||
c++; | |||
} | |||
} | |||
} | |||
} | |||
void MeterPluginGUI::UpdateValues() { | |||
void MeterPluginGUI::Update () { | |||
redraw(); | |||
} | |||
void MeterPluginGUI::SetMax (float NewValue) { | |||
Meter->maximum (NewValue); | |||
MaxBox->value (label_buf); | |||
void MeterPluginGUI::UpdateValues (SpiralPlugin* o) { | |||
MeterPlugin* Plugin = (MeterPlugin*)o; | |||
VUMode->value (Plugin->GetVUMode ()); | |||
MMMode->value (! Plugin->GetVUMode ()); | |||
} | |||
void MeterPluginGUI::SetMin (float NewValue) { | |||
Meter->minimum (NewValue); | |||
MinBox->value (label_buf); | |||
void MeterPluginGUI::SetMinMax (float NewMin, float NewMax) { | |||
m_Min = NewMin; | |||
m_Max = NewMax; | |||
snprintf (label_buf, 64, "%1.5f", m_Min); | |||
MinBox->value (label_buf); | |||
snprintf (label_buf, 64, "%1.5f", m_Max); | |||
MaxBox->value (label_buf); | |||
if (MMMode->value ()) { | |||
Meter->minimum (m_Min); | |||
Meter->maximum (m_Max); | |||
} | |||
else { | |||
Meter->minimum (0.0); | |||
Meter->maximum (1.0); | |||
if (m_Max > 1.0) { | |||
MaxBox->color (FL_RED); | |||
} | |||
} | |||
} | |||
void MeterPluginGUI::cb_Bypass_i (Fl_Button* o, void* v) { | |||
m_Bypass = o->value(); | |||
m_Bypass = o->value(); | |||
} | |||
void MeterPluginGUI::cb_Bypass (Fl_Button* o, void* v) { | |||
((MeterPluginGUI*)(o->parent()))->cb_Bypass_i (o,v); | |||
((MeterPluginGUI*)(o->parent()))->cb_Bypass_i (o, v); | |||
} | |||
void MeterPluginGUI::DoReset (void) { | |||
MaxBox->color (16); | |||
SetMinMax (10, -10); // Yes, I know that LOOKS the wrong way round, but it isn't! | |||
} | |||
void MeterPluginGUI::cb_Reset_i (Fl_Button* o, void* v) { | |||
SetMin (10); // Yes, I know that LOOKS the wrong way round, but it isn't! | |||
SetMax (-10); | |||
DoReset (); | |||
} | |||
void MeterPluginGUI::cb_Reset (Fl_Button* o, void* v) { | |||
((MeterPluginGUI*)(o->parent()))->cb_Reset_i (o,v); | |||
((MeterPluginGUI*)(o->parent()))->cb_Reset_i (o, v); | |||
} | |||
void MeterPluginGUI::cb_Mode_i (Fl_Check_Button* o, void* v) { | |||
DoReset (); | |||
if (o==VUMode) m_GUICH->SetCommand (MeterPlugin::SETVU); | |||
else m_GUICH->SetCommand (MeterPlugin::SETMM); | |||
} | |||
void MeterPluginGUI::cb_Mode (Fl_Check_Button* o, void* v) { | |||
((MeterPluginGUI*)(o->parent()))->cb_Mode_i (o, v); | |||
} | |||
const string MeterPluginGUI::GetHelpText (const string &loc) { | |||
return string ("") | |||
+ "The Meter lets you see a numeric representation of the\n" | |||
+ "data flowing through it. It does nothing to the signal,\n" | |||
+ "but its very useful for checking the layouts, looking at\n" | |||
+ "CV value etc.\n"; | |||
} |
@@ -23,30 +23,36 @@ | |||
#include "../Widgets/Fl_VU_Meter.h" | |||
#include "../Widgets/Fl_SevenSeg.H" | |||
#include <FL/Fl_Button.H> | |||
#include <FL/Fl_Check_Button.H> | |||
#include <FL/Fl_Output.H> | |||
#include "MeterPlugin.h" | |||
#include "../SpiralPluginGUI.h" | |||
class MeterPluginGUI : public SpiralPluginGUI { | |||
public: | |||
MeterPluginGUI (int w, int h, MeterPlugin *o, const HostInfo *Info); | |||
virtual void UpdateValues(); | |||
virtual void draw(); | |||
void Display (const float *data); | |||
virtual SpiralPlugin* GetPlugin() { return m_Plugin; } | |||
MeterPlugin *m_Plugin; | |||
private: | |||
int m_Bypass; | |||
void SetMax (float NewValue); | |||
void SetMin (float NewValue); | |||
Fl_SevenSeg *Digits[8]; | |||
Fl_Output *MaxBox, *MinBox; | |||
Fl_Button *Reset, *Bypass; | |||
Fl_VU_Meter *Meter; | |||
inline void cb_Reset_i (Fl_Button* o, void* v); | |||
static void cb_Reset (Fl_Button* o, void* v); | |||
inline void cb_Bypass_i (Fl_Button* o, void* v); | |||
static void cb_Bypass (Fl_Button* o, void* v); | |||
public: | |||
MeterPluginGUI (int w, int h, MeterPlugin *o, ChannelHandler *ch, const HostInfo *Info); | |||
virtual void UpdateValues (SpiralPlugin* o); | |||
virtual void Update (); | |||
virtual void draw (); | |||
protected: | |||
const string GetHelpText (const string &loc); | |||
private: | |||
bool m_Bypass; | |||
float *m_Data, m_Min, m_Max; | |||
int m_BufSize; | |||
void SetMinMax (float NewMin, float NewMax); | |||
inline void DoReset (void); | |||
Fl_SevenSeg *Digits[8]; | |||
Fl_Output *MaxBox, *MinBox; | |||
Fl_Button *Reset, *Bypass; | |||
Fl_Check_Button *VUMode, *MMMode; | |||
Fl_VU_Meter *Meter; | |||
inline void cb_Reset_i (Fl_Button* o, void* v); | |||
static void cb_Reset (Fl_Button* o, void* v); | |||
inline void cb_Bypass_i (Fl_Button* o, void* v); | |||
static void cb_Bypass (Fl_Button* o, void* v); | |||
inline void cb_Mode_i (Fl_Check_Button* o, void* v); | |||
static void cb_Mode (Fl_Check_Button* o, void* v); | |||
}; | |||
#endif |