Safe Haskell | Safe-Inferred |
---|
This is the part of Derive.Scale.Theory that's concerned with converting
Pitch.Pitch
es to and from Pitch.Note
s.
It's split off to avoid cluttering Theory, but also because the Derive.Scale import would make it a circular dependency.
This is basically just a bunch of functions that take a million arguments
to configure octave format, accidental format, key parsing, etc. To
avoid annoyingly long argument lists, they are mostly packaged up into
records, such as Config
, KeyConfig
, and RelativeFormat
.
It's basically all just an attempt to parameterize scale creation, so I can reuse the shared parts but still be able to configure them. It winds up being complicated, probably due to how it's evolved in reaction to increasingly varied scales, rather than according to an overarching design.
Synopsis
- data Config = Config {}
- default_config :: Config
- set_octave :: ShowOctave -> ParseOctave -> Config -> Config
- type ShowOctave = Pitch.Octave -> Text -> Text
- type ParseOctave = A.Parser (Pitch.PitchClass, Maybe Pitch.Accidentals) -> A.Parser RelativePitch
- data KeyConfig key = KeyConfig {
- key_parse :: Maybe Pitch.Key -> Either DeriveT.PitchError key
- key_default :: key
- data RelativePitch = RelativePitch !Pitch.Octave !Pitch.PitchClass !(Maybe Pitch.Accidentals)
- relative_to_absolute :: RelativePitch -> Pitch.Pitch
- letters :: Pitch.PitchClass -> Format
- letter_degrees :: [Text]
- absolute_c :: Format
- absolute_c_degrees :: [Text]
- data RelativeFormat key = RelativeFormat {
- rel_config :: Config
- rel_key_config :: KeyConfig key
- rel_show_degree :: ShowDegree key
- rel_to_absolute :: ToAbsolute key
- type ToAbsolute key = key -> Degrees -> RelativePitch -> Pitch.Pitch
- type ShowDegree key = key -> ShowOctave -> Degrees -> AccidentalFormat -> Either Pitch.Degree Pitch.Pitch -> Pitch.Note
- sargam :: RelativeFormat key -> Format
- cipher :: Pitch.PitchClass -> RelativeFormat key -> Format
- zh_cipher :: Pitch.PitchClass -> RelativeFormat key -> Format
- gongche :: RelativeFormat key -> Format
- make_pattern :: Degrees -> Text
- data Format = Format {}
- type ShowPitch = Maybe Pitch.Key -> Either Pitch.Degree Pitch.Pitch -> Pitch.Note
- type Degrees = Vector.Vector Text
- make_degrees :: [Text] -> Degrees
- show_key :: Format -> Theory.Key -> Pitch.Key
- show_key_signature :: Format -> Theory.Key -> Text
- show_signature :: Format -> Theory.Key -> [Text]
- key_degrees :: Theory.Key -> Format -> [Text]
- show_pitch :: Format -> Maybe Pitch.Key -> Pitch.Pitch -> Pitch.Note
- scale_show_pitch :: Format -> Maybe Pitch.Key -> Pitch.Pitch -> Either DeriveT.PitchError Pitch.Note
- show_degree :: Format -> Maybe Pitch.Key -> Pitch.Degree -> Text
- read_pitch :: Format -> Maybe Pitch.Key -> Pitch.Note -> Either DeriveT.PitchError Pitch.Pitch
- read_relative_pitch :: Format -> Pitch.Note -> Either DeriveT.PitchError RelativePitch
- make_absolute_format :: Text -> Degrees -> Format
- make_absolute_format_keyed :: Config -> KeyConfig Theory.Key -> Text -> Degrees -> Format
- make_absolute_format_config :: Config -> Text -> Degrees -> Format
- make_relative_format :: Text -> Degrees -> RelativeFormat key -> Format
- acc_pattern :: Text
- octave_pattern :: Text
- show_pitch_absolute :: Config -> Degrees -> ShowPitch
- show_degree_chromatic :: ShowDegree Theory.Key
- chromatic_to_absolute :: ToAbsolute Theory.Key
- type Tonic = Pitch.PitchClass
- show_degree_diatonic :: ShowDegree Tonic
- show_pc :: Degrees -> Tonic -> Pitch.PitchClass -> (Pitch.Octave, Text)
- degree_at :: Degrees -> Pitch.PitchClass -> (Pitch.Octave, Text)
- diatonic_to_absolute :: ToAbsolute Tonic
- show_pitch_keyed_absolute :: Config -> KeyConfig Theory.Key -> Degrees -> ShowPitch
- p_pitch :: Config -> Degrees -> A.Parser RelativePitch
- show_octave :: ShowOctave
- parse_octave :: ParseOctave
- parse_octave1 :: ParseOctave
- data AccidentalFormat = AccidentalFormat !Text !Text !Text !Text !Text
- ascii_accidentals :: AccidentalFormat
- symbol_accidentals :: AccidentalFormat
- p_accidentals :: AccidentalFormat -> A.Parser (Maybe Pitch.Accidentals)
- show_accidentals_keyed :: AccidentalFormat -> Pitch.Accidentals -> Pitch.Accidentals -> Text
- show_accidentals :: AccidentalFormat -> Pitch.Accidentals -> Text
types
General purpose config.
set_octave :: ShowOctave -> ParseOctave -> Config -> Config Source #
type ShowOctave = Pitch.Octave -> Text -> Text Source #
type ParseOctave = A.Parser (Pitch.PitchClass, Maybe Pitch.Accidentals) -> A.Parser RelativePitch Source #
This can't just be A.Parser Pitch.Octave because I don't know where the octave is in the pitch text.
Key config is only necessary for formatting that depends on the key, e.g.
RelativeFormat
.
KeyConfig | |
|
data RelativePitch Source #
This is a just-parsed pitch. It hasn't yet been adjusted according to the
key, so it's not yet an absolute Pitch.Pitch
. It also represents
a natural explicitly, via Just 0.
fmt_to_absolute
is responsible for converting this to a Pitch.Pitch
,
likely via rel_to_absolute
.
Instances
Show RelativePitch Source # | |
Defined in Derive.Scale.TheoryFormat showsPrec :: Int -> RelativePitch -> ShowS # show :: RelativePitch -> String # showList :: [RelativePitch] -> ShowS # | |
Pretty RelativePitch Source # | |
Defined in Derive.Scale.TheoryFormat pretty :: RelativePitch -> Text Source # format :: RelativePitch -> Doc Source # formatList :: [RelativePitch] -> Doc Source # |
absolute
letters :: Pitch.PitchClass -> Format Source #
Make an absolute scale starting at a
.
letter_degrees :: [Text] Source #
absolute_c :: Format Source #
The usual 7 note scale, which wraps around at c
instead of a
.
absolute_c_degrees :: [Text] Source #
relative
data RelativeFormat key Source #
Args for a relative scale format.
The Pitch.Pitch
es handled by a relative scale are still absolute, the same
as the Pitches of an absolute scale. The difference is that the
read_pitch
and show_pitch
functions adjust based on the key to display
the absolute Pitch relative to the tonic of the key.
RelativeFormat | |
|
type ToAbsolute key = key -> Degrees -> RelativePitch -> Pitch.Pitch Source #
Given a RelativePitch relative to the default key, adjust it to
be absolute. This is so I can figure out if a relative pitch is valid
without knowing the key, as described in fmt_to_absolute
.
type ShowDegree key = key -> ShowOctave -> Degrees -> AccidentalFormat -> Either Pitch.Degree Pitch.Pitch -> Pitch.Note Source #
This is a specialization of ShowPitch
for show functions that need
a key.
sargam :: RelativeFormat key -> Format Source #
cipher :: Pitch.PitchClass -> RelativeFormat key -> Format Source #
zh_cipher :: Pitch.PitchClass -> RelativeFormat key -> Format Source #
gongche :: RelativeFormat key -> Format Source #
make_pattern :: Degrees -> Text Source #
Format
This is the central data structure for this module. It has the set of
functions needed to parse and generate symbolic pitches. Making one of
these gives you access to the set of functions in here, such as show_pitch
and read_pitch
, which in turn can be used to implement
a Scale
.
Format | |
|
type ShowPitch = Maybe Pitch.Key -> Either Pitch.Degree Pitch.Pitch -> Pitch.Note Source #
This is used to show both a Pitch with an octave, and a Degree without one (used for key names). This is because the code is presumably mostly the same.
type Degrees = Vector.Vector Text Source #
make_degrees :: [Text] -> Degrees Source #
show keys
show_key_signature :: Format -> Theory.Key -> Text Source #
Show a key along with its key signature.
show_signature :: Format -> Theory.Key -> [Text] Source #
Show the signature of the given key by showing each scale degree with the the accidentals implied by the key signature.
key_degrees :: Theory.Key -> Format -> [Text] Source #
Get the degree names of a chromatic scale in this key.
show pitches
show_pitch :: Format -> Maybe Pitch.Key -> Pitch.Pitch -> Pitch.Note Source #
scale_show_pitch :: Format -> Maybe Pitch.Key -> Pitch.Pitch -> Either DeriveT.PitchError Pitch.Note Source #
show_pitch
adapted to scale_show
.
show_degree :: Format -> Maybe Pitch.Key -> Pitch.Degree -> Text Source #
read_pitch :: Format -> Maybe Pitch.Key -> Pitch.Note -> Either DeriveT.PitchError Pitch.Pitch Source #
read_relative_pitch :: Format -> Pitch.Note -> Either DeriveT.PitchError RelativePitch Source #
Parse a Note, but don't adjust it for the key. This means that relative
pitches will likely be incorrect. ToAbsolute
documents why this needs
to be separate.
make
make_absolute_format_keyed :: Config -> KeyConfig Theory.Key -> Text -> Degrees -> Format Source #
make_absolute_format_config :: Config -> Text -> Degrees -> Format Source #
A configurable version of make_absolute_format
.
make_relative_format :: Text -> Degrees -> RelativeFormat key -> Format Source #
Make a Format from a RelativeFormat
.
acc_pattern :: Text Source #
absolute
relative
type Tonic = Pitch.PitchClass Source #
show_pc :: Degrees -> Tonic -> Pitch.PitchClass -> (Pitch.Octave, Text) Source #
degree_at :: Degrees -> Pitch.PitchClass -> (Pitch.Octave, Text) Source #
diatonic_to_absolute :: ToAbsolute Tonic Source #
Convert a relative pitch using a simple diatonic key system, where the key is just a note in the scale.
keyed relative
show_pitch_keyed_absolute :: Config -> KeyConfig Theory.Key -> Degrees -> ShowPitch Source #
Like show_degree_chromatic
, but format the accidentals as staff notation
does, in that accidentals implicit in the key signature are omitted, and
a natural that differs from the key signature is emitted.
TODO tons of args, can I package some up?
parse
octave
show_octave :: ShowOctave Source #
Most scales display the octave as a leading number.
parse_octave1 :: ParseOctave Source #
Require a single digit octave.
accidentals
data AccidentalFormat Source #
natural, sharp1, sharp2, flat1, flat2
Instances
Show AccidentalFormat Source # | |
Defined in Derive.Scale.TheoryFormat showsPrec :: Int -> AccidentalFormat -> ShowS # show :: AccidentalFormat -> String # showList :: [AccidentalFormat] -> ShowS # |
show_accidentals_keyed :: AccidentalFormat -> Pitch.Accidentals -> Pitch.Accidentals -> Text Source #
Show accidentals relative to the key signature.