Difference between revisions of "ChucK/sequencer.ck"

From CSWiki
Jump to: navigation, search
m
 
(One intermediate revision by one other user not shown)
Line 5: Line 5:
 
</pre>
 
</pre>
  
where filename is a string containing the path to the sample you want to play, beats_per_measure is the number beats that sample will play during each measure, and volume_vector is a vector of floats in the range [0, 1] used to determine the volume of each beatThis 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.   
+
<ul>
 +
<li><b>filename</b> - string containing the path to the sample you want to play</li>
 +
<li><b>beats_per_measure</b> - number of beats will play during each measure</li>
 +
<li><b>volume_vector</b> - vector of floats in the range [0, 1] used to determine the volume of each beat</li>
 +
</ul>
 +
 
 +
 
 +
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.   
 
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,  
+
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 using the following function call:
+
You can change the measure length (in seconds) using the following function call:
 
<pre>
 
<pre>
 
sequencer.change_measure_length( new_measure_length );
 
sequencer.change_measure_length( new_measure_length );
 
</pre>
 
</pre>
  
You should use this function rather than setting it directly, because setting it directly will probably cause currently running sequences to become misaligned.   
+
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.ck:
 
sequencer.ck:
Line 22: Line 29:
 
// sequencer.ck
 
// sequencer.ck
 
// sequencer class for sequencing arbitrary samples  
 
// sequencer class for sequencing arbitrary samples  
// author: spencer salazar
+
// author: spencer salazar (updated by jason webb)
 
// Feel free to use/modify/distribute as you see fit.   
 
// Feel free to use/modify/distribute as you see fit.   
  
Line 28: Line 35:
 
{
 
{
 
static float measure_length;
 
static float measure_length;
static Event new_measure;
+
static Event @ new_measure;
 
static int on;
 
static int on;
 
 
Line 56: Line 63:
 
new_measure => now;
 
new_measure => now;
 
 
sndbuf buf => gain g => dac;
+
SndBuf buf => Gain g => dac;
 
filename => buf.read;
 
filename => buf.read;
 
.5 => g.gain;
 
.5 => g.gain;

Latest revision as of 18:55, 24 October 2007

Fairly simple sequencer. To use, first add sequencer.ck 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.ck:

// sequencer.ck
// 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 )
		{
			new_measure.broadcast();
			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 => buf.read;
		.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;
				}
				
				j++;
				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;

sequencer.start();