diff options
author | IOhannes m zmölnig <zmoelnig@users.sourceforge.net> | 2006-01-05 11:53:24 +0000 |
---|---|---|
committer | IOhannes m zmölnig <zmoelnig@users.sourceforge.net> | 2006-01-05 11:53:24 +0000 |
commit | 5c669899d3ccc8a60521e6bf8268f8f59fd3babb (patch) | |
tree | 6bb89a927cc55c4d3f33a9dd9b57dfe030fa82f6 /src | |
parent | ea546340b2574b2179eb14c34f26dc4b4c11dfb7 (diff) |
added [absgn~] as external (written by tim blechmann) and abstraction
the main purpose of this external is speed
svn path=/trunk/externals/zexy/; revision=4364
Diffstat (limited to 'src')
-rw-r--r-- | src/absgn~.c | 140 | ||||
-rw-r--r-- | src/z_zexy.c | 9 | ||||
-rw-r--r-- | src/z_zexy.h | 9 |
3 files changed, 150 insertions, 8 deletions
diff --git a/src/absgn~.c b/src/absgn~.c new file mode 100644 index 0000000..1d3d4bd --- /dev/null +++ b/src/absgn~.c @@ -0,0 +1,140 @@ +/****************************************************** + * + * zexy - implementation file + * + * (c) 2006 Tim Blechmann + * + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +#include "zexy.h" + +typedef struct _absgn +{ + t_object x_obj; + float x_f; +} t_absgn; + + +/* ------------------------ sigABSGN~ ----------------------------- */ + +static t_class *sigABSGN_class; + +static t_int *sigABSGN_perform(t_int *w) +{ + t_float *in = (t_float *)(w[1]); + t_float *out = (t_float *)(w[2]); + t_float *out2 = (t_float *)(w[3]); + int n = (int)(w[4]); + + while (n--) + { + t_float val = *in++; + *out++ = fabsf(val); + + if (val>0.) *out2++=1.; + else if (val<0.) *out2++=-1.; + else *out2++=0.; + } + + + return (w+5); +} + +#ifdef __SSE__ +static long l_bitmask[] ={0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; +static long l_sgnbitmask[]={0x80000000, 0x80000000, 0x80000000, 0x80000000}; +static t_int *sigABSGN_performSSE(t_int *w) +{ + __m128 *in = (__m128 *)(w[1]); + __m128 *out1 = (__m128 *)(w[2]); + __m128 *out2 = (__m128 *)(w[3]); + int n = (int)(w[4])>>3; + + const __m128 bitmask= _mm_loadu_ps((float*)l_bitmask); + const __m128 sgnmask= _mm_loadu_ps((float*)l_sgnbitmask); + const __m128 zero = _mm_setzero_ps(); + const __m128 one = _mm_set1_ps(1.f); + + do { + __m128 val, val2, xmm0, xmm1, xmm2, xmm3; + val=in[0]; + xmm0 = _mm_cmpneq_ps(val, zero); /* mask for non-zeros */ + xmm1 = _mm_and_ps (val, sgnmask);/* sign (without value) */ + xmm0 = _mm_and_ps (xmm0, one); /* (abs) value: (val==0.f)?0.f:1.f */ + out1[0]= _mm_and_ps (val, bitmask);/* abs: set sign-bit to "+" */ + out2[0]= _mm_or_ps (xmm1, xmm0); /* merge sign and value */ + + val2=in[1]; + xmm2 = _mm_cmpneq_ps(val2, zero); /* mask for non-zeros */ + xmm3 = _mm_and_ps (val2, sgnmask);/* sign (without value) */ + xmm2 = _mm_and_ps (xmm2, one); /* (abs) value: (val==0.f)?0.f:1.f */ + out1[1]= _mm_and_ps (val2, bitmask);/* abs: set sign-bit to "+" */ + out2[1]= _mm_or_ps (xmm3, xmm2); /* merge sign and value */ + + in +=2; + out+=2; + out2+=2; + } + while (--n); + + return (w+5); +} +#endif /* __SSE__ */ + +static void sigABSGN_dsp(t_absgn *x, t_signal **sp) +{ +#ifdef __SSE__ + if( + Z_SIMD_CHKBLOCKSIZE(sp[0]->s_n)&& + Z_SIMD_CHKALIGN(sp[0]->s_vec)&& + Z_SIMD_CHKALIGN(sp[1]->s_vec)&& + Z_SIMD_CHKALIGN(sp[2]->s_vec) + ) + { + dsp_add(sigABSGN_performSSE, 4, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n); + } else +#endif + { + dsp_add(sigABSGN_perform, 4, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n); + } +} + +static void sigABSGN_helper(void) +{ + post("\n%c absgn~ \t\t:: absolute value and sign of a signal", HEARTSYMBOL); + post(" \t\t copyright (c) Tim Blechmann 2006"); +} + +static void *sigABSGN_new(void) +{ + t_absgn *x = (t_absgn *)pd_new(sigABSGN_class); + x->x_f=0.f; + + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + + return (x); +} + +void absgn_tilde_setup(void) +{ + sigABSGN_class = class_new(gensym("absgn~"), (t_newmethod)sigABSGN_new, 0, + sizeof(t_absgn), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(sigABSGN_class, t_absgn, x_f); + class_addmethod(sigABSGN_class, (t_method)sigABSGN_dsp, gensym("dsp"), 0); + + class_addmethod(sigABSGN_class, (t_method)sigABSGN_helper, gensym("help"), 0); + class_sethelpsymbol(sigABSGN_class, gensym("zexy/sigbinops+")); + + zexy_register("absgn~"); +} + +void z_absgn__setup(void) +{ + absgn_tilde_setup(); +} diff --git a/src/z_zexy.c b/src/z_zexy.c index f7c1dc3..e1693c2 100644 --- a/src/z_zexy.c +++ b/src/z_zexy.c @@ -8,14 +8,15 @@ void z_zexy_setup(void) { z_a2l_setup(); /* a2l.c */ + z_absgn__setup(); /* absgn~.c */ z_abs__setup(); /* abs~.c */ z_atoi_setup(); /* atoi.c */ z_avg__setup(); /* avg~.c */ z_blockmirror__setup(); /* blockmirror~.c */ z_blockswap__setup(); /* blockswap~.c */ z_date_setup(); /* date.c */ - z_demultiplex__setup(); /* demultiplex~.c */ z_demultiplex_setup(); /* demultiplex.c */ + z_demultiplex__setup(); /* demultiplex~.c */ z_dfreq__setup(); /* dfreq~.c */ z_dirac__setup(); /* dirac~.c */ z_dot_setup(); /* dot.c */ @@ -36,14 +37,14 @@ void z_zexy_setup(void) z_minmax_setup(); /* minmax.c */ z_msgfile_setup(); /* msgfile.c */ z_multiline__setup(); /* multiline~.c */ - z_multiplex__setup(); /* multiplex~.c */ z_multiplex_setup(); /* multiplex.c */ + z_multiplex__setup(); /* multiplex~.c */ z_niagara_setup(); /* niagara.c */ z_noish__setup(); /* noish~.c */ z_noisi__setup(); /* noisi~.c */ z_operating_system_setup(); /* operating_system.c */ - z_pack__setup(); /* pack~.c */ z_packel_setup(); /* packel.c */ + z_pack__setup(); /* pack~.c */ z_pdf__setup(); /* pdf~.c */ z_prime_setup(); /* prime.c */ z_quantize__setup(); /* quantize~.c */ @@ -70,7 +71,7 @@ void z_zexy_setup(void) z_urn_setup(); /* urn.c */ z_winNT_portio_setup(); /* winNT_portio.c */ z_wrap_setup(); /* wrap.c */ - z_z__setup(); /* z~.c */ z_z_sigbin_setup(); /* z_sigbin.c */ + z_z__setup(); /* z~.c */ } diff --git a/src/z_zexy.h b/src/z_zexy.h index 6e09612..db1419d 100644 --- a/src/z_zexy.h +++ b/src/z_zexy.h @@ -6,14 +6,15 @@ #ifndef Z_ZEXY_H__ #define Z_ZEXY_H__ void z_a2l_setup(void); /* a2l.c */ +void z_absgn__setup(void); /* absgn~.c */ void z_abs__setup(void); /* abs~.c */ void z_atoi_setup(void); /* atoi.c */ void z_avg__setup(void); /* avg~.c */ void z_blockmirror__setup(void); /* blockmirror~.c */ void z_blockswap__setup(void); /* blockswap~.c */ void z_date_setup(void); /* date.c */ -void z_demultiplex__setup(void); /* demultiplex~.c */ void z_demultiplex_setup(void); /* demultiplex.c */ +void z_demultiplex__setup(void); /* demultiplex~.c */ void z_dfreq__setup(void); /* dfreq~.c */ void z_dirac__setup(void); /* dirac~.c */ void z_dot_setup(void); /* dot.c */ @@ -34,14 +35,14 @@ void z_mavg_setup(void); /* mavg.c */ void z_minmax_setup(void); /* minmax.c */ void z_msgfile_setup(void); /* msgfile.c */ void z_multiline__setup(void); /* multiline~.c */ -void z_multiplex__setup(void); /* multiplex~.c */ void z_multiplex_setup(void); /* multiplex.c */ +void z_multiplex__setup(void); /* multiplex~.c */ void z_niagara_setup(void); /* niagara.c */ void z_noish__setup(void); /* noish~.c */ void z_noisi__setup(void); /* noisi~.c */ void z_operating_system_setup(void); /* operating_system.c */ -void z_pack__setup(void); /* pack~.c */ void z_packel_setup(void); /* packel.c */ +void z_pack__setup(void); /* pack~.c */ void z_pdf__setup(void); /* pdf~.c */ void z_prime_setup(void); /* prime.c */ void z_quantize__setup(void); /* quantize~.c */ @@ -68,7 +69,7 @@ void z_unpack__setup(void); /* unpack~.c */ void z_urn_setup(void); /* urn.c */ void z_winNT_portio_setup(void); /* winNT_portio.c */ void z_wrap_setup(void); /* wrap.c */ -void z_z__setup(void); /* z~.c */ void z_z_sigbin_setup(void); /* z_sigbin.c */ +void z_z__setup(void); /* z~.c */ #endif /* Z_ZEXY_H__ */ |