{- | This was composed for the Teachers '95 morph of the Georg Cantor school in Halle in occasion of the 20th birthday in 2008. -} module Haskore.Interface.SuperCollider.Example.Morph where -- import qualified Sound.SC3 as SC import qualified Sound.SC3.UGen.UGen as SCUGen import qualified Sound.SC3.UGen.Oscillator as SCOsci import qualified Sound.SC3.UGen.Filter as SCFilt -- import qualified Sound.SC3.UGen.Math as SCMath import qualified Sound.SC3.UGen.Envelope as SCEnv import qualified Sound.SC3.UGen.Envelope.Construct as SCEnvCons import Sound.SC3.UGen.Enum (DoneAction(PauseSynth), {- EnvCurve(EnvSin,EnvExp) -} ) import Sound.SC3.UGen.Rate (Rate(KR,AR)) import Sound.SC3.UGen.UGen (UGen) import qualified Haskore.Interface.SuperCollider.Example as Example import qualified Haskore.Interface.SuperCollider.Play as Play import qualified Haskore.Interface.SuperCollider.Schedule as Schedule import qualified Haskore.Interface.SuperCollider.SoundMap as SoundMap import qualified Haskore.Interface.SuperCollider.Schedule.Channel as CSchedule import Haskore.Interface.SuperCollider.Schedule.Channel ({- rhythmicMusicFromDrum, -} rhythmicMusicFromMelody, ugenFromSound, installSound) import Haskore.Melody as Melody import qualified Haskore.Music as Music import Haskore.Music.Rhythmic as RhyMusic -- import qualified Haskore.Composition.Drum as Drum -- import Haskore.Composition.Chord as Chord import Haskore.Basic.Pitch as Pitch import qualified Haskore.Basic.Duration as Dur import System.Random (randomRs, mkStdGen) import Data.List (genericLength) {- blub :: UGen -> SoundMap.Instrument blub pan = SoundMap.instrumentFromUGen $ \ vel freq -> let dur = 0.3 env = SCEnv.envGen KR 1 1 0 1 PauseSynth (SCEnvCons.envSine dur 1) in 0.2 * env * SCUGen.MCE [1+pan,1-pan] * SCFilt.hpf (SCOsci.pulse AR (SCUGen.MCE [freq*0.995, freq*1.005]) 0.5) (4000 * 0.5**env) -} zirp :: UGen -> SoundMap.Instrument zirp pan = SoundMap.instrumentFromUGen $ \ vel freq -> let env = SCEnv.envGen KR 1 1 0 1 PauseSynth $ (SCEnvCons.envSine 0.2 1) {- SCEnvCons.env [0, 1, 0.1] [0.1, 0.5] [EnvSin, EnvExp] (-1) (-1) -} in vel * env * SCUGen.MCE [1+pan,1-pan] * SCFilt.hpf (SCOsci.saw AR (SCUGen.MCE [freq*0.995, freq*1.005])) (2000 * 0.5**env) -- cf. Example.Air sliceVertInf :: Int -> [a] -> [[a]] sliceVertInf n = map (take n) . iterate (drop n) -- properFraction is useless for negative numbers splitFraction :: (RealFrac a) => a -> (Int, a) splitFraction x = let n = floor x in (n, x - fromIntegral n) makeChord :: [Pitch.Octave -> Music.Dur -> attr -> Music.T note] -> attr -> Double -> Music.T note makeChord ns pan x = let (oct,p) = splitFraction x (high,low) = splitAt (floor (p*genericLength ns)) ns in chord $ map (\n -> n sn pan) $ map ($ oct) low ++ map ($ (oct+1)) high zirpScale :: Melody.T Double zirpScale = let binomDists = map sum $ sliceVertInf 3 $ randomRs (-1,1::Double) (mkStdGen 102) panoramas = randomRs (-0.5,0.5) (mkStdGen 95) in Music.legato hn $ Music.line $ zipWith3 makeChord (concat $ map (replicate 16) [[c, e, a], [c, e, g], [d, fs, a], [c, e, a]]) panoramas $ zipWith (+) binomDists $ iterate (0.02+) 0.2 bassSquare :: SoundMap.Instrument bassSquare = SoundMap.instrumentFromUGen $ \ vel freq -> vel * SCOsci.pulse AR (SCUGen.MCE [freq*0.999, freq*1.001]) (0.5 + 0.3 * SCOsci.sinOsc KR 0.3 0) infix 7 +: (+:) :: Music.T note -> Music.T note -> Music.T note m0 +: m1 = Music.take (Music.dur m0 - Music.dur m1) m0 +:+ m1 bassMelody :: Melody.T () bassMelody = Music.transpose (-24) $ Music.line $ -- a 0 wn () : c 1 wn () : d 1 wn () : a 1 wn () : [] a 0 wn () +: (g 0 sn () +:+ a 0 en ()) : c 1 wn () +: (a 0 sn () +:+ c 1 en ()) : d 1 wn () +: (c 1 sn () +:+ d 1 en () +:+ c 1 en ()) : a 1 wn () : [] tempo :: Dur.Ratio tempo = 2 schedule :: Schedule.T schedule = CSchedule.fromRhythmicMusic $ do zirpInstr <- installSound SoundMap.with1Attribute "zirp" zirp bassInstr <- installSound SoundMap.with0Attributes "bass" bassSquare hihatDrum <- installSound SoundMap.with0Attributes "hihat" Example.hihat let mix = -- flip SCMath.clip2 1 $ 0.2 * ( -- ugenFromSound zirpInstr + -- (let z = ugenFromSound zirpInstr -- in z + SCFilt.combN z 0.11 0.11 2) + (Example.reverb 4 (ugenFromSound zirpInstr)) + 0.4*(flip (SCFilt.rlpf (ugenFromSound bassInstr)) 0.1 $ flip SCFilt.lag 1 $ 400 * 8 ** SCOsci.lfSaw KR (Dur.toNumber tempo / 4) 1) + 5 * ugenFromSound hihatDrum) return (mix, Music.changeTempo tempo $ -- Music.take 10 $ -- Music.drop (4*4*4*dhn) $ (rhythmicMusicFromMelody zirpInstr zirpScale =:= Music.rest (sn/2) +:+ (-- Music.replicate (4*4) (rhythmicMusicFromDrum hihatDrum qn) =:= rhythmicMusicFromMelody bassInstr bassMelody)) +:+ Music.rest wn {- Music.transpose (12) ( Chord.harmonicGen () (qn) [e 0, a 0, c 1] +:+ Chord.harmonicGen () (qn) [g 0, c 1, e 1] +:+ Chord.harmonicGen () (qn) [a 0, d 1, fs 1] +:+ Chord.harmonicGen () (qn) [c 1, e 1, a 1]) -} ) main :: IO () main = Play.schedule Play.defaultLatency schedule