[sosten] add direction

This commit is contained in:
annieversary 2021-08-05 16:35:35 +02:00
parent 43605dfa87
commit 350e6d1bde
2 changed files with 55 additions and 6 deletions

View file

@ -83,13 +83,14 @@ it's useful when you want to play a note super fast (over 1/64 tempo) but don't
### sosten ### sosten
sustains a sound by replaying a grain of sound on loop sustains a sound by replaying a grain of sound on loop. small but versatile
parameters: parameters:
- `enable`: will enable the sustain if it's over 0.5 - `enable`: will enable the sustain if it's over 0.5
- `length`: length of the grain in samples. maximum is 48000 cause i said so - `length`: length of the grain in samples. maximum is 48000 cause i said so
- `manual/pitch detection`: whether to use the manually set length (if under 0.5) or use the detected pitch (over 0.5) - `manual/pitch detection`: whether to use the manually set length (if under 0.5) or use the detected pitch (over 0.5)
- `dissipation`: amount of dissipation of the input - `dissipation`: amount of dissipation of the input
- `direction`: direction in which the grain is played
to use this plugin, add an automation for `enable` and set the value to `1.0` wherever you want the sustain to happen. as soon as that happens, it'll start looping the last `length` samples to use this plugin, add an automation for `enable` and set the value to `1.0` wherever you want the sustain to happen. as soon as that happens, it'll start looping the last `length` samples
@ -97,13 +98,23 @@ if set to manual, it uses the provided length for the looped grain. if pitch det
dissipation is a weird thingy. it smooths out the sound, and i think it's a lowpass filter? not sure. makes cool sounds though. what it does is roughly `x[n] = dissipation * x[n] + (1 - dissipation) * x[n + 1]` after each time it plays a sample, so `dissipation = 1` will leave the audio untouched, and setting it to `0.5` provides the greatest effect dissipation is a weird thingy. it smooths out the sound, and i think it's a lowpass filter? not sure. makes cool sounds though. what it does is roughly `x[n] = dissipation * x[n] + (1 - dissipation) * x[n + 1]` after each time it plays a sample, so `dissipation = 1` will leave the audio untouched, and setting it to `0.5` provides the greatest effect
low lengths will almost produce a tone of frequency `1 / length`, which makes for interesting sounds direction is a selector, with three ranges:
- `[0, 0.4)`: the grain will be played backwards
- `[0.4, 0.6)`: the grain will cycle through forwards and backwards
- `[0.6, 1.0]`: the grain will play forwards
my three main uses are:
- sustaining a note, which you can do with `manual/pitch detection = 1`, `direction = 1`, and any amount of dissipation
- wavetable-ish kinda thing, by setting `manual = 0` and a really low length, you can play notes of frequency `1 / length`
- glitch repetition effect, by setting `manual = 0`, any direction (but usually forward), any dissipation, and a medium length. enable at the end of a bar or smth
but you can probably use it for more stuff! idk! this are just my suggestions
### quinoa [WIP] ### quinoa [WIP]
nothing implemented yet, but it's supposed to be a granular synthesis plugin that does stuff with an audio file nothing implemented yet, but it's supposed to be a granular synthesis plugin that does stuff with an audio file
since this needs a ui so we can select a file to play, and i still don't know how to do that, it's kinda stuck since this needs a ui so we can select a file to play, and i still don't know how to do that, progress is kinda stuck
### XLowpass ### XLowpass

View file

@ -27,6 +27,9 @@ baseplug::model! {
#[model(min = 0.0, max = 1.0)] #[model(min = 0.0, max = 1.0)]
#[parameter(name = "dissipation")] #[parameter(name = "dissipation")]
dissipation: f32, dissipation: f32,
#[model(min = 0.0, max = 1.0)]
#[parameter(name = "direction")]
direction: f32,
} }
} }
@ -37,6 +40,7 @@ impl Default for SostenModel {
length: 1000.0, length: 1000.0,
manual: 0.0, manual: 0.0,
dissipation: 1.0, dissipation: 1.0,
direction: 1.0,
} }
} }
} }
@ -53,6 +57,9 @@ struct Sosten {
/// Period of the processed input /// Period of the processed input
/// We keep both so we can instantly switch /// We keep both so we can instantly switch
period: Option<usize>, period: Option<usize>,
/// Keeps track of whether we are going forward while in cycle mode
forwards_in_cycle_mode: bool,
} }
impl Plugin for Sosten { impl Plugin for Sosten {
@ -76,6 +83,8 @@ impl Plugin for Sosten {
detector_thread: pitch_detection::PitchDetectorThread::<PITCH_LEN>::new(), detector_thread: pitch_detection::PitchDetectorThread::<PITCH_LEN>::new(),
used_period: None, used_period: None,
period: None, period: None,
forwards_in_cycle_mode: true,
} }
} }
@ -146,10 +155,39 @@ impl Plugin for Sosten {
self.buffers.r[a] += (1.0 - diss) * self.buffers.r[(a + 1) % LEN]; self.buffers.r[a] += (1.0 - diss) * self.buffers.r[(a + 1) % LEN];
// Loop index after we finish playing a section // Loop index after we finish playing a section
if model.direction[i] > 0.6 {
// we are going forwards, so increase the idx
self.buffers.idx += 1; self.buffers.idx += 1;
// and loop at the end
if self.buffers.idx >= len { if self.buffers.idx >= len {
self.buffers.idx = 0; self.buffers.idx = 0;
} }
} else if model.direction[i] > 0.4 {
// we're in cycle mode
// alternate directions at the end
if self.buffers.idx == 0 {
self.forwards_in_cycle_mode = true;
}
if self.buffers.idx >= len {
self.forwards_in_cycle_mode = false;
}
// increase/decrease index
if self.forwards_in_cycle_mode {
self.buffers.idx += 1;
} else {
self.buffers.idx -= 1;
}
} else {
// we are going backwards, so loop first
// this ensures we don't do 0 - 1
if self.buffers.idx == 0 {
self.buffers.idx = len + 1;
}
// then decrease index
self.buffers.idx -= 1;
}
} else { } else {
// If it's not on a repeat section, pass all the audio fully // If it's not on a repeat section, pass all the audio fully
output[0][i] = input[0][i]; output[0][i] = input[0][i];