Line data Source code
1 : #include "audio/engine/audio_engine.h"
2 : #include <cstring>
3 : #include <algorithm>
4 :
5 : namespace Amplitron {
6 :
7 291 : void AudioEngine::set_input_gain(float gain) {
8 291 : AudioCommand cmd{};
9 291 : cmd.type = AudioCommand::SetInputGain;
10 291 : cmd.value = gain;
11 291 : command_queue_.try_push(cmd);
12 291 : input_gain_.store(gain, std::memory_order_relaxed);
13 291 : }
14 :
15 243 : void AudioEngine::set_output_gain(float gain) {
16 243 : AudioCommand cmd{};
17 243 : cmd.type = AudioCommand::SetOutputGain;
18 243 : cmd.value = gain;
19 243 : command_queue_.try_push(cmd);
20 243 : output_gain_.store(gain, std::memory_order_relaxed);
21 243 : }
22 :
23 15 : void AudioEngine::toggle_metronome() {
24 15 : bool enabled = !metronome_enabled_state_.load(std::memory_order_relaxed);
25 15 : metronome_enabled_state_.store(enabled, std::memory_order_relaxed);
26 15 : }
27 :
28 18 : void AudioEngine::set_metronome_bpm(int bpm) {
29 18 : const int clamped = std::max(40, std::min(bpm, 240));
30 18 : metronome_bpm_state_.store(clamped, std::memory_order_relaxed);
31 18 : }
32 :
33 12 : void AudioEngine::set_metronome_volume(float volume) {
34 12 : const float clamped = std::max(0.0f, std::min(volume, 1.0f));
35 12 : metronome_volume_state_.store(clamped, std::memory_order_relaxed);
36 12 : }
37 :
38 33 : void AudioEngine::push_param_change(int effect_index, int param_index, float value) {
39 33 : AudioCommand cmd{};
40 33 : cmd.type = AudioCommand::SetEffectParam;
41 33 : cmd.effect_index = effect_index;
42 33 : cmd.param_index = param_index;
43 33 : cmd.value = value;
44 33 : command_queue_.try_push(cmd);
45 33 : }
46 :
47 21 : void AudioEngine::push_effect_enabled(int effect_index, float enabled) {
48 21 : AudioCommand cmd{};
49 21 : cmd.type = AudioCommand::SetEffectEnabled;
50 21 : cmd.effect_index = effect_index;
51 21 : cmd.value = enabled;
52 21 : command_queue_.try_push(cmd);
53 21 : }
54 :
55 6 : void AudioEngine::push_effect_mix(int effect_index, float mix) {
56 6 : AudioCommand cmd{};
57 6 : cmd.type = AudioCommand::SetEffectMix;
58 6 : cmd.effect_index = effect_index;
59 6 : cmd.value = mix;
60 6 : command_queue_.try_push(cmd);
61 6 : }
62 :
63 0 : void AudioEngine::push_mixer_gain_change(int node_id, int pin_index, float gain) {
64 0 : AudioCommand cmd{};
65 0 : cmd.type = AudioCommand::SetMixerGain;
66 0 : cmd.effect_index = node_id; // Overload effect_index to mean node_id
67 0 : cmd.param_index = pin_index; // Overload param_index to mean pin_index
68 0 : cmd.value = gain;
69 0 : command_queue_.try_push(cmd);
70 0 : }
71 :
72 9 : int AudioEngine::get_suggested_buffer_size() const {
73 9 : float load = cpu_load_.load(std::memory_order_relaxed);
74 9 : int current = buffer_size_;
75 :
76 9 : if (load > 0.80f) {
77 0 : if (current < MAX_BUFFER_SIZE) {
78 0 : return std::min(current * 2, MAX_BUFFER_SIZE);
79 : }
80 0 : }
81 9 : if (load < 0.30f) {
82 9 : if (current > MIN_BUFFER_SIZE) {
83 12 : return std::max(current / 2, MIN_BUFFER_SIZE);
84 : }
85 0 : }
86 0 : return current;
87 3 : }
88 :
89 15 : bool AudioEngine::copy_analyzer_snapshot(float* input_dest,
90 : float* output_dest,
91 : int sample_count) const {
92 15 : if (!input_dest || !output_dest || sample_count <= 0) {
93 6 : return false;
94 : }
95 :
96 6 : const int count = std::min(sample_count, ANALYZER_FFT_SIZE);
97 6 : std::lock_guard<std::mutex> lock(analyzer_mutex_);
98 6 : const uint64_t seq = analyzer_sequence_.load(std::memory_order_relaxed);
99 6 : if (seq == 0) {
100 2 : return false;
101 : }
102 :
103 3 : std::memcpy(input_dest, analyzer_snapshot_input_.data(), static_cast<size_t>(count) * sizeof(float));
104 3 : std::memcpy(output_dest, analyzer_snapshot_output_.data(), static_cast<size_t>(count) * sizeof(float));
105 3 : return true;
106 9 : }
107 :
108 3 : void AudioEngine::update_level_analyzer(float dt) {
109 3 : const float input_rms = get_input_rms();
110 3 : const float output_rms = get_output_rms();
111 3 : const bool input_clipped = consume_input_clipped();
112 3 : const bool output_clipped = consume_output_clipped();
113 3 : level_analyzer_.update(input_rms, output_rms, input_clipped, output_clipped, dt);
114 3 : }
115 :
116 3 : void AudioEngine::update_spectrum_analyzer(float dt) {
117 3 : const uint64_t seq = get_analyzer_sequence();
118 3 : if (seq == analyzer_last_sequence_) {
119 5 : spectrum_analyzer_.update(analyzer_input_buf_.data(),
120 4 : analyzer_output_buf_.data(),
121 1 : get_sample_rate(),
122 1 : dt);
123 3 : return;
124 : }
125 :
126 0 : if (copy_analyzer_snapshot(analyzer_input_buf_.data(),
127 0 : analyzer_output_buf_.data(),
128 : ANALYZER_FFT_SIZE)) {
129 0 : spectrum_analyzer_.update(analyzer_input_buf_.data(),
130 0 : analyzer_output_buf_.data(),
131 0 : get_sample_rate(),
132 0 : dt);
133 0 : analyzer_last_sequence_ = seq;
134 0 : }
135 1 : }
136 :
137 : } // namespace Amplitron
|