Add the basis for a simple STFT example
Right now it doesn't do any FFT operations yet, but all the pieces are in place using the new STFT helper.
This commit is contained in:
parent
b2600f4b93
commit
b416d1630b
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -855,6 +855,13 @@ dependencies = [
|
|||
"wayland-client",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stft"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"nih_plug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.86"
|
||||
|
|
|
@ -21,6 +21,7 @@ members = [
|
|||
"plugins/examples/gain",
|
||||
"plugins/examples/gain-gui",
|
||||
"plugins/examples/sine",
|
||||
"plugins/examples/stft",
|
||||
|
||||
"plugins/diopser",
|
||||
]
|
||||
|
|
|
@ -77,6 +77,10 @@ examples.
|
|||
- [**sine**](plugins/examples/sine) is a simple test tone generator plugin with
|
||||
frequency smoothing that can also make use of MIDI input instead of generating
|
||||
a static signal based on the plugin's parameters.
|
||||
- [**stft**](plugins/examples/stft) shows off some of NIH-plug's other optional
|
||||
helper features, like an adapter to process audio in buffered blocks meant for
|
||||
short-term Fourier transform operations, all using the compositional `Buffer`
|
||||
interface.
|
||||
|
||||
## Licensing
|
||||
|
||||
|
|
12
plugins/examples/stft/Cargo.toml
Normal file
12
plugins/examples/stft/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "stft"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Robbert van der Helm <mail@robbertvanderhelm.nl>"]
|
||||
license = "ISC"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
nih_plug = { path = "../../../", features = ["assert_process_allocs"] }
|
98
plugins/examples/stft/src/lib.rs
Normal file
98
plugins/examples/stft/src/lib.rs
Normal file
|
@ -0,0 +1,98 @@
|
|||
use nih_plug::prelude::*;
|
||||
use std::pin::Pin;
|
||||
|
||||
struct Stft {
|
||||
params: Pin<Box<StftParams>>,
|
||||
|
||||
stft: util::StftHelper,
|
||||
}
|
||||
|
||||
#[derive(Params)]
|
||||
struct StftParams {}
|
||||
|
||||
impl Default for Stft {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
params: Box::pin(StftParams::default()),
|
||||
|
||||
stft: util::StftHelper::new(2, 512),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for StftParams {
|
||||
fn default() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Plugin for Stft {
|
||||
const NAME: &'static str = "STFT Example";
|
||||
const VENDOR: &'static str = "Moist Plugins GmbH";
|
||||
const URL: &'static str = "https://youtu.be/dQw4w9WgXcQ";
|
||||
const EMAIL: &'static str = "info@example.com";
|
||||
|
||||
const VERSION: &'static str = "0.0.1";
|
||||
|
||||
const DEFAULT_NUM_INPUTS: u32 = 2;
|
||||
const DEFAULT_NUM_OUTPUTS: u32 = 2;
|
||||
|
||||
const ACCEPTS_MIDI: bool = false;
|
||||
|
||||
fn params(&self) -> Pin<&dyn Params> {
|
||||
self.params.as_ref()
|
||||
}
|
||||
|
||||
fn accepts_bus_config(&self, config: &BusConfig) -> bool {
|
||||
// We'll only do stereo for simplicity's sake
|
||||
config.num_input_channels == config.num_output_channels && config.num_input_channels == 2
|
||||
}
|
||||
|
||||
fn initialize(
|
||||
&mut self,
|
||||
_bus_config: &BusConfig,
|
||||
_buffer_config: &BufferConfig,
|
||||
context: &mut impl ProcessContext,
|
||||
) -> bool {
|
||||
// Normally we'd also initialize the STFT helper for the correct channel count here, but we
|
||||
// only do stereo so that's not necessary
|
||||
self.stft.set_block_size(512);
|
||||
context.set_latency_samples(self.stft.latency_samples());
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn process(
|
||||
&mut self,
|
||||
buffer: &mut Buffer,
|
||||
_context: &mut impl ProcessContext,
|
||||
) -> ProcessStatus {
|
||||
self.stft.process(buffer, [], |block, _| {
|
||||
for channel_samples in block.iter_mut() {
|
||||
for sample in channel_samples {
|
||||
// TODO: Use the FFTW bindings and do some STFT operation here instead of
|
||||
// reducing the gain at a 512 sample latency...
|
||||
*sample *= 0.5;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ProcessStatus::Normal
|
||||
}
|
||||
}
|
||||
|
||||
impl ClapPlugin for Stft {
|
||||
const CLAP_ID: &'static str = "com.moist-plugins-gmbh.stft";
|
||||
const CLAP_DESCRIPTION: &'static str = "An example plugin using the STFT helper";
|
||||
const CLAP_FEATURES: &'static [&'static str] = &["audio_effect", "stereo", "tool"];
|
||||
const CLAP_MANUAL_URL: &'static str = Self::URL;
|
||||
const CLAP_SUPPORT_URL: &'static str = Self::URL;
|
||||
}
|
||||
|
||||
impl Vst3Plugin for Stft {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"StftMoistestPlug";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Tools";
|
||||
}
|
||||
|
||||
nih_export_clap!(Stft);
|
||||
nih_export_vst3!(Stft);
|
Loading…
Reference in a new issue