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

Derive.Scale

Description

Scale is actually defined in Derive.Deriver.Monad to avoid circular imports. But you should refer to it from here.

The difference between this and Derive.Scale.Scales is that this is intended for using scales, while Scales is intended for implementing them.

Synopsis

# Documentation

The number of chromatic intervals between each Pitch.PitchClass, starting from 0, as returned by scale_read. The length is the number of degrees per octave. A diatonic-only scale will have all 1s, and a scale without octaves has an empty layout.

This is analogous to Layout, but is intended to be a minimal implementation that all scales can export, without having to support the full complexity of a chromatic scale.

Combined with scale_read and scale_show, I can use this to do math on scale degrees.

Constructors

 Chromatic Diatonic
Instances
 # Instance detailsDefined in Derive.Deriver.Monad MethodsshowList :: [Transposition] -> ShowS #

newtype LookupScale Source #

A scale can configure itself by looking in the environment and by looking up other scales.

Constructors

 LookupScale (BaseTypes.Environ -> Pitch.ScaleId -> Maybe (Either BaseTypes.PitchError Scale))
Instances
 # Instance detailsDefined in Derive.Deriver.Monad MethodsshowList :: [LookupScale] -> ShowS #

data Scale Source #

Constructors

 Scale Fieldsscale_id :: !Pitch.ScaleId scale_pattern :: !TextA pattern describing what the scale notes look like. Used only for error msgs (i.e. parse errors) so it should be human readable and doesn't have to follow any particular syntax. A regex is recommended though.scale_symbols :: ![Symbol]If a scale uses Symbols, it can include the definitions here so they are close to their use. This symbol list should be loaded as soon as possible, which means program startup for hardcoded scales.scale_transposers :: !(Set Control)The controls that will casue a pitch from this scale to change. This is used by PSignal.apply_controls to know when to reevaluate a given pitch. Other controls can affect the pitch, but if they aren't in this set, the pitch won't be reevaluated when they change.scale_read :: BaseTypes.Environ -> Pitch.Note -> Either BaseTypes.PitchError Pitch.PitchParse a Note into a Pitch.Pitch with scale degree and accidentals.scale_show :: BaseTypes.Environ -> Pitch.Pitch -> Either BaseTypes.PitchError Pitch.Note scale_bottom :: !Pitch.PitchBottom pitch of the scale, if there is one. You can find the top pitch by transposing until you get OutOfRange. TODO that's a dumb way, if I explicitly need the top I should just add it.scale_layout :: !LayoutIf a scale has a Layout, cmds can do math with Pitch.Pitches.scale_transpose :: !Transpose scale_enharmonics :: !Enharmonics scale_note_to_call :: !(Pitch.Note -> Maybe ValCall)Used by derivation.scale_input_to_note :: !(BaseTypes.Environ -> Pitch.Input -> Either BaseTypes.PitchError Pitch.Note)Used by note input.scale_input_to_nn :: !(ScoreTime -> Pitch.Input -> Deriver (Either BaseTypes.PitchError Pitch.NoteNumber))Used by MIDI thru. This is a shortcut for eval . note_to_call . input_to_note but can often be implemented more efficiently by the scale.The ScoreTime is the time at which this pitch is evaluated. If it depends on a control, it can get the control from Dynamic, but it needs to know at what point in time to look at the signal.This is because pitch val calls aren't evaluated in normalized time. If controls had (shift, stretch) I could normalize them efficiently and the pitch would just always look at time 0. But they don't.scale_call_doc :: !DocumentedCallDocumentation for all of the ValCalls that scale_note_to_call can return.
Instances
 # Instance detailsDefined in Derive.Deriver.Monad MethodsformatList :: [Scale] -> Doc Source #

data Range Source #

This is an inclusive pitch range, intended for instrument ranges.

Constructors

 Range Fields
Instances
 # Instance detailsDefined in Derive.Scale MethodsshowsPrec :: Int -> Range -> ShowS #show :: Range -> String #showList :: [Range] -> ShowS # # Instance detailsDefined in Derive.Scale MethodsformatList :: [Range] -> Doc Source #

I would much rather pass a more specific value than Environ. Unfortunately, ChromaticScales.SemisToNoteNumber needs a per-scale value (e.g. Environ.key or Environ.tuning). So pitch_nn needs to be parameterized with a "get_key" function, but it also needs Environ.key. I think it's doable by parameterizing pitch_nn and hence note_to_call and moving smap_semis_to_nn into note_to_call, but it seems complicated.

Constructors

 Make !Pitch.ScaleId !(Text, DocumentedCall) !(BaseTypes.Environ -> LookupScale -> Either BaseTypes.PitchError Scale) Fancy scales can configure themselves. Since you can't just look at the Scale directly, it has the ScaleId (pattern, doc) extracted. Simple !Scale

Number of chromatic steps in an octave. Nothing if this scale doesn't have octaves.

Number of diatonic steps in an octave. Nothing if this scale doesn't have octaves. This is the same as semis_per_octave for scales without a diatonic/chromatic distinction.

Return the pitches in the scale. If the scale has an unbounded range, this may go on forever, so zip with note_numbers if you want the usable range. Also, not all scales actually have defined degrees.

Return the notes in the scale. As with pitches, it may be unbounded.

Return pitches of the scale's degrees.

Make a patch scale from the NoteNumbers.

assign_keys :: Int -> [Pitch.NoteNumber] -> [(Int, Pitch.NoteNumber)] Source #

Try to assign MIDI keys that correspond to the NoteNumbers, but they won't line up if there are too many NoteNumbers.