ChucK is a music programming language (and compiler/synthesizer) written by a professor (Perry Cook) and his students at Princeton University. I'm learning how to use it; I thought that writing about how to use it would help...

Saturday, January 22, 2005

Using A Scale Function -- SuperLocrianBells.ck

Michael Johansson's scales.ck includes an extensive list of comments on various types of scales and modes. I thought it would be useful to illustrate the creation of a scale selecting function that picks out the notes of a specific scale. I picked C Super Locrian (which Michael subtitles Ravel). So I wrote a float note_to_midi( int note, int octave ) function. I used the code from my modification of the wurley.ck example program, which uses the TubeBell STK FM synthesis module.

The full program is here: SuperLocrianBells.ck (as usual, click to see full code in a new window, or right-click/SAVE to download).

I've clipped out [SNIP] the "standard" stuff from the example and just kept the new function and main driver (and scale comments from scales.ck). You'll notice that note_to_midi() contains four complete octaves, duplicating each octave note (C and C'). I did it this way because by having complete scales for each octave stresses the root note for the scale. Be picking 0 - 7, you have two chances in each octave to get a root note, focusing the piece on the "key". This may be mathematically illegitimate, but it's my choice because I have the illogical feeling that it makes it more "musical". (Heh — or jejeje as one of my Spanish friends says).

Anyway, here's the code:



// SuperLocrianBells.ck
// scale exercise using TubeBell STK

// modified from examples/wurley.ck by Gary Williams
// even more music for replicants Wurley changed to TubeBell

[SNIP...]

0 => int i;
0.0 => float freq;

// Super Locrian C Db Eb E Gb Ab Bb C octave (Ravel)
// MIDI 60 61 63 64 65 68 70 72 0
// 72 73 75 76 77 80 82 83 1
// 84 85 87 88 89 92 93 96 2
// 96 97 99 100 101 104 106 108 3
// NOTE # 0 1 2 3 4 5 6 7
fun float note_to_midi( int note, int octave ) {
if( note == 0 ){
if( octave == 0 ) { return(60.0); }
else if( octave == 1 ) { return( 72.0 ); }
else if( octave == 2 ) { return( 84.0 ); }
else return( 96.0 );
}
else if( note == 1 ){
if( octave == 0 ) { return(61.0); }
else if( octave == 1 ) { return( 73.0 ); }
else if( octave == 2 ) { return( 85.0 ); }
else return( 97.0 );
}
else if( note == 2 ){
if( octave == 0 ) { return(63.0); }
else if( octave == 1 ) { return( 75.0 ); }
else if( octave == 2 ) { return( 87.0 ); }
else return( 99.0 );
}
else if( note == 3 ){
if( octave == 0 ) { return(64.0); }
else if( octave == 1 ) { return( 76.0 ); }
else if( octave == 2 ) { return( 88.0 ); }
else return( 100.0 );
}
else if( note == 4 ){
if( octave == 0 ) { return(65.0); }
else if( octave == 1 ) { return( 77.0 ); }
else if( octave == 2 ) { return( 89.0 ); }
else return( 101.0 );
}
else if( note == 5 ){
if( octave == 0 ) { return(68.0); }
else if( octave == 1 ) { return( 80.0 ); }
else if( octave == 2 ) { return( 92.0 ); }
else return( 104.0 );
}
else if( note == 6 ){
if( octave == 0 ) { return(70.0); }
else if( octave == 1 ) { return( 82.0 ); }
else if( octave == 2 ) { return( 93.0 ); }
else return( 106.0 );
}
else if( note == 7 ){
if( octave == 0 ) { return(72.0); }
else if( octave == 1 ) { return( 83.0 ); }
else if( octave == 2 ) { return( 96.0 ); }
else return( 108.0 );
}
return( 120.0 ); // error code
}


// our main loop
while( true )
{
std.rand2(0, 7) => i;
std.rand2(0, 3) => int octave;
std.mtof( note_to_midi( i, octave) ) => float freq;
freq => voc.freq;

chout => "i, freq: " => i => ", " => freq => endl;
setnotedur();
}

// Scale references
// 1 2 3 4 5 6 7 8 9 10 11 12 13
// Chromatic C Db D Eb E F Gb G Ab A Bb B C

// Spanish 8 Tone C Db Eb E F Gb Ab Bb C
// Flamenco C Db Eb E F G Ab Bb C
// Symmetrical C Db Eb E Gb G A Bb C
// Diminished C D Eb F Gb Ab A B C
// Whole Tone C D E Gb Ab Bb C
// Augmented C Eb E G Ab B C
// 3 semitone C Eb Gb A C
// 4 semitone C E Ab C
//
// Ultra Locrian C Db Eb E Gb Ab A C
// Super Locrian C Db Eb E Gb Ab Bb C (Ravel)
// Indian-ish* C Db Eb E G Ab Bb C
// Locrian C Db Eb F Gb Ab Bb C
// Phrygian C Db Eb F G Ab Bb C
// Neapolitan Min C Db Eb F G Ab B C
// Javanese C Db Eb F G A Bb C
// Neapolitan Maj C Db Eb F G A B C
// Todi (Indian) C Db Eb Gb G Ab B C
// Persian C Db E F Gb Ab B C
// Oriental C Db E F Gb A Bb C
// Maj.Phryg. (Dom)C Db E F G Ab Bb C Spanish/ Jewish
// Double Harmonic C Db E F G Ab B C Gypsy/ Byzantine/ Ch$
// Marva (Indian) C Db E Gb G A B C
// Enigmatic C Db E Gb Ab Bb B C
//
// Locrian Natural 2nd C D Eb F Gb Ab Bb C
// Minor (natural) C D Eb F G Ab Bb C Aeolian/ Algerian (o$
// Harmonic Minor C D Eb F G Ab B C Mohammedan
// Dorian C D Eb F G A Bb C
// Melodic Minor (Asc) C D Eb F G A B C Hawaiian
// Hungarian Gypsy C D Eb Gb G Ab Bb C
// Hungarian Minor C D Eb Gb G Ab B C Algerian (oct1)
// Romanian C D Eb Gb G A Bb C
//
// Maj. Locrian C D E F Gb Ab Bb C Arabian
// Hindu C D E F G Ab Bb C -
// Ethiopian C D E F G Ab B C
// Mixolydian C D E F G A Bb C -
// Major C D E F G A B C Ionian
// Mixolydian Aug. C D E F Ab A Bb C -
// Harmonic Major C D E F Ab A B C -
// Lydian Min. C D E Gb G Ab Bb C -
// Lydian Dominant C D E Gb G A Bb C Overtone
// Lydian C D E Gb G A B C -
// Lydian Aug. C D E Gb Ab A Bb C -
// Leading Whole Tone C D E Gb Ab Bb B C -
// Bluesy R&R* C Eb E F G A Bb C -
// Hungarian Major C Eb E Gb G A Bb C Lydian sharp2nd
//
// "pB" C Db Eb Gb Ab C -
// Balinechuck@lists.cs.princeton.eduse 1 C Db Eb G Ab C "pE"
// Pelog (Balinese) C Db Eb G Bb C -
// Iwato (Japanese) C Db F Gb Bb C -
// Japanese 1 C Db F G Ab C Kumoi
// Hirajoshi (Japanese) C D Eb G Ab C "pA"
// "pD" C D Eb G A C -
// Pentatonic Major C D E G A C Chinese 1/ Mongolian/ "pFCG"
// Egyptian C D F G Bb C -
// Pentatonic Minor C Eb F G Bb C -
// Chinese 2 C E Gb G B C -




Oh, and if you'd like to hear it without running it yourself, here's SuperLocrianBells.mp3.