Skip to content

Commit

Permalink
Add capacitive voltage source (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
jatinchowdhury18 committed Jun 9, 2023
1 parent 53f6325 commit 0b40e5b
Show file tree
Hide file tree
Showing 2 changed files with 213 additions and 63 deletions.
85 changes: 85 additions & 0 deletions include/chowdsp_wdf/wdft/wdft_sources.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,91 @@ namespace wdft
T R_value = (T) 1.0e-9;
};

/** WDF Voltage source with series capacitance */
template <typename T>
class CapacitiveVoltageSourceT final : public BaseWDF
{
public:
/** Creates a new resistive voltage source.
* @param value: initial resistance value, in Ohms
*/
explicit CapacitiveVoltageSourceT (T value = NumericType<T> (1.0e-6), T fs = (T) 48000)
: C_value (value),
fs (fs)

{
calcImpedance();
}

/** Prepares the capacitor to operate at a new sample rate */
void prepare (T sampleRate)
{
fs = sampleRate;
propagateImpedanceChange();

reset();
}

void reset()
{
z = (T) 0;
v_1 = (T) 0;
}

/** Sets the capacitance value of the series resistor, in Farads. */
void setCapacitanceValue (T newC)
{
if (newC == C_value)
return;

C_value = newC;
propagateImpedanceChange();
}

/** Computes the impedance of the WDF capacitor,
* 1
* Z_C = --------------
* 2 * f_s * C
*/
inline void calcImpedance() override
{
wdf.R = (T) 1.0 / ((T) 2.0 * C_value * fs);
wdf.G = (T) 1.0 / wdf.R;
}

/** Sets the voltage of the voltage source, in Volts */
void setVoltage (T newV)
{
v_0 = newV;
}

/** Accepts an incident wave into a WDF resistive voltage source. */
inline void incident (T x) noexcept
{
wdf.a = x;
z = wdf.a;
}

/** Propogates a reflected wave from a WDF resistive voltage source. */
inline T reflected() noexcept
{
wdf.b = z + v_0 - v_1;
v_1 = v_0;
return wdf.b;
}

WDFMembers<T> wdf;

private:
T C_value = (T) 1.0e-6;

T z {};
T v_0 {};
T v_1 {};

T fs;
};

/** WDF Current source (non-adaptable) */
template <typename T, typename Next>
class IdealCurrentSourceT final : public RootWDF
Expand Down
191 changes: 128 additions & 63 deletions tests/CombinedComponentTest.cpp
Original file line number Diff line number Diff line change
@@ -1,82 +1,147 @@
#include <catch2/catch2.hpp>
#include <chowdsp_wdf/chowdsp_wdf.h>
#include <iostream>

using namespace chowdsp::wdft;

TEST_CASE ("Combined Component Test")
{
SECTION ("Resistor/Capacitor Series")
// SECTION ("Resistor/Capacitor Series")
// {
// static constexpr auto r_val = 2000.0f;
// static constexpr auto c_val = 2.0e-6f;
//
// ResistorT<float> r1 { r_val };
// CapacitorT<float> c1 { c_val };
// WDFSeriesT<float, decltype (r1), decltype (c1)> s1 { r1, c1 };
//
// ResistorCapacitorSeriesT<float> rc1 { r_val, c_val };
//
// float inputs[] = { 0.0f, 1.0f, -1.0f, 2.0f, -3.0f };
// for (auto& a : inputs)
// {
// s1.incident (a);
// const auto ref = s1.reflected();
//
// rc1.incident (a);
// const auto actual = rc1.reflected();
//
// REQUIRE (ref == Approx { actual }.margin (1.0e-4f));
// }
// }
//
// SECTION ("Resistor/Capacitor Parallel")
// {
// static constexpr auto r_val = 2000.0f;
// static constexpr auto c_val = 2.0e-6f;
//
// ResistorT<float> r1 { r_val };
// CapacitorT<float> c1 { c_val };
// WDFParallelT<float, decltype (r1), decltype (c1)> p1 { r1, c1 };
//
// ResistorCapacitorParallelT<float> rc1 { r_val, c_val };
//
// float inputs[] = { 0.0f, 1.0f, -1.0f, 2.0f, -3.0f };
// for (auto& a : inputs)
// {
// p1.incident (a);
// const auto ref = p1.reflected();
//
// rc1.incident (a);
// const auto actual = rc1.reflected();
//
// REQUIRE (ref == Approx { actual }.margin (1.0e-4f));
// }
// }
//
// SECTION ("Resistor/Capacitor/Voltage Source Series")
// {
// static constexpr auto r_val = 2000.0f;
// static constexpr auto c_val = 2.0e-6f;
// static constexpr auto source_v = 1.5f;
//
// ResistiveVoltageSourceT<float> rv1 { r_val };
// rv1.setVoltage (source_v);
// CapacitorT<float> c1 { c_val };
// WDFSeriesT<float, decltype (rv1), decltype (c1)> s1 { rv1, c1 };
//
// ResistiveCapacitiveVoltageSourceT<float> rc1 { r_val, c_val };
// rc1.setVoltage (source_v);
// rc1.reset();
//
// float inputs[] = { 0.0f, 1.0f, -1.0f, 2.0f, -3.0f };
// for (auto& a : inputs)
// {
// s1.incident (a);
// const auto ref = s1.reflected();
//
// rc1.incident (a);
// const auto actual = rc1.reflected();
//
// REQUIRE (ref == Approx { actual }.margin (1.0e-4f));
// }
// }

SECTION ("Capacitive Voltage Source")
{
static constexpr auto r_val = 2000.0f;
static constexpr auto c_val = 2.0e-6f;
static constexpr auto source_v = 1.5f;

ResistorT<float> r1 { r_val };
CapacitorT<float> c1 { c_val };
WDFSeriesT<float, decltype (r1), decltype (c1)> s1 { r1, c1 };

ResistorCapacitorSeriesT<float> rc1 { r_val, c_val };

float inputs[] = { 0.0f, 1.0f, -1.0f, 2.0f, -3.0f };
for (auto& a : inputs)
struct Ref
{
s1.incident (a);
const auto ref = s1.reflected();

rc1.incident (a);
const auto actual = rc1.reflected();

REQUIRE (ref == Approx { actual }.margin (1.0e-4f));
}
}

SECTION ("Resistor/Capacitor Parallel")
{
static constexpr auto r_val = 2000.0f;
static constexpr auto c_val = 2.0e-6f;

ResistorT<float> r1 { r_val };
CapacitorT<float> c1 { c_val };
WDFParallelT<float, decltype (r1), decltype (c1)> p1 { r1, c1 };

ResistorCapacitorParallelT<float> rc1 { r_val, c_val };

float inputs[] = { 0.0f, 1.0f, -1.0f, 2.0f, -3.0f };
for (auto& a : inputs)
ResistiveVoltageSourceT<float> rv1 { 1.0e3f };
CapacitorT<float> c1 { 1.0e-6f };
WDFSeriesT<float, decltype (rv1), decltype (c1)> s1 { rv1, c1 };
IdealVoltageSourceT<float, decltype (s1)> v0 { s1 };

void reset()
{
c1.reset();
v0.setVoltage (0.0f);
}

float process (float v)
{
rv1.setVoltage (v);
v0.incident (s1.reflected());
const auto y = voltage<float> (rv1) + voltage<float> (c1);
s1.incident (v0.reflected());
return y;
}
};
Ref ref_circuit;
ref_circuit.reset();

struct Test
{
p1.incident (a);
const auto ref = p1.reflected();

rc1.incident (a);
const auto actual = rc1.reflected();

REQUIRE (ref == Approx { actual }.margin (1.0e-4f));
}
}

SECTION ("Resistor/Capacitor/Voltage Source Series")
{
static constexpr auto r_val = 2000.0f;
static constexpr auto c_val = 2.0e-6f;
static constexpr auto source_v = 1.5f;

ResistiveVoltageSourceT<float> rv1 { r_val };
rv1.setVoltage (source_v);
CapacitorT<float> c1 { c_val };
WDFSeriesT<float, decltype (rv1), decltype (c1)> s1 { rv1, c1 };

ResistiveCapacitiveVoltageSourceT<float> rc1 { r_val, c_val };
rc1.setVoltage (source_v);
rc1.reset();
CapacitiveVoltageSourceT<float> cv1 { 1.0e-6f };
ResistorT<float> r1 { 1.0e3f };
WDFSeriesT<float, decltype (cv1), decltype (r1)> s1 { cv1, r1 };
IdealVoltageSourceT<float, decltype (s1)> v0 { s1 };

void reset()
{
cv1.reset();
v0.setVoltage (0.0f);
}

float process (float v)
{
cv1.setVoltage (v);
v0.incident (s1.reflected());
const auto y = voltage<float> (cv1) + voltage<float> (r1);
s1.incident (v0.reflected());
return y;
}
};
Test test_circuit;
test_circuit.reset();

float inputs[] = { 0.0f, 1.0f, -1.0f, 2.0f, -3.0f };
for (auto& a : inputs)
{
s1.incident (a);
const auto ref = s1.reflected();

rc1.incident (a);
const auto actual = rc1.reflected();

const auto ref = ref_circuit.process (a);
const auto actual = test_circuit.process (a);
REQUIRE (ref == Approx { actual }.margin (1.0e-4f));
}
}
Expand Down

0 comments on commit 0b40e5b

Please sign in to comment.