Skip to content

Melody and Harmony in a Key

On this page you write a melody and chord accompaniment in C major, then move both to a new key without rewriting the notes.

Finish Your First Groove. Open src/main.non in your project. Evaluate RESET; on its own, then remove it from the file. The session should be silent, with no tracks from earlier tutorials. Evaluate each block in order. The bundled keys kit supplies the pitched instrument; no plugin or MIDI synth is needed.

use "std/instruments" { SamplerMelodic, Kit };
set_bpm(120);
let melody = AudioTrack("melody");
melody.set_instrument(SamplerMelodic(Kit("keys")));
melody.volume << -12;
melody << [C4 D4 E4 G4 E4 D4 C4 _];
PLAY;

You hear a rising and falling melody. C major contains C, D, E, F, G, A and B. The octave number sets the register; C5 is one octave above C4.

Set the track’s key, then replace the notes with positions in its scale:

let home = Key(C4, "major");
melody.set_key(home);
melody << [^1 ^2 ^3 ^5 ^3 ^2 ^1 _];

It sounds the same. ^1 is the root C4, ^2 is D4, and ^3 is E4. These are scale degrees, not semitone distances. In C major the first step spans two semitones, but the step from degree 3 to degree 4 spans only one.

Try a phrase with an octave leap:

melody << [^1 ^3 ^5 ^8 ^5 ^3 ^2 _];

^8 is the root an octave up. The rhythm still fits one cycle.

Make a second track one octave below the melody. Give it one chord per cycle:

let harmony = AudioTrack("harmony");
harmony.set_instrument(SamplerMelodic(Kit("keys")));
harmony.volume << -18;
harmony.set_key(Key(C3, "major"));
harmony << <^1: ^4: ^5: ^1:>;

Listen for four cycles. The chords are C major, F major, G major and C major: I–IV–V–I. A trailing : asks the key to build a three-note chord on that degree. Angle brackets choose one element per cycle, so this accompaniment takes four cycles to repeat. Its lower register and quieter level leave room for the melody.

Move the roots from C to D, keeping the major scale:

melody.set_key(Key(D4, "major"));
harmony.set_key(Key(D3, "major"));

The melody and harmony follow together. Now keep D as the root but change to minor:

melody.set_key(Key(D4, "minor"));
harmony.set_key(Key(D3, "minor"));

The lowered third gives the phrase a different colour. The chords are now D minor, G minor, A minor and D minor. You changed the key, not the rhythm or the degree patterns.

Replace src/main.non with the final version:

use "std/instruments" { SamplerMelodic, Kit };
set_project_title("Melody and Harmony");
set_bpm(120);
let melody = AudioTrack("melody");
melody.set_instrument(SamplerMelodic(Kit("keys")));
melody.volume << -12;
melody.set_key(Key(D4, "minor"));
melody << [^1 ^3 ^5 ^8 ^5 ^3 ^2 _];
let harmony = AudioTrack("harmony");
harmony.set_instrument(SamplerMelodic(Kit("keys")));
harmony.volume << -18;
harmony.set_key(Key(D3, "minor"));
harmony << <^1: ^4: ^5: ^1:>;
render(8);

Save and run resonon run in the project folder. Open renders/melody_and_harmony_<date>_<time>/master.wav. You hear the four-chord progression twice. In VSCode, evaluate STOP; on its own to finish the live exercise.