Skip to content

How to Use

Element118 edited this page Aug 11, 2018 · 5 revisions

How to Use

JSON structure

Firstly, you would create a JSON structure which encodes all the information required. This JSON object can have the following properties:

  • title: Title of the music, stored as a string.
  • composer: Composer of the music, stored as a string.
  • arranger: Arranger of the music, stored as a string.
  • transcriber: Transcriber of the music, stored as a string.
  • tuning: A hashtable relating note numbers to their frequency.
  • defaultNoteConstructor: By default, PlayableNote, but supports any object constructor with the PlayableTone prototype.
  • noteMapping: An object used as a hashtable to store mappings from characters to note numbers. If tuning is omitted, note number i corresponds to a note with frequency 27.5*Math.pow(2, i/12), otherwise the hashtable provided is used to convert note numbers to frequencies.
  • volume: Optional object to use in volume changes in the music.
    • characters: An object with 2 properties, loud and soft.
    • mapping: An object with numerical properties. This maps integers to volume. It is recommended to map to numbers from 0 to 1. It is recommended that the integers used are consecutive and that the mapping is increasing.
  • instruments: An array containing the different types of instruments, as objects. Each object in the array has the following:
    • type: Either "sine", "triangle", "square", "sawtooth" or "custom", or any instrument in Instruments. If "custom", the wave property of this instrument should be used to store a return value from AudioContext.createPeriodicWave().
    • notes: A string of notes. This would be explained below.

Example:

new PlayableMusic({ // construct object
// song data
    title: "Tetris Theme A",
    composer: "",
    arranger: "Hirokazu Tanaka",
    transcriber: "",
    noteMapping: { // we will use this for now
        a: 39,
        w: 40,
        s: 41,
        e: 42,
        d: 43,
        f: 44,
        t: 45,
        g: 46,
        y: 47,
        h: 48,
        u: 49,
        j: 50,
    },
    volume: {
        characters: {
            soft: "*",
            loud: "#"
        },
        mapping: {
            "-4": 0.1,
            "-3": Math.pow(10, -3/4),
            "-2": Math.pow(10, -1/2),
            "-1": Math.pow(10, -1/4),
            0: 1,
            1: Math.pow(10, 1/4),
            2: Math.pow(10, 1/2),
            3: Math.pow(10, 3/4),
            4: 10
        },
    },
    instruments: [{ // an array
        type: "sample1", // instrument name
        notes: "240(/-[d3,y1,j2,y1,d1,|h3,a+1,d+2,s+1,a+1,|j3,a+1,s+2,d+2,|a+2,h2,h4,|]f3,g1,h2,g1,f1,|d3,f1,d2,s1,a1,|j-3,a1,s2,d2,|a2,h-2,h-4,)"
    }]
})

Basic Syntax

A single note is written as follows:

[note][octave][length]
a     ++      4

This a++4 gives the note and time, which means to play some notes two octaves higher. Of course, notes can be grouped together to form things playing at the same time.

a++4a+4,

This plays two notes an octave apart at the same time, with the same duration of 4 for each.

It is safe to insert random characters between notes, which are not:

  • () for BPM
  • /[] for modifiers
  • , for note groups
  • 0123456789. for numbers
  • The characters used for volume

I recommend | as a barline (syntactic sugar only, no effect).

Any character can be used for a rest, but I recommend "&". &12 means rest for 12 ticks.

g++4&2,a++4 means play first note for 4 ticks at time 0, then play second note for 4 ticks at time 2.

As you see, the last thing before the comma tells the interpreter how long to wait until the next frame of music. This allows for polyphonic music to be easily written.

Modifiers

Brackets allow for octave modifiers and time modifiers /[]. Modifiers occur between the / and [ characters. The notes which are modified are within the square brackets: []. Modifiers can be nested.

There are two types of modifiers, time modifiers and octave modifiers.

Time modifier 3: /3[notes]

Every number that represents an amount of time in the square brackets would be divided by 3.

Octave modifier (+2 octaves) /++[notes]

Every note in the square brackets would be played higher by 2 octaves.

Example: /3++-7+[a42,] divides the numbers inside by 21 (3 times 7), and increments by 2 octaves (++-+), hence, this is equivalent to a++2,.

BPM

Round brackets are required around everything. Do not nest them. Round brackets can be used to input BPM.

This shows a excerpt with 2 sections, one at 240 BPM and one at 140 BPM.

240(a24,)140(a+14,)

The result of this is two notes played for six seconds each, an octave apart.

Volume

Volume can be set for each instrument at any point in the song. To use this custom volume, remember to set the volume object. We will use the volume object in our example here.

a1a+1##a++1,

The result of this is three notes played at the same time for the same amount of time, with the highest pitch played at a volume louder than the initial volume.

This works via counting the number of loud and soft characters used consecutively. The number of soft characters is subtracted from the number of loud characters and the volume is obtain from a lookup of the mapping.

Clone this wiki locally