Copyright | (c) 2022 Andrew A. Cashner |
---|---|
Stability | Experimental |
Safe Haskell | None |
Language | Haskell2010 |
Cogito.Ficta
Contents
Description
This module provides functions to adjust music created by the ark to follow conventions of musica ficta.
Synopsis
- changeNotePitch :: Note -> Pitch -> Note
- adjustNotePitch :: (Pitch -> Pitch) -> Note -> Note
- accidentalShift :: Pitch -> Accid -> Pitch
- flatten :: Pitch -> Pitch
- sharpen :: Pitch -> Pitch
- changeAccid :: Accid -> AccidType -> Pitch -> Pitch
- changeNoteAccid :: Accid -> AccidType -> Note -> Note
- cancel :: Pitch -> Pitch
- noteCancel :: Note -> Note
- fictaAccid :: Pitch -> Pitch
- writeAccid :: Pitch -> Pitch
- adjustNotesInSection :: ([Note] -> [Note]) -> MusicSection -> MusicSection
- changeNotesInPhrase :: MusicPhrase -> [Note] -> MusicPhrase
- adjustNotesInPhrase :: ([Note] -> [Note]) -> MusicPhrase -> MusicPhrase
- fixFictaInSection :: ([Note] -> Note -> [Note]) -> MusicSection -> MusicSection
- fixFictaInPhrase :: ([Note] -> Note -> [Note]) -> MusicPhrase -> MusicPhrase
- foldStack :: ([a] -> a -> [a]) -> [a] -> [a]
- adjustPhrasesRelative :: (MusicPhrase -> MusicPhrase -> MusicPhrase) -> MusicSection -> MusicSection -> MusicSection
- findCounterpoint :: MusicPhrase -> MusicPhrase -> Int -> Note
- durQuantity :: Dur -> Int
- adjustFictaChorus :: ToneSystem -> ToneList -> MusicChorus -> MusicChorus
- adjustFictaVoice :: ToneList -> Tone -> MusicSection -> MusicSection
- pitchClass :: Note -> Pnum
- noteAccid :: Note -> Accid
- checkPnumAccid :: Pnum -> Accid -> Note -> Bool
- adjustRelBass :: ToneList -> Tone -> MusicSection -> MusicSection -> MusicSection
- adjustRelUpper :: MusicSection -> MusicSection -> MusicSection
- scaleDegree :: ToneList -> Tone -> Pitch -> Int
- scaleDegree1 :: ToneList -> Tone -> Pitch -> Int
- isFictaAccid :: Accid -> Pitch -> Bool
- isFictaAccidNote :: Accid -> Note -> Bool
- isCrossRelation :: Pitch -> Pitch -> Bool
- isAugFifth :: Pitch -> Pitch -> Bool
- isTritone :: Pitch -> Pitch -> Bool
- isTritoneNote :: Note -> Note -> Bool
Adjust accidentals of individual pitches
Utilities to adjust pitches by MusicSection
adjustNotesInSection :: ([Note] -> [Note]) -> MusicSection -> MusicSection Source #
Do something to the Note
s in every MusicPhrase
within a MusicSection
changeNotesInPhrase :: MusicPhrase -> [Note] -> MusicPhrase Source #
Copy a MusicPhrase
but with new notes
adjustNotesInPhrase :: ([Note] -> [Note]) -> MusicPhrase -> MusicPhrase Source #
Do something to the Note
list in a MusicPhrase
Arguments
:: ([Note] -> Note -> [Note]) | fold function (arguments: stack and new item) |
-> MusicSection | |
-> MusicSection |
Fold a ficta-adjusting function over a MusicSection
Arguments
:: ([Note] -> Note -> [Note]) | fold function (arguments: stack and new item) |
-> MusicPhrase | |
-> MusicPhrase |
Fold a ficta-adjusting function over a MusicPhrase
Arguments
:: ([a] -> a -> [a]) | fold function (arguments: stack and new item) |
-> [a] -> [a] |
Generate a stack folding function to process a list
adjustPhrasesRelative Source #
Arguments
:: (MusicPhrase -> MusicPhrase -> MusicPhrase) | phrase transform function |
-> MusicSection | lower voice section |
-> MusicSection | upper voice section |
-> MusicSection |
Map a function to the phrases in one section (upper voice) relative to the phrases in another section (lower voice).
Arguments
:: MusicPhrase | phrase to search for counterpoint |
-> MusicPhrase | phrase containing the point to match up in the other voice |
-> Int | index of point in its phrase |
-> Note |
Compare two MusicPhrase
s and find the note in the one (lower) voice that
coincides rhythmically with a given note in the other (upper) voice. Used
to find harmonies and test them for bad intervals.
We find the top note by index and add the durations up to that point, then we add the durations in the bottom voice up to each item (that is, a scan) and then stop at the first item that matches the elapsed duration of the top voice.
adjustFictaChorus :: ToneSystem -> ToneList -> MusicChorus -> MusicChorus Source #
Apply ficta adjustments to whole MusicPhrase
s. Adjust bass voice
first; then adjust the upper voices individually, then adjust them
again relative to the bass.
TODO nowhere do we deal with toneB (needed in s2/p4 for every 3rd and 4th line)
adjustFictaVoice :: ToneList -> Tone -> MusicSection -> MusicSection Source #
Adjust musica ficta for all the notes for one voice in a 'MusicSection.'
These rules are based on Kircher but had to be expanded as he doesn't account for some important and common cases.
TODO they still don't deal with every problem. Some would be automatically corrected by competent performers.
fix "illicit intervals" in the bass (p. 71)
#^7: (p. 69-70) - If the tone table has 8, keep the sharp - If it has #^7 and it is the last note in the phrase, and it is not the bass voice, keep the sharp - Otherwise make it natural
b^6: - If the tone table has b^6, cancel the flat if the next note is #^7
After making either of the above adjustments, go through and check for repeated notes: make them match the next accidental (G♮-G# should be G).
Arguments
:: ToneList | |
-> Tone | |
-> MusicSection | lower voice to compare |
-> MusicSection | upper voice to adjust |
-> MusicSection |
Adjust musica ficta in an upper voice relative to the bass. Avoid cross relations, augmented fifths, and certain tritones. (TODO which tritones?)
Arguments
:: MusicSection | upper voice to compare |
-> MusicSection | lower voice to adjust |
-> MusicSection |
Adjust the Note
s in a MusicSection
relative to the voice above: avoid
cross-relations between upper voices; where voices disagree, favor the
upper voice.
Specific adjustments by rule
scaleDegree :: ToneList -> Tone -> Pitch -> Int Source #
Return the 0-indexed scale degree of a given pitch in a given tone (scale degree 0 is the modal final)
scaleDegree1 :: ToneList -> Tone -> Pitch -> Int Source #
1-indexed scale degree (more intelligible to the musical programmer)
isFictaAccidNote :: Accid -> Note -> Bool Source #
Apply isFictaAccid
to a Note
isCrossRelation :: Pitch -> Pitch -> Bool Source #
Are these pitches the same pitch class but different accidentals? (E.g., F vs F#?)
Are these pitches an augmented fifth apart?