Scribbletune

Create music with JavaScript & Node.js!


Scribbletune has a very minimal API. The work flow involves creating clips and exporting them as MIDI files.

clip returns: Array

A clip is a like a measure of music. It can be a single bar or two bars or how many ever bars you need. In DAWs such as Ableton Live and Propellerhead Reason, a clip is what you create in the session or arrangement view to capture a musical idea.

The clip method takes an object literal as an argument. This object lets you define the parameters of that clip. Here is an example of the clip method being called with an object that sets up the most basic properties of the clip:

var scribble = require('scribbletune');

// Create a clip that plays the middle C
var clip = scribble.clip({
	notes: 'c4',
	pattern: 'x________________'
});

// Render a MIDI file of this clip
scribble.midi(clip, 'c.mid');

notes {String|Array}

This property lets you set up the notes we want to play in the clip. You can enter notes manually or use the built-in scale/mode method to generate notes from a scale and further mangle them into an array. For instance, in the preceding example we set the 'c4' note as the only note to be played across a pattern. You can even set up a bunch of notes:

var scribble = require('scribbletune');

// Create a clip that plays the C major scale
var clip = scribble.clip({
	notes: 'c4 d4 e4 f4 g4 a4 b4 c5', // Or ['c4', 'd4', 'e4', 'f4', 'g4', 'a4', 'b4', 'c5']
	pattern: 'x_x_x_x_x_x_x_x_'
});

// Render a MIDI file of this clip
scribble.midi(clip, 'cscale.mid');

In this example we explicitly set the notes of the C major scale in the 4th octave. Scribbletune also has a method to generate scales directly and output an array which you can then manipulate with JavaScript Array functions.

pattern {String}

This is the second most important parameter for the clip method's object. It abstracts away the MIDI note on and note off events along with the individual note durations into a nifty 3 character instruction language made up only of x, -(hyphen) and _(underscore). This is native to Scribbletune and it's used in multiple ways across the Scribbletune library. But maybe we are making it too complex to understand, here's an example of what a pattern looks like and what it means:

x---x---x---x---

This pattern is akin to what would look like the following in a DAW:

As you can deduce, each x implies a note on event (hence shows a note in the piano roll when imported) and each hyphen implies a note off event which does not have any note in that location in the 16 beat clip. Other than setting note on and off events, we can even set the duration of a note on event using the pattern language's third and final character: _ (underscore) character instead:

x__-x__-x__-x__-

Here we replaced 2 hyphens after each x with underscores. An underscores implies a sustain to the preceding x. More underscores imply more sustain of the preceding x. Here's how it now looks in a piano roll:

Basically the underscores just extended the notes set up by the x character. These are really simply examples but you can do a lot with patterns! The examples section showcase a lot more patterns and how they are useful when creating complex melodies or chord progressions. You can try out some patterns and see how they look on a 16 beat grid.

accentMap {String | Array}

An accent map is a way for you to tell the clip method to hit some notes harder than the others. It's a string of x and - (hyphen) characters. An x implies hit harder and a - (hyphen) implies hit softer.

Here's how you use an accent map. In the following example, we have a pattern that instructs Scribbletune's clip method to create a note on each beat on a 16 beat bar. Then it goes on to set up an accentMap parameter that instructs which of the notes to hit harder x and which to hit softer-

var scribble = require('scribbletune');

var clip = scribble.clip({
	notes: 'c3',
	pattern: 'xxxxxxxxxxxxxxxx',
	accentMap: 'x---x-x-x---x-x-'
});

scribble.midi(clip, 'hats.mid');

Here's how that looks in a piano roll. The vertical lines on the bottoms suggest the volume of each note. They co-incide with the accentMap we setup:

accentMap can be set up by individual note values as well. You can pass an array of numbers that will be applied to each of the notes.

var scribble = require('scribbletune');

	var clip = scribble.clip({
		notes: 'c4',
		pattern: 'x'.repeat(16),
		accentMap: [5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 127, 127, 127]
	});

	scribble.midi(clip);

Here's how that looks. As you can see, the gradual change in the color of the note as well as the vertical lines on the bottom suggest the upward rise in the levels setup by our Number Array.

accentHi {Number} default 127

In case you used a string to setup an accentMap, then this property lets you define the level for each x.

accentLow {Number} default 70

In case you used a string to setup an accentMap, then this property lets you define the level for each -.

shuffle (Boolean) default: false

Setting this property will randomize the order of the notes you set in the clip method.

sizzle {Boolean}

While accentMaps are great to wire up a individual note levels in a very controlled fashion, 'sizzle' lets you quickly add a bouncy feel to the clip by using Math.sin on the angles of a semi circle multiplied by the max level of 127.

noteLength {String}

By default each bar is 16 beats long. In other words each beat is 1/16th of a bar. This can be changed by setting another fraction for the smallest note length. Valid values are 1/4, 1/8, 1/16 (default), 1/32 etc. For instance in the following example, we are leaving the default (1/16) for one clip and setting it to 1/32 for another clip.

var scribble = require('scribbletune');

// Create a clip that occupies the first 12 notes of a 16 beat bar
var clip1 = scribble.clip({
	notes: 'c4',
	pattern: 'x'.repeat(12)
});

// Create another clip that occupies the last 4 notes of a 16 beat bar
// Since we are reducing the note length by half, we will double the pattern length
var clip2 = scribble.clip({
	notes: 'c4',
	pattern: 'x_xxx_x_',
	noteLength: '1/32'
});

// Concatenate both the clips and render a single MIDI file
scribble.midi(clip1.concat(clip2, 'music.mid'));

Then we concatenate both the clips and render as a single MIDI file. Here's how it looks in a piano roll (note the 2 highlighted notes - they are 1/32 of a beat whereas the rest are 1/16th)

One thing to ensure while playing with the note length is, if you reduce the note length (like the above example) then you must make sure that the final clip length continues to be like a full length 16 beat bar. In other words, reducing the note length also reduces the length of the bar by half which means you must have a doubled pattern to compensate!

arpegiate {Boolean|Object}

When you create a clip, you can chose to arpegiate the notes. Setting it simply true will arpegiate notes by alternating them to their octaves (a distance of 12 half steps).

var scribble = require('scribbletune');
var clip = scribble.clip({
	notes: 'c3',
	pattern: 'x_'.repeat(8),
	arpegiate: true
});

scribble.midi(clip);

You can change this by setting up a custom distance and number of steps in a object. Instead of a Boolean, pass an Object with steps and distance. In the following example, we set a distance of 7 (to simulate a circle of fifths) and steps are set to 11:

var scribble = require('scribbletune');
var clip = scribble.clip({
	notes: 'c3',
	pattern: 'x_'.repeat(8),
	arpegiate: {
		distance: 7,
		steps: 11
	}
});

scribble.midi(clip);

scale/mode returns: Array

A scale is a set of musical notes ordered by pitch. A displaced order of a scale is also called a mode. Scribbletune exports the same method as scale as well as mode

The scale method takes 4 optional parameters. Without any parameters, Scribble tune will output a C major scale. To customize it, you can pass the following parameters:

  • root {String} default: C
  • scale {String} default: major
  • octave {Number} default: 4
  • addRootFromNextOctave {Boolean} default: true
var scribble = require('scribbletune');

// Create a clip that plays the middle C
var cMajor = scribble.scale(); // [ 'c3', 'd3', 'e3', 'f3', 'g3', 'a3', 'b3', 'c4' ]
var cMinor = scribble.scale('c minor'); // [ 'c3', 'd3', 'd#3', 'f3', 'g3', 'g#3', 'a#3', 'c4' ]

// The scale method can also be refered to as `mode`
cMinor = scribble.mode('c minor'); // [ 'c3', 'd3', 'd#3', 'f3', 'g3', 'g#3', 'a#3', 'c4' ]

// That's the same as
cMinor = scribble.mode('c aeolian 3'); // [ 'c3', 'd3', 'd#3', 'f3', 'g3', 'g#3', 'a#3', 'c4' ]

// You can even set it as individual params if you like,
cMinor = scribble.mode('c', 'aeolian', 3); // [ 'c3', 'd3', 'd#3', 'f3', 'g3', 'g#3', 'a#3', 'c4' ]

There are a bunch of scales and modes available in Scribbletune. You can list the available modes by invoking the modes method. To view a list now, click here.

midi

As the name suggests, the midi method generates a MIDI file from it's input. It takes 1 mandatory and 1 optional parameter:

  1. clip {Array} The clip that you create using the clip method
  2. filename {String} This is optional. If you don't provide a filename, Scribbletune will create a file called music.mid
var scribble = require('scribbletune');

var clip = scribble.clip({
	notes: 'c4',
	pattern: 'x_______'
});

scribble.midi(clip); // Will create a file called music.mid
// OR
scribble.midi(clip, 'c.mid'); // Will create a file called c.mid

chord

Scribbletune recognizes chords by their commonly used names. For instance here is a chord progression set up via chord names:

var scribble = require('scribbletune');

var clip = scribble.clip({
	// Use chord names directly in the notes array
	notes: 'CMaj, FMaj, GMaj, CMaj',
	pattern: 'x---'.repeat(4)
});


scribble.midi(clip, 'chords.mid');

Here's how that looks on a piano roll when imported into a DAW

Other than recognizing chords in a notes array, Scribbletune also has a method to get a particular chord as an array of notes from that chord:

var scribble = require('scribbletune');
var cMajorChord = scribble.chord('CMaj'); // [ 'c4', 'e4', 'g4' ]

Lastly, you can get an array of the available chords by calling the getChords method:

var scribble = require('scribbletune');
var availableChords = scribble.listChords(); // Lists all available chords

Here is a list of all the available chords in Scribbletune with their alternative names:

  • 6th | Sixth | sixth
  • maj | Maj
  • min | Min | m
  • sus2 | Sus2
  • sus4 | Sus4
  • maj7 | Maj7
  • min7 | Min7
  • dom7 | Dom7 | 7th
  • dim | Dim
  • dim7 | Dim7
  • aug | Aug