From 92d50ec48554256e25b0b5918d3699fabae14f56 Mon Sep 17 00:00:00 2001 From: brummer10 Date: Thu, 12 Oct 2023 13:46:35 +0200 Subject: [PATCH] Add proper Description to the MOD variant, reduce peek-meter output --- plugins/NeuralRecord/MOD/neuralrecord_dsp.ttl | 34 +++++++++++++++++-- plugins/NeuralRecord/UINeuralCapture.cpp | 2 +- plugins/NeuralRecord/profiler.cc | 25 ++++++++++---- plugins/NeuralRecord/profiler.h | 1 + 4 files changed, 52 insertions(+), 10 deletions(-) diff --git a/plugins/NeuralRecord/MOD/neuralrecord_dsp.ttl b/plugins/NeuralRecord/MOD/neuralrecord_dsp.ttl index ff2aad6..e20c092 100644 --- a/plugins/NeuralRecord/MOD/neuralrecord_dsp.ttl +++ b/plugins/NeuralRecord/MOD/neuralrecord_dsp.ttl @@ -29,7 +29,6 @@ , ; - ui:ui ; lv2:port [ a lv2:InputPort, lv2:AudioPort ; @@ -85,7 +84,38 @@ lv2:maximum 4 ; ] ; - rdfs:comment "A Neural Record plug to make the process of cloning external soft/hardware a bit more comfortable " ; + rdfs:comment """ +Neural Record, a plug to make the process of cloning external soft/hardware a bit more comfortable. + +It features a round trip measurement routine. +This allows to load the plug, connect the output to the system output, +loop over external gear (soft or hardware) back over the System Input to the Neural Record input. + +Simply press "Capture" to play the "input.wav" file to the output and record the returning input +delayed by the measured round trip latency. + +Resulting recorded "target.wav" file will be perfectly in sync with the used "input.wav" file. +Currently, both files would be saved under "/data/user-files/Audio Recordings/profiles/". +The "target.wav" file will be overwritten on each capture run, so there will be always only one target file. +You need to download it from the device in order to use it with the AIDA-X or the NAM trainer. + +The round-trip latency will be measured on each "Capture" start. + +The "input.wav" file comes as resource with the plug and get copied over to +"/data/user-files/Audio Recordings/profiles/", when no input.wav file was found there. +This allows advanced users to use their own input.wav file by simply replace the one in that folder. + +The target.wav file get checked during record and run to a normalisation function when needed. +(Only when the max peek in target is above the max peek in input). + +The record will be saved in the PCM24 wav format (same as the input.wav file). + +The UI provide a progress bar, a peek-meter and, well the capture button. + +Features: +Developed by Brummer + +"""; mod:brand "brummer" ; mod:label "Neural Record" ; diff --git a/plugins/NeuralRecord/UINeuralCapture.cpp b/plugins/NeuralRecord/UINeuralCapture.cpp index 516fc7e..184ea9c 100644 --- a/plugins/NeuralRecord/UINeuralCapture.cpp +++ b/plugins/NeuralRecord/UINeuralCapture.cpp @@ -117,7 +117,7 @@ void UINeuralCapture::sampleRateChanged(double newSampleRate) { void UINeuralCapture::getPathInfo(std::string &pInfo) { #ifndef __MOD_DEVICES__ -#if defined(WIN32) || defined(_WIN32) +#ifdef _WIN32 pInfo = getenv("USERPROFILE"); if (pInfo.empty()) { pInfo = getenv("HOMEDRIVE"); diff --git a/plugins/NeuralRecord/profiler.cc b/plugins/NeuralRecord/profiler.cc index 7f6c302..1482f01 100644 --- a/plugins/NeuralRecord/profiler.cc +++ b/plugins/NeuralRecord/profiler.cc @@ -226,7 +226,7 @@ Profil::~Profil() { // get the path were we are installed std::string get_profile_library_path() { -#if defined(WIN32) || defined(_WIN32) +#ifdef _WIN32 char buffer[MAX_PATH]; GetModuleFileName( NULL, buffer, MAX_PATH ); return std::string(buffer); @@ -292,14 +292,15 @@ inline std::string Profil::get_ifilename() { return oname; } +// convert included input.flac to wav file format and save it to path inline void Profil::convert_to_wave(std::string fname, std::string oname) { if (tape1) { delete[] tape1; tape1 = 0; } int lsize = load_from_wave(fname); // load flac file + SF_INFO sfinfo ; sfinfo.channels = channel; sfinfo.samplerate = fSamplingFreq; sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_24; - SNDFILE * sf = sf_open(oname.c_str(), SFM_WRITE, &sfinfo); if (sf) { save_to_wave(sf, tape1, lsize); @@ -428,6 +429,7 @@ inline void Profil::init(unsigned int samplingFreq) { fConst2 = 0.1; nf = 1.0; iRef = 0; + iRefSet = 0; fRef = 0.0000003; errors = 0.0; reset_errors = 0; @@ -541,13 +543,13 @@ void always_inline Profil::compute(int count, const float *input0, float *output fbargraph1 = 0.0; } - // measure roundtrip latency, running 64 frames + // measure roundtrip latency, running 128 frames if (iSlow0 && !roundtrip) { mtdm_process (mtdm, count, input0, output0); measure++; if (measure < 128) return; } - // resolve roundtrip latency after 64 frames + // resolve roundtrip latency after 128 frames if (measure && !roundtrip) { // no signal comes in, stop the process here if (mtdm_resolve (mtdm) < 0) { @@ -664,9 +666,17 @@ void always_inline Profil::compute(int count, const float *input0, float *output iRecb1[1] = iRecb1[0]; fRecb0[1] = fRecb0[0]; } - // vu-meter - iRef = !iRef; - fRef = iRef ? 0.0000003 : 0.00000031; + // peek-meter, when the level fails below threshold trigger a little variance for 24 circles + // to ensure that the value cross the event throttle boarder of the host. + if (fRecb2[0] < fRef) { + if (iRefSet < 24) { + iRef = !iRef; + fRef = iRef ? 0.0000003 : 0.00000031; + iRefSet++; + } + } else { + iRefSet = 0; + } fbargraph = 20.*log10(fmax(fRef,fRecb2[0])); setOutputParameterValue(METER, fbargraph); // progress bar @@ -676,6 +686,7 @@ void always_inline Profil::compute(int count, const float *input0, float *output fbargraph1 = 0.0; setOutputParameterValue(STATE, fbargraph1); reset_errors++; + // rest error number to ensure we could show the same error again when needed if (reset_errors > 2000) { reset_errors = 0; setOutputParameterValue(ERRORS, errors); diff --git a/plugins/NeuralRecord/profiler.h b/plugins/NeuralRecord/profiler.h index 461df56..1473a99 100644 --- a/plugins/NeuralRecord/profiler.h +++ b/plugins/NeuralRecord/profiler.h @@ -125,6 +125,7 @@ class Profil { int iRecb1r[2]; float fRecb2r[2]; int iRef; + int iRefSet; float fRef; void mem_alloc();