Karya, built on 2018-05-31T02:46:59 (patch 0a1a35479c514820d77330ae8a978975ba22a47a)

Safe HaskellNone




This is the basic interface for slicing. This also includes inverting, which is a special case of slicing.



under_invert :: (NoteArgs -> NoteDeriver -> NoteDeriver) -> NoteArgs -> NoteDeriver -> NoteDeriver Source #

Cause this transformer to apply only after inversion. under_invert documents this, also see NOTE [under-invert].

Normally when a call is inverted, the transformers run outside the inversion, while only the generator runs underneath. However, some transformers rely on per-note controls, such as pitch and dyn, and therefore need to go under the invert. So this saves the transformer, and applies it only after all the inversion has happened.

If there are no sub-tracks, then inversion won't happen, and the transform is run right here. However, if there are sub-tracks, but the generator doesn't want to run, then the transform will be lost.

TODO I could probably fix it by making Eval.eval_generator apply the transform, but it would have to clear it out too to avoid evaluating more than once. Not sure which way is right.

inverting :: (PassedArgs d -> NoteDeriver) -> PassedArgs d -> NoteDeriver Source #

Convert a call into an inverting call. This is designed to be convenient to insert after the signature arg in a call definition. The args passed to the call have been stripped of their sub tracks to avoid another inversion.

inverting_args :: PassedArgs d -> (PassedArgs d -> NoteDeriver) -> NoteDeriver Source #

inverting with its arguments flipped. This is useful for calls that want to do stuff with the args before inverting. Make sure to shadow the old PassedArgs with the ones passed to the call, for the reason documented in inverting.


type Event = GenericEvent NoteDeriver Source #

Sliced sub-events are represented as a start, duration, and opaque deriver. This is a compromise between a plain NoteDeriver, which is fully abstract but also fully opaque, and some kind of note data structure, which is fully concrete (and thus inflexible), but also transparent to modification.

data GenericEvent a Source #


Functor GenericEvent # 
Instance details

Defined in Derive.Call.Sub


fmap :: (a -> b) -> GenericEvent a -> GenericEvent b #

(<$) :: a -> GenericEvent b -> GenericEvent a #

Show a => Show (GenericEvent a) # 
Instance details

Defined in Derive.Call.Sub

Pretty a => Pretty (GenericEvent a) # 
Instance details

Defined in Derive.Call.Sub

sub_events :: PassedArgs d -> Deriver [[Event]] Source #

Get the Events of subtracks, if any, returning one list of events per sub note track. This is the top-level utility for note calls that take other note calls as arguments.

sub_events_negative :: PassedArgs d -> Deriver [[Event]] Source #

Like sub_events, but exclude events at the start time, and include events at the end time. Presumably suitable for Negative calls.

assert_no_subs :: PassedArgs d -> Deriver () Source #

Throw an exception if there are sub-events.

modify_notes :: ([GenericEvent Event.Text] -> Either Text [GenericEvent Event.Text]) -> PassedArgs a -> Either Text (PassedArgs a) Source #

Modify the text of sub note tracks before deriving them. This can be used to implement an ad-hoc new language.

derive :: [Event] -> NoteDeriver Source #

Derive and merge Events.

derive_pitch :: Event -> Deriver (GenericEvent (Maybe Pitch.Note)) Source #

Get the pitch of an Event. Useful for debugging.

fit Source #


:: (ScoreTime, ScoreTime)

fit this range

-> (ScoreTime, ScoreTime)

into this range

-> [Event] 
-> NoteDeriver 

Re-fit the events from one range to another.


type RestEvent = GenericEvent (Maybe NoteDeriver) Source #

A Nothing represents a rest.

sub_rest_events Source #


:: Bool

end bias

-> Bool

if True, include the trailing gap as a rest

-> PassedArgs d 
-> Deriver [[RestEvent]] 

This is like sub_events, but gaps between the events are returned as explicit rests.


reapply :: Context Score.Event -> BaseTypes.Expr -> [[Event]] -> NoteDeriver Source #

Call a note parent with sub-events. While you can easily call other kinds of calls with Eval.reapply, note parents are more tricky because they expect a track structure in ctx_sub_tracks. This bypasses that and directly passes Events to the note parent, courtesy of ctx_sub_events.