Portability | non-portable (TF,GNTD) |
---|---|
Stability | experimental |
Maintainer | hans@hanshoglund.se |
Safe Haskell | None |
Provides a representation of pitch as defined in Common Music Theory (CMT).
- data Octaves
- class HasOctaves a where
- data Steps
- class HasSteps a where
- data Semitones
- class HasSemitones a where
- semitone :: Semitones
- tone :: Semitones
- ditone :: Semitones
- tritone :: Semitones
- isSemitone :: HasSemitones a => a -> Bool
- isTone :: HasSemitones a => a -> Bool
- isTritone :: HasSemitones a => a -> Bool
- (=:=) :: HasSemitones a => a -> a -> Bool
- (/:=) :: HasSemitones a => a -> a -> Bool
- data Name
- data Accidental
- doubleFlat :: Accidental
- flat :: Accidental
- natural :: Accidental
- sharp :: Accidental
- doubleSharp :: Accidental
- isNatural :: Accidental -> Bool
- isSharpened :: Accidental -> Bool
- isFlattened :: Accidental -> Bool
- isStandard :: Accidental -> Bool
- data Pitch
- pitch :: Name -> Accidental -> Pitch
- name :: Pitch -> Name
- accidental :: Pitch -> Accidental
- asPitch :: Pitch -> Pitch
- data Number
- class HasNumber a where
- unison :: Number
- prime :: Number
- second :: Number
- third :: Number
- fourth :: Number
- fifth :: Number
- sixth :: Number
- seventh :: Number
- octave :: Number
- ninth :: Number
- tenth :: Number
- twelfth :: Number
- duodecim :: Number
- thirteenth :: Number
- fourteenth :: Number
- fifteenth :: Number
- data Quality
- class HasQuality a where
- invertQuality :: Quality -> Quality
- isPerfect :: HasQuality a => a -> Bool
- isMajor :: HasQuality a => a -> Bool
- isMinor :: HasQuality a => a -> Bool
- isAugmented :: HasQuality a => a -> Bool
- isDiminished :: HasQuality a => a -> Bool
- data Interval
- interval :: Quality -> Number -> Interval
- perfect :: Number -> Interval
- major :: Number -> Interval
- minor :: Number -> Interval
- augmented :: Number -> Interval
- diminished :: Number -> Interval
- doublyAugmented :: Number -> Interval
- doublyDiminished :: Number -> Interval
- asInterval :: Interval -> Interval
- isNegative :: Interval -> Bool
- isPositive :: Interval -> Bool
- isNonNegative :: Interval -> Bool
- isPerfectUnison :: Interval -> Bool
- isStep :: Interval -> Bool
- isLeap :: Interval -> Bool
- isSimple :: Interval -> Bool
- isCompound :: Interval -> Bool
- separate :: Interval -> (Octaves, Interval)
- simple :: Interval -> Interval
- invert :: Interval -> Interval
- module Music.Pitch.Common.Spell
- module Music.Pitch.Common.Harmony
Enharmonic representation
Octaves
An interval represented as a number of octaves, including negative intervals.
octaves a = semitones a `div` 12 steps a = semitones a `mod` 12
class HasOctaves a whereSource
Class of intervals that has a number of Octaves
.
Returns the number of octaves spanned by an interval.
The number of octaves is negative if and only if the interval is negative.
Examples:
octaves (perfect unison) = 0 octaves (d5 ^* 4) = 2 octaves (-_P8) = -1
Steps
An interval represented as a number of steps in the range 0 ≤ x < 12.
octaves a = semitones a `div` 12 steps a = semitones a `mod` 12
Class of intervals that has a number of Steps
.
The number of steps is always in the range 0 ≤ x < 12.
Examples:
octaves (perfect unison) = 0 octaves (d5 ^* 4) = 2 octaves (-m7) = -1
Semitones
An interval represented as a number of semitones, including negative intervals, as well as intervals larger than one octave. This representation does not take spelling into account, so for example a major third and a diminished fourth can not be distinguished.
Intervals that name a number of semitones (i.e. semitone
, tritone
) does
not have an unequivocal spelling. To convert these to an interval, a
Spelling
must be provided as in:
spell sharps tritone == augmented fourth spell flats tritone == diminished fifth
class HasSemitones a whereSource
Class of intervals that can be converted to a number of Semitones
.
isSemitone :: HasSemitones a => a -> BoolSource
Returns true iff the given interval spans one semitone.
isTone :: HasSemitones a => a -> BoolSource
Returns true iff the given interval spans one whole tone (two semitones).
isTritone :: HasSemitones a => a -> BoolSource
Returns true iff the given interval spans three whole tones (six semitones).
Enharmonic equivalence
(=:=) :: HasSemitones a => a -> a -> BoolSource
Enharmonic equivalence.
(/:=) :: HasSemitones a => a -> a -> BoolSource
Enharmonic non-equivalence.
Pitches
Name type
Accidental type
data Accidental Source
An accidental is either flat, natural or sharp.
This representation allows for an arbitrary number of flats or sharps rather than just single (the ♯ and ♭ symbols) and double (i.e. the x and ♭♭ symbols).
The Num
and Enum
instances treat Accidental
as the number of altered semitones,
i.e. a double flat is -2
, natural 0
and so on.
Enum Accidental | |
Eq Accidental | |
Integral Accidental | |
Num Accidental | |
Ord Accidental | |
Real Accidental | |
Show Accidental | |
Alterable Accidental | |
(IsPitch a, Alterable a) => IsPitch (Accidental -> a) | Magic instance that allow us to write |
doubleFlat :: AccidentalSource
The double flat accidental.
The flat accidental.
The natural accidental.
The sharp accidental.
doubleSharp :: AccidentalSource
The double sharp accidental.
Inspecting accidentals
isNatural :: Accidental -> BoolSource
Returns whether this is a natural accidental.
isSharpened :: Accidental -> BoolSource
Returns whether this is a sharp, double sharp etc.
isFlattened :: Accidental -> BoolSource
Returns whether this is a flat, double flat etc.
isStandard :: Accidental -> BoolSource
Returns whether this is a standard accidental, i.e. either a double flat, flat, natural, sharp or doubl sharp.
Pitch type
Common pitch representation.
Intervals and pitches can be added using .+^
. To get the interval between
two pitches, use .-.
.
Pitches are normally entered using the following literals.
c d e f g a b
Notes with accidentals can be written by adding the s
or b
suffices
(or two for double sharps and flats).
cs, ds, es ... -- sharp cb, db, eb ... -- flat css, dss, ess ... -- double sharp cbb, dbb, ebb ... -- double flat
There is also a convenience syntax for entering pitches one octave up or
down, using '
and _
respectively.
g a b c' d c b_ c
Because of some overloading magic, we can actually write sharp
and
flat
as postfix functions. This gives a better read:
cs == c sharp db == c flat
You can of course use typical functional transformation of pitch as well.
For example sharpen
and flatten
are the ordinary (prefix) versions of
sharp
and flat
sharpen c == c sharp == cs flatten d == d flat == ds (sharpen . sharpen) c == c doubleSharp == css (flatten . flatten) d == d doubleFlat == dss
Note that there is no guarantee that your pitch representation use
enharmonic equivalence, so cs == db
may or may not hold.
c .+^ minor third == eb f .-. c == perfect fourth
Pitches are described by name, accidental and octave number.
c == fromIntegral 0 _P4 == perfect fourth == interval Perfect 5 d5 == diminished fifth == diminish (perfect fifth)
pitch :: Name -> Accidental -> PitchSource
Creates a pitch from name accidental.
accidental :: Pitch -> AccidentalSource
asPitch :: Pitch -> PitchSource
This is just the identity function, but is useful to fix the type of Pitch
.
Intervals
Number type
The number portion of an interval (i.e. second, third, etc).
Note that the interval number is always one step larger than number of steps spanned by
the interval (i.e. a third spans two diatonic steps). Thus number
does not distribute
over addition:
number (a + b) = number a + number b - 1
A synonym for 15
.
A synonym for 16
.
Quality type
Interval quality is either perfect, major, minor, augmented, and
diminished. This representation allows for an arbitrary number of
augmentation or diminishions, so augmented is represented by Augmented
1
, doubly augmented by Augmented 2
and so on.
The quality of a compound interval is the quality of the simple interval on which it is based.
invertQuality :: Quality -> QualitySource
Invert a quality.
Perfect is unaffected, major becomes minor and vice versa, augmented becomes diminished and vice versa.
isPerfect :: HasQuality a => a -> BoolSource
Returns whether the given quality is perfect.
isMajor :: HasQuality a => a -> BoolSource
Returns whether the given quality is major.
isMinor :: HasQuality a => a -> BoolSource
Returns whether the given quality is minor.
isAugmented :: HasQuality a => a -> BoolSource
Returns whether the given quality is augmented (including double augmented etc).
isDiminished :: HasQuality a => a -> BoolSource
Returns whether the given quality is diminished (including double diminished etc).
Interval type
An interval is the difference between two pitches, incuding negative intervals.
Intervals and pitches can be added using .+^
. To get the interval between
two pitches, use .-.
.
c .+^ minor third == eb f .-. c == perfect fourth
Adding intervals preserves spelling. For example:
m3 ^+^ _M3 = _P5 d5 ^+^ _M6 = m10
The scalar type of Interval
is Integer
, using ^*
to stack intervals of a certain
type on top of each other. For example _P5 ^* 2
is a stack of 2 perfect fifths, or a
major ninth. The Num
instance works as expected for +
, negate
and abs
, and
(arbitrarily) uses minor seconds for multiplication. If you find yourself *
, or
signum
on intervals, consider switching to *^
or normalized
.
Intervals are generally described in terms of Quality
and Number
. To
construct an interval, use the interval
constructor, the utility
constructors major
, minor
, augmented
and diminished
, or the
interval literals:
m5 == minor fifth == interval Minor 5 _P4 == perfect fourth == interval Perfect 5 d5 == diminished fifth == diminish (perfect fifth)
Creating intervals
perfect :: Number -> IntervalSource
Creates a perfect interval. If given an inperfect number, constructs a major interval.
major :: Number -> IntervalSource
Creates a major interval. If given a perfect number, constructs a perfect interval.
minor :: Number -> IntervalSource
Creates a minor interval. If given a perfect number, constructs a diminished interval.
diminished :: Number -> IntervalSource
Creates a diminished interval.
doublyAugmented :: Number -> IntervalSource
Creates a doubly augmented interval.
doublyDiminished :: Number -> IntervalSource
Creates a doubly diminished interval.
asInterval :: Interval -> IntervalSource
This is just the identity function, but is useful to fix the type of Interval
.
Inspecting intervals
isNegative :: Interval -> BoolSource
Returns whether the given interval is negative.
isPositive :: Interval -> BoolSource
Returns whether the given interval is positive.
isNonNegative :: Interval -> BoolSource
Returns whether the given interval is non-negative. This implies that it is either positive or a perfect unison.
isPerfectUnison :: Interval -> BoolSource
Returns whether the given interval a perfect unison.
isStep :: Interval -> BoolSource
Returns whether the given interval is a step (a second or smaller).
Only diatonic number
is taken into account, so _A2
is considered
a step and m3
a leap, even though they have the same number of
semitones.
isLeap :: Interval -> BoolSource
Returns whether the given interval is a leap (larger than a second).
Only the diatonic number
is taken into account, so _A2
is considered
a step and m3
a leap, even though they have the same number of
semitones.
Simple and compound intervals
isSimple :: Interval -> BoolSource
Returns whether the given interval is simple.
A simple interval is a non-negative interval spanning less than one octave.
isCompound :: Interval -> BoolSource
Returns whether the given interval is compound.
A compound interval is either a negative interval, or a positive interval spanning more than octave.
separate :: Interval -> (Octaves, Interval)Source
Separate a compound interval into octaves and a simple interval.
(perfect octave)^*x + y = z iff (x, y) = separate z
simple :: Interval -> IntervalSource
Returns the simple part of an interval.
(perfect octave)^*x + y = z iff y = simple z
Inversion
invert :: Interval -> IntervalSource
Intervallic inversion.
The inversion an interval is determined as follows:
- The number of a simple interval the difference of nine and the number of its inversion.
- The quality of a simple interval is the inversion of the quality of its inversion.
- The inversion of a compound interval is the inversion of its simple component.
Miscellaneous
module Music.Pitch.Common.Spell
module Music.Pitch.Common.Harmony