diff --git a/Cargo.lock b/Cargo.lock
index 5f50ab8d..e828726a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3756,6 +3756,7 @@ dependencies = [
name = "spectral_compressor"
version = "0.3.0"
dependencies = [
+ "atomic_float",
"crossbeam",
"nih_plug",
"nih_plug_vizia",
diff --git a/plugins/spectral_compressor/Cargo.toml b/plugins/spectral_compressor/Cargo.toml
index 13d57060..07b375e0 100644
--- a/plugins/spectral_compressor/Cargo.toml
+++ b/plugins/spectral_compressor/Cargo.toml
@@ -16,6 +16,7 @@ nih_plug_vizia = { path = "../../nih_plug_vizia" }
realfft = "3.0"
# For the GUI
+atomic_float = "0.1"
crossbeam = "0.8"
open = "3.0"
serde = { version = "1.0", features = ["derive"] }
diff --git a/plugins/spectral_compressor/src/editor.rs b/plugins/spectral_compressor/src/editor.rs
index 9ebe7e27..9f7a7457 100644
--- a/plugins/spectral_compressor/src/editor.rs
+++ b/plugins/spectral_compressor/src/editor.rs
@@ -14,15 +14,17 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+use atomic_float::AtomicF32;
use crossbeam::atomic::AtomicCell;
use nih_plug::prelude::*;
use nih_plug_vizia::vizia::prelude::*;
use nih_plug_vizia::widgets::*;
use nih_plug_vizia::{assets, create_vizia_editor, ViziaState, ViziaTheming};
use serde::{Deserialize, Serialize};
-use std::sync::Arc;
+use std::sync::{Arc, Mutex};
use self::mode_button::EditorModeButton;
+use crate::analyzer::AnalyzerData;
use crate::{SpectralCompressor, SpectralCompressorParams};
mod mode_button;
@@ -52,11 +54,16 @@ pub enum EditorMode {
AnalyzerVisible,
}
-#[derive(Lens)]
-struct Data {
- params: Arc,
+#[derive(Clone, Lens)]
+pub struct Data {
+ pub(crate) params: Arc,
- editor_mode: Arc>,
+ /// Determines which parts of the GUI are visible, and in turn decides the GUI's size.
+ pub(crate) editor_mode: Arc>,
+
+ pub(crate) analyzer_data: Arc>>,
+ /// Used by the analyzer to determine which FFT bins belong to which frequencies.
+ pub(crate) sample_rate: Arc,
}
impl Model for Data {}
@@ -69,20 +76,12 @@ pub(crate) fn default_state(editor_mode: Arc>) -> Arc,
- editor_state: Arc,
-) -> Option> {
+pub(crate) fn create(editor_state: Arc, editor_data: Data) -> Option> {
create_vizia_editor(editor_state, ViziaTheming::Custom, move |cx, _| {
assets::register_noto_sans_light(cx);
assets::register_noto_sans_thin(cx);
- Data {
- params: params.clone(),
-
- editor_mode: params.editor_mode.clone(),
- }
- .build(cx);
+ editor_data.clone().build(cx);
ResizeHandle::new(cx);
diff --git a/plugins/spectral_compressor/src/lib.rs b/plugins/spectral_compressor/src/lib.rs
index e9cf7b86..df4690f8 100644
--- a/plugins/spectral_compressor/src/lib.rs
+++ b/plugins/spectral_compressor/src/lib.rs
@@ -15,12 +15,14 @@
// along with this program. If not, see .
use analyzer::AnalyzerData;
+use atomic_float::AtomicF32;
use crossbeam::atomic::AtomicCell;
use editor::EditorMode;
use nih_plug::prelude::*;
use nih_plug_vizia::ViziaState;
use realfft::num_complex::Complex32;
use realfft::{ComplexToReal, RealFftPlanner, RealToComplex};
+use std::sync::atomic::Ordering;
use std::sync::{Arc, Mutex};
use triple_buffer::TripleBuffer;
@@ -54,6 +56,9 @@ pub struct SpectralCompressor {
/// The current buffer config, used for updating the compressors.
buffer_config: BufferConfig,
+ /// The current sample rate. Stores the same information as in `BufferConfig`, but this can be
+ /// shared with the editor where it's used to compute frequencies for the spectrum analyzer.
+ sample_rate: Arc,
/// An adapter that performs most of the overlap-add algorithm for us.
stft: util::StftHelper<1>,
@@ -166,6 +171,7 @@ impl Default for SpectralCompressor {
max_buffer_size: 0,
process_mode: ProcessMode::Realtime,
},
+ sample_rate: Arc::new(AtomicF32::new(1.0)),
// These three will be set to the correct values in the initialize function
stft: util::StftHelper::new(2, MAX_WINDOW_SIZE, 0),
@@ -311,7 +317,17 @@ impl Plugin for SpectralCompressor {
}
fn editor(&self, _async_executor: AsyncExecutor) -> Option> {
- editor::create(self.params.clone(), self.params.editor_state.clone())
+ editor::create(
+ self.params.editor_state.clone(),
+ editor::Data {
+ params: self.params.clone(),
+
+ editor_mode: self.params.editor_mode.clone(),
+
+ analyzer_data: self.analyzer_output_data.clone(),
+ sample_rate: self.sample_rate.clone(),
+ },
+ )
}
fn initialize(
@@ -323,6 +339,10 @@ impl Plugin for SpectralCompressor {
// Needed to update the compressors later
self.buffer_config = *buffer_config;
+ // And this is used in the editor to draw the analyzer
+ self.sample_rate
+ .store(buffer_config.sample_rate, Ordering::Relaxed);
+
// This plugin can accept a variable number of audio channels, so we need to resize
// channel-dependent data structures accordingly
let num_output_channels = audio_io_layout