Skip to content

Commit

Permalink
Add hardness parameter to Clip.
Browse files Browse the repository at this point in the history
  • Loading branch information
SamiPerttu committed Aug 1, 2024
1 parent 75f1c40 commit b7c302e
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Clarified latency: it only applies to involuntary causal latencies.
- `AdaptiveTanh` is now generic `Adaptive` distortion with an inner shape.
To migrate, try `Adaptive::new(timescale, Tanh(hardness))`.
- `Clip` shape now has a hardness parameter. `Clip(1.0)` to migrate.

### Version 0.18.2

Expand Down
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1256,18 +1256,19 @@ let partials = busf::<U20, _, _>(|f| noise() >> resonator_hz(xerp(1_000.0, 2_000

#### Waveshaping Modes

These are arguments to the `shape` opcode.
These are arguments to the `shape` opcode. Shapes `Atan`, `Clip`, `Softsign` and `Tanh`
all have a slope of 1 at the origin when hardness is 1 and saturate in the range -1...1.

- `Clip`: Clip signal to -1...1.
- `ClipTo(minimum, maximum)`: Clip signal between the two arguments.
- `Tanh(hardness)`: Apply `tanh` distortion with configurable hardness. Argument to `tanh` is multiplied by the hardness value.
- `Adaptive::new(timescale, inner)`: Apply adaptive normalizing distortion with smoothing `timescale` in seconds.
Smoothing timescale is the time it takes for level estimation to move halfway to a new value.
The argument to the `inner` shape is divided by the RMS level of the signal.
- `Atan(hardness)`: Apply `atan` distortion with configurable hardness, with the output range scaled to -1...1. Argument to `atan` is multiplied by the hardness value.
- `Softsign(hardness)`: Apply `softsign` distortion with configurable hardness. Argument to `softsign` is multiplied by the hardness value.
- `Clip(hardness)`: Multiply signal with hardness and then clamp it to -1...1.
- `ClipTo(minimum, maximum)`: Clip signal between the two arguments.
- `Crush(levels)`: Apply a staircase function with configurable number of levels per unit.
- `SoftCrush(levels)`: Apply a smooth staircase function with configurable number of levels per unit.
- `AdaptiveTanh::new(timescale, hardness)`: Apply adaptive normalizing distortion with smoothing `timescale` in seconds.
Smoothing timescale is the time it takes for level estimation to move halfway to a new value.
Argument to `tanh` is multiplied by the hardness value and divided by the RMS level of the signal.
- `Softsign(hardness)`: Apply `softsign` distortion with configurable hardness. Argument to `softsign` is multiplied by the hardness value.
- `Tanh(hardness)`: Apply `tanh` distortion with configurable hardness. Argument to `tanh` is multiplied by the hardness value.

#### Metering Modes

Expand Down
2 changes: 1 addition & 1 deletion src/hacker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,7 @@ pub fn shape<S: Shape>(mode: S) -> An<Shaper<S>> {
/// - Input 0: input signal
/// - Output 0: clipped signal
pub fn clip() -> An<Shaper<Clip>> {
An(Shaper::new(Clip))
An(Shaper::new(Clip(1.0)))
}

/// Clip signal to `minimum`...`maximum`.
Expand Down
2 changes: 1 addition & 1 deletion src/hacker32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,7 @@ pub fn shape<S: Shape>(mode: S) -> An<Shaper<S>> {
/// - Input 0: input signal
/// - Output 0: clipped signal
pub fn clip() -> An<Shaper<Clip>> {
An(Shaper::new(Clip))
An(Shaper::new(Clip(1.0)))
}

/// Clip signal to `minimum`...`maximum`.
Expand Down
2 changes: 1 addition & 1 deletion src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1184,7 +1184,7 @@ pub fn shape<S: Shape>(mode: S) -> An<Shaper<S>> {
/// - Input 0: input signal
/// - Output 0: clipped signal
pub fn clip() -> An<Shaper<Clip>> {
An(Shaper::new(Clip))
An(Shaper::new(Clip(1.0)))
}

/// Clip signal to `minimum`...`maximum`.
Expand Down
6 changes: 3 additions & 3 deletions src/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,16 @@ impl<S: Fn(f32) -> f32 + Clone + Sync + Send> Shape for ShapeFn<S> {

/// Clip signal to -1...1.
#[derive(Clone)]
pub struct Clip;
pub struct Clip(pub f32);

impl Shape for Clip {
#[inline]
fn shape(&mut self, input: f32) -> f32 {
input.clamp(-1.0, 1.0)
(input * self.0).clamp(-1.0, 1.0)
}
#[inline]
fn simd(&mut self, input: F32x) -> F32x {
input.fast_max(-F32x::ONE).fast_min(F32x::ONE)
(input * self.0).fast_max(-F32x::ONE).fast_min(F32x::ONE)
}
}

Expand Down

0 comments on commit b7c302e

Please sign in to comment.