From 71927731d31c8e4f9d337a7c6b365beec827cff9 Mon Sep 17 00:00:00 2001 From: HiveBeats <38073817+HiveBeats@users.noreply.github.com> Date: Tue, 1 Nov 2022 12:39:07 +0400 Subject: [PATCH] feat: waveshaper contains softclipping --- SoundGen/Fx.fs | 15 ++-- SoundGen/Program.fs | 167 +++++++++++++++++++++++++++++++++----------- 2 files changed, 135 insertions(+), 47 deletions(-) diff --git a/SoundGen/Fx.fs b/SoundGen/Fx.fs index 99f4853..d5a8a92 100644 --- a/SoundGen/Fx.fs +++ b/SoundGen/Fx.fs @@ -1,18 +1,23 @@ module SoundGen.Fx + open Settings + type Effect = | Saturator | Reverb -type Reverb = { Wet: float; Room: float } -type Saturator = { Gain: float } +type ReverbParam = { Wet: float; Room: float } +type SaturatorParam = { Gain: float } +type WaveshaperParam = {Gain: float; Factor: float;} -let saturate (param: Saturator, x: float) = tanh (param.Gain * x) +let saturator (param: SaturatorParam) (x: float) = tanh (param.Gain * x) -let sineWaveShape gain factor x = x + gain * sin (factor * x) +let waveshaper (param: WaveshaperParam) x = + (x + param.Gain * sin (param.Factor * x)) + |> saturator { Gain = 1.0 } let reverb (buffer: float seq) = - let delayMilliseconds = 500.//((1./8.) * beatDuration) // 500 is half a second + let delayMilliseconds = 500. //((1./8.) * beatDuration) // 500 is half a second let delaySamples = (delayMilliseconds * 48.0) |> int // assumes 44100 Hz sample rate diff --git a/SoundGen/Program.fs b/SoundGen/Program.fs index af1ab46..630b407 100644 --- a/SoundGen/Program.fs +++ b/SoundGen/Program.fs @@ -6,45 +6,130 @@ open SoundGen.Fx open Synth let song = - [ note 3 0.5 - note 3 0.5 - note 15 0.5 - note 15 0.5 - - note 6 0.5 - note 18 0.5 - note 3 0.5 - note 15 0.5 - - note (-1) 0.5 - note (-1) 0.5 - note 11 0.5 - note 15 0.5 - - note (-2) 0.5 - note (-2) 0.5 - note 10 0.5 - note 15 0.5 - // - note 3 0.5 - note 3 0.5 - note 15 0.5 - note 15 0.5 - - note 6 0.5 - note 18 0.5 - note 3 0.5 - note 15 0.5 - - note (-1) 0.5 - note (-1) 0.5 - note 11 0.5 - note 15 0.5 - - note (-2) 0.5 - note (-2) 0.5 - note 10 0.5 - note 15 0.5 ] + [ // + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.5 + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.25 + note 0 0.25; + note 0 0.5; + + note 5 0.25; + note 5 0.25; + note 5 0.25; + note 5 0.25; + note 5 0.25 + note 5 0.25; + note 5 0.5; + + note 3 0.25; + note 3 0.25; + note 3 0.25; + note 3 0.25; + note 3 0.25 + note 3 0.25; + note 3 0.5 + note (-2) 0.5 + // + // + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.5 + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.25 + note 0 0.25; + note 0 0.5; + + note 5 0.25; + note 5 0.25; + note 5 0.25; + note 5 0.25; + note 5 0.25 + note 5 0.25; + note 5 0.5; + + note 3 0.25; + note 3 0.25; + note 3 0.25; + note 3 0.25; + note 3 0.25 + note 3 0.25; + note 3 0.5 + note (-2) 0.5 + // + // + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.5 + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.25 + note 0 0.25; + note 0 0.5; + + note 5 0.25; + note 5 0.25; + note 5 0.25; + note 5 0.25; + note 5 0.25 + note 5 0.25; + note 5 0.5; + + note 3 0.25; + note 3 0.25; + note 3 0.25; + note 3 0.25; + note 3 0.25 + note 3 0.25; + note 3 0.5 + note (-2) 0.5 + // + // + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.5 + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.25; + note 0 0.25 + note 0 0.25; + note 0 0.5; + + note 5 0.25; + note 5 0.25; + note 5 0.25; + note 5 0.25; + note 5 0.25 + note 5 0.25; + note 5 0.5; + + note 3 0.25; + note 3 0.25; + note 3 0.25; + note 3 0.25; + note 3 0.25 + note 3 0.25; + note 3 0.5 + note (-2) 0.5 + ] |> Seq.concat @@ -56,8 +141,6 @@ let writeToFile (ms: MemoryStream) = song //|> reverb -|> Seq.map (fun x -> - let x1 = sineWaveShape 1.5 2.5 x - saturate ({ Gain = 1.0 }, x1)) +|> Seq.map (waveshaper {Gain=1.5; Factor=2.5}) |> createWAV |> writeToFile