module Haskore.Interface.Signal.Example.Guitar where
import Haskore.Example.Guitar(parallelSong, stringPitches)
import Filter.Example(guitar)
import qualified Haskore.Basic.Pitch as Pitch
import Haskore.Music.Standard as StdMusic
import Haskore.Music.Rhythmic as RhyMusic
import qualified Haskore.Performance.Fancy as FancyPf
import qualified Haskore.Interface.Signal.InstrumentMap as InstrMap
import qualified Haskore.Interface.Signal.Write as MusicSignal
import Haskore.Interface.Signal.Write(Time,Volume)
import qualified Synthesizer.Plain.Filter.NonRecursive as FiltNR
import qualified Synthesizer.Plain.Interpolation as Interpolation
import qualified Synthesizer.Plain.Signal as Sig
import Synthesizer.Plain.Instrument
(fastBell, simpleSaw, moogGuitar, moogGuitarSoft, fmBell, )
import qualified Sox.File
import Synthesizer.Utility(mapSnd)
import qualified Data.List as List
import System.Exit(ExitCode)
stringFreqs :: [Time]
stringFreqs =
map (\p -> Pitch.intToFreq (Pitch.toInt p) / 48000) stringPitches
sampleSong :: RhyMusic.T () Int
sampleSong = parallelSong [0 .. 5]
synthSong :: StdMusic.T
synthSong =
StdMusic.transpose 12 (parallelSong (repeat "moogguitarsoft"))
type IMap instr = InstrMap.InstrumentTable Time Volume instr
guitarToSignal :: Time -> Sig.T Volume -> InstrMap.Instrument Time Volume
guitarToSignal stringFreq sound sampleRate freq =
Interpolation.multiRelativeZeroPadConstant 0
(repeat (freq/sampleRate / stringFreq)) sound
sampleMap :: [Sig.T Volume] -> IMap Int
sampleMap samples =
zipWith3 (\chr stringFreq sound ->
(chr, guitarToSignal stringFreq sound))
[0 ..] stringFreqs samples
synthMap :: IMap StdMusic.Instr
synthMap = map (mapSnd (MusicSignal.amplify (1/5::Volume)))
[("guitar", (\sampleRate freq -> guitar (freq/sampleRate))),
("bell", fastBell),
("string", simpleSaw),
("moogguitar", moogGuitar),
("moogguitarsoft", moogGuitarSoft),
("fmguitar", (\sampleRate -> fmBell sampleRate 0.4 3.003))]
computeSignal :: (Ord drum, Ord instr) =>
RhyMusic.T drum instr -> IMap instr ->
Time -> Sig.T (Volume,Volume)
computeSignal music instrMap sampleRate =
let channel dif =
MusicSignal.fromRhythmicMusic sampleRate
(MusicSignal.detuneInstrs dif instrMap)
FancyPf.map
(MusicSignal.contextMetro 60 qn)
music
in zip (channel 1.001) (channel 0.999)
readSamples :: IO [Sig.T Volume]
readSamples =
do sampledSounds <- mapM Sox.File.readAIFFMono
(map (\chr -> "guitar/Zupf/Zupf"++chr:".aiff") ['0'..'5'])
return (zipWith FiltNR.amplifyVector
[0.5,0.5,0.5,0.5,0.5,0.3::Volume]
sampledSounds)
main :: IO ExitCode
main =
do
Sox.File.renderStereo "Guitar" 44100 . computeSignal sampleSong . sampleMap
=<< readSamples
Sox.File.renderStereo "GuitarSynth" 44100 (computeSignal synthSong synthMap)