#include "ext.h" #include "z_dsp.h" void *times_class; long fts_mode; #define VRSAVE asm { li r0,-1 ; mtspr vrsave,r0 } typedef struct _times { t_pxobject x_obj; t_float x_val; #ifdef __ALTIVEC__ #pragma altivec_model on vector float x_vecVal; #pragma altivec_model off #endif } t_times; void *times_new(double val); t_int *times_perform(t_int *w); t_int *scale_perform(t_int *w); void times_float(t_times *x, double f); void times_int(t_times *x, long n); void times_dsp(t_times *x, t_signal **sp, short *count); void times_assist(t_times *x, void *b, long m, long a, char *s); #ifdef __ALTIVEC__ void times_newAV(t_times *x, double val); t_int *times_performAV(t_int *w); t_int *scale_performAV(t_int *w); void times_floatAV(t_times *x, double f); void times_intAV(t_times *x, long n); #endif void main(void) { setup((t_messlist **)×_class, (method)times_new, 0L, (short)sizeof(t_times), 0L, A_DEFFLOAT, 0); dsp_initclass(); fts_mode = (long)dsp_fts_mode; addmess((method)times_dsp, "dsp", A_CANT, 0); if (!fts_mode) { addfloat((method)times_float); addint((method)times_int); } addmess((method)times_assist, "assist", A_CANT, 0); rescopy('STR#',3227); } void *times_new(double val) { t_times *x = (t_times *)newobject(times_class); dsp_setup((t_pxobject *)x,2); outlet_new((t_pxobject *)x, "signal"); x->x_val = val; #ifdef __ALTIVEC__ if (sys_altivec()) times_newAV(x,x->x_val); #endif return (x); } // this routine covers both inlets. It doesn't matter which one is involved void times_float(t_times *x, double f) { x->x_val = f; if (sys_optimize()) #ifdef __ALTIVEC__ times_floatAV(x,f); #else ; #endif } void times_int(t_times *x, long n) { times_float(x,(double)n); } t_int *times_perform(t_int *w) { t_float *in1,*in2,*out; int n; if (*(long *)(w[1])) goto out; in1 = (t_float *)(w[2]); in2 = (t_float *)(w[3]); out = (t_float *)(w[4]); n = (int)(w[5]); while (--n) *++out = *++in1 * *++in2; out: return (w + 6); } t_int *scale_perform(t_int *w) { t_float *in, *out; float val; int n; t_times *x = (t_times *)(w[3]); if (x->x_obj.z_disabled) goto out; in = (t_float *)(w[1]); out = (t_float *)(w[2]); val = x->x_val; n = (int)(w[4]); while (--n) *++out = val * *++in; out: return (w + 5); } #ifdef __ALTIVEC__ #pragma altivec_model on // turn AltiVec code generation on void times_newAV(t_times *x, double val) { VRSAVE vec_splat_float(x->x_vecVal, val); } void times_floatAV(t_times *x, double f) { VRSAVE vec_splat_float(x->x_vecVal, f); } void times_intAV(t_times *x, long n) { VRSAVE vec_splat_float(x->x_vecVal, (float)n); } t_int *times_performAV(t_int *w) { vector float *v_in1, *v_in2, *v_out, zero; unsigned int n = (int)(w[5]); VRSAVE if (*(long *)(w[1])) goto out; zero = (vector float) (0, 0, 0, 0); v_in1 = (vector float *)(w[2]); v_in2 = (vector float *)(w[3]); v_out = (vector float *)(w[4]); while (--n) { *++v_out = vec_madd(*++v_in1, *++v_in2, zero); } out: return (w + 6); } t_int *scale_performAV(t_int *w) { t_times *x = (t_times *)(w[3]); int n = (int)(w[4]); vector float *v_in, *v_out, val, zero; floatToVector foo; VRSAVE if (x->x_obj.z_disabled) goto out; zero = (vector float) (0, 0, 0, 0); v_in = (vector float *)(w[1]); v_out = (vector float *)(w[2]); val = x->x_vecVal; while (--n) { *++v_out = vec_madd(*++v_in, val, zero); } out: return (w + 5); } #pragma altivec_model off // turn AltiVec code generation off #endif void times_assist(t_times *x, void *b, long m, long a, char *s) { assist_string(3227,m,a,fts_mode? 4 : 1,3,s); } void times_dsp(t_times *x, t_signal **sp, short *count) { long i; if (fts_mode) dsp_add(times_perform, 5, &x->x_obj.z_disabled, sp[0]->s_vec-1, sp[1]->s_vec-1, sp[2]->s_vec-1, sp[0]->s_n+1); else { if (sys_optimize()) { #ifdef __ALTIVEC__ #pragma altivec_model on times_floatAV(x,x->x_val); // splat the vector if (!count[0]) dsp_add(scale_performAV, 4, sp[1]->s_vec-vec_step(vector float), sp[2]->s_vec-vec_step(vector float), x, (sp[0]->s_n / 4)+1); else if (!count[1]) dsp_add(scale_performAV, 4, sp[0]->s_vec-vec_step(vector float), sp[2]->s_vec-vec_step(vector float), x, (sp[0]->s_n / 4)+1); else { dsp_add(times_performAV, 5, &x->x_obj.z_disabled, sp[0]->s_vec-vec_step(vector float), sp[1]->s_vec-vec_step(vector float), sp[2]->s_vec-vec_step(vector float), (sp[0]->s_n / 4)+1); } #pragma altivec_model off #else error("*~: no optimizations available"); #endif } else { if (!count[0]) dsp_add(scale_perform, 4, sp[1]->s_vec-1, sp[2]->s_vec-1, x, sp[0]->s_n+1); else if (!count[1]) dsp_add(scale_perform, 4, sp[0]->s_vec-1, sp[2]->s_vec-1, x, sp[0]->s_n+1); else dsp_add(times_perform, 5, &x->x_obj.z_disabled, sp[0]->s_vec-1, sp[1]->s_vec-1, sp[2]->s_vec-1, sp[0]->s_n+1); } } }