{"id":17228661,"url":"https://github.com/njonsson/harmonex","last_synced_at":"2025-07-25T06:33:47.226Z","repository":{"id":48308396,"uuid":"90509855","full_name":"njonsson/harmonex","owner":"njonsson","description":"A collection of tools for music theory — pronounced “harmonics”","archived":false,"fork":false,"pushed_at":"2021-08-02T11:15:20.000Z","size":171,"stargazers_count":8,"open_issues_count":29,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-14T01:36:00.034Z","etag":null,"topics":["elixir","elixir-library","music","music-composition","music-theory"],"latest_commit_sha":null,"homepage":"https://njonsson.github.io/harmonex","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/njonsson.png","metadata":{"files":{"readme":"README.md","changelog":"History.md","contributing":null,"funding":null,"license":"License.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-07T04:57:34.000Z","updated_at":"2024-04-07T21:13:40.000Z","dependencies_parsed_at":"2022-08-24T04:20:31.338Z","dependency_job_id":null,"html_url":"https://github.com/njonsson/harmonex","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/njonsson/harmonex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/njonsson%2Fharmonex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/njonsson%2Fharmonex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/njonsson%2Fharmonex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/njonsson%2Fharmonex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/njonsson","download_url":"https://codeload.github.com/njonsson/harmonex/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/njonsson%2Fharmonex/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266966650,"owners_count":24013739,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-25T02:00:09.625Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","elixir-library","music","music-composition","music-theory"],"created_at":"2024-10-15T04:44:43.247Z","updated_at":"2025-07-25T06:33:47.204Z","avatar_url":"https://github.com/njonsson.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \u003cimg align=\"left\" alt=\"logo\" src=\"assets/logo.png\" /\u003e Harmonex\n\n[\u003cimg alt=\"Travis CI build status\" src=\"https://secure.travis-ci.org/njonsson/harmonex.svg?branch=master\" /\u003e][Travis-CI-build-status]\n[\u003cimg alt=\"HexFaktor dependencies status\" src=\"https://beta.hexfaktor.org/badge/all/github/njonsson/harmonex.svg\" /\u003e][HexFaktor-deps-status]\n[\u003cimg alt=\"Coveralls test coverage status\" src=\"https://coveralls.io/repos/njonsson/harmonex/badge.svg?branch=master\" /\u003e][Coveralls-test-coverage-status]\n[\u003cimg alt=\"Hex release\" src=\"https://img.shields.io/hexpm/v/harmonex.svg\" /\u003e][Hex-release]\n\nThis is a collection of tools for music theory called _Harmonex_ (pronounced\n“harmonics”).\n\n**See what’s changed lately by reading [the project history][project-history].**\n\n## Usage\n\nPitches and intervals are the two main constructs available in _Harmonex_ at\npresent.\n\nYou can refer to a **pitch** using any of the following styles of expressions:\n\n* An **atom** representing a pitch class (A♮ in an unspecified octave), for\n  example:\n  - `:a`, or\n  - `:a_natural`\n* A **map** representing a pitch class (A𝄫 in an unspecified octave) or a pitch\n  (A𝄫₄), for example:\n  - `%{natural_name: :a, accidental: :double_flat}`, or\n  - `%{natural_name: :a, accidental: :double_flat, octave: 4}`\n* A **struct** representing a pitch class (A♯ in an unspecified octave) or a\n  pitch (A♯₋₁) — constructed using `Harmonex.Pitch.new` — for example:\n  - `Harmonex.Pitch.new(:a_sharp)`, or\n  - `Harmonex.Pitch.new(:a, :sharp)`, or\n  - `Harmonex.Pitch.new(:a_sharp, -1)`, or\n  - `Harmonex.Pitch.new(:a, :sharp, -1)`, or\n  - `Harmonex.Pitch.new(%{natural_name: :a, accidental: :sharp, octave: -1})`\n\nYou can refer to an **interval** using either of the following styles of\nexpressions:\n\n* A **map** representing an interval (a doubly-diminished ninth), for example:\n  `%{quality: :doubly_diminished, size: 9}`\n* A **struct** representing an interval (a perfect unison) — constructed using\n  `Harmonex.Interval.new` — for example:\n  - `Harmonex.Interval.new(:perfect, 1)`, or\n  - `Harmonex.Interval.new(%{quality: :perfect, size: 1})`\n\n### What can you do with _Harmonex_?\n\nIts functions can answer elementary textbook music theory questions such as:\n\n* **Are C♯ and D♭ enharmonically equivalent pitches?**  \n  _Answer:_ `Harmonex.Pitch.enharmonic?(:c_sharp, :d_flat) == true`  \n  **What about B♯₄ and C₅?**  \n  _Answer:_ `Harmonex.Pitch.enharmonic?(Harmonex.Pitch.new(:b_sharp, 4),\n  Harmonex.Pitch.new(:c, 5)) == true`\n* **What are the enharmonic equivalents of F𝄪?**  \n  _Answer:_\n  `Harmonex.Pitch.enharmonics(:f_double_sharp) == [:g_natural, :a_double_flat]`\n* **How far apart, in semitones, are the pitches A♭ and D♯?**  \n  _Answer:_ `Harmonex.Pitch.semitones(:a_flat, :d_sharp) == 5`  \n* **How far across in semitones is a doubly augmented second?**  \n  _Answer:_ `Harmonex.Pitch.interval(:c_flat, :d_sharp) |\u003e\n  Harmonex.Interval.semitones == 4`  \n  _Answer:_\n  `Harmonex.Interval.semitones(%{quality: :doubly_augmented, size: 2}) == 4`\n* **What is the interval between the pitches F♮ and B𝄫?**  \n  _Answer:_\n  `Harmonex.Pitch.interval(:f, :b_double_flat) == %Harmonex.Interval{quality:\n  :diminished, size: 4}`  \n  _Answer:_\n  `Harmonex.Interval.from_pitches(:f, :b_double_flat) ==\n  %Harmonex.Interval{quality: :diminished, size: 4}`\n* **Is a minor ninth enharmonically narrower or wider than a\n  doubly-augmented octave?**  \n  _Answer:_\n  `Harmonex.Interval.compare(Harmonex.Interval.new(:minor, 9),\n  Harmonex.Interval.new(:doubly_augmented, 8)) == :lt`\n\n### Functionality still under development\n\n* **What is the key signature of G harmonic minor?**  \n  _Answer:_ two flats, one sharp — B♭, E♭, and F♯.\n* **What keys and modes have the signature of three sharps?**  \n  _Answer:_ A major/Ionian, B Dorian, C♯ Phrygian, D Lydian, E Mixolydian, F♯\n  minor/Aeolian, and G♯ Locrian.\n* **Does A♮ occur diatonically in the key of E♭ minor?**  \n  _Answer:_ no.\n* **What are the pitches of the simplest voicing of a D♭ minor triad in\n  second inversion?**  \n  _Answer:_ A♭, D♭, and F♭.\n* **What is the name and inversion of the chord described by the pitches C♮, F♯,\n  and A♮?**  \n  _Answer:_ F♯ diminished triad in second inversion.  \n  **of the chord described by A♭, C, and F♯?**  \n  _Answer:_ A♭ Italian sixth.  \n  **of the chord described by B, D♯, E, and G♯?**  \n  _Answer:_ E major seventh in second inversion.\n* **What are the jazz chart symbols of the chords just mentioned?**  \n  _Answer:_ F♯\u003csup\u003eo\u003c/sup\u003e/C, A♭\u003csup\u003e7(no 5)\u003c/sup\u003e, and E\u003csup\u003e△7\u003c/sup\u003e/B.\n* **What is the functional-harmonic symbol of the chord described by the pitches\n  C♮, E♮, F♯, and A♮ in C major?**  \n  _Answer:_ vii\u003csup\u003eø3\u003c/sup\u003e\u003cspan style=\"position: relative; left: -1ex;\"\u003e\u003csub\u003e2\u003c/sub\u003e/V.\u003c/span\u003e  \n  **of the chord described by A♭, C, and F♯ in C minor?**  \n  _Answer:_ It\u003csup\u003e6\u003c/sup\u003e.  \n  **of the chord described by B, D♯, E, and G♯ in E major?**  \n  _Answer:_ I\u003csup\u003e4\u003c/sup\u003e\u003cspan style=\"position: relative; left: -1ex;\"\u003e\u003csub\u003e3\u003c/sub\u003e.\n\n_Harmonex_ also will have functions for exploring compositional questions such\nas:\n\n* **What is the set of triads and seventh chords, including enharmonic\n  equivalents, that the keys of B Mixolydian and D Lydian have in common?**\n* **What is the set of seventh chords, including enharmonic equivalents, that are\n  within one degree of difference (by shifting one note by a half or whole step)\n  from an F major seventh chord?**  \n  **within two degrees?**  \n  **three?**  \n  **four?**\n* **What are sets of three-chord changes for modulating from the key of D minor\n  to F♯ major?**  \n  **four-chord changes?**  \n  **five-chord changes?**\n\n## Installation\n\nInstall [the Hex package][Hex-release] by adding `:harmonex` to the list of\ndependencies in your project’s _mix.exs_ file:\n\n```elixir\n# mix.exs\n\n# ...\ndef deps do\n  [{:harmonex, \"~\u003e 0.6.1\"}]\nend\n# ...\n```\n\n## Contributing\n\nTo submit a patch to the project:\n\n1. [Fork][fork-project] the official repository.\n2. Create your feature branch: `git checkout -b my-new-feature`.\n3. Commit your changes: `git commit -am 'Add some feature'`.\n4. Push to the branch: `git push origin my-new-feature`.\n5. [Create][compare-project-branches] a new pull request.\n\nAfter cloning the repository, `mix deps.get` to install dependencies. Then\n`mix test` to run the tests. You can also `iex` to get an interactive prompt that\nwill allow you to experiment. To build this package, `mix hex.build`.\n\nTo release a new version:\n\n1. Update [the project history in _History.md_][project-history], and then\n   commit.\n2. Update the version number in [_mix.exs_][mix-dot-exs-file] respecting\n   [Semantic Versioning][Semantic-Versioning], update\n   [the “Installation” section](#installation) of\n   [this readme][readme-dot-md-file] to reference the new version, and then\n   commit.\n3. Build and publish [the Hex package][Hex-release] with `mix hex.publish`.\n4. Tag with a name like `vMAJOR.MINOR.PATCH` corresponding to the new version,\n   and then push commits and tags.\n\n## License\n\nReleased under the [MIT License][MIT-License].\n\n[Travis-CI-build-status]:         http://travis-ci.org/njonsson/harmonex                                  \"Travis CI build status for ‘Harmonex’\"\n[HexFaktor-deps-status]:          https://beta.hexfaktor.org/github/njonsson/harmonex                     \"HexFaktor dependencies status for ‘Harmonex’\"\n[Coveralls-test-coverage-status]: https://coveralls.io/r/njonsson/harmonex?branch=master                  \"Coveralls test coverage status\"\n[Hex-release]:                    https://hex.pm/packages/harmonex                                        \"Hex release of ‘Harmonex’\"\n[project-history]:                https://github.com/njonsson/harmonex/blob/master/History.md             \"‘Harmonex’ project history\"\n[fork-project]:                   https://github.com/njonsson/harmonex/fork                               \"Fork the official repository of ‘Harmonex’\"\n[compare-project-branches]:       https://github.com/njonsson/harmonex/compare                            \"Compare branches of ‘Harmonex’ repositories\"\n[mix-dot-exs-file]:               https://github.com/njonsson/harmonex/blob/master/mix.exs                \"‘Harmonex’ project ‘mix.exs’ file\"\n[Semantic-Versioning]:            http://semver.org/\n[readme-dot-md-file]:             https://github.com/njonsson/harmonex/blob/master/README.md#installation \"‘Harmonex’ project ‘README.md’ file\"\n[MIT-License]:                    http://github.com/njonsson/harmonex/blob/master/License.md              \"MIT License claim for ‘Harmonex’\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnjonsson%2Fharmonex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnjonsson%2Fharmonex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnjonsson%2Fharmonex/lists"}