packages feed

haskore-supercollider 0.1 → 0.1.1

raw patch · 7 files changed

+370/−355 lines, 7 filesdep ~arraydep ~containersdep ~random

Dependency ranges changed: array, containers, random

Files

haskore-supercollider.cabal view
@@ -1,5 +1,5 @@ Name:           haskore-supercollider-Version:        0.1+Version:        0.1.1 License:        GPL License-File:   LICENSE Author:         Henning Thielemann <haskell@henning-thielemann.de>@@ -26,7 +26,7 @@ Source-Repository this   type:     darcs   location: http://darcs.haskell.org/haskore-supercollider/-  tag:      0.1+  tag:      0.1.1  Flag splitBase   description: Choose the new smaller, split-up base package.@@ -40,8 +40,10 @@     haskore-realtime >= 0.1 && < 0.2,     haskore >=0.1 && <0.2,     -- for SuperCollider support-    hosc >=0.6 && <0.7, hsc3 >=0.6 && <0.7,-    opensoundcontrol-ht >=0.1 && <0.2, supercollider-ht >=0.1 && <0.2,+    hosc >=0.6 && <0.7,+    hsc3 >=0.6 && <0.7,+    opensoundcontrol-ht >=0.1 && <0.2,+    supercollider-ht >=0.1 && <0.2,     bytestring >=0.9 && <1.0,     -- dependency on non-negative for Haddock     non-negative >=0.0.1 && <0.1,@@ -54,9 +56,9 @@   If flag(splitBase)     Build-Depends:       base >= 3,-      array >= 0.1 && <1.0,-      containers >=0.1 && <1.0,-      random >= 1.0 && <2.0,+      array >= 0.1 && <0.3,+      containers >=0.1 && <0.3,+      random >= 1.0 && <1.1,       process >= 1.0 && <1.1   Else     Build-Depends:@@ -65,31 +67,33 @@   GHC-Options:    -Wall   Hs-source-dirs: src   Exposed-modules:-    Haskore.Interface.SuperCollider.Channel,-    Haskore.Interface.SuperCollider.Channel.State,-    Haskore.Interface.SuperCollider.Channel.File,+    Haskore.Interface.SuperCollider.Channel+    Haskore.Interface.SuperCollider.Channel.State+    Haskore.Interface.SuperCollider.Channel.File     -- needs 'unix' package-    Haskore.Interface.SuperCollider.Channel.Env,-    Haskore.Interface.SuperCollider.Example,-    Haskore.Interface.SuperCollider.SoundMap,+    Haskore.Interface.SuperCollider.Channel.Env+    Haskore.Interface.SuperCollider.Example+    Haskore.Interface.SuperCollider.SoundMap     -- needs Haskore.Interface.SuperCollider.Channel.Env and thus 'unix' package-    Haskore.Interface.SuperCollider.Note,-    Haskore.Interface.SuperCollider.Performance,-    Haskore.Interface.SuperCollider.Play,-    Haskore.Interface.SuperCollider.Play.Install,-    Haskore.Interface.SuperCollider.Play.Channel,-    Haskore.Interface.SuperCollider.Play.Life,-    Haskore.Interface.SuperCollider.Render,-    Haskore.Interface.SuperCollider.Schedule,-    Haskore.Interface.SuperCollider.Schedule.Install,+    Haskore.Interface.SuperCollider.Note+    Haskore.Interface.SuperCollider.Performance+    Haskore.Interface.SuperCollider.Play+    Haskore.Interface.SuperCollider.Play.Install+    Haskore.Interface.SuperCollider.Play.Channel+    Haskore.Interface.SuperCollider.Play.Live+    Haskore.Interface.SuperCollider.Render+    Haskore.Interface.SuperCollider.Schedule+    Haskore.Interface.SuperCollider.Schedule.Install     Haskore.Interface.SuperCollider.Schedule.Channel+    -- deprecated+    Haskore.Interface.SuperCollider.Play.Life   Other-modules:-    Haskore.Interface.SuperCollider.Timer,-    Haskore.General.IdGenerator,-    Haskore.General.IdGenerator.Modulo,-    Haskore.General.IdGenerator.Set,-    Haskore.General.IdGenerator.Simple,-    Haskore.Interface.SuperCollider.Example.Air,+    Haskore.Interface.SuperCollider.Timer+    Haskore.General.IdGenerator+    Haskore.General.IdGenerator.Modulo+    Haskore.General.IdGenerator.Set+    Haskore.General.IdGenerator.Simple+    Haskore.Interface.SuperCollider.Example.Air     Haskore.Interface.SuperCollider.Example.Morph  Executable song-air@@ -98,12 +102,14 @@   Main-Is: Haskore/Interface/SuperCollider/Example/AirMain.hs  Executable test-  If !flag(buildTests)+  If flag(buildTests)+    Build-Depends:+      QuickCheck >=1 && <2, HUnit >=1.2 && <1.3+  Else     Buildable: False -  Build-Depends:-    QuickCheck >=1 && <2, HUnit >=1.2 && <1.3   Hs-source-dirs: src   GHC-Options:    -Wall   Main-Is: Test/Main.hs+  -- tests could not properly be extracted from main Haskore package   Buildable: False
src/Haskore/Interface/SuperCollider/Example.hs view
@@ -146,7 +146,7 @@ sawPerc :: SoundMap.Instrument sawPerc = SoundMap.instrumentFromUGen sawPercUGen --- for demonstration in Play.Life+-- for demonstration in Play.Live sawPercUGen :: UGen -> UGen -> UGen sawPercUGen vel freq =     let -- env = SCEnv.envGen SCRate.KR 1 2 0 1 PauseSynth SCEnv.envperc'@@ -159,7 +159,7 @@ dynPerc :: UGen -> SoundMap.Instrument dynPerc detune = SoundMap.instrumentFromUGen (dynPercUGen detune) --- for demonstration in Play.Life+-- for demonstration in Play.Live dynPercUGen :: UGen -> UGen -> UGen -> UGen dynPercUGen detune vel freq =     let env = SCEnv.xLine SCRate.KR 1.5 0.1 1 DoNothing
src/Haskore/Interface/SuperCollider/Performance.hs view
@@ -164,7 +164,7 @@    PfBE.fromPaddedPerformance makeNote .    FancyPf.paddedFromMusic -{- needed for Play.Install, Play.Channel, Life -}+{- needed for Play.Install, Play.Channel, Live -} {- fromRhythmicMusic ::    (Show drum, Show instr, Ord drum, Ord instr,
src/Haskore/Interface/SuperCollider/Play.hs view
@@ -3,7 +3,7 @@     schedule, scheduleWithPlayer, shutUp,     defaultLatency, timeStamp, -    -- for Life module+    -- for Live module     installSound, playAtom,     performanceTrans, messagesGrouped, @@ -122,7 +122,7 @@ {- * Initialization of replay -}  {- |-Default value for latency used in "Haskore.Interface.SuperCollider.Play.Life"+Default value for latency used in "Haskore.Interface.SuperCollider.Play.Live" and connected modules. -} defaultLatency :: Time
src/Haskore/Interface/SuperCollider/Play/Life.hs view
@@ -1,319 +1,5 @@-{- |-This is a module specialised to life performances.--You can create and install instruments in SuperCollider,-obtain a handle and use that in your song.--The alternative way would be to upload an instrument-whenever one tone shall be played.-This is less efficient but simpler and certainly more flexbile.--}-module Haskore.Interface.SuperCollider.Play.Life where--import qualified Sound.SC3 as SC-import qualified Sound.SC3.UGen.IO   as SCIO-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.Envelope   as SCUGEnv-import qualified Sound.SC3.UGen.Noise.Base as SCNoise-import qualified Sound.SC3.UGen.UId as SCUId--import Sound.SC3.UGen.Enum (DoneAction(DoNothing, PauseSynth))-import Sound.SC3.UGen.Rate (Rate(AR,KR))--import qualified Sound.SC3.Server.PlayEasy  as SCPlay-import qualified Sound.SC3.Server.Command   as SCCmd--import Sound.SC3.UGen.UGen (UGen)--import Sound.OpenSoundControl.Transport (Transport)-import qualified Sound.OpenSoundControl.Transport.Monad as Trans--import qualified Haskore.Interface.SuperCollider.Example       as Example-import qualified Haskore.Interface.SuperCollider.Play.Install  as IPlay-import qualified Haskore.Interface.SuperCollider.Play          as Play-import qualified Haskore.Interface.SuperCollider.Schedule      as Schedule-import qualified Haskore.Interface.SuperCollider.Schedule.Channel as CSched-import qualified Haskore.Interface.SuperCollider.Schedule.Install as ISched-import qualified Haskore.Interface.SuperCollider.Performance   as SCPf-import qualified Haskore.Interface.SuperCollider.SoundMap      as SoundMap--import Haskore.Interface.SuperCollider.SoundMap-         (InstrumentParameters, DrumParameters, AttributeList)--import qualified Haskore.Interface.SuperCollider.Channel.Env as ChannelEnv-import qualified Haskore.Interface.SuperCollider.Channel as Channel-import Haskore.Interface.SuperCollider.Channel (Channel, NumberChannels)--import Haskore.Interface.SuperCollider.Schedule.Channel-         (Sound(..), ugenFromSound,-          Instrument, -- InstrumentAttributes,-          Drum, -- DrumAttributes,-          rhythmicMusicFromDynamicMelody, rhythmicMusicFromMelody,-          rhythmicMusicFromRhythm, rhythmicMusicFromDrum)-import Haskore.Interface.SuperCollider.Schedule.Install-         (InstrumentAttributes(..), DrumAttributes(..))--import qualified Haskore.Basic.Pitch as Pitch-import qualified Haskore.Basic.Duration as Dur-import           Haskore.Basic.Duration ((%+))--import qualified Haskore.Interface.SuperCollider.Timer as SCTimer--import qualified Haskore.General.IdGenerator      as IdGen--import qualified Haskore.Composition.Drum  as Drum-import           Haskore.Composition.Chord as Chord--import           Haskore.Melody         as Melody-import qualified Haskore.Music          as Music-import           Haskore.Music (mapNote)-import qualified Haskore.Music.Rhythmic as RhyMusic-import           Haskore.Music.Rhythmic (-          (+:+), (=:=),-          wn, hn, qn, en, sn, tn, sfn,-          dwn, dhn, dqn, den, dsn, dtn,-          wnr, hnr, qnr, enr, snr, tnr, sfnr,-          dwnr, dhnr, dqnr, denr, dsnr, dtnr,)---- import System.Random (randomRs, mkStdGen)--import System.Posix.Process (forkProcess)--- import Control.Concurrent (forkIO)-import Control.Monad (liftM2)--import Data.List (elemIndex)----{- * Install instruments -}--type InstrumentUGen = UGen -> UGen -> UGen--installInstr ::-   (parameterTuple -> AttributeList, graph -> InstrumentUGen) ->-   String ->-   graph ->-   IO (ISched.Instrument parameterTuple)-installInstr (makeAttributeList, makeSoundUGen) name sound =-   SCPlay.withSC3 $-   IPlay.installSound-      (makeAttributeList, SoundMap.instrumentFromUGen . makeSoundUGen) name sound---installInstr0 ::-   String ->-   InstrumentUGen ->-   IO (ISched.Instrument ())-installInstr0 =-   installInstr SoundMap.with0Attributes--installInstr1 ::-   String ->-   (UGen -> InstrumentUGen) ->-   IO (ISched.Instrument Double)-installInstr1 =-   installInstr SoundMap.with1Attribute--installInstr2 ::-   String ->-   (UGen -> UGen -> InstrumentUGen) ->-   IO (ISched.Instrument (Double,Double))-installInstr2 =-   installInstr SoundMap.with2Attributes---type DrumUGen = UGen -> UGen--installDrum ::-   (parameterTuple -> AttributeList, graph -> DrumUGen) ->-   String ->-   graph ->-   IO (ISched.Drum parameterTuple)-installDrum (makeAttributeList, makeSoundUGen) name sound =-   SCPlay.withSC3 $-   IPlay.installSound-      (makeAttributeList, SoundMap.drumFromUGen . makeSoundUGen) name sound-----{- * Install instruments on specific channels -}---installSoundChan ::-   SoundMap.SoundParameters params =>-   String ->-   SoundMap.Sound params ->-   IO (Channel, NumberChannels)-installSoundChan name sound =-   do let ugen = SoundMap.ugenFromSound sound-      let numChan = SCPlay.mceDegree ugen-      chan <- Channel.next ChannelEnv.manager numChan-      SCPlay.withSC3 $-         SCPlay.simpleSync $ SCPlay.d_recv_synthdef name $-         SCIO.out (SCUGen.Constant (fromIntegral chan)) ugen-      return (chan, numChan)---installInstrChan ::-   (parameterTuple -> AttributeList, graph -> InstrumentUGen) ->-   String ->-   graph ->-   IO (Instrument parameterTuple)-installInstrChan (makeAttributeList, makeInstrumentUGen) name sound =-   do chanChunk <--         installSoundChan name $-         SoundMap.instrumentFromUGen $-         makeInstrumentUGen sound-      return (Sound name chanChunk makeAttributeList)--installDrumChan ::-   (parameterTuple -> AttributeList, graph -> DrumUGen) ->-   String ->-   graph ->-   IO (Drum parameterTuple)-installDrumChan (makeAttributeList, makeDrumUGen) name sound =-   do chanChunk <--         installSoundChan name $-         SoundMap.drumFromUGen $-         makeDrumUGen sound-      return (Sound name chanChunk makeAttributeList)----{- |-This one is more portable but less elegant.--}---{- * Play music -}--reset :: IO ()-reset =-   do Channel.reset ChannelEnv.manager-      SCPlay.withSC3 $ SCPlay.reset--playSound :: UGen -> IO ()-playSound = fmap (const ()) . SCPlay.withSC3 . SCPlay.play--playMusic ::-   RhyMusic.T DrumAttributes InstrumentAttributes -> IO ()-playMusic =-   Play.performance Play.defaultLatency [] .-   SCPf.fixNodeIds .-   SCPf.fromRhythmicMusicWithAttributes-      (\(ISched.SoundAttributes params name) -> (params,name))-      (\(ISched.SoundAttributes params name) -> (params,name))--playMusicEffect ::-   UGen ->-   RhyMusic.T CSched.DrumAttributes CSched.InstrumentAttributes ->-   IO ()-playMusicEffect effect song =-   let (sid,pf) =-          SCPf.fixNodeIds $-          liftM2 (,)-             IdGen.alloc-             (SCPf.fromRhythmicMusicWithAttributes-                 (\(CSched.SoundAttributes params name) -> (params,name))-                 (\(CSched.SoundAttributes params name) -> (params,name))-                 song)-       effectsName = "global effects"-   in  SCPlay.withSC3 $-          {- We rely on the fact, that the performance player-             always adds new nodes to the head.-             This way, the effect is run after the instrument nodes. -}-          Play.scheduleWithPlayer-             (Play.messagesGrouped SCTimer.timer Play.defaultLatency)-             (Schedule.fromPerformance-                [Schedule.installUGenMsg effectsName-                    Schedule.defaultChannel effect]-                [SCCmd.s_new effectsName sid SCCmd.AddToTail SCPlay.homeId []]-                pf) >>-          return ()---{- * Interactively play music on keyboard -}--germanLatin1Keyboard :: [Char]-germanLatin1Keyboard =-   let oUmlaut = '\246'-       uUmlaut = '\252'-       szLig   = '\223'-   in  "ysxdcvgbhnjm,l."++oUmlaut:"-q2w3e4rt6z7ui9o0p"++szLig:uUmlaut:"+"--playKey :: ISched.Instrument () -> Char -> IO ()-playKey (ISched.Sound name _) key =-   maybe-      (return ())-      (\pitch ->-          do SCPlay.withSC3 $-                Play.playAtom SCPlay.noId name $-                   ("pitch", Pitch.intToFreq pitch) :-                   ("velocity", 1) : []-             print (Pitch.fromInt pitch))-      (elemIndex key germanLatin1Keyboard)--{- |-Interprets the keyboard as piano and play according tones,-when keys are hit.--Is it more convenient to have a UGen parameter and install the instrument automatically?--}-{--Try suppressing output on keys by-System.IO.hSetEcho System.IO.stdin False--}-playKeyboard :: ISched.Instrument () -> IO ()-playKeyboard instr =-   let recourse =-          do char <- getChar-             if char == '\004'-               then putStrLn ""-               else do putChar '\008'-                       playKey instr char-                       recourse-   in  recourse----{- * Example music -}---example :: IO ()-example =-   do reset-      sawPerc <- installInstr0 "saw percussion" Example.sawPercUGen-      dynPerc <- installInstr1 "detuned bass"   Example.dynPercUGen-      let mel = ISched.rhythmicMusicFromMelody sawPerc $ Music.transpose 12 $ Music.line-            [c 0 qn (), e 0 qn (),-             Music.chord [c 0 qn (), e 0 qn (), g 0 qn ()]]-          bass = ISched.rhythmicMusicFromMelody dynPerc $ Music.line-            [c 0 qn 0.001, c 0 qn 0.003, c 0 qn 0.01]-      playMusic $-         Music.changeTempo 2 $-         Music.chord [mel,bass]---exampleEffect :: IO ()-exampleEffect =-   do reset-      sawPerc <- installInstrChan SoundMap.with0Attributes "saw percussion" Example.sawPercUGen-      dynPerc <- installInstrChan SoundMap.with1Attribute  "detuned bass"   Example.dynPercUGen-      let lfoSine   = exp (SCOsci.sinOsc KR 0.2 (-pi/2) * 0.5) * 1000-          lfoSquare = exp (SCOsci.pulse KR 5.1 0.5 * 1) * 1000-          mix =-            SCFilt.rlpf (0.5 * ugenFromSound sawPerc) lfoSine 0.1 +-            SCFilt.rlpf (0.5 * ugenFromSound dynPerc) lfoSquare 0.1-            -- SCUGen.Constant 0-      let mel = CSched.rhythmicMusicFromMelody sawPerc $ Music.transpose 12 $ Music.line $-            cycle [c 0 qn (), b 0 qn (), c 1 qn ()]-          bass = CSched.rhythmicMusicFromMelody dynPerc $ Music.line $-            cycle [c 0 qn 0.001, c 0 qn 0.003, c 0 qn 0.01]-      playMusicEffect mix $-         -- (0.3 * SCOsci.sinOsc AR 880 0) $-         Music.changeTempo 2 $-         Music.chord [Music.changeTempo 3 mel, bass]+module Haskore.Interface.SuperCollider.Play.Life+   {-# DEPRECATED "use Play.Live instead" #-}+   (module Haskore.Interface.SuperCollider.Play.Live) where +import Haskore.Interface.SuperCollider.Play.Live
+ src/Haskore/Interface/SuperCollider/Play/Live.hs view
@@ -0,0 +1,323 @@+{- |+This is a module specialised to life performances.++You can create and install instruments in SuperCollider,+obtain a handle and use that in your song.++The alternative way would be to upload an instrument+whenever one tone shall be played.+This is less efficient but simpler and certainly more flexible.++It is certainly not sensible to import that module.+Maybe I should provide it as Extra-Source-File or+as Main module of a dummy executable in order to ship it via Cabal.+-}+module Haskore.Interface.SuperCollider.Play.Live where++import qualified Sound.SC3 as SC+import qualified Sound.SC3.UGen.IO   as SCIO+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.Envelope   as SCUGEnv+import qualified Sound.SC3.UGen.Noise.Base as SCNoise+import qualified Sound.SC3.UGen.UId as SCUId++import Sound.SC3.UGen.Enum (DoneAction(DoNothing, PauseSynth))+import Sound.SC3.UGen.Rate (Rate(AR,KR))++import qualified Sound.SC3.Server.PlayEasy  as SCPlay+import qualified Sound.SC3.Server.Command   as SCCmd++import Sound.SC3.UGen.UGen (UGen)++import Sound.OpenSoundControl.Transport (Transport)+import qualified Sound.OpenSoundControl.Transport.Monad as Trans++import qualified Haskore.Interface.SuperCollider.Example       as Example+import qualified Haskore.Interface.SuperCollider.Play.Install  as IPlay+import qualified Haskore.Interface.SuperCollider.Play          as Play+import qualified Haskore.Interface.SuperCollider.Schedule      as Schedule+import qualified Haskore.Interface.SuperCollider.Schedule.Channel as CSched+import qualified Haskore.Interface.SuperCollider.Schedule.Install as ISched+import qualified Haskore.Interface.SuperCollider.Performance   as SCPf+import qualified Haskore.Interface.SuperCollider.SoundMap      as SoundMap++import Haskore.Interface.SuperCollider.SoundMap+         (InstrumentParameters, DrumParameters, AttributeList)++import qualified Haskore.Interface.SuperCollider.Channel.Env as ChannelEnv+import qualified Haskore.Interface.SuperCollider.Channel as Channel+import Haskore.Interface.SuperCollider.Channel (Channel, NumberChannels)++import Haskore.Interface.SuperCollider.Schedule.Channel+         (Sound(..), ugenFromSound,+          Instrument, -- InstrumentAttributes,+          Drum, -- DrumAttributes,+          rhythmicMusicFromDynamicMelody, rhythmicMusicFromMelody,+          rhythmicMusicFromRhythm, rhythmicMusicFromDrum)+import Haskore.Interface.SuperCollider.Schedule.Install+         (InstrumentAttributes(..), DrumAttributes(..))++import qualified Haskore.Basic.Pitch as Pitch+import qualified Haskore.Basic.Duration as Dur+import           Haskore.Basic.Duration ((%+))++import qualified Haskore.Interface.SuperCollider.Timer as SCTimer++import qualified Haskore.General.IdGenerator      as IdGen++import qualified Haskore.Composition.Drum  as Drum+import           Haskore.Composition.Chord as Chord++import           Haskore.Melody         as Melody+import qualified Haskore.Music          as Music+import           Haskore.Music (mapNote)+import qualified Haskore.Music.Rhythmic as RhyMusic+import           Haskore.Music.Rhythmic (+          (+:+), (=:=),+          wn, hn, qn, en, sn, tn, sfn,+          dwn, dhn, dqn, den, dsn, dtn,+          wnr, hnr, qnr, enr, snr, tnr, sfnr,+          dwnr, dhnr, dqnr, denr, dsnr, dtnr,)++-- import System.Random (randomRs, mkStdGen)++import System.Posix.Process (forkProcess)+-- import Control.Concurrent (forkIO)+import Control.Monad (liftM2)++import Data.List (elemIndex)++++{- * Install instruments -}++type InstrumentUGen = UGen -> UGen -> UGen++installInstr ::+   (parameterTuple -> AttributeList, graph -> InstrumentUGen) ->+   String ->+   graph ->+   IO (ISched.Instrument parameterTuple)+installInstr (makeAttributeList, makeSoundUGen) name sound =+   SCPlay.withSC3 $+   IPlay.installSound+      (makeAttributeList, SoundMap.instrumentFromUGen . makeSoundUGen) name sound+++installInstr0 ::+   String ->+   InstrumentUGen ->+   IO (ISched.Instrument ())+installInstr0 =+   installInstr SoundMap.with0Attributes++installInstr1 ::+   String ->+   (UGen -> InstrumentUGen) ->+   IO (ISched.Instrument Double)+installInstr1 =+   installInstr SoundMap.with1Attribute++installInstr2 ::+   String ->+   (UGen -> UGen -> InstrumentUGen) ->+   IO (ISched.Instrument (Double,Double))+installInstr2 =+   installInstr SoundMap.with2Attributes+++type DrumUGen = UGen -> UGen++installDrum ::+   (parameterTuple -> AttributeList, graph -> DrumUGen) ->+   String ->+   graph ->+   IO (ISched.Drum parameterTuple)+installDrum (makeAttributeList, makeSoundUGen) name sound =+   SCPlay.withSC3 $+   IPlay.installSound+      (makeAttributeList, SoundMap.drumFromUGen . makeSoundUGen) name sound+++++{- * Install instruments on specific channels -}+++installSoundChan ::+   SoundMap.SoundParameters params =>+   String ->+   SoundMap.Sound params ->+   IO (Channel, NumberChannels)+installSoundChan name sound =+   do let ugen = SoundMap.ugenFromSound sound+      let numChan = SCPlay.mceDegree ugen+      chan <- Channel.next ChannelEnv.manager numChan+      SCPlay.withSC3 $+         SCPlay.simpleSync $ SCPlay.d_recv_synthdef name $+         SCIO.out (SCUGen.Constant (fromIntegral chan)) ugen+      return (chan, numChan)+++installInstrChan ::+   (parameterTuple -> AttributeList, graph -> InstrumentUGen) ->+   String ->+   graph ->+   IO (Instrument parameterTuple)+installInstrChan (makeAttributeList, makeInstrumentUGen) name sound =+   do chanChunk <-+         installSoundChan name $+         SoundMap.instrumentFromUGen $+         makeInstrumentUGen sound+      return (Sound name chanChunk makeAttributeList)++installDrumChan ::+   (parameterTuple -> AttributeList, graph -> DrumUGen) ->+   String ->+   graph ->+   IO (Drum parameterTuple)+installDrumChan (makeAttributeList, makeDrumUGen) name sound =+   do chanChunk <-+         installSoundChan name $+         SoundMap.drumFromUGen $+         makeDrumUGen sound+      return (Sound name chanChunk makeAttributeList)++++{- |+This one is more portable but less elegant.+-}+++{- * Play music -}++reset :: IO ()+reset =+   do Channel.reset ChannelEnv.manager+      SCPlay.withSC3 $ SCPlay.reset++playSound :: UGen -> IO ()+playSound = fmap (const ()) . SCPlay.withSC3 . SCPlay.play++playMusic ::+   RhyMusic.T DrumAttributes InstrumentAttributes -> IO ()+playMusic =+   Play.performance Play.defaultLatency [] .+   SCPf.fixNodeIds .+   SCPf.fromRhythmicMusicWithAttributes+      (\(ISched.SoundAttributes params name) -> (params,name))+      (\(ISched.SoundAttributes params name) -> (params,name))++playMusicEffect ::+   UGen ->+   RhyMusic.T CSched.DrumAttributes CSched.InstrumentAttributes ->+   IO ()+playMusicEffect effect song =+   let (sid,pf) =+          SCPf.fixNodeIds $+          liftM2 (,)+             IdGen.alloc+             (SCPf.fromRhythmicMusicWithAttributes+                 (\(CSched.SoundAttributes params name) -> (params,name))+                 (\(CSched.SoundAttributes params name) -> (params,name))+                 song)+       effectsName = "global effects"+   in  SCPlay.withSC3 $+          {- We rely on the fact, that the performance player+             always adds new nodes to the head.+             This way, the effect is run after the instrument nodes. -}+          Play.scheduleWithPlayer+             (Play.messagesGrouped SCTimer.timer Play.defaultLatency)+             (Schedule.fromPerformance+                [Schedule.installUGenMsg effectsName+                    Schedule.defaultChannel effect]+                [SCCmd.s_new effectsName sid SCCmd.AddToTail SCPlay.homeId []]+                pf) >>+          return ()+++{- * Interactively play music on keyboard -}++germanLatin1Keyboard :: [Char]+germanLatin1Keyboard =+   let oUmlaut = '\246'+       uUmlaut = '\252'+       szLig   = '\223'+   in  "ysxdcvgbhnjm,l."++oUmlaut:"-q2w3e4rt6z7ui9o0p"++szLig:uUmlaut:"+"++playKey :: ISched.Instrument () -> Char -> IO ()+playKey (ISched.Sound name _) key =+   maybe+      (return ())+      (\pitch ->+          do SCPlay.withSC3 $+                Play.playAtom SCPlay.noId name $+                   ("pitch", Pitch.intToFreq pitch) :+                   ("velocity", 1) : []+             print (Pitch.fromInt pitch))+      (elemIndex key germanLatin1Keyboard)++{- |+Interprets the keyboard as piano and play according tones,+when keys are hit.++Is it more convenient to have a UGen parameter and install the instrument automatically?+-}+{-+Try suppressing output on keys by+System.IO.hSetEcho System.IO.stdin False+-}+playKeyboard :: ISched.Instrument () -> IO ()+playKeyboard instr =+   let recourse =+          do char <- getChar+             if char == '\004'+               then putStrLn ""+               else do putChar '\008'+                       playKey instr char+                       recourse+   in  recourse++++{- * Example music -}+++example :: IO ()+example =+   do reset+      sawPerc <- installInstr0 "saw percussion" Example.sawPercUGen+      dynPerc <- installInstr1 "detuned bass"   Example.dynPercUGen+      let mel = ISched.rhythmicMusicFromMelody sawPerc $ Music.transpose 12 $ Music.line+            [c 0 qn (), e 0 qn (),+             Music.chord [c 0 qn (), e 0 qn (), g 0 qn ()]]+          bass = ISched.rhythmicMusicFromMelody dynPerc $ Music.line+            [c 0 qn 0.001, c 0 qn 0.003, c 0 qn 0.01]+      playMusic $+         Music.changeTempo 2 $+         Music.chord [mel,bass]+++exampleEffect :: IO ()+exampleEffect =+   do reset+      sawPerc <- installInstrChan SoundMap.with0Attributes "saw percussion" Example.sawPercUGen+      dynPerc <- installInstrChan SoundMap.with1Attribute  "detuned bass"   Example.dynPercUGen+      let lfoSine   = exp (SCOsci.sinOsc KR 0.2 (-pi/2) * 0.5) * 1000+          lfoSquare = exp (SCOsci.pulse KR 5.1 0.5 * 1) * 1000+          mix =+            SCFilt.rlpf (0.5 * ugenFromSound sawPerc) lfoSine 0.1 ++            SCFilt.rlpf (0.5 * ugenFromSound dynPerc) lfoSquare 0.1+            -- SCUGen.Constant 0+      let mel = CSched.rhythmicMusicFromMelody sawPerc $ Music.transpose 12 $ Music.line $+            cycle [c 0 qn (), b 0 qn (), c 1 qn ()]+          bass = CSched.rhythmicMusicFromMelody dynPerc $ Music.line $+            cycle [c 0 qn 0.001, c 0 qn 0.003, c 0 qn 0.01]+      playMusicEffect mix $+         -- (0.3 * SCOsci.sinOsc AR 880 0) $+         Music.changeTempo 2 $+         Music.chord [Music.changeTempo 3 mel, bass]+
src/Haskore/Interface/SuperCollider/Schedule.hs view
@@ -248,7 +248,7 @@    OSC atomPlayMsg sid name =    SCCmd.s_new name sid SCCmd.AddToHead SCPlay.homeId-   -- adding to head is necessary for allowing global effects like in the Life module+   -- adding to head is necessary for allowing global effects like in the Live module   installUGenMsg ::