diff options
Diffstat (limited to 'src/audio/synth.cc')
| -rw-r--r-- | src/audio/synth.cc | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/src/audio/synth.cc b/src/audio/synth.cc index 0161385..d584c62 100644 --- a/src/audio/synth.cc +++ b/src/audio/synth.cc @@ -5,7 +5,9 @@ #include "synth.h" #include "audio/dct.h" #include "audio/ola.h" +#include "audio/ring_buffer.h" #include "util/debug.h" +#include <atomic> #include <math.h> #include <string.h> // For memset @@ -32,18 +34,18 @@ struct Voice { int start_sample_offset; // Samples to wait before producing audio output - const volatile float* active_spectral_data; + const float* active_spectral_data; }; static struct { Spectrogram spectrograms[MAX_SPECTROGRAMS]; - const volatile float* active_spectrogram_data[MAX_SPECTROGRAMS]; + std::atomic<const float*> active_spectrogram_data[MAX_SPECTROGRAMS]; bool spectrogram_registered[MAX_SPECTROGRAMS]; } g_synth_data; static Voice g_voices[MAX_VOICES]; -static volatile float g_current_output_peak = - 0.0f; // Global peak for visualization +static std::atomic<float> g_current_output_peak{ + 0.0f}; // Global peak for visualization static float g_tempo_scale = 1.0f; // Playback speed multiplier #if !defined(STRIP_ALL) @@ -53,7 +55,7 @@ static float g_elapsed_time_sec = 0.0f; // Tracks elapsed time for event hooks void synth_init() { memset(&g_synth_data, 0, sizeof(g_synth_data)); memset(g_voices, 0, sizeof(g_voices)); - g_current_output_peak = 0.0f; + g_current_output_peak.store(0.0f, std::memory_order_relaxed); #if !defined(STRIP_ALL) g_elapsed_time_sec = 0.0f; #endif /* !defined(STRIP_ALL) */ @@ -108,7 +110,8 @@ int synth_register_spectrogram(const Spectrogram* spec) { for (int i = 0; i < MAX_SPECTROGRAMS; ++i) { if (!g_synth_data.spectrogram_registered[i]) { g_synth_data.spectrograms[i] = *spec; - g_synth_data.active_spectrogram_data[i] = spec->spectral_data_a; + g_synth_data.active_spectrogram_data[i].store( + spec->spectral_data_a, std::memory_order_release); g_synth_data.spectrogram_registered[i] = true; return i; } @@ -128,8 +131,9 @@ float* synth_begin_update(int spectrogram_id) { return nullptr; } - const volatile float* active_ptr = - g_synth_data.active_spectrogram_data[spectrogram_id]; + const float* active_ptr = + g_synth_data.active_spectrogram_data[spectrogram_id].load( + std::memory_order_acquire); if (active_ptr == g_synth_data.spectrograms[spectrogram_id].spectral_data_a) { return (float*)(g_synth_data.spectrograms[spectrogram_id].spectral_data_b); @@ -144,18 +148,17 @@ void synth_commit_update(int spectrogram_id) { return; } - const volatile float* old_active_ptr = - g_synth_data.active_spectrogram_data[spectrogram_id]; + const float* old_active_ptr = + g_synth_data.active_spectrogram_data[spectrogram_id].load( + std::memory_order_acquire); const float* new_active_ptr = (old_active_ptr == g_synth_data.spectrograms[spectrogram_id].spectral_data_a) ? g_synth_data.spectrograms[spectrogram_id].spectral_data_b : g_synth_data.spectrograms[spectrogram_id].spectral_data_a; - // Atomic swap using GCC/Clang builtins for thread safety - __atomic_store_n( - (const float**)&g_synth_data.active_spectrogram_data[spectrogram_id], - new_active_ptr, __ATOMIC_RELEASE); + g_synth_data.active_spectrogram_data[spectrogram_id].store( + new_active_ptr, std::memory_order_release); } void synth_trigger_voice(int spectrogram_id, float volume, float pan, @@ -215,7 +218,8 @@ void synth_trigger_voice(int spectrogram_id, float volume, float pan, v.fractional_pos = 0.0f; v.start_sample_offset = start_offset_samples; v.active_spectral_data = - g_synth_data.active_spectrogram_data[spectrogram_id]; + g_synth_data.active_spectrogram_data[spectrogram_id].load( + std::memory_order_acquire); #if !defined(STRIP_ALL) // Notify backend of voice trigger event (for testing/tracking) @@ -233,7 +237,7 @@ void synth_trigger_voice(int spectrogram_id, float volume, float pan, void synth_render(float* output_buffer, int num_frames) { // Faster decay for more responsive visuals - g_current_output_peak *= 0.90f; + float peak = g_current_output_peak.load(std::memory_order_relaxed) * 0.90f; for (int i = 0; i < num_frames; ++i) { float left_sample = 0.0f; @@ -258,7 +262,8 @@ void synth_render(float* output_buffer, int num_frames) { // Fetch the latest active spectrogram pointer for this voice v.active_spectral_data = - g_synth_data.active_spectrogram_data[v.spectrogram_id]; + g_synth_data.active_spectrogram_data[v.spectrogram_id].load( + std::memory_order_acquire); const float* spectral_frame = (const float*)v.active_spectral_data + (v.current_spectral_frame * DCT_SIZE); @@ -286,14 +291,14 @@ void synth_render(float* output_buffer, int num_frames) { output_buffer[i * 2 + 1] = right_sample; // Update the peak with the new max (attack) - g_current_output_peak = fmaxf( - g_current_output_peak, fmaxf(fabsf(left_sample), fabsf(right_sample))); + peak = fmaxf(peak, fmaxf(fabsf(left_sample), fabsf(right_sample))); } + g_current_output_peak.store(peak, std::memory_order_release); + #if !defined(STRIP_ALL) - // Update elapsed time for event tracking (32000 Hz sample rate) - const float sample_rate = 32000.0f; - g_elapsed_time_sec += (float)num_frames / sample_rate; + // Update elapsed time for event tracking + g_elapsed_time_sec += (float)num_frames / RING_BUFFER_SAMPLE_RATE; #endif /* !defined(STRIP_ALL) */ } @@ -308,5 +313,5 @@ int synth_get_active_voice_count() { } float synth_get_output_peak() { - return g_current_output_peak; + return g_current_output_peak.load(std::memory_order_acquire); } |
