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

Cmd.Perf

Description

This module is for Cmds that want to peek into the derived score for whatever reason. Normally the flow of information goes from Cmd -> Derive -> Perform, but this module is for those cases when Cmd wants to know about the results of later stages.

Synopsis

# derive

derive_note_call :: Cmd.M m => BlockId -> TrackId -> TrackTime -> Expr.Symbol -> m (Either Text [Score.Event], [Log.Msg]) Source #

Specialized version of derive_expr for note calls with no arguments.

derive_expr :: (Cmd.M m, CallableExpr d) => BlockId -> TrackId -> TrackTime -> BaseTypes.Expr -> m (Either Text [d], [Log.Msg]) Source #

Derive an expression.

derive_at :: Cmd.M m => BlockId -> TrackId -> Deriver a -> m (Either Text a, [Log.Msg]) Source #

Run an ad-hoc derivation in the context of the given track.

get_derive_at :: Cmd.M m => BlockId -> TrackId -> Deriver a -> m a Source #

Like derive_at, but write logs and throw on a Left.

Return the NoteDeriver of a particular event on a particular track, or Nothing if the track isn't a NoteTrack.

Get the environment established by config_global_transform.

Smuggle the environ out in an event. It's annoying to require such shennanigans, rationale in NOTE [transform-without-derive-callable].

derive :: Cmd.M m => Deriver a -> m (Either Text a) Source #

A cheap quick derivation that sets up the correct initial state, but runs without the cache and throws away any logs.

# environ

type Track = (BlockId, Maybe TrackId) Source #

Functions that look in the saved Dynamic use this as a key.

If the TrackId is Nothing, take any old Dynamic found on the given block.

Get the scale in scope in a certain track on a certain block.

This tries really really hard to find a ScaleId. The reason is that pitch track entry uses it to insert pitch names, and if it gets the scale wrong it inserts bogus pitches. I can't rely on lookup_val because a new track has never been derived and thus has no Dynamic.

scale_from_titles :: Ui.M m => BlockId -> TrackId -> m (Maybe Pitch.ScaleId) Source #

Try to get a scale from the titles of the parents of the given track.

Find the instrument in scope.

lookup_val :: (Cmd.M m, Typecheck.Typecheck a) => Track -> EnvKey.Key -> m (Maybe a) Source #

Lookup value from the deriver's EnvKey at the given block and (possibly) track. See TrackDynamic for details on the limitations here.

The value is taken first from the root performance, and then the given block's performance if not present in the root performance. This is so that blocks which are not called from the root at all will still have environ values.

find_dynamic :: Cmd.M m => Track -> m (Maybe Dynamic) Source #

Try to find the Dynamic for the given block and track, first looking in the root performance, and then in the block's performance.

# infer muted tracks

Infer that instruments are muted if any of their tracks are muted. This is just a heuristic because of course a track may have multiple instruments. The only reason I do this is that muting and soloing tracks is easier than instruments since they're on the UI, and im supports only instrument mute, not track mute.

This should be in PlayUtil along with PlayUtil.muted_instruments, but can't due to using lookup_instrument and circular imports.

# default

lookup_default_environ :: (Typecheck.Typecheck a, Cmd.M m) => EnvKey.Key -> m (Maybe a) Source #

Get global defaults.

The default scale established by config_global_transform, or Config.default_scale_id if there is none.

# play

Given a block, track, and time, find the realtime at that position. If the track is Nothing, use the first track that has tempo information. This is necessary because if a track is muted it will have no tempo, but it's confusing if playing from a muted track fails.

get_realtimes :: Performance -> BlockId -> TrackId -> [ScoreTime] -> [(ScoreTime, RealTime)] Source #

Like get_realtime, but do multiple at once.

find_play_pos :: Ui.M m => Transport.InverseTempoFunction -> RealTime -> m [(ViewId, [(TrackNum, ScoreTime)])] Source #

Take a RealTime to all the ScoreTimes it corresponds to, if any.

block_pos_to_play_pos :: Ui.M m => [(BlockId, [(TrackId, ScoreTime)])] -> m [(ViewId, [(TrackNum, ScoreTime)])] Source #

Do all the annoying shuffling around to convert the deriver-oriented blocks and tracks to the view-oriented views and tracknums.

This function has to be careful to not throw on non-existent IDs, because it's called from the monitor_loop.

## find score times

sub_pos :: Cmd.M m => BlockId -> TrackId -> ScoreTime -> m [(BlockId, [(TrackId, ScoreTime)])] Source #

Give a block and score time, return the play position on sub-blocks. The block itself is filtered out of the result.