Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ jobs:
env:
CXX: clang++
run: |
cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE
cmake --build . --config $BUILD_TYPE -j4
cmake ..
cmake --build . -j4

- name: Run tests
working-directory: ${{github.workspace}}
Expand Down
2 changes: 1 addition & 1 deletion NAM/convnet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ void nam::convnet::ConvNet::_update_buffers_(NAM_SAMPLE* input, const int num_fr
{
this->Buffer::_update_buffers_(input, num_frames);

const size_t buffer_size = this->_input_buffer.size();
const long buffer_size = (long)this->_input_buffer.size();

if (this->_block_vals[0].rows() != 1 || this->_block_vals[0].cols() != buffer_size)
{
Expand Down
6 changes: 3 additions & 3 deletions NAM/convnet.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace convnet
class BatchNorm
{
public:
BatchNorm(){};
BatchNorm() {};
BatchNorm(const int dim, std::vector<float>::iterator& weights);
void process_(Eigen::MatrixXf& input, const long i_start, const long i_end) const;

Expand All @@ -39,7 +39,7 @@ class BatchNorm
class ConvNetBlock
{
public:
ConvNetBlock(){};
ConvNetBlock() {};
void set_weights_(const int in_channels, const int out_channels, const int _dilation, const bool batchnorm,
const std::string activation, std::vector<float>::iterator& weights);
void process_(const Eigen::MatrixXf& input, Eigen::MatrixXf& output, const long i_start, const long i_end) const;
Expand All @@ -55,7 +55,7 @@ class ConvNetBlock
class _Head
{
public:
_Head(){};
_Head() {};
_Head(const int channels, std::vector<float>::iterator& weights);
void process_(const Eigen::MatrixXf& input, Eigen::VectorXf& output, const long i_start, const long i_end) const;

Expand Down
6 changes: 3 additions & 3 deletions NAM/dsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void nam::DSP::prewarm()
void nam::DSP::process(NAM_SAMPLE* input, NAM_SAMPLE* output, const int num_frames)
{
// Default implementation is the null operation
for (size_t i = 0; i < num_frames; i++)
for (int i = 0; i < num_frames; i++)
output[i] = input[i];
}

Expand Down Expand Up @@ -173,9 +173,9 @@ void nam::Linear::process(NAM_SAMPLE* input, NAM_SAMPLE* output, const int num_f
this->nam::Buffer::_update_buffers_(input, num_frames);

// Main computation!
for (size_t i = 0; i < num_frames; i++)
for (int i = 0; i < num_frames; i++)
{
const size_t offset = this->_input_buffer_offset - this->_weight.size() + i + 1;
const long offset = this->_input_buffer_offset - this->_weight.size() + i + 1;
auto input = Eigen::Map<const Eigen::VectorXf>(&this->_input_buffer[offset], this->_receptive_field);
output[i] = this->_bias + this->_weight.dot(input);
}
Expand Down
25 changes: 17 additions & 8 deletions NAM/dsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,19 @@ class DSP
double GetExpectedSampleRate() const { return mExpectedSampleRate; };
// Input Level, in dBu, corresponding to 0 dBFS for a sine wave
// You should call HasInputLevel() first to be safe.
double GetInputLevel() {return mInputLevel.level;};
double GetInputLevel() { return mInputLevel.level; };
// Get how loud this model is, in dB.
// Throws a std::runtime_error if the model doesn't know how loud it is.
double GetLoudness() const;
// Output Level, in dBu, corresponding to 0 dBFS for a sine wave
// You should call HasOutputLevel() first to be safe.
double GetOutputLevel() {return mOutputLevel.level;};
double GetOutputLevel() { return mOutputLevel.level; };
// Does this model know its output level?
bool HasInputLevel() {return mInputLevel.haveLevel;};
bool HasInputLevel() { return mInputLevel.haveLevel; };
// Get whether the model knows how loud it is.
bool HasLoudness() const { return mHasLoudness; };
// Does this model know its output level?
bool HasOutputLevel() {return mOutputLevel.haveLevel;};
bool HasOutputLevel() { return mOutputLevel.haveLevel; };
// General function for resetting the DSP unit.
// This doesn't call prewarm(). If you want to do that, then you might want to use ResetAndPrewarm().
// See https://github.com/sdatkinson/NeuralAmpModelerCore/issues/96 for the reasoning.
Expand All @@ -83,12 +83,20 @@ class DSP
Reset(sampleRate, maxBufferSize);
prewarm();
}
void SetInputLevel(const double inputLevel) {mInputLevel.haveLevel = true; mInputLevel.level = inputLevel;};
void SetInputLevel(const double inputLevel)
{
mInputLevel.haveLevel = true;
mInputLevel.level = inputLevel;
};
// Set the loudness, in dB.
// This is usually defined to be the loudness to a standardized input. The trainer has its own, but you can always
// use this to define it a different way if you like yours better.
void SetLoudness(const double loudness);
void SetOutputLevel(const double outputLevel) {mOutputLevel.haveLevel = true; mOutputLevel.level = outputLevel;};
void SetOutputLevel(const double outputLevel)
{
mOutputLevel.haveLevel = true;
mOutputLevel.level = outputLevel;
};

protected:
bool mHasLoudness = false;
Expand All @@ -106,8 +114,9 @@ class DSP
virtual int PrewarmSamples() { return 0; };

private:
struct Level {
bool haveLevel=false;
struct Level
{
bool haveLevel = false;
float level = 0.0;
};
Level mInputLevel;
Expand Down
37 changes: 28 additions & 9 deletions NAM/get_dsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,23 +119,34 @@ std::unique_ptr<DSP> get_dsp(const std::filesystem::path config_filename, dspDat
return get_dsp(conf);
}

struct OptionalValue
{
bool have = false;
double value = 0.0;
};

std::unique_ptr<DSP> get_dsp(dspData& conf)
{
verify_config_version(conf.version);

auto& architecture = conf.architecture;
nlohmann::json& config = conf.config;
std::vector<float>& weights = conf.weights;
bool haveLoudness = false;
double loudness = 0.0;
OptionalValue loudness, inputLevel, outputLevel;

if (!conf.metadata.is_null())
{
if (conf.metadata.find("loudness") != conf.metadata.end())
auto AssignOptional = [&conf](const std::string key, OptionalValue& v) {
if (conf.metadata.find(key) != conf.metadata.end())
{
loudness = conf.metadata["loudness"];
haveLoudness = true;
v.value = conf.metadata[key];
v.have = true;
}
};

if (!conf.metadata.is_null())
{
AssignOptional("loudness", loudness);
AssignOptional("input_level_dbu", inputLevel);
AssignOptional("output_level_dbu", outputLevel);
}
const double expectedSampleRate = conf.expected_sample_rate;

Expand Down Expand Up @@ -180,9 +191,17 @@ std::unique_ptr<DSP> get_dsp(dspData& conf)
{
throw std::runtime_error("Unrecognized architecture");
}
if (haveLoudness)
if (loudness.have)
{
out->SetLoudness(loudness.value);
}
if (inputLevel.have)
{
out->SetInputLevel(inputLevel.value);
}
if (outputLevel.have)
{
out->SetLoudness(loudness);
out->SetOutputLevel(outputLevel.value);
}

// "pre-warm" the model to settle initial conditions
Expand Down
12 changes: 12 additions & 0 deletions NAM/get_dsp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <fstream>

namespace nam {
// Get NAM from a .nam file at the provided location
std::unique_ptr<DSP> get_dsp(const std::filesystem::path config_filename);

// Get NAM from a provided configuration struct
std::unique_ptr<DSP> get_dsp(dspData& conf);

// Get NAM from a provided .nam file path and store its configuration in the provided conf
std::unique_ptr<DSP> get_dsp(const std::filesystem::path config_filename, dspData& returnedConfig);
}; // namespace nam
2 changes: 1 addition & 1 deletion NAM/lstm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ nam::lstm::LSTM::LSTM(const int num_layers, const int input_size, const int hidd

void nam::lstm::LSTM::process(NAM_SAMPLE* input, NAM_SAMPLE* output, const int num_frames)
{
for (size_t i = 0; i < num_frames; i++)
for (int i = 0; i < num_frames; i++)
output[i] = this->_process_sample(input[i]);
}

Expand Down
2 changes: 1 addition & 1 deletion NAM/wavenet.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class _Layer
, _input_mixin(condition_size, gated ? 2 * channels : channels, false)
, _1x1(channels, channels, true)
, _activation(activations::Activation::get_activation(activation))
, _gated(gated){};
, _gated(gated) {};
void set_weights_(std::vector<float>::iterator& weights);
// :param `input`: from previous layer
// :param `output`: to next layer
Expand Down
7 changes: 6 additions & 1 deletion tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,9 @@ else()
"$<$<CONFIG:DEBUG>:-Og;-ggdb;-Werror>"
"$<$<CONFIG:RELEASE>:-Ofast>"
)
endif()
endif()

# There's an error in eigen's
# /Users/steve/src/NeuralAmpModelerCore/Dependencies/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h
# Don't let this break my build on debug:
set_source_files_properties(../NAM/dsp.cpp PROPERTIES COMPILE_FLAGS "-Wno-error")
29 changes: 17 additions & 12 deletions tools/run_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@

#include <iostream>
#include "test/test_dsp.cpp"
#include "test/test_get_dsp.cpp"

int main() {
std::cout << "Running tests..." << std::endl;
// TODO Automatically loop, catch exceptions, log results
test_dsp::test_construct();
test_dsp::test_get_input_level();
test_dsp::test_get_output_level();
test_dsp::test_has_input_level();
test_dsp::test_has_output_level();
test_dsp::test_set_input_level();
test_dsp::test_set_output_level();
int main()
{
std::cout << "Running tests..." << std::endl;
// TODO Automatically loop, catch exceptions, log results
test_dsp::test_construct();
test_dsp::test_get_input_level();
test_dsp::test_get_output_level();
test_dsp::test_has_input_level();
test_dsp::test_has_output_level();
test_dsp::test_set_input_level();
test_dsp::test_set_output_level();

std::cout << "Success!" << std::endl;
return 0;
test_get_dsp::test_gets_input_level();
test_get_dsp::test_gets_output_level();

std::cout << "Success!" << std::endl;
return 0;
}
115 changes: 61 additions & 54 deletions tools/test/test_dsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,65 @@

#include "NAM/dsp.h"

namespace test_dsp {
// Simplest test: can I construct something!
void test_construct() {
nam::DSP myDsp(48000.0);
}

void test_get_input_level() {
nam::DSP myDsp(48000.0);
const double expected = 19.3;
myDsp.SetInputLevel(expected);
assert(myDsp.HasInputLevel());
const double actual = myDsp.GetInputLevel();

assert(actual == expected);
}

void test_get_output_level() {
nam::DSP myDsp(48000.0);
const double expected = 12.3;
myDsp.SetOutputLevel(expected);
assert(myDsp.HasOutputLevel());
const double actual = myDsp.GetOutputLevel();

assert(actual == expected);
}

// Test correct function of DSP::HasInputLevel()
void test_has_input_level() {
nam::DSP myDsp(48000.0);
assert(!myDsp.HasInputLevel());

myDsp.SetInputLevel(19.3);
assert(myDsp.HasInputLevel());
}

void test_has_output_level() {
nam::DSP myDsp(48000.0);
assert(!myDsp.HasOutputLevel());

myDsp.SetOutputLevel(12.3);
assert(myDsp.HasOutputLevel());
}

// Test correct function of DSP::HasInputLevel()
void test_set_input_level() {
nam::DSP myDsp(48000.0);
myDsp.SetInputLevel(19.3);
}

void test_set_output_level() {
nam::DSP myDsp(48000.0);
myDsp.SetOutputLevel(19.3);
}
};
namespace test_dsp
{
// Simplest test: can I construct something!
void test_construct()
{
nam::DSP myDsp(48000.0);
}

void test_get_input_level()
{
nam::DSP myDsp(48000.0);
const double expected = 19.0;
myDsp.SetInputLevel(expected);
assert(myDsp.HasInputLevel());
const double actual = myDsp.GetInputLevel();

assert(actual == expected);
}

void test_get_output_level()
{
nam::DSP myDsp(48000.0);
const double expected = 12.0;
myDsp.SetOutputLevel(expected);
assert(myDsp.HasOutputLevel());
const double actual = myDsp.GetOutputLevel();

assert(actual == expected);
}

// Test correct function of DSP::HasInputLevel()
void test_has_input_level()
{
nam::DSP myDsp(48000.0);
assert(!myDsp.HasInputLevel());

myDsp.SetInputLevel(19.0);
assert(myDsp.HasInputLevel());
}

void test_has_output_level()
{
nam::DSP myDsp(48000.0);
assert(!myDsp.HasOutputLevel());

myDsp.SetOutputLevel(12.0);
assert(myDsp.HasOutputLevel());
}

// Test correct function of DSP::HasInputLevel()
void test_set_input_level()
{
nam::DSP myDsp(48000.0);
myDsp.SetInputLevel(19.0);
}

void test_set_output_level()
{
nam::DSP myDsp(48000.0);
myDsp.SetOutputLevel(19.0);
}
}; // namespace test_dsp
Loading