MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
MixProcessor.cpp
Go to the documentation of this file.
1#include "MixProcessor.hpp"
2
3#include "RootAudioBuffer.hpp"
4
5namespace MayaFlux::Buffers {
6
7MixSource::MixSource(const std::shared_ptr<AudioBuffer>& buffer, double level, bool once_flag)
8 : mix_level(level)
9 , once(once_flag)
10 , buffer_ref(buffer)
11{
12 if (buffer) {
13 data = buffer->get_data();
14 }
15}
16
18{
19 if (buffer_ref.expired()) {
20 return false;
21 }
22
23 if (auto buffer = buffer_ref.lock()) {
24 data = buffer->get_data();
25 return !data.empty();
26 }
27
28 return false;
29}
30
31bool MixProcessor::register_source(std::shared_ptr<AudioBuffer> source, double mix_level, bool once)
32{
33 if (!source || source->get_data().empty()) {
34 return false;
35 }
36
37 auto it = std::ranges::find_if(m_sources,
38 [&source](const MixSource& s) {
39 return s.matches_buffer(source);
40 });
41
42 if (it != m_sources.end()) {
43 it->mix_level = mix_level;
44 it->once = once;
45 it->refresh_data();
46 return true;
47 }
48
49 m_sources.emplace_back(source, mix_level, once);
50 return true;
51}
52
53void MixProcessor::processing_function(const std::shared_ptr<Buffer>& buffer)
54{
55 if (m_sources.empty()) {
56 return;
57 }
58
59 if (auto root_buffer = std::dynamic_pointer_cast<RootAudioBuffer>(buffer)) {
61
62 auto& data = root_buffer->get_data();
63
64 for (uint32_t i = 0; i < data.size(); i++) {
65 for (const auto& source : m_sources) {
66 if (source.has_sample_at(i)) {
67 data[i] += source.get_mixed_sample(i);
68 }
69 }
70
71 data[i] /= (double)m_sources.size();
72 }
73
74 cleanup();
75 }
76}
77
79{
80 std::erase_if(m_sources, [](const MixSource& s) { return s.once; });
81}
82
84{
85 std::erase_if(m_sources, [](MixSource& s) { return !s.refresh_data(); });
86}
87
88bool MixProcessor::remove_source(const std::shared_ptr<AudioBuffer>& buffer)
89{
90 if (!buffer) {
91 return false;
92 }
93
94 auto erased = std::erase_if(m_sources, [&buffer](const MixSource& s) {
95 return s.matches_buffer(buffer);
96 });
97
98 return erased > 0;
99}
100
101bool MixProcessor::update_source_mix(const std::shared_ptr<AudioBuffer>& buffer, double new_mix_level)
102{
103 for (auto& source : m_sources) {
104 if (source.matches_buffer(buffer)) {
105 source.mix_level = new_mix_level;
106 return true;
107 }
108 }
109 return false;
110}
111
112}
std::vector< MixSource > m_sources
void processing_function(const std::shared_ptr< Buffer > &buffer) override
the mechanism to mix output from one buffer to another channel
bool register_source(std::shared_ptr< AudioBuffer > source, double mix_level=1.0, bool once=false)
register an AudioBuffer source to be mixed into the output of specified channel
bool remove_source(const std::shared_ptr< AudioBuffer > &buffer)
Removes a source buffer from the mix.
bool update_source_mix(const std::shared_ptr< AudioBuffer > &buffer, double new_mix_level)
Updates the mix level of an existing source.
std::weak_ptr< AudioBuffer > buffer_ref
MixSource(const std::shared_ptr< AudioBuffer > &buffer, double level=1.0, bool once_flag=false)
bool matches_buffer(const std::shared_ptr< AudioBuffer > &buffer) const
Represents a source audio buffer with its data and mixing properties.