From b5473ca2492dba3d3d7bfa25cb26147d001c9900 Mon Sep 17 00:00:00 2001
From: Steven Atkinson <steven@atkinson.mn>
Date: Thu, 10 Oct 2024 21:11:55 -0700
Subject: [PATCH 1/8] Fix convnet errors

---
 NAM/convnet.cpp | 2 +-
 NAM/convnet.h   | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/NAM/convnet.cpp b/NAM/convnet.cpp
index 76d3baa..98bf649 100644
--- a/NAM/convnet.cpp
+++ b/NAM/convnet.cpp
@@ -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)
   {
diff --git a/NAM/convnet.h b/NAM/convnet.h
index b1fa142..458cf67 100644
--- a/NAM/convnet.h
+++ b/NAM/convnet.h
@@ -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;
 
@@ -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;
@@ -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;
 

From 8bebfef8f7ce218c678274f2b10573a8a589b697 Mon Sep 17 00:00:00 2001
From: Steven Atkinson <steven@atkinson.mn>
Date: Thu, 10 Oct 2024 21:12:13 -0700
Subject: [PATCH 2/8] Fix LSTM errors

---
 NAM/lstm.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/NAM/lstm.cpp b/NAM/lstm.cpp
index 437ce81..4d74c29 100644
--- a/NAM/lstm.cpp
+++ b/NAM/lstm.cpp
@@ -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]);
 }
 

From c1247218e122ca5ef84ccfc2efc54ff461b50cb1 Mon Sep 17 00:00:00 2001
From: Steven Atkinson <steven@atkinson.mn>
Date: Thu, 10 Oct 2024 21:23:40 -0700
Subject: [PATCH 3/8] Format wavenet.h

---
 NAM/wavenet.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/NAM/wavenet.h b/NAM/wavenet.h
index a2ad2fc..ff64b32 100644
--- a/NAM/wavenet.h
+++ b/NAM/wavenet.h
@@ -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

From 5e1d2938d049b6685f524d80c927d441c02a60de Mon Sep 17 00:00:00 2001
From: Steven Atkinson <steven@atkinson.mn>
Date: Thu, 10 Oct 2024 21:24:50 -0700
Subject: [PATCH 4/8] Fix bugs in dsp

---
 NAM/dsp.cpp |  6 +++---
 NAM/dsp.h   | 25 +++++++++++++++++--------
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/NAM/dsp.cpp b/NAM/dsp.cpp
index b15fc62..286f62e 100644
--- a/NAM/dsp.cpp
+++ b/NAM/dsp.cpp
@@ -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];
 }
 
@@ -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);
   }
diff --git a/NAM/dsp.h b/NAM/dsp.h
index 8739883..2f88cbd 100644
--- a/NAM/dsp.h
+++ b/NAM/dsp.h
@@ -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.
@@ -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;
@@ -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;

From e1073352edd29ed142dcc6bf134545e68fe8c7a1 Mon Sep 17 00:00:00 2001
From: Steven Atkinson <steven@atkinson.mn>
Date: Thu, 10 Oct 2024 21:25:11 -0700
Subject: [PATCH 5/8] Add input and output level getting to get_dsp, add header

---
 NAM/get_dsp.cpp | 37 ++++++++++++++++++++++++++++---------
 NAM/get_dsp.h   | 12 ++++++++++++
 2 files changed, 40 insertions(+), 9 deletions(-)
 create mode 100644 NAM/get_dsp.h

diff --git a/NAM/get_dsp.cpp b/NAM/get_dsp.cpp
index cb3b3b9..1155915 100644
--- a/NAM/get_dsp.cpp
+++ b/NAM/get_dsp.cpp
@@ -119,6 +119,12 @@ 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);
@@ -126,16 +132,21 @@ std::unique_ptr<DSP> get_dsp(dspData& conf)
   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;
 
@@ -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
diff --git a/NAM/get_dsp.h b/NAM/get_dsp.h
new file mode 100644
index 0000000..d414ca5
--- /dev/null
+++ b/NAM/get_dsp.h
@@ -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

From 0e5a951c7c3dd71797c15c7573f600772be2efeb Mon Sep 17 00:00:00 2001
From: Steven Atkinson <steven@atkinson.mn>
Date: Thu, 10 Oct 2024 21:25:56 -0700
Subject: [PATCH 6/8] Add tests for get_dsp()

---
 tools/run_tests.cpp         |  29 +++++----
 tools/test/test_dsp.cpp     | 115 +++++++++++++++++++-----------------
 tools/test/test_get_dsp.cpp |  57 ++++++++++++++++++
 3 files changed, 135 insertions(+), 66 deletions(-)
 create mode 100644 tools/test/test_get_dsp.cpp

diff --git a/tools/run_tests.cpp b/tools/run_tests.cpp
index a5ee3d1..243dcce 100644
--- a/tools/run_tests.cpp
+++ b/tools/run_tests.cpp
@@ -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;
 }
\ No newline at end of file
diff --git a/tools/test/test_dsp.cpp b/tools/test/test_dsp.cpp
index 179bc7c..bbdee63 100644
--- a/tools/test/test_dsp.cpp
+++ b/tools/test/test_dsp.cpp
@@ -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
diff --git a/tools/test/test_get_dsp.cpp b/tools/test/test_get_dsp.cpp
new file mode 100644
index 0000000..7695ba0
--- /dev/null
+++ b/tools/test/test_get_dsp.cpp
@@ -0,0 +1,57 @@
+#include <cassert>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "json.hpp"
+
+#include "NAM/get_dsp.h"
+
+namespace test_get_dsp
+{
+// Config
+const std::string configStr =
+  R"({"version": "0.5.4", "metadata": {"date": {"year": 2024, "month": 10, "day": 9, "hour": 18, "minute": 44, "second": 41}, "loudness": -37.8406867980957, "gain": 0.13508800804658277, "name": "Test LSTM", "modeled_by": "Steve", "gear_type": "amp", "gear_make": "Darkglass Electronics", "gear_model": "Microtubes 900 v2", "tone_type": "clean", "input_level_dbu": 18.3, "output_level_dbu": 12.3, "training": {"settings": {"ignore_checks": false}, "data": {"latency": {"manual": null, "calibration": {"algorithm_version": 1, "delays": [-16], "safety_factor": 1, "recommended": -17, "warnings": {"matches_lookahead": false, "disagreement_too_high": false}}}, "checks": {"version": 3, "passed": true}}, "validation_esr": null}}, "architecture": "LSTM", "config": {"input_size": 1, "hidden_size": 3, "num_layers": 1}, "weights": [-0.21677088737487793, -0.6683622002601624, -0.2560940980911255, -0.3588429093360901, 0.17952610552310944, 0.19445613026618958, -0.01662646047770977, 0.5353694558143616, -0.2536540627479553, -0.5132213234901428, -0.020476307719945908, 0.08592455089092255, -0.6891753673553467, 0.3627359867095947, 0.008421811275184155, 0.3113192617893219, 0.14251480996608734, 0.07989779114723206, -0.18211324512958527, 0.7118963003158569, 0.41084015369415283, -0.6571938395500183, -0.13214066624641418, -0.2698603868484497, 0.49387243390083313, -0.3491725027561188, 0.6353667974472046, -0.5005152225494385, 0.2052856683731079, -0.4301638901233673, -0.15770092606544495, -0.7181791067123413, 0.056290093809366226, -0.49049463868141174, 0.6623441576957703, 0.09029324352741241, 0.34005245566368103, 0.16416560113430023, 0.15520110726356506, -0.4155678153038025, -0.36928507685661316, 0.3211132884025574, -0.6769840121269226, -0.1575538069009781, 0.05268515646457672, -0.4191459119319916, 0.599330484867096, 0.21518059074878693, -4.246325492858887, -3.315647840499878, -4.328850746154785, 4.496089458465576, 5.015639305114746, 3.6492037773132324, 0.14431169629096985, -0.6633821725845337, 0.11673200130462646, -0.1418764889240265, -0.4897872805595398, -0.8689419031143188, -0.06714004278182983, -0.4450395107269287, -0.02142983116209507, -0.15136894583702087, -2.775207996368408, -0.08681213855743408, 0.05702732503414154, 0.670292317867279, 0.31442636251449585, 0.30793967843055725], "sample_rate": 48000})";
+
+// Copied over but shouldn't be publicly-exposed.
+std::vector<float> GetWeights(nlohmann::json const& j)
+{
+  auto it = j.find("weights");
+  if (it != j.end())
+  {
+    return *it;
+  }
+  else
+  {
+    throw std::runtime_error("Corrupted model file is missing weights.");
+  }
+}
+
+nam::dspData _GetConfig()
+{
+  nlohmann::json j = nlohmann::json::parse(configStr);
+
+  std::vector<float> weights = GetWeights(j);
+  nam::dspData returnedConfig;
+  returnedConfig.version = j["version"];
+  returnedConfig.architecture = j["architecture"];
+  returnedConfig.config = j["config"];
+  returnedConfig.metadata = j["metadata"];
+  returnedConfig.weights = weights;
+
+  return returnedConfig;
+}
+
+void test_gets_input_level()
+{
+  nam::dspData config = _GetConfig();
+  std::unique_ptr<nam::DSP> dsp = get_dsp(config);
+  assert(dsp->HasInputLevel());
+}
+void test_gets_output_level()
+{
+  nam::dspData config = _GetConfig();
+  std::unique_ptr<nam::DSP> dsp = get_dsp(config);
+  assert(dsp->HasOutputLevel());
+}
+}; // namespace test_get_dsp
\ No newline at end of file

From 892a5213a7c1274a437de1570ad7ff31e3549c46 Mon Sep 17 00:00:00 2001
From: Steven Atkinson <steven@atkinson.mn>
Date: Thu, 10 Oct 2024 21:56:01 -0700
Subject: [PATCH 7/8] Change build to warn and enable asserts

---
 .github/workflows/build.yml | 4 ++--
 tools/CMakeLists.txt        | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index bcdeef1..b0fd922 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -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}}
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 2508c38..71a88ab 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -36,7 +36,7 @@ if (MSVC)
 else()
 	target_compile_options(${TOOLS} PRIVATE
 		-Wall -Wextra -Wpedantic -Wstrict-aliasing -Wunreachable-code -Weffc++ -Wno-unused-parameter
-		"$<$<CONFIG:DEBUG>:-Og;-ggdb;-Werror>"
+		"$<$<CONFIG:DEBUG>:-Og;-ggdb>"  # ;-Werror>"  # HACK get this back
 		"$<$<CONFIG:RELEASE>:-Ofast>"
 	)
-endif()
\ No newline at end of file
+endif()

From b863bde7ca28c17af3d10c890c53724e73957956 Mon Sep 17 00:00:00 2001
From: Steven Atkinson <steven@atkinson.mn>
Date: Thu, 10 Oct 2024 22:09:39 -0700
Subject: [PATCH 8/8] Only -Wno-error on dsp.cpp

---
 tools/CMakeLists.txt | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 71a88ab..3174c3e 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -36,7 +36,12 @@ if (MSVC)
 else()
 	target_compile_options(${TOOLS} PRIVATE
 		-Wall -Wextra -Wpedantic -Wstrict-aliasing -Wunreachable-code -Weffc++ -Wno-unused-parameter
-		"$<$<CONFIG:DEBUG>:-Og;-ggdb>"  # ;-Werror>"  # HACK get this back
+		"$<$<CONFIG:DEBUG>:-Og;-ggdb;-Werror>"
 		"$<$<CONFIG:RELEASE>:-Ofast>"
 	)
 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")
