9 size_t underscore = str.find(
'_');
10 if (underscore == std::string::npos) {
11 throw std::invalid_argument(
"Invalid format. Supply numberical format of nInputs_nOutpits like 25_2");
14 int inputs = std::stoi(str.substr(0, underscore));
15 int outputs = std::stoi(str.substr(underscore + 1));
16 return std::make_pair(inputs, outputs);
19Filter::Filter(
const std::shared_ptr<Node>& input,
const std::string& zindex_shifts)
21 , m_context(0.0, m_input_history, m_output_history, m_coef_a, m_coef_b)
22 , m_context_gpu(0.0, m_input_history, m_output_history, m_coef_a, m_coef_b, get_gpu_data_buffer())
30Filter::Filter(
const std::shared_ptr<Node>& input,
const std::vector<double>& a_coef,
const std::vector<double>& b_coef)
34 , m_context(0.0, m_input_history, m_output_history, m_coef_a, m_coef_b)
35 , m_context_gpu(0.0, m_input_history, m_output_history, m_coef_a, m_coef_b, get_gpu_data_buffer())
40 throw std::invalid_argument(
"IIR coefficients cannot be empty");
43 throw std::invalid_argument(
"First denominator coefficient (a[0]) cannot be zero");
49Filter::Filter(
const std::vector<double>& a_coef,
const std::vector<double>& b_coef)
50 :
Filter(nullptr, a_coef, b_coef)
80 for (
size_t i = 0; i < lookback; ++i) {
106 if (new_coefs.empty()) {
107 throw std::invalid_argument(
"Denominator coefficients cannot be empty");
109 if (new_coefs[0] == 0.0F) {
110 throw std::invalid_argument(
"First denominator coefficient (a[0]) cannot be zero");
123 if (new_coefs.empty()) {
124 throw std::invalid_argument(
"Numerator coefficients cannot be empty");
137 std::vector<double> samples = source->process_batch(length);
144 std::vector<double> samples =
m_input_node->process_batch(length);
147 std::cerr <<
"No input node set for Filter. Use Filter::setInputNode() to set an input node.\n Alternatively, use Filter::updateCoefficientsFromNode() to specify a different source node.\n";
153 if (index > buffer.size()) {
154 buffer.resize(index + 1, 1.F);
156 buffer.at(index) = value;
194 double max_coef = 0.0;
196 max_coef = std::max(max_coef, std::abs(coef));
199 if (max_coef > 0.0) {
210 double omega = 2.0 * M_PI * frequency / sample_rate;
211 std::complex<double> z = std::exp(std::complex<double>(0, omega));
213 std::complex<double> numerator = 0.0;
214 for (
size_t i = 0; i <
m_coef_b.size(); ++i) {
215 numerator +=
m_coef_b[i] * std::pow(z, -
static_cast<int>(i));
218 std::complex<double> denominator = 0.0;
219 for (
size_t i = 0; i <
m_coef_a.size(); ++i) {
220 denominator +=
m_coef_a[i] * std::pow(z, -
static_cast<int>(i));
223 return numerator / denominator;
238 std::vector<double> output(num_samples);
239 for (
unsigned int i = 0; i < num_samples; ++i) {
263 if (condition(ctx)) {
void add_coef_internal(uint64_t index, double value, std::vector< double > &buffer)
Modifies a specific coefficient in a coefficient buffer.
void add_coef(int index, double value, coefficients type=coefficients::ALL)
Modifies a specific coefficient.
std::vector< double > process_batch(unsigned int num_samples) override
Calculates the phase response at a specific frequency.
virtual void reset()
Resets the filter's internal state.
void build_input_history(double current_sample)
Builds input history from external context or internal accumulation.
std::vector< double > m_coef_b
Feedforward (numerator) coefficients.
std::vector< double > m_output_history
Buffer storing previous output samples.
virtual void update_outputs(double current_sample)
Updates the output history buffer with a new sample.
std::shared_ptr< Node > m_input_node
The most recent sample value generated by this oscillator.
void update_coef_from_input(int length, coefficients type=coefficients::ALL)
Updates coefficients from the filter's own input.
virtual void initialize_shift_buffers()
Initializes the input and output history buffers.
std::complex< double > get_frequency_response(double frequency, double sample_rate) const
Calculates the complex frequency response at a specific frequency.
void set_coefs(const std::vector< double > &new_coefs, coefficients type=coefficients::ALL)
Updates filter coefficients.
Filter(const std::shared_ptr< Node > &input, const std::string &zindex_shifts)
Constructor using string-based filter configuration.
bool m_use_external_input_context
void normalize_coefficients(coefficients type=coefficients::ALL)
Normalizes filter coefficients.
void setACoefficients(const std::vector< double > &new_coefs)
Updates the feedback (denominator) coefficients.
std::vector< double > m_input_history
Buffer storing previous input samples.
void setBCoefficients(const std::vector< double > &new_coefs)
Updates the feedforward (numerator) coefficients.
virtual void update_inputs(double current_sample)
Updates the input history buffer with a new sample.
void update_coefs_from_node(int length, const std::shared_ptr< Node > &source, coefficients type=coefficients::ALL)
Updates coefficients from another node's output.
void notify_tick(double value) override
Notifies all registered callbacks with the current filter context.
FilterContextGpu m_context_gpu
std::pair< int, int > m_shift_config
Configuration for input and output buffer sizes.
std::span< double > m_external_input_context
External input context for input history.
double get_phase_response(double frequency, double sample_rate) const
Calculates the phase response at a specific frequency.
void update_context(double value) override
Updates filter-specific context object.
std::vector< double > m_coef_a
Feedback (denominator) coefficients.
double get_magnitude_response(double frequency, double sample_rate) const
Calculates the magnitude response at a specific frequency.
double process_sample(double input=0.) override=0
Processes a single sample through the filter.
NodeContext & get_last_context() override
Gets the last created context object.
Base class for computational signal transformers implementing difference equations.
double value
Current sample value.
Base context class for node callbacks.
std::vector< NodeHook > m_callbacks
Collection of standard callback functions.
std::vector< std::pair< NodeHook, NodeCondition > > m_conditional_callbacks
Collection of conditional callback functions with their predicates.
bool m_gpu_compatible
Flag indicating if the node supports GPU processing This flag is set by derived classes to indicate w...
std::pair< int, int > shift_parser(const std::string &str)
Parses a string representation of filter order into input/output shift configuration.