{"id":13433983,"url":"https://github.com/saebekassebil/teoria","last_synced_at":"2025-10-22T14:36:18.823Z","repository":{"id":1849873,"uuid":"2774613","full_name":"saebekassebil/teoria","owner":"saebekassebil","description":"Javascript taught Music Theory","archived":false,"fork":false,"pushed_at":"2019-12-01T00:57:13.000Z","size":449,"stargazers_count":1317,"open_issues_count":25,"forks_count":114,"subscribers_count":61,"default_branch":"master","last_synced_at":"2024-10-01T00:57:35.686Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://saebekassebil.github.io/teoria","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"effektif/react-mentions","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/saebekassebil.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}},"created_at":"2011-11-14T19:28:53.000Z","updated_at":"2024-09-27T13:59:37.000Z","dependencies_parsed_at":"2022-08-25T12:00:58.366Z","dependency_job_id":null,"html_url":"https://github.com/saebekassebil/teoria","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saebekassebil%2Fteoria","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saebekassebil%2Fteoria/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saebekassebil%2Fteoria/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saebekassebil%2Fteoria/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/saebekassebil","download_url":"https://codeload.github.com/saebekassebil/teoria/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221691252,"owners_count":16864551,"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-31T02:01:41.995Z","updated_at":"2025-10-22T14:36:13.789Z","avatar_url":"https://github.com/saebekassebil.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Sound creation","Libraries for Devs"],"sub_categories":["Instrument recordings","Javascript"],"readme":"Teoria.js\n=========\n\nTeoria.js is a lightweight and fast JavaScript library\nfor music theory, both Jazz and Classical. It aims at providing an intuitive\nprogramming interface for music software (such as Sheet Readers,\nSheet Writers, MIDI Players etc.).\n\nFeatures\n---------\n\n - A note object (`teoria.Note`), which understands alterations, octaves,\n key number, frequency and etc. and Helmholtz notation\n\n - A chord object (`teoria.Chord`), which understands everything\n from simple major/minor chords to advanced Jazz chords (Ab#5b9, F(#11) and such)\n\n - A scale object (`teoria.Scale`), The scale object is a powerful presentation of\n a scale, which supports quite a few handy methods. A scale can either be\n constructed from the predefined scales, which by default contains the 7 modes\n (Ionian, Dorian, Phrygian etc.) a major and minor pentatonic and the harmonic\n chromatic scale or from an arbitrary array of intervals. The scale object\n also supports solfège, which makes it perfect for tutorials on sight-reading.\n\n - An interval object (`teoria.Interval`), which makes it easy to find the\n interval between two notes, or find a note that is a given interval from a note.\n There's also support for counting the interval span in semitones and inverting the\n interval.\n\nUsage\n--------\n\n    $ npm install teoria\n\nCan be used with both Node and Browserify/webpack/etc.\n\n### ... or less preferable\n\nInclude the bundled build file, `teoria.js` from this repository, directly:\n```html\n\u003cscript src=\"path/to/teoria.js\"\u003e\u003c/script\u003e\n```\nSyntax\n---------\n\nThis is just a short introduction to what teoria-code looks like,\nfor a technical library reference, look further down this document.\n\n```javascript\n\n// Create notes:\nvar a4 = teoria.note('a4');       // Scientific notation\nvar g5 = teoria.note(\"g''\");      // Helmholtz notation\nvar c3 = teoria.note.fromKey(28); // From a piano key number\n\n// Find and create notes based on intervals\nteoria.interval(a4, g5);    // Returns a Interval object representing a minor seventh\nteoria.interval(a4, 'M6');  // Returns a Note representing F#5\na4.interval('m3');          // Returns a Note representing C#4\na4.interval(g5);            // Returns a Interval object representing a minor seventh\na4.interval(teoria.note('bb5')).invert(); // Returns a Interval representing a major seventh\n\n// Create scales, based on notes.\na4.scale('mixolydian').simple();  // Returns: [\"a\", \"b\", \"c#\", \"d\", \"e\", \"f#\", \"g\"]\na4.scale('aeolian').simple();     // Returns: [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"]\ng5.scale('ionian').simple();      // Returns: [\"g\", \"a\", \"b\", \"c\", \"d\", \"e\", \"f#\"]\ng5.scale('dorian');               // Returns a Scale object\n\n// Create chords with the powerful chord parser\na4.chord('sus2').name;    // Returns the name of the chord: 'Asus2'\nc3.chord('m').name;       // Returns 'Cm'\nteoria.chord('Ab#5b9');   // Returns a Chord object, representing a Ab#5b9 chord\ng5.chord('dim');          // Returns a Chord object, representing a Gdim chord\n\n// Calculate note frequencies or find the note corresponding to a frequency\nteoria.note.fromFrequency(467); // Returns: {'note':{...},'cents':3.102831} -\u003e A4# a little out of tune.\na4.fq(); // Outputs 440\ng5.fq(); // Outputs 783.9908719634985\n\n// teoria allows for crazy chaining:\nteoria.note('a')    // Create a note, A3\n  .scale('lydian')  // Create a lydian scale with that note as root (A lydian)\n  .interval('M2')   // Transpose the whole scale a major second up (B lydian)\n  .get('third')     // Get the third note of the scale (D#4)\n  .chord('maj9')    // Create a maj9 chord with that note as root (D#maj9)\n  .toString();      // Make a string representation: 'D#maj9'\n```\n\nDocumentation\n------------------------\n\n## teoria.note (name | coord[, duration])\n\n*name* - The name argument is the note name as a string. The note can both\nbe expressed in scientific and Helmholtz notation.\nSome examples of valid note names: `Eb4`, `C#,,`, `C4`, `d#''`, `Ab2`\n\n*coord* - If the first argument isn't a string, but a coord array,\nit will instantiate a `Note` instance.\n\n*duration* - The duration argument is an optional `object` argument.\nThe object has two also optional parameters:\n\n - `value` - A `number` corresponding to the value of the duration, such that:\n`1 = whole`, `2 = half (minim)`, `4 = quarter`, `8 = eight`\n\n - `dots` - The number of dots attached to the note. Defaults to `0`.\n\n### teoria.note.fromKey(key)\nA static method that returns an instance of Note set to the note\nat the given piano key, where A0 is key number 1.\nSee [Wikipedia's piano key article](http://en.wikipedia.org/wiki/Piano_key_frequencies)\nfor more information.\n\n### teoria.note.fromFrequency(fq)\nA static method returns an object containing two elements:\n\n*note* - A `Note` which corresponds to the closest note with the given frequency\n\n*cents* - A number value of how many cents the note is out of tune\n\n### teoria.note.fromMIDI(note)\n - Returns an instance of Note set to the corresponding MIDI note value.\n\n*note* - A number ranging from 0-127 representing a MIDI note value\n\n### teoria.note.fromString(note)\n - Returns an instance of Note representing the note name\n\n*note* - The name argument is the note name as a string. The note can both\nbe expressed in scientific and Helmholtz notation.\nSome examples of valid note names: `Eb4`, `C#,,`, `C4`, `d#''`, `Ab2`\n\n#### Note.name()\n - The name of the note, in lowercase letter (*only* the name, not the\n accidental signs)\n\n#### Note.octave()\n - The numeric value of the octave of the note\n\n#### Note.duration\n - The duration object as described in the constructor for Note\n\n#### Note.accidental()\n - Returns the string symbolic of the accidental sign (`x`, `#`, `b` or `bb`)\n\n#### Note.accidentalValue()\n - Returns the numeric value (mostly used internally) of the sign:\n`x = 2, # = 1, b = -1, bb = -2`\n\n#### Note#key([whitenotes])\n - Returns the piano key number. E.g. A4 would return 49\n\n*whitenotes* - If this parameter is set to `true` only the white keys will\nbe counted when finding the key number. This is mostly for internal use.\n\n#### Note#midi()\n - Returns a number ranging from 0-127 representing a MIDI note value\n\n#### Note#fq([concertPitch])\n - Calculates and returns the frequency of the note.\n\n*concertPitch* - If supplied this number will be used instead of the normal\nconcert pitch which is 440hz. This is useful for some classical music.\n\n#### Note#chroma()\n - Returns the pitch class (index) of the note.\n\nThis allows for easy enharmonic checking:\n\n    teoria.note('e').chroma() === teoria.note('fb').chroma();\n\nThe chroma number is ranging from pitch class C which is 0 to 11 which is B\n\n#### Note#scale(scaleName)\n - Returns an instance of Scale, with the tonic/root set to this note.\n\n*scaleName* - The name of the scale to be returned. `'minor'`,\n`'chromatic'`, `'ionian'` and others are valid scale names.\n\n#### Note#interval(interval)\n - A sugar function for calling teoria.interval(note, interval);\n\nLook at the documentation for `teoria.interval`\n\n#### Note#transpose(interval)\n - Like the `#interval` method, but changes `this` note, instead of returning a new\n\n#### Note#chord([name])\n - Returns an instance of Chord, with root note set to this note\n\n*name* - The name attribute is the last part of the chord symbol.\nExamples: `'m7'`, `'#5b9'`, `'major'`. If the name parameter\nisn't set, a standard major chord will be returned.\n\n#### Note#helmholtz()\n - Returns the note name formatted in Helmholtz notation.\n\nExample: `teoria.note('A5').helmholtz() -\u003e \"a''\"`\n\n#### Note#scientific()\n - Returns the note name formatted in scientific notation.\n\nExample: `teoria.note(\"ab'\").scientific() -\u003e \"Ab4\"`\n\n#### Note#enharmonics(oneAccidental)\n - Returns all notes that are enharmonic with the note\n\n*oneAccidental* - Boolean, if set to true, only enharmonic notes with one\naccidental is returned. E.g. results such as 'eb' and 'c#' but not 'ebb' and 'cx'\n\n```javascript\nteoria.note('c').enharmonics().toString();\n// -\u003e 'dbb, b#'\n\nteoria.note('c').enharmonics(true).toString();\n// -\u003e 'b#'\n```\n\n#### Note#durationInSeconds(bpm, beatUnit)\n - Returns the duration of the note, given a tempo (in bpm) and a beat unit\n (the lower numeral of the time signature)\n\n#### Note#solfege(scale, showOctaves)\n - Returns the solfege step in the given scale context\n\n*scale* - An instance of `Scale`, which is the context of the solfege step measuring\n\n*showOctaves* - A boolean. If set to true, a \"Helmholtz-like\" notation will be\nused if there's bigger intervals than an octave\n\n#### Note#durationName()\n - Returns the duration name.\n\nExamples: `teoria.note('A', 8).durationName() -\u003e 'eighth'`,\n`teoria.note('C', 16).durationName() -\u003e 'sixteenth'`\n\n#### Note#scaleDegree(scale)\n - Returns this note's degree in a given scale (Scale). For example a\n `D` in a C major scale will return `2` as it is the second degree of that scale.\n If however the note *isn't* a part of the scale, the degree returned will be\n `0`, meaning that the degree doesn't exist. This allows this method to be both\n a scale degree index finder *and* an \"isNoteInScale\" method.\n\n*scale* - An instance of `Scale` which is the context of the degree measuring\n\n#### Note#toString([dontShow])\n - Usability function for returning the note as a string\n\n*dontShow* - If set to `true` the octave will not be included in the returned string.\n\n## Chord(root, chord)\n - A chord class with a lot of functionality to alter and analyze the chord.\n\n*root* - A `Note` instance which is to be the root of the chord\n\n*chord* - A string containing the chord symbol. This can be anything from\nsimple chords, to super-advanced jazz chords thanks to the detailed and\nrobust chord parser engine. Example values:\n`'m'`, `'m7'`, `'#5b9'`, `'9sus4` and `'#11b5#9'`\n\n### teoria.chord(name || note[, octave || symbol])\n - A simple function for getting the notes, no matter the octave, in a chord\n\n*name* - A string containing the full chord symbol, with note name. Examples:\n`'Ab7'`, `'F#(#11b5)'`\n\n*note* - Instead of supplying a string containing the full chord symbol,\none can pass a `Note` object instead. The note will be considered root in\nthe new chord object\n\n*octave* - If the first argument of the function is a chord name (`typeof \"string\"`),\nthen the second argument is an optional octave number (`typeof \"number\"`) of the root.\n\n*symbol* - A string containing the chord symbol (excluding the note name)\n\n#### Chord.name\n - Holds the full chord symbol, inclusive the root name.\n\n#### Chord.root\n - Holds the `Note` that is the root of the chord.\n\n#### Chord#notes()\n - Returns an array of `Note`s that the chord consists of.\n\n#### Chord#simple()\n - Returns an `Array` of only the notes' names, not the full `Note` objects.\n\n#### Chord#bass()\n - Returns the bass note of the chord (The note voiced the lowest)\n\n#### Chord#voicing([voicing])\n - Works both as a setter and getter. If no parameter is supplied the\n current voicing is returned as an array of `Interval`s\n\n*voicing* - An optional array of intervals in simple-format\nthat represents the current voicing of the chord.\n\nHere's an example:\n```javascript\nvar bbmaj = teoria.chord('Bbmaj7');\n// Default voicing:\nbbmaj.voicing();  // #-\u003e ['P1', 'M3', 'P5', 'M7'];\nbbmaj.notes();    // #-\u003e ['bb', 'd', 'f', 'a'];\n\n// New voicing\nbbmaj.voicing(['P1', 'P5', 'M7', 'M10']);\nbbmaj.notes();    // #-\u003e ['bb', 'f', 'a', 'd'];\n```\n*NB:* Note that above returned results are pseudo-results, as they will be\nreturned wrapped in `Interval` and `Note` objects.\n\n#### Chord#quality()\n - Returns a string which holds the quality of the chord, `'major'`, `'minor'`,\n `'augmented'`, `'diminished'`, `'half-diminished'`, `'dominant'` or `undefined`\n\n#### Chord#get(interval)\n - Returns the note at a given interval in the chord, if it exists.\n\n*interval* - A string name of an interval, for example `'third'`, `'fifth'`, `'ninth'`.\n\n#### Chord#dominant([additional])\n - Returns the naïvely chosen dominant which is a perfect fifth away.\n\n*additional* - Additional chord extension, for example: `'b9'` or `'#5'`\n\n#### Chord#subdominant([additional])\n - Returns the naïvely chosen subdominant which is a perfect fourth away.\n\n*additional* - Like the dominant's.\n\n#### Chord#parallel([additional])\n - Returns the parallel chord for major and minor triads\n\n*additional* - Like the dominant's\n\n#### Chord#chordType()\n - Returns the type of the chord: `'dyad'`, `'triad'`, `'trichord'`,\n `'tetrad'` or `'unknown'`.\n\n#### Chord#interval(interval)\n - Returns the same chord, a `interval` away\n\n#### Chord#transpose(interval)\n - Like the `#interval` method, except it's `this` chord that gets changed instead of\n returning a new chord.\n\n#### Chord#toString()\n - Simple usability function which is an alias for Chord.name\n\n\n## Scale(tonic, scale)\n - The teoria representation of a scale, with a given tonic.\n\n*tonic* - A `Note` which is to be the tonic of the scale\n\n*scale* - Can either be a name of a scale (string), or an array of\nabsolute intervals that defines the scale. The scales supported by default are:\n\n - major\n - minor\n - ionian (Alias for major)\n - dorian\n - phrygian\n - lydian\n - mixolydian\n - aeolian (Alias for minor)\n - locrian\n - majorpentatonic\n - minorpentatonic\n - chromatic\n - harmonicchromatic (Alias for chromatic)\n - blues\n - doubleharmonic\n - flamenco\n - harmonicminor\n - melodicminor\n - wholetone\n\n### teoria.scale(tonic, scale)\n - Sugar function for constructing a new `Scale` object\n\n#### teoria.Scale.KNOWN_SCALES\n - An array of all the scale ID's that comes with teoria\n\n#### Scale.name\n - The name of the scale (if available). Type `string` or `undefined`\n\n#### Scale.tonic\n - The `Note` which is the scale's tonic\n\n#### Scale#notes()\n - Returns an array of `Note`s which is the scale's notes\n\n#### Scale#simple()\n - Returns an `Array` of only the notes' names, not the full `Note` objects.\n\n#### Scale#type()\n - Returns the type of the scale, depending on the number of notes.\n A scale of length x gives y:\n  - 2 gives 'ditonic'\n  - 3 gives 'tritonic'\n  - 4 gives 'tetratonic'\n  - 5 gives 'pentatonic'\n  - 6 gives 'hexatonic',\n  - 7 gives 'heptatonic',\n  - 8 gives 'octatonic'\n\n#### Scale#get(index)\n - Returns the note at the given scale index\n\n*index* - Can be a number referring to the scale step, or the name (string) of the\nscale step. E.g. 'first', 'second', 'fourth', 'seventh'.\n\n#### Scale#solfege(index, showOctaves)\n - Returns the solfege name of the given scale step\n\n*index* Same as `Scale#get`\n\n*showOctaves* - A boolean meaning the same as `showOctaves` in `Note#solfege`\n\n\n## teoria.interval(from, to)\n - A sugar function for the `#from` and `#between` methods of the same namespace and\n for creating `Interval` objects.\n\n#### teoria.interval(`string`: from)\n - A sugar method for the `Interval.toCoord` function\n\n#### teoria.interval(`Note`: from, `string`: to)\n - A sugar method for the `Interval.from` function\n\n#### teoria.interval(`Note`: from, `Interval`: to)\n - Like above, but with a `Interval` instead of a string representation of\n the interval\n\n#### teoria.interval(`Note`: from, `Note`: to)\n - A sugar method for the `Interval.between` function\n\n##### teoria.interval.from -\u003e Interval.from\n##### teoria.interval.between -\u003e Interval.between\n##### teoria.interval.invert -\u003e Interval.invert\n##### teoria.interval.toCoord -\u003e Interval.toCoord\n\n\n## Interval(coord)\n - A representation of a music interval\n\n### Interval.toCoord(simpleInterval)\n - Returns a `Interval` representing the interval expressed in string form.\n\n### Interval.from(from, to)\n - Returns a note which is a given interval away from a root note.\n\n*from* - The `Note` which is the root of the measuring\n\n*to* - A `Interval`\n\n### Interval.between(from, to)\n - Returns an interval object which represents the interval between two notes.\n\n*from* and *to* are two `Note`s which are the notes that the\ninterval is measured from. For example if 'a' and 'c' are given, the resulting\ninterval object would represent a minor third.\n\n```javascript\nInterval.between(teoria.note(\"a\"), teoria.note(\"c'\")) -\u003e teoria.interval('m3')\n```\n\n### Interval.invert(simpleInterval)\n - Returns the inversion of the interval provided\n\n*simpleInterval* - An interval represented in simple string form. Examples:\n\n - 'm3' = minor third\n - 'P4' = perfect fourth\n - 'A4' = augmented fifth\n - 'd7' = diminished seventh\n - 'M6' = major sixth.\n\n`'m' = minor`, `'M' = major`, `'A' = augmented` and\n`'d' = diminished`\n\nThe number may be prefixed with a `-` to signify that its direction is down. E.g.:\n\n`m-3` means a descending minor third, and `P-5` means a descending perfect fifth.\n\n#### Interval.coord\n - The interval representation of the interval\n\n#### Interval.number()\n - The interval number (A ninth = 9, A seventh = 7, fifteenth = 15)\n\n#### Interval.value()\n - The value of the interval - That is a ninth = 9, but a downwards ninth is = -9\n\n#### Interval.toString()\n - Returns the *simpleInterval* representation of the interval. E.g. `'P5'`,\n `'M3'`, `'A9'`, etc.\n\n#### Interval.base()\n - Returns the name of the simple interval (not compound)\n\n#### Interval.type()\n - Returns the type of array, either `'perfect'` (1, 4, 5, 8) or `'minor'` (2, 3, 6, 7)\n\n#### Interval.quality([verbose])\n - The quality of the interval (`'dd'`, `'d'` `'m'`, `'P'`, `'M'`, `'A'` or `'AA'`)\n\n*verbose*  is set to a truish value, then long quality names are returned:\n `'doubly diminished'`, `'diminished'`, `'minor'`, etc.\n\n#### Interval.direction([dir])\n - The direction of the interval\n\n*dir* - If supplied, then the interval's direction is to the `newDirection`\nwhich is either `'up'` or `'down'`\n\n#### Interval#semitones()\n - Returns the `number` of semitones the interval span.\n\n#### Interval#simple([ignoreDirection])\n - Returns the simple part of the interval as a Interval. Example:\n\n*ignoreDirection* - An optional boolean that, if set to `true`, returns the\n\"direction-agnostic\" interval. That is the interval with a positive number.\n\n```javascript\nteoria.interval('M17').simple();    // #-\u003e 'M3'\nteoria.interval('m23').simple();    // #-\u003e 'm2'\nteoria.interval('P5').simple();     // #-\u003e 'P5'\nteoria.interval('P-4').simple();    // #-\u003e 'P-4'\n\n// With ignoreDirection = true\nteoria.interval('M3').simple(true);     // #-\u003e'M3'\nteoria.interval('m-10').simple(true);   // #-\u003e 'm3'\n```\n\n*NB:* Note that above returned results are pseudo-results, as they will be\nreturned wrapped in `Interval` objects.\n\n#### Interval#octaves()\n - Returns the number of compound intervals\n\n#### Interval#isCompound()\n - Returns a boolean value, showing if the interval is a compound interval\n\n#### Interval#add(interval)\n - Adds the `interval` to this interval, and returns a `Interval`\n representing the result of the addition\n\n#### Interval#equal(interval)\n - Returns true if the supplied `interval` is equal to this interval\n\n#### Interval#greater(interval)\n - Returns true if the supplied `interval` is greater than this interval\n\n#### Interval#smaller(interval)\n - Returns true if the supplied `interval` is smaller than this interval\n\n#### Interval#invert()\n - Returns the inverted interval as a `Interval`\n\n#### Interval#qualityValue() - *internal*\n - Returns the relative to default, value of the quality.\n E.g. a teoria.interval('M6'), will have a relative quality value of 1, as all the\n intervals defaults to minor and perfect respectively.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaebekassebil%2Fteoria","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaebekassebil%2Fteoria","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaebekassebil%2Fteoria/lists"}