Line data Source code
1 : #include "audio/engine/analyzer_capture.h"
2 :
3 : #include <algorithm>
4 : #include <cstring>
5 :
6 : namespace Amplitron {
7 :
8 1090 : AnalyzerCapture::AnalyzerCapture() {
9 814 : capture_input_.fill(0.0f);
10 814 : capture_output_.fill(0.0f);
11 814 : snapshot_input_.fill(0.0f);
12 814 : snapshot_output_.fill(0.0f);
13 814 : }
14 :
15 12 : void AnalyzerCapture::set_analyzer_enabled(bool enabled) {
16 12 : enabled_.store(enabled, std::memory_order_release);
17 12 : }
18 :
19 4640 : bool AnalyzerCapture::is_analyzer_enabled() const {
20 4640 : return enabled_.load(std::memory_order_acquire);
21 : }
22 :
23 3 : uint64_t AnalyzerCapture::get_analyzer_sequence() const {
24 4 : return sequence_.load(std::memory_order_acquire);
25 : }
26 :
27 18 : bool AnalyzerCapture::copy_analyzer_snapshot(float* input_dest, float* output_dest,
28 : int sample_count) const {
29 18 : if (!input_dest || !output_dest || sample_count <= 0) {
30 6 : return false;
31 : }
32 :
33 9 : const int count = std::min(sample_count, ANALYZER_FFT_SIZE);
34 9 : std::lock_guard<std::mutex> lock(mutex_);
35 9 : const uint64_t seq = sequence_.load(std::memory_order_relaxed);
36 9 : if (seq == 0) {
37 4 : return false;
38 : }
39 :
40 3 : std::memcpy(input_dest, snapshot_input_.data(), static_cast<size_t>(count) * sizeof(float));
41 3 : std::memcpy(output_dest, snapshot_output_.data(), static_cast<size_t>(count) * sizeof(float));
42 3 : return true;
43 12 : }
44 :
45 24 : void AnalyzerCapture::capture_input(const float* input, int count) {
46 24 : if (!enabled_.load(std::memory_order_relaxed)) return;
47 :
48 24 : int cap = capture_index_;
49 7320 : for (int i = 0; i < count; ++i) {
50 7296 : capture_input_[cap] = input[i];
51 7296 : cap = (cap + 1) & ANALYZER_FFT_MASK;
52 2432 : }
53 24 : capture_index_ = cap;
54 8 : }
55 :
56 24 : void AnalyzerCapture::capture_output(const float* output, int count) {
57 24 : if (!enabled_.load(std::memory_order_relaxed)) return;
58 :
59 24 : int cap = (capture_index_ - count) & ANALYZER_FFT_MASK;
60 7320 : for (int i = 0; i < count; ++i) {
61 7296 : capture_output_[cap] = output[i];
62 7296 : cap = (cap + 1) & ANALYZER_FFT_MASK;
63 2432 : }
64 :
65 24 : samples_since_publish_ += count;
66 24 : if (samples_since_publish_ >= ANALYZER_HOP_SIZE) {
67 6 : if (mutex_.try_lock()) {
68 6 : const int start = capture_index_;
69 6 : const int first_chunk = ANALYZER_FFT_SIZE - start;
70 8 : std::memcpy(snapshot_input_.data(), capture_input_.data() + start,
71 6 : static_cast<size_t>(first_chunk) * sizeof(float));
72 8 : std::memcpy(snapshot_input_.data() + first_chunk, capture_input_.data(),
73 4 : static_cast<size_t>(start) * sizeof(float));
74 8 : std::memcpy(snapshot_output_.data(), capture_output_.data() + start,
75 4 : static_cast<size_t>(first_chunk) * sizeof(float));
76 8 : std::memcpy(snapshot_output_.data() + first_chunk, capture_output_.data(),
77 4 : static_cast<size_t>(start) * sizeof(float));
78 6 : sequence_.fetch_add(1, std::memory_order_release);
79 6 : samples_since_publish_ = 0;
80 6 : mutex_.unlock();
81 2 : }
82 2 : }
83 8 : }
84 :
85 : } // namespace Amplitron
|