feat: multiosc oscillator
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
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) } ]
|
||||
|
||||
Reference in New Issue
Block a user