-
Notifications
You must be signed in to change notification settings - Fork 1
Housekeeping #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Housekeeping #25
Changes from 8 commits
5f5d680
b143d6b
5d97044
415a4a4
89d57f1
8b7aee0
f52ad40
d617f04
b2017f9
1480526
0bb8021
a291d6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,7 +34,7 @@ import Base.Class.Rooted | |
|
|
||
| import Base.Core.Note | ||
| import Base.Core.Quality.CQuality as CQ | ||
| import Base.Core.Quality.IQuality as IQ | ||
| import Base.Core.Quality.IQuality as IQ hiding (major) | ||
|
||
|
|
||
| import Base.Core.Interval hiding (getQuality) | ||
| import qualified Base.Core.Interval as I(getQuality) | ||
|
|
@@ -53,12 +53,11 @@ import Language.Parser | |
| -- | Removes the P5 interval from a given chord's note if it exists | ||
| -- and returns the same chord symbol. | ||
| -- | ||
| -- prop> remove5 (chord, _) == chord | ||
| -- prop> getSymbol $ remove5 chord == getSymbol chord | ||
| -- | ||
| -- >>> c = canonicalizeChord $ fromJust $ parseChord "CM7" | ||
| -- >>> notes = chordToNotes c | ||
| -- >>> remove5 (c, notes) | ||
| -- (CM7,[C,E,B]) | ||
| -- >>> remove5 (chordFromSymbol c) | ||
| -- CM7, [C, E, B] | ||
| remove5 :: Chord -> Chord | ||
| remove5 chord = updateNotes chord $ toNotes (root chord) $ S.delete (fromJust(intervalFrom Perfect 5)) (toIntervals chord) | ||
| where | ||
|
|
@@ -118,33 +117,35 @@ negative key chord = head $ notesToChord newNotes | |
| -- this transposes the chord by that interval. Because this function | ||
| -- is only used internally by the module, it assumes the intervals are | ||
| -- validly constructed. | ||
| -- TODO: Make this a safe, general-purpose, exportable function | ||
| transposeChord :: Chord -> IQ.Quality -> Int -> Chord | ||
| transposeChord chord iQual i = | ||
| transposeChord :: Chord -> Interval -> Chord | ||
| transposeChord chord interval = | ||
| let | ||
| newChord = transposeToRoot (getSymbol chord )$ respell $ jumpIntervalFromNote (fromJust (intervalFrom iQual i)) $ root chord | ||
| newChord = transposeToRoot (getSymbol chord )$ respell $ jumpIntervalFromNote interval $ root chord | ||
| in | ||
| chordFromSymbol newChord | ||
|
|
||
| -- | Given a dominant chord or a minor 6 chord, this returns | ||
| -- a list of chord substitutions from its diminished family. | ||
| -- | ||
| -- >>> c = canonicalizeChord $ fromJust $ parseChord "C7" | ||
| -- >>> notes = chordToNotes c | ||
| -- >>> dimFamilySub (c, notes) | ||
| -- [(Eb7,[Eb,G,Bb,Db]),(Gb7,[Gb,Bb,Db,Fb]),(A7,[A,C#,E,G])] | ||
| -- >>> dimFamilySub (chordFromSymbol c) | ||
| -- [Chord {getSymbol = ChordSymbol {getChordRoot = Eb, getShape = ChordShape {getQuality = , getHighestNatural = 7, getExtensions = [], getSus = }}, getNotes = [Eb,G,Bb,Db]},Chord {getSymbol = ChordSymbol {getChordRoot = Gb, getShape = ChordShape {getQuality = , getHighestNatural = 7, getExtensions = [], getSus = }}, getNotes = [Gb,Bb,Db,Fb]},Chord {getSymbol = ChordSymbol {getChordRoot = A, getShape = ChordShape {getQuality = , getHighestNatural = 7, getExtensions = [], getSus = }}, getNotes = [A,C#,E,G]}] | ||
| dimFamilySub :: Chord -> [Chord] | ||
| dimFamilySub eChord | ||
| | quality eChord == CQ.Dominant || | ||
| (quality eChord == CQ.Minor && (fromJust (intervalFrom IQ.Major 6) `member` toIntervals eChord)) | ||
| = [transposeChord eChord IQ.Minor 3, transposeChord eChord (IQ.Diminished 1) 5, transposeChord eChord IQ.Major 6] | ||
| = [transposeBy IQ.Minor 3, transposeBy (IQ.Diminished 1) 5, transposeBy IQ.Major 6] | ||
| | otherwise = [] | ||
| where | ||
| transposeBy :: IQ.Quality -> Int -> Chord | ||
| transposeBy iQual i = transposeChord eChord $ fromJust $ intervalFrom iQual i | ||
|
|
||
|
|
||
| -- | Returns the same chord, but a tritone away. | ||
| -- If applied twice in a row, returns the same chord: | ||
| -- prop> tritoneSub $ tritoneSub (chord, notes) == (_, notes) | ||
| tritoneSub :: Chord -> Chord | ||
| tritoneSub eChord = transposeChord eChord (IQ.Augmented 1) 4 | ||
| tritoneSub eChord = transposeChord eChord $ fromJust $ intervalFrom (IQ.Augmented 1) 4 | ||
|
|
||
| -- | Given a key, and a chord in the key, this returns | ||
| -- a list of chords that are diatonic functional substitutes. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,11 @@ function to get the base quality of an interval size. | |
| -} | ||
| module Base.Core.Quality.IQuality | ||
| ( Quality(..) | ||
| , major | ||
| , perfect | ||
| , minor | ||
| , diminished | ||
| , augmented | ||
| , baseQuality | ||
| , raisePerfect | ||
| , raiseMajor | ||
|
|
@@ -27,9 +32,6 @@ import Common.Utils (modByFrom) | |
| 3. Minor | ||
| 4. Diminished (single, doubly, triply, etc.) | ||
| 5. Augmented (single, doubly, triply, etc.) | ||
|
|
||
| TODO: Make sure that interval qualities are using smart constructors | ||
| so that diminished and augmented only receive integers >= 1. | ||
| -} | ||
| data Quality | ||
| = Major | ||
|
|
@@ -48,6 +50,21 @@ instance Show Quality where | |
| show (Diminished i) = if i == 1 then "dim" else show i ++ "dim" | ||
| show (Augmented i) = if i == 1 then "aug" else show i ++ "aug" | ||
|
|
||
| major :: Quality | ||
| major = Major | ||
|
|
||
| perfect :: Quality | ||
| perfect = Perfect | ||
|
|
||
| minor :: Quality | ||
| minor = Minor | ||
|
|
||
| diminished :: Int -> Maybe Quality | ||
| diminished x = if x > 0 && x < 12 then Just $ Diminished x else Nothing | ||
|
|
||
| augmented :: Int -> Maybe Quality | ||
| augmented x = if x > 0 && x < 12 then Just $ Augmented x else Nothing | ||
|
||
|
|
||
| -- | Given an interval size, we return the base quality, either Perfect or Major | ||
| baseQuality :: Int -> Quality | ||
| baseQuality n | ||
|
|
@@ -58,34 +75,34 @@ baseQuality n | |
|
|
||
| -- | Given an interval quality, this raises that quality by a semitone | ||
| -- assuming that its base quality is Perfect. | ||
| raisePerfect :: Quality -> Quality | ||
| raisePerfect Perfect = Augmented 1 | ||
| raisePerfect (Augmented x) = Augmented $ x + 1 | ||
| raisePerfect (Diminished 1) = Perfect | ||
| raisePerfect (Diminished x) = Diminished $ x - 1 | ||
| raisePerfect :: Quality -> Maybe Quality | ||
| raisePerfect Perfect = Just $ Augmented 1 | ||
| raisePerfect (Augmented x) = augmented $ x + 1 | ||
| raisePerfect (Diminished 1) = Just Perfect | ||
| raisePerfect (Diminished x) = diminished $ x - 1 | ||
|
|
||
| -- | Given an interval quality, this raises that quality by a semitone | ||
| -- assuming that its base quality is Major. | ||
| raiseMajor :: Quality -> Quality | ||
| raiseMajor Major = Augmented 1 | ||
| raiseMajor (Augmented x) = Augmented $ x + 1 | ||
| raiseMajor Minor = Major | ||
| raiseMajor (Diminished 1) = Minor | ||
| raiseMajor (Diminished x) = Diminished $ x - 1 | ||
| raiseMajor :: Quality -> Maybe Quality | ||
| raiseMajor Major = Just $ Augmented 1 | ||
| raiseMajor (Augmented x) = augmented $ x + 1 | ||
| raiseMajor Minor = Just Major | ||
| raiseMajor (Diminished 1) = Just Minor | ||
| raiseMajor (Diminished x) = diminished $ x - 1 | ||
|
|
||
| -- | Given an interval quality, this lowers that quality by a semitone | ||
| -- assuming that its base quality is Perfect. | ||
| lowerPerfect :: Quality -> Quality | ||
| lowerPerfect Perfect = Diminished 1 | ||
| lowerPerfect (Diminished x) = Diminished $ x + 1 | ||
| lowerPerfect (Augmented 1) = Perfect | ||
| lowerPerfect (Augmented x) = Augmented $ x-1 | ||
| lowerPerfect :: Quality -> Maybe Quality | ||
| lowerPerfect Perfect = Just $ Diminished 1 | ||
| lowerPerfect (Diminished x) = diminished $ x + 1 | ||
| lowerPerfect (Augmented 1) = Just Perfect | ||
| lowerPerfect (Augmented x) = augmented $ x-1 | ||
|
|
||
| -- | Given an interval quality, this lowers that quality by a semitone | ||
| -- assuming that its base quality is Major. | ||
| lowerMajor :: Quality -> Quality | ||
| lowerMajor Major = Minor | ||
| lowerMajor Minor = Diminished 1 | ||
| lowerMajor (Diminished x) = Diminished $ x + 1 | ||
| lowerMajor (Augmented 1) = Major | ||
| lowerMajor (Augmented x) = Augmented $ x - 1 | ||
| lowerMajor :: Quality -> Maybe Quality | ||
| lowerMajor Major = Just Minor | ||
| lowerMajor Minor = Just $ Diminished 1 | ||
| lowerMajor (Diminished x) = diminished $ x + 1 | ||
| lowerMajor (Augmented 1) = Just Major | ||
| lowerMajor (Augmented x) = augmented $ x - 1 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quite a bit cleaner, no? :) |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I simplified this per the suggestion I made to your original commits.