haskore-synthesizer-0.0.2: src/Haskore/Interface/Signal/Example/SwanLake.hs
{-# OPTIONS -fno-implicit-prelude #-}
module Haskore.Interface.Signal.Example.SwanLake where
import qualified Synthesizer.Plain.Filter.NonRecursive as FiltNR
import qualified Synthesizer.Plain.Filter.Recursive.Moog as Moog
import qualified Synthesizer.Plain.Signal as Sig
import Synthesizer.Plain.Filter.Recursive (Pole(Pole))
import Synthesizer.Plain.Control(exponential2)
import Synthesizer.Plain.Instrument (simpleSaw)
import qualified Sox.File
import qualified Number.Ratio as Ratio
import qualified Algebra.Transcendental as Trans
import qualified Algebra.Field as Field
import qualified Algebra.Ring as Ring
-- import qualified Haskore.Music as Music
import Haskore.Music.Standard as StdMusic
import Haskore.Melody.Standard as StdMelody
import qualified Haskore.Performance.Fancy as FancyPf
import qualified Haskore.Interface.Signal.Write as MusicSignal
import Haskore.Interface.Signal.Write(Time,Volume)
import Data.Accessor.Basic as Accessor
import System.Exit(ExitCode)
import PreludeBase
import NumericPrelude
------------ The song description -------------
-- Comfortable creation of chords of notes of the same length
chordDur :: t -> [t -> NoteAttributes -> StdMelody.T] -> StdMelody.T
chordDur dr chd =
chord $
zipWith
(\n v -> n dr (Accessor.set StdMelody.velocity1 (Ratio.toRational98 v) na))
chd [1,0.3,0.3,0.3]
chords :: StdMelody.T
chords = transpose 12 (line
[chordDur wn [a (-3), e 0, a 0, c 1],
chordDur wn [d (-2), f 0, a 0, d 1],
chordDur wn [a (-2), e 0, a 0, c 1],
chordDur wn [gs(-2), e 0, a 0, c 1],
chordDur wn [g (-2), e 0, a 0, c 1],
chordDur hn [d (-2), f 0, a 0, d 1],
chordDur hn [f (-3), f 0, a 0, c 1],
chordDur wn [a (-3), e 0, a 0, c 1] ])
makeMelody :: [NoteAttributes -> StdMelody.T] -> StdMelody.T
makeMelody mel = transpose 24 (line (map ($ na) mel))
melody :: StdMelody.T
melody = makeMelody [e 1 wn,
a 0 qn, b 0 qn, c 1 qn, d 1 qn,
e 1 dhn, c 1 qn,
e 1 dhn, c 1 qn,
e 1 dhn, a 0 qn,
c 1 qn, a 0 qn, f 0 qn, c 1 qn,
a 0 wn]
----------- Configuration of the player -----------
defltSampleRate :: Ring.C a => a
defltSampleRate = 44100
-- Volume type arises from Haskore
songToSignalMono :: Volume -> StdMelody.T -> Sig.T Volume
songToSignalMono dif song =
MusicSignal.fromRhythmicMusic
defltSampleRate
(MusicSignal.detuneInstrs dif
[("string", MusicSignal.amplify (0.5::Volume) simpleSaw)])
FancyPf.map
(MusicSignal.contextMetro 120 qn)
(StdMusic.fromStdMelody "string" song)
songSignal :: Volume -> Sig.T Volume
songSignal dif = songToSignalMono dif chords
polarisator :: Trans.C a => a -> a -> [Pole a]
polarisator sampleRate freq =
map (flip Pole (freq/sampleRate))
(exponential2 (0.5*sampleRate) 100)
filterSignal :: Time -> [Pole Volume]
filterSignal dif =
-- we must remove gaps because a pole frequency 0 let most filters crash
-- hope that the signal doesn't become too short ...
filter (/= Pole 0 0)
(MusicSignal.fromRhythmicMusic
defltSampleRate
(MusicSignal.detuneInstrs dif [("filter", polarisator)])
FancyPf.map
(MusicSignal.contextMetro 120 qn)
(StdMusic.fromStdMelody "filter" melody))
filteredSignal :: Volume -> Sig.T Volume
filteredSignal dif = FiltNR.amplifyVector (0.1::Volume)
(Moog.lowpass 10
(map (Moog.parameter 10) (filterSignal 1))
(songSignal (1/dif)))
{-
filteredSignal dif =
map (\(_,_,x) -> 0.1*x)
(uniFilter (map uniFilterParam filterSignal)
songSignal)
-}
stereoSignal :: Sig.T (Volume,Volume)
stereoSignal = zip (filteredSignal 1.002)
(filteredSignal 0.998)
main :: IO ExitCode
main = Sox.File.writeStereo "SwanLake" defltSampleRate stereoSignal