Merge pull request #94 from mikeoliphant/smart_bypass

This commit is contained in:
Mike Oliphant
2025-11-11 08:16:31 -08:00
committed by GitHub
5 changed files with 69 additions and 1 deletions
+2
View File
@@ -58,4 +58,6 @@ After building, the plugin will be in **build/neural_amp_modeler.lv2**.
```-DUSE_NATIVE_ARCH=ON```: If you have a relatively modern x64 processor, you can pass ```-DUSE_NATIVE_ARCH=ON``` on your cmake command line to enable certain processor-specific optimizations. ```-DUSE_NATIVE_ARCH=ON```: If you have a relatively modern x64 processor, you can pass ```-DUSE_NATIVE_ARCH=ON``` on your cmake command line to enable certain processor-specific optimizations.
```-DSMART_BYPASS_ENABLED=ON```: If enabled, this will bypass model processing if input has been silent (below -100 dB by default) for a sufficient number of samples (determined by the model's receptive field size).
Also see the [NeuralAudio CMake options](https://github.com/mikeoliphant/NeuralAudio#cmake-options) - adding these to your neural-amp-modeler-lv2 cmake will pass them to the NeuralAudio build. Also see the [NeuralAudio CMake options](https://github.com/mikeoliphant/NeuralAudio#cmake-options) - adding these to your neural-amp-modeler-lv2 cmake will pass them to the NeuralAudio build.
+6
View File
@@ -54,6 +54,12 @@ if (DISABLE_DENORMALS)
add_definitions(-DDISABLE_DENORMALS) add_definitions(-DDISABLE_DENORMALS)
endif (DISABLE_DENORMALS) endif (DISABLE_DENORMALS)
option(SMART_BYPASS_ENABLED "Enable auto-bypass on silence" OFF)
if (SMART_BYPASS_ENABLED)
add_definitions(-DSMART_BYPASS_ENABLED)
endif (SMART_BYPASS_ENABLED)
set_target_properties(neural_amp_modeler set_target_properties(neural_amp_modeler
PROPERTIES PROPERTIES
CXX_VISIBILITY_PRESET hidden CXX_VISIBILITY_PRESET hidden
+56
View File
@@ -7,12 +7,18 @@
#define SMOOTH_EPSILON .0001f #define SMOOTH_EPSILON .0001f
#ifndef BYPASS_DB_THRESHOLD
#define BYPASS_DB_THRESHOLD -100
#endif
namespace NAM { namespace NAM {
Plugin::Plugin() Plugin::Plugin()
{ {
// prevent allocations on the audio thread // prevent allocations on the audio thread
currentModelPath.reserve(MAX_FILE_NAME + 1); currentModelPath.reserve(MAX_FILE_NAME + 1);
bypassThresholdLinear = powf(10, BYPASS_DB_THRESHOLD * 0.05f);
// NeuralAudio::NeuralModel::SetLSTMLoadMode( // NeuralAudio::NeuralModel::SetLSTMLoadMode(
//#ifdef LSTM_PREFER_NAM //#ifdef LSTM_PREFER_NAM
// NeuralAudio::PreferNAMCore // NeuralAudio::PreferNAMCore
@@ -181,6 +187,18 @@ namespace NAM {
nam->currentModelPath = msg->path; nam->currentModelPath = msg->path;
assert(nam->currentModelPath.capacity() >= MAX_FILE_NAME + 1); assert(nam->currentModelPath.capacity() >= MAX_FILE_NAME + 1);
if (nam->currentModel != nullptr)
{
int receptiveFieldSize = nam->currentModel->GetReceptiveFieldSize();
if (receptiveFieldSize > -1)
{
// A newly loaded model is prewarmed to have a silent sample history
nam->silentSamples = receptiveFieldSize;
nam->smartBypassed = true;
}
}
// send reply // send reply
nam->schedule->schedule_work(nam->schedule->handle, sizeof(reply), &reply); nam->schedule->schedule_work(nam->schedule->handle, sizeof(reply), &reply);
@@ -241,6 +259,44 @@ namespace NAM {
if (currentModel != nullptr) if (currentModel != nullptr)
{ {
modelInputAdjustmentDB = currentModel->GetRecommendedInputDBAdjustment(); modelInputAdjustmentDB = currentModel->GetRecommendedInputDBAdjustment();
#ifdef SMART_BYPASS_ENABLED
int receptiveFieldSamples = currentModel->GetReceptiveFieldSize();
if (receptiveFieldSamples > -1)
{
for (unsigned int i = 0; i < n_samples; i++)
{
if (abs(ports.audio_in[i]) <= bypassThresholdLinear)
{
silentSamples++;
}
else
{
silentSamples = 0;
}
}
if (silentSamples >= (uint32_t)receptiveFieldSamples)
{
silentSamples = (uint32_t)receptiveFieldSamples; // Prevent silentSamples growing and eventually overflowing uint32
if (smartBypassed)
{
for (unsigned int i = 0; i < n_samples; i++)
{
ports.audio_out[i] = ports.audio_in[i];
}
return;
}
smartBypassed = true; // If we aren't already, we'll be bypassed on the next process call
}
else
smartBypassed = false;
}
#endif
} }
// convert input level from db // convert input level from db
+4
View File
@@ -80,6 +80,7 @@ namespace NAM {
bool initialize(double rate, const LV2_Feature* const* features) noexcept; bool initialize(double rate, const LV2_Feature* const* features) noexcept;
void set_max_buffer_size(int size) noexcept; void set_max_buffer_size(int size) noexcept;
void activate() noexcept;
void process(uint32_t n_samples) noexcept; void process(uint32_t n_samples) noexcept;
void write_current_path(); void write_current_path();
@@ -120,5 +121,8 @@ namespace NAM {
float inputLevel = 0; float inputLevel = 0;
float outputLevel = 0; float outputLevel = 0;
int32_t maxBufferSize = 512; int32_t maxBufferSize = 512;
float bypassThresholdLinear = 0;
uint32_t silentSamples = 0;
bool smartBypassed = true;
}; };
} }