packages feed

csound-sampler 0.0.8.1 → 0.0.9.0

raw patch · 5 files changed

+168/−154 lines, 5 filesdep ~csound-expressionPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: csound-expression

API changes (from Hackage documentation)

+ Csound.Sam.Core: instance Csound.IO.RenderCsd (Csound.Typed.GlobalState.SE.SE (Csound.Typed.Gui.Widget.Source Csound.Sam.Core.Sam))
+ Csound.Sam.Core: instance Csound.IO.RenderCsd (Csound.Typed.GlobalState.SE.SE Csound.Sam.Core.Sam)
+ Csound.Sam.Core: instance Csound.Typed.Types.SigSpace.BindSig2 a => Csound.Typed.Types.SigSpace.BindSig2 (Csound.Sam.Core.Sample a)
+ Csound.Sam.Core: instance Csound.Typed.Types.SigSpace.SigSpace2 a => Csound.Typed.Types.SigSpace.SigSpace2 (Csound.Sam.Core.Sample a)
- Csound.Sam: arpDown :: Chord -> [D] -> Sam -> Sam
+ Csound.Sam: arpDown :: Chord -> [Sig] -> Sam -> Sam
- Csound.Sam: arpFreqOf :: [Sig] -> Chord -> [D] -> Sam -> Sam
+ Csound.Sam: arpFreqOf :: [Sig] -> Chord -> [Sig] -> Sam -> Sam
- Csound.Sam: arpOneOf :: Chord -> [D] -> Sam -> Sam
+ Csound.Sam: arpOneOf :: Chord -> [Sig] -> Sam -> Sam
- Csound.Sam: arpUp :: Chord -> [D] -> Sam -> Sam
+ Csound.Sam: arpUp :: Chord -> [Sig] -> Sam -> Sam
- Csound.Sam: arpy :: (D -> SE Sig2) -> D -> D -> Int -> [[D]] -> Sam
+ Csound.Sam: arpy :: (D -> SE Sig2) -> Sig -> Sig -> Int -> [[D]] -> Sam
- Csound.Sam: forAirports :: [(D, D, D)] -> Sam -> Sam
+ Csound.Sam: forAirports :: [(Sig, Sig, Sig)] -> Sam -> Sam
- Csound.Sam: fromSig1 :: D -> Sig -> Sam
+ Csound.Sam: fromSig1 :: Sig -> Sig -> Sam
- Csound.Sam: fromSig2 :: D -> Sig2 -> Sam
+ Csound.Sam: fromSig2 :: Sig -> Sig2 -> Sam
- Csound.Sam: genForAirports :: [(D, D, Sam)] -> Sam
+ Csound.Sam: genForAirports :: [(Sig, Sig, Sam)] -> Sam
- Csound.Sam: limSam :: ToSam a => D -> a -> Sam
+ Csound.Sam: limSam :: ToSam a => Sig -> a -> Sam
- Csound.Sam: pat :: [D] -> Sam -> Sam
+ Csound.Sam: pat :: [Sig] -> Sam -> Sam
- Csound.Sam: pat' :: [D] -> [D] -> Sam -> Sam
+ Csound.Sam: pat' :: [D] -> [Sig] -> Sam -> Sam
- Csound.Sam: pat1 :: D -> Sam -> Sam
+ Csound.Sam: pat1 :: Sig -> Sam -> Sam
- Csound.Sam: rep :: [D] -> Sam -> Sam
+ Csound.Sam: rep :: [Sig] -> Sam -> Sam
- Csound.Sam: rep1 :: D -> Sam -> Sam
+ Csound.Sam: rep1 :: Sig -> Sam -> Sam
- Csound.Sam: rndPat :: Sig -> [D] -> Sam -> Sam
+ Csound.Sam: rndPat :: Sig -> [Sig] -> Sam -> Sam
- Csound.Sam: rndPat' :: Sig -> [D] -> [D] -> Sam -> Sam
+ Csound.Sam: rndPat' :: Sig -> [D] -> [Sig] -> Sam -> Sam
- Csound.Sam: sig1 :: D -> Sig -> Sam
+ Csound.Sam: sig1 :: Sig -> Sig -> Sam
- Csound.Sam: sig2 :: D -> Sig2 -> Sam
+ Csound.Sam: sig2 :: Sig -> Sig2 -> Sam
- Csound.Sam: toSec :: Bpm -> D -> D
+ Csound.Sam: toSec :: Bpm -> Sig -> Sig
- Csound.Sam: type Bpm = D
+ Csound.Sam: type Bpm = Sig
- Csound.Sam: wall :: D -> Sam -> Sam
+ Csound.Sam: wall :: Sig -> Sam -> Sam
- Csound.Sam: wide :: D -> Sam -> Sam
+ Csound.Sam: wide :: Sig -> Sam -> Sam
- Csound.Sam.Core: Dur :: D -> Dur
+ Csound.Sam.Core: Dur :: Sig -> Dur
- Csound.Sam.Core: type Bpm = D
+ Csound.Sam.Core: type Bpm = Sig
- Csound.Sam.Trig: samCharTap :: D -> String -> Sam -> Sam
+ Csound.Sam.Trig: samCharTap :: Sig -> String -> Sam -> Sam
- Csound.Sam.Trig: samMidiTap :: MidiChn -> D -> Int -> Sam -> Sam
+ Csound.Sam.Trig: samMidiTap :: MidiChn -> Sig -> Int -> Sam -> Sam
- Csound.Sam.Trig: samMidiTapBy :: MidiTrigFun Sig2 -> MidiChn -> D -> Int -> Sam -> Sam
+ Csound.Sam.Trig: samMidiTapBy :: MidiTrigFun Sig2 -> MidiChn -> Sig -> Int -> Sam -> Sam
- Csound.Sam.Trig: samSyncCharCycle :: D -> Maybe Sam -> Char -> String -> [Sam] -> Sam
+ Csound.Sam.Trig: samSyncCharCycle :: Sig -> Maybe Sam -> Char -> String -> [Sam] -> Sam
- Csound.Sam.Trig: samSyncCharGroup :: D -> Maybe Sam -> [(Char, Sam)] -> String -> Sam
+ Csound.Sam.Trig: samSyncCharGroup :: Sig -> Maybe Sam -> [(Char, Sam)] -> String -> Sam
- Csound.Sam.Trig: samSyncCharPush :: D -> Maybe Sam -> Char -> Sam -> Sam
+ Csound.Sam.Trig: samSyncCharPush :: Sig -> Maybe Sam -> Char -> Sam -> Sam
- Csound.Sam.Trig: samSyncCharTap :: D -> D -> String -> Sam -> Sam
+ Csound.Sam.Trig: samSyncCharTap :: Sig -> Sig -> String -> Sam -> Sam
- Csound.Sam.Trig: samSyncCharToggle :: D -> Maybe Sam -> Char -> Sam -> Sam
+ Csound.Sam.Trig: samSyncCharToggle :: Sig -> Maybe Sam -> Char -> Sam -> Sam
- Csound.Sam.Trig: samSyncCharTrig :: D -> Maybe Sam -> String -> String -> Sam -> Sam
+ Csound.Sam.Trig: samSyncCharTrig :: Sig -> Maybe Sam -> String -> String -> Sam -> Sam
- Csound.Sam.Ui: uiSam :: String -> Bool -> D -> Source Sam -> Source Fx2
+ Csound.Sam.Ui: uiSam :: String -> Bool -> Sig -> Source Sam -> Source Fx2

Files

csound-sampler.cabal view
@@ -1,5 +1,5 @@ name:                csound-sampler-version:             0.0.8.1+version:             0.0.9.0 license:             BSD3 license-file:        LICENSE author:              Anton Kholomiov@@ -25,7 +25,7 @@ library   Ghc-Options:    -Wall   Hs-Source-Dirs:      src/-  build-depends:       base >= 4, base < 5, transformers >= 0.3, csound-expression >= 5.2.2+  build-depends:       base >= 4, base < 5, transformers >= 0.3, csound-expression >= 5.3.2   exposed-modules:     Csound.Sam     Csound.Sam.Core
src/Csound/Sam.hs view
@@ -1,7 +1,7 @@ -- | The sampler {-# Language TypeFamilies, DeriveFunctor, TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses #-} module Csound.Sam (-	Sample, Sam, Bpm, runSam, +	Sample, Sam, Bpm, runSam, 	-- * Lifters 	mapBpm, bindSam, bindBpm, liftSam, mapBpm2, bindBpm2, withBpm, 	-- * Constructors@@ -9,11 +9,11 @@ 	-- ** Stereo 	wav, wavr, seg, segr, rndWav, rndWavr, rndSeg, rndSegr, ramWav, 	-- ** Mono-	wav1, wavr1, seg1, segr1, rndWav1, rndWavr1, rndSeg1, rndSegr1, ramWav1,	+	wav1, wavr1, seg1, segr1, rndWav1, rndWavr1, rndSeg1, rndSegr1, ramWav1, 	-- * Reading from RAM 	-- ** Stereo 	ramLoop, ramRead, segLoop, segRead, relLoop, relRead,-	-- ** Mono	+	-- ** Mono 	ramLoop1, ramRead1, segLoop1, segRead1, relLoop1, relRead1,      -- ** Tempo/pitch scaling based on temposcal@@ -21,8 +21,8 @@ 	-- * Envelopes 	linEnv, expEnv, hatEnv, decEnv, riseEnv, edecEnv, eriseEnv, 	-- * Arrange-	wide, flow, pick, pickBy, -	atPan, atPch, atCps, atPanRnd, atVolRnd, atVolGauss,	+	wide, flow, pick, pickBy,+	atPan, atPch, atCps, atPanRnd, atVolRnd, atVolGauss, 	-- * Loops 	rep1, rep, pat1, pat, pat',	rndPat, rndPat', 	-- * Arpeggio@@ -51,7 +51,7 @@ import Csound.Sam.Ui import Csound.Sam.Trig -type instance DurOf Sam = D+type instance DurOf Sam = Sig  instance Melody Sam where 	mel = flow@@ -64,7 +64,7 @@ instance Delay Sam where 	del dt = tfmS phi 		where phi bpm x = x { samSig = asig, samDur = dur }-				where +				where 					absDt = toSec bpm dt 					asig  = delaySnd absDt $ samSig x 					dur   = addDur absDt $ samDur x@@ -73,8 +73,8 @@ 	str k (Sam a) = Sam $ withReaderT ( * k) a  instance Limit Sam where-	lim d = tfmS $ \bpm x -> -		let absD = toSec bpm d +	lim d = tfmS $ \bpm x ->+		let absD = toSec bpm d 		in  x { samSig = takeSnd absD $ samSig x 			  , samDur = Dur absD } @@ -99,15 +99,15 @@ instance At Sig Sig2 Sam where 	type AtOut Sig Sig2 Sam = Sam 	at f x = at phi x-		where +		where 			phi (a, b) = 0.5 * (f a + f b)  instance At Sig (SE Sig2) Sam where 	type AtOut Sig (SE Sig2) Sam = Sam 	at f x = at phi x-		where +		where 			phi (a, b) = do-				a' <- f a +				a' <- f a 				b' <- f b 				return $ 0.5 * (a' + b') @@ -135,40 +135,40 @@ infSig2 = pure  -- | Constructs sample from limited mono signal (duration is in seconds)-sig1 :: D -> Sig -> Sam+sig1 :: Sig -> Sig -> Sam sig1 dt a = Sam $ reader $ \_ -> S (a, a) (Dur dt)  -- | Constructs sample from limited stereo signal (duration is in seconds)-sig2 :: D -> Sig2 -> Sam+sig2 :: Sig -> Sig2 -> Sam sig2 dt a = Sam $ reader $ \_ -> S a (Dur dt)  -- | Constructs sample from limited mono signal (duration is in BPMs)-fromSig1 :: D -> Sig -> Sam+fromSig1 :: Sig -> Sig -> Sam fromSig1 dt = lim dt . infSig1  -- | Constructs sample from limited stereo signal (duration is in BPMs)-fromSig2 :: D -> Sig2 -> Sam+fromSig2 :: Sig -> Sig2 -> Sam fromSig2 dt = lim dt . infSig2  -- | Constructs sample from wav or aiff files. wav :: String -> Sam-wav fileName = Sam $ return $ S (readSnd fileName) (Dur $ lengthSnd fileName)+wav fileName = Sam $ return $ S (readSnd fileName) (Dur $ sig $ lengthSnd fileName)  -- | Constructs sample from wav that is played in reverse. wavr :: String -> Sam-wavr fileName = Sam $ return $ S (takeSnd len $ loopWav (-1) fileName) (Dur len)+wavr fileName = Sam $ return $ S (takeSnd (sig len) $ loopWav (-1) fileName) (Dur $ sig len) 	where len = lengthSnd fileName  -- | Constructs sample from the segment of a wav file. The start and end times are measured in seconds. -- -- > seg begin end fileName seg :: D -> D -> String -> Sam-seg start end fileName = Sam $ return $ S (readSegWav start end 1 fileName) (Dur len)+seg start end fileName = Sam $ return $ S (readSegWav start end 1 fileName) (Dur $ sig len) 	where len = end - start  --- | Constructs reversed sample from segment of an audio file. segr :: D -> D -> String -> Sam-segr start end fileName = Sam $ return $ S (readSegWav start end (-1) fileName) (Dur len)+segr start end fileName = Sam $ return $ S (readSegWav start end (-1) fileName) (Dur $ sig len) 	where len = end - start  -- | Picks segments from the wav file at random. The first argument is the length of the segment.@@ -192,40 +192,40 @@ 	x <- random 0 1 	let a = start + dl * x 	let b = a + len-	return $ S (readSegWav a b speed fileName) (Dur len)+	return $ S (readSegWav a b speed fileName) (Dur $ sig len) 	where dl = end - len  -- | Reads a sample from the file in RAM. -- -- > ramWav loopMode speed fileName ramWav :: LoopMode -> Sig -> String -> Sam-ramWav loopMode speed fileName = Sam $ return $ S (ramSnd loopMode speed fileName) (Dur $ lengthSnd fileName)+ramWav loopMode speed fileName = Sam $ return $ S (ramSnd loopMode speed fileName) (Dur $ sig $ lengthSnd fileName)  -- | Reads a sample from the mono file in RAM. -- -- > ramWav1 loopMode speed fileName ramWav1 :: LoopMode -> Sig -> String -> Sam-ramWav1 loopMode speed fileName = Sam $ return $ S (let x = ramSnd1 loopMode speed fileName in (x, x)) (Dur $ lengthSnd fileName)+ramWav1 loopMode speed fileName = Sam $ return $ S (let x = ramSnd1 loopMode speed fileName in (x, x)) (Dur $ sig $ lengthSnd fileName)  -- | Constructs sample from mono wav or aiff files. wav1 :: String -> Sam-wav1 fileName = Sam $ return $ S (let x = readSnd1 fileName in (x, x)) (Dur $ lengthSnd fileName)+wav1 fileName = Sam $ return $ S (let x = readSnd1 fileName in (x, x)) (Dur $ sig $ lengthSnd fileName)  -- | Constructs sample from mono wav that is played in reverse. wavr1 :: String -> Sam-wavr1 fileName = Sam $ return $ S (let x = takeSnd len $ loopWav1 (-1) fileName in (x, x)) (Dur len)+wavr1 fileName = Sam $ return $ S (let x = takeSnd (sig len) $ loopWav1 (-1) fileName in (x, x)) (Dur $ sig len) 	where len = lengthSnd fileName  -- | Constructs sample from the segment of a mono wav file. The start and end times are measured in seconds. -- -- > seg begin end fileName seg1 :: D -> D -> String -> Sam-seg1 start end fileName = Sam $ return $ S (let x = readSegWav1 start end 1 fileName in (x, x)) (Dur len)+seg1 start end fileName = Sam $ return $ S (let x = readSegWav1 start end 1 fileName in (x, x)) (Dur $ sig len) 	where len = end - start  --- | Constructs reversed sample from segment of a mono audio file. segr1 :: D -> D -> String -> Sam-segr1 start end fileName = Sam $ return $ S (let x = readSegWav1 start end (-1) fileName in (x, x)) (Dur len)+segr1 start end fileName = Sam $ return $ S (let x = readSegWav1 start end (-1) fileName in (x, x)) (Dur $ sig len) 	where len = end - start  -- | Picks segments from the mono wav file at random. The first argument is the length of the segment.@@ -249,17 +249,17 @@ 	x <- random 0 1 	let a = start + dl * x 	let b = a + len-	return $ S (let y = readSegWav1 a b speed fileName in (y, y)) (Dur len)+	return $ S (let y = readSegWav1 a b speed fileName in (y, y)) (Dur $ sig len) 	where dl = end - len  -toSec :: Bpm -> D -> D+toSec :: Bpm -> Sig -> Sig toSec bpm a = a * 60 / bpm -toSecSig :: Bpm -> Sig -> Sig-toSecSig bpm a = a * 60 / sig bpm+toSecD :: Bpm -> D -> D+toSecD bpm a = a * 60 / (ir bpm) -addDur :: D -> Dur -> Dur+addDur :: Sig -> Dur -> Dur addDur d x = case x of 	Dur a  -> Dur $ d + a 	InfDur -> InfDur@@ -283,7 +283,7 @@ tfmS f ra = Sam $ do 	bpm <- ask 	a <- unSam ra-	return $ f bpm a	+	return $ f bpm a  setInfDur :: Sam -> Sam setInfDur = Sam . fmap (\a -> a { samDur = InfDur }) . unSam@@ -291,13 +291,13 @@ -- | Makes the sampler broader. It's reciprocal of str -- -- > wide k = str (1 / k)-wide :: D -> Sam -> Sam+wide :: Sig -> Sam -> Sam wide = str . recip  -- | Plays a list of samples one after another. flow :: [Sam] -> Sam flow [] = 0-flow as = foldr1 flow2 as +flow as = foldr1 flow2 as  flow2 :: Sam -> Sam -> Sam flow2 (Sam ra) (Sam rb) = Sam $ do@@ -316,10 +316,11 @@ genPick pickFun dt as = Sam $ do 	bpm <- ask 	xs <- sequence $ fmap unSam as-	let ds = fmap (getDur . samDur)  xs+	let ds = fmap (ir . getDur . samDur)  xs 	let sigs = fmap samSig xs-	return $ S (sched (\n -> return $ atTuple sigs $ sig n) $ fmap (\(dt, a) -> str dt $ temp a) $ pickFun (zip ds (fmap int [0..])) $ metroS bpm dt) InfDur -	where getDur x = case x of+	return $ S (sched (\n -> return $ atTuple sigs $ sig n) $ fmap (\(dt, a) -> str (sig dt) $ temp a) $ pickFun (zip ds (fmap int [0..])) $ metroS bpm dt) InfDur+	where+		getDur x = case x of 			InfDur -> -1 			Dur d  -> d @@ -338,9 +339,9 @@ genEnv :: EnvFun -> D -> D -> Sam -> Sam genEnv env start end = tfmS f 	where f bpm a = a { samSig = mul (env (samDur a) absStart absEnd) $ samSig a }-			where -				absStart = toSec bpm start-				absEnd   = toSec bpm end+			where+				absStart = toSecD bpm start+				absEnd   = toSecD bpm end  -- | A linear rise-decay envelope. Times a given in BPMs. --@@ -349,25 +350,25 @@ linEnv = genEnv f 	where f dur start end = case dur of 			InfDur -> linseg [0, start, 1]-			Dur d  -> linseg [0, start, 1, maxB 0 (d - start - end), 1, end , 0]+			Dur d  -> linseg [0, start, 1, maxB 0 (ir d - start - end), 1, end , 0]  -- | An exponential rise-decay envelope. Times a given in BPMs. -- -- > expEnv rise dec sample expEnv :: D -> D -> Sam -> Sam expEnv = genEnv f-	where +	where 		f dur start end = case dur of 			InfDur -> expseg [zero, start, 1]-			Dur d  -> expseg [zero, start, 1, maxB 0 (d - start - end), 1, end , zero]+			Dur d  -> expseg [zero, start, 1, maxB 0 (ir d - start - end), 1, end , zero] 		zero = 0.00001  genEnv1 :: (D -> Sig) -> Sam -> Sam genEnv1 envFun = tfmBy f-	where +	where 		f a = flip mul (samSig a) $ case samDur a of 			InfDur -> 1-			Dur d  -> envFun d+			Dur d  -> envFun (ir d)   -- | Parabolic envelope that starts and ends at zero and reaches maximum at the center.@@ -390,11 +391,11 @@ edecEnv :: Sam -> Sam edecEnv = genEnv1 $ \d -> expseg [1, d, 0.0001] -type LoopFun = D -> D -> Sig2 -> Sig2+type LoopFun = Sig -> Sig -> Sig2 -> Sig2 -genLoop :: LoopFun -> Sam -> Sam +genLoop :: LoopFun -> Sam -> Sam genLoop g = setInfDur . tfmS f-	where +	where 		f bpm a = a { samSig = case samDur a of 			InfDur -> samSig a 			Dur d  -> g bpm d (samSig a)@@ -402,59 +403,59 @@   -- | Plays the sample at the given period (in BPMs). The samples don't overlap.-rep1 :: D -> Sam -> Sam+rep1 :: Sig -> Sam -> Sam rep1 = rep . return  -- | Plays the sample at the given period (in BPMs). The overlapped samples are mixed together.-pat1 :: D -> Sam -> Sam+pat1 :: Sig -> Sam -> Sam pat1 = pat . return  -- | Plays the sample at the given pattern of periods (in BPMs). The samples don't overlap.-rep :: [D] -> Sam -> Sam -rep dts = genLoop $ \bpm d asig -> sched (const $ return asig) $ fmap (const $ notes bpm d) $ metroS bpm (sig $ sum dts)-	where notes bpm _ = har $ zipWith (\t dt-> singleEvent (toSec bpm t) (toSec bpm dt) unit) (patDurs dts) dts	 -		+rep :: [Sig] -> Sam -> Sam+rep dts = genLoop $ \bpm d asig -> sched (const $ return asig) $ fmap (const $ notes bpm) $ metroS bpm (sum dts)+	where notes bpm = har $ zipWith (\t dt-> singleEvent (toSec bpm t) (toSec bpm dt) unit) (patDurs dts) dts+ -- | Plays the sample at the given pattern of periods (in BPMs). The overlapped samples are mixed together.-pat :: [D] -> Sam -> Sam -pat dts = genLoop $ \bpm d asig -> sched (const $ return asig) $ fmap (const $ notes bpm d) $ metroS bpm (sig $ sum dts)-	where notes bpm d = har $ fmap (\t -> fromEvent $ Event (toSec bpm t) d unit) $ patDurs dts		+pat :: [Sig] -> Sam -> Sam+pat dts = genLoop $ \bpm d asig -> sched (const $ return asig) $ fmap (const $ notes bpm d) $ metroS bpm (sum dts)+	where notes bpm d = har $ fmap (\t -> fromEvent $ Event (toSec bpm t) d unit) $ patDurs dts  -- | Plays the sample at the given pattern of periods (in BPMs) and sometimes skips the samples from playback. The overlapped samples are mixed together. -- The first argument is the probability of inclusion.-rndPat :: Sig -> [D] -> Sam -> Sam -rndPat prob dts = genLoop $ \bpm d asig -> sched (const $ rndSkipInstr prob asig) $ fmap (const $ notes bpm d) $ metroS bpm (sig $ sum dts)-	where -		notes bpm d = har $ fmap (\t -> fromEvent $ Event (toSec bpm t) d unit) $ patDurs dts	+rndPat :: Sig -> [Sig] -> Sam -> Sam+rndPat prob dts = genLoop $ \bpm d asig -> sched (const $ rndSkipInstr prob asig) $ fmap (const $ notes bpm d) $ metroS bpm (sum dts)+	where+		notes bpm d = har $ fmap (\t -> fromEvent $ Event (toSec bpm t) d unit) $ patDurs dts  -- | Plays the sample at the given pattern of volumes and periods (in BPMs). The overlapped samples are mixed together. -- -- > pat' volumes periods-pat' :: [D] -> [D] -> Sam -> Sam -pat' vols dts = genLoop $ \bpm d asig -> sched (instr asig) $ fmap (const $ notes bpm d) $ metroS bpm (sig $ sum dts')-	where -		notes bpm d = har $ zipWith (\v t -> singleEvent (toSec bpm t) d v) vols' $ patDurs dts'		+pat' :: [D] -> [Sig] -> Sam -> Sam+pat' vols dts = genLoop $ \bpm d asig -> sched (instr asig) $ fmap (const $ notes bpm d) $ metroS bpm (sum dts')+	where+		notes bpm d = har $ zipWith (\v t -> singleEvent (toSec bpm t) d v) vols' $ patDurs dts' 		instr asig v = return $ mul (sig v) asig 		(vols', dts') = unzip $ lcmList vols dts  rndSkipInstr probSig asig = do 	let prob = ir probSig-	ref <- newRef 0	+	ref <- newRef 0 	p <- random 0 (1 :: D)-	whenD1 (p `lessThan` prob) $ +	whenD1 (p `lessThan` prob) $ 		writeRef ref asig 	whenD1 (p `greaterThanEquals` prob) $ 		writeRef ref 0-	readRef ref	+	readRef ref  -- | Plays the sample at the given pattern of volumes and periods (in BPMs) and sometimes skips the samples from playback.  The overlapped samples are mixed together. -- The first argument is the probability of inclusion. -- -- > rndPat' probability volumes periods-rndPat' :: Sig -> [D] -> [D] -> Sam -> Sam -rndPat' prob vols dts = genLoop $ \bpm d asig -> sched (instr asig) $ fmap (const $ notes bpm d) $ metroS bpm (sig $ sum dts')-	where -		notes bpm d = har $ zipWith (\v t -> singleEvent (toSec bpm t) d v) vols' $ patDurs dts'		-		instr asig v = mul (sig v) $ rndSkipInstr prob asig			+rndPat' :: Sig -> [D] -> [Sig] -> Sam -> Sam+rndPat' prob vols dts = genLoop $ \bpm d asig -> sched (instr asig) $ fmap (const $ notes bpm d) $ metroS bpm (sum dts')+	where+		notes bpm d = har $ zipWith (\v t -> singleEvent (toSec bpm t) d v) vols' $ patDurs dts'+		instr asig v = mul (sig v) $ rndSkipInstr prob asig 		(vols', dts') = unzip $ lcmList vols dts  @@ -466,9 +467,9 @@ -- The segment length is given in BPMs. -- -- > wall segLength-wall :: D -> Sam -> Sam +wall :: Sig -> Sam -> Sam wall dt a = mean [b, del hdt b]-	where +	where 		hdt = 0.5 * dt 		f = pat1 hdt . hatEnv . lim dt 		b = f a@@ -479,13 +480,13 @@ type Arp1Fun = Evt Unit -> Evt D  arpInstr :: Sig2 -> D -> SE Sig2-arpInstr asig k = return $ mapSig (scalePitch (sig k)) asig +arpInstr asig k = return $ mapSig (scalePitch (sig k)) asig -patDurs :: [D] -> [D]+patDurs :: [Sig] -> [Sig] patDurs dts = reverse $ snd $ foldl (\(counter, res) a -> (a + counter, counter:res)) (0, []) dts  genArp1 :: Arp1Fun -> Sig -> Sam -> Sam-genArp1 arpFun dt = genLoop $ \bpm d asig -> +genArp1 arpFun dt = genLoop $ \bpm d asig -> 	sched (arpInstr asig) $ withDur d $ arpFun $ metroS bpm dt  -- | Plays ascending arpeggio of samples.@@ -505,69 +506,67 @@ arpFreqOf1 :: [Sig] -> Chord -> Sig -> Sam -> Sam arpFreqOf1 freqs ch = genArp1 (freqOf (zip freqs ch)) -genArp :: Arp1Fun -> [D] -> Sam -> Sam-genArp arpFun dts = genLoop $ \bpm d asig -> sched (arpInstr asig) $ fmap (notes bpm d) $ arpFun $ metroS bpm (sig $ sum dts)-	where notes bpm d pchScale = har $ fmap (\t -> singleEvent (toSec bpm t) d pchScale) $ patDurs dts		+genArp :: Arp1Fun -> [Sig] -> Sam -> Sam+genArp arpFun dts = genLoop $ \bpm d asig -> sched (arpInstr asig) $ fmap (notes bpm d) $ arpFun $ metroS bpm (sum dts)+	where notes bpm d pchScale = har $ fmap (\t -> singleEvent (toSec bpm t) d pchScale) $ patDurs dts  -- | Plays ascending arpeggio of samples.-arpUp :: Chord -> [D] -> Sam -> Sam+arpUp :: Chord -> [Sig] -> Sam -> Sam arpUp = genArp . cycleE  -- | Plays descending arpeggio of samples.-arpDown :: Chord -> [D] -> Sam -> Sam+arpDown :: Chord -> [Sig] -> Sam -> Sam arpDown ch = arpUp (reverse ch)  -- | Plays arpeggio of samles with random notes from the chord.-arpOneOf :: Chord -> [D] -> Sam -> Sam +arpOneOf :: Chord -> [Sig] -> Sam -> Sam arpOneOf = genArp . oneOf  -- | Plays arpeggio of samles with random notes from the chord. -- We can assign the frequencies of the notes.-arpFreqOf :: [Sig] -> Chord -> [D] -> Sam -> Sam+arpFreqOf :: [Sig] -> Chord -> [Sig] -> Sam -> Sam arpFreqOf freqs ch = genArp (freqOf $ zip freqs ch)  metroS :: Bpm -> Sig -> Evt Unit-metroS bpm dt = metroE (recip $ toSecSig bpm dt)+metroS bpm dt = metroE (recip $ toSec bpm dt)  -- | The pattern is influenced by the Brian Eno's work "Music fo Airports". -- The argument is list of tripples: -- -- > (delayTime, repeatPeriod, pitch)--- +-- -- It takes a Sample and plays it in the loop with given initial delay time. -- The third cell in the tuple pitch is a value for scaling of the pitch in tones.-forAirports :: [(D, D, D)] -> Sam -> Sam-forAirports xs sample = mean $ flip fmap xs $ -    \(delTime, loopTime, note) -> del delTime $ pat [loopTime] (atPch (sig note) sample)+forAirports :: [(Sig, Sig, Sig)] -> Sam -> Sam+forAirports xs sample = mean $ flip fmap xs $+    \(delTime, loopTime, note) -> del delTime $ pat [loopTime] (atPch note sample)  -- | The pattern is influenced by the Brian Eno's work "Music fo Airports". -- It's more generic than pattern @forAirport@ -- The argument is list of tripples: -- -- > (delayTime, repeatPeriod, Sample)--- +-- -- It takes a list of Samples and plays them in the loop with given initial delay time and repeat period.-genForAirports :: [(D, D, Sam)] -> Sam+genForAirports :: [(Sig, Sig, Sam)] -> Sam genForAirports xs = mean $ fmap (\(delTime, loopTime, sample) -> del delTime $ pat [loopTime] sample) xs ---arp1 :: (SigSpace a, Sigs a) => (D -> SE a) -> D -> D -> Int -> [D] -> a-arp1 instr bpm dt n ch = sched (\(amp, cps) -> fmap (mul (sig amp)) $ instr cps) $ -	withDur (toSec bpm dt) $ cycleE (lcmList (1 : replicate (n - 1) 0.7) ch) $ metroS bpm (sig dt)+arp1 :: (SigSpace a, Sigs a) => (D -> SE a) -> Sig -> Sig -> Int -> [D] -> a+arp1 instr bpm dt n ch = sched (\(amp, cps) -> fmap (mul (sig amp)) $ instr cps) $+	withDur (toSec bpm dt) $ cycleE (lcmList (1 : replicate (n - 1) 0.7) ch) $ metroS bpm dt --- | The arpeggiator for the sequence of chords. +-- | The arpeggiator for the sequence of chords. ----- > arpy instrument chordPeriod speedOfTheNote accentNumber chords +-- > arpy instrument chordPeriod speedOfTheNote accentNumber chords -- -- The first argument is an instrument that takes in a frequency of -- the note in Hz. The second argument is the period of--- chord change (in beats). The next argument is the speed +-- chord change (in beats). The next argument is the speed -- of the single note (in beats). The integer argument -- is number of notes in the group. Every n'th note is louder. -- The last argument is the sequence of chords. The chord is -- the list of frequencies.-arpy :: (D -> SE Sig2) -> D -> D -> Int -> [[D]] -> Sam+arpy :: (D -> SE Sig2) -> Sig -> Sig -> Int -> [[D]] -> Sam arpy instr chordPeriod speed accentNum chords = Sam $ do 	bpm <- ask 	res <- unSam $ loop $ flow $ map (linEnv 0.05 0.05 . fromSig2 chordPeriod . arp1 instr bpm speed accentNum) chords@@ -588,7 +587,7 @@ class ToSam a where 	toSam :: a -> Sam -limSam :: ToSam a => D -> a -> Sam+limSam :: ToSam a => Sig -> a -> Sam limSam dt = lim dt . toSam  instance ToSam Sig where@@ -616,7 +615,7 @@  -- | It's the same as readRam but wrapped in Sam (see "Csound.Air.Wav"). ramRead :: Fidelity -> TempoSig -> PitchSig -> String -> Sam-ramRead winSize tempo pitch file = sig2 (lengthSnd file / ir tempo) $ readRam winSize tempo pitch file+ramRead winSize tempo pitch file = sig2 (sig (lengthSnd file) / tempo) $ readRam winSize tempo pitch file  -- | It's the same as loopSeg but wrapped in Sam (see "Csound.Air.Wav"). segLoop :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam@@ -624,7 +623,7 @@  -- | It's the same as readSeg but wrapped in Sam (see "Csound.Air.Wav"). segRead :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam-segRead winSize ds@(kmin, kmax) tempo pitch file = sig2 (ir $ (kmax - kmin) / tempo) $ readSeg winSize ds tempo pitch file+segRead winSize ds@(kmin, kmax) tempo pitch file = sig2 ((kmax - kmin) / tempo) $ readSeg winSize ds tempo pitch file  -- | It's the same as loopRel but wrapped in Sam (see "Csound.Air.Wav"). relLoop :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam@@ -632,7 +631,7 @@  -- | It's the same as readRel but wrapped in Sam (see "Csound.Air.Wav"). relRead :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam-relRead winSize ds@(kmin, kmax) tempo pitch file = sig2 (ir $ (kmax - kmin) / tempo) $ readRel winSize ds tempo pitch file+relRead winSize ds@(kmin, kmax) tempo pitch file = sig2 ((kmax - kmin) / tempo) $ readRel winSize ds tempo pitch file  -- | It's the same as loopRam1 but wrapped in Sam (see "Csound.Air.Wav"). ramLoop1 :: Fidelity -> TempoSig -> PitchSig -> String -> Sam@@ -640,7 +639,7 @@  -- | It's the same as readRam1 but wrapped in Sam (see "Csound.Air.Wav"). ramRead1 :: Fidelity -> TempoSig -> PitchSig -> String -> Sam-ramRead1 winSize tempo pitch file = sig1 (lengthSnd file / ir tempo) $ readRam1 winSize tempo pitch file+ramRead1 winSize tempo pitch file = sig1 (sig (lengthSnd file) / tempo) $ readRam1 winSize tempo pitch file  -- | It's the same as loopSeg1 but wrapped in Sam (see "Csound.Air.Wav"). segLoop1 :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam@@ -648,7 +647,7 @@  -- | It's the same as readSeg1 but wrapped in Sam (see "Csound.Air.Wav"). segRead1 :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam-segRead1 winSize ds@(kmin, kmax) tempo pitch file = sig1 (ir $ (kmax - kmin) / tempo) $ readSeg1 winSize ds tempo pitch file+segRead1 winSize ds@(kmin, kmax) tempo pitch file = sig1 ((kmax - kmin) / tempo) $ readSeg1 winSize ds tempo pitch file  -- | It's the same as loopRel1 but wrapped in Sam (see "Csound.Air.Wav"). relLoop1 :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam@@ -656,7 +655,7 @@  -- | It's the same as readRel1 but wrapped in Sam (see "Csound.Air.Wav"). relRead1 :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam-relRead1 winSize ds@(kmin, kmax) tempo pitch file = sig1 (ir $ (kmax - kmin) / tempo) $ readRel1 winSize ds tempo pitch file+relRead1 winSize ds@(kmin, kmax) tempo pitch file = sig1 ((kmax - kmin) / tempo) $ readRel1 winSize ds tempo pitch file  ----------------------- -- temposcale
src/Csound/Sam/Core.hs view
@@ -15,21 +15,29 @@ type Sam = Sample Sig2  instance RenderCsd Sam where-    renderCsdBy opt sample = renderCsdBy opt (runSam (120 * 4) sample)+    renderCsdBy opt sample = renderCsdBy opt (runSam (getBpm * 4) sample)  instance RenderCsd (Source Sam) where-	renderCsdBy opt sample = renderCsdBy opt (lift1 (runSam (120 * 4)) sample)	+	renderCsdBy opt sample = renderCsdBy opt (lift1 (runSam (getBpm * 4)) sample) +instance RenderCsd (SE Sam) where+    renderCsdBy opt sample = renderCsdBy opt (runSam (getBpm * 4) =<< sample)++instance RenderCsd (SE (Source Sam)) where+    renderCsdBy opt sample = renderCsdBy opt $ do+    	sample' <- sample+    	lift1 (runSam (getBpm * 4)) sample'+ runSam :: Bpm -> Sam -> SE Sig2 runSam bpm x = fmap samSig $ runReaderT (unSam x) bpm -data Dur = Dur D | InfDur+data Dur = Dur Sig | InfDur  -- | The Beats Per Minute measure (BPM). Almost all values are measured in BPMs.-type Bpm = D+type Bpm = Sig  -- | The generic type for samples.-newtype Sample a = Sam { unSam :: ReaderT Bpm SE (S a) +newtype Sample a = Sam { unSam :: ReaderT Bpm SE (S a) 	} deriving (Functor)  instance Applicative Sample where@@ -38,7 +46,7 @@  data S a = S 	{ samSig :: a-	, samDur :: Dur +	, samDur :: Dur 	} deriving (Functor)  instance Applicative S where@@ -63,6 +71,12 @@ instance SigSpace a => SigSpace (Sample a) where 	mapSig f = fmap (mapSig f) +instance SigSpace2 a => SigSpace2 (Sample a) where+	mapSig2 f = fmap (mapSig2 f)++instance BindSig2 a => BindSig2 (Sample a) where+	bindSig2 f = return . bindSam (bindSig2 f)+ -- Lifters  -- | Hides the effects inside sample.@@ -74,14 +88,14 @@ -- | Transforms the sample with BPM. mapBpm :: (Bpm -> a -> b) -> Sample a -> Sample b mapBpm f a = Sam $ do-	bpm <- ask	+	bpm <- ask 	unSam $ fmap (f bpm) a  -- | Transforms the sample with BPM. mapBpm2 :: (Bpm -> a -> b -> c) -> Sample a -> Sample b -> Sample c mapBpm2 f a b = Sam $ do-	bpm <- ask	-	unSam $ liftA2 (f bpm) a b	+	bpm <- ask+	unSam $ liftA2 (f bpm) a b  -- | Lifts bind on stereo signals to samples. bindSam :: (a -> SE b) -> Sample a -> Sample b
src/Csound/Sam/Trig.hs view
@@ -43,7 +43,7 @@  -- | Char trigger with fixed note limiting by length in second. -- It's useful optimization. It's good to use for drum notes and short sounds.-samCharTap :: D -> String -> Sam -> Sam+samCharTap :: Sig -> String -> Sam -> Sam samCharTap stop starts = fmap (charTap stop starts)  -- | Plays one of the sample from the list when corresponding char is pressed.@@ -54,7 +54,7 @@ 	Just v0 -> liftA2 (\v xs -> charGroup (Just v) (zip starts xs) stop) v0 (sequenceA sams) 	where (starts, sams) = unzip as --- | Plays samples in sequence when key is pressed. The last string is +-- | Plays samples in sequence when key is pressed. The last string is -- for stopping the sequence. samCharCycle :: Maybe Sam -> Char -> String -> [Sam] -> Sam samCharCycle initVal start stop as = case initVal of@@ -65,26 +65,27 @@ ------------------------------------------------------ -- synchronised -syncBeats bpm beats = sig $ bpm / beats+syncBeats :: Sig -> Sig -> Sig+syncBeats bpm beats = bpm / beats  -- | Triggers the sample with any char from the first string -- and stops the sample with any char from the second string. -- The first argument is the number of beats for syncronization.-samSyncCharTrig :: D -> Maybe Sam -> String -> String -> Sam -> Sam+samSyncCharTrig :: Sig -> Maybe Sam -> String -> String -> Sam -> Sam samSyncCharTrig beats initVal starts stops x = case initVal of 	Nothing -> mapBpm (\bpm a -> syncCharTrig (syncBeats bpm beats) Nothing starts stops a) x 	Just v0 -> mapBpm2 (\bpm v sigs -> syncCharTrig (syncBeats bpm beats) (Just v) starts stops sigs) v0 x  -- | Plays a sample while the key is pressed. -- The first argument is the number of beats for syncronization.-samSyncCharPush :: D -> Maybe Sam -> Char -> Sam -> Sam+samSyncCharPush :: Sig -> Maybe Sam -> Char -> Sam -> Sam samSyncCharPush beats initVal ch x = case initVal of 	Nothing -> mapBpm (\bpm a -> syncCharPush (syncBeats bpm beats) Nothing ch a) x 	Just v0 -> mapBpm2 (\bpm v sigs -> syncCharPush (syncBeats bpm beats) (Just v) ch sigs) v0 x  -- | Toggles the sample when the key is pressed. -- The first argument is the number of beats for syncronization.-samSyncCharToggle :: D -> Maybe Sam -> Char -> Sam -> Sam+samSyncCharToggle :: Sig -> Maybe Sam -> Char -> Sam -> Sam samSyncCharToggle beats initVal ch x = case initVal of 	Nothing -> mapBpm (\bpm a -> syncCharToggle (syncBeats bpm beats) Nothing ch a) x 	Just v0 -> mapBpm2 (\bpm v sigs -> syncCharToggle (syncBeats bpm beats) (Just v) ch sigs) v0 x@@ -92,21 +93,21 @@ -- | Char trigger with fixed note limiting by length in second. -- It's useful optimization. It's good to use for drum notes and short sounds. -- The first argument is the number of beats for syncronization.-samSyncCharTap :: D -> D -> String -> Sam -> Sam+samSyncCharTap :: Sig -> Sig -> String -> Sam -> Sam samSyncCharTap beats stop starts = mapBpm (\bpm x -> syncCharTap (syncBeats bpm beats) stop starts x)  -- | Plays one of the sample from the list when corresponding char is pressed. -- The last string is for stopping the samples.-samSyncCharGroup :: D -> Maybe Sam -> [(Char, Sam)] -> String -> Sam+samSyncCharGroup :: Sig -> Maybe Sam -> [(Char, Sam)] -> String -> Sam samSyncCharGroup beats initVal as stop = case initVal of 	Nothing -> mapBpm (\bpm xs -> syncCharGroup (syncBeats bpm beats) Nothing (zip starts xs) stop) (sequenceA sams) 	Just v0 -> mapBpm2 (\bpm v xs -> syncCharGroup (syncBeats bpm beats) (Just v) (zip starts xs) stop) v0 (sequenceA sams) 	where (starts, sams) = unzip as --- | Plays samples in sequence when key is pressed. The last string is +-- | Plays samples in sequence when key is pressed. The last string is -- for stopping the sequence. -- The first argument is the number of beats for syncronization.-samSyncCharCycle :: D -> Maybe Sam -> Char -> String -> [Sam] -> Sam+samSyncCharCycle :: Sig -> Maybe Sam -> Char -> String -> [Sam] -> Sam samSyncCharCycle beats initVal start stop as = case initVal of 	Nothing -> mapBpm (\bpm -> syncCharCycle (syncBeats bpm beats) Nothing start stop) (sequenceA as) 	Just v0 -> mapBpm2 (\bpm v xs -> syncCharCycle (syncBeats bpm beats) (Just v) start stop xs) v0 (sequenceA as)@@ -121,7 +122,7 @@ -- | Midi trigger with fixed note limiting by length in second. -- It's useful optimization. It's good to use for drum notes and short sounds. -- The key is an integer midi code. The C1 is 60 and the A1 is 69.-samMidiTap :: MidiChn -> D -> Int -> Sam -> Sam+samMidiTap :: MidiChn -> Sig -> Int -> Sam -> Sam samMidiTap = samMidiTapBy midiAmpInstr  samMidiPush :: MidiChn -> Int -> Sam -> Sam@@ -147,7 +148,7 @@ -- | Generic samMidiTap. We can specify the midi triggering function. -- The midi function takes in a signal and a volume of the pressed key (it ranges from 0 to 1). -- It produces some output. The default is scaling the signal with the amplitude.-samMidiTapBy :: MidiTrigFun Sig2 -> MidiChn -> D -> Int -> Sam -> Sam+samMidiTapBy :: MidiTrigFun Sig2 -> MidiChn -> Sig -> Int -> Sam -> Sam samMidiTapBy midiFun midiChn dt key = bindSam (midiTapBy midiFun midiChn dt key)  -- | Generic samMidiPush. We can specify the midi triggering function.
src/Csound/Sam/Ui.hs view
@@ -46,7 +46,7 @@  genFreeSimInits :: ([Gui] -> Gui) -> [(String, Sam, Bool)] -> Source Sam genFreeSimInits gcat as = source $ do-	(guis, ts) <- fmap unzip $ zipWithM (\a b -> unSource $ toggle a b) names initVals+	(guis, ts) <- fmap unzip $ zipWithM (\a b -> toggle a b) names initVals 	let res = groupToggles mean sams ts 	return (gcat guis, res) 	where@@ -63,7 +63,7 @@  genFreeTog :: ([Gui] -> Gui) -> [(String, Sam)] -> Source Sam genFreeTog gcat as = source $ do-	(guis, writes, reads) <- fmap unzip3 $ mapM (unSinkSource . flip setToggleSig False) names+	(guis, writes, reads) <- fmap unzip3 $ mapM (flip setToggleSig False) names 	curRef <- newGlobalRef (0 :: Sig) 	current <- readRef curRef 	zipWithM_ (\w i -> w $ ifB (current ==* i) 1 0) writes ids@@ -86,11 +86,11 @@  genSimInits :: ([Gui] -> Gui) -> Int -> [(String, Sam, Bool)] -> Source Sam genSimInits gcat numBeats as = source $ do-	(guis, writes, reads) <- fmap unzip3 $ zipWithM (\a b -> unSinkSource $ setToggleSig a b) names initVals+	(guis, writes, reads) <- fmap unzip3 $ zipWithM (\a b -> setToggleSig a b) names initVals 	curRefs <- mapM (const $ newGlobalRef (0 :: Sig)) ids 	currents <- mapM readRef curRefs 	zipWithM_ (\w val -> w val) writes currents-	let mkReaders bpm = zipWithM_ (\r ref -> runEvt (syncBpm (sig $ bpm / int numBeats) $ snaps r) $ \x -> do+	let mkReaders bpm = zipWithM_ (\r ref -> runEvt (syncBpm (bpm / sig (int numBeats)) $ snaps r) $ \x -> do 			writeRef ref (sig x) 		) reads curRefs 	let res = bindBpm (\bpm x -> mkReaders bpm >> return x) $ groupToggles mean sams $ fmap snaps currents@@ -128,15 +128,15 @@   genTog :: ([Gui] -> Gui) -> Int -> [(String, Sam)] -> Source Sam-genTog gcat numBeats as = Source $ fmap (\(g, x) -> (g, fst x)) $ unSource $ genTogWithRef gcat numBeats as+genTog gcat numBeats as = fmap (\(g, x) -> (g, fst x)) $ genTogWithRef gcat numBeats as  genTogWithRef :: ([Gui] -> Gui) -> Int -> [(String, Sam)] -> Source (Sam, Ref Sig) genTogWithRef gcat numBeats as = source $ do-	(guis, writes, reads) <- fmap unzip3 $ mapM (unSinkSource . flip setToggleSig False) names+	(guis, writes, reads) <- fmap unzip3 $ mapM (flip setToggleSig False) names 	curRef <- newGlobalRef (0 :: Sig) 	current <- readRef curRef 	zipWithM_ (\w i -> w $ ifB (current ==* i) 1 0) writes ids-	let mkReaders bpm = zipWithM_ (\r i -> runEvt (syncBpm (sig $ bpm / int numBeats) $ snaps r) $ \x -> do+	let mkReaders bpm = zipWithM_ (\r i -> runEvt (syncBpm (bpm / (sig $ int numBeats)) $ snaps r) $ \x -> do 		when1 (sig x ==* 0 &&* current ==* i) $ do 			writeRef curRef 0 		when1 (sig x ==* 1) $ do@@ -174,10 +174,10 @@ -- in row-wise fashion. live :: Int -> [String] -> [Sam] -> Source Sam live numBeats names sams = source $ do-	(gVols, vols) <- fmap unzip $  mapM  (unSource . defSlider) $ replicate n "vol"-	(gs, xs) <- fmap unzip $ zipWithM (\a b -> unSource $ mkLiveRow numBeats a b) (zip names gVols) rows+	(gVols, vols) <- fmap unzip $  mapM  defSlider $ replicate n "vol"+	(gs, xs) <- fmap unzip $ zipWithM (\a b -> mkLiveRow numBeats a b) (zip names gVols) rows 	let (sigs, refs) = unzip xs-	(gMaster, masterVol) <- unSource $ defSlider "master"+	(gMaster, masterVol) <- defSlider "master" 	(g, proc) <- mkLiveSceneRow numBeats gMaster ids refs 	return $ (hor $ g : gs, bindBpm (\bpm asig -> proc bpm >> return asig) $ mul masterVol $ mean $ zipWith mul vols sigs) 	where@@ -188,13 +188,13 @@ mkLiveRow :: Int -> (String, Gui) -> [Sam] -> Source (Sam, Ref Sig) mkLiveRow numBeats (name, gVol) xs = genTogWithRef (\xs -> ver $ xs ++ [gVol]) numBeats (zip (name : repeat "") xs) -mkLiveSceneRow :: Int -> Gui -> [Sig] -> [Ref Sig] -> SE (Gui, D -> SE ())+mkLiveSceneRow :: Int -> Gui -> [Sig] -> [Ref Sig] -> SE (Gui, Sig -> SE ()) mkLiveSceneRow numBeats gMaster ids refs = do-	(guis, writes, reads) <- fmap unzip3 $ mapM (unSinkSource . flip setToggleSig False) names+	(guis, writes, reads) <- fmap unzip3 $ mapM (flip setToggleSig False) names 	curRef <- newGlobalRef (0 :: Sig) 	current <- readRef curRef 	zipWithM_ (\w i -> w $ ifB (current ==* i) 1 0) writes ids-	let mkReaders bpm = zipWithM_ (\r i -> runEvt (syncBpm (sig $ bpm / int numBeats) $ snaps r) $ \x -> do+	let mkReaders bpm = zipWithM_ (\r i -> runEvt (syncBpm (bpm / sig (int numBeats)) $ snaps r) $ \x -> do 		when1 (sig x ==* 0 &&* current ==* i) $ do 			writeRef curRef 0 			mapM_ (flip writeRef 0) refs@@ -221,14 +221,14 @@ -- between dry and wet signals. liveEf :: Int -> [String] -> [Sam] -> (Double, Fx2) -> [(Double, Fx2)] -> Source Sam liveEf numBeats names sams masterEff effs = source $ do-	(gVols, vols) <- fmap unzip $  mapM (unSource . defSlider) $ replicate n "vol"+	(gVols, vols) <- fmap unzip $  mapM defSlider $ replicate n "vol" 	(gEffs, effCtrls) <- fmap unzip $-		mapM (\(tag, initVal) -> unSource $ slider tag (linSpan 0 1) initVal) $ zip (replicate n "eff") (fmap fst effs)+		mapM (\(tag, initVal) -> slider tag (linSpan 0 1) initVal) $ zip (replicate n "eff") (fmap fst effs) 	let gCtrls = zipWith ctrlGui gEffs gVols-	(gs, xs) <- fmap unzip $ zipWithM (\a b -> unSource $ mkLiveRow numBeats a b) (zip names gCtrls) rows+	(gs, xs) <- fmap unzip $ zipWithM (\a b -> mkLiveRow numBeats a b) (zip names gCtrls) rows 	let (sigs, refs) = unzip xs-	(gMaster, masterVol) <- unSource $ defSlider "master"-	(gMasterEff, masterEffCtrl) <- unSource $slider "eff" (linSpan 0 1) (fst masterEff)+	(gMaster, masterVol) <- defSlider "master"+	(gMasterEff, masterEffCtrl) <- slider "eff" (linSpan 0 1) (fst masterEff) 	(g, proc) <- mkLiveSceneRow numBeats (ctrlGui gMasterEff gMaster) ids refs 	return $ (hor $ g : gs, bindBpm (\bpm asig -> proc bpm >> return asig) $ 		mul masterVol $ appEff (snd  masterEff) masterEffCtrl $@@ -250,18 +250,18 @@ -- | Creates fx-unit from sampler widget. -- -- > uisam name isOn bpm samWidget-uiSam :: String -> Bool -> D -> Source Sam -> Source Fx2+uiSam :: String -> Bool -> Sig -> Source Sam -> Source Fx2 uiSam name onOff bpm sam = uiSig name onOff (joinSource $ mapSource (runSam bpm) sam) 	where 		joinSource :: Source (SE Sig2) -> Source Sig2 		joinSource a = source $ do-			(g, mres) <- unSource a+			(g, mres) <- a 			res <- mres 			return (g, res)  -- | Adds gain slider on top of the widget. addGain :: SigSpace a => Source a -> Source a addGain x = source $ do-	(g, asig) <- unSource x-	(gainGui, gain) <- unSource $ slider "gain" (linSpan 0 1) 0.5+	(g, asig) <- x+	(gainGui, gain) <- slider "gain" (linSpan 0 1) 0.5 	return (ver [sca 0.15 gainGui, g], mul gain asig)