MayaFlux 1.0.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 const bool normalize = root_buffer->is_mix_normalized();
64
65 for (uint32_t i = 0; i < data.size(); i++) {
66 for (const auto& source : m_sources) {
67 if (source.has_sample_at(i)) {
68 data[i] += source.get_mixed_sample(i);
69 }
70 }
71
72 if (normalize) {
73 data[i] /= (double)m_sources.size();
74 }
75 }
76
77 cleanup();
78 }
79}
80
82{
83 std::erase_if(m_sources, [](const MixSource& s) { return s.once; });
84}
85
87{
88 std::erase_if(m_sources, [](MixSource& s) { return !s.refresh_data(); });
89}
90
91bool MixProcessor::remove_source(const std::shared_ptr<AudioBuffer>& buffer)
92{
93 if (!buffer) {
94 return false;
95 }
96
97 auto erased = std::erase_if(m_sources, [&buffer](const MixSource& s) {
98 return s.matches_buffer(buffer);
99 });
100
101 return erased > 0;
102}
103
104bool MixProcessor::update_source_mix(const std::shared_ptr<AudioBuffer>& buffer, double new_mix_level)
105{
106 for (auto& source : m_sources) {
107 if (source.matches_buffer(buffer)) {
108 source.mix_level = new_mix_level;
109 return true;
110 }
111 }
112 return false;
113}
114
115}
std::shared_ptr< NetworkGeometryBuffer > buffer
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.