From CSWiki
Revision as of 18:55, 24 October 2007 by H4T (talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Fairly simple sequencer. To use, first add to you virtual machine. Then, from add any ChucK program, make the following function call:

sequencer.sequence( filename, beats_per_measure, volume_vector );
  • filename - string containing the path to the sample you want to play
  • beats_per_measure - number of beats will play during each measure
  • volume_vector - vector of floats in the range [0, 1] used to determine the volume of each beat

This function call will not return, so you will have to use a separate source file for each call. Once sporking member functions works, you could also do that.

Each beat is equally spaced. Additionally, the volume vector can be larger or greater than the number of beats per measure, if desired; it is cycled through independently of the measure. For example, with a beats_per_measure of 4 and a volume vector of [1.0, 0.0], you will get 4 beats per measure, with the first and third beats having a volume of 1.0, and the second and fourth beats having a volume of 0.0. You'll notice that this lets programmers easily experiment with interesting polyrhythms, by deliberately misaligning the beats per measure and volume vectors for a given sequence, and across different sequences.

Additionally, if a volume of 0 is specified, the sample is simply not played, instead of being played at a volume of 0. In this way, the sound buffer for the sample is not reset for beats where the volume is 0.

You can change the measure length (in seconds) using the following function call:

sequencer.change_measure_length( new_measure_length );

You should use this function rather than setting it directly, because setting it directly will probably cause currently running sequences to become misaligned. measure length = BPM/60

// sequencer class for sequencing arbitrary samples 
// author: spencer salazar (updated by jason webb)
// Feel free to use/modify/distribute as you see fit.  

public class sequencer
	static float measure_length;
	static Event @ new_measure;
	static int on;
	fun static void start()
		while( on )
			measure_length::second => now;
	fun static void stop()
		0 => on;

	fun static void set_measure_length( float new_ml )
		// wait until the end of the measure
		new_measure => now;
		new_ml => measure_length;

	fun static void sequence( string filename, float bpmeasure, float volumev[] )
		new_measure => now;
		SndBuf buf => Gain g => dac;
		filename =>;
		.5 => g.gain;

		0 => int i;
		0 => int j;

		while( on )
			for( 0 => i; i < bpmeasure; i++ )
				if( volumev[j] > 0 )
				/* only play the sample if its meant to be heard */
					0 => buf.pos;
					volumev[j] => buf.gain;
				if( j >= volumev.cap() )
					0 => j;
				(measure_length/bpmeasure)::second => now;
			//new_measure => now;


Event e @=> sequencer.new_measure;
1.5 => sequencer.measure_length;
1 => sequencer.on;