Code Search for Developers
 
 
  

jcom.xfade~.cpp from Jamoma at Krugle


Show jcom.xfade~.cpp syntax highlighted

/* 
 * jcom.xfade~
 * External for Jamoma: multichannel crossfader using ttblue
 * By Tim Place, Copyright © 2005
 * 
 * License: This code is licensed under the terms of the GNU LGPL
 * http://www.gnu.org/licenses/lgpl.html 
 */

#include "ext.h"					// Max Header
#include "z_dsp.h"					// MSP Header
#include "ext_strings.h"			// String Functions
#include "commonsyms.h"				// Common symbols used by the Max 4.5 API
#include "ext_obex.h"				// Max Object Extensions (attributes) Header
#include "tt_audio_base.h"			// Tap.Tools Blue Headers...
#include "tt_audio_signal.h"
#include "tt_crossfade.h"	

#define MAX_NUM_CHANNELS 16


// Data Structure for this object
typedef struct _fade{					// Data Structure for this object
	t_pxobject 			x_obj;
	void				*obex;
	tt_crossfade		*xfade;			// crossfade object from the TapTools library
	long				attr_shape;
	long				attr_mode;
	float				attr_position;
	short				num_chans;
	tt_audio_signal 	*signal_in[3];
	tt_audio_signal		*signal_out;
} t_fade;

// Prototypes for methods
void *fade_new(t_symbol *s, short argc, t_atom *argv);				// New Object Creation Method
t_int *fade_perform1(t_int *w);										// An MSP Perform (signal) Method
t_int *fade_perform2(t_int *w);										// An MSP Perform (signal) Method
void fade_dsp(t_fade *x, t_signal **sp, short *count);				// DSP Method
void fade_assist(t_fade *x, void *b, long m, long a, char *s);		// Assistance Method
void fade_float(t_fade *x, double value );							// Float Method
void fade_free(t_fade *x);
t_max_err attr_set_position(t_fade *x, void *attr, long argc, t_atom *argv);
t_max_err attr_set_shape(t_fade *x, void *attr, long argc, t_atom *argv);
t_max_err attr_set_mode(t_fade *x, void *attr, long argc, t_atom *argv);
t_int *fade_perform_stereo_1(t_int *w);
t_int *fade_perform_stereo_2(t_int *w);

// Globals
t_class		*fade_class;		// Required. Global pointing to this class
t_symbol	*ps_float32;
t_symbol	*ps_long;
t_symbol	*ps_dumpout;


/************************************************************************************/
// Main() Function

int main(void)				// main recieves a copy of the Max function macros table
{
	long attrflags = 0;
	t_class *c;
	t_object *attr;
	
	common_symbols_init();
	ps_float32 = gensym("float32");
	ps_long = gensym("long");
	ps_dumpout = gensym("dumpout");

	// Define our class
	c = class_new("jcom.xfade~",(method)fade_new, (method)fade_free, (short)sizeof(t_fade), 
		(method)0L, A_GIMME, 0);
	class_obexoffset_set(c, calcoffset(t_fade, obex));

	// Make methods accessible for our class: 
	class_addmethod(c, (method)fade_float,				"float", A_FLOAT, 0L);
	class_addmethod(c, (method)fade_dsp, 				"dsp", A_CANT, 0L);
    class_addmethod(c, (method)object_obex_dumpout, 	"dumpout", A_CANT,0);  
    class_addmethod(c, (method)object_obex_quickref,	"quickref", A_CANT, 0);
    class_addmethod(c, (method)fade_assist, 			"assist", A_CANT, 0L);

	// Add attributes to our class:
	attr = attr_offset_new("shape", ps_long, attrflags,
		(method)0L,(method)attr_set_shape, calcoffset(t_fade, attr_shape));
	class_addattr(c, attr);
	
	attr = attr_offset_new("mode", ps_long, attrflags,
		(method)0L,(method)attr_set_mode, calcoffset(t_fade, attr_mode));
	class_addattr(c, attr);
	
	attr = attr_offset_new("position", ps_float32, attrflags,
		(method)0L,(method)attr_set_position, calcoffset(t_fade, attr_position));
	class_addattr(c, attr);	
	
	// Setup our class to work with MSP
	class_dspinit(c);

	// Finalize our class
	class_register(CLASS_BOX, c);
	fade_class = c;
	return 0;
}


/************************************************************************************/
// Object Life

// Create
void *fade_new(t_symbol *s, short argc, t_atom *argv)
{
	long attrstart = attr_args_offset(argc, argv);		// support normal arguments
	short i;
	
	t_fade *x = (t_fade *)object_alloc(fade_class);
	if(x){
		object_obex_store((void *)x, ps_dumpout, (object *)outlet_new(x, NULL));	// dumpout

		x->num_chans = 1;
		if(attrstart && argv){
			int argument = atom_getlong(argv);
			x->num_chans = tt_audio_base::clip(argument, 1, MAX_NUM_CHANNELS);
		}

		dsp_setup((t_pxobject *)x, (x->num_chans * 2) + 1);	// Create Object and N Inlets (last argument)
		x->x_obj.z_misc = Z_NO_INPLACE;  					// ESSENTIAL!   		
		for(i=0; i< (x->num_chans); i++)
			outlet_new((t_pxobject *)x, "signal");			// Create a signal Outlet   		
		
		x->xfade = new tt_crossfade;						// Constructors
		x->signal_out = new tt_audio_signal;
		for(i=0; i<3; i++){
			x->signal_in[i] = new tt_audio_signal;
		}
		
		x->xfade->set_attr(tt_crossfade::k_mode, 0);		// defaults
		x->xfade->set_attr(tt_crossfade::k_shape, 0);
		x->xfade->set_attr(tt_crossfade::k_position, 0.5);

		attr_args_process(x, argc, argv);					// handle attribute args				
	}
	return (x);												// Return the pointer
}

// Destroy
void fade_free(t_fade *x)
{
	short i;
	
	dsp_free((t_pxobject *)x);					// Always call dsp_free first in this routine
	delete x->xfade;
	delete x->signal_out;
	for(i=0; i<3; i++){
		delete x->signal_in[i];
	}
}

/************************************************************************************/
// Methods bound to input/inlets

// Method for Assistance Messages
void fade_assist(t_fade *x, void *b, long msg, long arg, char *dst)
{
	if(msg==1){ 	// Inlets
		if(arg < x->num_chans) strcpy(dst, "(signal) Input A");
		else if(arg < x->num_chans*2) strcpy(dst, "(signal) Input B");
		else strcpy(dst, "(float/signal) Crossfade Position");
	}
	else if(msg==2){ // Outlets
		if(arg < x->num_chans) strcpy(dst, "(signal) Crossfaded between A and B");
		else strcpy(dst, "dumpout");
	}
}


// Float Method
void fade_float(t_fade *x, double value)
{
	x->attr_position = value;
	x->xfade->set_attr(tt_crossfade::k_position, value);
}


// ATTRIBUTE: position
t_max_err attr_set_position(t_fade *x, void *attr, long argc, t_atom *argv)
{
	x->attr_position = atom_getfloat(argv);
	x->xfade->set_attr(tt_crossfade::k_position, x->attr_position);

	return MAX_ERR_NONE;
	#pragma unused(attr)
}


// ATTRIBUTE: shape
t_max_err attr_set_shape(t_fade *x, void *attr, long argc, t_atom *argv)
{
	x->attr_shape = atom_getlong(argv);
	if(x->attr_shape == 0) x->xfade->set_attr(tt_crossfade::k_shape, tt_crossfade::k_shape_equalpower);
	else x->xfade->set_attr(tt_crossfade::k_shape, tt_crossfade::k_shape_linear);

	return MAX_ERR_NONE;
	#pragma unused(attr)
}


// ATTRIBUTE: mode
t_max_err attr_set_mode(t_fade *x, void *attr, long argc, t_atom *argv)
{
	x->attr_mode = atom_getlong(argv);
	if(x->attr_mode == 0) x->xfade->set_attr(tt_crossfade::k_mode, tt_crossfade::k_mode_lookup);
	else x->xfade->set_attr(tt_crossfade::k_mode, tt_crossfade::k_mode_calculate);

	return MAX_ERR_NONE;
	#pragma unused(attr)
}


// control rate fading
t_int *fade_perform1(t_int *w)
{
  	t_fade *x = (t_fade *)(w[1]);						// Pointer
	x->signal_in[0]->set_vector((t_float *)(w[2]));		// Input Dry
	x->signal_in[1]->set_vector((t_float *)(w[3]));		// Input Wet
	x->signal_out->set_vector((t_float *)(w[4]));		// Output
	x->signal_in[0]->set_vectorsize((int)(w[5]));		// Vector Size

	if(!(x->x_obj.z_disabled))
		x->xfade->dsp_vector_calc(x->signal_in[0], x->signal_in[1], x->signal_out);

	return(w+6);
}


// signal rate fading
t_int *fade_perform2(t_int *w)
{
  	t_fade *x = (t_fade *)(w[1]);						// Pointer
	x->signal_in[0]->set_vector((t_float *)(w[2]));		// Input Dry
	x->signal_in[1]->set_vector((t_float *)(w[3]));		// Input Wet
	x->signal_in[2]->set_vector((t_float *)(w[4]));		// Input Control
	x->signal_out->set_vector((t_float *)(w[5]));		// Output
	x->signal_in[0]->set_vectorsize((int)(w[6]));		// Vector Size

	if(!(x->x_obj.z_disabled)){
		x->xfade->set_attr(tt_crossfade::k_position, *x->signal_in[2]->vector);	// automated at vector-rate rather than the sample-rate
		x->xfade->dsp_vector_calc(x->signal_in[0], x->signal_in[1], x->signal_out);
	}
	return(w+7);		// Return a pointer to the NEXT object in the DSP call chain
}


// DSP Method
void fade_dsp(t_fade *x, t_signal **sp, short *count)
{
	short i;

	// determine if a signal is being used to drive the crossfade position
	if(count[x->num_chans * 2]){			// SIGNAL RATE CROSSFADE CONNECTED
		for(i=0; i < x->num_chans; i++)		//add an instance of the perform method for each channel
			dsp_add(fade_perform2, 6, 
				x, 
				sp[i]->s_vec, 
				sp[i + x->num_chans]->s_vec, 
				sp[x->num_chans * 2]->s_vec, 
				sp[i + (x->num_chans * 2) + 1]->s_vec, 
				sp[i]->s_n 
			);
	}
	else{									// CONTROL RATE CROSSFADE
		for(i=0; i < x->num_chans; i++)		//add an instance of the perform method for each channel
			dsp_add(fade_perform1, 5, 
				x, 
				sp[i]->s_vec, 
				sp[i + x->num_chans]->s_vec, 
				sp[i + (x->num_chans * 2) + 1]->s_vec, 
				sp[i]->s_n 
			);
	}
}





See more files for this project here

Jamoma

Jamoma is a flexible framework for the creation of modules in Max, MSP, and Jitter

Project homepage: http://sourceforge.net/projects/jamoma
Programming language(s): C++,JavaScript,XML
License: other

  jcom.xfade~.xcodeproj/
    project.pbxproj
  jcom.xfade~.cpp
  jcom.xfade~.def
  jcom.xfade~.sln
  jcom.xfade~.vcproj