Karya, built on 2022-03-21T01:30:44 (patch 89d1651424c35e564138d93424a157ff87457245)
Safe HaskellSafe-Inferred



Utilities for simple scales, which simply map pitch names to frequencies. Ok, so they also have octave structure, used by the input mechanism and to parse to Pitch.Pitches, but it can be set to the number of degrees in the scale if you don't have octaves.



make_scale :: Pitch.ScaleId -> DegreeMap -> Text -> Doc.Doc -> Scale Source #

Make a simple scale where there is a direct mapping from input to note to nn.

empty_scale :: Pitch.ScaleId -> Text -> DocumentedCall -> Scale Source #

An empty scale that doesn't do anything.


data DegreeMap Source #





Instances details
Show DegreeMap Source # 
Instance details

Defined in Derive.Scale.Scales

Pretty.Pretty DegreeMap Source # 
Instance details

Defined in Derive.Scale.Scales

degree_map Source #


:: Pitch.PitchClass 
-> Pitch.Octave

The first Note is this Octave and PitchClass.

-> Pitch.PitchClass 
-> [Pitch.Note] 
-> [Pitch.NoteNumber] 
-> DegreeMap 

scale functions


non_transposing :: Transpose Source #

Transpose function for a non-transposing scale.

standard_transposers :: Set ScoreT.Control Source #

Indicate that this scale responds to the standard set of transpose signals. It still has to implement the support in its scale_note_to_call.


mapped_note_to_call :: DegreeMap -> DeriveT.Scale -> Pitch.Note -> Maybe.Maybe ValCall Source #

A specialization of note_to_call that operates on scales with a DegreeMap, i.e. a static map from notes to degrees, and from degrees to NNs.

note_to_call :: Pitch.Semi -> Maybe.Maybe Pitch.Semi -> DeriveT.Scale -> SemisToNoteNumber -> (Pitch.Semi -> Maybe.Maybe Pitch.Note) -> ValCall Source #

Create a note call that respects chromatic and diatonic transposition. However, diatonic transposition is mapped to chromatic transposition, so this is for scales that don't distinguish.


input_to_note :: DegreeMap -> InputToNote Source #

Input to note for simple scales without keys.

mapped_input_to_nn :: DegreeMap -> InputToNn Source #

Input to NoteNumber for scales that have a direct relationship between Degree and NoteNumber.

direct_input_to_nn :: InputToNn Source #

An Input maps directly to a NoteNumber. This is an efficient implementation for scales tuned to 12TET.

This obeys Controls.octave but none of the other transposer controls. This is inconsistent with computed_input_to_nn, but trying to implement diatonic transposition would make this not so direct any more. And in any case, Cmd.MidiThru shouldn't let through any transposers other than octave.

computed_input_to_nn :: InputToNote -> (Pitch.Note -> Maybe.Maybe ValCall) -> InputToNn Source #

Convert input to nn by going through note_to_call. This works for complicated scales that retune based on the environment but is more work.


lookup_kbd_to_scale :: Pitch.KbdType -> Pitch.PitchClass -> Pitch.PitchClass -> Pitch.Pitch -> Maybe.Maybe Pitch.Pitch Source #

Convert an absolute Pitch in the input keyboard's layout to a relative Pitch within a scale with the given number of diatonic steps per octave, or Nothing if that key should have no pitch.

piano_kbd_pitch :: Pitch.PitchClass -> Pitch.PitchClass -> Pitch.Pitch -> Maybe.Maybe Pitch.Pitch Source #

The MIDI kbd is absolute. This means that relative scales start on different keys rather than all starting on C. For example, in C major C produces the first scale degree, while in D major D produces the first scale degree.

In addition, if the scale octave is not an even multiple of the kbd octave (7), the extra notes produce Nothing. This check has to be done to the relative PitchClass. That way, a D on a 6 note scale starting on D is 1, and a C is Nothing. Thus, the returned Pitch is relative to the given tonic, so it should be formatted as-is, without the key.

ascii_kbd_pitch :: Pitch.PitchClass -> Pitch.Pitch -> Pitch.Pitch Source #

The ASCII kbd is relative. This means that relative scales always start on "C". So the tonic note of a key in a relative scale is irrelevant, C major and D major both start in the same place. Of course, they produce different frequencies, but that's the responsibility of scale_note_to_call.

Unlike absolute_to_pitch, if the scale octave is not an even multiple of the kbd octave (10), the extra notes wrap to the next highest octave.

adjust_octave :: Pitch.PitchClass -> Pitch.PitchClass -> Pitch.Octave -> Pitch.PitchClass -> (Pitch.Octave, Pitch.PitchClass) Source #

Try to fit a note from a keyboard into a scale. Round the note up to the nearest multiple of the keyboard octave and adjust the octave accordingly.



prepend_doc :: Doc.Doc -> DocumentedCall -> DocumentedCall Source #

Prepend a bit of text to the documentation.


read_environ Source #


:: (Typecheck.Typecheck a, ShowVal.ShowVal a) 
=> (a -> Maybe.Maybe val) 
-> Maybe.Maybe val

if Just, a missing value gets this, otherwise error

-> EnvKey.Key 
-> DeriveT.Environ 
-> Either DeriveT.PitchError val 

Like read_environ_, but with a simpler parser.

read_environ_default :: (Typecheck.Typecheck a, ShowVal.ShowVal a) => (a -> Maybe.Maybe val) -> Maybe.Maybe a -> EnvKey.Key -> DeriveT.Environ -> Either DeriveT.PitchError val Source #

Like read_environ, except the default is given to the parse function.

read_environ_ :: (Typecheck.Typecheck a, ShowVal.ShowVal a) => (a -> Either (Maybe.Maybe Text) val) -> Maybe.Maybe (Either DeriveT.PitchError val) -> EnvKey.Key -> DeriveT.Environ -> Either DeriveT.PitchError val Source #

Read and parse an environ value, or throw a ScaleError. This takes a parse function in addition to the usual Typecheck, because scales and keys don't use use Typecheck, beyond ensuring it's a string.


get_key :: key -> Map Pitch.Key key -> Maybe.Maybe Pitch.Key -> Either DeriveT.PitchError key Source #

Find a key in a map, or throw a ScaleError.