csound-expression-typed 0.2.2.0 → 0.2.3.1
raw patch · 10 files changed
+677/−6 lines, 10 filesdep ~basedep ~csound-expression-dynamicPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: base, csound-expression-dynamic
API changes (from Hackage documentation)
+ Csound.Typed.Plugins: ambiRow :: Arr1 Str -> Sig -> Sig -> D -> Sig2
+ Csound.Typed.Plugins: ambiRowMp3 :: Arr1 Str -> Sig -> Sig -> D -> Sig2
+ Csound.Typed.Plugins: liveRow :: D -> TabList -> D -> D -> Sig -> Tab -> Sig
+ Csound.Typed.Plugins: liveRows :: D -> TabList -> TabList -> D -> D -> Sig -> Tab -> Sig2
+ Csound.Typed.Types.Evt: instance GHC.Base.Semigroup (Csound.Typed.Types.Evt.Evt a)
+ Csound.Typed.Types.Evt: type family Snap a :: *
+ Csound.Typed.Types.Prim: instance GHC.Base.Semigroup Csound.Typed.Types.Prim.D
+ Csound.Typed.Types.Prim: instance GHC.Base.Semigroup Csound.Typed.Types.Prim.Sig
+ Csound.Typed.Types.Prim: instance GHC.Base.Semigroup Csound.Typed.Types.Prim.Unit
- Csound.Typed.Control: SfId :: (GE E) -> Sf
+ Csound.Typed.Control: SfId :: GE E -> Sf
- Csound.Typed.Control: data LocalHistory :: *
+ Csound.Typed.Control: data LocalHistory
- Csound.Typed.Control: forColumnArr :: (Tuple a) => Sig -> Arr Sig2 a -> ((Sig, a) -> SE ()) -> SE ()
+ Csound.Typed.Control: forColumnArr :: Tuple a => Sig -> Arr Sig2 a -> ((Sig, a) -> SE ()) -> SE ()
- Csound.Typed.Control: forRowArr :: (Tuple a) => Sig -> Arr Sig2 a -> ((Sig, a) -> SE ()) -> SE ()
+ Csound.Typed.Control: forRowArr :: Tuple a => Sig -> Arr Sig2 a -> ((Sig, a) -> SE ()) -> SE ()
- Csound.Typed.Control: mix :: (Sigs a) => Sco (Mix a) -> a
+ Csound.Typed.Control: mix :: Sigs a => Sco (Mix a) -> a
- Csound.Typed.Control: mixBy :: (Arg a, Sigs b) => (a -> Sco (Mix b)) -> (a -> b)
+ Csound.Typed.Control: mixBy :: (Arg a, Sigs b) => (a -> Sco (Mix b)) -> a -> b
- Csound.Typed.Control: mixBy_ :: (Arg a) => (a -> Sco (Mix Unit)) -> (a -> SE ())
+ Csound.Typed.Control: mixBy_ :: Arg a => (a -> Sco (Mix Unit)) -> a -> SE ()
- Csound.Typed.Control: newInstr :: (Arg a) => (a -> SE ()) -> SE (InstrRef a)
+ Csound.Typed.Control: newInstr :: Arg a => (a -> SE ()) -> SE (InstrRef a)
- Csound.Typed.Control: noteOn :: (Arg a) => D -> D -> InstrRef a -> a -> SE ()
+ Csound.Typed.Control: noteOn :: Arg a => D -> D -> InstrRef a -> a -> SE ()
- Csound.Typed.Control: schedBy :: (Arg a, Sigs b, Arg c) => (a -> SE b) -> (c -> Evt (Sco a)) -> (c -> b)
+ Csound.Typed.Control: schedBy :: (Arg a, Sigs b, Arg c) => (a -> SE b) -> (c -> Evt (Sco a)) -> c -> b
- Csound.Typed.Control: schedHarpBy :: (Arg a, Sigs b, Arg c) => D -> (a -> SE b) -> (c -> Evt [a]) -> (c -> b)
+ Csound.Typed.Control: schedHarpBy :: (Arg a, Sigs b, Arg c) => D -> (a -> SE b) -> (c -> Evt [a]) -> c -> b
- Csound.Typed.Control: sched_ :: (Arg a) => (a -> SE ()) -> Evt (Sco a) -> SE ()
+ Csound.Typed.Control: sched_ :: Arg a => (a -> SE ()) -> Evt (Sco a) -> SE ()
- Csound.Typed.Control: scheduleEvent :: (Arg a) => InstrRef a -> D -> D -> a -> SE ()
+ Csound.Typed.Control: scheduleEvent :: Arg a => InstrRef a -> D -> D -> a -> SE ()
- Csound.Typed.Control: sco_ :: (Arg a) => (a -> SE ()) -> Sco a -> Sco (Mix Unit)
+ Csound.Typed.Control: sco_ :: Arg a => (a -> SE ()) -> Sco a -> Sco (Mix Unit)
- Csound.Typed.Gui: Count :: ValDiap -> ValStep -> (Maybe ValStep) -> Elem
+ Csound.Typed.Gui: Count :: ValDiap -> ValStep -> Maybe ValStep -> Elem
- Csound.Typed.Gui: ThreeD :: (Maybe Int) -> KnobType
+ Csound.Typed.Gui: ThreeD :: Maybe Int -> KnobType
- Csound.Typed.Types.Evt: accumE :: (Tuple s) => s -> (a -> s -> (b, s)) -> Evt a -> Evt b
+ Csound.Typed.Types.Evt: accumE :: Tuple s => s -> (a -> s -> (b, s)) -> Evt a -> Evt b
- Csound.Typed.Types.Evt: accumSE :: (Tuple s) => s -> (a -> s -> SE (b, s)) -> Evt a -> Evt b
+ Csound.Typed.Types.Evt: accumSE :: Tuple s => s -> (a -> s -> SE (b, s)) -> Evt a -> Evt b
- Csound.Typed.Types.Evt: filterAccumE :: (Tuple s) => s -> (a -> s -> (BoolD, b, s)) -> Evt a -> Evt b
+ Csound.Typed.Types.Evt: filterAccumE :: Tuple s => s -> (a -> s -> (BoolD, b, s)) -> Evt a -> Evt b
- Csound.Typed.Types.Evt: filterAccumSE :: (Tuple s) => s -> (a -> s -> SE (BoolD, b, s)) -> Evt a -> Evt b
+ Csound.Typed.Types.Evt: filterAccumSE :: Tuple s => s -> (a -> s -> SE (BoolD, b, s)) -> Evt a -> Evt b
- Csound.Typed.Types.MonoArg: adsrMonoSynt :: (MonoAdsr -> (Sig, Sig) -> a) -> (MonoArg -> a)
+ Csound.Typed.Types.MonoArg: adsrMonoSynt :: (MonoAdsr -> (Sig, Sig) -> a) -> MonoArg -> a
- Csound.Typed.Types.Prim: ArgsPlain :: (Reader Int [Double]) -> TabArgs
+ Csound.Typed.Types.Prim: ArgsPlain :: Reader Int [Double] -> TabArgs
- Csound.Typed.Types.Prim: BoolD :: (GE E) -> BoolD
+ Csound.Typed.Types.Prim: BoolD :: GE E -> BoolD
- Csound.Typed.Types.Prim: BoolSig :: (GE E) -> BoolSig
+ Csound.Typed.Types.Prim: BoolSig :: GE E -> BoolSig
- Csound.Typed.Types.Prim: D :: (GE E) -> D
+ Csound.Typed.Types.Prim: D :: GE E -> D
- Csound.Typed.Types.Prim: Sig :: (GE E) -> Sig
+ Csound.Typed.Types.Prim: Sig :: GE E -> Sig
- Csound.Typed.Types.Prim: Tab :: (GE E) -> Tab
+ Csound.Typed.Types.Prim: Tab :: GE E -> Tab
- Csound.Typed.Types.Prim: frac' :: (SigOrD a) => a -> a
+ Csound.Typed.Types.Prim: frac' :: SigOrD a => a -> a
- Csound.Typed.Types.Prim: on1 :: (Val a, Val b) => (E -> E) -> (a -> b)
+ Csound.Typed.Types.Prim: on1 :: (Val a, Val b) => (E -> E) -> a -> b
- Csound.Typed.Types.Prim: on2 :: (Val a, Val b, Val c) => (E -> E -> E) -> (a -> b -> c)
+ Csound.Typed.Types.Prim: on2 :: (Val a, Val b, Val c) => (E -> E -> E) -> a -> b -> c
- Csound.Typed.Types.Prim: on3 :: (Val a, Val b, Val c, Val d) => (E -> E -> E -> E) -> (a -> b -> c -> d)
+ Csound.Typed.Types.Prim: on3 :: (Val a, Val b, Val c, Val d) => (E -> E -> E -> E) -> a -> b -> c -> d
- Csound.Typed.Types.Tuple: caseTuple :: (Tuple b) => a -> [(a -> BoolSig, b)] -> b -> b
+ Csound.Typed.Types.Tuple: caseTuple :: Tuple b => a -> [(a -> BoolSig, b)] -> b -> b
- Csound.Typed.Types.Tuple: guardedTuple :: (Tuple b) => [(BoolSig, b)] -> b -> b
+ Csound.Typed.Types.Tuple: guardedTuple :: Tuple b => [(BoolSig, b)] -> b -> b
- Csound.Typed.Types.Tuple: ifTuple :: (Tuple a) => BoolSig -> a -> a -> a
+ Csound.Typed.Types.Tuple: ifTuple :: Tuple a => BoolSig -> a -> a -> a
- Csound.Typed.Types.Tuple: makeTupleMethods :: (Tuple a) => (a -> b) -> (b -> a) -> TupleMethods b
+ Csound.Typed.Types.Tuple: makeTupleMethods :: Tuple a => (a -> b) -> (b -> a) -> TupleMethods b
Files
- csound-expression-typed.cabal +23/−3
- data/opcodes/AmbiRow.udo +68/−0
- data/opcodes/AmbiRowMp3.udo +68/−0
- data/opcodes/LiveRow.udo +215/−0
- data/opcodes/LiveRows.udo +226/−0
- src/Csound/Typed/GlobalState/Elements.hs +17/−1
- src/Csound/Typed/Plugins.hs +8/−0
- src/Csound/Typed/Plugins/AmbiRow.hs +25/−0
- src/Csound/Typed/Plugins/LiveRow.hs +25/−0
- src/Csound/Typed/Plugins/ZeroDelayConvolution.hs +2/−2
csound-expression-typed.cabal view
@@ -1,5 +1,5 @@ Name: csound-expression-typed-Version: 0.2.2.0+Version: 0.2.3.1 Cabal-Version: >= 1.22 License: BSD3 License-file: LICENSE@@ -35,6 +35,10 @@ data/opcodes/korg35.udo data/opcodes/zero-delay-convolution.udo data/opcodes/PitchShifterDelay.udo+ data/opcodes/AmbiRow.udo+ data/opcodes/AmbiRowMp3.udo+ data/opcodes/LiveRow.udo+ data/opcodes/LiveRows.udo data/opcodes/MultiFX/AnalogDelay.udo data/opcodes/MultiFX/Distortion.udo data/opcodes/MultiFX/EnvelopeFollower.udo@@ -63,8 +67,22 @@ Library Ghc-Options: -Wall Build-Depends:- base >= 4, base < 5, ghc-prim, containers, transformers >= 0.3, Boolean >= 0.1.0, colour >= 2.0, data-default, deepseq, NumInstances, filepath, directory,- wl-pprint >= 1.2.1, csound-expression-dynamic >= 0.3.3, temporal-media >= 0.6.3, hashable+ base >= 4.6,+ base < 5,+ ghc-prim,+ containers,+ transformers >= 0.3,+ Boolean >= 0.1.0,+ colour >= 2.0,+ data-default,+ deepseq,+ NumInstances,+ filepath,+ directory,+ wl-pprint >= 1.2.1,+ csound-expression-dynamic >= 0.3.5,+ temporal-media >= 0.6.3,+ hashable Hs-Source-Dirs: src/ Exposed-Modules: Csound.Typed@@ -137,6 +155,8 @@ Csound.Typed.Plugins.SolinaChorus Csound.Typed.Plugins.ZeroDelayConvolution Csound.Typed.Plugins.Iain+ Csound.Typed.Plugins.AmbiRow+ Csound.Typed.Plugins.LiveRow Csound.Typed.Plugins.Utilities Paths_csound_expression_typed
+ data/opcodes/AmbiRow.udo view
@@ -0,0 +1,68 @@+; plays wav-files in row+;+; > al, ar AmbiRow Sfiles, kSpeed, kUserIndex, iFadeTime+opcode AmbiRow, aa, S[]kki++Sfiles[], kSpeed, kUserIndex, iFadeTime xin+kNext init 0+iSize lenarray Sfiles++kEnvPoints init 0++kenv linseg 0, iFadeTime, 1, 1, 1+kUserIndex = floor(kUserIndex)+aLeft init 0+aRight init 0++kTrig changed kUserIndex+kTrigChange delayk kTrig, iFadeTime+kLoad init 1+kTrigChange = kTrigChange + kLoad++kSkipFirst linseg 1, 0.1, 1, 0.1, 0, iFadeTime + 0.1, 0, 0.1, 1+kTrigChange = kTrigChange * kSkipFirst++if (kTrig == 1) && (kNext != kUserIndex) then+ ;printks "Fade out: %d\n", 0.001, kUserIndex+ kNext = kUserIndex+ kEnvPoints = 0+ ; timout 0, iFadeTime, fade_out+ ;reinit fade_out+endif++if kTrigChange == 1 then+ ;printks "Change: %d\n", 0.001, kUserIndex+ kEnvPoints = 1+ reinit load_file+ kLoad = 0+endif++kEnv2 portk kEnvPoints, iFadeTime * 0.5++xout kEnv2 * aLeft, kEnv2 * aRight++fade_out:+ ;prints "Do fade\n", 0.001+ kenv linseg 1, iFadeTime, 0, 1, 0+ ; rireturn++load_file:+ kenv linseg 0, iFadeTime, 1, 1, 1+ ;prints "Do load: %d\n", 0.001, kNext+ iIndex = i(kNext)+ if (iIndex >= 0) && (iIndex < iSize) then+ Sfile = Sfiles[iIndex]+ iStop = 0+ else+ iStop = 1+ endif++ if iStop == 0 then+ aLeft, aRight diskin2 Sfile, kSpeed+ else+ aLeft = 0+ aRight = 0+ endif+ rireturn++endop
+ data/opcodes/AmbiRowMp3.udo view
@@ -0,0 +1,68 @@+; plays mp3-files in row+;+; > al, ar AmbiRowMp3 Sfiles, kUserIndex, iFadeTime+opcode AmbiRowMp3, aa, S[]ki++Sfiles[], kUserIndex, iFadeTime xin+kNext init 0+iSize lenarray Sfiles++kEnvPoints init 0++kenv linseg 0, iFadeTime, 1, 1, 1+kUserIndex = floor(kUserIndex)+aLeft init 0+aRight init 0++kTrig changed kUserIndex+kTrigChange delayk kTrig, iFadeTime+kLoad init 1+kTrigChange = kTrigChange + kLoad++kSkipFirst linseg 1, 0.1, 1, 0.1, 0, iFadeTime + 0.1, 0, 0.1, 1+kTrigChange = kTrigChange * kSkipFirst++if (kTrig == 1) && (kNext != kUserIndex) then+ ;printks "Fade out: %d\n", 0.001, kUserIndex+ kNext = kUserIndex+ kEnvPoints = 0+ ; timout 0, iFadeTime, fade_out+ ;reinit fade_out+endif++if kTrigChange == 1 then+ ;printks "Change: %d\n", 0.001, kUserIndex+ kEnvPoints = 1+ reinit load_file+ kLoad = 0+endif++kEnv2 portk kEnvPoints, iFadeTime * 0.5++xout kEnv2 * aLeft, kEnv2 * aRight++fade_out:+ ;prints "Do fade\n", 0.001+ kenv linseg 1, iFadeTime, 0, 1, 0+ ; rireturn++load_file:+ kenv linseg 0, iFadeTime, 1, 1, 1+ ;prints "Do load: %d\n", 0.001, kNext+ iIndex = i(kNext)+ if (iIndex >= 0) && (iIndex < iSize) then+ Sfile = Sfiles[iIndex]+ iStop = 0+ else+ iStop = 1+ endif++ if iStop == 0 then+ aLeft, aRight mp3in Sfile+ else+ aLeft = 0+ aRight = 0+ endif+ rireturn++endop
+ data/opcodes/LiveRow.udo view
@@ -0,0 +1,215 @@+; Anton Kholomiov, 2019++;+; UDO to play row of toggle clip like in Ableton Live+;+; Mono version. Toggle of audio clips syncronised with BPM.+;+; > aOut liveRow iTabSize, iTabs, iBpm, iBeatDur, kUserIndex, iAuxParams+;+; * iTabSize - how many audio clips in the row+; * iTabs - table that contains indices to tables with monophonic audio clips (loaded with GEN01)+; * iBpm - BPM of the track+; * iBeatDur - duration of the bar relative to quaters. So 4 - means 4/4, 3 means 3/4, 3.5 means 7/8 etc.+; * kUserIndex - index of the played clip, if it's out of bounds silence is played back.+;+; The clip switch happens only in even iBeatDur times. So that it's always in sync.+; It's supposed that audio clips are monophonic and aligned with specified tempo.+; So no automatic rescaling is done.+;+; Basic functionality is to switch the clips. But there are also aux-params that+; can control the length and spacing of playback.+;+; The aux-params are packed into single table. It's last parameter and we can omit it.+; The params follow by packets of 6 digits per audio-clip in the row.+;+; We can create the aux-param table with GEN02 like this+;+; > ; Aux params Size Del Tail AutoSwitch NeedRetrig Volume+; > f201 0 10 -2 1 0 1 -1 1 1+; 1 0 0 -1 0 1+;+; in the example above we can see two 5-packets sets for two audio clips.+;+; There are params:+; * Size (Int) - the size of the audio in bars+; * Delay (Int) - how many bars to skip on clip start+; * Tail delay (Int) - how many empty bara to play at the end of the clip+; * AutoSwitch (Int) - what audio-clip to switch when the current is over+; if it equals to -1 than we continue to play the current clip.+; * NeedRetrig - if we switch the clips we can continue to play from where we left out (default behaviour)+; or we can start from beginning on switch (if NeedRetrig equals 1).+; * Volume scale per audio-clip+;+opcode liveRow, a, iiiikjj+iTabSize, iTabs, iBpm, iBeatDur, kUserIndex, iAuxParams, isDebugPrint xin+kUserIndex = floor(kUserIndex)++iDur = iBeatDur / (iBpm / 60)++ii = 0+; iTabSize = ftlen(iTabs)+itTotalSteps[] init iTabSize+itTotalDurs[] init iTabSize+itTrans[] init iTabSize+itDels[] init iTabSize+itTailDels[] init iTabSize+itRetrig[] init iTabSize+itClipVolume[] init iTabSize+while ii < iTabSize do+ iTab tab_i ii, iTabs+ itCurrentFileSteps = floor((ftlen(iTab) / ftsr(iTab)) / iDur)++ if (iAuxParams < 0) then+ itTotalSteps[ii] = itCurrentFileSteps+ else+ itUserTotalSteps tab_i (ii * 6), iAuxParams+ if (itUserTotalSteps > 0) then+ itTotalSteps[ii] = itUserTotalSteps+ else+ itTotalSteps[ii] = itCurrentFileSteps+ endif+ endif++ itTotalDurs[ii] = itTotalSteps[ii] * iDur * itCurrentFileSteps / itTotalSteps[ii]++ if (iAuxParams < 0) then+ itDels[ii] = 0+ else+ itDels[ii] tab_i (ii * 6 + 1), iAuxParams+ if (itDels[ii] <= 0) then+ itDels[ii] = 0+ endif+ endif++ if (iAuxParams < 0) then+ itTailDels[ii] = 0+ else+ itTailDels[ii] tab_i (ii * 6 + 2), iAuxParams+ if (itTailDels[ii] <= 0) then+ itTailDels[ii] = 0+ endif+ endif++ if (iAuxParams < 0) then+ itTrans[ii] = ii+ else+ itTrans[ii] tab_i (ii * 6 + 3), iAuxParams+ if (itTrans[ii] < 0) then+ itTrans[ii] = ii+ endif+ endif++ if (iAuxParams < 0) then+ itRetrig[ii] = ii+ else+ itRetrig[ii] tab_i (ii * 6 + 4), iAuxParams+ if (itRetrig[ii] < 0) then+ itRetrig[ii] = 0+ endif+ endif++ if (iAuxParams < 0) then+ itClipVolume[ii] = 1+ else+ itClipVolume[ii] tab_i (ii * 6 + 5), iAuxParams+ if (itClipVolume[ii] < 0) then+ itClipVolume[ii] = 1+ endif+ endif+++ ii = ii + 1+od+++ki init 0+iInitTab tab_i 0, iTabs+iInitDur = itTotalDurs[0]+kTab init iInitTab+kTotalDur init iInitDur+kStart init 0+kDel init 0+kLim init 0+kClipVolume init 1+kStarts[] init iTabSize+kTrans[] init iTabSize+kStop init 0+ktTotalSteps[] init iTabSize+ktTotalDurs[] init iTabSize+ktDels[] init iTabSize+ktTailDels[] init iTabSize+ktRetrig[] init iTabSize+ktClipVolume[] init iTabSize+while ki < iTabSize do+ kStarts[ki] = 0+ kTrans[ki] = itTrans[ki]+ ktRetrig[ki] = itRetrig[ki]+ ktDels[ki] = itDels[ki]+ ktTailDels[ki] = itTailDels[ki]+ ktTotalSteps[ki] = itTotalSteps[ki] + ktDels[ki] + ktTailDels[ki]+ ktTotalDurs[ki] = itTotalDurs[ki]+ ktClipVolume[ki] = itClipVolume[ki]+ ki = ki + 1+od++aNdx phasor (1 / iDur)+aNdx = iDur * aNdx++kIndex init 0+kTrigIndex changed kUserIndex+if (kTrigIndex == 1) then+ if (kUserIndex != kIndex) then+ kIndex = kUserIndex++ ; should we retriger audio clip from the start or continue (default: continue)+ if ktRetrig[kIndex] == 1 then+ kStarts[kIndex] = 0+ endif+ endif+endif+++kTrig metro (1 / iDur)+if (kTrig == 1) then+ if kIndex >= 0 && kIndex <= (iTabSize - 1) then+ kStop = 0+ kTabNext tab kIndex, iTabs+ kStart = kStarts[kIndex]+ kDel = ktDels[kIndex]+ kLim = ktTotalSteps[kIndex] - ktTailDels[kIndex]+ kTotalDur = ktTotalDurs[kIndex]+ kClipVolume = ktClipVolume[kIndex]++ if (isDebugPrint > 0) then+ printks "kTab %d\n", 0, kTab+ printks "kTabNext %d\n", 0, kTabNext+ printks "kStart %d\n", 0, kStart+ printks "kLim %d\n", 0, (ktTotalSteps[kIndex] - 1)+ printks "kTotalDur %f\n", 0, kTotalDur+ printks "kDel %f\n", 0, kDel+ endif++ if (kStart == ktTotalSteps[kIndex] - 1) then+ kStarts[kIndex] = 0+ kIndex = kTrans[kIndex]+ else+ kStarts[kIndex] = (kStarts[kIndex] + 1) % ktTotalSteps[kIndex]+ endif+ kTab = kTabNext+ else+ kStop = 1+ endif+endif++kFadeEnv loopseg (1 / iDur), kTrig, 0, 1, 0.99, 1, 0.01, 0++if (kStop == 0 && kStart >= kDel && kStart < kLim) then+ aRes tableikt ((kStart - kDel) * iDur + aNdx) / kTotalDur, kTab, 1+ aRes = aRes * kClipVolume * kFadeEnv+else+ aRes = 0+endif++xout aRes+endop
+ data/opcodes/LiveRows.udo view
@@ -0,0 +1,226 @@+; Anton Kholomiov, 2019++; UDO to play row of toggle clip like in Ableton Live+;+; Stere version of liveRow. Toggle of stereo-audio clips syncronised with BPM.+;+; > aOut liveRows iTabSize, iLeftTabs, iRightTabs, iBpm, iBeatDur, kUserIndex, iAuxParams+;+; * iTabSize - how many audio clips in the row+; * iLeftTabs, iRightTabs - tables that contains indices to left and right channels+; of tables with monophonic audio clips (loaded with GEN01). Supposed that we load specific channels with GEN01.+; * iBpm - BPM of the track+; * iBeatDur - duration of the bar relative to quaters. So 4 - means 4/4, 3 means 3/4, 3.5 means 7/8 etc.+; * kUserIndex - index of the played clip, if it's out of bounds silence is played back.+;+; The clip switch happens only in even iBeatDur times. So that it's always in sync.+; It's supposed that audio clips of right and left channels are taken from single+; stereo source so they have the same length and they are aligned with specified tempo.+; So no automatic rescaling is done.+;+; Basic functionality is to switch the clips. But there are also aux-params that+; can control the length and spacing of playback.+;+; The aux-params are packed into single table. It's last parameter and we can omit it.+; The params follow by packets of 6 digits per audio-clip in the row.+;+; We can create the aux-param table with GEN02 like this+;+; > ; Aux params Size Del Tail AutoSwitch NeedRetrig Volume+; > f201 0 10 -2 1 0 1 -1 1 1+; 1 0 0 -1 0 1+;+; in the example above we can see two 5-packets sets for two audio clips.+;+; There are params:+; * Size (Int) - the size of the audio in bars+; * Delay (Int) - how many bars to skip on clip start+; * Tail delay (Int) - how many empty bara to play at the end of the clip+; * AutoSwitch (Int) - what audio-clip to switch when the current is over+; if it equals to -1 than we continue to play the current clip.+; * NeedRetrig - if we switch the clips we can continue to play from where we left out (default behaviour)+; or we can start from beginning on switch (if NeedRetrig equals 1).+; * Volume scale per audio-clip+;+opcode liveRows, aa, iiiiikjj+iTabSize, iLeftTabs, iRightTabs, iBpm, iBeatDur, kUserIndex, iAuxParams, isDebugPrint xin+kUserIndex = floor(kUserIndex)++iDur = iBeatDur / (iBpm / 60)++ii = 0+; iTabSize = ftlen(iTabs)+itTotalSteps[] init iTabSize+itTotalDurs[] init iTabSize+itTrans[] init iTabSize+itDels[] init iTabSize+itTailDels[] init iTabSize+itRetrig[] init iTabSize+itClipVolume[] init iTabSize+while ii < iTabSize do+ iTab tab_i ii, iLeftTabs+ itCurrentFileSteps = floor((ftlen(iTab) / ftsr(iTab)) / iDur)++ if (iAuxParams < 0) then+ itTotalSteps[ii] = itCurrentFileSteps+ else+ itUserTotalSteps tab_i (ii * 6), iAuxParams+ if (itUserTotalSteps > 0) then+ itTotalSteps[ii] = itUserTotalSteps+ else+ itTotalSteps[ii] = itCurrentFileSteps+ endif+ endif++ itTotalDurs[ii] = itTotalSteps[ii] * iDur * itCurrentFileSteps / itTotalSteps[ii]++ if (iAuxParams < 0) then+ itDels[ii] = 0+ else+ itDels[ii] tab_i (ii * 6 + 1), iAuxParams+ if (itDels[ii] <= 0) then+ itDels[ii] = 0+ endif+ endif++ if (iAuxParams < 0) then+ itTailDels[ii] = 0+ else+ itTailDels[ii] tab_i (ii * 6 + 2), iAuxParams+ if (itTailDels[ii] <= 0) then+ itTailDels[ii] = 0+ endif+ endif++ if (iAuxParams < 0) then+ itTrans[ii] = ii+ else+ itTrans[ii] tab_i (ii * 6 + 3), iAuxParams+ if (itTrans[ii] < 0) then+ itTrans[ii] = ii+ endif+ endif++ if (iAuxParams < 0) then+ itRetrig[ii] = ii+ else+ itRetrig[ii] tab_i (ii * 6 + 4), iAuxParams+ if (itRetrig[ii] < 0) then+ itRetrig[ii] = 0+ endif+ endif++ if (iAuxParams < 0) then+ itClipVolume[ii] = 1+ else+ itClipVolume[ii] tab_i (ii * 6 + 5), iAuxParams+ if (itClipVolume[ii] < 0) then+ itClipVolume[ii] = 1+ endif+ endif+++ ii = ii + 1+od++ki init 0+iLeftInitTab tab_i 0, iLeftTabs+iRightInitTab tab_i 0, iRightTabs+iInitDur = itTotalDurs[0]+kLeftTab init iLeftInitTab+kRightTab init iRightInitTab+kTotalDur init iInitDur+kStart init 0+kDel init 0+kLim init 0+kClipVolume init 1+kStarts[] init iTabSize+kTrans[] init iTabSize+kStop init 0+ktTotalSteps[] init iTabSize+ktTotalDurs[] init iTabSize+ktDels[] init iTabSize+ktTailDels[] init iTabSize+ktRetrig[] init iTabSize+ktClipVolume[] init iTabSize+while ki < iTabSize do+ kStarts[ki] = 0+ kTrans[ki] = itTrans[ki]+ ktRetrig[ki] = itRetrig[ki]+ ktClipVolume[ki] = itClipVolume[ki]+ ktDels[ki] = itDels[ki]+ ktTailDels[ki] = itTailDels[ki]+ ktTotalSteps[ki] = itTotalSteps[ki] + ktDels[ki] + ktTailDels[ki]+ ktTotalDurs[ki] = itTotalDurs[ki]+ ki = ki + 1+od++aNdx phasor (1 / iDur)+aNdx = iDur * aNdx++kIndex init 0+kTrigIndex changed kUserIndex+if (kTrigIndex == 1) then+ if (kUserIndex != kIndex) then+ kIndex = kUserIndex++ ; should we retriger audio clip from the start or continue (default: continue)+ if ktRetrig[kIndex] == 1 then+ kStarts[kIndex] = 0+ endif+ endif+endif+++kTrig metro (1 / iDur)+if (kTrig == 1) then+ if kIndex >= 0 && kIndex <= (iTabSize - 1) then+ kStop = 0+ kLeftTabNext tab kIndex, iLeftTabs+ kRightTabNext tab kIndex, iRightTabs+ kStart = kStarts[kIndex]+ kDel = ktDels[kIndex]+ kLim = ktTotalSteps[kIndex] - ktTailDels[kIndex]+ kTotalDur = ktTotalDurs[kIndex]+ kClipVolume = ktClipVolume[kIndex]++ if (isDebugPrint > 0) then+ printks "kTabLeft %d\n", 0, kLeftTab+ printks "kTabright %d\n", 0, kRightTab+ printks "kLeftTabNext %d\n", 0, kLeftTabNext+ printks "kRightTabNext %d\n", 0, kRightTabNext+ printks "kStart %d\n", 0, kStart+ printks "kLim %d\n", 0, (ktTotalSteps[kIndex] - 1)+ printks "kTotalDur %f\n", 0, kTotalDur+ printks "kDel %f\n", 0, kDel+ endif++ if (kStart == ktTotalSteps[kIndex] - 1) then+ kStarts[kIndex] = 0+ kIndex = kTrans[kIndex]+ else+ kStarts[kIndex] = (kStarts[kIndex] + 1) % ktTotalSteps[kIndex]+ endif+ kLeftTab = kLeftTabNext+ kRightTab = kRightTabNext+ else+ kStop = 1+ endif+endif++kFadeEnv loopseg (1 / iDur), kTrig, 0, 1, 0.99, 1, 0.01, 0++if (kStop == 0 && kStart >= kDel && kStart < kLim) then+ aPtr = ((kStart - kDel) * iDur + aNdx) / kTotalDur+ aLeft tableikt aPtr, kLeftTab, 1+ aRight tableikt aPtr, kRightTab, 1++ aLeft = aLeft * kClipVolume * kFadeEnv+ aRight = aRight * kClipVolume * kFadeEnv+else+ aLeft = 0+ aRight = 0+endif++xout aLeft, aRight+endop
src/Csound/Typed/GlobalState/Elements.hs view
@@ -44,6 +44,8 @@ ringModulatorPlugin, stChorusPlugin, stereoPingPongDelayPlugin, tapeEchoPlugin, delay1kPlugin,+ liveRowPlugin, liveRowsPlugin,+ ambiRowPlugin, ambiRowMp3Plugin ) where import Data.List@@ -96,8 +98,15 @@ newTabOfGens :: [Gen] -> State GenMap Int newTabOfGens = (saveGenId . intTab =<<) . mapM saveGenId- where intTab ns = Gen (length ns) (IntGenId (-2)) (fmap fromIntegral ns) Nothing+ where intTab ns = Gen (nextPowOfTwo $ length ns) (IntGenId (-2)) (fmap fromIntegral ns) Nothing +nextPowOfTwo :: Int -> Int+nextPowOfTwo n+ | frac == 0 = n+ | otherwise = 2 ^ (integ + 1)+ where+ (integ, frac) = properFraction $ logBase 2 (fromIntegral n)+ saveGenId :: Ord a => a -> State (IdMap a) Int saveGenId a = state $ \s -> case M.lookup a (idMapContent s) of@@ -602,3 +611,10 @@ tapeEchoPlugin = UdoPlugin "MultiFX/TapeEcho" delay1kPlugin = UdoPlugin "Utility/Delay1k"++liveRowPlugin = UdoPlugin "LiveRow" -- live like trigger, mono+liveRowsPlugin = UdoPlugin "LiveRows" -- stereo++ambiRowPlugin = UdoPlugin "AmbiRow" -- ambi trigger, wav+ambiRowMp3Plugin = UdoPlugin "AmbiRowMp3" -- mp3+
src/Csound/Typed/Plugins.hs view
@@ -39,6 +39,12 @@ -- * Tape echo tapeRead, tapeWrite, tapeEcho, + -- * Live row+ liveRow, liveRows,++ -- * Ambi row+ ambiRow, ambiRowMp3,+ -- utilities delay1k @@ -52,5 +58,7 @@ import Csound.Typed.Plugins.SolinaChorus import Csound.Typed.Plugins.ZeroDelayConvolution import Csound.Typed.Plugins.Iain+import Csound.Typed.Plugins.AmbiRow+import Csound.Typed.Plugins.LiveRow import Csound.Typed.Plugins.TapeEcho import Csound.Typed.Plugins.Utilities
+ src/Csound/Typed/Plugins/AmbiRow.hs view
@@ -0,0 +1,25 @@+module Csound.Typed.Plugins.AmbiRow(+ ambiRow, ambiRowMp3+) where++import Control.Monad.Trans.Class+import Control.Applicative++import Csound.Dynamic++import Csound.Typed.Types+import Csound.Typed.GlobalState+import qualified Csound.Typed.GlobalState.Elements as E(ambiRowPlugin, ambiRowMp3Plugin)++ambiRow :: Arr1 Str -> Sig -> Sig -> D -> Sig2+ambiRow (Arr sFiles) kSpeed kIndex iFadeTime = toTuple $ fmap ($ 2) $ do+ addUdoPlugin E.ambiRowPlugin+ f sFiles <$> toGE kSpeed <*> toGE kIndex <*> toGE iFadeTime+ where f sFiles kSpeed kIndex iFadeTime = mopcs "AmbiRow" ([Ar, Ar], [Sr, Kr, Kr, Ir]) [inlineVar $ head sFiles, kSpeed, kIndex, iFadeTime]++ambiRowMp3 :: Arr1 Str -> Sig -> Sig -> D -> Sig2+ambiRowMp3 (Arr sFiles) kSpeed kIndex iFadeTime = toTuple $ fmap ($ 2) $ do+ addUdoPlugin E.ambiRowMp3Plugin+ f sFiles <$> toGE kSpeed <*> toGE kIndex <*> toGE iFadeTime+ where f sFiles kSpeed kIndex iFadeTime = mopcs "AmbiRowMp3" ([Ar, Ar], [Sr, Kr, Kr, Ir]) [inlineVar $ head sFiles, kSpeed, kIndex, iFadeTime]+
+ src/Csound/Typed/Plugins/LiveRow.hs view
@@ -0,0 +1,25 @@+module Csound.Typed.Plugins.LiveRow(+ liveRow,+ liveRows+) where++import Control.Monad.Trans.Class+import Control.Applicative++import Csound.Dynamic++import Csound.Typed.Types+import Csound.Typed.GlobalState+import qualified Csound.Typed.GlobalState.Elements as E(liveRowPlugin, liveRowsPlugin)++liveRow :: D -> TabList -> D -> D -> Sig -> Tab -> Sig+liveRow iTabSize iTabs iBpm iBeatDur kUserIndex iAuxParams = fromGE $ do+ addUdoPlugin E.liveRowPlugin+ f <$> toGE iTabSize <*> toGE iTabs <*> toGE iBpm <*> toGE iBeatDur <*> toGE kUserIndex <*> toGE iAuxParams+ where f iTabSize iTabs iBpm iBeatDur kUserIndex iAuxParams = opcs "liveRow" [(Ar, [Ir, Ir, Ir, Ir, Kr, Ir])] [iTabSize, iTabs, iBpm, iBeatDur, kUserIndex, iAuxParams]++liveRows :: D -> TabList -> TabList -> D -> D -> Sig -> Tab -> Sig2+liveRows iTabSize iLeftTabs iRightTabs iBpm iBeatDur kUserIndex iAuxParams = toTuple $ fmap ($ 2) $ do+ addUdoPlugin E.liveRowsPlugin+ f <$> toGE iTabSize <*> toGE iLeftTabs <*> toGE iRightTabs <*> toGE iBpm <*> toGE iBeatDur <*> toGE kUserIndex <*> toGE iAuxParams+ where f iTabSize iLeftTabs iRightTabs iBpm iBeatDur kUserIndex iAuxParams = mopcs "liveRows" ([Ar, Ar], [Ir, Ir, Ir, Ir, Ir, Kr, Ir]) [iTabSize, iLeftTabs, iRightTabs, iBpm, iBeatDur, kUserIndex, iAuxParams]
src/Csound/Typed/Plugins/ZeroDelayConvolution.hs view
@@ -1,4 +1,4 @@-module Csound.Typed.Plugins.ZeroDelayConvolution( +module Csound.Typed.Plugins.ZeroDelayConvolution( ZConvSpec(..), zconv, zconv' ) where @@ -33,7 +33,7 @@ zconv = zconv' def -- | zero delay convolution.--- +-- -- > zconv' (ZConvSpec ipart irat inp) ifn ain -- -- Original UDO code by Victor Lazzarini.