{"id":13500115,"url":"https://github.com/synestematic/kord","last_synced_at":"2025-03-29T05:33:02.753Z","repository":{"id":56501130,"uuid":"305303876","full_name":"synestematic/kord","owner":"synestematic","description":"python framework for creating music applications","archived":false,"fork":false,"pushed_at":"2025-03-17T23:58:02.000Z","size":6239,"stargazers_count":380,"open_issues_count":2,"forks_count":13,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-18T00:32:36.675Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/synestematic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-19T07:48:01.000Z","updated_at":"2025-03-17T23:58:05.000Z","dependencies_parsed_at":"2024-10-31T18:31:51.347Z","dependency_job_id":"fb813544-d846-41f6-87c1-168d8422ff01","html_url":"https://github.com/synestematic/kord","commit_stats":{"total_commits":389,"total_committers":8,"mean_commits":48.625,"dds":0.5989717223650386,"last_synced_commit":"98d010b7c1a2dba32d2545b86d0f0b4423435f51"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synestematic%2Fkord","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synestematic%2Fkord/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synestematic%2Fkord/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synestematic%2Fkord/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/synestematic","download_url":"https://codeload.github.com/synestematic/kord/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246145012,"owners_count":20730494,"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","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":[],"created_at":"2024-07-31T22:00:51.415Z","updated_at":"2025-03-29T05:32:57.744Z","avatar_url":"https://github.com/synestematic.png","language":"Python","funding_links":[],"categories":["Python","\u003ca name=\"music\"\u003e\u003c/a\u003eSound and music"],"sub_categories":[],"readme":"# kord\nkord is a python framework that provides programmers with a simple api for the creation of music-based applications. While it's mainly intended for theoretical purposes, some of it's modules contain functionality specifically tailored for dealing with plucked-string instruments.\n\n![](https://github.com/synestematic/kord/blob/master/resources/chrom.png?raw=true)\n\n## installation\n\nThe only dependency for `kord` is the package `bestia`, my own library for creating command-line applications. Both can be automatically installed using pip:\n\n```\n$  python3 -m pip install kord\n```\n\nThe fretboard application component of the framework can also be run directly in a containerized form. This requires you to install 0 dependencies on your system besides docker. \n\n```\n$  docker run -t synestematic/kord  C --scale major\n```\n\nScroll to the bottom of the README for more information on the fretboard application.\n\n\n# api reference:\n\nPlease only expect to understand the following documentation if you have an above basic understanding of music theory. With that said, let's dive into the first module:\n\n\n## kord.notes\n\n### class MusicNote(object):\n\nMusicNote instances are the building blocks of the framework and have 3 main attributes:\n\n```\n* chr: str    ('C', 'D', 'E', 'F', 'G', 'A', 'B')\n* alt: str    ('bb', 'b', '', '#', '##')\n* oct: int    (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)\n```\n\nYou can set these values when creating an instance and only the `chr` argument is required. Arguments `alt` and `oct` will default to `''` and `3` respectively. These are __positional__ arguments, not keyword arguments so keep that in mind when creating your objects.\n\n```\n\u003e\u003e\u003e from kord.notes import MusicNote\n\u003e\u003e\u003e e3, f3 = MusicNote('e'), MusicNote('f')\n\u003e\u003e\u003e e3, f3\n(E³, F³) \n\u003e\u003e\u003e MusicNote('G', 'b')\nG♭³\n\u003e\u003e\u003e MusicNote('C', 9)\nC⁹\n\u003e\u003e\u003e MusicNote('B', 'b', 7)\nB♭⁷\n\u003e\u003e\u003e MusicNote('C', '#', 0)\nC♯⁰\n```\n\nNotes with double alterations are supported but Notes with triple or more alterations will raise an exception:\n\n```\n\u003e\u003e\u003e MusicNote('A', 'bb', 1)\nA𝄫¹\n\u003e\u003e\u003e MusicNote('F', '##', 1)\nF𝄪¹\n\u003e\u003e\u003e MusicNote('G', '###')\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  ...\nkord.errors.InvalidAlteration: ###\n```\n\nSimilarly, the maximum octave value currently supported is 9.\n\n```\n\u003e\u003e\u003e MusicNote('D', 10)\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  ...\nkord.errors.InvalidOctave: 10\n```\n\n### Comparing MusicNote objects:\n \nThe ```-   \u003c \u003e   \u003c= \u003e=   == !=   \u003e\u003e   ** ```  operators allow computation of semitone intervals between MusicNote instances and give insight into their enharmonic relationships. Let's take a quick look at each operator separately:\n\n#### - operator\n\nThe substraction operator lets you compute the difference in semitones between two notes:\n\n```\n\u003e\u003e\u003e f3 - e3\n1\n\u003e\u003e\u003e MusicNote('a', 'b', 2) - MusicNote('g', '#', 2)\n0\n\u003e\u003e\u003e MusicNote('a', 8) - MusicNote('c', 4)\n57\n\u003e\u003e\u003e MusicNote('a', 8) - MusicNote('c', '##', 4)\n55\n```\n\n\n####  \u003c \u003e   \u003c= \u003e=   == !=  operators\n\nComparison operators return boolean values based *exclusively* on the interval between the 2 objects. \n\n```\n\u003e\u003e\u003e f3 \u003e e3\nTrue\n\u003e\u003e\u003e f3 \u003e= e3\nTrue\n```\n\nWhile the concept is seemingly straightforward, special attention needs to be taken when using `== !=` with enharmonic notes.\n\n```\n\u003e\u003e\u003e n1 = MusicNote('F', '#', 5)\n\u003e\u003e\u003e n2 = MusicNote('G', 'b', 5)\n\u003e\u003e\u003e n1, n2\n(F♯⁵, G♭⁵)\n\u003e\u003e\u003e n1 == n2\nTrue\n```\n\nThe notes F♯⁵ and G♭⁵ are NOT the same but since their interval is a unison, the `==` comparison evaluates True. This might seem a bit counter-intuitive at first but you can still check for exact note matches with the use of 2 other operators.\n\n#### \u003e\u003e ** operators\n\nThe power and right-shift operators allow you to compare Notes for equality based not on their intervals, but on their intrinsic `chr`, `alt`, `oct` properties. The strictest operator `\u003e\u003e` compares all 3 attributes for equality while the looser `**` ignores `oct`: \n\n```\n\u003e\u003e\u003e ab1, ab5 = MusicNote('A', 'b', 1),  MusicNote('A', 'b', 5)\n\u003e\u003e\u003e ab1 == ab5\nFalse\n\u003e\u003e\u003e ab1 ** ab5\nTrue\n```\n\nNotice `**` evaluates True since both instances are A flat notes, even when there is a wide interval between them.\n\n```\n\u003e\u003e\u003e ab1 \u003e\u003e ab5\nFalse\n\u003e\u003e\u003e ab1.oct = 5\n\u003e\u003e\u003e ab1 \u003e\u003e ab5\nTrue\n```\n\nFor the `\u003e\u003e` operator to evaluate True, the octaves of the notes must match as well.\n\n\n\u003chr/\u003e\n\n\n\n\n## kord.keys\n\n\n### class MusicKey(object):\n\nThink of MusicKey objects as generators of MusicNote objects. You can define a new class which inherits MusicKey and use any theoretical arrangement of `intervals` from the root note in order to create chords, scales, modes, etc. You can further taylor these child classes by restricting `degrees` to specific values, this is very useful for creating chords.\n\nThese are a couple of pre-defined examples to give you an idea of how it works:\n\n```\nclass ChromaticScale(MusicKey):\n    intervals = (\n        UNISON,\n        MINOR_SECOND,\n        MAJOR_SECOND,\n        MINOR_THIRD,\n        MAJOR_THIRD,\n        PERFECT_FOURTH,\n        AUGMENTED_FOURTH,\n        PERFECT_FIFTH,\n        MINOR_SIXTH,\n        MAJOR_SIXTH,\n        MINOR_SEVENTH,\n        MAJOR_SEVENTH,\n    )\n\nclass MajorScale(MusicKey):\n    intervals = (\n        UNISON,\n        MAJOR_SECOND,\n        MAJOR_THIRD,\n        PERFECT_FOURTH,\n        PERFECT_FIFTH,\n        MAJOR_SIXTH,\n        MAJOR_SEVENTH,\n    )\n    \nclass MajorPentatonicScale(MajorScale):\n    degrees = (1, 2, 3, 5, 6)\n\nclass MajorTriad(MajorScale):\n    degrees = (1, 3, 5)\n```\n\nBare in mind that MusicKey objects are initialized with `chr` and `alt` attributes, `oct` values are not taken into consideration. These allows us to simply unpack MusicNote objects in order to create MusicKey instances based off of them. Once we have a MusicKey object, we can access it's single degrees using list index notation:\n\n```\n\u003e\u003e\u003e from kord.keys import ChromaticScale\n\u003e\u003e\u003e c = MusicNote('C')\n\u003e\u003e\u003e c_chromatic_scale = ChromaticScale(*c)\n\u003e\u003e\u003e c_chromatic_scale[2]\nC♯⁰\n\u003e\u003e\u003e c_chromatic_scale[12]\nB⁰\n```\n\n### MusicKey.spell()\n\nRetrieving individual degrees is good, but it is perhaps more interesting to look at a more dynamic way of getting notes out of our MusicKey instances. The `spell()` method provides such an interface for generating MusicNote instances on the fly. Let's take a look at a couple of examples and the several arguments that we can use when calling this method:\n\n```\n\u003e\u003e\u003e for note in c_chromatic_scale.spell():\n...     print(note, end=' ')\n...\nC⁰ C♯⁰ D⁰ D♯⁰ E⁰ F⁰ F♯⁰ G⁰ G♯⁰ A⁰ A♯⁰ B⁰ C¹ \u003e\u003e\u003e \n```\n\nAs seen above the method will generate the first octave of degrees of the object when called without arguments.\n\nThe `note_count` argument is an `int` and it allows us to set a specific amount of notes to retrieve:\n\n```\n\u003e\u003e\u003e from kord.keys import MinorScale\n\u003e\u003e\u003e a_minor_scale = MinorScale('A')\n\u003e\u003e\u003e for note in a_minor_scale.spell(note_count=4):\n...     print(note, end=' ')\n...\nA⁰ B⁰ C¹ D¹ \u003e\u003e\u003e \n```\n\nBe careful, ask for too many notes and kord will throw and Exception when `oct` 9 has been exceeded.\n\nThe `yield_all` argument is a `bool` that will make the method yield not just `MusicNote` instances, but also `None` objects for every non-diatonic semitone found:\n\n```\n\u003e\u003e\u003e for note in a_minor_scale.spell(note_count=4, yield_all=True):\n...     print(note, end=' ')\n...\nA⁰ None B⁰ C¹ None D¹ \u003e\u003e\u003e \n```\n\n\nThe `start_note` argument is a `MusicNote` object that can be used to start getting notes only after a specific note has been found. This can be done even if the note is not diatonic to the scale:\n\n```\n\u003e\u003e\u003e Db1 = MusicNote('D', 'b', 1)\n\u003e\u003e\u003e for note in a_minor_scale.spell(note_count=4, yield_all=True, start_note=Db1):\n...     print(note, end=' ')\n...\nNone D¹ None E¹ F¹ None G¹ \u003e\u003e\u003e \n```\n\n\n\n## fretboard tool\n\nA sample application `fretboard.py` comes built-in with `kord` and gives some insight into the possibilities of the framework. It displays a representation of your instrument's fretboard, tuned to your liking along with note patterns for any given mode (scale/chord) for any given root note. \n\nIf you installed via pip (as opposed to cloning this repo) installation path will depend on your system, it's usually something like `/usr/local/fretboard` or `~/.local/fretboard`. You will also find a `tunings` directory with some pre-defined instrument tunings in the form of .json files. Feel free to modify them or add your own and they should immediately become available to the run-time.\n\n```\n$  python3 fretboard.py --help\nusage: fretboard.py [-h] [-d] [-s  | -c ] [-i] [-t] [-f] [-v] root\n\n\u003c\u003c\u003c Fretboard visualizer sample tool for the kord music framework \u003e\u003e\u003e\n\npositional arguments:\n  root                select key ROOT note\n\noptional arguments:\n  -h, --help          show this help message and exit\n  -d, --degrees       show degree numbers instead of note pitches\n  -s , --scale        major, minor, melodic_minor, harmonic_minor, major_pentatonic, minor_pentatonic,\n                      ionian, lydian, mixolydian, aeolian, dorian, phrygian, locrian, chromatic\n  -c , --chord        maj, min, aug, dim, maj7, min7, 7, dim7, min7dim5, maj9, min9, 9\n  -i , --instrument   banjo, guitar, pedal, bass, ukulele\n  -t , --tuning       check .json files for available options\n  -f , --frets        1, 2, .., 36\n  -v , --verbosity    0, 1, 2\n```\n\nThe only required parameter is the `root` note. \n\nThe `--scale` and `--chord` options let you choose which note pattern to display for the selected root. They are mutually exclusive and the default value is `--chord maj` when left blank.\n\nThe `--instrument` and `--tuning` options refer to the json files you will find in the tunings directory. Default values are `--instrument guitar   --tuning standard`.\n\nThe `--frets` option let's you choose how many frets to visualize, maximum value is 36. Default value will fill your terminal screen.\n\nThe `--verbosity` option let's you choose how much information to see on-screen from 0 to 2. Default value is 1.\n\nThe `--degrees` option let's you display degree numbers instead of notes. Default value is false.\n\n\n## screenshots\n\nHere are a couple of pics to get you excited:\n\n### chords\n\n![](https://github.com/synestematic/kord/blob/master/resources/e7.png?raw=true)\n\n![](https://github.com/synestematic/kord/blob/master/resources/dim7.png?raw=true)\n\n### scales\n\n![](https://github.com/synestematic/kord/blob/master/resources/penta.png?raw=true)\n\n![](https://github.com/synestematic/kord/blob/master/resources/cs.png?raw=true)\n\n![](https://github.com/synestematic/kord/blob/master/resources/lydian.png?raw=true)\n\n\nKeep on rocking!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynestematic%2Fkord","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsynestematic%2Fkord","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynestematic%2Fkord/lists"}