MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
FeedbackBuffer.cpp
Go to the documentation of this file.
1#include "FeedbackBuffer.hpp"
2
3namespace MayaFlux::Buffers {
4
5FeedbackBuffer::FeedbackBuffer(uint32_t channel_id, uint32_t num_samples, float feedback, uint32_t feed_samples)
6 : AudioBuffer(channel_id, num_samples)
7 , m_feedback_amount(feedback)
8 , m_feed_samples(feed_samples)
9{
11 m_previous_buffer.resize(feed_samples, 0.F);
12}
13
15{
16 m_default_processor->process(shared_from_this());
17}
18
19void FeedbackProcessor::on_detach(std::shared_ptr<Buffer> /*buffer*/)
20{
22 m_previous_buffer.clear();
23 }
24}
25
26std::shared_ptr<BufferProcessor> FeedbackBuffer::create_default_processor()
27{
28 return std::make_shared<FeedbackProcessor>(m_feedback_amount, m_feed_samples);
29}
30
31FeedbackProcessor::FeedbackProcessor(float feedback, uint32_t feed_samples)
32 : m_feedback_amount(feedback)
33 , m_feed_samples(feed_samples)
34 , m_using_internal_buffer(false)
35{
36}
37
38void FeedbackProcessor::processing_function(std::shared_ptr<Buffer> buffer)
39{
40 auto audio_buffer = std::dynamic_pointer_cast<AudioBuffer>(buffer);
41 if (!audio_buffer)
42 return;
43
44 std::vector<double>* previous_data = nullptr;
45 auto& buffer_data = audio_buffer->get_data();
46
47 if (auto feedback_buffer = std::dynamic_pointer_cast<FeedbackBuffer>(buffer)) {
48 previous_data = &feedback_buffer->get_previous_buffer();
50 } else {
51 if (m_previous_buffer.size() != m_feed_samples) {
54 }
55 previous_data = &m_previous_buffer;
56 }
57
58 for (double& sample : buffer_data) {
59 double delayed_sample = (*previous_data)[m_buffer_index];
60
61 double output_sample = sample + (m_feedback_amount * delayed_sample);
62
63 if (m_feed_samples > 1) {
64 size_t next_index = (m_buffer_index + 1) % m_feed_samples;
65 output_sample = (output_sample + (*previous_data)[next_index]) * 0.5;
66 }
67
68 sample = output_sample;
69
70 (*previous_data)[m_buffer_index] = output_sample;
71
73 }
74}
75
76void FeedbackProcessor::on_attach(std::shared_ptr<Buffer> buffer)
77{
78 if (auto feedback_buffer = std::dynamic_pointer_cast<FeedbackBuffer>(buffer)) {
80
81 if (m_feed_samples != feedback_buffer->get_feed_samples()) {
82 m_feed_samples = feedback_buffer->get_feed_samples();
83 }
84
85 if (m_feedback_amount != feedback_buffer->get_feedback()) {
86 feedback_buffer->set_feedback(m_feedback_amount);
87 }
88 if (m_previous_buffer.size() != m_feed_samples) {
90 }
91
92 } else {
93 m_previous_buffer.resize(std::dynamic_pointer_cast<AudioBuffer>(buffer)->get_num_samples(), 0.0);
95 }
97}
98
99}
std::shared_ptr< BufferProcessor > m_default_processor
Default audio transformation processor for this buffer.
Concrete audio implementation of the Buffer interface for double-precision audio data.
void process_default() override
Processes this buffer using its default processor.
FeedbackBuffer(uint32_t channel_id=0, uint32_t num_samples=512, float feedback=0.5F, uint32_t feed_samples=512)
Creates a new feedback buffer.
std::vector< double > m_previous_buffer
Storage for the previous system state.
float m_feedback_amount
Feedback coefficient (0.0-1.0)
std::shared_ptr< BufferProcessor > create_default_processor() override
Creates the default processor for this buffer type.
FeedbackProcessor(float feedback=0.5F, uint32_t feed_samples=512)
Creates a new feedback processor.
bool m_using_internal_buffer
Flag indicating whether to use the buffer's internal previous state.
uint32_t m_feed_samples
Number of samples to feed back.
void on_detach(std::shared_ptr< Buffer > buffer) override
Called when this processor is detached from a buffer.
std::vector< double > m_previous_buffer
Storage for the previous system state.
void processing_function(std::shared_ptr< Buffer > buffer) override
Processes a buffer by applying the recursive algorithm.
void on_attach(std::shared_ptr< Buffer > buffer) override
Called when this processor is attached to a buffer.
float m_feedback_amount
Feedback coefficient (0.0-1.0)