Karya, built on Mon Jul 24 11:39:07 PDT 2017 (patch 33511aca01257b76b88de7c7a2763b7a965c084e)

Safe Haskell None

Derive.Score

Description

This has the basic data structures for the deriver level.

The events here are generated from UI Events, and will eventually be transformed into Perform Events, which are specific to the performance backend.

Synopsis

# Event

data Event Source #

Constructors

 Event Fieldsevent_start :: !RealTime.RealTimeevent_start, event_duration, and event_text are the core attributes that define an event.event_duration :: !RealTime.RealTime event_text :: !Text event_untransformed_controls :: !BaseTypes.ControlMapSee NOTE [event_control_offset] for what the untransformed is about.event_untransformed_pitch :: !BaseTypes.PSignal event_untransformed_pitches :: !BaseTypes.PitchMapNamed pitch signals.event_control_offset :: !RealTime.RealTimeThis is added to the untransformed controls on acces, so you can move an event without having to move all the samples in all the controls.event_stack :: !Stack.StackKeep track of where this event originally came from. That way, if an error or warning is emitted concerning this event, its position on the UI can be highlighted.event_highlight :: !Color.Highlight event_instrument :: !ScoreTypes.Instrument event_environ :: !BaseTypes.Environ event_flags :: !Flags.FlagsFlags have their own field rather than being in event_environ, this emphasizes that they're meant to be used by calls and not from the score.event_delayed_args :: !(Map Text Dynamic.Dynamic)This has arguments passed from a call that applies an attribute to one which is meant to later realize the attribute. This happens when a call needs to be configured at the track level, but also needs some information only available later, such as the real start time or pitch of the next note. They are indexed by attribute because there may be multiple delayed calls on a single note, and the realize postproc may want to ignore some, e.g. if they are overidden by another attribute.I couldn't think of a type safe way to do this, but Dynamic should be safe enough if you use a shared type declaration in both writer and reader.event_logs :: ![Log.Msg]Keep track of interesting things that have happened to this event. Postproc transforms that alter it should prefix a note.

Instances

 # MethodsshowsPrec :: Int -> Event -> ShowS #show :: Event -> String #showList :: [Event] -> ShowS # # MethodsshowList :: [InstrumentCalls] -> ShowS # # Methodsmconcat :: [NoteDeriver] -> NoteDeriver # # Methodsrnf :: Event -> () # # MethodsformatList :: [Event] -> Doc Source # # Methods # Methods # Methods # Methodsmconcat :: [Stream Event] -> Stream Event #

Format an event in a way suitable for including inline in log messages. It's short, but hopefully enough information to identify the event in question.

Get minimum and maximum edges of the event. event_start isn't necessarily the minimum because of negative durations.

Get minimum and maximum edges of the event. event_start isn't necessarily the minimum because of negative durations.

If you use an event to create another event, call this to clear out data that shouldn't go with the copy.

Apply event_control_offset and apply environ and controls to pitches. Normally this is done by Convert, but if you want to see an event for debugging it can be nicer to see the normalized version.

Unlike Perform.Midi.Convert, this doesn't trim the controls, so it applies out-of-range transpositions.

## delayed args

put_arg :: Typeable a => Text -> a -> Event -> Event Source #

take_arg :: Typeable a => Text -> Event -> Either Text (Event, Maybe a) Source #

Find an arg in event_delayed_args, and remove it from the event if it existed. Throw an error if it existed but had an unexpected type.

## modify events

Change the start time of an event and move its controls along with it.

Set the instrument on an event, and also update its environ from the instrument. You should really rederive with the new instrument, but this way can be more convenient, if somewhat sketchy.

### control

Get a control value from the event, or Nothing if that control isn't present.

modify_dynamic :: (Signal.Y -> Signal.Y) -> Event -> Event Source #

Use this instead of modify_control_vals because it also sets EnvKey.dynamic_val.

Use this instead of set_control because it also sets EnvKey.dynamic_val.

Modify a control. If there is no existing control, the modify function gets an empty signal.

### pitch

Unlike pitch_at, the transposition has already been applied. This is because callers expect to get the actual pitch, not the pitch plus some homework to do on the pitch. If you use this pitch to emit another pitch you proabbly need the raw pitch, but so far everyone doing that is at the Derive level, not postproc, so they use Derive.pitch_at.

## warp

Convert a Signal to a Warp.

Warp a ScoreTime to a RealTime.

The warp signal is extended linearly in either direction infinitely, with its last slope, or 1:1 if there are no samples at all. Previously, the warp signal was flat before zero and after its end, which effectively made the tempo infinitely fast at those points. But that made the optimization for ScoreTypes.id_warp_signal produce inconsistent results with a warp that was linear but not not equal to id_warp_signal, which in turn led to inconsistent results from ornaments that placed notes before ScoreTime 0.

The inverse of warp_pos. I originally would fail when the RealTime doesn't occur in the Warp, but now I extend it in the same way as warp_pos. Failing caused awkwardness with events at the end of the score.

Compose two warps. Warps with id signals are optimized. This is standard right to left composition

Flatten a ScoreTypes.Warp to a Signal.Warp.

# util

Use this constructor when making a Control from user input. Literals can use the IsString instance.

Use this constructor when making a PControl from user input. Literals can use the IsString instance.

Converted into velocity or breath depending on the instrument.

Parse either a Control or PControl.