158 config_.sample_rate = std::isfinite(config.sample_rate) && config.sample_rate > 0.0f
161 config_.spectrum_floor_db = std::isfinite(config.spectrum_floor_db)
162 ? std::clamp(config.spectrum_floor_db, -300.0f, 0.0f)
164 config_.max_frames_per_poll = std::max(0, config.max_frames_per_poll);
165 config_.max_callback_frames = std::max(1, config.max_callback_frames);
170 stft_cfg.
fft_size = config_.fft_size;
171 stft_cfg.
hop_size = config_.hop_size;
172 stft_cfg.
window = config_.window;
174 channel_stfts_.clear();
175 channel_stfts_.resize(
static_cast<std::size_t
>(config_.num_channels));
176 for (
auto& stft : channel_stfts_)
177 stft.configure(stft_cfg);
178 spectrum_edge_scale_ = 1.0;
179 spectrum_interior_scale_ = 1.0;
180 if (!channel_stfts_.empty()) {
181 const double window_sum =
static_cast<double>(channel_stfts_.front().window_sum());
182 if (std::isfinite(window_sum) && std::abs(window_sum) > 1.0e-12) {
183 spectrum_edge_scale_ = 1.0 / window_sum;
184 spectrum_interior_scale_ = 2.0 / window_sum;
189 meter_.prepare(config_.sample_rate, config_.num_channels);
192 waveform_length_ = config_.capture_waveform
193 ? std::clamp(config_.waveform_length, 1,
198 const int automatic_capacity = std::max(
199 {config_.fft_size * 4, std::max(1, waveform_length_), config_.max_callback_frames});
200 const int requested_capacity =
201 config_.capture_buffer_frames > 0 ? config_.capture_buffer_frames : automatic_capacity;
202 capture_capacity_frames_ =
203 std::max({config_.fft_size, requested_capacity, config_.max_callback_frames});
204 capture_ready_ = capture_.prepare(
static_cast<std::uint32_t
>(channel_stfts_.size()),
205 static_cast<std::uint64_t
>(capture_capacity_frames_));
207 consumer_chunk_frames_ = std::min(capture_capacity_frames_, 4096);
208 consumer_storage_.assign(
209 channel_stfts_.size() *
static_cast<std::size_t
>(consumer_chunk_frames_), 0.0f);
210 consumer_channels_.resize(channel_stfts_.size());
211 for (std::size_t ch = 0; ch < channel_stfts_.size(); ++ch) {
212 consumer_channels_[ch] =
213 consumer_storage_.data() + ch *
static_cast<std::size_t
>(consumer_chunk_frames_);
216 dropped_capture_frames_.store(0, std::memory_order_relaxed);
217 discontinuity_generation_.store(0, std::memory_order_relaxed);
218 acknowledged_discontinuity_.store(0, std::memory_order_relaxed);
219 observed_discontinuity_ = 0;
220 spectrum_sequence_ = 0;
221 waveform_sequence_ = 0;
254 return spectrum_buf_.read();
266 return meter_buf_.read();
271 return waveform_buf_.read();
284 return config_.fft_size;
287 return channel_stfts_.empty() ? 0 : channel_stfts_.front().num_bins();
290 return config_.num_channels;
293 return config_.sample_rate;
300 for (
auto& stft : channel_stfts_)
304 std::fill(waveform_ring_.begin(), waveform_ring_.end(), 0.0f);
305 dropped_capture_frames_.store(0, std::memory_order_relaxed);
306 discontinuity_generation_.store(0, std::memory_order_relaxed);
307 acknowledged_discontinuity_.store(0, std::memory_order_relaxed);
308 observed_discontinuity_ = 0;
309 spectrum_sequence_ = 0;
310 waveform_sequence_ = 0;
319 void reset_analysis_continuity();
325 bool capture_ready_ =
false;
326 int capture_capacity_frames_ = 0;
329 std::vector<signal::Stft> channel_stfts_;
330 std::vector<float> consumer_storage_;
331 std::vector<float*> consumer_channels_;
332 int consumer_chunk_frames_ = 0;
335 double spectrum_edge_scale_ = 1.0;
336 double spectrum_interior_scale_ = 1.0;
347 std::array<float, WaveformData::kMaxSamples> waveform_ring_{};
348 int waveform_length_ = 1024;
349 int waveform_pos_ = 0;
351 std::atomic<std::uint64_t> dropped_capture_frames_{0};
355 std::atomic<std::uint64_t> discontinuity_generation_{0};
356 std::atomic<std::uint64_t> acknowledged_discontinuity_{0};
357 std::uint64_t observed_discontinuity_ = 0;
358 std::uint64_t spectrum_sequence_ = 0;
359 std::uint64_t waveform_sequence_ = 0;
360 std::uint64_t epoch_ = 0;
363 VisualizationBenchSink bench_sink_{};
Definition planar_audio_ring_buffer.hpp:22
const WaveformData & peek_waveform()
Cheap snapshot-only waveform read. Never calls poll().
Definition visualization_bridge.hpp:270
const SpectrumData & read_spectrum()
Legacy snapshot-read name retained for compile compatibility.
Definition visualization_bridge.hpp:260
const WaveformData & read_waveform()
Legacy snapshot-read name retained for compile compatibility.
Definition visualization_bridge.hpp:277
const SpectrumData & peek_spectrum()
Cheap snapshot-only read. Never drains audio or performs FFT work.
Definition visualization_bridge.hpp:253
float sample_rate() const
Definition visualization_bridge.hpp:292
const signal::MultiChannelMeterData & read_meter()
Read the latest multi-channel meter data.
Definition visualization_bridge.hpp:265
void configure(const VisualizationConfig &config)
Configure all visualization subsystems.
Definition visualization_bridge.hpp:155
VisualizationBridge()=default
int fft_size() const
Definition visualization_bridge.hpp:283
void process(const float *const *channels, int num_channels, int num_samples) noexcept
Process audio from the audio callback.
void reset()
Reset all internal state after playback stops.
Definition visualization_bridge.hpp:298
bool poll()
Consume at most the captured frame count visible at entry and publish the latest spectrum/waveform.
int num_channels() const
Definition visualization_bridge.hpp:289
int num_bins() const
Definition visualization_bridge.hpp:286
Lock-free triple buffer for publishing the latest value from a writer thread to a reader thread witho...
Definition triple_buffer.hpp:45
Type
Definition windowing.hpp:43
@ hann
Definition windowing.hpp:45
Multi-channel metering: sample peak, RMS, K-weighted momentary and gated integrated loudness,...
Definition audio_bridge.hpp:9
VisualizationBacklogPolicy
How poll() treats captured audio it has not analyzed yet.
Definition visualization_bridge.hpp:73
@ latest_window
Display-oriented: every poll consumes the whole backlog, treating max_frames_per_poll as unbounded,...
Definition visualization_bridge.hpp:89
@ in_order
Analyze every captured frame in order, at most max_frames_per_poll per call.
Definition visualization_bridge.hpp:79
MultiChannelMeterT< float > MultiChannelMeter
Definition multi_channel_meter.hpp:1083
static constexpr int kMaxMeterChannels
Maximum supported channel count for metering.
Definition multi_channel_meter.hpp:35
Color ramp mapping and frequency axis utilities for spectrogram display.
Short-Time Fourier Transform abstraction for audio visualization.
Published one-sided amplitude spectrum (lock-free via TripleBuffer).
Definition visualization_bridge.hpp:46
int fft_size
Definition visualization_bridge.hpp:55
int source_channels
Definition visualization_bridge.hpp:54
float floor_db
Definition visualization_bridge.hpp:57
static constexpr int kMaxBins
Definition visualization_bridge.hpp:47
std::array< float, kMaxBins > magnitude_db
Definition visualization_bridge.hpp:49
std::uint64_t dropped_frames
Definition visualization_bridge.hpp:53
std::uint64_t sequence_number
Definition visualization_bridge.hpp:52
float sample_rate
Definition visualization_bridge.hpp:56
std::uint64_t epoch
Definition visualization_bridge.hpp:51
int num_bins
Definition visualization_bridge.hpp:50
Where the bridge reports its benchmark timings.
Definition visualization_bridge.hpp:34
std::atomic< double > * triplebuffer_publish_total_us
Definition visualization_bridge.hpp:36
std::atomic< double > * audio_copy_total_us
Definition visualization_bridge.hpp:35
Configuration for the visualization bridge.
Definition visualization_bridge.hpp:93
float spectrum_floor_db
Definition visualization_bridge.hpp:122
int hop_size
Definition visualization_bridge.hpp:96
int capture_buffer_frames
Definition visualization_bridge.hpp:114
VisualizationBacklogPolicy backlog_policy
Definition visualization_bridge.hpp:135
float sample_rate
Definition visualization_bridge.hpp:104
int waveform_length
Definition visualization_bridge.hpp:108
int num_channels
Definition visualization_bridge.hpp:103
int fft_size
Definition visualization_bridge.hpp:95
int max_callback_frames
Definition visualization_bridge.hpp:128
signal::WindowFunction::Type window
Definition visualization_bridge.hpp:97
int max_frames_per_poll
Definition visualization_bridge.hpp:119
bool capture_waveform
Definition visualization_bridge.hpp:107
float window_param
Definition visualization_bridge.hpp:98
Complete metering snapshot for all channels, published lock-free.
Definition multi_channel_meter.hpp:130
Configuration for an STFT processor.
Definition stft.hpp:20
float window_param
Definition stft.hpp:24
WindowFunction::Type window
Definition stft.hpp:23
int fft_size
Definition stft.hpp:21
int hop_size
Definition stft.hpp:22
Lock-free latest-value publication between two threads.