Ejemplo n.º 1
0
void buff_get_param(t_buff_info *buff)
{
  // If the buffer has no object
  if (buff->has_obj == false) {
    buff->has_file = false;
    return; }

  // Get the buffer variables  
  buff->fr_cnt = (t_uint32)buffer_getframecount(buff->obj);
  buff->ch_cnt = (t_uint8)buffer_getchannelcount(buff->obj);
  buff->msr     = buffer_getmillisamplerate(buff->obj);
    
  // Test the buffer variables
  if ((buff->fr_cnt == 0) || (buff->ch_cnt == 0) || (buff->msr == 0)) {
    buff->has_file = false; }

  // Otherwise the buffer is linked and a file is loaded.
  else {
    buff->has_file = true; }
}
Ejemplo n.º 2
0
/********************************************************************************
 void grainstream_initGrain()
 
 inputs:			x					-- pointer to this object
 in_freq			-- frequency of grain production
 in_pos_start		-- offset within sampled buffer
 in_pitch_mult		-- sample playback speed, 1 = normal
 in_gain_mult		-- scales gain output, 1 = no change
 description:	initializes grain vars; called from perform method when pulse is
 received
 returns:		nothing
 ********************************************************************************/
void grainstream_initGrain(t_grainstream *x, float in_freq, float in_pos_start, float in_pitch_mult, float in_gain_mult)
{
    #ifdef DEBUG
        post("%s: initializing grain", OBJECT_NAME);
    #endif /* DEBUG */
    
    /* should the buffers be updated ? */
    
    t_buffer_obj	*snd_object;
    t_buffer_obj	*win_object;
    
    if (x->next_snd_buf_ptr != NULL) {
        x->snd_buf_ptr = x->next_snd_buf_ptr;
        x->next_snd_buf_ptr = NULL;
        
        #ifdef DEBUG
            post("%s: sound buffer pointer updated", OBJECT_NAME);
        #endif /* DEBUG */
    }
    if (x->next_win_buf_ptr != NULL) {
        x->win_buf_ptr = x->next_win_buf_ptr;
        x->next_win_buf_ptr = NULL;
        
        #ifdef DEBUG
            post("%s: window buffer pointer updated", OBJECT_NAME);
        #endif /* DEBUG */
    }
    
    snd_object = buffer_ref_getobject(x->snd_buf_ptr);
    win_object = buffer_ref_getobject(x->win_buf_ptr);
    
    /* should input variables be at audio or control rate ? */
    
    x->grain_freq = x->grain_freq_connected ? in_freq : x->next_grain_freq;
    
    // temporarily stash here as milliseconds
    x->grain_pos_start = x->grain_pos_start_connected ? in_pos_start : x->next_grain_pos_start;
    
    x->grain_pitch = x->grain_pitch_connected ? in_pitch_mult : x->next_grain_pitch;
    
    x->grain_gain = x->grain_gain_connected ? in_gain_mult : x->next_grain_gain;
    
    /* compute dependent variables */
    
    // grain_freq must be positive and above 0.01 Hz or 1.66 min duration
    if (x->grain_freq < 0.) x->grain_freq *= -1;
    if (x->grain_freq < 0.01) x->grain_freq = 0.01;
    x->grain_length = 1000. / x->grain_freq;
    
    // compute window buffer step size per vector sample
    x->win_step_size = (double)(buffer_getframecount(win_object)) * x->grain_freq * x->output_1oversr;
    if (x->win_step_size < 0.) x->win_step_size *= -1.; // needs to be positive to prevent buffer overruns
    
    // compute sound buffer step size per vector sample
    x->snd_step_size = x->grain_pitch * buffer_getsamplerate(snd_object) * x->output_1oversr;
    if (x->snd_step_size < 0.) x->snd_step_size *= -1.; // needs to be positive to prevent buffer overruns
    
    // compute amount of sound file for grain
    x->grain_sound_length = x->grain_length * x->grain_pitch;
    if (x->grain_sound_length < 0.) x->grain_sound_length *= -1.; // needs to be positive to prevent buffer overruns
    
    // update direction option
    x->grain_direction = x->next_grain_direction;
    
    if (x->grain_direction == FORWARD_GRAINS) {	// if forward...
        x->grain_pos_start = x->grain_pos_start * buffer_getmillisamplerate(snd_object);
        x->curr_snd_pos = x->grain_pos_start - x->snd_step_size;
    } else {	// if reverse...
        x->grain_pos_start = (x->grain_pos_start + x->grain_sound_length) * buffer_getmillisamplerate(snd_object);
        x->curr_snd_pos = x->grain_pos_start + x->snd_step_size;
    }
    
    x->curr_win_pos = 0.0;
    
    // reset history
    x->curr_count_samp = -1;
    
    #ifdef DEBUG
        post("%s: beginning of grain", OBJECT_NAME);
        post("%s: win step size = %f samps", OBJECT_NAME, x->win_step_size);
        post("%s: snd step size = %f samps", OBJECT_NAME, x->snd_step_size);
    #endif /* DEBUG */
    
    return;
    
}
Ejemplo n.º 3
0
/********************************************************************************
t_int *grainstream_perform(t_int *w)

inputs:			w		-- array of signal vectors specified in "grainstream_dsp"
description:	called at interrupt level to compute object's output; used when
		outlets are connected; tests inlet 2 & 3 to use either control or audio
		rate data
returns:		pointer to the next 
********************************************************************************/
t_int *grainstream_perform(t_int *w)
{
	t_grainstream *x = (t_grainstream *)(w[1]);
	float *in_freq = (float *)(w[2]);
	float *in_pos_start = (float *)(w[3]);
	float *in_pitch_mult = (float *)(w[4]);
	float *out = (t_float *)(w[5]);
	int vec_size = (int)(w[6]);
	float out_1oversr = (float)x->output_1oversr;
	
	t_buffer_obj *snd_object, *win_object;
	float *tab_s, *tab_w;
	double s_step_size, w_step_size;
	double  snd_out, win_out;//, last_s, last_w;	//removed 2005.02.03
	double index_s, index_w, last_index_w, temp_index_frac;
	long size_s, size_w, temp_index_int;
	short interp_s, interp_w, g_direction;
	
	vec_size += 1;		//increase by one for pre-decrement
	--out;				//decrease by one for pre-increment
	
	if (x->x_obj.z_disabled)					// object is enabled
		goto out;
    if ((x->snd_buf_ptr == NULL) || (x->win_buf_ptr == NULL))		// buffer pointers are defined
        goto zero;
	
    // get sound buffer info
    snd_object = buffer_ref_getobject(x->snd_buf_ptr);
    tab_s = buffer_locksamples(snd_object);
    if (!tab_s)		// buffer samples were not accessible
        goto zero;
    size_s = buffer_getframecount(snd_object);
    
    // get window buffer info
    win_object = buffer_ref_getobject(x->win_buf_ptr);
    tab_w = buffer_locksamples(win_object);
    if (!tab_w)		// buffer samples were not accessible
        goto zero;
    size_w = buffer_getframecount(win_object);
	
	// get option settings
	interp_s = x->snd_interp;
	interp_w = x->win_interp;
	g_direction = x->grain_direction;
	// get pointer info
	s_step_size = x->snd_step_size;
	w_step_size = x->win_step_size;
	index_s = x->curr_snd_pos;
	index_w = x->curr_win_pos;
	// history
	last_index_w = x->win_last_index;
	
	while (--vec_size) {
		index_w += w_step_size;
		
		/* check bounds of window index */
		while (index_w < 0)
			index_w += size_w;
		while (index_w >= size_w)
			index_w -= size_w;
			
		if (index_w < last_index_w) {		// if window has wrapped...
			if (index_w < 10.0) {			// and is at beginning...
				// ...then begin a new grain
				
				if (x->next_snd_buf_ptr != NULL) {	//added 2002.07.24
                    buffer_unlocksamples(snd_object);
                    x->snd_buf_ptr = x->next_snd_buf_ptr;
                    x->next_snd_buf_ptr = NULL;
                    
                    snd_object = buffer_ref_getobject(x->snd_buf_ptr);
                    tab_s = buffer_locksamples(snd_object);
                    if (!tab_s)		// buffer samples were not accessible
                        goto zero;
                    size_s = buffer_getframecount(snd_object);
					
					#ifdef DEBUG
						post("%s: sound buffer pointer updated", OBJECT_NAME);
					#endif /* DEBUG */
				}
				if (x->next_win_buf_ptr != NULL) {	//added 2002.07.24
                    buffer_unlocksamples(win_object);
                    x->win_buf_ptr = x->next_win_buf_ptr;
                    x->next_win_buf_ptr = NULL;
                    
                    win_object = buffer_ref_getobject(x->win_buf_ptr);
                    tab_w = buffer_locksamples(win_object);
                    if (!tab_w)	{	// buffer samples were not accessible
                        goto zero;
                    }
                    size_w = buffer_getframecount(win_object);
					
					#ifdef DEBUG
						post("%s: window buffer pointer updated", OBJECT_NAME);
					#endif /* DEBUG */
				}
				
				//
				//
				
				x->grain_direction = x->next_grain_direction;
				g_direction = x->grain_direction;
				
				// test if freq should be at audio or control rate
				if (x->grain_freq_connected) { // if freq is at audio rate
					if (*in_freq != 0.0) x->grain_freq = *in_freq;
				} else { // if freq is at control rate
					if (x->next_grain_freq != 0.0) x->grain_freq = x->next_grain_freq;
				}
				x->grain_length = 1000.0 / x->grain_freq;
				
				// test if pitch should be at audio or control rate
				if (x->grain_pitch_connected) { // if pitch is at audio rate
					x->grain_pitch = *in_pitch_mult;
				} else { // if pitch is at control rate
					x->grain_pitch = x->next_grain_pitch;
				}
				x->grain_sound_length = x->grain_length * x->grain_pitch;
				
				// test if pos_start should be at audio or control rate
				if (x->grain_pos_start_connected) { // if position is at audio rate
					if (x->grain_direction == FORWARD_GRAINS) {	// if forward...
						x->grain_pos_start = *in_pos_start * buffer_getmillisamplerate(snd_object);
					} else {	// if reverse...
						x->grain_pos_start = (*in_pos_start + x->grain_sound_length) * buffer_getmillisamplerate(snd_object);
					}
				} else { // if position is at control rate
					if (x->grain_direction == FORWARD_GRAINS) {	// if forward...
						x->grain_pos_start = x->next_grain_pos_start * buffer_getmillisamplerate(snd_object);
					} else {	// if reverse...
						x->grain_pos_start = (x->next_grain_pos_start + x->grain_sound_length) * buffer_getmillisamplerate(snd_object);
					}
				}
				// compute window buffer step size per vector sample 
				x->win_step_size = size_w * x->grain_freq * out_1oversr;
				// compute sound buffer step size per vector sample
				x->snd_step_size = x->grain_pitch * buffer_getsamplerate(snd_object) * out_1oversr;
				// reset position tracking variables
				if (x->grain_direction == FORWARD_GRAINS) {	// if forward...
					x->curr_snd_pos = x->grain_pos_start - x->snd_step_size;
				} else {	// if reverse...
					x->curr_snd_pos = x->grain_pos_start + x->snd_step_size;
				}
				x->curr_win_pos = 0.0;
				// reset history
				//x->snd_last_out = x->win_last_out = 0.0;	//removed 2005.02.03
				
				// update local vars
				s_step_size = x->snd_step_size;
				w_step_size = x->win_step_size;
				index_s = x->curr_snd_pos;
				index_w = x->curr_win_pos;
				
				#ifdef DEBUG
					post("%s: beginning of grain", OBJECT_NAME);
				#endif /* DEBUG */
					
			}
		}
		
		/* sound index is a double because it uses interp */
		if (g_direction == FORWARD_GRAINS) {	// if forward...
			index_s += s_step_size;		// add to sound index
		} else {	// if reverse...
			index_s -= s_step_size;		// subtract from sound index
		}
		
		/* check bounds of sound index */
		while (index_s < 0)
			index_s += size_s;
		while (index_s >= size_s)
			index_s -= size_s;
		
		//WINDOW OUT
		
		/* handle temporary vars for interpolation */
		temp_index_int = (long)(index_w); // integer portion of index
		temp_index_frac = index_w - (double)temp_index_int; // fractional portion of index
		
		/*
		if (nc_w > 1) // if buffer has multiple channels...
		{
			// get index to sample from within the interleaved frame
			temp_index_int = temp_index_int * nc_w + chan_w;
		}
		*/
		
		switch (interp_w) {
			case INTERP_ON:
				// perform linear interpolation on window buffer output
				win_out = mcLinearInterp(tab_w, temp_index_int, temp_index_frac, size_w, 1);
				break;
			case INTERP_OFF:
				// interpolation sounds better than following, but uses more CPU
				win_out = tab_w[temp_index_int];
				break;
		}
		
		//SOUND OUT
		
		/* handle temporary vars for interpolation */
		temp_index_int = (long)(index_s); // integer portion of index
		temp_index_frac = index_s - (double)temp_index_int; // fractional portion of index
		
		/*
		if (nc_s > 1) // if buffer has multiple channels...
		{
			// get index to sample from within the interleaved frame
			temp_index_int = temp_index_int * nc_s + chan_s;
		}
		*/
		
		switch (interp_s) {
			case INTERP_ON:
				// perform linear interpolation on sound buffer output
				snd_out = mcLinearInterp(tab_s, temp_index_int, temp_index_frac, size_s, 1);
				break;
			case INTERP_OFF:
				// interpolation sounds better than following, but uses more CPU
				snd_out = tab_s[temp_index_int];
				break;
		}
		
		/* multiply snd_out by win_out */
		*++out = snd_out * win_out;
		
		/* update last output variables */
		//last_s = snd_out;	//removed 2005.02.03
		//last_w = win_out;	//removed 2005.02.03
		last_index_w = index_w;
		
		/* advance other pointers */
		++in_freq, ++in_pos_start, ++in_pitch_mult;
	}
	
	/* update global position and step_size vars */
	x->curr_snd_pos = index_s;
	x->curr_win_pos = index_w;
	x->snd_step_size = s_step_size;
	x->win_step_size = w_step_size;
	
	/* update last output variables */
	//x->snd_last_out = last_s;	//removed 2005.02.03
	//x->win_last_out = last_w;	//removed 2005.02.03
	x->win_last_index = index_w;
	
    buffer_unlocksamples(snd_object);
    buffer_unlocksamples(win_object);
	
	return (w + 7);
	
zero:
	while (--vec_size >= 0) *++out = 0.;
out:
	return (w + 7);
}