-- Copyright 2015 Evan Laforge
-- This program is distributed under the terms of the GNU General Public
-- License 3.0, see COPYING or http://www.gnu.org/licenses/gpl-3.0.txt

-- | Calls to deal with an entire ensemble, or miscellaneous instruments.
module Derive.C.Bali.Gong (library, make_cycle, nruk_generator) where
import qualified Data.Text as Text

import qualified Util.Doc as Doc
import qualified Util.Lists as Lists
import qualified Derive.Args as Args
import qualified Derive.C.Prelude.Trill as Trill
import qualified Derive.Call as Call
import qualified Derive.Call.ControlUtil as ControlUtil
import qualified Derive.Call.Module as Module
import qualified Derive.Call.Speed as Speed
import qualified Derive.Call.Sub as Sub
import qualified Derive.Call.SubT as SubT
import qualified Derive.Call.Tags as Tags
import qualified Derive.Derive as Derive
import qualified Derive.DeriveT as DeriveT
import qualified Derive.Eval as Eval
import qualified Derive.Expr as Expr
import qualified Derive.Flags as Flags
import qualified Derive.Library as Library
import qualified Derive.Scale as Scale
import qualified Derive.Scale.BaliScales as BaliScales
import qualified Derive.Scale.Legong as Legong
import qualified Derive.Score as Score
import qualified Derive.ScoreT as ScoreT
import qualified Derive.Sig as Sig
import qualified Derive.Typecheck as Typecheck

import qualified Perform.Pitch as Pitch
import qualified Perform.Signal as Signal
import qualified Ui.Meter.Meter as Meter
import qualified Ui.Types as Types

import           Global
import           Types


library :: Library.Library
library :: Library
library = forall a. Monoid a => [a] -> a
mconcat
    [ forall call.
ToLibrary (Generator call) =>
[(Symbol, Generator call)] -> Library
Library.generators
        [ (Symbol
"cycle", Generator Event
c_cycle)
        ]
    , forall call.
ToLibrary (Transformer call) =>
[(Symbol, Transformer call)] -> Library
Library.transformers
        [ (Symbol
"pokok", Transformer Event
c_pokok)
        , (Symbol
"J", Transformer Event
c_jegog)
        , (Symbol
"C", Transformer Event
c_calung)
        , (Symbol
"nruk", Transformer Event
c_nruk)
        ]
    ]

module_ :: Module.Module
module_ :: Module
module_ = Module
"bali" forall a. Semigroup a => a -> a -> a
<> Module
"gong"

c_pokok :: Derive.Transformer Derive.Note
c_pokok :: Transformer Event
c_pokok = forall d.
Module
-> CallName
-> Tags
-> Doc
-> WithArgDoc (TransformerF d)
-> Transformer d
Derive.transformer Module
module_ CallName
"pokok" (Tags
Tags.inst forall a. Semigroup a => a -> a -> a
<> Tags
Tags.under_invert)
    Doc
"Add a pokok note with 'Derive.Flags.infer_duration' and the same pitch,\
    \ transposed into the appropriate range."
    forall a b. (a -> b) -> a -> b
$ forall y a d.
Taggable y =>
Parser a -> (a -> Transformer y d) -> WithArgDoc (Transformer y d)
Sig.callt ((,,)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a deflt.
(Typecheck a, ToVal deflt) =>
ArgName -> deflt -> Doc -> Parser a
Sig.defaulted ArgName
"octave" UpDown
Call.Down
        Doc
"Which to choose if the pitch exists in multiple octaves."
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a.
Typecheck a =>
ArgName -> EnvironDefault -> Doc -> Parser a
Sig.required_environ ArgName
"insts" EnvironDefault
Sig.Prefixed Doc
"Instruments."
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Range
range_env
    ) forall a b. (a -> b) -> a -> b
$ \(UpDown
octave, [Instrument]
insts, Range
range) -> Transformer Event (Stream Event)
-> Transformer Event (Stream Event)
Sub.under_invert forall a b. (a -> b) -> a -> b
$ \NoteArgs
args NoteDeriver
deriver -> do
        NoteDeriver
note <- ScoreTime -> UpDown -> [Instrument] -> Range -> Deriver NoteDeriver
pokok (forall a. PassedArgs a -> ScoreTime
Args.start NoteArgs
args) UpDown
octave [Instrument]
insts Range
range
        NoteDeriver
deriver forall a. Semigroup a => a -> a -> a
<> NoteDeriver
note

pokok :: ScoreTime -> Call.UpDown -> [ScoreT.Instrument] -> Scale.Range
    -> Derive.Deriver Derive.NoteDeriver
pokok :: ScoreTime -> UpDown -> [Instrument] -> Range -> Deriver NoteDeriver
pokok ScoreTime
start UpDown
octave [Instrument]
insts Range
range = do
    (Note -> Maybe Pitch
parse_pitch, Pitch -> Maybe Note
show_pitch, Transposition -> Octave -> Pitch -> Maybe Pitch
_) <- Deriver
  (Note -> Maybe Pitch, Pitch -> Maybe Note,
   Transposition -> Octave -> Pitch -> Maybe Pitch)
Call.get_pitch_functions
    Pitch
from_pitch <- (Note -> Maybe Pitch) -> RealTime -> Deriver State Error Pitch
Call.get_parsed_pitch Note -> Maybe Pitch
parse_pitch forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. Time a => a -> Deriver RealTime
Derive.real ScoreTime
start
    Note
to_note <- forall a. HasCallStack => Text -> Maybe a -> Deriver a
Derive.require (Text
"can't show pitch: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
showt Pitch
from_pitch) forall a b. (a -> b) -> a -> b
$
        Pitch -> Maybe Note
show_pitch (Range -> UpDown -> Pitch -> Pitch
restrict Range
range UpDown
octave Pitch
from_pitch)
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ScoreTime -> [Instrument] -> Note -> NoteDeriver
realize_note ScoreTime
start [Instrument]
insts Note
to_note

-- How to choose high and low ding?
-- I should infer it based on the octave of the melody, but also be able to
-- override easily.  But to know the octave of the melody I need the melody
-- itself along with its range, which is not actually written anywhere or
-- even well defined.  So choose low and do manual for now.

-- | Transpose the pitch by octaves until it fits in the range.
-- Assumes the range is at least one octave, and less than two.
restrict :: Scale.Range -> Call.UpDown -> Pitch.Pitch -> Pitch.Pitch
restrict :: Range -> UpDown -> Pitch -> Pitch
restrict Range
range UpDown
octave Pitch
pitch
    | Range -> Pitch -> Bool
Scale.in_range Range
range Pitch
pitch = Pitch
pitch
    | Bool
otherwise = case UpDown
octave of
        UpDown
Call.Down
            | Octave -> Pitch
with_oct (Pitch -> Octave
oct_of Pitch
bottom) forall a. Ord a => a -> a -> Bool
< Pitch
bottom -> Octave -> Pitch
with_oct (Pitch -> Octave
oct_of Pitch
bottom forall a. Num a => a -> a -> a
+ Octave
1)
            | Bool
otherwise -> Octave -> Pitch
with_oct (Pitch -> Octave
oct_of Pitch
bottom)
            where bottom :: Pitch
bottom = Range -> Pitch
Scale.range_bottom Range
range
        UpDown
Call.Up
            | Octave -> Pitch
with_oct (Pitch -> Octave
oct_of Pitch
top) forall a. Ord a => a -> a -> Bool
> Pitch
top -> Octave -> Pitch
with_oct (Pitch -> Octave
oct_of Pitch
top forall a. Num a => a -> a -> a
- Octave
1)
            | Bool
otherwise -> Octave -> Pitch
with_oct (Pitch -> Octave
oct_of Pitch
top)
            where top :: Pitch
top = Range -> Pitch
Scale.range_top Range
range
    where
    with_oct :: Octave -> Pitch
with_oct Octave
oct = Pitch
pitch { pitch_octave :: Octave
Pitch.pitch_octave = Octave
oct }
    oct_of :: Pitch -> Octave
oct_of = Pitch -> Octave
Pitch.pitch_octave

realize_note :: ScoreTime -> [ScoreT.Instrument] -> Pitch.Note
    -> Derive.NoteDeriver
realize_note :: ScoreTime -> [Instrument] -> Note -> NoteDeriver
realize_note ScoreTime
start [Instrument]
instruments Note
note =
    Flags -> NoteDeriver -> NoteDeriver
Call.add_flags Flags
Flags.infer_duration forall a b. (a -> b) -> a -> b
$
        forall b a. Monoid b => (a -> b) -> [a] -> b
mconcatMap (\Instrument
inst -> forall d. Instrument -> Deriver d -> Deriver d
Derive.with_instrument Instrument
inst NoteDeriver
realize1) [Instrument]
instruments
    where
    realize1 :: NoteDeriver
realize1 = forall a. ScoreTime -> Deriver a -> Deriver a
Derive.at ScoreTime
start forall a b. (a -> b) -> a -> b
$
        Transposed -> NoteDeriver
Call.transposed_pitched_note forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ScoreTime -> Note -> Deriver Transposed
Call.eval_note ScoreTime
start Note
note

range_env :: Sig.Parser Scale.Range
range_env :: Parser Range
range_env = Pitch -> Pitch -> Range
Scale.Range
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a.
Typecheck a =>
ArgName -> EnvironDefault -> Doc -> Parser a
Sig.required_environ ArgName
"bottom" EnvironDefault
Sig.Prefixed Doc
"Bottom of the range."
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a.
Typecheck a =>
ArgName -> EnvironDefault -> Doc -> Parser a
Sig.required_environ ArgName
"top" EnvironDefault
Sig.Prefixed Doc
"Top of the range."

make_pokok :: Text -> Scale.Range -> [ScoreT.Instrument]
    -> Derive.Transformer Derive.Note
make_pokok :: Text -> Range -> [Instrument] -> Transformer Event
make_pokok Text
name Range
range [Instrument]
default_insts = forall d.
Module
-> CallName
-> Tags
-> Doc
-> WithArgDoc (TransformerF d)
-> Transformer d
Derive.transformer Module
module_
    (Text -> CallName
Derive.CallName Text
name) (Tags
Tags.inst forall a. Semigroup a => a -> a -> a
<> Tags
Tags.under_invert)
    (Doc
"Add a " forall a. Semigroup a => a -> a -> a
<> Text -> Doc
Doc.literal Text
name forall a. Semigroup a => a -> a -> a
<> Doc
" note with 'Derive.Flags.infer_duration'\
        \ and the same pitch, transposed into the " forall a. Semigroup a => a -> a -> a
<> Text -> Doc
Doc.literal Text
name
        forall a. Semigroup a => a -> a -> a
<> Doc
" range.")
    forall a b. (a -> b) -> a -> b
$ forall y a d.
Taggable y =>
Parser a -> (a -> Transformer y d) -> WithArgDoc (Transformer y d)
Sig.callt ((,)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a deflt.
(Typecheck a, ToVal deflt) =>
ArgName -> deflt -> Doc -> Parser a
Sig.defaulted ArgName
"octave" UpDown
Call.Down
        Doc
"If the pitch exists in multiple octaves, choose this one."
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a deflt.
(Typecheck a, ToVal deflt) =>
ArgName -> EnvironDefault -> deflt -> Doc -> Parser a
Sig.environ ArgName
"insts" EnvironDefault
Sig.Prefixed [Instrument]
default_insts Doc
"Instruments."
    ) forall a b. (a -> b) -> a -> b
$ \(UpDown
octave, [Instrument]
insts) -> Transformer Event (Stream Event)
-> Transformer Event (Stream Event)
Sub.under_invert forall a b. (a -> b) -> a -> b
$ \NoteArgs
args NoteDeriver
deriver -> do
        NoteDeriver
note <- ScoreTime -> UpDown -> [Instrument] -> Range -> Deriver NoteDeriver
pokok (forall a. PassedArgs a -> ScoreTime
Args.start NoteArgs
args) UpDown
octave [Instrument]
insts Range
range
        NoteDeriver
deriver forall a. Semigroup a => a -> a -> a
<> NoteDeriver
note

c_jegog :: Derive.Transformer Derive.Note
c_jegog :: Transformer Event
c_jegog = Text -> Range -> [Instrument] -> Transformer Event
make_pokok Text
"jegog" (Instrument -> Range
BaliScales.instrument_range Instrument
Legong.jegog)
    [Instrument
"jegog-p", Instrument
"jegog-s"]

c_calung :: Derive.Transformer Derive.Note
c_calung :: Transformer Event
c_calung = Text -> Range -> [Instrument] -> Transformer Event
make_pokok Text
"calung" (Instrument -> Range
BaliScales.instrument_range Instrument
Legong.calung)
    [Instrument
"calung-p", Instrument
"calung-s"]

-- * nruk tuk

c_nruk :: Derive.Transformer Derive.Note
c_nruk :: Transformer Event
c_nruk = forall d.
Module
-> CallName
-> Tags
-> Doc
-> WithArgDoc (TransformerF d)
-> Transformer d
Derive.transformer Module
module_ CallName
"nruk" Tags
Tags.inst
    Doc
"Nruktuk, for kajar or gangsa."
    forall a b. (a -> b) -> a -> b
$ forall y a d.
Taggable y =>
Parser a -> (a -> Transformer y d) -> WithArgDoc (Transformer y d)
Sig.callt Parser (Speed, Speed, Y, Duration)
nruk_args forall a.
(Speed, Speed, Y, Duration)
-> PassedArgs a -> NoteDeriver -> NoteDeriver
nruk

nruk_generator :: Module.Module -> Derive.CallName -> Doc.Doc
    -> (Derive.NoteArgs -> Derive.NoteDeriver)
    -> Derive.Generator Derive.Note
nruk_generator :: Module
-> CallName -> Doc -> (NoteArgs -> NoteDeriver) -> Generator Event
nruk_generator Module
mod CallName
name Doc
doc NoteArgs -> NoteDeriver
deriver = forall d.
Module
-> CallName
-> Tags
-> Doc
-> WithArgDoc (GeneratorF d)
-> Generator d
Derive.generator Module
mod CallName
name Tags
Tags.inst Doc
doc forall a b. (a -> b) -> a -> b
$
    forall y a d.
Taggable y =>
Parser a -> (a -> Generator y d) -> WithArgDoc (Generator y d)
Sig.call Parser (Speed, Speed, Y, Duration)
nruk_args forall a b. (a -> b) -> a -> b
$ \(Speed, Speed, Y, Duration)
params NoteArgs
args -> forall a.
(Speed, Speed, Y, Duration)
-> PassedArgs a -> NoteDeriver -> NoteDeriver
nruk (Speed, Speed, Y, Duration)
params NoteArgs
args (NoteArgs -> NoteDeriver
deriver NoteArgs
args)

nruk_args :: Sig.Parser (Speed.Speed, Speed.Speed, Signal.Y, DeriveT.Duration)
nruk_args :: Parser (Speed, Speed, Y, Duration)
nruk_args = (,,,)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a deflt.
(Typecheck a, ToVal deflt) =>
ArgName -> deflt -> Doc -> Parser a
Sig.defaulted ArgName
"start" (RealTime -> Speed
Speed.Real RealTime
4) Doc
"Start speed."
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a deflt.
(Typecheck a, ToVal deflt) =>
ArgName -> deflt -> Doc -> Parser a
Sig.defaulted ArgName
"end" (RealTime -> Speed
Speed.Real RealTime
19) Doc
"End speed."
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a deflt.
(Typecheck a, ToVal deflt) =>
ArgName -> deflt -> Doc -> Parser a
Sig.defaulted ArgName
"end-dyn" (Y
0.15 :: Double)
        Doc
"Dyn multiplier when the stroke duration reaches 0."
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Duration
Trill.hold_env

nruk :: (Speed.Speed, Speed.Speed, Signal.Y, DeriveT.Duration)
    -> Derive.PassedArgs a -> Derive.NoteDeriver -> Derive.NoteDeriver
nruk :: forall a.
(Speed, Speed, Y, Duration)
-> PassedArgs a -> NoteDeriver -> NoteDeriver
nruk (Speed
start_speed, Speed
end_speed, Y
end_dyn, Duration
hold) PassedArgs a
args NoteDeriver
deriver = do
    [ScoreTime]
starts <- CurveF
-> Duration
-> Speed
-> Speed
-> (ScoreTime, ScoreTime)
-> Deriver [ScoreTime]
Trill.tremolo_starts_curve forall {a}. a -> a
curve Duration
hold Speed
start_speed Speed
end_speed
        (forall a. PassedArgs a -> (ScoreTime, ScoreTime)
Args.range_or_next PassedArgs a
args)
    [Y]
dyns <- Y -> [RealTime] -> [Y]
dyn_from_duration Y
end_dyn forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall a. Time a => a -> Deriver RealTime
Derive.real [ScoreTime]
starts
    NoteDeriver -> [(ScoreTime, Y)] -> NoteDeriver
realize_nruk (forall a b. PassedArgs a -> Deriver b -> Deriver b
Args.normalized PassedArgs a
args NoteDeriver
deriver) (forall a b. [a] -> [b] -> [(a, b)]
zip [ScoreTime]
starts [Y]
dyns)
    where
    -- TODO it seems like it should start slower, but
    -- ControlUtil.expon 2 spends too little time fast.
    curve :: a -> a
curve = forall {a}. a -> a
id

realize_nruk :: Derive.NoteDeriver -> [(ScoreTime, Signal.Y)]
    -> Derive.NoteDeriver
realize_nruk :: NoteDeriver -> [(ScoreTime, Y)] -> NoteDeriver
realize_nruk NoteDeriver
deriver [(ScoreTime, Y)]
notes = [Event] -> NoteDeriver
Sub.derive
    [ forall a. ScoreTime -> ScoreTime -> a -> EventT a
SubT.EventT ScoreTime
start ScoreTime
0 (forall a. Y -> Deriver a -> Deriver a
Call.multiply_dynamic Y
dyn NoteDeriver
deriver)
    | (ScoreTime
start, Y
dyn) <- [(ScoreTime, Y)]
notes
    ]

-- | Decrease dyn as note duration decreases.  Over a threshold, dyn is 1.
-- Under that it approaches @low_dyn@ as the dur approaches 0.
dyn_from_duration :: Signal.Y -> [RealTime] -> [Signal.Y]
dyn_from_duration :: Y -> [RealTime] -> [Y]
dyn_from_duration Y
low_dyn = forall a b. (a -> b) -> [a] -> [b]
map RealTime -> Y
dyn_at forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Num a => [a] -> [a]
durations
    where
    dyn_at :: RealTime -> Y
dyn_at RealTime
dur
        | RealTime
dur forall a. Ord a => a -> a -> Bool
> RealTime
threshold = Y
1
        | Bool
otherwise = RealTime -> Y
f RealTime
dur
        where f :: RealTime -> Y
f = CurveF -> RealTime -> Y -> RealTime -> Y -> RealTime -> Y
ControlUtil.make_function forall {a}. a -> a
id RealTime
threshold Y
1 RealTime
0 Y
low_dyn
    -- Dyn is 1 above this.
    threshold :: RealTime
threshold = RealTime
0.18

durations :: Num a => [a] -> [a]
durations :: forall a. Num a => [a] -> [a]
durations [a]
starts = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (-) (forall a. Octave -> [a] -> [a]
drop Octave
1 [a]
starts) [a]
starts
    -- This loses the last one, but it's ok because that's the end time.

-- * cycle

c_cycle :: Derive.Generator Derive.Note
c_cycle :: Generator Event
c_cycle = CallName
-> Maybe (Either Text [Quoted])
-> Maybe (Either Rank DefaultScore)
-> Generator Event
make_cycle CallName
"cycle" forall a. Maybe a
Nothing forall a. Maybe a
Nothing

make_cycle :: Derive.CallName
    -> Maybe (Either Text [DeriveT.Quoted])
    -> Maybe (Either Meter.Rank Typecheck.DefaultScore)
    -> Derive.Generator Score.Event
make_cycle :: CallName
-> Maybe (Either Text [Quoted])
-> Maybe (Either Rank DefaultScore)
-> Generator Event
make_cycle CallName
name Maybe (Either Text [Quoted])
default_strokes Maybe (Either Rank DefaultScore)
default_dur =
    forall d.
Module
-> CallName
-> Tags
-> Doc
-> WithArgDoc (GeneratorF d)
-> Generator d
Derive.generator Module
module_ CallName
name Tags
Tags.inst
    Doc
"Cycle calls. Align to the end for negative duration."
    forall a b. (a -> b) -> a -> b
$ forall y a d.
Taggable y =>
Parser a -> (a -> Generator y d) -> WithArgDoc (Generator y d)
Sig.call ((,)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a deflt.
(Typecheck a, ToVal deflt) =>
ArgName -> Maybe deflt -> Doc -> Parser a
Sig.maybe_defaulted ArgName
"strokes" Maybe (Either Text [Quoted])
default_strokes Doc
"Cycle these strokes."
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a deflt.
(Typecheck a, ToVal deflt) =>
ArgName -> Maybe deflt -> Doc -> Parser a
Sig.maybe_defaulted ArgName
"dur" Maybe (Either Rank DefaultScore)
default_dur Doc
"Duration of each stroke.\
        \ A string is taken as a timestep."
    ) forall a b. (a -> b) -> a -> b
$ \(Either Text [Quoted]
strokes, Either Rank DefaultScore
dur) NoteArgs
args -> do
        [Quoted]
strokes <- forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Either Text [Quoted]
strokes of
            Left Text
str -> forall a b. (a -> b) -> [a] -> [b]
map (Symbol -> Quoted
DeriveT.quoted0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Symbol
Expr.Symbol forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Text
Text.singleton)
                (Text -> String
Text.unpack Text
str)
            Right [Quoted]
strs -> [Quoted]
strs
        Duration
dur <- case Either Rank DefaultScore
dur of
            Left Rank
ts -> ScoreTime -> Duration
DeriveT.ScoreDuration forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                forall a. PassedArgs a -> Rank -> Deriver ScoreTime
Call.timestep_duration NoteArgs
args Rank
ts
            Right (Typecheck.DefaultScore Duration
dur) -> forall (m :: * -> *) a. Monad m => a -> m a
return Duration
dur
        ScoreTime
dur <- forall a. Time a => a -> Deriver ScoreTime
Derive.score Duration
dur
        forall a b. PassedArgs a -> Deriver b -> Deriver b
Args.normalized_start NoteArgs
args forall a b. (a -> b) -> a -> b
$
            Context Event
-> (ScoreTime, ScoreTime)
-> Orientation
-> [Quoted]
-> ScoreTime
-> NoteDeriver
call_cycle (forall a. PassedArgs a -> Context a
Args.context NoteArgs
args) (forall a. PassedArgs a -> (ScoreTime, ScoreTime)
Args.range NoteArgs
args)
                (forall a. PassedArgs a -> Orientation
Args.orientation NoteArgs
args) [Quoted]
strokes ScoreTime
dur

call_cycle :: Derive.Context Score.Event -> (TrackTime, TrackTime)
    -> Types.Orientation -> [DeriveT.Quoted]
    -> ScoreTime -> Derive.NoteDeriver
call_cycle :: Context Event
-> (ScoreTime, ScoreTime)
-> Orientation
-> [Quoted]
-> ScoreTime
-> NoteDeriver
call_cycle Context Event
ctx (ScoreTime
start, ScoreTime
end) Orientation
orient [Quoted]
calls ScoreTime
dur =
    forall a. Monoid a => [a] -> a
mconcat [forall a. ScoreTime -> Deriver a -> Deriver a
Derive.at ScoreTime
t forall a b. (a -> b) -> a -> b
$ forall d.
CallableExpr d =>
Context d -> Quoted -> Deriver (Stream d)
Eval.eval_quoted Context Event
ctx Quoted
call | (ScoreTime
t, Quoted
call) <- [(ScoreTime, Quoted)]
ts]
    where
    ts :: [(ScoreTime, Quoted)]
ts = case Orientation
orient of
        Orientation
Types.Positive -> forall a b. [a] -> [b] -> [(a, b)]
zip (forall a. (Num a, Ord a) => a -> a -> a -> [a]
Lists.range' ScoreTime
start ScoreTime
end ScoreTime
dur) (forall a. [a] -> [a]
cycle [Quoted]
calls)
        Orientation
Types.Negative -> forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$
            forall a b. [a] -> [b] -> [(a, b)]
zip (forall a. (Num a, Ord a) => a -> a -> a -> [a]
Lists.range' ScoreTime
end ScoreTime
start (-ScoreTime
dur)) (forall a. [a] -> [a]
cycle (forall a. [a] -> [a]
reverse [Quoted]
calls))