From 9d37e057d75ff9f782b87fbcaf9e82f1ae8b492f Mon Sep 17 00:00:00 2001 From: HiveBeats <38073817+HiveBeats@users.noreply.github.com> Date: Tue, 1 Nov 2022 09:20:22 +0400 Subject: [PATCH] feat: multiosc oscillator --- SoundGen/Oscillator.fs | 25 +++++++++++++++++++++++-- SoundGen/Program.fs | 6 +++--- SoundGen/Synth.fs | 20 +++++++++++++------- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/SoundGen/Oscillator.fs b/SoundGen/Oscillator.fs index d3c0659..e53ad61 100644 --- a/SoundGen/Oscillator.fs +++ b/SoundGen/Oscillator.fs @@ -3,6 +3,21 @@ module SoundGen.Oscillator open System open Settings +type OscillatorType = + | Sine + | Triangle + | Saw + | Square + +type Hertz = float +type OscillatorParameter = { Osc: OscillatorType; Freq: Hertz } + +type GenerationParameter = + { Oscillators: OscillatorParameter list + Sample: float } + + + let pos hz x = (hz * x / sampleRate) % 1. let sineosc hz x = @@ -15,5 +30,11 @@ let squareosc hz x = let triangleosc (hz: float) (x: float) = 1. - Math.Abs((pos hz x) - 0.5) * 4. let sawosc hz x = (pos hz x) * 2. - 1. -let sinesquareosc hz x = - sawosc (hz / 4.) x + squareosc (hz / 2.) x +let multiosc (param: GenerationParameter) = + param.Oscillators + |> List.sumBy (fun x -> + match x.Osc with + | Sine -> sineosc x.Freq param.Sample + | Triangle -> triangleosc x.Freq param.Sample + | Square -> squareosc x.Freq param.Sample + | Saw -> sawosc x.Freq param.Sample) diff --git a/SoundGen/Program.fs b/SoundGen/Program.fs index 338a937..d6b847e 100644 --- a/SoundGen/Program.fs +++ b/SoundGen/Program.fs @@ -55,9 +55,9 @@ let writeToFile (ms: MemoryStream) = ms.WriteTo(fs) song -// |> Seq.map (fun x -> -// let x1 = sineWaveShape 2.8 2. x -// saturate ({ Gain = 1.0 }, x1)) +|> Seq.map (fun x -> + let x1 = sineWaveShape 1.5 2.5 x + saturate ({ Gain = 1.0 }, x1)) //|> reverb |> createWAV |> writeToFile diff --git a/SoundGen/Synth.fs b/SoundGen/Synth.fs index 4cdc8bf..2190b3d 100644 --- a/SoundGen/Synth.fs +++ b/SoundGen/Synth.fs @@ -1,6 +1,8 @@ module SoundGen.Synth + open Settings open Oscillator +open SoundGen.Oscillator let getHzBySemitones semi = pitchStandard * (2. ** (1. / 12.)) ** semi @@ -32,7 +34,7 @@ let getSemitonesByNote (str: string) = (octave - defaultOctave - 1) * 12 + noteShift -let freq hz duration = +let freq hz duration (osc: OscillatorParameter list) = let samples = seq { 0.0 .. (duration * sampleRate) } @@ -52,10 +54,8 @@ let freq hz duration = let output = Seq.map (fun x -> - x - |> sinesquareosc hz - |> (*) volume - ) + multiosc { Oscillators = osc; Sample = x } + |> (*) volume) samples let adsrLength = Seq.length output @@ -70,5 +70,11 @@ let freq hz duration = let note semitone beats = - let hz = getHzBySemitones semitone - freq hz (beats * beatDuration) \ No newline at end of file + let hz = getHzBySemitones (semitone - 12.) + + freq + hz + (beats * beatDuration) + [ { Osc = Sine; Freq = hz / 4. } + { Osc = Saw; Freq = (hz + 1.) } + { Osc = Saw; Freq = (hz - 1.3) } ]