[PD-cvs] externals/iem/iem_spec2/src iem_spec2.c, NONE, 1.1 iem_spec2.dsp, NONE, 1.1 iem_spec2.dsw, NONE, 1.1 iem_spec2.h, NONE, 1.1 iemlib.h, NONE, 1.1 makefile, NONE, 1.1 makefile_linux, NONE, 1.1 makefile_win, NONE, 1.1 spec2_1p1z_freq~.c, NONE, 1.1 spec2_1p1z_time~.c, NONE, 1.1 spec2_abs~.c, NONE, 1.1 spec2_add_scalar~.c, NONE, 1.1 spec2_add~.c, NONE, 1.1 spec2_block_delay~.c, NONE, 1.1 spec2_clip_max~.c, NONE, 1.1 spec2_clip_min~.c, NONE, 1.1 spec2_dbtopow~.c, NONE, 1.1 spec2_dbtorms~.c, NONE, 1.1 spec2_matrix_bundle_stat~.c, NONE, 1.1 spec2_mul_scalar~.c, NONE, 1.1 spec2_mul~.c, NONE, 1.1 spec2_powtodb~.c, NONE, 1.1 spec2_rmstodb~.c, NONE, 1.1 spec2_shift~.c, NONE, 1.1 spec2_sqrt~.c, NONE, 1.1 spec2_stretch~.c, NONE, 1.1 spec2_sub~.c, NONE, 1.1 spec2_sum~.c, NONE, 1.1 spec2_tab_conv~.c, NONE, 1.1 spec2_tabreceive_enable~.c, NONE, 1.1 spec2_tabreceive~.c, NONE, 1.1

musil tmusil at users.sourceforge.net
Fri Dec 8 08:47:51 CET 2006


Update of /cvsroot/pure-data/externals/iem/iem_spec2/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11414/iem/iem_spec2/src

Added Files:
	iem_spec2.c iem_spec2.dsp iem_spec2.dsw iem_spec2.h iemlib.h 
	makefile makefile_linux makefile_win spec2_1p1z_freq~.c 
	spec2_1p1z_time~.c spec2_abs~.c spec2_add_scalar~.c 
	spec2_add~.c spec2_block_delay~.c spec2_clip_max~.c 
	spec2_clip_min~.c spec2_dbtopow~.c spec2_dbtorms~.c 
	spec2_matrix_bundle_stat~.c spec2_mul_scalar~.c spec2_mul~.c 
	spec2_powtodb~.c spec2_rmstodb~.c spec2_shift~.c spec2_sqrt~.c 
	spec2_stretch~.c spec2_sub~.c spec2_sum~.c spec2_tab_conv~.c 
	spec2_tabreceive_enable~.c spec2_tabreceive~.c 
Log Message:
makefile
help
repaired spec2_sqrt~

--- NEW FILE: iem_spec2.dsw ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: makefile_linux ---
current: all

.SUFFIXES: .pd_linux

INCLUDE = -I. -I/usr/local/src/pd/src

LDFLAGS = -export-dynamic -shared
LIB = -ldl -lm -lpthread

#select either the DBG and OPT compiler flags below:

CFLAGS = -DPD -DUNIX -W -Werror -Wno-unused \
	-Wno-parentheses -Wno-switch -O6 -funroll-loops -fomit-frame-pointer -fno-strict-aliasing \
        -DDL_OPEN

SYSTEM = $(shell uname -m)

# the sources

SRC = spec2_1p1z_freq~.c \
	spec2_1p1z_time~.c \
	spec2_abs~.c \
	spec2_add_scalar~.c \
	spec2_add~.c \
	spec2_block_delay~.c \
	spec2_clip_max~.c \
	spec2_clip_min~.c \
	spec2_dbtopow~.c \
	spec2_dbtorms~.c \
	spec2_matrix_bundle_stat~.c \
	spec2_mul_scalar~.c \
	spec2_mul~.c \
  	spec2_powtodb~.c \
	spec2_rmstodb~.c \
	spec2_shift~.c \
	spec2_sqrt~.c \
	spec2_stretch~.c \
	spec2_sub~.c \
	spec2_sum~.c \
	spec2_tab_conv~.c \
	spec2_tabreceive_enable~.c \
	spec2_tabreceive~.c \
	iem_spec2.c

TARGET = iem_spec2.pd_linux


OBJ = $(SRC:.c=.o) 

#
#  ------------------ targets ------------------------------------
#

clean:
	rm ../$(TARGET)
	rm *.o

all: $(OBJ)
	@echo :: $(OBJ)
	$(LD) $(LDFLAGS) -o $(TARGET) *.o $(LIB)
	strip --strip-unneeded $(TARGET)
	mv $(TARGET) ..

$(OBJ) : %.o : %.c
	$(CC) $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c





--- NEW FILE: spec2_matrix_bundle_stat~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* ---------- spec2_matrix_bundle_stat~ - signal matrix multiplication object with message matrix-coeff. ----------- */

typedef struct spec2_matrix_bundle_stat_tilde
{
  t_object  x_obj;
  int       *x_matbuf;
  t_float   **x_io;
  t_float   *x_outsumbuf;
  int       x_outsumbufsize;
  int       x_n_in; /* columns */
  int       x_n_out;   /* rows  */
  t_float   x_msi;
} t_spec2_matrix_bundle_stat_tilde;

t_class *spec2_matrix_bundle_stat_tilde_class;

static void spec2_matrix_bundle_stat_tilde_element(t_spec2_matrix_bundle_stat_tilde *x, t_symbol *s, int argc, t_atom *argv)
{
  int inindex, outindex;
  int *matrix = x->x_matbuf;
  
  if(argc < 2)
  {
    post("spec2_matrix_bundle_stat~ : bad list: <int> output_row_index <int> input_col_index !");
    return;
  }
  
  outindex = (int)atom_getint(argv);
  argv++;
  inindex = (int)atom_getint(argv) - 1;
  
  if(inindex >= x->x_n_in)
    inindex = x->x_n_in - 1;
  if(inindex < 0)
    inindex = 0;
  if(outindex >= x->x_n_out)
    outindex = x->x_n_out;
  if(outindex < 0)
    outindex = 0;
  
  matrix[inindex] = outindex;
}

static void spec2_matrix_bundle_stat_tilde_list(t_spec2_matrix_bundle_stat_tilde *x, t_symbol *s, int argc, t_atom *argv)
{
  int outindex, i, n=x->x_n_in;
  int *matrix = x->x_matbuf;
  
  if(argc < n)
  {
    post("spec2_matrix_bundle_stat~ : bad list: (number_of_input_cols = %d) * <int> output_row_index !", n);
    return;
  }
  
  for(i=0; i<n; i++)
  {
    outindex = (int)atom_getint(argv);
    argv++;
    if(outindex >= x->x_n_out)
      outindex = x->x_n_out;
    if(outindex < 0)
      outindex = 0;
    matrix[i] = outindex;
  }
}

static void spec2_matrix_bundle_stat_tilde_bundle(t_spec2_matrix_bundle_stat_tilde *x, t_symbol *s, int argc, t_atom *argv)
{
  spec2_matrix_bundle_stat_tilde_list(x, &s_list, argc, argv);
}

/* the dsp thing */

static t_int *spec2_matrix_bundle_stat_tilde_perform(t_int *w)
{
  t_spec2_matrix_bundle_stat_tilde *x = (t_spec2_matrix_bundle_stat_tilde *)(w[1]);
  int n = (int)(w[2]);
  
  t_float **io = x->x_io;
  t_float *outsum;
  int *mat  = x->x_matbuf;
  int n_in = x->x_n_in;   /* columns */
  int n_out = x->x_n_out; /* rows */
  t_float *in, *out;
  int i, j, thrw;
  
  outsum = x->x_outsumbuf;
  for(j=0; j<n_out; j++)/* reset out-buffer */
  {
    for(i=0; i<=n; i++)
      *outsum++ = 0.0f;
  }
  
  for(j=0; j<n_in; j++)/* each in */
  {
    in = io[j];
    thrw = mat[j];
    if(thrw)
    {
      thrw--;
      outsum = x->x_outsumbuf + n*thrw;
      for(i=0; i<=n; i++)
        *outsum++ += *in++;
    }
  }
  
  outsum = x->x_outsumbuf;
  for(j=0; j<n_out; j++)/* copy out-buffer to out */
  {
    out = io[n_in+j];
    for(i=0; i<=n; i++)
      *out++ = *outsum++;
  }
  return (w+3);
}

static t_int *spec2_matrix_bundle_stat_tilde_perf8(t_int *w)
{
  t_spec2_matrix_bundle_stat_tilde *x = (t_spec2_matrix_bundle_stat_tilde *)(w[1]);
  int n = (int)(w[2]);
  
  t_float **io = x->x_io;
  t_float *outsum;
  int *mat  = x->x_matbuf;
  int n_in = x->x_n_in;   /* columns */
  int n_out = x->x_n_out; /* rows */
  t_float *in, *out;
  int i, j, thrw;
  
  for(j=0; j<n_out; j++)/* reset out-buffer */
  {
    outsum = x->x_outsumbuf + j*(n+1);
    for(i=n; i; i -= 8, outsum += 8)
    {
      outsum[0] = 0.0f;
      outsum[1] = 0.0f;
      outsum[2] = 0.0f;
      outsum[3] = 0.0f;
      outsum[4] = 0.0f;
      outsum[5] = 0.0f;
      outsum[6] = 0.0f;
      outsum[7] = 0.0f;
    }
    outsum[0] = 0.0f;
  }
  
  for(j=0; j<n_in; j++)/* each in */
  {
    in = io[j];
    thrw = mat[j];
    if(thrw)
    {
      thrw--;
      outsum = x->x_outsumbuf + (n+1)*thrw;
      for(i=n; i; i -= 8, outsum += 8, in += 8)
      {
        outsum[0] += in[0];
        outsum[1] += in[1];
        outsum[2] += in[2];
        outsum[3] += in[3];
        outsum[4] += in[4];
        outsum[5] += in[5];
        outsum[6] += in[6];
        outsum[7] += in[7];
      }
      outsum[0] += in[0];
    }
  }
  
  for(j=0; j<n_out; j++)/* copy out-buffer to out */
  {
    out = io[n_in+j];
    outsum = x->x_outsumbuf + j*(n+1);
    for (i=n; i; i -= 8, out += 8, outsum += 8)
    {
      out[0] = outsum[0];
      out[1] = outsum[1];
      out[2] = outsum[2];
      out[3] = outsum[3];
      out[4] = outsum[4];
      out[5] = outsum[5];
      out[6] = outsum[6];
      out[7] = outsum[7];
    }
    out[0] = outsum[0];
  }
  return (w+3);
}

static void spec2_matrix_bundle_stat_tilde_dsp(t_spec2_matrix_bundle_stat_tilde *x, t_signal **sp)
{
  int i, n=x->x_n_out*sp[0]->s_n/2;
  
  if(!x->x_outsumbuf)
  {
    x->x_outsumbufsize = n;
    x->x_outsumbuf = (t_float *)getbytes((x->x_outsumbufsize+x->x_n_out) * sizeof(t_float));
  }
  else if(x->x_outsumbufsize != n)
  {
    x->x_outsumbuf = (t_float *)resizebytes(x->x_outsumbuf, (x->x_outsumbufsize+x->x_n_out)*sizeof(t_float), (n+x->x_n_out)*sizeof(t_float));
    x->x_outsumbufsize = n;
  }
  
  n = x->x_n_in + x->x_n_out;
  for(i=0; i<n; i++)
  {
    x->x_io[i] = sp[i]->s_vec;
    /*post("iovec_addr = %d", (unsigned int)x->x_io[i]);*/
  }
  
  n = sp[0]->s_n/2;
  if(n&7)
    dsp_add(spec2_matrix_bundle_stat_tilde_perform, 2, x, n);
  else
    dsp_add(spec2_matrix_bundle_stat_tilde_perf8, 2, x, n);
}


/* setup/setdown things */

static void spec2_matrix_bundle_stat_tilde_free(t_spec2_matrix_bundle_stat_tilde *x)
{
  freebytes(x->x_matbuf, x->x_n_in * sizeof(int));
  freebytes(x->x_io, (x->x_n_in + x->x_n_out) * sizeof(t_float *));
  if(x->x_outsumbuf)
    freebytes(x->x_outsumbuf, (x->x_outsumbufsize+1) * sizeof(t_float));
}

static void *spec2_matrix_bundle_stat_tilde_new(t_symbol *s, int argc, t_atom *argv)
{
  t_spec2_matrix_bundle_stat_tilde *x = (t_spec2_matrix_bundle_stat_tilde *)pd_new(spec2_matrix_bundle_stat_tilde_class);
  int i;
  
  switch (argc)
  {
  case 0:
    x->x_n_in = x->x_n_out = 1;
    break;
  case 1:
    x->x_n_in = x->x_n_out = (int)atom_getint(argv);
    break;
  default:
    x->x_n_in = (int)atom_getint(argv);
    x->x_n_out = (int)atom_getint(argv+1);
    break;
  }
  
  if(x->x_n_in < 1)
    x->x_n_in = 1;
  if(x->x_n_out < 1)
    x->x_n_out = 1;
  i = x->x_n_in - 1;
  while(i--)
    inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
  i = x->x_n_out;
  while(i--)
    outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0;
  x->x_outsumbuf = (t_float *)0;
  x->x_outsumbufsize = 0;
  x->x_matbuf = (int *)getbytes(x->x_n_in * sizeof(int));
  x->x_io = (t_float **)getbytes((x->x_n_in + x->x_n_out) * sizeof(t_float *));
  return (x);
}

void spec2_matrix_bundle_stat_tilde_setup(void)
{
  spec2_matrix_bundle_stat_tilde_class = class_new(gensym("spec2_matrix_bundle_stat~"), (t_newmethod)spec2_matrix_bundle_stat_tilde_new, (t_method)spec2_matrix_bundle_stat_tilde_free,
    sizeof(t_spec2_matrix_bundle_stat_tilde), 0, A_GIMME, 0);
  CLASS_MAINSIGNALIN(spec2_matrix_bundle_stat_tilde_class, t_spec2_matrix_bundle_stat_tilde, x_msi);
  class_addmethod(spec2_matrix_bundle_stat_tilde_class, (t_method)spec2_matrix_bundle_stat_tilde_dsp, gensym("dsp"), 0);
  class_addlist(spec2_matrix_bundle_stat_tilde_class, (t_method)spec2_matrix_bundle_stat_tilde_list);
  class_addmethod(spec2_matrix_bundle_stat_tilde_class, (t_method)spec2_matrix_bundle_stat_tilde_element, gensym("element"), A_GIMME, 0);
  class_addmethod(spec2_matrix_bundle_stat_tilde_class, (t_method)spec2_matrix_bundle_stat_tilde_bundle, gensym("bundle"), A_GIMME, 0);
  class_sethelpsymbol(spec2_matrix_bundle_stat_tilde_class, gensym("iemhelp2/spec2_matrix_bundle_stat~-help"));
}

--- NEW FILE: spec2_powtodb~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"
#include <math.h>

#define SPEC2LOGTEN 2.302585092994f

/* ------------------------ spec2_powtodb_tilde~ ------------------------- */

static t_class *spec2_powtodb_tilde_class;

typedef struct _spec2_powtodb_tilde
{
  t_object  x_obj;
  t_float   x_msi;
} t_spec2_powtodb_tilde;

static t_int *spec2_powtodb_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  int n = w[3]+1;
  
  for(; n--; in++, out++)
  {
    t_float f = *in;
    
    if(f <= 0.0f)
      *out = 0.0f;
    else
    {
      t_float g = 100.0f + 10.0f/SPEC2LOGTEN * log(f);
      *out = (g < 0.0f ? 0.0f : g);
    }
  }
  return(w+4);
}

static void spec2_powtodb_tilde_dsp(t_spec2_powtodb_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  dsp_add(spec2_powtodb_tilde_perform, 3, sp[0]->s_vec, sp[0]->s_vec, n);
}

static void *spec2_powtodb_tilde_new(void)
{
  t_spec2_powtodb_tilde *x = (t_spec2_powtodb_tilde *)pd_new(spec2_powtodb_tilde_class);
  
  outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0.0f;
  return (x);
}

void spec2_powtodb_tilde_setup(void)
{
  spec2_powtodb_tilde_class = class_new(gensym("spec2_powtodb~"), (t_newmethod)spec2_powtodb_tilde_new,
    0, sizeof(t_spec2_powtodb_tilde), 0, 0);
  CLASS_MAINSIGNALIN(spec2_powtodb_tilde_class, t_spec2_powtodb_tilde, x_msi);
  class_addmethod(spec2_powtodb_tilde_class, (t_method)spec2_powtodb_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_powtodb_tilde_class, gensym("iemhelp2/spec2_powtodb~-help"));
}

--- NEW FILE: makefile_win ---

all: ..\iem_spec2.dll

VIS_CPP_PATH = "C:\Programme\Microsoft Visual Studio\Vc98"

PD_INST_PATH = "C:\Programme\pd"

PD_WIN_INCLUDE_PATH = /I. /I$(PD_INST_PATH)\src /I$(VIS_CPP_PATH)\include

PD_WIN_C_FLAGS = /nologo /W3 /WX /DMSW /DNT /DPD /DWIN32 /DWINDOWS /Ox -DPA_LITTLE_ENDIAN

PD_WIN_L_FLAGS = /nologo

PD_WIN_LIB = /NODEFAULTLIB:libc /NODEFAULTLIB:oldnames /NODEFAULTLIB:kernel /NODEFAULTLIB:uuid \
	$(VIS_CPP_PATH)\lib\libc.lib \
	$(VIS_CPP_PATH)\lib\oldnames.lib \
	$(VIS_CPP_PATH)\lib\kernel32.lib \
	$(VIS_CPP_PATH)\lib\wsock32.lib \
	$(VIS_CPP_PATH)\lib\winmm.lib \
	$(PD_INST_PATH)\bin\pd.lib


SRC =	spec2_1p1z_freq~.c \
	spec2_1p1z_time~.c \
	spec2_abs~.c \
	spec2_add_scalar~.c \
	spec2_add~.c \
	spec2_block_delay~.c \
	spec2_clip_max~.c \
	spec2_clip_min~.c \
	spec2_dbtopow~.c \
	spec2_dbtorms~.c \
	spec2_matrix_bundle_stat~.c \
	spec2_mul_scalar~.c \
	spec2_mul~.c \
  	spec2_powtodb~.c \
	spec2_rmstodb~.c \
	spec2_shift~.c \
	spec2_sqrt~.c \
	spec2_stretch~.c \
	spec2_sub~.c \
	spec2_sum~.c \
	spec2_tab_conv~.c \
	spec2_tabreceive_enable~.c \
	spec2_tabreceive~.c \
	iem_spec2.c


OBJ = $(SRC:.c=.obj)

.c.obj:
	cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c

..\iem_spec2.dll: $(OBJ)
	link $(PD_WIN_L_FLAGS) /dll /export:iem_spec2_setup \
	/out:..\iem_spec2.dll $(OBJ) $(PD_WIN_LIB)

clean:
	del *.obj

--- NEW FILE: iem_spec2.h ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#ifndef __IEMSPEC2_H__
#define __IEMSPEC2_H__

#define DELLINE_DEF_VEC_SIZE 64

#endif

--- NEW FILE: spec2_sqrt~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"
#include <math.h>

/* ------------------------ spec2_sqrt_tilde~ ------------------------- */

static t_class *spec2_sqrt_tilde_class;

#define SPEC2DUMTAB1SIZE 256
#define SPEC2DUMTAB2SIZE 1024

static t_float spec2_rsqrt_exptab[SPEC2DUMTAB1SIZE], spec2_rsqrt_mantissatab[SPEC2DUMTAB2SIZE];

static void init_spec2_rsqrt(void)
{
  int i;
  
  for (i=0; i<SPEC2DUMTAB1SIZE; i++)
  {
    t_float f;
    long l = (i ? (i == SPEC2DUMTAB1SIZE-1 ? SPEC2DUMTAB1SIZE-2 : i) : 1)<< 23;
    
    *(long *)(&f) = l;
    spec2_rsqrt_exptab[i] = 1.0f/sqrt(f); 
  }
  
  for (i=0; i<SPEC2DUMTAB2SIZE; i++)
  {
    t_float f = 1.0f + (1.0f / (t_float)SPEC2DUMTAB2SIZE) * (t_float)i;
    
    spec2_rsqrt_mantissatab[i] = 1.0f / sqrt(f);  
  }
}

typedef struct _spec2_sqrt_tilde
{
  t_object  x_obj;
  t_float   x_msi;
} t_spec2_sqrt_tilde;

static t_int *spec2_sqrt_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  int n = w[3]+1;
  
  while(n--)
  { 
    t_float f = *in;
    long l = *(long *)(in++);
    
    if(f < 0.0f)
      *out++ = 0.0f;
    else
    {
      t_float g = spec2_rsqrt_exptab[(l >> 23) & 0xff] * spec2_rsqrt_mantissatab[(l >> 13) & 0x3ff];
      
      *out++ = f*g*(1.5f - 0.5f*g*g*f);
    }
  }
  return(w+4);
}

static void spec2_sqrt_tilde_dsp(t_spec2_sqrt_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  dsp_add(spec2_sqrt_tilde_perform, 3, sp[0]->s_vec, sp[0]->s_vec, n);
}

static void *spec2_sqrt_tilde_new(void)
{
  t_spec2_sqrt_tilde *x = (t_spec2_sqrt_tilde *)pd_new(spec2_sqrt_tilde_class);
  
  outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0.0f;
  return (x);
}

void spec2_sqrt_tilde_setup(void)
{
  init_spec2_rsqrt();
  spec2_sqrt_tilde_class = class_new(gensym("spec2_sqrt~"), (t_newmethod)spec2_sqrt_tilde_new,
    0, sizeof(t_spec2_sqrt_tilde), 0, 0);
  CLASS_MAINSIGNALIN(spec2_sqrt_tilde_class, t_spec2_sqrt_tilde, x_msi);
  class_addmethod(spec2_sqrt_tilde_class, (t_method)spec2_sqrt_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_sqrt_tilde_class, gensym("iemhelp2/spec2_sqrt~-help"));
}

--- NEW FILE: spec2_stretch~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil (c) IEM KUG Graz Austria 2002 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* -- spec2_stretch~ - stretch spectral bins --- */

typedef struct spec2_stretch_tilde
{
  t_object  x_obj;
  int       x_blocksize;
  t_float   x_mul;
  t_float   *x_spec;
  t_float   x_msi;
} t_spec2_stretch_tilde;

t_class *spec2_stretch_tilde_class;

static t_int *spec2_stretch_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  t_spec2_stretch_tilde *x = (t_spec2_stretch_tilde *)(w[3]);
  int i, j, m, n = (t_int)(w[4])+1;
  t_float yn0, yn1, fract;
  t_float *spec=x->x_spec;
  t_float mul=x->x_mul;
  t_float rcp_mul = 1.0f / mul;
  
  for(i=0; i<n; i++)/* copy spec into buffer */
    spec[i] = in[i];
  
  m = (int)((t_float)n * mul);
  if(m > n)
    m = n;
  for(i=0; i<m; i++)/* stretch spec-buffer */
  {
    fract = (t_float)i * rcp_mul;
    j = (int)fract;
    fract -= (t_float)j;
    yn0 = spec[j];
    yn1 = spec[j+1];
    out[i] = (yn1 - yn0)*fract + yn0;
  }
  for(i=m; i<n; i++)/* clear residal of spec-buffer */
    out[i] = 0.0f;
  
  return(w+5);
}

static void spec2_stretch_tilde_mul(t_spec2_stretch_tilde *x, t_floatarg mul)
{
  if(mul <= 0.0f)
    mul = 1.0f;
  x->x_mul = mul;
}

static void spec2_stretch_tilde_dsp(t_spec2_stretch_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(!x->x_blocksize)
  {
    x->x_spec = (t_float *)getbytes((n+1)*sizeof(t_float));
    x->x_blocksize = n;
  }
  else if(x->x_blocksize != n)
  {
    x->x_spec = (t_float *)resizebytes(x->x_spec, (x->x_blocksize+1)*sizeof(t_float), (n+1)*sizeof(t_float));
    x->x_blocksize = n;
  }
  dsp_add(spec2_stretch_tilde_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
}

static void *spec2_stretch_tilde_new(t_floatarg mul)
{
  t_spec2_stretch_tilde *x = (t_spec2_stretch_tilde *)pd_new(spec2_stretch_tilde_class);
  
  outlet_new(&x->x_obj, &s_signal);
  if(mul <= 0.0f)
    mul = 1.0f;
  x->x_blocksize = 0;
  x->x_mul = mul;
  x->x_spec = (t_float *)0;
  return (x);
}

static void spec2_stretch_tilde_free(t_spec2_stretch_tilde *x)
{
  if(x->x_spec)
    freebytes(x->x_spec, (x->x_blocksize+1) * sizeof(t_float));
}

void spec2_stretch_tilde_setup(void)
{
  spec2_stretch_tilde_class = class_new(gensym("spec2_stretch~"), (t_newmethod)spec2_stretch_tilde_new,
    0, sizeof(t_spec2_stretch_tilde), 0, A_DEFFLOAT, 0);
  CLASS_MAINSIGNALIN(spec2_stretch_tilde_class, t_spec2_stretch_tilde, x_msi);
  class_addmethod(spec2_stretch_tilde_class, (t_method)spec2_stretch_tilde_dsp, gensym("dsp"), 0);
  class_addfloat(spec2_stretch_tilde_class, (t_method)spec2_stretch_tilde_mul);
  class_sethelpsymbol(spec2_stretch_tilde_class, gensym("iemhelp/spec2_stretch~-help"));
}

--- NEW FILE: spec2_tabreceive_enable~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* ------------------------ spec2_tabreceive_enable_tilde~ ------------------------- */

static t_class *spec2_tabreceive_enable_tilde_class;

typedef struct _spec2_tabreceive_enable_tilde
{
  t_object  x_obj;
  t_float   *x_vec;
  t_symbol  *x_arrayname;
  int       x_enable;
} t_spec2_tabreceive_enable_tilde;

static void spec2_tabreceive_enable_tilde_symbol(t_spec2_tabreceive_enable_tilde *x, t_symbol *s)
{
  x->x_arrayname = s;
}

static void spec2_tabreceive_enable_tilde_float(t_spec2_tabreceive_enable_tilde *x, t_floatarg f)
{
  int i=(int)f;
  
  if(i)
    i = 1;
  
  x->x_enable = i;
}

static t_int *spec2_tabreceive_enable_tilde_perform(t_int *w)
{
  t_spec2_tabreceive_enable_tilde *x = (t_spec2_tabreceive_enable_tilde *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  int n = w[3]+1;
  t_float *vec = x->x_vec;
  
  if(vec && x->x_enable)
    while(n--)
      *out++ = *vec++;
    else
      while(n--)
        *out++ = 0.0f;
      return(w+4);
}

static t_int *spec2_tabreceive_enable_tilde_perf16(t_int *w)
{
  t_spec2_tabreceive_enable_tilde *x = (t_spec2_tabreceive_enable_tilde *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  int n = w[3];
  t_float *vec = x->x_vec;
  
  if(vec && x->x_enable)
  {
    while(n)
    {
      out[0] = vec[0];
      out[1] = vec[1];
      out[2] = vec[2];
      out[3] = vec[3];
      out[4] = vec[4];
      out[5] = vec[5];
      out[6] = vec[6];
      out[7] = vec[7];
      out[8] = vec[8];
      out[9] = vec[9];
      out[10] = vec[10];
      out[11] = vec[11];
      out[12] = vec[12];
      out[13] = vec[13];
      out[14] = vec[14];
      out[15] = vec[15];
      
      vec += 16;
      out += 16;
      n -= 16;
    }
    out[0] = vec[0];
  }
  else
  {
    while(n)
    {
      out[0] = 0.0f;
      out[1] = 0.0f;
      out[2] = 0.0f;
      out[3] = 0.0f;
      out[4] = 0.0f;
      out[5] = 0.0f;
      out[6] = 0.0f;
      out[7] = 0.0f;
      out[8] = 0.0f;
      out[9] = 0.0f;
      out[10] = 0.0f;
      out[11] = 0.0f;
      out[12] = 0.0f;
      out[13] = 0.0f;
      out[14] = 0.0f;
      out[15] = 0.0f;
      
      out += 16;
      n -= 16;
    }
    out[0] = 0.0f;
  }
  
  return(w+4);
}

static void spec2_tabreceive_enable_tilde_dsp(t_spec2_tabreceive_enable_tilde *x, t_signal **sp)
{
  t_garray *a;
  int vecsize;
  
  if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
  {
    if(*x->x_arrayname->s_name)
      error("spec2_tabreceive_enable~: %s: no such array", x->x_arrayname->s_name);
  }
  else if(!garray_getfloatarray(a, &vecsize, &x->x_vec))
    error("%s: bad template for spec2_tabreceive_enable~", x->x_arrayname->s_name);
  else 
  {
    int n = sp[0]->s_n;
    
    if(n < vecsize)
      vecsize = n;
    vecsize /= 2;
    if(vecsize&15)
      dsp_add(spec2_tabreceive_enable_tilde_perform, 3, x, sp[0]->s_vec, vecsize);
    else
      dsp_add(spec2_tabreceive_enable_tilde_perf16, 3, x, sp[0]->s_vec, vecsize);
  }
}

static void *spec2_tabreceive_enable_tilde_new(t_symbol *s, int argc, t_atom *argv)
{
  t_spec2_tabreceive_enable_tilde *x = (t_spec2_tabreceive_enable_tilde *)pd_new(spec2_tabreceive_enable_tilde_class);
  
  x->x_enable = 0;
  if((argc >= 1) && IS_A_SYMBOL(argv,0))
    x->x_arrayname = atom_getsymbolarg(0, argc, argv);
  if((argc >= 2) && IS_A_FLOAT(argv,1))
    x->x_enable = (int)atom_getintarg(1, argc, argv);
  if(x->x_enable)
    x->x_enable = 1;
  
  outlet_new(&x->x_obj, &s_signal);
  return (x);
}

void spec2_tabreceive_enable_tilde_setup(void)
{
  spec2_tabreceive_enable_tilde_class = class_new(gensym("spec2_tabreceive_enable~"), (t_newmethod)spec2_tabreceive_enable_tilde_new,
    0, sizeof(t_spec2_tabreceive_enable_tilde), 0, A_GIMME, 0);
  class_addmethod(spec2_tabreceive_enable_tilde_class, (t_method)spec2_tabreceive_enable_tilde_dsp, gensym("dsp"), 0);
  class_addsymbol(spec2_tabreceive_enable_tilde_class, (t_method)spec2_tabreceive_enable_tilde_symbol);
  class_addfloat(spec2_tabreceive_enable_tilde_class, (t_method)spec2_tabreceive_enable_tilde_float);
  class_sethelpsymbol(spec2_tabreceive_enable_tilde_class, gensym("iemhelp2/spec2_tabreceive_enable~-help"));
}

--- NEW FILE: spec2_rmstodb~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */


#include "m_pd.h"
#include "iemlib.h"
#include <math.h>

#define SPEC2LOGTEN 2.302585092994f

/* ------------------------ spec2_rmstodb_tilde~ ------------------------- */

static t_class *spec2_rmstodb_tilde_class;

typedef struct _spec2_rmstodb_tilde
{
  t_object  x_obj;
  t_float   x_msi;
} t_spec2_rmstodb_tilde;

static t_int *spec2_rmstodb_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  int n = w[3]+1;
  
  for(; n--; in++, out++)
  {
    t_float f = *in;
    
    if(f <= 0.0f)
      *out = 0.0f;
    else
    {
      t_float g = 100.0f + 20.0f/SPEC2LOGTEN * log(f);
      *out = (g < 0.0f ? 0.0f : g);
    }
  }
  return(w+4);
}

static void spec2_rmstodb_tilde_dsp(t_spec2_rmstodb_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  dsp_add(spec2_rmstodb_tilde_perform, 3, sp[0]->s_vec, sp[0]->s_vec, n);
}

static void *spec2_rmstodb_tilde_new(void)
{
  t_spec2_rmstodb_tilde *x = (t_spec2_rmstodb_tilde *)pd_new(spec2_rmstodb_tilde_class);
  
  outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0.0f;
  return (x);
}

void spec2_rmstodb_tilde_setup(void)
{
  spec2_rmstodb_tilde_class = class_new(gensym("spec2_rmstodb~"), (t_newmethod)spec2_rmstodb_tilde_new,
    0, sizeof(t_spec2_rmstodb_tilde), 0, 0);
  CLASS_MAINSIGNALIN(spec2_rmstodb_tilde_class, t_spec2_rmstodb_tilde, x_msi);
  class_addmethod(spec2_rmstodb_tilde_class, (t_method)spec2_rmstodb_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_rmstodb_tilde_class, gensym("iemhelp2/spec2_rmstodb~-help"));
}

--- NEW FILE: iem_spec2.dsp ---
# Microsoft Developer Studio Project File - Name="iem_spec2" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** NICHT BEARBEITEN **

# TARGTYPE "Win32 (x86) External Target" 0x0106

CFG=iem_spec2 - Win32 Debug
!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
!MESSAGE 
!MESSAGE NMAKE /f "iem_spec2.mak".
!MESSAGE 
!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
!MESSAGE 
!MESSAGE NMAKE /f "iem_spec2.mak" CFG="iem_spec2 - Win32 Debug"
!MESSAGE 
!MESSAGE Für die Konfiguration stehen zur Auswahl:
!MESSAGE 
!MESSAGE "iem_spec2 - Win32 Release" (basierend auf  "Win32 (x86) External Target")
!MESSAGE "iem_spec2 - Win32 Debug" (basierend auf  "Win32 (x86) External Target")
!MESSAGE 

# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""

!IF  "$(CFG)" == "iem_spec2 - Win32 Release"

# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Cmd_Line "NMAKE /f makefile_win"
# PROP BASE Rebuild_Opt "/a"
# PROP BASE Target_File "makefile_win.exe"
# PROP BASE Bsc_Name "makefile_win.bsc"
# PROP BASE Target_Dir ""
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Cmd_Line "NMAKE /f makefile_win"
# PROP Rebuild_Opt "/a"
# PROP Target_File "iem_spec2.exe"
# PROP Bsc_Name "iem_spec2.bsc"
# PROP Target_Dir ""

!ELSEIF  "$(CFG)" == "iem_spec2 - Win32 Debug"

# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Cmd_Line "NMAKE /f makefile_win"
# PROP BASE Rebuild_Opt "/a"
# PROP BASE Target_File "makefile_win.exe"
# PROP BASE Bsc_Name "makefile_win.bsc"
# PROP BASE Target_Dir ""
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Cmd_Line "NMAKE /f makefile_win"
# PROP Rebuild_Opt "/a"
# PROP Target_File "iem_spec2.exe"
# PROP Bsc_Name "iem_spec2.bsc"
# PROP Target_Dir ""

!ENDIF 

# Begin Target

# Name "iem_spec2 - Win32 Release"
# Name "iem_spec2 - Win32 Debug"

!IF  "$(CFG)" == "iem_spec2 - Win32 Release"

!ELSEIF  "$(CFG)" == "iem_spec2 - Win32 Debug"

!ENDIF 

# Begin Source File

SOURCE=.\makefile_win
# End Source File
# End Target
# End Project

--- NEW FILE: spec2_dbtorms~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"
#include <math.h>

#define SPEC2LOGTEN 2.302585092994f

/* ------------------------ spec2_dbtorms_tilde~ ------------------------- */

static t_class *spec2_dbtorms_tilde_class;

typedef struct _spec2_dbtorms_tilde
{
  t_object  x_obj;
  t_float   x_msi;
} t_spec2_dbtorms_tilde;

static t_int *spec2_dbtorms_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  int n = w[3]+1;
  
  for (; n--; in++, out++)
  { 
    t_float f = *in;
    
    if(f <= 0.0f)
      *out = 0.0f;
    else
    {
      if(f > 485.0f)
        f = 485.0f;
      *out = exp((SPEC2LOGTEN * 0.05f) * (f-100.0f));
    }
  }
  return(w+4);
}

static void spec2_dbtorms_tilde_dsp(t_spec2_dbtorms_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  dsp_add(spec2_dbtorms_tilde_perform, 3, sp[0]->s_vec, sp[0]->s_vec, n);
}

static void *spec2_dbtorms_tilde_new(void)
{
  t_spec2_dbtorms_tilde *x = (t_spec2_dbtorms_tilde *)pd_new(spec2_dbtorms_tilde_class);
  
  outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0.0f;
  return (x);
}

void spec2_dbtorms_tilde_setup(void)
{
  spec2_dbtorms_tilde_class = class_new(gensym("spec2_dbtorms~"), (t_newmethod)spec2_dbtorms_tilde_new,
    0, sizeof(t_spec2_dbtorms_tilde), 0, 0);
  CLASS_MAINSIGNALIN(spec2_dbtorms_tilde_class, t_spec2_dbtorms_tilde, x_msi);
  class_addmethod(spec2_dbtorms_tilde_class, (t_method)spec2_dbtorms_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_dbtorms_tilde_class, gensym("iemhelp2/spec2_dbtorms~-help"));
}

--- NEW FILE: spec2_tab_conv~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil (c) IEM KUG Graz Austria 2002 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* -- spec2_tab_conv~ - convolute a spectrum with a table --- */

typedef struct spec2_tab_conv_tilde
{
  t_object  x_obj;
  t_float   *x_spec;
  t_float   *x_beg_array;
  int       x_blocksize;
  int       x_winsize;
  int       x_has_changed;
  t_symbol  *x_sym_array;
  t_float   x_msi;
} t_spec2_tab_conv_tilde;

t_class *spec2_tab_conv_tilde_class;

static void spec2_tab_conv_tilde_set(t_spec2_tab_conv_tilde *x, t_symbol *s, int argc, t_atom *argv)
{
  if(argc >= 2)
  {
    x->x_sym_array = (t_symbol *)(atom_getsymbol(argv));
    argv++;
    x->x_winsize = (int)(atom_getint(argv));
    x->x_has_changed = 1;
  }
}

static t_int *spec2_tab_conv_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  t_spec2_tab_conv_tilde *x = (t_spec2_tab_conv_tilde *)(w[3]);
  t_float sum=0.0f;
  t_float *vec1, *vec2, *vec3, *win;
  int i, m, n = (int)(w[4])+1;
  int j, ws=x->x_winsize;
  
  vec2 = x->x_spec + n;
  vec1 = vec2;
  vec3 = vec2 + 2*n - 2;
  
  for(i=0; i<n; i++)
  {
    sum = in[i];
    *vec2++ = sum;
    *vec1-- = sum;
    *vec3-- = sum;
  }
  vec2 = x->x_spec + n - ws/2;
  win = x->x_beg_array;
  
  for(i=0; i<n; i++)
  {
    sum = 0.0f;
    for(j=0; j<ws; j++)
      sum += win[j] * vec2[j];
    out[i] = sum;
    vec2++;
  }
  return(w+5);
}

static void spec2_tab_conv_tilde_dsp(t_spec2_tab_conv_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  t_garray *a;
  int n_points;
  
  if(x->x_has_changed)
  {
    x->x_has_changed = 0;
    if(!(a = (t_garray *)pd_findbyclass(x->x_sym_array, garray_class)))
    {
      if(*x->x_sym_array->s_name)
        error("spec2_tab_conv~: %s: no such array", x->x_sym_array->s_name);
    }
    else if(!garray_getfloatarray(a, &n_points, &x->x_beg_array))
      error("%s: bad template for spec2_tab_conv~", x->x_sym_array->s_name);
    else 
    {
      if(n_points > (n+1))
        n_points = n+1;
      if(x->x_winsize < 0)
        x->x_winsize = 0;
      if(x->x_winsize > n_points)
        x->x_winsize = n_points;
    }
  }
  
  if(!x->x_blocksize)
  {
    x->x_spec = (t_float *)getbytes(3*(n+1)*sizeof(t_float));
    x->x_blocksize = n;
  }
  else if(x->x_blocksize != n)
  {
    x->x_spec = (t_float *)resizebytes(x->x_spec, 3*(x->x_blocksize+1)*sizeof(t_float), 3*(n+1)*sizeof(t_float));
    x->x_blocksize = n;
  }
  
  dsp_add(spec2_tab_conv_tilde_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
}

static void spec2_tab_conv_tilde_free(t_spec2_tab_conv_tilde *x)
{
  if(x->x_spec)
    freebytes(x->x_spec, 3*(x->x_blocksize+1)*sizeof(t_float));
}

static void *spec2_tab_conv_tilde_new(t_symbol *s, int argc, t_atom *argv)
{
  t_spec2_tab_conv_tilde *x = (t_spec2_tab_conv_tilde *)pd_new(spec2_tab_conv_tilde_class);
  
  if(argc >= 2)
  {
    x->x_sym_array = (t_symbol *)(atom_getsymbol(argv));
    argv++;
    x->x_winsize = (int)(atom_getint(argv));
    x->x_spec = (t_float *)0;
    x->x_beg_array = (t_float *)0;
    x->x_blocksize = 0;
    x->x_has_changed = 1;
    outlet_new(&x->x_obj, &s_signal);
    x->x_msi = 0.0f;
    return(x);
  }
  else
  {
    post("spec2_tab_conv~-ERROR: needs 2 args: <sym> convolution-array-name + <float> convolution-array-size !!!");
    return(0);
  }
}

void spec2_tab_conv_tilde_setup(void)
{
  spec2_tab_conv_tilde_class = class_new(gensym("spec2_tab_conv~"), (t_newmethod)spec2_tab_conv_tilde_new,
    (t_method)spec2_tab_conv_tilde_free, sizeof(t_spec2_tab_conv_tilde), 0, A_GIMME, 0);
  CLASS_MAINSIGNALIN(spec2_tab_conv_tilde_class, t_spec2_tab_conv_tilde, x_msi);
  class_addmethod(spec2_tab_conv_tilde_class, (t_method)spec2_tab_conv_tilde_dsp, gensym("dsp"), 0);
  class_addmethod(spec2_tab_conv_tilde_class, (t_method)spec2_tab_conv_tilde_set, gensym("set"), A_GIMME, 0);
  class_sethelpsymbol(spec2_tab_conv_tilde_class, gensym("iemhelp/spec2_tab_conv~-help"));
}

--- NEW FILE: spec2_sub~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* -------------------------- spec2_sub~ ------------------------------ */
static t_class *spec2_sub_tilde_class;

typedef struct _spec2_sub_tilde
{
  t_object  x_obj;
  t_float   x_msi;
} t_spec2_sub_tilde;

static t_int *spec2_sub_tilde_perform(t_int *w)
{
  t_float *in1 = (t_float *)(w[1]);
  t_float *in2 = (t_float *)(w[2]);
  t_float *out = (t_float *)(w[3]);
  int i, n = (t_int)(w[4]);
  
  for(i=0; i<=n; i++)
  {
    out[i] = in1[i] - in2[i];
  }
  return(w+5);
}

static t_int *spec2_sub_tilde_perf16(t_int *w)
{
  t_float *in1 = (t_float *)(w[1]);
  t_float *in2 = (t_float *)(w[2]);
  t_float *out = (t_float *)(w[3]);
  int n = (t_int)(w[4]);
  
  while(n)
  {
    out[0] = in1[0] - in2[0];
    out[1] = in1[1] - in2[1];
    out[2] = in1[2] - in2[2];
    out[3] = in1[3] - in2[3];
    out[4] = in1[4] - in2[4];
    out[5] = in1[5] - in2[5];
    out[6] = in1[6] - in2[6];
    out[7] = in1[7] - in2[7];
    out[8] = in1[8] - in2[8];
    out[9] = in1[9] - in2[9];
    out[10] = in1[10] - in2[10];
    out[11] = in1[11] - in2[11];
    out[12] = in1[12] - in2[12];
    out[13] = in1[13] - in2[13];
    out[14] = in1[14] - in2[14];
    out[15] = in1[15] - in2[15];
    
    
    in1 += 16;
    in2 += 16;
    out += 16;
    n -= 16;
  }
  out[0] = in1[0] - in2[0];
  return(w+5);
}

static void spec2_sub_tilde_dsp(t_spec2_sub_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(n&15)
    dsp_add(spec2_sub_tilde_perform, 4, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, n);
  else
    dsp_add(spec2_sub_tilde_perf16, 4, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, n);
}

static void *spec2_sub_tilde_new(void)
{
  t_spec2_sub_tilde *x = (t_spec2_sub_tilde *)pd_new(spec2_sub_tilde_class);
  
  inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
  outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0.0f;
  return (x);
}

static void spec2_sub_tilde_free(t_spec2_sub_tilde *x)
{
}

void spec2_sub_tilde_setup(void)
{
  spec2_sub_tilde_class = class_new(gensym("spec2_sub~"), (t_newmethod)spec2_sub_tilde_new, (t_method)spec2_sub_tilde_free,
    sizeof(t_spec2_sub_tilde), 0, 0);
  class_addcreator((t_newmethod)spec2_sub_tilde_new, gensym("spec2-~"), 0);
  CLASS_MAINSIGNALIN(spec2_sub_tilde_class, t_spec2_sub_tilde, x_msi);
  class_addmethod(spec2_sub_tilde_class, (t_method)spec2_sub_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_sub_tilde_class, gensym("iemhelp2/spec2_sub~-help"));
}

--- NEW FILE: makefile ---
current: all

.SUFFIXES: .pd_linux

INCLUDE = -I. -I/usr/local/src/pd/src

LDFLAGS = -export-dynamic -shared
LIB = -ldl -lm -lpthread

#select either the DBG and OPT compiler flags below:

CFLAGS = -DPD -DUNIX -W -Werror -Wno-unused \
	-Wno-parentheses -Wno-switch -O6 -funroll-loops -fomit-frame-pointer -fno-strict-aliasing \
        -DDL_OPEN

SYSTEM = $(shell uname -m)

# the sources

SRC = spec2_1p1z_freq~.c \
	spec2_1p1z_time~.c \
	spec2_abs~.c \
	spec2_add_scalar~.c \
	spec2_add~.c \
	spec2_block_delay~.c \
	spec2_clip_max~.c \
	spec2_clip_min~.c \
	spec2_dbtopow~.c \
	spec2_dbtorms~.c \
	spec2_matrix_bundle_stat~.c \
	spec2_mul_scalar~.c \
	spec2_mul~.c \
  	spec2_powtodb~.c \
	spec2_rmstodb~.c \
	spec2_shift~.c \
	spec2_sqrt~.c \
	spec2_stretch~.c \
	spec2_sub~.c \
	spec2_sum~.c \
	spec2_tab_conv~.c \
	spec2_tabreceive_enable~.c \
	spec2_tabreceive~.c \
	iem_spec2.c

TARGET = iem_spec2.pd_linux


OBJ = $(SRC:.c=.o) 

#
#  ------------------ targets ------------------------------------
#

clean:
	rm ../$(TARGET)
	rm *.o

all: $(OBJ)
	@echo :: $(OBJ)
	$(LD) $(LDFLAGS) -o $(TARGET) *.o $(LIB)
	strip --strip-unneeded $(TARGET)
	mv $(TARGET) ..

$(OBJ) : %.o : %.c
	$(CC) $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c





--- NEW FILE: spec2_block_delay~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* -------------------------- spec2_block_delay~ ------------------------------ */
static t_class *spec2_block_delay_tilde_class;

typedef struct _spec2_block_delay_tilde
{
  t_object  x_obj;
  t_float   *x_begmem;
  int       x_blocksize;
  t_float   x_msi;
} t_spec2_block_delay_tilde;

static t_int *spec2_block_delay_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  t_spec2_block_delay_tilde *x = (t_spec2_block_delay_tilde *)(w[3]);
  int i, n = (t_int)(w[4]);
  t_float *rw_vec;
  
  rw_vec = x->x_begmem;
  for(i=0; i<=n; i++)
  {
    t_float f = in[i];
    out[i] = rw_vec[i];
    rw_vec[i] = f;
  }
  return(w+5);
}

static t_int *spec2_block_delay_tilde_perf16(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  t_spec2_block_delay_tilde *x = (t_spec2_block_delay_tilde *)(w[3]);
  int i, n = (t_int)(w[4]);
  t_float *rw_vec, ff;
  
  rw_vec = x->x_begmem;
  while(n)
  {
    t_float f[16];
    
    f[0] = in[0];
    f[1] = in[1];
    f[2] = in[2];
    f[3] = in[3];
    f[4] = in[4];
    f[5] = in[5];
    f[6] = in[6];
    f[7] = in[7];
    f[8] = in[8];
    f[9] = in[9];
    f[10] = in[10];
    f[11] = in[11];
    f[12] = in[12];
    f[13] = in[13];
    f[14] = in[14];
    f[15] = in[15];
    
    out[0] = rw_vec[0];
    out[1] = rw_vec[1];
    out[2] = rw_vec[2];
    out[3] = rw_vec[3];
    out[4] = rw_vec[4];
    out[5] = rw_vec[5];
    out[6] = rw_vec[6];
    out[7] = rw_vec[7];
    out[8] = rw_vec[8];
    out[9] = rw_vec[9];
    out[10] = rw_vec[10];
    out[11] = rw_vec[11];
    out[12] = rw_vec[12];
    out[13] = rw_vec[13];
    out[14] = rw_vec[14];
    out[15] = rw_vec[15];
    
    rw_vec[0] = f[0];
    rw_vec[1] = f[1];
    rw_vec[2] = f[2];
    rw_vec[3] = f[3];
    rw_vec[4] = f[4];
    rw_vec[5] = f[5];
    rw_vec[6] = f[6];
    rw_vec[7] = f[7];
    rw_vec[8] = f[8];
    rw_vec[9] = f[9];
    rw_vec[10] = f[10];
    rw_vec[11] = f[11];
    rw_vec[12] = f[12];
    rw_vec[13] = f[13];
    rw_vec[14] = f[14];
    rw_vec[15] = f[15];
    
    rw_vec += 16;
    in += 16;
    out += 16;
    n -= 16;
  }
  ff = in[0];
  out[0] = rw_vec[0];
  rw_vec[0] = ff;
  return(w+5);
}

static void spec2_block_delay_tilde_dsp(t_spec2_block_delay_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(!x->x_blocksize)/*first time*/
  {
    x->x_begmem = (t_float *)getbytes((n+1) * sizeof(t_float));
    x->x_blocksize = n;
  }
  else if(x->x_blocksize != n)
  {
    x->x_begmem = (t_float *)resizebytes(x->x_begmem, (x->x_blocksize+1)*sizeof(t_float), (n+1)*sizeof(t_float));
    x->x_blocksize = n;
  }
  if(n&15)
    dsp_add(spec2_block_delay_tilde_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
  else
    dsp_add(spec2_block_delay_tilde_perf16, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
}

static void *spec2_block_delay_tilde_new(void)
{
  t_spec2_block_delay_tilde *x = (t_spec2_block_delay_tilde *)pd_new(spec2_block_delay_tilde_class);
  
  x->x_blocksize = 0;
  x->x_begmem = (t_float *)0;
  outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0.0f;
  return (x);
}

static void spec2_block_delay_tilde_free(t_spec2_block_delay_tilde *x)
{
  if(x->x_begmem)
    freebytes(x->x_begmem, (x->x_blocksize+1) * sizeof(t_float));
}

void spec2_block_delay_tilde_setup(void)
{
  spec2_block_delay_tilde_class = class_new(gensym("spec2_block_delay~"), (t_newmethod)spec2_block_delay_tilde_new, (t_method)spec2_block_delay_tilde_free,
    sizeof(t_spec2_block_delay_tilde), 0, 0);
  CLASS_MAINSIGNALIN(spec2_block_delay_tilde_class, t_spec2_block_delay_tilde, x_msi);
  class_addmethod(spec2_block_delay_tilde_class, (t_method)spec2_block_delay_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_block_delay_tilde_class, gensym("iemhelp2/spec2_block_delay~-help"));
}

--- NEW FILE: spec2_abs~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */


#include "m_pd.h"
#include "iemlib.h"
#include <math.h>

/* ------------------------ spec2_abs_tilde~ ------------------------- */
static t_class *spec2_abs_tilde_class;

typedef struct _spec2_abs_tilde
{
  t_object  x_obj;
  t_float   x_msi;
} t_spec2_abs_tilde;

static t_int *spec2_abs_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  int n = w[3]+1;
  
  while(n--)
  { 
    *in++ = fabs(*out++);
  }
  return(w+4);
}

static t_int *spec2_abs_tilde_perf16(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  int n = w[3];
  
  while(n)
  { 
    in[0] = fabs(out[0]);
    in[1] = fabs(out[1]);
    in[2] = fabs(out[2]);
    in[3] = fabs(out[3]);
    in[4] = fabs(out[4]);
    in[5] = fabs(out[5]);
    in[6] = fabs(out[6]);
    in[7] = fabs(out[7]);
    in[8] = fabs(out[8]);
    in[9] = fabs(out[9]);
    in[10] = fabs(out[10]);
    in[11] = fabs(out[11]);
    in[12] = fabs(out[12]);
    in[13] = fabs(out[13]);
    in[14] = fabs(out[14]);
    in[15] = fabs(out[15]);
    
    in += 16;
    out += 16;
    n -= 16;
  }
  in[0] = fabs(out[0]);
  return(w+4);
}

static void spec2_abs_tilde_dsp(t_spec2_abs_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(n&15)
    dsp_add(spec2_abs_tilde_perform, 3, sp[0]->s_vec, sp[0]->s_vec, n);
  else
    dsp_add(spec2_abs_tilde_perf16, 3, sp[0]->s_vec, sp[0]->s_vec, n);
}

static void *spec2_abs_tilde_new(void)
{
  t_spec2_abs_tilde *x = (t_spec2_abs_tilde *)pd_new(spec2_abs_tilde_class);
  
  outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0.0f;
  return (x);
}

void spec2_abs_tilde_setup(void)
{
  spec2_abs_tilde_class = class_new(gensym("spec2_abs~"), (t_newmethod)spec2_abs_tilde_new,
    0, sizeof(t_spec2_abs_tilde), 0, 0);
  CLASS_MAINSIGNALIN(spec2_abs_tilde_class, t_spec2_abs_tilde, x_msi);
  class_addmethod(spec2_abs_tilde_class, (t_method)spec2_abs_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_abs_tilde_class, gensym("iemhelp2/spec2_abs~-help"));
}

--- NEW FILE: iemlib.h ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iemlib written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#ifndef __IEMLIB_H__
#define __IEMLIB_H__


#define IS_A_POINTER(atom,index) ((atom+index)->a_type == A_POINTER)
#define IS_A_FLOAT(atom,index) ((atom+index)->a_type == A_FLOAT)
#define IS_A_SYMBOL(atom,index) ((atom+index)->a_type == A_SYMBOL)
#define IS_A_DOLLAR(atom,index) ((atom+index)->a_type == A_DOLLAR)
#define IS_A_DOLLSYM(atom,index) ((atom+index)->a_type == A_DOLLSYM)
#define IS_A_SEMI(atom,index) ((atom+index)->a_type == A_SEMI)
#define IS_A_COMMA(atom,index) ((atom+index)->a_type == A_COMMA)


#ifdef NT
int sys_noloadbang;
//t_symbol *iemgui_key_sym=0;
#include <io.h>
#else
extern int sys_noloadbang;
//extern t_symbol *iemgui_key_sym;
#include <unistd.h>
#endif

#define DEFDELVS 64
#define XTRASAMPS 4
#define SAMPBLK 4


#define UNITBIT32 1572864.  /* 3*2^19; bit 32 has place value 1 */

/* machine-dependent definitions.  These ifdefs really
should have been by CPU type and not by operating system! */
#ifdef IRIX
/* big-endian.  Most significant byte is at low address in memory */
#define HIOFFSET 0    /* word offset to find MSB */
#define LOWOFFSET 1    /* word offset to find LSB */
#define int32 long  /* a data type that has 32 bits */
#else
#ifdef MSW
/* little-endian; most significant byte is at highest address */
#define HIOFFSET 1
#define LOWOFFSET 0
#define int32 long
#else
#ifdef __FreeBSD__
#include <machine/endian.h>
#if BYTE_ORDER == LITTLE_ENDIAN
#define HIOFFSET 1
#define LOWOFFSET 0
#else
#define HIOFFSET 0    /* word offset to find MSB */
#define LOWOFFSET 1    /* word offset to find LSB */
#endif /* BYTE_ORDER */
#include <sys/types.h>
#define int32 int32_t
#endif
#ifdef __linux__

#include <endian.h>

#if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)                         
#error No byte order defined                                                    
#endif                                                                          

#if __BYTE_ORDER == __LITTLE_ENDIAN                                             
#define HIOFFSET 1                                                              
#define LOWOFFSET 0                                                             
#else                                                                           
#define HIOFFSET 0    /* word offset to find MSB */                             
#define LOWOFFSET 1    /* word offset to find LSB */                            
#endif /* __BYTE_ORDER */                                                       

#include <sys/types.h>
#define int32 int32_t

#else
#ifdef __APPLE__
#define HIOFFSET 0    /* word offset to find MSB */
#define LOWOFFSET 1    /* word offset to find LSB */
#define int32 int  /* a data type that has 32 bits */

#endif /* __APPLE__ */
#endif /* __linux__ */
#endif /* MSW */
#endif /* SGI */

union tabfudge
{
  double tf_d;
  int32 tf_i[2];
};

#ifdef __i386__
#define IEM_DENORMAL(f) ((((*(unsigned int*)&(f))&0x60000000)==0) || \
(((*(unsigned int*)&(f))&0x60000000)==0x60000000))
/* more stringent test: anything not between 1e-19 and 1e19 in absolute val */
#else

#define IEM_DENORMAL(f) 0

#endif

#endif

--- NEW FILE: spec2_1p1z_time~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */


#include "m_pd.h"
#include "iemlib.h"

/* -------------------------- spec2_1p1z_time~ ------------------------------ */

static t_class *spec2_1p1z_time_tilde_class;

typedef struct _spec2_1p1z_time_tilde
{
  t_object  x_obj;
  t_float   x_a0;
  t_float   x_a1;
  t_float   x_b1;
  t_float   *x_begmem_forw;
  t_float   *x_begmem_back;
  int       x_blocksize;
  t_float   x_msi;
} t_spec2_1p1z_time_tilde;

static void spec2_1p1z_time_tilde_list(t_spec2_1p1z_time_tilde *x, t_symbol *s, int argc, t_atom *argv)
{
  if((argc >= 3) &&
    IS_A_FLOAT(argv,0) &&
    IS_A_FLOAT(argv,1) &&
    IS_A_FLOAT(argv,2))
  {
    x->x_a0 = (t_float)atom_getfloatarg(0, argc, argv);
    x->x_a1 = (t_float)atom_getfloatarg(1, argc, argv);
    x->x_b1 = (t_float)atom_getfloatarg(2, argc, argv);
  }
}

static t_int *spec2_1p1z_time_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  t_spec2_1p1z_time_tilde *x = (t_spec2_1p1z_time_tilde *)(w[3]);
  int i, n = (t_int)(w[4]);
  t_float a0 = x->x_a0;
  t_float a1 = x->x_a1;
  t_float b1 = x->x_b1;
  t_float *vec_forw = x->x_begmem_forw;
  t_float *vec_back = x->x_begmem_back;
  t_float f;
  
  for(i=0; i<=n; i++)
  {
    f = in[i];
    out[i] = a0*f + a1*vec_forw[i] + b1*vec_back[i];
    vec_forw[i] = f;
    vec_back[i] = out[i];
  }
  return(w+5);
}

static t_int *spec2_1p1z_time_tilde_perf16(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  t_spec2_1p1z_time_tilde *x = (t_spec2_1p1z_time_tilde *)(w[3]);
  int n = (t_int)(w[4]);
  t_float a0 = x->x_a0;
  t_float a1 = x->x_a1;
  t_float b1 = x->x_b1;
  t_float *vec_forw = x->x_begmem_forw;
  t_float *vec_back = x->x_begmem_back;
  t_float ff;
  
  while(n)
  {
    t_float f[16];
    
    f[0] = in[0];
    f[1] = in[1];
    f[2] = in[2];
    f[3] = in[3];
    f[4] = in[4];
    f[5] = in[5];
    f[6] = in[6];
    f[7] = in[7];
    f[8] = in[8];
    f[9] = in[9];
    f[10] = in[10];
    f[11] = in[11];
    f[12] = in[12];
    f[13] = in[13];
    f[14] = in[14];
    f[15] = in[15];
    
    out[0] = a0*f[0] + a1*vec_forw[0] + b1*vec_back[0];
    out[1] = a0*f[1] + a1*vec_forw[1] + b1*vec_back[1];
    out[2] = a0*f[2] + a1*vec_forw[2] + b1*vec_back[2];
    out[3] = a0*f[3] + a1*vec_forw[3] + b1*vec_back[3];
    out[4] = a0*f[4] + a1*vec_forw[4] + b1*vec_back[4];
    out[5] = a0*f[5] + a1*vec_forw[5] + b1*vec_back[5];
    out[6] = a0*f[6] + a1*vec_forw[6] + b1*vec_back[6];
    out[7] = a0*f[7] + a1*vec_forw[7] + b1*vec_back[7];
    out[8] = a0*f[8] + a1*vec_forw[8] + b1*vec_back[8];
    out[9] = a0*f[9] + a1*vec_forw[9] + b1*vec_back[9];
    out[10] = a0*f[10] + a1*vec_forw[10] + b1*vec_back[10];
    out[11] = a0*f[11] + a1*vec_forw[11] + b1*vec_back[11];
    out[12] = a0*f[12] + a1*vec_forw[12] + b1*vec_back[12];
    out[13] = a0*f[13] + a1*vec_forw[13] + b1*vec_back[13];
    out[14] = a0*f[14] + a1*vec_forw[14] + b1*vec_back[14];
    out[15] = a0*f[15] + a1*vec_forw[15] + b1*vec_back[15];
    
    vec_forw[0] = f[0];
    vec_forw[1] = f[1];
    vec_forw[2] = f[2];
    vec_forw[3] = f[3];
    vec_forw[4] = f[4];
    vec_forw[5] = f[5];
    vec_forw[6] = f[6];
    vec_forw[7] = f[7];
    vec_forw[8] = f[8];
    vec_forw[9] = f[9];
    vec_forw[10] = f[10];
    vec_forw[11] = f[11];
    vec_forw[12] = f[12];
    vec_forw[13] = f[13];
    vec_forw[14] = f[14];
    vec_forw[15] = f[15];
    
    vec_back[0] = out[0];
    vec_back[1] = out[1];
    vec_back[2] = out[2];
    vec_back[3] = out[3];
    vec_back[4] = out[4];
    vec_back[5] = out[5];
    vec_back[6] = out[6];
    vec_back[7] = out[7];
    vec_back[8] = out[8];
    vec_back[9] = out[9];
    vec_back[10] = out[10];
    vec_back[11] = out[11];
    vec_back[12] = out[12];
    vec_back[13] = out[13];
    vec_back[14] = out[14];
    vec_back[15] = out[15];
    
    in += 16;
    out += 16;
    vec_forw += 16;
    vec_back += 16;
    n -= 16;
  }
  ff = in[0];
  out[0] = a0*ff + a1*vec_forw[0] + b1*vec_back[0];
  vec_forw[0] = ff;
  vec_back[0] = out[0];
  return(w+5);
}

static void spec2_1p1z_time_tilde_dsp(t_spec2_1p1z_time_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(!x->x_blocksize)/*first time*/
  {
    x->x_begmem_forw = (t_float *)getbytes(2 * (n+1) * sizeof(t_float));
    x->x_blocksize = n;
    x->x_begmem_back = x->x_begmem_forw + n + 1;
  }
  else if(x->x_blocksize != n)
  {
    x->x_begmem_forw = (t_float *)resizebytes(x->x_begmem_forw, 2*(x->x_blocksize+1)*sizeof(t_float), 2*(n+1)*sizeof(t_float));
    x->x_blocksize = n;
    x->x_begmem_back = x->x_begmem_forw + n +1;
  }
  if(n&15)
    dsp_add(spec2_1p1z_time_tilde_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
  else
    dsp_add(spec2_1p1z_time_tilde_perf16, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
}

static void *spec2_1p1z_time_tilde_new(t_symbol *s, int argc, t_atom *argv)
{
  t_spec2_1p1z_time_tilde *x = (t_spec2_1p1z_time_tilde *)pd_new(spec2_1p1z_time_tilde_class);
  
  outlet_new(&x->x_obj, &s_signal);
  x->x_blocksize = 0;
  x->x_begmem_forw = (t_float *)0;
  if(argc >= 3)
    spec2_1p1z_time_tilde_list(x, s, argc, argv);
  else
  {
    x->x_a0 = 1.0f;
    x->x_a1 = 0.0f;
    x->x_b1 = 0.0f;
  }
  x->x_msi = 0.0f;
  return (x);
}

static void spec2_1p1z_time_tilde_free(t_spec2_1p1z_time_tilde *x)
{
  if(x->x_begmem_forw)
    freebytes(x->x_begmem_forw, 2 * (x->x_blocksize+1) * sizeof(t_float));
}

void spec2_1p1z_time_tilde_setup(void)
{
  spec2_1p1z_time_tilde_class = class_new(gensym("spec2_1p1z_time~"), (t_newmethod)spec2_1p1z_time_tilde_new, (t_method)spec2_1p1z_time_tilde_free,
    sizeof(t_spec2_1p1z_time_tilde), 0, A_GIMME, 0);
  CLASS_MAINSIGNALIN(spec2_1p1z_time_tilde_class, t_spec2_1p1z_time_tilde, x_msi);
  class_addlist(spec2_1p1z_time_tilde_class, (t_method)spec2_1p1z_time_tilde_list);
  class_addmethod(spec2_1p1z_time_tilde_class, (t_method)spec2_1p1z_time_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_1p1z_time_tilde_class, gensym("iemhelp2/spec2_1p1z_time~-help"));
}

--- NEW FILE: spec2_sum~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* ------------------------ spec2_sum_tilde~ ------------------------- */

static t_class *spec2_sum_tilde_class;

typedef struct _spec2_sum_tilde
{
  t_object  x_obj;
  t_float   x_msi;
} t_spec2_sum_tilde;

static t_int *spec2_sum_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  t_float sum = 0.0f;
  int n, hn;
  
  n = hn = w[3];
  sum = *in++;
  while(n--)
    sum += (*in++)*2.0f;
  while(hn--)
    *out++ = sum;
  *out++ = sum;
  return(w+4);
}

static t_int *spec2_sum_tilde_perf16(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  t_float sum=0.0f;
  int n, hn;
  
  n = hn = w[3];
  sum = *in++;
  while(n)
  { 
    sum += 2.0f*in[0];
    sum += 2.0f*in[1];
    sum += 2.0f*in[2];
    sum += 2.0f*in[3];
    sum += 2.0f*in[4];
    sum += 2.0f*in[5];
    sum += 2.0f*in[6];
    sum += 2.0f*in[7];
    sum += 2.0f*in[8];
    sum += 2.0f*in[9];
    sum += 2.0f*in[10];
    sum += 2.0f*in[11];
    sum += 2.0f*in[12];
    sum += 2.0f*in[13];
    sum += 2.0f*in[14];
    sum += 2.0f*in[15];
    
    in += 16;
    n -= 16;
  }
  
  while(hn)
  { 
    out[0] = sum;
    out[1] = sum;
    out[2] = sum;
    out[3] = sum;
    out[4] = sum;
    out[5] = sum;
    out[6] = sum;
    out[7] = sum;
    out[8] = sum;
    out[9] = sum;
    out[10] = sum;
    out[11] = sum;
    out[12] = sum;
    out[13] = sum;
    out[14] = sum;
    out[15] = sum;
    
    out += 16;
    hn -= 16;
  }
  out[0] = sum;
  return(w+4);
}

static void spec2_sum_tilde_dsp(t_spec2_sum_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(n&15)
    dsp_add(spec2_sum_tilde_perform, 3, sp[0]->s_vec, sp[0]->s_vec, n);
  else
    dsp_add(spec2_sum_tilde_perf16, 3, sp[0]->s_vec, sp[0]->s_vec, n);
}

static void *spec2_sum_tilde_new(void)
{
  t_spec2_sum_tilde *x = (t_spec2_sum_tilde *)pd_new(spec2_sum_tilde_class);
  
  outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0.0f;
  return (x);
}

void spec2_sum_tilde_setup(void)
{
  spec2_sum_tilde_class = class_new(gensym("spec2_sum~"), (t_newmethod)spec2_sum_tilde_new,
    0, sizeof(t_spec2_sum_tilde), 0, 0);
  CLASS_MAINSIGNALIN(spec2_sum_tilde_class, t_spec2_sum_tilde, x_msi);
  class_addmethod(spec2_sum_tilde_class, (t_method)spec2_sum_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_sum_tilde_class, gensym("iemhelp2/spec2_sum~-help"));
}

--- NEW FILE: spec2_shift~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil (c) IEM KUG Graz Austria 2002 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* -- spec2_shift~ - shift spectral bins to left (lower, negative) or to right (higher, positiv) --- */

typedef struct spec2_shift_tilde
{
  t_object  x_obj;
  int       x_blocksize;
  t_float   x_add;
  t_float   *x_spec;
  t_float   x_msi;
} t_spec2_shift_tilde;

t_class *spec2_shift_tilde_class;

static t_int *spec2_shift_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  t_spec2_shift_tilde *x = (t_spec2_shift_tilde *)(w[3]);
  int i, j, n = (t_int)(w[4])+1;
  t_float *spec=x->x_spec;
  t_float add=x->x_add;
  
  if((add >= n) || (add <= -n))
  {
    for(i=0; i<n; i++)/* clear residal of spec-buffer */
      out[i] = 0.0f;
  }
  else
  {
    for(i=0; i<n; i++)/* copy spec into buffer */
      spec[i] = in[i];
    
    if(add >= 0)
    {
      for(i=0; i<add; i++)/* clear residal of spec-buffer */
        out[i] = 0.0f;
      for(j=0; i<n; i++, j++)/* copy spec into buffer */
        out[i] = spec[j];
    }
    else
    {
      add *= -1;
      for(i=0, j=add; j<n; i++, j++)/* copy spec into buffer */
        out[i] = spec[j];
      for(; i<n; i++)/* clear residal of spec-buffer */
        out[i] = 0.0f;
    }
  }
  return(w+5);
}

static void spec2_shift_tilde_add(t_spec2_shift_tilde *x, t_floatarg add)
{
  x->x_add = add;
}

static void spec2_shift_tilde_dsp(t_spec2_shift_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(!x->x_blocksize)
  {
    x->x_spec = (t_float *)getbytes((n+1)*sizeof(t_float));
    x->x_blocksize = n;
  }
  else if(x->x_blocksize != n)
  {
    x->x_spec = (t_float *)resizebytes(x->x_spec, (x->x_blocksize+1)*sizeof(t_float), (n+1)*sizeof(t_float));
    x->x_blocksize = n;
  }
  dsp_add(spec2_shift_tilde_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
}

static void *spec2_shift_tilde_new(t_floatarg add)
{
  t_spec2_shift_tilde *x = (t_spec2_shift_tilde *)pd_new(spec2_shift_tilde_class);
  
  outlet_new(&x->x_obj, &s_signal);
  x->x_blocksize = 0;
  x->x_add = add;
  x->x_spec = (t_float *)0;
  return (x);
}

static void spec2_shift_tilde_free(t_spec2_shift_tilde *x)
{
  if(x->x_spec)
    freebytes(x->x_spec, (x->x_blocksize+1) * sizeof(t_float));
}

void spec2_shift_tilde_setup(void)
{
  spec2_shift_tilde_class = class_new(gensym("spec2_shift~"), (t_newmethod)spec2_shift_tilde_new,
    0, sizeof(t_spec2_shift_tilde), 0, A_DEFFLOAT, 0);
  CLASS_MAINSIGNALIN(spec2_shift_tilde_class, t_spec2_shift_tilde, x_msi);
  class_addmethod(spec2_shift_tilde_class, (t_method)spec2_shift_tilde_dsp, gensym("dsp"), 0);
  class_addfloat(spec2_shift_tilde_class, (t_method)spec2_shift_tilde_add);
  class_sethelpsymbol(spec2_shift_tilde_class, gensym("iemhelp/spec2_shift~-help"));
}

--- NEW FILE: spec2_clip_max~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* -------------------------- spec2_clip_max~ ------------------------------ */
static t_class *spec2_clip_max_tilde_class;

typedef struct _spec2_clip_max_tilde
{
  t_object  x_obj;
  t_float   x_msi;
} t_spec2_clip_max_tilde;

static t_int *spec2_clip_max_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *max = (t_float *)(w[2]);
  t_float *out = (t_float *)(w[3]);
  int i, n = (t_int)(w[4]);
  
  for(i=0; i<=n; i++)
  {
    if(in[i] > max[i])
      out[i] = max[i];
    else
      out[i] = in[i];
  }
  return(w+5);
}

static t_int *spec2_clip_max_tilde_perf16(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *max = (t_float *)(w[2]);
  t_float *out = (t_float *)(w[3]);
  int n = (t_int)(w[4]);
  
  while(n)
  {
    if(in[0] > max[0])
      out[0] = max[0];
    else
      out[0] = in[0];
    
    if(in[1] > max[1])
      out[1] = max[1];
    else
      out[1] = in[1];
    
    if(in[2] > max[2])
      out[2] = max[2];
    else
      out[2] = in[2];
    
    if(in[3] > max[3])
      out[3] = max[3];
    else
      out[3] = in[3];
    
    if(in[4] > max[4])
      out[4] = max[4];
    else
      out[4] = in[4];
    
    if(in[5] > max[5])
      out[5] = max[5];
    else
      out[5] = in[5];
    
    if(in[6] > max[6])
      out[6] = max[6];
    else
      out[6] = in[6];
    
    if(in[7] > max[7])
      out[7] = max[7];
    else
      out[7] = in[7];
    
    if(in[8] > max[8])
      out[8] = max[8];
    else
      out[8] = in[8];
    
    if(in[9] > max[9])
      out[9] = max[9];
    else
      out[9] = in[9];
    
    if(in[10] > max[10])
      out[10] = max[10];
    else
      out[10] = in[10];
    
    if(in[11] > max[11])
      out[11] = max[11];
    else
      out[11] = in[11];
    
    if(in[12] > max[12])
      out[12] = max[12];
    else
      out[12] = in[12];
    
    if(in[13] > max[13])
      out[13] = max[13];
    else
      out[13] = in[13];
    
    if(in[14] > max[14])
      out[14] = max[14];
    else
      out[14] = in[14];
    
    if(in[15] > max[15])
      out[15] = max[15];
    else
      out[15] = in[15];
    
    in += 16;
    max += 16;
    out += 16;
    n -= 16;
  }
  if(in[0] > max[0])
    out[0] = max[0];
  else
    out[0] = in[0];
  return(w+5);
}

static void spec2_clip_max_tilde_dsp(t_spec2_clip_max_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(n&15)
    dsp_add(spec2_clip_max_tilde_perform, 4, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, n);
  else
    dsp_add(spec2_clip_max_tilde_perf16, 4, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, n);
}

static void *spec2_clip_max_tilde_new(void)
{
  t_spec2_clip_max_tilde *x = (t_spec2_clip_max_tilde *)pd_new(spec2_clip_max_tilde_class);
  
  inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
  outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0.0f;
  return (x);
}

static void spec2_clip_max_tilde_free(t_spec2_clip_max_tilde *x)
{
}

void spec2_clip_max_tilde_setup(void)
{
  spec2_clip_max_tilde_class = class_new(gensym("spec2_clip_max~"), (t_newmethod)spec2_clip_max_tilde_new, (t_method)spec2_clip_max_tilde_free,
    sizeof(t_spec2_clip_max_tilde), 0, 0);
  CLASS_MAINSIGNALIN(spec2_clip_max_tilde_class, t_spec2_clip_max_tilde, x_msi);
  class_addmethod(spec2_clip_max_tilde_class, (t_method)spec2_clip_max_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_clip_max_tilde_class, gensym("iemhelp2/spec2_clip_max~-help"));
}

--- NEW FILE: spec2_mul~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* -------------------------- spec2_mul~ ------------------------------ */
static t_class *spec2_mul_tilde_class;

typedef struct _spec2_mul_tilde
{
  t_object  x_obj;
  t_float   x_msi;
} t_spec2_mul_tilde;

static t_int *spec2_mul_tilde_perform(t_int *w)
{
  t_float *in1 = (t_float *)(w[1]);
  t_float *in2 = (t_float *)(w[2]);
  t_float *out = (t_float *)(w[3]);
  int i, n = (t_int)(w[4]);
  
  for(i=0; i<=n; i++)
  {
    out[i] = in1[i] * in2[i];
  }
  return(w+5);
}

static t_int *spec2_mul_tilde_perf16(t_int *w)
{
  t_float *in1 = (t_float *)(w[1]);
  t_float *in2 = (t_float *)(w[2]);
  t_float *out = (t_float *)(w[3]);
  int n = (t_int)(w[4]);
  
  while(n)
  {
    out[0] = in1[0] * in2[0];
    out[1] = in1[1] * in2[1];
    out[2] = in1[2] * in2[2];
    out[3] = in1[3] * in2[3];
    out[4] = in1[4] * in2[4];
    out[5] = in1[5] * in2[5];
    out[6] = in1[6] * in2[6];
    out[7] = in1[7] * in2[7];
    out[8] = in1[8] * in2[8];
    out[9] = in1[9] * in2[9];
    out[10] = in1[10] * in2[10];
    out[11] = in1[11] * in2[11];
    out[12] = in1[12] * in2[12];
    out[13] = in1[13] * in2[13];
    out[14] = in1[14] * in2[14];
    out[15] = in1[15] * in2[15];
    
    
    in1 += 16;
    in2 += 16;
    out += 16;
    n -= 16;
  }
  out[0] = in1[0] * in2[0];
  return(w+5);
}

static void spec2_mul_tilde_dsp(t_spec2_mul_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(n&15)
    dsp_add(spec2_mul_tilde_perform, 4, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, n);
  else
    dsp_add(spec2_mul_tilde_perf16, 4, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, n);
}

static void *spec2_mul_tilde_new(void)
{
  t_spec2_mul_tilde *x = (t_spec2_mul_tilde *)pd_new(spec2_mul_tilde_class);
  
  inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
  outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0.0f;
  return (x);
}

static void spec2_mul_tilde_free(t_spec2_mul_tilde *x)
{
}

void spec2_mul_tilde_setup(void)
{
  spec2_mul_tilde_class = class_new(gensym("spec2_mul~"), (t_newmethod)spec2_mul_tilde_new, (t_method)spec2_mul_tilde_free,
    sizeof(t_spec2_mul_tilde), 0, 0);
  class_addcreator((t_newmethod)spec2_mul_tilde_new, gensym("spec2*~"), 0);
  CLASS_MAINSIGNALIN(spec2_mul_tilde_class, t_spec2_mul_tilde, x_msi);
  class_addmethod(spec2_mul_tilde_class, (t_method)spec2_mul_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_mul_tilde_class, gensym("iemhelp2/spec2_mul~-help"));
}

--- NEW FILE: spec2_mul_scalar~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* -------------------------- spec2_mul_scalar~ ------------------------------ */
static t_class *spec2_mul_scalar_tilde_class;

typedef struct _spec2_mul_scalar_tilde
{
  t_object  x_obj;
  t_float   x_f;
  t_float   x_msi;
} t_spec2_mul_scalar_tilde;

static void spec2_mul_scalar_tilde_ft1(t_spec2_mul_scalar_tilde *x, t_floatarg f)
{
  x->x_f = f;
}

static t_int *spec2_mul_scalar_tilde_perform(t_int *w)
{
  t_float *io = (t_float *)(w[1]);
  t_spec2_mul_scalar_tilde *x = (t_spec2_mul_scalar_tilde *)(w[2]);
  int i, n = (t_int)(w[3]);
  t_float f = x->x_f;
  
  for(i=0; i<=n; i++)
  {
    io[i] *= f;
  }
  return(w+4);
}

static t_int *spec2_mul_scalar_tilde_perf16(t_int *w)
{
  t_float *io = (t_float *)(w[1]);
  t_spec2_mul_scalar_tilde *x = (t_spec2_mul_scalar_tilde *)(w[2]);
  int n = (t_int)(w[3]);
  t_float f = x->x_f;
  
  while(n)
  {
    io[0] *= f;
    io[1] *= f;
    io[2] *= f;
    io[3] *= f;
    io[4] *= f;
    io[5] *= f;
    io[6] *= f;
    io[7] *= f;
    io[8] *= f;
    io[9] *= f;
    io[10] *= f;
    io[11] *= f;
    io[12] *= f;
    io[13] *= f;
    io[14] *= f;
    io[15] *= f;
    
    io += 16;
    n -= 16;
  }
  io[0] *= f;
  return(w+4);
}

static void spec2_mul_scalar_tilde_dsp(t_spec2_mul_scalar_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(n&15)
    dsp_add(spec2_mul_scalar_tilde_perform, 3, sp[0]->s_vec, x, n);
  else
    dsp_add(spec2_mul_scalar_tilde_perf16, 3, sp[0]->s_vec, x, n);
}

static void *spec2_mul_scalar_tilde_new(t_floatarg f)
{
  t_spec2_mul_scalar_tilde *x = (t_spec2_mul_scalar_tilde *)pd_new(spec2_mul_scalar_tilde_class);
  
  inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
  outlet_new(&x->x_obj, &s_signal);
  x->x_f = f;
  x->x_msi = 0.0f;
  return (x);
}

static void spec2_mul_scalar_tilde_free(t_spec2_mul_scalar_tilde *x)
{
}

void spec2_mul_scalar_tilde_setup(void)
{
  spec2_mul_scalar_tilde_class = class_new(gensym("spec2_mul_scalar~"), (t_newmethod)spec2_mul_scalar_tilde_new, (t_method)spec2_mul_scalar_tilde_free,
    sizeof(t_spec2_mul_scalar_tilde), 0, A_DEFFLOAT, 0);
  class_addcreator((t_newmethod)spec2_mul_scalar_tilde_new, gensym("spec2*s~"), A_DEFFLOAT, 0);
  CLASS_MAINSIGNALIN(spec2_mul_scalar_tilde_class, t_spec2_mul_scalar_tilde, x_msi);
  class_addmethod(spec2_mul_scalar_tilde_class, (t_method)spec2_mul_scalar_tilde_ft1, gensym("ft1"), A_FLOAT, 0);
  class_addmethod(spec2_mul_scalar_tilde_class, (t_method)spec2_mul_scalar_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_mul_scalar_tilde_class, gensym("iemhelp2/spec2_mul_scalar~-help"));
}

--- NEW FILE: iem_spec2.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */


#include "m_pd.h"
#include "iemlib.h"

static t_class *iem_spec2_class;

static void *iem_spec2_new(void)
{
  t_object *x = (t_object *)pd_new(iem_spec2_class);
  
  return (x);
}

void spec2_1p1z_freq_tilde_setup(void);
void spec2_1p1z_time_tilde_setup(void);
void spec2_abs_tilde_setup(void);
void spec2_add_scalar_tilde_setup(void);
void spec2_add_tilde_setup(void);
void spec2_block_delay_tilde_setup(void);
void spec2_clip_max_tilde_setup(void);
void spec2_clip_min_tilde_setup(void);
void spec2_dbtopow_tilde_setup(void);
void spec2_dbtorms_tilde_setup(void);
void spec2_matrix_bundle_stat_tilde_setup(void);
void spec2_mul_scalar_tilde_setup(void);
void spec2_mul_tilde_setup(void);
void spec2_powtodb_tilde_setup(void);
void spec2_rmstodb_tilde_setup(void);
void spec2_shift_tilde_setup(void);
void spec2_sqrt_tilde_setup(void);
void spec2_stretch_tilde_setup(void);
void spec2_sub_tilde_setup(void);
void spec2_sum_tilde_setup(void);
void spec2_tab_conv_tilde_setup(void);
void spec2_tabreceive_enable_tilde_setup(void);
void spec2_tabreceive_tilde_setup(void);

/* ------------------------ setup routine ------------------------- */

void iem_spec2_setup(void)
{
  iem_spec2_class = class_new(gensym("iem_spec2"), iem_spec2_new, 0,
    sizeof(t_object), CLASS_NOINLET, 0);
  
  spec2_1p1z_freq_tilde_setup();
  spec2_1p1z_time_tilde_setup();
  spec2_abs_tilde_setup();
  spec2_add_scalar_tilde_setup();
  spec2_add_tilde_setup();
  spec2_block_delay_tilde_setup();
  spec2_clip_max_tilde_setup();
  spec2_clip_min_tilde_setup();
  spec2_dbtopow_tilde_setup();
  spec2_dbtorms_tilde_setup();
  spec2_matrix_bundle_stat_tilde_setup();
  spec2_mul_scalar_tilde_setup();
  spec2_mul_tilde_setup();
  spec2_powtodb_tilde_setup();
  spec2_rmstodb_tilde_setup();
  spec2_shift_tilde_setup();
  spec2_sqrt_tilde_setup();
  spec2_stretch_tilde_setup();
  spec2_sub_tilde_setup();
  spec2_sum_tilde_setup();
  spec2_tab_conv_tilde_setup();
  spec2_tabreceive_enable_tilde_setup();
  spec2_tabreceive_tilde_setup();
  
  post("iem_spec2 (R-1.16) library loaded!   (c) Thomas Musil 05.2005");
  post("   musil%ciem.at iem KUG Graz Austria", '@');
}

--- NEW FILE: spec2_add_scalar~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */


#include "m_pd.h"
#include "iemlib.h"

/* -------------------------- spec2_add_scalar~ ------------------------------ */
static t_class *spec2_add_scalar_tilde_class;

typedef struct _spec2_add_scalar_tilde
{
  t_object  x_obj;
  t_float   x_f;
  t_float   x_msi;
} t_spec2_add_scalar_tilde;

static void spec2_add_scalar_tilde_ft1(t_spec2_add_scalar_tilde *x, t_floatarg f)
{
  x->x_f = f;
}

static t_int *spec2_add_scalar_tilde_perform(t_int *w)
{
  t_float *io = (t_float *)(w[1]);
  t_spec2_add_scalar_tilde *x = (t_spec2_add_scalar_tilde *)(w[2]);
  int i, n = (t_int)(w[3]);
  t_float f = x->x_f;
  
  for(i=0; i<=n; i++)
  {
    io[i] += f;
  }
  return(w+4);
}

static t_int *spec2_add_scalar_tilde_perf16(t_int *w)
{
  t_float *io = (t_float *)(w[1]);
  t_spec2_add_scalar_tilde *x = (t_spec2_add_scalar_tilde *)(w[2]);
  int n = (t_int)(w[3]);
  t_float f = x->x_f;
  
  while(n)
  {
    io[0] += f;
    io[1] += f;
    io[2] += f;
    io[3] += f;
    io[4] += f;
    io[5] += f;
    io[6] += f;
    io[7] += f;
    io[8] += f;
    io[9] += f;
    io[10] += f;
    io[11] += f;
    io[12] += f;
    io[13] += f;
    io[14] += f;
    io[15] += f;
    
    io += 16;
    n -= 16;
  }
  io[0] += f;
  return(w+4);
}

static void spec2_add_scalar_tilde_dsp(t_spec2_add_scalar_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(n&15)
    dsp_add(spec2_add_scalar_tilde_perform, 3, sp[0]->s_vec, x, n);
  else
    dsp_add(spec2_add_scalar_tilde_perf16, 3, sp[0]->s_vec, x, n);
}

static void *spec2_add_scalar_tilde_new(t_floatarg f)
{
  t_spec2_add_scalar_tilde *x = (t_spec2_add_scalar_tilde *)pd_new(spec2_add_scalar_tilde_class);
  
  inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
  outlet_new(&x->x_obj, &s_signal);
  x->x_f = f;
  x->x_msi = 0.0f;
  return (x);
}

static void spec2_add_scalar_tilde_free(t_spec2_add_scalar_tilde *x)
{
}

void spec2_add_scalar_tilde_setup(void)
{
  spec2_add_scalar_tilde_class = class_new(gensym("spec2_add_scalar~"), (t_newmethod)spec2_add_scalar_tilde_new, (t_method)spec2_add_scalar_tilde_free,
    sizeof(t_spec2_add_scalar_tilde), 0, A_DEFFLOAT, 0);
  class_addcreator((t_newmethod)spec2_add_scalar_tilde_new, gensym("spec2+s~"), A_DEFFLOAT, 0);
  CLASS_MAINSIGNALIN(spec2_add_scalar_tilde_class, t_spec2_add_scalar_tilde, x_msi);
  class_addmethod(spec2_add_scalar_tilde_class, (t_method)spec2_add_scalar_tilde_ft1, gensym("ft1"), A_FLOAT, 0);
  class_addmethod(spec2_add_scalar_tilde_class, (t_method)spec2_add_scalar_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_add_scalar_tilde_class, gensym("iemhelp2/spec2_add_scalar~-help"));
}

--- NEW FILE: spec2_tabreceive~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil (c) IEM KUG Graz Austria 2002 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* ------------------------ spec2_tabreceive_tilde~ ------------------------- */

static t_class *spec2_tabreceive_tilde_class;

typedef struct _spec2_tabreceive_tilde
{
  t_object  x_obj;
  t_float   *x_vec;
  t_symbol  *x_arrayname;
} t_spec2_tabreceive_tilde;

static void spec2_tabreceive_tilde_symbol(t_spec2_tabreceive_tilde *x, t_symbol *s)
{
  x->x_arrayname = s;
}

static t_int *spec2_tabreceive_tilde_perform(t_int *w)
{
  t_spec2_tabreceive_tilde *x = (t_spec2_tabreceive_tilde *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  int n = w[3]+1;
  t_float *vec = x->x_vec;
  
  if(vec)
    while(n--)
      *out++ = *vec++;
    else
      while(n--)
        *out++ = 0.0f;
      return(w+4);
}

static t_int *spec2_tabreceive_tilde_perf16(t_int *w)
{
  t_spec2_tabreceive_tilde *x = (t_spec2_tabreceive_tilde *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  int n = w[3];
  t_float *vec = x->x_vec;
  
  if(vec)
  {
    while(n)
    {
      out[0] = vec[0];
      out[1] = vec[1];
      out[2] = vec[2];
      out[3] = vec[3];
      out[4] = vec[4];
      out[5] = vec[5];
      out[6] = vec[6];
      out[7] = vec[7];
      out[8] = vec[8];
      out[9] = vec[9];
      out[10] = vec[10];
      out[11] = vec[11];
      out[12] = vec[12];
      out[13] = vec[13];
      out[14] = vec[14];
      out[15] = vec[15];
      
      vec += 16;
      out += 16;
      n -= 16;
    }
    out[0] = vec[0];
  }
  else
  {
    while(n)
    {
      out[0] = 0.0f;
      out[1] = 0.0f;
      out[2] = 0.0f;
      out[3] = 0.0f;
      out[4] = 0.0f;
      out[5] = 0.0f;
      out[6] = 0.0f;
      out[7] = 0.0f;
      out[8] = 0.0f;
      out[9] = 0.0f;
      out[10] = 0.0f;
      out[11] = 0.0f;
      out[12] = 0.0f;
      out[13] = 0.0f;
      out[14] = 0.0f;
      out[15] = 0.0f;
      
      out += 16;
      n -= 16;
    }
    out[0] = 0.0f;
  }
  
  return(w+4);
}

static void spec2_tabreceive_tilde_dsp(t_spec2_tabreceive_tilde *x, t_signal **sp)
{
  t_garray *a;
  int vecsize;
  
  if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
  {
    if(*x->x_arrayname->s_name)
      error("spec2_tabreceive~: %s: no such array", x->x_arrayname->s_name);
  }
  else if(!garray_getfloatarray(a, &vecsize, &x->x_vec))
    error("%s: bad template for spec2_tabreceive~", x->x_arrayname->s_name);
  else 
  {
    int n = sp[0]->s_n;
    
    if(n < vecsize)
      vecsize = n;
    vecsize /= 2;
    if(vecsize&15)
      dsp_add(spec2_tabreceive_tilde_perform, 3, x, sp[0]->s_vec, vecsize);
    else
      dsp_add(spec2_tabreceive_tilde_perf16, 3, x, sp[0]->s_vec, vecsize);
  }
}

static void *spec2_tabreceive_tilde_new(t_symbol *s)
{
  t_spec2_tabreceive_tilde *x = (t_spec2_tabreceive_tilde *)pd_new(spec2_tabreceive_tilde_class);
  
  x->x_arrayname = s;
  outlet_new(&x->x_obj, &s_signal);
  return (x);
}

void spec2_tabreceive_tilde_setup(void)
{
  spec2_tabreceive_tilde_class = class_new(gensym("spec2_tabreceive~"), (t_newmethod)spec2_tabreceive_tilde_new,
    0, sizeof(t_spec2_tabreceive_tilde), 0, A_DEFSYM, 0);
  class_addmethod(spec2_tabreceive_tilde_class, (t_method)spec2_tabreceive_tilde_dsp, gensym("dsp"), 0);
  class_addsymbol(spec2_tabreceive_tilde_class, (t_method)spec2_tabreceive_tilde_symbol);
  class_sethelpsymbol(spec2_tabreceive_tilde_class, gensym("iemhelp/spec2_tabreceive~-help"));
}

--- NEW FILE: spec2_1p1z_freq~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* -- spec2_1p1z_freq~ - filter the spectrum with a 1.order IIR twice, once forwards, once backwards --- */

typedef struct spec2_1p1z_freq_tilde
{
  t_object  x_obj;
  t_float   x_a0;
  t_float   x_a1;
  t_float   x_b1;
  t_float   *x_begmem;
  int       x_blocksize;
  t_float   x_msi;
} t_spec2_1p1z_freq_tilde;

t_class *spec2_1p1z_freq_tilde_class;

static void spec2_1p1z_freq_tilde_list(t_spec2_1p1z_freq_tilde *x, t_symbol *s, int argc, t_atom *argv)
{
  if((argc >= 3) &&
    IS_A_FLOAT(argv,0) &&
    IS_A_FLOAT(argv,1) &&
    IS_A_FLOAT(argv,2))
  {
    x->x_a0 = (t_float)atom_getfloatarg(0, argc, argv);
    x->x_a1 = (t_float)atom_getfloatarg(1, argc, argv);
    x->x_b1 = (t_float)atom_getfloatarg(2, argc, argv);
  }
}

static t_int *spec2_1p1z_freq_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  t_spec2_1p1z_freq_tilde *x = (t_spec2_1p1z_freq_tilde *)(w[3]);
  int i, m, n = (int)(w[4]);
  t_float a0 = x->x_a0;
  t_float a1 = x->x_a1;
  t_float b1 = x->x_b1;
  t_float *vec1, *vec2, *vec3;
  t_float in_old, out_old, f;
  
  vec2 = x->x_begmem + n + 1;
  vec1 = vec2 - 1;
  vec3 = vec2 + 2*n;
  
  *vec2++ = in[0];
  for(i=1; i<n; i++)
  {
    f = in[i];
    *vec2++ = f;
    *vec1-- = f;
    *vec3-- = f;
  }
  *vec2 = in[n];
  
  m = 3*n - 1;
  
  vec2 = x->x_begmem + 2;
  in_old = 0.0f;
  out_old = 0.0f;
  for(i=0; i<m; i++)
  {
    f = *vec2;
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    *vec2++ = out_old;
  }
  
  vec2 = x->x_begmem + 3*n - 2;
  in_old = 0.0f;
  out_old = 0.0f;
  for(i=0; i<m; i++)
  {
    f = *vec2;
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    *vec2-- = out_old;
  }
  
  vec2 = x->x_begmem + n + 1;
  for(i=0; i<=n; i++)
  {
    out[i] = *vec2++;
  }
  
  return(w+5);
}

static t_int *spec2_1p1z_freq_tilde_perf16(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  t_spec2_1p1z_freq_tilde *x = (t_spec2_1p1z_freq_tilde *)(w[3]);
  int i, m, n = (int)(w[4]);
  t_float a0 = x->x_a0;
  t_float a1 = x->x_a1;
  t_float b1 = x->x_b1;
  t_float *vec1, *vec2, *vec3;
  t_float in_old, out_old, f;
  
  m = 3*n;
  
  vec2 = x->x_begmem + n + 1;
  vec1 = vec2;
  //  vec3 = vec2 + 2*n + 2 - 2;
  vec3 = vec2 + 2*n;
  
  x->x_begmem[0] = 0.0f;
  x->x_begmem[m-1] = 0.0f;
  
  i = n;
  while(i)
  {
    f = in[0];
    vec2[0] = f;
    vec1[0] = f;
    vec3[0] = f;
    
    f = in[1];
    vec2[1] = f;
    vec1[-1] = f;
    vec3[-1] = f;
    
    f = in[2];
    vec2[2] = f;
    vec1[-2] = f;
    vec3[-2] = f;
    
    f = in[3];
    vec2[3] = f;
    vec1[-3] = f;
    vec3[-3] = f;
    
    f = in[4];
    vec2[4] = f;
    vec1[-4] = f;
    vec3[-4] = f;
    
    f = in[5];
    vec2[5] = f;
    vec1[-5] = f;
    vec3[-5] = f;
    
    f = in[6];
    vec2[6] = f;
    vec1[-6] = f;
    vec3[-6] = f;
    
    f = in[7];
    vec2[7] = f;
    vec1[-7] = f;
    vec3[-7] = f;
    
    f = in[8];
    vec2[8] = f;
    vec1[-8] = f;
    vec3[-8] = f;
    
    f = in[9];
    vec2[9] = f;
    vec1[-9] = f;
    vec3[-9] = f;
    
    f = in[10];
    vec2[10] = f;
    vec1[-10] = f;
    vec3[-10] = f;
    
    f = in[11];
    vec2[11] = f;
    vec1[-11] = f;
    vec3[-11] = f;
    
    f = in[12];
    vec2[12] = f;
    vec1[-12] = f;
    vec3[-12] = f;
    
    f = in[13];
    vec2[13] = f;
    vec1[-13] = f;
    vec3[-13] = f;
    
    f = in[14];
    vec2[14] = f;
    vec1[-14] = f;
    vec3[-14] = f;
    
    f = in[15];
    vec2[15] = f;
    vec1[-15] = f;
    vec3[-15] = f;
    
    in += 16;
    vec1 -= 16;
    vec2 += 16;
    vec3 -= 16;
    i -= 16;
  }
  f = in[0];
  vec2[0] = f;
  vec1[0] = f;
  vec3[0] = f;
  
  vec2 = x->x_begmem;
  in_old = 0.0f;
  out_old = 0.0f;
  i = m;
  while(i)
  {
    f = vec2[0];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[0] = out_old;
    
    f = vec2[1];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[1] = out_old;
    
    f = vec2[2];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[2] = out_old;
    
    f = vec2[3];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[3] = out_old;
    
    f = vec2[4];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[4] = out_old;
    
    f = vec2[5];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[5] = out_old;
    
    f = vec2[6];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[6] = out_old;
    
    f = vec2[7];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[7] = out_old;
    
    f = vec2[8];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[8] = out_old;
    
    f = vec2[9];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[9] = out_old;
    
    f = vec2[10];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[10] = out_old;
    
    f = vec2[11];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[11] = out_old;
    
    f = vec2[12];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[12] = out_old;
    
    f = vec2[13];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[13] = out_old;
    
    f = vec2[14];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[14] = out_old;
    
    f = vec2[15];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[15] = out_old;
    
    vec2 += 16;
    i -= 16;
  }
  f = vec2[0];
  out_old = a0*f + a1*in_old + b1*out_old;
  in_old = f;
  vec2[0] = out_old;
  
  f = vec2[1];
  out_old = a0*f + a1*in_old + b1*out_old;
  in_old = f;
  vec2[1] = out_old;
  
  f = vec2[2];
  out_old = a0*f + a1*in_old + b1*out_old;
  in_old = f;
  vec2[2] = out_old;
  
  //  vec2 = x->x_begmem + 3*n - 1 + 3;
  vec2 = x->x_begmem + 3*n + 2;
  in_old = 0.0f;
  out_old = 0.0f;
  for(i=0; i<m; )
  {
    f = vec2[0];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[0] = out_old;
    
    f = vec2[-1];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-1] = out_old;
    
    f = vec2[-2];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-2] = out_old;
    
    f = vec2[-3];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-3] = out_old;
    
    f = vec2[-4];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-4] = out_old;
    
    f = vec2[-5];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-5] = out_old;
    
    f = vec2[-6];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-6] = out_old;
    
    f = vec2[-7];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-7] = out_old;
    
    f = vec2[-8];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-8] = out_old;
    
    f = vec2[-9];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-9] = out_old;
    
    f = vec2[-10];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-10] = out_old;
    
    f = vec2[-11];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-11] = out_old;
    
    f = vec2[-12];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-12] = out_old;
    
    f = vec2[-13];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-13] = out_old;
    
    f = vec2[-14];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-14] = out_old;
    
    f = vec2[-15];
    out_old = a0*f + a1*in_old + b1*out_old;
    in_old = f;
    vec2[-15] = out_old;
    
    vec2 -= 16;
    i -= 16;
  }
  f = vec2[0];
  out_old = a0*f + a1*in_old + b1*out_old;
  in_old = f;
  vec2[0] = out_old;
  
  f = vec2[-1];
  out_old = a0*f + a1*in_old + b1*out_old;
  in_old = f;
  vec2[-1] = out_old;
  
  f = vec2[-2];
  out_old = a0*f + a1*in_old + b1*out_old;
  in_old = f;
  vec2[-2] = out_old;
  
  vec2 = x->x_begmem + n + 1;
  i = n;
  while(i)
  {
    out[0] = vec2[0];
    out[1] = vec2[1];
    out[2] = vec2[2];
    out[3] = vec2[3];
    out[4] = vec2[4];
    out[5] = vec2[5];
    out[6] = vec2[6];
    out[7] = vec2[7];
    out[8] = vec2[8];
    out[9] = vec2[9];
    out[10] = vec2[10];
    out[11] = vec2[11];
    out[12] = vec2[12];
    out[13] = vec2[13];
    out[14] = vec2[14];
    out[15] = vec2[15];
    
    vec2 += 16;
    out += 16;
    i -= 16;
  }
  out[0] = vec2[0];
  
  return(w+5);
}

static void spec2_1p1z_freq_tilde_dsp(t_spec2_1p1z_freq_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(!x->x_blocksize)
  {
    x->x_begmem = (t_float *)getbytes(3*(n+1)*sizeof(t_float));
    x->x_blocksize = n;
  }
  else if(x->x_blocksize != n)
  {
    x->x_begmem = (t_float *)resizebytes(x->x_begmem, 3*(x->x_blocksize+1)*sizeof(t_float), 3*(n+1)*sizeof(t_float));
    x->x_blocksize = n;
  }
  
  if(n&15)
    dsp_add(spec2_1p1z_freq_tilde_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
  else
    dsp_add(spec2_1p1z_freq_tilde_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
}

static void spec2_1p1z_freq_tilde_free(t_spec2_1p1z_freq_tilde *x)
{
  if(x->x_begmem)
    freebytes(x->x_begmem, 3*(x->x_blocksize+1)*sizeof(t_float));
}

static void *spec2_1p1z_freq_tilde_new(t_symbol *s, int argc, t_atom *argv)
{
  t_spec2_1p1z_freq_tilde *x = (t_spec2_1p1z_freq_tilde *)pd_new(spec2_1p1z_freq_tilde_class);
  
  outlet_new(&x->x_obj, &s_signal);
  x->x_blocksize = 0;
  x->x_begmem = (t_float *)0;
  if(argc >= 3)
    spec2_1p1z_freq_tilde_list(x, s, argc, argv);
  else
  {
    x->x_a0 = 1.0f;
    x->x_a1 = 0.0f;
    x->x_b1 = 0.0f;
  }
  x->x_msi = 0.0f;
  return (x);
}

void spec2_1p1z_freq_tilde_setup(void)
{
  spec2_1p1z_freq_tilde_class = class_new(gensym("spec2_1p1z_freq~"), (t_newmethod)spec2_1p1z_freq_tilde_new,
    (t_method)spec2_1p1z_freq_tilde_free, sizeof(t_spec2_1p1z_freq_tilde), 0, A_GIMME, 0);
  CLASS_MAINSIGNALIN(spec2_1p1z_freq_tilde_class, t_spec2_1p1z_freq_tilde, x_msi);
  class_addmethod(spec2_1p1z_freq_tilde_class, (t_method)spec2_1p1z_freq_tilde_dsp, gensym("dsp"), 0);
  class_addlist(spec2_1p1z_freq_tilde_class, (t_method)spec2_1p1z_freq_tilde_list);
  class_sethelpsymbol(spec2_1p1z_freq_tilde_class, gensym("iemhelp2/spec2_1p1z_freq~-help"));
}

--- NEW FILE: spec2_dbtopow~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"
#include <math.h>

#define SPEC2LOGTEN 2.302585092994f

/* ------------------------ spec2_dbtopow_tilde~ ------------------------- */

static t_class *spec2_dbtopow_tilde_class;

typedef struct _spec2_dbtopow_tilde
{
  t_object  x_obj;
  t_float   x_msi;
} t_spec2_dbtopow_tilde;

static t_int *spec2_dbtopow_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *out = (t_float *)(w[2]);
  int n = w[3]+1;
  
  for (; n--; in++, out++)
  { 
    t_float f = *in;
    
    if(f <= 0.0f)
      *out = 0.0f;
    else
    {
      if(f > 870.0f)
        f = 870.0f;
      *out = exp((SPEC2LOGTEN * 0.1f) * (f-100.0f));
    }
  }
  return(w+4);
}

static void spec2_dbtopow_tilde_dsp(t_spec2_dbtopow_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  dsp_add(spec2_dbtopow_tilde_perform, 3, sp[0]->s_vec, sp[0]->s_vec, n);
}

static void *spec2_dbtopow_tilde_new(void)
{
  t_spec2_dbtopow_tilde *x = (t_spec2_dbtopow_tilde *)pd_new(spec2_dbtopow_tilde_class);
  
  outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0.0f;
  return (x);
}

void spec2_dbtopow_tilde_setup(void)
{
  spec2_dbtopow_tilde_class = class_new(gensym("spec2_dbtopow~"), (t_newmethod)spec2_dbtopow_tilde_new,
    0, sizeof(t_spec2_dbtopow_tilde), 0, 0);
  CLASS_MAINSIGNALIN(spec2_dbtopow_tilde_class, t_spec2_dbtopow_tilde, x_msi);
  class_addmethod(spec2_dbtopow_tilde_class, (t_method)spec2_dbtopow_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_dbtopow_tilde_class, gensym("iemhelp2/spec2_dbtopow~-help"));
}

--- NEW FILE: spec2_add~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */


#include "m_pd.h"
#include "iemlib.h"

/* -------------------------- spec2_add~ ------------------------------ */
static t_class *spec2_add_tilde_class;

typedef struct _spec2_add_tilde
{
  t_object  x_obj;
  t_float   x_msi;
} t_spec2_add_tilde;

static t_int *spec2_add_tilde_perform(t_int *w)
{
  t_float *in1 = (t_float *)(w[1]);
  t_float *in2 = (t_float *)(w[2]);
  t_float *out = (t_float *)(w[3]);
  int i, n = (t_int)(w[4]);
  
  for(i=0; i<=n; i++)
  {
    out[i] = in1[i] + in2[i];
  }
  return(w+5);
}

static t_int *spec2_add_tilde_perf16(t_int *w)
{
  t_float *in1 = (t_float *)(w[1]);
  t_float *in2 = (t_float *)(w[2]);
  t_float *out = (t_float *)(w[3]);
  int n = (t_int)(w[4]);
  
  while(n)
  {
    out[0] = in1[0] + in2[0];
    out[1] = in1[1] + in2[1];
    out[2] = in1[2] + in2[2];
    out[3] = in1[3] + in2[3];
    out[4] = in1[4] + in2[4];
    out[5] = in1[5] + in2[5];
    out[6] = in1[6] + in2[6];
    out[7] = in1[7] + in2[7];
    out[8] = in1[8] + in2[8];
    out[9] = in1[9] + in2[9];
    out[10] = in1[10] + in2[10];
    out[11] = in1[11] + in2[11];
    out[12] = in1[12] + in2[12];
    out[13] = in1[13] + in2[13];
    out[14] = in1[14] + in2[14];
    out[15] = in1[15] + in2[15];
    
    
    in1 += 16;
    in2 += 16;
    out += 16;
    n -= 16;
  }
  out[0] = in1[0] + in2[0];
  return(w+5);
}

static void spec2_add_tilde_dsp(t_spec2_add_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(n&15)
    dsp_add(spec2_add_tilde_perform, 4, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, n);
  else
    dsp_add(spec2_add_tilde_perf16, 4, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, n);
}

static void *spec2_add_tilde_new(void)
{
  t_spec2_add_tilde *x = (t_spec2_add_tilde *)pd_new(spec2_add_tilde_class);
  
  inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
  outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0.0f;
  return (x);
}

static void spec2_add_tilde_free(t_spec2_add_tilde *x)
{
}

void spec2_add_tilde_setup(void)
{
  spec2_add_tilde_class = class_new(gensym("spec2_add~"), (t_newmethod)spec2_add_tilde_new, (t_method)spec2_add_tilde_free,
    sizeof(t_spec2_add_tilde), 0, 0);
  class_addcreator((t_newmethod)spec2_add_tilde_new, gensym("spec2+~"), 0);
  CLASS_MAINSIGNALIN(spec2_add_tilde_class, t_spec2_add_tilde, x_msi);
  class_addmethod(spec2_add_tilde_class, (t_method)spec2_add_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_add_tilde_class, gensym("iemhelp2/spec2_add~-help"));
}

--- NEW FILE: spec2_clip_min~.c ---
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.

iem_spec2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */

#include "m_pd.h"
#include "iemlib.h"

/* -------------------------- spec2_clip_min~ ------------------------------ */
static t_class *spec2_clip_min_tilde_class;

typedef struct _spec2_clip_min_tilde
{
  t_object  x_obj;
  t_float   x_msi;
} t_spec2_clip_min_tilde;

static t_int *spec2_clip_min_tilde_perform(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *min = (t_float *)(w[2]);
  t_float *out = (t_float *)(w[3]);
  int i, n = (t_int)(w[4]);
  
  for(i=0; i<=n; i++)
  {
    if(in[i] < min[i])
      out[i] = min[i];
    else
      out[i] = in[i];
  }
  return(w+5);
}

static t_int *spec2_clip_min_tilde_perf16(t_int *w)
{
  t_float *in = (t_float *)(w[1]);
  t_float *min = (t_float *)(w[2]);
  t_float *out = (t_float *)(w[3]);
  int n = (t_int)(w[4]);
  
  while(n)
  {
    if(in[0] < min[0])
      out[0] = min[0];
    else
      out[0] = in[0];
    
    if(in[1] < min[1])
      out[1] = min[1];
    else
      out[1] = in[1];
    
    if(in[2] < min[2])
      out[2] = min[2];
    else
      out[2] = in[2];
    
    if(in[3] < min[3])
      out[3] = min[3];
    else
      out[3] = in[3];
    
    if(in[4] < min[4])
      out[4] = min[4];
    else
      out[4] = in[4];
    
    if(in[5] < min[5])
      out[5] = min[5];
    else
      out[5] = in[5];
    
    if(in[6] < min[6])
      out[6] = min[6];
    else
      out[6] = in[6];
    
    if(in[7] < min[7])
      out[7] = min[7];
    else
      out[7] = in[7];
    
    if(in[8] < min[8])
      out[8] = min[8];
    else
      out[8] = in[8];
    
    if(in[9] < min[9])
      out[9] = min[9];
    else
      out[9] = in[9];
    
    if(in[10] < min[10])
      out[10] = min[10];
    else
      out[10] = in[10];
    
    if(in[11] < min[11])
      out[11] = min[11];
    else
      out[11] = in[11];
    
    if(in[12] < min[12])
      out[12] = min[12];
    else
      out[12] = in[12];
    
    if(in[13] < min[13])
      out[13] = min[13];
    else
      out[13] = in[13];
    
    if(in[14] < min[14])
      out[14] = min[14];
    else
      out[14] = in[14];
    
    if(in[15] < min[15])
      out[15] = min[15];
    else
      out[15] = in[15];
    
    in += 16;
    min += 16;
    out += 16;
    n -= 16;
  }
  if(in[0] < min[0])
    out[0] = min[0];
  else
    out[0] = in[0];
  return(w+5);
}

static void spec2_clip_min_tilde_dsp(t_spec2_clip_min_tilde *x, t_signal **sp)
{
  int n = (sp[0]->s_n)/2;
  
  if(n&15)
    dsp_add(spec2_clip_min_tilde_perform, 4, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, n);
  else
    dsp_add(spec2_clip_min_tilde_perf16, 4, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, n);
}

static void *spec2_clip_min_tilde_new(void)
{
  t_spec2_clip_min_tilde *x = (t_spec2_clip_min_tilde *)pd_new(spec2_clip_min_tilde_class);
  
  inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
  outlet_new(&x->x_obj, &s_signal);
  x->x_msi = 0.0f;
  return (x);
}

static void spec2_clip_min_tilde_free(t_spec2_clip_min_tilde *x)
{
}

void spec2_clip_min_tilde_setup(void)
{
  spec2_clip_min_tilde_class = class_new(gensym("spec2_clip_min~"), (t_newmethod)spec2_clip_min_tilde_new, (t_method)spec2_clip_min_tilde_free,
    sizeof(t_spec2_clip_min_tilde), 0, 0);
  CLASS_MAINSIGNALIN(spec2_clip_min_tilde_class, t_spec2_clip_min_tilde, x_msi);
  class_addmethod(spec2_clip_min_tilde_class, (t_method)spec2_clip_min_tilde_dsp, gensym("dsp"), 0);
  class_sethelpsymbol(spec2_clip_min_tilde_class, gensym("iemhelp2/spec2_clip_min~-help"));
}





More information about the Pd-cvs mailing list