aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHans-Christoph Steiner <eighthave@users.sourceforge.net>2004-05-18 21:33:33 +0000
committerHans-Christoph Steiner <eighthave@users.sourceforge.net>2004-05-18 21:33:33 +0000
commit577ac6e80ff4f436fbd054291ed7dddbc31bd49a (patch)
tree6ec69b216dda68d7de38a5eba1851b9d4f1431e6 /src
This commit was generated by cvs2svn to compensate for changes in r1738,svn2git-root
which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/iemlib/; revision=1739
Diffstat (limited to 'src')
-rw-r--r--src/iem_mp3/iem_mp3.c35
-rw-r--r--src/iem_mp3/iem_mp3.dsp85
-rw-r--r--src/iem_mp3/iem_mp3.dsw29
-rw-r--r--src/iem_mp3/iemlib.h98
-rw-r--r--src/iem_mp3/makefile50
-rw-r--r--src/iem_mp3/makefile_win38
-rw-r--r--src/iem_mp3/sigmp3play.c3865
-rw-r--r--src/iem_t3_lib/iem_t3_lib.c65
-rw-r--r--src/iem_t3_lib/iem_t3_lib.dsp85
-rw-r--r--src/iem_t3_lib/iem_t3_lib.dsw29
-rw-r--r--src/iem_t3_lib/iemlib.h98
-rw-r--r--src/iem_t3_lib/makefile56
-rw-r--r--src/iem_t3_lib/makefile_win43
-rw-r--r--src/iem_t3_lib/sigt3_line.c279
-rw-r--r--src/iem_t3_lib/sigt3_sig.c200
-rw-r--r--src/iem_t3_lib/t3_bpe.c142
-rw-r--r--src/iem_t3_lib/t3_delay.c97
-rw-r--r--src/iem_t3_lib/t3_metro.c121
-rw-r--r--src/iem_t3_lib/t3_timer.c55
-rw-r--r--src/iemlib1/biquad_freq_resp.c92
-rw-r--r--src/iemlib1/db2v.c45
-rw-r--r--src/iemlib1/f2note.c189
-rw-r--r--src/iemlib1/forpp.c192
-rw-r--r--src/iemlib1/gate.c84
-rw-r--r--src/iemlib1/iemlib.h98
-rw-r--r--src/iemlib1/iemlib1.c82
-rw-r--r--src/iemlib1/iemlib1.dsp85
-rw-r--r--src/iemlib1/iemlib1.dsw29
-rw-r--r--src/iemlib1/makefile72
-rw-r--r--src/iemlib1/makefile.darwin72
-rw-r--r--src/iemlib1/makefile_win61
-rw-r--r--src/iemlib1/sigFIR.c177
-rw-r--r--src/iemlib1/sigfilter.c822
-rw-r--r--src/iemlib1/sighml_shelf.c558
-rw-r--r--src/iemlib1/sigiem_cot4.c176
-rw-r--r--src/iemlib1/sigiem_delay.c208
-rw-r--r--src/iemlib1/sigiem_pow4.c86
-rw-r--r--src/iemlib1/sigiem_sqrt4.c117
-rw-r--r--src/iemlib1/siglp1_t.c219
-rw-r--r--src/iemlib1/sigmov_avrg_kern.c143
-rw-r--r--src/iemlib1/sigpara_bp2.c426
-rw-r--r--src/iemlib1/sigpeakenv.c102
-rw-r--r--src/iemlib1/sigprvu.c282
-rw-r--r--src/iemlib1/sigpvu.c206
-rw-r--r--src/iemlib1/sigrvu.c187
-rw-r--r--src/iemlib1/sigsin_phase.c129
-rw-r--r--src/iemlib1/sigvcf_filter.c334
-rw-r--r--src/iemlib1/soundfile_info.c261
-rw-r--r--src/iemlib1/split.c54
-rw-r--r--src/iemlib1/v2db.c45
-rw-r--r--src/iemlib2/add2_comma.c123
-rw-r--r--src/iemlib2/bpe.c125
-rw-r--r--src/iemlib2/dollarg.c113
-rw-r--r--src/iemlib2/exp_inc.c138
-rw-r--r--src/iemlib2/float24.c83
-rw-r--r--src/iemlib2/iem_anything_kernel.c148
-rw-r--r--src/iemlib2/iem_append_kernel.c351
-rw-r--r--src/iemlib2/iem_i_route.c111
-rw-r--r--src/iemlib2/iem_pbank_csv.c801
-rw-r--r--src/iemlib2/iem_prepend_kernel.c259
-rw-r--r--src/iemlib2/iem_receive_kernel.c155
-rw-r--r--src/iemlib2/iem_route.c198
-rw-r--r--src/iemlib2/iem_sel_any.c111
-rw-r--r--src/iemlib2/iem_send_kernel.c140
-rw-r--r--src/iemlib2/iemlib.h98
-rw-r--r--src/iemlib2/iemlib2.c121
-rw-r--r--src/iemlib2/iemlib2.dsp85
-rw-r--r--src/iemlib2/iemlib2.dsw29
-rw-r--r--src/iemlib2/init.c203
-rw-r--r--src/iemlib2/list2send.c246
-rw-r--r--src/iemlib2/makefile82
-rw-r--r--src/iemlib2/makefile_win71
-rw-r--r--src/iemlib2/mergefilename.c229
-rw-r--r--src/iemlib2/modulo_counter.c90
-rw-r--r--src/iemlib2/post_netreceive.c243
-rw-r--r--src/iemlib2/pre_inlet.c94
-rw-r--r--src/iemlib2/prepend_ascii.c127
-rw-r--r--src/iemlib2/prepend_kernel.c351
-rw-r--r--src/iemlib2/round_zero.c67
-rw-r--r--src/iemlib2/sigLFO_noise.c129
-rw-r--r--src/iemlib2/sigfade.c183
-rw-r--r--src/iemlib2/sigiem_blocksize.c61
-rw-r--r--src/iemlib2/sigiem_samplerate.c61
-rw-r--r--src/iemlib2/sigm2f.c127
-rw-r--r--src/iemlib2/speedlim.c107
-rw-r--r--src/iemlib2/splitfilename.c142
-rw-r--r--src/iemlib2/stripfilename.c81
-rw-r--r--src/iemlib2/toggle_mess.c119
-rw-r--r--src/iemlib2/transf_fader.c153
-rw-r--r--src/iemlib2/unsymbol.c49
-rw-r--r--src/iemlib2/wrap.c69
91 files changed, 17376 insertions, 0 deletions
diff --git a/src/iem_mp3/iem_mp3.c b/src/iem_mp3/iem_mp3.c
new file mode 100644
index 0000000..5b45515
--- /dev/null
+++ b/src/iem_mp3/iem_mp3.c
@@ -0,0 +1,35 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_mp3 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+
+static t_class *iem_mp3_class;
+
+static void *iem_mp3_new(void)
+{
+ t_object *x = (t_object *)pd_new(iem_mp3_class);
+
+ return (x);
+}
+
+void sigmp3play_setup(void);
+
+/* ------------------------ setup routine ------------------------- */
+
+void iem_mp3_setup(void)
+{
+ iem_mp3_class = class_new(gensym("iem_mp3"), iem_mp3_new, 0,
+ sizeof(t_object), CLASS_NOINLET, 0);
+
+ sigmp3play_setup();
+
+ post("iem_mp3 (R-1.15) library loaded!");
+}
diff --git a/src/iem_mp3/iem_mp3.dsp b/src/iem_mp3/iem_mp3.dsp
new file mode 100644
index 0000000..9fe129d
--- /dev/null
+++ b/src/iem_mp3/iem_mp3.dsp
@@ -0,0 +1,85 @@
+# Microsoft Developer Studio Project File - Name="iem_mp3" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) External Target" 0x0106
+
+CFG=iem_mp3 - 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_mp3.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_mp3.mak" CFG="iem_mp3 - Win32 Debug"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "iem_mp3 - Win32 Release" (basierend auf "Win32 (x86) External Target")
+!MESSAGE "iem_mp3 - Win32 Debug" (basierend auf "Win32 (x86) External Target")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF "$(CFG)" == "iem_mp3 - 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_mp3.exe"
+# PROP Bsc_Name "iem_mp3.bsc"
+# PROP Target_Dir ""
+
+!ELSEIF "$(CFG)" == "iem_mp3 - 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_mp3.exe"
+# PROP Bsc_Name "iem_mp3.bsc"
+# PROP Target_Dir ""
+
+!ENDIF
+
+# Begin Target
+
+# Name "iem_mp3 - Win32 Release"
+# Name "iem_mp3 - Win32 Debug"
+
+!IF "$(CFG)" == "iem_mp3 - Win32 Release"
+
+!ELSEIF "$(CFG)" == "iem_mp3 - Win32 Debug"
+
+!ENDIF
+
+# Begin Source File
+
+SOURCE=.\makefile_win
+# End Source File
+# End Target
+# End Project
diff --git a/src/iem_mp3/iem_mp3.dsw b/src/iem_mp3/iem_mp3.dsw
new file mode 100644
index 0000000..f352ffa
--- /dev/null
+++ b/src/iem_mp3/iem_mp3.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
+
+###############################################################################
+
+Project: "iem_mp3"=.\iem_mp3.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/src/iem_mp3/iemlib.h b/src/iem_mp3/iemlib.h
new file mode 100644
index 0000000..d518565
--- /dev/null
+++ b/src/iem_mp3/iemlib.h
@@ -0,0 +1,98 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#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 MACOSX
+#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 /* MACOSX */
+#endif /* __linux__ */
+#endif /* MSW */
+#endif /* SGI */
+
+union tabfudge
+{
+ double tf_d;
+ int32 tf_i[2];
+};
+
+#endif
diff --git a/src/iem_mp3/makefile b/src/iem_mp3/makefile
new file mode 100644
index 0000000..601a96f
--- /dev/null
+++ b/src/iem_mp3/makefile
@@ -0,0 +1,50 @@
+current: all
+
+.SUFFIXES: .pd_linux
+
+INCLUDE = -I. -I/usr/local/src/pd-0.36-0/src
+
+LDFLAGS = -export-dynamic -shared
+LIB = -ldl -lm -lpthread
+
+#select either the DBG and OPT compiler flags below:
+
+CFLAGS = -DPD -DUNIX -Wall -W -Werror -Wno-unused \
+ -Wno-parentheses -Wno-switch -O6 -funroll-loops -fomit-frame-pointer \
+ -DDL_OPEN
+
+SYSTEM = $(shell uname -m)
+
+# the sources
+
+SRC = sigmp3play.c \
+ iem_mp3.c
+
+TARGET = iem_mp3.pd_linux
+
+
+OBJ = $(SRC:.c=.o)
+
+#
+# ------------------ targets ------------------------------------
+#
+
+clean:
+ rm ../../lib/$(TARGET)
+ rm *.o
+
+all: $(OBJ)
+
+ @echo :: $(OBJ)
+
+ ld $(LDFLAGS) -o $(TARGET) *.o $(LIB)
+ strip --strip-unneeded $(TARGET)
+ mv $(TARGET) ../../lib
+ rm *.o
+
+$(OBJ) : %.o : %.c
+ touch $*.c
+ cc $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c
+
+
+
diff --git a/src/iem_mp3/makefile_win b/src/iem_mp3/makefile_win
new file mode 100644
index 0000000..d6b7fa1
--- /dev/null
+++ b/src/iem_mp3/makefile_win
@@ -0,0 +1,38 @@
+
+all: ..\..\lib\iem_mp3.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\pthreadVC.lib \
+ $(PD_INST_PATH)\bin\pd.lib
+
+
+SRC = sigmp3play.c \
+ iem_mp3.c
+
+
+OBJ = $(SRC:.c=.obj)
+
+.c.obj:
+ cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c
+
+..\..\lib\iem_mp3.dll: $(OBJ)
+ link $(PD_WIN_L_FLAGS) /dll /export:iem_mp3_setup \
+ /out:..\..\lib\iem_mp3.dll $(OBJ) $(PD_WIN_LIB)
+
+clean:
+ del *.obj
diff --git a/src/iem_mp3/sigmp3play.c b/src/iem_mp3/sigmp3play.c
new file mode 100644
index 0000000..1a1204d
--- /dev/null
+++ b/src/iem_mp3/sigmp3play.c
@@ -0,0 +1,3865 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_mp3 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+/*
+ sigmp3play.c - Mpeg Layer III Player for PD
+ Version:0.1
+ 05-18-2000
+ written by Thomas Musil (musil@iem.kug.ac.at), Norbert Math (math@iem.kug.ac.at)
+ IEM Graz
+
+ debugged for windows 013-03-2003
+
+ This MPEG Player is based on the mpglib 0.2 by Michael Hipp which comes with mpg123-0.59r
+
+ please see the README file for copyright notices!
+
+ */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <math.h>
+
+#ifndef NT
+#include <sys/signal.h>
+#include <unistd.h>
+#endif
+
+
+#define IEM_MPEG1
+
+#ifdef _WIN32
+# undef WIN32
+# define WIN32
+
+# define M_PI 3.14159265358979323846
+# define M_SQRT2 1.41421356237309504880
+# define REAL_IS_FLOAT
+# define NEW_DCT9
+
+# define random rand
+# define srandom srand
+
+#endif
+
+#ifdef REAL_IS_FLOAT
+# define real float
+#elif defined(REAL_IS_LONG_DOUBLE)
+# define real long double
+#else
+# define real double
+#endif
+
+#ifdef __GNUC__
+#define INLINE inline
+#else
+#define INLINE
+#endif
+
+/* AUDIOBUFSIZE = n*64 with n=1,2,3 ... */
+#define AUDIOBUFSIZE 16384
+
+#define FALSE 0
+#define TRUE 1
+#define SBLIMIT 32
+#define SSLIMIT 18
+#define MPG_MD_STEREO 0
+#define MPG_MD_JOINT_STEREO 1
+#define MPG_MD_DUAL_CHANNEL 2
+#define MPG_MD_MONO 3
+
+#define MAXFRAMESIZE 1792
+/* Pre Shift fo 16 to 8 bit converter table */
+#define AUSHIFT (3)
+#define BOOL int
+#define MP3_EX -2
+#define MP3_ERR -1
+#define MP3_OK 0
+#define MP3_NEED_MORE 1
+
+#define WRITE_SAMPLE(samples,sum,clip) \
+ if( (sum) > 32767.0) { *(samples) = 0x7fff; (clip)++; } \
+ else if( (sum) < -32768.0) { *(samples) = -0x8000; (clip)++; } \
+ else { *(samples) = sum; }
+
+
+#define HDRCMPMASK 0xfffffd00
+
+
+#define MY_MP3_MALLOC_IN_SIZE 16384
+#define MY_MP3_MALLOC_IN_SIZE2 8192
+#define MY_MP3_MALLOC_OUT_SIZE 65536
+#define MY_MP3_MALLOC_FN 400
+#define MY_MP3_CHSAMP_PER_FRAME 1152
+
+struct iemmp3_frame
+{
+ int stereo;
+ int jsbound;
+ int single;
+ int lsf;
+ int mpeg25;
+ int header_change;
+ int lay;
+ int error_protection;
+ int bitrate_index;
+ int sampling_frequency;
+ int padding;
+ int extension;
+ int mode;
+ int mode_ext;
+ int copyright;
+ int original;
+ int emphasis;
+ int framesize; /* computed framesize */
+};
+
+struct iemmp3_gr_info_s
+{
+ int scfsi;
+ unsigned part2_3_length;
+ unsigned big_values;
+ unsigned scalefac_compress;
+ unsigned block_type;
+ unsigned mixed_block_flag;
+ unsigned table_select[3];
+ unsigned subblock_gain[3];
+ unsigned maxband[3];
+ unsigned maxbandl;
+ unsigned maxb;
+ unsigned region1start;
+ unsigned region2start;
+ unsigned preflag;
+ unsigned scalefac_scale;
+ unsigned count1table_select;
+ real *full_gain[3];
+ real *pow2gain;
+};
+
+struct iemmp3_III_sideinfo
+{
+ unsigned main_data_begin;
+ unsigned private_bits;
+ struct
+ {
+ struct iemmp3_gr_info_s gr[2];
+ } ch[2];
+};
+
+struct iemmp3_buf
+{
+ unsigned char *pnt;
+ long size;
+ long pos;
+ struct iemmp3_buf *next;
+ struct iemmp3_buf *prev;
+};
+
+struct iemmp3Struct
+{
+ struct iemmp3_buf *head,*tail;
+ int bsize;
+ int framesize;
+ int fsizeold;
+ struct iemmp3_frame fr;
+ unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */
+ real hybrid_block[2][2][SBLIMIT*SSLIMIT];
+ int hybrid_blc[2];
+ unsigned long header;
+ int bsnum;
+ real synth_buffs[2][2][0x110];
+ int synth_bo;
+};
+
+struct iemmp3_bandInfoStruct
+{
+ short longIdx[23];
+ short longDiff[22];
+ short shortIdx[14];
+ short shortDiff[13];
+};
+
+struct iemmp3_newHuff
+{
+ unsigned int linbits;
+ short *table;
+};
+
+
+typedef struct _sigmp3play
+{
+ t_object x_obj;
+ float length_sec;
+ int samp_per_frame;
+ int frame_counter;
+ int time1_bang0_handle;
+ float time_factor;
+ int *begframeseek;
+ int curframeseek;
+ int maxframeseek;
+ char *filename;
+ float offset_sec;
+ int file_is_open;
+ int play_state;
+ int mp3_encode_size;
+ int mp3_out_index;
+ int file_size;
+ int file_block_num;
+ int file_remain;
+ int mp_is_init;
+ int mp3_ch;
+ int mp3_sr;
+ int mp3_byterate;
+ int obj_sr;
+ int obj_n;
+ int down;
+ float scale;
+ FILE *fh;
+ char *mp3inbuf;
+ char *mp3outbuf;
+ struct iemmp3Struct mp;
+ t_clock *x_clock;
+ t_outlet *x_bangout;
+ t_outlet *x_floatout;
+ t_canvas *x_canvas;
+} t_sigmp3play;
+
+
+
+static BOOL InitMP3 (struct iemmp3Struct *mp);
+static BOOL InitAgainMP3(struct iemmp3Struct *mp);
+static void ExitMP3 (struct iemmp3Struct *mp);
+static int decodeMP3 (struct iemmp3Struct *mp, char *in, int isize, char *out, int osize, int *done);
+static void make_decode_tables (long scaleval);
+static void init_layer3 (int down_sample_sblimit);
+static int decode_header (struct iemmp3_frame *fr,unsigned long newhead);
+static int do_layer3(struct iemmp3_frame *fr,unsigned char *pcm_sample,int *pcm_point,int *err);
+static int set_pointer(long backstep);
+static int synth_1to1_mono(real *bandPtr,unsigned char *samples,int *pnt);
+static int synth_1to1(real *bandPtr,int channel,unsigned char *out,int *pnt);
+static struct iemmp3_buf *addbuf(struct iemmp3Struct *mp,char *buf,int size);
+static void remove_buf(struct iemmp3Struct *mp);
+static int read_head(struct iemmp3Struct *mp);
+static int read_buf_byte(struct iemmp3Struct *mp,int *err);
+static int III_get_side_info_2(struct iemmp3_III_sideinfo *si,int stereo, int ms_stereo,long sfreq,int single);
+#ifdef IEM_MPEG1
+static int III_get_side_info_1(struct iemmp3_III_sideinfo *si,int stereo,int ms_stereo,long sfreq,int single);
+static int III_get_scale_factors_1(int *scf,struct iemmp3_gr_info_s *gr_info);
+#endif
+static int III_get_scale_factors_2(int *scf,struct iemmp3_gr_info_s *gr_info,int i_stereo);
+static int III_dequantize_sample(real xr[SBLIMIT][SSLIMIT],int *scf,struct iemmp3_gr_info_s *gr_info,int sfreq,int part2bits);
+static void III_i_stereo(real xr_buf[2][SBLIMIT][SSLIMIT],int *scalefac,struct iemmp3_gr_info_s *gr_info,int sfreq,int ms_stereo,int lsf);
+static void III_antialias(real xr[SBLIMIT][SSLIMIT],struct iemmp3_gr_info_s *gr_info);
+static void III_hybrid(real fsIn[SBLIMIT][SSLIMIT],real tsOut[SSLIMIT][SBLIMIT],int ch,struct iemmp3_gr_info_s *gr_info);
+static void dct64(real *a,real *b,real *c);
+static void dct64_1(real *out0,real *out1,real *b1,real *b2,real *samples);
+static void dct36(real *inbuf,real *o1,real *o2,real *wintab,real *tsbuf);
+static void dct12(real *in,real *rawout1,real *rawout2,register real *wi,register real *ts);
+static unsigned int getbits(int number_of_bits);
+static unsigned int getbits_fast(int number_of_bits);
+static unsigned int get1bit(void);
+
+static void sigmp3play_tick(t_sigmp3play *x);
+
+
+struct iemmp3Struct *iemmp3_gmp;
+
+int iemmp3_tabsel_123[2][3][16] = {
+ { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,},
+ {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,},
+ {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} },
+
+ { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,},
+ {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,},
+ {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} }
+};
+
+long iemmp3_freqs[9] = { 44100, 48000, 32000,
+22050, 24000, 16000 ,
+11025 , 12000 , 8000 };
+
+int iemmp3_bitindex;
+unsigned char *iemmp3_wordpointer;
+
+static real iemmp3_ispow[8207];
+static real iemmp3_aa_ca[8],iemmp3_aa_cs[8];
+static real iemmp3_COS1[12][6];
+static real iemmp3_win[4][36];
+static real iemmp3_win1[4][36];
+static real iemmp3_gainpow2[256+118+4];
+static real iemmp3_COS9[9];
+static real iemmp3_COS6_1,iemmp3_COS6_2;
+static real iemmp3_tfcos36[9];
+static real iemmp3_tfcos12[3];
+
+int iemmp3_longLimit[9][23];
+int iemmp3_shortLimit[9][14];
+
+struct iemmp3_bandInfoStruct bandInfo[9] = {
+
+ /* MPEG 1.0 */
+ { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576},
+ {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158},
+ {0,4*3,8*3,12*3,16*3,22*3,30*3,40*3,52*3,66*3, 84*3,106*3,136*3,192*3},
+ {4,4,4,4,6,8,10,12,14,18,22,30,56} } ,
+
+ { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576},
+ {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192},
+ {0,4*3,8*3,12*3,16*3,22*3,28*3,38*3,50*3,64*3, 80*3,100*3,126*3,192*3},
+ {4,4,4,4,6,6,10,12,14,16,20,26,66} } ,
+
+ { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} ,
+ {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} ,
+ {0,4*3,8*3,12*3,16*3,22*3,30*3,42*3,58*3,78*3,104*3,138*3,180*3,192*3} ,
+ {4,4,4,4,6,8,12,16,20,26,34,42,12} } ,
+
+ /* MPEG 2.0 */
+ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
+ {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
+ {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} ,
+ {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,
+
+ { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576},
+ {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,70,76,36 } ,
+ {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,136*3,180*3,192*3} ,
+ {4,4,4,6,8,10,12,14,18,24,32,44,12 } } ,
+
+ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
+ {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 },
+ {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,134*3,174*3,192*3},
+ {4,4,4,6,8,10,12,14,18,24,30,40,18 } } ,
+ /* MPEG 2.5 */
+ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} ,
+ {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54},
+ {0,12,24,36,54,78,108,144,186,240,312,402,522,576},
+ {4,4,4,6,8,10,12,14,18,24,30,40,18} },
+ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} ,
+ {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54},
+ {0,12,24,36,54,78,108,144,186,240,312,402,522,576},
+ {4,4,4,6,8,10,12,14,18,24,30,40,18} },
+ { {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576},
+ {12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2},
+ {0, 24, 48, 72,108,156,216,288,372,480,486,492,498,576},
+ {8,8,8,12,16,20,24,28,36,2,2,2,26} } ,
+};
+
+static int iemmp3_mapbuf0[9][152];
+static int iemmp3_mapbuf1[9][156];
+static int iemmp3_mapbuf2[9][44];
+static int *iemmp3_map[9][3];
+static int *iemmp3_mapend[9][3];
+
+static unsigned int iemmp3_n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */
+static unsigned int iemmp3_slen2[256]; /* MPEG 2.0 slen for intensity stereo */
+
+static real iemmp3_tan1_1[16],iemmp3_tan2_1[16],iemmp3_tan1_2[16],iemmp3_tan2_2[16];
+static real iemmp3_pow1_1[2][16],iemmp3_pow2_1[2][16],iemmp3_pow1_2[2][16],iemmp3_pow2_2[2][16];
+
+static int iemmp3_pretab1[22] = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0};
+static int iemmp3_pretab2[22] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+real iemmp3_decwin[512+32];
+static real iemmp3_cos64[16],iemmp3_cos32[8],iemmp3_cos16[4],iemmp3_cos8[2],iemmp3_cos4[1];
+real *iemmp3_pnts[] = { iemmp3_cos64,iemmp3_cos32,iemmp3_cos16,iemmp3_cos8,iemmp3_cos4 };
+
+static long iemmp3_intwinbase[] = {
+ 0, -1, -1, -1, -1, -1, -1, -2, -2, -2,
+ -2, -3, -3, -4, -4, -5, -5, -6, -7, -7,
+ -8, -9, -10, -11, -13, -14, -16, -17, -19, -21,
+ -24, -26, -29, -31, -35, -38, -41, -45, -49, -53,
+ -58, -63, -68, -73, -79, -85, -91, -97, -104, -111,
+ -117, -125, -132, -139, -147, -154, -161, -169, -176, -183,
+ -190, -196, -202, -208, -213, -218, -222, -225, -227, -228,
+ -228, -227, -224, -221, -215, -208, -200, -189, -177, -163,
+ -146, -127, -106, -83, -57, -29, 2, 36, 72, 111,
+ 153, 197, 244, 294, 347, 401, 459, 519, 581, 645,
+ 711, 779, 848, 919, 991, 1064, 1137, 1210, 1283, 1356,
+ 1428, 1498, 1567, 1634, 1698, 1759, 1817, 1870, 1919, 1962,
+ 2001, 2032, 2057, 2075, 2085, 2087, 2080, 2063, 2037, 2000,
+ 1952, 1893, 1822, 1739, 1644, 1535, 1414, 1280, 1131, 970,
+ 794, 605, 402, 185, -45, -288, -545, -814, -1095, -1388,
+ -1692, -2006, -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788,
+ -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, -7910, -8209,
+ -8491, -8755, -8998, -9219, -9416, -9585, -9727, -9838, -9916, -9959,
+ -9966, -9935, -9863, -9750, -9592, -9389, -9139, -8840, -8492, -8092,
+ -7640, -7134, -6574, -5959, -5288, -4561, -3776, -2935, -2037, -1082,
+ -70, 998, 2122, 3300, 4533, 5818, 7154, 8540, 9975, 11455,
+ 12980, 14548, 16155, 17799, 19478, 21189, 22929, 24694, 26482, 28289,
+ 30112, 31947, 33791, 35640, 37489, 39336, 41176, 43006, 44821, 46617,
+ 48390, 50137, 51853, 53534, 55178, 56778, 58333, 59838, 61289, 62684,
+ 64019, 65290, 66494, 67629, 68692, 69679, 70590, 71420, 72169, 72835,
+ 73415, 73908, 74313, 74630, 74856, 74992, 75038 };
+
+static short iemmp3_tab0[] =
+{
+ 0
+};
+
+static short iemmp3_tab1[] =
+{
+ -5, -3, -1, 17, 1, 16, 0
+};
+
+static short iemmp3_tab2[] =
+{
+ -15, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 17, -1, 1,
+ 16, 0
+};
+
+static short iemmp3_tab3[] =
+{
+ -13, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 16, 17, -1,
+ 1, 0
+};
+
+static short iemmp3_tab5[] =
+{
+ -29, -25, -23, -15, -7, -5, -3, -1, 51, 35, 50, 49, -3, -1, 19,
+ 3, -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, 17, -1, 1, 16,
+ 0
+};
+
+static short iemmp3_tab6[] =
+{
+ -25, -19, -13, -9, -5, -3, -1, 51, 3, 35, -1, 50, 48, -1, 19,
+ 49, -3, -1, 34, 2, 18, -3, -1, 33, 32, 1, -1, 17, -1, 16,
+ 0
+};
+
+static short iemmp3_tab7[] =
+{
+ -69, -65, -57, -39, -29, -17, -11, -7, -3, -1, 85, 69, -1, 84, 83,
+ -1, 53, 68, -3, -1, 37, 82, 21, -5, -1, 81, -1, 5, 52, -1,
+ 80, -1, 67, 51, -5, -3, -1, 36, 66, 20, -1, 65, 64, -11, -7,
+ -3, -1, 4, 35, -1, 50, 3, -1, 19, 49, -3, -1, 48, 34, 18,
+ -5, -1, 33, -1, 2, 32, 17, -1, 1, 16, 0
+};
+
+static short iemmp3_tab8[] =
+{
+ -65, -63, -59, -45, -31, -19, -13, -7, -5, -3, -1, 85, 84, 69, 83,
+ -3, -1, 53, 68, 37, -3, -1, 82, 5, 21, -5, -1, 81, -1, 52,
+ 67, -3, -1, 80, 51, 36, -5, -3, -1, 66, 20, 65, -3, -1, 4,
+ 64, -1, 35, 50, -9, -7, -3, -1, 19, 49, -1, 3, 48, 34, -1,
+ 2, 32, -1, 18, 33, 17, -3, -1, 1, 16, 0
+};
+
+static short iemmp3_tab9[] =
+{
+ -63, -53, -41, -29, -19, -11, -5, -3, -1, 85, 69, 53, -1, 83, -1,
+ 84, 5, -3, -1, 68, 37, -1, 82, 21, -3, -1, 81, 52, -1, 67,
+ -1, 80, 4, -7, -3, -1, 36, 66, -1, 51, 64, -1, 20, 65, -5,
+ -3, -1, 35, 50, 19, -1, 49, -1, 3, 48, -5, -3, -1, 34, 2,
+ 18, -1, 33, 32, -3, -1, 17, 1, -1, 16, 0
+};
+
+static short iemmp3_tab10[] =
+{
+ -125,-121,-111, -83, -55, -35, -21, -13, -7, -3, -1, 119, 103, -1, 118,
+ 87, -3, -1, 117, 102, 71, -3, -1, 116, 86, -1, 101, 55, -9, -3,
+ -1, 115, 70, -3, -1, 85, 84, 99, -1, 39, 114, -11, -5, -3, -1,
+ 100, 7, 112, -1, 98, -1, 69, 53, -5, -1, 6, -1, 83, 68, 23,
+ -17, -5, -1, 113, -1, 54, 38, -5, -3, -1, 37, 82, 21, -1, 81,
+ -1, 52, 67, -3, -1, 22, 97, -1, 96, -1, 5, 80, -19, -11, -7,
+ -3, -1, 36, 66, -1, 51, 4, -1, 20, 65, -3, -1, 64, 35, -1,
+ 50, 3, -3, -1, 19, 49, -1, 48, 34, -7, -3, -1, 18, 33, -1,
+ 2, 32, 17, -1, 1, 16, 0
+};
+
+static short iemmp3_tab11[] =
+{
+ -121,-113, -89, -59, -43, -27, -17, -7, -3, -1, 119, 103, -1, 118, 117,
+ -3, -1, 102, 71, -1, 116, -1, 87, 85, -5, -3, -1, 86, 101, 55,
+ -1, 115, 70, -9, -7, -3, -1, 69, 84, -1, 53, 83, 39, -1, 114,
+ -1, 100, 7, -5, -1, 113, -1, 23, 112, -3, -1, 54, 99, -1, 96,
+ -1, 68, 37, -13, -7, -5, -3, -1, 82, 5, 21, 98, -3, -1, 38,
+ 6, 22, -5, -1, 97, -1, 81, 52, -5, -1, 80, -1, 67, 51, -1,
+ 36, 66, -15, -11, -7, -3, -1, 20, 65, -1, 4, 64, -1, 35, 50,
+ -1, 19, 49, -5, -3, -1, 3, 48, 34, 33, -5, -1, 18, -1, 2,
+ 32, 17, -3, -1, 1, 16, 0
+};
+
+static short iemmp3_tab12[] =
+{
+ -115, -99, -73, -45, -27, -17, -9, -5, -3, -1, 119, 103, 118, -1, 87,
+ 117, -3, -1, 102, 71, -1, 116, 101, -3, -1, 86, 55, -3, -1, 115,
+ 85, 39, -7, -3, -1, 114, 70, -1, 100, 23, -5, -1, 113, -1, 7,
+ 112, -1, 54, 99, -13, -9, -3, -1, 69, 84, -1, 68, -1, 6, 5,
+ -1, 38, 98, -5, -1, 97, -1, 22, 96, -3, -1, 53, 83, -1, 37,
+ 82, -17, -7, -3, -1, 21, 81, -1, 52, 67, -5, -3, -1, 80, 4,
+ 36, -1, 66, 20, -3, -1, 51, 65, -1, 35, 50, -11, -7, -5, -3,
+ -1, 64, 3, 48, 19, -1, 49, 34, -1, 18, 33, -7, -5, -3, -1,
+ 2, 32, 0, 17, -1, 1, 16
+};
+
+static short iemmp3_tab13[] =
+{
+ -509,-503,-475,-405,-333,-265,-205,-153,-115, -83, -53, -35, -21, -13, -9,
+ -7, -5, -3, -1, 254, 252, 253, 237, 255, -1, 239, 223, -3, -1, 238,
+ 207, -1, 222, 191, -9, -3, -1, 251, 206, -1, 220, -1, 175, 233, -1,
+ 236, 221, -9, -5, -3, -1, 250, 205, 190, -1, 235, 159, -3, -1, 249,
+ 234, -1, 189, 219, -17, -9, -3, -1, 143, 248, -1, 204, -1, 174, 158,
+ -5, -1, 142, -1, 127, 126, 247, -5, -1, 218, -1, 173, 188, -3, -1,
+ 203, 246, 111, -15, -7, -3, -1, 232, 95, -1, 157, 217, -3, -1, 245,
+ 231, -1, 172, 187, -9, -3, -1, 79, 244, -3, -1, 202, 230, 243, -1,
+ 63, -1, 141, 216, -21, -9, -3, -1, 47, 242, -3, -1, 110, 156, 15,
+ -5, -3, -1, 201, 94, 171, -3, -1, 125, 215, 78, -11, -5, -3, -1,
+ 200, 214, 62, -1, 185, -1, 155, 170, -1, 31, 241, -23, -13, -5, -1,
+ 240, -1, 186, 229, -3, -1, 228, 140, -1, 109, 227, -5, -1, 226, -1,
+ 46, 14, -1, 30, 225, -15, -7, -3, -1, 224, 93, -1, 213, 124, -3,
+ -1, 199, 77, -1, 139, 184, -7, -3, -1, 212, 154, -1, 169, 108, -1,
+ 198, 61, -37, -21, -9, -5, -3, -1, 211, 123, 45, -1, 210, 29, -5,
+ -1, 183, -1, 92, 197, -3, -1, 153, 122, 195, -7, -5, -3, -1, 167,
+ 151, 75, 209, -3, -1, 13, 208, -1, 138, 168, -11, -7, -3, -1, 76,
+ 196, -1, 107, 182, -1, 60, 44, -3, -1, 194, 91, -3, -1, 181, 137,
+ 28, -43, -23, -11, -5, -1, 193, -1, 152, 12, -1, 192, -1, 180, 106,
+ -5, -3, -1, 166, 121, 59, -1, 179, -1, 136, 90, -11, -5, -1, 43,
+ -1, 165, 105, -1, 164, -1, 120, 135, -5, -1, 148, -1, 119, 118, 178,
+ -11, -3, -1, 27, 177, -3, -1, 11, 176, -1, 150, 74, -7, -3, -1,
+ 58, 163, -1, 89, 149, -1, 42, 162, -47, -23, -9, -3, -1, 26, 161,
+ -3, -1, 10, 104, 160, -5, -3, -1, 134, 73, 147, -3, -1, 57, 88,
+ -1, 133, 103, -9, -3, -1, 41, 146, -3, -1, 87, 117, 56, -5, -1,
+ 131, -1, 102, 71, -3, -1, 116, 86, -1, 101, 115, -11, -3, -1, 25,
+ 145, -3, -1, 9, 144, -1, 72, 132, -7, -5, -1, 114, -1, 70, 100,
+ 40, -1, 130, 24, -41, -27, -11, -5, -3, -1, 55, 39, 23, -1, 113,
+ -1, 85, 7, -7, -3, -1, 112, 54, -1, 99, 69, -3, -1, 84, 38,
+ -1, 98, 53, -5, -1, 129, -1, 8, 128, -3, -1, 22, 97, -1, 6,
+ 96, -13, -9, -5, -3, -1, 83, 68, 37, -1, 82, 5, -1, 21, 81,
+ -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, -19, -11,
+ -5, -1, 65, -1, 4, 64, -3, -1, 35, 50, 19, -3, -1, 49, 3,
+ -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16,
+ 0
+};
+
+static short iemmp3_tab15[] =
+{
+ -495,-445,-355,-263,-183,-115, -77, -43, -27, -13, -7, -3, -1, 255, 239,
+ -1, 254, 223, -1, 238, -1, 253, 207, -7, -3, -1, 252, 222, -1, 237,
+ 191, -1, 251, -1, 206, 236, -7, -3, -1, 221, 175, -1, 250, 190, -3,
+ -1, 235, 205, -1, 220, 159, -15, -7, -3, -1, 249, 234, -1, 189, 219,
+ -3, -1, 143, 248, -1, 204, 158, -7, -3, -1, 233, 127, -1, 247, 173,
+ -3, -1, 218, 188, -1, 111, -1, 174, 15, -19, -11, -3, -1, 203, 246,
+ -3, -1, 142, 232, -1, 95, 157, -3, -1, 245, 126, -1, 231, 172, -9,
+ -3, -1, 202, 187, -3, -1, 217, 141, 79, -3, -1, 244, 63, -1, 243,
+ 216, -33, -17, -9, -3, -1, 230, 47, -1, 242, -1, 110, 240, -3, -1,
+ 31, 241, -1, 156, 201, -7, -3, -1, 94, 171, -1, 186, 229, -3, -1,
+ 125, 215, -1, 78, 228, -15, -7, -3, -1, 140, 200, -1, 62, 109, -3,
+ -1, 214, 227, -1, 155, 185, -7, -3, -1, 46, 170, -1, 226, 30, -5,
+ -1, 225, -1, 14, 224, -1, 93, 213, -45, -25, -13, -7, -3, -1, 124,
+ 199, -1, 77, 139, -1, 212, -1, 184, 154, -7, -3, -1, 169, 108, -1,
+ 198, 61, -1, 211, 210, -9, -5, -3, -1, 45, 13, 29, -1, 123, 183,
+ -5, -1, 209, -1, 92, 208, -1, 197, 138, -17, -7, -3, -1, 168, 76,
+ -1, 196, 107, -5, -1, 182, -1, 153, 12, -1, 60, 195, -9, -3, -1,
+ 122, 167, -1, 166, -1, 192, 11, -1, 194, -1, 44, 91, -55, -29, -15,
+ -7, -3, -1, 181, 28, -1, 137, 152, -3, -1, 193, 75, -1, 180, 106,
+ -5, -3, -1, 59, 121, 179, -3, -1, 151, 136, -1, 43, 90, -11, -5,
+ -1, 178, -1, 165, 27, -1, 177, -1, 176, 105, -7, -3, -1, 150, 74,
+ -1, 164, 120, -3, -1, 135, 58, 163, -17, -7, -3, -1, 89, 149, -1,
+ 42, 162, -3, -1, 26, 161, -3, -1, 10, 160, 104, -7, -3, -1, 134,
+ 73, -1, 148, 57, -5, -1, 147, -1, 119, 9, -1, 88, 133, -53, -29,
+ -13, -7, -3, -1, 41, 103, -1, 118, 146, -1, 145, -1, 25, 144, -7,
+ -3, -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 71, -7,
+ -3, -1, 40, 130, -1, 24, 129, -7, -3, -1, 116, 8, -1, 128, 86,
+ -3, -1, 101, 55, -1, 115, 70, -17, -7, -3, -1, 39, 114, -1, 100,
+ 23, -3, -1, 85, 113, -3, -1, 7, 112, 54, -7, -3, -1, 99, 69,
+ -1, 84, 38, -3, -1, 98, 22, -3, -1, 6, 96, 53, -33, -19, -9,
+ -5, -1, 97, -1, 83, 68, -1, 37, 82, -3, -1, 21, 81, -3, -1,
+ 5, 80, 52, -7, -3, -1, 67, 36, -1, 66, 51, -1, 65, -1, 20,
+ 4, -9, -3, -1, 35, 50, -3, -1, 64, 3, 19, -3, -1, 49, 48,
+ 34, -9, -7, -3, -1, 18, 33, -1, 2, 32, 17, -3, -1, 1, 16,
+ 0
+};
+
+static short iemmp3_tab16[] =
+{
+ -509,-503,-461,-323,-103, -37, -27, -15, -7, -3, -1, 239, 254, -1, 223,
+ 253, -3, -1, 207, 252, -1, 191, 251, -5, -1, 175, -1, 250, 159, -3,
+ -1, 249, 248, 143, -7, -3, -1, 127, 247, -1, 111, 246, 255, -9, -5,
+ -3, -1, 95, 245, 79, -1, 244, 243, -53, -1, 240, -1, 63, -29, -19,
+ -13, -7, -5, -1, 206, -1, 236, 221, 222, -1, 233, -1, 234, 217, -1,
+ 238, -1, 237, 235, -3, -1, 190, 205, -3, -1, 220, 219, 174, -11, -5,
+ -1, 204, -1, 173, 218, -3, -1, 126, 172, 202, -5, -3, -1, 201, 125,
+ 94, 189, 242, -93, -5, -3, -1, 47, 15, 31, -1, 241, -49, -25, -13,
+ -5, -1, 158, -1, 188, 203, -3, -1, 142, 232, -1, 157, 231, -7, -3,
+ -1, 187, 141, -1, 216, 110, -1, 230, 156, -13, -7, -3, -1, 171, 186,
+ -1, 229, 215, -1, 78, -1, 228, 140, -3, -1, 200, 62, -1, 109, -1,
+ 214, 155, -19, -11, -5, -3, -1, 185, 170, 225, -1, 212, -1, 184, 169,
+ -5, -1, 123, -1, 183, 208, 227, -7, -3, -1, 14, 224, -1, 93, 213,
+ -3, -1, 124, 199, -1, 77, 139, -75, -45, -27, -13, -7, -3, -1, 154,
+ 108, -1, 198, 61, -3, -1, 92, 197, 13, -7, -3, -1, 138, 168, -1,
+ 153, 76, -3, -1, 182, 122, 60, -11, -5, -3, -1, 91, 137, 28, -1,
+ 192, -1, 152, 121, -1, 226, -1, 46, 30, -15, -7, -3, -1, 211, 45,
+ -1, 210, 209, -5, -1, 59, -1, 151, 136, 29, -7, -3, -1, 196, 107,
+ -1, 195, 167, -1, 44, -1, 194, 181, -23, -13, -7, -3, -1, 193, 12,
+ -1, 75, 180, -3, -1, 106, 166, 179, -5, -3, -1, 90, 165, 43, -1,
+ 178, 27, -13, -5, -1, 177, -1, 11, 176, -3, -1, 105, 150, -1, 74,
+ 164, -5, -3, -1, 120, 135, 163, -3, -1, 58, 89, 42, -97, -57, -33,
+ -19, -11, -5, -3, -1, 149, 104, 161, -3, -1, 134, 119, 148, -5, -3,
+ -1, 73, 87, 103, 162, -5, -1, 26, -1, 10, 160, -3, -1, 57, 147,
+ -1, 88, 133, -9, -3, -1, 41, 146, -3, -1, 118, 9, 25, -5, -1,
+ 145, -1, 144, 72, -3, -1, 132, 117, -1, 56, 131, -21, -11, -5, -3,
+ -1, 102, 40, 130, -3, -1, 71, 116, 24, -3, -1, 129, 128, -3, -1,
+ 8, 86, 55, -9, -5, -1, 115, -1, 101, 70, -1, 39, 114, -5, -3,
+ -1, 100, 85, 7, 23, -23, -13, -5, -1, 113, -1, 112, 54, -3, -1,
+ 99, 69, -1, 84, 38, -3, -1, 98, 22, -1, 97, -1, 6, 96, -9,
+ -5, -1, 83, -1, 53, 68, -1, 37, 82, -1, 81, -1, 21, 5, -33,
+ -23, -13, -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20,
+ -5, -1, 65, -1, 4, 64, -1, 35, 50, -3, -1, 19, 49, -3, -1,
+ 3, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16,
+ 0
+};
+
+static short iemmp3_tab24[] =
+{
+ -451,-117, -43, -25, -15, -7, -3, -1, 239, 254, -1, 223, 253, -3, -1,
+ 207, 252, -1, 191, 251, -5, -1, 250, -1, 175, 159, -1, 249, 248, -9,
+ -5, -3, -1, 143, 127, 247, -1, 111, 246, -3, -1, 95, 245, -1, 79,
+ 244, -71, -7, -3, -1, 63, 243, -1, 47, 242, -5, -1, 241, -1, 31,
+ 240, -25, -9, -1, 15, -3, -1, 238, 222, -1, 237, 206, -7, -3, -1,
+ 236, 221, -1, 190, 235, -3, -1, 205, 220, -1, 174, 234, -15, -7, -3,
+ -1, 189, 219, -1, 204, 158, -3, -1, 233, 173, -1, 218, 188, -7, -3,
+ -1, 203, 142, -1, 232, 157, -3, -1, 217, 126, -1, 231, 172, 255,-235,
+ -143, -77, -45, -25, -15, -7, -3, -1, 202, 187, -1, 141, 216, -5, -3,
+ -1, 14, 224, 13, 230, -5, -3, -1, 110, 156, 201, -1, 94, 186, -9,
+ -5, -1, 229, -1, 171, 125, -1, 215, 228, -3, -1, 140, 200, -3, -1,
+ 78, 46, 62, -15, -7, -3, -1, 109, 214, -1, 227, 155, -3, -1, 185,
+ 170, -1, 226, 30, -7, -3, -1, 225, 93, -1, 213, 124, -3, -1, 199,
+ 77, -1, 139, 184, -31, -15, -7, -3, -1, 212, 154, -1, 169, 108, -3,
+ -1, 198, 61, -1, 211, 45, -7, -3, -1, 210, 29, -1, 123, 183, -3,
+ -1, 209, 92, -1, 197, 138, -17, -7, -3, -1, 168, 153, -1, 76, 196,
+ -3, -1, 107, 182, -3, -1, 208, 12, 60, -7, -3, -1, 195, 122, -1,
+ 167, 44, -3, -1, 194, 91, -1, 181, 28, -57, -35, -19, -7, -3, -1,
+ 137, 152, -1, 193, 75, -5, -3, -1, 192, 11, 59, -3, -1, 176, 10,
+ 26, -5, -1, 180, -1, 106, 166, -3, -1, 121, 151, -3, -1, 160, 9,
+ 144, -9, -3, -1, 179, 136, -3, -1, 43, 90, 178, -7, -3, -1, 165,
+ 27, -1, 177, 105, -1, 150, 164, -17, -9, -5, -3, -1, 74, 120, 135,
+ -1, 58, 163, -3, -1, 89, 149, -1, 42, 162, -7, -3, -1, 161, 104,
+ -1, 134, 119, -3, -1, 73, 148, -1, 57, 147, -63, -31, -15, -7, -3,
+ -1, 88, 133, -1, 41, 103, -3, -1, 118, 146, -1, 25, 145, -7, -3,
+ -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 40, -17, -7,
+ -3, -1, 130, 24, -1, 71, 116, -5, -1, 129, -1, 8, 128, -1, 86,
+ 101, -7, -5, -1, 23, -1, 7, 112, 115, -3, -1, 55, 39, 114, -15,
+ -7, -3, -1, 70, 100, -1, 85, 113, -3, -1, 54, 99, -1, 69, 84,
+ -7, -3, -1, 38, 98, -1, 22, 97, -5, -3, -1, 6, 96, 53, -1,
+ 83, 68, -51, -37, -23, -15, -9, -3, -1, 37, 82, -1, 21, -1, 5,
+ 80, -1, 81, -1, 52, 67, -3, -1, 36, 66, -1, 51, 20, -9, -5,
+ -1, 65, -1, 4, 64, -1, 35, 50, -1, 19, 49, -7, -5, -3, -1,
+ 3, 48, 34, 18, -1, 33, -1, 2, 32, -3, -1, 17, 1, -1, 16,
+ 0
+};
+
+static short iemmp3_tab_c0[] =
+{
+ -29, -21, -13, -7, -3, -1, 11, 15, -1, 13, 14, -3, -1, 7, 5,
+ 9, -3, -1, 6, 3, -1, 10, 12, -3, -1, 2, 1, -1, 4, 8,
+ 0
+};
+
+static short iemmp3_tab_c1[] =
+{
+ -15, -7, -3, -1, 15, 14, -1, 13, 12, -3, -1, 11, 10, -1, 9,
+ 8, -7, -3, -1, 7, 6, -1, 5, 4, -3, -1, 3, 2, -1, 1,
+ 0
+};
+
+
+
+static struct iemmp3_newHuff iemmp3_ht[] =
+{
+ { /* 0 */ 0 , iemmp3_tab0 } ,
+ { /* 2 */ 0 , iemmp3_tab1 } ,
+ { /* 3 */ 0 , iemmp3_tab2 } ,
+ { /* 3 */ 0 , iemmp3_tab3 } ,
+ { /* 0 */ 0 , iemmp3_tab0 } ,
+ { /* 4 */ 0 , iemmp3_tab5 } ,
+ { /* 4 */ 0 , iemmp3_tab6 } ,
+ { /* 6 */ 0 , iemmp3_tab7 } ,
+ { /* 6 */ 0 , iemmp3_tab8 } ,
+ { /* 6 */ 0 , iemmp3_tab9 } ,
+ { /* 8 */ 0 , iemmp3_tab10 } ,
+ { /* 8 */ 0 , iemmp3_tab11 } ,
+ { /* 8 */ 0 , iemmp3_tab12 } ,
+ { /* 16 */ 0 , iemmp3_tab13 } ,
+ { /* 0 */ 0 , iemmp3_tab0 } ,
+ { /* 16 */ 0 , iemmp3_tab15 } ,
+
+ { /* 16 */ 1 , iemmp3_tab16 } ,
+ { /* 16 */ 2 , iemmp3_tab16 } ,
+ { /* 16 */ 3 , iemmp3_tab16 } ,
+ { /* 16 */ 4 , iemmp3_tab16 } ,
+ { /* 16 */ 6 , iemmp3_tab16 } ,
+ { /* 16 */ 8 , iemmp3_tab16 } ,
+ { /* 16 */ 10, iemmp3_tab16 } ,
+ { /* 16 */ 13, iemmp3_tab16 } ,
+ { /* 16 */ 4 , iemmp3_tab24 } ,
+ { /* 16 */ 5 , iemmp3_tab24 } ,
+ { /* 16 */ 6 , iemmp3_tab24 } ,
+ { /* 16 */ 7 , iemmp3_tab24 } ,
+ { /* 16 */ 8 , iemmp3_tab24 } ,
+ { /* 16 */ 9 , iemmp3_tab24 } ,
+ { /* 16 */ 11, iemmp3_tab24 } ,
+ { /* 16 */ 13, iemmp3_tab24 }
+};
+
+static struct iemmp3_newHuff iemmp3_htc[] =
+{
+ { /* 1 , 1 , */ 0 , iemmp3_tab_c0 } ,
+ { /* 1 , 1 , */ 0 , iemmp3_tab_c1 }
+};
+
+
+static t_class *sigmp3play_class;
+
+
+
+static BOOL InitMP3(struct iemmp3Struct *mp)
+{
+ memset(mp,0,sizeof(struct iemmp3Struct));
+
+ mp->framesize = 0;
+ mp->fsizeold = -1;
+ mp->bsize = 0;
+ mp->head = mp->tail = NULL;
+ mp->fr.single = -1;
+ mp->bsnum = 0;
+ mp->synth_bo = 1;
+
+ make_decode_tables(32767);
+ init_layer3(SBLIMIT);
+
+ return !0;
+}
+
+static BOOL InitAgainMP3(struct iemmp3Struct *mp)
+{
+ memset(mp,0,sizeof(struct iemmp3Struct));
+
+ mp->framesize = 0;
+ mp->fsizeold = -1;
+ mp->bsize = 0;
+ mp->head = mp->tail = NULL;
+ mp->fr.single = -1;
+ mp->bsnum = 0;
+ mp->synth_bo = 1;
+
+ return !0;
+}
+
+static void ExitMP3(struct iemmp3Struct *mp)
+{
+ struct iemmp3_buf *b,*bn;
+
+ b = mp->tail;
+ while(b)
+ {
+ free(b->pnt);
+ bn = b->next;
+ free(b);
+ b = bn;
+ }
+}
+
+static int decodeMP3(struct iemmp3Struct *mp, char *in, int isize, char *out, int osize, int *done)
+{
+ int len,error=1;
+
+ iemmp3_gmp = mp;
+
+ if(osize < 4608)
+ {
+ post("To less out space\n");
+ return MP3_ERR;
+ }
+
+ if(in)
+ {
+ if(addbuf(mp,in,isize) == NULL)
+ {
+ return MP3_ERR;
+ }
+ }
+
+ /* First decode header */
+ if(mp->framesize == 0)
+ {
+ if(mp->bsize < 4)
+ {
+ return MP3_NEED_MORE;
+ }
+ if(!read_head(mp))
+ return MP3_EX;
+ if(decode_header(&mp->fr,mp->header) == MP3_EX)
+ return MP3_EX;
+ mp->framesize = mp->fr.framesize;
+ }
+
+ if(mp->fr.framesize > mp->bsize)
+ return MP3_NEED_MORE;
+
+ iemmp3_wordpointer = mp->bsspace[mp->bsnum] + 512;
+ mp->bsnum = (mp->bsnum + 1) & 0x1;
+ iemmp3_bitindex = 0;
+
+ len = 0;
+ while(len < mp->framesize)
+ {
+ int nlen;
+ int blen = mp->tail->size - mp->tail->pos;
+ if( (mp->framesize - len) <= blen)
+ {
+ nlen = mp->framesize-len;
+ }
+ else
+ {
+ nlen = blen;
+ }
+ memcpy(iemmp3_wordpointer+len,mp->tail->pnt+mp->tail->pos,nlen);
+ len += nlen;
+ mp->tail->pos += nlen;
+ mp->bsize -= nlen;
+ if(mp->tail->pos == mp->tail->size)
+ {
+ remove_buf(mp);
+ }
+ }
+
+ *done = 0;
+ if(mp->fr.error_protection)
+ getbits(16);
+ do_layer3(&mp->fr,(unsigned char *) out,done,&error);
+ if(!error)
+ return MP3_EX;
+
+ mp->fsizeold = mp->framesize;
+ mp->framesize = 0;
+
+ return MP3_OK;
+}
+
+static void make_decode_tables(long scaleval)
+{
+ int i,j,k,kr,divv;
+ real *table,*costab;
+
+ for(i=0;i<5;i++)
+ {
+ kr=0x10>>i; divv=0x40>>i;
+ costab = iemmp3_pnts[i];
+ for(k=0;k<kr;k++)
+ costab[k] = 1.0 / (2.0 * cos(M_PI * ((double) k * 2.0 + 1.0) / (double) divv));
+ }
+
+ table = iemmp3_decwin;
+ scaleval = -scaleval;
+ for(i=0,j=0;i<256;i++,j++,table+=32)
+ {
+ if(table < iemmp3_decwin+512+16)
+ table[16] = table[0] = (double) iemmp3_intwinbase[j] / 65536.0 * (double) scaleval;
+ if(i % 32 == 31)
+ table -= 1023;
+ if(i % 64 == 63)
+ scaleval = - scaleval;
+ }
+
+ for( /* i=256 */ ;i<512;i++,j--,table+=32)
+ {
+ if(table < iemmp3_decwin+512+16)
+ table[16] = table[0] = (double) iemmp3_intwinbase[j] / 65536.0 * (double) scaleval;
+ if(i % 32 == 31)
+ table -= 1023;
+ if(i % 64 == 63)
+ scaleval = - scaleval;
+ }
+}
+
+
+static void init_layer3(int down_sample_sblimit)
+{
+ int i,j,k,l;
+
+ for(i=-256;i<118+4;i++)
+ iemmp3_gainpow2[i+256] = pow((double)2.0,-0.25 * (double) (i+210) );
+
+ for(i=0;i<8207;i++)
+ iemmp3_ispow[i] = pow((double)i,(double)4.0/3.0);
+
+ for (i=0;i<8;i++)
+ {
+ static double Ci[8]={-0.6,-0.535,-0.33,-0.185,-0.095,-0.041,-0.0142,-0.0037};
+ double sq=sqrt(1.0+Ci[i]*Ci[i]);
+ iemmp3_aa_cs[i] = 1.0/sq;
+ iemmp3_aa_ca[i] = Ci[i]/sq;
+ }
+
+ for(i=0;i<18;i++)
+ {
+ iemmp3_win[0][i] = iemmp3_win[1][i] = 0.5 * sin( M_PI / 72.0 * (double) (2*(i+0) +1) ) / cos ( M_PI * (double) (2*(i+0) +19) / 72.0 );
+ iemmp3_win[0][i+18] = iemmp3_win[3][i+18] = 0.5 * sin( M_PI / 72.0 * (double) (2*(i+18)+1) ) / cos ( M_PI * (double) (2*(i+18)+19) / 72.0 );
+ }
+ for(i=0;i<6;i++)
+ {
+ iemmp3_win[1][i+18] = 0.5 / cos ( M_PI * (double) (2*(i+18)+19) / 72.0 );
+ iemmp3_win[3][i+12] = 0.5 / cos ( M_PI * (double) (2*(i+12)+19) / 72.0 );
+ iemmp3_win[1][i+24] = 0.5 * sin( M_PI / 24.0 * (double) (2*i+13) ) / cos ( M_PI * (double) (2*(i+24)+19) / 72.0 );
+ iemmp3_win[1][i+30] = iemmp3_win[3][i] = 0.0;
+ iemmp3_win[3][i+6 ] = 0.5 * sin( M_PI / 24.0 * (double) (2*i+1) ) / cos ( M_PI * (double) (2*(i+6 )+19) / 72.0 );
+ }
+
+ for(i=0;i<9;i++)
+ iemmp3_COS9[i] = cos( M_PI / 18.0 * (double) i);
+
+ for(i=0;i<9;i++)
+ iemmp3_tfcos36[i] = 0.5 / cos ( M_PI * (double) (i*2+1) / 36.0 );
+ for(i=0;i<3;i++)
+ iemmp3_tfcos12[i] = 0.5 / cos ( M_PI * (double) (i*2+1) / 12.0 );
+
+ iemmp3_COS6_1 = cos( M_PI / 6.0 * (double) 1);
+ iemmp3_COS6_2 = cos( M_PI / 6.0 * (double) 2);
+
+ for(i=0;i<12;i++)
+ {
+ iemmp3_win[2][i] = 0.5 * sin( M_PI / 24.0 * (double) (2*i+1) ) / cos ( M_PI * (double) (2*i+7) / 24.0 );
+ for(j=0;j<6;j++)
+ iemmp3_COS1[i][j] = cos( M_PI / 24.0 * (double) ((2*i+7)*(2*j+1)) );
+ }
+
+ for(j=0;j<4;j++)
+ {
+ static int len[4] = { 36,36,12,36 };
+ for(i=0;i<len[j];i+=2)
+ iemmp3_win1[j][i] = + iemmp3_win[j][i];
+ for(i=1;i<len[j];i+=2)
+ iemmp3_win1[j][i] = - iemmp3_win[j][i];
+ }
+
+ for(i=0;i<16;i++)
+ {
+ double t = tan( (double) i * M_PI / 12.0 );
+ iemmp3_tan1_1[i] = t / (1.0+t);
+ iemmp3_tan2_1[i] = 1.0 / (1.0 + t);
+ iemmp3_tan1_2[i] = M_SQRT2 * t / (1.0+t);
+ iemmp3_tan2_2[i] = M_SQRT2 / (1.0 + t);
+
+ for(j=0;j<2;j++)
+ {
+ double base = pow(2.0,-0.25*(j+1.0));
+ double p1=1.0,p2=1.0;
+ if(i > 0)
+ {
+ if( i & 1 )
+ p1 = pow(base,(i+1.0)*0.5);
+ else
+ p2 = pow(base,i*0.5);
+ }
+ iemmp3_pow1_1[j][i] = p1;
+ iemmp3_pow2_1[j][i] = p2;
+ iemmp3_pow1_2[j][i] = M_SQRT2 * p1;
+ iemmp3_pow2_2[j][i] = M_SQRT2 * p2;
+ }
+ }
+
+ for(j=0;j<9;j++)
+ {
+ struct iemmp3_bandInfoStruct *bi = &bandInfo[j];
+ int *mp;
+ int cb,lwin;
+ short *bdf;
+
+ mp = iemmp3_map[j][0] = iemmp3_mapbuf0[j];
+ bdf = bi->longDiff;
+ for(i=0,cb = 0; cb < 8 ; cb++,i+=*bdf++)
+ {
+ *mp++ = (*bdf) >> 1;
+ *mp++ = i;
+ *mp++ = 3;
+ *mp++ = cb;
+ }
+ bdf = bi->shortDiff+3;
+ for(cb=3;cb<13;cb++)
+ {
+ int l = (*bdf++) >> 1;
+ for(lwin=0;lwin<3;lwin++)
+ {
+ *mp++ = l;
+ *mp++ = i + lwin;
+ *mp++ = lwin;
+ *mp++ = cb;
+ }
+ i += 6*l;
+ }
+ iemmp3_mapend[j][0] = mp;
+
+ mp = iemmp3_map[j][1] = iemmp3_mapbuf1[j];
+ bdf = bi->shortDiff+0;
+ for(i=0,cb=0;cb<13;cb++)
+ {
+ int l = (*bdf++) >> 1;
+ for(lwin=0;lwin<3;lwin++)
+ {
+ *mp++ = l;
+ *mp++ = i + lwin;
+ *mp++ = lwin;
+ *mp++ = cb;
+ }
+ i += 6*l;
+ }
+ iemmp3_mapend[j][1] = mp;
+
+ mp = iemmp3_map[j][2] = iemmp3_mapbuf2[j];
+ bdf = bi->longDiff;
+ for(cb = 0; cb < 22 ; cb++)
+ {
+ *mp++ = (*bdf++) >> 1;
+ *mp++ = cb;
+ }
+ iemmp3_mapend[j][2] = mp;
+ }
+
+ for(j=0;j<9;j++)
+ {
+ for(i=0;i<23;i++)
+ {
+ iemmp3_longLimit[j][i] = (bandInfo[j].longIdx[i] - 1 + 8) / 18 + 1;
+ if(iemmp3_longLimit[j][i] > (down_sample_sblimit) )
+ iemmp3_longLimit[j][i] = down_sample_sblimit;
+ }
+ for(i=0;i<14;i++)
+ {
+ iemmp3_shortLimit[j][i] = (bandInfo[j].shortIdx[i] - 1) / 18 + 1;
+ if(iemmp3_shortLimit[j][i] > (down_sample_sblimit) )
+ iemmp3_shortLimit[j][i] = down_sample_sblimit;
+ }
+ }
+
+ for(i=0;i<5;i++)
+ {
+ for(j=0;j<6;j++)
+ {
+ for(k=0;k<6;k++)
+ {
+ int n = k + j * 6 + i * 36;
+ iemmp3_slen2[n] = i|(j<<3)|(k<<6)|(3<<12);
+ }
+ }
+ }
+ for(i=0;i<4;i++)
+ {
+ for(j=0;j<4;j++)
+ {
+ for(k=0;k<4;k++)
+ {
+ int n = k + j * 4 + i * 16;
+ iemmp3_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12);
+ }
+ }
+ }
+ for(i=0;i<4;i++)
+ {
+ for(j=0;j<3;j++)
+ {
+ int n = j + i * 3;
+ iemmp3_slen2[n+244] = i|(j<<3) | (5<<12);
+ iemmp3_n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15);
+ }
+ }
+
+ for(i=0;i<5;i++)
+ {
+ for(j=0;j<5;j++)
+ {
+ for(k=0;k<4;k++)
+ {
+ for(l=0;l<4;l++)
+ {
+ int n = l + k * 4 + j * 16 + i * 80;
+ iemmp3_n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12);
+ }
+ }
+ }
+ }
+ for(i=0;i<5;i++)
+ {
+ for(j=0;j<5;j++)
+ {
+ for(k=0;k<4;k++)
+ {
+ int n = k + j * 4 + i * 20;
+ iemmp3_n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12);
+ }
+ }
+ }
+}
+
+static void remove_buf(struct iemmp3Struct *mp)
+{
+ struct iemmp3_buf *buf = mp->tail;
+
+ mp->tail = buf->next;
+ if(mp->tail)
+ mp->tail->prev = NULL;
+ else
+ {
+ mp->tail = mp->head = NULL;
+ }
+ free(buf->pnt);
+ free(buf);
+}
+
+static struct iemmp3_buf *addbuf(struct iemmp3Struct *mp,char *buf,int size)
+{
+ struct iemmp3_buf *nbuf;
+
+ nbuf = malloc( sizeof(struct iemmp3_buf) );
+ if(!nbuf)
+ {
+ post("Out of memory!\n");
+ return NULL;
+ }
+ nbuf->pnt = malloc(size);
+ if(!nbuf->pnt)
+ {
+ free(nbuf);
+ return NULL;
+ }
+ nbuf->size = size;
+ memcpy(nbuf->pnt,buf,size);
+ nbuf->next = NULL;
+ nbuf->prev = mp->head;
+ nbuf->pos = 0;
+ if(!mp->tail)
+ {
+ mp->tail = nbuf;
+ }
+ else
+ {
+ mp->head->next = nbuf;
+ }
+ mp->head = nbuf;
+ mp->bsize += size;
+ return nbuf;
+}
+
+static int read_buf_byte(struct iemmp3Struct *mp,int *err)
+{
+ unsigned int b;
+ int pos;
+
+ pos = mp->tail->pos;
+ while(pos >= mp->tail->size)
+ {
+ remove_buf(mp);
+ pos = mp->tail->pos;
+ if(!mp->tail)
+ {
+ post("Fatal error!\n");
+ *err = 0;
+ return(0);
+ }
+ }
+ b = mp->tail->pnt[pos];
+ mp->bsize--;
+ mp->tail->pos++;
+ return(b);
+}
+
+static int read_head(struct iemmp3Struct *mp)
+{
+ unsigned long head;
+ int error=1;
+
+ head = read_buf_byte(mp,&error);
+ head <<= 8;
+ head |= read_buf_byte(mp,&error);
+ head <<= 8;
+ head |= read_buf_byte(mp,&error);
+ head <<= 8;
+ head |= read_buf_byte(mp,&error);
+ mp->header = head;
+ return(error);
+}
+
+static int decode_header(struct iemmp3_frame *fr,unsigned long newhead)
+{
+ if( newhead & (1<<20) )
+ {
+ fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1;
+ fr->mpeg25 = 0;
+ }
+ else
+ {
+ fr->lsf = 1;
+ fr->mpeg25 = 1;
+ }
+ fr->lay = 4-((newhead>>17)&3);
+ if( ((newhead>>10)&0x3) == 0x3)
+ {
+ post("Stream error");
+ return(MP3_EX);
+ }
+ if(fr->mpeg25)
+ {
+ fr->sampling_frequency = 6 + ((newhead>>10)&0x3);
+ }
+ else
+ fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3);
+ fr->error_protection = ((newhead>>16)&0x1)^0x1;
+ if(fr->mpeg25) /* allow Bitrate change for 2.5 ... */
+ fr->bitrate_index = ((newhead>>12)&0xf);
+ fr->bitrate_index = ((newhead>>12)&0xf);
+ fr->padding = ((newhead>>9)&0x1);
+ fr->extension = ((newhead>>8)&0x1);
+ fr->mode = ((newhead>>6)&0x3);
+ fr->mode_ext = ((newhead>>4)&0x3);
+ fr->copyright = ((newhead>>3)&0x1);
+ fr->original = ((newhead>>2)&0x1);
+ fr->emphasis = newhead & 0x3;
+ fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
+ if(!fr->bitrate_index)
+ {
+ post("Free format not supported.\n");
+ return(0);
+ }
+ switch(fr->lay)
+ {
+ case 1:
+ post("Layer I not supported!\n");
+ break;
+ case 2:
+ post("Layer II not supported!\n");
+ break;
+ case 3:
+ fr->framesize = (long) iemmp3_tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
+ fr->framesize /= iemmp3_freqs[fr->sampling_frequency]<<(fr->lsf);
+ fr->framesize = fr->framesize + fr->padding - 4;
+ //post("Framesize: %d",fr->framesize);
+ break;
+ default:
+ post("Sorry, unknown layer type.\n");
+ return (0);
+ }
+ return(1);
+}
+
+static unsigned int getbits(int number_of_bits)
+{
+ unsigned long rval;
+
+ if(!number_of_bits)
+ return 0;
+ {
+ rval = iemmp3_wordpointer[0];
+ rval <<= 8;
+ rval |= iemmp3_wordpointer[1];
+ rval <<= 8;
+ rval |= iemmp3_wordpointer[2];
+ rval <<= iemmp3_bitindex;
+ rval &= 0xffffff;
+ iemmp3_bitindex += number_of_bits;
+ rval >>= (24-number_of_bits);
+ iemmp3_wordpointer += (iemmp3_bitindex>>3);
+ iemmp3_bitindex &= 7;
+ }
+ return rval;
+}
+
+static unsigned int getbits_fast(int number_of_bits)
+{
+ unsigned long rval;
+
+ {
+ rval = iemmp3_wordpointer[0];
+ rval <<= 8;
+ rval |= iemmp3_wordpointer[1];
+ rval <<= iemmp3_bitindex;
+ rval &= 0xffff;
+ iemmp3_bitindex += number_of_bits;
+ rval >>= (16-number_of_bits);
+ iemmp3_wordpointer += (iemmp3_bitindex>>3);
+ iemmp3_bitindex &= 7;
+ }
+ return rval;
+}
+
+static unsigned int get1bit(void)
+{
+ unsigned char rval;
+ rval = *iemmp3_wordpointer << iemmp3_bitindex;
+
+ iemmp3_bitindex++;
+ iemmp3_wordpointer += (iemmp3_bitindex>>3);
+ iemmp3_bitindex &= 7;
+
+ return rval>>7;
+}
+
+static int do_layer3(struct iemmp3_frame *fr,unsigned char *pcm_sample,int *pcm_point,int *err)
+{
+ int gr, ch, ss,clip=0;
+ int scalefacs[39]; /* max 39 for short[13][3] mode, mixed: 38, long: 22 */
+ struct iemmp3_III_sideinfo sideinfo;
+ int stereo = fr->stereo;
+ int single = fr->single;
+ int ms_stereo,i_stereo;
+ int sfreq = fr->sampling_frequency;
+ int stereo1,granules;
+
+ if(stereo == 1)
+ { /* stream is mono */
+ stereo1 = 1;
+ single = 0;
+ }
+ else if(single >= 0) /* stream is stereo, but force to mono */
+ stereo1 = 1;
+ else
+ stereo1 = 2;
+
+ if(fr->mode == MPG_MD_JOINT_STEREO)
+ {
+ ms_stereo = fr->mode_ext & 0x2;
+ i_stereo = fr->mode_ext & 0x1;
+ }
+ else
+ ms_stereo = i_stereo = 0;
+
+ if(fr->lsf)
+ {
+ granules = 1;
+ if(!III_get_side_info_2(&sideinfo,stereo,ms_stereo,sfreq,single))
+ {
+ *err = 0;
+ return 0;
+ }
+ }
+ else
+ {
+ granules = 2;
+#ifdef IEM_MPEG1
+ if(!III_get_side_info_1(&sideinfo,stereo,ms_stereo,sfreq,single))
+ {
+ *err = 0;
+ return 0;
+ }
+#else
+ post("Not supported\n");
+#endif
+ }
+
+ if(set_pointer(sideinfo.main_data_begin) == MP3_ERR)
+ return 0;
+
+ for (gr=0;gr<granules;gr++)
+ {
+ static real hybridIn[2][SBLIMIT][SSLIMIT];
+ static real hybridOut[2][SSLIMIT][SBLIMIT];
+
+ {
+ struct iemmp3_gr_info_s *gr_info = &(sideinfo.ch[0].gr[gr]);
+ long part2bits;
+ if(fr->lsf)
+ part2bits = III_get_scale_factors_2(scalefacs,gr_info,0);
+ else
+ {
+#ifdef IEM_MPEG1
+ part2bits = III_get_scale_factors_1(scalefacs,gr_info);
+#else
+ post("Not supported\n");
+#endif
+ }
+ if(III_dequantize_sample(hybridIn[0], scalefacs,gr_info,sfreq,part2bits))
+ return clip;
+ }
+ if(stereo == 2)
+ {
+ struct iemmp3_gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]);
+ long part2bits;
+ if(fr->lsf)
+ part2bits = III_get_scale_factors_2(scalefacs,gr_info,i_stereo);
+ else
+ {
+#ifdef IEM_MPEG1
+ part2bits = III_get_scale_factors_1(scalefacs,gr_info);
+#else
+ post("Not supported\n");
+#endif
+ }
+
+ if(III_dequantize_sample(hybridIn[1],scalefacs,gr_info,sfreq,part2bits))
+ return clip;
+
+ if(ms_stereo)
+ {
+ int i;
+ for(i=0;i<SBLIMIT*SSLIMIT;i++)
+ {
+ real tmp0,tmp1;
+ tmp0 = ((real *) hybridIn[0])[i];
+ tmp1 = ((real *) hybridIn[1])[i];
+ ((real *) hybridIn[1])[i] = tmp0 - tmp1;
+ ((real *) hybridIn[0])[i] = tmp0 + tmp1;
+ }
+ }
+
+ if(i_stereo)
+ III_i_stereo(hybridIn,scalefacs,gr_info,sfreq,ms_stereo,fr->lsf);
+
+ if(ms_stereo || i_stereo || (single == 3) )
+ {
+ if(gr_info->maxb > sideinfo.ch[0].gr[gr].maxb)
+ sideinfo.ch[0].gr[gr].maxb = gr_info->maxb;
+ else
+ gr_info->maxb = sideinfo.ch[0].gr[gr].maxb;
+ }
+
+ switch(single)
+ {
+ case 3:
+ {
+ register unsigned int i;
+ register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1];
+ for(i=0;i<SSLIMIT*gr_info->maxb;i++,in0++)
+ *in0 = (*in0 + *in1++); /* *0.5 done by pow-scale */
+ }
+ break;
+ case 1:
+ {
+ register unsigned int i;
+ register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1];
+ for(i=0;i<SSLIMIT*gr_info->maxb;i++)
+ *in0++ = *in1++;
+ }
+ break;
+ }
+ }
+
+ for(ch=0;ch<stereo1;ch++)
+ {
+ struct iemmp3_gr_info_s *gr_info = &(sideinfo.ch[ch].gr[gr]);
+ III_antialias(hybridIn[ch],gr_info);
+ III_hybrid(hybridIn[ch], hybridOut[ch], ch,gr_info);
+ }
+
+ for(ss=0;ss<SSLIMIT;ss++)
+ {
+ if(single >= 0)
+ {
+ clip += synth_1to1_mono(hybridOut[0][ss],pcm_sample,pcm_point);
+ }
+ else
+ {
+ int p1 = *pcm_point;
+ clip += synth_1to1(hybridOut[0][ss],0,pcm_sample,&p1);
+ clip += synth_1to1(hybridOut[1][ss],1,pcm_sample,pcm_point);
+ }
+ }
+ }
+
+ return clip;
+}
+
+static int III_get_side_info_2(struct iemmp3_III_sideinfo *si,int stereo,
+ int ms_stereo,long sfreq,int single)
+{
+ int ch;
+ int powdiff = (single == 3) ? 4 : 0;
+
+ si->main_data_begin = getbits(8);
+ if (stereo == 1)
+ si->private_bits = get1bit();
+ else
+ si->private_bits = getbits_fast(2);
+
+ for (ch=0; ch<stereo; ch++)
+ {
+ register struct iemmp3_gr_info_s *gr_info = &(si->ch[ch].gr[0]);
+
+ gr_info->part2_3_length = getbits(12);
+ gr_info->big_values = getbits_fast(9);
+ if(gr_info->big_values > 288)
+ {
+ post("big_values too large!\n");
+ gr_info->big_values = 288;
+ }
+ gr_info->pow2gain = iemmp3_gainpow2+256 - getbits_fast(8) + powdiff;
+ if(ms_stereo)
+ gr_info->pow2gain += 2;
+ gr_info->scalefac_compress = getbits(9);
+ /* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
+ if(get1bit())
+ {
+ int i;
+ gr_info->block_type = getbits_fast(2);
+ gr_info->mixed_block_flag = get1bit();
+ gr_info->table_select[0] = getbits_fast(5);
+ gr_info->table_select[1] = getbits_fast(5);
+ /*
+ * table_select[2] not needed, because there is no region2,
+ * but to satisfy some verifications tools we set it either.
+ */
+ gr_info->table_select[2] = 0;
+ for(i=0;i<3;i++)
+ gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast(3)<<3);
+ if(gr_info->block_type == 0)
+ {
+ post("Blocktype == 0 and window-switching == 1 not allowed.\n");
+ return(0);
+ }
+ /* region_count/start parameters are implicit in this case. */
+ /* check this again! */
+ if(gr_info->block_type == 2)
+ gr_info->region1start = 36>>1;
+ else if(sfreq == 8)
+ /* check this for 2.5 and sfreq=8 */
+ gr_info->region1start = 108>>1;
+ else
+ gr_info->region1start = 54>>1;
+ gr_info->region2start = 576>>1;
+ }
+ else
+ {
+ int i,r0c,r1c;
+ for (i=0; i<3; i++)
+ gr_info->table_select[i] = getbits_fast(5);
+ r0c = getbits_fast(4);
+ r1c = getbits_fast(3);
+ gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
+ gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
+ gr_info->block_type = 0;
+ gr_info->mixed_block_flag = 0;
+ }
+ gr_info->scalefac_scale = get1bit();
+ gr_info->count1table_select = get1bit();
+ }
+ return(1);
+}
+
+
+#ifdef IEM_MPEG1
+static int III_get_side_info_1(struct iemmp3_III_sideinfo *si,int stereo,
+ int ms_stereo,long sfreq,int single)
+{
+ int ch, gr;
+ int powdiff = (single == 3) ? 4 : 0;
+
+ si->main_data_begin = getbits(9);
+ if (stereo == 1)
+ si->private_bits = getbits_fast(5);
+ else
+ si->private_bits = getbits_fast(3);
+
+ for (ch=0; ch<stereo; ch++)
+ {
+ si->ch[ch].gr[0].scfsi = -1;
+ si->ch[ch].gr[1].scfsi = getbits_fast(4);
+ }
+
+ for (gr=0; gr<2; gr++)
+ {
+ for (ch=0; ch<stereo; ch++)
+ {
+ register struct iemmp3_gr_info_s *gr_info = &(si->ch[ch].gr[gr]);
+
+ gr_info->part2_3_length = getbits(12);
+ gr_info->big_values = getbits_fast(9);
+ if(gr_info->big_values > 288)
+ {
+ post("big_values too large!\n");
+ gr_info->big_values = 288;
+ }
+ gr_info->pow2gain = iemmp3_gainpow2+256 - getbits_fast(8) + powdiff;
+ if(ms_stereo)
+ gr_info->pow2gain += 2;
+ gr_info->scalefac_compress = getbits_fast(4);
+ /* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
+ if(get1bit())
+ {
+ int i;
+
+ gr_info->block_type = getbits_fast(2);
+ gr_info->mixed_block_flag = get1bit();
+ gr_info->table_select[0] = getbits_fast(5);
+ gr_info->table_select[1] = getbits_fast(5);
+ /*
+ * table_select[2] not needed, because there is no region2,
+ * but to satisfy some verifications tools we set it either.
+ */
+ gr_info->table_select[2] = 0;
+ for(i=0;i<3;i++)
+ gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast(3)<<3);
+
+ if(gr_info->block_type == 0)
+ {
+ post("Blocktype == 0 and window-switching == 1 not allowed.\n");
+ return(0);
+ }
+ /* region_count/start parameters are implicit in this case. */
+ gr_info->region1start = 36>>1;
+ gr_info->region2start = 576>>1;
+ }
+ else
+ {
+ int i,r0c,r1c;
+ for (i=0; i<3; i++)
+ gr_info->table_select[i] = getbits_fast(5);
+ r0c = getbits_fast(4);
+ r1c = getbits_fast(3);
+ gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
+ gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
+ gr_info->block_type = 0;
+ gr_info->mixed_block_flag = 0;
+ }
+ gr_info->preflag = get1bit();
+ gr_info->scalefac_scale = get1bit();
+ gr_info->count1table_select = get1bit();
+ }
+ }
+ return(1);
+}
+#endif
+
+static int set_pointer(long backstep)
+{
+ unsigned char *bsbufold;
+ if(iemmp3_gmp->fsizeold < 0 && backstep > 0)
+ {
+ post("Can't step back %ld!\n",backstep);
+ return MP3_ERR;
+ }
+ bsbufold = iemmp3_gmp->bsspace[iemmp3_gmp->bsnum] + 512;
+ iemmp3_wordpointer -= backstep;
+ if (backstep)
+ memcpy(iemmp3_wordpointer,bsbufold+iemmp3_gmp->fsizeold-backstep,backstep);
+ iemmp3_bitindex = 0;
+ return MP3_OK;
+}
+
+#ifdef IEM_MPEG1
+static int III_get_scale_factors_1(int *scf,struct iemmp3_gr_info_s *gr_info)
+{
+ static unsigned char slen[2][16] = {
+ {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4},
+ {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3}
+ };
+ int numbits;
+ int num0 = slen[0][gr_info->scalefac_compress];
+ int num1 = slen[1][gr_info->scalefac_compress];
+
+ if (gr_info->block_type == 2)
+ {
+ int i=18;
+
+ numbits = (num0 + num1) * 18;
+ if (gr_info->mixed_block_flag)
+ {
+ for (i=8;i;i--)
+ *scf++ = getbits_fast(num0);
+ i = 9;
+ numbits -= num0; /* num0 * 17 + num1 * 18 */
+ }
+
+ for (;i;i--)
+ *scf++ = getbits_fast(num0);
+ for (i = 18; i; i--)
+ *scf++ = getbits_fast(num1);
+ *scf++ = 0; *scf++ = 0; *scf++ = 0; /* short[13][0..2] = 0 */
+ }
+ else
+ {
+ int i;
+ int scfsi = gr_info->scfsi;
+
+ if(scfsi < 0)
+ { /* scfsi < 0 => granule == 0 */
+ for(i=11;i;i--)
+ *scf++ = getbits_fast(num0);
+ for(i=10;i;i--)
+ *scf++ = getbits_fast(num1);
+ numbits = (num0 + num1) * 10 + num0;
+ }
+ else
+ {
+ numbits = 0;
+ if(!(scfsi & 0x8))
+ {
+ for (i=6;i;i--)
+ *scf++ = getbits_fast(num0);
+ numbits += num0 * 6;
+ }
+ else
+ {
+ *scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */
+ *scf++ = 0; *scf++ = 0; *scf++ = 0;
+ }
+
+ if(!(scfsi & 0x4))
+ {
+ for (i=5;i;i--)
+ *scf++ = getbits_fast(num0);
+ numbits += num0 * 5;
+ }
+ else
+ {
+ *scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */
+ *scf++ = 0; *scf++ = 0;
+ }
+
+ if(!(scfsi & 0x2))
+ {
+ for(i=5;i;i--)
+ *scf++ = getbits_fast(num1);
+ numbits += num1 * 5;
+ }
+ else
+ {
+ *scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */
+ *scf++ = 0; *scf++ = 0;
+ }
+
+ if(!(scfsi & 0x1))
+ {
+ for (i=5;i;i--)
+ *scf++ = getbits_fast(num1);
+ numbits += num1 * 5;
+ }
+ else
+ {
+ *scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */
+ *scf++ = 0; *scf++ = 0;
+ }
+ }
+
+ *scf++ = 0; /* no l[21] in original sources */
+ }
+ return numbits;
+}
+#endif
+
+static int III_get_scale_factors_2(int *scf,struct iemmp3_gr_info_s *gr_info,int i_stereo)
+{
+ unsigned char *pnt;
+ int i,j;
+ unsigned int slen;
+ int n = 0;
+ int numbits = 0;
+
+ static unsigned char stab[3][6][4] = {
+ { { 6, 5, 5,5 } , { 6, 5, 7,3 } , { 11,10,0,0} ,
+ { 7, 7, 7,0 } , { 6, 6, 6,3 } , { 8, 8,5,0} } ,
+ { { 9, 9, 9,9 } , { 9, 9,12,6 } , { 18,18,0,0} ,
+ {12,12,12,0 } , {12, 9, 9,6 } , { 15,12,9,0} } ,
+ { { 6, 9, 9,9 } , { 6, 9,12,6 } , { 15,18,0,0} ,
+ { 6,15,12,0 } , { 6,12, 9,6 } , { 6,18,9,0} } };
+
+ if(i_stereo) /* i_stereo AND second channel -> do_layer3() checks this */
+ slen = iemmp3_slen2[gr_info->scalefac_compress>>1];
+ else
+ slen = iemmp3_n_slen2[gr_info->scalefac_compress];
+
+ gr_info->preflag = (slen>>15) & 0x1;
+
+ n = 0;
+ if( gr_info->block_type == 2 )
+ {
+ n++;
+ if(gr_info->mixed_block_flag)
+ n++;
+ }
+
+ pnt = stab[n][(slen>>12)&0x7];
+
+ for(i=0;i<4;i++)
+ {
+ int num = slen & 0x7;
+ slen >>= 3;
+ if(num)
+ {
+ for(j=0;j<(int)(pnt[i]);j++)
+ *scf++ = getbits_fast(num);
+ numbits += pnt[i] * num;
+ }
+ else
+ {
+ for(j=0;j<(int)(pnt[i]);j++)
+ *scf++ = 0;
+ }
+ }
+
+ n = (n << 1) + 1;
+ for(i=0;i<n;i++)
+ *scf++ = 0;
+
+ return numbits;
+}
+
+
+
+static int III_dequantize_sample(real xr[SBLIMIT][SSLIMIT],int *scf,
+ struct iemmp3_gr_info_s *gr_info,int sfreq,int part2bits)
+{
+ int shift = 1 + gr_info->scalefac_scale;
+ real *xrpnt = (real *) xr;
+ int l[3],l3;
+ int part2remain = gr_info->part2_3_length - part2bits;
+ int *me;
+
+ {
+ int bv = gr_info->big_values;
+ int region1 = gr_info->region1start;
+ int region2 = gr_info->region2start;
+
+ l3 = ((576>>1)-bv)>>1;
+ /*
+ * we may lose the 'odd' bit here !!
+ * check this later again
+ */
+ if(bv <= region1)
+ {
+ l[0] = bv; l[1] = 0; l[2] = 0;
+ }
+ else
+ {
+ l[0] = region1;
+ if(bv <= region2)
+ {
+ l[1] = bv - l[0]; l[2] = 0;
+ }
+ else
+ {
+ l[1] = region2 - l[0]; l[2] = bv - region2;
+ }
+ }
+ }
+
+ if(gr_info->block_type == 2)
+ {
+ /*
+ * decoding with short or mixed mode BandIndex table
+ */
+ int i,max[4];
+ int step=0,lwin=0,cb=0;
+ register real v = 0.0;
+ register int *m,mc;
+
+ if(gr_info->mixed_block_flag)
+ {
+ max[3] = -1;
+ max[0] = max[1] = max[2] = 2;
+ m = iemmp3_map[sfreq][0];
+ me = iemmp3_mapend[sfreq][0];
+ }
+ else
+ {
+ max[0] = max[1] = max[2] = max[3] = -1;
+ /* max[3] not really needed in this case */
+ m = iemmp3_map[sfreq][1];
+ me = iemmp3_mapend[sfreq][1];
+ }
+
+ mc = 0;
+ for(i=0;i<2;i++)
+ {
+ int lp = l[i];
+ struct iemmp3_newHuff *h = iemmp3_ht+gr_info->table_select[i];
+ for(;lp;lp--,mc--)
+ {
+ register int x,y;
+ if( (!mc) )
+ {
+ mc = *m++;
+ xrpnt = ((real *) xr) + (*m++);
+ lwin = *m++;
+ cb = *m++;
+ if(lwin == 3)
+ {
+ v = gr_info->pow2gain[(*scf++) << shift];
+ step = 1;
+ }
+ else
+ {
+ v = gr_info->full_gain[lwin][(*scf++) << shift];
+ step = 3;
+ }
+ }
+ {
+ register short *val = h->table;
+ while((y=*val++)<0)
+ {
+ if (get1bit())
+ val -= y;
+ part2remain--;
+ }
+ x = y >> 4;
+ y &= 0xf;
+ }
+ if(x == 15)
+ {
+ max[lwin] = cb;
+ part2remain -= h->linbits+1;
+ x += getbits(h->linbits);
+ if(get1bit())
+ *xrpnt = -iemmp3_ispow[x] * v;
+ else
+ *xrpnt = iemmp3_ispow[x] * v;
+ }
+ else if(x)
+ {
+ max[lwin] = cb;
+ if(get1bit())
+ *xrpnt = -iemmp3_ispow[x] * v;
+ else
+ *xrpnt = iemmp3_ispow[x] * v;
+ part2remain--;
+ }
+ else
+ *xrpnt = 0.0;
+ xrpnt += step;
+ if(y == 15)
+ {
+ max[lwin] = cb;
+ part2remain -= h->linbits+1;
+ y += getbits(h->linbits);
+ if(get1bit())
+ *xrpnt = -iemmp3_ispow[y] * v;
+ else
+ *xrpnt = iemmp3_ispow[y] * v;
+ }
+ else if(y)
+ {
+ max[lwin] = cb;
+ if(get1bit())
+ *xrpnt = -iemmp3_ispow[y] * v;
+ else
+ *xrpnt = iemmp3_ispow[y] * v;
+ part2remain--;
+ }
+ else
+ *xrpnt = 0.0;
+ xrpnt += step;
+ }
+ }
+ for(;l3 && (part2remain > 0);l3--)
+ {
+ struct iemmp3_newHuff *h = iemmp3_htc+gr_info->count1table_select;
+ register short *val = h->table,a;
+
+ while((a=*val++)<0)
+ {
+ part2remain--;
+ if(part2remain < 0)
+ {
+ part2remain++;
+ a = 0;
+ break;
+ }
+ if (get1bit())
+ val -= a;
+ }
+
+ for(i=0;i<4;i++)
+ {
+ if(!(i & 1))
+ {
+ if(!mc)
+ {
+ mc = *m++;
+ xrpnt = ((real *) xr) + (*m++);
+ lwin = *m++;
+ cb = *m++;
+ if(lwin == 3)
+ {
+ v = gr_info->pow2gain[(*scf++) << shift];
+ step = 1;
+ }
+ else
+ {
+ v = gr_info->full_gain[lwin][(*scf++) << shift];
+ step = 3;
+ }
+ }
+ mc--;
+ }
+ if( (a & (0x8>>i)) )
+ {
+ max[lwin] = cb;
+ part2remain--;
+ if(part2remain < 0)
+ {
+ part2remain++;
+ break;
+ }
+ if(get1bit())
+ *xrpnt = -v;
+ else
+ *xrpnt = v;
+ }
+ else
+ *xrpnt = 0.0;
+ xrpnt += step;
+ }
+ }
+
+ while( m < me )
+ {
+ if(!mc)
+ {
+ mc = *m++;
+ xrpnt = ((real *) xr) + *m++;
+ if( (*m++) == 3)
+ step = 1;
+ else
+ step = 3;
+ m++; /* cb */
+ }
+ mc--;
+ *xrpnt = 0.0;
+ xrpnt += step;
+ *xrpnt = 0.0;
+ xrpnt += step;
+ /* we could add a little opt. here:
+ * if we finished a band for window 3 or a long band
+ * further bands could copied in a simple loop without a
+ * special 'map' decoding
+ */
+ }
+
+ gr_info->maxband[0] = max[0]+1;
+ gr_info->maxband[1] = max[1]+1;
+ gr_info->maxband[2] = max[2]+1;
+ gr_info->maxbandl = max[3]+1;
+
+ {
+ int rmax = max[0] > max[1] ? max[0] : max[1];
+ rmax = (rmax > max[2] ? rmax : max[2]) + 1;
+ gr_info->maxb = rmax ? iemmp3_shortLimit[sfreq][rmax] : iemmp3_longLimit[sfreq][max[3]+1];
+ }
+
+ }
+ else
+ {
+ /*
+ * decoding with 'long' BandIndex table (block_type != 2)
+ */
+ int *pretab = gr_info->preflag ? iemmp3_pretab1 : iemmp3_pretab2;
+ int i,max = -1;
+ int cb = 0;
+ register int *m = iemmp3_map[sfreq][2];
+ register real v = 0.0;
+ register int mc = 0;
+
+ /*
+ * long hash table values
+ */
+ for(i=0;i<3;i++)
+ {
+ int lp = l[i];
+ struct iemmp3_newHuff *h = iemmp3_ht+gr_info->table_select[i];
+
+ for(;lp;lp--,mc--)
+ {
+ int x,y;
+
+ if(!mc)
+ {
+ mc = *m++;
+ v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift];
+ cb = *m++;
+ }
+ {
+ register short *val = h->table;
+ while((y=*val++)<0)
+ {
+ if (get1bit())
+ val -= y;
+ part2remain--;
+ }
+ x = y >> 4;
+ y &= 0xf;
+ }
+ if (x == 15)
+ {
+ max = cb;
+ part2remain -= h->linbits+1;
+ x += getbits(h->linbits);
+ if(get1bit())
+ *xrpnt++ = -iemmp3_ispow[x] * v;
+ else
+ *xrpnt++ = iemmp3_ispow[x] * v;
+ }
+ else if(x)
+ {
+ max = cb;
+ if(get1bit())
+ *xrpnt++ = -iemmp3_ispow[x] * v;
+ else
+ *xrpnt++ = iemmp3_ispow[x] * v;
+ part2remain--;
+ }
+ else
+ *xrpnt++ = 0.0;
+
+ if (y == 15)
+ {
+ max = cb;
+ part2remain -= h->linbits+1;
+ y += getbits(h->linbits);
+ if(get1bit())
+ *xrpnt++ = -iemmp3_ispow[y] * v;
+ else
+ *xrpnt++ = iemmp3_ispow[y] * v;
+ }
+ else if(y)
+ {
+ max = cb;
+ if(get1bit())
+ *xrpnt++ = -iemmp3_ispow[y] * v;
+ else
+ *xrpnt++ = iemmp3_ispow[y] * v;
+ part2remain--;
+ }
+ else
+ *xrpnt++ = 0.0;
+ }
+ }
+
+ /*
+ * short (count1table) values
+ */
+ for(;l3 && (part2remain > 0);l3--)
+ {
+ struct iemmp3_newHuff *h = iemmp3_htc+gr_info->count1table_select;
+ register short *val = h->table,a;
+
+ while((a=*val++)<0)
+ {
+ part2remain--;
+ if(part2remain < 0)
+ {
+ part2remain++;
+ a = 0;
+ break;
+ }
+ if (get1bit())
+ val -= a;
+ }
+
+ for(i=0;i<4;i++)
+ {
+ if(!(i & 1))
+ {
+ if(!mc)
+ {
+ mc = *m++;
+ cb = *m++;
+ v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift];
+ }
+ mc--;
+ }
+ if ( (a & (0x8>>i)) )
+ {
+ max = cb;
+ part2remain--;
+ if(part2remain < 0)
+ {
+ part2remain++;
+ break;
+ }
+ if(get1bit())
+ *xrpnt++ = -v;
+ else
+ *xrpnt++ = v;
+ }
+ else
+ *xrpnt++ = 0.0;
+ }
+ }
+
+ /*
+ * zero part
+ */
+ for(i=(&xr[SBLIMIT][0]-xrpnt)>>1;i;i--)
+ {
+ *xrpnt++ = 0.0;
+ *xrpnt++ = 0.0;
+ }
+
+ gr_info->maxbandl = max+1;
+ gr_info->maxb = iemmp3_longLimit[sfreq][gr_info->maxbandl];
+ }
+
+ while( part2remain > 16 )
+ {
+ getbits(16); /* Dismiss stuffing Bits */
+ part2remain -= 16;
+ }
+ if(part2remain > 0)
+ getbits(part2remain);
+ else if(part2remain < 0)
+ {
+ post("mpg123: Can't rewind stream by %d bits!\n",-part2remain);
+ return 1; /* -> error */
+ }
+ return 0;
+}
+
+static void III_i_stereo(real xr_buf[2][SBLIMIT][SSLIMIT],int *scalefac,
+ struct iemmp3_gr_info_s *gr_info,int sfreq,int ms_stereo,int lsf)
+{
+ real (*xr)[SBLIMIT*SSLIMIT] = (real (*)[SBLIMIT*SSLIMIT] ) xr_buf;
+ struct iemmp3_bandInfoStruct *bi = &bandInfo[sfreq];
+ real *tab1,*tab2;
+
+ if(lsf)
+ {
+ int p = gr_info->scalefac_compress & 0x1;
+ if(ms_stereo)
+ {
+ tab1 = iemmp3_pow1_2[p]; tab2 = iemmp3_pow2_2[p];
+ }
+ else
+ {
+ tab1 = iemmp3_pow1_1[p]; tab2 = iemmp3_pow2_1[p];
+ }
+ }
+ else
+ {
+ if(ms_stereo)
+ {
+ tab1 = iemmp3_tan1_2; tab2 = iemmp3_tan2_2;
+ }
+ else
+ {
+ tab1 = iemmp3_tan1_1; tab2 = iemmp3_tan2_1;
+ }
+ }
+
+ if (gr_info->block_type == 2)
+ {
+ int lwin,do_l = 0;
+ if( gr_info->mixed_block_flag )
+ do_l = 1;
+
+ for (lwin=0;lwin<3;lwin++) /* process each window */
+ {
+ /* get first band with zero values */
+ int is_p,sb,idx,sfb = gr_info->maxband[lwin]; /* sfb is minimal 3 for mixed mode */
+ if(sfb > 3)
+ do_l = 0;
+
+ for(;sfb<12;sfb++)
+ {
+ is_p = scalefac[sfb*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */
+ if(is_p != 7) {
+ real t1,t2;
+ sb = bi->shortDiff[sfb];
+ idx = bi->shortIdx[sfb] + lwin;
+ t1 = tab1[is_p]; t2 = tab2[is_p];
+ for (; sb > 0; sb--,idx+=3)
+ {
+ real v = xr[0][idx];
+ xr[0][idx] = v * t1;
+ xr[1][idx] = v * t2;
+ }
+ }
+ }
+
+#if 1
+ /* in the original: copy 10 to 11 , here: copy 11 to 12
+ maybe still wrong??? (copy 12 to 13?) */
+ is_p = scalefac[11*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */
+ sb = bi->shortDiff[12];
+ idx = bi->shortIdx[12] + lwin;
+#else
+ is_p = scalefac[10*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */
+ sb = bi->shortDiff[11];
+ idx = bi->shortIdx[11] + lwin;
+#endif
+ if(is_p != 7)
+ {
+ real t1,t2;
+ t1 = tab1[is_p]; t2 = tab2[is_p];
+ for ( ; sb > 0; sb--,idx+=3 )
+ {
+ real v = xr[0][idx];
+ xr[0][idx] = v * t1;
+ xr[1][idx] = v * t2;
+ }
+ }
+ } /* end for(lwin; .. ; . ) */
+
+ if (do_l)
+ {
+ /* also check l-part, if ALL bands in the three windows are 'empty'
+ * and mode = mixed_mode
+ */
+ int sfb = gr_info->maxbandl;
+ int idx = bi->longIdx[sfb];
+
+ for ( ; sfb<8; sfb++ )
+ {
+ int sb = bi->longDiff[sfb];
+ int is_p = scalefac[sfb]; /* scale: 0-15 */
+ if(is_p != 7) {
+ real t1,t2;
+ t1 = tab1[is_p]; t2 = tab2[is_p];
+ for ( ; sb > 0; sb--,idx++)
+ {
+ real v = xr[0][idx];
+ xr[0][idx] = v * t1;
+ xr[1][idx] = v * t2;
+ }
+ }
+ else
+ idx += sb;
+ }
+ }
+ }
+ else /* ((gr_info->block_type != 2)) */
+ {
+ int sfb = gr_info->maxbandl;
+ int is_p,idx = bi->longIdx[sfb];
+ for ( ; sfb<21; sfb++)
+ {
+ int sb = bi->longDiff[sfb];
+ is_p = scalefac[sfb]; /* scale: 0-15 */
+ if(is_p != 7) {
+ real t1,t2;
+ t1 = tab1[is_p]; t2 = tab2[is_p];
+ for ( ; sb > 0; sb--,idx++)
+ {
+ real v = xr[0][idx];
+ xr[0][idx] = v * t1;
+ xr[1][idx] = v * t2;
+ }
+ }
+ else
+ idx += sb;
+ }
+
+ is_p = scalefac[20]; /* copy l-band 20 to l-band 21 */
+ if(is_p != 7)
+ {
+ int sb;
+ real t1 = tab1[is_p],t2 = tab2[is_p];
+
+ for ( sb = bi->longDiff[21]; sb > 0; sb--,idx++ )
+ {
+ real v = xr[0][idx];
+ xr[0][idx] = v * t1;
+ xr[1][idx] = v * t2;
+ }
+ }
+ } /* ... */
+}
+
+
+static void III_antialias(real xr[SBLIMIT][SSLIMIT],struct iemmp3_gr_info_s *gr_info)
+{
+ int sblim;
+
+ if(gr_info->block_type == 2)
+ {
+ if(!gr_info->mixed_block_flag)
+ return;
+ sblim = 1;
+ }
+ else {
+ sblim = gr_info->maxb-1;
+ }
+
+ /* 31 alias-reduction operations between each pair of sub-bands */
+ /* with 8 butterflies between each pair */
+
+ {
+ int sb;
+ real *xr1=(real *) xr[1];
+
+ for(sb=sblim;sb;sb--,xr1+=10)
+ {
+ int ss;
+ real *cs=iemmp3_aa_cs,*ca=iemmp3_aa_ca;
+ real *xr2 = xr1;
+
+ for(ss=7;ss>=0;ss--)
+ { /* upper and lower butterfly inputs */
+ register real bu = *--xr2,bd = *xr1;
+ *xr2 = (bu * (*cs) ) - (bd * (*ca) );
+ *xr1++ = (bd * (*cs++) ) + (bu * (*ca++) );
+ }
+ }
+ }
+}
+
+static void III_hybrid(real fsIn[SBLIMIT][SSLIMIT],real tsOut[SSLIMIT][SBLIMIT],
+ int ch,struct iemmp3_gr_info_s *gr_info)
+{
+ real *tspnt = (real *) tsOut;
+ real (*block)[2][SBLIMIT*SSLIMIT] = iemmp3_gmp->hybrid_block;
+ int *blc = iemmp3_gmp->hybrid_blc;
+ real *rawout1,*rawout2;
+ int bt;
+ unsigned int sb = 0;
+
+ {
+ int b = blc[ch];
+ rawout1=block[b][ch];
+ b=-b+1;
+ rawout2=block[b][ch];
+ blc[ch] = b;
+ }
+
+
+ if(gr_info->mixed_block_flag) {
+ sb = 2;
+ dct36(fsIn[0],rawout1,rawout2,iemmp3_win[0],tspnt);
+ dct36(fsIn[1],rawout1+18,rawout2+18,iemmp3_win1[0],tspnt+1);
+ rawout1 += 36; rawout2 += 36; tspnt += 2;
+ }
+
+ bt = gr_info->block_type;
+ if(bt == 2) {
+ for (; sb<gr_info->maxb; sb+=2,tspnt+=2,rawout1+=36,rawout2+=36) {
+ dct12(fsIn[sb],rawout1,rawout2,iemmp3_win[2],tspnt);
+ dct12(fsIn[sb+1],rawout1+18,rawout2+18,iemmp3_win1[2],tspnt+1);
+ }
+ }
+ else {
+ for (; sb<gr_info->maxb; sb+=2,tspnt+=2,rawout1+=36,rawout2+=36) {
+ dct36(fsIn[sb],rawout1,rawout2,iemmp3_win[bt],tspnt);
+ dct36(fsIn[sb+1],rawout1+18,rawout2+18,iemmp3_win1[bt],tspnt+1);
+ }
+ }
+
+ for(;sb<SBLIMIT;sb++,tspnt++) {
+ int i;
+ for(i=0;i<SSLIMIT;i++) {
+ tspnt[i*SBLIMIT] = *rawout1++;
+ *rawout2++ = 0.0;
+ }
+ }
+}
+
+static void dct64_1(real *out0,real *out1,real *b1,real *b2,real *samples)
+{
+
+ {
+ register real *costab = iemmp3_pnts[0];
+
+ b1[0x00] = samples[0x00] + samples[0x1F];
+ b1[0x1F] = (samples[0x00] - samples[0x1F]) * costab[0x0];
+
+ b1[0x01] = samples[0x01] + samples[0x1E];
+ b1[0x1E] = (samples[0x01] - samples[0x1E]) * costab[0x1];
+
+ b1[0x02] = samples[0x02] + samples[0x1D];
+ b1[0x1D] = (samples[0x02] - samples[0x1D]) * costab[0x2];
+
+ b1[0x03] = samples[0x03] + samples[0x1C];
+ b1[0x1C] = (samples[0x03] - samples[0x1C]) * costab[0x3];
+
+ b1[0x04] = samples[0x04] + samples[0x1B];
+ b1[0x1B] = (samples[0x04] - samples[0x1B]) * costab[0x4];
+
+ b1[0x05] = samples[0x05] + samples[0x1A];
+ b1[0x1A] = (samples[0x05] - samples[0x1A]) * costab[0x5];
+
+ b1[0x06] = samples[0x06] + samples[0x19];
+ b1[0x19] = (samples[0x06] - samples[0x19]) * costab[0x6];
+
+ b1[0x07] = samples[0x07] + samples[0x18];
+ b1[0x18] = (samples[0x07] - samples[0x18]) * costab[0x7];
+
+ b1[0x08] = samples[0x08] + samples[0x17];
+ b1[0x17] = (samples[0x08] - samples[0x17]) * costab[0x8];
+
+ b1[0x09] = samples[0x09] + samples[0x16];
+ b1[0x16] = (samples[0x09] - samples[0x16]) * costab[0x9];
+
+ b1[0x0A] = samples[0x0A] + samples[0x15];
+ b1[0x15] = (samples[0x0A] - samples[0x15]) * costab[0xA];
+
+ b1[0x0B] = samples[0x0B] + samples[0x14];
+ b1[0x14] = (samples[0x0B] - samples[0x14]) * costab[0xB];
+
+ b1[0x0C] = samples[0x0C] + samples[0x13];
+ b1[0x13] = (samples[0x0C] - samples[0x13]) * costab[0xC];
+
+ b1[0x0D] = samples[0x0D] + samples[0x12];
+ b1[0x12] = (samples[0x0D] - samples[0x12]) * costab[0xD];
+
+ b1[0x0E] = samples[0x0E] + samples[0x11];
+ b1[0x11] = (samples[0x0E] - samples[0x11]) * costab[0xE];
+
+ b1[0x0F] = samples[0x0F] + samples[0x10];
+ b1[0x10] = (samples[0x0F] - samples[0x10]) * costab[0xF];
+ }
+
+
+ {
+ register real *costab = iemmp3_pnts[1];
+
+ b2[0x00] = b1[0x00] + b1[0x0F];
+ b2[0x0F] = (b1[0x00] - b1[0x0F]) * costab[0];
+ b2[0x01] = b1[0x01] + b1[0x0E];
+ b2[0x0E] = (b1[0x01] - b1[0x0E]) * costab[1];
+ b2[0x02] = b1[0x02] + b1[0x0D];
+ b2[0x0D] = (b1[0x02] - b1[0x0D]) * costab[2];
+ b2[0x03] = b1[0x03] + b1[0x0C];
+ b2[0x0C] = (b1[0x03] - b1[0x0C]) * costab[3];
+ b2[0x04] = b1[0x04] + b1[0x0B];
+ b2[0x0B] = (b1[0x04] - b1[0x0B]) * costab[4];
+ b2[0x05] = b1[0x05] + b1[0x0A];
+ b2[0x0A] = (b1[0x05] - b1[0x0A]) * costab[5];
+ b2[0x06] = b1[0x06] + b1[0x09];
+ b2[0x09] = (b1[0x06] - b1[0x09]) * costab[6];
+ b2[0x07] = b1[0x07] + b1[0x08];
+ b2[0x08] = (b1[0x07] - b1[0x08]) * costab[7];
+
+ b2[0x10] = b1[0x10] + b1[0x1F];
+ b2[0x1F] = (b1[0x1F] - b1[0x10]) * costab[0];
+ b2[0x11] = b1[0x11] + b1[0x1E];
+ b2[0x1E] = (b1[0x1E] - b1[0x11]) * costab[1];
+ b2[0x12] = b1[0x12] + b1[0x1D];
+ b2[0x1D] = (b1[0x1D] - b1[0x12]) * costab[2];
+ b2[0x13] = b1[0x13] + b1[0x1C];
+ b2[0x1C] = (b1[0x1C] - b1[0x13]) * costab[3];
+ b2[0x14] = b1[0x14] + b1[0x1B];
+ b2[0x1B] = (b1[0x1B] - b1[0x14]) * costab[4];
+ b2[0x15] = b1[0x15] + b1[0x1A];
+ b2[0x1A] = (b1[0x1A] - b1[0x15]) * costab[5];
+ b2[0x16] = b1[0x16] + b1[0x19];
+ b2[0x19] = (b1[0x19] - b1[0x16]) * costab[6];
+ b2[0x17] = b1[0x17] + b1[0x18];
+ b2[0x18] = (b1[0x18] - b1[0x17]) * costab[7];
+ }
+
+ {
+ register real *costab = iemmp3_pnts[2];
+
+ b1[0x00] = b2[0x00] + b2[0x07];
+ b1[0x07] = (b2[0x00] - b2[0x07]) * costab[0];
+ b1[0x01] = b2[0x01] + b2[0x06];
+ b1[0x06] = (b2[0x01] - b2[0x06]) * costab[1];
+ b1[0x02] = b2[0x02] + b2[0x05];
+ b1[0x05] = (b2[0x02] - b2[0x05]) * costab[2];
+ b1[0x03] = b2[0x03] + b2[0x04];
+ b1[0x04] = (b2[0x03] - b2[0x04]) * costab[3];
+
+ b1[0x08] = b2[0x08] + b2[0x0F];
+ b1[0x0F] = (b2[0x0F] - b2[0x08]) * costab[0];
+ b1[0x09] = b2[0x09] + b2[0x0E];
+ b1[0x0E] = (b2[0x0E] - b2[0x09]) * costab[1];
+ b1[0x0A] = b2[0x0A] + b2[0x0D];
+ b1[0x0D] = (b2[0x0D] - b2[0x0A]) * costab[2];
+ b1[0x0B] = b2[0x0B] + b2[0x0C];
+ b1[0x0C] = (b2[0x0C] - b2[0x0B]) * costab[3];
+
+ b1[0x10] = b2[0x10] + b2[0x17];
+ b1[0x17] = (b2[0x10] - b2[0x17]) * costab[0];
+ b1[0x11] = b2[0x11] + b2[0x16];
+ b1[0x16] = (b2[0x11] - b2[0x16]) * costab[1];
+ b1[0x12] = b2[0x12] + b2[0x15];
+ b1[0x15] = (b2[0x12] - b2[0x15]) * costab[2];
+ b1[0x13] = b2[0x13] + b2[0x14];
+ b1[0x14] = (b2[0x13] - b2[0x14]) * costab[3];
+
+ b1[0x18] = b2[0x18] + b2[0x1F];
+ b1[0x1F] = (b2[0x1F] - b2[0x18]) * costab[0];
+ b1[0x19] = b2[0x19] + b2[0x1E];
+ b1[0x1E] = (b2[0x1E] - b2[0x19]) * costab[1];
+ b1[0x1A] = b2[0x1A] + b2[0x1D];
+ b1[0x1D] = (b2[0x1D] - b2[0x1A]) * costab[2];
+ b1[0x1B] = b2[0x1B] + b2[0x1C];
+ b1[0x1C] = (b2[0x1C] - b2[0x1B]) * costab[3];
+ }
+
+ {
+ register real const cos0 = iemmp3_pnts[3][0];
+ register real const cos1 = iemmp3_pnts[3][1];
+
+ b2[0x00] = b1[0x00] + b1[0x03];
+ b2[0x03] = (b1[0x00] - b1[0x03]) * cos0;
+ b2[0x01] = b1[0x01] + b1[0x02];
+ b2[0x02] = (b1[0x01] - b1[0x02]) * cos1;
+
+ b2[0x04] = b1[0x04] + b1[0x07];
+ b2[0x07] = (b1[0x07] - b1[0x04]) * cos0;
+ b2[0x05] = b1[0x05] + b1[0x06];
+ b2[0x06] = (b1[0x06] - b1[0x05]) * cos1;
+
+ b2[0x08] = b1[0x08] + b1[0x0B];
+ b2[0x0B] = (b1[0x08] - b1[0x0B]) * cos0;
+ b2[0x09] = b1[0x09] + b1[0x0A];
+ b2[0x0A] = (b1[0x09] - b1[0x0A]) * cos1;
+
+ b2[0x0C] = b1[0x0C] + b1[0x0F];
+ b2[0x0F] = (b1[0x0F] - b1[0x0C]) * cos0;
+ b2[0x0D] = b1[0x0D] + b1[0x0E];
+ b2[0x0E] = (b1[0x0E] - b1[0x0D]) * cos1;
+
+ b2[0x10] = b1[0x10] + b1[0x13];
+ b2[0x13] = (b1[0x10] - b1[0x13]) * cos0;
+ b2[0x11] = b1[0x11] + b1[0x12];
+ b2[0x12] = (b1[0x11] - b1[0x12]) * cos1;
+
+ b2[0x14] = b1[0x14] + b1[0x17];
+ b2[0x17] = (b1[0x17] - b1[0x14]) * cos0;
+ b2[0x15] = b1[0x15] + b1[0x16];
+ b2[0x16] = (b1[0x16] - b1[0x15]) * cos1;
+
+ b2[0x18] = b1[0x18] + b1[0x1B];
+ b2[0x1B] = (b1[0x18] - b1[0x1B]) * cos0;
+ b2[0x19] = b1[0x19] + b1[0x1A];
+ b2[0x1A] = (b1[0x19] - b1[0x1A]) * cos1;
+
+ b2[0x1C] = b1[0x1C] + b1[0x1F];
+ b2[0x1F] = (b1[0x1F] - b1[0x1C]) * cos0;
+ b2[0x1D] = b1[0x1D] + b1[0x1E];
+ b2[0x1E] = (b1[0x1E] - b1[0x1D]) * cos1;
+ }
+
+ {
+ register real const cos0 = iemmp3_pnts[4][0];
+
+ b1[0x00] = b2[0x00] + b2[0x01];
+ b1[0x01] = (b2[0x00] - b2[0x01]) * cos0;
+ b1[0x02] = b2[0x02] + b2[0x03];
+ b1[0x03] = (b2[0x03] - b2[0x02]) * cos0;
+ b1[0x02] += b1[0x03];
+
+ b1[0x04] = b2[0x04] + b2[0x05];
+ b1[0x05] = (b2[0x04] - b2[0x05]) * cos0;
+ b1[0x06] = b2[0x06] + b2[0x07];
+ b1[0x07] = (b2[0x07] - b2[0x06]) * cos0;
+ b1[0x06] += b1[0x07];
+ b1[0x04] += b1[0x06];
+ b1[0x06] += b1[0x05];
+ b1[0x05] += b1[0x07];
+
+ b1[0x08] = b2[0x08] + b2[0x09];
+ b1[0x09] = (b2[0x08] - b2[0x09]) * cos0;
+ b1[0x0A] = b2[0x0A] + b2[0x0B];
+ b1[0x0B] = (b2[0x0B] - b2[0x0A]) * cos0;
+ b1[0x0A] += b1[0x0B];
+
+ b1[0x0C] = b2[0x0C] + b2[0x0D];
+ b1[0x0D] = (b2[0x0C] - b2[0x0D]) * cos0;
+ b1[0x0E] = b2[0x0E] + b2[0x0F];
+ b1[0x0F] = (b2[0x0F] - b2[0x0E]) * cos0;
+ b1[0x0E] += b1[0x0F];
+ b1[0x0C] += b1[0x0E];
+ b1[0x0E] += b1[0x0D];
+ b1[0x0D] += b1[0x0F];
+
+ b1[0x10] = b2[0x10] + b2[0x11];
+ b1[0x11] = (b2[0x10] - b2[0x11]) * cos0;
+ b1[0x12] = b2[0x12] + b2[0x13];
+ b1[0x13] = (b2[0x13] - b2[0x12]) * cos0;
+ b1[0x12] += b1[0x13];
+
+ b1[0x14] = b2[0x14] + b2[0x15];
+ b1[0x15] = (b2[0x14] - b2[0x15]) * cos0;
+ b1[0x16] = b2[0x16] + b2[0x17];
+ b1[0x17] = (b2[0x17] - b2[0x16]) * cos0;
+ b1[0x16] += b1[0x17];
+ b1[0x14] += b1[0x16];
+ b1[0x16] += b1[0x15];
+ b1[0x15] += b1[0x17];
+
+ b1[0x18] = b2[0x18] + b2[0x19];
+ b1[0x19] = (b2[0x18] - b2[0x19]) * cos0;
+ b1[0x1A] = b2[0x1A] + b2[0x1B];
+ b1[0x1B] = (b2[0x1B] - b2[0x1A]) * cos0;
+ b1[0x1A] += b1[0x1B];
+
+ b1[0x1C] = b2[0x1C] + b2[0x1D];
+ b1[0x1D] = (b2[0x1C] - b2[0x1D]) * cos0;
+ b1[0x1E] = b2[0x1E] + b2[0x1F];
+ b1[0x1F] = (b2[0x1F] - b2[0x1E]) * cos0;
+ b1[0x1E] += b1[0x1F];
+ b1[0x1C] += b1[0x1E];
+ b1[0x1E] += b1[0x1D];
+ b1[0x1D] += b1[0x1F];
+ }
+
+ out0[0x10*16] = b1[0x00];
+ out0[0x10*12] = b1[0x04];
+ out0[0x10* 8] = b1[0x02];
+ out0[0x10* 4] = b1[0x06];
+ out0[0x10* 0] = b1[0x01];
+ out1[0x10* 0] = b1[0x01];
+ out1[0x10* 4] = b1[0x05];
+ out1[0x10* 8] = b1[0x03];
+ out1[0x10*12] = b1[0x07];
+
+ b1[0x08] += b1[0x0C];
+ out0[0x10*14] = b1[0x08];
+ b1[0x0C] += b1[0x0a];
+ out0[0x10*10] = b1[0x0C];
+ b1[0x0A] += b1[0x0E];
+ out0[0x10* 6] = b1[0x0A];
+ b1[0x0E] += b1[0x09];
+ out0[0x10* 2] = b1[0x0E];
+ b1[0x09] += b1[0x0D];
+ out1[0x10* 2] = b1[0x09];
+ b1[0x0D] += b1[0x0B];
+ out1[0x10* 6] = b1[0x0D];
+ b1[0x0B] += b1[0x0F];
+ out1[0x10*10] = b1[0x0B];
+ out1[0x10*14] = b1[0x0F];
+
+ b1[0x18] += b1[0x1C];
+ out0[0x10*15] = b1[0x10] + b1[0x18];
+ out0[0x10*13] = b1[0x18] + b1[0x14];
+ b1[0x1C] += b1[0x1a];
+ out0[0x10*11] = b1[0x14] + b1[0x1C];
+ out0[0x10* 9] = b1[0x1C] + b1[0x12];
+ b1[0x1A] += b1[0x1E];
+ out0[0x10* 7] = b1[0x12] + b1[0x1A];
+ out0[0x10* 5] = b1[0x1A] + b1[0x16];
+ b1[0x1E] += b1[0x19];
+ out0[0x10* 3] = b1[0x16] + b1[0x1E];
+ out0[0x10* 1] = b1[0x1E] + b1[0x11];
+ b1[0x19] += b1[0x1D];
+ out1[0x10* 1] = b1[0x11] + b1[0x19];
+ out1[0x10* 3] = b1[0x19] + b1[0x15];
+ b1[0x1D] += b1[0x1B];
+ out1[0x10* 5] = b1[0x15] + b1[0x1D];
+ out1[0x10* 7] = b1[0x1D] + b1[0x13];
+ b1[0x1B] += b1[0x1F];
+ out1[0x10* 9] = b1[0x13] + b1[0x1B];
+ out1[0x10*11] = b1[0x1B] + b1[0x17];
+ out1[0x10*13] = b1[0x17] + b1[0x1F];
+ out1[0x10*15] = b1[0x1F];
+}
+
+/*
+ * the call via dct64 is a trick to force GCC to use
+ * (new) registers for the b1,b2 pointer to the bufs[xx] field
+ */
+void dct64(real *a,real *b,real *c)
+{
+ real bufs[0x40];
+ dct64_1(a,b,bufs,bufs+0x20,c);
+}
+
+static void dct36(real *inbuf,real *o1,real *o2,real *wintab,real *tsbuf)
+{
+ {
+ register real *in = inbuf;
+
+ in[17]+=in[16]; in[16]+=in[15]; in[15]+=in[14];
+ in[14]+=in[13]; in[13]+=in[12]; in[12]+=in[11];
+ in[11]+=in[10]; in[10]+=in[9]; in[9] +=in[8];
+ in[8] +=in[7]; in[7] +=in[6]; in[6] +=in[5];
+ in[5] +=in[4]; in[4] +=in[3]; in[3] +=in[2];
+ in[2] +=in[1]; in[1] +=in[0];
+
+ in[17]+=in[15]; in[15]+=in[13]; in[13]+=in[11]; in[11]+=in[9];
+ in[9] +=in[7]; in[7] +=in[5]; in[5] +=in[3]; in[3] +=in[1];
+
+
+ {
+
+#define MACRO0(v) { \
+ real tmp; \
+ out2[9+(v)] = (tmp = sum0 + sum1) * w[27+(v)]; \
+ out2[8-(v)] = tmp * w[26-(v)]; } \
+ sum0 -= sum1; \
+ ts[SBLIMIT*(8-(v))] = out1[8-(v)] + sum0 * w[8-(v)]; \
+ ts[SBLIMIT*(9+(v))] = out1[9+(v)] + sum0 * w[9+(v)];
+#define MACRO1(v) { \
+ real sum0,sum1; \
+ sum0 = tmp1a + tmp2a; \
+ sum1 = (tmp1b + tmp2b) * iemmp3_tfcos36[(v)]; \
+ MACRO0(v); }
+#define MACRO2(v) { \
+ real sum0,sum1; \
+ sum0 = tmp2a - tmp1a; \
+ sum1 = (tmp2b - tmp1b) * iemmp3_tfcos36[(v)]; \
+ MACRO0(v); }
+
+ register const real *c = iemmp3_COS9;
+ register real *out2 = o2;
+ register real *w = wintab;
+ register real *out1 = o1;
+ register real *ts = tsbuf;
+
+ real ta33,ta66,tb33,tb66;
+
+ ta33 = in[2*3+0] * c[3];
+ ta66 = in[2*6+0] * c[6];
+ tb33 = in[2*3+1] * c[3];
+ tb66 = in[2*6+1] * c[6];
+
+ {
+ real tmp1a,tmp2a,tmp1b,tmp2b;
+ tmp1a = in[2*1+0] * c[1] + ta33 + in[2*5+0] * c[5] + in[2*7+0] * c[7];
+ tmp1b = in[2*1+1] * c[1] + tb33 + in[2*5+1] * c[5] + in[2*7+1] * c[7];
+ tmp2a = in[2*0+0] + in[2*2+0] * c[2] + in[2*4+0] * c[4] + ta66 + in[2*8+0] * c[8];
+ tmp2b = in[2*0+1] + in[2*2+1] * c[2] + in[2*4+1] * c[4] + tb66 + in[2*8+1] * c[8];
+
+ MACRO1(0);
+ MACRO2(8);
+ }
+
+ {
+ real tmp1a,tmp2a,tmp1b,tmp2b;
+ tmp1a = ( in[2*1+0] - in[2*5+0] - in[2*7+0] ) * c[3];
+ tmp1b = ( in[2*1+1] - in[2*5+1] - in[2*7+1] ) * c[3];
+ tmp2a = ( in[2*2+0] - in[2*4+0] - in[2*8+0] ) * c[6] - in[2*6+0] + in[2*0+0];
+ tmp2b = ( in[2*2+1] - in[2*4+1] - in[2*8+1] ) * c[6] - in[2*6+1] + in[2*0+1];
+
+ MACRO1(1);
+ MACRO2(7);
+ }
+
+ {
+ real tmp1a,tmp2a,tmp1b,tmp2b;
+ tmp1a = in[2*1+0] * c[5] - ta33 - in[2*5+0] * c[7] + in[2*7+0] * c[1];
+ tmp1b = in[2*1+1] * c[5] - tb33 - in[2*5+1] * c[7] + in[2*7+1] * c[1];
+ tmp2a = in[2*0+0] - in[2*2+0] * c[8] - in[2*4+0] * c[2] + ta66 + in[2*8+0] * c[4];
+ tmp2b = in[2*0+1] - in[2*2+1] * c[8] - in[2*4+1] * c[2] + tb66 + in[2*8+1] * c[4];
+
+ MACRO1(2);
+ MACRO2(6);
+ }
+
+ {
+ real tmp1a,tmp2a,tmp1b,tmp2b;
+ tmp1a = in[2*1+0] * c[7] - ta33 + in[2*5+0] * c[1] - in[2*7+0] * c[5];
+ tmp1b = in[2*1+1] * c[7] - tb33 + in[2*5+1] * c[1] - in[2*7+1] * c[5];
+ tmp2a = in[2*0+0] - in[2*2+0] * c[4] + in[2*4+0] * c[8] + ta66 - in[2*8+0] * c[2];
+ tmp2b = in[2*0+1] - in[2*2+1] * c[4] + in[2*4+1] * c[8] + tb66 - in[2*8+1] * c[2];
+
+ MACRO1(3);
+ MACRO2(5);
+ }
+
+ {
+ real sum0,sum1;
+ sum0 = in[2*0+0] - in[2*2+0] + in[2*4+0] - in[2*6+0] + in[2*8+0];
+ sum1 = (in[2*0+1] - in[2*2+1] + in[2*4+1] - in[2*6+1] + in[2*8+1] ) * iemmp3_tfcos36[4];
+ MACRO0(4);
+ }
+ }
+
+ }
+}
+
+/*
+ * new DCT12
+ */
+static void dct12(real *in,real *rawout1,real *rawout2,register real *wi,register real *ts)
+{
+#define DCT12_PART1 \
+ in5 = in[5*3]; \
+ in5 += (in4 = in[4*3]); \
+ in4 += (in3 = in[3*3]); \
+ in3 += (in2 = in[2*3]); \
+ in2 += (in1 = in[1*3]); \
+ in1 += (in0 = in[0*3]); \
+ \
+ in5 += in3; in3 += in1; \
+ \
+ in2 *= iemmp3_COS6_1; \
+ in3 *= iemmp3_COS6_1; \
+
+#define DCT12_PART2 \
+ in0 += in4 * iemmp3_COS6_2; \
+ \
+ in4 = in0 + in2; \
+ in0 -= in2; \
+ \
+ in1 += in5 * iemmp3_COS6_2; \
+ \
+ in5 = (in1 + in3) * iemmp3_tfcos12[0]; \
+ in1 = (in1 - in3) * iemmp3_tfcos12[2]; \
+ \
+ in3 = in4 + in5; \
+ in4 -= in5; \
+ \
+ in2 = in0 + in1; \
+ in0 -= in1;
+
+
+ {
+ real in0,in1,in2,in3,in4,in5;
+ register real *out1 = rawout1;
+ ts[SBLIMIT*0] = out1[0]; ts[SBLIMIT*1] = out1[1]; ts[SBLIMIT*2] = out1[2];
+ ts[SBLIMIT*3] = out1[3]; ts[SBLIMIT*4] = out1[4]; ts[SBLIMIT*5] = out1[5];
+
+ DCT12_PART1
+
+ {
+ real tmp0,tmp1 = (in0 - in4);
+ {
+ real tmp2 = (in1 - in5) * iemmp3_tfcos12[1];
+ tmp0 = tmp1 + tmp2;
+ tmp1 -= tmp2;
+ }
+ ts[(17-1)*SBLIMIT] = out1[17-1] + tmp0 * wi[11-1];
+ ts[(12+1)*SBLIMIT] = out1[12+1] + tmp0 * wi[6+1];
+ ts[(6 +1)*SBLIMIT] = out1[6 +1] + tmp1 * wi[1];
+ ts[(11-1)*SBLIMIT] = out1[11-1] + tmp1 * wi[5-1];
+ }
+
+ DCT12_PART2
+
+ ts[(17-0)*SBLIMIT] = out1[17-0] + in2 * wi[11-0];
+ ts[(12+0)*SBLIMIT] = out1[12+0] + in2 * wi[6+0];
+ ts[(12+2)*SBLIMIT] = out1[12+2] + in3 * wi[6+2];
+ ts[(17-2)*SBLIMIT] = out1[17-2] + in3 * wi[11-2];
+
+ ts[(6+0)*SBLIMIT] = out1[6+0] + in0 * wi[0];
+ ts[(11-0)*SBLIMIT] = out1[11-0] + in0 * wi[5-0];
+ ts[(6+2)*SBLIMIT] = out1[6+2] + in4 * wi[2];
+ ts[(11-2)*SBLIMIT] = out1[11-2] + in4 * wi[5-2];
+ }
+
+ in++;
+
+ {
+ real in0,in1,in2,in3,in4,in5;
+ register real *out2 = rawout2;
+
+ DCT12_PART1
+
+ {
+ real tmp0,tmp1 = (in0 - in4);
+ {
+ real tmp2 = (in1 - in5) * iemmp3_tfcos12[1];
+ tmp0 = tmp1 + tmp2;
+ tmp1 -= tmp2;
+ }
+ out2[5-1] = tmp0 * wi[11-1];
+ out2[0+1] = tmp0 * wi[6+1];
+ ts[(12+1)*SBLIMIT] += tmp1 * wi[1];
+ ts[(17-1)*SBLIMIT] += tmp1 * wi[5-1];
+ }
+
+ DCT12_PART2
+
+ out2[5-0] = in2 * wi[11-0];
+ out2[0+0] = in2 * wi[6+0];
+ out2[0+2] = in3 * wi[6+2];
+ out2[5-2] = in3 * wi[11-2];
+
+ ts[(12+0)*SBLIMIT] += in0 * wi[0];
+ ts[(17-0)*SBLIMIT] += in0 * wi[5-0];
+ ts[(12+2)*SBLIMIT] += in4 * wi[2];
+ ts[(17-2)*SBLIMIT] += in4 * wi[5-2];
+ }
+
+ in++;
+
+ {
+ real in0,in1,in2,in3,in4,in5;
+ register real *out2 = rawout2;
+ out2[12]=out2[13]=out2[14]=out2[15]=out2[16]=out2[17]=0.0;
+
+ DCT12_PART1
+
+ {
+ real tmp0,tmp1 = (in0 - in4);
+ {
+ real tmp2 = (in1 - in5) * iemmp3_tfcos12[1];
+ tmp0 = tmp1 + tmp2;
+ tmp1 -= tmp2;
+ }
+ out2[11-1] = tmp0 * wi[11-1];
+ out2[6 +1] = tmp0 * wi[6+1];
+ out2[0+1] += tmp1 * wi[1];
+ out2[5-1] += tmp1 * wi[5-1];
+ }
+
+ DCT12_PART2
+
+ out2[11-0] = in2 * wi[11-0];
+ out2[6 +0] = in2 * wi[6+0];
+ out2[6 +2] = in3 * wi[6+2];
+ out2[11-2] = in3 * wi[11-2];
+
+ out2[0+0] += in0 * wi[0];
+ out2[5-0] += in0 * wi[5-0];
+ out2[0+2] += in4 * wi[2];
+ out2[5-2] += in4 * wi[5-2];
+ }
+}
+
+static int synth_1to1_mono(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[64];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_1to1(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<32;i++)
+ {
+ *( (short *) samples) = *tmp1;
+ samples += 2;
+ tmp1 += 2;
+ }
+ *pnt += 64;
+
+ return ret;
+}
+
+
+static int synth_1to1(real *bandPtr,int channel,unsigned char *out,int *pnt)
+{
+ static const int step = 2;
+ int bo;
+ short *samples = (short *) (out + *pnt);
+
+ real *b0,(*buf)[0x110];
+ int clip = 0;
+ int bo1;
+
+ bo = iemmp3_gmp->synth_bo;
+
+ if(!channel)
+ {
+ bo--;
+ bo &= 0xf;
+ buf = iemmp3_gmp->synth_buffs[0];
+ }
+ else
+ {
+ samples++;
+ buf = iemmp3_gmp->synth_buffs[1];
+ }
+
+ if(bo & 0x1)
+ {
+ b0 = buf[0];
+ bo1 = bo;
+ dct64(buf[1]+((bo+1)&0xf),buf[0]+bo,bandPtr);
+ }
+ else
+ {
+ b0 = buf[1];
+ bo1 = bo+1;
+ dct64(buf[0]+bo,buf[1]+bo+1,bandPtr);
+ }
+
+ iemmp3_gmp->synth_bo = bo;
+
+ {
+ register int j;
+ real *window = iemmp3_decwin + 16 - bo1;
+
+ for (j=16;j;j--,b0+=0x10,window+=0x20,samples+=step)
+ {
+ real sum;
+ sum = window[0x0] * b0[0x0];
+ sum -= window[0x1] * b0[0x1];
+ sum += window[0x2] * b0[0x2];
+ sum -= window[0x3] * b0[0x3];
+ sum += window[0x4] * b0[0x4];
+ sum -= window[0x5] * b0[0x5];
+ sum += window[0x6] * b0[0x6];
+ sum -= window[0x7] * b0[0x7];
+ sum += window[0x8] * b0[0x8];
+ sum -= window[0x9] * b0[0x9];
+ sum += window[0xA] * b0[0xA];
+ sum -= window[0xB] * b0[0xB];
+ sum += window[0xC] * b0[0xC];
+ sum -= window[0xD] * b0[0xD];
+ sum += window[0xE] * b0[0xE];
+ sum -= window[0xF] * b0[0xF];
+ WRITE_SAMPLE(samples,sum,clip);
+ }
+
+ {
+ real sum;
+ sum = window[0x0] * b0[0x0];
+ sum += window[0x2] * b0[0x2];
+ sum += window[0x4] * b0[0x4];
+ sum += window[0x6] * b0[0x6];
+ sum += window[0x8] * b0[0x8];
+ sum += window[0xA] * b0[0xA];
+ sum += window[0xC] * b0[0xC];
+ sum += window[0xE] * b0[0xE];
+ WRITE_SAMPLE(samples,sum,clip);
+ b0-=0x10,window-=0x20,samples+=step;
+ }
+ window += bo1<<1;
+
+ for (j=15;j;j--,b0-=0x10,window-=0x20,samples+=step)
+ {
+ real sum;
+ sum = -window[-0x1] * b0[0x0];
+ sum -= window[-0x2] * b0[0x1];
+ sum -= window[-0x3] * b0[0x2];
+ sum -= window[-0x4] * b0[0x3];
+ sum -= window[-0x5] * b0[0x4];
+ sum -= window[-0x6] * b0[0x5];
+ sum -= window[-0x7] * b0[0x6];
+ sum -= window[-0x8] * b0[0x7];
+ sum -= window[-0x9] * b0[0x8];
+ sum -= window[-0xA] * b0[0x9];
+ sum -= window[-0xB] * b0[0xA];
+ sum -= window[-0xC] * b0[0xB];
+ sum -= window[-0xD] * b0[0xC];
+ sum -= window[-0xE] * b0[0xD];
+ sum -= window[-0xF] * b0[0xE];
+ sum -= window[-0x0] * b0[0xF];
+ WRITE_SAMPLE(samples,sum,clip);
+ }
+ }
+ *pnt += 128;
+
+ return clip;
+}
+
+
+
+static void *sigmp3play_new(void)
+{
+ char *vec;
+ t_sigmp3play *x = (t_sigmp3play *)pd_new(sigmp3play_class);
+
+ x->file_is_open = 0;
+ x->play_state = 0;
+ x->mp3_encode_size = 0;
+ x->mp3_out_index = 0;
+ x->file_block_num = 0;
+ x->file_remain = 0;
+ x->file_size = 0;
+ x->mp3_ch = 1;
+ x->mp3_sr = 44100;
+ x->obj_sr = 44100;
+ x->obj_n = 1;
+ x->samp_per_frame = 1152;
+ x->mp3_byterate = 11;
+ x->down = 0;
+ x->scale = 1.0/32768.0;
+ x->offset_sec = 0.0;
+ x->fh = (FILE *)0L;
+ x->mp3inbuf = (char *)getzbytes(MY_MP3_MALLOC_IN_SIZE);
+ x->mp3outbuf = (char *)getzbytes(MY_MP3_MALLOC_OUT_SIZE);
+ x->filename = (char *)getzbytes(MY_MP3_MALLOC_FN);
+ x->begframeseek = (int *)0;
+ x->curframeseek = 0;
+ x->maxframeseek = 0;
+ x->frame_counter = 0;
+ x->time1_bang0_handle = 0;
+ x->time_factor = 0.0;
+ vec = x->filename;
+ *vec = 0;
+ InitMP3(&(x->mp));
+ x->mp_is_init = 1;
+ x->x_clock = clock_new(x, (t_method)sigmp3play_tick);
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_floatout = outlet_new(&x->x_obj, &s_float);
+ x->x_bangout = outlet_new(&x->x_obj, &s_bang);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
+ x->x_canvas = canvas_getcurrent();
+ return (x);
+}
+
+static void sigmp3play_cleanup(t_sigmp3play *x)
+{
+ x->file_is_open = 0;
+ fclose(x->fh);
+ x->play_state = 0;
+ x->mp3_out_index = 0;
+ x->mp_is_init = 0;
+ ExitMP3(&(x->mp));
+ x->time1_bang0_handle = 0;
+ clock_delay(x->x_clock, 0);
+}
+
+static int sigmp3play_read_frame_length_first(t_sigmp3play *x, int *frsz)
+{
+ int framesize, lsf, bitrate_index, sampling_frequency, padding, mpeg25, lay, ret=MP3_EX;
+ int version, syncword;
+ unsigned long head;
+ unsigned char chead;
+
+ *frsz = 0;
+ if((x->file_size) >= 4)
+ {
+ fread(&chead, 1, sizeof(char), x->fh);
+ head = (unsigned int)chead;
+ fread(&chead, 1, sizeof(char), x->fh);
+ head <<= 8;
+ head |= (unsigned int)chead;
+ fread(&chead, 1, sizeof(char), x->fh);
+ head <<= 8;
+ head |= (unsigned int)chead;
+ fread(&chead, 1, sizeof(char), x->fh);
+ head <<= 8;
+ head |= (unsigned int)chead;
+ syncword = (head >> 20) & 0x0fff;
+ version = ((head >> 19) & 0x01) ? 0 : 1;
+ if((syncword & 0x01) == 0)
+ version = 2;
+ if(version == 0)
+ x->samp_per_frame = 1152;
+ else
+ x->samp_per_frame = 576;
+
+ if(head & (1<<20))
+ {
+ lsf = (head & (1<<19)) ? 0x0 : 0x1;
+ mpeg25 = 0;
+ }
+ else
+ {
+ lsf = 1;
+ mpeg25 = 1;
+ }
+ lay = 4-((head>>17)&3);
+ if(((head>>10)&0x3) == 0x3)
+ {
+ post("Stream error");
+ return(MP3_EX);
+ }
+ if(mpeg25)
+ sampling_frequency = 6 + ((head>>10)&0x3);
+ else
+ sampling_frequency = ((head>>10)&0x3) + (lsf*3);
+ x->mp3_sr = (int)iemmp3_freqs[sampling_frequency];
+ if(mpeg25)
+ bitrate_index = ((head>>12)&0xf);
+ bitrate_index = ((head>>12)&0xf);
+ padding = ((head>>9)&0x1);
+ if(!bitrate_index)
+ {
+ post("Free format not supported.\n");
+ return(MP3_EX);
+ }
+ switch(lay)
+ {
+ case 1:
+ post("Layer I not supported!\n");
+ break;
+ case 2:
+ post("Layer II not supported!\n");
+ break;
+ case 3:
+ framesize = iemmp3_tabsel_123[lsf][2][bitrate_index]*144000;
+ framesize /= (iemmp3_freqs[sampling_frequency] << lsf);
+ framesize += padding;
+ *frsz = framesize;
+ ret = 0;
+ break;
+ default:
+ post("Sorry, unknown layer type.\n");
+ break;
+ }
+ return(ret);
+ }
+ else
+ {
+ return(1);
+ }
+}
+
+static int sigmp3play_read_frame_length_next(t_sigmp3play *x, int *frsz, int frame_counter)
+{
+ int framesize, lsf, bitrate_index, sampling_frequency, *begframeseek=x->begframeseek;
+ unsigned long head;
+ unsigned char chead;
+
+ *frsz = 0;
+ if(begframeseek[frame_counter] < ((x->file_size) - 4))
+ {
+ fread(&chead, 1, sizeof(char), x->fh);
+ head = (unsigned int)chead;
+ fread(&chead, 1, sizeof(char), x->fh);
+ head <<= 8;
+ head |= (unsigned int)chead;
+ fread(&chead, 1, sizeof(char), x->fh);
+ head <<= 8;
+ head |= (unsigned int)chead;
+ fread(&chead, 1, sizeof(char), x->fh);
+ head <<= 8;
+ head |= (unsigned int)chead;
+ if(head & (1<<20))
+ {
+ lsf = (head & (1<<19)) ? 0x0 : 0x1;
+ sampling_frequency = ((head>>10)&0x3) + (lsf*3);
+ }
+ else
+ {
+ lsf = 1;
+ sampling_frequency = 6 + ((head>>10)&0x3);
+ }
+ bitrate_index = ((head>>12)&0xf);
+ framesize = iemmp3_tabsel_123[lsf][2][bitrate_index]*144000;
+ framesize /= (iemmp3_freqs[sampling_frequency] << lsf);
+ framesize += ((head>>9)&0x1);
+ *frsz = framesize;
+ return(0);
+ }
+ else
+ return(1);
+}
+
+static int sigmp3play_calc_frames(t_sigmp3play *x)
+{
+ int *begframeseek=x->begframeseek, i, maxframeseek, framesize, frame_counter;
+ float length;
+
+ fseek(x->fh,0,SEEK_SET);
+ if(!sigmp3play_read_frame_length_first(x, &framesize))
+ {
+ if(framesize <= 0)
+ {
+ return(MP3_EX);
+ }
+ i = framesize - 6;
+ maxframeseek = (x->file_size) / i;
+ if(!begframeseek)
+ {
+ x->begframeseek = (int *)getzbytes((maxframeseek)*sizeof(int));
+ x->maxframeseek = maxframeseek;
+ }
+ else
+ {
+ if(maxframeseek > (x->maxframeseek))
+ {
+ freebytes(x->begframeseek, (x->maxframeseek)*sizeof(int));
+ x->begframeseek = (int *)getzbytes((maxframeseek)*sizeof(int));
+ x->maxframeseek = maxframeseek;
+ }
+ }
+ begframeseek = x->begframeseek;
+ begframeseek[0] = 0;
+ begframeseek[1] = framesize;
+ frame_counter = 1;
+ /*x->curframeseek = maxframeseek;*/
+ fseek(x->fh, begframeseek[1], SEEK_SET);
+ while(!sigmp3play_read_frame_length_next(x, &framesize, frame_counter))
+ {
+ begframeseek[frame_counter+1] = begframeseek[frame_counter] + framesize;
+ frame_counter++;
+ fseek(x->fh, begframeseek[frame_counter], SEEK_SET);
+ };
+ frame_counter--;
+ length = (float)(frame_counter)*(float)(x->samp_per_frame) / (float)(x->mp3_sr);
+ x->length_sec = length;
+ x->time_factor = length / (float)(frame_counter);
+ x->curframeseek = frame_counter;
+ fseek(x->fh,0,SEEK_SET);
+ return(MP3_OK);
+ }
+ else
+ return(MP3_EX);
+}
+
+static void sigmp3play_do_open(t_sigmp3play *x, char *str, int calc_it)
+{
+ int mp3_sr, obj_sr;
+ int file_size, size, mp3_encode_return=MP3_OK, mp3_read_length, i, j, *begframeseek;
+ static char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" };
+ static char *layers[4] = { "Unknown" , "I", "II", "III" };
+ char completefilename[400];
+
+ if(x->file_is_open)
+ {
+ post("mp3play-ERROR: file is already open, please stop it first!");
+ }
+ else if(*str == 0)
+ {
+ post("mp3play-ERROR: there is no filename to open");
+ }
+ else
+ {
+ if(str[0] == '/')
+ {
+ strcpy(completefilename, str);
+ }
+ else if(((str[0] >= 'A')&&(str[0] <= 'Z')||
+ (str[0] >= 'a')&&(str[0] <= 'z'))&&
+ (str[1] == ':')&&(str[2] == '/'))
+ {
+ strcpy(completefilename, str);
+ }
+ else
+ {
+ strcpy(completefilename, canvas_getdir(x->x_canvas)->s_name);
+ strcat(completefilename, "/");
+ strcat(completefilename, str);
+ }
+
+ if((x->fh = fopen(completefilename, "rb")) == NULL)
+ {
+ post("mp3play-ERROR: cannot open %s", completefilename);
+ }
+ else
+ {
+ strcpy(x->filename, completefilename);
+ fseek(x->fh,0,SEEK_END);
+ file_size = (int)ftell(x->fh);
+ x->file_size = file_size;
+ if(!x->mp_is_init)
+ {
+ InitAgainMP3(&(x->mp));
+ x->mp_is_init = 1;
+ }
+ if(calc_it)
+ mp3_encode_return = sigmp3play_calc_frames(x);
+ if(mp3_encode_return == MP3_EX)
+ {
+ sigmp3play_cleanup(x);
+ return;
+ }
+ if(x->frame_counter)
+ x->frame_counter = (int)(x->offset_sec / x->time_factor);
+ i = x->frame_counter;
+ if(i > (x->curframeseek - 1))
+ i = x->curframeseek - 1;
+ begframeseek = x->begframeseek;
+ j = begframeseek[i];
+ fseek(x->fh,j,SEEK_SET);
+ x->file_block_num = (file_size-j) / MY_MP3_MALLOC_IN_SIZE;
+ x->file_remain = (file_size-j) - (x->file_block_num)*MY_MP3_MALLOC_IN_SIZE;
+ if(x->file_block_num)
+ {
+ mp3_read_length = MY_MP3_MALLOC_IN_SIZE;
+ x->file_block_num--;
+ }
+ else
+ {
+ mp3_read_length = x->file_remain;
+ x->file_remain = 0;
+ }
+ if(mp3_read_length > 0)
+ {
+ fread(x->mp3inbuf, mp3_read_length, sizeof(char), x->fh);
+ mp3_encode_return = decodeMP3(&(x->mp), x->mp3inbuf, mp3_read_length, x->mp3outbuf,
+ MY_MP3_MALLOC_IN_SIZE2, &size);
+ if(mp3_encode_return == MP3_EX)
+ {
+ sigmp3play_cleanup(x);
+ return;
+ }
+ post ("MPEG %s, Layer: %s, Freq: %ld, mode: %s, modext: %d, BPF : %d",
+ x->mp.fr.mpeg25 ? "2.5" : (x->mp.fr.lsf ? "2.0" : "1.0"),
+ layers[x->mp.fr.lay],iemmp3_freqs[x->mp.fr.sampling_frequency],
+ modes[x->mp.fr.mode],x->mp.fr.mode_ext,x->mp.fr.framesize+4);
+ post ("Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.",
+ x->mp.fr.stereo,x->mp.fr.copyright?"Yes":"No",
+ x->mp.fr.original?"Yes":"No",x->mp.fr.error_protection?"Yes":"No",
+ x->mp.fr.emphasis);
+ post ("Bitrate: %d Kbits/s, Extension value: %d",
+ iemmp3_tabsel_123[x->mp.fr.lsf][x->mp.fr.lay-1]
+ [x->mp.fr.bitrate_index],x->mp.fr.extension);
+ post ("Original Soundfile-Length : %.3f sec.\n",x->length_sec);
+
+ x->mp3_byterate = 128*iemmp3_tabsel_123[x->mp.fr.lsf][x->mp.fr.lay-1][x->mp.fr.bitrate_index];
+ /* 1024/8 */
+
+ if(x->mp.fr.stereo == 2)
+ x->mp3_ch = 2;
+ else if(x->mp.fr.stereo == 1)
+ x->mp3_ch = 1;
+ else
+ {
+ x->mp3_ch = 1;
+ post("mp3_play~ WARNING: unknown number of channels : %d channels",
+ x->mp.fr.stereo);
+ }
+ mp3_sr = (int)(iemmp3_freqs[x->mp.fr.sampling_frequency]);
+ obj_sr = x->obj_sr;
+ x->mp3_sr = mp3_sr;
+ if(mp3_sr == obj_sr)
+ {
+ x->down = 0;
+ }
+ else if(2*mp3_sr == obj_sr)
+ {
+ x->down = 1;
+ }
+ else if(4*mp3_sr == obj_sr)
+ {
+ x->down = 2;
+ }
+ else if(mp3_sr == 2*obj_sr)
+ {
+ x->down = -1;
+ }
+ else if(mp3_sr == 4*obj_sr)
+ {
+ x->down = -2;
+ }
+ else
+ {
+ post("mp3_play~ WARNING: playing the filesamplerate of %d Hz at %d Hz", mp3_sr,obj_sr);
+ x->down = 0;
+ }
+
+ if(mp3_encode_return == MP3_OK)
+ {
+ x->file_is_open = 1;
+ x->mp3_encode_size = size * sizeof(char) / sizeof(short);
+ }
+ else
+ {
+ x->file_is_open = 0;
+ x->mp3_out_index = 0;
+ fclose(x->fh);
+ }
+ }
+ else
+ {
+ x->file_is_open = 0;
+ fclose(x->fh);
+ }
+ }
+ x->play_state = 2;
+ x->mp3_out_index = 0;
+ }
+}
+
+static t_int *sigmp3play_perform(t_int *w)
+{
+ t_sigmp3play *x = (t_sigmp3play *)(w[1]);
+ t_float *out1 = (t_float *)(w[2]);
+ t_float *out2 = (t_float *)(w[3]);
+ int n = (int)(w[4]);
+ short *ivec = (short *)(x->mp3outbuf);
+ int size, mp3_encode_return, mp3_read_length, mp3_ch, down;
+ float scale = x->scale, outa, outb;
+ int mp3_out_index = x->mp3_out_index;
+
+ if (!x->file_is_open)
+ goto sigmp3play_labelzero;
+ if (x->play_state != 1)
+ goto sigmp3play_labelzero;
+
+ if(mp3_out_index >= x->mp3_encode_size)
+ {
+ x->frame_counter++;
+ x->time1_bang0_handle = 1;
+ clock_delay(x->x_clock, 0);
+ mp3_out_index = 0;
+ mp3_encode_return = decodeMP3(&(x->mp), NULL, 0, x->mp3outbuf,
+ MY_MP3_MALLOC_IN_SIZE2, &size);
+ if(mp3_encode_return == MP3_OK)
+ x->mp3_encode_size = size * sizeof(char) / sizeof(short);
+ else if(mp3_encode_return == MP3_EX)
+ {
+ sigmp3play_cleanup(x);
+ goto sigmp3play_labelzero;
+ }
+ else
+ {
+ if(x->file_block_num > 0)
+ {
+ mp3_read_length = MY_MP3_MALLOC_IN_SIZE;
+ x->file_block_num--;
+ }
+ else if(x->file_remain > 0)
+ {
+ mp3_read_length = x->file_remain;
+ x->file_remain = 0;
+ }
+ else
+ {
+ sigmp3play_cleanup(x);
+ goto sigmp3play_labelzero;
+ }
+
+ fread(x->mp3inbuf, mp3_read_length, sizeof(char), x->fh);
+ mp3_encode_return = decodeMP3(&(x->mp), x->mp3inbuf, mp3_read_length,
+ x->mp3outbuf, MY_MP3_MALLOC_IN_SIZE2, &size);
+ x->mp3_encode_size = size * sizeof(char) / sizeof(short);
+ if(mp3_encode_return == MP3_EX)
+ {
+ sigmp3play_cleanup(x);
+ goto sigmp3play_labelzero;
+ }
+ }
+ }
+
+ mp3_ch = x->mp3_ch;
+ down = x->down;
+ if(mp3_ch == 2)
+ {
+ if(down == 0)
+ {
+ ivec += mp3_out_index;
+ x->mp3_out_index = mp3_out_index + 2*n;
+ while (n--)
+ {
+ *out1++ = scale * (float)(*ivec++);
+ *out2++ = scale * (float)(*ivec++);
+ }
+ }
+ else if(down == 1)
+ {
+ ivec += mp3_out_index;
+ x->mp3_out_index = mp3_out_index + n;
+ n /= 2;
+ while (n--)
+ {
+ outa = scale * (float)(*ivec++);
+ outb = scale * (float)(*ivec++);
+ *out1++ = outa;
+ *out2++ = outb;
+ *out1++ = outa;
+ *out2++ = outb;
+ }
+ }
+ else if(down == 2)
+ {
+ ivec += mp3_out_index;
+ x->mp3_out_index = mp3_out_index + n/2;
+ n /= 4;
+ while (n--)
+ {
+ outa = scale * (float)(*ivec++);
+ outb = scale * (float)(*ivec++);
+ *out1++ = outa;
+ *out2++ = outb;
+ *out1++ = outa;
+ *out2++ = outb;
+ *out1++ = outa;
+ *out2++ = outb;
+ *out1++ = outa;
+ *out2++ = outb;
+ }
+ }
+ else if(down == -1)
+ {
+ ivec += mp3_out_index;
+ x->mp3_out_index = mp3_out_index + 4*n;
+ while (n--)
+ {
+ outa = scale * (float)(*ivec++);
+ outb = scale * (float)(*ivec);
+ ivec += 3;
+ *out1++ = outa;
+ *out2++ = outa;
+ }
+ }
+ else if(down == -2)
+ {
+ ivec += mp3_out_index;
+ x->mp3_out_index = mp3_out_index + 8*n;
+ while (n--)
+ {
+ outa = scale * (float)(*ivec++);
+ outb = scale * (float)(*ivec);
+ ivec += 7;
+ *out1++ = outa;
+ *out2++ = outa;
+ }
+ }
+ }
+ else
+ {
+ if(down == 0)
+ {
+ ivec += mp3_out_index;
+ x->mp3_out_index = mp3_out_index + n;
+ while (n--)
+ {
+ outa = scale * (float)(*ivec++);
+ *out1++ = outa;
+ *out2++ = outa;
+ }
+ }
+ else if(down == 1)
+ {
+ ivec += mp3_out_index;
+ n /= 2;
+ x->mp3_out_index = mp3_out_index + n;
+ while (n--)
+ {
+ outa = scale * (float)(*ivec++);
+ *out1++ = outa;
+ *out2++ = outa;
+ *out1++ = outa;
+ *out2++ = outa;
+ }
+ }
+ else if(down == 2)
+ {
+ ivec += mp3_out_index;
+ n /= 4;
+ x->mp3_out_index = mp3_out_index + n;
+ while (n--)
+ {
+ outa = scale * (float)(*ivec++);
+ *out1++ = outa;
+ *out2++ = outa;
+ *out1++ = outa;
+ *out2++ = outa;
+ *out1++ = outa;
+ *out2++ = outa;
+ *out1++ = outa;
+ *out2++ = outa;
+ }
+ }
+ else if(down == -1)
+ {
+ ivec += mp3_out_index;
+ x->mp3_out_index = mp3_out_index + 2*n;
+ while (n--)
+ {
+ outa = scale * (float)(*ivec);
+ ivec += 2;
+ *out1++ = outa;
+ *out2++ = outa;
+ }
+ }
+ else if(down == -2)
+ {
+ ivec += mp3_out_index;
+ x->mp3_out_index = mp3_out_index + 4*n;
+ while (n--)
+ {
+ outa = scale * (float)(*ivec);
+ ivec += 4;
+ *out1++ = outa;
+ *out2++ = outa;
+ }
+ }
+ }
+ return (w+5);
+
+sigmp3play_labelzero:
+
+ while (n--)
+ {
+ *out1++ = 0;
+ *out2++ = 0;
+ }
+ return (w+5);
+}
+
+static void sigmp3play_dsp(t_sigmp3play *x, t_signal **sp)
+{
+ x->obj_sr = (int)(sp[0]->s_sr);
+ x->obj_n = (int)(sp[0]->s_n);
+ dsp_add(sigmp3play_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+
+
+static void sigmp3play_stop(t_sigmp3play *x)
+{
+ if(x->file_is_open)
+ {
+ x->file_block_num = 0;
+ x->file_remain = 0;
+ }
+}
+
+static void sigmp3play_start(t_sigmp3play *x)
+{
+ if(x->file_is_open)
+ {
+ x->play_state = 1;
+ }
+}
+
+static void sigmp3play_ft1(t_sigmp3play *x, t_floatarg offset)
+{
+ if(offset < 0.0)
+ offset = 0.0;
+ x->offset_sec = (float)offset;
+}
+
+static void sigmp3play_pause(t_sigmp3play *x)
+{
+ if(x->file_is_open)
+ {
+ if(x->play_state == 0)
+ x->play_state = 1;
+ else if(x->play_state == 1)
+ x->play_state = 0;
+ }
+}
+
+static void sigmp3play_open(t_sigmp3play *x, t_symbol *s)
+{
+ x->frame_counter = 0;
+ sigmp3play_do_open(x, (char *)s->s_name, 1);
+}
+
+static void sigmp3play_open_again(t_sigmp3play *x)
+{
+ x->frame_counter = 0;
+ sigmp3play_do_open(x, x->filename, 0);
+}
+
+static void sigmp3play_open_at(t_sigmp3play *x, t_symbol *s)
+{
+ x->frame_counter = 1;
+ sigmp3play_do_open(x, (char *)s->s_name, 1);
+}
+
+static void sigmp3play_open_again_at(t_sigmp3play *x)
+{
+ x->frame_counter = 1;
+ sigmp3play_do_open(x, x->filename, 0);
+}
+
+
+static void sigmp3play_tick(t_sigmp3play *x)
+{
+ if(x->time1_bang0_handle)
+ {
+ outlet_float(x->x_floatout, (float)(x->frame_counter)*(x->time_factor));
+ }
+ else
+ {
+ outlet_bang(x->x_bangout);
+ }
+}
+
+static void sigmp3play_free(t_sigmp3play *x)
+{
+ if(x->mp_is_init)
+ ExitMP3(&(x->mp));
+ if(x->begframeseek)
+ freebytes(x->begframeseek, (x->maxframeseek)*sizeof(int));
+ freebytes(x->filename, MY_MP3_MALLOC_FN);
+ freebytes(x->mp3outbuf, MY_MP3_MALLOC_OUT_SIZE);
+ freebytes(x->mp3inbuf, MY_MP3_MALLOC_IN_SIZE);
+ clock_free(x->x_clock);
+}
+
+void sigmp3play_setup(void)
+{
+ sigmp3play_class = class_new(gensym("mp3play~"), (t_newmethod)sigmp3play_new,
+ (t_method)sigmp3play_free, sizeof(t_sigmp3play), 0, 0);
+ class_addmethod(sigmp3play_class, (t_method)sigmp3play_dsp, gensym("dsp"), 0);
+ class_addmethod(sigmp3play_class, (t_method)sigmp3play_start, gensym("start"), 0);
+ class_addmethod(sigmp3play_class, (t_method)sigmp3play_ft1,
+ gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(sigmp3play_class, (t_method)sigmp3play_stop, gensym("stop"), 0);
+ class_addmethod(sigmp3play_class, (t_method)sigmp3play_pause, gensym("pause"), 0);
+ class_addmethod(sigmp3play_class, (t_method)sigmp3play_open_again_at, gensym("open_again_at"), 0);
+ class_addmethod(sigmp3play_class, (t_method)sigmp3play_open, gensym("open"), A_DEFSYM, 0);
+ class_addmethod(sigmp3play_class, (t_method)sigmp3play_open_again, gensym("open_again"), 0);
+ class_addmethod(sigmp3play_class, (t_method)sigmp3play_open_at, gensym("open_at"), A_DEFSYM, 0);
+ class_sethelpsymbol(sigmp3play_class, gensym("iemhelp/help-mp3play~"));
+ /*post("\nmp3play~ written by thomas musil & norbert math\nV 0.1 iem graz
+ austria 05 2000\n");*/
+}
+
diff --git a/src/iem_t3_lib/iem_t3_lib.c b/src/iem_t3_lib/iem_t3_lib.c
new file mode 100644
index 0000000..1e19576
--- /dev/null
+++ b/src/iem_t3_lib/iem_t3_lib.c
@@ -0,0 +1,65 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_t3_lib written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+/*
+#include <ctype.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifndef NT
+#include <sys/signal.h>
+#include <unistd.h>
+#endif
+
+#ifdef NT
+#include <io.h>
+#endif
+ */
+
+static t_class *iem_t3_lib_class;
+
+static void *iem_t3_lib_new(void)
+{
+ t_object *x = (t_object *)pd_new(iem_t3_lib_class);
+
+ return (x);
+}
+
+void sigt3_line_setup(void);
+void sigt3_sig_setup(void);
+void t3_bpe_setup(void);
+void t3_delay_setup(void);
+void t3_metro_setup(void);
+void t3_timer_setup(void);
+
+/* ------------------------ setup routine ------------------------- */
+
+void iem_t3_lib_setup(void)
+{
+ iem_t3_lib_class = class_new(gensym("iem_t3_lib"), iem_t3_lib_new, 0,
+ sizeof(t_object), CLASS_NOINLET, 0);
+
+ sigt3_line_setup();
+ sigt3_sig_setup();
+ t3_bpe_setup();
+ t3_delay_setup();
+ t3_metro_setup();
+ t3_timer_setup();
+
+ post("iem_t3_lib (R-1.15) library loaded!");
+}
diff --git a/src/iem_t3_lib/iem_t3_lib.dsp b/src/iem_t3_lib/iem_t3_lib.dsp
new file mode 100644
index 0000000..e6a61be
--- /dev/null
+++ b/src/iem_t3_lib/iem_t3_lib.dsp
@@ -0,0 +1,85 @@
+# Microsoft Developer Studio Project File - Name="iem_t3_lib" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) External Target" 0x0106
+
+CFG=iem_t3_lib - 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_t3_lib.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_t3_lib.mak" CFG="iem_t3_lib - Win32 Debug"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "iem_t3_lib - Win32 Release" (basierend auf "Win32 (x86) External Target")
+!MESSAGE "iem_t3_lib - Win32 Debug" (basierend auf "Win32 (x86) External Target")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF "$(CFG)" == "iem_t3_lib - 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_t3_lib.exe"
+# PROP Bsc_Name "iem_t3_lib.bsc"
+# PROP Target_Dir ""
+
+!ELSEIF "$(CFG)" == "iem_t3_lib - 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_t3_lib.exe"
+# PROP Bsc_Name "iem_t3_lib.bsc"
+# PROP Target_Dir ""
+
+!ENDIF
+
+# Begin Target
+
+# Name "iem_t3_lib - Win32 Release"
+# Name "iem_t3_lib - Win32 Debug"
+
+!IF "$(CFG)" == "iem_t3_lib - Win32 Release"
+
+!ELSEIF "$(CFG)" == "iem_t3_lib - Win32 Debug"
+
+!ENDIF
+
+# Begin Source File
+
+SOURCE=.\makefile_win
+# End Source File
+# End Target
+# End Project
diff --git a/src/iem_t3_lib/iem_t3_lib.dsw b/src/iem_t3_lib/iem_t3_lib.dsw
new file mode 100644
index 0000000..2b4e202
--- /dev/null
+++ b/src/iem_t3_lib/iem_t3_lib.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
+
+###############################################################################
+
+Project: "iem_t3_lib"=.\iem_t3_lib.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/src/iem_t3_lib/iemlib.h b/src/iem_t3_lib/iemlib.h
new file mode 100644
index 0000000..d518565
--- /dev/null
+++ b/src/iem_t3_lib/iemlib.h
@@ -0,0 +1,98 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#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 MACOSX
+#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 /* MACOSX */
+#endif /* __linux__ */
+#endif /* MSW */
+#endif /* SGI */
+
+union tabfudge
+{
+ double tf_d;
+ int32 tf_i[2];
+};
+
+#endif
diff --git a/src/iem_t3_lib/makefile b/src/iem_t3_lib/makefile
new file mode 100644
index 0000000..34d19d6
--- /dev/null
+++ b/src/iem_t3_lib/makefile
@@ -0,0 +1,56 @@
+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 -Wall -W -Werror -Wno-unused \
+ -Wno-parentheses -Wno-switch -O6 -funroll-loops -fomit-frame-pointer \
+ -DDL_OPEN
+
+SYSTEM = $(shell uname -m)
+
+# the sources
+
+SRC = sigt3_line.c \
+ sigt3_sig.c \
+ t3_bpe.c \
+ t3_delay.c \
+ t3_metro.c \
+ t3_timer.c \
+ iem_t3_lib.c
+
+TARGET = iem_t3_lib.pd_linux
+
+
+OBJ = $(SRC:.c=.o)
+
+#
+# ------------------ targets ------------------------------------
+#
+
+clean:
+ rm ../../lib/$(TARGET)
+ rm *.o
+
+all: $(OBJ)
+
+ @echo :: $(OBJ)
+
+ ld $(LDFLAGS) -o $(TARGET) *.o $(LIB)
+ strip --strip-unneeded $(TARGET)
+ mv $(TARGET) ../../lib
+ rm *.o
+
+$(OBJ) : %.o : %.c
+ touch $*.c
+ cc $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c
+
+
+
+
diff --git a/src/iem_t3_lib/makefile_win b/src/iem_t3_lib/makefile_win
new file mode 100644
index 0000000..6f31894
--- /dev/null
+++ b/src/iem_t3_lib/makefile_win
@@ -0,0 +1,43 @@
+
+all: ..\..\lib\iem_t3_lib.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\pthreadVC.lib \
+ $(PD_INST_PATH)\bin\pd.lib
+
+
+SRC = sigt3_line.c \
+ sigt3_sig.c \
+ t3_bpe.c \
+ t3_delay.c \
+ t3_metro.c \
+ t3_timer.c \
+ iem_t3_lib.c
+
+
+OBJ = $(SRC:.c=.obj)
+
+.c.obj:
+ cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c
+
+..\..\lib\iem_t3_lib.dll: $(OBJ)
+ link $(PD_WIN_L_FLAGS) /dll /export:iem_t3_lib_setup \
+ /out:..\..\lib\iem_t3_lib.dll $(OBJ) $(PD_WIN_LIB)
+
+clean:
+ del *.obj
diff --git a/src/iem_t3_lib/sigt3_line.c b/src/iem_t3_lib/sigt3_line.c
new file mode 100644
index 0000000..525f7f7
--- /dev/null
+++ b/src/iem_t3_lib/sigt3_line.c
@@ -0,0 +1,279 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_t3_lib written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* -------------------------- t3_line~ ------------------------------ */
+static t_class *sigt3_line_class;
+
+typedef struct _sigt3_line
+{
+ t_object x_obj;
+ t_clock *x_clock;
+ float *x_beg;
+ double x_cur_val;
+ double x_dst_val;
+ double x_inlet_val;
+ double x_inc64;
+ double x_inc;
+ double x_ms2samps;
+ double x_ticks2ms;
+ double x_inlet_time;
+ double x_dst_time;
+ int x_cur_samps;
+ int x_dur_samps;
+ int x_n;
+ int x_t3_bang_samps;
+ int x_transient;
+} t_sigt3_line;
+
+static void sigt3_line_nontransient(float *vec, t_sigt3_line *x, int n)
+{
+ int cur_samps = x->x_cur_samps, i;
+ double inc = x->x_inc;
+ double cur_val = x->x_cur_val;
+
+ if(cur_samps)
+ {
+ if(cur_samps > n)
+ {
+ x->x_cur_samps -= n;
+ while(n--)
+ {
+ cur_val += inc;
+ *vec++ = (float)cur_val;
+ }
+ x->x_cur_val += x->x_inc64;
+ }
+ else if(cur_samps == n)
+ {
+ x->x_cur_samps = 0;
+ while(n--)
+ {
+ cur_val += inc;
+ *vec++ = (float)cur_val;
+ }
+ x->x_cur_val = x->x_dst_val;
+ }
+ else
+ {
+ for(i=0; i<cur_samps; i++)
+ {
+ cur_val += inc;
+ *vec++ = (float)cur_val;
+ }
+ x->x_cur_val = cur_val = x->x_dst_val;
+ for(i=cur_samps; i<n; i++)
+ *vec++ = (float)cur_val;
+ x->x_cur_samps = 0;
+ }
+ }
+ else
+ {
+ while(n--)
+ *vec++ = (float)cur_val;
+ }
+}
+
+static t_int *sigt3_line_perform(t_int *w)
+{
+ t_float *out = (t_float *)(w[1]);
+ t_sigt3_line *x = (t_sigt3_line *)(w[2]);
+ int n = (int)(w[3]);
+
+ if(x->x_transient)
+ {
+ float *trans = x->x_beg;
+
+ while(n--)
+ *out++ = *trans++;
+ x->x_transient = 0;
+ }
+ else
+ sigt3_line_nontransient(out, x, n);
+ return(w+4);
+}
+
+static void sigt3_line_tick(t_sigt3_line *x)
+{
+ float *trans = x->x_beg;
+ int n = x->x_n, t3_bang_samps, cur_samps, i;
+ double inc, cur_val;
+
+ if(!x->x_transient)
+ sigt3_line_nontransient(trans, x, n);
+ t3_bang_samps = x->x_t3_bang_samps;
+ x->x_dst_val = x->x_inlet_val;
+ if(x->x_inlet_time <= 0.0)
+ {
+ x->x_inlet_time = 0.0;
+ x->x_dst_time = 0.0;
+ x->x_dur_samps = 0;
+ x->x_cur_samps = 0;
+ cur_val = x->x_cur_val = x->x_dst_val;
+ for(i=t3_bang_samps; i<n; i++)
+ trans[i] = (float)cur_val;
+ }
+ else
+ {
+ int diff, end;
+
+ x->x_dst_time = x->x_inlet_time;
+ x->x_inlet_time = 0.0;
+ cur_samps = (int)(x->x_dst_time * x->x_ms2samps);
+ if(!cur_samps)
+ cur_samps = 1;
+ x->x_dur_samps = cur_samps;
+ x->x_cur_samps = cur_samps;
+ cur_val = x->x_cur_val = (double)trans[t3_bang_samps];
+ inc = x->x_inc = (x->x_dst_val - cur_val)/(double)cur_samps;
+ x->x_inc64 = (double)x->x_n * inc;
+ diff = n - t3_bang_samps;
+ if(cur_samps > diff)
+ {
+ for(i=t3_bang_samps; i<n; i++)
+ {
+ cur_val += inc;
+ trans[i] = (float)cur_val;
+ }
+ x->x_cur_val += (double)diff * inc;
+ x->x_cur_samps -= diff;
+ }
+ else if(cur_samps == diff)
+ {
+ for(i=t3_bang_samps; i<n; i++)
+ {
+ cur_val += inc;
+ trans[i] = (float)cur_val;
+ }
+ x->x_cur_val = x->x_dst_val;
+ x->x_cur_samps = 0;
+ }
+ else
+ {
+ end = t3_bang_samps + cur_samps;
+ for(i=t3_bang_samps; i<end; i++)
+ {
+ cur_val += inc;
+ trans[i] = (float)cur_val;
+ }
+ cur_val = x->x_cur_val = x->x_dst_val;
+ x->x_cur_samps = 0;
+ for(i=end; i<n; i++)
+ trans[i] = (float)cur_val;
+ }
+ }
+ x->x_transient = 1;
+}
+
+static void sigt3_line_list(t_sigt3_line *x, t_symbol *s, int ac, t_atom *av)
+{
+ if((ac >= 2)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1))
+ {
+ int t3_bang_samps, ticks;
+ double time;
+
+ x->x_inlet_val = (double)atom_getfloatarg(1, ac, av);
+ t3_bang_samps = (int)((float)atom_getfloatarg(0, ac, av)*x->x_ms2samps);
+ if(t3_bang_samps < 0)
+ t3_bang_samps = 0;
+ ticks = t3_bang_samps / x->x_n;
+ x->x_t3_bang_samps = t3_bang_samps - x->x_n * ticks;
+ if((ac >= 3)&&IS_A_FLOAT(av,2))
+ {
+ time = (double)atom_getfloatarg(2, ac, av);
+ if(time < 0.0)
+ time = 0.0;
+ x->x_inlet_time = time;
+ }
+ if(ticks < 1)
+ sigt3_line_tick(x);
+ else
+ clock_delay(x->x_clock, (double)ticks * x->x_ticks2ms);
+ }
+}
+
+static void sigt3_line_ft1(t_sigt3_line *x, t_float time)
+{
+ if(time < 0.0)
+ time = 0.0;
+ x->x_inlet_time = (double)time;
+}
+
+static void sigt3_line_stop(t_sigt3_line *x)
+{
+ clock_unset(x->x_clock);
+ x->x_cur_samps = x->x_dur_samps = x->x_transient = 0;
+ x->x_inc = x->x_inc64 = x->x_inlet_time = x->x_dst_time = 0.0;
+}
+
+static void sigt3_line_dsp(t_sigt3_line *x, t_signal **sp)
+{
+ int i;
+ float val, *trans;
+
+ if(sp[0]->s_n > x->x_n)
+ {
+ freebytes(x->x_beg, x->x_n*sizeof(float));
+ x->x_n = (int)sp[0]->s_n;
+ x->x_beg = (float *)getbytes(x->x_n*sizeof(float));
+ }
+ else
+ x->x_n = (int)sp[0]->s_n;
+ i = x->x_n;
+ val = x->x_cur_val;
+ trans = x->x_beg;
+ while(i--)
+ *trans++ = val;
+ x->x_ms2samps = 0.001*(double)sp[0]->s_sr;
+ x->x_ticks2ms = (double)x->x_n / x->x_ms2samps;
+ dsp_add(sigt3_line_perform, 3, sp[0]->s_vec, x, sp[0]->s_n);
+}
+
+static void sigt3_line_free(t_sigt3_line *x)
+{
+ if(x->x_beg)
+ freebytes(x->x_beg, x->x_n*sizeof(float));
+ clock_free(x->x_clock);
+}
+
+static void *sigt3_line_new(t_floatarg init_val)
+{
+ t_sigt3_line *x = (t_sigt3_line *)pd_new(sigt3_line_class);
+ int i;
+
+ x->x_n = (int)sys_getblksize();
+ x->x_beg = (float *)getbytes(x->x_n*sizeof(float));
+ x->x_inlet_val = x->x_cur_val = x->x_dst_val = init_val;
+ x->x_t3_bang_samps = x->x_cur_samps = x->x_dur_samps = x->x_transient = 0;
+ x->x_inlet_time = x->x_dst_time = 0.0;
+ x->x_inc64 = x->x_inc = 0.0;
+ x->x_ms2samps = 0.001 * (double)sys_getsr();
+ x->x_ticks2ms = (double)x->x_n / x->x_ms2samps;
+ x->x_clock = clock_new(x, (t_method)sigt3_line_tick);
+ outlet_new(&x->x_obj, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
+ return (x);
+}
+
+void sigt3_line_setup(void)
+{
+ sigt3_line_class = class_new(gensym("t3_line~"), (t_newmethod)sigt3_line_new,
+ (t_method)sigt3_line_free, sizeof(t_sigt3_line), 0, A_DEFFLOAT, 0);
+ class_addmethod(sigt3_line_class, (t_method)sigt3_line_dsp, gensym("dsp"), 0);
+ class_addmethod(sigt3_line_class, (t_method)sigt3_line_stop, gensym("stop"), 0);
+ class_addmethod(sigt3_line_class, (t_method)sigt3_line_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addlist(sigt3_line_class, (t_method)sigt3_line_list);
+ class_sethelpsymbol(sigt3_line_class, gensym("iemhelp/help-t3_line~"));
+}
diff --git a/src/iem_t3_lib/sigt3_sig.c b/src/iem_t3_lib/sigt3_sig.c
new file mode 100644
index 0000000..84429b6
--- /dev/null
+++ b/src/iem_t3_lib/sigt3_sig.c
@@ -0,0 +1,200 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_t3_lib written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* -------------------------- sigt3_sig~ ------------------------------ */
+static t_class *sigt3_sig_class;
+
+typedef struct _sigt3_sig
+{
+ t_object x_obj;
+ t_clock *x_clock;
+ float x_old_val;
+ float x_new_val;
+ float *x_beg;
+ int x_n;
+ int x_t3_bang_samps;
+ int x_transient;
+ float x_ms2samps;
+ float x_ticks2ms;
+} t_sigt3_sig;
+
+static void sigt3_sig_tick(t_sigt3_sig *x)
+{
+ float *trans = x->x_beg, val;
+ int n = x->x_n, t3_bang_samps, i;
+
+ t3_bang_samps = x->x_t3_bang_samps;
+ if(!x->x_transient)
+ {
+ val = x->x_old_val;
+ for(i=0; i<t3_bang_samps; i++)
+ trans[i] = val;
+ x->x_transient = 1;
+ }
+ val = x->x_old_val = x->x_new_val;
+ for(i=t3_bang_samps; i<n; i++)
+ trans[i] = val;
+}
+
+static void sigt3_sig_stop(t_sigt3_sig *x)
+{
+ clock_unset(x->x_clock);
+ x->x_new_val = x->x_old_val;
+}
+
+static void sigt3_sig_list(t_sigt3_sig *x, t_symbol *s, int ac, t_atom *av)
+{
+ if((ac == 2)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1))
+ {
+ int n = x->x_n, t3_bang_samps, ticks;
+
+ t3_bang_samps = (int)((float)atom_getfloatarg(0, ac, av)*x->x_ms2samps);
+ x->x_new_val = (float)atom_getfloatarg(1, ac, av);
+ if(t3_bang_samps < 0)
+ t3_bang_samps = 0;
+ ticks = t3_bang_samps / n;
+ x->x_t3_bang_samps = t3_bang_samps - n*ticks;
+ if(ticks < 1)
+ sigt3_sig_tick(x);
+ else
+ clock_delay(x->x_clock, (double)ticks * (double)x->x_ticks2ms);
+ }
+}
+
+static t_int *sigt3_sig_perform(t_int *w)
+{
+ t_float *out = (t_float *)(w[1]);
+ t_sigt3_sig *x = (t_sigt3_sig *)(w[2]);
+ int n = (int)(w[3]);
+
+ if(x->x_transient)
+ {
+ float *trans = x->x_beg;
+
+ while(n--)
+ *out++ = *trans++;
+ x->x_transient = 0;
+ }
+ else
+ {
+ float val = x->x_new_val;
+
+ while(n--)
+ *out++ = val;
+ }
+ return (w+4);
+}
+
+static t_int *sigt3_sig_perf8(t_int *w)
+{
+ t_float *out = (t_float *)(w[1]);
+ t_sigt3_sig *x = (t_sigt3_sig *)(w[2]);
+ int n = (int)(w[3]), i;
+
+ if(x->x_transient)
+ {
+ float *trans = x->x_beg;
+
+ for(i=0; i<n; i+=8, out+=8, trans+=8)
+ {
+ out[0] = trans[0];
+ out[1] = trans[1];
+ out[2] = trans[2];
+ out[3] = trans[3];
+ out[4] = trans[4];
+ out[5] = trans[5];
+ out[6] = trans[6];
+ out[7] = trans[7];
+ }
+ x->x_transient = 0;
+ }
+ else
+ {
+ float val = x->x_new_val;
+
+ for(i=0; i<n; i+=8, out+=8)
+ {
+ out[0] = val;
+ out[1] = val;
+ out[2] = val;
+ out[3] = val;
+ out[4] = val;
+ out[5] = val;
+ out[6] = val;
+ out[7] = val;
+ }
+ }
+ return (w+4);
+}
+
+static void sigt3_sig_dsp(t_sigt3_sig *x, t_signal **sp)
+{
+ int i;
+ float *trans, val;
+
+ if(sp[0]->s_n > x->x_n)
+ {
+ freebytes(x->x_beg, x->x_n*sizeof(float));
+ x->x_n = sp[0]->s_n;
+ x->x_beg = (float *)getbytes(x->x_n*sizeof(float));
+ }
+ else
+ x->x_n = sp[0]->s_n;
+ x->x_ms2samps = 0.001*(float)sp[0]->s_sr;
+ x->x_ticks2ms = (float)x->x_n / x->x_ms2samps;
+ i = x->x_n;
+ val = x->x_new_val;
+ trans = x->x_beg;
+ while(i--)
+ *trans++ = val;
+
+ if((sp[0]->s_n)&7)
+ dsp_add(sigt3_sig_perform, 3, sp[0]->s_vec, x, sp[0]->s_n);
+ else
+ dsp_add(sigt3_sig_perf8, 3, sp[0]->s_vec, x, sp[0]->s_n);
+}
+
+static void sigt3_sig_free(t_sigt3_sig *x)
+{
+ if(x->x_beg)
+ freebytes(x->x_beg, x->x_n*sizeof(float));
+ clock_free(x->x_clock);
+}
+
+static void *sigt3_sig_new(t_floatarg init_val)
+{
+ t_sigt3_sig *x = (t_sigt3_sig *)pd_new(sigt3_sig_class);
+
+ x->x_new_val = x->x_old_val = init_val;
+ x->x_n = (int)sys_getblksize();
+ x->x_beg = (float *)getbytes(x->x_n*sizeof(float));
+ x->x_t3_bang_samps = x->x_transient = 0;
+ x->x_ms2samps = 0.001 * (float)sys_getsr();
+ x->x_ticks2ms = (float)x->x_n / x->x_ms2samps;
+ x->x_clock = clock_new(x, (t_method)sigt3_sig_tick);
+ outlet_new(&x->x_obj, &s_signal);
+ return (x);
+}
+
+void sigt3_sig_setup(void)
+{
+ sigt3_sig_class = class_new(gensym("t3_sig~"), (t_newmethod)sigt3_sig_new,
+ (t_method)sigt3_sig_free, sizeof(t_sigt3_sig), 0, A_DEFFLOAT, 0);
+ class_addmethod(sigt3_sig_class, (t_method)sigt3_sig_dsp, gensym("dsp"), 0);
+ class_addmethod(sigt3_sig_class, (t_method)sigt3_sig_stop, gensym("stop"), 0);
+ class_addlist(sigt3_sig_class, (t_method)sigt3_sig_list);
+ class_sethelpsymbol(sigt3_sig_class, gensym("iemhelp/help-t3_sig~"));
+}
diff --git a/src/iem_t3_lib/t3_bpe.c b/src/iem_t3_lib/t3_bpe.c
new file mode 100644
index 0000000..6a2dbe0
--- /dev/null
+++ b/src/iem_t3_lib/t3_bpe.c
@@ -0,0 +1,142 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_t3_lib written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ------------------------ t3_bpe ---------------------------- */
+static t_class *t3_bpe_class;
+
+typedef struct _t3_bpe
+{
+ t_object x_obj;
+ t_atom x_at[2];
+ t_clock *x_clock;
+ int x_maxnum;
+ int x_curnum;
+ int x_curindex;
+ t_atom *x_beg;
+ double x_t3_bang;
+ double x_ticks2ms;
+ int x_hit;
+ void *x_out_val;
+ void *x_out_time;
+ void *x_out_finished;
+} t_t3_bpe;
+
+static void t3_bpe_stop(t_t3_bpe *x)
+{
+ clock_unset(x->x_clock);
+}
+
+static void t3_bpe_tick(t_t3_bpe *x)
+{
+ t_atom *vec = x->x_beg;
+ float val;
+ double dticks, time;
+ int iticks;
+
+ if(x->x_curindex >= x->x_curnum)
+ {
+ t3_bpe_stop(x);
+ outlet_float(x->x_out_finished, x->x_t3_bang);
+ }
+ else
+ {
+ x->x_hit = 0;
+ vec += x->x_curindex;
+ val = atom_getfloat(vec++);
+ time = (double)atom_getfloat(vec);
+ outlet_float(x->x_out_time, (float)time);
+ x->x_at[1].a_w.w_float = val;
+ x->x_at[0].a_w.w_float = x->x_t3_bang;
+ outlet_list(x->x_obj.ob_outlet, &s_list, 2, x->x_at);
+ dticks = (time + x->x_t3_bang)/x->x_ticks2ms;
+ iticks = (int)dticks;
+ x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms;
+ if(!x->x_hit)
+ clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms);
+ x->x_curindex += 2;
+ }
+}
+
+static void t3_bpe_float(t_t3_bpe *x, t_floatarg f)
+{
+ double dticks;
+ int iticks;
+
+ if(x->x_curnum)
+ {
+ x->x_curindex = 0;
+ dticks = (double)f/x->x_ticks2ms;
+ iticks = (int)dticks;
+ x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms;
+ clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms);
+ x->x_hit = 1;
+ }
+}
+
+static void t3_bpe_list(t_t3_bpe *x, t_symbol *s, int ac, t_atom *av)
+{
+ int n = ac & 0xfffffffe, i;
+ t_atom *vec = x->x_beg;
+ if(n > x->x_maxnum)
+ {
+ freebytes(x->x_beg, x->x_maxnum*sizeof(t_atom));
+ x->x_maxnum = 2 + n;
+ x->x_beg = (t_atom *)getbytes(x->x_maxnum*sizeof(t_atom));
+ vec = x->x_beg;
+ }
+ x->x_curnum = n;
+ for(i=0; i<n; i++)
+ {
+ *vec++ = *av++;
+ }
+}
+
+static void t3_bpe_free(t_t3_bpe *x)
+{
+ freebytes(x->x_beg, x->x_maxnum*sizeof(t_atom));
+ clock_free(x->x_clock);
+}
+
+static void *t3_bpe_new(void)
+{
+ t_t3_bpe *x = (t_t3_bpe *)pd_new(t3_bpe_class);
+
+ x->x_t3_bang = 0.0;
+ x->x_ticks2ms = 1000.0*(double)sys_getblksize()/(double)sys_getsr();
+ x->x_curindex = 0;
+ x->x_maxnum = 20;
+ x->x_curnum = 0;
+ x->x_hit = 0;
+ x->x_beg = (t_atom *)getbytes(x->x_maxnum*sizeof(t_atom));
+ x->x_clock = clock_new(x, (t_method)t3_bpe_tick);
+ outlet_new(&x->x_obj, &s_list);
+ x->x_out_time = outlet_new(&x->x_obj, &s_float);
+ x->x_out_finished = outlet_new(&x->x_obj, &s_float);
+ x->x_at[0].a_type = A_FLOAT;
+ x->x_at[1].a_type = A_FLOAT;
+ return (x);
+}
+
+void t3_bpe_setup(void)
+{
+ t3_bpe_class = class_new(gensym("t3_bpe"), (t_newmethod)t3_bpe_new,
+ (t_method)t3_bpe_free, sizeof(t_t3_bpe), 0, 0);
+ class_addmethod(t3_bpe_class, (t_method)t3_bpe_stop, gensym("stop"), 0);
+ class_addfloat(t3_bpe_class, (t_method)t3_bpe_float);
+ class_addlist(t3_bpe_class, (t_method)t3_bpe_list);
+ class_sethelpsymbol(t3_bpe_class, gensym("iemhelp/help-t3_bpe"));
+}
+
diff --git a/src/iem_t3_lib/t3_delay.c b/src/iem_t3_lib/t3_delay.c
new file mode 100644
index 0000000..a422718
--- /dev/null
+++ b/src/iem_t3_lib/t3_delay.c
@@ -0,0 +1,97 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_t3_lib written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ------------------------ t3_delay ---------------------------- */
+static t_class *t3_delay_class;
+
+typedef struct _t3_delay
+{
+ t_object x_obj;
+ t_clock *x_clock;
+ double x_deltime;
+ double x_ticks2ms;
+ double x_t3_bang;
+} t_t3_delay;
+
+static void t3_delay_tick(t_t3_delay *x)
+{
+ outlet_float(x->x_obj.ob_outlet, x->x_t3_bang);
+}
+
+static void t3_delay_stop(t_t3_delay *x)
+{
+ clock_unset(x->x_clock);
+}
+
+static void t3_delay_float(t_t3_delay *x, t_floatarg t3_bang)
+{
+ double dticks;
+ int iticks;
+
+ if(t3_bang < 0)
+ t3_bang = 0;
+ dticks = (x->x_deltime + (double)t3_bang)/x->x_ticks2ms;
+ iticks = (int)dticks;
+ x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms;
+ clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms);
+}
+
+static void t3_delay_ft1(t_t3_delay *x, t_floatarg f)
+{
+ if(f < 0)
+ f = 0;
+ x->x_deltime = f;
+}
+
+static void t3_delay_list(t_t3_delay *x, t_symbol *s, int ac, t_atom *av)
+{
+ if((ac == 2)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1))
+ {
+ t3_delay_ft1(x, atom_getfloatarg(1, ac, av));
+ t3_delay_float(x, atom_getfloatarg(0, ac, av));
+ }
+}
+
+static void t3_delay_free(t_t3_delay *x)
+{
+ clock_free(x->x_clock);
+}
+
+static void *t3_delay_new(t_floatarg f)
+{
+ t_t3_delay *x = (t_t3_delay *)pd_new(t3_delay_class);
+
+ x->x_ticks2ms = 1000.0*(double)sys_getblksize()/(double)sys_getsr();
+ t3_delay_ft1(x, f);
+ x->x_clock = clock_new(x, (t_method)t3_delay_tick);
+ outlet_new(&x->x_obj, &s_float);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
+ return (x);
+}
+
+void t3_delay_setup(void)
+{
+ t3_delay_class = class_new(gensym("t3_delay"), (t_newmethod)t3_delay_new,
+ (t_method)t3_delay_free, sizeof(t_t3_delay), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)t3_delay_new, gensym("t3_del"), A_DEFFLOAT, 0);
+ class_addmethod(t3_delay_class, (t_method)t3_delay_stop, gensym("stop"), 0);
+ class_addmethod(t3_delay_class, (t_method)t3_delay_ft1,
+ gensym("ft1"), A_FLOAT, 0);
+ class_addfloat(t3_delay_class, (t_method)t3_delay_float);
+ class_addlist(t3_delay_class, (t_method)t3_delay_list);
+ class_sethelpsymbol(t3_delay_class, gensym("iemhelp/help-t3_delay"));
+}
+
diff --git a/src/iem_t3_lib/t3_metro.c b/src/iem_t3_lib/t3_metro.c
new file mode 100644
index 0000000..b33ad7e
--- /dev/null
+++ b/src/iem_t3_lib/t3_metro.c
@@ -0,0 +1,121 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_t3_lib written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ------------------------ t3_metro ---------------------------- */
+static t_class *t3_metro_class;
+
+typedef struct _t3_metro
+{
+ t_object x_obj;
+ t_clock *x_clock;
+ double x_metrotime;
+ double x_ticks2ms;
+ double x_t3_bang;
+ int x_hit;
+ void *x_out_next;
+} t_t3_metro;
+
+static void t3_metro_stop(t_t3_metro *x)
+{
+ clock_unset(x->x_clock);
+}
+
+static void t3_metro_tick(t_t3_metro *x)
+{
+ double dticks;
+ int iticks;
+
+ x->x_hit = 0;
+ outlet_float(x->x_out_next, x->x_metrotime);
+ outlet_float(x->x_obj.ob_outlet, x->x_t3_bang);
+ dticks = (x->x_metrotime + x->x_t3_bang)/x->x_ticks2ms;
+ iticks = (int)dticks;
+ x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms;
+ if(!x->x_hit)
+ clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms);
+}
+
+static void t3_metro_float(t_t3_metro *x, t_floatarg t3_bang)
+{
+ double dticks;
+ int iticks;
+
+ if(t3_bang < 0)
+ t3_bang = 0;
+ dticks = (double)t3_bang/x->x_ticks2ms;
+ iticks = (int)dticks;
+ x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms;
+ clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms);
+ x->x_hit = 1;
+}
+
+static void t3_metro_start(t_t3_metro *x, t_floatarg f)
+{
+ t3_metro_float(x, f);
+ x->x_hit = 1;
+}
+
+static void t3_metro_ft1(t_t3_metro *x, t_floatarg f)
+{
+ if(f < 0.01) f = 0.01;
+ x->x_metrotime = (double)f;
+}
+
+static void t3_metro_list(t_t3_metro *x, t_symbol *s, int ac, t_atom *av)
+{
+ if((ac == 2)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1))
+ {
+ t3_metro_ft1(x, atom_getfloatarg(1, ac, av));
+ t3_metro_float(x, atom_getfloatarg(0, ac, av));
+ }
+}
+
+static void t3_metro_free(t_t3_metro *x)
+{
+ clock_free(x->x_clock);
+}
+
+static void *t3_metro_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_t3_metro *x = (t_t3_metro *)pd_new(t3_metro_class);
+
+ x->x_metrotime = 10.0;
+ x->x_t3_bang = 0.0;
+ x->x_hit = 0;
+ if((ac == 1)&&IS_A_FLOAT(av,0))
+ {
+ t3_metro_ft1(x, atom_getfloatarg(0, ac, av));
+ }
+ x->x_ticks2ms = 1000.0*(double)sys_getblksize()/(double)sys_getsr();
+ x->x_clock = clock_new(x, (t_method)t3_metro_tick);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_out_next = outlet_new(&x->x_obj, &s_float);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
+ return (x);
+}
+
+void t3_metro_setup(void)
+{
+ t3_metro_class = class_new(gensym("t3_metro"), (t_newmethod)t3_metro_new,
+ (t_method)t3_metro_free, sizeof(t_t3_metro), 0, A_GIMME, 0);
+ class_addmethod(t3_metro_class, (t_method)t3_metro_stop, gensym("stop"), 0);
+ class_addmethod(t3_metro_class, (t_method)t3_metro_start, gensym("start"), A_FLOAT, 0);
+ class_addmethod(t3_metro_class, (t_method)t3_metro_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addfloat(t3_metro_class, (t_method)t3_metro_float);
+ class_addlist(t3_metro_class, (t_method)t3_metro_list);
+ class_sethelpsymbol(t3_metro_class, gensym("iemhelp/help-t3_metro"));
+}
+
diff --git a/src/iem_t3_lib/t3_timer.c b/src/iem_t3_lib/t3_timer.c
new file mode 100644
index 0000000..c52a926
--- /dev/null
+++ b/src/iem_t3_lib/t3_timer.c
@@ -0,0 +1,55 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_t3_lib written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* -------------------------- t3_timer ------------------------------ */
+static t_class *t3_timer_class;
+
+typedef struct _t3_timer
+{
+ t_object x_obj;
+ double x_settime;
+ double x_t3_off;
+} t_t3_timer;
+
+static void t3_timer_float(t_t3_timer *x, t_float t3_bang)
+{
+ x->x_settime = (double)clock_getsystime();
+ x->x_t3_off = (double)t3_bang;
+}
+
+static void t3_timer_ft1(t_t3_timer *x, t_float t3_bang)
+{
+ outlet_float(x->x_obj.ob_outlet, clock_gettimesince(x->x_settime)
+ + (double)t3_bang - x->x_t3_off);
+}
+
+static void *t3_timer_new(void)
+{
+ t_t3_timer *x = (t_t3_timer *)pd_new(t3_timer_class);
+ t3_timer_float(x, 0.0);
+ outlet_new(&x->x_obj, &s_float);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ return (x);
+}
+
+void t3_timer_setup(void)
+{
+ t3_timer_class = class_new(gensym("t3_timer"), (t_newmethod)t3_timer_new, 0,
+ sizeof(t_t3_timer), 0, 0);
+ class_addfloat(t3_timer_class, t3_timer_float);
+ class_addmethod(t3_timer_class, (t_method)t3_timer_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_sethelpsymbol(t3_timer_class, gensym("iemhelp/help-t3_timer"));
+}
diff --git a/src/iemlib1/biquad_freq_resp.c b/src/iemlib1/biquad_freq_resp.c
new file mode 100644
index 0000000..3ebe25d
--- /dev/null
+++ b/src/iemlib1/biquad_freq_resp.c
@@ -0,0 +1,92 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* --------------------------- biquad_freq_resp ----------------------------- */
+
+typedef struct _biquad_freq_resp
+{
+ t_object x_obj;
+ float a0;
+ float a1;
+ float a2;
+ float b1;
+ float b2;
+ t_outlet *x_out_re;
+ t_outlet *x_out_im;
+} t_biquad_freq_resp;
+
+static t_class *biquad_freq_resp_class;
+
+static void biquad_freq_resp_float(t_biquad_freq_resp *x, t_float f)
+{
+ float re1, im1, re2, im2;
+ float c, s, a;
+
+ if(f < 0.0f)
+ f = 0.0f;
+ else if(f > 180.0f)
+ f = 180.0;
+ f *= 3.14159265f;
+ f /= 180.0f;
+
+ c = cos(f);
+ s = sin(f);
+
+ re1 = x->a0 + x->a1*c + x->a2*(c*c - s*s);
+ im1 = x->a1*s + x->a2*2.0f*(s*c);
+ re2 = 1.0f - x->b1*c - x->b2*(c*c - s*s);
+ im2 = -x->b1*s - x->b2*2.0f*(s*c);
+ a = re2*re2 + im2*im2;
+ outlet_float(x->x_out_im, (re1*im2 - re2*im1)/a);/* because z^-1 = e^-jwt, negative sign */
+ outlet_float(x->x_out_re, (re1*re2 + im1*im2)/a);
+
+}
+/* y/x = (a0 + a1*z-1 + a2*z-2)/(1 - b1*z-1 - b2*z-2);*/
+
+static void biquad_freq_resp_list(t_biquad_freq_resp *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if((argc == 5)&&IS_A_FLOAT(argv,4)&&IS_A_FLOAT(argv,3)&&IS_A_FLOAT(argv,2)&&IS_A_FLOAT(argv,1)&&IS_A_FLOAT(argv,0))
+ {
+ x->b1 = (float)atom_getfloatarg(0, argc, argv);
+ x->b2 = (float)atom_getfloatarg(1, argc, argv);
+ x->a0 = (float)atom_getfloatarg(2, argc, argv);
+ x->a1 = (float)atom_getfloatarg(3, argc, argv);
+ x->a2 = (float)atom_getfloatarg(4, argc, argv);
+ }
+}
+
+static void *biquad_freq_resp_new(void)
+{
+ t_biquad_freq_resp *x = (t_biquad_freq_resp *)pd_new(biquad_freq_resp_class);
+ x->x_out_re = outlet_new(&x->x_obj, &s_float);
+ x->x_out_im = outlet_new(&x->x_obj, &s_float);
+ x->b1 = 0.0f;
+ x->b2 = 0.0f;
+ x->a0 = 0.0f;
+ x->a1 = 0.0f;
+ x->a2 = 0.0f;
+ return (x);
+}
+
+void biquad_freq_resp_setup(void)
+{
+ biquad_freq_resp_class = class_new(gensym("biquad_freq_resp"), (t_newmethod)biquad_freq_resp_new, 0,
+ sizeof(t_biquad_freq_resp), 0, 0);
+ class_addfloat(biquad_freq_resp_class, biquad_freq_resp_float);
+ class_addlist(biquad_freq_resp_class, (t_method)biquad_freq_resp_list);
+ class_sethelpsymbol(biquad_freq_resp_class, gensym("iemhelp/help-biquad_freq_resp"));
+} \ No newline at end of file
diff --git a/src/iemlib1/db2v.c b/src/iemlib1/db2v.c
new file mode 100644
index 0000000..bbf1c21
--- /dev/null
+++ b/src/iemlib1/db2v.c
@@ -0,0 +1,45 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ---------------- db2v - dB to value converter. ----------------- */
+
+static t_class *db2v_class;
+
+float db2v(float f)
+{
+ return (f <= -199.9 ? 0 : exp(0.11512925465 * f));
+}
+
+static void db2v_float(t_object *x, t_float f)
+{
+ outlet_float(x->ob_outlet, db2v(f));
+}
+
+static void *db2v_new(void)
+{
+ t_object *x = (t_object *)pd_new(db2v_class);
+ outlet_new(x, &s_float);
+ return (x);
+}
+
+void db2v_setup(void)
+{
+ db2v_class = class_new(gensym("db2v"), db2v_new, 0,
+ sizeof(t_object), 0, 0);
+ class_addfloat(db2v_class, (t_method)db2v_float);
+ class_sethelpsymbol(db2v_class, gensym("iemhelp/help-db2v"));
+}
diff --git a/src/iemlib1/f2note.c b/src/iemlib1/f2note.c
new file mode 100644
index 0000000..4df6612
--- /dev/null
+++ b/src/iemlib1/f2note.c
@@ -0,0 +1,189 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ------ frequency to note plus cents converter --------- */
+
+typedef struct _f2note
+{
+ t_object x_obj;
+ void *x_outlet_midi;
+ void *x_outlet_note;
+ void *x_outlet_cent;
+ int x_centomidi;
+ float x_refhz;
+ float x_refexp;
+ float x_reflog;
+ t_symbol *x_set;
+} t_f2note;
+
+static t_class *f2note_class;
+
+float f2note_mtof(t_f2note *x, float midi)
+{
+ return(x->x_refexp * exp(0.057762265047 * midi));
+}
+
+float f2note_ftom(t_f2note *x, float freq)
+{
+ return (freq > 0 ? 17.31234049 * log(x->x_reflog * freq) : -1500);
+}
+
+void f2note_calc_ref(t_f2note *x)
+{
+ float ln2=log(2.0);
+
+ x->x_refexp = x->x_refhz*exp(-5.75*ln2);
+ x->x_reflog = 1.0/x->x_refexp;
+}
+
+static void f2note_make_note(char *str, int midi)
+{
+ int j,k,l=0;
+
+ j = midi / 12;
+ k = midi % 12;
+ if(k <= 5)
+ {
+ if(k <= 2)
+ {
+ if(k==0)
+ str[l]='c';
+ else if(k==1)
+ {
+ str[l++]='#';
+ str[l]='c';
+ }
+ else
+ str[l]='d';
+ }
+ else
+ {
+ if(k==3)
+ {
+ str[l++]='#';
+ str[l]='d';
+ }
+ else if(k==4)
+ str[l]='e';
+ else
+ str[l]='f';
+ }
+ }
+ else
+ {
+ if(k <= 8)
+ {
+ if(k==6)
+ {
+ str[l++]='#';
+ str[l]='f';
+ }
+ else if(k==7)
+ str[l]='g';
+ else
+ {
+ str[l++]='#';
+ str[l]='g';
+ }
+ }
+ else
+ {
+ if(k==9)
+ str[l]='a';
+ else if(k==10)
+ {
+ str[l++]='#';
+ str[l]='a';
+ }
+ else
+ str[l]='h';
+ }
+ }
+
+ if(j < 4)
+ {
+ str[l] -= 'a';
+ str[l] += 'A';
+ }
+ l++;
+ if(j < 3)
+ {
+ str[l++] = '0' + (char)(3 - j);
+ }
+ else if(j > 4)
+ {
+ str[l++] = '0' + (char)(j - 4);
+ }
+ str[l] = 0;
+}
+
+static void f2note_bang(t_f2note *x)
+{
+ int i,j;
+ t_atom at;
+ char s[4];
+
+ i = (x->x_centomidi + 50)/100;
+ j = x->x_centomidi - 100*i;
+ outlet_float(x->x_outlet_cent, (float)j);
+ f2note_make_note(s, i);
+ SETSYMBOL(&at, gensym(s));
+ outlet_anything(x->x_outlet_note, x->x_set, 1, &at);
+ outlet_float(x->x_outlet_midi, 0.01*(float)(x->x_centomidi));
+}
+
+static void f2note_float(t_f2note *x, t_floatarg freq)
+{
+ x->x_centomidi = (int)(100.0*f2note_ftom(x, freq) + 0.5);
+ f2note_bang(x);
+}
+
+void f2note_ref(t_f2note *x, t_floatarg ref)
+{
+ x->x_refhz = ref;
+ f2note_calc_ref(x);
+}
+
+static void *f2note_new(t_floatarg ref)
+{
+ t_f2note *x = (t_f2note *)pd_new(f2note_class);
+
+ if(ref == 0.0)
+ ref=440.0;
+ x->x_refhz = ref;
+ x->x_centomidi = (int)(100.0*ref + 0.499);
+ f2note_calc_ref(x);
+ x->x_outlet_midi = outlet_new(&x->x_obj, &s_float);
+ x->x_outlet_note = outlet_new(&x->x_obj, &s_list);
+ x->x_outlet_cent = outlet_new(&x->x_obj, &s_float);
+ x->x_set = gensym("set");
+ return (x);
+}
+
+static void f2note_free(t_f2note *x)
+{
+}
+
+void f2note_setup(void)
+{
+ f2note_class = class_new(gensym("f2note"), (t_newmethod)f2note_new, (t_method)f2note_free,
+ sizeof(t_f2note), 0, A_DEFFLOAT, 0);
+ class_addbang(f2note_class,f2note_bang);
+ class_addfloat(f2note_class,f2note_float);
+ class_addmethod(f2note_class, (t_method)f2note_ref, gensym("ref"), A_FLOAT, 0);
+ class_sethelpsymbol(f2note_class, gensym("iemhelp/help-f2note"));
+}
diff --git a/src/iemlib1/forpp.c b/src/iemlib1/forpp.c
new file mode 100644
index 0000000..3e98539
--- /dev/null
+++ b/src/iemlib1/forpp.c
@@ -0,0 +1,192 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* -------------------------- forpp ------------------------------ */
+
+typedef struct _forpp
+{
+ t_object x_obj;
+ int x_beg;
+ int x_end;
+ float x_delay;
+ int x_cur;
+ int x_incr;
+ void *x_out_end;
+ void *x_clock;
+ void *x_clock2;
+} t_forpp;
+
+static t_class *forpp_class;
+
+static void forpp_tick2(t_forpp *x)
+{
+ outlet_bang(x->x_out_end);
+ clock_unset(x->x_clock2);
+}
+
+static void forpp_tick(t_forpp *x)
+{
+ outlet_float(x->x_obj.ob_outlet, x->x_cur);
+ x->x_cur += x->x_incr;
+ if(x->x_incr > 0)
+ {
+ if(x->x_cur <= x->x_end)
+ clock_delay(x->x_clock, x->x_delay);
+ else
+ {
+ clock_unset(x->x_clock);
+ clock_delay(x->x_clock2, x->x_delay);
+ }
+ }
+ else
+ {
+ if(x->x_cur >= x->x_end)
+ clock_delay(x->x_clock, x->x_delay);
+ else
+ {
+ clock_unset(x->x_clock);
+ clock_delay(x->x_clock2, x->x_delay);
+ }
+ }
+}
+
+static void forpp_bang(t_forpp *x)
+{
+ x->x_cur = x->x_beg;
+ outlet_float(x->x_obj.ob_outlet, x->x_cur);
+ x->x_cur += x->x_incr;
+ if(x->x_incr > 0)
+ {
+ if(x->x_cur <= x->x_end)
+ clock_delay(x->x_clock, x->x_delay);
+ else
+ {
+ clock_unset(x->x_clock);
+ clock_delay(x->x_clock2, x->x_delay);
+ }
+ }
+ else
+ {
+ if(x->x_cur >= x->x_end)
+ clock_delay(x->x_clock, x->x_delay);
+ else
+ {
+ clock_unset(x->x_clock);
+ clock_delay(x->x_clock2, x->x_delay);
+ }
+ }
+
+}
+
+static void forpp_start(t_forpp *x)
+{
+ forpp_bang(x);
+}
+
+static void forpp_stop(t_forpp *x)
+{
+ if(x->x_incr > 0)
+ x->x_cur = x->x_end + 1;
+ else
+ x->x_cur = x->x_end - 1;
+ clock_unset(x->x_clock);
+ clock_unset(x->x_clock2);
+}
+
+static void forpp_float(t_forpp *x, t_float beg)
+{
+ x->x_beg = (int)beg;
+ if(x->x_end < x->x_beg)
+ x->x_incr = -1;
+ else
+ x->x_incr = 1;
+}
+
+static void forpp_ft1(t_forpp *x, t_float end)
+{
+ x->x_end = (int)end;
+ if(x->x_end < x->x_beg)
+ x->x_incr = -1;
+ else
+ x->x_incr = 1;
+}
+
+static void forpp_ft2(t_forpp *x, t_float delay)
+{
+ if(delay < 0.0)
+ delay = 0.0;
+ x->x_delay = delay;
+}
+
+static void forpp_list(t_forpp *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if(argc == 2)
+ {
+ forpp_float(x, atom_getfloatarg(0, argc, argv));
+ forpp_ft1(x, atom_getfloatarg(1, argc, argv));
+ }
+ else if(argc == 3)
+ {
+ forpp_float(x, atom_getfloatarg(0, argc, argv));
+ forpp_ft1(x, atom_getfloatarg(1, argc, argv));
+ forpp_ft2(x, atom_getfloatarg(2, argc, argv));
+ }
+}
+
+static void *forpp_new(t_floatarg beg, t_floatarg end, t_floatarg delay)
+{
+ t_forpp *x = (t_forpp *)pd_new(forpp_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2"));
+ outlet_new(&x->x_obj, &s_float);
+ x->x_out_end = outlet_new(&x->x_obj, &s_bang);
+ x->x_clock = clock_new(x, (t_method)forpp_tick);
+ x->x_clock2 = clock_new(x, (t_method)forpp_tick2);
+ x->x_beg = (int)beg;
+ x->x_end = (int)end;
+ if(x->x_end < x->x_beg)
+ x->x_incr = -1;
+ else
+ x->x_incr = 1;
+ if(delay < 0.0)
+ delay = 0.0;
+ x->x_delay = delay;
+ x->x_cur = x->x_beg;
+ return(x);
+}
+
+static void forpp_ff(t_forpp *x)
+{
+ clock_free(x->x_clock);
+ clock_free(x->x_clock2);
+}
+
+void forpp_setup(void)
+{
+ forpp_class = class_new(gensym("for++"), (t_newmethod)forpp_new,
+ (t_method)forpp_ff, sizeof(t_forpp),
+ 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addbang(forpp_class, forpp_bang);
+ class_addfloat(forpp_class, forpp_float);
+ class_addlist(forpp_class, forpp_list);
+ class_addmethod(forpp_class, (t_method)forpp_start, gensym("start"), 0);
+ class_addmethod(forpp_class, (t_method)forpp_stop, gensym("stop"), 0);
+ class_addmethod(forpp_class, (t_method)forpp_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(forpp_class, (t_method)forpp_ft2, gensym("ft2"), A_FLOAT, 0);
+ class_sethelpsymbol(forpp_class, gensym("iemhelp/help-for++"));
+}
diff --git a/src/iemlib1/gate.c b/src/iemlib1/gate.c
new file mode 100644
index 0000000..957ee07
--- /dev/null
+++ b/src/iemlib1/gate.c
@@ -0,0 +1,84 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* -------------------------- gate ------------------------------ */
+
+typedef struct _gate
+{
+ t_object x_obj;
+ float x_state;
+} t_gate;
+
+static t_class *gate_class;
+
+static void gate_bang(t_gate *x)
+{
+ if(x->x_state != 0)
+ outlet_bang(x->x_obj.ob_outlet);
+}
+
+static void gate_pointer(t_gate *x, t_gpointer *gp)
+{
+ if(x->x_state != 0)
+ outlet_pointer(x->x_obj.ob_outlet, gp);
+}
+
+static void gate_float(t_gate *x, t_floatarg f)
+{
+ if(x->x_state != 0)
+ outlet_float(x->x_obj.ob_outlet, f);
+}
+
+static void gate_symbol(t_gate *x, t_symbol *s)
+{
+ if(x->x_state != 0)
+ outlet_symbol(x->x_obj.ob_outlet, s);
+}
+
+static void gate_list(t_gate *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if(x->x_state != 0)
+ outlet_list(x->x_obj.ob_outlet, s, argc, argv);
+}
+
+static void gate_anything(t_gate *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if(x->x_state != 0)
+ outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
+}
+
+static void *gate_new(t_floatarg f)
+{
+ t_gate *x = (t_gate *)pd_new(gate_class);
+ floatinlet_new(&x->x_obj, &x->x_state);
+ outlet_new(&x->x_obj, 0);
+ x->x_state = (f==0.0)?0:1;
+ return (x);
+}
+
+void gate_setup(void)
+{
+ gate_class = class_new(gensym("gate"), (t_newmethod)gate_new, 0,
+ sizeof(t_gate), 0, A_DEFFLOAT, 0);
+ class_addbang(gate_class, gate_bang);
+ class_addpointer(gate_class, gate_pointer);
+ class_addfloat(gate_class, gate_float);
+ class_addsymbol(gate_class, gate_symbol);
+ class_addlist(gate_class, gate_list);
+ class_addanything(gate_class, gate_anything);
+ class_sethelpsymbol(gate_class, gensym("iemhelp/help-gate"));
+}
diff --git a/src/iemlib1/iemlib.h b/src/iemlib1/iemlib.h
new file mode 100644
index 0000000..cc882b1
--- /dev/null
+++ b/src/iemlib1/iemlib.h
@@ -0,0 +1,98 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#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];
+};
+
+#endif
diff --git a/src/iemlib1/iemlib1.c b/src/iemlib1/iemlib1.c
new file mode 100644
index 0000000..3700c40
--- /dev/null
+++ b/src/iemlib1/iemlib1.c
@@ -0,0 +1,82 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+
+static t_class *iemlib1_class;
+
+static void *iemlib1_new(void)
+{
+ t_object *x = (t_object *)pd_new(iemlib1_class);
+
+ return (x);
+}
+
+void biquad_freq_resp_setup(void);
+void db2v_setup(void);
+void f2note_setup(void);
+void forpp_setup(void);
+void gate_setup(void);
+void sigfilter_setup(void);
+void sigFIR_setup(void);
+void sighml_shelf_setup(void);
+void sigiem_cot4_setup(void);
+void sigiem_delay_setup(void);
+void sigiem_sqrt4_setup(void);
+void sigiem_pow4_setup(void);
+void siglp1_t_setup(void);
+void sigmov_avrg_kern_setup(void);
+void sigpara_bp2_setup(void);
+void sigpeakenv_setup(void);
+void sigprvu_setup(void);
+void sigpvu_setup(void);
+void sigrvu_setup(void);
+void sigsin_phase_setup(void);
+void sigvcf_filter_setup(void);
+void soundfile_info_setup(void);
+void split_setup(void);
+void v2db_setup(void);
+
+/* ------------------------ setup routine ------------------------- */
+
+void iemlib1_setup(void)
+{
+ iemlib1_class = class_new(gensym("iemlib1"), iemlib1_new, 0,
+ sizeof(t_object), CLASS_NOINLET, 0);
+
+ biquad_freq_resp_setup();
+ db2v_setup();
+ f2note_setup();
+ forpp_setup();
+ gate_setup();
+ sigfilter_setup();
+ sigFIR_setup();
+ sighml_shelf_setup();
+ sigiem_cot4_setup();
+ sigiem_delay_setup();
+ sigiem_sqrt4_setup();
+ sigiem_pow4_setup();
+ siglp1_t_setup();
+ sigmov_avrg_kern_setup();
+ sigpara_bp2_setup();
+ sigpeakenv_setup();
+ sigprvu_setup();
+ sigpvu_setup();
+ sigrvu_setup();
+ sigsin_phase_setup();
+ sigvcf_filter_setup();
+ soundfile_info_setup();
+ split_setup();
+ v2db_setup();
+
+ post("iemlib1 (R-1.15) library loaded!");
+}
diff --git a/src/iemlib1/iemlib1.dsp b/src/iemlib1/iemlib1.dsp
new file mode 100644
index 0000000..7d63ad2
--- /dev/null
+++ b/src/iemlib1/iemlib1.dsp
@@ -0,0 +1,85 @@
+# Microsoft Developer Studio Project File - Name="iemlib1" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) External Target" 0x0106
+
+CFG=iemlib1 - 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 "iemlib1.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 "iemlib1.mak" CFG="iemlib1 - Win32 Debug"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "iemlib1 - Win32 Release" (basierend auf "Win32 (x86) External Target")
+!MESSAGE "iemlib1 - Win32 Debug" (basierend auf "Win32 (x86) External Target")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF "$(CFG)" == "iemlib1 - 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 "iemlib1.exe"
+# PROP Bsc_Name "iemlib1.bsc"
+# PROP Target_Dir ""
+
+!ELSEIF "$(CFG)" == "iemlib1 - 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 "iemlib1.exe"
+# PROP Bsc_Name "iemlib1.bsc"
+# PROP Target_Dir ""
+
+!ENDIF
+
+# Begin Target
+
+# Name "iemlib1 - Win32 Release"
+# Name "iemlib1 - Win32 Debug"
+
+!IF "$(CFG)" == "iemlib1 - Win32 Release"
+
+!ELSEIF "$(CFG)" == "iemlib1 - Win32 Debug"
+
+!ENDIF
+
+# Begin Source File
+
+SOURCE=.\makefile_win
+# End Source File
+# End Target
+# End Project
diff --git a/src/iemlib1/iemlib1.dsw b/src/iemlib1/iemlib1.dsw
new file mode 100644
index 0000000..c8260a7
--- /dev/null
+++ b/src/iemlib1/iemlib1.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
+
+###############################################################################
+
+Project: "iemlib1"=.\iemlib1.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/src/iemlib1/makefile b/src/iemlib1/makefile
new file mode 100644
index 0000000..c8148cf
--- /dev/null
+++ b/src/iemlib1/makefile
@@ -0,0 +1,72 @@
+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 -Wall -W -Werror -Wno-unused \
+ -Wno-parentheses -Wno-switch -O6 -funroll-loops -fomit-frame-pointer \
+ -DDL_OPEN
+
+SYSTEM = $(shell uname -m)
+
+# the sources
+
+SRC = biquad_freq_resp.c \
+ db2v.c \
+ f2note.c \
+ forpp.c \
+ gate.c \
+ sigfilter.c \
+ sigFIR.c \
+ sighml_shelf.c \
+ sigiem_cot4.c \
+ sigiem_delay.c \
+ sigiem_pow4.c \
+ sigiem_sqrt4.c \
+ siglp1_t.c \
+ sigmov_avrg_kern.c \
+ sigpara_bp2.c \
+ sigpeakenv.c \
+ sigprvu.c \
+ sigpvu.c \
+ sigrvu.c \
+ sigsin_phase.c \
+ sigvcf_filter.c \
+ soundfile_info.c \
+ split.c \
+ v2db.c \
+ iemlib1.c
+
+TARGET = iemlib1.pd_linux
+
+
+OBJ = $(SRC:.c=.o)
+
+#
+# ------------------ targets ------------------------------------
+#
+
+clean:
+ rm ../../lib/$(TARGET)
+ rm *.o
+
+all: $(OBJ)
+ @echo :: $(OBJ)
+ ld $(LDFLAGS) -o $(TARGET) *.o $(LIB)
+ strip --strip-unneeded $(TARGET)
+ mv $(TARGET) ../../lib
+ rm *.o
+
+$(OBJ) : %.o : %.c
+ touch $*.c
+ cc $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c
+
+
+
+
diff --git a/src/iemlib1/makefile.darwin b/src/iemlib1/makefile.darwin
new file mode 100644
index 0000000..338310e
--- /dev/null
+++ b/src/iemlib1/makefile.darwin
@@ -0,0 +1,72 @@
+current: all
+
+.SUFFIXES: .pd_darwin
+
+INCLUDE = -I. -I/usr/local/src/pd-0.37-1test6/src
+
+LDFLAGS = -export-dynamic -shared
+LIB = -ldl -lm -lpthread
+
+#select either the DBG and OPT compiler flags below:
+
+CFLAGS = -DPD -DUNIX -g -Wall -W -Werror -Wno-unused \
+ -Wno-parentheses -Wno-switch -O2 $(INCLUDE) $(UCFLAGS) $(AFLAGS) \
+
+MACOSXLINKFLAGS = -bundle -bundle_loader /usr/local/src/pd-0.37-1test6/bin/pd
+
+SYSTEM = $(shell uname -m)
+
+# the sources
+
+SRC = biquad_freq_resp.c \
+ db2v.c \
+ f2note.c \
+ forpp.c \
+ gate.c \
+ sigfilter.c \
+ sigFIR.c \
+ sighml_shelf.c \
+ sigiem_cot4.c \
+ sigiem_delay.c \
+ sigiem_pow4.c \
+ sigiem_sqrt4.c \
+ siglp1_t.c \
+ sigmov_avrg_kern.c \
+ sigpara_bp2.c \
+ sigpeakenv.c \
+ sigprvu.c \
+ sigpvu.c \
+ sigrvu.c \
+ sigsin_phase.c \
+ sigvcf_filter.c \
+ soundfile_info.c \
+ split.c \
+ v2db.c \
+ iemlib1.c
+
+TARGET = iemlib1.pd_darwin
+
+
+OBJ = $(SRC:.c=.o)
+
+#
+# ------------------ targets ------------------------------------
+#
+
+clean:
+ rm ../../lib/$(TARGET)
+ rm *.o
+
+all: $(OBJ)
+ @echo :: $(OBJ)
+ $(CC) $(MACOSXLINKFLAGS) -o $(TARGET) *.o $(LIB)
+ strip --strip-unneeded $(TARGET)
+ mv $(TARGET) ../../lib
+
+$(OBJ) : %.o : %.c
+ touch $*.c
+ $(CC) $(CFLAGS) -DPD $(INCLUDE) -c -o $*.o $*.c
+
+
+
+
diff --git a/src/iemlib1/makefile_win b/src/iemlib1/makefile_win
new file mode 100644
index 0000000..8ab353c
--- /dev/null
+++ b/src/iemlib1/makefile_win
@@ -0,0 +1,61 @@
+
+all: ..\..\lib\iemlib1.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\pthreadVC.lib \
+ $(PD_INST_PATH)\bin\pd.lib
+
+
+SRC = biquad_freq_resp.c \
+ db2v.c \
+ f2note.c \
+ forpp.c \
+ gate.c \
+ sigfilter.c \
+ sigFIR.c \
+ sighml_shelf.c \
+ sigiem_cot4.c \
+ sigiem_delay.c \
+ sigiem_sqrt4.c \
+ sigiem_pow4.c \
+ siglp1_t.c \
+ sigmov_avrg_kern.c \
+ sigpara_bp2.c \
+ sigpeakenv.c \
+ sigprvu.c \
+ sigpvu.c \
+ sigrvu.c \
+ sigsin_phase.c \
+ sigvcf_filter.c \
+ soundfile_info.c \
+ split.c \
+ v2db.c \
+ iemlib1.c
+
+
+OBJ = $(SRC:.c=.obj)
+
+.c.obj:
+ cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c
+
+..\..\lib\iemlib1.dll: $(OBJ)
+ link $(PD_WIN_L_FLAGS) /dll /export:iemlib1_setup \
+ /out:..\..\lib\iemlib1.dll $(OBJ) $(PD_WIN_LIB)
+
+clean:
+ del *.obj
diff --git a/src/iemlib1/sigFIR.c b/src/iemlib1/sigFIR.c
new file mode 100644
index 0000000..51c9de0
--- /dev/null
+++ b/src/iemlib1/sigFIR.c
@@ -0,0 +1,177 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* ---------- FIR~ - FIR-filter with table~-coef ----------- */
+
+typedef struct sigFIR
+{
+ t_object x_obj;
+ float *x_coef_beg;
+ float *x_history_beg;
+ int x_rw_index;
+ int x_fir_order;
+ t_symbol *x_table_name;
+ float x_msi;
+} t_sigFIR;
+
+t_class *sigFIR_class;
+
+static t_int *sigFIR_perform(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *out = (float *)(w[2]);
+ t_sigFIR *x = (t_sigFIR *)(w[3]);
+ int n = (t_int)(w[4]);
+ int rw_index = x->x_rw_index;
+ int i, j;
+ int order = x->x_fir_order;
+ int ord16 = order / 16;
+ float sum=0.0f;
+ float *coef = x->x_coef_beg;
+ float *write_hist1=x->x_history_beg;
+ float *write_hist2;
+ float *read_hist;
+ float *coef_vec;
+ float *hist_vec;
+
+ if(!coef)
+ goto sigFIRperfzero;
+
+ write_hist1 = x->x_history_beg;
+ write_hist2 = write_hist1 + order;
+ read_hist = write_hist2;
+
+ for(i=0; i<n; i++)
+ {
+ write_hist1[rw_index] = in[i];
+ write_hist2[rw_index] = in[i];
+
+ sum = 0.0f;
+ coef_vec = coef;
+ hist_vec = &read_hist[rw_index];
+ for(j=0; j<ord16; j++)
+ {
+ sum += coef_vec[0] * hist_vec[0];
+ sum += coef_vec[1] * hist_vec[-1];
+ sum += coef_vec[2] * hist_vec[-2];
+ sum += coef_vec[3] * hist_vec[-3];
+ sum += coef_vec[4] * hist_vec[-4];
+ sum += coef_vec[5] * hist_vec[-5];
+ sum += coef_vec[6] * hist_vec[-6];
+ sum += coef_vec[7] * hist_vec[-7];
+ sum += coef_vec[8] * hist_vec[-8];
+ sum += coef_vec[9] * hist_vec[-9];
+ sum += coef_vec[10] * hist_vec[-10];
+ sum += coef_vec[11] * hist_vec[-11];
+ sum += coef_vec[12] * hist_vec[-12];
+ sum += coef_vec[13] * hist_vec[-13];
+ sum += coef_vec[14] * hist_vec[-14];
+ sum += coef_vec[15] * hist_vec[-15];
+ coef_vec += 16;
+ hist_vec -= 16;
+ }
+ for(j=ord16*16; j<order; j++)
+ {
+ sum += coef[j] * read_hist[rw_index-j];
+ }
+ out[i] = sum;
+
+ rw_index++;
+ if(rw_index >= order)
+ rw_index -= order;
+ }
+
+ x->x_rw_index = rw_index;
+ return(w+5);
+
+sigFIRperfzero:
+
+ while(n--)
+ *out++ = 0.0f;
+ return(w+5);
+}
+
+void sigFIR_set(t_sigFIR *x, t_symbol *table_name, t_floatarg forder)
+{
+ t_garray *ga;
+ int table_size;
+ int order = (int)forder;
+
+ x->x_table_name = table_name;
+ if(!(ga = (t_garray *)pd_findbyclass(x->x_table_name, garray_class)))
+ {
+ if(*table_name->s_name)
+ error("FIR~: %s: no such table~", x->x_table_name->s_name);
+ x->x_coef_beg = 0;
+ }
+ else if(!garray_getfloatarray(ga, &table_size, &x->x_coef_beg))
+ {
+ error("%s: bad template for FIR~", x->x_table_name->s_name);
+ x->x_coef_beg = 0;
+ }
+ else if(table_size < order)
+ {
+ error("FIR~: tablesize %d < order %d !!!!", table_size, order);
+ x->x_coef_beg = 0;
+ }
+ else
+ garray_usedindsp(ga);
+ x->x_rw_index = 0;
+ if(order > x->x_fir_order)/* resize */
+ x->x_history_beg = (float *)resizebytes(x->x_history_beg, 2*x->x_fir_order*sizeof(float), 2*order*sizeof(float));
+ x->x_fir_order = order;
+}
+
+static void sigFIR_dsp(t_sigFIR *x, t_signal **sp)
+{
+ sigFIR_set(x, x->x_table_name, x->x_fir_order);
+ dsp_add(sigFIR_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n);
+}
+
+static void *sigFIR_new(t_symbol *ref, t_floatarg np)
+{
+ t_sigFIR *x = (t_sigFIR *)pd_new(sigFIR_class);
+
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_msi = 0;
+ x->x_table_name = ref;
+ x->x_coef_beg = 0;
+ if((int)np < 1)
+ np = 1.0;
+ x->x_fir_order = (int)np;
+ x->x_history_beg = (float *)getbytes((2*x->x_fir_order)*sizeof(float));
+ x->x_rw_index = 0;
+ return(x);
+}
+
+static void sigFIR_free(t_sigFIR *x)
+{
+ if(x->x_history_beg)
+ freebytes(x->x_history_beg, (2*x->x_fir_order)*sizeof(float));
+}
+
+void sigFIR_setup(void)
+{
+ sigFIR_class = class_new(gensym("FIR~"), (t_newmethod)sigFIR_new,
+ (t_method)sigFIR_free, sizeof(t_sigFIR), 0, A_DEFSYM, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(sigFIR_class, t_sigFIR, x_msi);
+ class_addmethod(sigFIR_class, (t_method)sigFIR_dsp, gensym("dsp"), 0);
+ class_addmethod(sigFIR_class, (t_method)sigFIR_set,
+ gensym("set"), A_SYMBOL, A_FLOAT, 0);
+ class_sethelpsymbol(sigFIR_class, gensym("iemhelp/help-FIR~"));
+}
diff --git a/src/iemlib1/sigfilter.c b/src/iemlib1/sigfilter.c
new file mode 100644
index 0000000..6a05206
--- /dev/null
+++ b/src/iemlib1/sigfilter.c
@@ -0,0 +1,822 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* ---------- filter~ - slow dynamic filter 1. and 2. order ----------- */
+
+typedef struct sigfilter
+{
+ t_object x_obj;
+ float wn1;
+ float wn2;
+ float a0;
+ float a1;
+ float a2;
+ float b1;
+ float b2;
+ float sr;
+ float cur_f;
+ float cur_l;
+ float cur_a;
+ float cur_b;
+ float delta_f;
+ float delta_a;
+ float delta_b;
+ float end_f;
+ float end_a;
+ float end_b;
+ float ticks_per_interpol_time;
+ float rcp_ticks;
+ float interpol_time;
+ int ticks;
+ int counter_f;
+ int counter_a;
+ int counter_b;
+ int inv;
+ int hp;
+ int first_order;
+ int event_mask;
+ void (*calc)();
+ void *x_debug_outlet;
+ t_atom x_at[5];
+ float x_msi;
+} t_sigfilter;
+
+t_class *sigfilter_class;
+
+static void sigfilter_snafu(t_sigfilter *x)
+{
+
+}
+
+static void sigfilter_lp1(t_sigfilter *x)
+{
+ float al;
+
+ al = x->cur_a * x->cur_l;
+ x->a0 = 1.0f/(1.0f + al);
+ x->a1 = x->a0;
+ x->b1 = (al - 1.0f)*x->a0;
+}
+
+static void sigfilter_lp2(t_sigfilter *x)
+{
+ float l, al, bl2, rcp;
+
+ l = x->cur_l;
+ al = l*x->cur_a;
+ bl2 = l*l*x->cur_b + 1.0f;
+ rcp = 1.0f/(al + bl2);
+ x->a0 = rcp;
+ x->a1 = 2.0f*rcp;
+ x->a2 = x->a0;
+ x->b1 = rcp*2.0f*(bl2 - 2.0f);
+ x->b2 = rcp*(al - bl2);
+}
+
+static void sigfilter_hp1(t_sigfilter *x)
+{
+ float al, rcp;
+
+ al = x->cur_a * x->cur_l;
+ rcp = 1.0f/(1.0f + al);
+ x->a0 = rcp*al;
+ x->a1 = -x->a0;
+ x->b1 = rcp*(al - 1.0f);
+}
+
+static void sigfilter_hp2(t_sigfilter *x)
+{
+ float l, al, bl2, rcp;
+
+ l = x->cur_l;
+ bl2 = l*l*x->cur_b + 1.0f;
+ al = l*x->cur_a;
+ rcp = 1.0f/(al + bl2);
+ x->a0 = rcp*(bl2 - 1.0f);
+ x->a1 = -2.0f*x->a0;
+ x->a2 = x->a0;
+ x->b1 = rcp*2.0f*(bl2 - 2.0f);
+ x->b2 = rcp*(al - bl2);
+}
+
+static void sigfilter_rp2(t_sigfilter *x)
+{
+ float l, al, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0f;
+ al = l*x->cur_a;
+ rcp = 1.0f/(al + l2);
+ x->a0 = rcp*l;
+ x->a2 = -x->a0;
+ x->b1 = rcp*2.0f*(l2 - 2.0f);
+ x->b2 = rcp*(al - l2);
+}
+
+static void sigfilter_bp2(t_sigfilter *x)
+{
+ float l, al, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0f;
+ al = l*x->cur_a;
+ rcp = 1.0f/(al + l2);
+ x->a0 = rcp*al;
+ x->a2 = -x->a0;
+ x->b1 = rcp*2.0f*(l2 - 2.0f);
+ x->b2 = rcp*(al - l2);
+}
+
+static void sigfilter_bs2(t_sigfilter *x)
+{
+ float l, al, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0f;
+ al = l*x->cur_a;
+ rcp = 1.0f/(al + l2);
+ x->a0 = rcp*l2;
+ x->a1 = rcp*2.0f*(2.0f - l2);
+ x->a2 = x->a0;
+ x->b1 = -x->a1;
+ x->b2 = rcp*(al - l2);
+}
+
+static void sigfilter_rpw2(t_sigfilter *x)
+{
+ float l, al, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0f;
+ al = l*x->cur_a/x->cur_f;
+ rcp = 1.0f/(al + l2);
+ x->a0 = rcp*l;
+ x->a2 = -x->a0;
+ x->b1 = rcp*2.0f*(l2 - 2.0f);
+ x->b2 = rcp*(al - l2);
+}
+
+static void sigfilter_bpw2(t_sigfilter *x)
+{
+ float l, al, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0f;
+ al = l*x->cur_a/x->cur_f;
+ rcp = 1.0f/(al + l2);
+ x->a0 = rcp*al;
+ x->a2 = -x->a0;
+ x->b1 = rcp*2.0f*(l2 - 2.0f);
+ x->b2 = rcp*(al - l2);
+}
+
+static void sigfilter_bsw2(t_sigfilter *x)
+{
+ float l, al, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0f;
+ al = l*x->cur_a/x->cur_f;
+ rcp = 1.0f/(al + l2);
+ x->a0 = rcp*l2;
+ x->a1 = rcp*2.0f*(2.0f - l2);
+ x->a2 = x->a0;
+ x->b1 = -x->a1;
+ x->b2 = rcp*(al - l2);
+}
+
+static void sigfilter_ap1(t_sigfilter *x)
+{
+ float al;
+
+ al = x->cur_a * x->cur_l;
+ x->a0 = (1.0f - al)/(1.0f + al);
+ x->b1 = -x->a0;
+}
+
+static void sigfilter_ap2(t_sigfilter *x)
+{
+ float l, al, bl2, rcp;
+
+ l = x->cur_l;
+ bl2 = l*l*x->cur_b + 1.0f;
+ al = l*x->cur_a;
+ rcp = 1.0f/(al + bl2);
+ x->a1 = rcp*2.0f*(2.0f - bl2);
+ x->a0 = rcp*(bl2 - al);
+ x->b1 = -x->a1;
+ x->b2 = -x->a0;
+}
+
+/*static void sigfilter_bp2(t_sigfilter *x)
+{
+ float l, al, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0;
+ al = l*x->cur_a;
+ rcp = 1.0f/(al + l2);
+ x->a0 = rcp*al;
+ x->a2 = -x->a0;
+ x->b1 = rcp*2.0f*(2.0f - l2);
+ x->b2 = rcp*(l2 - al);
+}*/
+
+static void sigfilter_dsp_tick(t_sigfilter *x)
+{
+ if(x->event_mask)
+ {
+ if(x->counter_f)
+ {
+ float l, si, co;
+
+ if(x->counter_f <= 1)
+ {
+ x->cur_f = x->end_f;
+ x->counter_f = 0;
+ x->event_mask &= 6;/*set event_mask_bit 0 = 0*/
+ }
+ else
+ {
+ x->counter_f--;
+ x->cur_f *= x->delta_f;
+ }
+ l = x->cur_f * x->sr;
+ if(l < 1.0e-20f)
+ x->cur_l = 1.0e20f;
+ else if(l > 1.57079632f)
+ x->cur_l = 0.0f;
+ else
+ {
+ si = sin(l);
+ co = cos(l);
+ x->cur_l = co/si;
+ }
+ }
+ if(x->counter_a)
+ {
+ if(x->counter_a <= 1)
+ {
+ x->cur_a = x->end_a;
+ x->counter_a = 0;
+ x->event_mask &= 5;/*set event_mask_bit 1 = 0*/
+ }
+ else
+ {
+ x->counter_a--;
+ x->cur_a *= x->delta_a;
+ }
+ }
+ if(x->counter_b)
+ {
+ if(x->counter_b <= 1)
+ {
+ x->cur_b = x->end_b;
+ x->counter_b = 0;
+ x->event_mask &= 3;/*set event_mask_bit 2 = 0*/
+ }
+ else
+ {
+ x->counter_b--;
+ x->cur_b *= x->delta_b;
+ }
+ }
+
+ (*(x->calc))(x);
+
+ /* stability check */
+ if(x->first_order)
+ {
+ if(x->b1 <= -0.9999998f)
+ x->b1 = -0.9999998f;
+ else if(x->b1 >= 0.9999998f)
+ x->b1 = 0.9999998f;
+ }
+ else
+ {
+ float discriminant = x->b1 * x->b1 + 4.0f * x->b2;
+
+ if(x->b1 <= -1.9999996f)
+ x->b1 = -1.9999996f;
+ else if(x->b1 >= 1.9999996f)
+ x->b1 = 1.9999996f;
+
+ if(x->b2 <= -0.9999998f)
+ x->b2 = -0.9999998f;
+ else if(x->b2 >= 0.9999998f)
+ x->b2 = 0.9999998f;
+
+ if(discriminant >= 0.0f)
+ {
+ if(0.9999998f - x->b1 - x->b2 < 0.0f)
+ x->b2 = 0.9999998f - x->b1;
+ if(0.9999998f + x->b1 - x->b2 < 0.0f)
+ x->b2 = 0.9999998f + x->b1;
+ }
+ }
+ }
+}
+
+static t_int *sigfilter_perform_2o(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *out = (float *)(w[2]);
+ t_sigfilter *x = (t_sigfilter *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ float wn0, wn1=x->wn1, wn2=x->wn2;
+ float a0=x->a0, a1=x->a1, a2=x->a2;
+ float b1=x->b1, b2=x->b2;
+
+ sigfilter_dsp_tick(x);
+ for(i=0; i<n; i++)
+ {
+ wn0 = *in++ + b1*wn1 + b2*wn2;
+ *out++ = a0*wn0 + a1*wn1 + a2*wn2;
+ wn2 = wn1;
+ wn1 = wn0;
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(wn2))
+ wn2 = 0.0f;
+ if(PD_BADFLOAT(wn1))
+ wn1 = 0.0f;
+
+ x->wn1 = wn1;
+ x->wn2 = wn2;
+ return(w+5);
+}
+/* yn0 = *out;
+ xn0 = *in;
+ *************
+ yn0 = a0*xn0 + a1*xn1 + a2*xn2 + b1*yn1 + b2*yn2;
+ yn2 = yn1;
+ yn1 = yn0;
+ xn2 = xn1;
+ xn1 = xn0;
+ *************************
+ y/x = (a0 + a1*z-1 + a2*z-2)/(1 - b1*z-1 - b2*z-2);*/
+
+static t_int *sigfilter_perf8_2o(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *out = (float *)(w[2]);
+ t_sigfilter *x = (t_sigfilter *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ float wn[10];
+ float a0=x->a0, a1=x->a1, a2=x->a2;
+ float b1=x->b1, b2=x->b2;
+
+ sigfilter_dsp_tick(x);
+ wn[0] = x->wn2;
+ wn[1] = x->wn1;
+ for(i=0; i<n; i+=8, in+=8, out+=8)
+ {
+ wn[2] = in[0] + b1*wn[1] + b2*wn[0];
+ out[0] = a0*wn[2] + a1*wn[1] + a2*wn[0];
+ wn[3] = in[1] + b1*wn[2] + b2*wn[1];
+ out[1] = a0*wn[3] + a1*wn[2] + a2*wn[1];
+ wn[4] = in[2] + b1*wn[3] + b2*wn[2];
+ out[2] = a0*wn[4] + a1*wn[3] + a2*wn[2];
+ wn[5] = in[3] + b1*wn[4] + b2*wn[3];
+ out[3] = a0*wn[5] + a1*wn[4] + a2*wn[3];
+ wn[6] = in[4] + b1*wn[5] + b2*wn[4];
+ out[4] = a0*wn[6] + a1*wn[5] + a2*wn[4];
+ wn[7] = in[5] + b1*wn[6] + b2*wn[5];
+ out[5] = a0*wn[7] + a1*wn[6] + a2*wn[5];
+ wn[8] = in[6] + b1*wn[7] + b2*wn[6];
+ out[6] = a0*wn[8] + a1*wn[7] + a2*wn[6];
+ wn[9] = in[7] + b1*wn[8] + b2*wn[7];
+ out[7] = a0*wn[9] + a1*wn[8] + a2*wn[7];
+ wn[0] = wn[8];
+ wn[1] = wn[9];
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(wn[0]))
+ wn[0] = 0.0f;
+ if(PD_BADFLOAT(wn[1]))
+ wn[1] = 0.0f;
+
+ x->wn1 = wn[1];
+ x->wn2 = wn[0];
+ return(w+5);
+}
+
+static t_int *sigfilter_perform_1o(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *out = (float *)(w[2]);
+ t_sigfilter *x = (t_sigfilter *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ float wn0, wn1=x->wn1;
+ float a0=x->a0, a1=x->a1;
+ float b1=x->b1;
+
+ sigfilter_dsp_tick(x);
+ for(i=0; i<n; i++)
+ {
+ wn0 = *in++ + b1*wn1;
+ *out++ = a0*wn0 + a1*wn1;
+ wn1 = wn0;
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(wn1))
+ wn1 = 0.0f;
+
+ x->wn1 = wn1;
+ return(w+5);
+}
+
+static t_int *sigfilter_perf8_1o(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *out = (float *)(w[2]);
+ t_sigfilter *x = (t_sigfilter *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ float wn[9];
+ float a0=x->a0, a1=x->a1;
+ float b1=x->b1;
+
+ sigfilter_dsp_tick(x);
+ wn[0] = x->wn1;
+ for(i=0; i<n; i+=8, in+=8, out+=8)
+ {
+ wn[1] = in[0] + b1*wn[0];
+ out[0] = a0*wn[1] + a1*wn[0];
+ wn[2] = in[1] + b1*wn[1];
+ out[1] = a0*wn[2] + a1*wn[1];
+ wn[3] = in[2] + b1*wn[2];
+ out[2] = a0*wn[3] + a1*wn[2];
+ wn[4] = in[3] + b1*wn[3];
+ out[3] = a0*wn[4] + a1*wn[3];
+ wn[5] = in[4] + b1*wn[4];
+ out[4] = a0*wn[5] + a1*wn[4];
+ wn[6] = in[5] + b1*wn[5];
+ out[5] = a0*wn[6] + a1*wn[5];
+ wn[7] = in[6] + b1*wn[6];
+ out[6] = a0*wn[7] + a1*wn[6];
+ wn[8] = in[7] + b1*wn[7];
+ out[7] = a0*wn[8] + a1*wn[7];
+ wn[0] = wn[8];
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(wn[0]))
+ wn[0] = 0.0f;
+
+ x->wn1 = wn[0];
+ return(w+5);
+}
+
+static void sigfilter_ft4(t_sigfilter *x, t_floatarg t)
+{
+ int i = (int)((x->ticks_per_interpol_time)*t+0.49999f);
+
+ x->interpol_time = t;
+ if(i <= 0)
+ {
+ x->ticks = 1;
+ x->rcp_ticks = 1.0;
+ }
+ else
+ {
+ x->ticks = i;
+ x->rcp_ticks = 1.0 / (float)i;
+ }
+}
+
+static void sigfilter_ft3(t_sigfilter *x, t_floatarg b)
+{
+ if(b <= 0.0f)
+ b = 0.000001f;
+ if(x->hp)
+ b = 1.0 / b;
+ if(b != x->cur_b)
+ {
+ x->end_b = b;
+ x->counter_b = x->ticks;
+ x->delta_b = exp(log(b/x->cur_b)*x->rcp_ticks);
+ x->event_mask |= 4;/*set event_mask_bit 2 = 1*/
+ }
+}
+
+static void sigfilter_ft2(t_sigfilter *x, t_floatarg a)
+{
+ if(a <= 0.0f)
+ a = 0.000001f;
+ if(x->inv)
+ a = 1.0f / a;
+ if(x->hp)
+ a /= x->cur_b;
+ if(a != x->cur_a)
+ {
+ x->end_a = a;
+ x->counter_a = x->ticks;
+ x->delta_a = exp(log(a/x->cur_a)*x->rcp_ticks);
+ x->event_mask |= 2;/*set event_mask_bit 1 = 1*/
+ }
+}
+
+static void sigfilter_ft1(t_sigfilter *x, t_floatarg f)
+{
+ if(f <= 0.0f)
+ f = 0.000001f;
+ if(f != x->cur_f)
+ {
+ x->end_f = f;
+ x->counter_f = x->ticks;
+ x->delta_f = exp(log(f/x->cur_f)*x->rcp_ticks);
+ x->event_mask |= 1;/*set event_mask_bit 0 = 1*/
+ }
+}
+
+static void sigfilter_print(t_sigfilter *x)
+{
+// post("fb1 = %g, fb2 = %g, ff1 = %g, ff2 = %g, ff3 = %g", x->b1, x->b2, x->a0, x->a1, x->a2);
+ x->x_at[0].a_w.w_float = x->b1;
+ x->x_at[1].a_w.w_float = x->b2;
+ x->x_at[2].a_w.w_float = x->a0;
+ x->x_at[3].a_w.w_float = x->a1;
+ x->x_at[4].a_w.w_float = x->a2;
+ outlet_list(x->x_debug_outlet, &s_list, 5, x->x_at);
+}
+
+static void sigfilter_dsp(t_sigfilter *x, t_signal **sp)
+{
+ float si, co, f;
+ int i, n=(int)sp[0]->s_n;
+
+ x->sr = 3.14159265358979323846f / (float)(sp[0]->s_sr);
+ x->ticks_per_interpol_time = 0.001f * (float)(sp[0]->s_sr) / (float)n;
+ i = (int)((x->ticks_per_interpol_time)*(x->interpol_time)+0.49999f);
+ if(i <= 0)
+ {
+ x->ticks = 1;
+ x->rcp_ticks = 1.0f;
+ }
+ else
+ {
+ x->ticks = i;
+ x->rcp_ticks = 1.0f / (float)i;
+ }
+ f = x->cur_f * x->sr;
+ if(f < 1.0e-20f)
+ x->cur_l = 1.0e20f;
+ else if(f > 1.57079632f)
+ x->cur_l = 0.0f;
+ else
+ {
+ si = sin(f);
+ co = cos(f);
+ x->cur_l = co/si;
+ }
+ if(x->first_order)
+ {
+ if(n&7)
+ dsp_add(sigfilter_perform_1o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+ else
+ dsp_add(sigfilter_perf8_1o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+ }
+ else
+ {
+ if(n&7)
+ dsp_add(sigfilter_perform_2o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+ else
+ dsp_add(sigfilter_perf8_2o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+ }
+}
+
+static void *sigfilter_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_sigfilter *x = (t_sigfilter *)pd_new(sigfilter_class);
+ char *filt_name;
+ int i;
+ float si, co, f=0.0f, a=0.0f, b=0.0f, interpol=0.0f;
+ t_symbol *filt_typ=gensym("");
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft3"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft4"));
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_debug_outlet = outlet_new(&x->x_obj, &s_list);
+ x->x_msi = 0.0f;
+
+ x->x_at[0].a_type = A_FLOAT;
+ x->x_at[1].a_type = A_FLOAT;
+ x->x_at[2].a_type = A_FLOAT;
+ x->x_at[3].a_type = A_FLOAT;
+ x->x_at[4].a_type = A_FLOAT;
+
+ x->event_mask = 1;
+ x->counter_f = 1;
+ x->counter_a = 0;
+ x->counter_b = 0;
+ x->delta_f = 0.0f;
+ x->delta_a = 0.0f;
+ x->delta_b = 0.0f;
+ x->interpol_time = 0.0f;
+ x->wn1 = 0.0f;
+ x->wn2 = 0.0f;
+ x->a0 = 0.0f;
+ x->a1 = 0.0f;
+ x->a2 = 0.0f;
+ x->b1 = 0.0f;
+ x->b2 = 0.0f;
+ x->sr = 3.14159265358979323846f / 44100.0f;
+ x->calc = sigfilter_snafu;
+ x->first_order = 0;
+ if((argc == 5)&&IS_A_FLOAT(argv,4)&&IS_A_FLOAT(argv,3)&&IS_A_FLOAT(argv,2)&&IS_A_FLOAT(argv,1)&&IS_A_SYMBOL(argv,0))
+ {
+ filt_typ = atom_getsymbolarg(0, argc, argv);
+ f = (float)atom_getfloatarg(1, argc, argv);
+ a = (float)atom_getfloatarg(2, argc, argv);
+ b = (float)atom_getfloatarg(3, argc, argv);
+ interpol = (float)atom_getfloatarg(4, argc, argv);
+ }
+ filt_name = (char *)filt_typ->s_name;
+ x->cur_f = f;
+ f *= x->sr;
+ if(f < 1.0e-20f)
+ x->cur_l = 1.0e20f;
+ else if(f > 1.57079632f)
+ x->cur_l = 0.0f;
+ else
+ {
+ si = sin(f);
+ co = cos(f);
+ x->cur_l = co/si;
+ }
+ if(a <= 0.0f)
+ a = 0.000001f;
+ if(b <= 0.0f)
+ b = 0.000001f;
+ x->cur_b = b;
+
+ if(interpol <= 0.0f)
+ interpol = 0.0f;
+ x->interpol_time = interpol;
+ x->ticks_per_interpol_time = 0.001f * 44100.0f / 64.0f;
+ i = (int)((x->ticks_per_interpol_time)*(x->interpol_time)+0.49999f);
+ if(i <= 0)
+ {
+ x->ticks = 1;
+ x->rcp_ticks = 1.0f;
+ }
+ else
+ {
+ x->ticks = i;
+ x->rcp_ticks = 1.0f / (float)i;
+ }
+
+ x->calc = sigfilter_snafu;
+
+ x->cur_a = 1.0f/a; /*a was Q*/
+ x->inv = 1;
+ x->hp = 0;
+
+ if(filt_name)
+ {
+ if(!strcmp(filt_name,"ap1"))
+ {
+ x->calc = sigfilter_ap1;
+ x->a1 = 1.0f;
+ x->first_order = 1;
+ }
+ else if(!strcmp(filt_name,"ap2"))
+ {
+ x->calc = sigfilter_ap2;
+ x->a2 = 1.0f;
+ }
+ else if(!strcmp(filt_name,"ap1c"))
+ {
+ x->calc = sigfilter_ap1;
+ x->a1 = 1.0f;
+ x->inv = 0;
+ x->cur_a = a; /*a was damping*/
+ x->first_order = 1;
+ }
+ else if(!strcmp(filt_name,"ap2c"))
+ {
+ x->calc = sigfilter_ap2;
+ x->a2 = 1.0f;
+ x->inv = 0;
+ x->cur_a = a; /*a was damping*/
+ }
+ else if(!strcmp(filt_name,"bpq2"))
+ {
+ x->calc = sigfilter_bp2;
+ }
+ else if(!strcmp(filt_name,"rbpq2"))
+ {
+ x->calc = sigfilter_rp2;
+ }
+ else if(!strcmp(filt_name,"bsq2"))
+ {
+ x->calc = sigfilter_bs2;
+ }
+ else if(!strcmp(filt_name,"bpw2"))
+ {
+ x->calc = sigfilter_bpw2;
+ x->inv = 0;
+ x->cur_a = a; /*a was bw*/
+ }
+ else if(!strcmp(filt_name,"rbpw2"))
+ {
+ x->calc = sigfilter_rpw2;
+ x->inv = 0;
+ x->cur_a = a; /*a was bw*/
+ }
+ else if(!strcmp(filt_name,"bsw2"))
+ {
+ x->calc = sigfilter_bsw2;
+ x->inv = 0;
+ x->cur_a = a; /*a was bw*/
+ }
+ else if(!strcmp(filt_name,"hp1"))
+ {
+ x->calc = sigfilter_hp1;
+ x->first_order = 1;
+ }
+ else if(!strcmp(filt_name,"hp2"))
+ {
+ x->calc = sigfilter_hp2;
+ }
+ else if(!strcmp(filt_name,"lp1"))
+ {
+ x->calc = sigfilter_lp1;
+ x->first_order = 1;
+ }
+ else if(!strcmp(filt_name,"lp2"))
+ {
+ x->calc = sigfilter_lp2;
+ }
+ else if(!strcmp(filt_name,"hp1c"))
+ {
+ x->calc = sigfilter_hp1;
+ x->cur_a = 1.0f / a;
+ x->first_order = 1;
+ }
+ else if(!strcmp(filt_name,"hp2c"))
+ {
+ x->calc = sigfilter_hp2;
+ x->inv = 0;
+ x->cur_a = a / b;
+ x->cur_b = 1.0f / b;
+ x->hp = 1;
+ }
+ else if(!strcmp(filt_name,"lp1c"))
+ {
+ x->calc = sigfilter_lp1;
+ x->inv = 0;
+ x->cur_a = a; /*a was damping*/
+ x->first_order = 1;
+ }
+ else if(!strcmp(filt_name,"lp2c"))
+ {
+ x->calc = sigfilter_lp2;
+ x->inv = 0;
+ x->cur_a = a; /*a was damping*/
+ }
+ else
+ {
+ post("filter~-Error: 1. initial-arguments: <sym> kind: \
+ lp1, lp2, hp1, hp2, \
+ lp1c, lp2c, hp1c, hp2c, \
+ ap1, ap2, ap1c, ap2c, \
+ bpq2, rbpq2, bsq2, \
+ bpw2, rbpw2, bsw2!");
+ }
+ x->end_f = x->cur_f;
+ x->end_a = x->cur_a;
+ x->end_b = x->cur_b;
+ }
+ return (x);
+}
+
+void sigfilter_setup(void)
+{
+ sigfilter_class = class_new(gensym("filter~"), (t_newmethod)sigfilter_new,
+ 0, sizeof(t_sigfilter), 0, A_GIMME, 0);
+ CLASS_MAINSIGNALIN(sigfilter_class, t_sigfilter, x_msi);
+ class_addmethod(sigfilter_class, (t_method)sigfilter_dsp, gensym("dsp"), 0);
+ class_addmethod(sigfilter_class, (t_method)sigfilter_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(sigfilter_class, (t_method)sigfilter_ft2, gensym("ft2"), A_FLOAT, 0);
+ class_addmethod(sigfilter_class, (t_method)sigfilter_ft3, gensym("ft3"), A_FLOAT, 0);
+ class_addmethod(sigfilter_class, (t_method)sigfilter_ft4, gensym("ft4"), A_FLOAT, 0);
+ class_addmethod(sigfilter_class, (t_method)sigfilter_print, gensym("print"), 0);
+ class_sethelpsymbol(sigfilter_class, gensym("iemhelp/help-filter~"));
+}
diff --git a/src/iemlib1/sighml_shelf.c b/src/iemlib1/sighml_shelf.c
new file mode 100644
index 0000000..ef209d1
--- /dev/null
+++ b/src/iemlib1/sighml_shelf.c
@@ -0,0 +1,558 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* ---------- hml_shelf~ - high-middle-low-shelving filter ----------- */
+
+typedef struct sighml_shelf
+{
+ t_object x_obj;
+ float wn1;
+ float wn2;
+ float a0;
+ float a1;
+ float a2;
+ float b1;
+ float b2;
+ float sr;
+ float cur_lf;
+ float cur_hf;
+ float cur_lg;
+ float cur_mg;
+ float cur_hg;
+ float delta_lf;
+ float delta_hf;
+ float delta_lg;
+ float delta_mg;
+ float delta_hg;
+ float end_lf;
+ float end_hf;
+ float end_lg;
+ float end_mg;
+ float end_hg;
+ float ticks_per_interpol_time;
+ float rcp_ticks;
+ float interpol_time;
+ int ticks;
+ int counter_lf;
+ int counter_hf;
+ int counter_lg;
+ int counter_mg;
+ int counter_hg;
+ int event_mask;
+ void *x_debug_outlet;
+ t_atom x_at[5];
+ float x_msi;
+} t_sighml_shelf;
+
+t_class *sighml_shelf_class;
+
+static void sighml_shelf_calc(t_sighml_shelf *x)
+{
+ float rf = x->cur_hf/x->cur_lf;
+ float mf = x->cur_hf*x->cur_lf;
+ float lg = x->cur_lg;
+ float rcplg = 1.0f/lg;
+ float mg = x->cur_mg;
+ float rcpmg = 1.0f/mg;
+ float hg = x->cur_hg;
+ float rcphg = 1.0f/hg;
+ float f = mf*x->sr;
+ float l = cos(f)/sin(f);
+ float k1 = rf*l;
+ float k2 = l/rf;
+ float k3 = l*l;
+ float k4 = k3*hg;
+ float k5 = k3*rcphg;
+ float k6 = rcplg + k5;
+ float k7 = rcpmg*k1 + k2*rcplg*rcphg*mg;
+ float k8 = lg + k4;
+ float k9 = mg*k1 + k2*lg*hg*rcpmg;
+ float k10 = 1.0f/(k6 + k7);
+
+ x->b2 = k10*(k7 - k6);
+ x->b1 = k10*2.0f*(k5 - rcplg);
+ x->a2 = k10*(k8 - k9);
+ x->a1 = k10*2.0f*(lg - k4);
+ x->a0 = k10*(k8 + k9);
+}
+/*
+high- & low- shelving-filter:
+L....sqrt(lowlevel);
+rL...rsqrt(lowlevel);
+M....sqrt(mediumlevel);
+rM...rsqrt(mediumlevel);
+H....sqrt(highlevel);
+rH...rsqrt(highlevel);
+V....sqrt(highfrequency/lowfrequency);
+P....j*2*pi*f/(2*pi*V*lowfrequency);
+
+Y/X = [M/(1/M)] * [(L/M + PV)/(M/L + PV)] * [(1 + HP/(VM))/(1 + MP/(VH))];
+Y/X = (L + P*(M*V + L*H/(V*M)) + P*P*H) / (rL + P*(rM*V + rL*rH/(V*rM)) + P*P*rH);
+
+hlshlv: lowlevel: ll; mediumlevel: lm; highlevel: hl; lowfrequency: fl; highfrequency: fh; samplerate: sr;
+ {
+ V = sqrt(fh/fl);
+ f = fl*V;
+ L = sqrt(ll);
+ rL = 1.0/L;
+ M = sqrt(lm);
+ rM = 1.0/M;
+ H = sqrt(lh);
+ rH = 1.0/H;
+
+ l = cot(f*3.14159265358979323846/sr);
+ k1 = V*l;
+ k2 = l/V;
+ l2 = l*l;
+ l3 = l2*H;
+ l4 = l2*rH;
+ m1 = k2*L*H*rM;
+ m2 = k2*rL*rH*M;
+ n1 = rL + l4;
+ n2 = rM*k1 + m2;
+ p1 = L + l3;
+ p2 = M*k1 + m1;
+ a012 = 1.0/(n1 + n2);
+
+ b2 = a012*(n2 - n1);
+ b1 = a012*2.0*(l4 - rL);
+ a2 = a012*(p1 - p2);
+ a1 = a012*2.0*(L - l3);
+ a0 = a012*(p1 + p2);
+
+
+
+
+
+
+ rf = sqrt(fh/fl);
+ mf = fl*rf;
+ L = sqrt(ll);
+ rL = 1.0/L;
+ M = sqrt(lm);
+ rM = 1.0/M;
+ H = sqrt(lh);
+ rH = 1.0/H;
+
+ l = cot(fm*3.14159265358979323846/sr);
+ k1 = V*l;
+ k2 = l/V;
+ k3 = l*l;
+ k4 = k3*H;
+ k5 = k3*rH;
+ k6 = rL + k5;
+ k7 = rM*k1 + k2*rL*rH*M;
+ k8 = L + k4;
+ k9 = M*k1 + k2*L*H*rM;
+ k10 = 1.0/(k6 + k7);
+
+ b2 = k10*(k7 - k6);
+ b1 = k10*2.0*(k5 - rL);
+ a2 = k10*(k8 - k9);
+ a1 = k10*2.0*(L - k4);
+ a0 = k10*(k8 + k9);
+*/
+
+static void sighml_shelf_dsp_tick(t_sighml_shelf *x)
+{
+ if(x->event_mask)
+ {
+ float discriminant;
+
+ if(x->counter_lg)
+ {
+ if(x->counter_lg <= 1)
+ {
+ x->cur_lg = x->end_lg;
+ x->counter_lg = 0;
+ x->event_mask &= 30;/*set event_mask_bit 0 = 0*/
+ }
+ else
+ {
+ x->counter_lg--;
+ x->cur_lg *= x->delta_lg;
+ }
+ }
+ if(x->counter_lf)
+ {
+ if(x->counter_lf <= 1)
+ {
+ x->cur_lf = x->end_lf;
+ x->counter_lf = 0;
+ x->event_mask &= 29;/*set event_mask_bit 1 = 0*/
+ }
+ else
+ {
+ x->counter_lf--;
+ x->cur_lf *= x->delta_lf;
+ }
+ }
+ if(x->counter_mg)
+ {
+ if(x->counter_mg <= 1)
+ {
+ x->cur_mg = x->end_mg;
+ x->counter_mg = 0;
+ x->event_mask &= 27;/*set event_mask_bit 2 = 0*/
+ }
+ else
+ {
+ x->counter_mg--;
+ x->cur_mg *= x->delta_mg;
+ }
+ }
+ if(x->counter_hf)
+ {
+ if(x->counter_hf <= 1)
+ {
+ x->cur_hf = x->end_hf;
+ x->counter_hf = 0;
+ x->event_mask &= 23;/*set event_mask_bit 3 = 0*/
+ }
+ else
+ {
+ x->counter_hf--;
+ x->cur_hf *= x->delta_hf;
+ }
+ }
+ if(x->counter_hg)
+ {
+ if(x->counter_hg <= 1)
+ {
+ x->cur_hg = x->end_hg;
+ x->counter_hg = 0;
+ x->event_mask &= 15;/*set event_mask_bit 4 = 0*/
+ }
+ else
+ {
+ x->counter_hg--;
+ x->cur_hg *= x->delta_hg;
+ }
+ }
+ sighml_shelf_calc(x);
+
+ /* stability check */
+
+ discriminant = x->b1 * x->b1 + 4.0f * x->b2;
+ if(x->b1 <= -1.9999996f)
+ x->b1 = -1.9999996f;
+ else if(x->b1 >= 1.9999996f)
+ x->b1 = 1.9999996f;
+
+ if(x->b2 <= -0.9999998f)
+ x->b2 = -0.9999998f;
+ else if(x->b2 >= 0.9999998f)
+ x->b2 = 0.9999998f;
+
+ if(discriminant >= 0.0f)
+ {
+ if(0.9999998f - x->b1 - x->b2 < 0.0f)
+ x->b2 = 0.9999998f - x->b1;
+ if(0.9999998f + x->b1 - x->b2 < 0.0f)
+ x->b2 = 0.9999998f + x->b1;
+ }
+ }
+}
+
+static t_int *sighml_shelf_perform(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *out = (float *)(w[2]);
+ t_sighml_shelf *x = (t_sighml_shelf *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ float wn0, wn1=x->wn1, wn2=x->wn2;
+ float a0=x->a0, a1=x->a1, a2=x->a2;
+ float b1=x->b1, b2=x->b2;
+
+ sighml_shelf_dsp_tick(x);
+ for(i=0; i<n; i++)
+ {
+ wn0 = *in++ + b1*wn1 + b2*wn2;
+ *out++ = a0*wn0 + a1*wn1 + a2*wn2;
+ wn2 = wn1;
+ wn1 = wn0;
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(wn2))
+ wn2 = 0.0f;
+ if(PD_BADFLOAT(wn1))
+ wn1 = 0.0f;
+
+ x->wn1 = wn1;
+ x->wn2 = wn2;
+ return(w+5);
+}
+/* yn0 = *out;
+ xn0 = *in;
+ *************
+ yn0 = a0*xn0 + a1*xn1 + a2*xn2 + b1*yn1 + b2*yn2;
+ yn2 = yn1;
+ yn1 = yn0;
+ xn2 = xn1;
+ xn1 = xn0;
+ *************************
+ y/x = (a0 + a1*z-1 + a2*z-2)/(1 - b1*z-1 - b2*z-2);*/
+
+static t_int *sighml_shelf_perf8(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *out = (float *)(w[2]);
+ t_sighml_shelf *x = (t_sighml_shelf *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ float wn[10];
+ float a0=x->a0, a1=x->a1, a2=x->a2;
+ float b1=x->b1, b2=x->b2;
+
+ sighml_shelf_dsp_tick(x);
+ wn[0] = x->wn2;
+ wn[1] = x->wn1;
+ for(i=0; i<n; i+=8, in+=8, out+=8)
+ {
+ wn[2] = in[0] + b1*wn[1] + b2*wn[0];
+ out[0] = a0*wn[2] + a1*wn[1] + a2*wn[0];
+ wn[3] = in[1] + b1*wn[2] + b2*wn[1];
+ out[1] = a0*wn[3] + a1*wn[2] + a2*wn[1];
+ wn[4] = in[2] + b1*wn[3] + b2*wn[2];
+ out[2] = a0*wn[4] + a1*wn[3] + a2*wn[2];
+ wn[5] = in[3] + b1*wn[4] + b2*wn[3];
+ out[3] = a0*wn[5] + a1*wn[4] + a2*wn[3];
+ wn[6] = in[4] + b1*wn[5] + b2*wn[4];
+ out[4] = a0*wn[6] + a1*wn[5] + a2*wn[4];
+ wn[7] = in[5] + b1*wn[6] + b2*wn[5];
+ out[5] = a0*wn[7] + a1*wn[6] + a2*wn[5];
+ wn[8] = in[6] + b1*wn[7] + b2*wn[6];
+ out[6] = a0*wn[8] + a1*wn[7] + a2*wn[6];
+ wn[9] = in[7] + b1*wn[8] + b2*wn[7];
+ out[7] = a0*wn[9] + a1*wn[8] + a2*wn[7];
+ wn[0] = wn[8];
+ wn[1] = wn[9];
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(wn[0]))
+ wn[0] = 0.0f;
+ if(PD_BADFLOAT(wn[1]))
+ wn[1] = 0.0f;
+
+ x->wn1 = wn[1];
+ x->wn2 = wn[0];
+ return(w+5);
+}
+
+static void sighml_shelf_ft6(t_sighml_shelf *x, t_floatarg t)
+{
+ int i = (int)((x->ticks_per_interpol_time)*t);
+
+ x->interpol_time = t;
+ if(i <= 0)
+ i = 1;
+ x->ticks = i;
+ x->rcp_ticks = 1.0f / (float)i;
+}
+
+static void sighml_shelf_ft5(t_sighml_shelf *x, t_floatarg hl)
+{
+ float hg = exp(0.057564627325 * hl);
+
+ if(hg != x->cur_hg)
+ {
+ x->end_hg = hg;
+ x->counter_hg = x->ticks;
+ x->delta_hg = exp(log(hg/x->cur_hg)*x->rcp_ticks);
+ x->event_mask |= 16;/*set event_mask_bit 4 = 1*/
+ }
+}
+
+static void sighml_shelf_ft4(t_sighml_shelf *x, t_floatarg hf)
+{
+ float sqhf;
+
+ if(hf <= 0.0f)
+ hf = 0.000001f;
+ sqhf = sqrt(hf);
+ if(sqhf != x->cur_hf)
+ {
+ x->end_hf = sqhf;
+ x->counter_hf = x->ticks;
+ x->delta_hf = exp(log(sqhf/x->cur_hf)*x->rcp_ticks);
+ x->event_mask |= 8;/*set event_mask_bit 3 = 1*/
+ }
+}
+
+static void sighml_shelf_ft3(t_sighml_shelf *x, t_floatarg ml)
+{
+ float mg = exp(0.057564627325 * ml);
+
+ if(mg != x->cur_mg)
+ {
+ x->end_mg = mg;
+ x->counter_mg = x->ticks;
+ x->delta_mg = exp(log(mg/x->cur_mg)*x->rcp_ticks);
+ x->event_mask |= 4;/*set event_mask_bit 2 = 1*/
+ }
+}
+
+static void sighml_shelf_ft2(t_sighml_shelf *x, t_floatarg lf)
+{
+ float sqlf;
+
+ if(lf <= 0.0f)
+ lf = 0.000001f;
+ sqlf = sqrt(lf);
+ if(sqlf != x->cur_lf)
+ {
+ x->end_lf = sqlf;
+ x->counter_lf = x->ticks;
+ x->delta_lf = exp(log(sqlf/x->cur_lf)*x->rcp_ticks);
+ x->event_mask |= 2;/*set event_mask_bit 1 = 1*/
+ }
+}
+
+static void sighml_shelf_ft1(t_sighml_shelf *x, t_floatarg ll)
+{
+ float lg = exp(0.057564627325 * ll);
+
+ if(lg != x->cur_lg)
+ {
+ x->end_lg = lg;
+ x->counter_lg = x->ticks;
+ x->delta_lg = exp(log(lg/x->cur_lg)*x->rcp_ticks);
+ x->event_mask |= 1;/*set event_mask_bit 0 = 1*/
+ }
+}
+
+static void sighml_shelf_print(t_sighml_shelf *x)
+{
+// post("fb1 = %g, fb2 = %g, ff1 = %g, ff2 = %g, ff3 = %g", x->b1, x->b2, x->a0, x->a1, x->a2);
+ x->x_at[0].a_w.w_float = x->b1;
+ x->x_at[1].a_w.w_float = x->b2;
+ x->x_at[2].a_w.w_float = x->a0;
+ x->x_at[3].a_w.w_float = x->a1;
+ x->x_at[4].a_w.w_float = x->a2;
+ outlet_list(x->x_debug_outlet, &s_list, 5, x->x_at);
+}
+
+static void sighml_shelf_dsp(t_sighml_shelf *x, t_signal **sp)
+{
+ int i, n=(int)sp[0]->s_n;
+
+ x->sr = 3.14159265358979323846f / (float)(sp[0]->s_sr);
+ x->ticks_per_interpol_time = 0.001f * (float)(sp[0]->s_sr) / (float)n;
+ i = (int)((x->ticks_per_interpol_time)*(x->interpol_time));
+ if(i <= 0)
+ i = 1;
+ x->ticks = i;
+ x->rcp_ticks = 1.0f / (float)i;
+ if(n&7)
+ dsp_add(sighml_shelf_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+ else
+ dsp_add(sighml_shelf_perf8, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+}
+
+static void *sighml_shelf_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_sighml_shelf *x = (t_sighml_shelf *)pd_new(sighml_shelf_class);
+ int i;
+ float lf=200.0f, hf=2000.0f, ll=0.0f, ml=0.0f, hl=0.0f, interpol=0.0f;
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft3"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft4"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft5"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft6"));
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_debug_outlet = outlet_new(&x->x_obj, &s_list);
+ x->x_msi = 0;
+
+ x->x_at[0].a_type = A_FLOAT;
+ x->x_at[1].a_type = A_FLOAT;
+ x->x_at[2].a_type = A_FLOAT;
+ x->x_at[3].a_type = A_FLOAT;
+ x->x_at[4].a_type = A_FLOAT;
+
+ x->event_mask = 2;
+ x->counter_lg = 0;
+ x->counter_lf = 1;
+ x->counter_mg = 0;
+ x->counter_hf = 0;
+ x->counter_hg = 0;
+ x->delta_lg = 0.0f;
+ x->delta_lf = 0.0f;
+ x->delta_mg = 0.0f;
+ x->delta_hf = 0.0f;
+ x->delta_hg = 0.0f;
+ x->interpol_time = 0.0f;
+ x->wn1 = 0.0f;
+ x->wn2 = 0.0f;
+ x->a0 = 0.0f;
+ x->a1 = 0.0f;
+ x->a2 = 0.0f;
+ x->b1 = 0.0f;
+ x->b2 = 0.0f;
+ x->sr = 3.14159265358979323846f / 44100.0f;
+ if((argc == 6)&&IS_A_FLOAT(argv,5)&&IS_A_FLOAT(argv,4)&&IS_A_FLOAT(argv,3)
+ &&IS_A_FLOAT(argv,2)&&IS_A_FLOAT(argv,1)&&IS_A_FLOAT(argv,0))
+ {
+ ll = (float)atom_getfloatarg(0, argc, argv);
+ lf = (float)atom_getfloatarg(1, argc, argv);
+ ml = (float)atom_getfloatarg(2, argc, argv);
+ hf = (float)atom_getfloatarg(3, argc, argv);
+ hl = (float)atom_getfloatarg(4, argc, argv);
+ interpol = (float)atom_getfloatarg(5, argc, argv);
+ }
+ x->cur_lg = exp(0.057564627325 * ll);
+ x->cur_mg = exp(0.057564627325 * ml);
+ x->cur_hg = exp(0.057564627325 * hl);
+ if(lf <= 0.0f)
+ lf = 0.000001f;
+ if(hf <= 0.0f)
+ hf = 0.000001f;
+ x->cur_lf = sqrt(lf);
+ x->cur_hf = sqrt(hf);
+ if(interpol < 0.0f)
+ interpol = 0.0f;
+ x->interpol_time = interpol;
+ x->ticks_per_interpol_time = 0.5f;
+ i = (int)((x->ticks_per_interpol_time)*(x->interpol_time));
+ if(i <= 0)
+ i = 1;
+ x->ticks = i;
+ x->rcp_ticks = 1.0f / (float)i;
+ x->end_lf = x->cur_lf;
+ x->end_hf = x->cur_hf;
+ x->end_lg = x->cur_lg;
+ x->end_mg = x->cur_mg;
+ x->end_hg = x->cur_hg;
+ return(x);
+}
+
+void sighml_shelf_setup(void)
+{
+ sighml_shelf_class = class_new(gensym("hml_shelf~"), (t_newmethod)sighml_shelf_new,
+ 0, sizeof(t_sighml_shelf), 0, A_GIMME, 0);
+ CLASS_MAINSIGNALIN(sighml_shelf_class, t_sighml_shelf, x_msi);
+ class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_dsp, gensym("dsp"), 0);
+ class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_ft2, gensym("ft2"), A_FLOAT, 0);
+ class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_ft3, gensym("ft3"), A_FLOAT, 0);
+ class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_ft4, gensym("ft4"), A_FLOAT, 0);
+ class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_ft5, gensym("ft5"), A_FLOAT, 0);
+ class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_ft6, gensym("ft6"), A_FLOAT, 0);
+ class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_print, gensym("print"), 0);
+ class_sethelpsymbol(sighml_shelf_class, gensym("iemhelp/help-hml_shelf~"));
+}
diff --git a/src/iemlib1/sigiem_cot4.c b/src/iemlib1/sigiem_cot4.c
new file mode 100644
index 0000000..b0990d9
--- /dev/null
+++ b/src/iemlib1/sigiem_cot4.c
@@ -0,0 +1,176 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ------------------------ iem_cot4~ ----------------------------- */
+
+float *iem_cot4_table_cos=(float *)0L;
+float *iem_cot4_table_sin=(float *)0L;
+
+static t_class *sigiem_cot4_class;
+
+typedef struct _sigiem_cot4
+{
+ t_object x_obj;
+ float x_sr;
+ float x_msi;
+} t_sigiem_cot4;
+
+static t_int *sigiem_cot4_perform(t_int *w)
+{
+ t_float *in = (t_float *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_float norm_freq;
+ t_float hout;
+ t_sigiem_cot4 *x = (t_sigiem_cot4 *)(w[3]);
+ t_float sr=x->x_sr;
+ int n = (int)(w[4]);
+ float *ctab = iem_cot4_table_cos, *stab = iem_cot4_table_sin;
+ float *caddr, *saddr, cf1, cf2, sf1, sf2, frac;
+ double dphase;
+ int normhipart;
+ int32 mytfi;
+ union tabfudge tf;
+
+ tf.tf_d = UNITBIT32;
+ normhipart = tf.tf_i[HIOFFSET];
+
+#if 0 /* this is the readable version of the code. */
+ while (n--)
+ {
+ norm_freq = *in * sr;
+ if(norm_freq < 0.0001f)
+ norm_freq = 0.0001f;
+ else if(norm_freq > 0.9f)
+ norm_freq = 0.9f;
+ dphase = (double)(norm_freq * (float)(COSTABSIZE)) + UNITBIT32;
+ tf.tf_d = dphase;
+ mytfi = tf.tf_i[HIOFFSET] & (COSTABSIZE-1);
+ saddr = stab + (mytfi);
+ caddr = ctab + (mytfi);
+ tf.tf_i[HIOFFSET] = normhipart;
+ frac = tf.tf_d - UNITBIT32;
+ sf1 = saddr[0];
+ sf2 = saddr[1];
+ cf1 = caddr[0];
+ cf2 = caddr[1];
+ in++;
+ *out++ = (cf1 + frac * (cf2 - cf1))/(sf1 + frac * (sf2 - sf1));
+ }
+#endif
+#if 1 /* this is the same, unwrapped by hand. prolog beg*/
+ n /= 4;
+ norm_freq = *in * sr;
+ if(norm_freq < 0.0001f)
+ norm_freq = 0.0001f;
+ else if(norm_freq > 0.9f)
+ norm_freq = 0.9f;
+ dphase = (double)(norm_freq * (float)(COSTABSIZE)) + UNITBIT32;
+ tf.tf_d = dphase;
+ mytfi = tf.tf_i[HIOFFSET] & (COSTABSIZE-1);
+ saddr = stab + (mytfi);
+ caddr = ctab + (mytfi);
+ tf.tf_i[HIOFFSET] = normhipart;
+ in += 4; /*prolog end*/
+ while (--n)
+ {
+ norm_freq = *in * sr;
+ if(norm_freq < 0.0001f)
+ norm_freq = 0.0001f;
+ else if(norm_freq > 0.9f)
+ norm_freq = 0.9f;
+ dphase = (double)(norm_freq * (float)(COSTABSIZE)) + UNITBIT32;
+ frac = tf.tf_d - UNITBIT32;
+ tf.tf_d = dphase;
+ sf1 = saddr[0];
+ sf2 = saddr[1];
+ cf1 = caddr[0];
+ cf2 = caddr[1];
+ mytfi = tf.tf_i[HIOFFSET] & (COSTABSIZE-1);
+ saddr = stab + (mytfi);
+ caddr = ctab + (mytfi);
+ hout = (cf1 + frac * (cf2 - cf1))/(sf1 + frac * (sf2 - sf1));
+ *out++ = hout;
+ *out++ = hout;
+ *out++ = hout;
+ *out++ = hout;
+ in += 4;
+ tf.tf_i[HIOFFSET] = normhipart;
+ }/*epilog beg*/
+ frac = tf.tf_d - UNITBIT32;
+ sf1 = saddr[0];
+ sf2 = saddr[1];
+ cf1 = caddr[0];
+ cf2 = caddr[1];
+ hout = (cf1 + frac * (cf2 - cf1))/(sf1 + frac * (sf2 - sf1));
+ *out++ = hout;
+ *out++ = hout;
+ *out++ = hout;
+ *out++ = hout;
+ /*epilog end*/
+#endif
+ return (w+5);
+}
+
+static void sigiem_cot4_dsp(t_sigiem_cot4 *x, t_signal **sp)
+{
+ x->x_sr = 2.0f / (float)sp[0]->s_sr;
+ dsp_add(sigiem_cot4_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n);
+}
+
+static void sigiem_cot4_maketable(void)
+{
+ int i;
+ float *fp, phase, fff, phsinc = 0.5*3.141592653 / ((float)COSTABSIZE);
+ union tabfudge tf;
+
+ if(!iem_cot4_table_sin)
+ {
+ iem_cot4_table_sin = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+ for(i=COSTABSIZE+1, fp=iem_cot4_table_sin, phase=0; i--; fp++, phase+=phsinc)
+ *fp = sin(phase);
+ }
+ if(!iem_cot4_table_cos)
+ {
+ iem_cot4_table_cos = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+ for(i=COSTABSIZE+1, fp=iem_cot4_table_cos, phase=0; i--; fp++, phase+=phsinc)
+ *fp = cos(phase);
+ }
+ tf.tf_d = UNITBIT32 + 0.5;
+ if((unsigned)tf.tf_i[LOWOFFSET] != 0x80000000)
+ bug("iem_cot4~: unexpected machine alignment");
+}
+
+static void *sigiem_cot4_new(void)
+{
+ t_sigiem_cot4 *x = (t_sigiem_cot4 *)pd_new(sigiem_cot4_class);
+
+ outlet_new(&x->x_obj, gensym("signal"));
+ x->x_msi = 0;
+ return (x);
+}
+
+void sigiem_cot4_setup(void)
+{
+ sigiem_cot4_class = class_new(gensym("iem_cot4~"), (t_newmethod)sigiem_cot4_new, 0,
+ sizeof(t_sigiem_cot4), 0, 0);
+ class_addcreator((t_newmethod)sigiem_cot4_new, gensym("iem_cot~"), 0);
+ CLASS_MAINSIGNALIN(sigiem_cot4_class, t_sigiem_cot4, x_msi);
+ class_addmethod(sigiem_cot4_class, (t_method)sigiem_cot4_dsp, gensym("dsp"), 0);
+ sigiem_cot4_maketable();
+ class_sethelpsymbol(sigiem_cot4_class, gensym("iemhelp/help-iem_cot4~"));
+}
+
diff --git a/src/iemlib1/sigiem_delay.c b/src/iemlib1/sigiem_delay.c
new file mode 100644
index 0000000..56afbf3
--- /dev/null
+++ b/src/iemlib1/sigiem_delay.c
@@ -0,0 +1,208 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil (c) IEM KUG Graz Austria 2002 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* -------------------------- sigiem_delay~ ------------------------------ */
+static t_class *sigiem_delay_class;
+
+#define IEMDELAY_DEF_VEC_SIZE 64
+
+typedef struct _sigiem_delay
+{
+ t_object x_obj;
+ int x_mallocsize;
+ t_float x_max_delay_ms;
+ t_float x_current_delay_ms;
+ t_float *x_begmem1;
+ t_float *x_begmem2;
+ int x_writeindex;
+ int x_blocksize;
+ int x_delay_samples;
+ t_float x_sr;
+ t_float x_msi;
+} t_sigiem_delay;
+
+static void sigiem_delay_cur_del(t_sigiem_delay *x, t_floatarg f)
+{
+ if(f < 0.0f)
+ f = 0.0f;
+ else if(f > x->x_max_delay_ms)
+ f = x->x_max_delay_ms;
+ x->x_current_delay_ms = f;
+ x->x_delay_samples = (int)(0.001f*x->x_sr * f + 0.5f);
+}
+
+static t_int *sigiem_delay_perform(t_int *w)
+{
+ t_float *in = (t_float *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_sigiem_delay *x = (t_sigiem_delay *)(w[3]);
+ int n=(int)(w[4]);
+ int writeindex = x->x_writeindex;
+ t_float *vec1, *vec2, *vec3;
+
+ vec1 = x->x_begmem1 + writeindex;
+ vec2 = x->x_begmem2 + writeindex;
+ vec3 = x->x_begmem2 + writeindex - x->x_delay_samples;
+ writeindex += n;
+ while(n--)
+ {
+ *vec1++ = *vec2++ = *in++;
+ *out++ = *vec3++;
+ }
+ if(writeindex >= x->x_mallocsize)
+ {
+ writeindex -= x->x_mallocsize;
+ }
+ x->x_writeindex = writeindex;
+ return(w+5);
+}
+
+static t_int *sigiem_delay_perf8(t_int *w)
+{
+ t_float *in = (t_float *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_sigiem_delay *x = (t_sigiem_delay *)(w[3]);
+ int i, n=(int)(w[4]);
+ int writeindex = x->x_writeindex;
+ t_float *vec1, *vec2;
+
+ vec1 = x->x_begmem1 + writeindex;
+ vec2 = x->x_begmem2 + writeindex;
+ for(i=0; i<n; i+=8)
+ {
+ *vec1++ = *vec2++ = *in++;
+ *vec1++ = *vec2++ = *in++;
+ *vec1++ = *vec2++ = *in++;
+ *vec1++ = *vec2++ = *in++;
+ *vec1++ = *vec2++ = *in++;
+ *vec1++ = *vec2++ = *in++;
+ *vec1++ = *vec2++ = *in++;
+ *vec1++ = *vec2++ = *in++;
+ }
+
+ vec2 = x->x_begmem2 + writeindex - x->x_delay_samples;
+ for(i=0; i<n; i+=8)
+ {
+ *out++ = *vec2++;
+ *out++ = *vec2++;
+ *out++ = *vec2++;
+ *out++ = *vec2++;
+ *out++ = *vec2++;
+ *out++ = *vec2++;
+ *out++ = *vec2++;
+ *out++ = *vec2++;
+ }
+
+ writeindex += n;
+ if(writeindex >= x->x_mallocsize)
+ {
+ writeindex -= x->x_mallocsize;
+ }
+ x->x_writeindex = writeindex;
+ return(w+5);
+}
+
+static void sigiem_delay_dsp(t_sigiem_delay *x, t_signal **sp)
+{
+ int blocksize = sp[0]->s_n, i;
+
+ if(!x->x_blocksize)/*first time*/
+ {
+ int nsamps = x->x_max_delay_ms * (t_float)sp[0]->s_sr * 0.001f;
+
+ if(nsamps < 1)
+ nsamps = 1;
+ nsamps += ((- nsamps) & (blocksize - 1));
+ nsamps += blocksize;
+ x->x_mallocsize = nsamps;
+ x->x_begmem1 = (t_float *)getbytes(2 * x->x_mallocsize * sizeof(t_float));
+ x->x_begmem2 = x->x_begmem1 + x->x_mallocsize;
+ post("beginn = %x", (unsigned long)x->x_begmem1);
+ x->x_writeindex = blocksize;
+ x->x_sr = (t_float)sp[0]->s_sr;
+ x->x_blocksize = blocksize;
+ x->x_delay_samples = (int)(0.001f*x->x_sr * x->x_current_delay_ms + 0.5f);
+ }
+ else if((x->x_blocksize != blocksize) || ((t_float)sp[0]->s_sr != x->x_sr))
+ {
+ int nsamps = x->x_max_delay_ms * (t_float)sp[0]->s_sr * 0.001f;
+
+ if(nsamps < 1)
+ nsamps = 1;
+ nsamps += ((- nsamps) & (blocksize - 1));
+ nsamps += blocksize;
+
+ x->x_begmem1 = (t_float *)resizebytes(x->x_begmem1, 2*x->x_mallocsize*sizeof(t_float), 2*nsamps*sizeof(t_float));
+ x->x_mallocsize = nsamps;
+ x->x_begmem2 = x->x_begmem1 + x->x_mallocsize;
+ post("beginn = %x", (unsigned long)x->x_begmem1);
+ if(x->x_writeindex >= nsamps)
+ x->x_writeindex -= nsamps;
+ x->x_sr = (t_float)sp[0]->s_sr;
+ x->x_blocksize = blocksize;
+ x->x_delay_samples = (int)(0.001f*x->x_sr * x->x_current_delay_ms + 0.5f);
+ }
+
+ if(blocksize&7)
+ dsp_add(sigiem_delay_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, blocksize);
+ else
+ dsp_add(sigiem_delay_perf8, 4, sp[0]->s_vec, sp[1]->s_vec, x, blocksize);
+}
+
+static void *sigiem_delay_new(t_floatarg max_delay_ms, t_floatarg current_delay_ms)
+{
+ t_sigiem_delay *x = (t_sigiem_delay *)pd_new(sigiem_delay_class);
+ int nsamps;
+
+ if(max_delay_ms < 2.0f)
+ max_delay_ms = 2.0f;
+ x->x_max_delay_ms = max_delay_ms;
+ if(current_delay_ms < 0.0f)
+ current_delay_ms = 0.0f;
+ else if(current_delay_ms > max_delay_ms)
+ current_delay_ms = max_delay_ms;
+ x->x_current_delay_ms = current_delay_ms;
+ nsamps = max_delay_ms * sys_getsr() * 0.001f;
+ if(nsamps < 1)
+ nsamps = 1;
+ nsamps += ((- nsamps) & (IEMDELAY_DEF_VEC_SIZE - 1));
+ nsamps += IEMDELAY_DEF_VEC_SIZE;
+ x->x_mallocsize = nsamps;
+ x->x_begmem1 = (t_float *)getbytes(2 * x->x_mallocsize * sizeof(t_float));
+ x->x_begmem2 = x->x_begmem1 + x->x_mallocsize;
+ x->x_writeindex = IEMDELAY_DEF_VEC_SIZE;
+ x->x_blocksize = 0;
+ x->x_sr = 0.0f;
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_msi = 0.0f;
+ return (x);
+}
+
+static void sigiem_delay_free(t_sigiem_delay *x)
+{
+ freebytes(x->x_begmem1, 2 * x->x_mallocsize * sizeof(t_float));
+}
+
+void sigiem_delay_setup(void)
+{
+ sigiem_delay_class = class_new(gensym("iem_delay~"), (t_newmethod)sigiem_delay_new, (t_method)sigiem_delay_free,
+ sizeof(t_sigiem_delay), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(sigiem_delay_class, t_sigiem_delay, x_msi);
+ class_addmethod(sigiem_delay_class, (t_method)sigiem_delay_dsp, gensym("dsp"), 0);
+ class_addmethod(sigiem_delay_class, (t_method)sigiem_delay_cur_del, gensym("ft1"), A_FLOAT, 0);
+}
diff --git a/src/iemlib1/sigiem_pow4.c b/src/iemlib1/sigiem_pow4.c
new file mode 100644
index 0000000..ae5334c
--- /dev/null
+++ b/src/iemlib1/sigiem_pow4.c
@@ -0,0 +1,86 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ------------------------ iem_pow4~ ----------------------------- */
+
+static t_class *sigiem_pow4_class;
+
+typedef struct _sigiem_pow4
+{
+ t_object x_obj;
+ float x_exp;
+ float x_msi;
+} t_sigiem_pow4;
+
+static void sigiem_pow4_ft1(t_sigiem_pow4 *x, t_floatarg f)
+{
+ x->x_exp = f;
+}
+
+static t_int *sigiem_pow4_perform(t_int *w)
+{
+ t_float *in = (t_float *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_sigiem_pow4 *x = (t_sigiem_pow4 *)(w[3]);
+ t_float y=x->x_exp;
+ t_float f, g;
+ int n = (int)(w[4])/4;
+
+ while (n--)
+ {
+ f = *in;
+ if(f < 0.01f)
+ f = 0.01f;
+ else if(f > 1000.0f)
+ f = 1000.0f;
+ g = log(f);
+ f = exp(g*y);
+ *out++ = f;
+ *out++ = f;
+ *out++ = f;
+ *out++ = f;
+ in += 4;
+ }
+ return (w+5);
+}
+
+static void sigiem_pow4_dsp(t_sigiem_pow4 *x, t_signal **sp)
+{
+ dsp_add(sigiem_pow4_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n);
+}
+
+static void *sigiem_pow4_new(t_floatarg f)
+{
+ t_sigiem_pow4 *x = (t_sigiem_pow4 *)pd_new(sigiem_pow4_class);
+
+ x->x_exp = f;
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ outlet_new(&x->x_obj, gensym("signal"));
+ x->x_msi = 0;
+ return (x);
+}
+
+void sigiem_pow4_setup(void)
+{
+ sigiem_pow4_class = class_new(gensym("iem_pow4~"), (t_newmethod)sigiem_pow4_new, 0,
+ sizeof(t_sigiem_pow4), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)sigiem_pow4_new, gensym("icot~"), 0);
+ CLASS_MAINSIGNALIN(sigiem_pow4_class, t_sigiem_pow4, x_msi);
+ class_addmethod(sigiem_pow4_class, (t_method)sigiem_pow4_dsp, gensym("dsp"), 0);
+ class_addmethod(sigiem_pow4_class, (t_method)sigiem_pow4_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_sethelpsymbol(sigiem_pow4_class, gensym("iemhelp/help-iem_pow4~"));
+}
diff --git a/src/iemlib1/sigiem_sqrt4.c b/src/iemlib1/sigiem_sqrt4.c
new file mode 100644
index 0000000..49d9982
--- /dev/null
+++ b/src/iemlib1/sigiem_sqrt4.c
@@ -0,0 +1,117 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#define IEMSQRT4TAB1SIZE 256
+#define IEMSQRT4TAB2SIZE 1024
+
+/* ------------------------ iem_sqrt4~ ----------------------------- */
+
+float *iem_sqrt4_exptab=(float *)0L;
+float *iem_sqrt4_mantissatab=(float *)0L;
+
+static t_class *sigiem_sqrt4_class;
+
+typedef struct _sigiem_sqrt4
+{
+ t_object x_obj;
+ float x_msi;
+} t_sigiem_sqrt4;
+
+static t_int *sigiem_sqrt4_perform(t_int *w)
+{
+ t_float *in = (t_float *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_int n = (t_int)(w[3])/4;
+
+ while(n--)
+ {
+ float f = *in;
+ float g, h;
+ long l = *(long *)(in);
+
+ if(f < 0.0f)
+ {
+ *out++ = 0.0f;
+ *out++ = 0.0f;
+ *out++ = 0.0f;
+ *out++ = 0.0f;
+ }
+ else
+ {
+ g = iem_sqrt4_exptab[(l >> 23) & 0xff] * iem_sqrt4_mantissatab[(l >> 13) & 0x3ff];
+ h = f * (1.5f * g - 0.5f * g * g * g * f);
+ *out++ = h;
+ *out++ = h;
+ *out++ = h;
+ *out++ = h;
+ }
+ in += 4;
+ }
+ return(w+4);
+}
+
+static void sigiem_sqrt4_dsp(t_sigiem_sqrt4 *x, t_signal **sp)
+{
+ dsp_add(sigiem_sqrt4_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+static void sigiem_sqrt4_maketable(void)
+{
+ int i;
+ float f;
+ long l;
+
+ if(!iem_sqrt4_exptab)
+ {
+ iem_sqrt4_exptab = (float *)getbytes(sizeof(float) * IEMSQRT4TAB1SIZE);
+ for(i=0; i<IEMSQRT4TAB1SIZE; i++)
+ {
+ l = (i ? (i == IEMSQRT4TAB1SIZE-1 ? IEMSQRT4TAB1SIZE-2 : i) : 1)<< 23;
+ *(long *)(&f) = l;
+ iem_sqrt4_exptab[i] = 1.0f/sqrt(f);
+ }
+ }
+ if(!iem_sqrt4_mantissatab)
+ {
+ iem_sqrt4_mantissatab = (float *)getbytes(sizeof(float) * IEMSQRT4TAB2SIZE);
+ for(i=0; i<IEMSQRT4TAB2SIZE; i++)
+ {
+ f = 1.0f + (1.0f/(float)IEMSQRT4TAB2SIZE) * (float)i;
+ iem_sqrt4_mantissatab[i] = 1.0f/sqrt(f);
+ }
+ }
+}
+
+static void *sigiem_sqrt4_new(void)
+{
+ t_sigiem_sqrt4 *x = (t_sigiem_sqrt4 *)pd_new(sigiem_sqrt4_class);
+
+ outlet_new(&x->x_obj, gensym("signal"));
+ x->x_msi = 0;
+ return (x);
+}
+
+void sigiem_sqrt4_setup(void)
+{
+ sigiem_sqrt4_class = class_new(gensym("iem_sqrt4~"), (t_newmethod)sigiem_sqrt4_new, 0,
+ sizeof(t_sigiem_sqrt4), 0, 0);
+ CLASS_MAINSIGNALIN(sigiem_sqrt4_class, t_sigiem_sqrt4, x_msi);
+ class_addmethod(sigiem_sqrt4_class, (t_method)sigiem_sqrt4_dsp, gensym("dsp"), 0);
+ sigiem_sqrt4_maketable();
+ class_sethelpsymbol(sigiem_sqrt4_class, gensym("iemhelp/help-iem_sqrt4~"));
+}
+
diff --git a/src/iemlib1/siglp1_t.c b/src/iemlib1/siglp1_t.c
new file mode 100644
index 0000000..060d988
--- /dev/null
+++ b/src/iemlib1/siglp1_t.c
@@ -0,0 +1,219 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -- lp1_t~ - slow dynamic lowpass-filter 1. order with tau input --- */
+
+typedef struct siglp1_t
+{
+ t_object x_obj;
+ float yn1;
+ float c0;
+ float c1;
+ float sr;
+ float cur_t;
+ float delta_t;
+ float end_t;
+ float ticks_per_interpol_time;
+ float rcp_ticks;
+ float interpol_time;
+ int ticks;
+ int counter_t;
+ float x_msi;
+} t_siglp1_t;
+
+t_class *siglp1_t_class;
+
+static void siglp1_t_dsp_tick(t_siglp1_t *x)
+{
+ if(x->counter_t)
+ {
+ if(x->counter_t <= 1)
+ {
+ x->cur_t = x->end_t;
+ x->counter_t = 0;
+ }
+ else
+ {
+ x->counter_t--;
+ x->cur_t += x->delta_t;
+ }
+ if(x->cur_t == 0.0f)
+ x->c1 = 0.0f;
+ else
+ x->c1 = exp((x->sr)/x->cur_t);
+ x->c0 = 1.0f - x->c1;
+ }
+}
+
+static t_int *siglp1_t_perform(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *out = (float *)(w[2]);
+ t_siglp1_t *x = (t_siglp1_t *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ float yn0, yn1=x->yn1;
+ float c0=x->c0, c1=x->c1;
+
+ siglp1_t_dsp_tick(x);
+ for(i=0; i<n; i++)
+ {
+ yn0 = (*in++)*c0 + yn1*c1;
+ *out++ = yn0;
+ yn1 = yn0;
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(yn1))
+ yn1 = 0.0f;
+ x->yn1 = yn1;
+ return(w+5);
+}
+
+static t_int *siglp1_t_perf8(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *out = (float *)(w[2]);
+ t_siglp1_t *x = (t_siglp1_t *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ float yn[9];
+ float c0=x->c0, c1=x->c1;
+
+ siglp1_t_dsp_tick(x);
+ yn[0] = x->yn1;
+ for(i=0; i<n; i+=8, in+=8, out+=8)
+ {
+ yn[1] = in[0]*c0 + yn[0]*c1;
+ out[0] = yn[1];
+ yn[2] = in[1]*c0 + yn[1]*c1;
+ out[1] = yn[2];
+ yn[3] = in[2]*c0 + yn[2]*c1;
+ out[2] = yn[3];
+ yn[4] = in[3]*c0 + yn[3]*c1;
+ out[3] = yn[4];
+ yn[5] = in[4]*c0 + yn[4]*c1;
+ out[4] = yn[5];
+ yn[6] = in[5]*c0 + yn[5]*c1;
+ out[5] = yn[6];
+ yn[7] = in[6]*c0 + yn[6]*c1;
+ out[6] = yn[7];
+ yn[8] = in[7]*c0 + yn[7]*c1;
+ out[7] = yn[8];
+ yn[0] = yn[8];
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(yn[0]))
+ yn[0] = 0.0f;
+
+ x->yn1 = yn[0];
+ return(w+5);
+}
+
+static void siglp1_t_ft2(t_siglp1_t *x, t_floatarg t)
+{
+ int i = (int)((x->ticks_per_interpol_time)*t);
+
+ x->interpol_time = t;
+ if(i <= 0)
+ i = 1;
+ x->ticks = i;
+ x->rcp_ticks = 1.0f / (float)i;
+}
+
+static void siglp1_t_ft1(t_siglp1_t *x, t_floatarg time_const)
+{
+ if(time_const < 0.0f)
+ time_const = 0.0f;
+ if(time_const != x->cur_t)
+ {
+ x->end_t = time_const;
+ x->counter_t = x->ticks;
+ x->delta_t = (time_const - x->cur_t) * x->rcp_ticks;
+ }
+}
+
+static void siglp1_t_dsp(t_siglp1_t *x, t_signal **sp)
+{
+ int i, n=(int)sp[0]->s_n;
+
+ x->sr = -1000.0f / (float)(sp[0]->s_sr);
+ x->ticks_per_interpol_time = 0.001f * (float)(sp[0]->s_sr) / (float)n;
+ i = (int)((x->ticks_per_interpol_time)*(x->interpol_time));
+ if(i <= 0)
+ i = 1;
+ x->ticks = i;
+ x->rcp_ticks = 1.0f / (float)i;
+ if(x->cur_t == 0.0f)
+ x->c1 = 0.0f;
+ else
+ x->c1 = exp((x->sr)/x->cur_t);
+ x->c0 = 1.0f - x->c1;
+ if(n&7)
+ dsp_add(siglp1_t_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+ else
+ dsp_add(siglp1_t_perf8, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+}
+
+static void *siglp1_t_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_siglp1_t *x = (t_siglp1_t *)pd_new(siglp1_t_class);
+ int i;
+ float time_const=0.0f, interpol=0.0f;
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2"));
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_msi = 0;
+ x->counter_t = 1;
+ x->delta_t = 0.0f;
+ x->interpol_time = 0.0f;
+ x->yn1 = 0.0f;
+ x->sr = -1.0f / 44.1f;
+ if((argc >= 1)&&IS_A_FLOAT(argv,0))
+ time_const = (float)atom_getfloatarg(0, argc, argv);
+ if((argc >= 2)&&IS_A_FLOAT(argv,1))
+ interpol = (float)atom_getfloatarg(1, argc, argv);
+ if(time_const < 0.0f)
+ time_const = 0.0f;
+ x->cur_t = time_const;
+ if(time_const == 0.0f)
+ x->c1 = 0.0f;
+ else
+ x->c1 = exp((x->sr)/time_const);
+ x->c0 = 1.0f - x->c1;
+ if(interpol < 0.0f)
+ interpol = 0.0f;
+ x->interpol_time = interpol;
+ x->ticks_per_interpol_time = 0.5f;
+ i = (int)((x->ticks_per_interpol_time)*(x->interpol_time));
+ if(i <= 0)
+ i = 1;
+ x->ticks = i;
+ x->rcp_ticks = 1.0f / (float)i;
+ x->end_t = x->cur_t;
+ return (x);
+}
+
+void siglp1_t_setup(void)
+{
+ siglp1_t_class = class_new(gensym("lp1_t~"), (t_newmethod)siglp1_t_new,
+ 0, sizeof(t_siglp1_t), 0, A_GIMME, 0);
+ CLASS_MAINSIGNALIN(siglp1_t_class, t_siglp1_t, x_msi);
+ class_addmethod(siglp1_t_class, (t_method)siglp1_t_dsp, gensym("dsp"), 0);
+ class_addmethod(siglp1_t_class, (t_method)siglp1_t_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(siglp1_t_class, (t_method)siglp1_t_ft2, gensym("ft2"), A_FLOAT, 0);
+ class_sethelpsymbol(siglp1_t_class, gensym("iemhelp/help-lp1_t~"));
+}
diff --git a/src/iemlib1/sigmov_avrg_kern.c b/src/iemlib1/sigmov_avrg_kern.c
new file mode 100644
index 0000000..1c77a49
--- /dev/null
+++ b/src/iemlib1/sigmov_avrg_kern.c
@@ -0,0 +1,143 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -- mov_avrg_kern~ - kernel for a moving-average-filter with IIR - */
+
+typedef struct sigmov_avrg_kern
+{
+ t_object x_obj;
+ double x_wn1;
+ double x_a0;
+ double x_sr;
+ double x_mstime;
+ int x_nsamps;
+ int x_counter;
+ float x_msi;
+} t_sigmov_avrg_kern;
+
+t_class *sigmov_avrg_kern_class;
+
+static t_int *sigmov_avrg_kern_perform(t_int *w)
+{
+ float *in_direct = (float *)(w[1]);
+ float *in_delayed = (float *)(w[2]);
+ float *out = (float *)(w[3]);
+ t_sigmov_avrg_kern *x = (t_sigmov_avrg_kern *)(w[4]);
+ int i, n = (int)(w[5]);
+ double wn0, wn1=x->x_wn1, a0=x->x_a0;
+
+ if(x->x_counter)
+ {
+ int counter = x->x_counter;
+
+ if(counter >= n)
+ {
+ x->x_counter = counter - n;
+ for(i=0; i<n; i++)
+ {
+ wn0 = wn1 + a0*(double)(*in_direct++);
+ *out++ = (float)wn0;
+ wn1 = wn0;
+ }
+ }
+ else
+ {
+ x->x_counter = 0;
+ for(i=0; i<counter; i++)
+ {
+ wn0 = wn1 + a0*(double)(*in_direct++);
+ *out++ = (float)wn0;
+ wn1 = wn0;
+ }
+ for(i=counter; i<n; i++)
+ {
+ wn0 = wn1 + a0*(double)(*in_direct++ - *in_delayed++);
+ *out++ = (float)wn0;
+ wn1 = wn0;
+ }
+ }
+ }
+ else
+ {
+ for(i=0; i<n; i++)
+ {
+ wn0 = wn1 + a0*(double)(*in_direct++ - *in_delayed++);
+ *out++ = (float)wn0;
+ wn1 = wn0;
+ }
+ }
+ x->x_wn1 = wn1;
+ return(w+6);
+}
+
+static void sigmov_avrg_kern_ft1(t_sigmov_avrg_kern *x, t_floatarg mstime)
+{
+ if(mstime < 0.04)
+ mstime = 0.04;
+ x->x_mstime = (double)mstime;
+ x->x_nsamps = (int)(x->x_sr * x->x_mstime);
+ x->x_counter = x->x_nsamps;
+ x->x_wn1 = 0.0;
+ x->x_a0 = 1.0/(double)(x->x_nsamps);
+}
+
+static void sigmov_avrg_kern_reset(t_sigmov_avrg_kern *x)
+{
+ x->x_counter = x->x_nsamps;
+ x->x_wn1 = 0.0;
+}
+
+static void sigmov_avrg_kern_dsp(t_sigmov_avrg_kern *x, t_signal **sp)
+{
+ x->x_sr = 0.001*(double)(sp[0]->s_sr);
+ x->x_nsamps = (int)(x->x_sr * x->x_mstime);
+ x->x_counter = x->x_nsamps;
+ x->x_wn1 = 0.0;
+ x->x_a0 = 1.0/(double)(x->x_nsamps);
+ dsp_add(sigmov_avrg_kern_perform, 5, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, x, sp[0]->s_n);
+}
+
+static void *sigmov_avrg_kern_new(t_floatarg mstime)
+{
+ t_sigmov_avrg_kern *x = (t_sigmov_avrg_kern *)pd_new(sigmov_avrg_kern_class);
+
+ if(mstime < 0.04)
+ mstime = 0.04;
+ x->x_mstime = (double)mstime;
+ x->x_sr = 44.1;
+ x->x_nsamps = (int)(x->x_sr * x->x_mstime);
+ x->x_counter = x->x_nsamps;
+ x->x_wn1 = 0.0;
+ x->x_a0 = 1.0/(double)(x->x_nsamps);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_msi = 0;
+ return(x);
+}
+
+void sigmov_avrg_kern_setup(void)
+{
+ sigmov_avrg_kern_class = class_new(gensym("mov_avrg_kern~"), (t_newmethod)sigmov_avrg_kern_new,
+ 0, sizeof(t_sigmov_avrg_kern), 0, A_FLOAT, 0);
+ CLASS_MAINSIGNALIN(sigmov_avrg_kern_class, t_sigmov_avrg_kern, x_msi);
+ class_addmethod(sigmov_avrg_kern_class, (t_method)sigmov_avrg_kern_dsp, gensym("dsp"), 0);
+ class_addmethod(sigmov_avrg_kern_class, (t_method)sigmov_avrg_kern_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(sigmov_avrg_kern_class, (t_method)sigmov_avrg_kern_reset, gensym("reset"), 0);
+}
diff --git a/src/iemlib1/sigpara_bp2.c b/src/iemlib1/sigpara_bp2.c
new file mode 100644
index 0000000..871191e
--- /dev/null
+++ b/src/iemlib1/sigpara_bp2.c
@@ -0,0 +1,426 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* ---------- para_bp2~ - parametric bandpass 2. order ----------- */
+
+typedef struct sigpara_bp2
+{
+ t_object x_obj;
+ float wn1;
+ float wn2;
+ float a0;
+ float a1;
+ float a2;
+ float b1;
+ float b2;
+ float sr;
+ float cur_f;
+ float cur_l;
+ float cur_a;
+ float cur_g;
+ float delta_f;
+ float delta_a;
+ float delta_g;
+ float end_f;
+ float end_a;
+ float end_g;
+ float ticks_per_interpol_time;
+ float rcp_ticks;
+ float interpol_time;
+ int ticks;
+ int counter_f;
+ int counter_a;
+ int counter_g;
+ int event_mask;
+ void *x_debug_outlet;
+ t_atom x_at[5];
+ float x_msi;
+} t_sigpara_bp2;
+
+t_class *sigpara_bp2_class;
+
+static void sigpara_bp2_calc(t_sigpara_bp2 *x)
+{
+ float l, al, gal, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0;
+ al = l*x->cur_a;
+ gal = al*x->cur_g;
+ rcp = 1.0f/(al + l2);
+ x->a0 = rcp*(l2 + gal);
+ x->a1 = rcp*2.0f*(2.0f - l2);
+ x->a2 = rcp*(l2 - gal);
+ x->b1 = -x->a1;
+ x->b2 = rcp*(al - l2);
+}
+
+static void sigpara_bp2_dsp_tick(t_sigpara_bp2 *x)
+{
+ if(x->event_mask)
+ {
+ float discriminant;
+
+ if(x->counter_f)
+ {
+ float l, si, co;
+
+ if(x->counter_f <= 1)
+ {
+ x->cur_f = x->end_f;
+ x->counter_f = 0;
+ x->event_mask &= 6;/*set event_mask_bit 0 = 0*/
+ }
+ else
+ {
+ x->counter_f--;
+ x->cur_f *= x->delta_f;
+ }
+ l = x->cur_f * x->sr;
+ if(l < 1.0e-20f)
+ x->cur_l = 1.0e20f;
+ else if(l > 1.57079632f)
+ x->cur_l = 0.0f;
+ else
+ {
+ si = sin(l);
+ co = cos(l);
+ x->cur_l = co/si;
+ }
+ }
+ if(x->counter_a)
+ {
+ if(x->counter_a <= 1)
+ {
+ x->cur_a = x->end_a;
+ x->counter_a = 0;
+ x->event_mask &= 5;/*set event_mask_bit 1 = 0*/
+ }
+ else
+ {
+ x->counter_a--;
+ x->cur_a *= x->delta_a;
+ }
+ }
+ if(x->counter_g)
+ {
+ if(x->counter_g <= 1)
+ {
+ x->cur_g = x->end_g;
+ x->counter_g = 0;
+ x->event_mask &= 3;/*set event_mask_bit 2 = 0*/
+ }
+ else
+ {
+ x->counter_g--;
+ x->cur_g *= x->delta_g;
+ }
+ }
+
+ sigpara_bp2_calc(x);
+
+ /* stability check */
+
+ discriminant = x->b1 * x->b1 + 4.0f * x->b2;
+ if(x->b1 <= -1.9999996f)
+ x->b1 = -1.9999996f;
+ else if(x->b1 >= 1.9999996f)
+ x->b1 = 1.9999996f;
+
+ if(x->b2 <= -0.9999998f)
+ x->b2 = -0.9999998f;
+ else if(x->b2 >= 0.9999998f)
+ x->b2 = 0.9999998f;
+
+ if(discriminant >= 0.0f)
+ {
+ if(0.9999998f - x->b1 - x->b2 < 0.0f)
+ x->b2 = 0.9999998f - x->b1;
+ if(0.9999998f + x->b1 - x->b2 < 0.0f)
+ x->b2 = 0.9999998f + x->b1;
+ }
+ }
+}
+
+static t_int *sigpara_bp2_perform(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *out = (float *)(w[2]);
+ t_sigpara_bp2 *x = (t_sigpara_bp2 *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ float wn0, wn1=x->wn1, wn2=x->wn2;
+ float a0=x->a0, a1=x->a1, a2=x->a2;
+ float b1=x->b1, b2=x->b2;
+
+ sigpara_bp2_dsp_tick(x);
+ for(i=0; i<n; i++)
+ {
+ wn0 = *in++ + b1*wn1 + b2*wn2;
+ *out++ = a0*wn0 + a1*wn1 + a2*wn2;
+ wn2 = wn1;
+ wn1 = wn0;
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(wn2))
+ wn2 = 0.0f;
+ if(PD_BADFLOAT(wn1))
+ wn1 = 0.0f;
+
+ x->wn1 = wn1;
+ x->wn2 = wn2;
+ return(w+5);
+}
+/* yn0 = *out;
+ xn0 = *in;
+ *************
+ yn0 = a0*xn0 + a1*xn1 + a2*xn2 + b1*yn1 + b2*yn2;
+ yn2 = yn1;
+ yn1 = yn0;
+ xn2 = xn1;
+ xn1 = xn0;
+ *************************
+ y/x = (a0 + a1*z-1 + a2*z-2)/(1 - b1*z-1 - b2*z-2);*/
+
+static t_int *sigpara_bp2_perf8(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *out = (float *)(w[2]);
+ t_sigpara_bp2 *x = (t_sigpara_bp2 *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ float wn[10];
+ float a0=x->a0, a1=x->a1, a2=x->a2;
+ float b1=x->b1, b2=x->b2;
+
+ sigpara_bp2_dsp_tick(x);
+ wn[0] = x->wn2;
+ wn[1] = x->wn1;
+ for(i=0; i<n; i+=8, in+=8, out+=8)
+ {
+ wn[2] = in[0] + b1*wn[1] + b2*wn[0];
+ out[0] = a0*wn[2] + a1*wn[1] + a2*wn[0];
+ wn[3] = in[1] + b1*wn[2] + b2*wn[1];
+ out[1] = a0*wn[3] + a1*wn[2] + a2*wn[1];
+ wn[4] = in[2] + b1*wn[3] + b2*wn[2];
+ out[2] = a0*wn[4] + a1*wn[3] + a2*wn[2];
+ wn[5] = in[3] + b1*wn[4] + b2*wn[3];
+ out[3] = a0*wn[5] + a1*wn[4] + a2*wn[3];
+ wn[6] = in[4] + b1*wn[5] + b2*wn[4];
+ out[4] = a0*wn[6] + a1*wn[5] + a2*wn[4];
+ wn[7] = in[5] + b1*wn[6] + b2*wn[5];
+ out[5] = a0*wn[7] + a1*wn[6] + a2*wn[5];
+ wn[8] = in[6] + b1*wn[7] + b2*wn[6];
+ out[6] = a0*wn[8] + a1*wn[7] + a2*wn[6];
+ wn[9] = in[7] + b1*wn[8] + b2*wn[7];
+ out[7] = a0*wn[9] + a1*wn[8] + a2*wn[7];
+ wn[0] = wn[8];
+ wn[1] = wn[9];
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(wn[0]))
+ wn[0] = 0.0f;
+ if(PD_BADFLOAT(wn[1]))
+ wn[1] = 0.0f;
+
+ x->wn1 = wn[1];
+ x->wn2 = wn[0];
+ return(w+5);
+}
+
+static void sigpara_bp2_ft4(t_sigpara_bp2 *x, t_floatarg t)
+{
+ int i = (int)((x->ticks_per_interpol_time)*t);
+
+ x->interpol_time = t;
+ if(i <= 0)
+ i = 1;
+ x->ticks = i;
+ x->rcp_ticks = 1.0f / (float)i;
+}
+
+static void sigpara_bp2_ft3(t_sigpara_bp2 *x, t_floatarg l)
+{
+ float g = exp(0.11512925465 * l);
+
+ if(g != x->cur_g)
+ {
+ x->end_g = g;
+ x->counter_g = x->ticks;
+ x->delta_g = exp(log(g/x->cur_g)*x->rcp_ticks);
+ x->event_mask |= 4;/*set event_mask_bit 2 = 1*/
+ }
+}
+
+static void sigpara_bp2_ft2(t_sigpara_bp2 *x, t_floatarg q)
+{
+ float a;
+
+ if(q <= 0.0f)
+ q = 0.000001f;
+ a = 1.0f/q;
+ if(a != x->cur_a)
+ {
+ x->end_a = a;
+ x->counter_a = x->ticks;
+ x->delta_a = exp(log(a/x->cur_a)*x->rcp_ticks);
+ x->event_mask |= 2;/*set event_mask_bit 1 = 1*/
+ }
+}
+
+static void sigpara_bp2_ft1(t_sigpara_bp2 *x, t_floatarg f)
+{
+ if(f <= 0.0f)
+ f = 0.000001f;
+ if(f != x->cur_f)
+ {
+ x->end_f = f;
+ x->counter_f = x->ticks;
+ x->delta_f = exp(log(f/x->cur_f)*x->rcp_ticks);
+ x->event_mask |= 1;/*set event_mask_bit 0 = 1*/
+ }
+}
+
+static void sigpara_bp2_print(t_sigpara_bp2 *x)
+{
+// post("fb1 = %g, fb2 = %g, ff1 = %g, ff2 = %g, ff3 = %g", x->b1, x->b2, x->a0, x->a1, x->a2);
+ x->x_at[0].a_w.w_float = x->b1;
+ x->x_at[1].a_w.w_float = x->b2;
+ x->x_at[2].a_w.w_float = x->a0;
+ x->x_at[3].a_w.w_float = x->a1;
+ x->x_at[4].a_w.w_float = x->a2;
+ outlet_list(x->x_debug_outlet, &s_list, 5, x->x_at); post("fb1 = %g, fb2 = %g, ff1 = %g, ff2 = %g, ff3 = %g", x->b1, x->b2, x->a0, x->a1, x->a2);
+}
+
+static void sigpara_bp2_dsp(t_sigpara_bp2 *x, t_signal **sp)
+{
+ float si, co, f;
+ int i, n=(int)sp[0]->s_n;
+
+ x->sr = 3.14159265358979323846f / (float)(sp[0]->s_sr);
+ x->ticks_per_interpol_time = 0.001f * (float)(sp[0]->s_sr) / (float)n;
+ i = (int)((x->ticks_per_interpol_time)*(x->interpol_time));
+ if(i <= 0)
+ i = 1;
+ x->ticks = i;
+ x->rcp_ticks = 1.0f / (float)i;
+ f = x->cur_f * x->sr;
+ if(f < 1.0e-20f)
+ x->cur_l = 1.0e20f;
+ else if(f > 1.57079632f)
+ x->cur_l = 0.0f;
+ else
+ {
+ si = sin(f);
+ co = cos(f);
+ x->cur_l = co/si;
+ }
+ if(n&7)
+ dsp_add(sigpara_bp2_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+ else
+ dsp_add(sigpara_bp2_perf8, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+}
+
+static void *sigpara_bp2_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_sigpara_bp2 *x = (t_sigpara_bp2 *)pd_new(sigpara_bp2_class);
+ int i;
+ float si, co, f=0.0, q=1.0, l=0.0, interpol=0.0;
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft3"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft4"));
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_debug_outlet = outlet_new(&x->x_obj, &s_list);
+ x->x_msi = 0;
+
+ x->x_at[0].a_type = A_FLOAT;
+ x->x_at[1].a_type = A_FLOAT;
+ x->x_at[2].a_type = A_FLOAT;
+ x->x_at[3].a_type = A_FLOAT;
+ x->x_at[4].a_type = A_FLOAT;
+
+ x->event_mask = 1;
+ x->counter_f = 1;
+ x->counter_a = 0;
+ x->counter_g = 0;
+ x->delta_f = 0.0f;
+ x->delta_a = 0.0f;
+ x->delta_g = 0.0f;
+ x->interpol_time = 500.0f;
+ x->wn1 = 0.0;
+ x->wn2 = 0.0;
+ x->a0 = 0.0;
+ x->a1 = 0.0;
+ x->a2 = 0.0;
+ x->b1 = 0.0;
+ x->b2 = 0.0;
+ x->sr = 3.14159265358979323846f / 44100.0f;
+ x->cur_a = 1.0;
+ if((argc == 4)&&IS_A_FLOAT(argv,3)&&IS_A_FLOAT(argv,2)&&IS_A_FLOAT(argv,1)&&IS_A_FLOAT(argv,0))
+ {
+ f = (float)atom_getfloatarg(0, argc, argv);
+ q = (float)atom_getfloatarg(1, argc, argv);
+ l = (float)atom_getfloatarg(2, argc, argv);
+ interpol = (float)atom_getfloatarg(3, argc, argv);
+ }
+ if(f <= 0.0f)
+ f = 0.000001f;
+ x->cur_f = f;
+ f *= x->sr;
+ if(f < 1.0e-20f)
+ x->cur_l = 1.0e20f;
+ else if(f > 1.57079632f)
+ x->cur_l = 0.0f;
+ else
+ {
+ si = sin(f);
+ co = cos(f);
+ x->cur_l = co/si;
+ }
+ if(q <= 0.0f)
+ q = 0.000001f;
+ x->cur_a = 1.0f/q;
+ x->cur_g = exp(0.11512925465 * l);
+ if(interpol <= 0.0f)
+ interpol = 0.0f;
+ x->interpol_time = interpol;
+ x->ticks_per_interpol_time = 0.5f;
+ i = (int)((x->ticks_per_interpol_time)*(x->interpol_time));
+ if(i <= 0)
+ i = 1;
+ x->ticks = i;
+ x->rcp_ticks = 1.0f / (float)i;
+ x->end_f = x->cur_f;
+ x->end_a = x->cur_a;
+ x->end_g = x->cur_g;
+ return(x);
+}
+
+void sigpara_bp2_setup(void)
+{
+ sigpara_bp2_class = class_new(gensym("para_bp2~"), (t_newmethod)sigpara_bp2_new,
+ 0, sizeof(t_sigpara_bp2), 0, A_GIMME, 0);
+ CLASS_MAINSIGNALIN(sigpara_bp2_class, t_sigpara_bp2, x_msi);
+ class_addmethod(sigpara_bp2_class, (t_method)sigpara_bp2_dsp, gensym("dsp"), 0);
+ class_addmethod(sigpara_bp2_class, (t_method)sigpara_bp2_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(sigpara_bp2_class, (t_method)sigpara_bp2_ft2, gensym("ft2"), A_FLOAT, 0);
+ class_addmethod(sigpara_bp2_class, (t_method)sigpara_bp2_ft3, gensym("ft3"), A_FLOAT, 0);
+ class_addmethod(sigpara_bp2_class, (t_method)sigpara_bp2_ft4, gensym("ft4"), A_FLOAT, 0);
+ class_addmethod(sigpara_bp2_class, (t_method)sigpara_bp2_print, gensym("print"), 0);
+ class_sethelpsymbol(sigpara_bp2_class, gensym("iemhelp/help-para_bp2~"));
+}
diff --git a/src/iemlib1/sigpeakenv.c b/src/iemlib1/sigpeakenv.c
new file mode 100644
index 0000000..a16638e
--- /dev/null
+++ b/src/iemlib1/sigpeakenv.c
@@ -0,0 +1,102 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ---------------- peakenv~ - simple peak-envelope-converter. ----------------- */
+
+typedef struct sigpeakenv
+{
+ t_object x_obj;
+ float x_sr;
+ float x_old_peak;
+ float x_c1;
+ float x_releasetime;
+ float x_msi;
+} t_sigpeakenv;
+
+t_class *sigpeakenv_class;
+
+static void sigpeakenv_reset(t_sigpeakenv *x)
+{
+ x->x_old_peak = 0.0f;
+}
+
+static void sigpeakenv_ft1(t_sigpeakenv *x, t_floatarg f)/* release-time in ms */
+{
+ if(f < 0.0f)
+ f = 0.0f;
+ x->x_releasetime = f;
+ x->x_c1 = exp(-1.0/(x->x_sr*0.001*x->x_releasetime));
+}
+
+static t_int *sigpeakenv_perform(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *out = (float *)(w[2]);
+ t_sigpeakenv *x = (t_sigpeakenv *)(w[3]);
+ int n = (int)(w[4]);
+ float peak = x->x_old_peak;
+ float c1 = x->x_c1;
+ float absolute;
+ int i;
+
+ for(i=0; i<n; i++)
+ {
+ absolute = fabs(*in++);
+ peak *= c1;
+ if(absolute > peak)
+ peak = absolute;
+ *out++ = peak;
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(peak))
+ peak = 0.0f;
+ x->x_old_peak = peak;
+ return(w+5);
+}
+
+static void sigpeakenv_dsp(t_sigpeakenv *x, t_signal **sp)
+{
+ x->x_sr = (float)sp[0]->s_sr;
+ sigpeakenv_ft1(x, x->x_releasetime);
+ dsp_add(sigpeakenv_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n);
+}
+
+static void *sigpeakenv_new(t_floatarg f)
+{
+ t_sigpeakenv *x = (t_sigpeakenv *)pd_new(sigpeakenv_class);
+
+ if(f <= 0.0f)
+ f = 0.0f;
+ x->x_sr = 44100.0f;
+ sigpeakenv_ft1(x, f);
+ x->x_old_peak = 0.0f;
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_msi = 0;
+ return(x);
+}
+
+void sigpeakenv_setup(void)
+{
+ sigpeakenv_class = class_new(gensym("peakenv~"), (t_newmethod)sigpeakenv_new,
+ 0, sizeof(t_sigpeakenv), 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(sigpeakenv_class, t_sigpeakenv, x_msi);
+ class_addmethod(sigpeakenv_class, (t_method)sigpeakenv_dsp, gensym("dsp"), 0);
+ class_addmethod(sigpeakenv_class, (t_method)sigpeakenv_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(sigpeakenv_class, (t_method)sigpeakenv_reset, gensym("reset"), 0);
+ class_sethelpsymbol(sigpeakenv_class, gensym("iemhelp/help-peakenv~"));
+}
diff --git a/src/iemlib1/sigprvu.c b/src/iemlib1/sigprvu.c
new file mode 100644
index 0000000..bb4b72a
--- /dev/null
+++ b/src/iemlib1/sigprvu.c
@@ -0,0 +1,282 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ---------------- prvu~ - simple peak&rms-vu-meter. ----------------- */
+
+typedef struct sigprvu
+{
+ t_object x_obj;
+ t_atom x_at[3];
+ void *x_clock_metro;
+ int x_metro_time;
+ void *x_clock_hold;
+ int x_hold_time;
+ float x_cur_peak;
+ float x_old_peak;
+ float x_hold_peak;
+ int x_hold;
+ float x_sum_rms;
+ float x_old_rms;
+ float x_rcp;
+ float x_sr;
+ float x_threshold_over;
+ int x_overflow_counter;
+ float x_release_time;
+ float x_c1;
+ int x_started;
+ float x_msi;
+} t_sigprvu;
+
+t_class *sigprvu_class;
+static void sigprvu_tick_metro(t_sigprvu *x);
+static void sigprvu_tick_hold(t_sigprvu *x);
+
+static void sigprvu_reset(t_sigprvu *x)
+{
+ x->x_at[0].a_w.w_float = -99.9f;
+ x->x_at[1].a_w.w_float = -99.9f;
+ x->x_at[2].a_w.w_float = 0.0f;
+ outlet_list(x->x_obj.ob_outlet, &s_list, 3, x->x_at);
+ x->x_overflow_counter = 0;
+ x->x_cur_peak = 0.0f;
+ x->x_old_peak = 0.0f;
+ x->x_hold_peak = 0.0f;
+ x->x_sum_rms = 0.0f;
+ x->x_old_rms = 0.0f;
+ x->x_hold = 0;
+ clock_unset(x->x_clock_hold);
+ clock_delay(x->x_clock_metro, x->x_metro_time);
+}
+
+static void sigprvu_stop(t_sigprvu *x)
+{
+ clock_unset(x->x_clock_metro);
+ x->x_started = 0;
+}
+
+static void sigprvu_start(t_sigprvu *x)
+{
+ clock_delay(x->x_clock_metro, x->x_metro_time);
+ x->x_started = 1;
+}
+
+static void sigprvu_float(t_sigprvu *x, t_floatarg f)
+{
+ if(f == 0.0)
+ {
+ clock_unset(x->x_clock_metro);
+ x->x_started = 0;
+ }
+ else
+ {
+ clock_delay(x->x_clock_metro, x->x_metro_time);
+ x->x_started = 1;
+ }
+}
+
+static void sigprvu_t_release(t_sigprvu *x, t_floatarg release_time)
+{
+ if(release_time <= 20.0f)
+ release_time = 20.0f;
+ x->x_release_time = release_time;
+ x->x_c1 = exp(-2.0*(float)x->x_metro_time/x->x_release_time);
+}
+
+static void sigprvu_t_metro(t_sigprvu *x, t_floatarg metro_time)
+{
+ if(metro_time <= 20.0f)
+ metro_time = 20.0f;
+ x->x_metro_time = (int)metro_time;
+ x->x_c1 = exp(-2.0*(float)x->x_metro_time/x->x_release_time);
+ x->x_rcp = 1.0f/(x->x_sr*(float)x->x_metro_time);
+}
+
+static void sigprvu_t_hold(t_sigprvu *x, t_floatarg hold_time)
+{
+ if(hold_time <= 20.0f)
+ hold_time = 20.0f;
+ x->x_hold_time = (int)hold_time;
+}
+
+static void sigprvu_threshold(t_sigprvu *x, t_floatarg thresh)
+{
+ x->x_threshold_over = thresh;
+}
+
+static t_int *sigprvu_perform(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ t_sigprvu *x = (t_sigprvu *)(w[2]);
+ int n = (int)(w[3]);
+ float peak = x->x_cur_peak, pow, sum=x->x_sum_rms;
+ int i;
+
+ if(x->x_started)
+ {
+ for(i=0; i<n; i++)
+ {
+ pow = in[i]*in[i];
+ if(pow > peak)
+ peak = pow;
+ sum += pow;
+ }
+ x->x_cur_peak = peak;
+ x->x_sum_rms = sum;
+ }
+ return(w+4);
+}
+
+static void sigprvu_dsp(t_sigprvu *x, t_signal **sp)
+{
+ x->x_sr = 0.001*(float)sp[0]->s_sr;
+ x->x_rcp = 1.0f/(x->x_sr*(float)x->x_metro_time);
+ dsp_add(sigprvu_perform, 3, sp[0]->s_vec, x, sp[0]->s_n);
+ clock_delay(x->x_clock_metro, x->x_metro_time);
+}
+
+static void sigprvu_tick_hold(t_sigprvu *x)
+{
+ x->x_hold = 0;
+ x->x_hold_peak = x->x_old_peak;
+}
+
+static void sigprvu_tick_metro(t_sigprvu *x)
+{
+ float dbr, dbp, cur_rms, c1=x->x_c1;
+
+ x->x_old_peak *= c1;
+ /* NAN protect */
+ if(PD_BADFLOAT(x->x_old_peak))
+ x->x_old_peak = 0.0f;
+
+ if(x->x_cur_peak > x->x_old_peak)
+ x->x_old_peak = x->x_cur_peak;
+ if(x->x_old_peak > x->x_hold_peak)
+ {
+ x->x_hold = 1;
+ x->x_hold_peak = x->x_old_peak;
+ clock_delay(x->x_clock_hold, x->x_hold_time);
+ }
+ if(!x->x_hold)
+ x->x_hold_peak = x->x_old_peak;
+ if(x->x_hold_peak <= 0.0000000001f)
+ dbp = -99.9f;
+ else if(x->x_hold_peak > 1000000.0f)
+ {
+ dbp = 60.0f;
+ x->x_hold_peak = 1000000.0f;
+ x->x_old_peak = 1000000.0f;
+ }
+ else
+ dbp = 4.3429448195f*log(x->x_hold_peak);
+ x->x_cur_peak = 0.0f;
+ if(dbp >= x->x_threshold_over)
+ x->x_overflow_counter++;
+ x->x_at[1].a_w.w_float = dbp;
+ x->x_at[2].a_w.w_float = (float)x->x_overflow_counter;
+
+ cur_rms = (1.0f - c1)*x->x_sum_rms*x->x_rcp + c1*x->x_old_rms;
+ /* NAN protect */
+ if(PD_BADFLOAT(cur_rms))
+ cur_rms = 0.0f;
+
+ if(cur_rms <= 0.0000000001f)
+ dbr = -99.9f;
+ else if(cur_rms > 1000000.0f)
+ {
+ dbr = 60.0f;
+ x->x_old_rms = 1000000.0f;
+ }
+ else
+ dbr = 4.3429448195f*log(cur_rms);
+ x->x_sum_rms = 0.0f;
+ x->x_old_rms = cur_rms;
+ x->x_at[0].a_w.w_float = dbr;
+ outlet_list(x->x_obj.ob_outlet, &s_list, 3, x->x_at);
+ clock_delay(x->x_clock_metro, x->x_metro_time);
+}
+
+static void sigprvu_ff(t_sigprvu *x)
+{
+ clock_free(x->x_clock_metro);
+ clock_free(x->x_clock_hold);
+}
+
+static void *sigprvu_new(t_floatarg metro_time, t_floatarg hold_time,
+ t_floatarg release_time, t_floatarg threshold)
+{
+ t_sigprvu *x;
+ float t;
+ int i;
+
+ x = (t_sigprvu *)pd_new(sigprvu_class);
+ if(metro_time <= 0.0f)
+ metro_time = 300.0f;
+ if(metro_time <= 20.0f)
+ metro_time = 20.0f;
+ if(release_time <= 0.0f)
+ release_time = 300.0f;
+ if(release_time <= 20.0f)
+ release_time = 20.0f;
+ if(hold_time <= 0.0f)
+ hold_time = 1000.0f;
+ if(hold_time <= 20.0f)
+ hold_time = 20.0f;
+ if(threshold == 0.0f)
+ threshold = -0.01f;
+ x->x_metro_time = (int)metro_time;
+ x->x_release_time = release_time;
+ x->x_hold_time = (int)hold_time;
+ x->x_threshold_over = threshold;
+ x->x_c1 = exp(-2.0*(float)x->x_metro_time/x->x_release_time);
+ x->x_cur_peak = 0.0f;
+ x->x_old_peak = 0.0f;
+ x->x_hold_peak = 0.0f;
+ x->x_hold = 0;
+ x->x_sum_rms = 0.0f;
+ x->x_old_rms = 0.0f;
+ x->x_sr = 44.1f;
+ x->x_rcp = 1.0f/(x->x_sr*(float)x->x_metro_time);
+ x->x_overflow_counter = 0;
+ x->x_clock_metro = clock_new(x, (t_method)sigprvu_tick_metro);
+ x->x_clock_hold = clock_new(x, (t_method)sigprvu_tick_hold);
+ x->x_started = 1;
+ outlet_new(&x->x_obj, &s_list);
+ x->x_at[0].a_type = A_FLOAT;
+ x->x_at[1].a_type = A_FLOAT;
+ x->x_at[2].a_type = A_FLOAT;
+ x->x_msi = 0.0f;
+ return(x);
+}
+
+void sigprvu_setup(void)
+{
+ sigprvu_class = class_new(gensym("prvu~"), (t_newmethod)sigprvu_new,
+ (t_method)sigprvu_ff, sizeof(t_sigprvu), 0,
+ A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(sigprvu_class, t_sigprvu, x_msi);
+ class_addmethod(sigprvu_class, (t_method)sigprvu_dsp, gensym("dsp"), 0);
+ class_addfloat(sigprvu_class, sigprvu_float);
+ class_addmethod(sigprvu_class, (t_method)sigprvu_reset, gensym("reset"), 0);
+ class_addmethod(sigprvu_class, (t_method)sigprvu_start, gensym("start"), 0);
+ class_addmethod(sigprvu_class, (t_method)sigprvu_stop, gensym("stop"), 0);
+ class_addmethod(sigprvu_class, (t_method)sigprvu_t_release, gensym("t_release"), A_FLOAT, 0);
+ class_addmethod(sigprvu_class, (t_method)sigprvu_t_metro, gensym("t_metro"), A_FLOAT, 0);
+ class_addmethod(sigprvu_class, (t_method)sigprvu_t_hold, gensym("t_hold"), A_FLOAT, 0);
+ class_addmethod(sigprvu_class, (t_method)sigprvu_threshold, gensym("threshold"), A_FLOAT, 0);
+ class_sethelpsymbol(sigprvu_class, gensym("iemhelp/help-prvu~"));
+}
diff --git a/src/iemlib1/sigpvu.c b/src/iemlib1/sigpvu.c
new file mode 100644
index 0000000..5dd4ea4
--- /dev/null
+++ b/src/iemlib1/sigpvu.c
@@ -0,0 +1,206 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ---------------- pvu~ - simple peak-vu-meter. ----------------- */
+
+typedef struct sigpvu
+{
+ t_object x_obj;
+ void *x_outlet_meter;
+ void *x_outlet_over;
+ void *x_clock;
+ float x_cur_peak;
+ float x_old_peak;
+ float x_threshold_over;
+ float x_c1;
+ int x_metro_time;
+ float x_release_time;
+ int x_overflow_counter;
+ int x_started;
+ float x_msi;
+} t_sigpvu;
+
+t_class *sigpvu_class;
+static void sigpvu_tick(t_sigpvu *x);
+
+static void sigpvu_reset(t_sigpvu *x)
+{
+ outlet_float(x->x_outlet_over, (t_float)0);
+ outlet_float(x->x_outlet_meter, -199.9);
+ x->x_overflow_counter = 0;
+ x->x_cur_peak = 0.0f;
+ x->x_old_peak = 0.0f;
+ clock_delay(x->x_clock, x->x_metro_time);
+}
+
+static void sigpvu_stop(t_sigpvu *x)
+{
+ clock_unset(x->x_clock);
+ x->x_started = 0;
+}
+
+static void sigpvu_start(t_sigpvu *x)
+{
+ clock_delay(x->x_clock, x->x_metro_time);
+ x->x_started = 1;
+}
+
+static void sigpvu_float(t_sigpvu *x, t_floatarg f)
+{
+ if(f == 0.0)
+ {
+ clock_unset(x->x_clock);
+ x->x_started = 0;
+ }
+ else
+ {
+ clock_delay(x->x_clock, x->x_metro_time);
+ x->x_started = 1;
+ }
+}
+
+static void sigpvu_t_release(t_sigpvu *x, t_floatarg release_time)
+{
+ if(release_time <= 20.0f)
+ release_time = 20.0f;
+ x->x_release_time = release_time;
+ x->x_c1 = exp(-(float)x->x_metro_time/(float)release_time);
+}
+
+static void sigpvu_t_metro(t_sigpvu *x, t_floatarg metro_time)
+{
+ if(metro_time <= 20.0f)
+ metro_time = 20.0f;
+ x->x_metro_time = (int)metro_time;
+ x->x_c1 = exp(-(float)metro_time/(float)x->x_release_time);
+}
+
+static void sigpvu_threshold(t_sigpvu *x, t_floatarg thresh)
+{
+ x->x_threshold_over = thresh;
+}
+
+static t_int *sigpvu_perform(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ t_sigpvu *x = (t_sigpvu *)(w[2]);
+ int n = (int)(w[3]);
+ float peak = x->x_cur_peak;
+ float absolute;
+ int i;
+
+ if(x->x_started)
+ {
+ for(i=0; i<n; i++)
+ {
+ absolute = fabs(*in++);
+ if(absolute > peak)
+ peak = absolute;
+ }
+ x->x_cur_peak = peak;
+ }
+ return(w+4);
+}
+
+static void sigpvu_dsp(t_sigpvu *x, t_signal **sp)
+{
+ dsp_add(sigpvu_perform, 3, sp[0]->s_vec, x, sp[0]->s_n);
+ clock_delay(x->x_clock, x->x_metro_time);
+}
+
+static void sigpvu_tick(t_sigpvu *x)
+{
+ float db;
+ int i;
+
+ x->x_old_peak *= x->x_c1;
+ /* NAN protect */
+ if(PD_BADFLOAT(x->x_old_peak))
+ x->x_old_peak = 0.0f;
+
+ if(x->x_cur_peak > x->x_old_peak)
+ x->x_old_peak = x->x_cur_peak;
+ if(x->x_old_peak <= 0.0000000001f)
+ db = -199.9f;
+ else if(x->x_old_peak > 1000000.0f)
+ {
+ db = 120.0f;
+ x->x_old_peak = 1000000.0f;
+ }
+ else
+ db = 8.6858896381f*log(x->x_old_peak);
+ if(db >= x->x_threshold_over)
+ {
+ x->x_overflow_counter++;
+ outlet_float(x->x_outlet_over, (t_float)x->x_overflow_counter);
+ }
+ outlet_float(x->x_outlet_meter, db);
+ x->x_cur_peak = 0.0f;
+ clock_delay(x->x_clock, x->x_metro_time);
+}
+
+static void *sigpvu_new(t_floatarg metro_time, t_floatarg release_time, t_floatarg threshold)
+{
+ t_sigpvu *x;
+ float t;
+
+ x = (t_sigpvu *)pd_new(sigpvu_class);
+ if(metro_time <= 0.0f)
+ metro_time = 300.0f;
+ if(metro_time <= 20.0f)
+ metro_time = 20.0f;
+ if(release_time <= 0.0f)
+ release_time = 300.0f;
+ if(release_time <= 20.0f)
+ release_time = 20.0f;
+ if(threshold == 0.0f)
+ threshold = -0.01f;
+ x->x_threshold_over = threshold;
+ x->x_overflow_counter = 0;
+ x->x_metro_time = (int)metro_time;
+ x->x_release_time = release_time;
+ x->x_c1 = exp(-(float)metro_time/(float)release_time);
+ x->x_cur_peak = 0.0f;
+ x->x_old_peak = 0.0f;
+ x->x_clock = clock_new(x, (t_method)sigpvu_tick);
+ x->x_outlet_meter = outlet_new(&x->x_obj, &s_float);/* left */
+ x->x_outlet_over = outlet_new(&x->x_obj, &s_float); /* right */
+ x->x_started = 1;
+ x->x_msi = 0;
+ return(x);
+}
+
+static void sigpvu_ff(t_sigpvu *x)
+{
+ clock_free(x->x_clock);
+}
+
+void sigpvu_setup(void )
+{
+ sigpvu_class = class_new(gensym("pvu~"), (t_newmethod)sigpvu_new,
+ (t_method)sigpvu_ff, sizeof(t_sigpvu), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(sigpvu_class, t_sigpvu, x_msi);
+ class_addmethod(sigpvu_class, (t_method)sigpvu_dsp, gensym("dsp"), 0);
+ class_addfloat(sigpvu_class, sigpvu_float);
+ class_addmethod(sigpvu_class, (t_method)sigpvu_reset, gensym("reset"), 0);
+ class_addmethod(sigpvu_class, (t_method)sigpvu_start, gensym("start"), 0);
+ class_addmethod(sigpvu_class, (t_method)sigpvu_stop, gensym("stop"), 0);
+ class_addmethod(sigpvu_class, (t_method)sigpvu_t_release, gensym("t_release"), A_FLOAT, 0);
+ class_addmethod(sigpvu_class, (t_method)sigpvu_t_metro, gensym("t_metro"), A_FLOAT, 0);
+ class_addmethod(sigpvu_class, (t_method)sigpvu_threshold, gensym("threshold"), A_FLOAT, 0);
+ class_sethelpsymbol(sigpvu_class, gensym("iemhelp/help-pvu~"));
+}
diff --git a/src/iemlib1/sigrvu.c b/src/iemlib1/sigrvu.c
new file mode 100644
index 0000000..70b9cd7
--- /dev/null
+++ b/src/iemlib1/sigrvu.c
@@ -0,0 +1,187 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ---------------- rvu~ - simple peak&rms-vu-meter. ----------------- */
+
+typedef struct sigrvu
+{
+ t_object x_obj;
+ void *x_clock_metro;
+ int x_metro_time;
+ float x_sum_rms;
+ float x_old_rms;
+ float x_rcp;
+ float x_sr;
+ float x_release_time;
+ float x_c1;
+ int x_started;
+ float x_msi;
+} t_sigrvu;
+
+t_class *sigrvu_class;
+static void sigrvu_tick_metro(t_sigrvu *x);
+
+static void sigrvu_reset(t_sigrvu *x)
+{
+ outlet_float(x->x_obj.ob_outlet, -99.9f);
+ x->x_sum_rms = 0.0f;
+ x->x_old_rms = 0.0f;
+ clock_delay(x->x_clock_metro, x->x_metro_time);
+}
+
+static void sigrvu_stop(t_sigrvu *x)
+{
+ clock_unset(x->x_clock_metro);
+ x->x_started = 0;
+}
+
+static void sigrvu_start(t_sigrvu *x)
+{
+ clock_delay(x->x_clock_metro, x->x_metro_time);
+ x->x_started = 1;
+}
+
+static void sigrvu_float(t_sigrvu *x, t_floatarg f)
+{
+ if(f == 0.0)
+ {
+ clock_unset(x->x_clock_metro);
+ x->x_started = 0;
+ }
+ else
+ {
+ clock_delay(x->x_clock_metro, x->x_metro_time);
+ x->x_started = 1;
+ }
+}
+
+static void sigrvu_t_release(t_sigrvu *x, t_floatarg release_time)
+{
+ if(release_time <= 20.0f)
+ release_time = 20.0f;
+ x->x_release_time = release_time;
+ x->x_c1 = exp(-2.0*(float)x->x_metro_time/x->x_release_time);
+}
+
+static void sigrvu_t_metro(t_sigrvu *x, t_floatarg metro_time)
+{
+ if(metro_time <= 20.0f)
+ metro_time = 20.0f;
+ x->x_metro_time = (int)metro_time;
+ x->x_c1 = exp(-2.0*(float)x->x_metro_time/x->x_release_time);
+ x->x_rcp = 1.0f/(x->x_sr*(float)x->x_metro_time);
+}
+
+static t_int *sigrvu_perform(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ t_sigrvu *x = (t_sigrvu *)(w[2]);
+ int n = (int)(w[3]);
+ float pow, sum=x->x_sum_rms;
+ int i;
+
+ if(x->x_started)
+ {
+ for(i=0; i<n; i++)
+ {
+ sum += in[i]*in[i];
+ }
+ x->x_sum_rms = sum;
+ }
+ return(w+4);
+}
+
+static void sigrvu_dsp(t_sigrvu *x, t_signal **sp)
+{
+ x->x_sr = 0.001*(float)sp[0]->s_sr;
+ x->x_rcp = 1.0f/(x->x_sr*(float)x->x_metro_time);
+ dsp_add(sigrvu_perform, 3, sp[0]->s_vec, x, sp[0]->s_n);
+ clock_delay(x->x_clock_metro, x->x_metro_time);
+}
+
+static void sigrvu_tick_metro(t_sigrvu *x)
+{
+ float dbr, cur_rms, c1=x->x_c1;
+
+ cur_rms = (1.0f - c1)*x->x_sum_rms*x->x_rcp + c1*x->x_old_rms;
+ /* NAN protect */
+ if(PD_BADFLOAT(cur_rms))
+ cur_rms = 0.0f;
+
+ if(cur_rms <= 0.0000000001f)
+ dbr = -99.9f;
+ else if(cur_rms > 1000000.0f)
+ {
+ dbr = 60.0f;
+ x->x_old_rms = 1000000.0f;
+ }
+ else
+ dbr = 4.3429448195f*log(cur_rms);
+ x->x_sum_rms = 0.0f;
+ x->x_old_rms = cur_rms;
+ outlet_float(x->x_obj.ob_outlet, dbr);
+ clock_delay(x->x_clock_metro, x->x_metro_time);
+}
+
+static void sigrvu_ff(t_sigrvu *x)
+{
+ clock_free(x->x_clock_metro);
+}
+
+static void *sigrvu_new(t_floatarg metro_time, t_floatarg release_time)
+{
+ t_sigrvu *x=(t_sigrvu *)pd_new(sigrvu_class);
+ float t;
+ int i;
+
+ if(metro_time <= 0.0f)
+ metro_time = 300.0f;
+ if(metro_time <= 20.0f)
+ metro_time = 20.0f;
+ if(release_time <= 0.0f)
+ release_time = 300.0f;
+ if(release_time <= 20.0f)
+ release_time = 20.0f;
+ x->x_metro_time = (int)metro_time;
+ x->x_release_time = release_time;
+ x->x_c1 = exp(-2.0*(float)x->x_metro_time/x->x_release_time);
+ x->x_sum_rms = 0.0f;
+ x->x_old_rms = 0.0f;
+ x->x_sr = 44.1f;
+ x->x_rcp = 1.0f/(x->x_sr*(float)x->x_metro_time);
+ x->x_clock_metro = clock_new(x, (t_method)sigrvu_tick_metro);
+ x->x_started = 1;
+ outlet_new(&x->x_obj, &s_float);
+ x->x_msi = 0.0f;
+ return(x);
+}
+
+void sigrvu_setup(void)
+{
+ sigrvu_class = class_new(gensym("rvu~"), (t_newmethod)sigrvu_new,
+ (t_method)sigrvu_ff, sizeof(t_sigrvu), 0,
+ A_DEFFLOAT, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(sigrvu_class, t_sigrvu, x_msi);
+ class_addmethod(sigrvu_class, (t_method)sigrvu_dsp, gensym("dsp"), 0);
+ class_addfloat(sigrvu_class, sigrvu_float);
+ class_addmethod(sigrvu_class, (t_method)sigrvu_reset, gensym("reset"), 0);
+ class_addmethod(sigrvu_class, (t_method)sigrvu_start, gensym("start"), 0);
+ class_addmethod(sigrvu_class, (t_method)sigrvu_stop, gensym("stop"), 0);
+ class_addmethod(sigrvu_class, (t_method)sigrvu_t_release, gensym("t_release"), A_FLOAT, 0);
+ class_addmethod(sigrvu_class, (t_method)sigrvu_t_metro, gensym("t_metro"), A_FLOAT, 0);
+ class_sethelpsymbol(sigrvu_class, gensym("iemhelp/help-rvu~"));
+}
diff --git a/src/iemlib1/sigsin_phase.c b/src/iemlib1/sigsin_phase.c
new file mode 100644
index 0000000..0594962
--- /dev/null
+++ b/src/iemlib1/sigsin_phase.c
@@ -0,0 +1,129 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* --- sin_phase~ - output the phase-difference between 2 sinewaves in samples (sig) ---- */
+
+typedef struct sigsin_phase
+{
+ t_object x_obj;
+ float x_prev1;
+ float x_prev2;
+ float x_cur_out;
+ int x_counter1;
+ int x_counter2;
+ int x_state1;
+ int x_state2;
+ float x_msi;
+} t_sigsin_phase;
+
+t_class *sigsin_phase_class;
+
+static t_int *sigsin_phase_perform(t_int *w)
+{
+ float *in1 = (float *)(w[1]);
+ float *in2 = (float *)(w[2]);
+ float *out = (float *)(w[3]);
+ t_sigsin_phase *x = (t_sigsin_phase *)(w[4]);
+ int i, n = (t_int)(w[5]);
+ float prev1=x->x_prev1;
+ float prev2=x->x_prev2;
+ float cur_out=x->x_cur_out;
+ int counter1=x->x_counter1;
+ int counter2=x->x_counter2;
+ int state1=x->x_state1;
+ int state2=x->x_state2;
+
+ for(i=0; i<n; i++)
+ {
+ if((in1[i] >= 0.0f) && (prev1 < 0.0f))
+ {
+ state1 = 1;
+ counter1 = 0;
+ }
+ else if((in1[i] < 0.0f) && (prev1 >= 0.0f))
+ {
+ state2 = 1;
+ counter2 = 0;
+ }
+
+ if((in2[i] >= 0.0f) && (prev2 < 0.0f))
+ {
+ state1 = 0;
+ cur_out = (float)(counter1);
+ counter1 = 0;
+ }
+ else if((in2[i] < 0.0f) && (prev2 >= 0.0f))
+ {
+ state2 = 0;
+ cur_out = (float)(counter2);
+ counter2 = 0;
+ }
+
+ if(state1)
+ counter1++;
+ if(state2)
+ counter2++;
+
+ prev1 = in1[i];
+ prev2 = in2[i];
+ out[i] = cur_out;
+ }
+
+ x->x_prev1 = prev1;
+ x->x_prev2 = prev2;
+ x->x_cur_out = cur_out;
+ x->x_counter1 = counter1;
+ x->x_counter2 = counter2;
+ x->x_state1 = state1;
+ x->x_state2 = state2;
+
+ return(w+6);
+}
+
+static void sigsin_phase_dsp(t_sigsin_phase *x, t_signal **sp)
+{
+ dsp_add(sigsin_phase_perform, 5, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, x, sp[0]->s_n);
+}
+
+static void *sigsin_phase_new(void)
+{
+ t_sigsin_phase *x = (t_sigsin_phase *)pd_new(sigsin_phase_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+
+ x->x_prev1 = 0.0f;
+ x->x_prev2 = 0.0f;
+ x->x_cur_out = 0.0f;
+ x->x_counter1 = 0;
+ x->x_counter2 = 0;
+ x->x_state1 = 0;
+ x->x_state2 = 0;
+ x->x_msi = 0;
+
+ return (x);
+}
+
+void sigsin_phase_setup(void)
+{
+ sigsin_phase_class = class_new(gensym("sin_phase~"), (t_newmethod)sigsin_phase_new,
+ 0, sizeof(t_sigsin_phase), 0, 0);
+ CLASS_MAINSIGNALIN(sigsin_phase_class, t_sigsin_phase, x_msi);
+ class_addmethod(sigsin_phase_class, (t_method)sigsin_phase_dsp, gensym("dsp"), 0);
+ class_sethelpsymbol(sigsin_phase_class, gensym("iemhelp/help-sin_phase~"));
+}
diff --git a/src/iemlib1/sigvcf_filter.c b/src/iemlib1/sigvcf_filter.c
new file mode 100644
index 0000000..ec14306
--- /dev/null
+++ b/src/iemlib1/sigvcf_filter.c
@@ -0,0 +1,334 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ---------- vcf_filter~ - slow dynamic vcf_filter 1. and 2. order ----------- */
+
+typedef struct sigvcf_filter
+{
+ t_object x_obj;
+ float x_wn1;
+ float x_wn2;
+ float x_msi;
+ char x_filtname[6];
+} t_sigvcf_filter;
+
+t_class *sigvcf_filter_class;
+
+static t_int *sigvcf_filter_perform_snafu(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *out = (float *)(w[4]);
+ int n = (t_int)(w[6]);
+
+ while(n--)
+ *out++ = *in++;
+ return(w+7);
+}
+
+/*
+lp2
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*(wn0 + 2.0f*wn1 + wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+bp2
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*al*(wn0 - wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+rbp2
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*l*(wn0 - wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+hp2
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*(wn0 - 2.0f*wn1 + wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+*/
+
+static t_int *sigvcf_filter_perform_lp2(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *lp = (float *)(w[2]);
+ float *q = (float *)(w[3]);
+ float *out = (float *)(w[4]);
+ t_sigvcf_filter *x = (t_sigvcf_filter *)(w[5]);
+ int i, n = (t_int)(w[6]);
+ float wn0, wn1=x->x_wn1, wn2=x->x_wn2;
+ float l, al, l2, rcp;
+
+ for(i=0; i<n; i+=4)
+ {
+ l = lp[i];
+ if(q[i] < 0.000001)
+ al = 1000000.0*l;
+ else if(q[i] > 1000000.0)
+ al = 0.000001*l;
+ else
+ al = l/q[i];
+ l2 = l*l + 1.0f;
+ rcp = 1.0f/(al + l2);
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*(wn0 + 2.0f*wn1 + wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*(wn0 + 2.0f*wn1 + wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*(wn0 + 2.0f*wn1 + wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*(wn0 + 2.0f*wn1 + wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(wn2))
+ wn2 = 0.0f;
+ if(PD_BADFLOAT(wn1))
+ wn1 = 0.0f;
+
+ x->x_wn1 = wn1;
+ x->x_wn2 = wn2;
+ return(w+7);
+}
+
+static t_int *sigvcf_filter_perform_bp2(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *lp = (float *)(w[2]);
+ float *q = (float *)(w[3]);
+ float *out = (float *)(w[4]);
+ t_sigvcf_filter *x = (t_sigvcf_filter *)(w[5]);
+ int i, n = (t_int)(w[6]);
+ float wn0, wn1=x->x_wn1, wn2=x->x_wn2;
+ float l, al, l2, rcp;
+
+ for(i=0; i<n; i+=4)
+ {
+ l = lp[i];
+ if(q[i] < 0.000001)
+ al = 1000000.0*l;
+ else if(q[i] > 1000000.0)
+ al = 0.000001*l;
+ else
+ al = l/q[i];
+ l2 = l*l + 1.0f;
+ rcp = 1.0f/(al + l2);
+
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*al*(wn0 - wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*al*(wn0 - wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*al*(wn0 - wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*al*(wn0 - wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(wn2))
+ wn2 = 0.0f;
+ if(PD_BADFLOAT(wn1))
+ wn1 = 0.0f;
+
+ x->x_wn1 = wn1;
+ x->x_wn2 = wn2;
+ return(w+7);
+}
+
+static t_int *sigvcf_filter_perform_rbp2(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *lp = (float *)(w[2]);
+ float *q = (float *)(w[3]);
+ float *out = (float *)(w[4]);
+ t_sigvcf_filter *x = (t_sigvcf_filter *)(w[5]);
+ int i, n = (t_int)(w[6]);
+ float wn0, wn1=x->x_wn1, wn2=x->x_wn2;
+ float al, l, l2, rcp;
+
+ for(i=0; i<n; i+=4)
+ {
+ l = lp[i];
+ if(q[i] < 0.000001)
+ al = 1000000.0*l;
+ else if(q[i] > 1000000.0)
+ al = 0.000001*l;
+ else
+ al = l/q[i];
+ l2 = l*l + 1.0f;
+ rcp = 1.0f/(al + l2);
+
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*l*(wn0 - wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*l*(wn0 - wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*l*(wn0 - wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = rcp*l*(wn0 - wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(wn2))
+ wn2 = 0.0f;
+ if(PD_BADFLOAT(wn1))
+ wn1 = 0.0f;
+
+ x->x_wn1 = wn1;
+ x->x_wn2 = wn2;
+ return(w+7);
+}
+
+static t_int *sigvcf_filter_perform_hp2(t_int *w)
+{
+ float *in = (float *)(w[1]);
+ float *lp = (float *)(w[2]);
+ float *q = (float *)(w[3]);
+ float *out = (float *)(w[4]);
+ t_sigvcf_filter *x = (t_sigvcf_filter *)(w[5]);
+ int i, n = (t_int)(w[6]);
+ float wn0, wn1=x->x_wn1, wn2=x->x_wn2;
+ float l, al, l2, rcp, forw;
+
+ for(i=0; i<n; i+=4)
+ {
+ l = lp[i];
+ if(q[i] < 0.000001)
+ al = 1000000.0*l;
+ else if(q[i] > 1000000.0)
+ al = 0.000001*l;
+ else
+ al = l/q[i];
+ l2 = l*l + 1.0f;
+ rcp = 1.0f/(al + l2);
+ forw = rcp * (l2 - 1.0f);
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = forw*(wn0 - 2.0f*wn1 + wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = forw*(wn0 - 2.0f*wn1 + wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = forw*(wn0 - 2.0f*wn1 + wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+
+ wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2);
+ *out++ = forw*(wn0 - 2.0f*wn1 + wn2);
+ wn2 = wn1;
+ wn1 = wn0;
+ }
+ /* NAN protect */
+ if(PD_BADFLOAT(wn2))
+ wn2 = 0.0f;
+ if(PD_BADFLOAT(wn1))
+ wn1 = 0.0f;
+
+ x->x_wn1 = wn1;
+ x->x_wn2 = wn2;
+ return(w+7);
+}
+
+static void sigvcf_filter_dsp(t_sigvcf_filter *x, t_signal **sp)
+{
+ if(!strcmp(x->x_filtname,"bp2"))
+ dsp_add(sigvcf_filter_perform_bp2, 6, sp[0]->s_vec, sp[1]->s_vec,
+ sp[2]->s_vec, sp[3]->s_vec, x, sp[0]->s_n);
+ else if(!strcmp(x->x_filtname,"rbp2"))
+ dsp_add(sigvcf_filter_perform_rbp2, 6, sp[0]->s_vec, sp[1]->s_vec,
+ sp[2]->s_vec, sp[3]->s_vec, x, sp[0]->s_n);
+ else if(!strcmp(x->x_filtname,"lp2"))
+ dsp_add(sigvcf_filter_perform_lp2, 6, sp[0]->s_vec, sp[1]->s_vec,
+ sp[2]->s_vec, sp[3]->s_vec, x, sp[0]->s_n);
+ else if(!strcmp(x->x_filtname,"hp2"))
+ dsp_add(sigvcf_filter_perform_hp2, 6, sp[0]->s_vec, sp[1]->s_vec,
+ sp[2]->s_vec, sp[3]->s_vec, x, sp[0]->s_n);
+ else
+ {
+ dsp_add(sigvcf_filter_perform_snafu, 6, sp[0]->s_vec, sp[1]->s_vec,
+ sp[2]->s_vec, sp[3]->s_vec, x, sp[0]->s_n);
+ post("vcf_filter~-Error: 1. initial-arguments: <sym> kind: lp2, bp2, rbp2, hp2!");
+ }
+}
+
+static void *sigvcf_filter_new(t_symbol *filt_typ)
+{
+ t_sigvcf_filter *x = (t_sigvcf_filter *)pd_new(sigvcf_filter_class);
+ char *c;
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ 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;
+ x->x_wn1 = 0.0;
+ x->x_wn2 = 0.0;
+ c = (char *)filt_typ->s_name;
+ c[5] = 0;
+ strcpy(x->x_filtname, c);
+ return(x);
+}
+
+void sigvcf_filter_setup(void)
+{
+ sigvcf_filter_class = class_new(gensym("vcf_filter~"), (t_newmethod)sigvcf_filter_new,
+ 0, sizeof(t_sigvcf_filter), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(sigvcf_filter_class, t_sigvcf_filter, x_msi);
+ class_addmethod(sigvcf_filter_class, (t_method)sigvcf_filter_dsp, gensym("dsp"), 0);
+ class_sethelpsymbol(sigvcf_filter_class, gensym("iemhelp/help-vcf_filter~"));
+}
diff --git a/src/iemlib1/soundfile_info.c b/src/iemlib1/soundfile_info.c
new file mode 100644
index 0000000..f7cbf6b
--- /dev/null
+++ b/src/iemlib1/soundfile_info.c
@@ -0,0 +1,261 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#define SFI_HEADER_SAMPLERATE 0
+#define SFI_HEADER_FILENAME 1
+#define SFI_HEADER_MULTICHANNEL_FILE_LENGTH 2
+#define SFI_HEADER_HEADERBYTES 3
+#define SFI_HEADER_CHANNELS 4
+#define SFI_HEADER_BYTES_PER_SAMPLE 5
+#define SFI_HEADER_ENDINESS 6
+
+#define SFI_HEADER_SIZE 7
+
+
+
+/* -------------------- soundfile_info ------------------------------- */
+
+static t_class *soundfile_info_class;
+
+typedef struct _soundfile_info
+{
+ t_object x_obj;
+ long *x_begmem;
+ int x_size;
+ t_atom x_atheader[SFI_HEADER_SIZE];
+ t_canvas *x_canvas;
+ void *x_list_out;
+} t_soundfile_info;
+
+static short soundfile_info_str2short(char *cvec)
+{
+ short s=0;
+ unsigned char *uc=(unsigned char *)cvec;
+
+ s += (short)(*uc);
+ s += (short)(*(uc+1)*256);
+ return(s);
+}
+
+static long soundfile_info_str2long(char *cvec)
+{
+ long l=0;
+ unsigned char *uc=(unsigned char *)cvec;
+
+ l += (long)(*uc);
+ l += (long)(*(uc+1)*256);
+ l += (long)(*(uc+2)*65536);
+ l += (long)(*(uc+3)*16777216);
+ return(l);
+}
+
+static void soundfile_info_read(t_soundfile_info *x, t_symbol *filename)
+{
+ char completefilename[400];
+ int i, n, n2, n4, filesize, read_chars, header_size=0, ch, bps, sr;
+ FILE *fh;
+ t_atom *at;
+ char *cvec;
+ long ll;
+ short ss;
+
+ if(filename->s_name[0] == '/')/*make complete path + filename*/
+ {
+ strcpy(completefilename, filename->s_name);
+ }
+ else if(((filename->s_name[0] >= 'A')&&(filename->s_name[0] <= 'Z')||
+ (filename->s_name[0] >= 'a')&&(filename->s_name[0] <= 'z'))&&
+ (filename->s_name[1] == ':')&&(filename->s_name[2] == '/'))
+ {
+ strcpy(completefilename, filename->s_name);
+ }
+ else
+ {
+ strcpy(completefilename, canvas_getdir(x->x_canvas)->s_name);
+ strcat(completefilename, "/");
+ strcat(completefilename, filename->s_name);
+ }
+
+ fh = fopen(completefilename,"rb");
+ if(!fh)
+ {
+ post("soundfile_info_read: cannot open %s !!\n", completefilename);
+ }
+ else
+ {
+ n = x->x_size;
+ n2 = sizeof(short) * x->x_size;
+ n4 = sizeof(long) * x->x_size;
+ fseek(fh, 0, SEEK_END);
+ filesize = ftell(fh);
+ fseek(fh,0,SEEK_SET);
+ read_chars = (int)fread(x->x_begmem, sizeof(char), n4, fh) /2;
+ fclose(fh);
+// post("read chars = %d", read_chars);
+ cvec = (char *)x->x_begmem;
+ if(read_chars > 4)
+ {
+ if(strncmp(cvec, "RIFF", 4))
+ {
+ post("soundfile_info_read-error: %s is no RIFF-WAVE-file", completefilename);
+ goto soundfile_info_end;
+ }
+ header_size += 8;
+ cvec += 8;
+ if(strncmp(cvec, "WAVE", 4))
+ {
+ post("soundfile_info_read-error: %s is no RIFF-WAVE-file", completefilename);
+ goto soundfile_info_end;
+ }
+ header_size += 4;
+ cvec += 4;
+
+ for(i=header_size/2; i<read_chars; i++)
+ {
+ if(!strncmp(cvec, "fmt ", 4))
+ goto soundfile_info_fmt;
+ header_size += 2;
+ cvec += 2;
+ }
+ post("soundfile_info_read-error: %s has at begin no format-chunk", completefilename);
+ goto soundfile_info_end;
+
+soundfile_info_fmt:
+ header_size += 4;
+ cvec += 4;
+ ll = soundfile_info_str2long(cvec);
+ if(ll != 16)
+ {
+ post("soundfile_info_read-error: %s has a format-chunk not equal to 16", completefilename);
+ goto soundfile_info_end;
+ }
+ header_size += 4;
+ cvec += 4;
+ ss = soundfile_info_str2short(cvec);
+ /* format */
+ if(ss != 1) /* PCM = 1 */
+ {
+ post("soundfile_info_read-error: %s is not PCM-format coded", completefilename);
+ goto soundfile_info_end;
+ }
+ header_size += 2;
+ cvec += 2;
+ ss = soundfile_info_str2short(cvec);
+ /* channels */
+ if((ss < 1) || (ss > 100))
+ {
+ post("soundfile_info_read-error: %s has no common channel-number", completefilename);
+ goto soundfile_info_end;
+ }
+ SETFLOAT(x->x_atheader+SFI_HEADER_CHANNELS, (float)ss);
+ ch = ss;
+ header_size += 2;
+ cvec += 2;
+ ll = soundfile_info_str2long(cvec);
+ /* samplerate */
+ if((ll > 400000) || (ll < 200))
+ {
+ post("soundfile_info_read-error: %s has no common samplerate", completefilename);
+ goto soundfile_info_end;
+ }
+ SETFLOAT(x->x_atheader+SFI_HEADER_SAMPLERATE, (float)ll);
+ sr = ll;
+ header_size += 4;
+ cvec += 4;
+
+ header_size += 4; /* bytes_per_sec */
+ cvec += 4;
+ ss = soundfile_info_str2short(cvec);
+
+ /* bytes_per_sample */
+ if((ss < 1) || (ss > 100))
+ {
+ post("soundfile_info_read-error: %s has no common number of bytes per sample", completefilename);
+ goto soundfile_info_end;
+ }
+ SETFLOAT(x->x_atheader+SFI_HEADER_BYTES_PER_SAMPLE, (float)(ss/ch));
+ bps = ss;
+ header_size += 2;
+ cvec += 2;
+
+ header_size += 2; /* bits_per_sample */
+ cvec += 2;
+
+ for(i=header_size/2; i<read_chars; i++)
+ {
+ if(!strncmp(cvec, "data", 4))
+ goto soundfile_info_data;
+ header_size += 2;
+ cvec += 2;
+ }
+ post("soundfile_info_read-error: %s has at begin no data-chunk", completefilename);
+ goto soundfile_info_end;
+
+soundfile_info_data:
+ header_size += 8;
+ cvec += 8;
+
+ SETFLOAT(x->x_atheader+SFI_HEADER_HEADERBYTES, (float)header_size);
+
+ filesize -= header_size;
+ filesize /= bps;
+ SETFLOAT(x->x_atheader+SFI_HEADER_MULTICHANNEL_FILE_LENGTH, (float)filesize);
+ SETSYMBOL(x->x_atheader+SFI_HEADER_ENDINESS, gensym("l"));
+ SETSYMBOL(x->x_atheader+SFI_HEADER_FILENAME, gensym(completefilename));
+
+/* post("ch = %d", ss);
+ post("sr = %d", ll);
+ post("bps = %d", ss/ch);
+ post("head = %d", header_size);
+ post("len = %d", filesize);*/
+
+ outlet_list(x->x_list_out, &s_list, SFI_HEADER_SIZE, x->x_atheader);
+
+
+soundfile_info_end:
+
+ ;
+ }
+ }
+}
+
+static void soundfile_info_free(t_soundfile_info *x)
+{
+ freebytes(x->x_begmem, x->x_size * sizeof(long));
+}
+
+static void *soundfile_info_new(void)
+{
+ t_soundfile_info *x = (t_soundfile_info *)pd_new(soundfile_info_class);
+
+ x->x_size = 10000;
+ x->x_begmem = (long *)getbytes(x->x_size * sizeof(long));
+ x->x_list_out = outlet_new(&x->x_obj, &s_list);
+ x->x_canvas = canvas_getcurrent();
+ return (x);
+}
+
+/* ---------------- global setup function -------------------- */
+
+void soundfile_info_setup(void)
+{
+ soundfile_info_class = class_new(gensym("soundfile_info"), (t_newmethod)soundfile_info_new,
+ (t_method)soundfile_info_free, sizeof(t_soundfile_info), 0, 0);
+ class_addmethod(soundfile_info_class, (t_method)soundfile_info_read, gensym("read"), A_SYMBOL, 0);
+ class_sethelpsymbol(soundfile_info_class, gensym("iemhelp/help-soundfile_info"));
+}
+
diff --git a/src/iemlib1/split.c b/src/iemlib1/split.c
new file mode 100644
index 0000000..0a3bcff
--- /dev/null
+++ b/src/iemlib1/split.c
@@ -0,0 +1,54 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* --------------------------- split ----------------------------- */
+
+typedef struct _split
+{
+ t_object x_obj;
+ t_outlet *x_out_less;
+ t_outlet *x_out_greater_equal;
+ float x_threshold;
+} t_split;
+
+static t_class *split_class;
+
+static void split_float(t_split *x, t_float f)
+{
+ if(f < x->x_threshold)
+ outlet_float(x->x_out_less, f);
+ else
+ outlet_float(x->x_out_greater_equal, f);
+}
+
+static void *split_new(t_floatarg f)
+{
+ t_split *x = (t_split *)pd_new(split_class);
+ floatinlet_new(&x->x_obj, &x->x_threshold);
+ x->x_out_less = outlet_new(&x->x_obj, &s_float);
+ x->x_out_greater_equal = outlet_new(&x->x_obj, &s_float);
+ x->x_threshold = f;
+ return (x);
+}
+
+void split_setup(void)
+{
+ split_class = class_new(gensym("split"), (t_newmethod)split_new, 0,
+ sizeof(t_split), 0, A_DEFFLOAT, 0);
+ class_addfloat(split_class, split_float);
+ class_sethelpsymbol(split_class, gensym("iemhelp/help-split"));
+} \ No newline at end of file
diff --git a/src/iemlib1/v2db.c b/src/iemlib1/v2db.c
new file mode 100644
index 0000000..b3e342d
--- /dev/null
+++ b/src/iemlib1/v2db.c
@@ -0,0 +1,45 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ---------------- v2db - value to dB converter. ----------------- */
+
+static t_class *v2db_class;
+
+float v2db(float f)
+{
+ return (f <= 0 ? -199.9 : 8.6858896381*log(f));
+}
+
+static void v2db_float(t_object *x, t_float f)
+{
+ outlet_float(x->ob_outlet, v2db(f));
+}
+
+static void *v2db_new(void)
+{
+ t_object *x = (t_object *)pd_new(v2db_class);
+ outlet_new(x, &s_float);
+ return (x);
+}
+
+void v2db_setup(void)
+{
+ v2db_class = class_new(gensym("v2db"), v2db_new, 0,
+ sizeof(t_object), 0, 0);
+ class_addfloat(v2db_class, (t_method)v2db_float);
+ class_sethelpsymbol(v2db_class, gensym("iemhelp/help-v2db"));
+}
diff --git a/src/iemlib2/add2_comma.c b/src/iemlib2/add2_comma.c
new file mode 100644
index 0000000..62ee45f
--- /dev/null
+++ b/src/iemlib2/add2_comma.c
@@ -0,0 +1,123 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ add2_comma ---------------------------- */
+static t_class *add2_comma_class;
+
+typedef struct _add2_comma
+{
+ t_object x_obj;
+ int x_size;
+ t_atom *x_at;
+ t_symbol *x_sym;
+ t_atomtype x_type;
+} t_add2_comma;
+
+static void add2_comma_bang(t_add2_comma *x)
+{
+ SETCOMMA(x->x_at);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, 1, x->x_at);
+}
+
+static void add2_comma_float(t_add2_comma *x, t_float f)
+{
+ SETCOMMA(x->x_at);
+ SETFLOAT(x->x_at+1, f);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, 2, x->x_at);
+}
+
+static void add2_comma_symbol(t_add2_comma *x, t_symbol *s)
+{
+ SETCOMMA(x->x_at);
+ SETSYMBOL(x->x_at+1, s);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, 2, x->x_at);
+}
+
+/*static void add2_comma_pointer(t_add2_comma *x, t_gpointer *gp)
+{
+ if(!x->x_at)
+ {
+ x->x_n = 1;
+ x->x_at = (t_atom *)getbytes(sizeof(t_atom));
+ }
+ x->x_ac = 1;
+ SETPOINTER(x->x_at, gp);
+ x->x_sym = &s_pointer;
+ outlet_pointer(x->x_obj.ob_outlet, gp);
+}*/
+
+static void add2_comma_list(t_add2_comma *x, t_symbol *s, int ac, t_atom *av)
+{
+ int i;
+
+ if((ac+1) > x->x_size)
+ {
+ x->x_at = (t_atom *)resizebytes(x->x_at, x->x_size*sizeof(t_atom), (ac+2)*sizeof(t_atom));
+ x->x_size = ac+2;
+ }
+ SETCOMMA(x->x_at);
+ for(i=1; i<=ac; i++)
+ x->x_at[i] = av[i-1];
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, ac+1, x->x_at);
+}
+
+static void add2_comma_anything(t_add2_comma *x, t_symbol *s, int ac, t_atom *av)
+{
+ int i;
+
+ if((ac+2) > x->x_size)
+ {
+ x->x_at = (t_atom *)resizebytes(x->x_at, x->x_size*sizeof(t_atom), (ac+3)*sizeof(t_atom));
+ x->x_size = ac+3;
+ }
+ SETCOMMA(x->x_at);
+ SETSYMBOL(x->x_at+1, s);
+ for(i=1; i<=ac; i++)
+ x->x_at[i+1] = av[i-1];
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, ac+2, x->x_at);
+}
+
+static void add2_comma_free(t_add2_comma *x)
+{
+ if(x->x_at)
+ freebytes(x->x_at, x->x_size * sizeof(t_atom));
+}
+
+static void *add2_comma_new(void)
+{
+ t_add2_comma *x = (t_add2_comma *)pd_new(add2_comma_class);
+
+ x->x_size = 10;
+ x->x_at = (t_atom *)getbytes(x->x_size * sizeof(t_atom));
+ x->x_sym = gensym("add2");
+ outlet_new(&x->x_obj, &s_list);
+ return(x);
+}
+
+void add2_comma_setup(void)
+{
+ add2_comma_class = class_new(gensym("add2_comma"), (t_newmethod)add2_comma_new,
+ (t_method)add2_comma_free, sizeof(t_add2_comma), 0, 0);
+ class_addbang(add2_comma_class, (t_method)add2_comma_bang);
+ class_addanything(add2_comma_class, add2_comma_anything);
+ class_addlist(add2_comma_class, add2_comma_list);
+ /*class_addpointer(add2_comma_class, add2_comma_pointer);*/
+ class_addfloat(add2_comma_class, (t_method)add2_comma_float);
+ class_addsymbol(add2_comma_class, add2_comma_symbol);
+ class_sethelpsymbol(add2_comma_class, gensym("iemhelp/help-add2_comma"));
+}
+
diff --git a/src/iemlib2/bpe.c b/src/iemlib2/bpe.c
new file mode 100644
index 0000000..c011424
--- /dev/null
+++ b/src/iemlib2/bpe.c
@@ -0,0 +1,125 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ bpe ---------------------------- */
+static t_class *bpe_class;
+
+typedef struct _bpe
+{
+ t_object x_obj;
+ t_clock *x_clock;
+ int x_maxnum;
+ int x_curnum;
+ int x_curindex;
+ t_atom *x_beg;
+ void *x_out_val;
+ void *x_out_time;
+ void *x_out_finished;
+} t_bpe;
+
+static void bpe_stop(t_bpe *x)
+{
+ clock_unset(x->x_clock);
+}
+
+static void bpe_tick(t_bpe *x)
+{
+ t_atom *vec = x->x_beg;
+ float val, time;
+
+ if(x->x_curindex >= x->x_curnum)
+ {
+ bpe_stop(x);
+ outlet_bang(x->x_out_finished);
+ }
+ else
+ {
+ vec += x->x_curindex;
+ val = atom_getfloat(vec++);
+ time = atom_getfloat(vec);
+ outlet_float(x->x_out_time, time);
+ outlet_float(x->x_out_val, val);
+ x->x_curindex += 2;
+ clock_delay(x->x_clock, time);
+ }
+}
+
+static void bpe_bang(t_bpe *x)
+{
+ t_atom *vec = x->x_beg;
+ float val, time;
+
+ if(x->x_curnum)
+ {
+ x->x_curindex = 2;
+ val = atom_getfloat(vec++);
+ time = atom_getfloat(vec);
+ outlet_float(x->x_out_time, time);
+ outlet_float(x->x_out_val, val);
+ clock_delay(x->x_clock, time);
+ }
+}
+
+static void bpe_list(t_bpe *x, t_symbol *s, int ac, t_atom *av)
+{
+ int n = ac & 0xfffffffe, i;
+ t_atom *vec = x->x_beg;
+ if(n > x->x_maxnum)
+ {
+ freebytes(x->x_beg, x->x_maxnum*sizeof(t_atom));
+ x->x_maxnum = 2 + n;
+ x->x_beg = (t_atom *)getbytes(x->x_maxnum*sizeof(t_atom));
+ vec = x->x_beg;
+ }
+ x->x_curnum = n;
+ for(i=0; i<n; i++)
+ {
+ *vec++ = *av++;
+ }
+}
+
+static void bpe_free(t_bpe *x)
+{
+ freebytes(x->x_beg, x->x_maxnum*sizeof(t_atom));
+ clock_free(x->x_clock);
+}
+
+static void *bpe_new(void)
+{
+ t_bpe *x = (t_bpe *)pd_new(bpe_class);
+
+ x->x_curindex = 0;
+ x->x_maxnum = 20;
+ x->x_curnum = 0;
+ x->x_beg = (t_atom *)getbytes(x->x_maxnum*sizeof(t_atom));
+ x->x_clock = clock_new(x, (t_method)bpe_tick);
+ x->x_out_val = outlet_new(&x->x_obj, &s_float);
+ x->x_out_time = outlet_new(&x->x_obj, &s_float);
+ x->x_out_finished = outlet_new(&x->x_obj, &s_bang);
+ return (x);
+}
+
+void bpe_setup(void)
+{
+ bpe_class = class_new(gensym("bpe"), (t_newmethod)bpe_new,
+ (t_method)bpe_free, sizeof(t_bpe), 0, 0);
+ class_addmethod(bpe_class, (t_method)bpe_stop, gensym("stop"), 0);
+ class_addbang(bpe_class, bpe_bang);
+ class_addlist(bpe_class, (t_method)bpe_list);
+ class_sethelpsymbol(bpe_class, gensym("iemhelp/help-bpe"));
+}
+
diff --git a/src/iemlib2/dollarg.c b/src/iemlib2/dollarg.c
new file mode 100644
index 0000000..253c0ff
--- /dev/null
+++ b/src/iemlib2/dollarg.c
@@ -0,0 +1,113 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "g_canvas.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+EXTERN void canvas_getargs(int *argcp, t_atom **argvp);
+
+/* ------------------------ dollarg ---------------------------- */
+
+static t_class *dollarg_class;
+
+typedef struct _dollarg
+{
+ t_object x_obj;
+ void *x_outlet_ac;
+ t_atom *x_at;
+ int x_ac;
+} t_dollarg;
+
+static void dollarg_float(t_dollarg *x, t_floatarg f)
+{
+ int i = (int)f;
+
+ if(!i)
+ {
+ outlet_float(x->x_outlet_ac, x->x_ac);
+ if(x->x_ac)
+ outlet_list(x->x_obj.ob_outlet, &s_list, x->x_ac, x->x_at);
+ }
+ else if(i > 0)
+ {
+ if(i <= x->x_ac)
+ {
+ outlet_float(x->x_outlet_ac, i);
+ if(IS_A_FLOAT(x->x_at, i-1))
+ outlet_float(x->x_obj.ob_outlet, atom_getfloatarg(i-1, x->x_ac, x->x_at));
+ else if(IS_A_SYMBOL(x->x_at, i-1))
+ outlet_symbol(x->x_obj.ob_outlet, atom_getsymbolarg(i-1, x->x_ac, x->x_at));
+ }
+ else
+ outlet_float(x->x_outlet_ac, 0);
+ }
+ else
+ {
+ int j = x->x_ac + i;
+
+ if(j >= 0)
+ {
+ outlet_float(x->x_outlet_ac, j+1);
+ if(IS_A_FLOAT(x->x_at, j))
+ outlet_float(x->x_obj.ob_outlet, atom_getfloatarg(j, x->x_ac, x->x_at));
+ else if(IS_A_SYMBOL(x->x_at, j))
+ outlet_symbol(x->x_obj.ob_outlet, atom_getsymbolarg(j, x->x_ac, x->x_at));
+ }
+ else
+ outlet_float(x->x_outlet_ac, 0);
+ }
+}
+
+static void dollarg_bang(t_dollarg *x)
+{
+ dollarg_float(x, 0.0f);
+}
+
+static void dollarg_free(t_dollarg *x)
+{
+ if(x->x_ac)
+ freebytes(x->x_at, x->x_ac * sizeof(t_atom));
+}
+
+static void *dollarg_new(void)
+{
+ t_dollarg *x = (t_dollarg *)pd_new(dollarg_class);
+ t_glist *glist=(t_glist *)canvas_getcurrent();
+ t_canvas *canvas=glist_getcanvas(glist);
+ int pargc;
+ t_atom *pargv, *at;
+
+ canvas_setcurrent(canvas);
+ canvas_getargs(&pargc, &pargv);
+ canvas_unsetcurrent(canvas);
+ x->x_at = (t_atom *)getbytes(pargc*sizeof(t_atom));
+ x->x_ac = pargc;
+ at = x->x_at;
+ while(pargc--)
+ *at++ = *pargv++;
+ outlet_new(&x->x_obj, &s_list);
+ x->x_outlet_ac = outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+void dollarg_setup(void)
+{
+ dollarg_class = class_new(gensym("dollarg"), (t_newmethod)dollarg_new,
+ (t_method)dollarg_free, sizeof(t_dollarg), 0, 0);
+ class_addcreator((t_newmethod)dollarg_new, gensym("$n"), 0);
+ class_addbang(dollarg_class, (t_method)dollarg_bang);
+ class_addfloat(dollarg_class, (t_method)dollarg_float);
+ class_sethelpsymbol(dollarg_class, gensym("iemhelp/help-dollarg"));
+}
diff --git a/src/iemlib2/exp_inc.c b/src/iemlib2/exp_inc.c
new file mode 100644
index 0000000..065937f
--- /dev/null
+++ b/src/iemlib2/exp_inc.c
@@ -0,0 +1,138 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ exp_inc ---------------------------- */
+static t_class *exp_inc_class;
+
+typedef struct _exp_inc
+{
+ t_object x_obj;
+ float x_initialval;
+ float x_currentval;
+ float x_mulfactor;
+ float x_addincrement;
+ float x_min;
+ float x_max;
+} t_exp_inc;
+
+static void exp_inc_bang(t_exp_inc *x)
+{
+ outlet_float(x->x_obj.ob_outlet, x->x_currentval);
+ x->x_currentval = x->x_currentval * x->x_mulfactor + x->x_addincrement;
+ if(x->x_currentval < x->x_min)
+ x->x_currentval = x->x_min;
+ if(x->x_currentval > x->x_max)
+ x->x_currentval = x->x_max;
+}
+
+static void exp_inc_reset(t_exp_inc *x)
+{
+ x->x_currentval = x->x_initialval;
+ if(x->x_currentval < x->x_min)
+ x->x_currentval = x->x_min;
+ if(x->x_currentval > x->x_max)
+ x->x_currentval = x->x_max;
+}
+
+static void exp_inc_float(t_exp_inc *x, t_floatarg f)
+{
+ x->x_initialval = (float)f;
+ x->x_currentval = x->x_initialval;
+ if(x->x_currentval < x->x_min)
+ x->x_currentval = x->x_min;
+ if(x->x_currentval > x->x_max)
+ x->x_currentval = x->x_max;
+}
+
+static void exp_inc_ft1(t_exp_inc *x, t_floatarg f)
+{
+ x->x_mulfactor = 1.0 + 0.01*(float)f;
+}
+
+static void exp_inc_ft2(t_exp_inc *x, t_floatarg f)
+{
+ x->x_addincrement = (float)f;
+}
+
+static void exp_inc_ft3(t_exp_inc *x, t_floatarg f)
+{
+ x->x_min = (float)f;
+ if(x->x_currentval < x->x_min)
+ x->x_currentval = x->x_min;
+}
+
+static void exp_inc_ft4(t_exp_inc *x, t_floatarg f)
+{
+ x->x_max = (float)f;
+ if(x->x_currentval > x->x_max)
+ x->x_currentval = x->x_max;
+}
+
+static void exp_inc_list(t_exp_inc *x, t_symbol *s, int ac, t_atom *av)
+{
+ if((ac == 5)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1)&&IS_A_FLOAT(av,2)
+ &&IS_A_FLOAT(av,3)&&IS_A_FLOAT(av,4))
+ {
+ exp_inc_ft4(x, atom_getfloatarg(4, ac, av));
+ exp_inc_ft3(x, atom_getfloatarg(3, ac, av));
+ exp_inc_ft2(x, atom_getfloatarg(2, ac, av));
+ exp_inc_ft1(x, atom_getfloatarg(1, ac, av));
+ exp_inc_float(x, atom_getfloatarg(0, ac, av));
+ }
+}
+
+static void *exp_inc_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_exp_inc *x = (t_exp_inc *)pd_new(exp_inc_class);
+
+ x->x_currentval = 10.0;
+ x->x_mulfactor = 1.0;
+ x->x_addincrement = 0.0;
+ x->x_min = 0.0;
+ x->x_max = 1000.0;
+ if((ac == 5)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1)&&IS_A_FLOAT(av,2)
+ &&IS_A_FLOAT(av,3)&&IS_A_FLOAT(av,4))
+ {
+ exp_inc_ft4(x, atom_getfloatarg(4, ac, av));
+ exp_inc_ft3(x, atom_getfloatarg(3, ac, av));
+ exp_inc_ft2(x, atom_getfloatarg(2, ac, av));
+ exp_inc_ft1(x, atom_getfloatarg(1, ac, av));
+ exp_inc_float(x, atom_getfloatarg(0, ac, av));
+ }
+ outlet_new(&x->x_obj, &s_float);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft3"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft4"));
+ return (x);
+}
+
+void exp_inc_setup(void)
+{
+ exp_inc_class = class_new(gensym("exp_inc"), (t_newmethod)exp_inc_new,
+ 0, sizeof(t_exp_inc), 0, A_GIMME, 0);
+ class_addbang(exp_inc_class, exp_inc_bang);
+ class_addlist(exp_inc_class, (t_method)exp_inc_list);
+ class_addmethod(exp_inc_class, (t_method)exp_inc_reset, gensym("reset"), 0);
+ class_addfloat(exp_inc_class, (t_method)exp_inc_float);
+ class_addmethod(exp_inc_class, (t_method)exp_inc_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(exp_inc_class, (t_method)exp_inc_ft2, gensym("ft2"), A_FLOAT, 0);
+ class_addmethod(exp_inc_class, (t_method)exp_inc_ft3, gensym("ft3"), A_FLOAT, 0);
+ class_addmethod(exp_inc_class, (t_method)exp_inc_ft4, gensym("ft4"), A_FLOAT, 0);
+ class_sethelpsymbol(exp_inc_class, gensym("iemhelp/help-exp_inc"));
+}
+
diff --git a/src/iemlib2/float24.c b/src/iemlib2/float24.c
new file mode 100644
index 0000000..3923482
--- /dev/null
+++ b/src/iemlib2/float24.c
@@ -0,0 +1,83 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ---- float24 - float=int or list of float=symbol concaternat to int=float ----- */
+
+typedef struct _float24
+{
+ t_object x_obj;
+ float x_arg;
+} t_float24;
+
+static t_class *float24_class;
+
+static float float24_calc_sum(int argc, t_atom *argv)
+{
+ int i;
+ char str[1000], buf[100];
+
+ str[0] = 0;
+ for(i=0; i<argc; i++)
+ {
+ if(IS_A_FLOAT(argv, i))
+ {
+ sprintf(buf, "%g", (float)atom_getfloatarg(i, argc, argv));
+ strcat(str, buf);
+ }
+ }
+ return(atof(str));
+}
+
+static void float24_bang(t_float24 *x)
+{
+ outlet_float(x->x_obj.ob_outlet, x->x_arg);
+}
+
+static void float24_float(t_float24 *x, t_float f)
+{
+ x->x_arg = f;
+ float24_bang(x);
+}
+
+static void float24_list(t_float24 *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if(argc > 0)
+ x->x_arg = float24_calc_sum(argc, argv);
+ float24_bang(x);
+}
+
+static void *float24_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_float24 *x = (t_float24 *)pd_new(float24_class);
+
+ outlet_new(&x->x_obj, &s_float);
+ x->x_arg = 0.0f;
+ if(argc > 0)
+ x->x_arg = float24_calc_sum(argc, argv);
+ return (x);
+}
+
+void float24_setup(void)
+{
+ float24_class = class_new(gensym("float24"), (t_newmethod)float24_new, 0,
+ sizeof(t_float24), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)float24_new, gensym("f24"), A_GIMME, 0);
+ class_addbang(float24_class, (t_method)float24_bang);
+ class_addfloat(float24_class, (t_method)float24_float);
+ class_addlist(float24_class, (t_method)float24_list);
+ class_sethelpsymbol(float24_class, gensym("iemhelp/help-float24"));
+}
diff --git a/src/iemlib2/iem_anything_kernel.c b/src/iemlib2/iem_anything_kernel.c
new file mode 100644
index 0000000..11fee81
--- /dev/null
+++ b/src/iemlib2/iem_anything_kernel.c
@@ -0,0 +1,148 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "g_canvas.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+EXTERN void canvas_getargs(int *argcp, t_atom **argvp);
+
+/* ------------------------ iem_anything_kernel ---------------------------- */
+static t_class *iem_anything_kernel_class;
+
+typedef struct _iem_anything_kernel
+{
+ t_object x_obj;
+ int x_inlet_select;
+ int x_size;
+ int x_ac;
+ t_atom *x_at;
+ t_symbol *x_sym;
+} t_iem_anything_kernel;
+
+static void iem_anything_kernel_atcopy(t_atom *src, t_atom *dst, int n)
+{
+ while(n--)
+ *dst++ = *src++;
+}
+
+static void iem_anything_kernel_inlet_select(t_iem_anything_kernel *x, t_floatarg in_sel_01)
+{
+ x->x_inlet_select = (int)in_sel_01;
+}
+
+static void iem_anything_kernel_anything(t_iem_anything_kernel *x, t_symbol *s, int ac, t_atom *av)
+{
+ if((ac == 0)&&(s == &s_bang))
+ {
+ if(x->x_inlet_select)
+ {
+ x->x_ac = ac;
+ x->x_sym = s;
+ }
+ else
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, x->x_ac, x->x_at);
+ }
+ else
+ {
+ if(ac > x->x_size)
+ {
+ x->x_at = (t_atom *)resizebytes(x->x_at, x->x_size*sizeof(t_atom), ac*sizeof(t_atom));
+ x->x_size = ac;
+ }
+ x->x_ac = ac;
+ x->x_sym = s;
+ iem_anything_kernel_atcopy(av, x->x_at, ac);
+ if(!x->x_inlet_select)
+ outlet_anything(x->x_obj.ob_outlet, s, ac, av);
+ }
+}
+
+static void iem_anything_kernel_free(t_iem_anything_kernel *x)
+{
+ if(x->x_at)
+ freebytes(x->x_at, x->x_size * sizeof(t_atom));
+}
+
+static void *iem_anything_kernel_new(void)
+{
+ t_iem_anything_kernel *x = (t_iem_anything_kernel *)pd_new(iem_anything_kernel_class);
+ t_glist *glist = (t_glist *)canvas_getcurrent();
+ t_canvas *canvas=glist_getcanvas(glist);
+ int ac=0;
+ t_atom *av;
+
+ canvas_setcurrent(canvas);
+ canvas_getargs(&ac, &av);
+ canvas_unsetcurrent(canvas);
+
+ if(!ac)
+ {
+ x->x_sym = &s_bang;
+ x->x_size = 10;
+ x->x_ac = 0;
+ x->x_at = (t_atom *)getbytes(x->x_size * sizeof(t_atom));
+ }
+ else if(ac == 1)
+ {
+ x->x_size = 10;
+ x->x_at = (t_atom *)getbytes(x->x_size * sizeof(t_atom));
+ if(IS_A_SYMBOL(av,0))
+ {
+ x->x_sym = atom_getsymbol(av);
+ x->x_ac = 0;
+ }
+ else
+ {
+ x->x_sym = &s_list;
+ x->x_ac = 1;
+ x->x_at[0] = *av;
+ }
+ }
+ else /* ac > 1 */
+ {
+ if(IS_A_SYMBOL(av,0))
+ {
+ x->x_sym = atom_getsymbol(av++);
+ ac--;
+ }
+ else
+ x->x_sym = &s_list;
+ if(ac < 10)
+ x->x_size = 10;
+ else
+ x->x_size = ac;
+ x->x_ac = ac;
+ x->x_at = (t_atom *)getbytes(x->x_size * sizeof(t_atom));
+ iem_anything_kernel_atcopy(av, x->x_at, ac);
+ }
+ x->x_inlet_select = 1;
+ outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+void iem_anything_kernel_setup(void)
+{
+ char str[2];
+
+ str[0] = 1;/*inlet-sym = "\0x01"*/
+ str[1] = 0;
+ iem_anything_kernel_class = class_new(gensym("iem_anything_kernel"),
+ (t_newmethod)iem_anything_kernel_new, (t_method)iem_anything_kernel_free,
+ sizeof(t_iem_anything_kernel), 0, 0);
+ class_addmethod(iem_anything_kernel_class, (t_method)iem_anything_kernel_inlet_select, gensym(str), A_FLOAT, 0);
+ class_addanything(iem_anything_kernel_class, iem_anything_kernel_anything);
+ class_sethelpsymbol(iem_anything_kernel_class, gensym("iemhelp/help-iem_anything"));
+}
+
diff --git a/src/iemlib2/iem_append_kernel.c b/src/iemlib2/iem_append_kernel.c
new file mode 100644
index 0000000..2c67872
--- /dev/null
+++ b/src/iemlib2/iem_append_kernel.c
@@ -0,0 +1,351 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "g_canvas.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+EXTERN void canvas_getargs(int *argcp, t_atom **argvp);
+
+
+/* ------------------------ iem_append_kernel ---------------------------- */
+static t_class *iem_append_kernel_class;
+
+typedef struct _iem_append_kernel
+{
+ t_object x_obj;
+ int x_inlet_select;
+ int x_size12;
+ int x_size2;
+ int x_ac1;
+ int x_ac2;
+ t_atom *x_at12;
+ t_atom *x_at2;
+ t_symbol *x_sym1;
+ t_symbol *x_sym2;
+ t_atomtype x_type1;
+ t_atomtype x_type2;
+} t_iem_append_kernel;
+
+static void iem_append_kernel_atcopy(t_atom *src, t_atom *dst, int n)
+{
+ while(n--)
+ *dst++ = *src++;
+}
+
+static void iem_append_kernel_merge(t_iem_append_kernel *x, int off)
+{
+ if((x->x_ac1+x->x_ac2+1) > x->x_size12)
+ {
+ x->x_at12 = (t_atom *)resizebytes(x->x_at12, x->x_size12*sizeof(t_atom), 2*(x->x_ac1+x->x_ac2+1)*sizeof(t_atom));
+ x->x_size12 = 2*(x->x_ac1+x->x_ac2+1);
+ }
+ if(off)
+ SETSYMBOL(x->x_at12 + x->x_ac1, x->x_sym2);
+ iem_append_kernel_atcopy(x->x_at2, x->x_at12 + x->x_ac1 + off, x->x_ac2);
+}
+
+static void iem_append_kernel_out(t_iem_append_kernel *x)
+{
+ int off=0;
+
+ if(x->x_type1 == A_GIMME)
+ {
+ if(x->x_type2 == A_COMMA)
+ off = 1;
+ else
+ off = 0;
+ iem_append_kernel_merge(x, off);
+ outlet_list(x->x_obj.ob_outlet, &s_list, x->x_ac1+x->x_ac2+off, x->x_at12);
+ }
+ else if(x->x_type1 == A_COMMA)
+ {
+ if(x->x_type2 == A_COMMA)
+ off = 1;
+ else
+ off = 0;
+ iem_append_kernel_merge(x, off);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym1, x->x_ac1+x->x_ac2+off, x->x_at12);
+ }
+ else if(x->x_type1 == A_NULL)/*depends on 2.part*/
+ {
+ iem_append_kernel_merge(x, 0);
+ if(x->x_type2 == A_GIMME)
+ outlet_list(x->x_obj.ob_outlet, &s_list, x->x_ac2, x->x_at12);
+ else if(x->x_type2 == A_COMMA)
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym2, x->x_ac2, x->x_at12);
+ else if(x->x_type2 == A_FLOAT)
+ outlet_float(x->x_obj.ob_outlet, atom_getfloat(x->x_at12));
+ else if(x->x_type2 == A_SYMBOL)
+ outlet_symbol(x->x_obj.ob_outlet, atom_getsymbol(x->x_at12));
+ else if(x->x_type2 == A_NULL)
+ outlet_bang(x->x_obj.ob_outlet);
+ else if(x->x_type2 == A_POINTER)
+ outlet_pointer(x->x_obj.ob_outlet, (t_gpointer *)x->x_at12->a_w.w_gpointer);
+ }
+ else
+ {
+ if(x->x_type2 == A_COMMA)
+ off = 1;
+ else
+ off = 0;
+ iem_append_kernel_merge(x, off);
+ if(x->x_type2 == A_NULL)
+ {
+ if(x->x_type1 == A_FLOAT)
+ outlet_float(x->x_obj.ob_outlet, atom_getfloat(x->x_at12));
+ else if(x->x_type1 == A_SYMBOL)
+ outlet_symbol(x->x_obj.ob_outlet, atom_getsymbol(x->x_at12));
+ else if(x->x_type1 == A_POINTER)
+ outlet_pointer(x->x_obj.ob_outlet, (t_gpointer *)x->x_at12->a_w.w_gpointer);
+ }
+ else
+ outlet_list(x->x_obj.ob_outlet, &s_list, x->x_ac1+x->x_ac2+off, x->x_at12);
+ }
+}
+
+static void iem_append_kernel_inlet_select(t_iem_append_kernel *x, t_floatarg fin_sel_01)
+{
+ x->x_inlet_select = (int)fin_sel_01;
+}
+
+static void iem_append_kernel_bang(t_iem_append_kernel *x)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ x->x_ac2 = 0;
+ x->x_type2 = A_NULL;
+ x->x_sym2 = &s_list;
+ }
+ else /* if 1st inlet */
+ {
+ x->x_ac1 = 0;
+ x->x_type1 = A_NULL;
+ iem_append_kernel_out(x);
+ }
+}
+
+static void iem_append_kernel_float(t_iem_append_kernel *x, t_float f)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ x->x_ac2 = 1;
+ x->x_type2 = A_FLOAT;
+ SETFLOAT(x->x_at2, f);
+ x->x_sym2 = &s_list;
+ }
+ else /* if 1st inlet */
+ {
+ x->x_ac1 = 1;
+ x->x_type1 = A_FLOAT;
+ SETFLOAT(x->x_at12, f);
+ iem_append_kernel_out(x);
+ }
+}
+
+static void iem_append_kernel_symbol(t_iem_append_kernel *x, t_symbol *s)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ x->x_ac2 = 1;
+ x->x_type2 = A_SYMBOL;
+ SETSYMBOL(x->x_at2, s);
+ x->x_sym2 = &s_list;
+ }
+ else /* if 1st inlet */
+ {
+ x->x_ac1 = 1;
+ x->x_type1 = A_SYMBOL;
+ SETSYMBOL(x->x_at12, s);
+ iem_append_kernel_out(x);
+ }
+}
+
+static void iem_append_kernel_pointer(t_iem_append_kernel *x, t_gpointer *gp)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ x->x_ac2 = 1;
+ x->x_type2 = A_POINTER;
+ SETPOINTER(x->x_at2, gp);
+ x->x_sym2 = &s_list;
+ }
+ else /* if 1st inlet */
+ {
+ x->x_ac1 = 1;
+ x->x_type1 = A_POINTER;
+ SETPOINTER(x->x_at12, gp);
+ iem_append_kernel_out(x);
+ }
+}
+
+static void iem_append_kernel_list(t_iem_append_kernel *x, t_symbol *s, int ac, t_atom *av)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ if(ac > x->x_size2)
+ {
+ x->x_at2 = (t_atom *)resizebytes(x->x_at2, x->x_size2*sizeof(t_atom), 2*ac*sizeof(t_atom));
+ x->x_size2 = 2*ac;
+ }
+ x->x_ac2 = ac;
+ x->x_type2 = A_GIMME;
+ x->x_sym2 = &s_list;
+ iem_append_kernel_atcopy(av, x->x_at2, ac);
+ }
+ else /* if 1st inlet */
+ {
+ if((x->x_size2+ac) > x->x_size12)
+ {
+ x->x_at12 = (t_atom *)resizebytes(x->x_at12, x->x_size12*sizeof(t_atom), 2*(x->x_size2+ac)*sizeof(t_atom));
+ x->x_size12 = 2*(x->x_size2+ac);
+ }
+ x->x_ac1 = ac;
+ x->x_type1 = A_GIMME;
+ iem_append_kernel_atcopy(av, x->x_at12, ac);
+ x->x_sym1 = &s_list;
+ iem_append_kernel_out(x);
+ }
+}
+
+static void iem_append_kernel_anything(t_iem_append_kernel *x, t_symbol *s, int ac, t_atom *av)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ if((ac+1) > x->x_size2)
+ {
+ x->x_at2 = (t_atom *)resizebytes(x->x_at2, x->x_size2*sizeof(t_atom), 2*ac*sizeof(t_atom));
+ x->x_size2 = 2*ac;
+ }
+ x->x_ac2 = ac;
+ x->x_type2 = A_COMMA;
+ x->x_sym2 = s;
+ iem_append_kernel_atcopy(av, x->x_at2, ac);
+ }
+ else /* if 1st inlet */
+ {
+ if((x->x_size2+ac+1) > x->x_size12)
+ {
+ x->x_at12 = (t_atom *)resizebytes(x->x_at12, x->x_size12*sizeof(t_atom), 2*(x->x_size2+ac+1)*sizeof(t_atom));
+ x->x_size12 = 2*(x->x_size2+ac+1);
+ }
+ x->x_ac1 = ac;
+ x->x_type1 = A_COMMA;
+ iem_append_kernel_atcopy(av, x->x_at12, ac);
+ x->x_sym1 = s;
+ iem_append_kernel_out(x);
+ }
+}
+
+static void iem_append_kernel_free(t_iem_append_kernel *x)
+{
+ if(x->x_at12)
+ freebytes(x->x_at12, x->x_size12 * sizeof(t_atom));
+ if(x->x_at2)
+ freebytes(x->x_at2, x->x_size2 * sizeof(t_atom));
+}
+
+static void *iem_append_kernel_new(void)
+{
+ t_iem_append_kernel *x = (t_iem_append_kernel *)pd_new(iem_append_kernel_class);
+ t_glist *glist = (t_glist *)canvas_getcurrent();
+ t_canvas *canvas=glist_getcanvas(glist);
+ int ac=0;
+ t_atom *av;
+
+ canvas_setcurrent(canvas);
+ canvas_getargs(&ac, &av);
+ canvas_unsetcurrent(canvas);
+
+ x->x_type1 = A_NULL;
+ x->x_sym1 = &s_list;
+ x->x_size2 = 10;
+ if(ac > 5)
+ x->x_size2 = 2*ac;
+ x->x_at2 = (t_atom *)getbytes(x->x_size2 * sizeof(t_atom));
+ x->x_size12 = x->x_size2 + 10;
+ x->x_at12 = (t_atom *)getbytes(x->x_size12 * sizeof(t_atom));
+ x->x_ac1 = 0;
+ x->x_inlet_select = 1;
+ if(ac <= 0)
+ {
+ x->x_type2 = A_NULL;
+ x->x_ac2 = 0;
+ x->x_sym2 = &s_list;
+ }
+ else
+ {
+ if(IS_A_FLOAT(av, 0))
+ {
+ if(ac == 1)
+ iem_append_kernel_float(x, atom_getfloat(av));
+ else
+ iem_append_kernel_list(x, &s_list, ac, av);
+ }
+ else if(IS_A_SYMBOL(av, 0))
+ {
+ t_symbol *xsym=atom_getsymbol(av);
+
+ if(xsym == gensym("symbol"))
+ {
+ if(ac > 1)
+ iem_append_kernel_symbol(x, atom_getsymbol(av+1));
+ else
+ iem_append_kernel_symbol(x, gensym(""));
+ }
+ else if(xsym == gensym("float"))
+ {
+ if(ac > 1)
+ {
+ if(IS_A_FLOAT(av, 1))
+ iem_append_kernel_float(x, atom_getfloat(av+1));
+ else
+ iem_append_kernel_float(x, 0.0f);
+ }
+ else
+ iem_append_kernel_float(x, 0.0f);
+ }
+ else if(xsym == gensym("list"))
+ {
+ iem_append_kernel_list(x, &s_list, ac-1, av+1);
+ }
+ else
+ {
+ iem_append_kernel_anything(x, xsym, ac-1, av+1);
+ }
+ }
+ }
+ outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+void iem_append_kernel_setup(void)
+{
+ char str[2];
+
+ str[0] = 1;
+ str[1] = 0;
+ iem_append_kernel_class = class_new(gensym("iem_append_kernel"),
+ (t_newmethod)iem_append_kernel_new, (t_method)iem_append_kernel_free,
+ sizeof(t_iem_append_kernel), 0, 0);
+ class_addbang(iem_append_kernel_class, (t_method)iem_append_kernel_bang);
+ class_addpointer(iem_append_kernel_class, iem_append_kernel_pointer);
+ class_addfloat(iem_append_kernel_class, (t_method)iem_append_kernel_float);
+ class_addsymbol(iem_append_kernel_class, iem_append_kernel_symbol);
+ class_addlist(iem_append_kernel_class, iem_append_kernel_list);
+ class_addmethod(iem_append_kernel_class, (t_method)iem_append_kernel_inlet_select, gensym(str), A_FLOAT, 0);
+ class_addanything(iem_append_kernel_class, iem_append_kernel_anything);
+ class_sethelpsymbol(iem_append_kernel_class, gensym("iemhelp/help-merge_any"));
+}
diff --git a/src/iemlib2/iem_i_route.c b/src/iemlib2/iem_i_route.c
new file mode 100644
index 0000000..48855e6
--- /dev/null
+++ b/src/iemlib2/iem_i_route.c
@@ -0,0 +1,111 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* -------------------------- iem_i_route ------------------------------ */
+/* routes a list beginning with a float to an outlet, which are defined by
+ first- , last- index and offset-index */
+
+static t_class *iem_i_route_class;
+
+typedef struct _iem_i_route
+{
+ t_object x_obj;
+ int x_first_element;
+ int x_last_element;
+ t_outlet **x_out;
+} t_iem_i_route;
+
+static void iem_i_route_list(t_iem_i_route *x, t_symbol *sel, int argc, t_atom *argv)
+{
+ t_outlet **out;
+ int first, last, i;
+
+ if(!argc)
+ return;
+ i = (int)atom_getintarg(0, argc, argv);
+ first = x->x_first_element;
+ last = x->x_last_element;
+ out = x->x_out;
+ if((i >= first)&&(i <= last))
+ {
+ out += i - first;
+ if(argc >= 3)
+ {
+ if(IS_A_FLOAT(argv,1))
+ outlet_list(*out, &s_list, argc-1, argv+1);
+ else if(IS_A_SYMBOL(argv,1))
+ outlet_anything(*out, atom_getsymbolarg(1, argc, argv), argc-2, argv+2);
+ }
+ else if(argc >= 2)
+ {
+ if(IS_A_FLOAT(argv,1))
+ outlet_float(*out, (float)atom_getfloatarg(1, argc, argv));
+ else if(IS_A_SYMBOL(argv,1))
+ outlet_anything(*out, atom_getsymbolarg(1, argc, argv), 0, argv+2);
+ }
+ else
+ outlet_bang(*out);
+ }
+ else
+ {
+ out += last - first + 1;
+ outlet_list(*out, &s_list, argc, argv);
+ }
+}
+
+static void iem_i_route_free(t_iem_i_route *x)
+{
+ freebytes(x->x_out, (x->x_last_element-x->x_first_element+2) * sizeof(t_outlet *));
+}
+
+static void *iem_i_route_new(t_symbol *s, int argc, t_atom *argv)
+{
+ int n, i;
+ t_outlet **out;
+ t_iem_i_route *x = (t_iem_i_route *)pd_new(iem_i_route_class);
+
+ if((argc >= 2)&&IS_A_FLOAT(argv,0)&&IS_A_FLOAT(argv,1))
+ {
+ x->x_first_element = (int)atom_getintarg(0, argc, argv);
+ x->x_last_element = (int)atom_getintarg(1, argc, argv);
+ if((argc >= 3)&&IS_A_FLOAT(argv,2))
+ {
+ i = (int)atom_getintarg(2, argc, argv);
+ x->x_first_element += i;
+ x->x_last_element += i;
+ }
+ x->x_out = (t_outlet **)getbytes((x->x_last_element-x->x_first_element+2) * sizeof(t_outlet *));
+ n = x->x_last_element - x->x_first_element + 2;
+ for(i=0, out=x->x_out; i<n; i++, out++)
+ *out = outlet_new(&x->x_obj, &s_list);
+ return (x);
+ }
+ else
+ {
+ post("iem_i_route-ERROR: needs 3 floats!!");
+ return(0);
+ }
+}
+
+void iem_i_route_setup(void)
+{
+ iem_i_route_class = class_new(gensym("iem_i_route"), (t_newmethod)iem_i_route_new,
+ (t_method)iem_i_route_free, sizeof(t_iem_i_route), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)iem_i_route_new, gensym("iiroute"), A_GIMME, 0);
+ class_addlist(iem_i_route_class, iem_i_route_list);
+ class_sethelpsymbol(iem_i_route_class, gensym("iemhelp/help-iem_i_route"));
+}
diff --git a/src/iemlib2/iem_pbank_csv.c b/src/iemlib2/iem_pbank_csv.c
new file mode 100644
index 0000000..d426d2d
--- /dev/null
+++ b/src/iemlib2/iem_pbank_csv.c
@@ -0,0 +1,801 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+
+/* -------------------- iem_pbank_csv ------------------------------- */
+
+/* read and write method needs 2 symbols,
+ 1. symbol is a filename,
+ 2. symbol is a 3 character descriptor
+
+ 1.char: 'b'...for blank as ITEM_SEPARATOR (" ")
+ 1.char: 'c'...for comma as ITEM_SEPARATOR (",")
+ 1.char: 's'...for semicolon as ITEM_SEPARATOR (";")
+ 1.char: 't'...for tabulator as ITEM_SEPARATOR (" " = 0x09)
+
+ 2.char: 'b'...for blank,return as END_OF_LINE (" \n")
+ 2.char: 'r'...for return-only as END_OF_LINE ("\n")
+ 2.char: 's'...for semicolon,return as END_OF_LINE (";\n")
+
+ 3.char: 'l'...for linux RETURN (0x0A)
+ 3.char: 'w'...for windows RETURN (0x0D,0x0A)
+ 3.char: 'm'...for mac RETURN (0x0D)
+
+
+
+ change: recall + offset + number
+ */
+
+static t_class *iem_pbank_csv_class;
+
+typedef struct _iem_pbank_csv
+{
+ t_object x_obj;
+ int x_nr_para;
+ int x_nr_line;
+ int x_line;
+ t_atom *x_atbegmem;
+ t_atom *x_atbegbuf;
+ t_atom *x_atbegout;
+ t_canvas *x_canvas;
+ void *x_list_out;
+ void *x_offset_list_out;
+} t_iem_pbank_csv;
+
+static void iem_pbank_csv_write(t_iem_pbank_csv *x, t_symbol *filename, t_symbol *format)
+{
+ char completefilename[400], eol[4], sep, mode[4], string[200];
+ int size, p, l, nrl=x->x_nr_line, nrp=x->x_nr_para;
+ int state, max=nrl*nrp, org_size, eollen;
+ FILE *fh;
+ t_atom *ap=x->x_atbegmem;
+ char formattext[100];
+
+ strcpy(mode, "bsl"); /*blank-separator, semicolon-return-eol, linux_return*/
+ sep = ' ';
+ eol[0] = ';';
+ eol[1] = 0x0a;
+ eol[2] = 0;
+ if(filename->s_name[0] == '/')
+ {
+ strcpy(completefilename, filename->s_name);
+ }
+ else if(((filename->s_name[0] >= 'A')&&(filename->s_name[0] <= 'Z')||
+ (filename->s_name[0] >= 'a')&&(filename->s_name[0] <= 'z'))&&
+ (filename->s_name[1] == ':')&&(filename->s_name[2] == '/'))
+ {
+ strcpy(completefilename, filename->s_name);
+ }
+ else
+ {
+ strcpy(completefilename, canvas_getdir(x->x_canvas)->s_name);
+ strcat(completefilename, "/");
+ strcat(completefilename, filename->s_name);
+ }
+
+ fh = fopen(completefilename,"wb");
+ if(!fh)
+ {
+ post("iem_pbank_csv_write: cannot create %s !!\n", completefilename);
+ }
+ else
+ {
+ if(strlen(format->s_name) >= 3)
+ {
+ for(p=0; p<3; p++)
+ {
+ if((format->s_name[p] >= 'A')&&(format->s_name[p] <= 'Z'))
+ format->s_name[p] += 'a' - 'A';
+ }
+ if((format->s_name[0] == 'b')||(format->s_name[0] == 'c')||(format->s_name[0] == 's')||(format->s_name[0] == 't'))
+ mode[0] = format->s_name[0];
+ if((format->s_name[1] == 'b')||(format->s_name[1] == 'r')||(format->s_name[1] == 's'))
+ mode[1] = format->s_name[1];
+ if((format->s_name[2] == 'l')||(format->s_name[2] == 'w')||(format->s_name[2] == 'm'))
+ mode[2] = format->s_name[2];
+ }
+ else
+ post("iem_pbank_csv_write: use default format %s !!\n", mode);
+
+ if(mode[0] == 'b')
+ {
+ sep = ' ';
+ strcpy(formattext, "item-separator = BLANK; ");
+ }
+ else if(mode[0] == 'c')
+ {
+ sep = ',';
+ strcpy(formattext, "item-separator = COMMA; ");
+ }
+ else if(mode[0] == 's')
+ {
+ sep = ';';
+ strcpy(formattext, "item-separator = SEMICOLON; ");
+ }
+ else if(mode[0] == 't')
+ {
+ sep = 0x09;
+ strcpy(formattext, "item-separator = TABULATOR; ");
+ }
+
+ eollen = 1;
+ if(mode[1] == 'b')
+ {
+ eol[0] = ' ';
+ strcat(formattext, "end_of_line_terminator = BLANK-RETURN in ");
+ }
+ else if(mode[1] == 'r')
+ {
+ eollen = 0;
+ strcat(formattext, "end_of_line_terminator = RETURN in ");
+ }
+ else if(mode[1] == 's')
+ {
+ eol[0] = ';';
+ strcat(formattext, "end_of_line_terminator = SEMICOLON-RETURN in ");
+ }
+
+ if(mode[2] == 'l')
+ {
+ eol[eollen++] = 0x0a;
+ strcat(formattext, "LINUX-Format.");
+ }
+ else if(mode[2] == 'w')
+ {
+ eol[eollen++] = 0x0d;
+ eol[eollen++] = 0x0a;
+ strcat(formattext, "WINDOWS-Format.");
+ }
+ else if(mode[2] == 'm')
+ {
+ eol[eollen++] = 0x0d;
+ strcat(formattext, "MACINTOSH-Format.");
+ }
+ eol[eollen] = 0;
+
+ ap = x->x_atbegmem;
+ for(l=0; l<nrl; l++)
+ {
+ for(p=1; p<nrp; p++)
+ {
+ if(IS_A_FLOAT(ap, 0))
+ fprintf(fh, "%g%c", ap->a_w.w_float, sep);
+ else if(IS_A_SYMBOL(ap, 0))
+ fprintf(fh, "%s%c", ap->a_w.w_symbol->s_name, sep);
+ ap++;
+ }
+ if(IS_A_FLOAT(ap, 0))
+ fprintf(fh, "%g%s", ap->a_w.w_float, eol);
+ else if(IS_A_SYMBOL(ap, 0))
+ fprintf(fh, "%s%s", ap->a_w.w_symbol->s_name, eol);
+ ap++;
+ }
+ fclose(fh);
+ post("iem_pbank_csv: wrote %d parameters x %d lines to file:\n%s\nwith following format:\n%s\n", nrp, nrl, completefilename, formattext);
+ }
+}
+
+int iem_pbank_csv_text2atom(char *text, int text_size, t_atom **at_beg,
+ int *nalloc, char sep, char eol)
+{
+ char buf[MAXPDSTRING+1], *bufp, *ebuf = buf+MAXPDSTRING;
+ const char *textp = text, *etext = text + text_size;
+ int natom = 0;
+ t_atom *ap = *at_beg;
+ float f;
+
+ while(1)
+ {
+ int type;
+
+ if(textp == etext)
+ break;
+ if(*textp == eol)
+ {
+ SETSEMI(ap);
+ textp++;
+ }
+ else if(*textp == sep)
+ {
+ SETCOMMA(ap);
+ textp++;
+ }
+ else
+ {
+ char c;
+ int flst = 0, slash = 0, lastslash = 0;
+ int firstslash = (*textp == '\\');
+
+ bufp = buf;
+ do
+ {
+ c = *bufp = *textp++;
+ lastslash = slash;
+ slash = (c == '\\');
+
+ if (flst >= 0)
+ {
+ int digit = (c >= '0' && c <= '9'),
+ dot = (c == '.'), minus = (c == '-'),
+ plusminus = (minus || (c == '+')),
+ expon = (c == 'e' || c == 'E');
+ if (flst == 0) /* beginning */
+ {
+ if (minus) flst = 1;
+ else if (digit) flst = 2;
+ else if (dot) flst = 3;
+ else flst = -1;
+ }
+ else if (flst == 1) /* got minus */
+ {
+ if (digit) flst = 2;
+ else if (dot) flst = 3;
+ else flst = -1;
+ }
+ else if (flst == 2) /* got digits */
+ {
+ if (dot) flst = 4;
+ else if (expon) flst = 6;
+ else if (!digit) flst = -1;
+ }
+ else if (flst == 3) /* got '.' without digits */
+ {
+ if (digit) flst = 5;
+ else flst = -1;
+ }
+ else if (flst == 4) /* got '.' after digits */
+ {
+ if (digit) flst = 5;
+ else if (expon) flst = 6;
+ else flst = -1;
+ }
+ else if (flst == 5) /* got digits after . */
+ {
+ if (expon) flst = 6;
+ else if (!digit) flst = -1;
+ }
+ else if (flst == 6) /* got 'e' */
+ {
+ if (plusminus) flst = 7;
+ else if (digit) flst = 8;
+ else flst = -1;
+ }
+ else if (flst == 7) /* got plus or minus */
+ {
+ if (digit) flst = 8;
+ else flst = -1;
+ }
+ else if (flst == 8) /* got digits */
+ {
+ if (!digit) flst = -1;
+ }
+ }
+ if (!slash) bufp++;
+ }
+ while (textp != etext && bufp != ebuf && *textp != ' ' &&
+ (slash || (*textp != sep && *textp != eol)));
+ *bufp = 0;
+
+ if(*buf == '$' && buf[1] >= '0' && buf[1] <= '9' && !firstslash)
+ {
+ for (bufp = buf+2; *bufp; bufp++)
+ if (*bufp < '0' || *bufp > '9')
+ {
+ SETDOLLSYM(ap, gensym(buf+1));
+ goto iem_pbank_csv_didit;
+ }
+ SETDOLLAR(ap, atoi(buf+1));
+ iem_pbank_csv_didit: ;
+ }
+ else
+ {
+ if(flst == 2 || flst == 4 || flst == 5 || flst == 8)
+ {
+ f = atof(buf);
+ if((f < 1.0e-20)&&(f > -1.0e-20))
+ f = 0.0;
+ SETFLOAT(ap, f);
+ }
+ else
+ SETSYMBOL(ap, gensym(buf));
+ }
+ }
+
+ ap++;
+ natom++;
+ if(natom == *nalloc)
+ {
+ *at_beg = t_resizebytes(*at_beg, *nalloc * sizeof(t_atom),
+ *nalloc * (2*sizeof(t_atom)));
+ *nalloc = *nalloc * 2;
+ ap = *at_beg + natom;
+ }
+ if(textp == etext)
+ break;
+ }
+ return(natom);
+}
+
+/*static char myq(t_atom *a, int off)
+{
+ char c='0';
+
+ if(IS_A_SEMI(a,off))
+ c = 's';
+ else if(IS_A_COMMA(a,off))
+ c = 'c';
+ else if(IS_A_FLOAT(a,off))
+ c = 'f';
+ else if(IS_A_SYMBOL(a,off))
+ c = 'y';
+ return(c);
+} */
+
+static void iem_pbank_csv_read(t_iem_pbank_csv *x, t_symbol *filename, t_symbol *format)
+{
+ char completefilename[400], eol[4], sep, mode[4], *txbuf1, *txbuf2, *txvec_src, *txvec_dst;
+ int size, p, l, i, j, nrl=x->x_nr_line, nrp=x->x_nr_para, atlen=0;
+ int txlen, txalloc, hat_alloc, max, eollen;
+ FILE *fh;
+ t_atom *ap, *hap, *at;
+ char formattext[100];
+
+ strcpy(mode, "bsl"); /*blank-separator, semicolon-return-eol, linux_return*/
+ sep = ' ';
+ eol[0] = ';';
+ eol[1] = 0x0a;
+ eol[2] = 0;
+ if(filename->s_name[0] == '/')/*make complete path + filename*/
+ {
+ strcpy(completefilename, filename->s_name);
+ }
+ else if(((filename->s_name[0] >= 'A')&&(filename->s_name[0] <= 'Z')||
+ (filename->s_name[0] >= 'a')&&(filename->s_name[0] <= 'z'))&&
+ (filename->s_name[1] == ':')&&(filename->s_name[2] == '/'))
+ {
+ strcpy(completefilename, filename->s_name);
+ }
+ else
+ {
+ strcpy(completefilename, canvas_getdir(x->x_canvas)->s_name);
+ strcat(completefilename, "/");
+ strcat(completefilename, filename->s_name);
+ }
+
+ fh = fopen(completefilename,"rb");
+ if(!fh)
+ {
+ post("iem_pbank_csv_read: cannot open %s !!\n", completefilename);
+ }
+ else
+ {
+ if(strlen(format->s_name) >= 3)
+ {
+ for(p=0; p<3; p++)
+ {
+ if((format->s_name[p] >= 'A')&&(format->s_name[p] <= 'Z'))
+ format->s_name[p] += 'a' - 'A';
+ }
+ if((format->s_name[0] == 'b')||(format->s_name[0] == 'c')||(format->s_name[0] == 's')||(format->s_name[0] == 't'))
+ mode[0] = format->s_name[0];
+ if((format->s_name[1] == 'b')||(format->s_name[1] == 'r')||(format->s_name[1] == 's'))
+ mode[1] = format->s_name[1];
+ if((format->s_name[2] == 'l')||(format->s_name[2] == 'w')||(format->s_name[2] == 'm'))
+ mode[2] = format->s_name[2];
+ }
+ else
+ post("iem_pbank_csv_read: use default format %s !!\n", mode);
+ if(mode[0] == 'b')
+ {
+ sep = ' ';
+ strcpy(formattext, "item-separator = BLANK; ");
+ }
+ else if(mode[0] == 'c')
+ {
+ sep = ',';
+ strcpy(formattext, "item-separator = COMMA; ");
+ }
+ else if(mode[0] == 's')
+ {
+ sep = ';';
+ strcpy(formattext, "item-separator = SEMICOLON; ");
+ }
+ else if(mode[0] == 't')
+ {
+ sep = 0x09;
+ strcpy(formattext, "item-separator = TABULATOR; ");
+ }
+
+ eollen = 1;
+ if(mode[1] == 'b')
+ {
+ eol[0] = ' ';
+ strcat(formattext, "end_of_line_terminator = BLANK-RETURN in ");
+ }
+ else if(mode[1] == 'r')
+ {
+ eollen = 0;
+ strcat(formattext, "end_of_line_terminator = RETURN in ");
+ }
+ else if(mode[1] == 's')
+ {
+ eol[0] = ';';
+ strcat(formattext, "end_of_line_terminator = SEMICOLON-RETURN in ");
+ }
+
+ if(mode[2] == 'l')
+ {
+ eol[eollen++] = 0x0a;
+ strcat(formattext, "LINUX-Format.");
+ }
+ else if(mode[2] == 'w')
+ {
+ eol[eollen++] = 0x0d;
+ eol[eollen++] = 0x0a;
+ strcat(formattext, "WINDOWS-Format.");
+ }
+ else if(mode[2] == 'm')
+ {
+ eol[eollen++] = 0x0d;
+ strcat(formattext, "MACINTOSH-Format.");
+ }
+ eol[eollen] = 0;
+
+ fseek(fh, 0, SEEK_END);
+ txalloc = ftell(fh);
+ fseek(fh,0,SEEK_SET);
+ txbuf1 = (char *)getbytes(2 * txalloc * sizeof(char));
+ txbuf2 = (char *)getbytes(2 * txalloc * sizeof(char));
+ fread(txbuf1, sizeof(char), txalloc, fh);
+ fclose(fh);
+
+ txvec_src = txbuf1;
+ txvec_dst = txbuf2;
+ p = 0;
+ for(l=0; l<txalloc; l++)
+ {
+ if(!strncmp(txvec_src, eol, eollen)) /* replace eol by 0x0a */
+ {
+ txvec_src += eollen;
+ l += eollen - 1;
+ *txvec_dst++ = 0x0a;
+ p++;
+ }
+ else if(*txvec_src == sep) /* replace sep by ; */
+ {
+ txvec_src++;
+ *txvec_dst++ = ';';
+ p++;
+ }
+ else if((*txvec_src == '\r')||(*txvec_src == '\n')||(*txvec_src == '\t')) /* remove '\n'-returns */
+ txvec_src++;
+ else /* copy the same char */
+ {
+ *txvec_dst++ = *txvec_src++;
+ p++;
+ }
+ }
+ txlen = p;
+
+ txvec_src = txbuf2;
+ txvec_dst = txbuf1;
+ p = 0;
+ for(l=0; l<txlen; l++)
+ {
+ if((*txvec_src == ';')&&(txvec_src[1] == ';')) /* fill between 2 sep a zero */
+ {
+ *txvec_dst++ = *txvec_src++;
+ *txvec_dst++ = '0';
+ p += 2;
+ }
+ else if((*txvec_src == ';')&&(txvec_src[1] == 0x0a)) /* fill between sep and eol a zero */
+ {
+ *txvec_dst++ = *txvec_src++;
+ *txvec_dst++ = '0';
+ p += 2;
+ }
+ else if((*txvec_src == 0x0a)&&(txvec_src[1] == ';')) /* fill between eol and sep a zero */
+ {
+ *txvec_dst++ = *txvec_src++;
+ *txvec_dst++ = '0';
+ p += 2;
+ }
+ else if(*txvec_src == ',') /* replace a comma by a dot */
+ {
+ *txvec_dst++ = '.';
+ txvec_src++;
+ p++;
+ }
+ else /* copy the same char */
+ {
+ *txvec_dst++ = *txvec_src++;
+ p++;
+ }
+ }
+ txlen = p;
+
+ /* strncpy(txbuf2, txbuf1, txlen);
+ txbuf2[txlen] = 0;
+ post("\n\n%s\n\n", txbuf2); */
+
+ hat_alloc = 200;
+ hap = t_getbytes(hat_alloc * sizeof(t_atom));
+
+ atlen = iem_pbank_csv_text2atom(txbuf1, txlen, &hap, &hat_alloc, ';', 0x0a);
+
+ /* ap = hap;
+ i = atlen;
+ while(i >= 20)
+ {
+ post("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",myq(ap,0),myq(ap,1),myq(ap,2),myq(ap,3),myq(ap,4),myq(ap,5),myq(ap,6),myq(ap,7),myq(ap,8),myq(ap,9),myq(ap,10),myq(ap,11),myq(ap,12),myq(ap,13),myq(ap,14),myq(ap,15),myq(ap,16),myq(ap,17),myq(ap,18),myq(ap,19));
+ ap += 20;
+ i -= 20;
+ } */
+
+ at = x->x_atbegmem;
+ for(l=0; l<nrl; l++)/*reset all*/
+ {
+ for(p=0; p<nrp; p++)
+ {
+ SETFLOAT(at, 0.0f);
+ at++;
+ }
+ }
+
+ at = x->x_atbegmem;
+ ap = hap;
+ nrp++;
+ i = 0; /* atom-counter */
+ j = 0;
+ for(l=0; l<nrl; l++)/* nrl line times */
+ {
+ for(p=1; p<=nrp;)
+ {
+ if((p == nrp) && !(IS_A_SEMI(ap,0)))
+ {
+ /*post("too long");*/
+ while(!(IS_A_SEMI(ap,0)))
+ {
+ ap++;
+ atlen--;
+ /*post("ignore");*/
+ j++;
+ if(atlen <= 0)
+ {
+ goto iem_pbank_csv_end;
+ }
+ }
+ }
+ else
+ {
+ if(IS_A_FLOAT(ap,0))
+ {
+ SETFLOAT(at, ap->a_w.w_float);
+ /*post("float");*/
+ p++;
+ i++;
+ at++;
+ }
+ else if(IS_A_SYMBOL(ap,0))
+ {
+ SETSYMBOL(at, ap->a_w.w_symbol);
+ /*post("sym");*/
+ p++;
+ i++;
+ at++;
+ }
+ else if(IS_A_SEMI(ap,0))
+ {
+ /*post("semi");*/
+ for(; p<nrp;)
+ {
+ SETFLOAT(at,0.0);
+ /*post("zero");*/
+ p++;
+ i++;
+ at++;
+ }
+ p=nrp + 1;
+ }
+ ap++;
+ atlen--;
+ j++;
+ }
+ if(atlen <= 0)
+ {
+ goto iem_pbank_csv_end;
+ }
+ }
+ }
+
+iem_pbank_csv_end:
+
+
+ freebytes(hap, hat_alloc * sizeof(t_atom));
+ freebytes(txbuf1, 2 * txalloc * sizeof(char));
+ freebytes(txbuf2, 2 * txalloc * sizeof(char));
+ post("iem_pbank_csv: read %d parameters x %d lines from file:\n%s\nwith following format:\n%s\n", nrp-1, nrl, completefilename, formattext);
+ }
+}
+
+static void iem_pbank_csv_recall(t_iem_pbank_csv *x, t_symbol *s, int ac, t_atom *av)
+{
+ int i, n, beg=0, nrp=x->x_nr_para;
+ t_atom *atbuf=x->x_atbegbuf, *atmem=x->x_atbegmem;
+ t_atom *atout=x->x_atbegout;
+
+ if(ac >= 2)
+ nrp = atom_getintarg(1, ac, av);
+ if(ac >= 1)
+ beg = atom_getintarg(0, ac, av);
+ if(beg < 0)
+ beg = 0;
+ else if(beg >= x->x_nr_para)
+ beg = x->x_nr_para - 1;
+ if(nrp < 0)
+ nrp = 0;
+ else if((beg+nrp) > x->x_nr_para)
+ nrp = x->x_nr_para - beg;
+ atmem += x->x_nr_para * x->x_line + beg;
+ atbuf += beg;
+ SETFLOAT(atout, (float)beg);
+ atout++;
+ for(i=0; i<nrp; i++)
+ {
+ *atbuf++ = *atmem;
+ *atout++ = *atmem++;
+ }
+ outlet_list(x->x_offset_list_out, &s_list, nrp+1, x->x_atbegout);
+ outlet_list(x->x_list_out, &s_list, nrp, x->x_atbegout+1);
+}
+
+static void iem_pbank_csv_bang(t_iem_pbank_csv *x)
+{
+ int i, nrp=x->x_nr_para;
+ t_atom *atbuf=x->x_atbegbuf;
+ t_atom *atout=x->x_atbegout;
+
+ SETFLOAT(atout, 0.0f);
+ atout++;
+ for(i=0; i<nrp; i++)
+ *atout++ = *atbuf++;
+ outlet_list(x->x_offset_list_out, &s_list, nrp+1, x->x_atbegout);
+ outlet_list(x->x_list_out, &s_list, nrp, x->x_atbegout+1);
+}
+
+static void iem_pbank_csv_store(t_iem_pbank_csv *x, t_symbol *s, int ac, t_atom *av)
+{
+ int i, beg=0, nrp=x->x_nr_para;
+ t_atom *atbuf=x->x_atbegbuf, *atmem=x->x_atbegmem;
+
+ if(ac >= 2)
+ nrp = atom_getintarg(1, ac, av);
+ if(ac >= 1)
+ beg = atom_getintarg(0, ac, av);
+ if(beg < 0)
+ beg = 0;
+ else if(beg >= x->x_nr_para)
+ beg = x->x_nr_para - 1;
+ if(nrp < 0)
+ nrp = 0;
+ else if((beg+nrp) > x->x_nr_para)
+ nrp = x->x_nr_para - beg;
+ atmem += x->x_nr_para * x->x_line;
+ atmem += beg;
+ atbuf += beg;
+ for(i=0; i<nrp; i++)
+ *atmem++ = *atbuf++;
+}
+
+static void iem_pbank_csv_list(t_iem_pbank_csv *x, t_symbol *s, int ac, t_atom *av)
+{
+ if(ac >= 2)
+ {
+ int para_index = atom_getintarg(0, ac, av);
+
+ if(para_index >= 0)
+ {
+ if((para_index+ac-1) <= x->x_nr_para)
+ {
+ int i;
+
+ for(i=1; i<ac; i++)
+ {
+ x->x_atbegbuf[para_index] = av[i];
+ para_index++;
+ }
+ }
+ }
+ }
+}
+
+static void iem_pbank_csv_ft1(t_iem_pbank_csv *x, t_float fline_nr)
+{
+ int line = (int)fline_nr;
+
+ if(line < 0)
+ line = 0;
+ else if(line >= x->x_nr_line)
+ line = x->x_nr_line - 1;
+ x->x_line = line;
+}
+
+static void iem_pbank_csv_free(t_iem_pbank_csv *x)
+{
+ freebytes(x->x_atbegmem, x->x_nr_para * x->x_nr_line * sizeof(t_atom));
+ freebytes(x->x_atbegbuf, x->x_nr_para * sizeof(t_atom));
+ freebytes(x->x_atbegout, (x->x_nr_para+1) * sizeof(t_atom));
+}
+
+static void *iem_pbank_csv_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_iem_pbank_csv *x = (t_iem_pbank_csv *)pd_new(iem_pbank_csv_class);
+ int nrpp=0, nrp=10, nrl=10, p, l, i;
+ t_atom *ap;
+
+ if((ac >= 1) && IS_A_FLOAT(av,0))
+ nrp = atom_getintarg(0, ac, av);
+ if((ac >= 2) && IS_A_FLOAT(av,1))
+ nrl = atom_getintarg(1, ac, av);
+ if(nrp <= 0)
+ nrp = 10;
+ if(nrl <= 0)
+ nrl = 10;
+ x->x_line = 0;
+ x->x_nr_para = nrp;
+ x->x_nr_line = nrl;
+ x->x_atbegmem = (t_atom *)getbytes(x->x_nr_para * x->x_nr_line * sizeof(t_atom));
+ x->x_atbegbuf = (t_atom *)getbytes(x->x_nr_para * sizeof(t_atom));
+ x->x_atbegout = (t_atom *)getbytes((x->x_nr_para+1) * sizeof(t_atom));
+ ap = x->x_atbegmem;
+ for(l=0; l<nrl; l++)
+ {
+ for(p=0; p<nrp; p++)
+ {
+ SETFLOAT(ap, 0.0f);
+ ap++;
+ }
+ }
+ ap = x->x_atbegbuf;
+ for(p=0; p<nrp; p++)
+ {
+ SETFLOAT(ap, 0.0f);
+ ap++;
+ }
+ x->x_list_out = outlet_new(&x->x_obj, &s_list); /*left out*/
+ x->x_offset_list_out = outlet_new(&x->x_obj, &s_list); /*right out*/
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ x->x_canvas = canvas_getcurrent();
+ return (x);
+}
+
+/* ---------------- global setup function -------------------- */
+
+void iem_pbank_csv_setup(void )
+{
+ iem_pbank_csv_class = class_new(gensym("iem_pbank_csv"), (t_newmethod)iem_pbank_csv_new,
+ (t_method)iem_pbank_csv_free, sizeof(t_iem_pbank_csv), 0, A_GIMME, 0);
+ class_addmethod(iem_pbank_csv_class, (t_method)iem_pbank_csv_recall, gensym("recall"), A_GIMME, 0);
+ class_addmethod(iem_pbank_csv_class, (t_method)iem_pbank_csv_store, gensym("store"), A_GIMME, 0);
+ class_addmethod(iem_pbank_csv_class, (t_method)iem_pbank_csv_read, gensym("read"), A_SYMBOL, A_DEFSYM, 0);
+ class_addmethod(iem_pbank_csv_class, (t_method)iem_pbank_csv_write, gensym("write"), A_SYMBOL, A_DEFSYM, 0);
+ class_addlist(iem_pbank_csv_class, iem_pbank_csv_list);
+ class_addbang(iem_pbank_csv_class, iem_pbank_csv_bang);
+ class_addmethod(iem_pbank_csv_class, (t_method)iem_pbank_csv_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_sethelpsymbol(iem_pbank_csv_class, gensym("iemhelp/help-iem_pbank_csv"));
+}
+
diff --git a/src/iemlib2/iem_prepend_kernel.c b/src/iemlib2/iem_prepend_kernel.c
new file mode 100644
index 0000000..5147107
--- /dev/null
+++ b/src/iemlib2/iem_prepend_kernel.c
@@ -0,0 +1,259 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "g_canvas.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+EXTERN void canvas_getargs(int *argcp, t_atom **argvp);
+
+
+/* ------------------------ iem_prepend_kernel ---------------------------- */
+static t_class *iem_prepend_kernel_class;
+
+typedef struct _iem_prepend_kernel
+{
+ t_object x_obj;
+ int x_inlet_select;
+ int x_size;
+ int x_ac;
+ t_atom *x_at;
+ t_symbol *x_sym;
+ t_atomtype x_type;
+} t_iem_prepend_kernel;
+
+static void iem_prepend_kernel_atcopy(t_atom *src, t_atom *dst, int n)
+{
+ while(n--)
+ *dst++ = *src++;
+}
+
+static void iem_prepend_kernel_inlet_select(t_iem_prepend_kernel *x, t_floatarg fin_sel_01)
+{
+ x->x_inlet_select = (int)fin_sel_01;
+}
+
+static void iem_prepend_kernel_bang(t_iem_prepend_kernel *x)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ x->x_ac = 0;
+ x->x_type = A_NULL;
+ x->x_sym = &s_bang;
+ }
+ else /* if 1st inlet */
+ {
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, x->x_ac, x->x_at);
+ }
+}
+
+static void iem_prepend_kernel_float(t_iem_prepend_kernel *x, t_float f)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ x->x_ac = 1;
+ x->x_type = A_FLOAT;
+ SETFLOAT(x->x_at, f);
+ x->x_sym = &s_list;
+ }
+ else /* if 1st inlet */
+ {
+ if(x->x_type == A_NULL)
+ {
+ outlet_float(x->x_obj.ob_outlet, f);
+ }
+ else
+ {
+ SETFLOAT(x->x_at+x->x_ac, f);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, x->x_ac+1, x->x_at);
+ }
+ }
+}
+
+static void iem_prepend_kernel_symbol(t_iem_prepend_kernel *x, t_symbol *s)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ x->x_ac = 1;
+ x->x_type = A_SYMBOL;
+ SETSYMBOL(x->x_at, s);
+ x->x_sym = &s_list;
+ }
+ else /* if 1st inlet */
+ {
+ if(x->x_type == A_NULL)
+ {
+ outlet_symbol(x->x_obj.ob_outlet, s);
+ }
+ else
+ {
+ SETSYMBOL(x->x_at+x->x_ac, s);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, x->x_ac+1, x->x_at);
+ }
+ }
+}
+
+static void iem_prepend_kernel_pointer(t_iem_prepend_kernel *x, t_gpointer *gp)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ x->x_ac = 1;
+ x->x_type = A_POINTER;
+ SETPOINTER(x->x_at, gp);
+ x->x_sym = &s_list;
+ }
+ else /* if 1st inlet */
+ {
+ if(x->x_type == A_NULL)
+ {
+ outlet_pointer(x->x_obj.ob_outlet, gp);
+ }
+ else
+ {
+ SETPOINTER(x->x_at+x->x_ac, gp);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, x->x_ac+1, x->x_at);
+ }
+ }
+}
+
+static void iem_prepend_kernel_list(t_iem_prepend_kernel *x, t_symbol *s, int ac, t_atom *av)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ if((ac+10) > x->x_size)
+ {
+ x->x_at = (t_atom *)resizebytes(x->x_at, x->x_size*sizeof(t_atom), 2*(ac+10)*sizeof(t_atom));
+ x->x_size = 2*(ac+10);
+ }
+ x->x_ac = ac;
+ x->x_type = A_GIMME;
+ x->x_sym = &s_list;
+ iem_prepend_kernel_atcopy(av, x->x_at, ac);
+ }
+ else /* if 1st inlet */
+ {
+ if((ac+x->x_ac+1) > x->x_size)
+ {
+ x->x_at = (t_atom *)resizebytes(x->x_at, x->x_size*sizeof(t_atom), 2*(ac+x->x_ac+1)*sizeof(t_atom));
+ x->x_size = 2*(ac+x->x_ac+1);
+ }
+ if(x->x_type == A_NULL)
+ {
+ outlet_anything(x->x_obj.ob_outlet, &s_list, ac, av);
+ }
+ else
+ {
+ iem_prepend_kernel_atcopy(av, x->x_at + x->x_ac, ac);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, x->x_ac+ac, x->x_at);
+ }
+ }
+}
+
+static void iem_prepend_kernel_anything(t_iem_prepend_kernel *x, t_symbol *s, int ac, t_atom *av)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ if((ac+10) > x->x_size)
+ {
+ x->x_at = (t_atom *)resizebytes(x->x_at, x->x_size*sizeof(t_atom), 2*(ac+10)*sizeof(t_atom));
+ x->x_size = 2*(ac+10);
+ }
+ x->x_ac = ac;
+ x->x_type = A_COMMA;
+ x->x_sym = s;
+ iem_prepend_kernel_atcopy(av, x->x_at, ac);
+ }
+ else /* if 1st inlet */
+ {
+ if((ac+x->x_ac+1) > x->x_size)
+ {
+ x->x_at = (t_atom *)resizebytes(x->x_at, x->x_size*sizeof(t_atom), 2*(ac+x->x_ac+1)*sizeof(t_atom));
+ x->x_size = 2*(ac+x->x_ac+1);
+ }
+ if(x->x_type == A_NULL)
+ {
+ outlet_anything(x->x_obj.ob_outlet, s, ac, av);
+ }
+ else
+ {
+ SETSYMBOL(x->x_at + x->x_ac, s);
+ iem_prepend_kernel_atcopy(av, x->x_at+x->x_ac+1, ac);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, x->x_ac+ac+1, x->x_at);
+ }
+ }
+}
+
+static void iem_prepend_kernel_free(t_iem_prepend_kernel *x)
+{
+ if(x->x_at)
+ freebytes(x->x_at, x->x_size * sizeof(t_atom));
+}
+
+static void *iem_prepend_kernel_new(void)
+{
+ t_iem_prepend_kernel *x = (t_iem_prepend_kernel *)pd_new(iem_prepend_kernel_class);
+ t_glist *glist = (t_glist *)canvas_getcurrent();
+ t_canvas *canvas=glist_getcanvas(glist);
+ int ac=0;
+ t_atom *av;
+
+ canvas_setcurrent(canvas);
+ canvas_getargs(&ac, &av);
+ canvas_unsetcurrent(canvas);
+
+ x->x_size = 30;
+ if(ac > 5)
+ x->x_size = 2*(ac+10);
+ x->x_at = (t_atom *)getbytes(x->x_size * sizeof(t_atom));
+ x->x_inlet_select = 1;
+ if(ac <= 0)
+ {
+ x->x_type = A_NULL;
+ x->x_ac = 0;
+ x->x_sym = &s_bang;
+ }
+ else
+ {
+ if(IS_A_FLOAT(av, 0))
+ {
+ iem_prepend_kernel_list(x, &s_list, ac, av);
+ }
+ else if(IS_A_SYMBOL(av, 0))
+ {
+ iem_prepend_kernel_anything(x, atom_getsymbol(av), ac-1, av+1);
+ }
+ }
+ outlet_new(&x->x_obj, &s_list);
+ return(x);
+}
+
+void iem_prepend_kernel_setup(void)
+{
+ char str[2];
+
+ str[0] = 1;
+ str[1] = 0;
+ iem_prepend_kernel_class = class_new(gensym("iem_prepend_kernel"),
+ (t_newmethod)iem_prepend_kernel_new, (t_method)iem_prepend_kernel_free,
+ sizeof(t_iem_prepend_kernel), 0, 0);
+ class_addbang(iem_prepend_kernel_class, (t_method)iem_prepend_kernel_bang);
+ class_addpointer(iem_prepend_kernel_class, iem_prepend_kernel_pointer);
+ class_addfloat(iem_prepend_kernel_class, (t_method)iem_prepend_kernel_float);
+ class_addsymbol(iem_prepend_kernel_class, iem_prepend_kernel_symbol);
+ class_addlist(iem_prepend_kernel_class, iem_prepend_kernel_list);
+ class_addmethod(iem_prepend_kernel_class, (t_method)iem_prepend_kernel_inlet_select, gensym(str), A_FLOAT, 0);
+ class_addanything(iem_prepend_kernel_class, iem_prepend_kernel_anything);
+ class_sethelpsymbol(iem_prepend_kernel_class, gensym("iemhelp/help-merge_any"));
+}
diff --git a/src/iemlib2/iem_receive_kernel.c b/src/iemlib2/iem_receive_kernel.c
new file mode 100644
index 0000000..4ff3c76
--- /dev/null
+++ b/src/iemlib2/iem_receive_kernel.c
@@ -0,0 +1,155 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "g_canvas.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+EXTERN void canvas_getargs(int *argcp, t_atom **argvp);
+
+/* ------------------------ iem_receive_kernel ---------------------------- */
+
+static t_class *iem_receive_kernel_class;
+
+typedef struct _iem_receive_kernel
+{
+ t_object x_obj;
+ t_symbol *x_sym;
+} t_iem_receive_kernel;
+
+void iem_receive_kernel_copy_at(t_atom *src, t_atom *dst, int n)
+{
+ while(n--)
+ *dst++ = *src++;
+}
+
+static void iem_receive_kernel_set_name(t_iem_receive_kernel *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if((argc > 0)&&((IS_A_SYMBOL(argv,0))||(IS_A_FLOAT(argv,0))))
+ {
+ if(x->x_sym)
+ pd_unbind(&x->x_obj.ob_pd, x->x_sym);
+ if(IS_A_SYMBOL(argv,0))
+ x->x_sym = atom_getsymbol(argv);
+ else if(IS_A_FLOAT(argv,0))
+ {
+ char str[100];
+
+ sprintf(str, "%g", atom_getfloat(argv));
+ x->x_sym = gensym(str);
+ }
+ pd_bind(&x->x_obj.ob_pd, x->x_sym);
+ }
+}
+
+static void iem_receive_kernel_clear(t_iem_receive_kernel *x)
+{
+ if(x->x_sym)
+ pd_unbind(&x->x_obj.ob_pd, x->x_sym);
+ x->x_sym = 0;
+}
+
+static void iem_receive_kernel_bang(t_iem_receive_kernel *x)
+{
+ outlet_bang(x->x_obj.ob_outlet);
+}
+
+static void iem_receive_kernel_float(t_iem_receive_kernel *x, t_float f)
+{
+ outlet_float(x->x_obj.ob_outlet, f);
+}
+
+static void iem_receive_kernel_symbol(t_iem_receive_kernel *x, t_symbol *s)
+{
+ outlet_symbol(x->x_obj.ob_outlet, s);
+}
+
+static void iem_receive_kernel_pointer(t_iem_receive_kernel *x, t_gpointer *gp)
+{
+ outlet_pointer(x->x_obj.ob_outlet, gp);
+}
+
+static void iem_receive_kernel_list(t_iem_receive_kernel *x, t_symbol *s, int argc, t_atom *argv)
+{
+ outlet_list(x->x_obj.ob_outlet, &s_list, argc, argv);
+}
+
+static void iem_receive_kernel_anything(t_iem_receive_kernel *x, t_symbol *s, int argc, t_atom *argv)
+{
+ outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
+}
+
+static void iem_receive_kernel_free(t_iem_receive_kernel *x)
+{
+ if(x->x_sym)
+ pd_unbind(&x->x_obj.ob_pd, x->x_sym);
+}
+
+static void *iem_receive_kernel_new(void)
+{
+ t_iem_receive_kernel *x = (t_iem_receive_kernel *)pd_new(iem_receive_kernel_class);
+ t_glist *glist = (t_glist *)canvas_getcurrent();
+ t_canvas *canvas=glist_getcanvas(glist);
+ int ac=0;
+ t_atom *av;
+
+ canvas_setcurrent(canvas);
+ canvas_getargs(&ac, &av);
+ canvas_unsetcurrent(canvas);
+
+ if(ac > 0)
+ {
+ if(IS_A_SYMBOL(av,0))
+ {
+ x->x_sym = atom_getsymbol(av);
+ pd_bind(&x->x_obj.ob_pd, x->x_sym);
+ }
+ else if(IS_A_FLOAT(av,0))
+ {
+ char str[100];
+
+ sprintf(str, "%g", atom_getfloat(av));
+ x->x_sym = gensym(str);
+ pd_bind(&x->x_obj.ob_pd, x->x_sym);
+ }
+ else
+ x->x_sym = 0;
+ }
+ else
+ x->x_sym = 0;
+
+ outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+void iem_receive_kernel_setup(void)
+{
+ char str[2];
+
+ str[1] = 0;
+ iem_receive_kernel_class = class_new(gensym("iem_receive_kernel"), (t_newmethod)iem_receive_kernel_new,
+ (t_method)iem_receive_kernel_free, sizeof(t_iem_receive_kernel), 0, 0);
+ class_addbang(iem_receive_kernel_class, iem_receive_kernel_bang);
+ class_addfloat(iem_receive_kernel_class, iem_receive_kernel_float);
+ class_addsymbol(iem_receive_kernel_class, iem_receive_kernel_symbol);
+ class_addpointer(iem_receive_kernel_class, iem_receive_kernel_pointer);
+ class_addlist(iem_receive_kernel_class, iem_receive_kernel_list);
+ class_addanything(iem_receive_kernel_class, iem_receive_kernel_anything);
+// class_addmethod(iem_receive_kernel_class, (t_method)iem_receive_kernel_set, gensym("set"), A_GIMME, 0);
+ str[0] = 1;/*inlet-sym = "\0x01"*/
+ class_addmethod(iem_receive_kernel_class, (t_method)iem_receive_kernel_set_name, gensym(str), A_GIMME, 0);
+ str[0] = 2;/*inlet-sym = "\0x02"*/
+ class_addmethod(iem_receive_kernel_class, (t_method)iem_receive_kernel_clear, gensym(str), 0);
+ class_sethelpsymbol(iem_receive_kernel_class, gensym("iemhelp/help-iem_receive"));
+}
diff --git a/src/iemlib2/iem_route.c b/src/iemlib2/iem_route.c
new file mode 100644
index 0000000..85071ae
--- /dev/null
+++ b/src/iemlib2/iem_route.c
@@ -0,0 +1,198 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* -------------------------- iem_route ------------------------------ */
+
+static t_class *iem_route_class;
+
+typedef struct _iem_routeelement
+{
+ t_word e_w;
+ t_outlet *e_outlet;
+} t_iem_routeelement;
+
+typedef struct _iem_route
+{
+ t_object x_obj;
+ t_atomtype x_type;
+ t_int x_nelement;
+ t_iem_routeelement *x_vec;
+ t_outlet *x_rejectout;
+} t_iem_route;
+
+static void iem_route_anything(t_iem_route *x, t_symbol *sel, int argc, t_atom *argv)
+{
+ t_iem_routeelement *e;
+ int nelement;
+
+ if(x->x_type == A_SYMBOL)
+ {
+ for(nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
+ {
+ if(e->e_w.w_symbol == sel)
+ {
+ if(!argc)
+ outlet_bang(e->e_outlet);
+ else
+ {
+ if(argc == 1)
+ {
+ if(argv[0].a_type == A_FLOAT)
+ outlet_float(e->e_outlet, argv[0].a_w.w_float);
+ else
+ outlet_anything(e->e_outlet, argv[0].a_w.w_symbol, 0, argv+1);
+ }
+ else
+ {
+ if(argv[0].a_type == A_SYMBOL)
+ outlet_anything(e->e_outlet, argv[0].a_w.w_symbol, argc-1, argv+1);
+ else
+ outlet_list(e->e_outlet, &s_list, argc, argv);
+ }
+ }
+ return;
+ }
+ }
+ }
+ outlet_anything(x->x_rejectout, sel, argc, argv);
+}
+
+static void iem_route_list(t_iem_route *x, t_symbol *sel, int argc, t_atom *argv)
+{
+ t_iem_routeelement *e;
+ int nelement;
+
+ if (x->x_type == A_FLOAT)
+ {
+ float f;
+
+ if(!argc)
+ return;
+ f = atom_getfloat(argv);
+ for(nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
+ {
+ if(e->e_w.w_float == f)
+ {
+ if(argc > 1 && argv[1].a_type == A_SYMBOL)
+ outlet_anything(e->e_outlet, argv[1].a_w.w_symbol, argc-2, argv+2);
+ else
+ {
+ if(argc == 1)
+ outlet_bang(e->e_outlet);
+ else if(argc == 2)
+ outlet_float(e->e_outlet, atom_getfloat(argv+1));
+ else
+ outlet_list(e->e_outlet, &s_list, argc-1, argv+1);
+ }
+ return;
+ }
+ }
+ }
+ else /* symbol arguments */
+ {
+ if(argc > 1) /* 2 or more args: treat as "list" */
+ {
+ for(nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
+ {
+ if(e->e_w.w_symbol == &s_list)
+ {
+ if(argv[0].a_type == A_SYMBOL)
+ outlet_anything(e->e_outlet, argv[0].a_w.w_symbol, argc-1, argv+1);
+ else
+ outlet_list(e->e_outlet, &s_list, argc, argv);
+ return;
+ }
+ }
+ }
+ else if(argc == 0) /* no args: treat as "bang" */
+ {
+ for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
+ {
+ if (e->e_w.w_symbol == &s_bang)
+ {
+ outlet_bang(e->e_outlet);
+ return;
+ }
+ }
+ }
+ else if (argv[0].a_type == A_FLOAT) /* one float arg */
+ {
+ for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
+ {
+ if (e->e_w.w_symbol == &s_float)
+ {
+ outlet_float(e->e_outlet, argv[0].a_w.w_float);
+ return;
+ }
+ }
+ }
+ else
+ {
+ for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
+ {
+ if (e->e_w.w_symbol == &s_symbol)
+ {
+ outlet_symbol(e->e_outlet, argv[0].a_w.w_symbol);
+ return;
+ }
+ }
+ }
+ }
+ outlet_list(x->x_rejectout, &s_list, argc, argv);
+}
+
+
+static void iem_route_free(t_iem_route *x)
+{
+ freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
+}
+
+static void *iem_route_new(t_symbol *s, int argc, t_atom *argv)
+{
+ int n;
+ t_iem_routeelement *e;
+ t_iem_route *x = (t_iem_route *)pd_new(iem_route_class);
+ t_atom a;
+ if (argc == 0)
+ {
+ argc = 1;
+ SETFLOAT(&a, 0);
+ argv = &a;
+ }
+ x->x_type = argv[0].a_type;
+ x->x_nelement = argc;
+ x->x_vec = (t_iem_routeelement *)getbytes(argc * sizeof(*x->x_vec));
+ for (n = 0, e = x->x_vec; n < argc; n++, e++)
+ {
+ e->e_outlet = outlet_new(&x->x_obj, &s_list);
+ if (x->x_type == A_FLOAT)
+ e->e_w.w_float = atom_getfloatarg(n, argc, argv);
+ else e->e_w.w_symbol = atom_getsymbolarg(n, argc, argv);
+ }
+ x->x_rejectout = outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+void iem_route_setup(void)
+{
+ iem_route_class = class_new(gensym("iem_route"), (t_newmethod)iem_route_new,
+ (t_method)iem_route_free, sizeof(t_iem_route), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)iem_route_new, gensym("ir"), A_GIMME, 0);
+ class_addlist(iem_route_class, iem_route_list);
+ class_addanything(iem_route_class, iem_route_anything);
+ class_sethelpsymbol(iem_route_class, gensym("iemhelp/help-iem_route"));
+}
diff --git a/src/iemlib2/iem_sel_any.c b/src/iemlib2/iem_sel_any.c
new file mode 100644
index 0000000..e6ff7e0
--- /dev/null
+++ b/src/iemlib2/iem_sel_any.c
@@ -0,0 +1,111 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ iem_sel_any ---------------------------- */
+static t_class *iem_sel_any_class;
+
+typedef struct _iem_sel_any
+{
+ t_object x_obj;
+ int x_ac;
+ int x_max_ac;
+ t_symbol **x_any;
+ t_symbol *x_set;
+ void *x_out_any;
+ void *x_out_set_any;
+} t_iem_sel_any;
+
+
+static void iem_sel_any_float(t_iem_sel_any *x, t_float f)
+{
+ int i = (int)f;
+ t_atom at;
+
+ if(x->x_ac > 0)
+ {
+ if(i < 0)
+ i = 0;
+ if(i >= x->x_ac)
+ i = x->x_ac - 1;
+ SETSYMBOL(&at, x->x_any[i]);
+ outlet_anything(x->x_out_any, x->x_any[i], 0, 0);
+ outlet_anything(x->x_out_set_any, x->x_set, 1, &at);
+ }
+}
+
+static void iem_sel_any_add(t_iem_sel_any *x, t_symbol *s, int ac, t_atom *av)
+{
+ if((ac >= 2) && (IS_A_FLOAT(av, 0)))
+ {
+ int i = (int)atom_getintarg(0, ac, av);
+
+ if((i >= 0) && (i < x->x_max_ac))
+ {
+ if(IS_A_SYMBOL(av, 1))
+ x->x_any[i] = atom_getsymbolarg(1, ac, av);
+ else if(IS_A_FLOAT(av, 1))
+ {
+ char str[100];
+
+ sprintf(str, "%g", atom_getfloatarg(1, ac, av));
+ x->x_any[i] = gensym(str);
+ }
+ if(i >= x->x_ac)
+ x->x_ac = i+1;
+ }
+ }
+}
+
+static void iem_sel_any_clear(t_iem_sel_any *x)
+{
+ x->x_ac = 0;
+}
+
+static void iem_sel_any_free(t_iem_sel_any *x)
+{
+ freebytes(x->x_any, x->x_max_ac * sizeof(t_symbol *));
+}
+
+static void *iem_sel_any_new(t_float fmax)
+{
+ t_iem_sel_any *x = (t_iem_sel_any *)pd_new(iem_sel_any_class);
+ int i;
+ t_symbol *default_sym=gensym("no_entry");
+
+ if(fmax <= 0.0)
+ fmax = 10.0;
+ x->x_max_ac = (int)fmax;
+ x->x_any = (t_symbol **)getbytes(x->x_max_ac * sizeof(t_symbol *));
+ x->x_ac = 0;
+ x->x_set = gensym("set");
+ for(i=0; i<x->x_max_ac; i++)
+ x->x_any[i] = default_sym;
+ x->x_out_set_any = outlet_new(&x->x_obj, &s_list);
+ x->x_out_any = outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+void iem_sel_any_setup(void)
+{
+ iem_sel_any_class = class_new(gensym("iem_sel_any"), (t_newmethod)iem_sel_any_new,
+ (t_method)iem_sel_any_free, sizeof(t_iem_sel_any), 0, A_DEFFLOAT, 0);
+ class_addmethod(iem_sel_any_class, (t_method)iem_sel_any_add, gensym("add"), A_GIMME, 0);
+ class_addmethod(iem_sel_any_class, (t_method)iem_sel_any_clear, gensym("clear"), 0);
+ class_addfloat(iem_sel_any_class, (t_method)iem_sel_any_float);
+ class_sethelpsymbol(iem_sel_any_class, gensym("iemhelp/help-iem_sel_any"));
+}
+
diff --git a/src/iemlib2/iem_send_kernel.c b/src/iemlib2/iem_send_kernel.c
new file mode 100644
index 0000000..62adec7
--- /dev/null
+++ b/src/iemlib2/iem_send_kernel.c
@@ -0,0 +1,140 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "g_canvas.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+EXTERN void canvas_getargs(int *argcp, t_atom **argvp);
+
+/* -------------------- iem_send_kernel ------------------------------ */
+
+static t_class *iem_send_kernel_class;
+
+typedef struct _iem_send_kernel
+{
+ t_object x_obj;
+ t_symbol *x_sym;
+} t_iem_send_kernel;
+
+static void iem_send_kernel_set_name(t_iem_send_kernel *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if((argc > 0)&&((IS_A_SYMBOL(argv,0))||(IS_A_FLOAT(argv,0))))
+ {
+ if(IS_A_SYMBOL(argv,0))
+ x->x_sym = atom_getsymbol(argv);
+ else if(IS_A_FLOAT(argv,0))
+ {
+ char str[100];
+
+ sprintf(str, "%g", atom_getfloat(argv));
+ x->x_sym = gensym(str);
+ }
+ }
+}
+
+static void iem_send_kernel_clear(t_iem_send_kernel *x)
+{
+ x->x_sym = 0;
+}
+
+static void iem_send_kernel_bang(t_iem_send_kernel *x)
+{
+ if(x->x_sym->s_thing)
+ pd_bang(x->x_sym->s_thing);
+}
+
+static void iem_send_kernel_float(t_iem_send_kernel *x, t_float f)
+{
+ if(x->x_sym->s_thing)
+ pd_float(x->x_sym->s_thing, f);
+}
+
+static void iem_send_kernel_symbol(t_iem_send_kernel *x, t_symbol *s)
+{
+ if(x->x_sym->s_thing)
+ pd_symbol(x->x_sym->s_thing, s);
+}
+
+static void iem_send_kernel_pointer(t_iem_send_kernel *x, t_gpointer *gp)
+{
+ if(x->x_sym->s_thing)
+ pd_pointer(x->x_sym->s_thing, gp);
+}
+
+static void iem_send_kernel_list(t_iem_send_kernel *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if(x->x_sym->s_thing)
+ pd_list(x->x_sym->s_thing, s, argc, argv);
+}
+
+static void iem_send_kernel_anything(t_iem_send_kernel *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if(x->x_sym->s_thing)
+ typedmess(x->x_sym->s_thing, s, argc, argv);
+}
+
+static void *iem_send_kernel_new(void)
+{
+ t_iem_send_kernel *x = (t_iem_send_kernel *)pd_new(iem_send_kernel_class);
+ t_glist *glist = (t_glist *)canvas_getcurrent();
+ t_canvas *canvas=glist_getcanvas(glist);
+ int ac=0;
+ t_atom *av;
+
+ canvas_setcurrent(canvas);
+ canvas_getargs(&ac, &av);
+ canvas_unsetcurrent(canvas);
+
+ if(ac > 0)
+ {
+ if(IS_A_SYMBOL(av,0))
+ {
+ x->x_sym = atom_getsymbol(av);
+ }
+ else if(IS_A_FLOAT(av,0))
+ {
+ char str[100];
+
+ sprintf(str, "%g", atom_getfloat(av));
+ x->x_sym = gensym(str);
+ }
+ else
+ x->x_sym = 0;
+ }
+ else
+ x->x_sym = 0;
+ return (x);
+}
+
+void iem_send_kernel_setup(void)
+{
+ char str[2];
+
+ str[1] = 0;
+ iem_send_kernel_class = class_new(gensym("iem_send_kernel"), (t_newmethod)iem_send_kernel_new, 0,
+ sizeof(t_iem_send_kernel), 0, 0);
+ class_addcreator((t_newmethod)iem_send_kernel_new, gensym("s"), A_DEFSYM, 0);
+ class_addbang(iem_send_kernel_class, iem_send_kernel_bang);
+ class_addfloat(iem_send_kernel_class, iem_send_kernel_float);
+ class_addsymbol(iem_send_kernel_class, iem_send_kernel_symbol);
+ class_addpointer(iem_send_kernel_class, iem_send_kernel_pointer);
+ class_addlist(iem_send_kernel_class, iem_send_kernel_list);
+ class_addanything(iem_send_kernel_class, iem_send_kernel_anything);
+ str[0] = 1;/*inlet-sym = "\0x01"*/
+ class_addmethod(iem_send_kernel_class, (t_method)iem_send_kernel_set_name, gensym(str), A_GIMME, 0);
+ str[0] = 2;/*inlet-sym = "\0x02"*/
+ class_addmethod(iem_send_kernel_class, (t_method)iem_send_kernel_clear, gensym(str), 0);
+ class_sethelpsymbol(iem_send_kernel_class, gensym("iemhelp/help-iem_send"));
+}
diff --git a/src/iemlib2/iemlib.h b/src/iemlib2/iemlib.h
new file mode 100644
index 0000000..d518565
--- /dev/null
+++ b/src/iemlib2/iemlib.h
@@ -0,0 +1,98 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#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 MACOSX
+#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 /* MACOSX */
+#endif /* __linux__ */
+#endif /* MSW */
+#endif /* SGI */
+
+union tabfudge
+{
+ double tf_d;
+ int32 tf_i[2];
+};
+
+#endif
diff --git a/src/iemlib2/iemlib2.c b/src/iemlib2/iemlib2.c
new file mode 100644
index 0000000..2875f26
--- /dev/null
+++ b/src/iemlib2/iemlib2.c
@@ -0,0 +1,121 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+/*
+#include <ctype.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifndef NT
+#include <sys/signal.h>
+#include <unistd.h>
+#endif
+
+#ifdef NT
+#include <io.h>
+#endif
+ */
+
+static t_class *iemlib2_class;
+
+static void *iemlib2_new(void)
+{
+ t_object *x = (t_object *)pd_new(iemlib2_class);
+
+ return (x);
+}
+
+void add2_comma_setup(void);
+void bpe_setup(void);
+void dollarg_setup(void);
+void exp_inc_setup(void);
+void float24_setup(void);
+void iem_anything_kernel_setup(void);
+void iem_append_kernel_setup(void);
+void iem_i_route_setup(void);
+void iem_prepend_kernel_setup(void);
+void iem_pbank_csv_setup(void);
+void iem_receive_kernel_setup(void);
+void iem_send_kernel_setup(void);
+void iem_route_setup(void);
+void iem_sel_any_setup(void);
+void init_setup(void);
+void list2send_setup(void);
+void mergefilename_setup(void);
+void modulo_counter_setup(void);
+void pre_inlet_setup(void);
+void prepend_ascii_setup(void);
+void post_netreceive_setup(void);
+void round_zero_setup(void);
+void sigfade_setup(void);
+void sigiem_blocksize_setup(void);
+void sigiem_samplerate_setup(void);
+void sigLFO_noise_setup(void);
+void sigm2f_setup(void);
+void speedlim_setup(void);
+void splitfilename_setup(void);
+void stripfilename_setup(void);
+void toggle_mess_setup(void);
+void transf_fader_setup(void);
+void unsymbol_setup(void);
+void wrap_setup(void);
+
+/* ------------------------ setup routine ------------------------- */
+
+void iemlib2_setup(void)
+{
+ iemlib2_class = class_new(gensym("iemlib2"), iemlib2_new, 0,
+ sizeof(t_object), CLASS_NOINLET, 0);
+
+ add2_comma_setup();
+ bpe_setup();
+ dollarg_setup();
+ exp_inc_setup();
+ float24_setup();
+ iem_anything_kernel_setup();
+ iem_append_kernel_setup();
+ iem_i_route_setup();
+ iem_pbank_csv_setup();
+ iem_prepend_kernel_setup();
+ iem_receive_kernel_setup();
+ iem_send_kernel_setup();
+ iem_route_setup();
+ iem_sel_any_setup();
+ init_setup();
+ list2send_setup();
+ mergefilename_setup();
+ modulo_counter_setup();
+ pre_inlet_setup();
+ prepend_ascii_setup();
+ post_netreceive_setup();
+ round_zero_setup();
+ sigfade_setup();
+ sigiem_blocksize_setup();
+ sigiem_samplerate_setup();
+ sigLFO_noise_setup();
+ sigm2f_setup();
+ speedlim_setup();
+ splitfilename_setup();
+ stripfilename_setup();
+ toggle_mess_setup();
+ transf_fader_setup();
+ unsymbol_setup();
+ wrap_setup();
+
+ post("iemlib2 (R-1.15) library loaded!");
+}
diff --git a/src/iemlib2/iemlib2.dsp b/src/iemlib2/iemlib2.dsp
new file mode 100644
index 0000000..d8c2966
--- /dev/null
+++ b/src/iemlib2/iemlib2.dsp
@@ -0,0 +1,85 @@
+# Microsoft Developer Studio Project File - Name="iemlib2" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) External Target" 0x0106
+
+CFG=iemlib2 - 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 "iemlib2.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 "iemlib2.mak" CFG="iemlib2 - Win32 Debug"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "iemlib2 - Win32 Release" (basierend auf "Win32 (x86) External Target")
+!MESSAGE "iemlib2 - Win32 Debug" (basierend auf "Win32 (x86) External Target")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF "$(CFG)" == "iemlib2 - 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 "iemlib2.exe"
+# PROP Bsc_Name "iemlib2.bsc"
+# PROP Target_Dir ""
+
+!ELSEIF "$(CFG)" == "iemlib2 - 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 "iemlib2.exe"
+# PROP Bsc_Name "iemlib2.bsc"
+# PROP Target_Dir ""
+
+!ENDIF
+
+# Begin Target
+
+# Name "iemlib2 - Win32 Release"
+# Name "iemlib2 - Win32 Debug"
+
+!IF "$(CFG)" == "iemlib2 - Win32 Release"
+
+!ELSEIF "$(CFG)" == "iemlib2 - Win32 Debug"
+
+!ENDIF
+
+# Begin Source File
+
+SOURCE=.\makefile_win
+# End Source File
+# End Target
+# End Project
diff --git a/src/iemlib2/iemlib2.dsw b/src/iemlib2/iemlib2.dsw
new file mode 100644
index 0000000..2226931
--- /dev/null
+++ b/src/iemlib2/iemlib2.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
+
+###############################################################################
+
+Project: "iemlib2"=.\iemlib2.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/src/iemlib2/init.c b/src/iemlib2/init.c
new file mode 100644
index 0000000..e7ab93b
--- /dev/null
+++ b/src/iemlib2/init.c
@@ -0,0 +1,203 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ init ---------------------------- */
+static t_class *init_class;
+
+typedef struct _init
+{
+ t_object x_obj;
+ int x_n;
+ int x_ac;
+ t_atom *x_at;
+ t_symbol *x_sym;
+ t_atomtype x_type;
+} t_init;
+
+static void init_bang(t_init *x)
+{
+ if(x->x_type == A_FLOAT)
+ outlet_float(x->x_obj.ob_outlet, atom_getfloat(x->x_at));
+ else if(x->x_type == A_SYMBOL)
+ outlet_symbol(x->x_obj.ob_outlet, atom_getsymbol(x->x_at));
+ else if(x->x_type == A_NULL)
+ outlet_bang(x->x_obj.ob_outlet);
+ else if(x->x_type == A_COMMA)
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, x->x_ac, x->x_at);
+ else if(x->x_type == A_GIMME)
+ outlet_list(x->x_obj.ob_outlet, &s_list, x->x_ac, x->x_at);
+ else if(x->x_type == A_POINTER)
+ outlet_pointer(x->x_obj.ob_outlet, (t_gpointer *)x->x_at->a_w.w_gpointer);
+}
+
+static void init_loadbang(t_init *x)
+{
+ if(!sys_noloadbang)
+ init_bang(x);
+}
+
+static void init_float(t_init *x, t_float f)
+{
+ x->x_ac = 1;
+ SETFLOAT(x->x_at, f);
+ x->x_sym = &s_float;
+ x->x_type = A_FLOAT;
+ outlet_float(x->x_obj.ob_outlet, f);
+}
+
+static void init_symbol(t_init *x, t_symbol *s)
+{
+ x->x_ac = 1;
+ SETSYMBOL(x->x_at, s);
+ x->x_sym = &s_symbol;
+ x->x_type = A_SYMBOL;
+ outlet_symbol(x->x_obj.ob_outlet, s);
+}
+
+static void init_pointer(t_init *x, t_gpointer *gp)
+{
+ x->x_ac = 1;
+ SETPOINTER(x->x_at, gp);
+ x->x_sym = &s_pointer;
+ x->x_type = A_POINTER;
+ outlet_pointer(x->x_obj.ob_outlet, gp);
+}
+
+static void init_list(t_init *x, t_symbol *s, int ac, t_atom *av)
+{
+ t_atom *at;
+
+ if(ac > x->x_n)
+ {
+ if(x->x_at)
+ freebytes(x->x_at, x->x_n * sizeof(t_atom));
+ x->x_n = ac;
+ x->x_at = (t_atom *)getbytes(x->x_n * sizeof(t_atom));
+ }
+ x->x_ac = ac;
+ x->x_sym = &s_list;
+ at = x->x_at;
+ while(ac--)
+ *at++ = *av++;
+ x->x_type = A_GIMME;
+ outlet_list(x->x_obj.ob_outlet, &s_list, x->x_ac, x->x_at);
+}
+
+static void init_anything(t_init *x, t_symbol *s, int ac, t_atom *av)
+{
+ t_atom *at;
+
+ if(ac > x->x_n)
+ {
+ if(x->x_at)
+ freebytes(x->x_at, x->x_n * sizeof(t_atom));
+ x->x_n = ac;
+ x->x_at = (t_atom *)getbytes(x->x_n * sizeof(t_atom));
+ }
+ x->x_ac = ac;
+ x->x_sym = s;
+ at = x->x_at;
+ while(ac--)
+ *at++ = *av++;
+ x->x_type = A_COMMA;
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, x->x_ac, x->x_at);
+}
+
+static void init_free(t_init *x)
+{
+ if(x->x_at)
+ freebytes(x->x_at, x->x_n * sizeof(t_atom));
+}
+
+static void *init_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_init *x = (t_init *)pd_new(init_class);
+ int i;
+
+ x->x_type = A_NULL;
+ if(!ac)
+ {
+ x->x_type = A_NULL;
+ x->x_sym = &s_bang;
+ x->x_n = 1;
+ x->x_ac = 0;
+ x->x_at = (t_atom *)getbytes(x->x_n * sizeof(t_atom));
+ }
+ else if(ac == 1)
+ {
+ if(IS_A_SYMBOL(av,0))
+ {
+ x->x_type = A_COMMA;
+ x->x_sym = atom_getsymbol(av);
+ x->x_n = 1;
+ x->x_ac = 0;
+ x->x_at = (t_atom *)getbytes(x->x_n * sizeof(t_atom));
+ }
+ else
+ {
+ if(IS_A_FLOAT(av,0))
+ {
+ x->x_type = A_FLOAT;
+ x->x_sym = &s_float;
+ }
+ else if(IS_A_POINTER(av,0))
+ {
+ x->x_type = A_POINTER;
+ x->x_sym = &s_pointer;
+ }
+ x->x_n = x->x_ac = 1;
+ x->x_at = (t_atom *)getbytes(x->x_n * sizeof(t_atom));
+ x->x_at[0] = *av;
+ }
+ }
+ else
+ {
+ if(IS_A_SYMBOL(av,0))
+ {
+ x->x_type = A_COMMA;/*for anything*/
+ x->x_sym = atom_getsymbol(av++);
+ ac--;
+ }
+ else
+ {
+ x->x_type = A_GIMME;
+ x->x_sym = &s_list;
+ }
+ x->x_n = x->x_ac = ac;
+ x->x_at = (t_atom *)getbytes(x->x_n * sizeof(t_atom));
+ for(i=0; i<ac; i++)
+ x->x_at[i] = *av++;
+ }
+ outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+void init_setup(void)
+{
+ init_class = class_new(gensym("init"), (t_newmethod)init_new,
+ (t_method)init_free, sizeof(t_init), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)init_new, gensym("ii"), A_GIMME, 0);
+ class_addmethod(init_class, (t_method)init_loadbang, gensym("loadbang"), 0);
+ class_addbang(init_class, (t_method)init_bang);
+ class_addanything(init_class, init_anything);
+ class_addlist(init_class, init_list);
+ class_addpointer(init_class, init_pointer);
+ class_addfloat(init_class, (t_method)init_float);
+ class_addsymbol(init_class, init_symbol);
+ class_sethelpsymbol(init_class, gensym("iemhelp/help-init"));
+}
+
diff --git a/src/iemlib2/list2send.c b/src/iemlib2/list2send.c
new file mode 100644
index 0000000..eb956d1
--- /dev/null
+++ b/src/iemlib2/list2send.c
@@ -0,0 +1,246 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ list2send ---------------------------- */
+static t_class *list2send_class;
+
+typedef struct _list2send
+{
+ t_object x_obj;
+ int x_max;
+ char *x_snd_able;
+ t_symbol **x_send_entries;
+ t_symbol *x_set;
+} t_list2send;
+
+static void list2send_list(t_list2send *x, t_symbol *s, int ac, t_atom *av)
+{
+ if((ac >= 2) && (IS_A_FLOAT(av,0)))
+ {
+ int identifier_index = (int)atom_getintarg(0, ac, av);
+
+ if(identifier_index < x->x_max)
+ {
+ if(x->x_snd_able[identifier_index])
+ {
+ t_symbol *sender = x->x_send_entries[identifier_index];
+
+ if(sender->s_thing)
+ {
+ if(ac == 2)
+ {
+ if(IS_A_FLOAT(av, 1))
+ pd_float(sender->s_thing, atom_getfloatarg(1, ac, av));
+ else if(IS_A_SYMBOL(av, 1))
+ pd_symbol(sender->s_thing, atom_getsymbolarg(1, ac, av));
+ }
+ else
+ pd_list(sender->s_thing, &s_list, ac-1, av+1);
+ }
+ }
+ }
+ }
+}
+
+static void list2send_set(t_list2send *x, t_symbol *s, int ac, t_atom *av)
+{
+ if((ac >= 2) && (IS_A_FLOAT(av,0)))
+ {
+ int identifier_index = (int)atom_getintarg(0, ac, av);
+
+ if(identifier_index < x->x_max)
+ {
+ if(x->x_snd_able[identifier_index])
+ {
+ t_symbol *sender = x->x_send_entries[identifier_index];
+
+ if(sender->s_thing)
+ typedmess(sender->s_thing, s, ac-1, av+1);
+ }
+ }
+ }
+}
+
+static void list2send_all(t_list2send *x, t_symbol *s, int ac, t_atom *av)
+{
+ int i, n=x->x_max;
+
+ if(ac == n)
+ {
+ for(i=n-1; i>=0; i--)/*change*/
+ {
+ if(x->x_snd_able[i])
+ {
+ t_symbol *sender = x->x_send_entries[i];
+
+ if(sender->s_thing)
+ {
+ if(IS_A_FLOAT(av, i))
+ pd_float(sender->s_thing, atom_getfloatarg(i, ac, av));
+ else if(IS_A_SYMBOL(av, i))
+ pd_symbol(sender->s_thing, atom_getsymbolarg(i, ac, av));
+ }
+ }
+ }
+ }
+}
+
+static void list2send_set_all(t_list2send *x, t_symbol *s, int ac, t_atom *av)
+{
+ int i, n=x->x_max;
+
+ if(ac == n)
+ {
+ for(i=n-1; i>=0; i--)/*change*/
+ {
+ if(x->x_snd_able[i])
+ {
+ t_symbol *sender = x->x_send_entries[i];
+
+ if(sender->s_thing)
+ typedmess(sender->s_thing, x->x_set, 1, av+i);
+ }
+ }
+ }
+}
+
+static void list2send_from(t_list2send *x, t_symbol *s, int ac, t_atom *av)
+{
+ int n=x->x_max;
+
+ if(ac >= 1)
+ {
+ int i, j, beg=(int)atom_getintarg(0, ac, av);
+
+ if((beg + ac - 1) <= n)
+ {
+ for(i=ac-1,j=beg+ac-2; i>=1; i--,j--)/*change*/
+ {
+ if(x->x_snd_able[j])
+ {
+ t_symbol *sender = x->x_send_entries[j];
+
+ if(sender->s_thing)
+ {
+ if(IS_A_FLOAT(av, i))
+ pd_float(sender->s_thing, atom_getfloatarg(i, ac, av));
+ else if(IS_A_SYMBOL(av, i))
+ pd_symbol(sender->s_thing, atom_getsymbolarg(i, ac, av));
+ }
+ }
+ }
+ }
+ }
+}
+
+static void list2send_set_from(t_list2send *x, t_symbol *s, int ac, t_atom *av)
+{
+ int n=x->x_max;
+
+ if(ac >= 1)
+ {
+ int i, j, beg=(int)atom_getintarg(0, ac, av);
+
+ if((beg + ac - 1) <= n)
+ {
+ for(i=ac-1,j=beg+ac-2; i>=1; i--,j--)/*change*/
+ {
+ if(x->x_snd_able[j])
+ {
+ t_symbol *sender = x->x_send_entries[j];
+
+ if(sender->s_thing)
+ typedmess(sender->s_thing, x->x_set, 1, av+i);
+ }
+ }
+ }
+ }
+}
+
+static void list2send_add(t_list2send *x, t_symbol *s, int ac, t_atom *av)
+{
+ if(ac == 2)
+ {
+ int identifier_index = (int)atom_getintarg(0, ac, av);
+
+ if(identifier_index < x->x_max)
+ {
+ if(IS_A_SYMBOL(av, 1))
+ {
+ x->x_send_entries[identifier_index] = atom_getsymbolarg(1, ac, av);
+ x->x_snd_able[identifier_index] = 1;
+ }
+ else if(IS_A_FLOAT(av, 1))
+ {
+ char str[100];
+
+ sprintf(str, "%g", atom_getfloatarg(1, ac, av));
+ x->x_send_entries[identifier_index] = gensym(str);
+ x->x_snd_able[identifier_index] = 1;
+ }
+ }
+ }
+}
+
+static void list2send_clear(t_list2send *x)
+{
+ int i, n=x->x_max;
+
+ for(i=0; i<n; i++)
+ {
+ if(x->x_snd_able[i])
+ x->x_snd_able[i] = 0;
+ }
+}
+
+static void list2send_free(t_list2send *x)
+{
+ freebytes(x->x_snd_able, x->x_max * sizeof(char));
+ freebytes(x->x_send_entries, x->x_max * sizeof(t_symbol *));
+}
+
+static void *list2send_new(t_float fmax)
+{
+ t_list2send *x = (t_list2send *)pd_new(list2send_class);
+ int i, max = (int)fmax;
+ t_atom *ap;
+
+ if(max <= 0)
+ max = 80;
+ x->x_max = max;
+ x->x_snd_able = (char *)getbytes(max * sizeof(char));
+ x->x_send_entries = (t_symbol **)getbytes(max * sizeof(t_symbol *));
+ for(i=0; i<max; i++)
+ x->x_snd_able[i] = 0;
+ x->x_set = gensym("set");
+ return (x);
+}
+
+void list2send_setup(void)
+{
+ list2send_class = class_new(gensym("list2send"), (t_newmethod)list2send_new,
+ (t_method)list2send_free, sizeof(t_list2send), 0, A_DEFFLOAT, 0);
+ class_addlist(list2send_class, list2send_list);
+ class_addmethod(list2send_class, (t_method)list2send_add, gensym("add"), A_GIMME, 0);
+ class_addmethod(list2send_class, (t_method)list2send_set, gensym("set"), A_GIMME, 0);
+ class_addmethod(list2send_class, (t_method)list2send_all, gensym("all"), A_GIMME, 0);
+ class_addmethod(list2send_class, (t_method)list2send_set_all, gensym("set_all"), A_GIMME, 0);
+ class_addmethod(list2send_class, (t_method)list2send_from, gensym("from"), A_GIMME, 0);
+ class_addmethod(list2send_class, (t_method)list2send_set_from, gensym("set_from"), A_GIMME, 0);
+ class_addmethod(list2send_class, (t_method)list2send_clear, gensym("clear"), 0);
+ class_sethelpsymbol(list2send_class, gensym("iemhelp/help-list2send"));
+}
diff --git a/src/iemlib2/makefile b/src/iemlib2/makefile
new file mode 100644
index 0000000..d44bf58
--- /dev/null
+++ b/src/iemlib2/makefile
@@ -0,0 +1,82 @@
+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 -Wall -W -Werror -Wno-unused \
+ -Wno-parentheses -Wno-switch -O6 -funroll-loops -fomit-frame-pointer \
+ -DDL_OPEN
+
+SYSTEM = $(shell uname -m)
+
+# the sources
+
+SRC = add2_comma.c \
+ bpe.c \
+ dollarg.c \
+ exp_inc.c \
+ float24.c \
+ iem_anything_kernel.c \
+ iem_append_kernel.c \
+ iem_i_route.c \
+ iem_pbank_csv.c \
+ iem_prepend_kernel.c \
+ iem_receive_kernel.c \
+ iem_route.c \
+ iem_sel_any.c \
+ iem_send_kernel.c \
+ init.c \
+ list2send.c \
+ mergefilename.c \
+ modulo_counter.c \
+ post_netreceive.c \
+ pre_inlet.c \
+ prepend_ascii.c \
+ round_zero.c \
+ sigfade.c \
+ sigiem_blocksize.c \
+ sigiem_samplerate.c \
+ sigLFO_noise.c \
+ sigm2f.c \
+ speedlim.c \
+ splitfilename.c \
+ stripfilename.c \
+ toggle_mess.c \
+ transf_fader.c \
+ unsymbol.c \
+ wrap.c \
+ iemlib2.c
+
+TARGET = iemlib2.pd_linux
+
+
+OBJ = $(SRC:.c=.o)
+
+#
+# ------------------ targets ------------------------------------
+#
+
+clean:
+ rm ../../lib/$(TARGET)
+ rm *.o
+
+all: $(OBJ)
+ @echo :: $(OBJ)
+ ld $(LDFLAGS) -o $(TARGET) *.o $(LIB)
+ strip --strip-unneeded $(TARGET)
+ mv $(TARGET) ../../lib
+ rm *.o
+
+$(OBJ) : %.o : %.c
+ touch $*.c
+ cc $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c
+
+
+
+
diff --git a/src/iemlib2/makefile_win b/src/iemlib2/makefile_win
new file mode 100644
index 0000000..21e5678
--- /dev/null
+++ b/src/iemlib2/makefile_win
@@ -0,0 +1,71 @@
+
+all: ..\..\lib\iemlib2.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\pthreadVC.lib \
+ $(PD_INST_PATH)\bin\pd.lib
+
+
+SRC = add2_comma.c \
+ bpe.c \
+ dollarg.c \
+ exp_inc.c \
+ float24.c \
+ iem_anything_kernel.c \
+ iem_append_kernel.c \
+ iem_i_route.c \
+ iem_pbank_csv.c \
+ iem_prepend_kernel.c \
+ iem_receive_kernel.c \
+ iem_route.c \
+ iem_sel_any.c \
+ iem_send_kernel.c \
+ init.c \
+ list2send.c \
+ mergefilename.c \
+ modulo_counter.c \
+ post_netreceive.c \
+ pre_inlet.c \
+ prepend_ascii.c \
+ round_zero.c \
+ sigfade.c \
+ sigiem_blocksize.c \
+ sigiem_samplerate.c \
+ sigLFO_noise.c \
+ sigm2f.c \
+ speedlim.c \
+ splitfilename.c \
+ stripfilename.c \
+ toggle_mess.c \
+ transf_fader.c \
+ unsymbol.c \
+ wrap.c \
+ iemlib2.c
+
+
+OBJ = $(SRC:.c=.obj)
+
+.c.obj:
+ cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c
+
+..\..\lib\iemlib2.dll: $(OBJ)
+ link $(PD_WIN_L_FLAGS) /dll /export:iemlib2_setup \
+ /out:..\..\lib\iemlib2.dll $(OBJ) $(PD_WIN_LIB)
+
+clean:
+ del *.obj
diff --git a/src/iemlib2/mergefilename.c b/src/iemlib2/mergefilename.c
new file mode 100644
index 0000000..7fe134b
--- /dev/null
+++ b/src/iemlib2/mergefilename.c
@@ -0,0 +1,229 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* -------------------------- mergefilename ------------------------------ */
+
+static t_class *mergefilename_class;
+
+typedef struct _mergefilename
+{
+ t_object x_obj;
+ char x_sep[2];
+} t_mergefilename;
+
+static void mergefilename_separator(t_mergefilename *x, t_symbol *s, int ac, t_atom *av)
+{
+ if(ac > 0)
+ {
+ if(IS_A_SYMBOL(av, 0))
+ {
+ if(strlen(av->a_w.w_symbol->s_name) == 1)
+ x->x_sep[0] = av->a_w.w_symbol->s_name[0];
+ else if(!strcmp(av->a_w.w_symbol->s_name, "backslash"))
+ x->x_sep[0] = '\\';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "slash"))
+ x->x_sep[0] = '/';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "blank"))
+ x->x_sep[0] = ' ';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "space"))
+ x->x_sep[0] = ' ';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "dollar"))
+ x->x_sep[0] = '$';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "comma"))
+ x->x_sep[0] = ',';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "semi"))
+ x->x_sep[0] = ';';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "leftbrace"))
+ x->x_sep[0] = '{';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "rightbrace"))
+ x->x_sep[0] = '}';
+ else
+ x->x_sep[0] = 0;
+ }
+ else if(IS_A_FLOAT(av, 0))
+ {
+ int i;
+ float f=fabs(av->a_w.w_float);
+
+ while(f >= 10.0)
+ f *= 0.1;
+ i = (int)f;
+ x->x_sep[0] = (char)i + '0';
+ }
+ }
+ else
+ x->x_sep[0] = 0;
+}
+
+static void mergefilename_float(t_mergefilename *x, t_floatarg f)
+{
+ char fbuf[30];
+
+ fbuf[0] = 0;
+ sprintf(fbuf, "%g", f);
+ outlet_symbol(x->x_obj.ob_outlet, gensym(fbuf));
+}
+
+static void mergefilename_symbol(t_mergefilename *x, t_symbol *s)
+{
+ outlet_symbol(x->x_obj.ob_outlet, s);
+}
+
+static void mergefilename_list(t_mergefilename *x, t_symbol *s, int ac, t_atom *av)
+{
+ char *cbeg, fbuf[30];
+ int size=400, i, len, cursize=0;
+
+ cbeg = (char *)getbytes(size * sizeof(char));
+ cbeg[0] = 0;
+ if(ac > 0)
+ {
+ if(IS_A_SYMBOL(av, 0))
+ {
+ len = strlen(av->a_w.w_symbol->s_name);
+ if((len + cursize) >= (size-1))
+ {
+ cbeg = (char *)resizebytes(cbeg, size*sizeof(char), 2*(len + cursize)*sizeof(char));
+ size = 2*(len + cursize);
+ }
+ strcat(cbeg, av->a_w.w_symbol->s_name);
+ cursize += len;
+ }
+ else if(IS_A_FLOAT(av, 0))
+ {
+ sprintf(fbuf, "%g", av->a_w.w_float);
+ len = strlen(fbuf);
+ if((len + cursize) >= (size-1))
+ {
+ cbeg = (char *)resizebytes(cbeg, size*sizeof(char), 2*(len + cursize)*sizeof(char));
+ size = 2*(len + cursize);
+ }
+ strcat(cbeg, fbuf);
+ cursize += len;
+ }
+ }
+
+ if(ac > 1)
+ {
+ for(i=1; i<ac; i++)
+ {
+ av++;
+ strcat(cbeg, x->x_sep);
+ if(IS_A_SYMBOL(av, 0))
+ {
+ len = strlen(av->a_w.w_symbol->s_name);
+ if((len + cursize) >= (size-1))
+ {
+ cbeg = (char *)resizebytes(cbeg, size*sizeof(char), 2*(len + cursize)*sizeof(char));
+ size = 2*(len + cursize);
+ }
+ strcat(cbeg, av->a_w.w_symbol->s_name);
+ cursize += len;
+ }
+ else if(IS_A_FLOAT(av, 0))
+ {
+ sprintf(fbuf, "%g", av->a_w.w_float);
+ len = strlen(fbuf);
+ if((len + cursize) >= (size-1))
+ {
+ cbeg = (char *)resizebytes(cbeg, size*sizeof(char), 2*(len + cursize)*sizeof(char));
+ size = 2*(len + cursize);
+ }
+ strcat(cbeg, fbuf);
+ cursize += len;
+ }
+ }
+ }
+ outlet_symbol(x->x_obj.ob_outlet, gensym(cbeg));
+ freebytes(cbeg, size * sizeof(char));
+}
+
+static void mergefilename_anything(t_mergefilename *x, t_symbol *s, int ac, t_atom *av)
+{
+ char *cbeg, fbuf[30];
+ int size=400, i, len, cursize=0;
+
+ cbeg = (char *)getbytes(size * sizeof(char));
+ cbeg[0] = 0;
+ len = strlen(s->s_name);
+ if((len + cursize) >= (size-1))
+ {
+ cbeg = (char *)resizebytes(cbeg, size*sizeof(char), 2*(len + cursize)*sizeof(char));
+ size = 2*(len + cursize);
+ }
+ strcat(cbeg, s->s_name);
+ cursize += len;
+ if(ac > 0)
+ {
+ for(i=0; i<ac; i++)
+ {
+ strcat(cbeg, x->x_sep);
+ if(IS_A_SYMBOL(av, 0))
+ {
+ len = strlen(av->a_w.w_symbol->s_name);
+ if((len + cursize) >= (size-1))
+ {
+ cbeg = (char *)resizebytes(cbeg, size*sizeof(char), 2*(len + cursize)*sizeof(char));
+ size = 2*(len + cursize);
+ }
+ strcat(cbeg, av->a_w.w_symbol->s_name);
+ cursize += len;
+ }
+ else if(IS_A_FLOAT(av, 0))
+ {
+ sprintf(fbuf, "%g", av->a_w.w_float);
+ len = strlen(fbuf);
+ if((len + cursize) >= (size-1))
+ {
+ cbeg = (char *)resizebytes(cbeg, size*sizeof(char), 2*(len + cursize)*sizeof(char));
+ size = 2*(len + cursize);
+ }
+ strcat(cbeg, fbuf);
+ cursize += len;
+ }
+ av++;
+ }
+ }
+ outlet_symbol(x->x_obj.ob_outlet, gensym(cbeg));
+ freebytes(cbeg, size * sizeof(char));
+}
+
+static void *mergefilename_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_mergefilename *x = (t_mergefilename *)pd_new(mergefilename_class);
+
+ x->x_sep[0] = 0;
+ x->x_sep[1] = 0;
+ if(ac > 0)
+ mergefilename_separator(x, s, ac, av);
+ outlet_new(&x->x_obj, &s_symbol);
+ return (x);
+}
+
+void mergefilename_setup(void)
+{
+ mergefilename_class = class_new(gensym("mergefilename"), (t_newmethod)mergefilename_new,
+ 0, sizeof(t_mergefilename), 0, A_GIMME, 0);
+ class_addmethod(mergefilename_class, (t_method)mergefilename_separator, gensym("separator"), A_GIMME, 0);
+ class_addmethod(mergefilename_class, (t_method)mergefilename_separator, gensym("sep"), A_GIMME, 0);
+ class_addfloat(mergefilename_class, mergefilename_float);
+ class_addsymbol(mergefilename_class, mergefilename_symbol);
+ class_addlist(mergefilename_class, mergefilename_list);
+ class_addanything(mergefilename_class, mergefilename_anything);
+ class_sethelpsymbol(mergefilename_class, gensym("iemhelp/help-mergefilename"));
+}
diff --git a/src/iemlib2/modulo_counter.c b/src/iemlib2/modulo_counter.c
new file mode 100644
index 0000000..3c072e2
--- /dev/null
+++ b/src/iemlib2/modulo_counter.c
@@ -0,0 +1,90 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ---------------- modulo-counter. ----------------- */
+
+static t_class *modulo_counter_class;
+
+typedef struct _modulo_counter
+{
+ t_object x_obj;
+ int x_max;
+ int x_cur;
+} t_modulo_counter;
+
+static void modulo_counter_bang(t_modulo_counter *x)
+{
+ outlet_float(x->x_obj.ob_outlet, x->x_cur++);
+ x->x_cur = x->x_cur % x->x_max;
+}
+
+static void modulo_counter_float(t_modulo_counter *x, t_float max)
+{
+ int i = (int)max;
+
+ if(i < 1)
+ i = 1;
+ if(x->x_cur >= i)
+ x->x_cur = i - 1;
+ x->x_max = i;
+}
+
+static void modulo_counter_ft1(t_modulo_counter *x, t_float set_init)
+{
+ int i = (int)set_init;
+
+ if(i < 0)
+ i = 0;
+ if(i >= x->x_max)
+ i = x->x_max - 1;
+ x->x_cur = i;
+}
+
+static void *modulo_counter_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_modulo_counter *x = (t_modulo_counter *)pd_new(modulo_counter_class);
+ int max = 1, cur = 0;
+
+ if((ac > 0) && IS_A_FLOAT(av, 0))
+ max = atom_getintarg(0, ac, av);
+ if((ac > 1) && IS_A_FLOAT(av, 1))
+ cur = atom_getintarg(1, ac, av);
+ if(max < 1)
+ x->x_max = 1;
+ else
+ x->x_max = max;
+ if(cur < 0)
+ cur = 0;
+ if(cur >= x->x_max)
+ cur = x->x_max - 1;
+ x->x_cur = cur;
+ outlet_new(&x->x_obj, &s_float);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ return (x);
+}
+
+void modulo_counter_setup(void)
+{
+ modulo_counter_class = class_new(gensym("modulo_counter"),
+ (t_newmethod)modulo_counter_new, 0,
+ sizeof(t_modulo_counter), 0, A_GIMME, 0);
+ class_addbang(modulo_counter_class, (t_method)modulo_counter_bang);
+ class_addfloat(modulo_counter_class, (t_method)modulo_counter_float);
+ class_addmethod(modulo_counter_class, (t_method)modulo_counter_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_sethelpsymbol(modulo_counter_class, gensym("iemhelp/help-modulo_counter"));
+}
diff --git a/src/iemlib2/post_netreceive.c b/src/iemlib2/post_netreceive.c
new file mode 100644
index 0000000..1d42c3d
--- /dev/null
+++ b/src/iemlib2/post_netreceive.c
@@ -0,0 +1,243 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ post_netreceive ---------------------------- */
+static t_class *post_netreceive_class;
+
+typedef struct _post_netreceive
+{
+ t_object x_obj;
+ int x_max_send_entries;
+ int x_min_send_entries;
+ char *x_snd_able;
+ t_symbol **x_send_entries;
+ t_symbol **x_plus_entries;
+ t_symbol *x_set;
+ t_atom x_at[2];
+ t_atom *x_atbuf;
+ t_symbol *x_send;
+ t_symbol *x_setall;
+} t_post_netreceive;
+
+static void post_netreceive_list(t_post_netreceive *x, t_symbol *s, int ac, t_atom *av)
+{
+ int identifier_index = (int)atom_getintarg(0, ac, av);
+ t_symbol *sender=0;
+
+ if((identifier_index >= x->x_min_send_entries) && (identifier_index < x->x_max_send_entries))
+ {
+ if(x->x_snd_able[identifier_index] == 1)
+ {
+ sender = x->x_send_entries[identifier_index];
+ if(sender->s_thing)
+ {
+ if(ac == 2)
+ pd_float(sender->s_thing, atom_getfloatarg(1, ac, av));
+ else
+ pd_list(sender->s_thing, &s_list, ac-1, av+1);
+ }
+ }
+ else if(x->x_snd_able[identifier_index] == 2)
+ {
+ sender = x->x_send_entries[identifier_index];
+ if(sender->s_thing)
+ {
+ typedmess(sender->s_thing, x->x_plus_entries[identifier_index], ac-1, av+1);
+ }
+ }
+ if(IS_A_FLOAT(av,1))
+ SETFLOAT(x->x_atbuf+identifier_index+1, atom_getfloatarg(1, ac, av));
+ else if(IS_A_SYMBOL(av,1))
+ SETSYMBOL(x->x_atbuf+identifier_index+1, atom_getsymbolarg(1, ac, av));
+ }
+}
+
+/*static void post_netreceive_set_item_name(t_post_netreceive *x, t_symbol *snd, t_float findex)
+{
+ int index = (int)findex;
+
+ if((index >= 0) && (index < x->x_max_send_entries))
+ {
+ x->x_send_entries[index] = snd;
+ x->x_snd_able[index] = 1;
+ }
+}*/
+
+static void post_netreceive_set_item_name(t_post_netreceive *x, t_symbol *s, int ac, t_atom *av)
+{
+ if(ac == 2)
+ {
+ int identifier_index = (int)atom_getintarg(1, ac, av);
+
+ if((identifier_index >= x->x_min_send_entries) && (identifier_index < x->x_max_send_entries))
+ {
+ x->x_send_entries[identifier_index] = atom_getsymbolarg(0, ac, av);
+ x->x_snd_able[identifier_index] = 1;
+ }
+ }
+ else if(ac >= 3)
+ {
+ int identifier_index = (int)atom_getintarg(2, ac, av);
+
+ if((identifier_index >= 0) && (identifier_index < x->x_max_send_entries))
+ {
+ x->x_send_entries[identifier_index] = atom_getsymbolarg(1, ac, av);
+ x->x_snd_able[identifier_index] = 2;
+ x->x_plus_entries[identifier_index] = atom_getsymbolarg(0, ac, av);
+ }
+ }
+}
+
+static void post_netreceive_all_parameters(t_post_netreceive *x, t_symbol *s, int ac, t_atom *av)
+{
+ int i, min = x->x_min_send_entries, max = x->x_max_send_entries;
+ t_symbol *sendname=0;
+
+ if(min > ac)
+ min = ac;
+ if(max > ac)
+ max = ac;
+ for(i=min; i<max; i++)
+ {
+ if(x->x_snd_able[i] == 1)
+ {
+ sendname = x->x_send_entries[i];
+ if(sendname->s_thing)
+ {
+ pd_float(sendname->s_thing, atom_getfloatarg(i, ac, av));
+ }
+ }
+ else if(x->x_snd_able[i] == 2)
+ {
+ sendname = x->x_send_entries[i];
+ if(sendname->s_thing)
+ {
+ typedmess(sendname->s_thing, x->x_plus_entries[i], 1, av+i);
+ }
+ }
+ if(IS_A_FLOAT(av,i))
+ SETFLOAT(x->x_atbuf+i+1, atom_getfloatarg(i, ac, av));
+ else if(IS_A_SYMBOL(av,i))
+ SETSYMBOL(x->x_atbuf+i+1, atom_getsymbolarg(i, ac, av));
+ }
+}
+
+static void post_netreceive_set_all_parameters(t_post_netreceive *x, t_symbol *s, int ac, t_atom *av)
+{
+ int i, min = x->x_min_send_entries, max = x->x_max_send_entries;
+ t_symbol *sendname;
+
+ if(min > ac)
+ min = ac;
+ if(max > ac)
+ max = ac;
+ for(i=min; i<max; i++)
+ {
+ if(x->x_snd_able[i])
+ {
+ sendname = x->x_send_entries[i];
+ if(sendname->s_thing)
+ {
+ typedmess(sendname->s_thing, x->x_set, 1, av+i);
+ }
+ }
+ }
+}
+
+static void post_netreceive_clear(t_post_netreceive *x)
+{
+ int i, max = x->x_max_send_entries;
+
+ for(i=0; i<max; i++)
+ {
+ if(x->x_snd_able[i])
+ {
+ x->x_snd_able[i] = 0;
+ }
+ }
+}
+
+static void post_netreceive_fetch_all_parameters(t_post_netreceive *x, t_float nr_sended_para)
+{
+ int nrsp=(int)nr_sended_para;
+ t_atom *ap=x->x_atbuf+x->x_min_send_entries;
+
+ if(nrsp <= 0)
+ nrsp = 1;
+ if(nrsp > (x->x_max_send_entries - x->x_min_send_entries))
+ nrsp = (x->x_max_send_entries - x->x_min_send_entries);
+ outlet_anything(x->x_obj.ob_outlet, x->x_send, nrsp+1, x->x_atbuf);
+}
+
+static void post_netreceive_free(t_post_netreceive *x)
+{
+ freebytes(x->x_snd_able, x->x_max_send_entries * sizeof(char));
+ freebytes(x->x_send_entries, x->x_max_send_entries * sizeof(t_symbol *));
+ freebytes(x->x_atbuf, (x->x_max_send_entries+2) * sizeof(t_atom));
+ freebytes(x->x_plus_entries, x->x_max_send_entries * sizeof(t_symbol *));
+}
+
+static void *post_netreceive_new(t_float fmin, t_float fmax)
+{
+ t_post_netreceive *x = (t_post_netreceive *)pd_new(post_netreceive_class);
+ int i, min = (int)fmin, max = (int)fmax;
+ t_atom *ap;
+
+ if(min < 0)
+ min = 0;
+ if(max <= 0)
+ max = 80;
+ x->x_min_send_entries = min;
+ x->x_max_send_entries = max;
+ x->x_atbuf = (t_atom *)getbytes((x->x_max_send_entries+2) * sizeof(t_atom));
+ x->x_snd_able = (char *)getbytes(x->x_max_send_entries * sizeof(char));
+ x->x_send_entries = (t_symbol **)getbytes(x->x_max_send_entries * sizeof(t_symbol *));
+ x->x_plus_entries = (t_symbol **)getbytes(x->x_max_send_entries * sizeof(t_symbol *));
+ x->x_set = gensym("set");
+ x->x_setall = gensym("set_all_parameters");
+ x->x_send = gensym("send");
+ ap = x->x_atbuf;
+ SETSYMBOL(ap, x->x_setall);
+ ap++;
+ for(i=1; i<=max; i++)
+ {
+ SETFLOAT(ap, 0.0);
+ ap++;
+ }
+ for(i=0; i<max; i++)
+ {
+ x->x_snd_able[i] = 0;
+ x->x_plus_entries[i] = x->x_set;
+ }
+ outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+void post_netreceive_setup(void)
+{
+ post_netreceive_class = class_new(gensym("post_netreceive"), (t_newmethod)post_netreceive_new,
+ (t_method)post_netreceive_free, sizeof(t_post_netreceive), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addlist(post_netreceive_class, post_netreceive_list);
+ class_addmethod(post_netreceive_class, (t_method)post_netreceive_set_item_name, gensym("set_item_name"), A_GIMME, 0);
+ class_addmethod(post_netreceive_class, (t_method)post_netreceive_all_parameters, gensym("all_parameters"), A_GIMME, 0);
+ class_addmethod(post_netreceive_class, (t_method)post_netreceive_set_all_parameters, gensym("set_all_parameters"), A_GIMME, 0);
+ class_addmethod(post_netreceive_class, (t_method)post_netreceive_fetch_all_parameters, gensym("fetch_all_parameters"), A_DEFFLOAT, 0);
+ class_addmethod(post_netreceive_class, (t_method)post_netreceive_clear, gensym("clear"), 0);
+ class_sethelpsymbol(post_netreceive_class, gensym("iemhelp/help-post_netreceive"));
+}
+
diff --git a/src/iemlib2/pre_inlet.c b/src/iemlib2/pre_inlet.c
new file mode 100644
index 0000000..dd0b440
--- /dev/null
+++ b/src/iemlib2/pre_inlet.c
@@ -0,0 +1,94 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ pre_inlet ---------------------------- */
+static t_class *pre_inlet_class;
+
+typedef struct _pre_inlet
+{
+ t_object x_obj;
+ t_atom x_at;
+ t_symbol *x_sym;
+} t_pre_inlet;
+
+static void pre_inlet_bang(t_pre_inlet *x)
+{
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, 1, &x->x_at);
+ outlet_bang(x->x_obj.ob_outlet);
+}
+
+static void pre_inlet_float(t_pre_inlet *x, t_float f)
+{
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, 1, &x->x_at);
+ outlet_float(x->x_obj.ob_outlet, f);
+}
+
+static void pre_inlet_symbol(t_pre_inlet *x, t_symbol *s)
+{
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, 1, &x->x_at);
+ outlet_symbol(x->x_obj.ob_outlet, s);
+}
+
+static void pre_inlet_pointer(t_pre_inlet *x, t_gpointer *gp)
+{
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, 1, &x->x_at);
+ outlet_pointer(x->x_obj.ob_outlet, gp);
+}
+
+static void pre_inlet_list(t_pre_inlet *x, t_symbol *s, int ac, t_atom *av)
+{
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, 1, &x->x_at);
+ outlet_list(x->x_obj.ob_outlet, s, ac, av);
+}
+
+static void pre_inlet_anything(t_pre_inlet *x, t_symbol *s, int ac, t_atom *av)
+{
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, 1, &x->x_at);
+ outlet_anything(x->x_obj.ob_outlet, s, ac, av);
+}
+
+static void pre_inlet_free(t_pre_inlet *x)
+{
+}
+
+static void *pre_inlet_new(t_floatarg fsym, t_floatarg finlet)
+{
+ t_pre_inlet *x = (t_pre_inlet *)pd_new(pre_inlet_class);
+ char str[2];
+
+ SETFLOAT(&x->x_at, finlet);
+ str[0] = (char)((int)(fsym)&0xff);
+ str[1] = 0;
+ x->x_sym = gensym(str);
+ outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+void pre_inlet_setup(void)
+{
+ pre_inlet_class = class_new(gensym("pre_inlet"), (t_newmethod)pre_inlet_new,
+ (t_method)pre_inlet_free, sizeof(t_pre_inlet), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addbang(pre_inlet_class, (t_method)pre_inlet_bang);
+ class_addfloat(pre_inlet_class, (t_method)pre_inlet_float);
+ class_addsymbol(pre_inlet_class, pre_inlet_symbol);
+ class_addpointer(pre_inlet_class, pre_inlet_pointer);
+ class_addlist(pre_inlet_class, pre_inlet_list);
+ class_addanything(pre_inlet_class, pre_inlet_anything);
+ class_sethelpsymbol(pre_inlet_class, gensym("iemhelp/help-pre_inlet"));
+}
+
diff --git a/src/iemlib2/prepend_ascii.c b/src/iemlib2/prepend_ascii.c
new file mode 100644
index 0000000..7541ff9
--- /dev/null
+++ b/src/iemlib2/prepend_ascii.c
@@ -0,0 +1,127 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ prepend_ascii ---------------------------- */
+static t_class *prepend_ascii_class;
+
+typedef struct _prepend_ascii
+{
+ t_object x_obj;
+ t_atom *x_at;
+ int x_size;
+ int x_ac;
+ t_symbol *x_sym;
+} t_prepend_ascii;
+
+static void prepend_ascii_atcopy(t_atom *src, t_atom *dst, int n)
+{
+ while(n--)
+ *dst++ = *src++;
+}
+
+static void prepend_ascii_bang(t_prepend_ascii *x)
+{
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, x->x_ac, x->x_at);
+}
+
+static void prepend_ascii_float(t_prepend_ascii *x, t_float f)
+{
+ SETFLOAT(x->x_at+x->x_ac, f);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, x->x_ac+1, x->x_at);
+}
+
+static void prepend_ascii_symbol(t_prepend_ascii *x, t_symbol *s)
+{
+ SETSYMBOL(x->x_at+x->x_ac, s);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, x->x_ac+1, x->x_at);
+}
+
+static void prepend_ascii_pointer(t_prepend_ascii *x, t_gpointer *gp)
+{
+ SETPOINTER(x->x_at+x->x_ac, gp);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, x->x_ac+1, x->x_at);
+}
+
+static void prepend_ascii_list(t_prepend_ascii *x, t_symbol *s, int ac, t_atom *av)
+{
+ if((ac+x->x_ac) > x->x_size)
+ {
+ x->x_at = (t_atom *)resizebytes(x->x_at, x->x_size*sizeof(t_atom), (ac+x->x_ac)*sizeof(t_atom));
+ x->x_size = (ac+x->x_ac);
+ }
+ prepend_ascii_atcopy(av, x->x_at+x->x_ac, ac);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, ac+x->x_ac, x->x_at);
+}
+
+static void prepend_ascii_anything(t_prepend_ascii *x, t_symbol *s, int ac, t_atom *av)
+{
+ if((ac+x->x_ac+1) > x->x_size)
+ {
+ x->x_at = (t_atom *)resizebytes(x->x_at, x->x_size*sizeof(t_atom), (ac+x->x_ac+1)*sizeof(t_atom));
+ x->x_size = (ac+x->x_ac+1);
+ }
+ SETSYMBOL(x->x_at+x->x_ac, s);
+ prepend_ascii_atcopy(av, x->x_at+x->x_ac+1, ac);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym, ac+x->x_ac+1, x->x_at);
+}
+
+static void prepend_ascii_free(t_prepend_ascii *x)
+{
+ if(x->x_at)
+ freebytes(x->x_at, x->x_size * sizeof(t_atom));
+}
+
+static void *prepend_ascii_new(t_symbol *s, int ac, t_atom *av)
+{
+ if((ac <= 0) || (!IS_A_FLOAT(av,0)))
+ {
+ post("ERROR: prepend_ascii need a float between 1 and 255 as 1. arg. !!!");
+ return(0);
+ }
+ else
+ {
+ t_prepend_ascii *x = (t_prepend_ascii *)pd_new(prepend_ascii_class);
+ char str[2];
+ int i;
+
+ x->x_size = 10 + ac;
+ x->x_at = (t_atom *)getbytes(x->x_size * sizeof(t_atom));
+ str[0] = (char)((int)(atom_getfloatarg(0,ac,av))&0xff);
+ str[1] = 0;
+ x->x_sym = gensym(str);
+ x->x_ac = ac - 1;
+ for(i=1; i<ac; i++)
+ x->x_at[i-1] = av[i];
+ outlet_new(&x->x_obj, &s_list);
+ return (x);
+ }
+}
+
+void prepend_ascii_setup(void)
+{
+ prepend_ascii_class = class_new(gensym("prepend_ascii"), (t_newmethod)prepend_ascii_new,
+ (t_method)prepend_ascii_free, sizeof(t_prepend_ascii), 0, A_GIMME, 0);
+ class_addbang(prepend_ascii_class, (t_method)prepend_ascii_bang);
+ class_addfloat(prepend_ascii_class, (t_method)prepend_ascii_float);
+ class_addsymbol(prepend_ascii_class, prepend_ascii_symbol);
+ class_addpointer(prepend_ascii_class, prepend_ascii_pointer);
+ class_addlist(prepend_ascii_class, prepend_ascii_list);
+ class_addanything(prepend_ascii_class, prepend_ascii_anything);
+ class_sethelpsymbol(prepend_ascii_class, gensym("iemhelp/help-prepend_ascii"));
+}
+
diff --git a/src/iemlib2/prepend_kernel.c b/src/iemlib2/prepend_kernel.c
new file mode 100644
index 0000000..d66c7be
--- /dev/null
+++ b/src/iemlib2/prepend_kernel.c
@@ -0,0 +1,351 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+
+/* ------------------------ prepend_kernel ---------------------------- */
+static t_class *prepend_kernel_class;
+
+typedef struct _prepend_kernel
+{
+ t_object x_obj;
+ int x_inlet_select;
+ int x_size12;
+ int x_size2;
+ int x_ac1;
+ int x_ac2;
+ t_atom *x_at12;
+ t_atom *x_at2;
+ t_symbol *x_sym1;
+ t_symbol *x_sym2;
+ t_atomtype x_type1;
+ t_atomtype x_type2;
+} t_prepend_kernel;
+
+static void prepend_kernel_atcopy(t_atom *src, t_atom *dst, int n)
+{
+ while(n--)
+ *dst++ = *src++;
+}
+
+static void prepend_kernel_merge(t_prepend_kernel *x, int off)
+{
+ if((x->x_ac1+x->x_ac2) > x->x_size1)
+ {
+ x->x_at1 = (t_atom *)resizebytes(x->x_at1, x->x_size1*sizeof(t_atom), 2*(x->x_ac1+x->x_ac2)*sizeof(t_atom));
+ x->x_size1 = 2*(x->x_ac1+x->x_ac2);
+ }
+ if(off)
+ SETSYMBOL(x->x_at1 + x->x_ac1, x->x_sym2);
+ prepend_kernel_atcopy(x->x_at2, x->x_at1 + x->x_ac1 + off, x->x_ac2);
+}
+
+static void prepend_kernel_out(t_prepend_kernel *x)
+{
+ int off=0;
+
+ if(x->x_type1 == A_GIMME)
+ {
+ if(x->x_type2 == A_COMMA)
+ off = 1;
+ else
+ off = 0;
+ prepend_kernel_merge(x, off);
+ outlet_list(x->x_obj.ob_outlet, &s_list, x->x_ac1+x->x_ac2+off, x->x_at1);
+ }
+ else if(x->x_type1 == A_COMMA)
+ {
+ if(x->x_type2 == A_COMMA)
+ off = 1;
+ else
+ off = 0;
+ prepend_kernel_merge(x, off);
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym1, x->x_ac1+x->x_ac2+off, x->x_at1);
+ }
+ else if(x->x_type1 == A_NULL)/*depends on 2.part*/
+ {
+ prepend_kernel_merge(x, 0);
+ if(x->x_type2 == A_GIMME)
+ outlet_list(x->x_obj.ob_outlet, &s_list, x->x_ac2, x->x_at1);
+ else if(x->x_type2 == A_COMMA)
+ outlet_anything(x->x_obj.ob_outlet, x->x_sym2, x->x_ac2, x->x_at1);
+ else if(x->x_type2 == A_FLOAT)
+ outlet_float(x->x_obj.ob_outlet, atom_getfloat(x->x_at1));
+ else if(x->x_type2 == A_SYMBOL)
+ outlet_symbol(x->x_obj.ob_outlet, atom_getsymbol(x->x_at1));
+ else if(x->x_type2 == A_NULL)
+ outlet_bang(x->x_obj.ob_outlet);
+ else if(x->x_type2 == A_POINTER)
+ outlet_pointer(x->x_obj.ob_outlet, (t_gpointer *)x->x_at1->a_w.w_gpointer);
+ }
+ else
+ {
+ if(x->x_type2 == A_COMMA)
+ off = 1;
+ else
+ off = 0;
+ prepend_kernel_merge(x, off);
+ if(x->x_type2 == A_NULL)
+ {
+ if(x->x_type1 == A_FLOAT)
+ outlet_float(x->x_obj.ob_outlet, atom_getfloat(x->x_at1));
+ else if(x->x_type1 == A_SYMBOL)
+ outlet_symbol(x->x_obj.ob_outlet, atom_getsymbol(x->x_at1));
+ else if(x->x_type1 == A_POINTER)
+ outlet_pointer(x->x_obj.ob_outlet, (t_gpointer *)x->x_at1->a_w.w_gpointer);
+ }
+ else
+ outlet_list(x->x_obj.ob_outlet, &s_list, x->x_ac1+x->x_ac2+off, x->x_at1);
+ }
+}
+
+static void prepend_kernel_inlet_select(t_prepend_kernel *x, t_floatarg fin_sel_01)
+{
+ x->x_inlet_select = (int)fin_sel_01;
+}
+
+static void prepend_kernel_bang(t_prepend_kernel *x)
+{
+ if(!x->x_inlet_select) /* if 2nd inlet */
+ {
+ x->x_ac2 = 0;
+ x->x_type2 = A_NULL;
+ x->x_sym2 = &s_list;
+ }
+ else /* if 1st inlet */
+ {
+ x->x_ac1 = 0;
+ x->x_type1 = A_NULL;
+ prepend_kernel_out(x);
+ }
+}
+
+static void prepend_kernel_float(t_prepend_kernel *x, t_float f)
+{
+ if(!x->x_inlet_select) /* if 2nd inlet */
+ {
+ x->x_ac2 = 1;
+ x->x_type2 = A_FLOAT;
+ SETFLOAT(x->x_at2, f);
+ x->x_sym2 = &s_list;
+ }
+ else /* if 1st inlet */
+ {
+ x->x_ac1 = 1;
+ x->x_type1 = A_FLOAT;
+ SETFLOAT(x->x_at1, f);
+ prepend_kernel_out(x);
+ }
+}
+
+static void prepend_kernel_symbol(t_prepend_kernel *x, t_symbol *s)
+{
+ if(!x->x_inlet_select) /* if 2nd inlet */
+ {
+ x->x_ac2 = 1;
+ x->x_type2 = A_SYMBOL;
+ SETSYMBOL(x->x_at2, s);
+ x->x_sym2 = &s_list;
+ }
+ else /* if 1st inlet */
+ {
+ x->x_ac1 = 1;
+ x->x_type1 = A_SYMBOL;
+ SETSYMBOL(x->x_at12, s);
+ prepend_kernel_out(x);
+ }
+}
+
+static void prepend_kernel_pointer(t_prepend_kernel *x, t_gpointer *gp)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ x->x_ac2 = 1;
+ x->x_type2 = A_POINTER;
+ SETPOINTER(x->x_at2, gp);
+ x->x_sym2 = &s_list;
+ }
+ else /* if 1st inlet */
+ {
+ x->x_ac1 = 1;
+ x->x_type1 = A_POINTER;
+ SETPOINTER(x->x_at12, gp);
+ prepend_kernel_out(x);
+ }
+}
+
+static void prepend_kernel_list(t_prepend_kernel *x, t_symbol *s, int ac, t_atom *av)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ if(ac > x->x_size2)
+ {
+ x->x_at2 = (t_atom *)resizebytes(x->x_at2, x->x_size2*sizeof(t_atom), 2*ac*sizeof(t_atom));
+ x->x_size2 = 2*ac;
+ }
+ x->x_ac2 = ac;
+ x->x_type2 = A_GIMME;
+ x->x_sym2 = &s_list;
+ prepend_kernel_atcopy(av, x->x_at2, ac);
+ }
+ else /* if 1st inlet */
+ {
+ if((x->x_ac1+ac) > x->x_size12)
+ {
+ x->x_at12 = (t_atom *)resizebytes(x->x_at12, x->x_size12*sizeof(t_atom), 2*(x->x_ac1+ac)*sizeof(t_atom));
+ x->x_size12 = 2*(x->x_ac1+ac);
+ }
+ x->x_ac1 = ac;
+ x->x_type1 = A_GIMME;
+ prepend_kernel_atcopy(av, x->x_at12, ac);
+ x->x_sym1 = &s_list;
+ prepend_kernel_out(x);
+ }
+}
+
+static void prepend_kernel_anything(t_prepend_kernel *x, t_symbol *s, int ac, t_atom *av)
+{
+ if(x->x_inlet_select) /* if 2nd inlet */
+ {
+ if((ac+1) > x->x_size2)
+ {
+ x->x_at2 = (t_atom *)resizebytes(x->x_at2, x->x_size2*sizeof(t_atom), 2*ac*sizeof(t_atom));
+ x->x_size2 = 2*ac;
+ }
+ SETSYMBOL(x->x_at2, s);
+ x->x_ac2 = ac;
+ x->x_type2 = A_COMMA;
+ x->x_sym2 = s;
+ prepend_kernel_atcopy(av, x->x_at2, ac);
+ }
+ else /* if 1st inlet */
+ {
+ if((x->x_ac1+ac) > x->x_size12)
+ {
+ x->x_at12 = (t_atom *)resizebytes(x->x_at12, x->x_size12*sizeof(t_atom), (2*x->x_ac1+ac)*sizeof(t_atom));
+ x->x_size12 = (2*x->x_ac1+ac);
+ }
+ x->x_ac1 = ac;
+ x->x_type1 = A_COMMA;
+ prepend_kernel_atcopy(av, x->x_at12, ac);
+ x->x_sym1 = s;
+ prepend_kernel_out(x);
+ }
+}
+
+static void prepend_kernel_free(t_prepend_kernel *x)
+{
+ if(x->x_at1)
+ freebytes(x->x_at1, x->x_size1 * sizeof(t_atom));
+}
+
+static void *prepend_kernel_new(void)
+{
+ t_prepend_kernel *x = (t_prepend_kernel *)pd_new(prepend_kernel_class);
+ t_glist *glist = (t_glist *)canvas_getcurrent();
+ t_canvas *canvas=glist_getcanvas(glist);
+ int ac=0;
+ t_atom *av;
+
+ x->x_type2 = A_NULL;
+ x->x_sym2 = &s_list;
+ x->x_ac2 = 0;
+
+ canvas_setcurrent(canvas);
+ canvas_getargs(&ac, &av);
+ canvas_unsetcurrent(canvas);
+
+ x->x_type1 = A_NULL;
+ if(!ac)
+ {
+ x->x_type1 = A_NULL;
+ x->x_sym1 = &s_bang;
+ x->x_size1 = 10;
+ x->x_ac1 = 0;
+ x->x_at1 = (t_atom *)getbytes(x->x_size1 * sizeof(t_atom));
+ }
+ else if(ac == 1)
+ {
+ if(IS_A_SYMBOL(av,0))
+ {
+ x->x_type1 = A_COMMA;
+ x->x_sym1 = atom_getsymbol(av);
+ x->x_size1 = 10;
+ x->x_ac1 = 0;
+ x->x_at1 = (t_atom *)getbytes(x->x_size1 * sizeof(t_atom));
+ }
+ else
+ {
+ if(IS_A_FLOAT(av,0))
+ {
+ x->x_type1 = A_FLOAT;
+ x->x_sym1 = &s_float;
+ }
+ else if(IS_A_POINTER(av,0))
+ {
+ x->x_type1 = A_POINTER;
+ x->x_sym1 = &s_pointer;
+ }
+ x->x_size1 = 11;
+ x->x_ac1 = 1;
+ x->x_at1 = (t_atom *)getbytes(x->x_size1 * sizeof(t_atom));
+ x->x_at1[0] = *av;
+ }
+ }
+ else /* ac > 1 */
+ {
+ if(IS_A_SYMBOL(av,0))
+ {
+ x->x_type1 = A_COMMA;/*for anything*/
+ x->x_sym1 = atom_getsymbol(av++);
+ ac--;
+ }
+ else
+ {
+ x->x_type1 = A_GIMME;
+ x->x_sym1 = &s_list;
+ }
+ x->x_size1 = ac + 10;
+ x->x_ac1 = ac;
+ x->x_at1 = (t_atom *)getbytes(x->x_size1 * sizeof(t_atom));
+ prepend_kernel_atcopy(av, x->x_at1, ac);
+ }
+
+ x->x_inlet_select = 1;
+ outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+void prepend_kernel_setup(void)
+{
+ char str[2];
+
+ str[0] = 1;
+ str[1] = 0;
+ prepend_kernel_class = class_new(gensym("prepend_kernel"),
+ (t_newmethod)prepend_kernel_new, (t_method)prepend_kernel_free,
+ sizeof(t_prepend_kernel), 0, 0);
+ class_addbang(prepend_kernel_class, (t_method)prepend_kernel_bang);
+ class_addpointer(prepend_kernel_class, prepend_kernel_pointer);
+ class_addfloat(prepend_kernel_class, (t_method)prepend_kernel_float);
+ class_addsymbol(prepend_kernel_class, prepend_kernel_symbol);
+ class_addlist(prepend_kernel_class, prepend_kernel_list);
+ class_addmethod(prepend_kernel_class, (t_method)prepend_kernel_inlet_select, gensym(str), A_FLOAT, 0);
+ class_addanything(prepend_kernel_class, prepend_kernel_anything);
+ class_sethelpsymbol(prepend_kernel_class, gensym("iemhelp/help-merge_any"));
+}
+
diff --git a/src/iemlib2/round_zero.c b/src/iemlib2/round_zero.c
new file mode 100644
index 0000000..b37afb4
--- /dev/null
+++ b/src/iemlib2/round_zero.c
@@ -0,0 +1,67 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* ------------------------ round_zero ---------------------------- */
+static t_class *round_zero_class;
+
+typedef struct _round_zero
+{
+ t_object x_obj;
+ t_float x_bound;
+} t_round_zero;
+
+static void round_zero_anything(t_round_zero *x, t_symbol *s, int ac, t_atom *av)
+{
+ int i;
+ t_float f, bound=x->x_bound;
+
+ for(i=0; i<ac; i++)
+ {
+ if(IS_A_FLOAT(av, i))
+ {
+ f = atom_getfloatarg(i, ac, av);
+ if((f <= bound)&&(f >= -bound))
+ {
+ f = 0.0f;
+ SETFLOAT(av+i, f);
+ }
+ }
+ }
+ outlet_anything(x->x_obj.ob_outlet, s, ac, av);
+}
+
+static void *round_zero_new(t_floatarg bound)
+{
+ t_round_zero *x = (t_round_zero *)pd_new(round_zero_class);
+
+ if(bound < 0.0f)
+ x->x_bound = -bound;
+ else
+ x->x_bound = bound;
+ outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+void round_zero_setup(void)
+{
+ round_zero_class = class_new(gensym("round_zero"), (t_newmethod)round_zero_new,
+ 0, sizeof(t_round_zero), 0, A_DEFFLOAT, 0);
+ class_addanything(round_zero_class, round_zero_anything);
+ class_sethelpsymbol(round_zero_class, gensym("iemhelp/help-round_zero"));
+}
+
diff --git a/src/iemlib2/sigLFO_noise.c b/src/iemlib2/sigLFO_noise.c
new file mode 100644
index 0000000..3714f5a
--- /dev/null
+++ b/src/iemlib2/sigLFO_noise.c
@@ -0,0 +1,129 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ LFO_noise~ ----------------------------- */
+
+static t_class *sigLFO_noise_class;
+
+typedef struct _sigLFO_noise
+{
+ t_object x_obj;
+ double x_range;
+ double x_rcp_range;
+ unsigned int x_state;
+ float x_fact;
+ float x_incr;
+ float x_y1;
+ float x_y2;
+ float x_phase;
+} t_sigLFO_noise;
+
+static int sigLFO_noise_makeseed(void)
+{
+ static unsigned int sigLFO_noise_nextseed = 1489853723;
+
+ sigLFO_noise_nextseed = sigLFO_noise_nextseed * 435898247 + 938284287;
+ return(sigLFO_noise_nextseed & 0x7fffffff);
+}
+
+static float sigLFO_noise_new_rand(t_sigLFO_noise *x)
+{
+ unsigned int state = x->x_state;
+ double new_val, range = x->x_range;
+
+ x->x_state = state = state * 472940017 + 832416023;
+ new_val = range * ((double)state) * (1./4294967296.);
+ if(new_val >= range)
+ new_val = range-1;
+ new_val -= 32767.0;
+ return(new_val*(1.0/32767.0));
+}
+
+static void *sigLFO_noise_new(t_float freq)
+{
+ t_sigLFO_noise *x = (t_sigLFO_noise *)pd_new(sigLFO_noise_class);
+
+ x->x_range = 65535.0;
+ x->x_rcp_range = (double)x->x_range * (1.0/4294967296.0);
+ x->x_state = sigLFO_noise_makeseed();
+ x->x_fact = 2. / 44100.0;
+ x->x_incr = freq * x->x_fact;
+ if(x->x_incr < 0.0)
+ x->x_incr = 0.0;
+ else if(x->x_incr > 0.1)
+ x->x_incr = 0.1;
+ x->x_y1 = sigLFO_noise_new_rand(x);
+ x->x_y2 = sigLFO_noise_new_rand(x);
+ x->x_phase = 0.0;
+ outlet_new(&x->x_obj, gensym("signal"));
+ return (x);
+}
+
+static t_int *sigLFO_noise_perform(t_int *w)
+{
+ t_float *out = (t_float *)(w[1]);
+ t_sigLFO_noise *x = (t_sigLFO_noise *)(w[2]);
+ int n = (int)(w[3]);
+ float phase = x->x_phase;
+ float x_y1 = x->x_y1;
+ float x_y2 = x->x_y2;
+ float incr = x->x_incr;
+
+ while(n--)
+ {
+ if(phase > 1.0)
+ {
+ x_y1 = x_y2;
+ x_y2 = sigLFO_noise_new_rand(x);
+ phase -= 1.0;
+ }
+ *out++ = (x_y2 - x_y1) * phase + x_y1;
+ phase += incr;
+ }
+ x->x_phase = phase;
+ x->x_y1 = x_y1;
+ x->x_y2 = x_y2;
+ return (w+4);
+}
+
+static void sigLFO_noise_float(t_sigLFO_noise *x, t_float freq)
+{
+ x->x_incr = freq * x->x_fact;
+ if(x->x_incr < 0.0)
+ x->x_incr = 0.0;
+ else if(x->x_incr > 0.1)
+ x->x_incr = 0.1;
+}
+
+static void sigLFO_noise_dsp(t_sigLFO_noise *x, t_signal **sp)
+{
+ x->x_fact = 2. / sp[0]->s_sr;
+ dsp_add(sigLFO_noise_perform, 3, sp[0]->s_vec, x, sp[0]->s_n);
+}
+
+void sigLFO_noise_setup(void)
+{
+ sigLFO_noise_class = class_new(gensym("LFO_noise~"),
+ (t_newmethod)sigLFO_noise_new, 0,
+ sizeof(t_sigLFO_noise), 0, A_DEFFLOAT, 0);
+ class_addmethod(sigLFO_noise_class, (t_method)sigLFO_noise_dsp,
+ gensym("dsp"), 0);
+ class_addfloat(sigLFO_noise_class, (t_method)sigLFO_noise_float);
+ class_sethelpsymbol(sigLFO_noise_class, gensym("iemhelp/help-LFO_noise~"));
+}
+
diff --git a/src/iemlib2/sigfade.c b/src/iemlib2/sigfade.c
new file mode 100644
index 0000000..d63f363
--- /dev/null
+++ b/src/iemlib2/sigfade.c
@@ -0,0 +1,183 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ fade~ ----------------------------- */
+
+float *iem_fade_table_lin=(float *)0L;
+float *iem_fade_table_linsqrt=(float *)0L;
+float *iem_fade_table_sqrt=(float *)0L;
+float *iem_fade_table_sin=(float *)0L;
+float *iem_fade_table_sinhann=(float *)0L;
+float *iem_fade_table_hann=(float *)0L;
+
+static t_class *sigfade_class;
+
+typedef struct _sigfade
+{
+ t_object x_obj;
+ float *x_table;
+ float x_f;
+} t_sigfade;
+
+static void sigfade_set(t_sigfade *x, t_symbol *s)
+{
+ if(!strcmp(s->s_name, "_lin"))
+ x->x_table = iem_fade_table_lin;
+ else if(!strcmp(s->s_name, "_linsqrt"))
+ x->x_table = iem_fade_table_linsqrt;
+ else if(!strcmp(s->s_name, "_sqrt"))
+ x->x_table = iem_fade_table_sqrt;
+ else if(!strcmp(s->s_name, "_sin"))
+ x->x_table = iem_fade_table_sin;
+ else if(!strcmp(s->s_name, "_sinhann"))
+ x->x_table = iem_fade_table_sinhann;
+ else if(!strcmp(s->s_name, "_hann"))
+ x->x_table = iem_fade_table_hann;
+}
+
+static void *sigfade_new(t_symbol *s)
+{
+ t_sigfade *x = (t_sigfade *)pd_new(sigfade_class);
+ outlet_new(&x->x_obj, gensym("signal"));
+ x->x_f = 0;
+ x->x_table = iem_fade_table_lin;
+ sigfade_set(x, s);
+ return (x);
+}
+
+static t_int *sigfade_perform(t_int *w)
+{
+ t_float *in = (t_float *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_sigfade *x = (t_sigfade *)(w[3]);
+ int n = (int)(w[4]);
+ float *tab = x->x_table, *addr, f1, f2, frac;
+ double dphase;
+ int normhipart;
+ union tabfudge tf;
+
+ tf.tf_d = UNITBIT32;
+ normhipart = tf.tf_i[HIOFFSET];
+
+#if 0 /* this is the readable version of the code. */
+ while (n--)
+ {
+ dphase = (double)(*in++ * (float)(COSTABSIZE) * 0.99999) + UNITBIT32;
+ tf.tf_d = dphase;
+ addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
+ tf.tf_i[HIOFFSET] = normhipart;
+ frac = tf.tf_d - UNITBIT32;
+ f1 = addr[0];
+ f2 = addr[1];
+ *out++ = f1 + frac * (f2 - f1);
+ }
+#endif
+#if 1 /* this is the same, unwrapped by hand. */
+ dphase = (double)(*in++ * (float)(COSTABSIZE) * 0.99999) + UNITBIT32;
+ tf.tf_d = dphase;
+ addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
+ tf.tf_i[HIOFFSET] = normhipart;
+ while (--n)
+ {
+ dphase = (double)(*in++ * (float)(COSTABSIZE) * 0.99999) + UNITBIT32;
+ frac = tf.tf_d - UNITBIT32;
+ tf.tf_d = dphase;
+ f1 = addr[0];
+ f2 = addr[1];
+ addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
+ *out++ = f1 + frac * (f2 - f1);
+ tf.tf_i[HIOFFSET] = normhipart;
+ }
+ frac = tf.tf_d - UNITBIT32;
+ f1 = addr[0];
+ f2 = addr[1];
+ *out++ = f1 + frac * (f2 - f1);
+#endif
+ return (w+5);
+}
+
+static void sigfade_dsp(t_sigfade *x, t_signal **sp)
+{
+ dsp_add(sigfade_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n);
+}
+
+static void sigfade_maketable(void)
+{
+ int i;
+ float *fp, phase, fff,phsinc = 0.5*3.141592653 / ((float)COSTABSIZE*0.99999);
+ union tabfudge tf;
+
+ if(!iem_fade_table_sin)
+ {
+ iem_fade_table_sin = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+ for(i=COSTABSIZE+1, fp=iem_fade_table_sin, phase=0; i--; fp++, phase+=phsinc)
+ *fp = sin(phase);
+ }
+ if(!iem_fade_table_sinhann)
+ {
+ iem_fade_table_sinhann = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+ for(i=COSTABSIZE+1, fp=iem_fade_table_sinhann, phase=0; i--; fp++, phase+=phsinc)
+ {
+ fff = sin(phase);
+ *fp = fff*sqrt(fff);
+ }
+ }
+ if(!iem_fade_table_hann)
+ {
+ iem_fade_table_hann = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+ for(i=COSTABSIZE+1, fp=iem_fade_table_hann, phase=0; i--; fp++, phase+=phsinc)
+ {
+ fff = sin(phase);
+ *fp = fff*fff;
+ }
+ }
+ phsinc = 1.0 / ((float)COSTABSIZE*0.99999);
+ if(!iem_fade_table_lin)
+ {
+ iem_fade_table_lin = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+ for(i=COSTABSIZE+1, fp=iem_fade_table_lin, phase=0; i--; fp++, phase+=phsinc)
+ *fp = phase;
+ }
+ if(!iem_fade_table_linsqrt)
+ {
+ iem_fade_table_linsqrt = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+ for(i=COSTABSIZE+1, fp=iem_fade_table_linsqrt, phase=0; i--; fp++, phase+=phsinc)
+ *fp = pow(phase, 0.75);
+ }
+ if(!iem_fade_table_sqrt)
+ {
+ iem_fade_table_sqrt = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+ for(i=COSTABSIZE+1, fp=iem_fade_table_sqrt, phase=0; i--; fp++, phase+=phsinc)
+ *fp = sqrt(phase);
+ }
+ tf.tf_d = UNITBIT32 + 0.5;
+ if((unsigned)tf.tf_i[LOWOFFSET] != 0x80000000)
+ bug("fade~: unexpected machine alignment");
+}
+
+void sigfade_setup(void)
+{
+ sigfade_class = class_new(gensym("fade~"), (t_newmethod)sigfade_new, 0,
+ sizeof(t_sigfade), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(sigfade_class, t_sigfade, x_f);
+ class_addmethod(sigfade_class, (t_method)sigfade_dsp, gensym("dsp"), 0);
+ class_addmethod(sigfade_class, (t_method)sigfade_set, gensym("set"), A_DEFSYM, 0);
+ class_sethelpsymbol(sigfade_class, gensym("iemhelp/help-fade~"));
+ sigfade_maketable();
+}
+
diff --git a/src/iemlib2/sigiem_blocksize.c b/src/iemlib2/sigiem_blocksize.c
new file mode 100644
index 0000000..1f8d016
--- /dev/null
+++ b/src/iemlib2/sigiem_blocksize.c
@@ -0,0 +1,61 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+
+/* ------------------------ iem_blocksize~ ----------------------------- */
+
+static t_class *sigiem_blocksize_class;
+
+typedef struct _sigiem_blocksize
+{
+ t_object x_obj;
+ t_float x_blocksize;
+ t_clock *x_clock;
+ t_float x_f;
+} t_sigiem_blocksize;
+
+static void sigiem_blocksize_out(t_sigiem_blocksize *x)
+{
+ outlet_float(x->x_obj.ob_outlet, x->x_blocksize);
+}
+
+static void sigiem_blocksize_free(t_sigiem_blocksize *x)
+{
+ clock_free(x->x_clock);
+}
+
+static void *sigiem_blocksize_new(t_symbol *s)
+{
+ t_sigiem_blocksize *x = (t_sigiem_blocksize *)pd_new(sigiem_blocksize_class);
+ x->x_clock = clock_new(x, (t_method)sigiem_blocksize_out);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_blocksize = 64.0f;
+ x->x_f = 0.0f;
+ return (x);
+}
+
+static void sigiem_blocksize_dsp(t_sigiem_blocksize *x, t_signal **sp)
+{
+ x->x_blocksize = (t_float)(sp[0]->s_n);
+ clock_delay(x->x_clock, 0.0f);
+}
+
+void sigiem_blocksize_setup(void)
+{
+ sigiem_blocksize_class = class_new(gensym("iem_blocksize~"), (t_newmethod)sigiem_blocksize_new,
+ (t_method)sigiem_blocksize_free, sizeof(t_sigiem_blocksize), 0, 0);
+ CLASS_MAINSIGNALIN(sigiem_blocksize_class, t_sigiem_blocksize, x_f);
+ class_addmethod(sigiem_blocksize_class, (t_method)sigiem_blocksize_dsp, gensym("dsp"), 0);
+}
+
diff --git a/src/iemlib2/sigiem_samplerate.c b/src/iemlib2/sigiem_samplerate.c
new file mode 100644
index 0000000..fee7f5c
--- /dev/null
+++ b/src/iemlib2/sigiem_samplerate.c
@@ -0,0 +1,61 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+
+/* ------------------------ iem_samplerate~ ----------------------------- */
+
+static t_class *sigiem_samplerate_class;
+
+typedef struct _sigiem_samplerate
+{
+ t_object x_obj;
+ t_float x_samplerate;
+ t_clock *x_clock;
+ t_float x_f;
+} t_sigiem_samplerate;
+
+static void sigiem_samplerate_out(t_sigiem_samplerate *x)
+{
+ outlet_float(x->x_obj.ob_outlet, x->x_samplerate);
+}
+
+static void sigiem_samplerate_free(t_sigiem_samplerate *x)
+{
+ clock_free(x->x_clock);
+}
+
+static void *sigiem_samplerate_new(t_symbol *s)
+{
+ t_sigiem_samplerate *x = (t_sigiem_samplerate *)pd_new(sigiem_samplerate_class);
+ x->x_clock = clock_new(x, (t_method)sigiem_samplerate_out);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_samplerate = 44100.0f;
+ x->x_f = 0.0f;
+ return (x);
+}
+
+static void sigiem_samplerate_dsp(t_sigiem_samplerate *x, t_signal **sp)
+{
+ x->x_samplerate = (t_float)(sp[0]->s_sr);
+ clock_delay(x->x_clock, 0.0f);
+}
+
+void sigiem_samplerate_setup(void)
+{
+ sigiem_samplerate_class = class_new(gensym("iem_samplerate~"), (t_newmethod)sigiem_samplerate_new,
+ (t_method)sigiem_samplerate_free, sizeof(t_sigiem_samplerate), 0, 0);
+ CLASS_MAINSIGNALIN(sigiem_samplerate_class, t_sigiem_samplerate, x_f);
+ class_addmethod(sigiem_samplerate_class, (t_method)sigiem_samplerate_dsp, gensym("dsp"), 0);
+}
+
diff --git a/src/iemlib2/sigm2f.c b/src/iemlib2/sigm2f.c
new file mode 100644
index 0000000..f623905
--- /dev/null
+++ b/src/iemlib2/sigm2f.c
@@ -0,0 +1,127 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ m2f~ ----------------------------- */
+
+#define M2FTABSIZE 2048
+
+float *iem_m2f_table=(float *)0L;
+
+static t_class *sigm2f_class;
+
+typedef struct _sigm2f
+{
+ t_object x_obj;
+ float x_msi;
+} t_sigm2f;
+
+static void *sigm2f_new(void)
+{
+ t_sigm2f *x = (t_sigm2f *)pd_new(sigm2f_class);
+ outlet_new(&x->x_obj, gensym("signal"));
+ x->x_msi = 0;
+ return (x);
+}
+
+static t_int *sigm2f_perform(t_int *w)
+{
+ t_float *in = (t_float *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_sigm2f *x = (t_sigm2f *)(w[3]);
+ int n = (int)(w[4]);
+ float *tab = iem_m2f_table, *addr, f1, f2, frac, iinn;
+ double dphase;
+ int normhipart;
+ union tabfudge tf;
+
+ tf.tf_d = UNITBIT32;
+ normhipart = tf.tf_i[HIOFFSET];
+
+#if 0 /* this is the readable version of the code. */
+ while (n--)
+ {
+ iinn = (*in++)*10.0+670.0;
+ dphase = (double)iinn + UNITBIT32;
+ tf.tf_d = dphase;
+ addr = tab + (tf.tf_i[HIOFFSET] & (M2FTABSIZE-1));
+ tf.tf_i[HIOFFSET] = normhipart;
+ frac = tf.tf_d - UNITBIT32;
+ f1 = addr[0];
+ f2 = addr[1];
+ *out++ = f1 + frac * (f2 - f1);
+ }
+#endif
+#if 1 /* this is the same, unwrapped by hand. */
+ iinn = (*in++)*10.0+670.0;
+ dphase = (double)iinn + UNITBIT32;
+ tf.tf_d = dphase;
+ addr = tab + (tf.tf_i[HIOFFSET] & (M2FTABSIZE-1));
+ tf.tf_i[HIOFFSET] = normhipart;
+ while (--n)
+ {
+ iinn = (*in++)*10.0+670.0;
+ dphase = (double)iinn + UNITBIT32;
+ frac = tf.tf_d - UNITBIT32;
+ tf.tf_d = dphase;
+ f1 = addr[0];
+ f2 = addr[1];
+ addr = tab + (tf.tf_i[HIOFFSET] & (M2FTABSIZE-1));
+ *out++ = f1 + frac * (f2 - f1);
+ tf.tf_i[HIOFFSET] = normhipart;
+ }
+ frac = tf.tf_d - UNITBIT32;
+ f1 = addr[0];
+ f2 = addr[1];
+ *out++ = f1 + frac * (f2 - f1);
+#endif
+ return (w+5);
+}
+
+static void sigm2f_dsp(t_sigm2f *x, t_signal **sp)
+{
+ dsp_add(sigm2f_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n);
+}
+
+static void sigm2f_maketable(void)
+{
+ union tabfudge tf;
+
+ if(!iem_m2f_table)
+ {
+ int i;
+ float *fp, midi, refexp=440.0*exp(-5.75*log(2.0));
+
+ iem_m2f_table = (float *)getbytes(sizeof(float) * (M2FTABSIZE+1));
+ for(i=0, fp=iem_m2f_table, midi=-67.0; i<=M2FTABSIZE; i++, fp++, midi+=0.1)
+ *fp = refexp * exp(0.057762265047 * midi);
+ }
+ tf.tf_d = UNITBIT32 + 0.5;
+ if((unsigned)tf.tf_i[LOWOFFSET] != 0x80000000)
+ bug("m2f~: unexpected machine alignment");
+}
+
+void sigm2f_setup(void)
+{
+ sigm2f_class = class_new(gensym("m2f~"), (t_newmethod)sigm2f_new, 0,
+ sizeof(t_sigm2f), 0, 0);
+ CLASS_MAINSIGNALIN(sigm2f_class, t_sigm2f, x_msi);
+ class_addmethod(sigm2f_class, (t_method)sigm2f_dsp, gensym("dsp"), 0);
+ sigm2f_maketable();
+ class_sethelpsymbol(sigm2f_class, gensym("iemhelp/help-m2f~"));
+}
+
diff --git a/src/iemlib2/speedlim.c b/src/iemlib2/speedlim.c
new file mode 100644
index 0000000..023835a
--- /dev/null
+++ b/src/iemlib2/speedlim.c
@@ -0,0 +1,107 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ speedlim ---------------------------- */
+static t_class *speedlim_class;
+
+typedef struct _speedlim
+{
+ t_object x_obj;
+ t_clock *x_clock;
+ float x_delay;
+ int x_output_is_locked;
+ int x_there_was_n_event;
+ float x_curval;
+ float x_lastout;
+} t_speedlim;
+
+static void speedlim_stop(t_speedlim *x)
+{
+ x->x_output_is_locked = 0;
+ x->x_there_was_n_event = 0;
+ clock_unset(x->x_clock);
+}
+
+static void speedlim_tick(t_speedlim *x)
+{
+ if(x->x_there_was_n_event)
+ {
+ x->x_output_is_locked = 1;
+ x->x_there_was_n_event = 0;
+ outlet_float(x->x_obj.ob_outlet, x->x_curval);
+ clock_delay(x->x_clock, x->x_delay);
+ }
+ else
+ {
+ x->x_output_is_locked = 0;
+ x->x_there_was_n_event = 0;
+ }
+}
+
+static void speedlim_float(t_speedlim *x, t_float val)
+{
+ x->x_curval = val;
+ if(!x->x_output_is_locked)
+ {
+ x->x_output_is_locked = 1;
+ x->x_there_was_n_event = 0;
+ outlet_float(x->x_obj.ob_outlet, x->x_curval);
+ clock_delay(x->x_clock, x->x_delay);
+ }
+ else
+ x->x_there_was_n_event = 1;
+}
+
+static void speedlim_ft1(t_speedlim *x, t_float delay)
+{
+ if(delay < 0.0)
+ delay = 0.0;
+ x->x_delay = delay;
+}
+
+static void speedlim_free(t_speedlim *x)
+{
+ clock_free(x->x_clock);
+}
+
+static void *speedlim_new(t_float delay)
+{
+ t_speedlim *x = (t_speedlim *)pd_new(speedlim_class);
+
+ if(delay < 0.0)
+ delay = 0.0;
+ x->x_delay = delay;
+ x->x_curval = 0.0f;
+ x->x_output_is_locked = 0;
+ x->x_there_was_n_event = 0;
+ x->x_clock = clock_new(x, (t_method)speedlim_tick);
+ outlet_new(&x->x_obj, &s_float);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ return (x);
+}
+
+void speedlim_setup(void)
+{
+ speedlim_class = class_new(gensym("speedlim"), (t_newmethod)speedlim_new,
+ (t_method)speedlim_free, sizeof(t_speedlim), 0, A_DEFFLOAT, 0);
+ class_addmethod(speedlim_class, (t_method)speedlim_stop, gensym("stop"), 0);
+ class_addfloat(speedlim_class, (t_method)speedlim_float);
+ class_addmethod(speedlim_class, (t_method)speedlim_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_sethelpsymbol(speedlim_class, gensym("iemhelp/help-speedlim"));
+}
+
diff --git a/src/iemlib2/splitfilename.c b/src/iemlib2/splitfilename.c
new file mode 100644
index 0000000..485b214
--- /dev/null
+++ b/src/iemlib2/splitfilename.c
@@ -0,0 +1,142 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* -------------------------- splitfilename ------------------------------ */
+
+static t_class *splitfilename_class;
+
+typedef struct _splitfilename
+{
+ t_object x_obj;
+ char x_sep[2];
+ void *x_outpath;
+ void *x_outfile;
+} t_splitfilename;
+
+static void splitfilename_separator(t_splitfilename *x, t_symbol *s, int ac, t_atom *av)
+{
+ if(ac > 0)
+ {
+ if(IS_A_SYMBOL(av, 0))
+ {
+ if(strlen(av->a_w.w_symbol->s_name) == 1)
+ x->x_sep[0] = av->a_w.w_symbol->s_name[0];
+ else if(!strcmp(av->a_w.w_symbol->s_name, "backslash"))
+ x->x_sep[0] = '\\';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "slash"))
+ x->x_sep[0] = '/';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "blank"))
+ x->x_sep[0] = ' ';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "space"))
+ x->x_sep[0] = ' ';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "dollar"))
+ x->x_sep[0] = '$';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "comma"))
+ x->x_sep[0] = ',';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "semi"))
+ x->x_sep[0] = ';';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "leftbrace"))
+ x->x_sep[0] = '{';
+ else if(!strcmp(av->a_w.w_symbol->s_name, "rightbrace"))
+ x->x_sep[0] = '}';
+ else
+ x->x_sep[0] = '/';
+ }
+ else if(IS_A_FLOAT(av, 0))
+ {
+ int i;
+ float f=fabs(av->a_w.w_float);
+
+ while(f >= 10.0)
+ f *= 0.1;
+ i = (int)f;
+ x->x_sep[0] = (char)i + '0';
+ }
+ }
+ else
+ x->x_sep[0] = 0;
+}
+
+static void splitfilename_symbol(t_splitfilename *x, t_symbol *s)
+{
+ int len = strlen(s->s_name);
+
+ if(len)
+ {
+ if(x->x_sep[0] != 0)
+ {
+ char *str_path = (char *)getbytes(len*sizeof(char));
+ char *str_file = (char *)getbytes(len*sizeof(char));
+ char *cpp, *cpf;
+
+ strcpy(str_path, s->s_name);
+ strcpy(str_file, s->s_name);
+ cpp = strrchr(str_path, x->x_sep[0]);
+ cpf = strrchr(str_file, x->x_sep[0]);
+ if(((int)cpp - (int)str_path) < 0)
+ {
+ outlet_symbol(x->x_outfile, gensym(str_file));
+ outlet_symbol(x->x_outpath, &s_);
+ }
+ else if(((int)cpp - (int)str_path) >= len)
+ {
+ outlet_symbol(x->x_outfile, &s_);
+ outlet_symbol(x->x_outpath, gensym(str_path));
+ }
+ else
+ {
+ *cpp = 0;
+ cpf++;
+ outlet_symbol(x->x_outfile, gensym(cpf));
+ outlet_symbol(x->x_outpath, gensym(str_path));
+ }
+ freebytes(str_file, len*sizeof(char));
+ freebytes(str_path, len*sizeof(char));
+ }
+ else
+ {
+ outlet_symbol(x->x_outfile, &s_);
+ outlet_symbol(x->x_outpath, s);
+ }
+ }
+}
+
+static void *splitfilename_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_splitfilename *x = (t_splitfilename *)pd_new(splitfilename_class);
+
+ x->x_sep[0] = 0;
+ x->x_sep[1] = 0;
+ if(ac == 0)
+ x->x_sep[0] = '/';
+ else
+ splitfilename_separator(x, s, ac, av);
+ x->x_outpath = outlet_new(&x->x_obj, &s_symbol);
+ x->x_outfile = outlet_new(&x->x_obj, &s_symbol);
+ return (x);
+}
+
+void splitfilename_setup(void)
+{
+ splitfilename_class = class_new(gensym("splitfilename"), (t_newmethod)splitfilename_new,
+ 0, sizeof(t_splitfilename), 0, A_GIMME, 0);
+ class_addsymbol(splitfilename_class, splitfilename_symbol);
+ class_addmethod(splitfilename_class, (t_method)splitfilename_separator, gensym("separator"), A_GIMME, 0);
+ class_addmethod(splitfilename_class, (t_method)splitfilename_separator, gensym("sep"), A_GIMME, 0);
+ class_sethelpsymbol(splitfilename_class, gensym("iemhelp/help-splitfilename"));
+}
diff --git a/src/iemlib2/stripfilename.c b/src/iemlib2/stripfilename.c
new file mode 100644
index 0000000..d229086
--- /dev/null
+++ b/src/iemlib2/stripfilename.c
@@ -0,0 +1,81 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* -------------------------- stripfilename ------------------------------ */
+
+static t_class *stripfilename_class;
+
+typedef struct _stripfilename
+{
+ t_object x_obj;
+ int x_nr_char;
+} t_stripfilename;
+
+static void stripfilename_symbol(t_stripfilename *x, t_symbol *s)
+{
+ if(x->x_nr_char < 0)
+ {
+ int len = strlen(s->s_name);
+ char *str=(char *)getbytes((len+2)*sizeof(char));
+ int i=len + x->x_nr_char;
+
+ strcpy(str, s->s_name);
+ if(i < 0)
+ i = 0;
+ str[i] = 0;
+ outlet_symbol(x->x_obj.ob_outlet, gensym(str));
+ freebytes(str, (len+2)*sizeof(char));
+ }
+ else if(x->x_nr_char > 0)
+ {
+ int len = strlen(s->s_name);
+ char *str=(char *)getbytes((len+2)*sizeof(char));
+ int i=x->x_nr_char;
+
+ strcpy(str, s->s_name);
+ if(i > len)
+ i = len;
+ outlet_symbol(x->x_obj.ob_outlet, gensym(str+i));
+ freebytes(str, (len+2)*sizeof(char));
+ }
+ else
+ outlet_symbol(x->x_obj.ob_outlet, s);
+}
+
+static void stripfilename_set(t_stripfilename *x, t_floatarg nr_char)
+{
+ x->x_nr_char = (int)nr_char;
+}
+
+static void *stripfilename_new(t_floatarg nr_char)
+{
+ t_stripfilename *x = (t_stripfilename *)pd_new(stripfilename_class);
+
+ stripfilename_set(x, nr_char);
+ outlet_new(&x->x_obj, &s_symbol);
+ return (x);
+}
+
+void stripfilename_setup(void)
+{
+ stripfilename_class = class_new(gensym("stripfilename"), (t_newmethod)stripfilename_new,
+ 0, sizeof(t_stripfilename), 0, A_DEFFLOAT, 0);
+ class_addsymbol(stripfilename_class, stripfilename_symbol);
+ class_addmethod(stripfilename_class, (t_method)stripfilename_set, gensym("set"), A_FLOAT, 0);
+ class_sethelpsymbol(stripfilename_class, gensym("iemhelp/help-stripfilename"));
+}
diff --git a/src/iemlib2/toggle_mess.c b/src/iemlib2/toggle_mess.c
new file mode 100644
index 0000000..b8cb569
--- /dev/null
+++ b/src/iemlib2/toggle_mess.c
@@ -0,0 +1,119 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ------------------------ toggle_mess ---------------------------- */
+static t_class *toggle_mess_class;
+
+typedef struct _toggle_mess
+{
+ t_object x_obj;
+ int x_index;
+ int x_ac;
+ t_atom *x_at;
+ void *x_out_mid_sym;
+ void *x_out_rght_flt;
+ t_symbol *x_set;
+} t_toggle_mess;
+
+static void toggle_mess_bang(t_toggle_mess *x)
+{
+ int i = x->x_index;
+
+ outlet_float(x->x_out_rght_flt, (float)i);
+ if(IS_A_FLOAT(x->x_at, i))
+ outlet_float(x->x_out_mid_sym, atom_getfloat(&x->x_at[i]));
+ else
+ outlet_anything(x->x_out_mid_sym, atom_getsymbol(&x->x_at[i]), 0, x->x_at);
+ outlet_anything(x->x_obj.ob_outlet, x->x_set, 1, &x->x_at[i]);
+}
+
+static void toggle_mess_float(t_toggle_mess *x, t_float f)
+{
+ x->x_index++;
+ if(x->x_index >= x->x_ac)
+ x->x_index = 0;
+ toggle_mess_bang(x);
+}
+
+static void toggle_mess_set(t_toggle_mess *x, t_symbol *s, int ac, t_atom *av)
+{
+ if((ac >= 1) && (IS_A_FLOAT(av, 0)))
+ {
+ int x_index = (int)atom_getint(av);
+
+ if(x_index < 0)
+ x_index = 0;
+ else if(x_index >= x->x_ac)
+ x_index = x->x_ac;
+ x->x_index = x_index;
+ outlet_anything(x->x_obj.ob_outlet, x->x_set, 1, &x->x_at[x_index]);
+ }
+ else
+ toggle_mess_float(x, 0);
+}
+
+static void toggle_mess_symbol(t_toggle_mess *x, t_symbol *s)
+{
+ toggle_mess_float(x, 0);
+}
+
+static void toggle_mess_anything(t_toggle_mess *x, t_symbol *s, int ac, t_atom *av)
+{
+ toggle_mess_float(x, 0);
+}
+
+static void toggle_mess_free(t_toggle_mess *x)
+{
+ freebytes(x->x_at, x->x_ac * sizeof(t_atom));
+}
+
+static void *toggle_mess_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_toggle_mess *x = (t_toggle_mess *)pd_new(toggle_mess_class);
+ int i;
+
+ if(!ac)
+ {
+ post("toggle_mess-ERROR: must have at least one argument!");
+ x->x_at = (t_atom *)0;
+ return(0);
+ }
+ x->x_ac = ac;
+ x->x_at = (t_atom *)getbytes(ac * sizeof(t_atom));
+ for(i=0; i<ac; i++)
+ x->x_at[i] = *av++;
+ x->x_index = 0;
+ x->x_set = gensym("set");
+ outlet_new(&x->x_obj, &s_list);
+ x->x_out_mid_sym = outlet_new(&x->x_obj, &s_list);
+ x->x_out_rght_flt = outlet_new(&x->x_obj, &s_float);
+ return(x);
+}
+
+void toggle_mess_setup(void)
+{
+ toggle_mess_class = class_new(gensym("toggle_mess"), (t_newmethod)toggle_mess_new,
+ (t_method)toggle_mess_free, sizeof(t_toggle_mess), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)toggle_mess_new, gensym("tm"), A_GIMME, 0);
+ class_addbang(toggle_mess_class, (t_method)toggle_mess_bang);
+ class_addmethod(toggle_mess_class, (t_method)toggle_mess_set, gensym("set"), A_GIMME, 0);
+ class_addfloat(toggle_mess_class, (t_method)toggle_mess_float);
+ class_addsymbol(toggle_mess_class, toggle_mess_symbol);
+ class_addanything(toggle_mess_class, toggle_mess_anything);
+ class_sethelpsymbol(toggle_mess_class, gensym("iemhelp/help-toggle_mess"));
+}
diff --git a/src/iemlib2/transf_fader.c b/src/iemlib2/transf_fader.c
new file mode 100644
index 0000000..e2988d6
--- /dev/null
+++ b/src/iemlib2/transf_fader.c
@@ -0,0 +1,153 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- transf_fader ------------------------------ */
+
+typedef struct _transf_fader
+{
+ t_object x_obj;
+ int x_size;
+ int x_message;
+ float *x_array;
+} t_transf_fader;
+
+static t_class *transf_fader_class;
+
+static void transf_fader_pairs(t_transf_fader *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if(argc >= 4)
+ {
+ int i, j, k, ac=argc/2;
+ int n=1000;
+ int i_prev=0;
+ int first=1;
+ int i_delta;
+ float val_delta;
+ float delta;
+ float val_prev=0.0f;
+ float val=0.0f;
+ float *vec=x->x_array;
+ float fad_in, fad_out;
+
+ for(j=0; j<n; j++)
+ {
+ vec[j] = -123456.0f;
+ }
+
+ for(j=0; j<ac; j++)
+ {
+ fad_in = atom_getfloat(argv++);
+ while(fad_in < 0.0f)
+ fad_in = 0.0f;
+ while(fad_in > 1000.0f)
+ fad_in = 1000.0f;
+
+ fad_out = atom_getfloat(argv++);
+ while(fad_out < -123455.0f)
+ fad_out = -123455.0f;
+
+ i = (int)fad_in;
+ vec[i] = fad_out;
+ }
+
+ for(j=0; j<n; j++)
+ {
+ if(vec[j] > -123456.0f)
+ {
+ if(first)
+ {
+ first = 0;
+ i_prev = j;
+ val_prev = vec[j];
+ }
+ else
+ {
+ i = j;
+ val = vec[j];
+ i_delta = i - i_prev;
+ val_delta = val - val_prev;
+ if(i_delta > 1)
+ {
+ delta = val_delta / (float)i_delta;
+ for(k=i_prev+1; k<i; k++)
+ {
+ vec[k] = val_prev + delta*(float)(k - i_prev);
+ }
+ }
+ i_prev = i;
+ val_prev = val;
+ }
+ }
+ }
+ }
+ else
+ {
+ if(x->x_message)
+ post("transf_fader-ERROR: less than 2 pairs make no sense");
+ }
+}
+
+static void transf_fader_float(t_transf_fader *x, t_floatarg fad_in)
+{
+ float fad_out;
+ float *vec=x->x_array;
+ float fract;
+ int i;
+
+ while(fad_in < 0.0f)
+ fad_in = 0.0f;
+ while(fad_in > 999.0f)
+ fad_in = 999.0f;
+
+ i = (int)fad_in;
+ fract = fad_in - (float)i;
+ fad_out = vec[i] + fract*(vec[i+1] - vec[i]);
+ if(fad_out > -123455.0f)
+ outlet_float(x->x_obj.ob_outlet, fad_out);
+}
+
+static void transf_fader_free(t_transf_fader *x)
+{
+ freebytes(x->x_array, x->x_size * sizeof(float));
+}
+
+static void *transf_fader_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_transf_fader *x = (t_transf_fader *)pd_new(transf_fader_class);
+ int i, n;
+
+ x->x_size = 1001;
+ x->x_message = 0;
+ x->x_array = (float *)getbytes(x->x_size * sizeof(float));
+ n = x->x_size;
+ for(i=0; i<n; i++)
+ x->x_array[i] = -123456.0f;
+ transf_fader_pairs(x, gensym("pairs"), argc, argv);
+ x->x_message = 1;
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+void transf_fader_setup(void)
+{
+ transf_fader_class = class_new(gensym("transf_fader"), (t_newmethod)transf_fader_new, (t_method)transf_fader_free,
+ sizeof(t_transf_fader), 0, A_GIMME, 0);
+ class_addfloat(transf_fader_class, (t_method)transf_fader_float);
+ class_addmethod(transf_fader_class, (t_method)transf_fader_pairs, gensym("pairs"), A_GIMME, 0);
+ class_sethelpsymbol(transf_fader_class, gensym("iemhelp/help-transf_fader"));
+}
diff --git a/src/iemlib2/unsymbol.c b/src/iemlib2/unsymbol.c
new file mode 100644
index 0000000..b617836
--- /dev/null
+++ b/src/iemlib2/unsymbol.c
@@ -0,0 +1,49 @@
+/* Copyright (c) 1997-2003 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* -------------------------- unsymbol ------------------------------ */
+
+static t_class *unsymbol_class;
+
+typedef struct _unsymbol
+{
+ t_object x_obj;
+ t_atom x_at;
+} t_unsymbol;
+
+static void unsymbol_symbol(t_unsymbol *x, t_symbol *s)
+{
+ outlet_anything(x->x_obj.ob_outlet, s, 0, &(x->x_at));
+}
+
+static void *unsymbol_new(void)
+{
+ t_unsymbol *x = (t_unsymbol *)pd_new(unsymbol_class);
+
+ outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+void unsymbol_setup(void)
+{
+ unsymbol_class = class_new(gensym("unsymbol"), (t_newmethod)unsymbol_new,
+ 0, sizeof(t_unsymbol), 0, 0);
+ class_addcreator((t_newmethod)unsymbol_new, gensym("unsym"), 0);
+ class_addsymbol(unsymbol_class, unsymbol_symbol);
+ class_sethelpsymbol(unsymbol_class, gensym("iemhelp/help-unsymbol"));
+}
diff --git a/src/iemlib2/wrap.c b/src/iemlib2/wrap.c
new file mode 100644
index 0000000..b594998
--- /dev/null
+++ b/src/iemlib2/wrap.c
@@ -0,0 +1,69 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* ---- wrap - float=int or list of float=symbol concaternat to int=float ----- */
+
+
+
+typedef struct _wrap
+{
+ t_object x_obj;
+ float x_f;
+} t_wrap;
+
+static t_class *wrap_class;
+
+static void wrap_bang(t_wrap *x)
+{
+ outlet_float(x->x_obj.ob_outlet, x->x_f);
+}
+
+static void wrap_float(t_wrap *x, t_float f)
+{
+ int i=(int)f;
+
+ if(f > 0.0)
+ x->x_f = f - (float)i;
+ else
+ x->x_f = f - (float)(i - 1);
+ wrap_bang(x);
+}
+
+static void wrap_list(t_wrap *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if((argc > 0) && (IS_A_FLOAT(argv, 0)))
+ wrap_float(x, atom_getfloat(argv));
+}
+
+static void *wrap_new(void)
+{
+ t_wrap *x = (t_wrap *)pd_new(wrap_class);
+
+ outlet_new(&x->x_obj, &s_float);
+ x->x_f = 0.0;
+ return (x);
+}
+
+void wrap_setup(void)
+{
+ wrap_class = class_new(gensym("wrap"), (t_newmethod)wrap_new, 0,
+ sizeof(t_wrap), 0, 0);
+ class_addbang(wrap_class, (t_method)wrap_bang);
+ class_addfloat(wrap_class, (t_method)wrap_float);
+ class_addlist(wrap_class, (t_method)wrap_list);
+ class_sethelpsymbol(wrap_class, gensym("iemhelp/help-wrap"));
+}