Skip to content

A collection of tools for music theory — pronounced “harmonics”

License

Notifications You must be signed in to change notification settings

njonsson/harmonex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

logo Harmonex

Travis CI build status HexFaktor dependencies status Coveralls test coverage status Hex release

This is a collection of tools for music theory called Harmonex (pronounced “harmonics”).

See what’s changed lately by reading the project history.

Usage

Pitches and intervals are the two main constructs available in Harmonex at present.

You can refer to a pitch using any of the following styles of expressions:

  • An atom representing a pitch class (A♮ in an unspecified octave), for example:
    • :a, or
    • :a_natural
  • A map representing a pitch class (A𝄫 in an unspecified octave) or a pitch (A𝄫₄), for example:
    • %{natural_name: :a, accidental: :double_flat}, or
    • %{natural_name: :a, accidental: :double_flat, octave: 4}
  • A struct representing a pitch class (A♯ in an unspecified octave) or a pitch (A♯₋₁) — constructed using Harmonex.Pitch.new — for example:
    • Harmonex.Pitch.new(:a_sharp), or
    • Harmonex.Pitch.new(:a, :sharp), or
    • Harmonex.Pitch.new(:a_sharp, -1), or
    • Harmonex.Pitch.new(:a, :sharp, -1), or
    • Harmonex.Pitch.new(%{natural_name: :a, accidental: :sharp, octave: -1})

You can refer to an interval using either of the following styles of expressions:

  • A map representing an interval (a doubly-diminished ninth), for example: %{quality: :doubly_diminished, size: 9}
  • A struct representing an interval (a perfect unison) — constructed using Harmonex.Interval.new — for example:
    • Harmonex.Interval.new(:perfect, 1), or
    • Harmonex.Interval.new(%{quality: :perfect, size: 1})

What can you do with Harmonex?

Its functions can answer elementary textbook music theory questions such as:

  • Are C♯ and D♭ enharmonically equivalent pitches?
    Answer: Harmonex.Pitch.enharmonic?(:c_sharp, :d_flat) == true
    What about B♯₄ and C₅?
    Answer: Harmonex.Pitch.enharmonic?(Harmonex.Pitch.new(:b_sharp, 4), Harmonex.Pitch.new(:c, 5)) == true
  • What are the enharmonic equivalents of F𝄪?
    Answer: Harmonex.Pitch.enharmonics(:f_double_sharp) == [:g_natural, :a_double_flat]
  • How far apart, in semitones, are the pitches A♭ and D♯?
    Answer: Harmonex.Pitch.semitones(:a_flat, :d_sharp) == 5
  • How far across in semitones is a doubly augmented second?
    Answer: Harmonex.Pitch.interval(:c_flat, :d_sharp) |> Harmonex.Interval.semitones == 4
    Answer: Harmonex.Interval.semitones(%{quality: :doubly_augmented, size: 2}) == 4
  • What is the interval between the pitches F♮ and B𝄫?
    Answer: Harmonex.Pitch.interval(:f, :b_double_flat) == %Harmonex.Interval{quality: :diminished, size: 4}
    Answer: Harmonex.Interval.from_pitches(:f, :b_double_flat) == %Harmonex.Interval{quality: :diminished, size: 4}
  • Is a minor ninth enharmonically narrower or wider than a doubly-augmented octave?
    Answer: Harmonex.Interval.compare(Harmonex.Interval.new(:minor, 9), Harmonex.Interval.new(:doubly_augmented, 8)) == :lt

Functionality still under development

  • What is the key signature of G harmonic minor?
    Answer: two flats, one sharp — B♭, E♭, and F♯.
  • What keys and modes have the signature of three sharps?
    Answer: A major/Ionian, B Dorian, C♯ Phrygian, D Lydian, E Mixolydian, F♯ minor/Aeolian, and G♯ Locrian.
  • Does A♮ occur diatonically in the key of E♭ minor?
    Answer: no.
  • What are the pitches of the simplest voicing of a D♭ minor triad in second inversion?
    Answer: A♭, D♭, and F♭.
  • What is the name and inversion of the chord described by the pitches C♮, F♯, and A♮?
    Answer: F♯ diminished triad in second inversion.
    of the chord described by A♭, C, and F♯?
    Answer: A♭ Italian sixth.
    of the chord described by B, D♯, E, and G♯?
    Answer: E major seventh in second inversion.
  • What are the jazz chart symbols of the chords just mentioned?
    Answer: F♯o/C, A♭7(no 5), and E△7/B.
  • What is the functional-harmonic symbol of the chord described by the pitches C♮, E♮, F♯, and A♮ in C major?
    Answer: viiø32/V.
    of the chord described by A♭, C, and F♯ in C minor?
    Answer: It6.
    of the chord described by B, D♯, E, and G♯ in E major?
    Answer: I43.

Harmonex also will have functions for exploring compositional questions such as:

  • What is the set of triads and seventh chords, including enharmonic equivalents, that the keys of B Mixolydian and D Lydian have in common?
  • What is the set of seventh chords, including enharmonic equivalents, that are within one degree of difference (by shifting one note by a half or whole step) from an F major seventh chord?
    within two degrees?
    three?
    four?
  • What are sets of three-chord changes for modulating from the key of D minor to F♯ major?
    four-chord changes?
    five-chord changes?

Installation

Install the Hex package by adding :harmonex to the list of dependencies in your project’s mix.exs file:

# mix.exs

# ...
def deps do
  [{:harmonex, "~> 0.6.1"}]
end
# ...

Contributing

To submit a patch to the project:

  1. Fork the official repository.
  2. Create your feature branch: git checkout -b my-new-feature.
  3. Commit your changes: git commit -am 'Add some feature'.
  4. Push to the branch: git push origin my-new-feature.
  5. Create a new pull request.

After cloning the repository, mix deps.get to install dependencies. Then mix test to run the tests. You can also iex to get an interactive prompt that will allow you to experiment. To build this package, mix hex.build.

To release a new version:

  1. Update the project history in History.md, and then commit.
  2. Update the version number in mix.exs respecting Semantic Versioning, update the “Installation” section of this readme to reference the new version, and then commit.
  3. Build and publish the Hex package with mix hex.publish.
  4. Tag with a name like vMAJOR.MINOR.PATCH corresponding to the new version, and then push commits and tags.

License

Released under the MIT License.