Karya, built on 2020-11-26T21:03:17 (patch 23b5be2d53a9e8e7d6136cda5aae2849abe5cded)
Safe HaskellNone

Derive.PSignal

Synopsis

Documentation

data PSignal Source #

A pitch signal is similar to a Signal.Control, except that its values are Pitches instead of plain floating point values.

Instances

Instances details
Show PSignal # 
Instance details

Defined in Derive.DeriveT

Show Builtins # 
Instance details

Defined in Derive.Deriver.Monad

Show Library # 
Instance details

Defined in Derive.Library

Semigroup PSignal # 
Instance details

Defined in Derive.DeriveT

Monoid PSignal # 
Instance details

Defined in Derive.DeriveT

NFData PSignal # 
Instance details

Defined in Derive.DeriveT

Methods

rnf :: PSignal -> () #

Pretty DeriveT.PControlRef # 
Instance details

Defined in Derive.DeriveT

Pretty PSignal # 
Instance details

Defined in Derive.DeriveT

ShowVal DeriveT.PControlRef #

There's no way to convert a pitch back into the expression that produced it, so this is the best I can do.

Similar to ShowVal DeriveT.ControlRef, there's no signal literal so I use the value at 0. A pitch can be turned into an expression, but not necessarily accurately since it doesn't take things like pitch interpolation into account.

Instance details

Defined in Derive.DeriveT

ShowVal PitchDeriver # 
Instance details

Defined in Derive.Deriver.Monad

Taggable Pitch # 
Instance details

Defined in Derive.Deriver.Monad

ToVal DeriveT.PControlRef # 
Instance details

Defined in Derive.Typecheck

Typecheck DeriveT.PControlRef # 
Instance details

Defined in Derive.Typecheck

Typecheck PitchDeriver # 
Instance details

Defined in Derive.Sig

Cacheable PSignal # 
Instance details

Defined in Derive.Cache

Semigroup (Stream PSignal) # 
Instance details

Defined in Derive.Stream

Monoid (Stream PSignal) # 
Instance details

Defined in Derive.Stream

Callable (Transformer Pitch) # 
Instance details

Defined in Derive.Deriver.Monad

Callable (Generator Pitch) # 
Instance details

Defined in Derive.Deriver.Monad

Callable (TrackCall Pitch) # 
Instance details

Defined in Derive.Deriver.Monad

ToLibrary (Transformer Pitch) # 
Instance details

Defined in Derive.Library

ToLibrary (Generator Pitch) # 
Instance details

Defined in Derive.Library

ToLibrary (TrackCall Pitch) # 
Instance details

Defined in Derive.Library

sig_scale_id :: PSignal -> Pitch.ScaleId Source #

Get the scale id of the signal.

A PSignal can contain pitches from multiple scales, though I don't think this should ever happen. But if it does, the first pitch wins.

data Scale Source #

PSignal can't take a Scale because that would be a circular import. Fortunately it only needs a few fields. However, because of the circularity, the Scale.Scale -> PSignal.Scale constructor is in Derive.Derive.

Constructors

Scale 

Fields

  • pscale_scale_id :: !Pitch.ScaleId

    It can be useful to see the scale of a pitch, e.g. to create more pitches in the same scale as an existing pitch.

  • pscale_transposers :: !(Set ScoreT.Control)

    The set of transposer signals for this scale, as documented in scale_transposers.

    They are stored here because they're needed by to_nn. I could store them separately, e.g. in the Event alongside the event_pitch, but the scale at event creation time is not guaranteed to be the same as the one when the pitch was created, so the safest thing to do is keep it with the pitch itself.

Instances

Instances details
Show Scale # 
Instance details

Defined in Derive.DeriveT

Methods

showsPrec :: Int -> Scale -> ShowS #

show :: Scale -> String #

showList :: [Scale] -> ShowS #

Pretty Scale # 
Instance details

Defined in Derive.DeriveT

construct / destruct

to_nn :: PSignal -> (Signal.NoteNumber, [(RealTime, PitchError)]) Source #

Flatten a signal to a non-transposeable Signal.NoteNumber. TODO I could probably avoid the intermediate list

unfoldr :: (state -> Maybe ((RealTime, Pitch), state)) -> state -> PSignal Source #

query

interpolate :: Segment.Interpolate Pitch Source #

A pitch interpolated a certain distance between two other pitches.

transform

apply_controls :: ControlMap -> PSignal -> PSignal Source #

Resample the signal according to the sig_transposers and apply the given controls to the signal.

Controls are added so if this is not correct for a given control then this will do the wrong thing. Transpose signals should be additive so it'll be ok as long as you only apply transposing signals and only apply the complete ControlMap once at the end (i.e. Perform.Midi.Convert).

apply_environ :: DeriveT.Environ -> PSignal -> PSignal Source #

Apply an environ to all the pitches in the signal. Unlike apply_controls, this doesn't have to resample the signal.

hacks

Pitch

type Transposed = RawPitch DeriveT.Transposed_ Source #

The transposed version of Pitch.

type Pitch = RawPitch DeriveT.Untransposed_ Source #

This is an untransposed pitch. All pitches have transposition signals from the dynamic state applied when they are converted to MIDI or whatever backend. So if I want the final concrete pitch, I have to apply the transposition signals. But if I want to emit a note with this pitch, I want the untransposed one, or the transposition will be applied twice. I use a phantom type parameter to keep them straight.

data RawPitch a Source #

A pitch is an abstract value that can generate a Pitch.NoteNumber or symbolic Pitch.Note.

Instances

Instances details
ToVal Pitch # 
Instance details

Defined in Derive.Typecheck

Typecheck Pitch # 
Instance details

Defined in Derive.Typecheck

Show (RawPitch a) # 
Instance details

Defined in Derive.DeriveT

Methods

showsPrec :: Int -> RawPitch a -> ShowS #

show :: RawPitch a -> String #

showList :: [RawPitch a] -> ShowS #

NFData (RawPitch a) #

It can't be reduced since it has lambdas, but at least this way you can easily rnf things that contain it.

Instance details

Defined in Derive.DeriveT

Methods

rnf :: RawPitch a -> () #

Pretty (RawPitch a) #

Will look like: 62.95nn,4i(*wayang)

Instance details

Defined in Derive.DeriveT

ShowVal (RawPitch a) #

Pitches have no literal syntax, but I have to print something.

Instance details

Defined in Derive.DeriveT

Methods

show_val :: RawPitch a -> Text Source #

data PitchConfig Source #

A PitchConfig is the data that can continue to influence the pitch's frequency.

Pitches are configured by controls and by an environ. The controls are for values that change over time, such as transposition or tuning. They're combined additively, which is really only appropriate for transposition. Controls are mostly applied only on conversion to the performer. TODO I don't entirely remember why. However, this leads to some trickiness because if I want to compare a pitch to an absolute NoteNumber, I need the final transposed value, but if I put it in an event it must be untransposed, or transposition will be applied twice. To avoid double. To avoid this, there's a phantom type parameter to distinguish an untransposed Pitch from a Transposed one.

The Environ is for symbolic configuration, such as key or tuning mode. Unlike controls, though, it's taken from the environ in scope when the pith is created. Otherwise, you can't evaluate a pitch with a different key by setting the environ.

symbolic_pitch :: RawPitch a -> Text Source #

This is like pretty for pitch, but just shows the symbolic note name.

data PitchError Source #

Things that can go wrong evaluating a pitch.

Constructors

UnparseableNote 
OutOfRangeError !DeriveT.OutOfRange

Note out of the scale's range. The values are transpositions from the environment, in case it was out of range because of a transposition.

Some scales have a restricted range, in which case they should throw DeriveT.out_of_range, which pitch_nn and pitch_note will annotate with the transposition signals. Other scales have unlimited range, in which case they're limited by the backend. In this case pitch_nn checks 0--127, which happens to be MIDI's limitation.

InvalidInput

Input note doesn't map to a scale note.

EnvironError !Key !(Maybe Text)

A required environ value was missing or had the wrong type or value. Nothing if the value is missing, otherwise a Text description.

ControlError !ScoreT.Control !Text

Same as EnvironError, but for control vals.

NotImplemented

The scale doesn't implement that operation.

PitchError !Text

Other kind of error.

Instances

Instances details
Eq PitchError # 
Instance details

Defined in Derive.DeriveT

Ord PitchError # 
Instance details

Defined in Derive.DeriveT

Show PitchError # 
Instance details

Defined in Derive.DeriveT

Pretty PitchError # 
Instance details

Defined in Derive.DeriveT

apply_config :: PitchConfig -> RawPitch a -> RawPitch b Source #

Apply a config to a pitch.

apply :: Map ScoreT.Control Signal.Y -> Pitch -> Transposed Source #

Apply just the controls part of a config to a pitch.

pitch_nn :: Transposed -> Either.Either PitchError Pitch.NoteNumber Source #

Usually I only want to evaluate a fully transposed pitch. Exceptions are documented by applying coerce.

pitch_note :: Transposed -> Either.Either PitchError Pitch.Note Source #

Usually I only want to evaluate a fully transposed pitch. Exceptions are documented by applying coerce.

create

constant_pitch :: Pitch.ScaleId -> Pitch.Note -> Pitch.NoteNumber -> Pitch Source #

Create a Pitch that only emits the given NoteNumber, and doesn't respond to transposition.

nn_pitch :: Pitch.NoteNumber -> Pitch Source #

Like constant_pitch, but easier to use, but uses no_scale, which means the result will be unparseable.