Sessions

SessionComposer

Sessions are the top-level object that house compositions.

Do not invoke the constructor directly; instead, use the session() factory.

Example
session('my-masterpiece', ({ library }) => {
  session.use('core.instrument.mono-synth').as('synth');

  session.track('synth', ({ track }) => {
     track.at(0).play(quarter.note('C4'));
  });

  session.send.instrument('synth').to.track('synth');
  session.send.track('synth').to.main();
});
Source:

Extends

Methods

use(params) → {InstrumentComposer|EffectComposer}

Import an instrument or effect from an external library.

Examples

Use piano from core library:

session.use('core.instrument.piano');

Use piano from core library and name it "piano-1":

session.use('core.instrument.piano').as('piano-1');

Proxied syntax:

session.use.instrument('piano').from.library('core');
session.use.instrument('piano').from.library('core').as('piano-1');

Low-level syntax:

session.use({
  name: 'piano',
  collection: 'instruments',
  source: 'library',
  libraryName: 'core',
  composer: 'instrument'
});
Parameters:
Name Type Description
params Object
Properties
Name Type Attributes Default Description
source string <optional>
library

Source type (only "library" allowed for now)

collection string <optional>
instruments

Collection type

composer string <optional>
instrument

Composer type (effect, instrument, phrase, or track)

libraryName string <optional>
core

name of library

name string <optional>

name of object

Source:

instrument(name, fn, options) → {InstrumentComposer}

Compose an instrument.

Parameters:
Name Type Description
name string

name of new instrument

fn sessionComposerInstrumentCallback

builder function that returns an AudioNode

options object

options to pass to builder function at render time

Source:

track(name, fn) → {TrackComposer}

Compose a track.

Parameters:
Name Type Description
name string

name of new track

fn sessionComposerTrackCallback

builder function

Source:

phrase(name, sequence) → {PhraseComposer}

Compose a musical phrase.

Parameters:
Name Type Description
name String

name of new phrase

sequence sessionComposerPhraseCallback | Array | ExpressionModel

sequenced notes as array or a builder function

Source:

effect(name, fn, options) → {EffectComposer}

Compose an effect.

Parameters:
Name Type Description
name string

name of new effect

fn sessionComposerEffectCallback

builder function that returns an AudioNode

options object

options to pass to builder function at render time

Source:

send(properties) → {PatchModel}

Route the output of one node to the input of another.

Each session requires at least 2 types of sends in order to produce audio-- instruments to tracks, and tracks to main.

Examples

Send an instrument to a track:

session.send.instrument('electric-guitar').to.track('lead-guitar');

Send a track to main:

session.send.track('lead-guitars').to.main();

Send two instruments to the same track to play the same notes:

session.send.instrument('electric-guitar').to.track('lead-guitars');
session.send.instrument('acoustic-guitar').to.track('lead-guitars');

Add reverb to a track:

session.effect('lead-guitars-reverb', ...);

session.send.track('lead-guitars').to.effect('lead-guitars-reverb');
session.send.effect('lead-guitars-reverb').to.main();

Chain multiple effects to a single track:

session.effect('lead-guitars-reverb', ...);
session.effect('lead-guitars-phaser', ...);
session.effect('lead-guitars-delay', ...);

session.send.track('lead-guitars').to.effect('lead-guitars-reverb');
session.send.effect('lead-guitars-reverb').to.effect('lead-guitars-phaser');
session.send.effect('lead-guitars-phaser').to.effect('lead-guitars-delay');
session.send.effect('lead-guitars-delay').to.main();

Create a master effect chain by adding an intermediary track before main:

session('master-effect-chain', ({session}) => {

  // ...instruments
  // ...tracks

  // Main effects
  session.effect('main-reverb', () { // ... });
  session.effect('main-phaser', () { // ... });
  session.effect('main-delay', () { // ... });

  // This track contains no notes; it's for routing only
  session.track('main-fx', () => {});

  session.send.track('lead-guitar').to.track('main-fx');
  session.send.track('bass').to.track('main-fx');
  session.send.track('drums').to.track('main-fx');
  session.send.track('xylophone').to.track('main-fx');
 
  session.send.effect('main-fx').to.effect('main-phaser');
  session.send.effect('main-phaser').to.effect('main-delay');
  session.send.effect('main-delay').to.main();

});

Alternatively, patches can be created using send() directly:

session.send({
  inputType: 'track',
  input: 'drums',
  outputType: 'effect',
  output: 'drums-reverb'
})
Parameters:
Name Type Description
properties object
Properties
Name Type Description
inputType string

type of input (instrument, track, or effect)

input string

name of input device

outputType string

type of output (instrument, track, or effect)

output string

name of output device

Source:

annotate(name) → {SessionComposer}

Name a specific place on the timeline.

session('example', ({ session }) => {
  session.at(0).annotate('intro');

  session.track('drums', ({ track }) => {
    track.at('intro').play.phrase('jam-beat');
  });
});
Parameters:
Name Type Description
name string

unique name for timeline position

Source:

meter(meter) → {SessionComposer}

Set meter (time signature).

Examples

Set meter to 4/4:

session.at(0).meter([4, 4])

Change to 6/8 at measure 25:

session.at(25).meter([6, 8])
Parameters:
Name Type Description
meter Array

time signature as fraction ([4, 4], [6, 8], etc.)

Source:

swing(swing) → {SessionComposer}

Set swing amount.

Examples

Traditional swing:

session.at(0).swing(0.5);

Mellower swing for vibin':

session.at(0).swing(0.25);
Parameters:
Name Type Description
swing decimal

swing amount between zero and 1

Source:

tempo(tempo) → {SessionComposer}

Set tempo in beats per minute.

session.at(0).tempo(160);
Parameters:
Name Type Description
tempo integer

beats per minute

Source:

key(key) → {SessionComposer}

Set root note of key signature. Accepts any valid ABC note.

Examples:

Play song in key of D:

session.at(0).key('D');

Play song in key of D, but in octave 2 instead of 4 (default):

session.at(0).key('D2');

Change key signatures throughout composition:

session.at(0).key('D').scale('major');
session.at(20).key('Eb').scale('minor');
session.at(30).key('G').scale('minor');
Parameters:
Name Type Description
key string

root note of key signature (A..G)

Source:

scale(scale) → {SessionComposer}

Set the scale part of the key signature. Accepts any valid mode:

  • Major (Ionian)
  • Dorian
  • Phrygian
  • Lydian
  • Mixolydian
  • Minor (Aeolian)
  • Locrean
Examples

Play song in D minor:

session.at(0).key('D').scale('minor');

Play song in A major, but in octave 2 instead of 4 (default):

session.at(0).key('A2').scale('major');

Change key signatures throughout composition:

session.at(0).key('D').scale('major');
session.at(20).key('Eb').scale('minor');
session.at(30).key('G').scale('minor');
Parameters:
Name Type Description
scale string

name of scale/mode (see supported values above)

Source:

at(measure, beat, subdivision) → {Proxy}

Select a position on the timeline by measure, beat and subdivision.

Positions begin from 0, meaning that "measure 1, beat 1" in spoken word implies "measure 0, beat 0" in Harmonicon.

Examples

Set tempo to 120 at the beginning of song:

session('my-song', ({ session }) => {
  session.at(0).tempo(120);
})

Play a C# on beat 2 of measure 1:

track('my-song', ({ session }) => {
  track.at(1, 2).play(quarter.note('C#'));
})

Trigger multiple actions at the same position:

track('my-song', ({ session }) => {
  session.at(0)
    .meter([ 4, 4 ])
    .tempo(120)
    .key('C')
})
Parameters:
Name Type Description
measure Number

Measure number starting from zero

beat Number

Beat number starting from zero

subdivision Number

Subdivision (between 0 and 1)

Inherited From:
Source: