Skip to content

Composition: how to write music for Cahors

Jamie Matthews edited this page Mar 16, 2015 · 1 revision

Introduction

This page will attempt to explain how music is written for Cahors.

The main Cahors download comes with a sample composition called "cerealdata". The best way to learn is to have a look at it, play with it, change it, and try to figure out how it works.

Warning: Cahors does not provide a particularly "nice" or natural way of writing or notating music. It fact, it's probably the least natural way of being creative that I can think of. However, I am probably not alone in finding that severely restricting the pallet of tools available for expression can sometimes be very inspiring, and can often produce completely unexpected results. Once you get the hang of it, writing for Cahors can be quite good fun.

People who are used to creating electronic music with Tracker software will probably be most at home with Cahors. However, the process and concepts are still quite different, as Cahors deals with MIDI notes rather than samples.

Warning 2: This guide is probably not very good. There was a significant period of time between me writing Cahors and releasing it (and writing this guide), during which time I was working on my MSc thesis and didn't use Cahors at all. So I'm a bit rusty myself. You'll probably need to have a fairly good grasp of programming to be able to make progress with Cahors anyway, and you'll benefit more from simply reading the source code and figuring out how it works. If you'd like to modify or rewrite this page to be more helpful, please feel free.

Details

All music for Cahors should be placed in the song.h file. This should be the only file you need to change in order to write music for Cahors, unless you want to change how the sequencer itself works. This file contains arrays of song data (patterns), and a master array of pointers to these patterns, from which the complete song is assembled.

A song is divided into bars, which correspond to rows in the song arrangement array. A bar is subdivided into thirty-two ticks. Ticks are the intervals at which your notes can start and stop.

There are two types of patterns, drum patterns and melodies. At any time during your song, one drum pattern and a number of melodies may be playing.

Drum Patterns

Each drum pattern can involve up to four drums. Drums are usually mapped to General MIDI channel 9, and different notes on that channel correspond to different drums.

Drum patterns are represented in a binary format. At each tick in a bar, a particular drum may either be hit or not hit (1 or 0). This is similar to the way drum tablature works. The main difference in Cahors is that each bar is divided into 32 'ticks', so there are 32 bits of information to store per drum per bar.

To illustrate this, let's convert the famous Amen break into a Cahors drum pattern.

Tablature for this drum pattern looks like this:

R-R-R-R-R-R-R-R-
----S--S-S--S--S
K-K-------KK----

R : Ride cymbal
S : Snare drum
K : Kick

(taken from Wikipedia).

Here, the bar is divided into only 16 beats. So we must "fill in the gaps" with more zeroes to make up the full 32:

R: 10001000 10001000 10001000 10001000
S: 00000000 10000010 00100000 10000010
K: 10001000 00000000 00001010 00000000

Now, to make this easier to write, we use hexadecimal notation:

R: 0x88 0x88 0x88 0x88
S: 0x00 0x82 0x20 0x82
K: 0x88 0x08 0x0a 0x00

This is then converted into a Cahors pattern which looks like this:

prog_uchar pat2[4][7] PROGMEM =
  { 
   
    {  note_ride,   100,  1,  0x88,  0x88,  0x88,  0x88  },
    {  note_snare,  100,  1,  0x00,  0x82,  0x20,  0x82  },
    {  note_kick,   100,  1,  0x88,  0x08,  0x0a,  0x00  },
  };

The first column is the shorthand for the note which you will #define at the top of the song.h file. The second column is the MIDI velocity, or volume, at which you want the pattern to be played. The third column is the duration (in ticks) of each note. And the final four columns are the patterns themselves in hexadecimal format, one byte to eight ticks.

Melody Patterns

The other type of pattern which you can use in your Cahors composition is a melody pattern. In fact, this are used to create basslines and chords as well as melodies.

The best way to explain the structure of the melody patterns is to provide some simple examples.

Single note

The simplest melody pattern is one which defines a single note, and looks like this:

prog_uchar mel_a[][4] PROGMEM = 
  {
    {  0,  C+oct5, 100,  64 },
    {  END, END, END, END }
  };

mel_a is the name by which the pattern will be referred to in the Song Arrangement Array, which will be discussed below. It might be sensible to give it a descriptive name, like chorus_melody, for example.

The first column, which contains a zero in this example, is the tick at which you want the note to start. Zero means at the beginning of the bar, 16 would be half way through the bar, and so on.

The second column is the note itself. Have a look in the file util.h which is part of Cahors. It contains shorthands for the MIDI note numbers which you can use in your compositions. C is the note itself (if you want a sharp, append a lowercase 's' to the note name eg: Cs). Added to this is the octave, with oct0 being the lowest in the MIDI specification. So C+oct5 is translated into 0+60, which plays MIDI note 60, which happens to be Middle C.

The third column is the MIDI note velocity, or how hard the note is struck. It is in the range zero (silence) to 127.

The fourth column is the duration of the note, in ticks (or 1/32nds of a bar). So this Middle C note, with a duration of 64 ticks, will last for two bars. You don't have to wait for a note to finish before you start playing another note: each note is added to a queue and dealt with asynchronously.

Your melody pattern should always finish with a row that looks like { END, END, END, END }, to tell Cahors that it shouldn't look for any more notes in the pattern.

=== Multi-note melodies ===

To create a melody, add more notes with later starting points:

prog_uchar mel_n[][4] PROGMEM = 
  {
    {  0,  G+oct4, 120, 4 },
    {  8,  A+oct4, 120, 4 },
    {  16, E+oct4, 120, 4 },
    {  24, F+oct4, 120, 4 },
    {  END, END, END, END }
  };

Chords

To play a chord, simply play different notes with the same starting tick:

prog_uchar mel_c[][4] PROGMEM = 
  {
    {  0,  C+oct3, 100,  64 },
    {  0,  E+oct3, 100,  64 },
    {  0,  G+oct3, 100,  64 },
    {  END, END, END, END}
  };

The Song Arrangement Array

To put your patterns together into a full composition, pointers to each pattern are assembled in the song arrangement array, which is placed after the pattern definitions in song.h.

Example

Here's a simple example of a Song Arrangement Array, containing one drum pattern and three melody patterns (melody, chords and bass) with a duration of eight bars:

prog_uchar *song[][melody_count+1] PROGMEM = 
  { //     DRUMS         | MELODY          | CHORDS            | BASS               

    {  &drums_a[0][0],    &mel_a[0][0],    &empty_mel[0][0],    &bass_a[0][0],    },
    {  &drums_a[0][0],    &mel_b[0][0],    &empty_mel[0][0],    &bass_a[0][0],    },
    {  &drums_a[0][0],    &mel_c[0][0],    &empty_mel[0][0],    &bass_a[0][0],    },
    {  &drums_b[0][0],    &mel_d[0][0],    &empty_mel[0][0],    &bass_a[0][0],    },
    {  &drums_a[0][0],    &mel_a[0][0],    &chords_a[0][0],     &bass_b[0][0],    },
    {  &drums_a[0][0],    &mel_b[0][0],    &chords_b[0][0],     &bass_b[0][0],    },
    {  &drums_a[0][0],    &mel_c[0][0],    &chords_a[0][0],     &bass_b[0][0],    },
    {  &drums_c[0][0],    &mel_d[0][0],    &chords_b[0][0],     &bass_b[0][0],    },
    {  &SONGEND,          &SONGEND,        &SONGEND,            &SONGEND,         }
  };

One row in the array corresponds to one bar (32 ticks), and can contain pointers to one drum pattern and a number of melodies. The pattern names (drums_a and mel_d for example) correspond to your pattern names, which you have defined above. They should always start with an & and end with [0][0]).

Cahors will run down this array, one bar at a time. It will follow the pointer to each pattern it finds, and play the notes defined in that pattern. When that bar is over, it will move onto the next row in the array.

Summary

As you can see, the process of writing music for Cahors is a little unusual and probably unfamiliar to most people. However, once you've got your head around the examples and start writing your own music, it can be pretty addictive. Have fun!

Clone this wiki locally