This example plays a one-octave chromatic scale.
For this first example, let's start at the beginning with sound. Sound is a physical phenomenon caused by rapid and repeated changes in air pressure. These changes in air pressure are like waves on a pond and are called oscillations. The number of oscillations per second is called frequency, which our brains perceive as pitch.
Next, let's consider the octave. An octave is a fundamental aspect of sound that people can readily identify. From a physical perspective, each octave is a doubling of the frequency of the previous octave. There is a direct relationship between what we hear (an octave) and the underlying physics (a doubling in frequency).
Western music divides each octave into 12 distinct pitches or notes. These 12 notes form a chromatic scale. On a piano, a chromatic scale consists of a sequence of 12 consecutive keys, counting both white (7) and black (5) keys.
var notesInChromaticScale = 12; // 12 semitones make up a complete octave
In the MIDI world, each pitch is assigned a MIDI note number from 0 to 127. This range covers the 88 keys of a standard piano and more. The first key on a standard piano is MIDI note 21. This is an A. We'll get into note names in the next example.
var first = 21; // MIDI note number for lowest note on a standard piano
To start playing a MIDI note, we turn it on by its MIDI note number. To stop playing a MIDI note, we turn it off by its MIDI note number.
Now let's move on to programming. In this JavaScript example we use
ws.fire to fire events and turn MIDI notes on and off.
The object named ws is the Wildwood Soundworks JavaScript
interface. The method fire is a built-in function that sends an
event message to other components within the device.
For those who are not familiar with JavaScript, the letters ws
represent an object name, the letters fire represent a method
name, and the dot (.) separates them. A method is a function
associated with an object. A function is a reusable building block: you tell it
to do something, optionally pass it some parameters, it does it, and optionally
returns a result.
An event is a message (like a text message on your phone). It tells software components on the device to do something, or that something has happened.
The device's synthesizer listens for note_on and
note_off events. When it receives note_on, it starts
the sound, and when it receives note_off, it stops the sound.
The note_on event requires the channel (which of
the 16 MIDI channels to use), the note number, the
velocity (e.g. how fast you press the key) and a
delay in milliseconds (used for "swing"). Velocity controls the
volume of the note when it is played, from 0 (silent) to 127 (loud). We'll get
into the details on channels in a later example.
Finally, we need to sleep a bit between starting the note and stopping the
note to give the note a chance to play. We use the Wildwood Soundworks
sleep method, which pauses for the specified number of
milliseconds.
A millisecond is 1/1000 of a second, so 250 milliseconds is 250/1000 of a second, or 1/4 of a second.
In music terms, a song playing at 120 beats per minute (BPM) moves at 2 beats per second. That's 1/2 second per beat or 500 milliseconds per beat. If a single beat represents a quarter note, then 250 milliseconds is half of that, or an eighth note.
Whew! That's a lot of background for this simple example, but hopefully it helps to fill in some missing pieces and explain why it all works the way it does.
Press the Copy button below to copy the example to the
clipboard.
// Example: chromatic-scale.js - Play notes in a chromatic scale
// Here we initialize some variables to make the purpose of the numeric
// constants more understandable.
var notesInChromaticScale = 12; // 12 semitones make up a complete octave
var first = 21; // MIDI note number for lowest note on a standard piano
var channel = 0; // Channels in range 0 to 15 (MIDI channel 1 to 16)
var velocity = 80; // MIDI velocity in range 0 to 127 (note volume)
var delay = 0; // Delay in milliseconds before playing note (for swing)
var duration = 250; // 250 milliseconds is an eighth note at 120 bpm
// Define a new JavaScript function named playChromaticScale
function playChromaticScale()
{
var last = first + notesInChromaticScale; // last note to play
// Loop across the MIDI note range from first (21)
// up to but not including last (33)
for (var note = first; note < last; note++) {
// Write the current MIDI note number to the console pane
print("Playing note " + note);
// Start playing the note
ws.fire("note_on", channel, note, velocity, delay);
// Let the note play
ws.sleep(duration);
// Stop playing the note
ws.fire("note_off", channel, note);
}
}
// Invoke the function we just defined
playChromaticScale();