diff --git a/plugins/NeuralRecord/CairoWidgets.hpp b/plugins/NeuralRecord/CairoWidgets.hpp index 968c992..c5b0090 100644 --- a/plugins/NeuralRecord/CairoWidgets.hpp +++ b/plugins/NeuralRecord/CairoWidgets.hpp @@ -18,6 +18,72 @@ START_NAMESPACE_DISTRHO +class CairoColourTheme +{ +public: + CairoColourTheme() + { + init(); + } + + struct CairoColour{ + double r; + double g; + double b; + double a; + }; + + void setCairoColour(cairo_t* const cr, const CairoColour idColour, bool darken = false) + { + double darker = 1.0; + if (darken) darker = 0.8; + cairo_set_source_rgba(cr, idColour.r * darker, idColour.g * darker, + idColour.b * darker, idColour.a); + } + + void setIdColour(CairoColour &idColour, double r, double g, double b, double a) { + idColour = CairoColour {r, g, b, a}; + } + + CairoColour idColourBackground; + CairoColour idColourBackgroundNormal; + CairoColour idColourBackgroundPrelight; + CairoColour idColourBackgroundActive; + CairoColour idColourBackgroundProgress; + + CairoColour idColourForground; + CairoColour idColourForgroundNormal; + CairoColour idColourForgroundActive; + + CairoColour idColourFrame; + + CairoColour idColourShadow; + CairoColour idColourLight; + +protected: + + void init() + { + setIdColour(idColourBackground, 0.13, 0.13, 0.13, 1); + setIdColour(idColourBackgroundNormal, 0.13, 0.13, 0.13, 1.0); + setIdColour(idColourBackgroundPrelight, 0.63, 0.63, 0.63, 0.03); + setIdColour(idColourBackgroundActive, 0.63, 0.13, 0.13, 1.0); + setIdColour(idColourBackgroundProgress, 0.4, 0.4, 0.4, 1.0); + + setIdColour(idColourForground, 0.63, 0.63, 0.63, 1.0); + setIdColour(idColourForgroundNormal, 0.63, 0.63, 0.63, 1.0); + setIdColour(idColourForgroundActive, 0.93, 0.63, 0.63, 1.0); + + setIdColour(idColourFrame, 0.03, 0.03, 0.03, 1.0); + + setIdColour(idColourShadow, 0.05, 0.05, 0.05, 1.0); + setIdColour(idColourLight, 0.33, 0.33, 0.33, 1.0); + } + +private: + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CairoColourTheme) +}; + // ----------------------------------------------------------------------- class CairoShadows @@ -115,24 +181,27 @@ class CairoShadows class CairoButton : public CairoSubWidget, public CairoShadows { public: - explicit CairoButton(SubWidget* const parent, const char* lab, const uint32_t index) + + explicit CairoButton(SubWidget* const parent, CairoColourTheme &theme_, + UI *ui, const char* lab, const uint32_t index) : CairoSubWidget(parent), - setParameterValue([parent] (const uint32_t index, float value) - {dynamic_cast(parent)->setParameterValue(index, value);}), - label(lab), port(index) { - value = 0.0f; - state = 0; - prelight = false; + theme(theme_), + setParameterValue([ui] (const uint32_t index, float value) + {ui->setParameterValue(index, value);}), + label(lab), port(index) + { + init(); } - explicit CairoButton(TopLevelWidget* const parent, const char* lab, const uint32_t index) + explicit CairoButton(TopLevelWidget* const parent, CairoColourTheme &theme_, + UI *ui, const char* lab, const uint32_t index) : CairoSubWidget(parent), - setParameterValue([parent] (const uint32_t index, float value) - {dynamic_cast(parent)->setParameterValue(index, value);}), - label(lab), port(index) { - value = 0.0f; - state = 0; - prelight = false; + theme(theme_), + setParameterValue([ui] (const uint32_t index, float value) + {ui->setParameterValue(index, value);}), + label(lab), port(index) + { + init(); } void setValue(float v) @@ -143,6 +212,14 @@ class CairoButton : public CairoSubWidget, public CairoShadows } protected: + + void init() + { + value = 0.0f; + state = 0; + prelight = false; + } + void onCairoDisplay(const CairoGraphicsContext& context) override { cairo_t* const cr = context.handle; @@ -153,13 +230,13 @@ class CairoButton : public CairoSubWidget, public CairoShadows cairo_push_group (cr); if (!state) - cairo_set_source_rgba(cr, 0.13, 0.13, 0.13, 1.0); + theme.setCairoColour(cr, theme.idColourBackgroundNormal); else - cairo_set_source_rgba(cr, 0.63, 0.13, 0.13, 1.0); + theme.setCairoColour(cr, theme.idColourBackgroundActive); cairo_paint(cr); if (prelight) { - cairo_set_source_rgba(cr, 0.63, 0.63, 0.63, 0.03); + theme.setCairoColour(cr, theme.idColourBackgroundPrelight); cairo_paint(cr); } @@ -171,9 +248,9 @@ class CairoButton : public CairoSubWidget, public CairoShadows int offset = 0; cairo_text_extents_t extents; if(state==0) { - cairo_set_source_rgba(cr, 0.63, 0.63, 0.63, 1.0); + theme.setCairoColour(cr, theme.idColourForgroundNormal); } else if(state==1) { - cairo_set_source_rgba(cr, 0.93, 0.63, 0.63, 1.0); + theme.setCairoColour(cr, theme.idColourForgroundActive); offset = 2; } cairo_set_font_size (cr, h/2.2); @@ -220,6 +297,7 @@ class CairoButton : public CairoSubWidget, public CairoShadows } private: + CairoColourTheme &theme; std::function setParameterValue; float value; uint state; @@ -234,14 +312,19 @@ class CairoButton : public CairoSubWidget, public CairoShadows class CairoProgressBar : public CairoSubWidget, public CairoShadows { public: - explicit CairoProgressBar(SubWidget* const parent) - : CairoSubWidget(parent) { - value = 0.0f; + + explicit CairoProgressBar(SubWidget* const parent, CairoColourTheme &theme_) + : CairoSubWidget(parent), + theme(theme_) + { + init(); } - explicit CairoProgressBar(TopLevelWidget* const parent) - : CairoSubWidget(parent) { - value = 0.0f; + explicit CairoProgressBar(TopLevelWidget* const parent, CairoColourTheme &theme_) + : CairoSubWidget(parent), + theme(theme_) + { + init(); } void setValue(float v) @@ -251,6 +334,11 @@ class CairoProgressBar : public CairoSubWidget, public CairoShadows } protected: + void init() + { + value = 0.0f; + } + void onCairoDisplay(const CairoGraphicsContext& context) override { cairo_t* const cr = context.handle; @@ -260,12 +348,12 @@ class CairoProgressBar : public CairoSubWidget, public CairoShadows const int width = sz.getWidth(); const int height = sz.getHeight(); - cairo_set_source_rgba(cr, 0.03, 0.03, 0.03, 1.0); + theme.setCairoColour(cr,theme.idColourFrame); cairo_rectangle(cr,0, 0, width, height); cairo_set_line_width(cr,2); cairo_stroke(cr); - cairo_set_source_rgba(cr, 0.4, 0.4, 0.4, 1.0); + theme.setCairoColour(cr, theme.idColourBackgroundProgress); cairo_rectangle(cr,0, 0, width * value, height); cairo_fill(cr); @@ -275,7 +363,7 @@ class CairoProgressBar : public CairoSubWidget, public CairoShadows snprintf(s, 63,"%d%%", (int) (value * 100.0)); cairo_text_extents(cr,s , &extents); cairo_move_to (cr, width * 0.5 - extents.width * 0.5, height * 0.5 + extents.height * 0.5 ); - cairo_set_source_rgba(cr, 0.63, 0.63, 0.63, 1.0); + theme.setCairoColour(cr, theme.idColourForground); cairo_set_operator(cr, CAIRO_OPERATOR_ADD); cairo_show_text(cr, s); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); @@ -286,6 +374,7 @@ class CairoProgressBar : public CairoSubWidget, public CairoShadows } private: + CairoColourTheme &theme; float value; DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CairoProgressBar) }; @@ -295,20 +384,21 @@ class CairoProgressBar : public CairoSubWidget, public CairoShadows class CairoPeekMeter : public CairoSubWidget, public CairoShadows { public: - explicit CairoPeekMeter(SubWidget* const parent) + + explicit CairoPeekMeter(SubWidget* const parent, CairoColourTheme &theme_) : CairoSubWidget(parent), - image(nullptr) { - old_value = -70.0f; - std_value = -70.0f; - value = -70.0f; + image(nullptr), + theme(theme_) + { + init(); } - explicit CairoPeekMeter(TopLevelWidget* const parent) + explicit CairoPeekMeter(TopLevelWidget* const parent, CairoColourTheme &theme_) : CairoSubWidget(parent), - image(nullptr) { - old_value = -70.0f; - std_value = -70.0f; - value = -70.0f; + image(nullptr), + theme(theme_) + { + init(); } void setValue(float v) @@ -322,6 +412,13 @@ class CairoPeekMeter : public CairoSubWidget, public CairoShadows } protected: + void init() + { + old_value = -70.0f; + std_value = -70.0f; + value = -70.0f; + } + float power2db(float power) { const float falloff = 27 * 60 * 0.0005; @@ -381,7 +478,7 @@ class CairoPeekMeter : public CairoSubWidget, public CairoShadows cairo_t *cri = cairo_create (image); cairo_push_group (cri); - cairo_set_source_rgba(cri, 0.03, 0.03, 0.03, 1); + theme.setCairoColour(cri, theme.idColourFrame); cairo_paint(cri); cairo_pattern_t *pat = cairo_pattern_create_linear (0, 0, width, 0.0); @@ -438,7 +535,7 @@ class CairoPeekMeter : public CairoSubWidget, public CairoShadows char buf[32]; cairo_set_font_size (cr, (float)rect_height * 0.5); - cairo_set_source_rgba(cr, 0.6, 0.6, 0.6, 0.6); + theme.setCairoColour(cr, theme.idColourForground); for (unsigned int i = 0; i < sizeof (db_points)/sizeof (db_points[0]); ++i) { @@ -460,7 +557,7 @@ class CairoPeekMeter : public CairoSubWidget, public CairoShadows cairo_show_text (cr, buf); } - cairo_set_source_rgba(cr, 0.6, 0.6, 0.6, 0.6); + theme.setCairoColour(cr, theme.idColourForground); cairo_set_line_width(cr, 1.5); cairo_stroke(cr); } @@ -500,6 +597,7 @@ class CairoPeekMeter : public CairoSubWidget, public CairoShadows private: cairo_surface_t* image; + CairoColourTheme &theme; float value; float old_value; float std_value; @@ -511,18 +609,23 @@ class CairoPeekMeter : public CairoSubWidget, public CairoShadows class CairoToolTip : public CairoSubWidget, public Runner { public: - explicit CairoToolTip(SubWidget* const parent_, const char* lab) + + explicit CairoToolTip(SubWidget* const parent_, CairoColourTheme &theme_, const char* lab) : CairoSubWidget(parent_), - parent(parent_), label(lab) { - hide(); - state.store(false, std::memory_order_release); + parent(parent_), + theme(theme_), + label(lab) + { + init(); } - explicit CairoToolTip(TopLevelWidget* const parent_, const char* lab) + explicit CairoToolTip(TopLevelWidget* const parent_, CairoColourTheme &theme_, const char* lab) : CairoSubWidget(parent_), - parent(parent_), label(lab) { - hide(); - state.store(false, std::memory_order_release); + parent(parent_), + theme(theme_), + label(lab) + { + init(); } ~CairoToolTip() {if (isRunnerActive()) stopRunner();} @@ -545,6 +648,12 @@ class CairoToolTip : public CairoSubWidget, public Runner } protected: + void init() + { + hide(); + state.store(false, std::memory_order_release); + } + void onCairoDisplay(const CairoGraphicsContext& context) override { cairo_t* const cr = context.handle; @@ -553,14 +662,14 @@ class CairoToolTip : public CairoSubWidget, public Runner const Size sz = getSize(); const int w = sz.getWidth(); const int h = sz.getHeight(); - cairo_set_source_rgba(cr, 0.13, 0.13, 0.13, 1.0); + theme.setCairoColour(cr, theme.idColourBackground); cairo_rectangle(cr, 0, 0, w, h); cairo_fill_preserve(cr); - cairo_set_source_rgba(cr, 0., 0., 0., 1.0); + theme.setCairoColour(cr, theme.idColourFrame); cairo_stroke(cr); cairo_text_extents_t extents; - cairo_set_source_rgba(cr, 0.63, 0.63, 0.63, 1.0); + theme.setCairoColour(cr, theme.idColourForground); cairo_set_font_size (cr, h * 0.24); cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); @@ -587,6 +696,7 @@ class CairoToolTip : public CairoSubWidget, public Runner private: Widget * const parent; + CairoColourTheme &theme; const char* label; std::atomic state; DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CairoToolTip) diff --git a/plugins/NeuralRecord/PluginNeuralCapture.cpp b/plugins/NeuralRecord/PluginNeuralCapture.cpp index a92288f..a4cd572 100644 --- a/plugins/NeuralRecord/PluginNeuralCapture.cpp +++ b/plugins/NeuralRecord/PluginNeuralCapture.cpp @@ -71,7 +71,7 @@ void PluginNeuralCapture::initParameter(uint32_t index, Parameter& parameter) { parameter.shortName = "Error"; parameter.symbol = "ERRORS"; parameter.ranges.min = 0.0f; - parameter.ranges.max = 3.0f; + parameter.ranges.max = 4.0f; parameter.hints = kParameterIsOutput; break; } diff --git a/plugins/NeuralRecord/UINeuralCapture.cpp b/plugins/NeuralRecord/UINeuralCapture.cpp index 70d729a..ad3f926 100644 --- a/plugins/NeuralRecord/UINeuralCapture.cpp +++ b/plugins/NeuralRecord/UINeuralCapture.cpp @@ -15,22 +15,29 @@ START_NAMESPACE_DISTRHO // Init / Deinit UINeuralCapture::UINeuralCapture() -: UI(350, 250, true) { +: UI(350, 250, true), theme() { kInitialHeight = 250; kInitialWidth = 350; sizeGroup = new UiSizeGroup(kInitialWidth, kInitialHeight); getPathInfo(pathInfo); + inputFile = "Error: Couldn't find "; + inputFile += pathInfo; + inputFile += "input.wav"; - fButton = new CairoButton(this, "Capture", PluginNeuralCapture::paramButton); + outputFile = "Saved to "; + outputFile += pathInfo; + outputFile += "target.wav"; + + fButton = new CairoButton(this, theme, dynamic_cast(this), "Capture", PluginNeuralCapture::paramButton); sizeGroup->addToSizeGroup(fButton, 75, 30, 200, 50); - fProgressBar = new CairoProgressBar(this); + fProgressBar = new CairoProgressBar(this, theme); sizeGroup->addToSizeGroup(fProgressBar, 75, 105, 200, 30); - fPeekMeter = new CairoPeekMeter(this); + fPeekMeter = new CairoPeekMeter(this, theme); sizeGroup->addToSizeGroup(fPeekMeter, 75, 160, 200, 50); - fToolTip = new CairoToolTip(this, "This is a Message"); + fToolTip = new CairoToolTip(this, theme, "This is a Message"); sizeGroup->addToSizeGroup(fToolTip, 0, 95, 350, 50); setGeometryConstraints(kInitialWidth, kInitialHeight, true); @@ -58,7 +65,7 @@ void UINeuralCapture::parameterChanged(uint32_t index, float value) { fButton->setValue(0.0f); setParameterValue(PluginNeuralCapture::paramButton, 0.0f); } else if (value > 0.9969) { - fToolTip->setLabel(pathInfo.c_str()); + fToolTip->setLabel(outputFile.c_str()); } break; case PluginNeuralCapture::paramMeter: @@ -74,6 +81,8 @@ void UINeuralCapture::parameterChanged(uint32_t index, float value) { fToolTip->setLabel("Error: seems we receive garbage, stop the process here"); else if ((int)value == 3) fToolTip->setLabel("Error: Sample Rate mismatch, please use 48kHz"); + else if ((int)value == 4) + fToolTip->setLabel(inputFile.c_str()); break; } @@ -108,12 +117,11 @@ void UINeuralCapture::sampleRateChanged(double newSampleRate) { void UINeuralCapture::getPathInfo(std::string &pInfo) { - pInfo = "Saved to: "; #ifndef __MOD_DEVICES__ #if defined(WIN32) || defined(_WIN32) - pInfo += getenv("USERPROFILE"); + pInfo = getenv("USERPROFILE"); if (pInfo.empty()) { - pInfo += getenv("HOMEDRIVE"); + pInfo = getenv("HOMEDRIVE"); pInfo += getenv("HOMEPATH"); } #else @@ -125,7 +133,7 @@ void UINeuralCapture::getPathInfo(std::string &pInfo) #else pInfo += "/data/user-files/Audio Recordings/profiles/"; #endif - pInfo += "target.wav"; + //pInfo += "target.wav"; } @@ -157,7 +165,7 @@ void UINeuralCapture::onCairoDisplay(const CairoGraphicsContext& context) { int height = getHeight(); cairo_push_group (cr); - cairo_set_source_rgba(cr, 0.13, 0.13, 0.13, 1.0); + theme.setCairoColour(cr, theme.idColourBackground); cairo_paint(cr); box_shadow(cr, width, height, 25, 25); cairo_pop_group_to_source (cr); diff --git a/plugins/NeuralRecord/UINeuralCapture.hpp b/plugins/NeuralRecord/UINeuralCapture.hpp index 5c90895..b4df0cb 100644 --- a/plugins/NeuralRecord/UINeuralCapture.hpp +++ b/plugins/NeuralRecord/UINeuralCapture.hpp @@ -116,9 +116,12 @@ class UINeuralCapture : public UI, public CairoShadows void onResize(const ResizeEvent& ev) override; private: + CairoColourTheme theme; int kInitialHeight; int kInitialWidth; std::string pathInfo; + std::string inputFile; + std::string outputFile; ScopedPointer sizeGroup; ScopedPointer fButton; ScopedPointer fProgressBar; diff --git a/plugins/NeuralRecord/profiler.cc b/plugins/NeuralRecord/profiler.cc index 8280fdc..2d09ef2 100644 --- a/plugins/NeuralRecord/profiler.cc +++ b/plugins/NeuralRecord/profiler.cc @@ -209,13 +209,19 @@ Profil::Profil(int channel_, std::function setOut err(false), setOutputParameterValue(setOutputParameterValue_), requestParameterValueChange(requestParameterValueChange_) { - sem_init(&m_trig, 0, 0); + sem_unlink("/nrecord"); + m_trig = sem_open("/nrecord", O_CREAT|O_EXCL, S_IRWXU, 0); + if(m_trig == SEM_FAILED){ + err = true; + } } + Profil::~Profil() { stop_thread(); free(mtdm); activate(false); + sem_unlink("/nrecord"); } // get the path were we are installed @@ -281,7 +287,7 @@ inline std::string Profil::get_ifilename() { iname += PATH_SEPARATOR; iname += "input.wav"; std::string oname = get_path() + "input.wav"; - if (stat (oname.c_str(), &sb) != 0) { + if (stat (oname.c_str(), &sb) != 0 && stat (iname.c_str(), &sb) == 0) { std::ifstream src(iname.c_str(), std::ios::binary); std::ofstream dest(oname.c_str(), std::ios::binary); dest << src.rdbuf(); @@ -318,7 +324,7 @@ inline int Profil::load_from_wave(std::string fname) { // save the chunks to disk void Profil::disc_stream() { for (;;) { - sem_wait(&m_trig); + sem_wait(m_trig); if (!recfile) { std::string fname = get_ffilename(); recfile = open_stream(fname); @@ -400,6 +406,7 @@ inline void Profil::init(unsigned int samplingFreq) { fSamplingFreq = samplingFreq; IOTA = 0; IOTAP = 0; + inputsize = 0; latency = 0; roundtrip = 0; measure = 0; @@ -525,7 +532,7 @@ void always_inline Profil::compute(int count, const float *input0, float *output if (iSlow0 && !roundtrip) { mtdm_process (mtdm, count, input0, output0); measure++; - if (measure < 64) return; + if (measure < 128) return; } // resolve roundtrip latency after 64 frames if (measure && !roundtrip) { @@ -560,6 +567,15 @@ void always_inline Profil::compute(int count, const float *input0, float *output //fprintf (stderr, "seems we receive garbage, stop the process here\n"); return; } + if (!inputsize) { + roundtrip = 0; + measure = 0; + finish = 1; + errors = 4.0; + setOutputParameterValue(ERRORS, errors); + requestParameterValueChange((PortIndex)PROFILE, 0.0f); + return; + } // clear the roundtrip measurement struct mtdm_clear(mtdm); } @@ -589,7 +605,7 @@ void always_inline Profil::compute(int count, const float *input0, float *output tape = iA ? fRec0 : fRec1; keep_stream = true; savesize = IOTA; - sem_post(&m_trig); + sem_post(m_trig); IOTA = 0; } // play input.wav file once @@ -621,7 +637,7 @@ void always_inline Profil::compute(int count, const float *input0, float *output tape = iA ? fRec1 : fRec0; savesize = IOTA; keep_stream = false; - sem_post(&m_trig); + sem_post(m_trig); IOTA = 0; iA = 0; IOTAP = 0; @@ -641,7 +657,10 @@ void always_inline Profil::compute(int count, const float *input0, float *output fbargraph = 20.*log10(fmax(fRef,fRecb2[0])); setOutputParameterValue(METER, fbargraph); // progress bar - fbargraph1 = finish ? 1.0 : float(float(IOTAP) / float(inputsize)); + if (inputsize) + fbargraph1 = finish ? 1.0 : float(float(IOTAP) / float(inputsize)); + else + fbargraph1 = 0.0; setOutputParameterValue(STATE, fbargraph1); reset_errors++; if (reset_errors > 2000) { diff --git a/plugins/NeuralRecord/profiler.h b/plugins/NeuralRecord/profiler.h index 024efa9..4922aa6 100644 --- a/plugins/NeuralRecord/profiler.h +++ b/plugins/NeuralRecord/profiler.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -106,7 +107,7 @@ class Profil { float *fRec1; float *tape; float *tape1; - sem_t m_trig; + sem_t *m_trig; pthread_t m_pthr; int32_t rt_prio; int32_t rt_policy;