
MUSIC.js is a music creation library containing functions and data sets to generate notes, intervals, chords, and scales.
With the new client-side script APIs (Firefox’s Audio Data API and Webkit’s Web Audio API) we have the ability to do audio synthesis (generate sound) with javascript. MUSIC.js is designed to make it easier to do audio synthesis with javascript by providing functionality for frequency calculations and transposing notes.
How it works
Piers Titus and I worked together to design MUSIC.js to provide a clean syntax for defining and managing notes. Piers is the brains behind the music theory involved in this library. Currently MUSIC.js only uses twelve-tone equal temperament tuning since its the most popular tuning and the easiest to implement. The library is built with flexibility in mind to support other tunings. MUSIC.js is currently a work in progress.
Notes
The Circle of Fifths is used to define notes in MUSIC.js. The main benefits of using the Circle of Fifths are that it gives us the ability to distinguish sharps and flats, and that it makes calculations such as transposing and frequency calculation very easy. We define notes as two valued coordinates [octave, fifth] based on the number of octaves and fifths relative to the ‘main note’. The D note at octave 0 is used as the ‘main note’ in MUSIC.js since it is the center of the circle of fifths (F-C-G-D-A-E-B). All notes are defined by their distance from this main note. Lets take a look at an example:
Circle of Fifths Chart w/ the D note highlighted

Since D0 is our main note it has the coordinate of [0, 0]. The note A is a fifth from D so A0 has the coordinate [0, 1]. The note E is two fifths away from D and requires us to use the octave coordinate to define E0. Since E1 would be [0, 2] we need to drop one octave to get E0 which is [-1, 2].
The note A4 has a nice frequency of 440 and is used as the base frequency. In order to use A4 as the base frequency a base offset coordinate is added ([4, 1]) to change the ‘main note’ from D0 to A4. Make sense? If not, don’t worry because MUSIC.js handles this logic so you don’t have to.
Here is the syntax to use for defining notes with MUSIC.js:
var n = Note.fromLatin('A4'); console.log(n); //prints ({coord:[0, 0]}) //getters var freq = n.frequency(); // returns 440 var noteName = n.latin(); // returns "A" var octave = n.octave(); // returns 4
The coordinate is the only attribute stored for a note object. All other note attributes like frequency, latin name, and octave are calculated upon request.
Intervals
Intervals measure the distance between two notes and are used by MUSIC.js to define chords and scales. Intervals can be defined by name (ex: “major third”, “fifth”, etc…), by number of semitones, or by the coordinate directly. MUSIC.js also contains add() and subtract() methods for transposing notes and chords with an interval.
var c = Note.fromLatin('C3'); // by semitone var wholeStep = Interval.fromSemitones(2); var d = c.add(wholeStep); console.log(d.latin()); // "D" // by interval name var g = c.add('fifth'); console.log(g.latin()); // "G"
Chords
Chords are defined by an array of note objects. Chords can be created using intervals or note names.
// by intervals var c = Note.fromLatin('C4'); var cmaj = c.add(['unison','major third','fifth']); // or by note names var cmaj = Note.fromLatin('C4E4G4'); // then loop through chord array for each note object for (var i = 0; i < cmaj.length; i++) { console.log(cmaj[i].frequency()); }
Scales
MUSIC.js contains a library of scales that are accessed based on the scale name (ex: ‘major’, ‘harmonic minor’, etc…). A scale returns an array of note objects.
var n = Note.fromLatin('C4'); var majorScale = n.scale('major'); // then loop through scale array for each note object for (var i = 0; i < majorScale.length; i++) { console.log(majorScale[i].frequency()); }
Future of MUSIC.js
The goal for MUSIC.js is to keep it independent from the Audio APIs. This way a modular design can be used for synthesizing audio. MUSIC.js can be responsible for creating the music and a music synthesizer module can be responsible for actually generating the sound data. With this design one synthesizer could be easily swapped out for another.
Right now MUSIC.js is an incomplete music creation library. It can create notes, chords, and scales but can’t define note duration, sequence, volume, etc… I am not sure if this functionality should be included in MUSIC.js or in a separate library. Perhaps a library containing a Song class composed of Tracks and Tracks composed of Notes.
The MusicXML format does a good job with storing music notation and has become the standard format for sharing sheet music between notation software. However, MusicXML files for complex songs can become quite large and can take a while to parse with javascript. Now that we can render music notation with javascript (ex: alphatab.net) and we can synthesize audio with javascript it makes sense to store music notation with JSON instead of XML. The JSON format is more lightweight and easier to parse with javascript. Perhaps MUSIC.js could be part of a solution for processing music notation in a JSON format.
Leave a comment and let me know what you think of MUSIC.js.
19 Comments
Trackbacks
- Web Audio – It is finally (almost) here? | pixelpusher :: pixel performance and art
- The digits of MUSIC.js » By Dave Mahon » article » Ajax Bestiary


Hi,
This looks very interesting!
I don’t know if you heard of it before, but VexFlow is also another way of visualising music in a browser (http://www.vexflow.com/). There might be some common music related code that could be usefull.
Wow, I had no idea that VexFlow has its own Music Theory API. That’s awesome. Thanks for pointing this out. A lot of great improvements have been added to VexFlow over the last couple months and I am glad to see that VexFlow is being actively developed. There is some overlap between the two apis and I definitely need to look into this in more detail.
This looks very nice.
I must admit from the title I did think you might be calculating the frequency of audio from a given sample, which is actually something I’m personally very interested in, especially speech analysis.
You mention being audio API agnostic. I’m not sure whether you’ve heard of https://github.com/jussi-kalliokoski/audiolib.js#readme Might be useful to you.
Keep up the good work!
Thanks for the kind words. I agree that the title is a bit misleading with using the words “calculating frequency” since that commonly refers to processing audio and calculating FFT spectrum data. Music.js is a music creation library for audio synthesis and doesn’t have any functionality for audio processing.
I have seen Jussi’s audiolib.js library and its pretty awesome since it works with both audio apis and includes a bunch of features to make audio synthesis easier. I plan on using it in my next audio project.
This looks fantastic – great job! I’m a musician and Javascript enthusiast.. so I’m pretty much hooked.
I’m gonna get to know the source code and see if I can contribute anything.
Joss
Awesome. Let me know if you have any questions about source code. There is a lot more work that can be done with music.js. Like creating a wrapper class for it to store complete musical scores like musicxml but using json instead of xml. Or creating a standardized way to implement synthesizers with it and audiolib.js.
I’m not a professional developer, but I did have this – json – thought as well. MusicXML is a great way to store notated scores to allow sharing between different notation programs, but it sucks as an intuitive interface for dealing with music, well musically. I wold love to talk to you some time about this idea and how it might be used with VexFlow. Having the ability to store a score in json would be totally awesome an not just for the web community. MaxMSP uses a ton of Javascript internally, so having that data readily available would be spectacular.
Hit me back, violoncello [at] gmail
Awesome. I will private message you and we can talk about starting a MusicJSON project.
This is really funny, I started quite some time ago, thinking about developing a music engraver in JavaScript, and even started! But then I found VexFlow and I dismissed my project, though I’m not nearly satisfied with VexFlow. So after some time I started again, and began thinking about the representation of the music and I looked at several different fileformats, including MusicXML, which I decided to use and made my “MusicJSON” which is just a translation of MusicXML. I haven’t worked on this project for quite a long time now, but I found this site because I’m developing a music theory library in JavaScript too and would check out if there was already existing such.
My framework, teoria.js (https://github.com/saebekassebil/teoria), uses another approach to the problem. First I do not like the way your library and others I’ve found have a “lookup” table for notes with sharps and flats. It’s seems wrong to me and “un-generic”. Still since I, yesterday, found your music.js, I’ve made some changes to teoria.js. I really like the style your “object” can interact, and be used in different ways!
I too would like to participate in such a project, but with the background information I’ve collected from LilyPonds developers it’s *really* hard to make a properly working sheet engraver. And from MusicXML that it is *really-really* hard to define a fileformat that can express the many diversities of sheet music.
Bottomline is, I’m very interested in starting such a project, but only with the right infrastructure of classes, and the right approach, which I think VexFlow lacks.
I’m glad you like how the Note class is designed in music.js. I will definitely check out your music theory library and your MusicJSON project. They both sound awesome!
I agree that there is a huge need for a js sheet music engraver library and have decided to support and contribute to VexFlow. VexFlow is evolving into a great library and I think you should give it another chance. We are currently redesigning many of the classes in Vexflow to improve the formatter and the syntax (read more about this redesign here: https://github.com/0xfe/vexflow/issues/23).
VexFlow is still alpha and Mohit (author of VexFlow) is open to suggestions for improvements. You should open up an issue on GitHub with your suggestions. If you’re in support of an open source music engraver library I think VexFlow is the way to go.
I think this is great; however, I am not able to hear the sound files on the demo. Any idea why? I really want to make use of this.
Glad you like it. The demo should work in Firefox 4.0+. You can use Chrome too if you down load the beta or canary build from the dev channel then launch Chrome and type “about: flags” into the url and then enable the Web Audio API feature. The demo uses the experimental JavaScript Audio APIs for audio synthesis which is why it only works in a couple browsers. There is a W3C Audio Working Group plugging away at standardizing an Audio API.
I’m distinctly dubious about the use of JSON to store music files, as there is currently no governing standard. The only safe way seems to be to convert from MusicXML (for which there IS both a “standard” and very widespread tool support) to JSON. Anything else would at the moment be a disservice to the music community.
I also have to disagree with the assertion above that MusicXML is counter-intuitive. On the contrary, aside from superfluous presentation-related tags, it’s clean and with a little effort easily understood.
An orchestral score can comprise more than a dozen voices. Regardless of exchange format, I’d be interested in your view of music.js’s possible role in the creation, combination and playback of multi-channel (voiced) music in the browser.
When the W3C Audio Working Group finishes the Web Audio API spec we are going to have the tools to build music apps for the browser using javascript. If we are drawing sheet music (vexflow) and synthesizing audio in javascript, why not use JSON for representing music notation? Yes, we can convert MusicXML files to JSON but I think it would be better to develop a new music notation format optimized for JSON. If developers are going to use JSON for describing music notation for web-based music apps then why not develop a standardized MusicJSON format?
Here are a couple links discussing and demoing JSON as a music notation format:
http://smcnetwork.org/node/1349
http://jams.no.de/
Playing multiple voices/tracks in realtime with the Web Audio API will be very performance intensive. The Web Audio API is going to have native effects like oscillators which should be faster than developing your own in javascript (audiolib.js uses javascript to implement all effects). Still I don’t know if the browser is fast enough to synthesize a dozen voices in realtime (this would be a cool experiment… perhaps a topic for my next post). If you want to play many voices at the same time you would be better off preprocessing your audio before playing it which is how the Sonant Live tracker works.
I’m no music expert, which is probably why I’m confused over the designation of D as the “centre of the circle of fifths” both in your blog and in music.js itself.
The symmetry surrounding sharp and flat fifth displacements from C, Middle C’s widespread recognition as a reference in auditory and musical science and it’s position of the bottom of the 4th octave (arguably more easily understood as a coordinate [0,0]) seem to suggest it as a fulcrum rather than D or A.
I’d be glad if you can provide a little more insight into your adoption of D. Thanks.
Mm. If I’d looked two seconds longer I’d have seen that D sits at the centre of the notes arrange alphabetically. (A B C D E F G), but I’m still not clear what purpose this serves: it seems just a little too arbitrary.
Forget my last remark. Having looked more closely at the notes definition, I recognise an even distribution of sharped and flatted notes around a central (pivot, D) note, and that this is used only internally.
This “view” is, however, (so to say) orthogonal to the circle of fifths diagram itself and so somehow counter-intuitive. Other than it’s appeal to a sense of order, the “why” is still a mystery: a fifth displacement from the centre of symmetry on the circle of fifths is not the same as a fifth displacement from the centre of this table..
It seems to me the most useful applications of a table such as this would be to return the number of sharps or flats to be displayed at the start of a stave, or to convert quickly between keys, but in both cases an offset conversion would be required. Moreover, I can think of no reason why I’d want to know how many fifths separate some note x from this pivotal D.
Don’t get me wrong – the overall aim of this library is admirable, but I’m still confused.
By playing around with the code I think I’ve understood. The use of D is simply to ensure that each note name (whether flattened, natural or sharped) appears only once as an array key. Perfectly ligitimate: any other note leads to duplicated note names in the sequence.
Sorry for any confusion. The main points of this post are the circle of fifths allows us to define notes in any tuning and distinguish between sharps and flats. For example, if we used semitones to define notes it would only work for 12tet tuning but not others. We plan on adding support to the library for several other tunings like 5tet, 7tet, and Werckmeister temperament.
Based on your comments it sounds like you dug through the code and now follow whats going on with D as the center of the circle of fifths. When the order of the notes is following the circle of fifths: F-C-G-D-A-E-B, the accidentals can easily be added by repeating this sequence for each accidental. Fb-Cb-Gb-Db-Ab-Eb-Bb-F-C-G-D-A-E-B-F#-C#-G#-D#-A#-E#-B# (-Fx-Cx-Gx-Dx-Ax-Ex-Bx, etc.). This is why we chose D as our main note since its the center of the circle of fifths.
Let me know if you have any other questions and I can try to get Piers involved in the discussion who is the brains behind the music theory involved in music.js.