aboutsummaryrefslogtreecommitdiff
path: root/sc4pd
diff options
context:
space:
mode:
authorIOhannes m zmölnig <zmoelnig@iem.at>2015-10-14 15:14:38 +0200
committerIOhannes m zmölnig <zmoelnig@iem.at>2015-10-14 15:14:38 +0200
commit28b7e464fd119b8c848753a1f41070422c463c41 (patch)
tree07449abdf85d8f1fd4068839b974242b429720ca /sc4pd
parent90c6018a9401e38859f733b3521c919e042322b7 (diff)
parent6932ee2d22511226378218992b0005cb01eb235e (diff)
- abstractions/tb - externals/tb
Diffstat (limited to 'sc4pd')
-rw-r--r--sc4pd/build-max-msvc.bat4
-rw-r--r--sc4pd/build-pd-bcc.bat3
-rw-r--r--sc4pd/build-pd-cygwin.sh15
-rwxr-xr-xsc4pd/build-pd-darwin.sh17
-rwxr-xr-xsc4pd/build-pd-linux.sh17
-rw-r--r--sc4pd/build-pd-mingw.bat3
-rw-r--r--sc4pd/build-pd-msvc.bat4
-rw-r--r--sc4pd/config-max-msvc.txt27
-rw-r--r--sc4pd/config-pd-bcc.txt23
-rw-r--r--sc4pd/config-pd-cygwin.txt35
-rw-r--r--sc4pd/config-pd-darwin.txt35
-rw-r--r--sc4pd/config-pd-linux.txt36
-rw-r--r--sc4pd/config-pd-mingw.txt35
-rw-r--r--sc4pd/config-pd-msvc.txt19
-rw-r--r--sc4pd/gpl.txt346
-rw-r--r--sc4pd/headers/app/AIAttributedStringAdditions.h39
-rw-r--r--sc4pd/headers/app/AIColorAdditions.h39
-rw-r--r--sc4pd/headers/app/AIHTMLDecoder.h28
-rw-r--r--sc4pd/headers/app/AIStringAdditions.h25
-rw-r--r--sc4pd/headers/app/AITextAttributes.h44
-rw-r--r--sc4pd/headers/app/ChangeCounter.h30
-rw-r--r--sc4pd/headers/app/ControlSpec.h36
-rw-r--r--sc4pd/headers/app/DrawBackground.h83
-rw-r--r--sc4pd/headers/app/GetStringFromUser.h46
-rw-r--r--sc4pd/headers/app/GoToPanel.h52
-rw-r--r--sc4pd/headers/app/MyDocument.h107
-rw-r--r--sc4pd/headers/app/RendezvousClient.h39
-rw-r--r--sc4pd/headers/app/SCDialog.h41
-rw-r--r--sc4pd/headers/app/SCGeom.h90
-rw-r--r--sc4pd/headers/app/SCGraphView.h55
-rw-r--r--sc4pd/headers/app/SCService.h16
-rw-r--r--sc4pd/headers/app/SCTextView.h33
-rw-r--r--sc4pd/headers/app/SCView.h784
-rw-r--r--sc4pd/headers/app/SCVirtualMachine.h65
-rw-r--r--sc4pd/headers/app/TabletEvents.h75
-rw-r--r--sc4pd/headers/app/TextFinder.h64
-rw-r--r--sc4pd/headers/app/UserPanel.h40
-rw-r--r--sc4pd/headers/common/SC_AllocPool.h278
-rw-r--r--sc4pd/headers/common/SC_Altivec.h118
-rw-r--r--sc4pd/headers/common/SC_Endian.h64
-rw-r--r--sc4pd/headers/common/SC_Sem.h43
-rw-r--r--sc4pd/headers/common/SC_StringBuffer.h67
-rw-r--r--sc4pd/headers/common/SC_StringParser.h40
-rw-r--r--sc4pd/headers/common/dfftlib.h62
-rw-r--r--sc4pd/headers/common/fftlib.h62
-rw-r--r--sc4pd/headers/common/scsynthsend.h191
-rw-r--r--sc4pd/headers/lang/AdvancingAllocPool.h82
-rw-r--r--sc4pd/headers/lang/AllocPools.h34
-rw-r--r--sc4pd/headers/lang/ByteCodeArray.h50
-rw-r--r--sc4pd/headers/lang/FIFOT.h75
-rw-r--r--sc4pd/headers/lang/GC.h263
-rw-r--r--sc4pd/headers/lang/HashTable.h274
-rw-r--r--sc4pd/headers/lang/InitAlloc.h32
-rw-r--r--sc4pd/headers/lang/MiscInlineMath.h54
-rw-r--r--sc4pd/headers/lang/OSCData.h1
-rw-r--r--sc4pd/headers/lang/Opcodes.h426
-rw-r--r--sc4pd/headers/lang/PowerOfTwoAllocPool.h154
-rw-r--r--sc4pd/headers/lang/PredefinedSymbols.h29
-rw-r--r--sc4pd/headers/lang/PriorityQueue.h90
-rw-r--r--sc4pd/headers/lang/PyrArchiverT.h619
-rw-r--r--sc4pd/headers/lang/PyrDeepCopier.h221
-rw-r--r--sc4pd/headers/lang/PyrDeepFreezer.h178
-rw-r--r--sc4pd/headers/lang/PyrErrors.h49
-rw-r--r--sc4pd/headers/lang/PyrFilePrim.h62
-rw-r--r--sc4pd/headers/lang/PyrFileUtils.h50
-rw-r--r--sc4pd/headers/lang/PyrInterpreter.h47
-rw-r--r--sc4pd/headers/lang/PyrKernel.h256
-rw-r--r--sc4pd/headers/lang/PyrKernelProto.h62
-rw-r--r--sc4pd/headers/lang/PyrLexer.h136
-rw-r--r--sc4pd/headers/lang/PyrListPrim.h34
-rw-r--r--sc4pd/headers/lang/PyrMathPrim.h51
-rw-r--r--sc4pd/headers/lang/PyrMessage.h55
-rw-r--r--sc4pd/headers/lang/PyrObject.h288
-rw-r--r--sc4pd/headers/lang/PyrObjectProto.h44
-rw-r--r--sc4pd/headers/lang/PyrParseNode.h456
-rw-r--r--sc4pd/headers/lang/PyrPrimitive.h42
-rw-r--r--sc4pd/headers/lang/PyrPrimitiveProto.h81
-rw-r--r--sc4pd/headers/lang/PyrSched.h58
-rw-r--r--sc4pd/headers/lang/PyrSignal.h417
-rw-r--r--sc4pd/headers/lang/PyrSignalPrim.h56
-rw-r--r--sc4pd/headers/lang/PyrSlot.h286
-rw-r--r--sc4pd/headers/lang/PyrSymbol.h59
-rw-r--r--sc4pd/headers/lang/PyrSymbolTable.h78
-rw-r--r--sc4pd/headers/lang/ReadWriteMacros.h336
-rw-r--r--sc4pd/headers/lang/SCBase.h68
-rw-r--r--sc4pd/headers/lang/SC_ComPort.h118
-rw-r--r--sc4pd/headers/lang/SC_LanguageClient.h164
-rw-r--r--sc4pd/headers/lang/SC_LibraryConfig.h108
-rw-r--r--sc4pd/headers/lang/SC_List.h229
-rw-r--r--sc4pd/headers/lang/SC_LogFile.h29
-rw-r--r--sc4pd/headers/lang/SC_Msg.h70
-rw-r--r--sc4pd/headers/lang/SC_SynthImpl.h42
-rw-r--r--sc4pd/headers/lang/SC_TerminalClient.h92
-rw-r--r--sc4pd/headers/lang/SC_UnorderedList.h60
-rw-r--r--sc4pd/headers/lang/SFHeaders.h140
-rw-r--r--sc4pd/headers/lang/Samp.h46
-rw-r--r--sc4pd/headers/lang/SimpleStack.h32
-rw-r--r--sc4pd/headers/lang/VMGlobals.h94
-rw-r--r--sc4pd/headers/lang/bullet.h7
-rw-r--r--sc4pd/headers/lang/libraryConfig.h31
-rw-r--r--sc4pd/headers/lang/readSamples.h1
-rw-r--r--sc4pd/headers/plugin_interface/Hash.h152
-rw-r--r--sc4pd/headers/plugin_interface/SC_BoundsMacros.h29
-rw-r--r--sc4pd/headers/plugin_interface/SC_BufGen.h40
-rw-r--r--sc4pd/headers/plugin_interface/SC_Constants.h46
-rw-r--r--sc4pd/headers/plugin_interface/SC_DemandUnit.h54
-rw-r--r--sc4pd/headers/plugin_interface/SC_Dimension.h31
-rw-r--r--sc4pd/headers/plugin_interface/SC_FifoMsg.h59
-rw-r--r--sc4pd/headers/plugin_interface/SC_Graph.h53
-rw-r--r--sc4pd/headers/plugin_interface/SC_InlineBinaryOp.h574
-rw-r--r--sc4pd/headers/plugin_interface/SC_InlineUnaryOp.h448
-rw-r--r--sc4pd/headers/plugin_interface/SC_InterfaceTable.h175
-rw-r--r--sc4pd/headers/plugin_interface/SC_Node.h48
-rw-r--r--sc4pd/headers/plugin_interface/SC_PlugIn.h53
-rw-r--r--sc4pd/headers/plugin_interface/SC_RGen.h288
-rw-r--r--sc4pd/headers/plugin_interface/SC_Rate.h42
-rw-r--r--sc4pd/headers/plugin_interface/SC_SndBuf.h109
-rw-r--r--sc4pd/headers/plugin_interface/SC_Types.h67
-rw-r--r--sc4pd/headers/plugin_interface/SC_Unit.h101
-rw-r--r--sc4pd/headers/plugin_interface/SC_Wire.h36
-rw-r--r--sc4pd/headers/plugin_interface/SC_World.h105
-rw-r--r--sc4pd/headers/plugin_interface/SC_WorldOptions.h91
-rw-r--r--sc4pd/headers/plugin_interface/Unroll.h249
-rw-r--r--sc4pd/headers/plugin_interface/clz.h195
-rw-r--r--sc4pd/headers/plugin_interface/sc_msg_iter.h264
-rw-r--r--sc4pd/headers/server/HashTable.h356
-rw-r--r--sc4pd/headers/server/IntFifo.h87
-rw-r--r--sc4pd/headers/server/MsgFifo.h169
-rw-r--r--sc4pd/headers/server/OSC_Packet.h43
-rw-r--r--sc4pd/headers/server/PriorityQueue.h123
-rw-r--r--sc4pd/headers/server/ReadWriteMacros.h430
-rw-r--r--sc4pd/headers/server/Rendezvous.h41
-rw-r--r--sc4pd/headers/server/SC_ComPort.h144
-rw-r--r--sc4pd/headers/server/SC_Complex.h142
-rw-r--r--sc4pd/headers/server/SC_CoreAudio.h263
-rw-r--r--sc4pd/headers/server/SC_Errors.h58
-rw-r--r--sc4pd/headers/server/SC_GraphDef.h75
-rw-r--r--sc4pd/headers/server/SC_Group.h34
-rw-r--r--sc4pd/headers/server/SC_HiddenWorld.h113
-rw-r--r--sc4pd/headers/server/SC_Lib.h62
-rw-r--r--sc4pd/headers/server/SC_Lib_Cintf.h124
-rw-r--r--sc4pd/headers/server/SC_List.h229
-rw-r--r--sc4pd/headers/server/SC_Lock.h38
-rw-r--r--sc4pd/headers/server/SC_Prototypes.h213
-rw-r--r--sc4pd/headers/server/SC_Reply.h55
-rw-r--r--sc4pd/headers/server/SC_Samp.h38
-rw-r--r--sc4pd/headers/server/SC_SequencedCommand.h481
-rw-r--r--sc4pd/headers/server/SC_Str4.h103
-rw-r--r--sc4pd/headers/server/SC_SyncCondition.h45
-rw-r--r--sc4pd/headers/server/SC_SynthDef.h43
-rw-r--r--sc4pd/headers/server/SC_UnitDef.h69
-rw-r--r--sc4pd/headers/server/SC_UnitSpec.h41
-rw-r--r--sc4pd/headers/server/SC_WireSpec.h47
-rw-r--r--sc4pd/make-files.txt19
-rw-r--r--sc4pd/makefile.max-msvc77
-rw-r--r--sc4pd/makefile.pd-bcc73
-rw-r--r--sc4pd/makefile.pd-cygwin86
-rwxr-xr-xsc4pd/makefile.pd-darwin77
-rw-r--r--sc4pd/makefile.pd-linux94
-rw-r--r--sc4pd/makefile.pd-mingw85
-rw-r--r--sc4pd/makefile.pd-msvc53
-rw-r--r--sc4pd/package.txt24
-rw-r--r--sc4pd/pd/LinRand.pd4
-rw-r--r--sc4pd/pd/allpassc.pd20
-rw-r--r--sc4pd/pd/allpassl.pd20
-rw-r--r--sc4pd/pd/allpassn.pd20
-rw-r--r--sc4pd/pd/amclip.pd16
-rw-r--r--sc4pd/pd/bpf.pd15
-rw-r--r--sc4pd/pd/bpz2.pd12
-rw-r--r--sc4pd/pd/brf.pd15
-rw-r--r--sc4pd/pd/brz2.pd12
-rw-r--r--sc4pd/pd/clipnoise.pd13
-rw-r--r--sc4pd/pd/combc.pd20
-rw-r--r--sc4pd/pd/combl.pd20
-rw-r--r--sc4pd/pd/combn.pd20
-rw-r--r--sc4pd/pd/crackle.pd10
-rw-r--r--sc4pd/pd/decay.pd12
-rw-r--r--sc4pd/pd/decay2.pd12
-rw-r--r--sc4pd/pd/delayc.pd11
-rw-r--r--sc4pd/pd/delayl.pd11
-rw-r--r--sc4pd/pd/delayn.pd11
-rw-r--r--sc4pd/pd/dust.pd11
-rw-r--r--sc4pd/pd/excess.pd16
-rw-r--r--sc4pd/pd/fos.pd45
-rw-r--r--sc4pd/pd/hasher.pd17
-rw-r--r--sc4pd/pd/hpf.pd11
-rw-r--r--sc4pd/pd/hpz1.pd12
-rw-r--r--sc4pd/pd/impulse.pd31
-rw-r--r--sc4pd/pd/integrator.pd21
-rw-r--r--sc4pd/pd/lag.pd17
-rw-r--r--sc4pd/pd/lag2.pd17
-rw-r--r--sc4pd/pd/lag3.pd17
-rw-r--r--sc4pd/pd/latoocarfian.pd18
-rw-r--r--sc4pd/pd/lfclipnoise.pd13
-rw-r--r--sc4pd/pd/lfdnoise0.pd5
-rw-r--r--sc4pd/pd/lfnoise0.pd17
-rw-r--r--sc4pd/pd/lfnoise1.pd17
-rw-r--r--sc4pd/pd/lfnoise2.pd17
-rw-r--r--sc4pd/pd/lfpulse.pd42
-rw-r--r--sc4pd/pd/lfsaw.pd29
-rw-r--r--sc4pd/pd/lincong.pd17
-rw-r--r--sc4pd/pd/linexp.pd17
-rw-r--r--sc4pd/pd/logistic.pd24
-rw-r--r--sc4pd/pd/lpf.pd11
-rw-r--r--sc4pd/pd/lpz1.pd12
-rw-r--r--sc4pd/pd/lpz2.pd12
-rw-r--r--sc4pd/pd/mantissamask.pd21
-rw-r--r--sc4pd/pd/onepole.pd28
-rw-r--r--sc4pd/pd/onezero.pd21
-rw-r--r--sc4pd/pd/pitchshift.pd19
-rw-r--r--sc4pd/pd/resonz.pd15
-rw-r--r--sc4pd/pd/rhpf.pd15
-rw-r--r--sc4pd/pd/rlpf.pd15
-rw-r--r--sc4pd/pd/scaleneg.pd16
-rw-r--r--sc4pd/pd/sos.pd38
-rw-r--r--sc4pd/pd/trand.pd16
-rw-r--r--sc4pd/pd/twopole.pd15
-rw-r--r--sc4pd/pd/twozero.pd15
-rw-r--r--sc4pd/readme.txt26
-rw-r--r--sc4pd/source/AllpassC.cpp315
-rw-r--r--sc4pd/source/AllpassL.cpp276
-rw-r--r--sc4pd/source/AllpassN.cpp348
-rw-r--r--sc4pd/source/BPF.cpp190
-rw-r--r--sc4pd/source/BPZ2.cpp140
-rw-r--r--sc4pd/source/BRF.cpp199
-rw-r--r--sc4pd/source/BRZ2.cpp140
-rw-r--r--sc4pd/source/BrownNoise.cpp156
-rw-r--r--sc4pd/source/ClipNoise.cpp136
-rw-r--r--sc4pd/source/CoinGate.cpp84
-rw-r--r--sc4pd/source/CombC.cpp314
-rw-r--r--sc4pd/source/CombL.cpp272
-rw-r--r--sc4pd/source/CombN.cpp341
-rw-r--r--sc4pd/source/Convolution.cpp222
-rw-r--r--sc4pd/source/Crackle.cpp153
-rw-r--r--sc4pd/source/Decay.cpp212
-rw-r--r--sc4pd/source/Decay2.cpp154
-rw-r--r--sc4pd/source/DelayC.cpp287
-rw-r--r--sc4pd/source/DelayL.cpp236
-rw-r--r--sc4pd/source/DelayN.cpp238
-rw-r--r--sc4pd/source/DelayUnit.cpp81
-rw-r--r--sc4pd/source/DelayUnit.hpp67
-rw-r--r--sc4pd/source/Dust.cpp188
-rw-r--r--sc4pd/source/Dust2.cpp188
-rw-r--r--sc4pd/source/ExpRand.cpp160
-rw-r--r--sc4pd/source/FOS.cpp258
-rw-r--r--sc4pd/source/GrayNoise.cpp143
-rw-r--r--sc4pd/source/HPF.cpp180
-rw-r--r--sc4pd/source/HPZ1.cpp132
-rw-r--r--sc4pd/source/HPZ2.cpp140
-rw-r--r--sc4pd/source/Hasher.cpp115
-rw-r--r--sc4pd/source/IRand.cpp159
-rw-r--r--sc4pd/source/Impulse.cpp264
-rw-r--r--sc4pd/source/Integrator.cpp199
-rw-r--r--sc4pd/source/LFClipNoise.cpp195
-rw-r--r--sc4pd/source/LFDNoise0.cpp166
-rw-r--r--sc4pd/source/LFDNoise1.cpp172
-rw-r--r--sc4pd/source/LFDNoise2.cpp188
-rw-r--r--sc4pd/source/LFNoise0.cpp195
-rw-r--r--sc4pd/source/LFNoise1.cpp232
-rw-r--r--sc4pd/source/LFNoise2.cpp271
-rw-r--r--sc4pd/source/LFPulse.cpp292
-rw-r--r--sc4pd/source/LFSaw.cpp256
-rw-r--r--sc4pd/source/LPF.cpp180
-rw-r--r--sc4pd/source/LPZ1.cpp132
-rw-r--r--sc4pd/source/LPZ2.cpp140
-rw-r--r--sc4pd/source/Lag.cpp124
-rw-r--r--sc4pd/source/Lag2.cpp132
-rw-r--r--sc4pd/source/Lag3.cpp137
-rw-r--r--sc4pd/source/Latoocarfian.cpp217
-rw-r--r--sc4pd/source/LinCong.cpp211
-rw-r--r--sc4pd/source/LinExp.cpp223
-rw-r--r--sc4pd/source/LinRand.cpp177
-rw-r--r--sc4pd/source/Logistic.cpp198
-rw-r--r--sc4pd/source/MantissaMask.cpp153
-rw-r--r--sc4pd/source/Median.cpp213
-rw-r--r--sc4pd/source/NRand.cpp173
-rw-r--r--sc4pd/source/OnePole.cpp245
-rw-r--r--sc4pd/source/OneZero.cpp200
-rw-r--r--sc4pd/source/PinkNoise.cpp174
-rw-r--r--sc4pd/source/PitchShift.cpp629
-rw-r--r--sc4pd/source/RHPF.cpp192
-rw-r--r--sc4pd/source/RLPF.cpp192
-rw-r--r--sc4pd/source/Rand.cpp160
-rw-r--r--sc4pd/source/Resonz.cpp190
-rw-r--r--sc4pd/source/SOS.cpp258
-rw-r--r--sc4pd/source/TExpRand.cpp210
-rw-r--r--sc4pd/source/TIRand.cpp210
-rw-r--r--sc4pd/source/TRand.cpp210
-rw-r--r--sc4pd/source/TwoPole.cpp167
-rw-r--r--sc4pd/source/TwoZero.cpp175
-rw-r--r--sc4pd/source/WhiteNoise.cpp137
-rw-r--r--sc4pd/source/absdif.cpp132
-rw-r--r--sc4pd/source/amclip.cpp128
-rw-r--r--sc4pd/source/difsqr.cpp131
-rw-r--r--sc4pd/source/excess.cpp124
-rw-r--r--sc4pd/source/fftlib.c3306
-rw-r--r--sc4pd/source/fftlib.h62
-rw-r--r--sc4pd/source/hypot.cpp125
-rw-r--r--sc4pd/source/main.cpp308
-rw-r--r--sc4pd/source/ring1.cpp130
-rw-r--r--sc4pd/source/ring2.cpp130
-rw-r--r--sc4pd/source/ring3.cpp130
-rw-r--r--sc4pd/source/ring4.cpp131
-rw-r--r--sc4pd/source/sc+.cpp113
-rw-r--r--sc4pd/source/sc-.cpp142
-rw-r--r--sc4pd/source/sc4pd.hpp128
-rw-r--r--sc4pd/source/scaleneg.cpp125
-rw-r--r--sc4pd/source/scdiv.cpp142
-rw-r--r--sc4pd/source/scmul.cpp113
-rw-r--r--sc4pd/source/sqrdif.cpp132
-rw-r--r--sc4pd/source/sqrsum.cpp132
-rw-r--r--sc4pd/source/sumsqr.cpp131
-rw-r--r--sc4pd/source/support.cpp184
-rw-r--r--sc4pd/source/support.hpp124
-rw-r--r--sc4pd/source/template.cpp37
315 files changed, 39607 insertions, 0 deletions
diff --git a/sc4pd/build-max-msvc.bat b/sc4pd/build-max-msvc.bat
new file mode 100644
index 0000000..130a3bc
--- /dev/null
+++ b/sc4pd/build-max-msvc.bat
@@ -0,0 +1,4 @@
+@echo --- Building with MS Visual C++ ---
+
+nmake -f makefile.max-msvc clean
+nmake -f makefile.max-msvc
diff --git a/sc4pd/build-pd-bcc.bat b/sc4pd/build-pd-bcc.bat
new file mode 100644
index 0000000..3dd2132
--- /dev/null
+++ b/sc4pd/build-pd-bcc.bat
@@ -0,0 +1,3 @@
+@echo --- Building with BorlandC++ ---
+
+make -f makefile.pd-bcc
diff --git a/sc4pd/build-pd-cygwin.sh b/sc4pd/build-pd-cygwin.sh
new file mode 100644
index 0000000..9477844
--- /dev/null
+++ b/sc4pd/build-pd-cygwin.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+SYS=pd-cygwin
+
+. config-${SYS}.txt
+
+make -f makefile.${SYS} &&
+{
+ if [ $INSTDIR != "" ]; then
+ make -f makefile.${SYS} install
+ fi
+ if [ $HELPDIR != "" ]; then
+ make -f makefile.${SYS} install-help
+ fi
+}
diff --git a/sc4pd/build-pd-darwin.sh b/sc4pd/build-pd-darwin.sh
new file mode 100755
index 0000000..38814a9
--- /dev/null
+++ b/sc4pd/build-pd-darwin.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+SYS=pd-darwin
+
+. config-${SYS}.txt
+
+make -f makefile.${SYS} &&
+{
+ if [ $INSTDIR != "" ]; then
+ echo Now install as root
+ sudo make -f makefile.${SYS} install
+ fi
+ if [ $HELPDIR != "" ]; then
+ echo Now install help as root
+ sudo make -f makefile.${SYS} install-help
+ fi
+}
diff --git a/sc4pd/build-pd-linux.sh b/sc4pd/build-pd-linux.sh
new file mode 100755
index 0000000..77c6e3f
--- /dev/null
+++ b/sc4pd/build-pd-linux.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+SYS=pd-linux
+
+. config-${SYS}.txt
+
+make -f makefile.${SYS} &&
+{
+ if [ $INSTDIR != "" ]; then
+ echo Now install as root
+ su -c "make -f makefile.${SYS} install"
+ fi
+ if [ $HELPDIR != "" ]; then
+ echo Now install help as root
+ su -c "make -f makefile.${SYS} install-help"
+ fi
+}
diff --git a/sc4pd/build-pd-mingw.bat b/sc4pd/build-pd-mingw.bat
new file mode 100644
index 0000000..fa8919a
--- /dev/null
+++ b/sc4pd/build-pd-mingw.bat
@@ -0,0 +1,3 @@
+mingw32-make -f makefile.pd-mingw
+mingw32-make -f makefile.pd-mingw install
+mingw32-make -f makefile.pd-mingw install-help
diff --git a/sc4pd/build-pd-msvc.bat b/sc4pd/build-pd-msvc.bat
new file mode 100644
index 0000000..d6187f0
--- /dev/null
+++ b/sc4pd/build-pd-msvc.bat
@@ -0,0 +1,4 @@
+@echo --- Building with MS Visual C++ ---
+
+nmake -f makefile.pd-msvc clean
+nmake -f makefile.pd-msvc
diff --git a/sc4pd/config-max-msvc.txt b/sc4pd/config-max-msvc.txt
new file mode 100644
index 0000000..95dfe38
--- /dev/null
+++ b/sc4pd/config-max-msvc.txt
@@ -0,0 +1,27 @@
+# config file for sc4pd, adapted from Thomas Grill's xsample makefile
+#
+
+# where is the Max SDK?
+# you should have the latest version!
+MAXSDKPATH="F:\prog\audio\MaxWinSDK\c74support"
+
+# where do the flext libraries reside?
+FLEXTPATH="%CommonProgramFiles%\Cycling '74\flext"
+
+# where is MS VC++?
+# (need not be defined if the build is started with the compiler environment set)
+# MSVCPATH="c:\programme\prog\microsoft visual studio\VC98"
+
+
+# where should the external be built?
+# (path for temporary files)
+OUTPATH=max-msvc
+
+# where should the external be installed?
+# (leave blank to omit installation)
+INSTPATH="%CommonProgramFiles%\Cycling '74\externals\flext"
+
+
+# some user-definable flags
+# (check if they match your system!)
+UFLAGS=/G6 /arch:SSE
diff --git a/sc4pd/config-pd-bcc.txt b/sc4pd/config-pd-bcc.txt
new file mode 100644
index 0000000..8f8ba75
--- /dev/null
+++ b/sc4pd/config-pd-bcc.txt
@@ -0,0 +1,23 @@
+# config file for sc4pd, adapted from Thomas Grill's xsample makefile
+#
+
+# where is PD?
+PDPATH=c:\programme\audio\pd
+
+# where do the flext libraries reside?
+FLEXTPATH=$(PDPATH)\flext
+
+# where is BorlandC++?
+BCCPATH=c:\programme\prog\bcc55
+
+# where should the external(s) be built?
+OUTPATH=.\pd-bcc
+
+# should the external be installed? (yes/no)
+INSTALL=yes
+
+# where should the external be installed?
+INSTDIR=$(PDPATH)\extra
+
+# additional compiler flags
+UFLAGS=-6 -O2 -OS -ff
diff --git a/sc4pd/config-pd-cygwin.txt b/sc4pd/config-pd-cygwin.txt
new file mode 100644
index 0000000..feb8d31
--- /dev/null
+++ b/sc4pd/config-pd-cygwin.txt
@@ -0,0 +1,35 @@
+# config file for sc4pd, adapted from Thomas Grill's xsample makefile
+#
+
+# your c++ compiler (define only if it's different than g++)
+# CXX=g++
+
+# where does the PD installation reside?
+PD=/cygdrive/c/programme/audio/pd
+
+# where are the PD header files?
+# leave it blank if it is a system directory (like /usr/local/include),
+# since gcc 3.2 complains about it
+PDINC=${PD}/src
+
+# where do the flext libraries reside?
+FLEXTPATH=${PD}/flext
+
+# where should sc4pd objects be built?
+TARGDIR=./pd-cygwin
+
+# where should sc4pd be installed?
+# (leave blank to omit installation)
+INSTDIR=${PD}/extra
+
+# where should the sc4pd help be installed?
+# (leave blank to omit installation)
+HELPDIR=${PD}/doc/5.reference
+
+# additional compiler flags
+# (check whether they fit to your system!)
+UFLAGS=-mcpu=pentium4 -msse -mfpmath=sse # gcc 3.2
+# UFLAGS=-mcpu=pentiumpro # gcc 2.95
+
+# define to build with shared flext library
+#FLEXT_SHARED=1
diff --git a/sc4pd/config-pd-darwin.txt b/sc4pd/config-pd-darwin.txt
new file mode 100644
index 0000000..82c5b70
--- /dev/null
+++ b/sc4pd/config-pd-darwin.txt
@@ -0,0 +1,35 @@
+# config file for sc4pd, adapted from Thomas Grill's xsample makefile
+#
+
+# your c++ compiler (if not g++)
+#CXX=g++-3.3
+
+# where does the PD installation reside?
+PD=/usr/local/lib/pd
+
+# where are the PD header files?
+# leave it blank if it is a system directory (like /usr/local/include),
+# since gcc 3.2 complains about it
+PDINC=${PD}/src
+
+# where is the PD executable?
+PDBIN=/usr/local/bin/pd
+
+# where do the flext libraries reside?
+FLEXTPATH=${PD}/flext
+
+# where should the sc4pd objects be built?
+TARGDIR=./pd-darwin
+
+# where should sc4pd be installed?
+# (leave blank to omit installation)
+INSTDIR=${PD}/extra
+
+# where should the sc4pd help be installed?
+# (leave blank to omit installation)
+HELPDIR=${PD}/doc/5.reference
+
+# additional compiler flags
+# (check whether they fit your system!)
+UFLAGS=-malign-power -maltivec -faltivec
+
diff --git a/sc4pd/config-pd-linux.txt b/sc4pd/config-pd-linux.txt
new file mode 100644
index 0000000..3d67664
--- /dev/null
+++ b/sc4pd/config-pd-linux.txt
@@ -0,0 +1,36 @@
+# config file for sc4pd, adapted from Thomas Grill's xsample makefile
+
+# your c++ compiler (if not g++)
+# CXX=icc
+
+
+# where does the PD installation reside?
+PD=/usr/lib/pd
+
+# where are the PD header files?
+# leave it blank if it is a system directory (like /usr/local/include),
+# since gcc 3.2 complains about it
+PDINC=/home/tim/pd/pd/src
+
+# where do the flext libraries reside?
+FLEXTPATH=/usr/lib/flext
+
+# where should sc4pd objects be built?
+TARGDIR=./pd-linux
+
+# where should sc4pd be installed?
+# (leave blank to omit installation)
+INSTDIR=${PD}/externs
+
+# where should the sc4pd help be installed?
+# (leave blank to omit installation)
+HELPDIR=${PD}/doc/5.reference
+
+# additional compiler flags
+# (check whether they fit to your system!)
+#UFLAGS=-xN -tpp7 -ip -ipo_obj # icc
+UFLAGS=-march=pentium4 -mmmx -msse2 -msse -mfpmath=sse -g # gcc 3.2
+
+# define to link against shared flext library (flext version >= 0.5.0)
+FLEXT_SHARED=1
+
diff --git a/sc4pd/config-pd-mingw.txt b/sc4pd/config-pd-mingw.txt
new file mode 100644
index 0000000..d5352b7
--- /dev/null
+++ b/sc4pd/config-pd-mingw.txt
@@ -0,0 +1,35 @@
+# config file for sc4pd, adapted from Thomas Grill's xsample makefile
+#
+
+# your c++ compiler (define only if it's different than g++)
+# CXX=g++
+
+# where does the PD installation reside?
+PD=c:/programme/audio/pd
+
+# where are the PD header files?
+# leave it blank if it is a system directory (like /usr/local/include),
+# since gcc 3.2 complains about it
+PDINC=${PD}/src
+
+# where do the flext libraries reside?
+FLEXTPATH=${PD}/flext
+
+# where should sc4pd objects be built?
+TARGDIR=./pd-mingw
+
+# where should sc4pd be installed?
+# (leave blank to omit installation)
+INSTDIR=${PD}/extra
+
+# where should the sc4pd help be installed?
+# (leave blank to omit installation)
+HELPDIR=${PD}/doc/5.reference
+
+# additional compiler flags
+# (check whether they fit to your system!)
+UFLAGS=-mcpu=pentium4 -msse -mfpmath=sse # gcc 3.2
+# UFLAGS=-mcpu=pentiumpro # gcc 2.95
+
+# define to build with shared flext library
+# FLEXT_SHARED=1 \ No newline at end of file
diff --git a/sc4pd/config-pd-msvc.txt b/sc4pd/config-pd-msvc.txt
new file mode 100644
index 0000000..9ba68f2
--- /dev/null
+++ b/sc4pd/config-pd-msvc.txt
@@ -0,0 +1,19 @@
+# config file for sc4pd, adapted from Thomas Grill's xsample makefile
+#
+
+# where is PD?
+PDPATH=c:\programme\audio\pd
+
+# where do the flext libraries reside?
+FLEXTPATH=$(PDPATH)\flext
+
+# where is MS VC++?
+# (not necessary if the build started with the compiler environment)
+# MSVCPATH=c:\programme\prog\microsoft visual studio\VC98
+
+# where should the external be built?
+OUTPATH=pd-msvc
+
+# where should the external be installed?
+# (leave blank to omit installation)
+INSTDIR=$(PDPATH)\extra
diff --git a/sc4pd/gpl.txt b/sc4pd/gpl.txt
new file mode 100644
index 0000000..5ea29a7
--- /dev/null
+++ b/sc4pd/gpl.txt
@@ -0,0 +1,346 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
diff --git a/sc4pd/headers/app/AIAttributedStringAdditions.h b/sc4pd/headers/app/AIAttributedStringAdditions.h
new file mode 100644
index 0000000..ae81326
--- /dev/null
+++ b/sc4pd/headers/app/AIAttributedStringAdditions.h
@@ -0,0 +1,39 @@
+/*-------------------------------------------------------------------------------------------------------*\
+| Adium, Copyright (C) 2001-2003, Adam Iser (adamiser@mac.com | http://www.adiumx.com) |
+\---------------------------------------------------------------------------------------------------------/
+ | This program is free software; you can redistribute it and/or modify it under the terms of the GNU
+ | General Public License as published by the Free Software Foundation; either version 2 of the License,
+ | or (at your option) any later version.
+ |
+ | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ | the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ | Public License for more details.
+ |
+ | You should have received a copy of the GNU General Public License along with this program; if not,
+ | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ \------------------------------------------------------------------------------------------------------ */
+
+#import <Cocoa/Cocoa.h>
+#import <Foundation/Foundation.h>
+
+@interface NSMutableAttributedString (AIAttributedStringAdditions)
+
+- (void)appendString:(NSString *)aString withAttributes:(NSDictionary *)attrs;
+- (NSData *)dataRepresentation;
+- (NSAttributedString *)safeString;
+- (unsigned int)replaceOccurrencesOfString:(NSString *)target withString:(NSString*)replacement options:(unsigned)opts range:(NSRange)searchRange;
+- (unsigned int)replaceOccurrencesOfString:(NSString *)target withString:(NSString*)replacement attributes:(NSDictionary*)attributes options:(unsigned)opts range:(NSRange)searchRange;
+- (void)adjustColorsToShowOnBackground:(NSColor *)backgroundColor;
+- (void)adjustColorsToShowOnBackgroundRelativeToOriginalBackground:(NSColor *)backgroundColor;
+@end
+
+@interface NSAttributedString (AIAttributedStringAdditions)
+
+- (float)heightWithWidth:(float)width;
+- (NSData *)dataRepresentation;
++ (NSAttributedString *)stringWithData:(NSData *)inData;
+- (NSAttributedString *)safeString;
+
+@end
+
+
diff --git a/sc4pd/headers/app/AIColorAdditions.h b/sc4pd/headers/app/AIColorAdditions.h
new file mode 100644
index 0000000..6af9dc8
--- /dev/null
+++ b/sc4pd/headers/app/AIColorAdditions.h
@@ -0,0 +1,39 @@
+/*-------------------------------------------------------------------------------------------------------*\
+| Adium, Copyright (C) 2001-2003, Adam Iser (adamiser@mac.com | http://www.adiumx.com) |
+\---------------------------------------------------------------------------------------------------------/
+ | This program is free software; you can redistribute it and/or modify it under the terms of the GNU
+ | General Public License as published by the Free Software Foundation; either version 2 of the License,
+ | or (at your option) any later version.
+ |
+ | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ | the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ | Public License for more details.
+ |
+ | You should have received a copy of the GNU General Public License along with this program; if not,
+ | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ \------------------------------------------------------------------------------------------------------ */
+
+#import <Cocoa/Cocoa.h>
+#import <Foundation/Foundation.h>
+
+@interface NSString (AIColorAdditions)
+
+- (NSColor *)hexColor;
+- (NSColor *)representedColor;
+- (NSColor *)representedColorWithAlpha:(float)alpha;
+
+@end
+
+@interface NSColor (AIColorAdditions)
+
+- (BOOL)equalToRGBColor:(NSColor *)inColor;
+- (BOOL)colorIsDark;
+- (NSColor *)darkenBy:(float)amount;
+- (NSString *)hexString;
+- (NSString *)stringRepresentation;
+- (void)getHue:(float *)hue luminance:(float *)luminance saturation:(float *)saturation;
++ (NSColor *)colorWithCalibratedHue:(float)hue luminance:(float)luminance saturation:(float)saturation alpha:(float)alpha;
+- (NSColor *)colorWithInvertedLuminance;
+- (NSColor *)adjustHue:(float)dHue saturation:(float)dSat brightness:(float)dBrit;
+
+@end
diff --git a/sc4pd/headers/app/AIHTMLDecoder.h b/sc4pd/headers/app/AIHTMLDecoder.h
new file mode 100644
index 0000000..492d663
--- /dev/null
+++ b/sc4pd/headers/app/AIHTMLDecoder.h
@@ -0,0 +1,28 @@
+/*-------------------------------------------------------------------------------------------------------*\
+| Adium, Copyright (C) 2001-2003, Adam Iser (adamiser@mac.com | http://www.adiumx.com) |
+\---------------------------------------------------------------------------------------------------------/
+ | This program is free software; you can redistribute it and/or modify it under the terms of the GNU
+ | General Public License as published by the Free Software Foundation; either version 2 of the License,
+ | or (at your option) any later version.
+ |
+ | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ | the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ | Public License for more details.
+ |
+ | You should have received a copy of the GNU General Public License along with this program; if not,
+ | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ \------------------------------------------------------------------------------------------------------ */
+
+#import <Cocoa/Cocoa.h>
+#import <Foundation/Foundation.h>
+#import "AIStringAdditions.h"
+
+@interface AIHTMLDecoder : NSObject {
+
+}
+
++ (NSAttributedString *)decodeHTML:(NSString *)inMessage;
++ (NSString *)encodeHTML:(NSAttributedString *)inMessage encodeFullString:(BOOL)encodeFullString;
++ (NSString *)encodeHTML:(NSAttributedString *)inMessage headers:(BOOL)includeHeaders fontTags:(BOOL)includeFontTags closeFontTags:(BOOL)closeFontTags styleTags:(BOOL)includeStyleTags closeStyleTagsOnFontChange:(BOOL)closeStyleTagsOnFontChange encodeNonASCII:(BOOL)encodeNonASCII;
+
+@end
diff --git a/sc4pd/headers/app/AIStringAdditions.h b/sc4pd/headers/app/AIStringAdditions.h
new file mode 100644
index 0000000..b0a5a64
--- /dev/null
+++ b/sc4pd/headers/app/AIStringAdditions.h
@@ -0,0 +1,25 @@
+/*-------------------------------------------------------------------------------------------------------*\
+| Adium, Copyright (C) 2001-2003, Adam Iser (adamiser@mac.com | http://www.adiumx.com) |
+\---------------------------------------------------------------------------------------------------------/
+ | This program is free software; you can redistribute it and/or modify it under the terms of the GNU
+ | General Public License as published by the Free Software Foundation; either version 2 of the License,
+ | or (at your option) any later version.
+ |
+ | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ | the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ | Public License for more details.
+ |
+ | You should have received a copy of the GNU General Public License along with this program; if not,
+ | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ \------------------------------------------------------------------------------------------------------ */
+
+#import <Cocoa/Cocoa.h>
+#import <Foundation/Foundation.h>
+
+@interface NSString (AIStringAdditions)
+- (NSString *)compactedString;
+- (int)intValueFromHex;
+- (NSString *)stringByExpandingBundlePath;
+- (NSString *)stringByCollapsingBundlePath;
+- (NSString *)stringByTruncatingTailToWidth:(float)inWidth;
+@end
diff --git a/sc4pd/headers/app/AITextAttributes.h b/sc4pd/headers/app/AITextAttributes.h
new file mode 100644
index 0000000..02b0754
--- /dev/null
+++ b/sc4pd/headers/app/AITextAttributes.h
@@ -0,0 +1,44 @@
+/*-------------------------------------------------------------------------------------------------------*\
+| Adium, Copyright (C) 2001-2003, Adam Iser (adamiser@mac.com | http://www.adiumx.com) |
+\---------------------------------------------------------------------------------------------------------/
+ | This program is free software; you can redistribute it and/or modify it under the terms of the GNU
+ | General Public License as published by the Free Software Foundation; either version 2 of the License,
+ | or (at your option) any later version.
+ |
+ | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ | the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ | Public License for more details.
+ |
+ | You should have received a copy of the GNU General Public License along with this program; if not,
+ | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ \------------------------------------------------------------------------------------------------------ */
+
+#import <Cocoa/Cocoa.h>
+#import <Foundation/Foundation.h>
+
+#define AIBodyColorAttributeName @"AIBodyColor"
+
+@interface AITextAttributes : NSObject {
+
+ NSMutableDictionary *dictionary;
+
+ NSString *fontFamilyName;
+ NSFontTraitMask fontTraitsMask;
+ int fontSize;
+
+}
+
++ (id)textAttributesWithFontFamily:(NSString *)inFamilyName traits:(NSFontTraitMask)inTraits size:(int)inSize;
+- (void)dealloc;
+- (void)setFontFamily:(NSString *)inName;
+- (void)setFontSize:(int)inSize;
+- (void)enableTrait:(NSFontTraitMask)inTrait;
+- (void)disableTrait:(NSFontTraitMask)inTrait;
+- (NSDictionary *)dictionary;
+- (void)setUnderline:(BOOL)inUnderline;
+- (void)setTextColor:(NSColor *)inColor;
+- (void)setTextBackgroundColor:(NSColor *)inColor;
+- (void)setBackgroundColor:(NSColor *)inColor;
+- (void)setLinkURL:(NSString *)inURL;
+
+@end
diff --git a/sc4pd/headers/app/ChangeCounter.h b/sc4pd/headers/app/ChangeCounter.h
new file mode 100644
index 0000000..db74fe5
--- /dev/null
+++ b/sc4pd/headers/app/ChangeCounter.h
@@ -0,0 +1,30 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+class ChangeCounter
+{
+ int changes, updates;
+public:
+ ChangeCounter() { changes = updates = 0; }
+ bool NeedsUpdate() { return changes != updates; }
+ void Update() { updates = changes; }
+ void Change() { changes++; }
+};
+
diff --git a/sc4pd/headers/app/ControlSpec.h b/sc4pd/headers/app/ControlSpec.h
new file mode 100644
index 0000000..7446759
--- /dev/null
+++ b/sc4pd/headers/app/ControlSpec.h
@@ -0,0 +1,36 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+struct ControlSpec {
+ float minval, maxval, initial;
+ int numticks;
+ bool constrained;
+
+ ControlSpec();
+};
+
+inline ControlSpec()
+ : minval(0.), maxval(1.), initial(0.), numticks(11), constrained(false)
+{
+}
+
+
+*/ \ No newline at end of file
diff --git a/sc4pd/headers/app/DrawBackground.h b/sc4pd/headers/app/DrawBackground.h
new file mode 100644
index 0000000..e5fe040
--- /dev/null
+++ b/sc4pd/headers/app/DrawBackground.h
@@ -0,0 +1,83 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#import "SCGeom.h"
+
+class DrawBackground
+{
+public:
+ DrawBackground();
+ virtual void draw(CGContextRef cgc, CGRect rect);
+ virtual void drawSelf(CGContextRef cgc, CGRect rect);
+};
+
+
+class SolidColorBackground : public DrawBackground
+{
+public:
+ SolidColorBackground(SCColor inColor);
+ virtual void drawSelf(CGContextRef cgc, CGRect rect);
+private:
+ SCColor mColor;
+};
+
+enum {
+ grad_Horizontal,
+ grad_Vertical,
+ grad_Narrow,
+ grad_Wide
+};
+
+class GradientBackground : public DrawBackground
+{
+public:
+ GradientBackground(SCColor inStartColor, SCColor inEndColor, int inDirection, int inSteps);
+ virtual void drawSelf(CGContextRef cgc, CGRect rect);
+
+protected:
+ SCColor mStartColor, mEndColor;
+ int mDirection, mSteps;
+};
+
+class HiliteGradientBackground : public GradientBackground
+{
+public:
+ HiliteGradientBackground(SCColor inStartColor, SCColor inEndColor, int inDirection, int inSteps, float inFrac = .33);
+
+ virtual void drawSelf(CGContextRef cgc, CGRect rect);
+
+protected:
+ float mFrac, mFrac1;
+};
+
+/*
+class TiledBackground : public DrawBackground
+{
+public:
+ TiledBackground(NSImage* inTile);
+
+ virtual void drawSelf(CGContextRef cgc, CGRect rect);
+
+protected:
+ NSImage* mTile;
+ CGRect mTiledBounds;
+};
+
+*/
diff --git a/sc4pd/headers/app/GetStringFromUser.h b/sc4pd/headers/app/GetStringFromUser.h
new file mode 100644
index 0000000..0e13d71
--- /dev/null
+++ b/sc4pd/headers/app/GetStringFromUser.h
@@ -0,0 +1,46 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#import <Cocoa/Cocoa.h>
+
+@interface GetStringFromUser : NSObject {
+ NSString *string;
+ id textField;
+ id promptField;
+ id okButton;
+ id cancelButton;
+}
+
++ (id)sharedInstance;
+
+/* Loads UI lazily */
+- (NSPanel *)getStringPanel;
+
+- (NSString *)string;
+- (void)setString:(NSString *)string;
+
+- (void)setPrompt:(NSString *)string;
+
+/* Action methods, sent from the find panel UI; can also be connected to menu items */
+- (void)ok:(id)sender;
+- (void)cancel:(id)sender;
+
+@end
diff --git a/sc4pd/headers/app/GoToPanel.h b/sc4pd/headers/app/GoToPanel.h
new file mode 100644
index 0000000..6808884
--- /dev/null
+++ b/sc4pd/headers/app/GoToPanel.h
@@ -0,0 +1,52 @@
+/*
+ * GoToPanel.M
+ * SC3lang
+ *
+ * Created by j. trutzschler on 02 sept 2003.
+ derived from TextFinder.m by Ali Ozer
+
+ a panel that searches and selects a line
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@interface GoToPanel : NSObject {
+ id findTextField;
+ id okButton;
+}
+
+/* Common way to get a text finder. One instance of TextFinder per app is good enough. */
++ (id)sharedInstance;
+
+/* Main method for external users; does a find in the first responder. Selects found range or beeps. */
+- (void)selectLine:(id)sender;
+- (void) getAndDisplayCurrentLine;
+- (void)prselectLine:(int)linenum;
+
+/* Loads UI lazily */
+- (NSPanel *)gotoLinePanel;
+
+/* Gets the first responder and returns it if it's an NSTextView */
+- (NSTextView *)textObjectToSelectIn;
+
+- (void)orderFrontGotoLinePanel:(id)sender;
+
+/* Misc internal methods */
+- (void)appDidActivate:(NSNotification *)notification;
+
+
+@end
diff --git a/sc4pd/headers/app/MyDocument.h b/sc4pd/headers/app/MyDocument.h
new file mode 100644
index 0000000..d52eabc
--- /dev/null
+++ b/sc4pd/headers/app/MyDocument.h
@@ -0,0 +1,107 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#import <Cocoa/Cocoa.h>
+#import "UserPanel.h"
+#include "PyrObject.h"
+#include "PyrKernel.h"
+#include "GC.h"
+#include "VMGlobals.h"
+
+extern pthread_mutex_t gLangMutex;
+extern PyrSymbol *s_closed;
+
+@interface MyDocument : NSDocument
+{
+ IBOutlet NSTextView* initTextView;
+ IBOutlet NSTextView* textView;
+ IBOutlet NSScrollView* scrollView;
+ Boolean isRichText;
+ struct PyrObject *mWindowObj;
+}
+
+
+- (NSTextView*)makeTextView;
+- (NSTextView*) textView;
+
+- (void)windowControllerDidLoadNib:(NSWindowController*) aController;
+
+- (void)addDocument;
+
+- (IBAction)openCode:(id)sender;
+- (IBAction)methodTemplates: (id)sender;
+- (IBAction)methodReferences: (id)sender;
+
+- (IBAction)balanceParens: (id)sender;
+
+- (IBAction)syntaxColorize: (id)sender;
+- (void) insertText: (char*) text length: (int)length;
+- (IBAction)shiftLeft: (id)sender;
+- (IBAction)shiftRight: (id)sender;
+- (IBAction)commentCode: (id)sender;
+- (IBAction)uncommentCode:(id)sender;
+
+- (IBAction) executeSelection: (id) sender;
+- (NSString*)currentlySelectedTextOrLine: (NSRange*) outRange;
+-(void)selectRangeStart:(int)rangeStart size:(int)rangeSize;
+
+- (IBAction) showHelp: (id) sender;
+
+- (BOOL) textView: (NSTextView *) textView
+ clickedOnLink: (id) link
+ atIndex: (unsigned) charIndex;
+- (IBAction) createLink: (id) sender;
+
+- (void)sendSelection: (char*) methodName;
+
+- (NSString *)windowNibName;
+
+- (BOOL)writeToFile:(NSString*) path ofType:(NSString *)aType;
+- (BOOL)readFromFile:(NSString *)path ofType:(NSString *)aType;
+
+- (BOOL) shouldRunSavePanelWithAccessoryView;
+
+- (BOOL)windowShouldClose:(id)sender;
+- (void)windowWillClose:(NSNotification *)aNotification;
+- (IBAction) becomePostWindow: (id) sender;
+- (BOOL) isDocumentEdited;
+
+- (void)doToggleRich;
+// toggleRich: puts up an alert before ultimately calling doToggleRich
+- (IBAction)toggleRich:(id)sender;
+- (void)setRichText:(BOOL)flag;
+
+- (BOOL)validateMenuItem:(NSMenuItem *)aCell;
+
+- (void)setSCObject: (struct PyrObject*)inObject;
+- (struct PyrObject*)getSCObject;
+- (void) closeWindow;
+- (void)setBackgroundColor:(NSColor *)color;
+- (NSScrollView*) scrollView;
+- (NSTextView*) initTextView;
+-(void)selectLine:(int)linenum;
+- (IBAction)selectLineWindow: (id) sender;
+- (void) callSCLangWithMethod: (PyrSymbol*) method;
+
+@end
+
+NSString* pathOfHelpFileFor(NSString* selection);
+void showHelpFor(NSString* selection);
+
diff --git a/sc4pd/headers/app/RendezvousClient.h b/sc4pd/headers/app/RendezvousClient.h
new file mode 100644
index 0000000..e66f518
--- /dev/null
+++ b/sc4pd/headers/app/RendezvousClient.h
@@ -0,0 +1,39 @@
+//
+// RendezvousClient.h
+// SC3lang
+//
+// Created by C. Ramakrishnan on Mon Feb 24 2003.
+// Copyright (c) 2003 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface OSCService : NSObject {
+// a glorified struct (declared as an Obj-C class so I can put it in NSArrays)
+// stored in the oscServices ivar of RendezvousClient
+@public
+ NSNetService* netService;
+ BOOL isResolved;
+ NSString* hostName;
+ const struct sockaddr_in* sockaddr;
+ unsigned hostAddress;
+ unsigned short port;
+ int refCount;
+}
+
+@end
+
+@interface RendezvousClient : NSObject {
+ NSNetServiceBrowser* browser;
+ NSMutableArray* oscServices;
+}
+
++ (RendezvousClient*)sharedClient;
+
+// interface
+- (void)findOSCServices;
+- (OSCService*)oscServiceAtIndex:(unsigned)index;
+- (unsigned)numberOfOSCServices;
+
+@end
+
diff --git a/sc4pd/headers/app/SCDialog.h b/sc4pd/headers/app/SCDialog.h
new file mode 100644
index 0000000..fdebdbb
--- /dev/null
+++ b/sc4pd/headers/app/SCDialog.h
@@ -0,0 +1,41 @@
+//
+// SCDialogs.h
+// SC3lang
+//
+// Created by cruxxial on Tue Dec 17 2002.
+// Copyright (c) 2002 crucial-systems. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+#include "PyrPrimitive.h"
+#include "PyrObject.h"
+#include "PyrKernel.h"
+#include "VMGlobals.h"
+#include "GC.h"
+#include "PyrSched.h"
+#import "SCVirtualMachine.h"
+
+@interface SCDialog : NSObject {
+ PyrObject *receiver;
+ PyrObject *result;
+ NSOpenPanel *openPanel;
+}
+
++(id)receiver:(PyrObject*)argReceiver result:(PyrObject*)argResult;
+-(id)initWithReceiver:(PyrObject*)argReceiver result:(PyrObject*)argResult;
+
+-(void)ok;
+-(void)cancel;
+-(void)error;
+
+-(void)returnPaths:(NSArray*)urls;
+-(void)getPaths;
+-(void)returnPath:(NSString*)path;
+
+
+// call method on self when SCVM is ready for sclang usage
+-(void)scvmDeferWithSelector:(SEL)selector;
+
+
+@end
diff --git a/sc4pd/headers/app/SCGeom.h b/sc4pd/headers/app/SCGeom.h
new file mode 100644
index 0000000..04904a4
--- /dev/null
+++ b/sc4pd/headers/app/SCGeom.h
@@ -0,0 +1,90 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#import <Carbon/Carbon.h>
+#include "SC_BoundsMacros.h"
+
+struct SCColor {
+ float red, green, blue, alpha;
+};
+typedef struct SCColor SCColor;
+
+inline SCColor SCMakeColor(float red, float green, float blue, float alpha)
+{
+ SCColor sccolor;
+ sccolor.red = red;
+ sccolor.green = green;
+ sccolor.blue = blue;
+ sccolor.alpha = alpha;
+ return sccolor;
+}
+
+struct SCPoint {
+ float x, y;
+};
+
+inline SCPoint SCMakePoint(float x, float y)
+{
+ SCPoint p;
+ p.x = x;
+ p.y = y;
+ return p;
+}
+
+struct SCRect {
+ float x, y, width, height;
+};
+
+inline SCRect SCRectUnion(SCRect a, SCRect b)
+{
+ if (a.height <= 0. && a.width <= 0.) return b;
+ if (b.height <= 0. && b.width <= 0.) return a;
+
+ SCRect u;
+ u.x = sc_min(a.x, b.x);
+ u.y = sc_min(a.y, b.y);
+ u.width = sc_max(a.x + a.width, b.x + b.width) - u.x;
+ u.height = sc_max(a.y + a.height, b.y + b.height) - u.y;
+ return u;
+}
+
+inline bool SCRectsDoIntersect(SCRect a, SCRect b)
+{
+ if (a.x + a.width < b.x) return false;
+ if (a.y + a.height < b.y) return false;
+ if (a.x > b.x + b.width) return false;
+ if (a.y > b.y + b.height) return false;
+ return true;
+}
+
+inline SCRect SCMakeRect(float x, float y, float width, float height)
+{
+ SCRect r;
+ r.x = x; r.y = y; r.width = width; r.height = height;
+ return r;
+}
+
+inline bool SCPointInRect(SCPoint p, SCRect r)
+{
+ return
+ p.x >= r.x && p.x <= r.x + r.width
+ && p.y >= r.y && p.y <= r.y + r.height;
+
+}
diff --git a/sc4pd/headers/app/SCGraphView.h b/sc4pd/headers/app/SCGraphView.h
new file mode 100644
index 0000000..84b259d
--- /dev/null
+++ b/sc4pd/headers/app/SCGraphView.h
@@ -0,0 +1,55 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#import <Cocoa/Cocoa.h>
+#import "SCView.h"
+
+@interface SCGraphView : NSView
+{
+ struct PyrObject *mWindowObj;
+ SCTopView *mTopView;
+ bool mDragStarted;
+ SCView* mMenuView;
+ bool windowShouldClose;
+}
+
+- (void)drawRect: (NSRect)bounds;
+- (void) keyDown: (NSEvent*) event;
+- (void) keyUp: (NSEvent*) event;
+- (void) mouseDown: (NSEvent*) event;
+- (void)setSCObject: (struct PyrObject*)inObject;
+- (struct PyrObject*)getSCObject;
+- (BOOL)isFlipped;
+- (BOOL)mouseDownCanMoveWindow;
+
+- (void)setSCTopView: (SCTopView*)inView;
+//- (void)dealloc;
+- (void)closeWindow;
+- (void)willClose;
+- (void)setWindowShouldClose:(BOOL)boo;
+- (BOOL)windowShouldClose;
+- (void) beginDragFrom: (NSPoint)where of: (PyrSlot*)slot;
+
+- (NSMenu*) menuForEvent:(NSEvent*)event;
+- (void)startMenuTracking: (SCView*) inView;
+
+- (IBAction) toggleUIEditMode: (id) sender;
+
+@end
diff --git a/sc4pd/headers/app/SCService.h b/sc4pd/headers/app/SCService.h
new file mode 100644
index 0000000..64a78a0
--- /dev/null
+++ b/sc4pd/headers/app/SCService.h
@@ -0,0 +1,16 @@
+//
+// SCService.h
+// SC3lang
+//
+// Created by C. Ramakrishnan on Mon Oct 20 2003.
+// Copyright (c) 2003 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+@interface SCService : NSObject {
+
+}
+
+@end
diff --git a/sc4pd/headers/app/SCTextView.h b/sc4pd/headers/app/SCTextView.h
new file mode 100644
index 0000000..b1b721c
--- /dev/null
+++ b/sc4pd/headers/app/SCTextView.h
@@ -0,0 +1,33 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#import <Cocoa/Cocoa.h>
+
+@interface SCTextView : NSTextView
+{
+
+}
+
+ - (void) keyDown: (NSEvent*) event;
+ - (void) mouseDown: (NSEvent*) event;
+ - (void) autoIndent: (NSEvent*) event;
+ - (void) mouseDownAction;
+
+@end
diff --git a/sc4pd/headers/app/SCView.h b/sc4pd/headers/app/SCView.h
new file mode 100644
index 0000000..a752445
--- /dev/null
+++ b/sc4pd/headers/app/SCView.h
@@ -0,0 +1,784 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#import "DrawBackground.h"
+#include "PyrObject.h"
+
+enum {
+ layout_NoResize,
+ layout_Resize
+};
+
+enum {
+ // mHResize
+ layout_FixedLeft = -1,
+ layout_HElastic,
+ layout_FixedRight,
+};
+enum {
+ // mVResize
+ layout_FixedTop = -1,
+ layout_VElastic,
+ layout_FixedBottom
+};
+
+
+struct Layout
+{
+ Layout();
+
+ // layout params for dynamic layout views
+ float mMinWidth, mMaxWidth, mMinHeight, mMaxHeight;
+ float mWeight;
+ bool mShouldResize;
+ // layout params for composite views
+ char mHResize, mVResize;
+};
+
+
+
+class SCView;
+class SCContainerView;
+class SCTopView;
+
+typedef SCView* (*SCViewCtor)(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+struct SCViewMaker
+{
+ SCViewMaker(const char* inName, SCViewCtor inCtor);
+ static SCView* MakeSCView(PyrObject* inObj, SCContainerView *inParent, SCRect inBounds, const char* classname);
+
+ SCViewMaker *mNext;
+ SCViewCtor mCtor;
+ const char* mName;
+};
+
+extern SCViewMaker *gSCViewMakers;
+extern SCView *gAnimatedViews;
+
+class SCView
+{
+public:
+ SCView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCView();
+
+ virtual void draw(SCRect inDamage);
+ virtual void drawFocus(SCRect inDamage);
+ virtual void drawDisabled(SCRect inDamage);
+ virtual void drawDragHilite(SCRect inDamage);
+ virtual void drawIfNecessary(SCRect inDamage);
+ virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseOver(SCPoint where);
+ virtual void keyDown(int character, int modifiers, unsigned short keycode);
+ virtual void keyUp(int character, int modifiers, unsigned short keycode);
+ virtual bool shouldDim();
+ void beginDrag(SCPoint where);
+
+ virtual bool canReceiveDrag();
+ virtual void receiveDrag();
+
+ bool isFocus() const;
+ bool hit(SCPoint p) const;
+ void refresh();
+ void refreshFocus();
+ void setDragHilite(bool inFlag);
+
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+
+ virtual bool isDragSource() const;
+ virtual SCView* findView(SCPoint where);
+ virtual SCView* findViewByID(int32 inID);
+ virtual void makeFocus(bool focus);
+ virtual SCView* nextFocus(bool *foundFocus, bool canFocus);
+ virtual SCView* prevFocus(SCView **prevView, bool canFocus);
+ virtual bool canFocus();
+
+ void sendMessage(PyrSymbol *method, int numargs, PyrSlot *args, PyrSlot *result);
+
+ virtual void setBounds(SCRect inBounds);
+ virtual SCRect getBounds();
+ virtual Layout getLayout();
+
+ SCView* next() { return mNext; }
+ SCContainerView* parent() { return mParent; }
+
+ virtual NSMenu* contextMenu(SCPoint inPoint);
+
+ virtual void setMenuItemChosen(int inItem) {}
+
+ PyrObject* GetSCObj() { return mObj; }
+ SCView* NextAnimatedView() const { return mNextAnimatedView; }
+
+ void startAnimation();
+ void stopAnimation();
+ virtual void animate() { refresh(); }
+
+protected:
+ friend class SCContainerView;
+
+ SCView *mNext;
+ SCView *mNextAnimatedView;
+ SCView *mPrevAnimatedView;
+ SCContainerView *mParent;
+ SCTopView *mTop;
+ PyrObject* mObj;
+ SCRect mBounds;
+ Layout mLayout;
+ DrawBackground* mBackground;
+ bool mVisible;
+ bool mEnabled;
+ bool mCanFocus;
+ bool mDragHilite;
+ int32 mID;
+};
+
+
+class SCContainerView : public SCView
+{
+public:
+ SCContainerView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCContainerView();
+
+ virtual void drawIfNecessary(SCRect inDamage);
+
+ virtual void add(SCView *inChild);
+ virtual void remove(SCView *inChild);
+ virtual SCView* findView(SCPoint where);
+ virtual SCView* findViewByID(int32 inID);
+ virtual void makeFocus(bool focus);
+ virtual SCView* nextFocus(bool *foundFocus, bool canFocus);
+ virtual SCView* prevFocus(SCView **prevView, bool canFocus);
+ virtual bool canFocus();
+
+protected:
+ SCView *mChildren;
+ int mNumChildren;
+};
+
+class SCCompositeView : public SCContainerView
+{
+public:
+ SCCompositeView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCCompositeView();
+
+ virtual void setBounds(SCRect inBounds);
+
+protected:
+};
+
+class SCLayoutView : public SCContainerView
+{
+public:
+ SCLayoutView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCLayoutView();
+
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+
+protected:
+ float mSpacing;
+};
+
+class SCHLayoutView : public SCLayoutView
+{
+public:
+ SCHLayoutView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCHLayoutView();
+
+ virtual void setBounds(SCRect inBounds);
+
+protected:
+};
+
+class SCVLayoutView : public SCLayoutView
+{
+public:
+ SCVLayoutView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCVLayoutView();
+
+ virtual void setBounds(SCRect inBounds);
+
+protected:
+};
+
+// tell host to draw stuff.
+typedef void (*DamageCallback)(SCRect inRect, void *inData);
+typedef void (*DragCallback)(SCPoint where, PyrSlot* inSlot, void *inData);
+
+class SCTopView : public SCCompositeView
+{
+public:
+ SCTopView(PyrObject* inObj, SCRect inBounds);
+
+ SCView *focusView() { return mFocusView; }
+
+ void resetFocus();
+ void addDamage(SCRect inRect);
+ void beginDragCallback(SCPoint where, PyrSlot* slot);
+
+ void setDamageCallback(DamageCallback inFunc, void *inHostData)
+ { mDamageCallback = inFunc; mHostData = inHostData; }
+ void setDragCallback(DragCallback inFunc)
+ { mDragCallback = inFunc; }
+
+ void tabNextFocus();
+ void tabPrevFocus();
+ void setDragView(SCView *inView);
+
+ NSView* GetNSView() { return mNSView; }
+ void SetNSView(NSView* inView) { mNSView = inView; }
+
+ bool ConstructionMode() { return mConstructionMode; }
+ void SetConstructionMode(bool inFlag) { mConstructionMode = inFlag; }
+
+ virtual void drawFocus(SCRect inDamage);
+
+protected:
+ friend class SCView;
+ void focusIs(SCView *inView) { mFocusView = inView; }
+
+ DamageCallback mDamageCallback;
+ DragCallback mDragCallback;
+ void *mHostData;
+ SCView *mFocusView;
+ SCView *mDragView;
+ NSView *mNSView;
+
+ bool mConstructionMode;
+};
+
+inline bool SCView::isFocus() const { return mTop->focusView() == this; }
+
+class SCSlider : public SCView
+{
+public:
+ SCSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+ virtual void draw(SCRect inDamage);
+ virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+
+ double value() { return mValue; }
+ bool setValue(double inValue, bool send);
+
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+
+ virtual bool canReceiveDrag();
+ virtual void receiveDrag();
+
+protected:
+ virtual void setValueFromPoint(SCPoint point);
+ void calcThumbRect();
+
+ SCRect mThumbRect;
+ double mValue, mStepSize, mStepScale;
+ DrawBackground* mKnob;
+};
+SCView* NewSCSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+
+class SCRangeSlider : public SCView
+{
+public:
+ SCRangeSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+ virtual void draw(SCRect inDamage);
+ virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+
+ bool setValue(double inLo, double inHi, bool send);
+
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+
+ virtual bool canReceiveDrag();
+ virtual void receiveDrag();
+
+protected:
+ virtual void setValueFromPoint(SCPoint point);
+ // sc.solar addition
+ void moveRangeFromPoint(SCPoint point);
+ void adjustLoFromPoint(SCPoint point);
+ void adjustHiFromPoint(SCPoint point);
+ // sc.solar addition end
+ void calcRangeRect();
+
+ SCRect mRangeRect;
+ double mLo, mHi, mStepSize, mStepScale;
+ SCPoint mAnchor;
+ DrawBackground* mKnob;
+};
+SCView* NewSCRangeSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+
+
+class SC2DSlider : public SCView
+{
+public:
+ SC2DSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+ virtual void draw(SCRect inDamage);
+ virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+
+ virtual bool setValue(double inLo, double inHi, bool send);
+
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+
+ virtual bool canReceiveDrag();
+ virtual void receiveDrag();
+
+protected:
+ virtual void setValueFromPoint(SCPoint point);
+ void calcThumbRect();
+
+ SCRect mThumbRect;
+ double mX, mY;
+ double mStepSize, mStepScale;
+ DrawBackground* mKnob;
+};
+SCView* NewSC2DSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+
+class SC2DTabletSlider : public SC2DSlider
+{
+public:
+ SC2DTabletSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+ virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+
+ virtual bool setValue(double inX, double inY,bool send);
+
+protected:
+ int mClipInBounds;
+
+};
+SCView* NewSC2DTabletSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+
+#include "SC_SndBuf.h"
+
+const int kMaxScopeChannels = 16;
+class SCScope : public SCView
+{
+public:
+ SCScope(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCScope();
+
+ virtual void draw(SCRect inDamage);
+ virtual void draw0(CGContextRef cgc);
+ virtual void draw1(CGContextRef cgc);
+ virtual void draw2(CGContextRef cgc);
+ virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void animate();
+
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+
+ SCPoint pixelToUnits(SCPoint p, SCRect r)
+ {
+ return SCMakePoint(
+ (p.x - r.x) * mZoom.x + mScroll.x,
+ (p.y - r.y) * mZoom.y + mScroll.y);
+ }
+ SCPoint unitsToPixel(SCPoint u, SCRect r)
+ {
+ return SCMakePoint(
+ (u.x - mScroll.x) * mInvZoom.x + r.x,
+ (u.y - mScroll.y) * mInvZoom.y + r.y);
+ }
+
+protected:
+
+ int mBufNum;
+ SndBuf mSndBuf;
+ SCPoint mZoom, mInvZoom, mScroll;
+ int mStyle; // 0 = separate, 1 = overlay, 2 = x,y.
+ SCColor mWaveColors[kMaxScopeChannels];
+ SCColor mGridColor;
+ bool mGridOn;
+};
+SCView* NewSCScope(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+
+
+const int kLabelSize = 64;
+struct SCButtonState
+{
+ char mLabel[kLabelSize];
+ SCColor mLabelColor;
+ SCColor mButtonColor;
+};
+
+const int kFontNameSize = 80;
+
+class SCButton : public SCView
+{
+public:
+ SCButton(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCButton();
+
+ virtual void draw(SCRect inDamage);
+ virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+
+ bool setValue(int inValue, bool send);
+
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+
+ virtual bool canReceiveDrag();
+ virtual void receiveDrag();
+
+protected:
+
+ int mValue;
+ char mFontName[kFontNameSize];
+ float mFontSize;
+ int mNumStates;
+ SCButtonState *mStates;
+ bool mPushed;
+};
+SCView* NewSCButton(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+
+class SCPopUpMenu : public SCView
+{
+public:
+ SCPopUpMenu(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCPopUpMenu();
+
+ virtual void draw(SCRect inDamage);
+ virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+
+ bool setValue(int inValue, bool send);
+ virtual void setMenuItemChosen(int inItem) { setValue(inItem, true); }
+
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+
+ virtual bool canReceiveDrag();
+ virtual void receiveDrag();
+
+protected:
+
+ int mValue;
+ MenuHandle mMenuH;
+ char mFontName[kFontNameSize];
+ float mFontSize;
+ SCColor mStringColor;
+};
+SCView* NewSCPopUpMenu(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+
+class SCListView : public SCView
+{
+public:
+ SCListView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCListView();
+
+ virtual void draw(SCRect inDamage);
+ virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseTrack(SCPoint where, int modifiers, NSEvent *theEvent);
+
+ bool setValue(int inValue, bool send);
+
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+
+ virtual bool canReceiveDrag();
+ virtual void receiveDrag();
+
+ void scrollToValue();
+
+protected:
+
+ int mValue;
+ CFMutableArrayRef mArray;
+ char mFontName[kFontNameSize];
+ float mFontSize;
+ float mScroll;
+ float mAnchorScroll;
+ SCPoint mAnchor;
+ SCColor mStringColor;
+ SCColor mSelectedStringColor;
+ SCColor mHiliteColor;
+ int mAlignment;
+ NSSize mStrSize;
+ bool mScrolling;
+};
+SCView* NewSCListView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+//by jan trutzschler (jt@kandos.de)
+class SCMultiSliderView : public SCView
+{
+public:
+ SCMultiSliderView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCMultiSliderView();
+
+ virtual void draw(SCRect inDamage);
+ virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+
+ void setSelection(SCPoint where);
+ bool setValue(int inX, double inY, bool send);
+ //virtual void setPoint(int x, double y, bool send);
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+ void setVisibleSize();
+ virtual bool canReceiveDrag();
+ virtual void receiveDrag();
+
+protected:
+ int indexFromPoint(SCPoint where);
+// int getVisibleMax();
+
+ double valueFromPoint(SCPoint where);
+ void setValueFromPoint(SCPoint point);
+ SCRect calcThumbRect(int xIn, double valIn, double step);
+ int mThumbSize, mThumbSizeY; // size of the rect
+ int mTabSize, mVisibleSize; // size of the table
+ SCColor mFillColor;
+ SCColor mStrokeColor;
+ SCRect mThumbRect;
+ double mCurrentY, mCurrentX;
+ int mCurrentIndex, mStartIndex, mSelectionSize;
+ double mStepSize, mStepScale;
+ double * mYValues;
+ double * mSecYValues;
+ DrawBackground* mKnob;
+ float mXOffset ; //space between points
+ bool mReadOnly, mDrawLinesActive, mShowIndex, mDrawRectsActive, mIsHorizontal, mIsFilled;
+ SCPoint mPrevPoint;
+ int mElasticMode;
+ double mElasticIndexStep;
+
+};
+SCView* NewSCMultiSliderView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+////
+//by jan truetzschler jt@kandos.de
+struct SCEnvObject {
+ SCColor mColor; //changes between selected and mObjectColor
+ SCColor mObjectColor; //if its not selected
+ SCRect mRect;
+ int mNumConnection;
+ SCPoint mDrawPoint;
+ double * mConnections; //tells to where it is connected
+ int mNumInputs, mNumOutputs;
+ double x, y;
+ bool mIsSelected, mIsVisible, mIsStatic;
+ char *mString;
+};
+typedef struct SCEnvObject SCEnvObject;
+
+class SCEnvelopeView : public SCView
+{
+public:
+ SCEnvelopeView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCEnvelopeView();
+ virtual void draw(SCRect inDamage);
+ virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+
+ void setSelection(SCPoint where, bool fixed, bool checkForConnection);
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual bool canReceiveDrag();
+ virtual void receiveDrag();
+
+protected:
+
+ void setValueFromPoint(SCPoint point);
+ bool setValue(SCEnvObject * envob, double x, double y, bool send);
+ int allocSlotEnvObjArray(PyrSlot *slot, SCEnvObject **arr);
+ bool setEnvRect(double valX, double valY, SCEnvObject * envobIn);
+
+ int mThumbSize, mThumbSizeY; // size of the rect
+ int mTabSize, mVisibleSize, mActiveSize; // size of the table
+ SCColor mFillColor, mSelectedColor, mStrokeColor;
+ SCRect mThumbRect;
+ double mCurrentY, mCurrentX, mAbsoluteX;
+ int mCurrentIndex, mStartIndex, mSelectionSize, mLastIndex;
+ double mStepSize, mStepScale;
+ SCEnvObject * mEnvObj;
+ //DrawBackground* mKnob;
+ bool mDrawLinesActive, mShowIndex, mDrawRectsActive, mIsFilled, mIsFixedSelection, mIsEnvView;
+ int mSelectedIndex;
+ SCPoint mMousePoint;
+
+ double xGridMultiplier;
+
+ //draw string in box
+ char mFontName[kFontNameSize];
+ float mFontSize;
+ SCColor mStringColor;
+ int mAlignment;
+ bool mDrawCenteredConnection;
+
+
+};
+SCView* NewSCEnvelopeView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+
+//
+
+class SCUserView : public SCView
+{
+public:
+ SCUserView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+ virtual void draw(SCRect inDamage);
+ virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void keyDown(int character, int modifiers);
+ virtual void keyUp(int character, int modifiers);
+
+protected:
+ void mouseAction(PyrSymbol *method, SCPoint where, int modifiers);
+};
+SCView* NewSCUserView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+
+enum {
+ kSCAlignLeft = -1,
+ kSCAlignCenter,
+ kSCAlignRight
+};
+
+class SCStaticText : public SCView
+{
+public:
+ SCStaticText(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCStaticText();
+
+ virtual void draw(SCRect inDamage);
+ virtual bool shouldDim();
+
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+
+protected:
+ virtual void drawString(SCRect bounds);
+
+ char *mString;
+ char mFontName[kFontNameSize];
+ float mFontSize;
+ SCColor mStringColor;
+ int mAlignment;
+
+};
+SCView* NewSCStaticText(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+class SCNumberBox : public SCStaticText
+{
+public:
+ SCNumberBox(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCNumberBox();
+
+ virtual void draw(SCRect inDamage);
+ virtual bool shouldDim();
+
+ virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ //virtual void mouseEndTrack(SCPoint where, int modifiers);
+
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+
+ virtual bool canReceiveDrag();
+ virtual void receiveDrag();
+
+protected:
+ SCColor mBoxColor;
+};
+SCView* NewSCNumberBox(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+class SCDragSource : public SCStaticText
+{
+public:
+ SCDragSource(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCDragSource();
+
+ virtual void draw(SCRect inDamage);
+ virtual bool shouldDim();
+ virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+
+protected:
+};
+SCView* NewSCDragSource(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+
+class SCDragSink : public SCStaticText
+{
+public:
+ SCDragSink(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCDragSink();
+
+ virtual void draw(SCRect inDamage);
+ virtual bool shouldDim();
+
+ virtual bool canReceiveDrag();
+ virtual void receiveDrag();
+
+protected:
+};
+SCView* NewSCDragSink(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+
+class SCDragBoth : public SCDragSink
+{
+public:
+ SCDragBoth(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+ virtual void draw(SCRect inDamage);
+
+ virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+
+protected:
+};
+SCView* NewSCDragBoth(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
+
+//felix
+class SCTabletView : public SCView
+{
+public:
+ SCTabletView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCTabletView();
+
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+
+ virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+ virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent);
+protected:
+ int mClipToBounds;
+};
+SCView* NewSCTabletView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+
diff --git a/sc4pd/headers/app/SCVirtualMachine.h b/sc4pd/headers/app/SCVirtualMachine.h
new file mode 100644
index 0000000..354e8a5
--- /dev/null
+++ b/sc4pd/headers/app/SCVirtualMachine.h
@@ -0,0 +1,65 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface SCVirtualMachine : NSObject {
+ NSMutableArray *deferredOperations;
+ NSMutableArray *guiWindows;
+ NSTimer *deferredTaskTimer;
+ NSTimer *appClockTimer;
+}
+
++ (id)sharedInstance;
+
+- (id)init;
+- (void)start;
+- (void)doPeriodicTask: (NSTimer*) timer;
+- (void)doClockTask: (NSTimer*) timer;
+- (void)setCmdLine: (const char*) text length: (int)length;
+- (void)sendMain: (char*) methodName;
+
+- (void)defer: (NSInvocation*) action;
+- (void)performDeferredOperations;
+- (void)doAnimatedViews;
+
+- (void)addWindow: (NSWindow*)window;
+- (void)closeAllGUIWindows;
+
+- (IBAction) runMain: (id) sender;
+- (IBAction) stopMain: (id) sender;
+- (IBAction) compileLibrary: (id) sender;
+- (IBAction) newSCWindow: (id) sender;
+- (IBAction)clearPostWindow:(id)sender;
+- (void)postWindowToFront:(id)sender;
+
+// deferred primitives
+
+
+- (void)becomeFullScreen: (NSWindow*)window;
+- (void)endFullScreen: (NSWindow*)window;
+- (void)loadUserPanel:(NSString*)filename SCObject: (void*)scobj;
+
+
+-(IBAction)showHelp:(id)sender;
+
+
+@end
diff --git a/sc4pd/headers/app/TabletEvents.h b/sc4pd/headers/app/TabletEvents.h
new file mode 100644
index 0000000..3607ab9
--- /dev/null
+++ b/sc4pd/headers/app/TabletEvents.h
@@ -0,0 +1,75 @@
+/*----------------------------------------------------------------------------
+
+FILE NAME
+
+TabletEvents.h - Header file for TabletEvent Category.
+ This is an extension to the NSEvent class.
+
+COPYRIGHT
+
+Copyright WACOM Technology, Inc. 2001.
+
+All rights reserved.
+
+----------------------------------------------------------------------------*/
+
+#import <Cocoa/Cocoa.h>
+#import <Carbon/Carbon.h>
+
+@interface NSEvent ( TabletEvents )
+
+- (void *)eventRef;
+- (BOOL) isTabletPointerEvent;
+- (BOOL) isTabletProximityEvent;
+- (void) setLocation:(NSPoint)loc;
+- (TabletPointerRec) tabletRec;
+- (SInt32) absoluteX;
+- (SInt32) absoluteY;
+- (SInt32) absoluteZ;
+- (void) getAbsoluteX:(SInt32*)absX Y:(SInt32*)absY Z:(SInt32*)absZ;
+- (NSPoint) tilt;
+- (UInt16) rawTabletPressure;
+- (float) scaledTabletPressure;
+- (float) rotationInDegrees; /* 0¡ <-> +359.9999¡ */
+- (float) rotationInRadians; /* 0 <-> 2¹ */
+- (UInt16) deviceID;
+
+@end
+
+///////////////////////////////////////////////////////////////////////////
+/* This is the name of the Notification sent when a proximity event is
+ captured by the application */
+extern NSString *kProximityNotification;
+
+/* vendor-defined ID - typically will be USB vendor ID */
+extern NSString *kVendorID;
+
+/* vendor-defined tablet ID */
+extern NSString *kTabletID;
+
+/* vendor-defined ID of the specific pointing device */
+extern NSString *kPointerID;
+
+/* unique device ID - matches to deviceID field in tablet event */
+extern NSString *kDeviceID;
+
+/* unique tablet ID */
+extern NSString *kSystemTabletID;
+
+/* vendor-defined pointer type */
+extern NSString *kVendorPointerType;
+
+ /* vendor-defined serial number of the specific pointing device */
+extern NSString *kPointerSerialNumber;
+
+ /* vendor-defined unique ID for this pointer */
+extern NSString *kUniqueID;
+
+/* mask representing the capabilities of the device */
+extern NSString *kCapabilityMask;
+
+ /* type of pointing device - enum to be defined */
+extern NSString *kPointerType;
+
+ /* non-zero = entering; zero = leaving */
+extern NSString *kEnterProximity;
diff --git a/sc4pd/headers/app/TextFinder.h b/sc4pd/headers/app/TextFinder.h
new file mode 100644
index 0000000..66de160
--- /dev/null
+++ b/sc4pd/headers/app/TextFinder.h
@@ -0,0 +1,64 @@
+/*
+ Reusable find panel functionality (find, replace).
+ Need one shared instance of TextFinder to which the menu items and widgets in the find panel are connected.
+ Loads UI lazily.
+ Works on first responder, assumed to be an NSTextView.
+*/
+
+#import <Cocoa/Cocoa.h>
+
+#define Forward YES
+#define Backward NO
+
+@interface TextFinder : NSObject {
+ NSString *findString;
+ NSString *replaceString;
+ id findTextField;
+ id replaceTextField;
+ id ignoreCaseButton;
+ id findNextButton;
+ id replaceAllScopeMatrix;
+ id statusField;
+ BOOL lastFindWasSuccessful;
+}
+
+/* Common way to get a text finder. One instance of TextFinder per app is good enough. */
++ (id)sharedInstance;
+
+/* Main method for external users; does a find in the first responder. Selects found range or beeps. */
+- (BOOL)find:(BOOL)direction;
+
+/* Loads UI lazily */
+- (NSPanel *)findPanel;
+
+/* Gets the first responder and returns it if it's an NSTextView */
+- (NSTextView *)textObjectToSearchIn;
+
+/* Get/set the current find string. Will update UI if UI is loaded */
+- (NSString *)findString;
+- (void)setFindString:(NSString *)string;
+- (void)setFindString:(NSString *)string writeToPasteboard:(BOOL)flag;
+
+/* Get/set the current replace string. Will update UI if UI is loaded */
+- (NSString *)replaceString;
+- (void)setReplaceString:(NSString *)string;
+
+/* Misc internal methods */
+- (void)appDidActivate:(NSNotification *)notification;
+- (void)loadFindStringFromPasteboard;
+- (void)loadStringToPasteboard:(NSString *)string;
+
+/* Action methods, sent from the find panel UI; can also be connected to menu items */
+- (void)findNext:(id)sender;
+- (void)findPrevious:(id)sender;
+- (void)findNextAndOrderFindPanelOut:(id)sender;
+- (void)replace:(id)sender;
+- (void)replaceAndFind:(id)sender;
+- (void)replaceAll:(id)sender;
+- (void)orderFrontFindPanel:(id)sender;
+- (void)takeFindStringFromSelection:(id)sender;
+- (void)takeReplaceStringFromSelection:(id)sender;
+- (void)jumpToSelection:(id)sender;
+
+@end
+
diff --git a/sc4pd/headers/app/UserPanel.h b/sc4pd/headers/app/UserPanel.h
new file mode 100644
index 0000000..4dd724b
--- /dev/null
+++ b/sc4pd/headers/app/UserPanel.h
@@ -0,0 +1,40 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#import <Cocoa/Cocoa.h>
+
+@interface UserPanel : NSObject
+{
+ IBOutlet id window;
+ void *scobject;
+}
+
++ (void)closeAll;
+
+- (id)init;
+- (NSWindow*)window;
+- (void)close;
+- (void)windowWillClose:(NSNotification *)aNotification;
+- (void)setSCObject: (void*)inObject;
+- (void*) getSCObject;
+
+- (IBAction) panelAction: (id) sender;
+
+@end
diff --git a/sc4pd/headers/common/SC_AllocPool.h b/sc4pd/headers/common/SC_AllocPool.h
new file mode 100644
index 0000000..fc9d72a
--- /dev/null
+++ b/sc4pd/headers/common/SC_AllocPool.h
@@ -0,0 +1,278 @@
+
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+This is based on Doug Lea's allocator but rewritten so I can read and understand it...
+also features of free all-at-once pools are added.
+Now uses 16 byte alignment, which does increase the minimum allocation size to 32 bytes
+including the overhead.
+Improved bit block scanning by using a count leading zeroes instruction.
+
+*/
+
+#ifndef _AllocPool_
+#define _AllocPool_
+
+#include "SC_List.h"
+#include "clz.h"
+#include <stdlib.h>
+
+const int kNumAllocBins = 128;
+const int kNumSmallBins = 64;
+const int kMaxSmallBin = kNumSmallBins - 1;
+const int kBinWidth = 8;
+const int kMaxSmallBinSize = kNumSmallBins * kBinWidth;
+const int kBinBlockWidth = 4;
+const int kBinBlockMask = kBinBlockWidth - 1;
+
+const size_t kAlign = 16;
+const size_t kAlignMask = kAlign - 1;
+const size_t kChunkFree = 0;
+const size_t kChunkInUse = 1;
+const size_t kSizeBits = ~kChunkInUse;
+
+class AllocChunk;
+class AllocPool;
+typedef AllocChunk *AllocChunkPtr;
+typedef Link<AllocChunk> AllocBin;
+typedef AllocBin* AllocBinPtr;
+
+class AllocChunk : public Link<AllocChunk>
+{
+ friend class AllocPool;
+
+ size_t Size()
+ { return mSize & kSizeBits; }
+
+ size_t PrevSize()
+ { return mPrevSize & kSizeBits; }
+
+ AllocChunkPtr ChunkAtOffset(size_t inSize)
+ { return AllocChunkPtr((char*)this + inSize); }
+
+ AllocChunkPtr NextChunk()
+ { return ChunkAtOffset(Size()); }
+
+ AllocChunkPtr PrevChunk()
+ { return ChunkAtOffset(-PrevSize()); }
+
+ bool InUse()
+ { return (bool)(mSize & kChunkInUse); }
+
+ bool PrevInUse()
+ { return (bool)(mPrevSize & kChunkInUse); }
+
+ void SetSizeFree(size_t inSize)
+ { mSize = ChunkAtOffset(inSize)->mPrevSize = inSize; }
+
+ void SetSizeInUse(size_t inSize)
+ { mSize = ChunkAtOffset(inSize)->mPrevSize = inSize | kChunkInUse; }
+
+ void SetNeighborsInUse(size_t inOffset)
+ { mPrevSize = ChunkAtOffset(inOffset)->mSize = kChunkInUse; }
+
+ bool IsArea()
+ { return mPrevSize == kChunkInUse && NextChunk()->mSize == kChunkInUse; }
+
+ void* ToPtr()
+ { return (void*)((char*)this + sizeof(AllocChunk)); }
+
+ size_t mPrevSize;
+ size_t mSize;
+};
+
+class AllocArea;
+typedef AllocArea* AllocAreaPtr;
+
+class AllocAreaHdr /* for size calculations */
+{
+protected:
+ friend class AllocPool;
+
+ AllocAreaPtr mPrev, mNext;
+ size_t mSize;
+ void *mUnalignedPointerToThis;
+};
+
+class AllocArea : public AllocAreaHdr
+{
+public:
+ void SanityCheck();
+
+private:
+ friend class AllocPool;
+
+ AllocChunk mChunk;
+};
+
+const size_t kMinAllocSize = 2 * kAlign;
+// FIXME: add kAlign to overhead? <sk>
+const size_t kAreaOverhead = sizeof(AllocAreaHdr) + 2 * sizeof(AllocChunk);
+
+typedef void* (*NewAreaFunc)(size_t size);
+typedef void (*FreeAreaFunc)(void *);
+
+class AllocPool
+{
+public:
+ AllocPool(NewAreaFunc allocArea, FreeAreaFunc freeArea,
+ size_t areaInitSize, size_t areaMoreSize);
+ ~AllocPool();
+
+ void Reinit();
+
+ void *Alloc(size_t inBytes);
+ void *Realloc(void* inPtr, size_t inBytes);
+ void Free(void* inPtr);
+ void FreeAll();
+ void FreeAllInternal();
+
+ // debugging
+ size_t TotalFree();
+ size_t LargestFreeChunk();
+
+ void DoCheckPool();
+ void DoCheckInUseChunk(AllocChunkPtr p);
+
+ static AllocChunkPtr MemToChunk(void *inPtr)
+ { return (AllocChunkPtr)((char*)(inPtr) - sizeof(AllocChunk)); }
+
+private:
+ void InitAlloc();
+ void InitBins();
+ AllocAreaPtr NewArea(size_t inAreaSize);
+ void FreeArea(AllocChunkPtr chunk);
+
+ // debugging
+ void DoCheckArea(AllocAreaPtr area);
+ void DoCheckBin(AllocChunkPtr bin, long idx);
+ void DoCheckChunk(AllocChunkPtr p);
+ void DoCheckFreeChunk(AllocChunkPtr p);
+ void DoCheckAllocedChunk(AllocChunkPtr p, size_t s);
+ void DoGarbageFill(AllocChunkPtr p);
+ void DoGarbageFill(AllocChunkPtr p, long size);
+
+ // inlines
+
+ static size_t RequestToSize(size_t inReqSize)
+ {
+ size_t sizePlusOverhead = inReqSize + sizeof(AllocChunk);
+ if (sizePlusOverhead <= kMinAllocSize) return kMinAllocSize;
+ else return (sizePlusOverhead + kAlignMask) & ~kAlignMask;
+ }
+
+ static int SmallBinIndex(size_t inSize)
+ { return inSize >> 4; }
+
+ static int BinIndex2(size_t inSize)
+ {
+ return
+ ((inSize < 1024) ? (inSize>>4):
+ (inSize < 2048) ? 56 + (inSize>>7):
+ (inSize < 4096) ? 64 + (inSize>>8):
+ (inSize < 8192) ? 72 + (inSize>>9):
+ (inSize < 16384) ? 80 + (inSize>>10):
+ (inSize < 32768) ? 88 + (inSize>>11):
+ (inSize < 65536) ? 96 + (inSize>>12):
+ (inSize < 131072) ? 104 + (inSize>>13):
+ (inSize < 262144) ? 112 + (inSize>>14):127);
+ }
+
+ static int BinIndex(size_t inSize)
+ {
+ if (inSize < 1024) return inSize >> 4;
+ if (inSize >= 262144) return 127;
+ int bits = 28 - CLZ(inSize);
+ return (bits << 3) + (inSize >> bits) ;
+ }
+
+ void MarkBinBlock(int inIndex)
+ {
+ unsigned long word = inIndex >> 5;
+ unsigned long bitPosition = inIndex & 31;
+ unsigned long bitValue = 1L << bitPosition;
+ mBinBlocks[word] |= bitValue;
+ }
+
+ void ClearBinBlock(int inIndex)
+ {
+ unsigned long word = inIndex >> 5;
+ unsigned long bitPosition = inIndex & 31;
+ unsigned long bitValue = 1L << bitPosition;
+ mBinBlocks[word] &= ~bitValue;
+ }
+
+ int NextFullBin(int inStartingBinIndex)
+ {
+ if (inStartingBinIndex >= 128) return -1;
+ int word = inStartingBinIndex >> 5;
+ int bitPosition = inStartingBinIndex & 31;
+ unsigned long bitValue = 1L << bitPosition;
+ unsigned long binBits = mBinBlocks[word];
+
+ if (binBits >= bitValue) {
+ binBits = (~(bitValue - 1) & binBits);
+ } else {
+ for (++word; word<4 && !mBinBlocks[word]; ++word) {}
+ if (word==4) return -1;
+ binBits = mBinBlocks[word];
+ }
+ bitPosition = CTZ((int32)binBits);
+
+ return (word << 5) + bitPosition;
+ }
+
+ void LinkFree(AllocChunkPtr inChunk);
+ /*
+ {
+ size_t size = inChunk->Size();
+ int index = BinIndex(size);
+
+ AllocChunkPtr bin = mBins + index;
+
+ if (index < kNumSmallBins || bin->IsEmpty()) {
+ inChunk->InsertAfter(bin);
+ MarkBinBlock(index);
+ } else {
+ AllocChunkPtr link = bin->Next();
+ while (link != bin && size < link->Size()) link = link->Next();
+ inChunk->InsertBefore(link);
+ }
+ }
+ */
+
+ void UnlinkFree(AllocChunkPtr inChunk)
+ {
+ inChunk->RemoveLeaveDangling();
+ size_t size = inChunk->Size();
+ int index = BinIndex(size);
+ AllocChunkPtr bin = mBins + index;
+ if (bin->IsEmpty()) ClearBinBlock(index);
+ }
+
+ AllocChunk mBins[kNumAllocBins];
+ AllocAreaPtr mAreas;
+ NewAreaFunc mAllocArea;
+ FreeAreaFunc mFreeArea;
+ size_t mAreaInitSize, mAreaMoreSize;
+ unsigned long mBinBlocks[4];
+};
+
+#endif
diff --git a/sc4pd/headers/common/SC_Altivec.h b/sc4pd/headers/common/SC_Altivec.h
new file mode 100644
index 0000000..8ae3f66
--- /dev/null
+++ b/sc4pd/headers/common/SC_Altivec.h
@@ -0,0 +1,118 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2003 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_Altivec_
+#define _SC_Altivec_
+
+#if defined(SC_LINUX) && defined(__ALTIVEC__)
+# include <altivec.h>
+#endif
+
+#if __VEC__
+
+typedef vector signed int vint32;
+typedef vector unsigned int vuint32;
+typedef vector float vfloat32;
+
+// Since gcc 3.3 vector initializers are surrounded by brackets. <sk>
+#if defined(__GNUC__) && (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 3)
+# define vinit(x) { x, x, x, x }
+#else
+# define vinit(x) ( x )
+#endif
+
+//#define vload(x) (*vtempptr = (x), vec_splat(vtemp,0))
+#define define_vtemp vfloat32 vtemp; float *vtempptr = (float*)&vtemp;
+#define define_vones vfloat32 vones = vec_ctf(vec_splat_s32(1),0);
+#define define_vzero vfloat32 vzero = (vfloat32)vec_splat_s32(0);
+#define vi0123 (vec_unpackh(vec_unpackh((vector signed char)vec_lvsl(0,(int*)0))))
+#define v0123 (vec_ctf(vec_unpackh(vec_unpackh((vector signed char)vec_lvsl(0,(int*)0))), 0))
+#define v0123_4ths (vec_ctf(vec_unpackh(vec_unpackh((vector signed char)vec_lvsl(0,(int*)0))), 2))
+#define vstart(x, vslope) (vec_madd(vslope, v0123_4ths, vload(x)))
+
+#define vec_not(a) (vtemp = (a); vec_nor(vtemp, vtemp))
+#define vec_cmplt(a, b) (vec_cmpgt(b, a))
+#define vec_cmple(a, b) (vec_cmpge(b, a))
+#define vec_mul(a, b) (vec_madd(a, b, vzero))
+#define vec_2sComp(x) (vec_sub(vec_sub (x, x), x))
+
+#define USEVEC (ft->mAltivecAvailable && !(BUFLENGTH & 3))
+
+typedef union vec_union {
+ int32 i[4];
+ float32 f[4];
+ vint32 vi;
+ vfloat32 vf;
+} vec_union;
+
+inline vfloat32 vload( float f )
+{
+ vec_union temp;
+ temp.f[0] = f;
+ return vec_splat( vec_lde( 0, temp.f ), 0 );
+}
+
+inline vint32 vload( int32 i )
+{
+ vec_union temp;
+ temp.i[0] = i;
+ return vec_splat( vec_lde( 0, temp.i ), 0 );
+}
+
+inline vint32 vload( int32 a, int32 b, int32 c, int32 d )
+{
+ vec_union temp;
+ temp.i[0] = a;
+ temp.i[1] = b;
+ temp.i[2] = c;
+ temp.i[3] = d;
+ return temp.vi;
+}
+
+inline vector float vec_float_1( void )
+{
+ return vec_ctf( vec_splat_u32(1), 0);
+}
+
+inline vector float vec_reciprocal( vector float v )
+{
+ vector float reciprocal = vec_re( v );
+ return vec_madd( reciprocal, vec_nmsub( reciprocal, v, vec_float_1()), reciprocal ); //Newton Rapheson refinement
+}
+
+#define vec_div(a, b) vec_mul(a, vec_reciprocal(b))
+
+// seed = ((seed & mask) << shift1) ^ (((seed << shift2) ^ seed) >> shift3);
+
+#define define_trshifts \
+ vuint32 trmask = ((vuint32)(0xFFFFFFFE,0xFFFFFFF8,0xFFFFFFF0,0)); \
+ vuint32 trshift1 = ((vuint32)(12, 14, 7, 0)); \
+ vuint32 trshift2 = ((vuint32)(13, 2, 3, 0)); \
+ vuint32 trshift3 = ((vuint32)(19, 25, 11, 0));
+
+inline vuint32 trands(vuint32 seed, vuint32 trmask, vuint32 shift1, vuint32 shift2, vuint32 shift3)
+{
+ return vec_xor(vec_sl(vec_and(seed, trmask),shift1), vec_sr(vec_xor(vec_sl(seed,shift2),seed),shift3));
+}
+
+#endif
+#endif
+
+
diff --git a/sc4pd/headers/common/SC_Endian.h b/sc4pd/headers/common/SC_Endian.h
new file mode 100644
index 0000000..ba127f5
--- /dev/null
+++ b/sc4pd/headers/common/SC_Endian.h
@@ -0,0 +1,64 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* NOTE: This file should declare/define the following functions/macros:
+
+ htonl
+ htons
+ ntohl
+ ntohs
+
+ either explicitly or implicitly by including system headers.
+*/
+
+#ifndef SC_ENDIAN_H_INCLUDED
+#define SC_ENDIAN_H_INCLUDED
+
+#ifdef SC_DARWIN
+
+# include <machine/endian.h>
+
+#elif defined(SC_WIN32)
+
+# define LITTLE_ENDIAN 1234
+# define BIG_ENDIAN 4321
+# define BYTE_ORDER LITTLE_ENDIAN
+# include <winsock2.h>
+
+#else
+
+# include <endian.h>
+# include <netinet/in.h>
+
+#endif
+
+#ifndef BYTE_ORDER
+# error BYTE_ORDER undefined, check __FILE__
+#endif // BYTE_ORDER
+
+#ifndef BIG_ENDIAN
+# error BIG_ENDIAN undefined, check __FILE__
+#endif // BIG_ENDIAN
+
+#ifndef LITTLE_ENDIAN
+# error LITTLE_ENDIAN undefined, check __FILE__
+#endif // LITTLE_ENDIAN
+
+#endif // SC_ENDIAN_H_INCLUDED
diff --git a/sc4pd/headers/common/SC_Sem.h b/sc4pd/headers/common/SC_Sem.h
new file mode 100644
index 0000000..22a2ffa
--- /dev/null
+++ b/sc4pd/headers/common/SC_Sem.h
@@ -0,0 +1,43 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Semaphore_
+#define _SC_Semaphore_
+
+#include <pthread.h>
+
+class SC_Semaphore
+{
+public:
+ SC_Semaphore(int initialCount);
+ ~SC_Semaphore();
+
+ void Acquire();
+ void Release();
+
+private:
+ pthread_cond_t available;
+ pthread_mutex_t mutex;
+ int count;
+};
+
+#endif
+
diff --git a/sc4pd/headers/common/SC_StringBuffer.h b/sc4pd/headers/common/SC_StringBuffer.h
new file mode 100644
index 0000000..24bcd4d
--- /dev/null
+++ b/sc4pd/headers/common/SC_StringBuffer.h
@@ -0,0 +1,67 @@
+// emacs: -*- c++ -*-
+// file: SC_StringBuffer.h
+// copyright: 2003 stefan kersten <steve@k-hornz.de>
+// cvs: $Id: SC_StringBuffer.h,v 1.1.1.1 2004-07-14 16:21:36 timblech Exp $
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+
+#ifndef SC_STRINGBUFFER_H_INCLUDED
+#define SC_STRINGBUFFER_H_INCLUDED
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+// =====================================================================
+// SC_StringBuffer - Autogrowing string buffer.
+// =====================================================================
+
+class SC_StringBuffer
+{
+public:
+ SC_StringBuffer(size_t initialSize=0);
+ SC_StringBuffer(const SC_StringBuffer& other);
+ ~SC_StringBuffer();
+
+ size_t getCapacity() const { return mCapacity; }
+ size_t getSize() const { return mPtr - mData; }
+ size_t getRemaining() const { return mCapacity - getSize(); }
+ char* getData() const { return mData; }
+
+ bool isEmpty() const { return getSize() == 0; }
+
+ void finish() { append('\0'); }
+ void reset() { mPtr = mData; }
+ void append(const char* src, size_t len);
+ void append(char c);
+ void append(const char* str);
+ void vappendf(const char* fmt, va_list vargs);
+ void appendf(const char* fmt, ...);
+
+protected:
+ enum {
+ kGrowAlign = 256,
+ kGrowMask = kGrowAlign - 1
+ };
+
+ void growBy(size_t request);
+
+private:
+ size_t mCapacity;
+ char* mPtr;
+ char* mData;
+};
+
+#endif // SC_STRINGBUFFER_H_INCLUDED
diff --git a/sc4pd/headers/common/SC_StringParser.h b/sc4pd/headers/common/SC_StringParser.h
new file mode 100644
index 0000000..f2d414e
--- /dev/null
+++ b/sc4pd/headers/common/SC_StringParser.h
@@ -0,0 +1,40 @@
+// emacs: -*- c++ -*-
+// file: SC_StringParser.h
+// copyright: 2003 stefan kersten <steve@k-hornz.de>
+// cvs: $Id: SC_StringParser.h,v 1.1.1.1 2004-07-14 16:21:37 timblech Exp $
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+
+#ifndef _SC_StringParser_
+#define _SC_StringParser_
+
+#define SC_MAX_TOKEN_LENGTH 256
+
+class SC_StringParser
+{
+ char *mSpec, *mStart, *mEnd;
+ char mSep, mBuf[SC_MAX_TOKEN_LENGTH];
+
+public:
+ SC_StringParser();
+ SC_StringParser(char *spec, char sep);
+
+ bool AtEnd() const;
+ const char *NextToken();
+};
+
+#endif
+
diff --git a/sc4pd/headers/common/dfftlib.h b/sc4pd/headers/common/dfftlib.h
new file mode 100644
index 0000000..409267e
--- /dev/null
+++ b/sc4pd/headers/common/dfftlib.h
@@ -0,0 +1,62 @@
+long dFFTInit(long *fftMptr, long fftN, double *Utbl);
+/* Compute cosine table and check size for complex ffts */
+/* INPUTS */
+/* fftN = size of fft */
+/* OUTPUTS */
+/* *fftMptr = log2 of fft size */
+/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */
+/* RETURNS */
+/* 1 if fftN is invalid, 0 otherwise */
+
+long drFFTInit(long *fftMptr, long fftN, double *Utbl);
+/* Compute cosine table and check size for a real input fft */
+/* INPUTS */
+/* fftN = size of fft */
+/* OUTPUTS */
+/* *fftMptr = log2 of fft size */
+/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */
+/* RETURNS */
+/* 1 if fftN is invalid, 0 otherwise */
+
+void dffts(double *ioptr, long M, long Rows, double *Utbl);
+/* Compute in-place complex fft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = input data array */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = output data array */
+
+void diffts(double *ioptr, long M, long Rows, double *Utbl);
+/* Compute in-place inverse complex fft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = input data array */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = output data array */
+
+void drffts(double *ioptr, long M, long Rows, double *Utbl);
+/* Compute in-place real fft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = real input data array */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = output data array in the following order */
+/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */
+
+
+void driffts(double *ioptr, long M, long Rows, double *Utbl);
+/* Compute in-place real ifft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = input data array in the following order */
+/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = real output data array */
diff --git a/sc4pd/headers/common/fftlib.h b/sc4pd/headers/common/fftlib.h
new file mode 100644
index 0000000..b03317d
--- /dev/null
+++ b/sc4pd/headers/common/fftlib.h
@@ -0,0 +1,62 @@
+long FFTInit(long *fftMptr, long fftN, float *Utbl);
+/* Compute cosine table and check size for complex ffts */
+/* INPUTS */
+/* fftN = size of fft */
+/* OUTPUTS */
+/* *fftMptr = log2 of fft size */
+/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */
+/* RETURNS */
+/* 1 if fftN is invalid, 0 otherwise */
+
+long rFFTInit(long *fftMptr, long fftN, float *Utbl);
+/* Compute cosine table and check size for a real input fft */
+/* INPUTS */
+/* fftN = size of fft */
+/* OUTPUTS */
+/* *fftMptr = log2 of fft size */
+/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */
+/* RETURNS */
+/* 1 if fftN is invalid, 0 otherwise */
+
+void ffts(float *ioptr, long M, long Rows, float *Utbl);
+/* Compute in-place complex fft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = input data array */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = output data array */
+
+void iffts(float *ioptr, long M, long Rows, float *Utbl);
+/* Compute in-place inverse complex fft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = input data array */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = output data array */
+
+void rffts(float *ioptr, long M, long Rows, float *Utbl);
+/* Compute in-place real fft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = real input data array */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = output data array in the following order */
+/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */
+
+
+void riffts(float *ioptr, long M, long Rows, float *Utbl);
+/* Compute in-place real ifft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = input data array in the following order */
+/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = real output data array */
diff --git a/sc4pd/headers/common/scsynthsend.h b/sc4pd/headers/common/scsynthsend.h
new file mode 100644
index 0000000..97f345b
--- /dev/null
+++ b/sc4pd/headers/common/scsynthsend.h
@@ -0,0 +1,191 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _scpacket_
+#define _scpacket_
+
+#include "SC_Endian.h"
+#include "SC_Types.h"
+#include <stdexcept>
+
+struct netaddr {
+ int socket;
+ int addr;
+ int port;
+};
+typedef struct netaddr netaddr;
+
+#define kSCMaxPacketSize 8192
+
+struct scpacket {
+ int32 *wrpos, *endpos, *msgsizepos;
+ char *tagwrpos;
+ int inbundle;
+ int32 buf[kSCMaxPacketSize];
+
+ scpacket();
+ void reset();
+ void addi(int i);
+ void addii(int64 ii);
+ void addf(float f);
+ void addd(double f);
+ void adds(char *cstr);
+ void adds(char *src, size_t len);
+ void addb(uint8 *src, size_t len);
+ void addtag(char c);
+ void skip(int n);
+ void maketags(int n);
+ int size() { return (char*)wrpos - (char*)buf; }
+ char* data() { return (char*)buf; }
+
+ void sendudp(int socket, int addr, int port);
+
+ void OpenBundle(int64 time);
+ void CloseBundle();
+
+ void BeginMsg();
+ void EndMsg();
+};
+
+inline scpacket::scpacket() { reset(); }
+
+// ways to fail
+#define BUFFEROVERFLOW return
+//#define BUFFEROVERFLOW throw std::runtime_error("buffer overflow")
+
+inline void scpacket::reset()
+{
+ wrpos = buf;
+ endpos = buf + kSCMaxPacketSize;
+ inbundle = 0;
+}
+
+inline void scpacket::skip(int n)
+{
+ if (wrpos + n > endpos) BUFFEROVERFLOW;
+ wrpos += n;
+}
+
+inline void scpacket::addtag(char c)
+{
+ *tagwrpos++ = c;
+}
+
+inline void scpacket::maketags(int n)
+{
+ int size4 = (n + 4) >> 2;
+ tagwrpos = (char*)wrpos;
+ skip(size4);
+ wrpos[-1] = 0;
+}
+
+
+inline void scpacket::addi(int i)
+{
+ if (wrpos >= endpos) BUFFEROVERFLOW;
+ *wrpos++ = htonl(i);
+}
+
+inline void scpacket::addii(int64 ii)
+{
+ int i;
+ i = (int)(ii >> 32);
+ addi(i);
+ i = (int)ii;
+ addi(i);
+}
+
+inline void scpacket::addf(float f)
+{
+ if (wrpos >= endpos) BUFFEROVERFLOW;
+ elem32 slot;
+ slot.f = f;
+ *wrpos++ = htonl(slot.i);
+}
+
+inline void scpacket::addd(double f)
+{
+ if (wrpos >= endpos) BUFFEROVERFLOW;
+ elem64 slot;
+ slot.f = f;
+ *wrpos++ = htonl(slot.i >> 32);
+ *wrpos++ = htonl(slot.i & 0x00000000FFFFFFFF);
+}
+
+inline void scpacket::adds(char *src)
+{
+ size_t len = strlen(src);
+ size_t len4 = (len + 4) >> 2;
+ if (wrpos + len4 > endpos) BUFFEROVERFLOW;
+ wrpos[len4 - 1] = 0;
+ memcpy(wrpos, src, (size_t)len);
+ wrpos += len4;
+}
+
+inline void scpacket::adds(char *src, size_t len)
+{
+ size_t len4 = (len + 4) >> 2;
+ if (wrpos + len4 > endpos) BUFFEROVERFLOW;
+ wrpos[len4 - 1] = 0;
+ memcpy(wrpos, src, (size_t)len);
+ wrpos += len4;
+}
+
+// support binary objects
+inline void scpacket::addb(uint8 *src, size_t len)
+{
+ size_t len4 = (len + 3) >> 2;
+ if (wrpos + (len4 + 1) > endpos) BUFFEROVERFLOW;
+ wrpos[len4 - 1] = 0;
+ int32 swaplen = len;
+ *wrpos++ = htonl(swaplen);
+ memcpy(wrpos, src, (size_t)len);
+ wrpos += len4;
+}
+
+inline void scpacket::OpenBundle(int64 time)
+{
+ inbundle++;
+ adds("#bundle");
+ addii(time);
+}
+
+inline void scpacket::CloseBundle()
+{
+ if (inbundle) inbundle--;
+}
+
+inline void scpacket::BeginMsg()
+{
+ if (inbundle) {
+ msgsizepos = wrpos;
+ addi(0);
+ }
+}
+
+inline void scpacket::EndMsg()
+{
+ if (inbundle) {
+ *msgsizepos = htonl(((wrpos - msgsizepos) - 1) * sizeof(int32));
+ }
+}
+
+#endif
+
diff --git a/sc4pd/headers/lang/AdvancingAllocPool.h b/sc4pd/headers/lang/AdvancingAllocPool.h
new file mode 100644
index 0000000..b89d69b
--- /dev/null
+++ b/sc4pd/headers/lang/AdvancingAllocPool.h
@@ -0,0 +1,82 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+AdvancingAllocPool implements a simple advancing pointer allocation scheme.
+There is no Free(). All objects in the pool are freed at once with FreeAll().
+Thus it is very fast.
+
+*/
+
+#ifndef _AdvancingAllocPool_
+#define _AdvancingAllocPool_
+
+#include <stdexcept>
+#include <stdlib.h>
+
+class AllocPool;
+
+struct AdvancingAllocPoolChunk;
+
+typedef int int32;
+
+inline void FailNil(void *ptr) {
+ if (!ptr) throw std::runtime_error("alloc failed");
+}
+
+struct AdvancingAllocPoolChunkHdr {
+ AdvancingAllocPoolChunk *mNext;
+ size_t mSize;
+ int32 mPad1, mPad2;
+};
+
+struct AdvancingAllocPoolChunk {
+ AdvancingAllocPoolChunk *mNext;
+ size_t mSize;
+ int32 mPad1, mPad2;
+ char mSpace[16];
+};
+
+class AdvancingAllocPool
+{
+public:
+ AdvancingAllocPool();
+ ~AdvancingAllocPool() { FreeAll(); }
+
+ void Init(AllocPool *inAllocPool, size_t initSize, size_t growSize, size_t tooBigSize);
+
+ void *Alloc(size_t inBytes);
+ void FreeAll();
+
+ bool SanityCheck();
+
+private:
+ void AddChunk(size_t inSize);
+
+ AllocPool* mAllocPool;
+ size_t mInitSize;
+ size_t mGrowSize;
+ size_t mCurSize;
+ size_t mTooBig;
+ AdvancingAllocPoolChunk *mChunks;
+ AdvancingAllocPoolChunk *mFatties;
+};
+
+#endif
diff --git a/sc4pd/headers/lang/AllocPools.h b/sc4pd/headers/lang/AllocPools.h
new file mode 100644
index 0000000..111f7c3
--- /dev/null
+++ b/sc4pd/headers/lang/AllocPools.h
@@ -0,0 +1,34 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+Pools for memory allocation.
+
+*/
+
+
+#ifndef _AllocPools_
+#define _AllocPools_
+
+class AllocPool;
+extern AllocPool *pyr_pool_compile;
+extern AllocPool *pyr_pool_runtime;
+
+#endif
diff --git a/sc4pd/headers/lang/ByteCodeArray.h b/sc4pd/headers/lang/ByteCodeArray.h
new file mode 100644
index 0000000..5ec1520
--- /dev/null
+++ b/sc4pd/headers/lang/ByteCodeArray.h
@@ -0,0 +1,50 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+typedef unsigned char Byte;
+
+#define BYTE_CODE_CHUNK_SIZE 64
+
+typedef struct {
+ Byte *bytes;
+ Byte *ptr;
+ long size;
+} ByteCodeArray, *ByteCodes;
+
+extern ByteCodes gCompilingByteCodes;
+extern long totalByteCodes;
+
+void initByteCodes();
+void compileByte(long byte);
+void compileAndFreeByteCodes(ByteCodes byteCodes);
+void copyByteCodes(Byte *dest, ByteCodes byteCodes);
+ByteCodes getByteCodes();
+ByteCodes saveByteCodeArray();
+void restoreByteCodeArray(ByteCodes byteCodes);
+int byteCodeLength(ByteCodes byteCodes);
+void compileByteCodes(ByteCodes byteCodes);
+ByteCodes allocByteCodes();
+void reallocByteCodes(ByteCodes byteCodes);
+void freeByteCodes(ByteCodes byteCodes);
+int compileOpcode(long opcode, long operand1);
+void compileJump(long opcode, long jumplen);
+int compileNumber(unsigned long value);
+int compileNumber24(unsigned long value);
+
diff --git a/sc4pd/headers/lang/FIFOT.h b/sc4pd/headers/lang/FIFOT.h
new file mode 100644
index 0000000..52b6203
--- /dev/null
+++ b/sc4pd/headers/lang/FIFOT.h
@@ -0,0 +1,75 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+A Fifo for sending/receiving some type of object.
+
+*/
+
+#ifndef _FIFOT_
+#define _FIFOT_
+
+template <class T, int N> class FIFOT
+{
+public:
+ FIFOT()
+ : mMask(N-1), mReadHead(0), mWriteHead(0)
+ {
+ }
+ void MakeEmpty() { mReadHead = mWriteHead; }
+ bool IsEmpty() { return mReadHead == mWriteHead; }
+ int CanGet() {
+ int diff = mWriteHead - mReadHead;
+ return diff >= 0 ? diff : N - diff;
+ }
+ int CanPut() { return N-1-CanGet(); }
+
+ int NextPos(int inPos) { return (inPos + 1) & mMask; }
+
+ bool Put(const T& inItem)
+ {
+ long next = NextPos(mWriteHead);
+ if (next == mReadHead) return false; // fifo is full
+ mItems[next] = inItem;
+ mWriteHead = next;
+ return true;
+ }
+
+ bool Get(T& outItem) // get next and advance
+ {
+ if (IsEmpty()) return false;
+ long next = NextPos(mReadHead);
+ outItem = mItems[next];
+ mReadHead = next;
+ return true;
+ }
+ void DebugDump()
+ {
+ post("FIFO N %d mMask %d mReadHead %d mWriteHead%d\n",
+ N, mMask, mReadHead, mWriteHead);
+ }
+
+private:
+ long mMask;
+ volatile long mReadHead, mWriteHead;// mReclaimHead;
+ T mItems[N];
+};
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/GC.h b/sc4pd/headers/lang/GC.h
new file mode 100644
index 0000000..4dc162a
--- /dev/null
+++ b/sc4pd/headers/lang/GC.h
@@ -0,0 +1,263 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+The garbage collector for SuperCollider.
+Based on Wilson and Johnstone's real time collector and the Baker treadmill.
+
+*/
+
+#ifndef _GC_
+#define _GC_
+
+#include "PyrObject.h"
+#include "VMGlobals.h"
+#include "AdvancingAllocPool.h"
+
+void DumpSimpleBackTrace(VMGlobals *g);
+
+const int kMaxPoolSet = 7;
+const int kNumGCSizeClasses = 28;
+const int kFinalizerSet = kNumGCSizeClasses;
+const int kNumGCSets = kNumGCSizeClasses + 1;
+
+class GCSet
+{
+public:
+ GCSet() {}
+ void Init(int inSizeClass);
+
+ bool HasFree() { return mFree != &mBlack; }
+
+private:
+ friend class PyrGC;
+
+ void MoveWhiteToFree();
+
+ PyrObjectHdr mBlack;
+ PyrObjectHdr mWhite;
+ PyrObjectHdr* mFree;
+};
+
+struct SlotRef {
+ SlotRef(PyrObject* inObj, int32 inIndex) : obj(inObj), slotIndex(inIndex) {}
+
+ PyrObject *obj;
+ int32 slotIndex;
+};
+
+class PyrGC
+{
+public:
+ PyrGC(VMGlobals *g, AllocPool *inPool, PyrClass *mainProcessClass, long poolSize);
+
+ PyrObject* New(size_t inNumBytes, long inFlags, long inFormat, bool inCollect);
+
+ static PyrObject* NewPermanent(size_t inNumBytes,
+ long inFlags, long inFormat);
+
+ PyrObject* NewFinalizer(ObjFuncPtr finalizeFunc, PyrObject *inObject, bool inCollect);
+
+ int32 ProcessID() { return mProcessID; }
+
+#if 0
+// Codewarrior is not inlining these.. why?
+ bool IsBlack(PyrObjectHdr* inObj) { return inObj->gc_color == mBlackColor; }
+ bool IsWhite(PyrObjectHdr* inObj) { return inObj->gc_color == mWhiteColor; }
+ bool IsGrey(PyrObjectHdr* inObj) { return inObj->gc_color == mGreyColor; }
+ bool IsMarker(PyrObjectHdr* inObj) { return inObj->gc_color == obj_gcmarker; }
+#else
+
+#define IsBlack(inObj) ((inObj)->gc_color == mBlackColor)
+#define IsWhite(inObj) ((inObj)->gc_color == mWhiteColor)
+#define IsGrey(inObj) ((inObj)->gc_color == mGreyColor)
+#define IsFree(inObj) (!(IsMarker(inObj) || inObj->IsPermanent() || \
+ IsBlack(inObj) || IsWhite(inObj) || IsGrey(inObj)))
+#define IsMarker(inObj) ((inObj)->gc_color == obj_gcmarker)
+#endif
+
+ bool ObjIsBlack(PyrObjectHdr* inObj) { return IsBlack(inObj); }
+ bool ObjIsGrey(PyrObjectHdr* inObj) { return IsGrey(inObj); }
+ bool ObjIsFree(PyrObjectHdr* inObj) { return IsFree(inObj); }
+
+
+ // general purpose write barriers:
+ void GCWrite(PyrObjectHdr* inParent, PyrSlot* inSlot)
+ {
+ if (IsBlack(inParent) && IsObj(inSlot) && IsWhite(inSlot->uo)) {
+ ToGrey(inSlot->uo);
+ }
+ }
+ void GCWrite(PyrObjectHdr* inParent, PyrObjectHdr* inChild)
+ {
+ if (IsBlack(inParent) && IsWhite(inChild)) {
+ ToGrey(inChild);
+ }
+ }
+ // when you know the parent is black:
+ void GCWriteBlack(PyrSlot* inSlot)
+ {
+ if (IsObj(inSlot)) {
+ if (IsWhite(inSlot->uo)) {
+ ToGrey(inSlot->uo);
+ }
+ }
+ }
+ void GCWriteBlack(PyrObjectHdr* inChild)
+ {
+ if (IsWhite(inChild)) {
+ ToGrey(inChild);
+ }
+ }
+ // when you know the child is white
+ void GCWriteNew(PyrObjectHdr* inParent, PyrObjectHdr* inChild)
+ {
+ if (IsBlack(inParent)) {
+ ToGrey(inChild);
+ }
+ }
+
+// users should not call anything below.
+
+ void Collect();
+ void Collect(int32 inNumToScan);
+ void FullCollection();
+ void ScanFinalizers();
+ GCSet* GetGCSet(PyrObjectHdr* inObj);
+ void CompletePartialScan(PyrObject *obj);
+
+ void ToGrey(PyrObjectHdr* inObj);
+ void ToGrey2(PyrObjectHdr* inObj);
+ void ToBlack(PyrObjectHdr* inObj);
+ void ToWhite(PyrObjectHdr *obj);
+
+ int32 StackDepth() { return mVMGlobals->sp - mStack->slots + 1; }
+ PyrObject* Stack() { return mStack; }
+ void SetStack(PyrObject* inStack) { mStack = inStack; }
+
+ bool SanityCheck();
+ bool SanityCheck2();
+ bool LinkSanity();
+ bool ListSanity();
+ bool BlackToWhiteCheck(PyrObject *objA);
+ bool SanityMarkObj(PyrObject *objA, PyrObject *fromObj, int level);
+ bool SanityClearObj(PyrObject *objA, int level);
+ void DumpInfo();
+ void DumpEverything();
+
+ void BecomePermanent(PyrObject *inObject);
+ void BecomeImmutable(PyrObject *inObject);
+
+private:
+ void Free(PyrObject* inObj);
+ void ScanSlots(PyrSlot *inSlots, long inNumToScan);
+ void SweepBigObjects();
+ void DoPartialScan(int32 inObjSize);
+ bool ScanOneObj();
+ void Flip();
+ void ScanStack();
+ void DLRemove(PyrObjectHdr *obj);
+ void DLInsertAfter(PyrObjectHdr *after, PyrObjectHdr *obj);
+ void DLInsertBefore(PyrObjectHdr *before, PyrObjectHdr *obj);
+
+ void ClearMarks();
+ void Finalize(PyrObject *obj);
+
+ VMGlobals *mVMGlobals;
+ AllocPool *mPool;
+ AdvancingAllocPool mNewPool;
+ GCSet mSets[kNumGCSets];
+ PyrProcess *mProcess; // the root is the pyrprocess which contains this struct
+ PyrObject *mStack;
+ PyrObject *mPartialScanObj;
+ PyrObjectHdr mGrey;
+
+ GCSet *mPartialScanSet;
+ int32 mPartialScanSlot;
+ int32 mNumToScan;
+ int32 mNumGrey;
+ int32 mCurSet;
+
+ int32 mFlips, mCollects, mAllocTotal, mScans, mNumAllocs;
+
+ unsigned char mBlackColor, mGreyColor, mWhiteColor, mFreeColor;
+ int8 mProcessID;
+ bool mCanSweep;
+ bool mRunning;
+};
+
+inline void PyrGC::DLRemove(PyrObjectHdr *obj)
+{
+ obj->next->prev = obj->prev;
+ obj->prev->next = obj->next;
+}
+
+inline void PyrGC::DLInsertAfter(PyrObjectHdr *after, PyrObjectHdr *obj)
+{
+ obj->next = after->next;
+ obj->prev = after;
+ after->next->prev = obj;
+ after->next = obj;
+}
+
+inline void PyrGC::DLInsertBefore(PyrObjectHdr *before, PyrObjectHdr *obj)
+{
+ obj->prev = before->prev;
+ obj->next = before;
+ before->prev->next = obj;
+ before->prev = obj;
+}
+
+inline GCSet* PyrGC::GetGCSet(PyrObjectHdr* inObj)
+{
+ return mSets + (inObj->classptr == class_finalizer ? kFinalizerSet : inObj->obj_sizeclass);
+}
+
+inline void PyrGC::ToBlack(PyrObjectHdr *obj)
+{
+ if (IsGrey(obj)) {
+ mNumGrey--;
+ //post("ToBlack %d\n", mNumGrey);
+ }
+
+ DLRemove(obj);
+
+ GCSet *gcs = GetGCSet(obj);
+ DLInsertAfter(&gcs->mBlack, obj);
+
+ obj->gc_color = mBlackColor;
+}
+
+inline void PyrGC::ToWhite(PyrObjectHdr *obj)
+{
+ if (IsGrey(obj)) {
+ mNumGrey--;
+ //post("ToWhite %d\n", mNumGrey);
+ }
+
+ DLRemove(obj);
+
+ GCSet *gcs = GetGCSet(obj);
+ DLInsertAfter(&gcs->mWhite, obj);
+
+ obj->gc_color = mWhiteColor;
+}
+
+#endif
diff --git a/sc4pd/headers/lang/HashTable.h b/sc4pd/headers/lang/HashTable.h
new file mode 100644
index 0000000..835f593
--- /dev/null
+++ b/sc4pd/headers/lang/HashTable.h
@@ -0,0 +1,274 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _HashTable_
+#define _HashTable_
+
+#include "SC_Types.h"
+#include "SC_BoundsMacros.h"
+#include "Hash.h"
+#include <stddef.h>
+
+template<class T, class Allocator, class KeyType>
+class HashTable
+{
+ Allocator *mPool;
+ int32 mNumItems, mMaxItems, mTableSize, mHashMask;
+ T** mItems;
+ bool mCanResize;
+
+public:
+
+ HashTable(Allocator *inPool, int32 inMaxItems, bool inCanResize = true)
+ : mPool(inPool)
+ {
+ mNumItems = 0;
+ mMaxItems = inMaxItems;
+ mTableSize = mMaxItems << 1;
+ mItems = AllocTable(mTableSize);
+ mHashMask = mTableSize - 1;
+ mCanResize = inCanResize;
+ }
+
+ ~HashTable() {
+ mPool->Free(mItems);
+ }
+
+ int32 TableSize() const { return mTableSize; }
+ int32 MaxItems() const { return mMaxItems; }
+ int32 NumItems() const { return mNumItems; }
+
+ T** AllocTable(int inTableSize)
+ {
+ size_t size = inTableSize * sizeof(T*);
+ T** items = static_cast<T**>(mPool->Alloc(size));
+ for (int i=0; i<inTableSize; ++i) {
+ items[i] = 0;
+ }
+ return items;
+ }
+
+ void Resize()
+ {
+ int32 newSize = sc_max(mTableSize << 1, 32);
+ T** oldItems = mItems;
+ mItems = AllocTable(newSize);
+ for (int i=0; i<mTableSize; ++i) {
+ T* item = oldItems[i];
+ if (item) Add(item);
+ }
+ mTableSize = newSize;
+ mMaxItems = mTableSize >> 1;
+ mHashMask = mTableSize - 1;
+ mPool->Free(oldItems);
+ //printf("mMaxItems %d mTableSize %d newSize %d\n", mMaxItems, mTableSize, newSize);
+ }
+
+ bool Add(T* inItem)
+ {
+ //printf("mNumItems %d\n", mNumItems);
+ //printf("mMaxItems %d\n", mMaxItems);
+ //printf("mCanResize %d\n", mCanResize);
+ if (mNumItems >= mMaxItems) {
+ if (!mCanResize) return false;
+ Resize();
+ }
+
+ //printf("GetHash(inItem) %d\n", GetHash(inItem));
+ //printf("GetKey(inItem) %s\n", GetKey(inItem));
+ int32 index = IndexFor(GetHash(inItem), GetKey(inItem));
+ //printf("index %d\n", index);
+
+ T *item = mItems[index];
+ if (item) return item == inItem;
+
+ mItems[index] = inItem;
+ mNumItems++;
+ return true;
+ }
+
+ bool Remove(T* inItem)
+ {
+ int32 index = IndexFor(GetHash(inItem), GetKey(inItem));
+ if (mItems[index] != inItem) return false;
+ mItems[index] = 0;
+
+ FixCollisionsFrom(index);
+ mNumItems--;
+ return true;
+ }
+
+ int32 IndexFor(int32 inHashID, KeyType inKey) const
+ {
+ int index = inHashID & mHashMask;
+ for(;;) {
+ T *item = mItems[index];
+ if (!item) return index;
+ if (GetHash(item) == inHashID
+ && strcmp(inKey, GetKey(item)) == 0) return index;
+ index = (index + 1) & mHashMask;
+ }
+ }
+
+ T* Get(KeyType inKey) const
+ {
+ return Get(Hash(inKey), inKey);
+ }
+
+ T* Get(int32 inHashID, KeyType inKey) const
+ {
+ int32 index = IndexFor(inHashID, inKey);
+ return mItems[index];
+ }
+
+ bool Includes(T* inItem) const
+ {
+ return Get(GetHash(inItem), GetKey(inItem)) == inItem;
+ }
+
+ T* AtIndex(int32 inIndex) const
+ {
+ return mItems[inIndex];
+ }
+
+private:
+ void FixCollisionsFrom(int32 inIndex)
+ {
+ int oldIndex = inIndex;
+ for (;;) {
+ oldIndex = (oldIndex + 1) & mHashMask;
+ T *oldItem = mItems[oldIndex];
+ if (!oldItem) break;
+ int newIndex = IndexFor(GetHash(oldItem), GetKey(oldItem));
+ if (oldIndex != newIndex) {
+ mItems[oldIndex] = mItems[newIndex];
+ mItems[newIndex] = oldItem;
+ }
+ }
+ }
+};
+
+template<class T, int kMaxItems, class KeyType>
+class StaticHashTable
+{
+ int32 mNumItems, mTableSize, mHashMask;
+ T* mItems[kMaxItems*2];
+
+public:
+
+ StaticHashTable()
+ {
+ mNumItems = 0;
+ mTableSize = kMaxItems << 1;
+ ClearTable();
+ mHashMask = mTableSize - 1;
+ }
+
+ ~StaticHashTable() {
+ }
+
+ int32 TableSize() const { return mTableSize; }
+ int32 MaxItems() const { return kMaxItems; }
+ int32 NumItems() const { return mNumItems; }
+
+ void ClearTable()
+ {
+ for (int i=0; i<mTableSize; ++i) {
+ mItems[i] = 0;
+ }
+ }
+
+ bool Add(T* inItem)
+ {
+ if (mNumItems >= kMaxItems) return false;
+
+ int32 index = IndexFor(GetHash(inItem), GetKey(inItem));
+
+ T *item = mItems[index];
+ if (item) return item == inItem;
+
+ mItems[index] = inItem;
+ mNumItems++;
+ return true;
+ }
+
+ bool Remove(T* inItem)
+ {
+ int32 index = IndexFor(GetHash(inItem), GetKey(inItem));
+ if (mItems[index] != inItem) return false;
+ mItems[index] = 0;
+
+ FixCollisionsFrom(index);
+ mNumItems--;
+ return true;
+ }
+
+ int32 IndexFor(int32 inHashID, KeyType inKey) const
+ {
+ int index = inHashID & mHashMask;
+ for(;;) {
+ T *item = mItems[index];
+ if (!item) return index;
+ if (GetHash(item) == inHashID
+ && strcmp(inKey, GetKey(item)) == 0) return index;
+ index = (index + 1) & mHashMask;
+ }
+ }
+
+ T* Get(KeyType inKey) const
+ {
+ return Get(Hash(inKey), inKey);
+ }
+
+ T* Get(int32 inHashID, KeyType inKey) const
+ {
+ int32 index = IndexFor(inHashID, inKey);
+ return mItems[index];
+ }
+
+ bool Includes(T* inItem) const
+ {
+ return Get(GetHash(inItem), GetKey(inItem)) == inItem;
+ }
+
+ T* AtIndex(int32 inIndex) const
+ {
+ return mItems[inIndex];
+ }
+
+private:
+ void FixCollisionsFrom(int32 inIndex)
+ {
+ int oldIndex = inIndex;
+ for (;;) {
+ oldIndex = (oldIndex + 1) & mHashMask;
+ T *oldItem = mItems[oldIndex];
+ if (!oldItem) break;
+ int newIndex = IndexFor(GetHash(oldItem), GetKey(oldItem));
+ if (oldIndex != newIndex) {
+ mItems[oldIndex] = mItems[newIndex];
+ mItems[newIndex] = oldItem;
+ }
+ }
+ }
+};
+
+
+#endif
diff --git a/sc4pd/headers/lang/InitAlloc.h b/sc4pd/headers/lang/InitAlloc.h
new file mode 100644
index 0000000..762b940
--- /dev/null
+++ b/sc4pd/headers/lang/InitAlloc.h
@@ -0,0 +1,32 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _InitAlloc_
+#define _InitAlloc_
+
+#include "SCBase.h"
+#include "SC_AllocPool.h"
+#include <stdexcept>
+
+#define MEMFAIL(ptr) if (!(ptr)) { throw std::runtime_error("Out of memory!\n"); }
+#define MEMFAILED throw std::runtime_error("Out of memory!\n");
+
+#endif
+
diff --git a/sc4pd/headers/lang/MiscInlineMath.h b/sc4pd/headers/lang/MiscInlineMath.h
new file mode 100644
index 0000000..6dd33ab
--- /dev/null
+++ b/sc4pd/headers/lang/MiscInlineMath.h
@@ -0,0 +1,54 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define NUMPRIMES 6542
+long nthPrime(int n);
+long findPrime(int n);
+long prevPrime(int n);
+long nextPrime(int n);
+
+
+inline double linlin(double x, double a, double b, double c, double d)
+{
+ if (x <= a) return c;
+ if (x >= b) return d;
+ return (x-a)/(b-a) * (d-c) + c;
+}
+
+inline double explin(double x, double a, double b, double c, double d)
+{
+ if (x <= a) return c;
+ if (x >= b) return d;
+ return (log(x/a)) / (log(b/a)) * (d-c) + c;
+}
+
+inline double expexp(double x, double a, double b, double c, double d)
+{
+ if (x <= a) return c;
+ if (x >= b) return d;
+ return pow(d/c, log(x/a)) / (log(b/a)) * c;
+}
+
+inline double linexp(double x, double a, double b, double c, double d)
+{
+ if (x <= a) return c;
+ if (x >= b) return d;
+ return pow(d/c, (x-a)/(b-a)) * c;
+}
diff --git a/sc4pd/headers/lang/OSCData.h b/sc4pd/headers/lang/OSCData.h
new file mode 100644
index 0000000..b2721b0
--- /dev/null
+++ b/sc4pd/headers/lang/OSCData.h
@@ -0,0 +1 @@
+/* SuperCollider real time audio synthesis system Copyright (c) 2002 James McCartney. All rights reserved. http://www.audiosynth.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OSCData_ #define _OSCData_ #include "PyrObject.h" #include "FIFOT.h" #include <netinet/in.h> #endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/Opcodes.h b/sc4pd/headers/lang/Opcodes.h
new file mode 100644
index 0000000..c5e1c7a
--- /dev/null
+++ b/sc4pd/headers/lang/Opcodes.h
@@ -0,0 +1,426 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _OPCODES_H_
+#define _OPCODES_H_
+
+/* opcodes */
+enum {
+ opExtended, // 0
+ opPushInstVar,
+ opPushTempVar,
+ opPushTempZeroVar,
+ opPushLiteral,
+ opPushClassVar, // 5
+ opPushSpecialValue,
+ opStoreInstVar,
+ opStoreTempVar,
+ opStoreClassVar,
+ opSendMsg, // 10
+ opSendSuper,
+ opSendSpecialMsg,
+ opSendSpecialUnaryArithMsg,
+ opSendSpecialBinaryArithMsg,
+ opSpecialOpcode, // 15
+
+
+ opNumOpcodes
+};
+
+/* special opcodes */
+enum {
+ opcDrop, // 0
+ opcDup,
+ opcFunctionReturn,
+ opcReturn,
+ opcReturnSelf,
+ opcReturnTrue, // 5
+ opcReturnFalse,
+ opcReturnNil,
+ opcJumpIfFalse, // IF 3 args
+ opcJumpIfFalsePushNil, // IF 2 args
+ opcJumpIfFalsePushFalse, // AND: (10)
+ opcJumpIfTruePushTrue, // OR:
+ opcJumpFwd,
+ opcJumpBak,
+ opcSpecialBinaryOpWithAdverb,
+ opcSuperNew, // 15
+
+ opcNewList,
+
+ opcNumSpecialOpcodes
+/*
+ opcSlotAt,
+ opcByteAt, // 15
+ opcShortAt,
+ opcInt32At,
+ opcColorAt,
+ opcFloatAt,
+ opcDoubleAt
+*/
+};
+
+/* special unary math operators */
+enum {
+ opNeg,
+ opNot,
+ opIsNil,
+ opNotNil,
+ opBitNot,
+ opAbs,
+ opAsFloat,
+ opAsInt,
+ opCeil, //5
+ opFloor,
+ opFrac,
+ opSign,
+ opSquared,
+ opCubed, //10
+ opSqrt,
+ opExp,
+ opRecip,
+ opMIDICPS,
+ opCPSMIDI, //15
+
+ opMIDIRatio,
+ opRatioMIDI,
+ opDbAmp,
+ opAmpDb,
+ opOctCPS, //20
+ opCPSOct,
+ opLog,
+ opLog2,
+ opLog10,
+ opSin, //25
+ opCos,
+ opTan,
+ opArcSin,
+ opArcCos,
+ opArcTan,
+ opSinH,
+ opCosH, //30
+ opTanH,
+ opRand,
+ opRand2,
+ opLinRand,
+ opBiLinRand,
+
+// opExpRand,
+// opBiExpRand,
+ opSum3Rand,
+// opGammaRand,
+// opGaussRand,
+// opPoiRand,
+
+ opDistort,
+ opSoftClip,
+ opCoin,
+
+ opDigitValue,
+ opSilence,
+ opThru,
+ opRectWindow,
+ opHanWindow,
+ opWelchWindow,
+ opTriWindow,
+
+ opRamp,
+ opSCurve,
+
+ opNumUnarySelectors
+};
+
+#define IS_UNARY_BOOL_OP(op) ((op)>=opCoin && (op)<=opOdd)
+#define IS_BINARY_BOOL_OP(op) ((op)>=opEQ && (op)<=opGE)
+
+/* special binary math operators */
+enum {
+ opAdd,
+ opSub,
+ opMul,
+ opIDiv,
+ opFDiv,
+ opMod,
+ opEQ,
+ opNE,
+ opLT,
+ opGT,
+ opLE,
+ opGE,
+ //opIdentical,
+ //opNotIdentical,
+
+ opMin,
+ opMax,
+ opBitAnd,
+ opBitOr,
+ opBitXor,
+ opLCM,
+ opGCD,
+ opRound,
+ opRoundUp,
+ opTrunc,
+ opAtan2,
+ opHypot,
+ opHypotx,
+ opPow,
+ opShiftLeft,
+ opShiftRight,
+ opUnsignedShift,
+ opFill,
+ opRing1, // a * (b + 1) == a * b + a
+ opRing2, // a * b + a + b
+ opRing3, // a*a*b
+ opRing4, // a*a*b - a*b*b
+ opDifSqr, // a*a - b*b
+ opSumSqr, // a*a + b*b
+ opSqrSum, // (a + b)^2
+ opSqrDif, // (a - b)^2
+ opAbsDif, // |a - b|
+ opThresh,
+ opAMClip,
+ opScaleNeg,
+ opClip2,
+ opExcess,
+ opFold2,
+ opWrap2,
+ opFirstArg,
+ opRandRange,
+ opExpRandRange,
+
+ opNumBinarySelectors
+};
+
+/* other special math operators */
+enum {
+ /* 3 operands */
+ opDivz,
+ opClip,
+ opWrap,
+ opFold,
+ opRampMult,
+ opMix,
+ /* 4 operands */
+ opPoly3,
+ /* 5 operands */
+ opMapRange
+};
+
+enum {
+ opmNew, // 0
+ opmInit,
+ opmAt,
+ opmPut,
+ opmNext,
+ opmReset, // 5
+ opmValue,
+ opmCopyToEnd, // used by multi assign
+ opmAdd, // used by dynamic list
+ //opmIsNil,
+ //opmNotNil, // 10
+ opmSize,
+ opmClass,
+ opmIf,
+ opmWhile,
+ opmFor, // 15
+ opmAnd,
+ opmOr,
+ opmIdentical,
+ opmNotIdentical,
+ opmPrint, // 20
+ opmRemove,
+ opmIndexOf,
+ opmWrapAt,
+ opmClipAt,
+ opmFoldAt, // 25
+ opmWrapPut,
+ opmClipPut,
+ opmFoldPut,
+ opmDo,
+ opmCollect, // 30
+ opmSelect,
+ opmReject,
+ opmAny,
+ opmEvery,
+ opmFind,
+ opmChoose,
+ opmValueList,
+ opmAddFirst,
+ opmPrimitiveFailed,
+ opmSubclassResponsibility,
+ opmShouldNotImplement,
+ opmNotYetImplemented,
+ opmDoesNotUnderstand,
+
+ opmAtSign,
+ opmWrapAtSign,
+ opmClipAtSign,
+ opmFoldAtSign,
+
+ opmNewClear,
+ opmNewCopyArgs,
+ opmMultiNew,
+ opmMultiNewList,
+ opmAR,
+ opmKR,
+ opmIR,
+
+ opmCopy,
+ opmPerformList,
+ opmIsKindOf,
+ opmPostln,
+ opmAsString,
+
+ opmEnvirGet,
+ opmEnvirPut,
+
+ opmHalt,
+ opmForBy,
+ opmReverseDo,
+ opmLoop,
+
+ opmNonBooleanError,
+
+ opmPlusPlus,
+ opmLTLT,
+ opmQuestionMark,
+ opmDoubleQuestionMark,
+
+ opmYield,
+ opmName,
+ opmMulAdd,
+
+ opmNumSpecialSelectors
+};
+
+enum {
+ opsvSelf, // 0
+ opsvMinusOne,
+ opsvNegOne,
+ opsvZero,
+ opsvOne,
+ opsvTwo, // 5
+ opsvFHalf,
+ opsvFNegOne,
+ opsvFZero,
+ opsvFOne,
+ opsvFTwo, // 10
+ opsvPlusOne,
+ opsvTrue,
+ opsvFalse,
+ opsvNil,
+ opsvInf, // 15
+
+ opsvNumSpecialValues
+};
+
+enum {
+ opgProcess,
+ opgMethod,
+ opgFunctionDef,
+ opgFunction,
+ opgThread,
+ //opgSampleRate,
+ //opgAudioClock,
+ //opgLogicalClock,
+
+ opgNumPseudoVars
+};
+
+/* selector types */
+enum {
+ selNormal,
+ selSpecial,
+ selUnary,
+ selBinary,
+ selIf,
+ selWhile,
+ selAnd,
+ selOr,
+ selLoop,
+ selSuperNew,
+
+ selNumSelectorTypes
+};
+
+
+
+/*
+ special classes:
+ Object, List, Number, Int, Float, Signal, Complex, Point
+*/
+enum {
+ op_class_object,
+ op_class_symbol,
+ op_class_nil,
+ op_class_boolean,
+ op_class_true,
+ op_class_false,
+ op_class_magnitude,
+ op_class_char,
+ op_class_number,
+ op_class_complex,
+ op_class_simple_number,
+ op_class_int,
+ op_class_float,
+ op_class_method,
+ op_class_fundef,
+ op_class_stream,
+ op_class_func,
+ op_class_frame,
+ op_class_process,
+ op_class_main,
+ op_class_class,
+ op_class_string,
+ op_class_collection,
+ op_class_sequenceable_collection,
+ op_class_arrayed_collection,
+ op_class_array,
+ op_class_int8array,
+ op_class_int16array,
+ op_class_int32array,
+ op_class_floatarray,
+ op_class_signal,
+ op_class_doublearray,
+ op_class_symbolarray,
+ op_class_list,
+ op_class_linkedlist,
+ op_class_bag,
+ op_class_set,
+ op_class_identityset,
+ op_class_dictionary,
+ op_class_identitydictionary,
+ op_class_sortedlist,
+ op_class_synth,
+ op_class_ref,
+ op_class_environment,
+ op_class_wavetable,
+ op_class_env,
+
+ op_class_routine,
+ op_class_color,
+ op_class_rect,
+
+ op_NumSpecialClasses
+};
+
+
+
+#endif
diff --git a/sc4pd/headers/lang/PowerOfTwoAllocPool.h b/sc4pd/headers/lang/PowerOfTwoAllocPool.h
new file mode 100644
index 0000000..8dde18f
--- /dev/null
+++ b/sc4pd/headers/lang/PowerOfTwoAllocPool.h
@@ -0,0 +1,154 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+// Implements a power of two size class allocator.
+// There is no consolidation of free space. Once a chunk is allocated it
+// remains at that size from then on whether free or allocated.
+// It uses AdvancingAllocPool as its parent allocator.
+// It is very fast. This is used to allocate Unit output buffers.
+
+#ifndef _PowerOfTwoAllocPool_
+#define _PowerOfTwoAllocPool_
+
+#include <stdexcept>
+#include <stdlib.h>
+#include "clz.h"
+#include "AdvancingAllocPool.h"
+#include "SC_AllocPool.h"
+void post(const char *fmt, ...);
+void postbuf(const char *fmt, ...);
+
+template<class Hdr, class Obj, class Elem, int LargeObjSizeClass, int Align>
+class PowerOfTwoAllocPool
+{
+public:
+ PowerOfTwoAllocPool(::AllocPool *inPool,
+ size_t initSize = 64*1024,
+ size_t growSize = 64*1024
+ )
+ {
+ mLargeObjPool = inPool;
+ mNumLargeObjects = 0;
+ mNumAlloc = 0;
+ mNumFree = 0;
+ size_t tooBigSize = (sizeof(Hdr) + (sizeof(Elem) << (LargeObjSizeClass-1))) + 1;
+ mSmallObjPool.Init(inPool, initSize, growSize, tooBigSize);
+ Init();
+ assert(SanityCheck());
+ }
+ ~PowerOfTwoAllocPool()
+ {
+ assert(SanityCheck());
+ assert(mNumLargeObjects == 0); // you have to free the big ones yourself
+ mSmallObjPool.FreeAll();
+ }
+
+ Obj* Alloc(int32 inNumElems)
+ {
+ //mNumAlloc++;
+ assert(SanityCheck());
+ int sizeclass = LOG2CEIL(inNumElems);
+ if (sizeclass >= LargeObjSizeClass) {
+ mNumLargeObjects++;
+ size_t size = sizeof(Hdr) + (sizeof(Elem) * inNumElems);
+ return (Obj*)mLargeObjPool->Alloc(size);
+ }
+
+ // get from free list
+ Obj* obj = mFreeLists[sizeclass];
+ if (obj != NULL) {
+ // set free list to next element.
+ mFreeLists[sizeclass] = *(Obj**)obj;
+ } else {
+ // have to allocate it
+ size_t size = mSizes[sizeclass];
+ obj = (Obj*)mSmallObjPool.Alloc(size);
+ if (!obj) throw runtime_error("PowerOfTwoAllocPool out of memory");
+ }
+ //obj->mMagic = 'magk';
+ assert(SanityCheck());
+ return obj;
+ }
+ void Free(Obj* inObjPtr)
+ {
+ //mNumFree++;
+ assert(SanityCheck());
+ if (inObjPtr == 0) return; /* free(0) has no effect */
+ /*if (inObjPtr->mMagic != 'magk') {
+ postbuf("bad object\n");
+ throw runtime_error("bad object");
+ }*/
+ int sizeclass = inObjPtr->SizeClass();
+ if (sizeclass >= LargeObjSizeClass) {
+ mLargeObjPool->Free(inObjPtr);
+ mNumLargeObjects--;
+ } else {
+ Obj* nextfree = mFreeLists[sizeclass];
+ mFreeLists[sizeclass] = inObjPtr;
+ *(Obj**)inObjPtr = nextfree;
+ }
+ assert(SanityCheck());
+ }
+ void FreeAll()
+ {
+ assert(mNumLargeObjects == 0); // you have to free the big ones yourself
+ mSmallObjPool.FreeAll();
+ Init();
+ }
+
+ bool SanityCheck()
+ {
+ //postbuf("PowerOfTwoAllocPool::SanityCheck %d %d\n", mNumAlloc, mNumFree);
+ mLargeObjPool->DoCheckPool();
+ mSmallObjPool.SanityCheck();
+ for (int i=0; i<LargeObjSizeClass; ++i) {
+ Obj* obj = mFreeLists[i];
+ for (int j=0; obj; ++j) {
+ if (j>=1000) {
+ post("linked loop??\n");
+ throw runtime_error("linked loop??\n");
+ return false;
+ }
+ obj = *(Obj**)obj;
+ }
+ }
+ return true;
+ }
+private:
+ void Init()
+ {
+ for (int i=0; i<LargeObjSizeClass; ++i) {
+ mFreeLists[i] = NULL;
+ size_t size = sizeof(Hdr) + (sizeof(Elem) << i);
+ mSizes[i] = (size + (Align-1)) & ~(Align-1); // alignment
+ }
+ }
+
+ Obj* mFreeLists[LargeObjSizeClass];
+ size_t mSizes[LargeObjSizeClass];
+ AllocPool* mLargeObjPool;
+ AdvancingAllocPool mSmallObjPool;
+ int mNumLargeObjects;
+ int mNumAlloc, mNumFree;
+};
+
+
+#endif
+
diff --git a/sc4pd/headers/lang/PredefinedSymbols.h b/sc4pd/headers/lang/PredefinedSymbols.h
new file mode 100644
index 0000000..c6e09b9
--- /dev/null
+++ b/sc4pd/headers/lang/PredefinedSymbols.h
@@ -0,0 +1,29 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+extern PyrSymbol *s_func, *s_absfunc;
+extern PyrSymbol *s_docmdline;
+extern PyrSymbol *s_nocomprendo;
+extern PyrSymbol *s_curProcess, *s_curMethod, *s_curBlock, *s_curClosure, *s_curThread;
+extern PyrSymbol *s_startup;
+extern PyrSymbol *s_hardwaresetup, *s_shutdown;
+extern PyrSymbol *s_envirGet, *s_envirPut;
+
diff --git a/sc4pd/headers/lang/PriorityQueue.h b/sc4pd/headers/lang/PriorityQueue.h
new file mode 100644
index 0000000..0bd19f1
--- /dev/null
+++ b/sc4pd/headers/lang/PriorityQueue.h
@@ -0,0 +1,90 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PriorityQueue_
+#define _PriorityQueue_
+
+#include <limits>
+
+template <class Event, class TimeType, int N>
+class PriorityQueueT
+{
+public:
+ PriorityQueueT() {
+ Empty();
+ }
+
+ bool Add(Event& inEvent)
+ {
+ if (mSize >= N) return false;
+ long mom = mSize++;
+ long me = mom;
+ for (; mom>0;) { /* percolate up heap */
+ mom = mom - 1 >> 1;
+ if (inEvent.mTime < mEvents[mom].mTime) {
+ mEvents[me] = mEvents[mom];
+ me = mom;
+ } else break;
+ }
+ mEvents[me] = inEvent;
+ return true;
+ }
+ void Perform(TimeType inNow)
+ {
+ while (NextTime() <= inNow) {
+ Event event = Remove();
+ event.Perform();
+ }
+ }
+ TimeType NextTime() { return mEvents[0].mTime; }
+ bool Ready(TimeType inTime) { return NextTime() <= inTime; }
+ void Flush() { Perform(std::numeric_limits<TimeType>::max()); }
+ void Empty() { mSize = 0; SetEmptyTime(); }
+ void SetEmptyTime() { mEvents[0].mTime = std::numeric_limits<TimeType>::max(); }
+
+ Event Remove()
+ {
+ Event event = mEvents[0];
+ if (--mSize == 0) SetEmptyTime();
+ else {
+ Event temp = mEvents[mSize];
+ long mom = 0;
+ long me = 1;
+ for (;me < mSize;) { /* demote heap */
+ if (me+1 < mSize && mEvents[me].mTime > mEvents[me+1].mTime) {
+ me ++;
+ }
+ if (temp.mTime > mEvents[me].mTime) {
+ mEvents[mom] = mEvents[me];
+ mom = me;
+ me = (me << 1) + 1;
+ } else break;
+ }
+ mEvents[mom] = temp;
+ }
+ return event;
+ }
+
+private:
+ long mSize;
+ Event mEvents[N];
+};
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/PyrArchiverT.h b/sc4pd/headers/lang/PyrArchiverT.h
new file mode 100644
index 0000000..3beaa0c
--- /dev/null
+++ b/sc4pd/headers/lang/PyrArchiverT.h
@@ -0,0 +1,619 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+An object archiving system for SuperCollider.
+
+*/
+
+
+#ifndef _PyrArchiver_
+#define _PyrArchiver_
+
+#include "PyrObject.h"
+#include "SC_AllocPool.h"
+
+#include "PyrKernel.h"
+#include "PyrPrimitive.h"
+#include "VMGlobals.h"
+#include "GC.h"
+#include "ReadWriteMacros.h"
+
+const int32 kArchHdrSize = 12;
+const int32 kObjectArrayInitialCapacity = 32;
+
+template <class S>
+class PyrArchiver
+{
+public:
+ PyrArchiver(VMGlobals *inG, bool inSameAddressSpace = false)
+ : g(inG), mObjectArray(mInitialObjectArray), mNumObjects(0),
+ mObjectArrayCapacity( kObjectArrayInitialCapacity ),
+ mSameAddressSpace(inSameAddressSpace), mReadArchiveVersion(0)
+ {
+ }
+
+ ~PyrArchiver()
+ {
+ if (mObjectArray != mInitialObjectArray) {
+ g->allocPool->Free(mObjectArray);
+ }
+ }
+
+ void setStream(S s) { mStream.SetStream(s); }
+
+ int32 calcArchiveSize()
+ {
+ PyrSlot *slot;
+ int32 size = kArchHdrSize;
+ if (mNumObjects == 0) {
+ size += sizeOfElem(&mTopSlot) + 1;
+ } else {
+ // object table size
+ for (int i=0; i<mNumObjects; ++i) {
+ PyrObject* obj = mObjectArray[i];
+ size += obj->classptr->name.us->length + 1; // class name symbol
+ size += sizeof(int32); // size
+ if (obj->obj_format <= obj_slot) {
+ size += obj->size; // tags
+ slot = obj->slots;
+ for (int j=0; j<obj->size; ++j, ++slot) {
+ size += sizeOfElem(slot);
+ }
+ } else if (obj->obj_format == obj_symbol) {
+ PyrSymbol **symbol = ((PyrSymbolArray*)obj)->symbols;
+ for (int j=0; j<obj->size; ++j, ++symbol) {
+ size += (**symbol).length + 1;
+ }
+ } else {
+ size += obj->size * gFormatElemSize[obj->obj_format];
+ }
+ }
+ }
+ return size;
+ }
+
+ long prepareToWriteArchive(PyrSlot *objectSlot)
+ {
+ long err = errNone;
+
+ try {
+ mTopSlot.ucopy = objectSlot->ucopy;
+ if (IsObj(objectSlot)) constructObjectArray(objectSlot->uo);
+ } catch (std::exception &ex) {
+ error(ex.what());
+ err = errFailed;
+ }
+ return err;
+ }
+
+ long writeArchive()
+ {
+ long err = errNone;
+
+ try {
+ writeArchiveHeader();
+
+ if (mNumObjects == 0) {
+ writeSlot(&mTopSlot);
+ } else {
+ for (int i=0; i<mNumObjects; ++i) {
+ writeObjectHeader(mObjectArray[i]);
+ }
+ for (int i=0; i<mNumObjects; ++i) {
+ writeSlots(mObjectArray[i]);
+ }
+ }
+ } catch (std::exception &ex) {
+ error(ex.what());
+ err = errFailed;
+ }
+ return err;
+ }
+
+ long readArchive(PyrSlot *objectSlot)
+ {
+ //postfl("->readArchive\n");
+ long err = errNone;
+
+
+ SetNil(objectSlot);
+
+ try {
+ readArchiveHeader();
+ //postfl("readObjectHeaders %d\n", mNumObjects);
+ if (mNumObjects == 0) {
+ readSlot(objectSlot);
+ } else {
+ for (int i=0; i<mNumObjects; ++i) {
+ mObjectArray[i] = readObjectHeader();
+ }
+ //postfl("readSlots\n");
+ for (int i=0; i<mNumObjects; ++i) {
+ readSlots(mObjectArray[i]);
+ }
+ //postfl("done reading\n");
+ //postfl("SetObject\n");
+ SetObject(objectSlot, mObjectArray[0]);
+ }
+ } catch (std::exception &ex) {
+ error(ex.what());
+ err = errFailed;
+ } catch (...) {
+ err = errFailed;
+ }
+ //postfl("<-readArchive\n");
+ return err;
+ }
+
+private:
+
+ void writeArchiveHeader()
+ {
+ mStream.writeInt32_be('!SCa');
+ mStream.writeInt32_be(2); // file version
+ mStream.writeInt32_be(mNumObjects);
+ }
+
+ void readArchiveHeader()
+ {
+ int32 magicNumber = mStream.readInt32_be();
+ if (magicNumber != '!SCa') {
+ throw std::runtime_error("not an SC archive.\n");
+ }
+ mReadArchiveVersion = mStream.readInt32_be(); // file version
+ mNumObjects = mStream.readInt32_be();
+ //post("readArchiveHeader %d %d\n", mReadArchiveVersion, mNumObjects);
+
+ if (mNumObjects > kObjectArrayInitialCapacity) {
+ mObjectArray = (PyrObject**)g->allocPool->Alloc(mNumObjects * sizeof(PyrObject*));
+ mObjectArrayCapacity = mNumObjects;
+ }
+
+ }
+
+ void recurse(PyrObject *obj, int n)
+ {
+ PyrSlot *slot = obj->slots;
+ for (int i=0; i<n; ++i, ++slot) {
+ if (IsObj(slot)) constructObjectArray(slot->uo);
+ }
+ }
+
+ void growObjectArray()
+ {
+ int32 newObjectArrayCapacity = mObjectArrayCapacity << 1;
+
+ int32 newSize = newObjectArrayCapacity * sizeof(PyrObject*);
+ PyrObject** newArray = (PyrObject**)g->allocPool->Alloc(newSize);
+ memcpy(newArray, mObjectArray, mNumObjects * sizeof(PyrObject*));
+ if (mObjectArray != mInitialObjectArray) {
+ g->allocPool->Free(mObjectArray);
+ }
+ mObjectArrayCapacity = newObjectArrayCapacity;
+ mObjectArray = newArray;
+ }
+
+ void putObject(PyrObject *obj)
+ {
+ obj->SetMark();
+ obj->scratch1 = mNumObjects;
+
+ // expand array if needed
+ if (mNumObjects >= mObjectArrayCapacity) growObjectArray();
+
+ // add to array
+ mObjectArray[mNumObjects++] = obj;
+ }
+
+ void constructObjectArray(PyrObject *obj)
+ {
+ if (!obj->IsMarked()) {
+ if (isKindOf(obj, class_class)) {
+ } else if (isKindOf(obj, class_process)) {
+ } else if (isKindOf(obj, s_interpreter->u.classobj)) {
+ } else if (isKindOf(obj, class_method)) {
+ throw std::runtime_error("cannot archive Methods.\n");
+ } else if (isKindOf(obj, class_thread)) {
+ throw std::runtime_error("cannot archive Threads.\n");
+ } else if (isKindOf(obj, class_frame)) {
+ throw std::runtime_error("cannot archive Frames.\n");
+ } else if (isKindOf(obj, class_func)) {
+ if (NotNil(&((PyrClosure*)obj)->block.uoblk->context)) {
+ throw std::runtime_error("open Function can not be archived.\n");
+ }
+ putObject(obj);
+ recurse(obj, obj->size);
+ } else {
+ if (mSameAddressSpace && obj->IsPermanent()) {
+ // skip it
+ } else {
+ if (isKindOf(obj, class_rawarray)) {
+ putObject(obj);
+ } else if (isKindOf(obj, class_array)) {
+ putObject(obj);
+ recurse(obj, obj->size);
+
+ } else {
+ putObject(obj);
+ recurse(obj, obj->size);
+ }
+ }
+ }
+ }
+ }
+
+ int32 sizeOfElem(PyrSlot *slot)
+ {
+ //postfl("writeSlot %08X\n", slot->utag);
+ switch (slot->utag) {
+ case tagObj :
+ if (isKindOf(slot->uo, class_class)) {
+ return slot->uoc->name.us->length + 1;
+ } else if (isKindOf(slot->uo, class_process)) {
+ return 0;
+ } else if (isKindOf(slot->uo, s_interpreter->u.classobj)) {
+ return 0;
+ } else {
+ return sizeof(int32);
+ }
+ break;
+ case tagHFrame :
+ case tagSFrame :
+ return 0;
+ case tagInt :
+ return sizeof(int32);
+ case tagSym :
+ return slot->us->length + 1;
+ case tagChar :
+ return sizeof(int32);
+ case tagNil :
+ return 0;
+ case tagFalse :
+ return 0;
+ case tagTrue :
+ return 0;
+ case tagInf :
+ return 0;
+ case tagPtr :
+ throw std::runtime_error("cannot archive RawPointers.");
+ return 0;
+ default :
+ return sizeof(double);
+ }
+ }
+
+ PyrSymbol* readSymbolID()
+ {
+ char str[256];
+ mStream.readSymbol(str);
+ return getsym(str);
+ }
+
+
+ PyrObject* readObjectID()
+ {
+ int32 objID = mStream.readInt32_be();
+ //postfl("readObjectID %d\n", objID);
+ return mObjectArray[objID];
+ }
+
+ void writeObjectHeader(PyrObject *obj)
+ {
+ obj->ClearMark();
+
+ //postfl("writeObjectHeader %s\n", obj->classptr->name.us->name);
+ mStream.writeSymbol(obj->classptr->name.us->name);
+
+ mStream.writeInt32_be(obj->size);
+ }
+
+ PyrObject* readObjectHeader()
+ {
+ PyrSymbol* classname = readSymbolID();
+ //post("readObjectHeader %s\n", classname->name);
+ PyrObject *obj;
+ int32 size = mStream.readInt32_be();
+ if (classname->u.classobj->classFlags.ui & classHasIndexableInstances) {
+ obj = instantiateObject(g->gc, classname->u.classobj, size, false, false);
+ obj->size = size;
+ } else {
+ obj = instantiateObject(g->gc, classname->u.classobj, 0, false, false);
+ }
+ return obj;
+ }
+
+ void writeSlots(PyrObject *obj)
+ {
+ //postfl(" writeSlots %s\n", obj->classptr->name.us->name);
+ if (isKindOf(obj, class_rawarray)) {
+ writeRawArray(obj);
+ } else if (isKindOf(obj, class_func)) {
+ PyrClosure* closure = (PyrClosure*)obj;
+ writeSlot(&closure->block);
+ } else {
+ for (int i=0; i<obj->size; ++i) {
+ writeSlot(obj->slots + i);
+ }
+ }
+ }
+
+ void readSlots(PyrObject *obj)
+ {
+ //postfl("readSlots\n");
+ if (isKindOf(obj, class_rawarray)) {
+ readRawArray(obj);
+ } else if (isKindOf(obj, class_func)) {
+ PyrClosure* closure = (PyrClosure*)obj;
+ readSlot(&closure->block);
+ closure->context.ucopy = g->process->interpreter.uoi->context.ucopy;
+ } else {
+ for (int i=0; i<obj->size; ++i) {
+ readSlot(obj->slots + i);
+ }
+ }
+ }
+
+ void writeSlot(PyrSlot *slot)
+ {
+ PyrObject *obj;
+ //postfl(" writeSlot %08X\n", slot->utag);
+ switch (slot->utag) {
+ case tagObj :
+ obj = slot->uo;
+ if (isKindOf(obj, class_class)) {
+ mStream.writeInt8('C');
+ mStream.writeSymbol(slot->uoc->name.us->name);
+ } else if (isKindOf(obj, class_process)) {
+ mStream.writeInt8('P');
+ } else if (isKindOf(obj, s_interpreter->u.classobj)) {
+ mStream.writeInt8('R');
+ } else {
+ if (mSameAddressSpace && obj->IsPermanent()) {
+ mStream.writeInt8('z');
+ mStream.writeInt32_be((int32)obj);
+ } else {
+ mStream.writeInt8('o');
+ mStream.writeInt32_be(obj->scratch1);
+ }
+ }
+ break;
+ case tagHFrame :
+ case tagSFrame :
+ mStream.writeInt8('N');
+ break;
+ case tagInt :
+ mStream.writeInt8('i');
+ mStream.writeInt32_be(slot->ui);
+ break;
+ case tagSym :
+ mStream.writeInt8('s');
+ mStream.writeSymbol(slot->us->name);
+ break;
+ case tagChar :
+ mStream.writeInt8('c');
+ mStream.writeInt32_be(slot->ui);
+ break;
+ case tagNil :
+ mStream.writeInt8('N');
+ break;
+ case tagFalse :
+ mStream.writeInt8('F');
+ break;
+ case tagTrue :
+ mStream.writeInt8('T');
+ break;
+ case tagInf :
+ mStream.writeInt8('I');
+ break;
+ case tagPtr :
+ mStream.writeInt8('N');
+ break;
+ default :
+ mStream.writeInt8('f');
+ mStream.writeDouble_be(slot->uf);
+ break;
+ }
+ }
+
+ void readSlot(PyrSlot *slot)
+ {
+ char tag = mStream.readInt8();
+ switch (tag) {
+ case 'o' :
+ slot->utag = tagObj;
+ slot->uo = readObjectID();
+ break;
+ case 'z' :
+ slot->utag = tagObj;
+ slot->ui = mStream.readInt32_be();
+ break;
+ case 'C' :
+ slot->utag = tagObj;
+ slot->uo = (PyrObject*)readSymbolID()->u.classobj;
+ break;
+ case 'P' :
+ slot->utag = tagObj;
+ slot->uo = (PyrObject*)g->process;
+ break;
+ case 'R' :
+ slot->utag = tagObj;
+ slot->uo = g->process->interpreter.uo;
+ break;
+ case 'i' :
+ slot->utag = tagInt;
+ slot->ui = mStream.readInt32_be();
+ break;
+ case 's' :
+ slot->utag = tagSym;
+ slot->us = readSymbolID();
+ break;
+ case 'c' :
+ slot->utag = tagChar;
+ slot->ui = mStream.readInt32_be();
+ break;
+ case 'f' :
+ slot->uf = mStream.readDouble_be();
+ break;
+ case 'N' :
+ slot->utag = tagNil;
+ slot->ui = 0;
+ break;
+ case 'T' :
+ slot->utag = tagTrue;
+ slot->ui = 0;
+ break;
+ case 'F' :
+ slot->utag = tagFalse;
+ slot->ui = 0;
+ break;
+ case 'I' :
+ slot->utag = tagInf;
+ slot->ui = 0;
+ break;
+ default :
+ slot->utag = tagNil;
+ slot->ui = 0;
+ break;
+ }
+ }
+
+ void writeRawArray(PyrObject *obj)
+ {
+ int32 size = obj->size;
+ //postfl("writeRawArray %d\n", size);
+ switch (obj->obj_format) {
+ case obj_char :
+ case obj_int8 : {
+ char *data = (char*)obj->slots;
+ mStream.writeData(data, size);
+ } break;
+ case obj_int16 : {
+ int16 *data = (int16*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ mStream.writeInt16_be(data[i]);
+ }
+ } break;
+ case obj_int32 :
+ case obj_float : {
+ int32 *data = (int32*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ mStream.writeInt32_be(data[i]);
+ }
+ } break;
+ case obj_double : {
+ double *data = (double*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ mStream.writeDouble_be(data[i]);
+ }
+ } break;
+ case obj_symbol : {
+ PyrSymbol **data = (PyrSymbol**)obj->slots;
+ for (int i=0; i<size; ++i) {
+ mStream.writeSymbol(data[i]->name);
+ }
+ } break;
+ }
+ }
+
+ void readRawArray(PyrObject *obj)
+ {
+ //postfl("readRawArray\n");
+ int32 size = obj->size;
+ switch (obj->obj_format) {
+ case obj_char :
+ case obj_int8 : {
+ int8 *data = (int8*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ data[i] = mStream.readInt8();
+ }
+ } break;
+ case obj_int16 : {
+ int16 *data = (int16*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ data[i] = mStream.readInt16_be();
+ }
+ } break;
+ case obj_int32 :
+ case obj_float : {
+ int32 *data = (int32*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ data[i] = mStream.readInt32_be();
+ }
+ } break;
+ case obj_double : {
+ double *data = (double*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ data[i] = mStream.readDouble_be();
+ }
+ } break;
+ case obj_symbol : {
+ PyrSymbol **data = (PyrSymbol**)obj->slots;
+ for (int i=0; i<size; ++i) {
+ data[i] = readSymbolID();
+ }
+ } break;
+ }
+
+ }
+
+ VMGlobals *g;
+
+ PyrObject **mObjectArray;
+ int32 mNumObjects;
+ int32 mObjectArrayCapacity;
+ PyrSlot mTopSlot;
+
+ bool mSameAddressSpace;
+ SC_IOStream<S> mStream;
+ int32 mReadArchiveVersion;
+
+ PyrObject *mInitialObjectArray[kObjectArrayInitialCapacity];
+};
+
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+An object archiving system for SuperCollider.
+
+*/
+
+
+
+#endif
+
diff --git a/sc4pd/headers/lang/PyrDeepCopier.h b/sc4pd/headers/lang/PyrDeepCopier.h
new file mode 100644
index 0000000..3b46280
--- /dev/null
+++ b/sc4pd/headers/lang/PyrDeepCopier.h
@@ -0,0 +1,221 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+An object archiving system for SuperCollider.
+
+*/
+
+
+#ifndef _PyrDeepCopier_
+#define _PyrDeepCopier_
+
+#include "PyrObject.h"
+#include "SC_AllocPool.h"
+
+#include "PyrKernel.h"
+#include "PyrPrimitive.h"
+#include "VMGlobals.h"
+#include "GC.h"
+#include "ReadWriteMacros.h"
+
+const int32 kDeepCopierObjectArrayInitialCapacity = 32;
+
+class PyrDeepCopier
+{
+public:
+ PyrDeepCopier(VMGlobals *inG)
+ : g(inG), objectArray(initialObjectArray), numObjects(0),
+ objectArrayCapacity( kDeepCopierObjectArrayInitialCapacity )
+ {
+ }
+
+ ~PyrDeepCopier()
+ {
+ if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) {
+ g->allocPool->Free(objectArray);
+ }
+ }
+
+ long doDeepCopy(PyrSlot *objectSlot)
+ {
+ long err = errNone;
+
+ try {
+ if (IsObj(objectSlot)) {
+ constructObjectArray(objectSlot->uo);
+ for (int i=0; i<numObjects; ++i) {
+ fixSlots(objectArray[i]);
+ }
+ fixObjSlot(objectSlot);
+ for (int i=0; i<numObjects; ++i) {
+ objectArray[i]->ClearMark();
+ }
+
+ }
+ } catch (std::exception &ex) {
+ error(ex.what());
+ err = errFailed;
+ }
+ return err;
+ }
+
+private:
+
+ void recurse(PyrObject *obj, int n)
+ {
+ //post("->recurse %s %08X\n", obj->classptr->name.us->name, obj);
+ PyrSlot *slot = obj->slots;
+ for (int i=0; i<n; ++i, ++slot) {
+ if (IsObj(slot)) constructObjectArray(slot->uo);
+ }
+ //post("<-recurse %s %08X\n", obj->classptr->name.us->name, obj);
+ }
+
+ void growObjectArray()
+ {
+ int32 newObjectArrayCapacity = objectArrayCapacity << 1;
+
+ int32 newSize = newObjectArrayCapacity * sizeof(PyrObject*);
+ PyrObject** newArray = (PyrObject**)g->allocPool->Alloc(newSize);
+ memcpy(newArray, objectArray, numObjects * sizeof(PyrObject*));
+ if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) {
+ g->allocPool->Free(objectArray);
+ }
+ objectArrayCapacity = newObjectArrayCapacity;
+ objectArray = newArray;
+ }
+
+ void putSelf(PyrObject *obj)
+ {
+ obj->SetMark();
+ obj->scratch1 = numObjects;
+
+ // expand array if needed
+ if (numObjects >= objectArrayCapacity) growObjectArray();
+
+ //post("putSelf %d %08X\n", numObjects, obj);
+ // add to array
+ objectArray[numObjects++] = obj;
+ }
+
+ void putCopy(PyrObject *obj)
+ {
+ obj->SetMark();
+ obj->scratch1 = numObjects;
+
+ // expand array if needed
+ if (numObjects+2 >= objectArrayCapacity) growObjectArray();
+
+ // add a shallow copy to object array
+ PyrObject *copy = copyObject(g->gc, obj, false);
+ copy->ClearMark();
+
+ //post("putCopy %d %08X\n", numObjects, copy);
+
+ // add to array
+ objectArray[numObjects++] = copy;
+ objectArray[numObjects++] = obj;
+ }
+
+ void constructObjectArray(PyrObject *obj)
+ {
+ //post("->constructObjectArray %s %08X\n", obj->classptr->name.us->name, obj);
+ if (!obj->IsMarked()) {
+ if (isKindOf(obj, class_class)) {
+ putSelf(obj);
+ } else if (isKindOf(obj, class_process)) {
+ putSelf(obj);
+ } else if (isKindOf(obj, s_interpreter->u.classobj)) {
+ putSelf(obj);
+ } else if (isKindOf(obj, class_rawarray)) {
+ putCopy(obj);
+ } else if (isKindOf(obj, class_array)) {
+ putCopy(obj);
+ recurse(obj, obj->size);
+ } else if (isKindOf(obj, class_func)) {
+ putSelf(obj);
+ } else if (isKindOf(obj, class_method)) {
+ putSelf(obj);
+ } else if (isKindOf(obj, class_thread)) {
+ putSelf(obj);
+ } else {
+ putCopy(obj);
+ recurse(obj, obj->size);
+ }
+ }
+ //post("<-constructObjectArray %s %08X\n", obj->classptr->name.us->name, obj);
+ }
+
+ void fixObjSlot(PyrSlot* slot)
+ {
+ //post("fixObjSlot %s %08X %d %08X\n", slot->uo->classptr->name.us->name, slot->uo, slot->uo->scratch1, objectArray[slot->uo->scratch1]);
+ slot->uo = objectArray[slot->uo->scratch1];
+ }
+
+ void fixSlots(PyrObject *obj)
+ {
+ //post("fixSlots %s %08X %d\n", obj->classptr->name.us->name, obj, obj->IsMarked());
+ if (!obj->IsMarked() && obj->obj_format <= obj_slot) { // it is a copy
+ PyrSlot *slot = obj->slots;
+ for (int i=0; i<obj->size; ++i, ++slot) {
+ if (IsObj(slot)) fixObjSlot(slot);
+ }
+ }
+ }
+
+ VMGlobals *g;
+
+ PyrObject **objectArray;
+ int32 numObjects;
+ int32 objectArrayCapacity;
+
+ PyrObject *initialObjectArray[kDeepCopierObjectArrayInitialCapacity];
+};
+
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+An object archiving system for SuperCollider.
+
+*/
+
+
+
+#endif
+
diff --git a/sc4pd/headers/lang/PyrDeepFreezer.h b/sc4pd/headers/lang/PyrDeepFreezer.h
new file mode 100644
index 0000000..28d9a12
--- /dev/null
+++ b/sc4pd/headers/lang/PyrDeepFreezer.h
@@ -0,0 +1,178 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+An object archiving system for SuperCollider.
+
+*/
+
+#ifndef _PyrDeepFreezer_
+#define _PyrDeepFreezer_
+
+#include "PyrObject.h"
+#include "SC_AllocPool.h"
+#include "PyrKernel.h"
+#include "PyrPrimitive.h"
+#include "VMGlobals.h"
+#include "GC.h"
+
+const int32 kDeepFreezerObjectArrayInitialCapacity = 32;
+
+class PyrDeepFreezer
+{
+public:
+ PyrDeepFreezer(VMGlobals *inG)
+ : g(inG), objectArray(initialObjectArray), numObjects(0),
+ objectArrayCapacity( kDeepCopierObjectArrayInitialCapacity )
+ {
+ }
+
+ ~PyrDeepFreezer()
+ {
+ if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) {
+ g->allocPool->Free(objectArray);
+ }
+ }
+
+ long doDeepFreeze(PyrSlot *objectSlot)
+ {
+ long err = errNone;
+
+ try {
+ if (IsObj(objectSlot)) {
+ constructObjectArray(objectSlot->uo);
+ for (int i=0; i<numObjects; ++i) {
+ g->gc->BecomePermanent( objectArray[i] );
+ }
+ }
+ } catch (std::exception &ex) {
+ error(ex.what());
+ err = errFailed;
+ }
+ return err;
+ }
+
+private:
+
+ void recurse(PyrObject *obj, int n)
+ {
+ PyrSlot *slot = obj->slots;
+ for (int i=0; i<n; ++i, ++slot) {
+ if (IsObj(slot)) constructObjectArray(slot->uo);
+ }
+ }
+
+ void growObjectArray()
+ {
+ int32 newObjectArrayCapacity = objectArrayCapacity << 1;
+
+ int32 newSize = newObjectArrayCapacity * sizeof(PyrObject*);
+ PyrObject** newArray = (PyrObject**)g->allocPool->Alloc(newSize);
+ memcpy(newArray, objectArray, numObjects * sizeof(PyrObject*));
+ if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) {
+ g->allocPool->Free(objectArray);
+ }
+ objectArrayCapacity = newObjectArrayCapacity;
+ objectArray = newArray;
+ }
+
+ void putObject(PyrObject *obj)
+ {
+ obj->SetMark();
+ obj->scratch1 = numObjects;
+
+ // expand array if needed
+ if (numObjects >= objectArrayCapacity) growObjectArray();
+
+ // add to array
+ objectArray[numObjects++] = obj;
+ }
+
+ void constructObjectArray(PyrObject *obj)
+ {
+ if (obj->IsPermanent()) return;
+
+ if (!obj->IsMarked()) {
+ if (isKindOf(obj, class_process)) {
+ throw std::runtime_error("cannot freeze Process.\n");
+ } else if (isKindOf(obj, s_interpreter->u.classobj)) {
+ throw std::runtime_error("cannot freeze Interpreter.\n");
+ } else if (isKindOf(obj, class_rawarray)) {
+ putObject(obj);
+ } else if (isKindOf(obj, class_array)) {
+ putObject(obj);
+ recurse(obj, obj->size);
+ } else if (isKindOf(obj, class_func)) {
+ if (NotNil(&((PyrClosure*)obj)->block.uoblk->context)) {
+ throw std::runtime_error("open Function can not be frozen.\n");
+ }
+ putObject(obj);
+ recurse(obj, obj->size);
+ } else if (isKindOf(obj, class_method)) {
+ throw std::runtime_error("cannot freeze Methods.\n");
+ } else if (isKindOf(obj, class_thread)) {
+ throw std::runtime_error("cannot freeze Threads.\n");
+ } else if (isKindOf(obj, class_frame)) {
+ throw std::runtime_error("cannot freeze Frames.\n");
+ } else {
+ putObject(obj);
+ recurse(obj, obj->size);
+ }
+ }
+ }
+
+ VMGlobals *g;
+
+ PyrObject **objectArray;
+ int32 numObjects;
+ int32 objectArrayCapacity;
+
+ PyrObject *initialObjectArray[kDeepCopierObjectArrayInitialCapacity];
+};
+
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+An object archiving system for SuperCollider.
+
+*/
+
+
+
+#endif
+
diff --git a/sc4pd/headers/lang/PyrErrors.h b/sc4pd/headers/lang/PyrErrors.h
new file mode 100644
index 0000000..b2be76e
--- /dev/null
+++ b/sc4pd/headers/lang/PyrErrors.h
@@ -0,0 +1,49 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+virtual machine error codes.
+
+*/
+
+#ifndef _SCErrors_
+#define _SCErrors_
+
+enum { // primitive errors
+ errReturn = -1, // not really an error.. primitive executed a non-local return
+ errNone,
+ errFailed = 5000,
+ errBadPrimitive,
+ errWrongType,
+ errIndexNotAnInteger,
+ errIndexOutOfRange,
+ errImmutableObject,
+ errNotAnIndexableObject,
+ errStackOverflow,
+ errOutOfMemory,
+ errCantCallOS,
+ errException,
+
+ errPropertyNotFound = 6000,
+
+ errLastError
+};
+
+#endif
diff --git a/sc4pd/headers/lang/PyrFilePrim.h b/sc4pd/headers/lang/PyrFilePrim.h
new file mode 100644
index 0000000..3574927
--- /dev/null
+++ b/sc4pd/headers/lang/PyrFilePrim.h
@@ -0,0 +1,62 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef _PYRFILEPRIM_H_
+#define _PYRFILEPRIM_H_
+
+#include "PyrObject.h"
+
+struct PyrFile : public PyrObjectHdr
+{
+ PyrSlot fileptr;
+};
+
+void initFilePrimitives();
+
+long prFileDelete(VMGlobals *g, long numArgsPushed);
+long prFileOpen(VMGlobals *g, long numArgsPushed);
+long prFileClose(VMGlobals *g, long numArgsPushed);
+long prFileSeek(VMGlobals *g, long numArgsPushed);
+long prFilePos(VMGlobals *g, long numArgsPushed);
+long prFileLength(VMGlobals *g, long numArgsPushed);
+long prFileWrite(VMGlobals *g, long numArgsPushed);
+long prFileReadLine(VMGlobals *g, long numArgsPushed);
+
+long prFilePutRGB(VMGlobals *g, long numArgsPushed);
+long prFilePutInt32(VMGlobals *g, long numArgsPushed);
+long prFilePutInt16(VMGlobals *g, long numArgsPushed);
+long prFilePutInt8(VMGlobals *g, long numArgsPushed);
+long prFilePutChar(VMGlobals *g, long numArgsPushed);
+long prFilePutFloat(VMGlobals *g, long numArgsPushed);
+long prFilePutDouble(VMGlobals *g, long numArgsPushed);
+
+long prFileGetRGB(VMGlobals *g, long numArgsPushed);
+long prFileGetInt32(VMGlobals *g, long numArgsPushed);
+long prFileGetInt16(VMGlobals *g, long numArgsPushed);
+long prFileGetInt8(VMGlobals *g, long numArgsPushed);
+long prFileGetChar(VMGlobals *g, long numArgsPushed);
+long prFileGetFloat(VMGlobals *g, long numArgsPushed);
+long prFileGetDouble(VMGlobals *g, long numArgsPushed);
+
+long prFilePutString(VMGlobals *g, long numArgsPushed);
+long prFileRead(VMGlobals *g, long numArgsPushed);
+
+
+#endif
+
diff --git a/sc4pd/headers/lang/PyrFileUtils.h b/sc4pd/headers/lang/PyrFileUtils.h
new file mode 100644
index 0000000..1fd682b
--- /dev/null
+++ b/sc4pd/headers/lang/PyrFileUtils.h
@@ -0,0 +1,50 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+Some utils for file i/o.
+
+*/
+
+#ifndef _PYRFILEUTIL_H_
+#define _PYRFILEUTIL_H_
+
+int headerFormatFromSymbol(struct PyrSymbol *inSymbol);
+int sampleFormatFromSymbol(struct PyrSymbol *inSymbol, int inHeaderFormat);
+
+#ifdef __MAC__
+
+#include <Files.h>
+
+long setTypeCreator(unsigned char *filename, long type, long creator);
+bool filelen(FILE *file, size_t *length);
+
+int allocasync(int fildes, int count, IOParam *pb, IOCompletionUPP completionFunc);
+int createasync(unsigned char *path, int oflag, HParamBlockRec *hpb, IOCompletionUPP completionFunc);
+int openasync(unsigned char *path, int oflag, HParamBlockRec *hpb, IOCompletionUPP completionFunc);
+int closeasync(int fildes, HParamBlockRec *hpb, IOCompletionUPP completionFunc);
+int writeasync(int fildes, const char *buf, int count, IOParam *pb, IOCompletionUPP completionFunc);
+int readasync(int fildes, char *buf, int count, IOParam *pb, IOCompletionUPP completionFunc);
+int seekwriteasync(int fildes, const char *buf, int count, int pos, IOParam *pb, IOCompletionUPP completionFunc);
+int seekreadasync(int fildes, char *buf, int count, int pos, IOParam *pb, IOCompletionUPP completionFunc);
+
+
+#endif
+#endif
diff --git a/sc4pd/headers/lang/PyrInterpreter.h b/sc4pd/headers/lang/PyrInterpreter.h
new file mode 100644
index 0000000..a21126d
--- /dev/null
+++ b/sc4pd/headers/lang/PyrInterpreter.h
@@ -0,0 +1,47 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PYRINTERPRETER_H_
+#define _PYRINTERPRETER_H_
+
+#include "PyrSlot.h"
+#include "VMGlobals.h"
+
+extern bool gRunningInterpreterThread;
+
+extern int gNumClasses;
+
+bool initInterpreter(VMGlobals *g, PyrSymbol *selector, int numArgsPushed);
+bool initRuntime(VMGlobals *g, int poolSize, AllocPool *inPool, int processID);
+void Interpret(VMGlobals *g);
+void endInterpreter(VMGlobals *g);
+
+int doSpecialUnaryArithMsg(VMGlobals *g, int numArgsPushed);
+int prSpecialBinaryArithMsg(VMGlobals *g, int numArgsPushed);
+int doSpecialBinaryArithMsg(VMGlobals *g, int numArgsPushed, bool isPrimitive);
+void DumpBackTrace(VMGlobals *g);
+void DumpStack(VMGlobals *g, PyrSlot *sp);
+void DumpFrame(struct PyrFrame *frame);
+bool FrameSanity(PyrFrame *frame, char *tagstr);
+struct PyrProcess* newPyrProcess(VMGlobals *g, struct PyrClass *classobj);
+void startProcess(VMGlobals *g, PyrSymbol *selector);
+void runInterpreter(VMGlobals *g, PyrSymbol *selector, int numArgsPushed);
+
+#endif
diff --git a/sc4pd/headers/lang/PyrKernel.h b/sc4pd/headers/lang/PyrKernel.h
new file mode 100644
index 0000000..d5c6af7
--- /dev/null
+++ b/sc4pd/headers/lang/PyrKernel.h
@@ -0,0 +1,256 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+This file contains the definitions of the core objects that implement the class system.
+
+*/
+
+#ifndef _PYRKERNEL_H_
+#define _PYRKERNEL_H_
+
+#include "PyrObject.h"
+#include "VMGlobals.h"
+
+#define classClassNumInstVars 16
+
+enum { classIsIntrinsic = 1, classHasIndexableInstances = 2, classCompileUGen = 4 };
+
+struct PyrClass : public PyrObjectHdr
+{
+ PyrSlot name;
+ PyrSlot nextclass;
+ PyrSlot superclass;
+ PyrSlot subclasses;
+ PyrSlot methods;
+
+ PyrSlot instVarNames;
+ PyrSlot classVarNames;
+ PyrSlot iprototype; // instance prototype
+ PyrSlot cprototype; // class var prototype
+
+ PyrSlot instanceFormat;
+ PyrSlot instanceFlags;
+ PyrSlot classIndex;
+ PyrSlot classFlags;
+ PyrSlot maxSubclassIndex; // used by isKindOf
+ PyrSlot filenameSym;
+ PyrSlot charPos;
+};
+
+
+
+inline bool isKindOf(PyrObjectHdr *obj, struct PyrClass *testclass)
+{
+ int objClassIndex = obj->classptr->classIndex.ui;
+ return objClassIndex >= testclass->classIndex.ui && objClassIndex <= testclass->maxSubclassIndex.ui;
+}
+
+inline bool isKindOfSlot(PyrSlot *slot, struct PyrClass *testclass)
+{
+ return IsObj(slot) && isKindOf(slot->uo, testclass);
+}
+
+/*
+ operations on class:
+ numInstVars()
+ numClassVars()
+
+*/
+
+struct PyrFrame {
+ PyrSlot vars[1];
+ PyrSlot myself;
+ PyrSlot method;
+ PyrSlot caller;
+ PyrSlot context;
+ PyrSlot homeContext;
+ PyrSlot ip;
+};
+
+#define FRAMESIZE 6
+#define USESTACKFRAMES 1
+
+struct PyrProcess : public PyrObjectHdr
+{
+
+ PyrSlot classVars;
+ PyrSlot interpreter;
+ PyrSlot curThread, mainThread;
+ PyrSlot processID;
+ PyrSlot sysSchedulerQueue;
+};
+
+
+enum { tInit, tStart, tReady, tRunning, tSleeping, tBlocked, tYieldToChild, tYieldToParent, tDone };
+
+struct PyrThread : public PyrObjectHdr
+{
+
+ PyrSlot state, func, stack, stackSize, method, block, frame, ip, sp;
+ PyrSlot numpop, returnLevels, receiver, numArgsPushed;
+ PyrSlot parent, terminalValue;
+ PyrSlot primitiveError;
+ PyrSlot primitiveIndex;
+ PyrSlot randData;
+ PyrSlot beats, seconds, clock;
+ PyrSlot environment;
+ PyrSlot exceptionHandler;
+};
+
+#define EVALSTACKDEPTH 8192
+
+
+
+struct PyrMethodRaw {
+
+ unsigned short unused1;
+ unsigned short specialIndex;
+ unsigned short methType;
+ unsigned short frameSize;
+
+ unsigned char unused2;
+ unsigned char numargs;
+ unsigned char varargs;
+ unsigned char numvars;
+ unsigned char numtemps;
+ unsigned char needsHeapContext;
+ unsigned char popSize;
+ unsigned char posargs;
+
+};
+
+
+#define METHRAW(obj) ((PyrMethodRaw*)&(((PyrBlock*)obj)->rawData1))
+
+struct PyrBlock : public PyrObjectHdr
+{
+
+ PyrSlot rawData1;
+ PyrSlot rawData2;
+ PyrSlot code; // byte codes, nil if inlined
+ PyrSlot selectors; // method selectors, class names, closures table
+ PyrSlot constants; // floating point constants table (to alleviate the literal table problem)
+ PyrSlot prototypeFrame; // prototype of an activation frame
+ PyrSlot context; // ***defining block context
+ PyrSlot argNames; // ***arguments to block
+ PyrSlot varNames; // ***variables in block
+ PyrSlot sourceCode; // source code if it is a closed function.
+};
+
+struct PyrMethod : public PyrBlock
+{
+ PyrSlot ownerclass;
+ PyrSlot name;
+ PyrSlot primitiveName;
+ PyrSlot filenameSym;
+ PyrSlot charPos;
+ //PyrSlot byteMeter;
+ //PyrSlot callMeter;
+};
+
+enum {
+ methNormal = 0,
+ methReturnSelf,
+ methReturnLiteral,
+ methReturnArg,
+ methReturnInstVar,
+ methAssignInstVar,
+ methReturnClassVar,
+ methAssignClassVar,
+ methRedirect,
+ methForward,
+ methPrimitive,
+ methBlock
+};
+
+struct PyrClosure : public PyrObjectHdr
+{
+
+ PyrSlot block;
+ PyrSlot context;
+};
+
+struct PyrInterpreter : public PyrObjectHdr
+{
+
+ PyrSlot cmdLine, context;
+ PyrSlot a, b, c, d, e, f, g, h, i, j;
+ PyrSlot k, l, m, n, o, p, q, r, s, t;
+ PyrSlot u, v, w, x, y, z;
+ PyrSlot codeDump;
+};
+
+/* special values */
+enum {
+ svNil,
+ svFalse,
+ svTrue,
+ svNegOne,
+ svZero,
+ svOne,
+ svTwo,
+ svFHalf,
+ svFNegOne,
+ svFZero,
+ svFOne,
+ svFTwo,
+ svInf,
+
+ svNumSpecialValues
+};
+
+extern double gSpecialValues[svNumSpecialValues];
+
+extern PyrMethod *gNullMethod; // used to fill row table
+
+PyrObject* instantiateObject(class PyrGC *gc, PyrClass* classobj, int size,
+ bool fill, bool collect);
+
+PyrObject* newPyrObject(class PyrGC *gc, size_t inNumBytes, int inFlags, int inFormat, bool inCollect);
+PyrString* newPyrString(class PyrGC *gc, const char *s, int flags, bool collect);
+PyrString* newPyrStringN(class PyrGC *gc, int size, int flags, bool collect);
+PyrObject* newPyrArray(class PyrGC *gc, int size, int flags, bool collect);
+PyrSymbolArray* newPyrSymbolArray(class PyrGC *gc, int size, int flags, bool collect);
+PyrInt8Array* newPyrInt8Array(class PyrGC *gc, int size, int flags, bool collect);
+PyrInt32Array* newPyrInt32Array(class PyrGC *gc, int size, int flags, bool collect);
+PyrDoubleArray* newPyrDoubleArray(class PyrGC *gc, int size, int flags, bool collect);
+
+PyrObject* copyObject(class PyrGC *gc, PyrObject *inobj, bool collect);
+PyrObject* copyObjectRange(class PyrGC *gc, PyrObject *inobj, int start, int end, bool collect);
+
+inline void SetFrame(PyrSlot* slot, PyrFrame* frame)
+{
+ (slot)->ui = ((int)(frame));
+ (slot)->utag = tagSFrame - METHRAW((frame)->method.uoblk)->needsHeapContext;
+}
+
+inline void SetFrameOrNil(PyrSlot* slot, PyrFrame* frame)
+{
+ if (frame) {
+ (slot)->ui = ((int)(frame));
+ (slot)->utag = tagSFrame - METHRAW((frame)->method.uoblk)->needsHeapContext;
+ } else {
+ (slot)->utag = tagNil;
+ (slot)->ui = 0;
+ }
+}
+
+#endif
diff --git a/sc4pd/headers/lang/PyrKernelProto.h b/sc4pd/headers/lang/PyrKernelProto.h
new file mode 100644
index 0000000..f040507
--- /dev/null
+++ b/sc4pd/headers/lang/PyrKernelProto.h
@@ -0,0 +1,62 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _PYRKERNELPROTO_H_
+#define _PYRKERNELPROTO_H_
+
+PyrClass* newClassObj(PyrClass *classObjSuperClass,
+ PyrSymbol* className, PyrSymbol* superClassName,
+ int numInstVars, int numClassVars, int numInstMethods,
+ int instFormat, int instFlags);
+
+void reallocClassObj(PyrClass* classobj,
+ int numInstVars, int numClassVars, int numMethods,
+ int instFormat, int instFlags);
+
+int numInstVars(PyrClass* classobj);
+int numClassVars(PyrClass* classobj);
+int numSuperInstVars(PyrClass *superclassobj);
+bool classFindInstVar(PyrClass* classobj, PyrSymbol *name, int *index);
+bool classFindClassVar(PyrClass** classobj, PyrSymbol *name, int *index);
+
+void buildClassTree();
+void indexClassTree(PyrClass *classobj, int numSuperMethods);
+void postClassTree(PyrClass *classobj, int level);
+void setSelectorFlags();
+void buildBigMethodMatrix();
+void fillClassRow(PyrClass *classobj, struct PyrMethod** bigTable);
+
+bool funcFindArg(PyrBlock* func, PyrSymbol *name, int *index);
+bool funcFindVar(PyrBlock* func, PyrSymbol *name, int *index);
+void addMethod(PyrClass *classobj, PyrMethod *method);
+
+
+PyrMethod* classFindDirectMethod(PyrClass* classobj, PyrSymbol *name);
+
+PyrBlock* newPyrBlock(int flags);
+PyrMethod* newPyrMethod();
+PyrClass* makeIntrinsicClass(PyrSymbol *className, PyrSymbol *superClassName,
+ int numInstVars, int numClassVars);
+void addIntrinsicVar(PyrClass *classobj, char *varName, PyrSlot *slot);
+
+
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/PyrLexer.h b/sc4pd/headers/lang/PyrLexer.h
new file mode 100644
index 0000000..5166337
--- /dev/null
+++ b/sc4pd/headers/lang/PyrLexer.h
@@ -0,0 +1,136 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _PYRLEXER_H_
+#define _PYRLEXER_H_
+
+#include "PyrSymbol.h"
+
+extern int charno, lineno, linepos;
+extern int *linestarts;
+
+struct ClassExtFile {
+ struct ClassExtFile *next;
+ PyrSymbol *fileSym;
+};
+
+typedef struct classdep {
+ struct classdep *next;
+ struct classdep *superClassDep;
+ struct classdep *subclasses;
+ PyrSymbol *className;
+ PyrSymbol *superClassName;
+ PyrSymbol *fileSym;
+} ClassDependancy;
+
+extern PyrSymbol *gCompilingFileSym;
+
+ClassDependancy* newClassDependancy(PyrSymbol *className, PyrSymbol *superClassName,
+ PyrSymbol *fileSym);
+bool parseOneClass(PyrSymbol *fileSym);
+void initPassOne();
+void finiPassOne();
+bool passOne();
+void buildDepTree();
+void traverseFullDepTree();
+void traverseDepTree(ClassDependancy *classdep, int level);
+void traverseFullDepTree2();
+void traverseDepTree2(ClassDependancy *classdep, int level);
+void compileClassExtensions();
+void compileFileSym(PyrSymbol *fileSym);
+
+void runLibrary(PyrSymbol* selector);
+
+void interpretCmdLine(const char *textbuf, int textlen, char *methodname);
+
+
+int input();
+int input0();
+void unput(int c);
+void unput0(int c);
+
+void finiLexer() ;
+bool startLexer(char* filename) ;
+void startLexerCmdLine(char *textbuf, int textbuflen);
+int yylex() ;
+void yyerror(char *s) ;
+void fatal() ;
+bool isValidSourceFileName(char *filename);
+bool passOne_ProcessOneFile(char *filename, int level);
+
+extern void asRelativePath(char *inPath,char *outPath);
+
+void initLexer();
+void init_SuperCollider();
+
+int processbinop(char *token);
+int processident(char *token);
+int processfloat(char *token, int sawpi);
+int processint(char *token);
+int processchar(int c);
+int processintradix(char *s);
+int processfloatradix(char *s);
+int processhex(char *s);
+int processsymbol(char *token);
+int processstring(char *token);
+int processkeywordbinop(char *token);
+
+void postErrorLine(int linenum, int start, int charpos);
+bool scanForClosingBracket();
+void parseClasses();
+
+extern int parseFailed;
+extern bool compilingCmdLine;
+extern bool compilingCmdLineErrorWindow;
+extern bool compiledOK;
+
+#define MAXYYLEN 8192
+
+extern int gNumCompiledFiles;
+extern int gClassCompileOrderNum;
+extern ClassDependancy **gClassCompileOrder;
+extern char curfilename[PATH_MAX];
+
+extern int runcount;
+
+extern char *binopchars;
+extern char yytext[MAXYYLEN];
+extern char linebuf[256];
+extern char curfilename[PATH_MAX];
+
+extern int yylen;
+extern int lexCmdLine;
+extern bool compilingCmdLine;
+extern bool compilingCmdLineErrorWindow;
+extern long zzval;
+
+extern int lineno, charno, linepos;
+extern int *linestarts;
+extern int maxlinestarts;
+
+extern char *text;
+extern int textlen;
+extern int textpos;
+extern int parseFailed;
+extern bool compiledOK;
+extern int radixcharpos, decptpos;
+
+#endif
diff --git a/sc4pd/headers/lang/PyrListPrim.h b/sc4pd/headers/lang/PyrListPrim.h
new file mode 100644
index 0000000..43288a7
--- /dev/null
+++ b/sc4pd/headers/lang/PyrListPrim.h
@@ -0,0 +1,34 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _PYRARRAYPRIM_H_
+#define _PYRARRAYPRIM_H_
+
+void initArrayPrimitives();
+
+int prArrayMultiChanExpand(VMGlobals *g, int numArgsPushed);
+
+int arrayAtIdentityHash(PyrObject *array, PyrSlot *key);
+int arrayAtIdentityHashInPairs(PyrObject *array, PyrSlot *key);
+int arrayAtIdentityHashInPairsWithHash(PyrObject *array, PyrSlot *key, int hash);
+
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/PyrMathPrim.h b/sc4pd/headers/lang/PyrMathPrim.h
new file mode 100644
index 0000000..f4e2dd1
--- /dev/null
+++ b/sc4pd/headers/lang/PyrMathPrim.h
@@ -0,0 +1,51 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PYRMATHPRIM_H_
+#define _PYRMATHPRIM_H_
+
+void initMathPrimitives();
+
+int prAddNum(VMGlobals *g, int numArgsPushed);
+int prSubNum(VMGlobals *g, int numArgsPushed);
+int prMulNum(VMGlobals *g, int numArgsPushed);
+
+int prAddInt(VMGlobals *g, int numArgsPushed);
+int prSubInt(VMGlobals *g, int numArgsPushed);
+int prMulInt(VMGlobals *g, int numArgsPushed);
+
+int prAddFloat(VMGlobals *g, int numArgsPushed);
+int prSubFloat(VMGlobals *g, int numArgsPushed);
+int prMulFloat(VMGlobals *g, int numArgsPushed);
+
+int mathClip(VMGlobals *g, int numArgsPushed);
+int mathWrap(VMGlobals *g, int numArgsPushed);
+int mathFold(VMGlobals *g, int numArgsPushed);
+int mathClipInt(VMGlobals *g, int numArgsPushed);
+int mathWrapInt(VMGlobals *g, int numArgsPushed);
+int mathFoldInt(VMGlobals *g, int numArgsPushed);
+int mathClipFloat(VMGlobals *g, int numArgsPushed);
+int mathWrapFloat(VMGlobals *g, int numArgsPushed);
+int mathFoldFloat(VMGlobals *g, int numArgsPushed);
+int mathClipSignal(VMGlobals *g, int numArgsPushed);
+int mathWrapSignal(VMGlobals *g, int numArgsPushed);
+int mathFoldSignal(VMGlobals *g, int numArgsPushed);
+
+#endif
diff --git a/sc4pd/headers/lang/PyrMessage.h b/sc4pd/headers/lang/PyrMessage.h
new file mode 100644
index 0000000..436128a
--- /dev/null
+++ b/sc4pd/headers/lang/PyrMessage.h
@@ -0,0 +1,55 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _PYRMESSAGE_H_
+#define _PYRMESSAGE_H_
+
+#include "PyrKernel.h"
+
+#define MAXKEYSLOTS 128
+extern PyrSlot keywordstack[MAXKEYSLOTS];
+extern bool gKeywordError;
+extern PyrMethod **gRowTable;
+
+void initUniqueMethods();
+
+void sendMessageWithKeys(VMGlobals *g, PyrSymbol *selector,
+ long numArgsPushed, long numKeyArgsPushed);
+void sendMessage(VMGlobals *g, PyrSymbol *selector, long numArgsPushed);
+void sendSuperMessageWithKeys(VMGlobals *g, PyrSymbol *selector,
+ long numArgsPushed, long numKeyArgsPushed);
+void sendSuperMessage(VMGlobals *g, PyrSymbol *selector, long numArgsPushed);
+void doesNotUnderstandWithKeys(VMGlobals *g, PyrSymbol *selector,
+ long numArgsPushed, long numKeyArgsPushed);
+void doesNotUnderstand(VMGlobals *g, PyrSymbol *selector,
+ long numArgsPushed);
+void returnFromBlock(VMGlobals *g);
+void returnFromMethod(VMGlobals *g);
+void executeMethod(VMGlobals *g, PyrMethod *meth, long numArgsPushed);
+void executeMethodWithKeys(VMGlobals *g, PyrMethod *meth, long allArgsPushed,
+ long numKeyArgsPushed);
+void keywordFixStack(VMGlobals *g, PyrMethod *meth, PyrMethodRaw *methraw, long allArgsPushed,
+ long numKeyArgsPushed);
+
+#endif
+
+
+
diff --git a/sc4pd/headers/lang/PyrObject.h b/sc4pd/headers/lang/PyrObject.h
new file mode 100644
index 0000000..05abf21
--- /dev/null
+++ b/sc4pd/headers/lang/PyrObject.h
@@ -0,0 +1,288 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+PyrObject represents the structure of all SC Objects.
+
+*/
+
+#ifndef _PYROBJECT_H_
+#define _PYROBJECT_H_
+
+#include "PyrSlot.h"
+
+/* special gc colors */
+enum {
+ obj_permanent = 1, // sent to gc->New as a flag
+ obj_gcmarker = 2 // gc treadmill marker
+};
+
+/* obj flag fields */
+enum {
+ obj_immutable = 16,
+ obj_marked = 128
+};
+
+/* format types : */
+enum {
+ obj_notindexed,
+ obj_slot,
+ obj_double,
+ obj_float,
+ obj_int32,
+ obj_int16,
+ obj_int8,
+ obj_char,
+ obj_symbol,
+
+ NUMOBJFORMATS
+};
+
+
+/*
+ PyrObjectHdr : object header fields
+ prev, next : pointers in the GC treadmill
+ classptr : pointer to the object's class
+ size : number of slots or indexable elements.
+
+ obj_format : what kind of data this object holds
+ obj_sizeclass : power of two size class of the object
+ obj_flags :
+ immutable : set if object may not be updated.
+ finalize : set if object requires finalization.
+ marked : used by garbage collector debug sanity check. may be used by primitives but must be cleared before exiting primitive.
+ gc_color : GC color : black, grey, white, free, permanent
+ scratch1 : undefined value. may be used within primitives as a temporary scratch value.
+*/
+
+struct PyrObjectHdr {
+ struct PyrObjectHdr *prev, *next;
+ struct PyrClass *classptr;
+ int size;
+
+ unsigned char obj_format;
+ unsigned char obj_sizeclass;
+ unsigned char obj_flags;
+ unsigned char gc_color;
+
+ int scratch1;
+
+ int SizeClass() { return obj_sizeclass; }
+
+ void SetMark() { obj_flags |= obj_marked; }
+ void ClearMark() { obj_flags &= ~obj_marked; }
+ bool IsMarked() { return obj_flags & obj_marked; }
+ bool IsPermanent() { return gc_color == obj_permanent; }
+};
+
+struct PyrObject : public PyrObjectHdr {
+ PyrSlot slots[1];
+};
+
+struct PyrList : public PyrObjectHdr
+{
+ PyrSlot array;
+};
+
+struct PyrDoubleArray : public PyrObjectHdr
+{
+ double d[1];
+};
+
+struct PyrFloatArray : public PyrObjectHdr
+{
+ float f[1];
+};
+
+struct PyrInt32Array : public PyrObjectHdr
+{
+ uint32 i[1];
+};
+
+struct PyrInt16Array : public PyrObjectHdr
+{
+ uint16 i[1];
+};
+
+struct PyrInt8Array : public PyrObjectHdr
+{
+ uint8 b[1];
+};
+
+struct PyrRGBArray : public PyrObjectHdr
+{
+ RGBColor8 r[1];
+};
+
+struct PyrString : public PyrObjectHdr
+{
+ char s[1];
+};
+
+struct PyrSymbolArray : public PyrObjectHdr
+{
+ PyrSymbol* symbols[1];
+};
+
+extern struct PyrClass *class_object;
+extern struct PyrClass *class_array;
+extern struct PyrClass *class_list, *class_method, *class_fundef, *class_frame, *class_class;
+extern struct PyrClass *class_symbol, *class_nil;
+extern struct PyrClass *class_boolean, *class_true, *class_false;
+extern struct PyrClass *class_int, *class_char, *class_float, *class_complex;
+extern struct PyrClass *class_rawptr;
+extern struct PyrClass *class_string;
+extern struct PyrClass *class_magnitude, *class_number, *class_collection;
+extern struct PyrClass *class_sequenceable_collection;
+extern struct PyrClass *class_arrayed_collection;
+extern struct PyrClass *class_simple_number;
+extern struct PyrClass *class_signal;
+extern struct PyrClass *class_wavetable;
+extern struct PyrClass *class_rawarray;
+extern struct PyrClass *class_int8array;
+extern struct PyrClass *class_int16array;
+extern struct PyrClass *class_int32array;
+extern struct PyrClass *class_symbolarray;
+extern struct PyrClass *class_floatarray;
+extern struct PyrClass *class_doublearray;
+extern struct PyrClass *class_func, *class_absfunc;
+extern struct PyrClass *class_stream;
+extern struct PyrClass *class_process;
+extern struct PyrClass *class_thread;
+extern struct PyrClass *class_routine;
+extern struct PyrClass *class_inf;
+extern struct PyrClass *class_finalizer;
+
+extern PyrSymbol *s_none;
+extern PyrSymbol *s_object;
+extern PyrSymbol *s_bag;
+extern PyrSymbol *s_set;
+extern PyrSymbol *s_identityset;
+extern PyrSymbol *s_dictionary;
+extern PyrSymbol *s_identitydictionary;
+extern PyrSymbol *s_linkedlist;
+extern PyrSymbol *s_sortedlist;
+extern PyrSymbol *s_array;
+extern PyrSymbol *s_list, *s_method, *s_fundef, *s_frame, *s_class;
+extern PyrSymbol *s_symbol, *s_nil, *s_inf;
+extern PyrSymbol *s_boolean, *s_true, *s_false;
+extern PyrSymbol *s_int, *s_char, *s_color, *s_float, *s_complex;
+extern PyrSymbol *s_rawptr, *s_objptr;
+extern PyrSymbol *s_string;
+extern PyrSymbol *s_magnitude, *s_number, *s_collection;
+extern PyrSymbol *s_ordered_collection;
+extern PyrSymbol *s_sequenceable_collection;
+extern PyrSymbol *s_arrayed_collection;
+extern PyrSymbol *s_simple_number;
+extern PyrSymbol *s_signal;
+extern PyrSymbol *s_wavetable;
+extern PyrSymbol *s_int8array;
+extern PyrSymbol *s_int16array;
+extern PyrSymbol *s_int32array;
+extern PyrSymbol *s_symbolarray;
+extern PyrSymbol *s_floatarray;
+extern PyrSymbol *s_doublearray;
+extern PyrSymbol *s_point;
+extern PyrSymbol *s_rect;
+extern PyrSymbol *s_stream;
+extern PyrSymbol *s_process;
+extern PyrSymbol *s_main;
+extern PyrSymbol *s_thread;
+extern PyrSymbol *s_routine;
+extern PyrSymbol *s_linear, *s_exponential, *s_gate;
+extern PyrSymbol *s_env;
+
+extern PyrSymbol *s_audio, *s_control, *s_scalar;
+extern PyrSymbol *s_run;
+extern PyrSymbol *s_next;
+extern PyrSymbol *s_at;
+extern PyrSymbol *s_put;
+extern PyrSymbol *s_series, *s_copyseries, *s_putseries;
+extern PyrSymbol *s_value;
+extern PyrSymbol *s_performList;
+extern PyrSymbol *s_superPerformList;
+extern PyrSymbol *s_ugen, *s_outputproxy;
+extern PyrSymbol *s_new, *s_ref;
+extern PyrSymbol *s_synth, *s_spawn, *s_environment, *s_event;
+extern PyrSymbol *s_interpreter;
+extern PyrSymbol *s_finalizer;
+extern PyrSymbol *s_awake;
+extern PyrSymbol *s_appclock;
+extern PyrSymbol *s_systemclock;
+
+
+extern int gFormatElemSize[NUMOBJFORMATS];
+extern int gFormatElemCapc[NUMOBJFORMATS];
+extern int gFormatElemTag[NUMOBJFORMATS];
+
+void dumpObject(PyrObject *obj);
+void dumpObjectSlot(PyrSlot *slot);
+
+bool respondsTo(PyrSlot *slot, PyrSymbol *selector);
+bool isSubclassOf(struct PyrClass *classobj, struct PyrClass *testclass);
+
+const int kFloatTagIndex = 12;
+extern struct PyrClass* gTagClassTable[16];
+
+inline struct PyrClass* classOfSlot(PyrSlot *slot)
+{
+ PyrClass *classobj;
+ int tag;
+ if (IsFloat(slot)) classobj = gTagClassTable[kFloatTagIndex];
+ else if ((tag = slot->utag & 0xF) == 1) classobj = slot->uo->classptr;
+ else classobj = gTagClassTable[tag];
+
+ return classobj;
+}
+
+typedef int (*ObjFuncPtr)(struct VMGlobals*, struct PyrObject*);
+
+void stringFromPyrString(PyrString *obj, char *str, int maxlength);
+void pstringFromPyrString(PyrString *obj, unsigned char *str, int maxlength);
+
+int instVarOffset(char *classname, char *instvarname);
+int classVarOffset(char *classname, char *classvarname, PyrClass** classobj);
+
+void fillSlots(PyrSlot* slot, int size, PyrSlot* fillslot);
+void nilSlots(PyrSlot* slot, int size);
+void zeroSlots(PyrSlot* slot, int size);
+
+int calcHash(PyrSlot *a);
+int getIndexedFloat(struct PyrObject *obj, int index, float *value);
+int getIndexedDouble(struct PyrObject *obj, int index, double *value);
+void getIndexedSlot(struct PyrObject *obj, PyrSlot *a, int index);
+int putIndexedSlot(struct VMGlobals *g, struct PyrObject *obj, PyrSlot *c, int index);
+int putIndexedFloat(PyrObject *obj, double val, int index);
+
+inline int ARRAYMAXINDEXSIZE(PyrObjectHdr* obj)
+{
+ return (1L << obj->obj_sizeclass);
+}
+
+inline int MAXINDEXSIZE(PyrObjectHdr* obj)
+{
+ return ((1L << obj->obj_sizeclass) * gFormatElemCapc[ obj->obj_format ]);
+}
+
+void InstallFinalizer(VMGlobals* g, PyrObject *inObj, int slotIndex, ObjFuncPtr inFunc);
+
+/////
+
+#endif
diff --git a/sc4pd/headers/lang/PyrObjectProto.h b/sc4pd/headers/lang/PyrObjectProto.h
new file mode 100644
index 0000000..b66ecc2
--- /dev/null
+++ b/sc4pd/headers/lang/PyrObjectProto.h
@@ -0,0 +1,44 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PYROBJPROTO_H_
+#define _PYROBJPROTO_H_
+
+#include "PyrObject.h"
+
+void initSymbols();
+void initClasses();
+void buildClassTree();
+
+void freePyrSlot(PyrSlot *slot);
+void freePyrObject(PyrObject* obj);
+
+bool objAddIndexedSlot(PyrObject *obj, PyrSlot *slot);
+bool objAddIndexedSymbol(PyrSymbolArray *obj, PyrSymbol *symbol);
+bool objAddIndexedObject(PyrObject *obj, PyrObject *obj2);
+
+void CallStackSanity(struct VMGlobals *g, char* tagstr);
+bool FrameSanity(struct PyrFrame *frame, char* tagstr);
+
+void dumpBadObject(PyrObject *obj);
+void initRawRegistry();
+
+#endif
+
diff --git a/sc4pd/headers/lang/PyrParseNode.h b/sc4pd/headers/lang/PyrParseNode.h
new file mode 100644
index 0000000..cd6688c
--- /dev/null
+++ b/sc4pd/headers/lang/PyrParseNode.h
@@ -0,0 +1,456 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PYRPARSENODE_H_
+#define _PYRPARSENODE_H_
+
+#include "PyrSlot.h"
+#include "PyrKernel.h"
+#include "ByteCodeArray.h"
+#include "Opcodes.h"
+#include "AdvancingAllocPool.h"
+
+extern AdvancingAllocPool gParseNodePool;
+
+#define ALLOCNODE(type) (type*)gParseNodePool.Alloc(sizeof(type))
+//#define FREENODE(node) if (node) (*parseNodeClasses[(node)->classno]->deleteFunc)(node);
+#define DUMPNODE(node, level) if (node) (*parseNodeClasses[(node)->classno]->dumpFunc)((node),(level));
+#define COMPILENODE(node, result) (*parseNodeClasses[(node)->classno]->compileFunc)((node),(result));
+
+typedef void (*PyrCompileNodeFunc)(void*, void*);
+typedef void (*PyrDumpNodeFunc)(void*,int);
+
+typedef struct pyrparsenodeclass {
+ int type;
+ PyrCompileNodeFunc compileFunc;
+ PyrDumpNodeFunc dumpFunc;
+} PyrParseNodeClass;
+
+
+struct PyrParseNode {
+ struct PyrParseNode *next;
+ struct PyrParseNode *tail;
+ short lineno;
+ unsigned char charno, classno;
+};
+
+
+struct PyrSlotNode : public PyrParseNode {
+ PyrSlot slot;
+};
+
+extern PyrParseNodeClass *pyrSlotNodeClass;
+
+struct PyrPushNameNode : public PyrParseNode {
+ PyrSlot varName;
+} ;
+
+extern PyrParseNodeClass *pyrPushNameNodeClass;
+
+struct PyrClassExtNode : public PyrParseNode {
+ struct PyrSlotNode* className;
+ struct PyrMethodNode *methods;
+} ;
+
+extern PyrParseNodeClass *pyrClassExtNodeClass;
+
+struct PyrClassNode : public PyrParseNode {
+ struct PyrSlotNode* className;
+ struct PyrSlotNode* superClassName;
+ struct PyrSlotNode* indexType;
+ struct PyrVarListNode *varlists;
+ struct PyrMethodNode *methods;
+ int varTally[3];
+ int numsuperinstvars;
+} ;
+
+extern PyrParseNodeClass *pyrClassNodeClass;
+
+struct PyrMethodNode : public PyrParseNode {
+ struct PyrSlotNode* methodName;
+ struct PyrSlotNode* primitiveName;
+ struct PyrArgListNode *arglist;
+ struct PyrVarListNode *varlist;
+ struct PyrParseNode *body;
+ int isClassMethod; // is class method?
+ bool extension;
+} ;
+
+extern PyrParseNodeClass *pyrMethodNodeClass;
+
+struct PyrVarListNode : public PyrParseNode {
+ struct PyrVarDefNode *varDefs;
+ int flags;
+} ;
+
+extern PyrParseNodeClass *pyrVarListNodeClass;
+
+struct PyrVarDefNode : public PyrParseNode {
+ struct PyrSlotNode* varName;
+ struct PyrLiteralNode* defVal;
+ int flags;
+} ;
+
+extern PyrParseNodeClass *pyrVarDefNodeClass;
+
+struct PyrCallNode : public PyrParseNode {
+ struct PyrSlotNode* selector;
+ struct PyrParseNode *arglist;
+ struct PyrParseNode *keyarglist;
+} ;
+
+extern PyrParseNodeClass *pyrCallNodeClass;
+
+struct PyrBinopCallNode : public PyrParseNode {
+ struct PyrSlotNode* selector;
+ struct PyrParseNode *arg1;
+ struct PyrParseNode *arg2;
+ struct PyrParseNode *arg3;
+} ;
+
+extern PyrParseNodeClass *pyrBinopCallNodeClass;
+
+struct PyrDropNode : public PyrParseNode {
+ struct PyrParseNode *expr1;
+ struct PyrParseNode *expr2;
+} ;
+
+extern PyrParseNodeClass *pyrDropNodeClass;
+
+struct PyrPushLitNode : public PyrParseNode {
+ PyrSlot literalSlot;
+} ;
+
+extern PyrParseNodeClass *pyrPushLitNodeClass;
+
+struct PyrPushKeyArgNode : public PyrParseNode {
+ struct PyrSlotNode* selector;
+ struct PyrParseNode *expr;
+} ;
+
+extern PyrParseNodeClass *pyrPushKeyArgNodeClass;
+
+struct PyrLiteralNode : public PyrParseNode {
+ PyrSlot literalSlot;
+} ;
+
+extern PyrParseNodeClass *pyrLiteralNodeClass;
+
+
+struct PyrReturnNode : public PyrParseNode {
+ struct PyrParseNode *expr; // if null, return self
+} ;
+
+extern PyrParseNodeClass *pyrReturnNodeClass;
+
+struct PyrBlockReturnNode : public PyrParseNode {
+ struct PyrParseNode *expr; // if null, return self
+} ;
+
+extern PyrParseNodeClass *pyrBlockReturnNodeClass;
+
+
+struct PyrAssignNode : public PyrParseNode {
+ struct PyrSlotNode* varName;
+ struct PyrParseNode *expr;
+ bool drop; // allow drop
+} ;
+
+extern PyrParseNodeClass *pyrAssignNodeClass;
+
+struct PyrSetterNode : public PyrParseNode {
+ struct PyrSlotNode* selector;
+ struct PyrParseNode *expr1;
+ struct PyrParseNode *expr2;
+ int flags; // is a var def ?
+} ;
+
+extern PyrParseNodeClass *pyrSetterNodeClass;
+
+struct PyrMultiAssignNode : public PyrParseNode {
+ struct PyrMultiAssignVarListNode *varList;
+ struct PyrParseNode *expr;
+ bool drop; // allow drop
+} ;
+
+extern PyrParseNodeClass *pyrMultiAssignNodeClass;
+
+struct PyrMultiAssignVarListNode : public PyrParseNode {
+ struct PyrSlotNode *varNames;
+ struct PyrSlotNode *rest;
+} ;
+
+extern PyrParseNodeClass *pyrMultiAssignVarListNodeClass;
+
+struct PyrBlockNode : public PyrParseNode {
+ struct PyrArgListNode *arglist;
+ struct PyrVarListNode *varlist;
+ struct PyrParseNode *body;
+ bool isTopLevel;
+ int beginCharNo;
+} ;
+
+
+extern PyrParseNodeClass *pyrBlockNodeClass;
+
+struct PyrArgListNode : public PyrParseNode {
+ struct PyrVarDefNode *varDefs;
+ struct PyrSlotNode *rest;
+} ;
+
+extern PyrParseNodeClass *pyrArgListNodeClass;
+
+struct PyrDynListNode : public PyrParseNode {
+ struct PyrParseNode *classname;
+ struct PyrParseNode *elems;
+} ;
+
+extern PyrParseNodeClass *pyrDynListNodeClass;
+
+struct PyrDynDictNode : public PyrParseNode {
+ struct PyrParseNode *elems;
+} ;
+
+extern PyrParseNodeClass *pyrDynDictNodeClass;
+
+struct PyrLitListNode : public PyrParseNode {
+ struct PyrParseNode *classname;
+ struct PyrParseNode *elems;
+} ;
+
+extern PyrParseNodeClass *pyrLitListNodeClass;
+
+extern PyrParseNode* gRootParseNode;
+extern int gParserResult;
+
+enum { rwPrivate=0, rwReadOnly=1, rwWriteOnly=2, rwReadWrite=3 };
+
+enum { varInst, varClass, varTemp, varPseudo };
+
+enum {
+ /* structural units */
+ pn_ClassNode,
+ pn_ClassExtNode,
+ pn_MethodNode,
+ pn_BlockNode,
+ pn_SlotNode,
+
+ /* variable declarations */
+ pn_VarListNode,
+ pn_VarDefNode,
+ pn_DynDictNode,
+ pn_DynListNode,
+ pn_LitListNode,
+
+ pn_StaticVarListNode,
+ pn_InstVarListNode,
+ pn_PoolVarListNode,
+ pn_ArgListNode,
+ pn_SlotDefNode,
+
+ /* selectors */
+ pn_LiteralNode,
+
+ /* code */
+ pn_PushLitNode,
+ pn_PushNameNode,
+ pn_PushKeyArgNode,
+ pn_CallNode,
+ pn_BinopCallNode,
+ pn_DropNode,
+ pn_AssignNode,
+ pn_MultiAssignNode,
+ pn_MultiAssignVarListNode,
+ pn_SetterNode,
+
+ pn_ReturnNode,
+ pn_BlockReturnNode,
+
+ pn_NumTypes
+};
+
+extern char *parseNodeFormat[pn_NumTypes];
+extern PyrParseNodeClass* parseNodeClasses[pn_NumTypes];
+
+
+void initParseNodes();
+
+PyrParseNodeClass* newParseNodeClass(int type, PyrCompileNodeFunc compileFunc,
+ PyrDumpNodeFunc dumpFunc);
+
+PyrSlotNode* newPyrSlotNode(PyrSlot *slot);
+PyrClassNode* newPyrClassNode(PyrSlotNode* className, PyrSlotNode* superClassName,
+ PyrVarListNode* varlists, PyrMethodNode* methods, PyrSlotNode* indexType);
+PyrClassExtNode* newPyrClassExtNode(PyrSlotNode* className, PyrMethodNode* methods);
+PyrMethodNode* newPyrMethodNode(PyrSlotNode* methodName, PyrSlotNode* primitiveName,
+ PyrArgListNode* arglist, PyrVarListNode *varlist, PyrParseNode* body, int isClassMethod);
+PyrArgListNode* newPyrArgListNode(PyrVarDefNode* varDefs, PyrSlotNode* rest);
+PyrVarListNode* newPyrVarListNode(PyrVarDefNode* vardefs, int flags);
+PyrVarDefNode* newPyrVarDefNode(PyrSlotNode* varName, PyrLiteralNode* defVal, int flags);
+PyrCallNode* newPyrCallNode(PyrSlotNode* selector, PyrParseNode* arglist,
+ PyrParseNode* keyarglist, PyrParseNode* blocklist);
+PyrBinopCallNode* newPyrBinopCallNode(PyrSlotNode* selector,
+ PyrParseNode* arg1, PyrParseNode* arg2, PyrParseNode* arg3);
+PyrDropNode* newPyrDropNode(PyrParseNode* expr1, PyrParseNode* expr2);
+PyrPushKeyArgNode* newPyrPushKeyArgNode(PyrSlotNode* selector, PyrParseNode* expr);
+PyrPushLitNode* newPyrPushLitNode(PyrSlotNode* literalSlot, PyrParseNode* literalObj);
+PyrLiteralNode* newPyrLiteralNode(PyrSlotNode* literalSlot, PyrParseNode* literalObj);
+PyrReturnNode* newPyrReturnNode(PyrParseNode* expr);
+PyrBlockReturnNode* newPyrBlockReturnNode();
+PyrAssignNode* newPyrAssignNode(PyrSlotNode* varName, PyrParseNode* expr, int flags);
+PyrSetterNode* newPyrSetterNode(PyrSlotNode* varName,
+ PyrParseNode* expr1, PyrParseNode* expr2);
+PyrMultiAssignNode* newPyrMultiAssignNode(PyrMultiAssignVarListNode* varList,
+ PyrParseNode* expr, int flags);
+PyrPushNameNode* newPyrPushNameNode(PyrSlotNode *slotNode);
+PyrDynDictNode* newPyrDynDictNode(PyrParseNode *elems);
+PyrDynListNode* newPyrDynListNode(PyrParseNode *classname, PyrParseNode *elems);
+PyrLitListNode* newPyrLitListNode(PyrParseNode *classname, PyrParseNode *elems);
+PyrMultiAssignVarListNode* newPyrMultiAssignVarListNode(PyrSlotNode* varNames,
+ PyrSlotNode* rest);
+PyrBlockNode* newPyrBlockNode(PyrArgListNode *arglist, PyrVarListNode *varlist, PyrParseNode *body, bool isTopLevel);
+
+void compilePyrSlotNode(PyrSlotNode* node, void *result);
+void compilePyrClassNode(PyrClassNode* node, void *result);
+void compilePyrClassExtNode(PyrClassExtNode* node, void *result);
+void compilePyrMethodNode(PyrMethodNode* node, void *result);
+void compilePyrArgListNode(PyrArgListNode* node, void *result);
+void compilePyrVarListNode(PyrVarListNode* node, void *result);
+void compilePyrVarDefNode(PyrVarDefNode* node, void *result);
+void compilePyrCallNode(PyrCallNode* node, void *result);
+void compilePyrBinopCallNode(PyrBinopCallNode* node, void *result);
+void compilePyrPushLitNode(PyrPushLitNode* node, void *result);
+void compilePyrLiteralNode(PyrLiteralNode* node, void *result);
+void compilePyrReturnNode(PyrReturnNode* node, void *result);
+void compilePyrBlockReturnNode(PyrBlockReturnNode* node, void *result);
+void compilePyrAssignNode(PyrAssignNode* node, void *result);
+void compilePyrSetterNode(PyrSetterNode* node, void* result);
+void compilePyrMultiAssignNode(PyrMultiAssignNode* node, void *result);
+void compilePyrMultiAssignVarListNode(PyrMultiAssignVarListNode* node, void *result);
+void compilePyrDynDictNode(PyrDynDictNode* node, void *result);
+void compilePyrDynListNode(PyrDynListNode* node, void *result);
+void compilePyrLitListNode(PyrLitListNode* node, void *result);
+void compilePyrBlockNode(PyrBlockNode* node, void *result);
+void compilePyrPushNameNode(PyrPushNameNode* node, void *result);
+void compilePyrDropNode(PyrDropNode* node, void *result);
+void compilePyrPushKeyArgNode(PyrPushKeyArgNode* node, void *result);
+
+void dumpPyrSlotNode(PyrSlotNode* node, int level);
+void dumpPyrClassNode(PyrClassNode* node, int level);
+void dumpPyrClassExtNode(PyrClassExtNode* node, int level);
+void dumpPyrMethodNode(PyrMethodNode* node, int level);
+void dumpPyrArgListNode(PyrArgListNode* node, int level);
+void dumpPyrVarListNode(PyrVarListNode* node, int level);
+void dumpPyrVarDefNode(PyrVarDefNode* node, int level);
+void dumpPyrCallNode(PyrCallNode* node, int level);
+void dumpPyrBinopCallNode(PyrBinopCallNode* node, int level);
+void dumpPyrPushLitNode(PyrPushLitNode* node, int level);
+void dumpPyrLiteralNode(PyrLiteralNode* node, int level);
+void dumpPyrReturnNode(PyrReturnNode* node, int level);
+void dumpPyrBlockReturnNode(PyrBlockReturnNode* node, int level);
+void dumpPyrAssignNode(PyrAssignNode* node, int level);
+void dumpPyrSetterNode(PyrSetterNode* node, int level);
+void dumpPyrMultiAssignNode(PyrMultiAssignNode* node, int level);
+void dumpPyrMultiAssignVarListNode(PyrMultiAssignVarListNode* node, int level);
+void dumpPyrDynDictNode(PyrDynDictNode* node, int level);
+void dumpPyrDynListNode(PyrDynListNode* node, int level);
+void dumpPyrLitListNode(PyrLitListNode* node, int level);
+void dumpPyrBlockNode(PyrBlockNode* node, int level);
+void dumpPyrPushNameNode(PyrPushNameNode* node, int level);
+void dumpPyrPushKeyArgNode(PyrPushKeyArgNode* node, int level);
+void dumpPyrDropNode(PyrDropNode* node, int level);
+
+PyrClass* getNodeSuperclass(PyrClassNode *node);
+void countNodeMethods(PyrClassNode* node, int *numClassMethods, int *numInstMethods);
+void compileExtNodeMethods(PyrClassExtNode* node);
+void countVarDefs(PyrClassNode* node);
+bool compareVarDefs(PyrClassNode* node, PyrClass* classobj);
+void recompileSubclasses(PyrClass* classobj);
+void compileNodeMethods(PyrClassNode* node);
+void fillClassPrototypes(PyrClassNode *node, PyrClass *classobj, PyrClass *superclassobj);
+
+int nodeListLength(PyrParseNode *node);
+bool isSuperObjNode(PyrParseNode *node);
+bool isThisObjNode(PyrParseNode *node);
+int conjureSelectorIndex(PyrParseNode *node, PyrBlock* func,
+ bool isSuper, PyrSymbol *selector, int *selType);
+int conjureLiteralSlotIndex(PyrParseNode *node, PyrBlock* func, PyrSlot *slot);
+bool findVarName(PyrBlock* func, PyrClass **classobj, PyrSymbol *name,
+ int *varType, int *level, int *index, PyrBlock** tempfunc);
+void countClassVarDefs(PyrClassNode* node, int *numClassMethods, int *numInstMethods);
+void compileNodeList(PyrParseNode *node);
+void dumpNodeList(PyrParseNode *node);
+int compareCallArgs(PyrMethodNode* node, PyrCallNode *cnode, int *varIndex);
+
+bool findSpecialClassName(PyrSymbol *className, int *index);
+int getIndexType(PyrClassNode *classnode);
+
+void compileIfMsg(PyrCallNode* node);
+void compileWhileMsg(PyrCallNode* node);
+void compileLoopMsg(PyrCallNode* node);
+void compileAndMsg(PyrParseNode* arg1, PyrParseNode* arg2);
+void compileOrMsg(PyrParseNode* arg1, PyrParseNode* arg2);
+
+void compilePushInt(int value);
+void compileAssignVar(PyrParseNode *node, PyrSymbol* varName, bool drop);
+void compilePushVar(PyrParseNode *node, PyrSymbol *varName);
+bool isAnInlineableBlock(PyrParseNode *node);
+bool isWhileTrue(PyrParseNode *node);
+void installByteCodes(PyrBlock *block);
+
+ByteCodes compileSubExpression(PyrPushLitNode* litnode);
+ByteCodes compileSubExpressionWithGoto(PyrPushLitNode* litnode, int branchLen);
+//ByteCodes compileDefaultValue(int litIndex, int realExprLen);
+
+void initParser();
+void finiParser();
+void initParserPool();
+void freeParserPool();
+
+void initSpecialSelectors();
+void initSpecialClasses();
+
+void nodePostErrorLine(PyrParseNode* node);
+
+PyrParseNode* linkNextNode(PyrParseNode* a, PyrParseNode* b);
+PyrParseNode* linkAfterHead(PyrParseNode* a, PyrParseNode* b);
+
+extern int compileErrors;
+
+extern long zzval;
+extern PyrSymbol *ps_newlist;
+extern PyrSymbol *gSpecialUnarySelectors[opNumUnarySelectors];
+extern PyrSymbol *gSpecialBinarySelectors[opNumBinarySelectors];
+extern PyrSymbol *gSpecialSelectors[opmNumSpecialSelectors];
+extern PyrSymbol* gSpecialClasses[op_NumSpecialClasses];
+
+extern PyrClass *gCurrentClass;
+extern PyrClass *gCurrentMetaClass;
+extern PyrClass *gCompilingClass;
+extern PyrMethod *gCompilingMethod;
+extern PyrBlock *gCompilingBlock;
+
+/*
+ compiling
+ "inlining" of special arithmetic opcodes.
+ inlining of IF, WHILE, AND, OR
+*/
+
+#endif
diff --git a/sc4pd/headers/lang/PyrPrimitive.h b/sc4pd/headers/lang/PyrPrimitive.h
new file mode 100644
index 0000000..4afe653
--- /dev/null
+++ b/sc4pd/headers/lang/PyrPrimitive.h
@@ -0,0 +1,42 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+Functions for defining language primitives.
+
+*/
+
+#ifndef _PYRPRIMITIVE_H_
+#define _PYRPRIMITIVE_H_
+
+#include "PyrSlot.h"
+
+typedef int (*PrimitiveHandler)(struct VMGlobals *g, int numArgsPushed);
+typedef int (*PrimitiveWithKeysHandler)(struct VMGlobals *g, int numArgsPushed, int numKeyArgsPushed);
+
+int nextPrimitiveIndex();
+int definePrimitive(int base, int index, char *name, PrimitiveHandler handler, int numArgs, int varArgs);
+int definePrimitiveWithKeys(int base, int index, char *name,
+ PrimitiveHandler handler, PrimitiveWithKeysHandler keyhandler,
+ int numArgs, int varArgs);
+int getPrimitiveNumArgs(int index);
+PyrSymbol* getPrimitiveName(int index);
+
+#endif
diff --git a/sc4pd/headers/lang/PyrPrimitiveProto.h b/sc4pd/headers/lang/PyrPrimitiveProto.h
new file mode 100644
index 0000000..43464a4
--- /dev/null
+++ b/sc4pd/headers/lang/PyrPrimitiveProto.h
@@ -0,0 +1,81 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PYRPRIMITIVEPROTO_H_
+#define _PYRPRIMITIVEPROTO_H_
+
+#include "PyrPrimitive.h"
+
+int basicNew(VMGlobals *g, int numArgsPushed);
+int basicNewClear(VMGlobals *g, int numArgsPushed);
+int basicSwap(VMGlobals *g, int numArgsPushed);
+int instVarAt(VMGlobals *g, int numArgsPushed);
+int instVarPut(VMGlobals *g, int numArgsPushed);
+int instVarSize(VMGlobals *g, int numArgsPushed);
+int objectHash(VMGlobals *g, int numArgsPushed);
+int objectClass(VMGlobals *g, int numArgsPushed);
+int blockValue(VMGlobals *g, int numArgsPushed);
+int blockValueWithKeys(VMGlobals *g, int allArgsPushed, int numKeyArgsPushed);
+int blockValueArray(VMGlobals *g, int numArgsPushed);
+int blockSpawn(VMGlobals *g, int numArgsPushed);
+
+int objectIsKindOf(VMGlobals *g, int numArgsPushed);
+int objectIsMemberOf(VMGlobals *g, int numArgsPushed);
+int objectDump(VMGlobals *g, int numArgsPushed);
+int haltInterpreter(VMGlobals *g, int numArgsPushed);
+int objectIdentical(VMGlobals *g, int numArgsPushed);
+int objectNotIdentical(VMGlobals *g, int numArgsPushed);
+int objectPerform(VMGlobals *g, int numArgsPushed);
+int objectPerformList(VMGlobals *g, int numArgsPushed);
+int objectPerformSelList(VMGlobals *g, int numArgsPushed);
+int undefinedPrimitive(VMGlobals *g, int numArgsPushed);
+
+int prObjectString(VMGlobals *g, int numArgsPushed);
+int prClassString(VMGlobals *g, int numArgsPushed);
+int prSymbolString(VMGlobals *g, int numArgsPushed);
+int prSymbolClass(VMGlobals *g, int numArgsPushed);
+int prPostString(VMGlobals *g, int numArgsPushed);
+int prPostLine(VMGlobals *g, int numArgsPushed);
+int prFlushPostBuf(VMGlobals *g, int numArgsPushed);
+
+int prPrimitiveError(VMGlobals *g, int numArgsPushed);
+int prPrimitiveErrorString(VMGlobals *g, int numArgsPushed);
+int prDumpStack(VMGlobals *g, int numArgsPushed);
+int prDebugger(VMGlobals *g, int numArgsPushed);
+int prPrimName(VMGlobals *g, int numArgsPushed);
+int prObjectShallowCopy(VMGlobals *g, int numArgsPushed);
+int prObjectCopyRange(VMGlobals *g, int numArgsPushed);
+int prObjectPointsTo(VMGlobals *g, int numArgsPushed);
+int prObjectRespondsTo(VMGlobals *g, int numArgsPushed);
+
+int prCompileString(VMGlobals *g, int numArgsPushed);
+int prDumpBackTrace(VMGlobals *g, int numArgsPushed);
+int prDumpByteCodes(VMGlobals *g, int numArgsPushed);
+int prAllClasses(VMGlobals *g, int numArgsPushed);
+int prPostClassTree(VMGlobals *g, int numArgsPushed);
+
+void initPrimitiveTable();
+void growPrimitiveTable(int newsize);
+
+void initPrimitives();
+void doPrimitive(VMGlobals* g, struct PyrMethod* meth, int numArgsPushed);
+void doPrimitiveWithKeys(VMGlobals* g, struct PyrMethod* meth, int allArgsPushed, int numKeysPushed);
+
+#endif
diff --git a/sc4pd/headers/lang/PyrSched.h b/sc4pd/headers/lang/PyrSched.h
new file mode 100644
index 0000000..5102582
--- /dev/null
+++ b/sc4pd/headers/lang/PyrSched.h
@@ -0,0 +1,58 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PYRSCHED_H_
+#define _PYRSCHED_H_
+
+#include "VMGlobals.h"
+#include <pthread.h>
+
+extern pthread_mutex_t gLangMutex;
+
+void schedInit();
+void schedCleanup();
+
+void schedRun();
+void schedStop();
+void schedClear();
+
+double elapsedTime();
+int64 OSCTime();
+
+int64 ElapsedTimeToOSC(double elapsed);
+double OSCToElapsedTime(int64 oscTime);
+
+void syncOSCOffsetWithTimeOfDay();
+void doubleToTimespec(double secs, struct timespec *spec);
+
+
+bool addheap(VMGlobals *g, PyrObject *heap, double schedtime, PyrSlot *task);
+bool lookheap(PyrObject *heap, double *schedtime, PyrSlot *task) ;
+bool getheap(PyrObject *heap, double *schedtime, PyrSlot *task) ;
+void offsetheap(VMGlobals *g, PyrObject *heap, double offset) ;
+void dumpheap(PyrObject *heap);
+
+const double kSecondsToOSC = 4294967296.; // pow(2,32)/1
+const double kMicrosToOSC = 4294.967296; // pow(2,32)/1e6
+const double kNanosToOSC = 4.294967296; // pow(2,32)/1e9
+const double kOSCtoSecs = 2.328306436538696e-10; // 1/pow(2,32)
+const double kOSCtoNanos = 0.2328306436538696; // 1e9/pow(2,32)
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/PyrSignal.h b/sc4pd/headers/lang/PyrSignal.h
new file mode 100644
index 0000000..ee57b38
--- /dev/null
+++ b/sc4pd/headers/lang/PyrSignal.h
@@ -0,0 +1,417 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#pragma once on
+
+#include "PyrObject.h"
+#include "GC.h"
+
+#define UNROLL 1
+
+enum {
+ kSignalRate = 0, // index of rate slot
+ kSignalNextNode
+};
+
+#define FSINESIZE 8192.
+#define SINESIZE 8192
+#define SINEMASK 8191
+#define VERY_BIG_FLOAT (1.e10)
+extern float *sineCycle;
+extern float *invSineCycle;
+extern float *pmSineCycle;
+extern double phaseToSineIndex;
+extern double sineIndexToPhase;
+
+//#define FRACTABLESIZE 4096
+//#define FRACMASK 0x3FFC
+//extern float *gFracTable;
+
+
+PyrObject* newPyrSignal(VMGlobals *g, long size);
+
+#if 0
+#define UNROLL8_CODE(size,var,stmt) \
+ endptr = var + size; \
+ switch (size & 7) { \
+ while (var < endptr) { \
+ stmt; \
+ case 7 : stmt; \
+ case 6 : stmt; \
+ case 5 : stmt; \
+ case 4 : stmt; \
+ case 3 : stmt; \
+ case 2 : stmt; \
+ case 1 : stmt; \
+ case 0 : ; \
+ } \
+ }
+#else
+#define UNROLL8_CODE(size,var,stmt) \
+ { int tempi, tempend; \
+ tempend = size>>3; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt;stmt;stmt;stmt; \
+ stmt;stmt;stmt;stmt; \
+ } \
+ tempend = size&7; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt; \
+ } \
+ }
+#endif
+
+#if 0
+#define UNROLL4_CODE(size,var,stmt) \
+ endptr = var + size; \
+ switch (size & 3) { \
+ while (var < endptr) { \
+ stmt; \
+ case 3 : stmt; \
+ case 2 : stmt; \
+ case 1 : stmt; \
+ case 0 : ; \
+ } \
+ }
+#else
+#define UNROLL4_CODE(size,var,stmt) \
+ { int tempi, tempend; \
+ tempend = size>>2; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt;stmt;stmt;stmt; \
+ } \
+ tempend = size&3; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt; \
+ } \
+ }
+#endif
+
+#if 0
+#define FILTER_LOOP(size,var,stmt,stmt2) \
+ endptr = var + size; \
+ switch (size & 3) { \
+ case 0 : while (var < endptr) { \
+ stmt; \
+ case 3 : stmt; \
+ case 2 : stmt; \
+ case 1 : stmt; \
+ stmt2; \
+ } \
+ }
+#else
+#define FILTER_LOOP(size,var,stmt,stmt2) \
+ { int tempi, tempend; \
+ tempend = size>>2; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt;stmt;stmt;stmt; \
+ stmt2; \
+ } \
+ tempend = size&3; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt; \
+ } \
+ }
+#endif
+
+#define UNROLL1_CODE(size,var,stmt) \
+ { int tempi, tempend; \
+ tempend = size; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt; \
+ } \
+ }
+
+
+#if UNROLL == 8
+#define UNROLL_CODE UNROLL8_CODE
+#elif UNROLL == 4
+#define UNROLL_CODE UNROLL4_CODE
+#else
+#define UNROLL_CODE UNROLL1_CODE
+#endif
+
+#if 0
+
+#define BINOP_LOOP1(OP)
+#define BINOP_LOOP2(STMT1, STMT2, STMT3)
+
+#else
+
+#define BINOP_LOOP1(OP) \
+ float *a, *b, *c, *endptr; \
+ PyrObject *outc; \
+ long size; \
+ a = (float*)(ina->slots) - 1; \
+ b = (float*)(inb->slots) - 1; \
+ size = sc_min(ina->size, inb->size); \
+ outc = newPyrSignal(g, size); \
+ c = (float*)(outc->slots) - 1; \
+ endptr = c + size; \
+ switch (size & 3) { \
+ while (c < endptr) { \
+ *++c = *++a OP *++b; \
+ case 3 : *++c = *++a OP *++b; \
+ case 2 : *++c = *++a OP *++b; \
+ case 1 : *++c = *++a OP *++b; \
+ case 0 : ; \
+ } \
+ } \
+ return outc; \
+
+
+#define BINOP_LOOP2(STMT1) \
+ float *a, *b, *c, *endptr; \
+ PyrObject *outc; \
+ long size; \
+ a = (float*)(ina->slots) - 1; \
+ b = (float*)(inb->slots) - 1; \
+ size = sc_min(ina->size, inb->size); \
+ outc = newPyrSignal(g, size); \
+ c = (float*)(outc->slots) - 1; \
+ endptr = c + size; \
+ switch (size & 3) { \
+ while (c < endptr) { \
+ STMT1; \
+ case 3 :STMT1; \
+ case 2 :STMT1; \
+ case 1 :STMT1; \
+ case 0 : ; \
+ } \
+ } \
+ return outc; \
+
+#endif
+
+/*
+ compound formulas :
+ amclip out = B<=0 ? 0 : A*B; // two quadrant amplitude modulation
+ ring1 out = A*(B+1) = A*B + A; // amplitude modulation of a by b.
+ ring2 out = A*B + A + B; // ring modulation plus both original signals
+ ring3 out = A*A*B; // ring modulation variant
+ ring4 out = A*A*B - A*B*B; // ring modulation variant
+ difsqr out = A*A - B*B; // difference of squares
+ sumsqr out = A*A + B*B; // sum of squares
+ sqrdif out = (A - B)^2 // square of the difference = a^2 + b^2 - 2ab
+ sqrsum out = (A + B)^2 // square of the sum = a^2 + b^2 + 2ab
+*/
+
+void signal_init_globs();
+PyrObject* signal_fill(PyrObject *outSignal, float inValue);
+PyrObject* signal_scale(PyrObject *outSignal, float inValue);
+PyrObject* signal_offset(PyrObject *outSignal, float inValue);
+PyrObject* signal_scale_offset(PyrObject *outSignal, float mul, float add);
+PyrObject* signal_mix(PyrObject* ina, PyrObject* inb, float start, float end, float slopeFactor);
+PyrObject* signal_add_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_sub_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_mul_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_mul_ds_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_add_ds_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_sub_ds_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_ring1_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_ring2_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_ring3_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_ring4_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_thresh_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_amclip_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_div_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_difsqr_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_sumsqr_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_sqrsum_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_sqrdif_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_add_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_sub_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_mul_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_ring1_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_ring2_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_ring3_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_ring4_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_thresh_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_amclip_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_div_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_difsqr_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_sumsqr_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_sqrsum_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_sqrdif_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_ring1_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_ring2_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_ring3_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_ring4_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_thresh_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_amclip_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_sub_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_div_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_difsqr_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_sumsqr_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_sqrsum_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_sqrdif_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_min_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_max_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_min_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_max_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_invert(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_recip(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_squared(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_cubed(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_abs(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_sign(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_negative(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_positive(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_strictly_positive(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_nyqring(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_clip_f(VMGlobals *g, PyrObject *inPyrSignal, float lo, float hi);
+PyrObject* signal_clip_f_ds(PyrObject *inPyrSignal, float lo, float hi);
+PyrObject* signal_clip_x(VMGlobals *g, PyrObject *ina, PyrObject *inb, PyrObject *inc);
+PyrObject* signal_wrap_f(VMGlobals *g, PyrObject *inPyrSignal, float lo, float hi);
+PyrObject* signal_wrap_x(VMGlobals *g, PyrObject *ina, PyrObject *inb, PyrObject *inc);
+PyrObject* signal_fold_f(VMGlobals *g, PyrObject *inPyrSignal, float lo, float hi);
+PyrObject* signal_fold_x(VMGlobals *g, PyrObject *ina, PyrObject *inb, PyrObject *inc);
+PyrObject* signal_log(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_log2(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_log10(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_sin(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_cos(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_tan(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_sinh(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_cosh(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_tanh(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_asin(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_acos(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_atan(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_exp(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_sqrt(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_distort(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_distortneg(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_softclip(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_softclipneg(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_fsin(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_poly3(VMGlobals *g, PyrObject *inPyrSignal, float a, float b, float c);
+PyrObject* signal_poly3r(VMGlobals *g, PyrObject *inPyrSignal,
+ float a1, float a2, float b1, float b2, float c1, float c2, float slopeFactor);
+PyrObject* signal_integrate(VMGlobals *g, PyrObject *inPyrSignal, float *ioSum);
+PyrObject* signal_leakdc(VMGlobals *g, PyrObject *inPyrSignal, float *ioDC, float leakFactor);
+PyrObject* signal_ampflw1(VMGlobals *g, PyrObject *inPyrSignal, float *ioAmp, float leak1);
+PyrObject* signal_ampflw2(VMGlobals *g, PyrObject *inPyrSignal, float *ioAmp, float leak1);
+PyrObject* signal_differentiate(VMGlobals *g, PyrObject *inPyrSignal, float *ioPrev);
+PyrObject* signal_rotate(VMGlobals *g, PyrObject* ina, int rot);
+PyrObject* signal_reverse_ds(PyrObject* ina);
+PyrObject* signal_cat(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_insert(VMGlobals *g, PyrObject* ina, PyrObject* inb, long index);
+PyrObject* signal_overdub(VMGlobals *g, PyrObject* ina, PyrObject* inb, long index);
+PyrObject* signal_overwrite(VMGlobals *g, PyrObject* ina, PyrObject* inb, long index);
+PyrObject* signal_cat3(VMGlobals *g, PyrObject* ina, PyrObject* inb, PyrObject* inc);
+PyrObject* signal_linen(VMGlobals *g, PyrObject* ina, long atk, long dcy, float amp);
+PyrObject* signal_linen2(VMGlobals *g, PyrObject* ina, long atk, long dcy, float amp, float midamp);
+PyrObject* signal_writesplice(VMGlobals *g, PyrObject* outc, PyrObject* ina, PyrObject* inb,
+ long indexc, long indexa, long indexb, long fadelen, float midamp);
+PyrObject* signal_splice(VMGlobals *g, PyrObject* ina, PyrObject* inb,
+ long indexa, long indexb, long fadelen, float midamp);
+
+PyrObject* signal_invert_ds(PyrObject *inPyrSignal);
+PyrObject* signal_recip_ds(PyrObject *inPyrSignal);
+PyrObject* signal_squared_ds(PyrObject *inPyrSignal);
+PyrObject* signal_cubed_ds(PyrObject *inPyrSignal);
+PyrObject* signal_abs_ds(PyrObject *inPyrSignal);
+PyrObject* signal_sign_ds(PyrObject *inPyrSignal);
+PyrObject* signal_negative_ds(PyrObject *inPyrSignal);
+PyrObject* signal_positive_ds(PyrObject *inPyrSignal);
+PyrObject* signal_strictly_positive_ds(PyrObject *inPyrSignal);
+PyrObject* signal_nyqring_ds(PyrObject *inPyrSignal);
+
+PyrObject* signal_clipneg_ds(PyrObject *inPyrSignal);
+PyrObject* signal_distort_ds(PyrObject *inPyrSignal);
+PyrObject* signal_distortneg_ds(PyrObject *inPyrSignal);
+PyrObject* signal_softclip_ds(PyrObject *inPyrSignal);
+PyrObject* signal_softclipneg_ds(PyrObject *inPyrSignal);
+PyrObject* signal_fsin_ds(PyrObject *inPyrSignal);
+
+PyrObject* signal_log_ds(PyrObject *inPyrSignal);
+PyrObject* signal_log2_ds(PyrObject *inPyrSignal);
+PyrObject* signal_log10_ds(PyrObject *inPyrSignal);
+PyrObject* signal_sin_ds(PyrObject *inPyrSignal);
+PyrObject* signal_cos_ds(PyrObject *inPyrSignal);
+PyrObject* signal_tan_ds(PyrObject *inPyrSignal);
+PyrObject* signal_sinh_ds(PyrObject *inPyrSignal);
+PyrObject* signal_cosh_ds(PyrObject *inPyrSignal);
+PyrObject* signal_tanh_ds(PyrObject *inPyrSignal);
+PyrObject* signal_asin_ds(PyrObject *inPyrSignal);
+PyrObject* signal_acos_ds(PyrObject *inPyrSignal);
+PyrObject* signal_atan_ds(PyrObject *inPyrSignal);
+PyrObject* signal_exp_ds(PyrObject *inPyrSignal);
+PyrObject* signal_sqrt_ds(PyrObject *inPyrSignal);
+
+float signal_findpeak(PyrObject *inPyrSignal);
+PyrObject* signal_normalize(PyrObject *inPyrSignal);
+PyrObject* signal_normalize_transfer_fn(PyrObject *inPyrSignal);
+float signal_integral(PyrObject *inPyrSignal);
+PyrObject* signal_combself(VMGlobals *g, PyrObject* ina, long rot);
+PyrObject* signal_bilinen(VMGlobals *g, PyrObject* ina, long atk, long dcy, float amp, float midamp);
+PyrObject* signal_lace2(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+void signal_unlace2(VMGlobals *g, PyrObject* ina, PyrObject** outb, PyrObject** outc);
+void signal_convolve(VMGlobals *g, PyrObject* ina, PyrObject* ir, PyrObject* previn, long *ppos);
+PyrObject* signal_thumbnail(VMGlobals *g, PyrObject* ina, long startpos, long length, int binsize);
+
+PyrObject* signal_scaleneg_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_scaleneg_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_scaleneg_fx(VMGlobals *g, float ina, PyrObject* inb);
+
+PyrObject* signal_clip2_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_clip2_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_clip2_fx(VMGlobals *g, float ina, PyrObject* inb);
+
+PyrObject* signal_fold2_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_fold2_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_fold2_fx(VMGlobals *g, float ina, PyrObject* inb);
+
+PyrObject* signal_wrap2_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_wrap2_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_wrap2_fx(VMGlobals *g, float ina, PyrObject* inb);
+
+PyrObject* signal_excess_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_excess_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_excess_fx(VMGlobals *g, float ina, PyrObject* inb);
+
+PyrObject* signal_absdif_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_absdif_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_absdif_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+
+bool signal_equal_xf(VMGlobals *g, PyrObject* ina, float inb);
+bool signal_equal_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+
+void signal_get_bounds(PyrObject* ina, float *ominval, float *omaxval);
+
+void signal_smooth_ds(PyrObject* inPyrSignal);
+void signal_hanning_ds(PyrObject* inPyrSignal);
+void signal_welch_ds(PyrObject* inPyrSignal);
+void signal_parzen_ds(PyrObject* inPyrSignal);
+
+PyrObject* signal_normalize_range(PyrObject* ina, long start, long end);
+PyrObject* signal_zero_range(PyrObject* ina, long start, long end);
+PyrObject* signal_invert_range(PyrObject* ina, long start, long end);
+PyrObject* signal_reverse_range(PyrObject* ina, long start, long end);
+PyrObject* signal_fade_in(PyrObject* ina, long start, long end);
+PyrObject* signal_fade_out(PyrObject* ina, long start, long end);
+PyrObject* signal_abs_range(PyrObject* ina, long start, long end);
+PyrObject* signal_squared_range(PyrObject* ina, long start, long end);
+PyrObject* signal_cubed_range(PyrObject* ina, long start, long end);
+PyrObject* signal_distort_range(PyrObject* ina, long start, long end);
+
+PyrObject* signal_fade_range(PyrObject* ina, long start, long end, float lvl0, float lvl1);
diff --git a/sc4pd/headers/lang/PyrSignalPrim.h b/sc4pd/headers/lang/PyrSignalPrim.h
new file mode 100644
index 0000000..bea68ca
--- /dev/null
+++ b/sc4pd/headers/lang/PyrSignalPrim.h
@@ -0,0 +1,56 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _PYRSIGNALPRIM_H_
+#define _PYRSIGNALPRIM_H_
+
+extern PyrSymbol *s_wavetable;
+extern struct PyrClass *class_wavetable;
+
+void initSignalPrimitives();
+
+int prSignalCat(VMGlobals *g, int numArgsPushed);
+int prSignalFill(VMGlobals *g, int numArgsPushed);
+int prSignalRamp(VMGlobals *g, int numArgsPushed);
+int prSignalScale(VMGlobals *g, int numArgsPushed);
+int prSignalOffset(VMGlobals *g, int numArgsPushed);
+int prSignalString(VMGlobals *g, int numArgsPushed);
+
+int prSignalPeak(VMGlobals *g, int numArgsPushed);
+int prSignalNormalize(VMGlobals *g, int numArgsPushed);
+int prSignalNormalizeTransferFn(VMGlobals *g, int numArgsPushed);
+int prSignalIntegral(VMGlobals *g, int numArgsPushed);
+
+int prSignalOverDub(VMGlobals *g, int numArgsPushed);
+int prSignalOverWrite(VMGlobals *g, int numArgsPushed);
+int prSignalFade(VMGlobals *g, int numArgsPushed);
+int prSignalAddHarmonic(VMGlobals *g, int numArgsPushed);
+int prSignalAsWavetable(VMGlobals *g, int numArgsPushed);
+int prWavetableAsSignal(VMGlobals *g, int numArgsPushed);
+
+int prSignalInvert(VMGlobals *g, int numArgsPushed);
+int prSignalReverse(VMGlobals *g, int numArgsPushed);
+int prSignalRotate(VMGlobals *g, int numArgsPushed);
+
+void signalAsWavetable(float *signal, float *wavetable, int size);
+void wavetableAsSignal(float *wavetable, float *signal, int size);
+
+#endif
diff --git a/sc4pd/headers/lang/PyrSlot.h b/sc4pd/headers/lang/PyrSlot.h
new file mode 100644
index 0000000..78bcd12
--- /dev/null
+++ b/sc4pd/headers/lang/PyrSlot.h
@@ -0,0 +1,286 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+PyrSlot is a value holder for SC variables.
+A PyrSlot is an 8-byte value which is either a double precision float or a
+32-bit tag plus a 32-bit value.
+
+*/
+
+#ifndef _PYRSLOT_H_
+#define _PYRSLOT_H_
+
+#include "SC_Endian.h"
+#include "PyrSymbol.h"
+
+/*
+ Pyrite slots are the size of an 8 byte double. If the upper bits
+ indicate that the double is a 'Not-A-Number' then the upper 32
+ bits are used as a tag to indicate one of a number of other types
+ whose data is in the lower 32 bits.
+*/
+
+/* some DSPs like the TIC32 do not support 8 byte doubles */
+/* on such CPUs, set DOUBLESLOTS to zero */
+
+#define DOUBLESLOTS 1
+
+/* use the high order bits of an IEEE double NaN as a tag */
+enum {
+ tagObj = 0x7FF90001,
+ tagHFrame = 0x7FF90002,
+ tagSFrame = 0x7FF90003,
+ tagInt = 0x7FF90004,
+ tagSym = 0x7FF90005,
+ tagChar = 0x7FF90006,
+ tagNil = 0x7FF90007, // nil, false, and true are indicated by the tag alone.
+ tagFalse = 0x7FF90008, // the lower 32 bits are zero.
+ tagTrue = 0x7FF90009,
+ tagInf = 0x7FF9000A,
+ tagPtr = 0x7FF9000B,
+ /* anything else is a double */
+ tagUnused = 0x7FF9000E
+
+
+#if !DOUBLESLOTS
+ ,tagFloat = 0x7FF9000F /* used only to initialized 4 byte float tags, never compared with */
+#endif
+};
+
+struct RGBColor8 {
+ unsigned char c[4];
+};
+
+typedef union pyrslot {
+ double f;
+ struct {
+#if BYTE_ORDER == BIG_ENDIAN
+ int tag;
+#endif // BIG_ENDIAN
+ union {
+ int c; /* char */
+ int i;
+ float f;
+ void *ptr;
+ struct RGBColor8 r;
+ struct PyrObject *o;
+ PyrSymbol *s;
+ struct PyrMethod *om;
+ struct PyrBlock *oblk;
+ struct PyrClass *oc;
+ struct PyrFrame *of;
+ struct PyrList *ol;
+ struct PyrString *os;
+ struct PyrInt8Array *ob;
+ struct PyrDoubleArray *od;
+ struct PyrSymbolArray *osym;
+ struct PyrParseNode *opn;
+ struct PyrProcess *op;
+ struct PyrThread *ot;
+ struct PyrInterpreter *oi;
+ struct PyrPlug *plug;
+ } u;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ // need to swap on intel <sk>
+ int tag;
+#endif // LITTLE_ENDIAN
+ } s;
+} PyrSlot;
+
+/*
+ these are some defines to make accessing the structure less verbose.
+ obviously it polutes the namespace of identifiers beginning with 'u'.
+*/
+#define utag s.tag
+//int
+#define ui s.u.i
+//PyrObject
+#define uo s.u.o
+//PyrSymbol
+#define us s.u.s
+//RGBColor8
+#define ur s.u.r
+#define uc s.u.c
+#define uoc s.u.oc
+#define uof s.u.of
+#define uol s.u.ol
+#define uod s.u.od
+#define uob s.u.ob
+#define uop s.u.op
+#define uoi s.u.oi
+#define uod s.u.od
+//string
+#define uos s.u.os
+#define uot s.u.ot
+//method
+#define uom s.u.om
+//symbol array
+#define uosym s.u.osym
+#define uoblk s.u.oblk
+#define uopn s.u.opn
+#define uptr s.u.ptr
+#define uplug s.u.plug
+
+#if DOUBLESLOTS
+#define uf f
+#else
+#define uf s.u.f
+#endif
+
+#define ucopy f
+
+/*
+ Note that on the PowerPC, the fastest way to copy a slot is to
+ copy the double field, not the struct.
+*/
+
+/* some macros for setting values of slots */
+inline void SetInt(PyrSlot* slot, int val) { (slot)->utag = tagInt; (slot)->ui = (val); }
+inline void SetObject(PyrSlot* slot, void* val) { (slot)->utag = tagObj; (slot)->uo = (PyrObject*)(val); }
+inline void SetSymbol(PyrSlot* slot, PyrSymbol *val) { (slot)->utag = tagSym; (slot)->us = (val); }
+inline void SetChar(PyrSlot* slot, char val) { (slot)->utag = tagChar; (slot)->uc = (val); }
+inline void SetPtr(PyrSlot* slot, void* val) { (slot)->utag = tagPtr; (slot)->uptr = (void*)(val); }
+inline void SetObjectOrNil(PyrSlot* slot, PyrObject* val)
+{
+ if (val) {
+ (slot)->utag = tagObj;
+ (slot)->uo = (val);
+ } else {
+ (slot)->utag = tagNil;
+ (slot)->ui = 0;
+ }
+}
+
+inline void SetTrue(PyrSlot* slot) { (slot)->utag = tagTrue; (slot)->ui = 0; }
+inline void SetFalse(PyrSlot* slot) { (slot)->utag = tagFalse; (slot)->ui = 0; }
+inline void SetBool(PyrSlot* slot, bool test) { (slot)->utag = ((test) ? tagTrue : tagFalse); (slot)->ui = 0; }
+inline void SetNil(PyrSlot* slot) { (slot)->utag = tagNil; (slot)->ui = 0; }
+inline void SetInf(PyrSlot* slot) { (slot)->utag = tagInf; (slot)->ui = 0; }
+
+#if DOUBLESLOTS
+inline void SetFloat(PyrSlot* slot, double val) { (slot)->uf = (val); }
+#else
+inline void SetFloat(PyrSlot* slot, double val) { (slot)->utag = s_float; (slot)->uf = (val); }
+#endif
+
+inline bool IsObj(PyrSlot* slot) { return ((slot)->utag == tagObj); }
+inline bool NotObj(PyrSlot* slot) { return ((slot)->utag != tagObj); }
+
+inline bool IsNil(PyrSlot* slot) { return ((slot)->utag == tagNil); }
+inline bool NotNil(PyrSlot* slot) { return ((slot)->utag != tagNil); }
+
+inline bool IsFalse(PyrSlot* slot) { return ((slot)->utag == tagFalse); }
+inline bool IsTrue(PyrSlot* slot) { return ((slot)->utag == tagTrue); }
+
+inline bool SlotEq(PyrSlot* a, PyrSlot* b) { return ((a)->ui == (b)->ui && (a)->utag == (b)->utag); }
+
+inline bool IsSym(PyrSlot* slot) { return ((slot)->utag == tagSym); }
+inline bool NotSym(PyrSlot* slot) { return ((slot)->utag != tagSym); }
+
+inline bool IsInt(PyrSlot* slot) { return ((slot)->utag == tagInt); }
+inline bool NotInt(PyrSlot* slot) { return ((slot)->utag != tagInt); }
+
+inline bool IsFloatTag(int tag) { return ((tag & 0xFFFFFFF0) != 0x7FF90000); }
+inline bool IsFloat(PyrSlot* slot) { return (((slot)->utag & 0xFFFFFFF0) != 0x7FF90000); }
+inline bool NotFloat(PyrSlot* slot) { return (((slot)->utag & 0xFFFFFFF0) == 0x7FF90000); }
+
+inline bool IsInf(PyrSlot* slot) { return ((slot)->utag == tagInf); }
+inline bool IsPtr(PyrSlot* slot) { return ((slot)->utag == tagPtr); }
+
+inline bool IsFrame(PyrSlot* slot) { return ((slot)->utag == tagHFrame || (slot)->utag == tagSFrame); }
+
+
+void dumpPyrSlot(PyrSlot* slot);
+void slotString(PyrSlot *slot, char *str);
+void slotOneWord(PyrSlot *slot, char *str);
+bool postString(PyrSlot *slot, char *str);
+char *slotSymString(PyrSlot* slot);
+int asCompileString(PyrSlot *slot, char *str);
+
+int slotIntVal(PyrSlot* slot, int *value);
+int slotFloatVal(PyrSlot* slot, float *value);
+int slotDoubleVal(PyrSlot *slot, double *value);
+int slotStrVal(PyrSlot *slot, char *str, int maxlen);
+int slotPStrVal(PyrSlot *slot, unsigned char *str);
+int slotSymbolVal(PyrSlot *slot, PyrSymbol **symbol);
+
+extern PyrSlot o_nil, o_true, o_false, o_inf;
+extern PyrSlot o_pi, o_twopi;
+extern PyrSlot o_fhalf, o_fnegone, o_fzero, o_fone, o_ftwo;
+extern PyrSlot o_negtwo, o_negone, o_zero, o_one, o_two;
+extern PyrSlot o_emptyarray, o_onenilarray, o_argnamethis;
+
+extern PyrSymbol *s_object; // "Object"
+extern PyrSymbol *s_this; // "this"
+extern PyrSymbol *s_super; // "super"
+
+inline int slotFloatVal(PyrSlot *slot, float *value)
+{
+ if (IsFloat(slot)) {
+ *value = slot->uf;
+ return errNone;
+ } else if (IsInt(slot)) {
+ *value = slot->ui;
+ return errNone;
+ }
+ return errWrongType;
+}
+
+inline int slotIntVal(PyrSlot *slot, int *value)
+{
+ if (IsInt(slot)) {
+ *value = slot->ui;
+ return errNone;
+ } else if (IsFloat(slot)) {
+ *value = (int)slot->uf;
+ return errNone;
+ }
+ return errWrongType;
+}
+
+inline int slotDoubleVal(PyrSlot *slot, double *value)
+{
+ if (IsFloat(slot)) {
+ *value = slot->uf;
+ return errNone;
+ } else if (IsInt(slot)) {
+ *value = slot->ui;
+ return errNone;
+ }
+ return errWrongType;
+}
+
+inline int slotSymbolVal(PyrSlot *slot, PyrSymbol **symbol)
+{
+ if (!IsSym(slot)) return errWrongType;
+ *symbol = slot->us;
+ return errNone;
+}
+
+inline void slotCopy(PyrSlot *dst, PyrSlot *src, int num)
+{
+ double *dstp = (double*)dst - 1;
+ double *srcp = (double*)src - 1;
+ for (int i=0;i<num;++i) { *++dstp = *++srcp; }
+}
+
+
+#endif
diff --git a/sc4pd/headers/lang/PyrSymbol.h b/sc4pd/headers/lang/PyrSymbol.h
new file mode 100644
index 0000000..621f7c2
--- /dev/null
+++ b/sc4pd/headers/lang/PyrSymbol.h
@@ -0,0 +1,59 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+A PyrSymbol is a unique string that resides in a global hash table.
+
+*/
+
+#ifndef _PYRSYMBOL_H_
+#define _PYRSYMBOL_H_
+
+#include "SCBase.h"
+
+struct PyrSymbol {
+ char *name;
+ long hash;
+ short specialIndex;
+ uint8 flags;
+ uint8 length;
+ union {
+ long index; // index in row table or primitive table
+ struct PyrClass *classobj; // pointer to class with this name.
+ } u;
+ struct classdep *classdep;
+};
+
+enum {
+ sym_Selector = 1,
+ sym_Class = 2,
+ sym_Compiled = 4,
+ sym_Called = 8,
+ sym_Primitive = 16,
+ sym_Setter = 32,
+ sym_MetaClass = 64,
+ sym_Filename = 128
+};
+
+PyrSymbol* getsym(const char *name);
+PyrSymbol* getmetasym(const char *name);
+PyrSymbol* findsym(const char *name);
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/PyrSymbolTable.h b/sc4pd/headers/lang/PyrSymbolTable.h
new file mode 100644
index 0000000..7cc03cb
--- /dev/null
+++ b/sc4pd/headers/lang/PyrSymbolTable.h
@@ -0,0 +1,78 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SymbolTable_
+#define _SymbolTable_
+
+#include "PyrSymbol.h"
+#include "AdvancingAllocPool.h"
+
+#define STRINGCHUNK 32000
+#define SYMBOLCHUNK 32000
+
+class SymbolSpace
+{
+public:
+ SymbolSpace(AllocPool *inPool);
+ PyrSymbol* NewSymbol(const char *inName, int inHash, int inLength);
+
+private:
+ AllocPool *mPool;
+ AdvancingAllocPool mStringPool;
+ AdvancingAllocPool mSymbolPool;
+};
+
+class SymbolTable
+{
+public:
+
+ SymbolTable(AllocPool *inPool, int inSize);
+
+ void CopyFrom(SymbolTable& inTable);
+
+ int NumItems() { return mNumItems; }
+ int TableSize() { return mMaxItems; }
+ PyrSymbol* Get(int inIndex) { return mTable[inIndex]; }
+
+ void CheckSymbols();
+
+private:
+ friend PyrSymbol* getsym(const char *name);
+ friend PyrSymbol* findsym(const char *name);
+
+ PyrSymbol* Find(const char *inName);
+ PyrSymbol* Make(const char *inName);
+ PyrSymbol* MakeNew(const char *inName, int inHash, int inLength);
+
+ int StrHash(const char *inName, int *outLength);
+ void AllocTable();
+ void Grow();
+ PyrSymbol* Find(const char *inName, int inHash);
+ void Add(PyrSymbol* inSymbol);
+ void Rehash(PyrSymbol** inTable, int inSize);
+ void MakeEmpty();
+
+ AllocPool *mPool;
+ SymbolSpace mSpace;
+ PyrSymbol **mTable;
+ int mNumItems, mMaxItems, mMask;
+};
+
+#endif
diff --git a/sc4pd/headers/lang/ReadWriteMacros.h b/sc4pd/headers/lang/ReadWriteMacros.h
new file mode 100644
index 0000000..2117fb6
--- /dev/null
+++ b/sc4pd/headers/lang/ReadWriteMacros.h
@@ -0,0 +1,336 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _ReadWriteMacros_
+#define _ReadWriteMacros_
+
+#include "SC_Types.h"
+#include "SC_Endian.h"
+#include <stdio.h>
+#include <string.h>
+
+template <class T>
+class SC_IOStream
+{
+protected:
+ T s;
+public:
+ SC_IOStream() : s(0) {}
+ SC_IOStream(T inStream) : s(inStream) {}
+
+ void SetStream(T inStream) { s = inStream; }
+ T GetStream() { return s; }
+
+ // core routines
+ void readData(char *data, int size);
+ uint8 readUInt8();
+
+ void writeData(char *data, int size);
+ void writeUInt8(uint8 inInt);
+
+ // built using core routines
+ void writeInt8(int8 inInt)
+ {
+ writeUInt8((uint8)inInt);
+ }
+
+ void writeInt16_be(int16 inInt)
+ {
+ writeUInt8((uint8)(inInt >> 8));
+ writeUInt8(inInt);
+ }
+
+ void writeInt16_le(int16 inInt)
+ {
+ writeUInt8((uint8)inInt);
+ writeUInt8((uint8)(inInt >> 8));
+ }
+
+ void writeInt32_be(int32 inInt)
+ {
+ writeUInt8((uint8)(inInt >> 24));
+ writeUInt8((uint8)(inInt >> 16));
+ writeUInt8((uint8)(inInt >> 8));
+ writeUInt8((uint8)inInt);
+ }
+
+ void writeInt32_le(int32 inInt)
+ {
+ writeUInt8((uint8)inInt);
+ writeUInt8((uint8)(inInt >> 8));
+ writeUInt8((uint8)(inInt >> 16));
+ writeUInt8((uint8)(inInt >> 24));
+ }
+
+#if BYTE_ORDER == BIG_ENDIAN
+ void writeFloat_be(float inFloat)
+#else
+ void writeFloat_le(float inFloat)
+#endif
+ {
+ union {
+ float f;
+ uint8 c[4];
+ } u;
+ u.f = inFloat;
+ writeUInt8(u.c[0]);
+ writeUInt8(u.c[1]);
+ writeUInt8(u.c[2]);
+ writeUInt8(u.c[3]);
+ }
+
+#if BYTE_ORDER == BIG_ENDIAN
+ void writeFloat_le(float inFloat)
+#else
+ void writeFloat_be(float inFloat)
+#endif
+ {
+ union {
+ float f;
+ uint8 c[4];
+ } u;
+ u.f = inFloat;
+ writeUInt8(u.c[3]);
+ writeUInt8(u.c[2]);
+ writeUInt8(u.c[1]);
+ writeUInt8(u.c[0]);
+ }
+
+
+#if BYTE_ORDER == BIG_ENDIAN
+ void writeDouble_be(double inDouble)
+#else
+ void writeDouble_le(double inDouble)
+#endif
+ {
+ union {
+ double f;
+ uint8 c[8];
+ } u;
+ u.f = inDouble;
+ writeUInt8(u.c[0]);
+ writeUInt8(u.c[1]);
+ writeUInt8(u.c[2]);
+ writeUInt8(u.c[3]);
+ writeUInt8(u.c[4]);
+ writeUInt8(u.c[5]);
+ writeUInt8(u.c[6]);
+ writeUInt8(u.c[7]);
+ }
+
+#if BYTE_ORDER == BIG_ENDIAN
+ void writeDouble_le(double inDouble)
+#else
+ void writeDouble_be(double inDouble)
+#endif
+ {
+ union {
+ double f;
+ uint8 c[8];
+ } u;
+ u.f = inDouble;
+ writeUInt8(u.c[7]);
+ writeUInt8(u.c[6]);
+ writeUInt8(u.c[5]);
+ writeUInt8(u.c[4]);
+ writeUInt8(u.c[3]);
+ writeUInt8(u.c[2]);
+ writeUInt8(u.c[1]);
+ writeUInt8(u.c[0]);
+ }
+
+
+ int8 readInt8()
+ {
+ return (int8)readUInt8();
+ }
+
+ int16 readInt16_be()
+ {
+ uint8 a = readUInt8();
+ uint8 b = readUInt8();
+ return (int16)((a << 8) | b);
+ }
+
+ int16 readInt16_le()
+ {
+ uint8 a = readUInt8();
+ uint8 b = readUInt8();
+ return (int16)((b << 8) | a);
+ }
+
+ int32 readInt32_be()
+ {
+ uint8 a = readUInt8();
+ uint8 b = readUInt8();
+ uint8 c = readUInt8();
+ uint8 d = readUInt8();
+ return (int32)((a << 24) | (b << 16) | (c << 8) | d);
+ }
+
+ int32 readInt32_le()
+ {
+ uint8 a = readUInt8();
+ uint8 b = readUInt8();
+ uint8 c = readUInt8();
+ uint8 d = readUInt8();
+ return (int32)((d << 24) | (c << 16) | (b << 8) | a);
+ }
+
+#if BYTE_ORDER == BIG_ENDIAN
+ float readFloat_be()
+#else
+ float readFloat_le()
+#endif
+ {
+ union {
+ float f;
+ uint8 c[4];
+ } u;
+ u.c[0] = readUInt8();
+ u.c[1] = readUInt8();
+ u.c[2] = readUInt8();
+ u.c[3] = readUInt8();
+ return u.f;
+ }
+
+#if BYTE_ORDER == BIG_ENDIAN
+ float readFloat_le()
+#else
+ float readFloat_be()
+#endif
+ {
+ union {
+ float f;
+ uint8 c[4];
+ } u;
+ u.c[3] = readUInt8();
+ u.c[2] = readUInt8();
+ u.c[1] = readUInt8();
+ u.c[0] = readUInt8();
+ return u.f;
+ }
+
+
+#if BYTE_ORDER == BIG_ENDIAN
+ double readDouble_be()
+#else
+ double readDouble_le()
+#endif
+ {
+ union {
+ double f;
+ uint8 c[8];
+ } u;
+ u.c[0] = readUInt8();
+ u.c[1] = readUInt8();
+ u.c[2] = readUInt8();
+ u.c[3] = readUInt8();
+ u.c[4] = readUInt8();
+ u.c[5] = readUInt8();
+ u.c[6] = readUInt8();
+ u.c[7] = readUInt8();
+ return u.f;
+ }
+
+#if BYTE_ORDER == BIG_ENDIAN
+ double readDouble_le()
+#else
+ double readDouble_be()
+#endif
+ {
+ union {
+ double f;
+ uint8 c[8];
+ } u;
+ u.c[7] = readUInt8();
+ u.c[6] = readUInt8();
+ u.c[5] = readUInt8();
+ u.c[4] = readUInt8();
+ u.c[3] = readUInt8();
+ u.c[2] = readUInt8();
+ u.c[1] = readUInt8();
+ u.c[0] = readUInt8();
+ return u.f;
+ }
+
+ void readSymbol(char *outString)
+ {
+ int length = readUInt8();
+ readData(outString, length);
+ outString[length] = 0;
+ }
+
+ void writeSymbol(char *inString)
+ {
+ int32 length = strlen(inString);
+ writeUInt8((uint8)length);
+ writeData(inString, length);
+ }
+};
+
+
+// core routines
+inline void SC_IOStream<FILE*>::readData(char *data, int size)
+{
+ fread(data, 1, size, s);
+}
+
+inline uint8 SC_IOStream<FILE*>::readUInt8()
+{
+ return (uint8)fgetc(s);
+}
+
+inline void SC_IOStream<FILE*>::writeData(char *data, int size)
+{
+ fwrite(data, 1, size, s);
+}
+
+inline void SC_IOStream<FILE*>::writeUInt8(uint8 inInt)
+{
+ fputc(inInt, s);
+}
+
+// core routines
+inline void SC_IOStream<char*>::readData(char *data, int size)
+{
+ memcpy(data, s, size);
+ s += size;
+}
+inline uint8 SC_IOStream<char*>::readUInt8()
+{
+ return (uint8)*s++;
+}
+
+inline void SC_IOStream<char*>::writeData(char *data, int size)
+{
+ memcpy(s, data, size);
+ s += size;
+}
+
+inline void SC_IOStream<char*>::writeUInt8(uint8 inInt)
+{
+ *s++ = (inInt & 255);
+}
+
+
+#endif
+
diff --git a/sc4pd/headers/lang/SCBase.h b/sc4pd/headers/lang/SCBase.h
new file mode 100644
index 0000000..10fe0ed
--- /dev/null
+++ b/sc4pd/headers/lang/SCBase.h
@@ -0,0 +1,68 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+Contains the most common definitions.
+
+*/
+
+#ifndef _SCBASE_
+#define _SCBASE_
+
+#include <limits.h>
+#include <stdio.h>
+
+#include "SC_BoundsMacros.h"
+#include "SC_Types.h"
+#include "PyrErrors.h"
+#include "AllocPools.h"
+
+void postfl(const char *fmt, ...);
+void post(const char *fmt, ...);
+void error(const char *fmt, ...);
+void postText(const char *text, long length);
+void postChar(char c);
+void flushPostBuf();
+void setPostFile(FILE *file); // If file is not NULL, causes all posted text to also be written to the file.
+
+void debugf(char *fmt, ...);
+void pprintf(unsigned char *str, char *fmt, ...);
+
+#pragma export on
+
+extern "C" {
+void schedInit();
+void init_OSC(int port);
+bool pyr_init_mem_pools(int runtime_space, int runtime_grow);
+
+void schedRun();
+void schedStop();
+bool compileLibrary();
+void runLibrary(struct PyrSymbol* selector);
+struct VMGlobals* scGlobals();
+void runInterpreter(struct VMGlobals *g, struct PyrSymbol *selector, int numArgsPushed);
+
+struct PyrSymbol* getsym(const char *inName);
+struct PyrSymbol* findsym(const char *name);
+}
+
+#pragma export off
+
+#endif
diff --git a/sc4pd/headers/lang/SC_ComPort.h b/sc4pd/headers/lang/SC_ComPort.h
new file mode 100644
index 0000000..bdbeabc
--- /dev/null
+++ b/sc4pd/headers/lang/SC_ComPort.h
@@ -0,0 +1,118 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_ComPort_
+#define _SC_ComPort_
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include "SC_Msg.h"
+#include "SC_Sem.h"
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_CmdPort
+{
+protected:
+ pthread_t mThread;
+
+ void Start();
+ virtual ReplyFunc GetReplyFunc()=0;
+public:
+ SC_CmdPort();
+
+ virtual void* Run()=0;
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_ComPort : public SC_CmdPort
+{
+protected:
+ int mPortNum;
+ int mSocket;
+ struct sockaddr_in mBindSockAddr;
+
+public:
+ SC_ComPort(int inPortNum);
+ virtual ~SC_ComPort();
+
+ int Socket() { return mSocket; }
+
+ int PortNum() const { return mPortNum; }
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_UdpInPort : public SC_ComPort
+{
+protected:
+ struct sockaddr_in mReplySockAddr;
+ virtual ReplyFunc GetReplyFunc();
+
+public:
+ SC_UdpInPort(int inPortNum);
+ ~SC_UdpInPort();
+
+ int PortNum() const { return mPortNum; }
+
+ void* Run();
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_TcpInPort : public SC_ComPort
+{
+ SC_Semaphore mConnectionAvailable;
+ int mBacklog;
+
+protected:
+ virtual ReplyFunc GetReplyFunc();
+
+public:
+ SC_TcpInPort(int inPortNum, int inMaxConnections, int inBacklog);
+
+ virtual void* Run();
+
+ void ConnectionTerminated();
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_TcpConnectionPort : public SC_ComPort
+{
+ SC_TcpInPort *mParent;
+
+protected:
+ virtual ReplyFunc GetReplyFunc();
+
+public:
+ SC_TcpConnectionPort(SC_TcpInPort *inParent, int inSocket);
+ virtual ~SC_TcpConnectionPort();
+
+ virtual void* Run();
+};
+
+const int kTextBufSize = 8192;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/sc4pd/headers/lang/SC_LanguageClient.h b/sc4pd/headers/lang/SC_LanguageClient.h
new file mode 100644
index 0000000..b7a499c
--- /dev/null
+++ b/sc4pd/headers/lang/SC_LanguageClient.h
@@ -0,0 +1,164 @@
+// emacs: -*- c++ -*-
+// file: SC_LanguageClient.h
+// copyright: 2003 stefan kersten <steve@k-hornz.de>
+// cvs: $Id: SC_LanguageClient.h,v 1.1.1.1 2004-07-14 16:21:17 timblech Exp $
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+
+#ifndef SC_LANGUAGECLIENT_H_INCLUDED
+#define SC_LANGUAGECLIENT_H_INCLUDED
+
+#include "SC_StringBuffer.h"
+#include <pthread.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+// =====================================================================
+// SC_LanguageClient - abstract sclang client.
+// =====================================================================
+
+struct PyrSymbol;
+struct VMGlobals;
+
+extern long compiledOK;
+extern pthread_mutex_t gLangMutex;
+extern VMGlobals* gMainVMGlobals;
+
+class SC_LanguageClient
+{
+public:
+ struct Options
+ {
+ Options()
+ : mMemSpace(2*1024*1024),
+ mMemGrow(256*1024),
+ mPort(57120),
+ mRuntimeDir(0)
+ { }
+
+ int mMemSpace; // memory space in bytes
+ int mMemGrow; // memory growth in bytes
+ int mPort; // network port number
+ char* mRuntimeDir; // runtime directory
+ };
+
+public:
+ // create singleton instance
+ SC_LanguageClient(const char* name);
+ virtual ~SC_LanguageClient();
+
+ // return the singleton instance
+ static SC_LanguageClient* instance() { return gInstance; }
+
+ // initialize language runtime
+ void initRuntime(const Options& opt=Options());
+
+ // return application name
+ const char* getName() const { return mName; }
+
+ // library startup/shutdown
+ bool readLibraryConfig(const char* filePath, const char* fileName=0);
+ bool readDefaultLibraryConfig();
+ bool isLibraryCompiled() { return compiledOK; }
+ void compileLibrary();
+ void shutdownLibrary();
+ void recompileLibrary();
+
+ // interpreter access
+ void lock() { pthread_mutex_lock(&gLangMutex); }
+ bool trylock() { return pthread_mutex_trylock(&gLangMutex) == 0; }
+ void unlock() { pthread_mutex_unlock(&gLangMutex); }
+
+ VMGlobals* getVMGlobals() { return gMainVMGlobals; }
+
+ void setCmdLine(const char* buf, size_t size);
+ void setCmdLine(const char* str);
+ void setCmdLine(const SC_StringBuffer& strBuf);
+ void setCmdLinef(const char* fmt, ...);
+ void runLibrary(PyrSymbol* pyrSymbol);
+ void runLibrary(const char* methodName);
+ void interpretCmdLine() { runLibrary(s_interpretCmdLine); }
+ void interpretPrintCmdLine() { runLibrary(s_interpretPrintCmdLine); }
+ void executeFile(const char* fileName);
+ void runMain() { runLibrary(s_run); }
+ void stopMain() { runLibrary(s_stop); }
+
+ // post file access
+ FILE* getPostFile() { return mPostFile; }
+ void setPostFile(FILE* file) { mPostFile = file; }
+
+ // post buffer output (subclass responsibility)
+ // these routines should be thread-save.
+ virtual void post(const char *fmt, va_list ap, bool error) = 0;
+ virtual void post(char c) = 0;
+ virtual void post(const char* str, size_t len) = 0;
+ virtual void flush() = 0;
+
+ // common symbols
+ // only valid after the library has been compiled.
+ static PyrSymbol* s_interpretCmdLine;
+ static PyrSymbol* s_interpretPrintCmdLine;
+ static PyrSymbol* s_run;
+ static PyrSymbol* s_stop;
+
+ // command line argument handling utilities
+ static void snprintMemArg(char* dst, size_t size, int arg);
+ static bool parseMemArg(const char* arg, int* res);
+ static bool parsePortArg(const char* arg, int* res);
+
+protected:
+ // AppClock driver
+ // to be called from client mainloop.
+ void tick();
+
+ // language notifications, subclasses can override
+
+ // called after language runtime has been initialized
+ virtual void onInitRuntime();
+ // called after the library has been compiled
+ virtual void onLibraryStartup();
+ // called before the library is shut down
+ virtual void onLibraryShutdown();
+ // called after the interpreter has been started
+ virtual void onInterpStartup();
+
+private:
+ friend void closeAllGUIScreens();
+ friend void initGUIPrimitives();
+ friend void initGUI();
+
+private:
+ char* mName;
+ FILE* mPostFile;
+ SC_StringBuffer mScratch;
+ bool mRunning;
+ static SC_LanguageClient* gInstance;
+};
+
+// =====================================================================
+// library functions
+// =====================================================================
+
+extern void setPostFile(FILE* file);
+extern "C" int vpost(const char *fmt, va_list vargs);
+extern void post(const char *fmt, ...);
+extern void postfl(const char *fmt, ...);
+extern void postText(const char *text, long length);
+extern void postChar(char c);
+extern void error(const char *fmt, ...);
+extern void flushPostBuf();
+
+#endif // SC_LANGUAGECLIENT_H_INCLUDED
diff --git a/sc4pd/headers/lang/SC_LibraryConfig.h b/sc4pd/headers/lang/SC_LibraryConfig.h
new file mode 100644
index 0000000..5f7df3b
--- /dev/null
+++ b/sc4pd/headers/lang/SC_LibraryConfig.h
@@ -0,0 +1,108 @@
+// emacs: -*- c++ -*-
+// file: SC_LibraryConfig.h
+// cvs: $Id: SC_LibraryConfig.h,v 1.1.1.1 2004-07-14 16:21:24 timblech Exp $
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+
+#ifndef SC_LIBRARYCONFIG_H_INCLUDED
+#define SC_LIBRARYCONFIG_H_INCLUDED
+
+#include <stdarg.h>
+#include <stdio.h>
+
+// =====================================================================
+// SC_LibraryConfigFile
+// simple library configuration file parser
+// =====================================================================
+
+class SC_LibraryConfig;
+
+class SC_LibraryConfigFile
+{
+public:
+ typedef void (*ErrorFunc)(const char* fmt, ...);
+
+public:
+ SC_LibraryConfigFile(ErrorFunc errorFunc=0);
+
+ bool open(const char* filePath);
+ bool read(const char* fileName, SC_LibraryConfig* libConf);
+ void close();
+
+protected:
+ enum State
+ {
+ kBegin,
+ kAction,
+ kPath,
+ kEscape,
+ kEnvVar,
+ kEnvVarName,
+ kEnd
+ };
+
+ enum
+ {
+ kMaxIncludeDepth = 10
+ };
+
+ bool read(int depth, const char* fileName, SC_LibraryConfig* libConf);
+ bool parseLine(int depth, const char* fileName, int lineNumber, const char* line, SC_LibraryConfig* libConf);
+ static void defaultErrorFunc(const char* fmt, ...);
+
+private:
+ ErrorFunc mErrorFunc;
+ FILE* mFile;
+};
+
+// =====================================================================
+// SC_LibraryConfig
+// library configuration management
+// Copyright 2003 Maurizio Umberto Puxeddu
+// =====================================================================
+
+class SC_LibraryConfig
+{
+public:
+ SC_LibraryConfig(void);
+ virtual ~SC_LibraryConfig();
+
+ char **includedDirectories(void);
+ char **excludedDirectories(void);
+
+ void postExcludedDirectories(void);
+ bool forEachIncludedDirectory(bool (*func)(char *, int));
+
+ bool pathIsExcluded(const char *path);
+
+ void addIncludedDirectory(char *name);
+ void addExcludedDirectory(char *name);
+
+ // convenience functions to access the global library config
+ static bool readLibraryConfig(SC_LibraryConfigFile& file, const char* fileName);
+ static void freeLibraryConfig();
+
+private:
+ int m_nIncludedDirectories;
+ char **m_includedDirectories;
+ int m_nExcludedDirectories;
+ char **m_excludedDirectories;
+};
+
+extern SC_LibraryConfig* gLibraryConfig;
+extern char *unixStandardizePath(const char *path, char *newpath);
+
+#endif // SC_LIBRARYCONFIG_H_INCLUDED
diff --git a/sc4pd/headers/lang/SC_List.h b/sc4pd/headers/lang/SC_List.h
new file mode 100644
index 0000000..1713521
--- /dev/null
+++ b/sc4pd/headers/lang/SC_List.h
@@ -0,0 +1,229 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+
+A doubly linked list template.
+
+*/
+
+#ifndef _SC_List_
+#define _SC_List_
+
+#include <stdexcept>
+#ifndef NDEBUG
+# define NDEBUG
+#endif
+#include <assert.h>
+
+
+// A Link can be a node in a list or a list itself.
+
+template <class T>
+class Link
+{
+public:
+ Link() : mNext(this), mPrev(this) {}
+
+ T* Prev() { return static_cast<T*>(mPrev); }
+ T* Next() { return static_cast<T*>(mNext); }
+
+ void RemoveLeaveDangling()
+ {
+ mPrev->mNext = mNext;
+ mNext->mPrev = mPrev;
+ }
+
+ void Remove()
+ {
+ RemoveLeaveDangling();
+ mNext = mPrev = this;
+ }
+
+ void InsertAfter(T *inLink)
+ {
+ mPrev = inLink;
+ mNext = inLink->mNext;
+ mNext->mPrev = this;
+ mPrev->mNext = this;
+ }
+
+ void InsertBefore(T *inLink)
+ {
+ mNext = inLink;
+ mPrev = inLink->mPrev;
+ mNext->mPrev = this;
+ mPrev->mNext = this;
+ }
+
+ T* Head() { return static_cast<T*>(mNext); }
+ T* Tail() { return static_cast<T*>(mPrev); }
+
+ T* PopHead();
+ T* PopTail();
+ void PushHead(T* inBuf);
+ void PushTail(T* inBuf);
+
+ bool ContainsBuf(T* inBuf);
+ bool IsEmpty() { return mNext == this; }
+ void BeEmpty() { mNext = mPrev = this; }
+
+ void Cat(T* inLink);
+
+ bool SanityCheck();
+ void DebugDump();
+
+//private:
+// Codewarrior refuses to inline Next() in some places..
+ Link<T> *mNext, *mPrev;
+};
+
+template <class T, class Alloc>
+void MakeListEmpty(Link<T> *inLink, Alloc* inAlloc)
+{
+ Link<T>* link = inLink->mNext;
+ while (link != inLink) {
+ Link<T>* nextlink = link->mNext;
+ // SC uses placement new extensively, so here we do a 'placement delete'.
+ // Using DestructSelf allows me to have either virtual
+ // or non virtual destructors in subclasses at the discretion of the subclass.
+ ((T*)(link))->DestructSelf();
+ inAlloc->Free(static_cast<T*>(link));
+ link = nextlink;
+ }
+ inLink->mNext = inLink->mPrev = inLink;
+}
+
+template <class T>
+void Link<T>::PushHead(T* inLink)
+{
+ assert(SanityCheck());
+
+ Link<T>* link = static_cast<Link<T>*>(inLink);
+ link->InsertAfter(static_cast<T*>(this));
+
+ assert(SanityCheck());
+}
+
+template <class T>
+T* Link<T>::PopHead()
+{
+ assert(SanityCheck());
+ if (IsEmpty()) return 0;
+
+ Link<T>* link = mNext;
+
+ link->Remove();
+
+ assert(SanityCheck());
+ return static_cast<T*>(link);
+}
+
+template <class T>
+void Link<T>::PushTail(T* inLink)
+{
+ assert(SanityCheck());
+
+ Link<T>* link = static_cast<Link<T>*>(inLink);
+ link->InsertBefore(static_cast<T*>(this));
+
+ assert(SanityCheck());
+}
+
+template <class T>
+T* Link<T>::PopTail()
+{
+ assert(SanityCheck());
+ if (IsEmpty()) return 0;
+
+ Link<T>* link = mPrev;
+ link->Remove();
+
+ assert(SanityCheck());
+ return static_cast<T*>(link);
+}
+
+template <class T>
+void Link<T>::Cat(T* inLink)
+{
+ assert(SanityCheck());
+
+ Link<T>* link = static_cast<Link<T>*>(inLink);
+
+ if (link->IsEmpty()) return;
+ if (IsEmpty()) {
+ mNext = link->mNext;
+ mPrev = link->mPrev;
+ link->mNext->mPrev = this;
+ link->mPrev->mNext = this;
+ } else {
+ link->mNext->mPrev = mPrev;
+ link->mPrev->mNext = this;
+ mPrev->mNext = link->mNext;
+ mPrev = link->mPrev;
+ }
+ link->mPrev = link;
+ link->mNext = link;
+
+ assert(SanityCheck());
+}
+
+template <class T>
+bool Link<T>::ContainsBuf(T* inLink)
+{
+ Link<T>* link = static_cast<Link<T>*>(inLink);
+ Link<T>* curLink = mNext;
+ while (curLink != this) {
+ if (curLink == link) return true;
+ curLink = curLink->mNext;
+ }
+ return false;
+}
+
+template <class T>
+void Link<T>::DebugDump()
+{
+ Link<T>* link = mNext;
+ while (link != this) {
+ //post("Link-> %08X next %08X prev %08X\n",
+ // link, link->mNext, link->mPrev);
+ link = link->mNext;
+ }
+}
+
+template <class T>
+bool Link<T>::SanityCheck()
+{
+ Link<T>* link = mNext;
+ while (link != this) {
+ if (link->mPrev->mNext != link) {
+ throw std::runtime_error("Link: bad link <-,->");
+ }
+ if (link->mNext->mPrev != link) {
+ throw std::runtime_error("Link: bad link ->,<-");
+ }
+ link = link->mNext;
+ }
+ return true;
+}
+
+
+
+#endif
diff --git a/sc4pd/headers/lang/SC_LogFile.h b/sc4pd/headers/lang/SC_LogFile.h
new file mode 100644
index 0000000..d94c4e2
--- /dev/null
+++ b/sc4pd/headers/lang/SC_LogFile.h
@@ -0,0 +1,29 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_LogFile_
+#define _SC_LogFile_
+
+#include <stdio.h>
+
+extern FILE *gLogFile;
+
+#endif
diff --git a/sc4pd/headers/lang/SC_Msg.h b/sc4pd/headers/lang/SC_Msg.h
new file mode 100644
index 0000000..b187f09
--- /dev/null
+++ b/sc4pd/headers/lang/SC_Msg.h
@@ -0,0 +1,70 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Msg_
+#define _SC_Msg_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include "sc_msg_iter.h"
+
+class SC_Msg;
+
+enum { // Handler IDs
+ kUnknownAction = 0,
+ kRealTimeAction = 1,
+ kNonRealTimeAction = 2,
+ kEitherTimeAction = 3
+};
+
+typedef void (*ReplyFunc)(struct ReplyAddress *inReplyAddr, char* inBuf, int inSize);
+
+struct ReplyAddress
+{
+ struct sockaddr_in mSockAddr;
+ int mSockAddrLen;
+ int mSocket;
+ ReplyFunc mReplyFunc;
+};
+
+inline void SendReply(ReplyAddress *inReplyAddr, char* inBuf, int inSize)
+{
+ (inReplyAddr->mReplyFunc)(inReplyAddr, inBuf, inSize);
+}
+
+void DumpReplyAddress(ReplyAddress *inReplyAddress);
+int32 Hash(ReplyAddress *inReplyAddress);
+
+struct OSC_Packet
+{
+ char *mData;
+ int32 mSize;
+ bool mIsBundle;
+
+ ReplyAddress mReplyAddr;
+};
+
+void FreeOSCPacket(OSC_Packet *inPacket);
+
+#endif
+
+
diff --git a/sc4pd/headers/lang/SC_SynthImpl.h b/sc4pd/headers/lang/SC_SynthImpl.h
new file mode 100644
index 0000000..88411b3
--- /dev/null
+++ b/sc4pd/headers/lang/SC_SynthImpl.h
@@ -0,0 +1,42 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_SynthImpl_
+#define _SC_SynthImpl_
+
+#include "SC_Synth.h"
+#include "SC_SynthDef.h"
+#include "HashTable.h"
+#include "SC_AllocPool.h"
+#include "SC_UnorderedList.h"
+
+extern SynthInterfaceTable gSynthInterfaceTable;
+void InitSynthInterfaceTable();
+
+typedef void (*SetupInterfaceFunc)(SynthInterfaceTable*);
+
+const int kMaxSynths = 1024;
+extern StaticHashTable<Synth, kMaxSynths, const char*> gSynthTable;
+extern AllocPool *gSynthAllocPool;
+
+extern float32 gSine[8193];
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/SC_TerminalClient.h b/sc4pd/headers/lang/SC_TerminalClient.h
new file mode 100644
index 0000000..b0375d0
--- /dev/null
+++ b/sc4pd/headers/lang/SC_TerminalClient.h
@@ -0,0 +1,92 @@
+// emacs: -*- c++ -*-
+// file: SC_TerminalClient.h
+// copyright: 2003 stefan kersten <steve@k-hornz.de>
+// cvs: $Id: SC_TerminalClient.h,v 1.1.1.1 2004-07-14 16:21:27 timblech Exp $
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+
+#ifndef SC_TERMINALCLIENT_H_INCLUDED
+#define SC_TERMINALCLIENT_H_INCLUDED
+
+#include "SC_LanguageClient.h"
+#include "SC_StringBuffer.h"
+
+// =====================================================================
+// SC_TerminalClient - command line sclang client.
+// =====================================================================
+
+class SC_TerminalClient : public SC_LanguageClient
+{
+public:
+ enum
+ {
+ kInterpretCmdLine = 0x1b,
+ kInterpretPrintCmdLine = 0x0c
+ };
+
+ struct Options : public SC_LanguageClient::Options
+ {
+ Options()
+ : mLibraryConfigFile(0),
+ mDaemon(false),
+ mCallRun(false),
+ mCallStop(false),
+ mArgc(0), mArgv(0)
+ { }
+
+ char* mLibraryConfigFile;
+ bool mDaemon;
+ bool mCallRun;
+ bool mCallStop;
+ int mArgc;
+ char** mArgv;
+ };
+
+ SC_TerminalClient(const char* name);
+
+ const Options& options() const { return mOptions; }
+ bool shouldBeRunning() const { return mShouldBeRunning; }
+
+ int run(int argc, char** argv);
+ void quit(int code);
+
+ virtual void post(const char *fmt, va_list ap, bool error);
+ virtual void post(char c);
+ virtual void post(const char* str, size_t len);
+ virtual void flush();
+
+protected:
+ bool parseOptions(int& argc, char**& argv, Options& opt);
+ void printUsage();
+
+ // fd is assumed to be non-blocking
+ bool readCmdLine(int fd, SC_StringBuffer& cmdLine);
+ void interpretCmdLine(PyrSymbol* method, SC_StringBuffer& cmdLine);
+
+ // subclasses should override
+ virtual void commandLoop();
+ virtual void daemonLoop();
+
+ static int prExit(struct VMGlobals* g, int);
+ virtual void onLibraryStartup();
+
+private:
+ bool mShouldBeRunning;
+ int mReturnCode;
+ Options mOptions;
+};
+
+#endif // SC_TERMINALCLIENT_H_INCLUDED
diff --git a/sc4pd/headers/lang/SC_UnorderedList.h b/sc4pd/headers/lang/SC_UnorderedList.h
new file mode 100644
index 0000000..37ce8d9
--- /dev/null
+++ b/sc4pd/headers/lang/SC_UnorderedList.h
@@ -0,0 +1,60 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_UnorderedList_
+#define _SC_UnorderedList_
+
+template <class T, int kMaxItems>
+class SC_UnorderedList
+{
+ T* mList[kMaxItems];
+ unsigned int mSize;
+public:
+ SC_UnorderedList() : mSize(0) {}
+
+ unsigned int Size() const { return mSize; }
+ Synth* GetAt(unsigned int inIndex)
+ {
+ if (inIndex >= mSize) return 0;
+ return mList[inIndex];
+ }
+
+ void Add(T *inItem)
+ {
+ if (mSize < kMaxItems) {
+ mList[mSize] = inItem;
+ SetListIndex(inItem, mSize++);
+ }
+ }
+
+ void Remove(T *inItem)
+ {
+ --mSize;
+ unsigned int index = GetListIndex(inItem);
+ if (index < mSize) {
+ mList[index] = mList[mSize];
+ SetListIndex(mList[index], index);
+ }
+ }
+};
+
+#endif
+
diff --git a/sc4pd/headers/lang/SFHeaders.h b/sc4pd/headers/lang/SFHeaders.h
new file mode 100644
index 0000000..143652d
--- /dev/null
+++ b/sc4pd/headers/lang/SFHeaders.h
@@ -0,0 +1,140 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SFHeaders_
+#define _SFHeaders_
+
+#include "SCBase.h"
+#include "ReadWriteMacros.h"
+
+enum {
+ unsupported_sound_file = -1,
+ AIFF_sound_file,
+ AIFC_sound_file,
+ RIFF_sound_file,
+ NeXT_sound_file,
+ IRCAM_sound_file,
+ SD2_sound_file,
+ raw_sound_file
+};
+
+enum {
+ snd_unsupported = -1,
+ snd_no_snd,
+ snd_16_linear,
+ snd_8_mulaw,
+ snd_8_linear,
+ snd_32_float,
+ snd_32_linear,
+ snd_8_alaw,
+ snd_8_unsigned,
+ snd_24_linear,
+ snd_64_double,
+ snd_16_linear_little_endian,
+ snd_32_linear_little_endian,
+ snd_32_float_little_endian,
+ snd_64_double_little_endian,
+ snd_16_unsigned,
+ snd_16_unsigned_little_endian,
+ snd_24_linear_little_endian,
+ snd_32_vax_float,
+ snd_12_linear,
+ snd_12_linear_little_endian,
+ snd_12_unsigned,
+ snd_12_unsigned_little_endian
+};
+
+
+class SFHeaderInfo
+{
+public:
+ SFHeaderInfo();
+
+ bool WriteHeader(FILE *inFile);
+
+ void SetPath(char *inPath);
+ double SampleRate() { return mSampleRate; }
+ void SetSampleRate(double inSampleRate) { mSampleRate = inSampleRate; }
+ void SetFormat(int inHeaderFormat, int inSampleFormat, int inCreator);
+
+ double Freq() { return mFreq; }
+
+ uint8 LoNote() { return mLoNote; }
+ uint8 HiNote() { return mHiNote; }
+ uint8 LoVeloc() { return mLoVeloc; }
+ uint8 HiVeloc() { return mHiVeloc; }
+
+ uint8 NumChannels() { return mNumChannels; }
+ int32 NumFramesInFile() { return mNumFramesInFile; }
+
+ int makeSoundFileHeader(SC_IOStream<char*>& rw);
+
+ int32 headerFileType();
+ int headerSize();
+ int sampleFormatSize();
+ void newSoundFilePath();
+
+ bool ReadSoundFileHeader(FILE *fp);
+
+ int32 CalcFrameSize();
+ bool SetTypeCreator();
+
+ char mPath[256];
+ double mSampleRate;
+ double mFreq;
+ int32 mNumFramesInFile;
+ int32 mDataOffset;
+ int32 mCreator;
+ void *mExtraStuff;
+ int16 mGain;
+ int8 mHeaderFormat;
+ int8 mSampleFormat;
+ uint8 mNumChannels;
+ uint8 mLoNote, mHiNote, mLoVeloc, mHiVeloc;
+
+private:
+
+
+ int make_AIFF_header(SC_IOStream<char*>& rw);
+ int make_AIFC_header(SC_IOStream<char*>& rw);
+ int make_RIFF_header(SC_IOStream<char*>& rw);
+ int make_Next_header(SC_IOStream<char*>& rw);
+ int make_IRCAM_header(SC_IOStream<char*>& rw);
+
+ int sampleFormat_AIFF();
+ int sampleFormat_AIFC();
+ int sampleFormat_RIFF();
+ int sampleFormat_Next();
+ int sampleFormat_Next_inv(int inFormat);
+ void writeCompressionFormat_AIFC(SC_IOStream<char*>& rw);
+
+ bool read_AIFF_Header(SC_IOStream<FILE*>& rw);
+ bool read_RIFF_Header(SC_IOStream<FILE*>& rw);
+ bool read_Next_Header(SC_IOStream<FILE*>& rw);
+};
+
+
+extern char gDefaultSoundFolder[256];
+extern char gDefaultSoundFilePath[256];
+
+int sampleFormatSize(int inSampleFormat);
+
+#endif
diff --git a/sc4pd/headers/lang/Samp.h b/sc4pd/headers/lang/Samp.h
new file mode 100644
index 0000000..7593ba8
--- /dev/null
+++ b/sc4pd/headers/lang/Samp.h
@@ -0,0 +1,46 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+
+Samp is a typedef for the output sample type.
+Should be defined to be either float or double.
+
+*/
+
+#ifndef _Samp_
+#define _Samp_
+
+#include "SC_Types.h"
+
+const long kSineSize = 8192;
+const long kSineMask = kSineSize - 1;
+const double kSinePhaseScale = kSineSize / (2.0 * 3.1415926535897932384626433832795);
+
+extern float32 gSine[kSineSize+1];
+extern float32 gPMSine[kSineSize+1];
+extern float32 gInvSine[kSineSize+1];
+extern float32 gSineWavetable[2*kSineSize];
+
+void SignalAsWavetable(float32* signal, float32* wavetable, long inSize);
+void WavetableAsSignal(float32* wavetable, float32* signal, long inSize);
+
+#endif
+
diff --git a/sc4pd/headers/lang/SimpleStack.h b/sc4pd/headers/lang/SimpleStack.h
new file mode 100644
index 0000000..3313785
--- /dev/null
+++ b/sc4pd/headers/lang/SimpleStack.h
@@ -0,0 +1,32 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+typedef struct {
+ long *stak;
+ short num, maxsize;
+} LongStack;
+
+void initLongStack(LongStack *self) ;
+void freeLongStack(LongStack *self);
+void growLongStack(LongStack *self);
+void pushls(LongStack *self, long value);
+long popls(LongStack *self);
+int emptyls(LongStack *self);
diff --git a/sc4pd/headers/lang/VMGlobals.h b/sc4pd/headers/lang/VMGlobals.h
new file mode 100644
index 0000000..9b5f2e1
--- /dev/null
+++ b/sc4pd/headers/lang/VMGlobals.h
@@ -0,0 +1,94 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+Each virtual machine has a copy of VMGlobals, which contains the state of the virtual machine.
+
+*/
+
+#ifndef _VMGLOBALS_H_
+#define _VMGLOBALS_H_
+
+#include "PyrSlot.h"
+#include "SC_AllocPool.h"
+#include "SC_RGen.h"
+
+const int kNumProcesses = 1;
+const int kMainProcessID = 0;
+
+typedef void (*FifoMsgFunc)(struct VMGlobals*, struct FifoMsg*);
+
+struct FifoMsg {
+ FifoMsg() : func(0), dataPtr(0) { dataWord[0] = dataWord[1] = 0; }
+ void Perform(struct VMGlobals* g);
+ void Free(struct VMGlobals* g);
+
+ FifoMsgFunc func;
+ void* dataPtr;
+ long dataWord[2];
+};
+
+struct VMGlobals {
+ VMGlobals();
+
+ // global context
+ class AllocPool *allocPool;
+ struct PyrProcess *process;
+ class SymbolTable *symbolTable;
+ class PyrGC *gc; // garbage collector for this process
+ PyrSlot *classvars;
+ bool canCallOS;
+
+ // thread context
+ struct PyrThread *thread;
+ struct PyrMethod *method;
+ struct PyrBlock *block;
+ struct PyrFrame *frame;
+ struct PyrMethod *primitiveMethod;
+ unsigned char *ip; // current instruction pointer
+ PyrSlot *sp; // current stack ptr
+ PyrSlot *args;
+ PyrSlot receiver; // the receiver
+ PyrSlot result;
+ int numpop; // number of args to pop for primitive
+ long returnLevels;
+ long processID;
+ long primitiveIndex;
+ RGen *rgen;
+
+ // scratch context
+ long execMethod;
+} ;
+
+inline void FifoMsg::Perform(struct VMGlobals* g)
+ {
+ (func)(g, this);
+ }
+
+inline void FifoMsg::Free(struct VMGlobals* g)
+ {
+ g->allocPool->Free(dataPtr);
+ }
+
+extern VMGlobals gVMGlobals[kNumProcesses];
+extern VMGlobals *gMainVMGlobals;
+extern VMGlobals *gCompilingVMGlobals;
+#endif
+
diff --git a/sc4pd/headers/lang/bullet.h b/sc4pd/headers/lang/bullet.h
new file mode 100644
index 0000000..463b062
--- /dev/null
+++ b/sc4pd/headers/lang/bullet.h
@@ -0,0 +1,7 @@
+
+// this should be an outstanding character
+// it is used in printing errors
+
+#define BULLET "¥"
+#define BULLET_CHAR '¥'
+
diff --git a/sc4pd/headers/lang/libraryConfig.h b/sc4pd/headers/lang/libraryConfig.h
new file mode 100644
index 0000000..b1f3844
--- /dev/null
+++ b/sc4pd/headers/lang/libraryConfig.h
@@ -0,0 +1,31 @@
+// Copyright 2003 Maurizio Umberto Puxeddu
+
+#ifndef _Supercollider_libraryConfig_h_
+#define _Supercollider_libraryConfig_h_
+
+class LibraryConfig {
+ public:
+ LibraryConfig(void);
+ virtual ~LibraryConfig();
+
+ char **includedDirectories(void);
+ char **excludedDirectories(void);
+
+ void postExcludedDirectories(void);
+ bool forEachIncludedDirectory(bool (*func)(char *, int));
+
+ bool pathIsExcluded(const char *path);
+
+ void addIncludedDirectory(char *name);
+ void addExcludedDirectory(char *name);
+
+ private:
+ int m_nIncludedDirectories;
+ char **m_includedDirectories;
+ int m_nExcludedDirectories;
+ char **m_excludedDirectories;
+};
+
+extern char *unixStandardizePath(const char *path, char *newpath);
+
+#endif // _Supercollider_libraryConfig_h_
diff --git a/sc4pd/headers/lang/readSamples.h b/sc4pd/headers/lang/readSamples.h
new file mode 100644
index 0000000..835f975
--- /dev/null
+++ b/sc4pd/headers/lang/readSamples.h
@@ -0,0 +1 @@
+/* SuperCollider real time audio synthesis system Copyright (c) 2002 James McCartney. All rights reserved. http://www.audiosynth.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _readSamples_ #define _readSamples_ long readSamplesInterleaved(FILE* fp, float *out, long numSamplesToRead, long format); void convertSamplesIn(float **out, char *in, long numFramesToRead, long numChannels, long sampOffset, long format); float convertSamplesOut(float **in, char *buffer, int numFramesToWrite, int numChannels, long sampOffset, int format); void convertSamplesInInterleaved(float *out, char *buffer, long numSamplesToRead, long sampOffset, long format); float convertSamplesOutInterleaved(float *in, char *buffer, long numSampsToWrite, int format); #endif \ No newline at end of file
diff --git a/sc4pd/headers/plugin_interface/Hash.h b/sc4pd/headers/plugin_interface/Hash.h
new file mode 100644
index 0000000..e42eaf4
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/Hash.h
@@ -0,0 +1,152 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _Hash_
+#define _Hash_
+
+#include "SC_Types.h"
+#include "SC_Endian.h"
+
+// These hash functions are among the best there are in terms of both speed and quality.
+// A good hash function makes a lot of difference.
+// I have not used Bob Jenkins own hash function because the keys I use are relatively short.
+
+
+// hash function for a string
+inline int32 Hash(const char *inKey)
+{
+ // the one-at-a-time hash.
+ // a very good hash function. ref: a web page by Bob Jenkins.
+ // http://www.burtleburtle.net/bob/hash/doobs.html
+ int32 hash = 0;
+ while (*inKey) {
+ hash += *inKey++;
+ hash += hash << 10;
+ hash ^= hash >> 6;
+ }
+ hash += hash << 3;
+ hash ^= hash >> 11;
+ hash += hash << 15;
+ return hash;
+}
+
+// hash function for a string that also returns the length
+inline int32 Hash(const char *inKey, int32 *outLength)
+{
+ // the one-at-a-time hash.
+ // a very good hash function. ref: a web page by Bob Jenkins.
+ const char *origKey = inKey;
+ int32 hash = 0;
+ while (*inKey) {
+ hash += *inKey++;
+ hash += hash << 10;
+ hash ^= hash >> 6;
+ }
+ hash += hash << 3;
+ hash ^= hash >> 11;
+ hash += hash << 15;
+ *outLength = inKey - origKey;
+ return hash;
+}
+
+// hash function for an array of char
+inline int32 Hash(const char *inKey, int32 inLength)
+{
+ // the one-at-a-time hash.
+ // a very good hash function. ref: a web page by Bob Jenkins.
+ int32 hash = 0;
+ for (int i=0; i<inLength; ++i) {
+ hash += *inKey++;
+ hash += hash << 10;
+ hash ^= hash >> 6;
+ }
+ hash += hash << 3;
+ hash ^= hash >> 11;
+ hash += hash << 15;
+ return hash;
+}
+
+// hash function for integers
+inline int32 Hash(int32 inKey)
+{
+ // Thomas Wang's integer hash.
+ // http://www.concentric.net/~Ttwang/tech/inthash.htm
+ // a faster hash for integers. also very good.
+ uint32 hash = (uint32)inKey;
+ hash += ~(hash << 15);
+ hash ^= hash >> 10;
+ hash += hash << 3;
+ hash ^= hash >> 6;
+ hash += ~(hash << 11);
+ hash ^= hash >> 16;
+ return (int32)hash;
+}
+
+inline int64 Hash64(int64 inKey)
+{
+ // Thomas Wang's 64 bit integer hash.
+ uint64 hash = (uint64)inKey;
+ hash += ~(hash << 32);
+ hash ^= (hash >> 22);
+ hash += ~(hash << 13);
+ hash ^= (hash >> 8);
+ hash += (hash << 3);
+ hash ^= (hash >> 15);
+ hash += ~(hash << 27);
+ hash ^= (hash >> 31);
+ return (int64)hash;
+}
+
+inline int32 Hash(const int32 *inKey, int32 inLength)
+{
+ // one-at-a-time hashing of a string of int32's.
+ // uses Thomas Wang's integer hash for the combining step.
+ int32 hash = 0;
+ for (int i=0; i<inLength; ++i) {
+ hash = Hash(hash + *inKey++);
+ }
+ return hash;
+}
+
+#ifndef _LASTCHAR_
+#define _LASTCHAR_
+#if BYTE_ORDER == LITTLE_ENDIAN
+const int32 kLASTCHAR = 0xFF000000;
+#else
+const int32 kLASTCHAR = 0x000000FF;
+#endif
+#endif
+
+inline int32 Hash(const int32 *inKey)
+{
+ // hashing of a string of int32's.
+ // uses Thomas Wang's integer hash for the combining step.
+ int32 hash = 0;
+ int32 c;
+ do {
+ c = *inKey++;
+ hash = Hash(hash + c);
+ } while (c & kLASTCHAR);
+ return hash;
+}
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/SC_BoundsMacros.h b/sc4pd/headers/plugin_interface/SC_BoundsMacros.h
new file mode 100644
index 0000000..6c65795
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_BoundsMacros.h
@@ -0,0 +1,29 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_BoundsMacros_
+#define _SC_BoundsMacros_
+
+#define sc_abs(a) ((a)>=0?(a) : -(a))
+#define sc_max(a,b) (((a) > (b)) ? (a) : (b))
+#define sc_min(a,b) (((a) < (b)) ? (a) : (b))
+#define sc_clip(x, lo, hi) ((x) > (hi) ? (hi) : ((x) < (lo) ? (lo) : (x)))
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_BufGen.h b/sc4pd/headers/plugin_interface/SC_BufGen.h
new file mode 100644
index 0000000..9a275c1
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_BufGen.h
@@ -0,0 +1,40 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _BufGen_
+#define _BufGen_
+
+#include "SC_Types.h"
+
+typedef void (*BufGenFunc)(struct World *world, struct SndBuf *buf, struct sc_msg_iter *msg);
+
+struct BufGen
+{
+ int32 mBufGenName[kSCNameLen];
+ int32 mHash;
+
+ BufGenFunc mBufGenFunc;
+};
+
+extern "C" {
+bool BufGen_Create(char *inName, BufGenFunc inFunc);
+}
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_Constants.h b/sc4pd/headers/plugin_interface/SC_Constants.h
new file mode 100644
index 0000000..b9e49bf
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Constants.h
@@ -0,0 +1,46 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_Constants_
+#define _SC_Constants_
+
+#include <math.h>
+
+#ifndef __FP__
+const double pi = acos(-1.);
+#endif
+const double pi2 = pi * .5;
+const double pi32 = pi * 1.5;
+const double twopi = pi * 2.;
+const double rtwopi = 1. / twopi;
+const double log001 = log(0.001);
+const double log01 = log(0.01);
+const double log1 = log(0.1);
+const double rlog2 = 1./log(2.);
+const double sqrt2 = sqrt(2.);
+const double rsqrt2 = 1. / sqrt2;
+
+// used to truncate precision
+const float truncFloat = (float)(3. * pow(2,22));
+const double truncDouble = 3. * pow(2,51);
+
+const float kBadValue = 1e20f; // used in the secant table for values very close to 1/0
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_DemandUnit.h b/sc4pd/headers/plugin_interface/SC_DemandUnit.h
new file mode 100644
index 0000000..6f273b3
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_DemandUnit.h
@@ -0,0 +1,54 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_DemandUnit_
+#define _SC_DemandUnit_
+
+#include "SC_Unit.h"
+#include "SC_Wire.h"
+
+// demand rate unit support.
+
+inline bool IsDemandInput(Unit* unit, int index)
+{
+ Unit* fromUnit = unit->mInput[index]->mFromUnit;
+ return fromUnit && fromUnit->mCalcRate == calc_DemandRate;
+}
+
+inline float DemandInput(Unit* unit, int index)
+{
+ Unit* fromUnit = unit->mInput[index]->mFromUnit;
+ if (fromUnit && fromUnit->mCalcRate == calc_DemandRate)
+ (fromUnit->mCalcFunc)(fromUnit, 1);
+ return IN0(index);
+}
+
+inline void ResetInput(Unit* unit, int index)
+{
+ Unit* fromUnit = unit->mInput[index]->mFromUnit;
+ if (fromUnit && fromUnit->mCalcRate == calc_DemandRate)
+ (fromUnit->mCalcFunc)(fromUnit, 0);
+}
+
+#define ISDEMANDINPUT(index) IsDemandInput(unit, (index))
+#define DEMANDINPUT(index) DemandInput(unit, (index))
+#define RESETINPUT(index) ResetInput(unit, (index))
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_Dimension.h b/sc4pd/headers/plugin_interface/SC_Dimension.h
new file mode 100644
index 0000000..923b283
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Dimension.h
@@ -0,0 +1,31 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_Dimension_
+#define _SC_Dimension_
+
+struct SC_Dimension
+{
+ long mWidth, mHeight, mNumPixels;
+ float mXSlopeFactor, mYSlopeFactor;
+};
+typedef struct SC_Dimension SC_Dimension;
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_FifoMsg.h b/sc4pd/headers/plugin_interface/SC_FifoMsg.h
new file mode 100644
index 0000000..7d83e0a
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_FifoMsg.h
@@ -0,0 +1,59 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _FifoMsg_
+#define _FifoMsg_
+
+typedef void (*FifoMsgFunc)(struct FifoMsg*);
+
+struct FifoMsg
+{
+ FifoMsg() : mPerformFunc(0), mFreeFunc(0), mData(0), mWorld(0) {}
+
+ void Set(struct World *inWorld, FifoMsgFunc inPerform, FifoMsgFunc inFree, void* inData);
+ void Perform();
+ void Free();
+
+ FifoMsgFunc mPerformFunc;
+ FifoMsgFunc mFreeFunc;
+ void* mData;
+ struct World *mWorld;
+};
+
+inline void FifoMsg::Set(World *inWorld, FifoMsgFunc inPerform, FifoMsgFunc inFree, void* inData)
+{
+ mWorld = inWorld;
+ mPerformFunc = inPerform;
+ mFreeFunc = inFree;
+ mData = inData;
+}
+
+inline void FifoMsg::Perform()
+{
+ if (mPerformFunc) (mPerformFunc)(this);
+}
+
+inline void FifoMsg::Free()
+{
+ if (mFreeFunc) (mFreeFunc)(this);
+}
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/SC_Graph.h b/sc4pd/headers/plugin_interface/SC_Graph.h
new file mode 100644
index 0000000..68d3d59
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Graph.h
@@ -0,0 +1,53 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_Graph_
+#define _SC_Graph_
+
+#include "SC_Node.h"
+#include "SC_Rate.h"
+#include "SC_Dimension.h"
+
+struct Graph
+{
+ Node mNode;
+
+ uint32 mNumWires;
+ struct Wire *mWire;
+
+ uint32 mNumControls;
+ float *mControls;
+ float **mMapControls;
+
+ uint32 mNumUnits;
+ struct Unit **mUnits;
+
+ int mNumCalcUnits;
+ struct Unit **mCalcUnits; // excludes i-rate units.
+
+ int mSampleOffset;
+ struct RGen* mRGen;
+
+ struct Unit *mLocalAudioBusUnit;
+ struct Unit *mLocalControlBusUnit;
+};
+typedef struct Graph Graph;
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_InlineBinaryOp.h b/sc4pd/headers/plugin_interface/SC_InlineBinaryOp.h
new file mode 100644
index 0000000..2d9668b
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_InlineBinaryOp.h
@@ -0,0 +1,574 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _BinaryOpUGen_
+#define _BinaryOpUGen_
+
+#include "SC_BoundsMacros.h"
+#include <math.h>
+
+inline float sc_mod(float in, float hi)
+{
+ // avoid the divide if possible
+ const float lo = (float)0.;
+ if (in >= hi) {
+ in -= hi;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ in += hi;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ return in - hi*floor(in/hi);
+}
+
+inline double sc_mod(double in, double hi)
+{
+ // avoid the divide if possible
+ const double lo = (double)0.;
+ if (in >= hi) {
+ in -= hi;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ in += hi;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ return in - hi*floor(in/hi);
+}
+
+inline float sc_wrap(float in, float lo, float hi)
+{
+ float range;
+ // avoid the divide if possible
+ if (in >= hi) {
+ range = hi - lo;
+ in -= range;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ range = hi - lo;
+ in += range;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ return in - range * floor((in - lo)/range);
+}
+
+inline double sc_wrap(double in, double lo, double hi)
+{
+ double range;
+ // avoid the divide if possible
+ if (in >= hi) {
+ range = hi - lo;
+ in -= range;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ range = hi - lo;
+ in += range;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ return in - range * floor((in - lo)/range);
+}
+
+inline double sc_wrap(double in, double lo, double hi, double range)
+{
+ // avoid the divide if possible
+ if (in >= hi) {
+ in -= range;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ in += range;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ return in - range * floor((in - lo)/range);
+}
+
+inline double sc_wrap(float in, float lo, float hi, float range)
+{
+ // avoid the divide if possible
+ if (in >= hi) {
+ in -= range;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ in += range;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ return in - range * floor((in - lo)/range);
+}
+
+inline float sc_fold(float in, float lo, float hi)
+{
+ float x, c, range, range2;
+ x = in - lo;
+
+ // avoid the divide if possible
+ if (in >= hi) {
+ in = hi + hi - in;
+ if (in >= lo) return in;
+ } else if (in < lo) {
+ in = lo + lo - in;
+ if (in < hi) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ // ok do the divide
+ range = hi - lo;
+ range2 = range + range;
+ c = x - range2 * floor(x / range2);
+ if (c>=range) c = range2 - c;
+ return c + lo;
+}
+
+inline double sc_fold(double in, double lo, double hi)
+{
+ double x, c, range, range2;
+ x = in - lo;
+
+ // avoid the divide if possible
+ if (in >= hi) {
+ in = hi + hi - in;
+ if (in >= lo) return in;
+ } else if (in < lo) {
+ in = lo + lo - in;
+ if (in < hi) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ // ok do the divide
+ range = hi - lo;
+ range2 = range + range;
+ c = x - range2 * floor(x / range2);
+ if (c>=range) c = range2 - c;
+ return c + lo;
+}
+
+inline double sc_fold(float in, float lo, float hi, float range, float range2)
+{
+ float x, c;
+ x = in - lo;
+
+ // avoid the divide if possible
+ if (in >= hi) {
+ in = hi + hi - in;
+ if (in >= lo) return in;
+ } else if (in < lo) {
+ in = lo + lo - in;
+ if (in < hi) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ // ok do the divide
+ c = x - range2 * floor(x / range2);
+ if (c>=range) c = range2 - c;
+ return c + lo;
+}
+
+inline double sc_fold(double in, double lo, double hi, double range, double range2)
+{
+ double x, c;
+ x = in - lo;
+
+ // avoid the divide if possible
+ if (in >= hi) {
+ in = hi + hi - in;
+ if (in >= lo) return in;
+ } else if (in < lo) {
+ in = lo + lo - in;
+ if (in < hi) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ // ok do the divide
+ c = x - range2 * floor(x / range2);
+ if (c>=range) c = range2 - c;
+ return c + lo;
+}
+
+inline float sc_pow(float a, float b)
+{
+ return a >= 0.f ? pow(a, b) : -pow(-a, b);
+}
+
+inline double sc_pow(double a, double b)
+{
+ return a >= 0.f ? pow(a, b) : -pow(-a, b);
+}
+
+template <class T>
+inline float sc_thresh(T a, T b)
+{
+ return a < b ? (T)0 : a;
+}
+
+inline float sc_clip2(float a, float b)
+{
+ return sc_clip(a, -b, b);
+}
+
+inline float sc_wrap2(float a, float b)
+{
+ return sc_wrap(a, -b, b);
+}
+
+inline float sc_fold2(float a, float b)
+{
+ return sc_fold(a, -b, b);
+}
+
+inline float sc_excess(float a, float b)
+{
+ return a - sc_clip(a, -b, b);
+}
+
+inline float sc_round(float x, float quant)
+{
+ return quant==0. ? x : floor(x/quant + .5f) * quant;
+}
+
+inline double sc_round(double x, double quant)
+{
+ return quant==0. ? x : floor(x/quant + .5) * quant;
+}
+
+inline float sc_roundUp(float x, float quant)
+{
+ return quant==0. ? x : ceil(x/quant) * quant;
+}
+
+inline double sc_roundUp(double x, double quant)
+{
+ return quant==0. ? x : ceil(x/quant) * quant;
+}
+
+inline float sc_trunc(float x, float quant)
+{
+ return quant==0. ? x : floor(x/quant) * quant;
+}
+
+inline double sc_trunc(double x, double quant)
+{
+ return quant==0. ? x : floor(x/quant) * quant;
+}
+
+inline float sc_atan2(float a, float b)
+{
+ return atan2(a, b);
+}
+
+
+inline float sc_scaleneg(float a, float b)
+{
+ b = 0.5f * b + 0.5f;
+ return (fabs(a) - a) * b + a;
+}
+
+inline float sc_amclip(float a, float b)
+{
+ return a * 0.5f * (b + fabs(b));
+}
+
+inline double sc_amclip(double a, double b)
+{
+ return a * 0.5 * (b + fabs(b));
+}
+
+const float kFSQRT2M1 = sqrt(2.) - 1.;
+const double kDSQRT2M1 = sqrt(2.) - 1.;
+
+inline float sc_hypotx(float x, float y)
+{
+ float minxy;
+
+ x = fabs(x);
+ y = fabs(y);
+
+ minxy = sc_min(x,y);
+
+ return x + y - kFSQRT2M1 * minxy;
+}
+
+inline double sc_hypotx(double x, double y)
+{
+ double minxy;
+
+ x = fabs(x);
+ y = fabs(y);
+
+ minxy = sc_min(x,y);
+
+ return x + y - kDSQRT2M1 * minxy;
+}
+
+#pragma mark -
+
+
+inline int sc_div(int a, int b)
+{
+ int c;
+ if (b) {
+ if (a<0) c = (a+1)/b - 1;
+ else c = a/b;
+ } else c = a;
+ return c;
+}
+
+/*
+inline int sc_mod(int a, int b)
+{
+ long c;
+ c = a % b;
+ if (c<0) c += b;
+ return c;
+}
+*/
+
+inline int sc_mod(int in, int hi)
+{
+ // avoid the divide if possible
+ const int lo = 0;
+ if (in >= hi) {
+ in -= hi;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ in += hi;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+
+ int c;
+ c = in % hi;
+ if (c<0) c += hi;
+ return c;
+}
+
+inline int sc_wrap(int in, int lo, int hi)
+{
+ return sc_mod(in - lo, hi - lo + 1) + lo;
+}
+
+inline int sc_clip2(int a, int b)
+{
+ return sc_clip(a, -b, b);
+}
+
+inline int sc_wrap2(int a, int b)
+{
+ return sc_wrap(a, -b, b);
+}
+
+inline int sc_fold(int in, int lo, int hi)
+{
+ int b = hi - lo;
+ int b2 = b+b-2;
+ int c = sc_mod(in - lo, b2);
+ if (c>=b) c = b2-c;
+ return c + lo;
+}
+
+inline int sc_fold2(int a, int b)
+{
+ return sc_fold(a, -b, b);
+}
+
+inline int sc_excess(int a, int b)
+{
+ return a - sc_clip(a, -b, b);
+}
+
+inline int sc_gcd(int u, int v)
+{
+ int t;
+ u = sc_abs(u);
+ v = sc_abs(v);
+ if (u <= 1 || v <= 1) return 1;
+ while (u>0) {
+ if (u<v) { t=u; u=v; v=t; }
+ u = u % v;
+ }
+ return v;
+}
+
+inline int sc_lcm(int u, int v)
+{
+ return (u * v)/sc_gcd(u,v);
+}
+
+inline int sc_thresh(int a, int b)
+{
+ return a < b ? 0 : a;
+}
+
+inline int sc_bitAnd(int a, int b)
+{
+ return a & b;
+}
+
+inline int sc_bitOr(int a, int b)
+{
+ return a | b;
+}
+
+inline int sc_leftShift(int a, int b)
+{
+ return a << b;
+}
+
+inline int sc_rightShift(int a, int b)
+{
+ return a >> b;
+}
+
+inline int sc_unsignedRightShift(int a, int b)
+{
+ return (uint32)a >> b;
+}
+
+inline int sc_round(int x, int quant)
+{
+ return quant==0 ? x : sc_div(x + quant/2, quant) * quant;
+}
+
+
+inline int sc_roundUp(int x, int quant)
+{
+ return quant==0 ? x : sc_div(x + quant - 1, quant) * quant;
+}
+
+inline int sc_trunc(int x, int quant)
+{
+ return quant==0 ? x : sc_div(x, quant) * quant;
+}
+
+#pragma mark -
+
+#if 0
+
+inline long sc_div(long a, long b)
+{
+ int c;
+ if (b) {
+ if (a<0) c = (a+1)/b - 1;
+ else c = a/b;
+ } else c = a;
+ return c;
+}
+
+
+inline long sc_clip2(long a, long b)
+{
+ return sc_clip(a, -b, b);
+}
+
+inline long sc_wrap(long in, long lo, long hi)
+{
+ return sc_mod(in - lo, hi - lo + 1) + lo;
+}
+
+inline long sc_wrap2(long a, long b)
+{
+ return sc_wrap(a, -b, b);
+}
+
+inline long sc_fold(long in, long lo, long hi)
+{
+ long b = hi - lo;
+ long b2 = b+b-2;
+ long c = sc_mod(in - lo, b2);
+ if (c>=b) c = b2-c;
+ return c + lo;
+}
+
+inline long sc_fold2(long a, long b)
+{
+ return sc_fold(a, -b, b);
+}
+
+inline long sc_thresh(long a, long b)
+{
+ return a < b ? 0 : a;
+}
+
+inline long sc_bitAnd(long a, long b)
+{
+ return a & b;
+}
+
+inline long sc_bitOr(long a, long b)
+{
+ return a | b;
+}
+
+inline long sc_leftShift(long a, long b)
+{
+ return a << b;
+}
+
+inline long sc_rightShift(long a, long b)
+{
+ return a >> b;
+}
+
+inline long sc_unsignedRightShift(long a, long b)
+{
+ return (unsigned long)a >> b;
+}
+
+inline long sc_gcd(long u, long v)
+{
+ long t;
+ u = sc_abs(u);
+ v = sc_abs(v);
+ if (u <= 1 || v <= 1) return 1;
+ while (u>0) {
+ if (u<v) { t=u; u=v; v=t; }
+ u = u % v;
+ }
+ return v;
+}
+
+inline long sc_lcm(long u, long v)
+{
+ return (u * v)/sc_gcd(u,v);
+}
+
+inline long sc_excess(long a, long b)
+{
+ return a - sc_clip(a, -b, b);
+}
+
+inline long sc_round(long x, long quant)
+{
+ return quant==0 ? x : sc_div(x + quant/2, quant) * quant;
+}
+
+#endif
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/SC_InlineUnaryOp.h b/sc4pd/headers/plugin_interface/SC_InlineUnaryOp.h
new file mode 100644
index 0000000..9ea2e0b
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_InlineUnaryOp.h
@@ -0,0 +1,448 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _UnaryOpUGen_
+#define _UnaryOpUGen_
+
+#include "SC_Types.h"
+#include "SC_Constants.h"
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+inline bool sc_isnan(float x)
+{
+ return (!(x >= 0.f || x <= 0.f));
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+// versions provided for float32 and float64
+// did not supply template because do not want to instantiate for integers.
+// all constants explicitly cast to prevent PowerPC frsp instruction generation.
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+// this is a function for preventing pathological math operations in ugens.
+// can be used at the end of a block to fix any recirculating filter values.
+inline float32 zapgremlins(float32 x)
+{
+ float32 absx = fabs(x);
+ // very small numbers fail the first test, eliminating denormalized numbers
+ // (zero also fails the first test, but that is OK since it returns zero.)
+ // very large numbers fail the second test, eliminating infinities
+ // Not-a-Numbers fail both tests and are eliminated.
+ return (absx > (float32)1e-15 && absx < (float32)1e15) ? x : (float32)0.;
+}
+
+inline float32 sc_log2(float32 x)
+{
+ return log(fabs(x)) * rlog2;
+}
+
+inline float32 sc_log10(float32 x)
+{
+ return log10(fabs(x));
+}
+
+inline float32 sc_midicps(float32 note)
+{
+ return (float32)440. * pow((float32)2., (note - (float32)69.) * (float32)0.083333333333);
+}
+
+inline float32 sc_cpsmidi(float32 freq)
+{
+ return sc_log2(freq * (float32)0.0022727272727) * (float32)12. + (float32)69.;
+}
+
+inline float32 sc_midiratio(float32 midi)
+{
+ return pow((float32)2. , midi * (float32)0.083333333333);
+}
+
+inline float32 sc_ratiomidi(float32 ratio)
+{
+ return (float32)12. * sc_log2(ratio);
+}
+
+inline float32 sc_octcps(float32 note)
+{
+ return (float32)440. * pow((float32)2., note - (float32)4.75);
+}
+
+inline float32 sc_cpsoct(float32 freq)
+{
+ return sc_log2(freq * (float32)0.0022727272727) + (float32)4.75;
+}
+
+inline float32 sc_ampdb(float32 amp)
+{
+ return log10(amp) * (float32)20.;
+}
+
+inline float32 sc_dbamp(float32 db)
+{
+ return pow((float32)10., db * (float32).05);
+}
+
+inline float32 sc_squared(float32 x)
+{
+ return x * x;
+}
+
+inline float32 sc_cubed(float32 x)
+{
+ return x * x * x;
+}
+
+inline float32 sc_sqrt(float32 x)
+{
+ return x < (float32)0. ? -sqrt(-x) : sqrt(x);
+}
+
+
+inline float32 sc_hanwindow(float32 x)
+{
+ if (x < (float32)0. || x > (float32)1.) return (float32)0.;
+ return (float32)0.5 - (float32)0.5 * cos(x * twopi);
+}
+
+inline float32 sc_welwindow(float32 x)
+{
+ if (x < (float32)0. || x > (float32)1.) return (float32)0.;
+ return sin(x * pi);
+}
+
+inline float32 sc_triwindow(float32 x)
+{
+ if (x < (float32)0. || x > (float32)1.) return (float32)0.;
+ if (x < (float32)0.5) return (float32)2. * x;
+ else return (float32)-2. * x + (float32)2.;
+}
+
+inline float32 sc_bitriwindow(float32 x)
+{
+ float32 ax = (float32)1. - fabs(x);
+ if (ax <= (float32)0.) return (float32)0.;
+ return ax;
+}
+
+inline float32 sc_rectwindow(float32 x)
+{
+ if (x < (float32)0. || x > (float32)1.) return (float32)0.;
+ return (float32)1.;
+}
+
+inline float32 sc_scurve(float32 x)
+{
+ if (x <= (float32)0.) return (float32)0.;
+ if (x >= (float32)1.) return (float32)1.;
+ return x * x * ((float32)3. - (float32)2. * x);
+}
+
+inline float32 sc_scurve0(float32 x)
+{
+ // assumes that x is in range
+ return x * x * ((float32)3. - (float32)2. * x);
+}
+
+inline float32 sc_ramp(float32 x)
+{
+ if (x <= (float32)0.) return (float32)0.;
+ if (x >= (float32)1.) return (float32)1.;
+ return x;
+}
+
+inline float32 sc_distort(float32 x)
+{
+ return x / ((float32)1. + fabs(x));
+}
+
+inline float32 sc_softclip(float32 x)
+{
+ float32 absx = fabs(x);
+ if (absx <= (float32)0.5) return x;
+ else return (absx - (float32)0.25) / x;
+}
+
+// Taylor expansion out to x**9/9! factored into multiply-adds
+// from Phil Burk.
+inline float32 taylorsin(float32 x)
+{
+ // valid range from -pi/2 to +3pi/2
+ x = pi2 - fabs(pi2 - x);
+ float32 x2 = x * x;
+ return x*(x2*(x2*(x2*(x2*(1.0/362880.0)
+ - (1.0/5040.0))
+ + (1.0/120.0))
+ - (1.0/6.0))
+ + 1.0);
+}
+
+inline float32 sc_trunc(float32 x)
+{
+ // truncFloat is a number which causes a loss of precision of
+ // the fractional part.
+ // NOTE: this will only work if the FPU is set to round downward.
+ // That is NOT the default rounding mode. SC sets it to this mode.
+ float32 tmp1 = x + truncFloat;
+ float32 tmp2 = tmp1 - truncFloat;
+ return tmp2;
+}
+
+inline float32 sc_frac(float32 x)
+{
+ return x - sc_trunc(x);
+}
+
+inline float32 sc_lg3interp(float32 x1, float32 a, float32 b, float32 c, float32 d)
+{
+ // cubic lagrange interpolator
+ float32 x0 = x1 + 1.f;
+ float32 x2 = x1 - 1.f;
+ float32 x3 = x1 - 2.f;
+
+ float32 x03 = x0 * x3 * 0.5f;
+ float32 x12 = x1 * x2 * 0.16666666666666667f;
+
+ return x12 * (d * x0 - a * x3) + x03 * (b * x2 - c * x1);
+}
+
+inline float32 sc_CalcFeedback(float32 delaytime, float32 decaytime)
+{
+ if (delaytime == 0.f) {
+ return 0.f;
+ } else if (decaytime > 0.f) {
+ return exp(log001 * delaytime / decaytime);
+ } else if (decaytime < 0.f) {
+ return -exp(log001 * delaytime / -decaytime);
+ } else {
+ return 0.f;
+ }
+}
+
+inline float32 sc_wrap1(float32 x)
+{
+ if (x >= (float32) 1.) return x + (float32)-2.;
+ if (x < (float32)-1.) return x + (float32) 2.;
+ return x;
+}
+
+inline float32 sc_fold1(float32 x)
+{
+ if (x >= (float32) 1.) return (float32) 2. - x;
+ if (x < (float32)-1.) return (float32)-2. - x;
+ return x;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+inline float64 zapgremlins(float64 x)
+{
+ float64 absx = fabs(x);
+ // very small numbers fail the first test, eliminating denormalized numbers
+ // (zero also fails the first test, but that is OK since it returns zero.)
+ // very large numbers fail the second test, eliminating infinities
+ // Not-a-Numbers fail both tests and are eliminated.
+ return (absx > (float64)1e-15 && absx < (float64)1e15) ? x : (float64)0.;
+}
+
+inline float64 sc_log2(float64 x)
+{
+ return log(fabs(x)) * rlog2;
+}
+
+inline float64 sc_log10(float64 x)
+{
+ return log10(fabs(x));
+}
+
+inline float64 sc_midicps(float64 note)
+{
+ return (float64)440. * pow((float64)2., (note - (float64)69.) * (float64)0.083333333333);
+}
+
+inline float64 sc_cpsmidi(float64 freq)
+{
+ return sc_log2(freq * (float64)0.0022727272727) * (float64)12. + (float64)69.;
+}
+
+inline float64 sc_midiratio(float64 midi)
+{
+ return pow((float64)2. , midi * (float64)0.083333333333);
+}
+
+inline float64 sc_ratiomidi(float64 ratio)
+{
+ return (float64)12. * sc_log2(ratio);
+}
+
+inline float64 sc_octcps(float64 note)
+{
+ return (float64)440. * pow((float64)2., note - (float64)4.75);
+}
+
+inline float64 sc_cpsoct(float64 freq)
+{
+ return sc_log2(freq * (float64)0.0022727272727) + (float64)4.75;
+}
+
+inline float64 sc_ampdb(float64 amp)
+{
+ return log10(amp) * (float64)20.;
+}
+
+inline float64 sc_dbamp(float64 db)
+{
+ return pow((float64)10., db * (float64).05);
+}
+
+inline float64 sc_squared(float64 x)
+{
+ return x * x;
+}
+
+inline float64 sc_cubed(float64 x)
+{
+ return x * x * x;
+}
+
+inline float64 sc_sqrt(float64 x)
+{
+ return x < (float64)0. ? -sqrt(-x) : sqrt(x);
+}
+
+inline float64 sc_hanwindow(float64 x)
+{
+ if (x < (float64)0. || x > (float64)1.) return (float64)0.;
+ return (float64)0.5 - (float64)0.5 * cos(x * twopi);
+}
+
+inline float64 sc_welwindow(float64 x)
+{
+ if (x < (float64)0. || x > (float64)1.) return (float64)0.;
+ return sin(x * pi);
+}
+
+inline float64 sc_triwindow(float64 x)
+{
+ if (x < (float64)0. || x > (float64)1.) return (float64)0.;
+ if (x < (float64)0.5) return (float64)2. * x;
+ else return (float64)-2. * x + (float64)2.;
+}
+
+inline float64 sc_bitriwindow(float64 x)
+{
+ float64 ax = fabs(x);
+ if (ax > (float64)1.) return (float64)0.;
+ return (float64)1. - ax;
+}
+
+inline float64 sc_rectwindow(float64 x)
+{
+ if (x < (float64)0. || x > (float64)1.) return (float64)0.;
+ return (float64)1.;
+}
+
+inline float64 sc_scurve(float64 x)
+{
+ if (x <= (float64)0.) return (float64)0.;
+ if (x >= (float64)1.) return (float64)1.;
+ return x * x * ((float64)3. - (float64)2. * x);
+}
+
+inline float64 sc_scurve0(float64 x)
+{
+ // assumes that x is in range
+ return x * x * ((float64)3. - (float64)2. * x);
+}
+
+inline float64 sc_ramp(float64 x)
+{
+ if (x <= (float64)0.) return (float64)0.;
+ if (x >= (float64)1.) return (float64)1.;
+ return x;
+}
+
+inline float64 sc_distort(float64 x)
+{
+ return x / ((float64)1. + fabs(x));
+}
+
+inline float64 sc_softclip(float64 x)
+{
+ float64 absx = fabs(x);
+ if (absx <= (float64)0.5) return x;
+ else return (absx - (float64)0.25) / x;
+}
+
+// Taylor expansion out to x**9/9! factored into multiply-adds
+// from Phil Burk.
+inline float64 taylorsin(float64 x)
+{
+ x = pi2 - fabs(pi2 - x);
+ float64 x2 = x * x;
+ return x*(x2*(x2*(x2*(x2*(1.0/362880.0)
+ - (1.0/5040.0))
+ + (1.0/120.0))
+ - (1.0/6.0))
+ + 1.0);
+}
+
+inline float64 sc_trunc(float64 x)
+{
+ // truncDouble is a number which causes a loss of precision of
+ // the fractional part.
+ // NOTE: this will only work if the FPU is set to round downward.
+ // That is NOT the default rounding mode. SC sets it to this mode.
+ float64 tmp1 = x + truncDouble;
+ float64 tmp2 = tmp1 - truncDouble;
+ return tmp2;
+}
+
+inline float64 sc_frac(float64 x)
+{
+ return x - sc_trunc(x);
+}
+
+inline float64 sc_wrap1(float64 x)
+{
+ if (x >= (float64) 1.) return x + (float64)-2.;
+ if (x < (float64)-1.) return x + (float64) 2.;
+ return x;
+}
+
+inline float64 sc_fold1(float64 x)
+{
+ if (x >= (float64) 1.) return (float64) 2. - x;
+ if (x < (float64)-1.) return (float64)-2. - x;
+ return x;
+}
+
+inline int32 sc_grayCode(int32 x)
+{
+ return x ^ (x >> 1);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_InterfaceTable.h b/sc4pd/headers/plugin_interface/SC_InterfaceTable.h
new file mode 100644
index 0000000..20cb864
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_InterfaceTable.h
@@ -0,0 +1,175 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_SynthInterfaceTable_
+#define _SC_SynthInterfaceTable_
+
+#include "SC_Types.h"
+#include "SC_SndBuf.h"
+#include "SC_Unit.h"
+#include "SC_BufGen.h"
+#include "SC_FifoMsg.h"
+#include <sndfile.h>
+
+struct World;
+
+typedef bool (*AsyncStageFn)(World *inWorld, void* cmdData);
+typedef void (*AsyncFreeFn)(World *inWorld, void* cmdData);
+
+struct InterfaceTable
+{
+ unsigned int mSineSize;
+ float32 *mSineWavetable;
+ float32 *mSine;
+ float32 *mCosecant;
+
+ // call printf for debugging. should not use in finished code.
+ int (*fPrint)(const char *fmt, ...);
+
+ // get a seed for a random number generator
+ int32 (*fRanSeed)();
+
+ // define a unit def
+ bool (*fDefineUnit)(char *inUnitClassName, size_t inAllocSize,
+ UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags);
+
+ // define a command /cmd
+ bool (*fDefinePlugInCmd)(char *inCmdName, PlugInCmdFunc inFunc, void* inUserData);
+
+ // define a command for a unit generator /u_cmd
+ bool (*fDefineUnitCmd)(char *inUnitClassName, char *inCmdName, UnitCmdFunc inFunc);
+
+ // define a buf gen
+ bool (*fDefineBufGen)(char *inName, BufGenFunc inFunc);
+
+ // clear all of the unit's outputs.
+ void (*fClearUnitOutputs)(Unit *inUnit, int inNumSamples);
+
+ // non real time memory allocation
+ void* (*fNRTAlloc)(size_t inSize);
+ void* (*fNRTRealloc)(void *inPtr, size_t inSize);
+ void (*fNRTFree)(void *inPtr);
+
+ // real time memory allocation
+ void* (*fRTAlloc)(World *inWorld, size_t inSize);
+ void* (*fRTRealloc)(World *inWorld, void *inPtr, size_t inSize);
+ void (*fRTFree)(World *inWorld, void *inPtr);
+
+ // call to set a Node to run or not.
+ void (*fNodeRun)(struct Node* node, int run);
+
+ // call to stop a Graph after the next buffer.
+ void (*fNodeEnd)(struct Node* graph);
+
+ // send a trigger from a Node to clients
+ void (*fSendTrigger)(struct Node* inNode, int triggerID, float value);
+
+ // sending messages between real time and non real time levels.
+ bool (*fSendMsgFromRT)(World *inWorld, struct FifoMsg& inMsg);
+ bool (*fSendMsgToRT)(World *inWorld, struct FifoMsg& inMsg);
+
+ // libsndfile support
+ int (*fSndFileFormatInfoFromStrings)(SF_INFO *info,
+ const char *headerFormatString, const char *sampleFormatString);
+
+ // get nodes by id
+ struct Node* (*fGetNode)(World *inWorld, int inID);
+ struct Graph* (*fGetGraph)(World *inWorld, int inID);
+
+ void (*fNRTLock)(World *inWorld);
+ void (*fNRTUnlock)(World *inWorld);
+
+ bool mAltivecAvailable;
+
+ void (*fGroup_DeleteAll)(struct Group* group);
+ void (*fDoneAction)(int doneAction, struct Unit *unit);
+
+ int (*fDoAsynchronousCommand)
+ (
+ World *inWorld,
+ void* replyAddr,
+ const char* cmdName,
+ void *cmdData,
+ AsyncStageFn stage2, // stage2 is non real time
+ AsyncStageFn stage3, // stage3 is real time - completion msg performed if stage3 returns true
+ AsyncStageFn stage4, // stage4 is non real time - sends done if stage4 returns true
+ AsyncFreeFn cleanup,
+ int completionMsgSize,
+ void* completionMsgData
+ );
+
+
+ // fBufAlloc should only be called within a BufGenFunc
+ int (*fBufAlloc)(SndBuf *inBuf, int inChannels, int inFrames, double inSampleRate);
+};
+typedef struct InterfaceTable InterfaceTable;
+
+#define Print (*ft->fPrint)
+#define RanSeed (*ft->fRanSeed)
+#define NodeEnd (*ft->fNodeEnd)
+#define NodeRun (*ft->fNodeRun)
+#define DefineUnit (*ft->fDefineUnit)
+#define DefinePlugInCmd (*ft->fDefinePlugInCmd)
+#define DefineUnitCmd (*ft->fDefineUnitCmd)
+#define DefineBufGen (*ft->fDefineBufGen)
+#define ClearUnitOutputs (*ft->fClearUnitOutputs)
+#define SendTrigger (*ft->fSendTrigger)
+#define SendMsgFromRT (*ft->fSendMsgFromRT)
+#define SendMsgToRT (*ft->fSendMsgToRT)
+#define DoneAction (*ft->fDoneAction)
+
+#define NRTAlloc (*ft->fNRTAlloc)
+#define NRTRealloc (*ft->fNRTRealloc)
+#define NRTFree (*ft->fNRTFree)
+
+#define RTAlloc (*ft->fRTAlloc)
+#define RTRealloc (*ft->fRTRealloc)
+#define RTFree (*ft->fRTFree)
+
+#define SC_GetNode (*ft->fGetNode)
+#define SC_GetGraph (*ft->fGetGraph)
+
+#define NRTLock (*ft->fNRTLock)
+#define NRTUnlock (*ft->fNRTUnlock)
+
+#define BufAlloc (*ft->fBufAlloc)
+
+#define GroupDeleteAll (*ft->fGroup_DeleteAll)
+
+#define SndFileFormatInfoFromStrings (*ft->fSndFileFormatInfoFromStrings)
+
+#define DoAsynchronousCommand (*ft->fDoAsynchronousCommand)
+
+#define DefineSimpleUnit(name) \
+ (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, 0, 0);
+
+#define DefineDtorUnit(name) \
+ (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, \
+ (UnitDtorFunc)&name##_Dtor, 0);
+
+#define DefineSimpleCantAliasUnit(name) \
+ (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, 0, kUnitDef_CantAliasInputsToOutputs);
+
+#define DefineDtorCantAliasUnit(name) \
+ (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, \
+ (UnitDtorFunc)&name##_Dtor, kUnitDef_CantAliasInputsToOutputs);
+
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_Node.h b/sc4pd/headers/plugin_interface/SC_Node.h
new file mode 100644
index 0000000..36dd412
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Node.h
@@ -0,0 +1,48 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Node_
+#define _SC_Node_
+
+#include "SC_Types.h"
+
+typedef void (*NodeCalcFunc)(struct Node *inNode);
+
+struct Node
+{
+ int32 mID;
+ int32 mHash;
+
+ struct World *mWorld;
+ struct NodeDef *mDef;
+ NodeCalcFunc mCalcFunc;
+
+ struct Node *mPrev, *mNext;
+ struct Group *mParent;
+
+ int32 mIsGroup;
+};
+typedef struct Node Node;
+
+enum { kNode_Go, kNode_End, kNode_On, kNode_Off, kNode_Move, kNode_Info };
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/SC_PlugIn.h b/sc4pd/headers/plugin_interface/SC_PlugIn.h
new file mode 100644
index 0000000..4f01fd3
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_PlugIn.h
@@ -0,0 +1,53 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#include "SC_World.h"
+#include "SC_Graph.h"
+#include "SC_Unit.h"
+#include "SC_Wire.h"
+#include "SC_InterfaceTable.h"
+#include "Unroll.h"
+#include "SC_InlineUnaryOp.h"
+#include "SC_InlineBinaryOp.h"
+#include "SC_BoundsMacros.h"
+#include "SC_RGen.h"
+#include "SC_DemandUnit.h"
+#include "clz.h"
+#include "sc_msg_iter.h"
+#include "SC_Altivec.h"
+#include <stdlib.h>
+
+#ifdef SC_WIN32
+
+// temporarily override __attribute__ for (unused), later we'll remove it
+#ifndef __GCC__
+#define __attribute__(x)
+#endif
+
+// workaround for IN/OUT conflict with Win32 headers. see SC_Unit.h for details
+#define IN SC_IN
+#define OUT SC_OUT
+
+#ifdef _MSC_VER
+#include <xmath.h>
+#endif //_MSC_VER
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_RGen.h b/sc4pd/headers/plugin_interface/SC_RGen.h
new file mode 100644
index 0000000..11f8c9a
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_RGen.h
@@ -0,0 +1,288 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+//----------------------------------------------------------------------------//
+// Ran088: L'Ecuyer's 1996 three-component Tausworthe generator "taus88"
+//----------------------------------------------------------------------------//
+//
+// Returns an integer random number uniformly distributed within [0,4294967295]
+//
+// The period length is approximately 2^88 (which is 3*10^26).
+// This generator is very fast and passes all standard statistical tests.
+//
+// Reference:
+// (1) P. L'Ecuyer, Maximally equidistributed combined Tausworthe generators,
+// Mathematics of Computation, 65, 203-213 (1996), see Figure 4.
+// (2) recommended in:
+// P. L'Ecuyer, Random number generation, chapter 4 of the
+// Handbook on Simulation, Ed. Jerry Banks, Wiley, 1997.
+//
+//----------------------------------------------------------------------------//
+
+//----------------------------------------------------------------------------//
+// I chose this random number generator for the following reasons:
+// fast.
+// easier and faster to seed than other high quality rng's such as Mersenne Twister.
+// the internal state is only 12 bytes.
+// the period is long enough for music/audio.
+// possible to code in altivec in future if needed.
+// - James McCartney
+//----------------------------------------------------------------------------//
+
+#ifndef _SC_RGen_
+#define _SC_RGen_
+
+#include "SC_Endian.h"
+#include "SC_Types.h"
+#include "SC_BoundsMacros.h"
+#include "Hash.h"
+#include <math.h>
+
+struct RGen
+{
+ void init(uint32 seed);
+
+ uint32 trand();
+
+ int32 irand(int32 scale);
+ int32 irand2(int32 scale);
+ int32 ilinrand(int32 scale);
+ int32 ibilinrand(int32 scale);
+
+ float fcoin();
+ float frand();
+ float frand2();
+ float frand0();
+ float frand8();
+ double drand();
+ double drand2(double scale);
+ double linrand(double scale);
+ double bilinrand(double scale);
+ double exprandrng(double lo, double hi);
+ double exprand(double scale);
+ double biexprand(double scale);
+ double sum3rand(double scale);
+
+ uint32 s1, s2, s3; // random generator state
+};
+
+inline void RGen::init(uint32 seed)
+{
+ // humans tend to use small seeds - mess up the bits
+ seed = (uint32)Hash((int)seed);
+
+ // initialize seeds using the given seed value taking care of
+ // the requirements. The constants below are arbitrary otherwise
+ s1 = 1243598713U ^ seed; if (s1 < 2) s1 = 1243598713U;
+ s2 = 3093459404U ^ seed; if (s2 < 8) s2 = 3093459404U;
+ s3 = 1821928721U ^ seed; if (s3 < 16) s3 = 1821928721U;
+}
+
+inline uint32 trand( uint32& s1, uint32& s2, uint32& s3 )
+{
+ // This function is provided for speed in inner loops where the
+ // state variables are loaded into registers.
+ // Thus updating the instance variables can
+ // be postponed until the end of the loop.
+ s1 = ((s1 & -2) << 12) ^ (((s1 << 13) ^ s1) >> 19);
+ s2 = ((s2 & -8) << 4) ^ (((s2 << 2) ^ s2) >> 25);
+ s3 = ((s3 & -16) << 17) ^ (((s3 << 3) ^ s3) >> 11);
+ return s1 ^ s2 ^ s3;
+}
+
+inline uint32 RGen::trand()
+{
+ // generate a random 32 bit number
+ s1 = ((s1 & -2) << 12) ^ (((s1 << 13) ^ s1) >> 19);
+ s2 = ((s2 & -8) << 4) ^ (((s2 << 2) ^ s2) >> 25);
+ s3 = ((s3 & -16) << 17) ^ (((s3 << 3) ^ s3) >> 11);
+ return s1 ^ s2 ^ s3;
+}
+
+inline double RGen::drand()
+{
+ // return a double from 0.0 to 0.999...
+#if BYTE_ORDER == BIG_ENDIAN
+ union { struct { uint32 hi, lo; } i; double f; } du;
+#else
+ union { struct { uint32 lo, hi; } i; double f; } du;
+#endif
+ du.i.hi = 0x41300000;
+ du.i.lo = trand();
+ return du.f - 1048576.;
+}
+
+inline float RGen::frand()
+{
+ // return a float from 0.0 to 0.999...
+ union { uint32 i; float f; } u; // union for floating point conversion of result
+ u.i = 0x3F800000 | (trand() >> 9);
+ return u.f - 1.f;
+}
+
+inline float RGen::frand0()
+{
+ // return a float from +1.0 to +1.999...
+ union { uint32 i; float f; } u; // union for floating point conversion of result
+ u.i = 0x3F800000 | (trand() >> 9);
+ return u.f;
+}
+
+inline float RGen::frand2()
+{
+ // return a float from -1.0 to +0.999...
+ union { uint32 i; float f; } u; // union for floating point conversion of result
+ u.i = 0x40000000 | (trand() >> 9);
+ return u.f - 3.f;
+}
+
+inline float RGen::frand8()
+{
+ // return a float from -0.125 to +0.124999...
+ union { uint32 i; float f; } u; // union for floating point conversion of result
+ u.i = 0x3E800000 | (trand() >> 9);
+ return u.f - 0.375f;
+}
+
+inline float RGen::fcoin()
+{
+ // only return one of the two values -1.0 or +1.0
+ union { uint32 i; float f; } u; // union for floating point conversion of result
+ u.i = 0x3F800000 | (0x80000000 & trand());
+ return u.f;
+}
+
+inline int32 RGen::irand(int32 scale)
+{
+ // return an int from 0 to scale - 1
+ return (int32)floor(scale * drand());
+}
+
+inline int32 RGen::irand2(int32 scale)
+{
+ // return a int from -scale to +scale
+ return (int32)floor((2. * scale + 1.) * drand() - scale);
+}
+
+inline int32 RGen::ilinrand(int32 scale)
+{
+ int32 a = irand(scale);
+ int32 b = irand(scale);
+ return sc_min(a,b);
+}
+
+inline double RGen::linrand(double scale)
+{
+ double a = drand();
+ double b = drand();
+ return sc_min(a,b) * scale;
+}
+
+inline int32 RGen::ibilinrand(int32 scale)
+{
+ int32 a = irand(scale);
+ int32 b = irand(scale);
+ return a - b;
+}
+
+inline double RGen::bilinrand(double scale)
+{
+ double a = drand();
+ double b = drand();
+ return (a - b) * scale;
+}
+
+inline double RGen::exprandrng(double lo, double hi)
+{
+ return lo * exp(log(hi / lo) * drand());
+}
+
+inline double RGen::exprand(double scale)
+{
+ double z;
+ while ((z = drand()) == 0.0) {}
+ return -log(z) * scale;
+}
+
+inline double RGen::biexprand(double scale)
+{
+ double z;
+ while ((z = drand2(1.)) == 0.0 || z == -1.0) {}
+ if (z > 0.0) z = log(z);
+ else z = -log(-z);
+ return z * scale;
+}
+
+inline double RGen::sum3rand(double scale)
+{
+ // larry polansky's poor man's gaussian generator
+ return (drand() + drand() + drand() - 1.5) * 0.666666667 * scale;
+}
+
+inline double drand( uint32& s1, uint32& s2, uint32& s3 )
+{
+ union { struct { uint32 hi, lo; } i; double f; } u;
+ u.i.hi = 0x41300000;
+ u.i.lo = trand(s1,s2,s3);
+ return u.f - 1048576.;
+}
+
+inline float frand( uint32& s1, uint32& s2, uint32& s3 )
+{
+ // return a float from 0.0 to 0.999...
+ union { uint32 i; float f; } u;
+ u.i = 0x3F800000 | (trand(s1,s2,s3) >> 9);
+ return u.f - 1.f;
+}
+
+inline float frand0( uint32& s1, uint32& s2, uint32& s3 )
+{
+ // return a float from +1.0 to +1.999...
+ union { uint32 i; float f; } u;
+ u.i = 0x3F800000 | (trand(s1,s2,s3) >> 9);
+ return u.f;
+}
+
+inline float frand2( uint32& s1, uint32& s2, uint32& s3 )
+{
+ // return a float from -1.0 to +0.999...
+ union { uint32 i; float f; } u;
+ u.i = 0x40000000 | (trand(s1,s2,s3) >> 9);
+ return u.f - 3.f;
+}
+
+inline float frand8( uint32& s1, uint32& s2, uint32& s3 )
+{
+ // return a float from -0.125 to +0.124999...
+ union { uint32 i; float f; } u;
+ u.i = 0x3E800000 | (trand(s1,s2,s3) >> 9);
+ return u.f - 0.375f;
+}
+
+inline float fcoin( uint32& s1, uint32& s2, uint32& s3 )
+{
+ // only return one of the two values -1.0 or +1.0
+ union { uint32 i; float f; } u;
+ u.i = 0x3F800000 | (0x80000000 & trand(s1,s2,s3));
+ return u.f;
+}
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/SC_Rate.h b/sc4pd/headers/plugin_interface/SC_Rate.h
new file mode 100644
index 0000000..63c160d
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Rate.h
@@ -0,0 +1,42 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _Rate_
+#define _Rate_
+
+enum { calc_ScalarRate, calc_BufRate, calc_FullRate, calc_DemandRate };
+
+struct Rate
+{
+ double mSampleRate; // samples per second
+ double mSampleDur; // seconds per sample
+ double mBufDuration; // seconds per buffer
+ double mBufRate; // buffers per second
+ double mSlopeFactor; // 1. / NumSamples
+ double mRadiansPerSample; // 2pi / SampleRate
+ int mBufLength; // length of the buffer
+ // second order filter loops are often unrolled by 3
+ int mFilterLoops, mFilterRemain;
+ double mFilterSlope;
+};
+typedef struct Rate Rate;
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_SndBuf.h b/sc4pd/headers/plugin_interface/SC_SndBuf.h
new file mode 100644
index 0000000..affd2b9
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_SndBuf.h
@@ -0,0 +1,109 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SndBuf_
+#define _SndBuf_
+
+#include <sys/types.h>
+#include <sndfile.h>
+
+struct SndBuf
+{
+ double samplerate;
+ double sampledur; // = 1/ samplerate
+ float *data;
+ int channels;
+ int samples;
+ int frames;
+ int mask; // for delay lines
+ int mask1; // for interpolating oscillators.
+ int coord; // used by fft ugens
+ SNDFILE *sndfile; // used by disk i/o
+};
+typedef struct SndBuf SndBuf;
+
+struct SndBufUpdates
+{
+ int reads;
+ int writes;
+};
+typedef struct SndBufUpdates SndBufUpdates;
+
+enum { coord_None, coord_Complex, coord_Polar };
+
+
+inline float PhaseFrac(unsigned long inPhase)
+ {
+ union { unsigned long itemp; float ftemp; } u;
+ u.itemp = 0x3F800000 | (0x007FFF80 & ((inPhase)<<7));
+ return u.ftemp - 1.f;
+ }
+
+inline float PhaseFrac1(unsigned long inPhase)
+ {
+ union { unsigned long itemp; float ftemp; } u;
+ u.itemp = 0x3F800000 | (0x007FFF80 & ((inPhase)<<7));
+ return u.ftemp;
+ }
+
+inline float lookup(float *table, int32 phase, int32 mask)
+{
+ return table[(phase >> 16) & mask];
+}
+
+
+#define xlobits 14
+#define xlobits1 13
+
+inline float lookupi(float *table, uint32 phase, uint32 mask)
+{
+ float frac = PhaseFrac(phase);
+ float *tbl = table + ((phase >> 16) & mask);
+ float a = tbl[0];
+ float b = tbl[1];
+ return a + frac * (b - a);
+}
+
+inline float lookupi2(float *table, uint32 phase, uint32 mask)
+{
+ float frac = PhaseFrac1(phase);
+ float *tbl = table + ((phase >> 16) & mask);
+ float a = tbl[0];
+ float b = tbl[1];
+ return a + frac * b;
+}
+
+inline float lookupi1(float* table0, float* table1, uint32 pphase, int32 lomask)
+{
+ float pfrac = PhaseFrac1(pphase);
+ uint32 index = ((pphase >> xlobits1) & lomask);
+ float val1 = *(float*)((char*)table0 + index);
+ float val2 = *(float*)((char*)table1 + index);
+ return val1 + val2 * pfrac;
+}
+
+
+inline float lininterp(float x, float a, float b)
+{
+ return a + x * (b - a);
+}
+
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_Types.h b/sc4pd/headers/plugin_interface/SC_Types.h
new file mode 100644
index 0000000..d635b07
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Types.h
@@ -0,0 +1,67 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_Types_
+#define _SC_Types_
+
+#include <sys/types.h>
+
+typedef int SCErr;
+
+#ifdef SC_WIN32
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+#else
+typedef long long int64;
+typedef unsigned long long uint64;
+#endif
+
+typedef int int32;
+typedef unsigned int uint32;
+#ifdef SC_DARWIN
+typedef unsigned int ulong;
+#endif
+
+typedef short int16;
+typedef unsigned short uint16;
+
+typedef signed char int8;
+typedef unsigned char uint8;
+
+typedef float float32;
+typedef double float64;
+
+typedef union {
+ uint32 u;
+ int32 i;
+ float32 f;
+} elem32;
+
+typedef union {
+ uint64 u;
+ int64 i;
+ float64 f;
+} elem64;
+
+const unsigned int kSCNameLen = 8;
+const unsigned int kSCNameByteLen = kSCNameLen * sizeof(int32);
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/SC_Unit.h b/sc4pd/headers/plugin_interface/SC_Unit.h
new file mode 100644
index 0000000..2ded017
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Unit.h
@@ -0,0 +1,101 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Unit_
+#define _SC_Unit_
+
+#include "SC_Types.h"
+
+typedef void (*UnitCtorFunc)(struct Unit* inUnit);
+typedef void (*UnitDtorFunc)(struct Unit* inUnit);
+
+typedef void (*UnitCalcFunc)(struct Unit *inThing, int inNumSamples);
+
+struct Unit
+{
+ struct World *mWorld;
+ struct UnitDef *mUnitDef;
+ struct Graph *mParent;
+ uint16 mNumInputs, mNumOutputs;
+ int16 mCalcRate;
+ int16 mSpecialIndex; // used by unary and binary ops
+ int16 mParentIndex;
+ int16 mDone;
+
+ struct Wire **mInput, **mOutput;
+ struct Rate *mRate;
+ struct SC_Dimension *mDimension;
+ float **mInBuf, **mOutBuf;
+
+ UnitCalcFunc mCalcFunc;
+ int mBufLength;
+};
+typedef struct Unit Unit;
+
+enum {
+ kUnitDef_CantAliasInputsToOutputs = 1
+};
+
+// easy macros, the unit variable must be named 'unit'.
+#ifndef SC_WIN32
+
+// These return float* pointers to input and output buffers.
+#define IN(index) (unit->mInBuf[index])
+#define OUT(index) (unit->mOutBuf[index])
+
+// These return a float value. Used for control rate inputs and outputs.
+#define IN0(index) (IN(index)[0])
+#define OUT0(index) (OUT(index)[0])
+
+#else
+
+// Win32 headers (included by C std library headers) define IN and OUT macros
+// for their own purposes. To avoid problems we don't define IN and OUT here
+// but define SC_IN and SC_OUT instead. Source files that use IN and OUT need
+// to include definitions of IN, and OUT referencing SC_IN and SC_OUT after
+// all headers have been included.
+#define SC_IN(index) (unit->mInBuf[index])
+#define SC_OUT(index) (unit->mOutBuf[index])
+#define IN0(index) (SC_IN(index)[0])
+#define OUT0(index) (SC_OUT(index)[0])
+
+#endif
+
+// get the rate of the input.
+#define INRATE(index) (unit->mInput[index]->mCalcRate)
+
+// set the calculation function
+#define SETCALC(func) (unit->mCalcFunc = (UnitCalcFunc)&func)
+
+// calculate a slope for control rate interpolation to audio rate.
+#define CALCSLOPE(next,prev) ((next - prev) * unit->mRate->mSlopeFactor)
+
+// get useful values
+#define SAMPLERATE (unit->mRate->mSampleRate)
+#define SAMPLEDUR (unit->mRate->mSampleDur)
+#define BUFLENGTH (unit->mBufLength)
+#define BUFRATE (unit->mRate->mBufRate)
+#define BUFDUR (unit->mRate->mBufDuration)
+
+typedef void (*UnitCmdFunc)(struct Unit *unit, struct sc_msg_iter *args);
+typedef void (*PlugInCmdFunc)(World *inWorld, void* inUserData, struct sc_msg_iter *args, void *replyAddr);
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_Wire.h b/sc4pd/headers/plugin_interface/SC_Wire.h
new file mode 100644
index 0000000..f2680ac
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Wire.h
@@ -0,0 +1,36 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Wire_
+#define _SC_Wire_
+
+#include "SC_Types.h"
+
+struct Wire
+{
+ struct Unit *mFromUnit;
+ int32 mCalcRate;
+ float32 *mBuffer;
+ float32 mScalarValue;
+};
+typedef struct Wire Wire;
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_World.h b/sc4pd/headers/plugin_interface/SC_World.h
new file mode 100644
index 0000000..8586432
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_World.h
@@ -0,0 +1,105 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_World_
+#define _SC_World_
+
+#include "SC_Types.h"
+#include "SC_Rate.h"
+#include "SC_SndBuf.h"
+#include "SC_RGen.h"
+#include "SC_Lock.h"
+
+struct World
+{
+ // a pointer to private implementation, not available to plug-ins.
+ struct HiddenWorld *hw;
+
+ // a pointer to the table of function pointers that implement the plug-ins'
+ // interface to the server.
+ struct InterfaceTable *ft;
+
+ // data accessible to plug-ins :
+ double mSampleRate;
+ int mBufLength;
+ int mBufCounter;
+
+ uint32 mNumAudioBusChannels;
+ uint32 mNumControlBusChannels;
+ uint32 mNumInputs;
+ uint32 mNumOutputs;
+
+ // vector of samples for all audio busses
+ float *mAudioBus;
+
+ // vector of samples for all control busses
+ float *mControlBus;
+
+ // these tell if a buss has been written to during a control period
+ // if the value is equal to mBufCounter then the buss has been touched
+ // this control period.
+ int32 *mAudioBusTouched;
+ int32 *mControlBusTouched;
+
+ uint32 mNumSndBufs;
+ SndBuf *mSndBufs;
+ SndBuf *mSndBufsNonRealTimeMirror;
+ SndBufUpdates *mSndBufUpdates;
+
+ struct Group *mTopGroup;
+
+ Rate mFullRate, mBufRate;
+
+ uint32 mNumRGens;
+ RGen *mRGen;
+
+ uint32 mNumUnits, mNumGraphs, mNumGroups;
+ int mSampleOffset; // offset in the buffer of current event time.
+
+ SC_Lock* mNRTLock;
+
+ uint32 mNumSharedControls;
+ float *mSharedControls;
+
+ bool mRealTime;
+ bool mRunning;
+ int mDumpOSC;
+};
+
+extern "C" {
+ int scprintf(const char *fmt, ...);
+}
+
+inline SndBuf* World_GetBuf(struct World *inWorld, uint32 index)
+{
+ if (index > inWorld->mNumSndBufs) index = 0;
+ return inWorld->mSndBufs + index;
+}
+
+inline SndBuf* World_GetNRTBuf(struct World *inWorld, uint32 index)
+{
+ if (index > inWorld->mNumSndBufs) index = 0;
+ return inWorld->mSndBufsNonRealTimeMirror + index;
+}
+
+typedef void (*LoadPlugInFunc)(struct InterfaceTable *);
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_WorldOptions.h b/sc4pd/headers/plugin_interface/SC_WorldOptions.h
new file mode 100644
index 0000000..b04850f
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_WorldOptions.h
@@ -0,0 +1,91 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_WorldOptions_
+#define _SC_WorldOptions_
+
+#include <stdarg.h>
+#include "SC_Types.h"
+
+typedef int (*PrintFunc)(const char *format, va_list ap);
+
+struct WorldOptions
+{
+ const char* mPassword;
+ uint32 mNumBuffers;
+ uint32 mMaxLogins;
+ uint32 mMaxNodes;
+ uint32 mMaxGraphDefs;
+ uint32 mMaxWireBufs;
+ uint32 mNumAudioBusChannels;
+ uint32 mNumInputBusChannels;
+ uint32 mNumOutputBusChannels;
+ uint32 mNumControlBusChannels;
+ uint32 mBufLength;
+ uint32 mRealTimeMemorySize;
+
+ int mNumSharedControls;
+ float *mSharedControls;
+
+ bool mRealTime;
+
+ const char *mNonRealTimeCmdFilename;
+ const char *mNonRealTimeInputFilename;
+ const char *mNonRealTimeOutputFilename;
+ const char *mNonRealTimeOutputHeaderFormat;
+ const char *mNonRealTimeOutputSampleFormat;
+
+ uint32 mPreferredSampleRate;
+ uint32 mNumRGens;
+
+ uint32 mPreferredHardwareBufferFrameSize;
+
+ uint32 mLoadGraphDefs;
+
+#ifdef SC_DARWIN
+ const char *mInputStreamsEnabled;
+ const char *mOutputStreamsEnabled;
+#endif
+};
+
+const WorldOptions kDefaultWorldOptions =
+{
+ 0,1024,64,1024,1024,64,128,8,8,4096,64,8192, 0,0, 1, 0,0,0,0,0, 0, 64, 0, 1
+#ifdef SC_DARWIN
+ ,0,0
+#endif
+};
+
+#include "SC_Reply.h"
+
+extern "C" {
+ void SetPrintFunc(PrintFunc func);
+ struct World* World_New(WorldOptions *inOptions);
+ void World_OpenUDP(struct World *inWorld, int inPort);
+ void World_OpenTCP(struct World *inWorld, int inPort, int inMaxConnections, int inBacklog);
+ void World_WaitForQuit(struct World *inWorld);
+ bool World_SendPacket(struct World *inWorld, int inSize, char *inData, ReplyFunc inFunc);
+ int World_CopySndBuf(World *world, uint32 index, struct SndBuf *outBuf, bool onlyIfChanged, bool &didChange);
+ int scprintf(const char *fmt, ...);
+}
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/Unroll.h b/sc4pd/headers/plugin_interface/Unroll.h
new file mode 100644
index 0000000..12ae864
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/Unroll.h
@@ -0,0 +1,249 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+
+These macros allow one to write code which can be compiled optimally depending on
+what loop constructs the compiler can best generate code.
+
+*/
+
+#ifndef _Unroll_
+#define _Unroll_
+
+#if 1
+
+// loop type
+#define FOR_IS_FASTER 1
+#define WHILE_IS_FASTER 0
+// indexing type
+#define PREINCREMENT_IS_FASTER 1
+#define POSTINCREMENT_IS_FASTER 0
+
+#else
+
+// loop type
+#define FOR_IS_FASTER 1
+#define WHILE_IS_FASTER 0
+// indexing type
+#define PREINCREMENT_IS_FASTER 0
+#define POSTINCREMENT_IS_FASTER 1
+
+#endif
+
+
+// LOOPING MACROS :
+
+#if FOR_IS_FASTER
+
+#define LOOP(length, stmt) for (int xxi=0; xxi<(length); ++xxi) { stmt; }
+
+#elif WHILE_IS_FASTER
+
+#define LOOP(length, stmt) \
+ { int xxn = (length); \
+ while (--xxn) { \
+ stmt; \
+ } \
+ }
+
+#endif
+
+
+
+// above macros are not friendly to the debugger
+#if FOR_IS_FASTER
+
+#define LooP(length) for (int xxi=0; xxi<(length); ++xxi)
+
+#elif WHILE_IS_FASTER
+
+#define LooP(length) for (int xxi=(length); --xxi;)
+
+#endif
+
+
+// LOOP INDEXING :
+
+/*
+meanings of the indexing macros:
+ ZXP = dereference and pre or post increment
+ ZX = dereference
+ PZ = preincrement (if applicable)
+ ZP = postincrement (if applicable)
+ ZOFF = offset from the pointer of the first element of the array
+ (preincrement requires a ZOFF of 1 which is pre-subtracted from the
+ base pointer. For other indexing types ZOFF is zero)
+*/
+
+#if PREINCREMENT_IS_FASTER
+#define ZXP(z) (*++(z))
+#define ZX(z) (*(z))
+#define PZ(z) (++(z))
+#define ZP(z) (z)
+#define ZOFF (1)
+#elif POSTINCREMENT_IS_FASTER
+#define ZXP(z) (*(z)++)
+#define ZX(z) (*(z))
+#define PZ(z) (z)
+#define ZP(z) ((z)++)
+#define ZOFF (0)
+#endif
+
+// ACCESSING INLETS AND OUTLETS :
+
+// unit inputs
+#define ZIN(i) (IN(i) - ZOFF) // get buffer pointer offset for iteration
+#define ZIN0(i) (IN(i)[0]) // get first sample
+
+// unit outputs
+#define ZOUT(i) (OUT(i) - ZOFF) // get buffer pointer offset for iteration
+#define ZOUT0(i) (OUT(i)[0]) // get first sample
+
+#include "SC_BoundsMacros.h"
+
+#ifndef NDEBUG
+# define NDEBUG
+#endif
+#include <assert.h>
+
+inline void Clear(int numSamples, float *out)
+{
+ //assert((((long)(out+ZOFF) & 7) == 0)); // pointer must be 8 byte aligned
+
+ if ((numSamples & 1) == 0) {
+ // copying doubles is faster on powerpc.
+ double *outd = (double*)out - ZOFF;
+ LOOP(numSamples >> 1, ZXP(outd) = 0.; );
+ } else {
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) = 0.f; );
+ }
+}
+
+inline void Copy(int numSamples, float *out, float *in)
+{
+ // pointers must be 8 byte aligned
+ //assert((((long)(out+ZOFF) & 7) == 0) && (((long)(in+ZOFF) & 7) == 0));
+ if (in == out) return;
+ if ((numSamples & 1) == 0) {
+ // copying doubles is faster on powerpc.
+ double *outd = (double*)out - ZOFF;
+ double *ind = (double*)in - ZOFF;
+ LOOP(numSamples >> 1, ZXP(outd) = ZXP(ind); );
+ } else {
+ in -= ZOFF;
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) = ZXP(in); );
+ }
+}
+
+inline void Fill(int numSamples, float *out, float level)
+{
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) = level; );
+}
+
+inline void Fill(int numSamples, float *out, float level, float slope)
+{
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) = level; level += slope; );
+}
+
+inline void Accum(int numSamples, float *out, float *in)
+{
+ in -= ZOFF;
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) += ZXP(in); );
+}
+
+inline void Scale(int numSamples, float *out, float level)
+{
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) *= level;);
+}
+
+inline float Scale(int numSamples, float *out, float level, float slope)
+{
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) *= level; level += slope;);
+ return level;
+}
+
+inline float Scale(int numSamples, float *out, float *in, float level, float slope)
+{
+ in -= ZOFF;
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) = ZXP(in) * level; level += slope;);
+ return level;
+}
+
+inline float ScaleMix(int numSamples, float *out, float *in, float level, float slope)
+{
+ in -= ZOFF;
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) += ZXP(in) * level; level += slope;);
+ return level;
+}
+
+inline void Scale(int numSamples, float *out, float *in, float level)
+{
+ in -= ZOFF;
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) = ZXP(in) * level; );
+}
+
+// in these the pointers are assumed to already have been pre-offset.
+inline void ZCopy(int numSamples, float *out, float *in)
+{
+ // pointers must be 8 byte aligned
+ //assert((((long)(out+ZOFF) & 7) == 0) && (((long)(in+ZOFF) & 7) == 0));
+ if (in == out) return;
+ if ((numSamples & 1) == 0) {
+ // copying doubles is faster on powerpc.
+ double *outd = (double*)(out + ZOFF) - ZOFF;
+ double *ind = (double*)(in + ZOFF) - ZOFF;
+ LOOP(numSamples >> 1, ZXP(outd) = ZXP(ind); );
+ } else {
+ LOOP(numSamples, ZXP(out) = ZXP(in); );
+ }
+}
+
+inline void ZClear(int numSamples, float *out)
+{
+ // pointers must be 8 byte aligned
+ //assert((((long)(out+ZOFF) & 7) == 0) && (((long)(in+ZOFF) & 7) == 0));
+ if ((numSamples & 1) == 0) {
+ // copying doubles is faster on powerpc.
+ double *outd = (double*)(out + ZOFF) - ZOFF;
+ LOOP(numSamples >> 1, ZXP(outd) = 0.; );
+ } else {
+ LOOP(numSamples, ZXP(out) = 0.f; );
+ }
+}
+
+inline void ZAccum(int numSamples, float *out, float *in)
+{
+ LOOP(numSamples, ZXP(out) += ZXP(in); );
+}
+
+
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/clz.h b/sc4pd/headers/plugin_interface/clz.h
new file mode 100644
index 0000000..f205c02
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/clz.h
@@ -0,0 +1,195 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+count leading zeroes function and those that can be derived from it
+
+*/
+
+
+#ifndef _CLZ_
+#define _CLZ_
+
+#include "SC_Types.h"
+
+#ifdef __MWERKS__
+
+#define __PPC__ 1
+#define __X86__ 0
+
+// powerpc native count leading zeroes instruction:
+#define CLZ(x) ((int)__cntlzw((unsigned int)x))
+
+#elif defined(SC_WIN32) && !defined(__GCC__)
+
+static int32 CLZ( int32 arg )
+{
+ __asm{
+ bsr eax, arg
+ jnz non_zero
+ mov arg, 32
+ jmp end
+non_zero:
+ xor eax, 31
+ mov arg, eax
+end:
+ }
+ return arg;
+}
+
+#elif defined(__ppc__) || defined(__powerpc__) || defined(__PPC__)
+
+static __inline__ int32 CLZ(int32 arg) {
+ __asm__ volatile("cntlzw %0, %1" : "=r" (arg) : "r" (arg));
+ return arg;
+}
+
+#elif defined(__i386__) || defined(__x86_64__)
+static __inline__ int32 CLZ(int32 arg) {
+ if (arg) {
+ __asm__ volatile("bsrl %0, %0\nxorl $31, %0\n"
+ : "=r" (arg) : "0" (arg));
+ } else {
+ arg = 32;
+ }
+ return arg;
+}
+
+#else
+# error "clz.h: Unsupported architecture"
+#endif
+
+// count trailing zeroes
+inline int32 CTZ(int32 x)
+{
+ return 32 - CLZ(~x & (x-1));
+}
+
+// count leading ones
+inline int32 CLO(int32 x)
+{
+ return CLZ(~x);
+}
+
+// count trailing ones
+inline int32 CTO(int32 x)
+{
+ return 32 - CLZ(x & (~x-1));
+}
+
+// number of bits required to represent x.
+inline int32 NUMBITS(int32 x)
+{
+ return 32 - CLZ(x);
+}
+
+// log2 of the next power of two greater than or equal to x.
+inline int32 LOG2CEIL(int32 x)
+{
+ return 32 - CLZ(x - 1);
+}
+
+// next power of two greater than or equal to x
+inline int32 NEXTPOWEROFTWO(int32 x)
+{
+ return 1L << LOG2CEIL(x);
+}
+
+// is x a power of two
+inline bool ISPOWEROFTWO(int32 x)
+{
+ return (x & (x-1)) == 0;
+}
+
+// input a series of counting integers, outputs a series of gray codes .
+inline int32 GRAYCODE(int32 x)
+{
+ return x & (x>>1);
+}
+
+// find least significant bit
+inline int32 LSBit(int32 x)
+{
+ return x & -x;
+}
+
+// find least significant bit position
+inline int32 LSBitPos(int32 x)
+{
+ return CTZ(x & -x);
+}
+
+// find most significant bit position
+inline int32 MSBitPos(int32 x)
+{
+ return 31 - CLZ(x);
+}
+
+// find most significant bit
+inline int32 MSBit(int32 x)
+{
+ return 1L << MSBitPos(x);
+}
+
+// count number of one bits
+inline uint32 ONES(uint32 x)
+{
+ uint32 t;
+ x = x - ((x >> 1) & 0x55555555);
+ t = ((x >> 2) & 0x33333333);
+ x = (x & 0x33333333) + t;
+ x = (x + (x >> 4)) & 0x0F0F0F0F;
+ x = x + (x << 8);
+ x = x + (x << 16);
+ return x >> 24;
+}
+
+// count number of zero bits
+inline uint32 ZEROES(uint32 x)
+{
+ return ONES(~x);
+}
+
+
+// reverse bits in a word
+inline uint32 BitReverse(uint32 x)
+{
+ x = ((x & 0xAAAAAAAA) >> 1) | ((x & 0x55555555) << 1);
+ x = ((x & 0xCCCCCCCC) >> 2) | ((x & 0x33333333) << 2);
+ x = ((x & 0xF0F0F0F0) >> 4) | ((x & 0x0F0F0F0F) << 4);
+ x = ((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8);
+ return (x >> 16) | (x << 16);
+}
+
+// barrel shifts
+inline uint32 RotateRight (uint32 x, uint32 s)
+{
+ s = s & 31;
+ return (x << (32-s)) | (x >> s);
+}
+
+inline uint32 RotateLeft (uint32 x, uint32 s)
+{
+ s = s & 31;
+ return (x >> (32-s)) | (x << s);
+}
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/sc_msg_iter.h b/sc4pd/headers/plugin_interface/sc_msg_iter.h
new file mode 100644
index 0000000..240a30f
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/sc_msg_iter.h
@@ -0,0 +1,264 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _sc_msg_iter_
+#define _sc_msg_iter_
+
+#include "SC_Endian.h"
+#include "SC_Types.h"
+#include <string.h>
+
+// return the ptr to the byte after the OSC string.
+inline char* OSCstrskip(char *str)
+{
+// while (str[3]) { str += 4; }
+// return str + 4;
+ do { str += 4; } while (str[-1]);
+ return str;
+}
+
+// returns the number of bytes (including padding) for an OSC string.
+inline int OSCstrlen(char *strin)
+{
+ return OSCstrskip(strin) - strin;
+}
+
+// returns a float, converting an int if necessary
+inline float32 OSCfloat(char* inData)
+{
+ elem32* elem = (elem32*)inData;
+ elem->u = ntohl(elem->u);
+ return elem->f;
+}
+
+inline int32 OSCint(char* inData)
+{
+ return (int32)ntohl(*(uint32*)inData);
+}
+
+inline int64 OSCtime(char* inData)
+{
+ return ((int64)ntohl(*(uint32*)inData) << 32) + (ntohl(*(uint32*)(inData + 4)));
+}
+
+inline float64 OSCdouble(char* inData)
+{
+ elem64 slot;
+ slot.i = ((int64)ntohl(*(uint32*)inData) << 32) + (ntohl(*(uint32*)(inData + 4)));
+ return slot.f;
+}
+
+struct sc_msg_iter
+{
+ char *data, *rdpos, *endpos, *tags;
+ int size, count;
+
+ sc_msg_iter();
+ sc_msg_iter(int inSize, char* inData);
+ void init(int inSize, char* inData);
+ int32 geti(int32 defaultValue = 0);
+ float32 getf(float32 defaultValue = 0.f);
+ float64 getd(float64 defaultValue = 0.f);
+ char *gets(char* defaultValue = 0);
+ int32 *gets4(char* defaultValue = 0);
+ size_t getbsize();
+ void getb(char* outData, size_t inSize);
+ void skipb();
+ int remain() { return endpos - rdpos; }
+
+ char nextTag(char defaultTag = 'f') { return tags ? tags[count] : defaultTag; }
+};
+
+inline sc_msg_iter::sc_msg_iter()
+{
+}
+
+inline sc_msg_iter::sc_msg_iter(int inSize, char* inData)
+{
+ init(inSize, inData);
+}
+
+inline void sc_msg_iter::init(int inSize, char* inData)
+{
+ data = inData;
+ size = inSize;
+ endpos = data + size;
+ count = 0;
+ if (data[0] == ',') {
+ tags = data+1;
+ rdpos = OSCstrskip(data);
+ } else {
+ tags = 0;
+ rdpos = data;
+ }
+}
+
+inline int32 sc_msg_iter::geti(int32 defaultValue)
+{
+ int value;
+ if (remain() <= 0) return defaultValue;
+ if (tags) {
+ if (tags[count] == 'i') {
+ value = OSCint(rdpos);
+ rdpos += sizeof(int32);
+ } else if (tags[count] == 'f') {
+ value = (int32)OSCfloat(rdpos);
+ rdpos += sizeof(float32);
+/* } else if (tags[count] == 's') {
+ value = atoi(rdpos);
+ rdpos = OSCstrskip(rdpos);
+*/
+ } else {
+ value = defaultValue;
+ }
+ } else {
+ value = (int)OSCint(rdpos);
+ rdpos += sizeof(int32);
+ }
+ count ++;
+ return value;
+}
+
+inline float32 sc_msg_iter::getf(float32 defaultValue)
+{
+ float32 value;
+ if (remain() <= 0) return defaultValue;
+ if (tags) {
+ if (tags[count] == 'f') {
+ value = OSCfloat(rdpos);
+ rdpos += sizeof(float32);
+ } else if (tags[count] == 'd') {
+ value = (float64)OSCdouble(rdpos);
+ rdpos += sizeof(float64);
+ } else if (tags[count] == 'i') {
+ value = (float32)OSCint(rdpos);
+ rdpos += sizeof(int32);
+/* } else if (tags[count] == 's') {
+ value = atof(rdpos);
+ rdpos = OSCstrskip(rdpos);
+*/
+ } else {
+ value = defaultValue;
+ }
+ } else {
+ value = OSCfloat(rdpos);
+ rdpos += sizeof(float32);
+ }
+ count ++;
+ return value;
+}
+
+inline float64 sc_msg_iter::getd(float64 defaultValue)
+{
+ float64 value;
+ if (remain() <= 0) return defaultValue;
+ if (tags) {
+ if (tags[count] == 'f') {
+ value = (float64)OSCfloat(rdpos);
+ rdpos += sizeof(float32);
+ } else if (tags[count] == 'd') {
+ value = OSCdouble(rdpos);
+ rdpos += sizeof(float64);
+ } else if (tags[count] == 'i') {
+ value = (float64)OSCint(rdpos);
+ rdpos += sizeof(int32);
+/* } else if (tags[count] == 's') {
+ value = atof(rdpos);
+ rdpos = OSCstrskip(rdpos);
+*/
+ } else {
+ value = defaultValue;
+ }
+ } else {
+ value = OSCdouble(rdpos);
+ rdpos += sizeof(float64);
+ }
+ count ++;
+ return value;
+}
+
+
+inline char* sc_msg_iter::gets(char* defaultValue)
+{
+ char* value;
+ if (remain() <= 0) return 0;
+ if (tags) {
+ if (tags[count] == 's') {
+ value = rdpos;
+ rdpos = OSCstrskip(rdpos);
+ } else {
+ value = defaultValue;
+ }
+ } else {
+ value = rdpos;
+ rdpos = OSCstrskip(rdpos);
+ }
+ count ++;
+ return value;
+}
+
+inline int32* sc_msg_iter::gets4(char* defaultValue)
+{
+ int32* value;
+ if (remain() <= 0) return 0;
+ if (tags) {
+ if (tags[count] == 's') {
+ value = (int32*)rdpos;
+ rdpos = OSCstrskip(rdpos);
+ } else {
+ value = (int32*)defaultValue;
+ }
+ } else {
+ value = (int32*)rdpos;
+ rdpos = OSCstrskip(rdpos);
+ }
+ count ++;
+ return value;
+}
+
+inline size_t sc_msg_iter::getbsize()
+{
+ if (remain() <= 0) return 0;
+ if (tags && tags[count] != 'b') return 0;
+ return (size_t)OSCint(rdpos);
+}
+
+inline void sc_msg_iter::getb(char* outArray, size_t size)
+{
+ size_t len = OSCint(rdpos);
+ if (size < len) return;
+ rdpos += sizeof(int32);
+ size_t len4 = (len + 3) & -4;
+ memcpy(outArray, rdpos, size);
+ rdpos += len4;
+ count ++;
+}
+
+inline void sc_msg_iter::skipb()
+{
+ size_t len = OSCint(rdpos);
+ rdpos += sizeof(int32);
+ size_t len4 = (len + 3) & -4;
+ rdpos += len4;
+ count ++;
+}
+
+#endif
diff --git a/sc4pd/headers/server/HashTable.h b/sc4pd/headers/server/HashTable.h
new file mode 100644
index 0000000..85da92c
--- /dev/null
+++ b/sc4pd/headers/server/HashTable.h
@@ -0,0 +1,356 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _HashTable_
+#define _HashTable_
+
+#include "SC_Types.h"
+#include "SC_BoundsMacros.h"
+#include "SC_Str4.h"
+#include "Hash.h"
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+template<class T, class Allocator>
+class HashTable
+{
+ Allocator *mPool;
+ int32 mNumItems, mMaxItems, mTableSize, mHashMask;
+ T** mItems;
+ bool mCanResize;
+
+public:
+
+ HashTable(Allocator *inPool, int32 inMaxItems, bool inCanResize = true)
+ : mPool(inPool)
+ {
+ mNumItems = 0;
+ mMaxItems = inMaxItems;
+ mTableSize = mMaxItems << 1;
+ mItems = AllocTable(mTableSize);
+ mHashMask = mTableSize - 1;
+ mCanResize = inCanResize;
+ }
+
+ ~HashTable() {
+ mPool->Free(mItems);
+ }
+
+ int32 TableSize() const { return mTableSize; }
+ int32 MaxItems() const { return mMaxItems; }
+ int32 NumItems() const { return mNumItems; }
+
+ T** AllocTable(int inTableSize)
+ {
+ size_t size = inTableSize * sizeof(T*);
+ T** items = static_cast<T**>(mPool->Alloc(size));
+ for (int i=0; i<inTableSize; ++i) {
+ items[i] = 0;
+ }
+ return items;
+ }
+
+ void MakeEmpty()
+ {
+ for (int i=0; i<mTableSize; ++i) {
+ mItems[i] = 0;
+ }
+ mNumItems = 0;
+ }
+
+ void Resize()
+ {
+ int32 newSize = sc_max(mTableSize << 1, 32);
+ int32 oldSize = mTableSize;
+ T** oldItems = mItems;
+ mItems = AllocTable(newSize);
+ mTableSize = newSize;
+ mMaxItems = mTableSize >> 1;
+ mHashMask = mTableSize - 1;
+ mNumItems = 0;
+ for (int i=0; i<oldSize; ++i) {
+ T* item = oldItems[i];
+ if (item) Add(item);
+ }
+ mPool->Free(oldItems);
+ //printf("mMaxItems %d mTableSize %d newSize %d\n", mMaxItems, mTableSize, newSize);
+ }
+
+ bool Add(T* inItem)
+ {
+ //printf("mNumItems %d\n", mNumItems);
+ //printf("mMaxItems %d\n", mMaxItems);
+ //printf("mCanResize %d\n", mCanResize);
+ if (mNumItems >= mMaxItems) {
+ if (!mCanResize) return false;
+ Resize();
+ }
+
+ //printf("GetHash(inItem) %d\n", GetHash(inItem));
+ //printf("GetKey(inItem) %s\n", GetKey(inItem));
+ int32 index = IndexFor(GetHash(inItem), (int32*)GetKey(inItem));
+ //printf("index %d\n", index);
+
+ T *item = mItems[index];
+ if (item) return item == inItem;
+
+ mItems[index] = inItem;
+ mNumItems++;
+ return true;
+ }
+
+ bool Remove(T* inItem)
+ {
+ int32 index = IndexFor(GetHash(inItem), (int32*)GetKey(inItem));
+ if (mItems[index] != inItem) return false;
+ mItems[index] = 0;
+
+ FixCollisionsFrom(index);
+ mNumItems--;
+ return true;
+ }
+
+ bool RemoveKey(int32* inKey)
+ {
+ T* item = Get(inKey);
+ if (!item) return false;
+ return Remove(item);
+ }
+
+ int32 IndexFor(int32 inHashID, int32* inKey) const
+ {
+ int index = inHashID & mHashMask;
+ for(;;) {
+ T *item = mItems[index];
+ if (!item) return index;
+ if (GetHash(item) == inHashID && str4eq(inKey, GetKey(item))) return index;
+ index = (index + 1) & mHashMask;
+ }
+ }
+
+ T* Get(int32* inKey) const
+ {
+ return Get(Hash(inKey), inKey);
+ }
+
+ T* Get(int32 inHashID, int32* inKey) const
+ {
+ //printf("Get hash %d %s\n", inHashID, inKey);
+ int32 index = IndexFor(inHashID, inKey);
+ //printf("index %d\n", index);
+ return mItems[index];
+ }
+
+ bool Includes(T* inItem) const
+ {
+ return Get(GetHash(inItem), GetKey(inItem)) == inItem;
+ }
+
+ T* AtIndex(int32 inIndex) const
+ {
+ return mItems[inIndex];
+ }
+
+private:
+ void FixCollisionsFrom(int32 inIndex)
+ {
+ int oldIndex = inIndex;
+ for (;;) {
+ oldIndex = (oldIndex + 1) & mHashMask;
+ T *oldItem = mItems[oldIndex];
+ if (!oldItem) break;
+ int newIndex = IndexFor(GetHash(oldItem), (int32*)GetKey(oldItem));
+ if (oldIndex != newIndex) {
+ mItems[oldIndex] = mItems[newIndex];
+ mItems[newIndex] = oldItem;
+ }
+ }
+ }
+};
+
+
+template<class T, class Allocator>
+class IntHashTable
+{
+ Allocator *mPool;
+ int32 mNumItems, mMaxItems, mTableSize, mHashMask;
+ T** mItems;
+ bool mCanResize;
+
+public:
+
+ IntHashTable(Allocator *inPool, int32 inMaxItems, bool inCanResize = true)
+ : mPool(inPool)
+ {
+ mNumItems = 0;
+ mMaxItems = inMaxItems;
+ mTableSize = mMaxItems << 1;
+ mItems = AllocTable(mTableSize);
+ mHashMask = mTableSize - 1;
+ mCanResize = inCanResize;
+ }
+
+ ~IntHashTable() {
+ mPool->Free(mItems);
+ }
+
+ int32 TableSize() const { return mTableSize; }
+ int32 MaxItems() const { return mMaxItems; }
+ int32 NumItems() const { return mNumItems; }
+
+ T** AllocTable(int inTableSize)
+ {
+ size_t size = inTableSize * sizeof(T*);
+ T** items = static_cast<T**>(mPool->Alloc(size));
+ for (int i=0; i<inTableSize; ++i) {
+ items[i] = 0;
+ }
+ return items;
+ }
+
+ void Resize()
+ {
+ int32 newSize = sc_max(mTableSize << 1, 32);
+ T** oldItems = mItems;
+ mItems = AllocTable(newSize);
+ for (int i=0; i<mTableSize; ++i) {
+ T* item = oldItems[i];
+ if (item) Add(item);
+ }
+ mTableSize = newSize;
+ mMaxItems = mTableSize >> 1;
+ mHashMask = mTableSize - 1;
+ mPool->Free(oldItems);
+ //printf("mMaxItems %d mTableSize %d newSize %d\n", mMaxItems, mTableSize, newSize);
+ }
+
+ bool Add(T* inItem)
+ {
+ //printf("mNumItems %d\n", mNumItems);
+ //printf("mMaxItems %d\n", mMaxItems);
+ //printf("mCanResize %d\n", mCanResize);
+ if (mNumItems >= mMaxItems) {
+ if (!mCanResize) return false;
+ Resize();
+ }
+
+ //printf("GetHash(inItem) %d\n", GetHash(inItem));
+ //printf("GetKey(inItem) %d\n", GetKey(inItem));
+ int32 index = IndexFor(GetHash(inItem), GetKey(inItem));
+ //printf("index %d\n", index);
+
+ T *item = mItems[index];
+ if (item) return item == inItem;
+
+ mItems[index] = inItem;
+ mNumItems++;
+ return true;
+ }
+
+ bool Remove(T* inItem)
+ {
+ int32 index = IndexFor(GetHash(inItem), GetKey(inItem));
+ //printf("rmv index %d hash %d key %d\n", index, GetHash(inItem), GetKey(inItem));
+ if (mItems[index] != inItem) return false;
+ mItems[index] = 0;
+
+ FixCollisionsFrom(index);
+ mNumItems--;
+ return true;
+ }
+
+ bool RemoveKey(int32 inKey)
+ {
+ T* item = Get(inKey);
+ if (!item) return false;
+ return Remove(item);
+ }
+
+ int32 IndexFor(int32 inHashID, int32 inKey) const
+ {
+ int index = inHashID & mHashMask;
+ for(;;) {
+ T *item = mItems[index];
+ if (!item) return index;
+ if (GetHash(item) == inHashID && inKey == GetKey(item)) return index;
+ index = (index + 1) & mHashMask;
+ }
+ }
+
+ T* Get(int32 inKey) const
+ {
+ //printf("Get key %d\n", inKey);
+ return Get(Hash(inKey), inKey);
+ }
+
+ T* Get(int32 inHashID, int32 inKey) const
+ {
+ int32 index = IndexFor(inHashID, inKey);
+ //printf("Get index %d hash %d key %d\n", index, inHashID, inKey);
+ return mItems[index];
+ }
+
+ bool Includes(T* inItem) const
+ {
+ return Get(GetHash(inItem), GetKey(inItem)) == inItem;
+ }
+
+ T* AtIndex(int32 inIndex) const
+ {
+ return mItems[inIndex];
+ }
+
+ void Dump()
+ {
+ for (int i=0; i<mTableSize; ++i) {
+ T* item = mItems[i];
+ if (item) {
+ printf("%4d %4d %08X %08X\n", i, GetKey(item), GetHash(item), item);
+ }
+ }
+ }
+
+private:
+ void FixCollisionsFrom(int32 inIndex)
+ {
+ //printf("FixCollisionsFrom %d\n", inIndex);
+ int oldIndex = inIndex;
+ for (;;) {
+ oldIndex = (oldIndex + 1) & mHashMask;
+ T *oldItem = mItems[oldIndex];
+ if (!oldItem) break;
+ int newIndex = IndexFor(GetHash(oldItem), GetKey(oldItem));
+ if (oldIndex != newIndex) {
+ //printf("swap %d %d\n", oldIndex, newIndex);
+ mItems[oldIndex] = mItems[newIndex];
+ mItems[newIndex] = oldItem;
+ }
+ }
+ }
+};
+
+struct Malloc
+{
+ void Free(void* ptr) { free(ptr); }
+ void* Alloc(size_t size) { return malloc(size); }
+};
+
+#endif
diff --git a/sc4pd/headers/server/IntFifo.h b/sc4pd/headers/server/IntFifo.h
new file mode 100644
index 0000000..3dde5ec
--- /dev/null
+++ b/sc4pd/headers/server/IntFifo.h
@@ -0,0 +1,87 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _IntFifo_
+#define _IntFifo_
+
+#ifdef SC_DARWIN
+# include <CoreServices/CoreServices.h>
+#endif
+
+template <int N>
+class IntFifo
+{
+public:
+ IntFifo()
+ : mMask(N - 1), mReadHead(0), mWriteHead(0)
+ {}
+
+ void MakeEmpty() { mReadHead = mWriteHead; }
+ bool IsEmpty() { return mReadHead == mWriteHead; }
+ bool HasData() { return mReadHead != mWriteHead; }
+
+ bool Put(int data)
+ {
+ long next = NextPos(mWriteHead);
+ if (next == mReadHead) return false; // fifo is full
+ mItems[next] = data;
+#ifdef SC_DARWIN
+ // we don't really need a compare and swap, but this happens to call
+ // the PowerPC memory barrier instruction lwsync.
+ CompareAndSwap(mWriteHead, next, &mWriteHead);
+#elif defined SC_WIN32
+ InterlockedExchange(reinterpret_cast<volatile LONG*>(&mWriteHead),next);
+#else
+ mWriteHead = next;
+#endif
+ return true;
+ }
+
+ int32 Get()
+ {
+ //assert(HasData());
+ long next = NextPos(mReadHead);
+ out = mItems[next].Perform();
+#ifdef SC_DARWIN
+ // we don't really need a compare and swap, but this happens to call
+ // the PowerPC memory barrier instruction lwsync.
+ CompareAndSwap(mReadHead, next, &mReadHead);
+#elif defined SC_WIN32
+ InterlockedExchange(reinterpret_cast<volatile LONG*>(&mReadHead),next);
+#else
+ mReadHead = next;
+#endif
+ }
+
+private:
+ int NextPos(int inPos) { return (inPos + 1) & mMask; }
+
+ long mMask;
+#ifdef SC_DARWIN
+ UInt32 mReadHead, mWriteHead;
+#else
+ volatile int mReadHead, mWriteHead;
+#endif
+ int32 mItems[N];
+};
+
+#endif
+
+
diff --git a/sc4pd/headers/server/MsgFifo.h b/sc4pd/headers/server/MsgFifo.h
new file mode 100644
index 0000000..cdc8578
--- /dev/null
+++ b/sc4pd/headers/server/MsgFifo.h
@@ -0,0 +1,169 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _MsgFifo_
+#define _MsgFifo_
+
+#ifdef SC_DARWIN
+# include <CoreServices/CoreServices.h>
+#endif
+
+/////////////////////////////////////////////////////////////////////
+
+template <class MsgType, int N>
+class MsgFifo
+{
+public:
+ MsgFifo()
+ : mReadHead(0), mWriteHead(0), mFreeHead(0)
+ {}
+
+ void MakeEmpty() { mFreeHead = mReadHead = mWriteHead; }
+ bool IsEmpty() { return mReadHead == mWriteHead; }
+ bool HasData() { return mReadHead != mWriteHead; }
+ bool NeedsFree() { return mFreeHead != mReadHead; }
+
+ bool Write(MsgType& data)
+ {
+ unsigned int next = NextPos(mWriteHead);
+ if (next == mFreeHead) return false; // fifo is full
+ mItems[next] = data;
+#ifdef SC_DARWIN
+ // we don't really need a compare and swap, but this happens to call
+ // the PowerPC memory barrier instruction lwsync.
+ CompareAndSwap(mWriteHead, next, &mWriteHead);
+#elif defined SC_WIN32
+ InterlockedExchange(reinterpret_cast<volatile LONG*>(&mWriteHead),next);
+#else
+ mWriteHead = next;
+#endif
+ return true;
+ }
+
+ void Perform() // get next and advance
+ {
+ while (HasData()) {
+ unsigned int next = NextPos(mReadHead);
+ mItems[next].Perform();
+#ifdef SC_DARWIN
+ // we don't really need a compare and swap, but this happens to call
+ // the PowerPC memory barrier instruction lwsync.
+ CompareAndSwap(mReadHead, next, &mReadHead);
+#elif defined SC_WIN32
+ InterlockedExchange(reinterpret_cast<volatile LONG*>(&mReadHead),next);
+#else
+ mReadHead = next;
+#endif
+ }
+ }
+ void Free() // reclaim messages
+ {
+ while (NeedsFree()) {
+ unsigned int next = NextPos(mFreeHead);
+ mItems[next].Free();
+#ifdef SC_DARWIN
+ // we don't really need a compare and swap, but this happens to call
+ // the PowerPC memory barrier instruction lwsync.
+ CompareAndSwap(mFreeHead, next, &mFreeHead);
+#elif defined SC_WIN32
+ InterlockedExchange(reinterpret_cast<volatile LONG*>(&mFreeHead),next);
+#else
+ mFreeHead = next;
+#endif
+ }
+ }
+
+private:
+ int NextPos(int inPos) { return (inPos + 1) & (N - 1); }
+
+#ifdef SC_DARWIN
+ UInt32 mReadHead, mWriteHead, mFreeHead;
+#else
+ volatile unsigned int mReadHead, mWriteHead, mFreeHead;
+#endif
+ MsgType mItems[N];
+};
+
+/////////////////////////////////////////////////////////////////////
+
+template <class MsgType, int N>
+class MsgFifoNoFree
+{
+public:
+ MsgFifoNoFree()
+ : mReadHead(0), mWriteHead(0)
+ {
+ }
+
+ void MakeEmpty() { mReadHead = mWriteHead; }
+ bool IsEmpty() { return mReadHead == mWriteHead; }
+ bool HasData() { return mReadHead != mWriteHead; }
+
+ bool Write(MsgType& data)
+ {
+ unsigned int next = NextPos(mWriteHead);
+ if (next == mReadHead) return false; // fifo is full
+ mItems[next] = data;
+#ifdef SC_DARWIN
+ // we don't really need a compare and swap, but this happens to call
+ // the PowerPC memory barrier instruction lwsync.
+ CompareAndSwap(mWriteHead, next, &mWriteHead);
+#elif defined SC_WIN32
+ InterlockedExchange(reinterpret_cast<volatile LONG*>(&mWriteHead),next);
+#else
+ mWriteHead = next;
+#endif
+ return true;
+ }
+
+ void Perform() // get next and advance
+ {
+ while (HasData()) {
+ unsigned int next = NextPos(mReadHead);
+ mItems[next].Perform();
+#ifdef SC_DARWIN
+ // we don't really need a compare and swap, but this happens to call
+ // the PowerPC memory barrier instruction lwsync.
+ CompareAndSwap(mReadHead, next, &mReadHead);
+#elif defined SC_WIN32
+ InterlockedExchange(reinterpret_cast<volatile LONG*>(&mReadHead),next);
+#else
+ mReadHead = next;
+#endif
+ }
+ }
+
+private:
+ int NextPos(int inPos) { return (inPos + 1) & (N - 1); }
+
+#ifdef SC_DARWIN
+ UInt32 mReadHead, mWriteHead;
+#else
+ volatile unsigned int mReadHead, mWriteHead;
+#endif
+ MsgType mItems[N];
+};
+
+/////////////////////////////////////////////////////////////////////
+
+
+#endif
+
+
diff --git a/sc4pd/headers/server/OSC_Packet.h b/sc4pd/headers/server/OSC_Packet.h
new file mode 100644
index 0000000..5964e81
--- /dev/null
+++ b/sc4pd/headers/server/OSC_Packet.h
@@ -0,0 +1,43 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+ * OSC_Packet.h
+ * SC3synth
+ *
+ * Created by James McCartney on Sat Aug 24 2002.
+ * Copyright (c) 2001 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#ifndef _OSC_Packet_
+#define _OSC_Packet_
+
+#include "SC_Reply.h"
+
+struct OSC_Packet
+{
+ char *mData;
+ int32 mSize;
+ bool mIsBundle;
+
+ ReplyAddress mReplyAddr;
+};
+
+#endif
diff --git a/sc4pd/headers/server/PriorityQueue.h b/sc4pd/headers/server/PriorityQueue.h
new file mode 100644
index 0000000..eb1064f
--- /dev/null
+++ b/sc4pd/headers/server/PriorityQueue.h
@@ -0,0 +1,123 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PriorityQueue_
+#define _PriorityQueue_
+
+#include <stdio.h>
+#include <math.h>
+#include <stdexcept>
+
+#define SANITYCHECK 0
+
+#ifdef SC_WIN32
+const int64 kMaxInt64 = 0x7FFFFFFFFFFFFFFF;
+#else
+const int64 kMaxInt64 = ~(1LL<<63);
+#endif
+
+template <class Event, int N>
+class PriorityQueueT
+{
+public:
+ PriorityQueueT() {
+ Empty();
+ }
+
+ bool Add(Event& inEvent)
+ {
+ if (mSize >= N) return false;
+ long mom = mSize++;
+ long me = mom;
+ for (; mom>0;) { /* percolate up heap */
+ mom = mom - 1 >> 1;
+ if (inEvent.mTime < mEvents[mom].mTime) {
+ mEvents[me] = mEvents[mom];
+ me = mom;
+ } else break;
+ }
+ mEvents[me] = inEvent;
+#if SANITYCHECK
+ SanityCheck();
+#endif
+ return true;
+ }
+ void Perform(int64 inTime)
+ {
+ while (NextTime() <= inTime) {
+ Event event = Remove();
+ event.Perform();
+ }
+ }
+ int64 NextTime() { return mEvents[0].mTime; }
+ bool Ready(int64 inTime) { return NextTime() <= inTime; }
+ void Flush() { Perform(kMaxInt64); }
+ void Empty() { mSize = 0; SetEmptyTime(); }
+ void SetEmptyTime() { mEvents[0].mTime = kMaxInt64; }
+ int Size() { return mSize; }
+
+ Event Remove()
+ {
+ Event event = mEvents[0];
+ if (--mSize == 0) SetEmptyTime();
+ else {
+ Event temp = mEvents[mSize];
+ long mom = 0;
+ long me = 1;
+ for (;me < mSize;) { /* demote heap */
+ if (me+1 < mSize && mEvents[me].mTime > mEvents[me+1].mTime) {
+ me ++;
+ }
+ if (temp.mTime > mEvents[me].mTime) {
+ mEvents[mom] = mEvents[me];
+ mom = me;
+ me = (me << 1) + 1;
+ } else break;
+ }
+ mEvents[mom] = temp;
+ }
+#if SANITYCHECK
+ SanityCheck();
+#endif
+ return event;
+ }
+ void SanityCheck()
+ {
+ for (int i=0; i<mSize; ++i)
+ {
+ int j = (i<<1)+1;
+ int k = j+1;
+ //if (j<mSize && mEvents[i].mTime > mEvents[j].mTime) throw std::runtime_error("priority queue unsorted");
+ //if (k<mSize && mEvents[i].mTime > mEvents[k].mTime) throw std::runtime_error("priority queue unsorted");
+ }
+ }
+ void DebugDump()
+ {
+ for (int i=0; i<mSize; ++i)
+ {
+ printf("%d %016llX\n", i, mEvents[i].mTime);
+ }
+ }
+private:
+ int mSize;
+ Event mEvents[N];
+};
+
+#endif
diff --git a/sc4pd/headers/server/ReadWriteMacros.h b/sc4pd/headers/server/ReadWriteMacros.h
new file mode 100644
index 0000000..a1bd226
--- /dev/null
+++ b/sc4pd/headers/server/ReadWriteMacros.h
@@ -0,0 +1,430 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _ReadWriteMacros_
+#define _ReadWriteMacros_
+
+#include "SC_Types.h"
+#include <stdio.h>
+#include <string.h>
+
+inline void writeData(char *&buf, char *data, int size)
+{
+ memcpy(buf, data, size);
+ buf += size;
+}
+
+inline void writeZero(char *&buf, int len)
+{
+ for (int i=0; i<len; ++i) *buf++ = 0;
+}
+
+inline void writeSkip(char *&buf, int len)
+{
+ buf += len;
+}
+
+inline void writeInt8(char *&buf, int8 inInt)
+{
+ *buf++ = (char)(inInt & 255);
+}
+
+inline void writeUInt8(char *&buf, uint8 inInt)
+{
+ *buf++ = (char)(inInt & 255);
+}
+
+inline void writeInt16_be(char *&buf, int16 inInt)
+{
+ *buf++ = (char)((inInt >> 8) & 255);
+ *buf++ = (char)(inInt & 255);
+}
+
+inline void writeInt16_le(char *&buf, int16 inInt)
+{
+ *buf++ = (char)(inInt & 255);
+ *buf++ = (char)((inInt >> 8) & 255);
+}
+
+inline void writeInt32_be(char *&buf, int32 inInt)
+{
+ *buf++ = (char)((inInt >> 24) & 255);
+ *buf++ = (char)((inInt >> 16) & 255);
+ *buf++ = (char)((inInt >> 8) & 255);
+ *buf++ = (char)(inInt & 255);
+}
+
+inline void writeInt32_le(char *&buf, int32 inInt)
+{
+ *buf++ = (char)(inInt & 255);
+ *buf++ = (char)((inInt >> 8) & 255);
+ *buf++ = (char)((inInt >> 16) & 255);
+ *buf++ = (char)((inInt >> 24) & 255);
+}
+
+inline void writeSymbol(char *&buf, char *inString)
+{
+ size_t length = strlen(inString);
+ writeUInt8(buf, (uint8)length);
+ memcpy(buf, inString, length);
+ buf += length;
+}
+
+inline void writeString(char *&buf, char *inString, size_t inLength)
+{
+ writeInt32_be(buf, inLength);
+ memcpy(buf, inString, inLength);
+ buf += inLength;
+}
+
+inline void writeString(char *&buf, char *inString)
+{
+ size_t length = strlen(inString);
+ writeString(buf, inString, length);
+}
+
+
+
+inline void writeData(FILE *file, char *data, size_t size)
+{
+ fwrite(data, 1, size, file);
+}
+
+inline void writeInt8(FILE *file, int8 inInt)
+{
+ fputc(inInt & 255, file);
+}
+
+inline void writeUInt8(FILE *file, uint8 inInt)
+{
+ fputc(inInt & 255, file);
+}
+
+inline void writeInt16_be(FILE *file, int16 inInt)
+{
+ fputc((inInt >> 8) & 255, file);
+ fputc(inInt & 255, file);
+}
+
+inline void writeInt16_le(FILE *file, int16 inInt)
+{
+ fputc(inInt & 255, file);
+ fputc((inInt >> 8) & 255, file);
+}
+
+inline void writeInt32_be(FILE *file, int32 inInt)
+{
+ fputc((inInt >> 24) & 255, file);
+ fputc((inInt >> 16) & 255, file);
+ fputc((inInt >> 8) & 255, file);
+ fputc(inInt & 255, file);
+}
+
+inline void writeInt64_be(FILE *file, int64 inInt)
+{
+ writeInt32_be(file, (int32)((inInt >> 32) & 0x00000000FFFFFFFF));
+ writeInt32_be(file, (int32)(inInt));
+}
+
+inline void writeInt32_le(FILE *file, int32 inInt)
+{
+ fputc(inInt & 255, file);
+ fputc((inInt >> 8) & 255, file);
+ fputc((inInt >> 16) & 255, file);
+ fputc((inInt >> 24) & 255, file);
+}
+
+inline void writeFloat_be(FILE *file, float inFloat)
+{
+ union {
+ float f;
+ int32 i;
+ } u;
+ u.f = inFloat;
+ writeInt32_be(file, u.i);
+}
+
+inline void writeFloat_le(FILE *file, float inFloat)
+{
+ union {
+ float f;
+ int32 i;
+ } u;
+ u.f = inFloat;
+ writeInt32_le(file, u.i);
+}
+
+inline void writeSymbol(FILE *file, char *inString)
+{
+ size_t length = strlen(inString);
+ writeUInt8(file, (uint8)length);
+ fwrite(inString, 1, length, file);
+}
+
+inline void writeString(FILE *file, char *inString, size_t inLength)
+{
+ writeInt32_be(file, inLength);
+ fwrite(inString, 1, inLength, file);
+}
+
+inline void writeString(FILE *file, char *inString)
+{
+ size_t length = strlen(inString);
+ writeString(file, inString, length);
+}
+
+inline int32 readInt8(FILE *file)
+{
+ int32 res = fgetc(file);
+
+ return res;
+}
+
+inline uint32 readUInt8(FILE *file)
+{
+ uint32 res = (uint32)fgetc(file);
+ return res;
+}
+
+inline int32 readInt16_be(FILE *file)
+{
+ int32 c = fgetc(file);
+ int32 d = fgetc(file);
+
+ int32 res = ((c & 255) << 8) | (d & 255);
+ return res;
+}
+
+inline int32 readInt16_le(FILE *file)
+{
+ int32 c = fgetc(file);
+ int32 d = fgetc(file);
+
+ int32 res = ((d & 255) << 8) | (c & 255);
+ return res;
+}
+
+inline int32 readInt32_be(FILE *file)
+{
+ int32 a = fgetc(file);
+ int32 b = fgetc(file);
+ int32 c = fgetc(file);
+ int32 d = fgetc(file);
+
+ int32 res = ((a & 255) << 24) | ((b & 255) << 16) | ((c & 255) << 8) | (d & 255);
+ return res;
+}
+
+inline int32 readInt32_le(FILE *file)
+{
+ int32 a = fgetc(file);
+ int32 b = fgetc(file);
+ int32 c = fgetc(file);
+ int32 d = fgetc(file);
+
+ int32 res = ((d & 255) << 24) | ((c & 255) << 16) | ((b & 255) << 8) | (a & 255);
+ return res;
+}
+
+inline int64 readInt64_be(FILE *file)
+{
+ int64 hi = readInt32_be(file);
+ int64 lo = readInt32_be(file);
+ return (hi << 32) | (lo & 0x00000000FFFFFFFF);
+}
+
+inline float readFloat_be(FILE *file)
+{
+ union {
+ float f;
+ int32 i;
+ } u;
+ u.i = readInt32_be(file);
+ //post("readFloat %g\n", u.f);
+ return u.f;
+}
+
+inline float readFloat_le(FILE *file)
+{
+ union {
+ float f;
+ int32 i;
+ } u;
+ u.i = readInt32_le(file);
+ //post("readFloat %g\n", u.f);
+ return u.f;
+}
+
+inline void readString(FILE *file, char *outString, size_t inLength)
+{
+ fread(outString, 1, inLength, file);
+ outString[inLength] = 0;
+}
+
+inline void readSymbol(FILE *file, char *outString)
+{
+ size_t length = (size_t)readUInt8(file);
+ readString(file, outString, length);
+}
+
+inline void readData(FILE *file, char *outData, size_t inLength)
+{
+ fread(outData, 1, inLength, file);
+}
+
+
+inline int32 readInt8(char *&buf)
+{
+ int32 res = *buf++;
+ return res;
+}
+
+inline uint32 readUInt8(char *&buf)
+{
+ uint32 res = *buf++;
+ return res;
+}
+
+inline int32 readInt16_be(char *&buf)
+{
+ int32 c = readInt8(buf);
+ int32 d = readInt8(buf);
+
+ int32 res = ((c & 255) << 8) | (d & 255);
+ return res;
+}
+
+inline int32 readInt16_le(char *&buf)
+{
+ int32 c = readInt8(buf);
+ int32 d = readInt8(buf);
+
+ int32 res = ((d & 255) << 8) | (c & 255);
+ return res;
+}
+
+
+inline int32 readInt32_be(char *&buf)
+{
+ int32 a = readInt8(buf);
+ int32 b = readInt8(buf);
+ int32 c = readInt8(buf);
+ int32 d = readInt8(buf);
+
+ int32 res = ((a & 255) << 24) | ((b & 255) << 16) | ((c & 255) << 8) | (d & 255);
+ return res;
+}
+
+inline int32 readInt32_le(char *&buf)
+{
+ int32 a = readInt8(buf);
+ int32 b = readInt8(buf);
+ int32 c = readInt8(buf);
+ int32 d = readInt8(buf);
+
+ int32 res = ((d & 255) << 24) | ((c & 255) << 16) | ((b & 255) << 8) | (a & 255);
+ return res;
+}
+
+inline float readFloat_be(char *&buf)
+{
+ union {
+ float f;
+ int32 i;
+ } u;
+ u.i = readInt32_be(buf);
+ //post("readFloat %g\n", u.f);
+ return u.f;
+}
+
+inline float readFloat_le(char *&buf)
+{
+ union {
+ float f;
+ int32 i;
+ } u;
+ u.i = readInt32_le(buf);
+ //post("readFloat %g\n", u.f);
+ return u.f;
+}
+
+inline double readDouble_be(char *&buf)
+{
+ //post("readDouble\n");
+ union {
+ double f;
+ uint8 c[8];
+ } u;
+
+ u.c[0] = (uint8)readInt8(buf);
+ u.c[1] = (uint8)readInt8(buf);
+ u.c[2] = (uint8)readInt8(buf);
+ u.c[3] = (uint8)readInt8(buf);
+ u.c[4] = (uint8)readInt8(buf);
+ u.c[5] = (uint8)readInt8(buf);
+ u.c[6] = (uint8)readInt8(buf);
+ u.c[7] = (uint8)readInt8(buf);
+ //post("readDouble %g %08X %08X\n", u.f, u.f);
+ return u.f;
+}
+
+inline double readDouble_le(char *&buf)
+{
+ //post("readDouble\n");
+ union {
+ double f;
+ uint8 c[8];
+ } u;
+
+ u.c[7] = (uint8)readInt8(buf);
+ u.c[6] = (uint8)readInt8(buf);
+ u.c[5] = (uint8)readInt8(buf);
+ u.c[4] = (uint8)readInt8(buf);
+ u.c[3] = (uint8)readInt8(buf);
+ u.c[2] = (uint8)readInt8(buf);
+ u.c[1] = (uint8)readInt8(buf);
+ u.c[0] = (uint8)readInt8(buf);
+
+ //post("readDouble %g\n", u.f);
+ return u.f;
+}
+
+inline void readString(char *&buf, char *outString, size_t inLength)
+{
+ memcpy(outString, buf, inLength);
+ outString[inLength] = 0;
+ buf += inLength;
+}
+
+inline void readSymbol(char *&buf, char *outString)
+{
+ size_t length = (size_t)readUInt8(buf);
+ readString(buf, outString, length);
+}
+
+inline void readData(char *&buf, char *outData, size_t inLength)
+{
+ memcpy(outData, buf, inLength);
+ buf += inLength;
+}
+
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/server/Rendezvous.h b/sc4pd/headers/server/Rendezvous.h
new file mode 100644
index 0000000..2067cd2
--- /dev/null
+++ b/sc4pd/headers/server/Rendezvous.h
@@ -0,0 +1,41 @@
+/*
+ * Rendezvous.h
+ * SC3synth
+ *
+ * Created by C. Ramakrishnan on Wed Dec 18 2002.
+ * Illposed Software
+ *
+ */
+
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _Rendezvous_
+#define _Rendezvous_
+
+typedef enum {
+ kSCRendezvous_UDP,
+ kSCRendezvous_TCP
+} SCRendezvousProtocol;
+
+void PublishPortToRendezvous(SCRendezvousProtocol protocol, short portNum);
+
+#endif
+
diff --git a/sc4pd/headers/server/SC_ComPort.h b/sc4pd/headers/server/SC_ComPort.h
new file mode 100644
index 0000000..3674fd5
--- /dev/null
+++ b/sc4pd/headers/server/SC_ComPort.h
@@ -0,0 +1,144 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_ComPort_
+#define _SC_ComPort_
+
+#if defined (__APPLE__) && defined (__GNUC__)
+#define USE_RENDEZVOUS
+#endif
+
+#include <sys/types.h>
+#ifdef SC_WIN32
+# include <winsock2.h>
+#else
+# include <sys/socket.h>
+#endif
+#include "OSC_Packet.h"
+#include "SC_Sem.h"
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_CmdPort
+{
+protected:
+ pthread_t mThread;
+ struct World *mWorld;
+
+ void Start();
+ virtual ReplyFunc GetReplyFunc()=0;
+public:
+ SC_CmdPort(struct World *inWorld);
+
+ virtual void* Run()=0;
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_ComPort : public SC_CmdPort
+{
+protected:
+ int mPortNum;
+ int mSocket;
+ struct sockaddr_in mBindSockAddr;
+
+#ifdef USE_RENDEZVOUS
+ pthread_t mRendezvousThread;
+#endif
+
+public:
+ SC_ComPort(struct World *inWorld, int inPortNum);
+ virtual ~SC_ComPort();
+
+ int Socket() { return mSocket; }
+
+ int PortNum() const { return mPortNum; }
+#ifdef USE_RENDEZVOUS
+ // default implementation does nothing (this is correct for
+ // SC_TcpConnectionPort). Subclasses may override.
+ virtual void PublishToRendezvous() { };
+#endif
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_UdpInPort : public SC_ComPort
+{
+protected:
+ struct sockaddr_in mReplySockAddr;
+ virtual ReplyFunc GetReplyFunc();
+
+public:
+ SC_UdpInPort(struct World *inWorld, int inPortNum);
+ ~SC_UdpInPort();
+
+ int PortNum() const { return mPortNum; }
+
+ void* Run();
+#ifdef USE_RENDEZVOUS
+ virtual void PublishToRendezvous();
+#endif
+
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_TcpInPort : public SC_ComPort
+{
+ SC_Semaphore mConnectionAvailable;
+ int mBacklog;
+
+protected:
+ virtual ReplyFunc GetReplyFunc();
+
+public:
+ SC_TcpInPort(struct World *inWorld, int inPortNum, int inMaxConnections, int inBacklog);
+
+ virtual void* Run();
+
+ void ConnectionTerminated();
+#ifdef USE_RENDEZVOUS
+ virtual void PublishToRendezvous();
+#endif
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_TcpConnectionPort : public SC_ComPort
+{
+ SC_TcpInPort *mParent;
+
+protected:
+ virtual ReplyFunc GetReplyFunc();
+
+public:
+ SC_TcpConnectionPort(struct World *inWorld, SC_TcpInPort *inParent, int inSocket);
+ virtual ~SC_TcpConnectionPort();
+
+ virtual void* Run();
+};
+
+const int kPacketBufSize = 8192; // this seems to be the maximum size of a UDP packet
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/sc4pd/headers/server/SC_Complex.h b/sc4pd/headers/server/SC_Complex.h
new file mode 100644
index 0000000..d4aed20
--- /dev/null
+++ b/sc4pd/headers/server/SC_Complex.h
@@ -0,0 +1,142 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Complex_
+#define _SC_Complex_
+
+#include "SC_Types.h"
+#include "float.h"
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct Polar;
+
+struct Complex
+{
+ Complex() {}
+ Complex(float r, float i) : real(r), imag(i) {}
+ void Set(float r, float i) { real = r; imag = i; }
+
+ Complex& operator=(Complex b) { real = b.real; imag = b.imag; return *this; }
+ Complex& operator=(float b) { real = b; imag = 0.; return *this; }
+
+ Polar ToPolar();
+ Polar ToPolarApx();
+
+ void ToPolarInPlace();
+ void ToPolarApxInPlace();
+
+ float real, imag;
+};
+
+struct Polar
+{
+ Polar() {}
+ Polar(float m, float p) : mag(m), phase(p) {}
+ void Set(float m, float p) { mag = m; phase = p; }
+
+ Complex ToComplex();
+ Complex ToComplexApx();
+
+ void ToComplexInPlace();
+ void ToComplexApxInPlace();
+
+ float mag, phase;
+};
+
+struct ComplexFT
+{
+ float dc, nyq;
+ Complex complex[1];
+};
+
+struct PolarFT
+{
+ float dc, nyq;
+ Polar polar[1];
+};
+
+void ToComplex(Polar in, Complex& out);
+
+inline Complex operator+(Complex a, Complex b) { return Complex(a.real + b.real, a.imag + b.imag); }
+inline Complex operator+(Complex a, float b) { return Complex(a.real + b, a.imag); }
+inline Complex operator+(float a, Complex b) { return Complex(a + b.real, b.imag); }
+
+inline Complex& operator+=(Complex& a, const Complex& b) { a.real += b.real, a.imag += b.imag; return a; }
+inline Complex& operator+=(Complex& a, float b) { a.real += b; return a; }
+
+inline Complex operator-(Complex a, Complex b) { return Complex(a.real - b.real, a.imag - b.imag); }
+inline Complex operator-(Complex a, float b) { return Complex(a.real - b, a.imag); }
+inline Complex operator-(float a, Complex b) { return Complex(a - b.real, b.imag); }
+
+inline Complex operator-=(Complex a, Complex b) { a.real -= b.real, a.imag -= b.imag; return a; }
+inline Complex operator-=(Complex a, float b) { a.real -= b; return a; }
+
+inline Complex operator*(Complex a, Complex b)
+{
+ return Complex(a.real * b.real - a.imag * b.imag, a.real * b.imag + a.imag * b.real);
+}
+
+inline Complex operator*(Complex a, float b)
+{
+ return Complex(a.real * b, a.imag * b);
+}
+
+inline Complex operator*(float a, Complex b)
+{
+ return Complex(b.real * a, b.imag * a);
+}
+
+inline Complex operator*=(Complex a, Complex b)
+{
+ a.Set(
+ a.real * b.real - a.imag * b.imag,
+ a.real * b.imag + a.imag * b.real
+ );
+ return a;
+}
+
+inline Complex operator*=(Complex a, float b)
+{
+ a.real *= b;
+ a.imag *= b;
+ return a;
+}
+
+
+inline Polar operator*(Polar a, float b)
+{
+ return Polar(a.mag * b, a.phase);
+}
+
+inline Polar operator*(float a, Polar b)
+{
+ return Polar(a * b.mag, b.phase);
+}
+
+inline Polar operator*=(Polar a, float b)
+{
+ a.mag *= b;
+ return a;
+}
+
+
+#endif
diff --git a/sc4pd/headers/server/SC_CoreAudio.h b/sc4pd/headers/server/SC_CoreAudio.h
new file mode 100644
index 0000000..fba5184
--- /dev/null
+++ b/sc4pd/headers/server/SC_CoreAudio.h
@@ -0,0 +1,263 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_CoreAudio_
+#define _SC_CoreAudio_
+
+#include "MsgFifo.h"
+#include "SC_FifoMsg.h"
+#include "OSC_Packet.h"
+#include "SC_SyncCondition.h"
+#include "PriorityQueue.h"
+#include "SC_Lock.h"
+
+#define SC_AUDIO_API_COREAUDIO 1
+#define SC_AUDIO_API_JACK 2
+#define SC_AUDIO_API_PORTAUDIO 3
+
+#ifdef SC_WIN32
+# define SC_AUDIO_API SC_AUDIO_API_PORTAUDIO
+#endif
+
+#ifndef SC_AUDIO_API
+# define SC_AUDIO_API SC_AUDIO_API_COREAUDIO
+#endif // SC_AUDIO_API
+
+#if SC_AUDIO_API == SC_AUDIO_API_COREAUDIO
+# include <CoreAudio/AudioHardware.h>
+# include <CoreAudio/HostTime.h>
+#endif
+
+#if SC_AUDIO_API == SC_AUDIO_API_JACK
+# include <jack/jack.h>
+class SC_JackPortList;
+#endif
+
+#if SC_AUDIO_API == SC_AUDIO_API_PORTAUDIO
+#include "portaudio.h"
+#endif
+
+
+struct SC_ScheduledEvent
+{
+ SC_ScheduledEvent() : mTime(0), mPacket(0) {}
+ SC_ScheduledEvent(struct World *inWorld, int64 inTime, OSC_Packet *inPacket)
+ : mTime(inTime), mPacket(inPacket), mWorld(inWorld) {}
+
+ int64 Time() { return mTime; }
+ void Perform();
+
+ int64 mTime;
+ OSC_Packet *mPacket;
+ struct World *mWorld;
+};
+
+typedef MsgFifo<FifoMsg, 1024> EngineFifo;
+
+
+class SC_AudioDriver
+{
+protected:
+ int64 mOSCincrement;
+ struct World *mWorld;
+ double mOSCtoSamples;
+ int mSampleTime;
+
+ // Common members
+ uint32 mHardwareBufferSize; // bufferSize returned by kAudioDevicePropertyBufferSize
+ EngineFifo mFromEngine, mToEngine;
+ SC_SyncCondition mAudioSync;
+ pthread_t mThread;
+ bool mRunThreadFlag;
+ uint32 mSafetyOffset;
+ PriorityQueueT<SC_ScheduledEvent, 2048> mScheduler;
+ SC_Lock *mProcessPacketLock;
+ int mNumSamplesPerCallback;
+ uint32 mPreferredHardwareBufferFrameSize;
+ uint32 mPreferredSampleRate;
+ double mBuffersPerSecond;
+ double mAvgCPU, mPeakCPU;
+ int mPeakCounter, mMaxPeakCounter;
+ double mOSCincrementNumerator;
+
+ double mStartHostSecs;
+ double mPrevHostSecs;
+ double mStartSampleTime;
+ double mPrevSampleTime;
+ double mSmoothSampleRate;
+ double mSampleRate;
+
+ // Driver interface methods, implemented by subclasses
+ virtual bool DriverSetup(int* outNumSamplesPerCallback, double* outSampleRate) = 0;
+ virtual bool DriverStart() = 0;
+ virtual bool DriverStop() = 0;
+
+public:
+ // Common methods
+ SC_AudioDriver(struct World *inWorld);
+ virtual ~SC_AudioDriver();
+
+ int64 mOSCbuftime;
+
+ bool Setup();
+ bool Start();
+ bool Stop();
+
+ void ClearSched() { mScheduler.Empty(); }
+
+ void Lock() { mProcessPacketLock->Lock(); }
+ void Unlock() { mProcessPacketLock->Unlock(); }
+
+ void RunNonRealTime(float *in, float *out, int numSamples, int64 oscTime);
+ void* RunThread();
+
+ int SafetyOffset() const { return mSafetyOffset; }
+ int NumSamplesPerCallback() const { return mNumSamplesPerCallback; }
+ void SetPreferredHardwareBufferFrameSize(int inSize)
+ {
+ mPreferredHardwareBufferFrameSize = inSize;
+ }
+ void SetPreferredSampleRate(int inRate)
+ {
+ mPreferredSampleRate = inRate;
+ }
+
+ bool SendMsgToEngine(FifoMsg& inMsg);
+ bool SendMsgFromEngine(FifoMsg& inMsg);
+
+ void AddEvent(SC_ScheduledEvent& event) { mScheduler.Add(event); }
+
+ double GetAvgCPU() const { return mAvgCPU; }
+ double GetPeakCPU() const { return mPeakCPU; }
+ double GetSampleRate() const { return mSampleRate; }
+ double GetActualSampleRate() const { return mSmoothSampleRate; }
+};
+
+
+// the following classes should be split out into separate source files.
+#if SC_AUDIO_API == SC_AUDIO_API_COREAUDIO
+class SC_CoreAudioDriver : public SC_AudioDriver
+{
+
+ AudioBufferList * mInputBufList;
+ AudioDeviceID mInputDevice;
+ AudioDeviceID mOutputDevice;
+
+ AudioStreamBasicDescription inputStreamDesc; // info about the default device
+ AudioStreamBasicDescription outputStreamDesc; // info about the default device
+
+ friend OSStatus appIOProc ( AudioDeviceID inDevice,
+ const AudioTimeStamp* inNow,
+ const AudioBufferList* inInputData,
+ const AudioTimeStamp* inInputTime,
+ AudioBufferList* outOutputData,
+ const AudioTimeStamp* inOutputTime,
+ void* defptr);
+
+protected:
+ // Driver interface methods
+ virtual bool DriverSetup(int* outNumSamplesPerCallback, double* outSampleRate);
+ virtual bool DriverStart();
+ virtual bool DriverStop();
+
+public:
+ SC_CoreAudioDriver(struct World *inWorld);
+ virtual ~SC_CoreAudioDriver();
+
+ void Run(const AudioBufferList* inInputData, AudioBufferList* outOutputData, int64 oscTime);
+
+ bool UseInput() { return mInputDevice != kAudioDeviceUnknown; }
+ bool UseSeparateIO() { return UseInput() && mInputDevice != mOutputDevice; }
+ AudioDeviceID InputDevice() { return mInputDevice; }
+ AudioDeviceID OutputDevice() { return mOutputDevice; }
+
+ void SetInputBufferList(AudioBufferList * inBufList) { mInputBufList = inBufList; }
+ AudioBufferList* GetInputBufferList() const { return mInputBufList; }
+};
+
+inline SC_AudioDriver* SC_NewAudioDriver(struct World *inWorld)
+{
+ return new SC_CoreAudioDriver(inWorld);
+}
+#endif // SC_AUDIO_API_COREAUDIO
+
+
+#if SC_AUDIO_API == SC_AUDIO_API_JACK
+class SC_JackDriver : public SC_AudioDriver
+{
+ jack_client_t *mClient;
+ SC_JackPortList *mInputList;
+ SC_JackPortList *mOutputList;
+ int64 mMaxOutputLatency;
+
+protected:
+ // Driver interface methods
+ virtual bool DriverSetup(int* outNumSamplesPerCallback, double* outSampleRate);
+ virtual bool DriverStart();
+ virtual bool DriverStop();
+
+public:
+ SC_JackDriver(struct World *inWorld);
+ virtual ~SC_JackDriver();
+
+ void Run();
+ void BufferSizeChanged(int numSamples);
+ void SampleRateChanged(double sampleRate);
+ void GraphOrderChanged();
+};
+
+inline SC_AudioDriver* SC_NewAudioDriver(struct World *inWorld)
+{
+ return new SC_JackDriver(inWorld);
+}
+#endif // SC_AUDIO_API_JACK
+
+
+#if SC_AUDIO_API == SC_AUDIO_API_PORTAUDIO
+class SC_PortAudioDriver : public SC_AudioDriver
+{
+
+ int mInputChannelCount, mOutputChannelCount;
+ PaStream *mStream;
+
+protected:
+ // Driver interface methods
+ virtual bool DriverSetup(int* outNumSamplesPerCallback, double* outSampleRate);
+ virtual bool DriverStart();
+ virtual bool DriverStop();
+
+public:
+ SC_PortAudioDriver(struct World *inWorld);
+ virtual ~SC_PortAudioDriver();
+
+ int PortAudioCallback( const void *input, void *output,
+ unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo,
+ PaStreamCallbackFlags statusFlags );
+};
+
+inline SC_AudioDriver* SC_NewAudioDriver(struct World *inWorld)
+{
+ return new SC_PortAudioDriver(inWorld);
+}
+#endif // SC_AUDIO_API_PORTAUDIO
+
+
+#endif
diff --git a/sc4pd/headers/server/SC_Errors.h b/sc4pd/headers/server/SC_Errors.h
new file mode 100644
index 0000000..3d3459a
--- /dev/null
+++ b/sc4pd/headers/server/SC_Errors.h
@@ -0,0 +1,58 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Errors_
+#define _SC_Errors_
+
+typedef int SCErr;
+
+const char *SC_ErrorString(SCErr err);
+
+enum {
+ kSCErr_None,
+ kSCErr_Failed,
+ kSCErr_NodeNotFound,
+ kSCErr_TargetNodeNotFound,
+ kSCErr_GroupNotFound,
+ kSCErr_SynthDefNotFound,
+ kSCErr_NoSuchCommand,
+ kSCErr_WrongArgType,
+ kSCErr_IndexOutOfRange,
+ kSCErr_AccessDenied,
+ kSCErr_NoReplyPort,
+ kSCErr_InvalidControlIndex,
+ kSCErr_AlreadyLoggedIn,
+ kSCErr_NotLoggedIn,
+ kSCErr_TooManyUsers,
+ kSCErr_TooManyNodes,
+ kSCErr_DuplicateNodeID,
+ kSCErr_ReservedNodeID,
+ kSCErr_OutOfRealTimeMemory,
+
+ kSCErr_UnsupportedHeaderFormat,
+ kSCErr_UnsupportedSampleFormat,
+
+ kSCErr_BufGenNotFound,
+
+ kSCErr_NumErrors
+};
+
+#endif
diff --git a/sc4pd/headers/server/SC_GraphDef.h b/sc4pd/headers/server/SC_GraphDef.h
new file mode 100644
index 0000000..dca6fd2
--- /dev/null
+++ b/sc4pd/headers/server/SC_GraphDef.h
@@ -0,0 +1,75 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_GraphDef_
+#define _SC_GraphDef_
+
+#include "SC_SynthDef.h"
+#include "HashTable.h"
+
+struct ParamSpec
+{
+ int32 mName[kSCNameLen];
+ int32 mIndex;
+ int32 mHash;
+};
+
+typedef HashTable<ParamSpec, Malloc> ParamSpecTable;
+
+struct GraphDef
+{
+ NodeDef mNodeDef;
+
+ uint32 mNumControls;
+
+ uint32 mNumWires;
+ uint32 mNumConstants;
+ uint32 mNumUnitSpecs;
+ uint32 mNumWireBufs;
+ uint32 mNumCalcUnits;
+
+ float32 *mInitialControlValues;
+ float32 *mConstants;
+
+ struct UnitSpec *mUnitSpecs;
+
+ size_t mWiresAllocSize, mUnitsAllocSize, mCalcUnitsAllocSize;
+ size_t mControlAllocSize, mMapControlsAllocSize;
+
+ uint32 mNumParamSpecs;
+ ParamSpec *mParamSpecs;
+ ParamSpecTable *mParamSpecTable;
+
+ int mRefCount;
+ struct GraphDef* mNext;
+};
+typedef struct GraphDef GraphDef;
+
+GraphDef* GraphDef_Recv(World *inWorld, char *buffer, GraphDef *inList);
+GraphDef* GraphDef_Load(struct World *inWorld, const char *filename, GraphDef* inList);
+GraphDef* GraphDef_LoadDir(struct World *inWorld, char *dirname, GraphDef* inList);
+GraphDef* GraphDef_LoadGlob(World *inWorld, const char *pattern, GraphDef *inList);
+void GraphDef_DeleteMsg(struct World *inWorld, GraphDef *inDef);
+void GraphDef_Dump(GraphDef *inGraphDef);
+int32 GetHash(ParamSpec* inParamSpec);
+int32* GetKey(ParamSpec* inParamSpec);
+
+#endif
diff --git a/sc4pd/headers/server/SC_Group.h b/sc4pd/headers/server/SC_Group.h
new file mode 100644
index 0000000..5a104a7
--- /dev/null
+++ b/sc4pd/headers/server/SC_Group.h
@@ -0,0 +1,34 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Group_
+#define _SC_Group_
+
+#include "SC_Graph.h"
+
+struct Group {
+ Node mNode;
+
+ Node *mHead, *mTail;
+};
+typedef struct Group Group;
+
+#endif
diff --git a/sc4pd/headers/server/SC_HiddenWorld.h b/sc4pd/headers/server/SC_HiddenWorld.h
new file mode 100644
index 0000000..7776874
--- /dev/null
+++ b/sc4pd/headers/server/SC_HiddenWorld.h
@@ -0,0 +1,113 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_HiddenWorld_
+#define _SC_HiddenWorld_
+
+#include "SC_Types.h"
+#include "SC_Sem.h"
+#include "SC_Rate.h"
+#include "SC_SndBuf.h"
+#include "SC_RGen.h"
+#include "HashTable.h"
+#include "SC_World.h"
+#include "SC_Reply.h"
+#include "MsgFifo.h"
+
+extern HashTable<struct UnitDef, Malloc> *gUnitDefLib;
+
+
+struct TriggerMsg {
+ World *mWorld;
+ int32 mNodeID;
+ int32 mTriggerID;
+ float mValue;
+
+ void Perform();
+};
+
+struct NodeEndMsg {
+ World *mWorld;
+ int32 mNodeID;
+ int32 mGroupID;
+ int32 mPrevNodeID;
+ int32 mNextNodeID;
+ int32 mIsGroup;
+ int32 mHeadID;
+ int32 mTailID;
+ int32 mState;
+
+ void Perform();
+};
+
+struct DeleteGraphDefMsg {
+ struct GraphDef* mDef;
+
+ void Perform();
+};
+
+
+typedef MsgFifoNoFree<TriggerMsg, 1024> TriggersFifo;
+typedef MsgFifoNoFree<NodeEndMsg, 1024> NodeEndsFifo;
+typedef MsgFifoNoFree<DeleteGraphDefMsg, 512> DeleteGraphDefsFifo;
+
+struct HiddenWorld
+{
+
+ class AllocPool *mAllocPool;
+ IntHashTable<struct Node, AllocPool> *mNodeLib;
+ HashTable<struct GraphDef, Malloc> *mGraphDefLib;
+ uint32 mNumUsers, mMaxUsers;
+ ReplyAddress *mUsers;
+
+ class SC_AudioDriver *mAudioDriver;
+ char mPassword[32];
+
+ uint32 mMaxWireBufs;
+ float *mWireBufSpace;
+
+ TriggersFifo mTriggers;
+ NodeEndsFifo mNodeEnds;
+ DeleteGraphDefsFifo mDeleteGraphDefs;
+
+ SC_Semaphore* mQuitProgram;
+
+ SNDFILE *mNRTInputFile;
+ SNDFILE *mNRTOutputFile;
+ FILE *mNRTCmdFile;
+
+ int32 mHiddenID;
+ int32 mRecentID;
+
+#ifdef SC_DARWIN
+ const char* mInputStreamsEnabled;
+ const char* mOutputStreamsEnabled;
+#endif
+};
+
+typedef struct HiddenWorld HiddenWorld;
+
+inline SC_AudioDriver *AudioDriver(World *inWorld)
+{
+ return inWorld->hw->mAudioDriver;
+}
+
+#endif
diff --git a/sc4pd/headers/server/SC_Lib.h b/sc4pd/headers/server/SC_Lib.h
new file mode 100644
index 0000000..552a231
--- /dev/null
+++ b/sc4pd/headers/server/SC_Lib.h
@@ -0,0 +1,62 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Lib_
+#define _SC_Lib_
+
+#include "SC_Errors.h"
+#include "SC_Lock.h"
+#include "SC_Types.h"
+#include "Hash.h"
+#include "HashTable.h"
+#include <stdlib.h>
+#include <string.h>
+
+class SC_NamedObj
+{
+public:
+ SC_NamedObj();
+ virtual ~SC_NamedObj();
+
+ const int32* Name() const { return mName; }
+ void SetName(const char *inName);
+ void SetName(const int32 *inName);
+
+private:
+ friend int32 GetHash(const SC_NamedObj *inObj);
+ friend const int32* GetKey(const SC_NamedObj *inObj);
+
+ int32 mName[kSCNameLen];
+ int32 mHash;
+};
+
+inline int32 GetHash(const SC_NamedObj *inObj)
+{
+ return inObj->mHash;
+}
+
+inline const int32 *GetKey(const SC_NamedObj *inObj)
+{
+ return inObj->mName;
+}
+
+#endif
+
diff --git a/sc4pd/headers/server/SC_Lib_Cintf.h b/sc4pd/headers/server/SC_Lib_Cintf.h
new file mode 100644
index 0000000..64eda5e
--- /dev/null
+++ b/sc4pd/headers/server/SC_Lib_Cintf.h
@@ -0,0 +1,124 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Lib_Cintf_
+#define _SC_Lib_Cintf_
+
+#include "SC_Lib.h"
+#include "SC_Reply.h"
+
+typedef SCErr (*SC_CommandFunc)(struct World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
+
+class SC_LibCmd : public SC_NamedObj
+{
+public:
+ SC_LibCmd(SC_CommandFunc inFunc);
+
+ SCErr Perform(struct World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
+
+private:
+ SC_CommandFunc mFunc;
+};
+
+extern Malloc gMalloc;
+extern HashTable<class SC_LibCmd, Malloc> *gCmdLib;
+
+void initialize_library();
+SCErr NewCommand(const char *inPath, uint32 inCommandNumber, SC_CommandFunc inFunc);
+
+// command numbers:
+enum {
+ cmd_none = 0,
+
+ cmd_notify = 1,
+ cmd_status = 2,
+ cmd_quit = 3,
+ cmd_cmd = 4,
+
+ cmd_d_recv = 5,
+ cmd_d_load = 6,
+ cmd_d_loadDir = 7,
+ cmd_d_freeAll = 8,
+
+ cmd_s_new = 9,
+
+ cmd_n_trace = 10,
+ cmd_n_free = 11,
+ cmd_n_run = 12,
+ cmd_n_cmd = 13,
+ cmd_n_map = 14,
+ cmd_n_set = 15,
+ cmd_n_setn = 16,
+ cmd_n_fill = 17,
+ cmd_n_before = 18,
+ cmd_n_after = 19,
+
+ cmd_u_cmd = 20,
+
+ cmd_g_new = 21,
+ cmd_g_head = 22,
+ cmd_g_tail = 23,
+ cmd_g_freeAll = 24,
+
+ cmd_c_set = 25,
+ cmd_c_setn = 26,
+ cmd_c_fill = 27,
+
+ cmd_b_alloc = 28,
+ cmd_b_allocRead = 29,
+ cmd_b_read = 30,
+ cmd_b_write = 31,
+ cmd_b_free = 32,
+ cmd_b_close = 33,
+ cmd_b_zero = 34,
+ cmd_b_set = 35,
+ cmd_b_setn = 36,
+ cmd_b_fill = 37,
+ cmd_b_gen = 38,
+
+ cmd_dumpOSC = 39,
+
+ cmd_c_get = 40,
+ cmd_c_getn = 41,
+ cmd_b_get = 42,
+ cmd_b_getn = 43,
+ cmd_s_get = 44,
+ cmd_s_getn = 45,
+
+ cmd_n_query = 46,
+ cmd_b_query = 47,
+
+ cmd_n_mapn = 48,
+ cmd_s_noid = 49,
+
+ cmd_g_deepFree = 50,
+ cmd_clearSched = 51,
+
+ cmd_sync = 52,
+
+ NUMBER_OF_COMMANDS = 53
+};
+
+extern SC_LibCmd* gCmdArray[NUMBER_OF_COMMANDS];
+
+
+#endif
+
diff --git a/sc4pd/headers/server/SC_List.h b/sc4pd/headers/server/SC_List.h
new file mode 100644
index 0000000..d5bed41
--- /dev/null
+++ b/sc4pd/headers/server/SC_List.h
@@ -0,0 +1,229 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+
+A doubly linked list template.
+
+*/
+
+#ifndef _SC_List_
+#define _SC_List_
+
+#include <stdexcept>
+#ifndef NDEBUG
+# define NDEBUG
+#endif
+#include <assert.h>
+
+
+// A Link can be a node in a list or a list itself.
+
+template <class T>
+class Link
+{
+public:
+ Link() : mNext(this), mPrev(this) {}
+
+ T* Prev() { return static_cast<T*>(mPrev); }
+ T* Next() { return static_cast<T*>(mNext); }
+
+ void RemoveLeaveDangling()
+ {
+ mPrev->mNext = mNext;
+ mNext->mPrev = mPrev;
+ }
+
+ void Remove()
+ {
+ RemoveLeaveDangling();
+ mNext = mPrev = this;
+ }
+
+ void InsertAfter(T *inLink)
+ {
+ mPrev = inLink;
+ mNext = inLink->mNext;
+ mNext->mPrev = this;
+ mPrev->mNext = this;
+ }
+
+ void InsertBefore(T *inLink)
+ {
+ mNext = inLink;
+ mPrev = inLink->mPrev;
+ mNext->mPrev = this;
+ mPrev->mNext = this;
+ }
+
+ T* Head() { return static_cast<T*>(mNext); }
+ T* Tail() { return static_cast<T*>(mPrev); }
+
+ T* PopHead();
+ T* PopTail();
+ void PushHead(T* inBuf);
+ void PushTail(T* inBuf);
+
+ bool ContainsBuf(T* inBuf);
+ bool IsEmpty() { return mNext == this; }
+ void BeEmpty() { mNext = mPrev = this; }
+
+ void Cat(T* inLink);
+
+ bool SanityCheck();
+ void DebugDump();
+
+//private:
+// Codewarrior refuses to inline Next() in some places..
+ Link<T> *mNext, *mPrev;
+};
+
+template <class T, class Alloc>
+void MakeListEmpty(Link<T> *inLink, Alloc* inAlloc)
+{
+ Link<T>* link = inLink->mNext;
+ while (link != inLink) {
+ Link<T>* nextlink = link->mNext;
+ // SC uses placement new extensively, so here we do a 'placement delete'.
+ // Using DestructSelf allows me to have either virtual
+ // or non virtual destructors in subclasses at the discretion of the subclass.
+ ((T*)(link))->DestructSelf();
+ inAlloc->Free(static_cast<T*>(link));
+ link = nextlink;
+ }
+ inLink->mNext = inLink->mPrev = inLink;
+}
+
+template <class T>
+void Link<T>::PushHead(T* inLink)
+{
+ assert(SanityCheck());
+
+ Link<T>* link = static_cast<Link<T>*>(inLink);
+ link->InsertAfter(static_cast<T*>(this));
+
+ assert(SanityCheck());
+}
+
+template <class T>
+T* Link<T>::PopHead()
+{
+ assert(SanityCheck());
+ if (IsEmpty()) return 0;
+
+ Link<T>* link = mNext;
+
+ link->Remove();
+
+ assert(SanityCheck());
+ return static_cast<T*>(link);
+}
+
+template <class T>
+void Link<T>::PushTail(T* inLink)
+{
+ assert(SanityCheck());
+
+ Link<T>* link = static_cast<Link<T>*>(inLink);
+ link->InsertBefore(static_cast<T*>(this));
+
+ assert(SanityCheck());
+}
+
+template <class T>
+T* Link<T>::PopTail()
+{
+ assert(SanityCheck());
+ if (IsEmpty()) return 0;
+
+ Link<T>* link = mPrev;
+ link->Remove();
+
+ assert(SanityCheck());
+ return static_cast<T*>(link);
+}
+
+template <class T>
+void Link<T>::Cat(T* inLink)
+{
+ assert(SanityCheck());
+
+ Link<T>* link = static_cast<Link<T>*>(inLink);
+
+ if (link->IsEmpty()) return;
+ if (IsEmpty()) {
+ mNext = link->mNext;
+ mPrev = link->mPrev;
+ link->mNext->mPrev = this;
+ link->mPrev->mNext = this;
+ } else {
+ link->mNext->mPrev = mPrev;
+ link->mPrev->mNext = this;
+ mPrev->mNext = link->mNext;
+ mPrev = link->mPrev;
+ }
+ link->mPrev = link;
+ link->mNext = link;
+
+ assert(SanityCheck());
+}
+
+template <class T>
+bool Link<T>::ContainsBuf(T* inLink)
+{
+ Link<T>* link = static_cast<Link<T>*>(inLink);
+ Link<T>* curLink = mNext;
+ while (curLink != this) {
+ if (curLink == link) return true;
+ curLink = curLink->mNext;
+ }
+ return false;
+}
+
+template <class T>
+void Link<T>::DebugDump()
+{
+ Link<T>* link = mNext;
+ while (link != this) {
+ //postbuf("Link-> %08X next %08X prev %08X\n",
+ // link, link->mNext, link->mPrev);
+ link = link->mNext;
+ }
+}
+
+template <class T>
+bool Link<T>::SanityCheck()
+{
+ Link<T>* link = mNext;
+ while (link != this) {
+ if (link->mPrev->mNext != link) {
+ throw std::runtime_error("Link: bad link <-,->");
+ }
+ if (link->mNext->mPrev != link) {
+ throw std::runtime_error("Link: bad link ->,<-");
+ }
+ link = link->mNext;
+ }
+ return true;
+}
+
+
+
+#endif
diff --git a/sc4pd/headers/server/SC_Lock.h b/sc4pd/headers/server/SC_Lock.h
new file mode 100644
index 0000000..57635fe
--- /dev/null
+++ b/sc4pd/headers/server/SC_Lock.h
@@ -0,0 +1,38 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Lock_
+#define _SC_Lock_
+
+#include <pthread.h>
+
+class SC_Lock
+{
+public:
+ SC_Lock() { pthread_mutex_init (&mutex, NULL); }
+ ~SC_Lock() { pthread_mutex_destroy (&mutex); }
+ void Lock() { pthread_mutex_lock (&mutex); }
+ void Unlock() { pthread_mutex_unlock (&mutex); }
+private:
+ pthread_mutex_t mutex;
+};
+
+#endif
diff --git a/sc4pd/headers/server/SC_Prototypes.h b/sc4pd/headers/server/SC_Prototypes.h
new file mode 100644
index 0000000..c2f353e
--- /dev/null
+++ b/sc4pd/headers/server/SC_Prototypes.h
@@ -0,0 +1,213 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Prototypes_
+#define _SC_Prototypes_
+
+#include <ctype.h> // for size_t
+
+#include "SC_Types.h"
+
+////////////////////////////////////////////////////////////////////////
+
+// replacement for calloc.
+// calloc lazily zeroes memory on first touch. This is good for most purposes, but bad for realtime audio.
+void* zalloc(size_t n, size_t size);
+
+////////////////////////////////////////////////////////////////////////
+
+void World_Run(struct World *inWorld);
+void World_Start(World *inWorld);
+void World_Cleanup(World *inWorld);
+void World_SetSampleRate(struct World *inWorld, double inSampleRate);
+
+extern "C" {
+void* World_Alloc(struct World *inWorld, size_t inByteSize);
+void* World_Realloc(struct World *inWorld, void *inPtr, size_t inByteSize);
+void World_Free(struct World *inWorld, void *inPtr);
+void World_NRTLock(World *world);
+void World_NRTUnlock(World *world);
+}
+
+size_t World_TotalFree(struct World *inWorld);
+size_t World_LargestFreeChunk(struct World *inWorld);
+
+
+int32 GetKey(struct Node *inNode);
+int32 GetHash(struct Node *inNode);
+bool World_AddNode(struct World *inWorld, struct Node* inNode);
+bool World_RemoveNode(struct World *inWorld, struct Node* inNode);
+
+extern "C" {
+struct Node* World_GetNode(struct World *inWorld, int32 inID);
+struct Graph* World_GetGraph(struct World *inWorld, int32 inID);
+}
+
+struct Group* World_GetGroup(struct World *inWorld, int32 inID);
+
+int32 *GetKey(struct UnitDef *inUnitDef);
+int32 GetHash(struct UnitDef *inUnitDef);
+bool AddUnitDef(struct UnitDef* inUnitDef);
+bool RemoveUnitDef(struct UnitDef* inUnitDef);
+struct UnitDef* GetUnitDef(int32* inKey);
+
+int32 *GetKey(struct BufGen *inBufGen);
+int32 GetHash(struct BufGen *inBufGen);
+bool AddBufGen(struct BufGen* inBufGen);
+bool RemoveBufGen(struct BufGen* inBufGen);
+struct BufGen* GetBufGen(int32* inKey);
+
+int32 *GetKey(struct PlugInCmd *inPlugInCmd);
+int32 GetHash(struct PlugInCmd *inPlugInCmd);
+bool AddPlugInCmd(struct PlugInCmd* inPlugInCmd);
+bool RemovePlugInCmd(struct PlugInCmd* inPlugInCmd);
+struct PlugInCmd* GetPlugInCmd(int32* inKey);
+int PlugIn_DoCmd(struct World *inWorld, int inSize, char *inArgs, struct ReplyAddress *inReply);
+
+int32 *GetKey(struct GraphDef *inGraphDef);
+int32 GetHash(struct GraphDef *inGraphDef);
+bool World_AddGraphDef(struct World *inWorld, struct GraphDef* inGraphDef);
+bool World_FreeGraphDef(struct World *inWorld, struct GraphDef* inGraphDef);
+bool World_RemoveGraphDef(struct World *inWorld, struct GraphDef* inGraphDef);
+struct GraphDef* World_GetGraphDef(struct World *inWorld, int32* inKey);
+void World_FreeAllGraphDefs(World *inWorld);
+void GraphDef_Free(GraphDef *inGraphDef);
+void GraphDef_Define(World *inWorld, GraphDef *inList);
+void GraphDef_FreeOverwritten(World *inWorld);
+
+SCErr bufAlloc(struct SndBuf* buf, int numChannels, int numFrames, double sampleRate);
+
+////////////////////////////////////////////////////////////////////////
+
+void Rate_Init(struct Rate *inRate, double inSampleRate, int inBufLength);
+
+void Dimension_Init(struct SC_Dimension *inDimension, int inWidth, int inHeight);
+
+////////////////////////////////////////////////////////////////////////
+
+#define GRAPHDEF(inGraph) ((GraphDef*)((inGraph)->mNode.mDef))
+#define GRAPH_PARAM_TABLE(inGraph) (GRAPHDEF(inGraph)->mParamSpecTable)
+
+int Graph_New(struct World *inWorld, struct GraphDef *def, int32 inID, struct sc_msg_iter* args, struct Graph** outGraph);
+void Graph_Ctor(struct World *inWorld, struct GraphDef *inGraphDef, struct Graph *graph, struct sc_msg_iter *msg);
+void Graph_Dtor(struct Graph *inGraph);
+int Graph_GetControl(struct Graph* inGraph, uint32 inIndex, float& outValue);
+int Graph_GetControl(struct Graph* inGraph, int32 inHash, int32 *inName, uint32 inIndex, float& outValue);
+void Graph_SetControl(struct Graph* inGraph, uint32 inIndex, float inValue);
+void Graph_SetControl(struct Graph* inGraph, int32 inHash, int32 *inName, uint32 inIndex, float inValue);
+void Graph_MapControl(Graph* inGraph, uint32 inIndex, uint32 inBus);
+void Graph_MapControl(Graph* inGraph, int32 inHash, int32 *inName, uint32 inIndex, uint32 inBus);
+void Graph_Trace(Graph *inGraph);
+void Graph_RemoveID(World* inWorld, Graph *inGraph);
+
+////////////////////////////////////////////////////////////////////////
+
+int Node_New(struct World *inWorld, struct NodeDef *def, int32 inID, struct Node **outNode);
+void Node_Dtor(struct Node *inNode);
+void Node_Remove(struct Node* s);
+void Node_Delete(struct Node* inNode);
+void Node_AddAfter(struct Node* s, struct Node *afterThisOne);
+void Node_AddBefore(struct Node* s, struct Node *beforeThisOne);
+void Node_Replace(struct Node* s, struct Node *replaceThisOne);
+void Node_SetControl(Node* inNode, int inIndex, float inValue);
+void Node_SetControl(Node* inNode, int32 inHash, int32 *inName, int inIndex, float inValue);
+void Node_MapControl(Node* inNode, int inIndex, int inBus);
+void Node_MapControl(Node* inNode, int32 inHash, int32 *inName, int inIndex, int inBus);
+void Node_StateMsg(Node* inNode, int inState);
+void Node_Trace(Node* inNode);
+
+extern "C" {
+void Node_SetRun(Node* inNode, int inRun);
+void Node_SendTrigger(Node* inNode, int triggerID, float value);
+void Node_End(struct Node* inNode);
+void Node_NullCalc(struct Node* inNode);
+void Unit_DoneAction(int doneAction, struct Unit* unit);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+extern "C" {
+void Group_Calc(Group *inGroup);
+void Graph_Calc(struct Graph *inGraph);
+}
+
+int Group_New(World *inWorld, int32 inID, Group** outGroup);
+void Group_Dtor(Group *inGroup);
+void Group_DeleteAll(Group *inGroup);
+void Group_DeepFreeGraphs(Group *inGroup);
+void Group_AddHead (Group *s, Node *child);
+void Group_AddTail (Group *s, Node *child);
+void Group_Insert(Group *s, Node *child, int inIndex);
+void Group_SetControl(struct Group* inGroup, uint32 inIndex, float inValue);
+void Group_SetControl(struct Group *inGroup, int32 inHash, int32 *inName, uint32 inIndex, float inValue);
+void Group_MapControl(Group* inGroup, uint32 inIndex, uint32 inBus);
+void Group_MapControl(Group* inGroup, int32 inHash, int32 *inName, uint32 inIndex, uint32 inBus);
+void Group_Trace(Group* inGroup);
+
+////////////////////////////////////////////////////////////////////////
+
+struct Unit* Unit_New(struct World *inWorld, struct UnitSpec *inUnitSpec, char*& memory);
+void Unit_EndCalc(struct Unit *inUnit, int inNumSamples);
+void Unit_End(struct Unit *inUnit);
+
+void Unit_Dtor(struct Unit *inUnit);
+
+extern "C" {
+void Unit_ZeroOutputs(struct Unit *inUnit, int inNumSamples);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void SendDone(struct ReplyAddress *inReply, char *inCommandName);
+void SendFailure(struct ReplyAddress *inReply, char *inCommandName, char *errString);
+void ReportLateness(struct ReplyAddress *inReply, float32 seconds);
+void DumpReplyAddress(struct ReplyAddress *inReplyAddress);
+int32 Hash(struct ReplyAddress *inReplyAddress);
+
+////////////////////////////////////////////////////////////////////////
+
+extern "C" {
+int32 timeseed();
+}
+
+////////////////////////////////////////////////////////////////////////
+
+typedef bool (*AsyncStageFn)(World *inWorld, void* cmdData);
+typedef void (*AsyncFreeFn)(World *inWorld, void* cmdData);
+
+int PerformAsynchronousCommand
+ (
+ World *inWorld,
+ void* replyAddr,
+ const char* cmdName,
+ void *cmdData,
+ AsyncStageFn stage2, // stage2 is non real time
+ AsyncStageFn stage3, // stage3 is real time - completion msg performed if stage3 returns true
+ AsyncStageFn stage4, // stage4 is non real time - sends done if stage4 returns true
+ AsyncFreeFn cleanup,
+ int completionMsgSize,
+ void* completionMsgData
+ );
+
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/sc4pd/headers/server/SC_Reply.h b/sc4pd/headers/server/SC_Reply.h
new file mode 100644
index 0000000..0400747
--- /dev/null
+++ b/sc4pd/headers/server/SC_Reply.h
@@ -0,0 +1,55 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Msg_
+#define _SC_Msg_
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef SC_WIN32
+# include <winsock2.h>
+#else
+#include <netinet/in.h>
+#endif
+#include "sc_msg_iter.h"
+
+typedef void (*ReplyFunc)(struct ReplyAddress *inReplyAddr, char* inBuf, int inSize);
+
+void null_reply_func(struct ReplyAddress* addr, char* msg, int size);
+
+struct ReplyAddress
+{
+ struct sockaddr_in mSockAddr;
+ int mSockAddrLen;
+ int mSocket;
+ ReplyFunc mReplyFunc;
+};
+
+bool operator==(const ReplyAddress& a, const ReplyAddress& b);
+
+inline void SendReply(ReplyAddress *inReplyAddr, char* inBuf, int inSize)
+{
+ (inReplyAddr->mReplyFunc)(inReplyAddr, inBuf, inSize);
+}
+
+#endif
+
+
diff --git a/sc4pd/headers/server/SC_Samp.h b/sc4pd/headers/server/SC_Samp.h
new file mode 100644
index 0000000..dde9159
--- /dev/null
+++ b/sc4pd/headers/server/SC_Samp.h
@@ -0,0 +1,38 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Samp_
+#define _SC_Samp_
+
+#include "SC_Types.h"
+
+const int kSineSize = 8192;
+const int kSineMask = kSineSize - 1;
+
+extern float32 gSine[kSineSize+1];
+extern float32 gPMSine[kSineSize+1];
+extern float32 gInvSine[kSineSize+1];
+extern float32 gSineWavetable[2*kSineSize];
+
+void SignalAsWavetable(float32* signal, float32* wavetable, long inSize);
+void WavetableAsSignal(float32* wavetable, float32* signal, long inSize);
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/server/SC_SequencedCommand.h b/sc4pd/headers/server/SC_SequencedCommand.h
new file mode 100644
index 0000000..d1a7fb5
--- /dev/null
+++ b/sc4pd/headers/server/SC_SequencedCommand.h
@@ -0,0 +1,481 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+ * Having SequencedCommands allows performing actions that might otherwise require
+ * taking a mutex, which is undesirable in a real time thread.
+ * Some commands require several stages of processing at both the real time
+ * and non real time levels. This class does the messaging between levels for you
+ * so that you only need to write the functions.
+ */
+
+#ifndef _SC_SequencedCommand_
+#define _SC_SequencedCommand_
+
+#include "OSC_Packet.h"
+#include "SC_World.h"
+#include "SC_BufGen.h"
+#include "sc_msg_iter.h"
+#include <sndfile.h>
+#include <new>
+
+#define CallSequencedCommand(T, inWorld, inSize, inData, inReply) \
+ void* space = World_Alloc(inWorld, sizeof(T)); \
+ T *cmd = new (space) T(inWorld, inReply); \
+ if (!cmd) return kSCErr_Failed; \
+ int err = cmd->Init(inData, inSize); \
+ if (err) { \
+ cmd->~T(); \
+ World_Free(inWorld, space); \
+ return err; \
+ } \
+ if (inWorld->mRealTime) cmd->CallNextStage(); \
+ else cmd->CallEveryStage();
+
+
+class SC_SequencedCommand
+{
+public:
+ SC_SequencedCommand(World *inWorld, ReplyAddress *inReplyAddress);
+ virtual ~SC_SequencedCommand();
+
+ void Delete();
+
+ void CallEveryStage();
+ void CallNextStage();
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage1(); // real time
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+ void SendDone(char *inCommandName);
+
+protected:
+ int mNextStage;
+ ReplyAddress mReplyAddress;
+ World *mWorld;
+
+ int mMsgSize;
+ char *mMsgData;
+
+ virtual void CallDestructor()=0;
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+class SyncCmd : public SC_SequencedCommand
+{
+public:
+ SyncCmd(World *inWorld, ReplyAddress *inReplyAddress);
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+ virtual void CallDestructor();
+ int mID;
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+class BufGenCmd : public SC_SequencedCommand
+{
+public:
+ BufGenCmd(World *inWorld, ReplyAddress *inReplyAddress);
+ virtual ~BufGenCmd();
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+ int mBufIndex;
+ BufGen *mBufGen;
+ sc_msg_iter mMsg;
+ char *mData;
+ int mSize;
+ SndBuf mSndBuf;
+ float *mFreeData;
+
+ virtual void CallDestructor();
+
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+class BufAllocCmd : public SC_SequencedCommand
+{
+public:
+ BufAllocCmd(World *inWorld, ReplyAddress *inReplyAddress);
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+ int mBufIndex;
+ SndBuf mSndBuf;
+ int mNumChannels, mNumFrames;
+ float *mFreeData;
+
+ virtual void CallDestructor();
+
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+
+class BufFreeCmd : public SC_SequencedCommand
+{
+public:
+ BufFreeCmd(World *inWorld, ReplyAddress *inReplyAddress);
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+ int mBufIndex;
+ float *mFreeData;
+
+ virtual void CallDestructor();
+};
+
+
+///////////////////////////////////////////////////////////////////////////
+
+
+class BufCloseCmd : public SC_SequencedCommand
+{
+public:
+ BufCloseCmd(World *inWorld, ReplyAddress *inReplyAddress);
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+ int mBufIndex;
+
+ virtual void CallDestructor();
+};
+
+
+///////////////////////////////////////////////////////////////////////////
+
+
+class BufZeroCmd : public SC_SequencedCommand
+{
+public:
+ BufZeroCmd(World *inWorld, ReplyAddress *inReplyAddress);
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+ int mBufIndex;
+
+ virtual void CallDestructor();
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+class BufAllocReadCmd : public SC_SequencedCommand
+{
+public:
+ BufAllocReadCmd(World *inWorld, ReplyAddress *inReplyAddress);
+ virtual ~BufAllocReadCmd();
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+ int mBufIndex;
+ float *mFreeData;
+ SndBuf mSndBuf;
+ char *mFilename;
+ int mFileOffset, mNumFrames;
+
+ virtual void CallDestructor();
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+class BufReadCmd : public SC_SequencedCommand
+{
+public:
+ BufReadCmd(World *inWorld, ReplyAddress *inReplyAddress);
+ virtual ~BufReadCmd();
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+ int mBufIndex;
+ char *mFilename;
+ int mFileOffset, mNumFrames, mBufOffset;
+ bool mLeaveFileOpen;
+ virtual void CallDestructor();
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+class BufWriteCmd : public SC_SequencedCommand
+{
+public:
+ BufWriteCmd(World *inWorld, ReplyAddress *inReplyAddress);
+ virtual ~BufWriteCmd();
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+ int mBufIndex;
+ char *mFilename;
+ SF_INFO mFileInfo;
+ int mNumFrames, mBufOffset;
+ bool mLeaveFileOpen;
+
+ virtual void CallDestructor();
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+class AudioQuitCmd : public SC_SequencedCommand
+{
+public:
+ AudioQuitCmd(World *inWorld, ReplyAddress *inReplyAddress);
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+
+ virtual void CallDestructor();
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+class AudioStatusCmd : public SC_SequencedCommand
+{
+public:
+ AudioStatusCmd(World *inWorld, ReplyAddress *inReplyAddress);
+
+ virtual bool Stage2(); // non real time
+
+protected:
+
+ virtual void CallDestructor();
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+class NotifyCmd : public SC_SequencedCommand
+{
+public:
+ NotifyCmd(World *inWorld, ReplyAddress *inReplyAddress);
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+
+protected:
+
+ virtual void CallDestructor();
+
+ int mOnOff;
+ int mID;
+};
+
+
+///////////////////////////////////////////////////////////////////////////
+
+#define CallSendFailureCommand(inWorld, inCmdName, inErrString, inReply) \
+ void* space = World_Alloc(inWorld, sizeof(SendFailureCmd)); \
+ SendFailureCmd *cmd = new (space) SendFailureCmd(inWorld, inReply); \
+ if (!cmd) return kSCErr_Failed; \
+ cmd->InitSendFailureCmd(inCmdName, inErrString); \
+ if (inWorld->mRealTime) cmd->CallNextStage(); \
+ else cmd->CallEveryStage(); \
+
+class SendFailureCmd : public SC_SequencedCommand
+{
+public:
+ SendFailureCmd(World *inWorld, ReplyAddress *inReplyAddress);
+ virtual ~SendFailureCmd();
+
+ virtual void InitSendFailureCmd(const char *inCmdName, const char* inErrString);
+
+ virtual bool Stage2(); // non real time
+
+protected:
+ char *mCmdName, *mErrString;
+
+ virtual void CallDestructor();
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+#include "SC_GraphDef.h"
+
+class LoadSynthDefCmd : public SC_SequencedCommand
+{
+public:
+ LoadSynthDefCmd(World *inWorld, ReplyAddress *inReplyAddress);
+ virtual ~LoadSynthDefCmd();
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+ char *mFilename;
+ GraphDef *mDefs;
+
+ virtual void CallDestructor();
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+#include "SC_GraphDef.h"
+
+class RecvSynthDefCmd : public SC_SequencedCommand
+{
+public:
+ RecvSynthDefCmd(World *inWorld, ReplyAddress *inReplyAddress);
+ virtual ~RecvSynthDefCmd();
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+ char *mBuffer;
+ GraphDef *mDefs;
+
+ virtual void CallDestructor();
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+class LoadSynthDefDirCmd : public SC_SequencedCommand
+{
+public:
+ LoadSynthDefDirCmd(World *inWorld, ReplyAddress *inReplyAddress);
+ virtual ~LoadSynthDefDirCmd();
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+ char *mFilename;
+ GraphDef *mDefs;
+
+ virtual void CallDestructor();
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+class SendReplyCmd : public SC_SequencedCommand
+{
+public:
+ SendReplyCmd(World *inWorld, ReplyAddress *inReplyAddress);
+
+ virtual int Init(char *inData, int inSize);
+
+ virtual bool Stage2(); // non real time
+
+protected:
+
+ virtual void CallDestructor();
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+
+typedef bool (*AsyncStageFn)(World *inWorld, void* cmdData);
+typedef void (*AsyncFreeFn)(World *inWorld, void* cmdData);
+
+class AsyncPlugInCmd : public SC_SequencedCommand
+{
+public:
+ AsyncPlugInCmd(World *inWorld, ReplyAddress *inReplyAddress,
+ const char* cmdName,
+ void *cmdData,
+ AsyncStageFn stage2, // stage2 is non real time
+ AsyncStageFn stage3, // stage3 is real time - completion msg performed if stage3 returns true
+ AsyncStageFn stage4, // stage4 is non real time - sends done if stage4 returns true
+ AsyncFreeFn cleanup,
+ int completionMsgSize,
+ void* completionMsgData);
+
+ virtual ~AsyncPlugInCmd();
+
+ virtual bool Stage2(); // non real time
+ virtual bool Stage3(); // real time
+ virtual void Stage4(); // non real time
+
+protected:
+ const char *mCmdName;
+ void *mCmdData;
+ AsyncStageFn mStage2, mStage3, mStage4;
+ AsyncFreeFn mCleanup;
+
+ virtual void CallDestructor();
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/sc4pd/headers/server/SC_Str4.h b/sc4pd/headers/server/SC_Str4.h
new file mode 100644
index 0000000..306b823
--- /dev/null
+++ b/sc4pd/headers/server/SC_Str4.h
@@ -0,0 +1,103 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* a 4 byte aligned and zero padded string allows faster string operations. */
+
+#ifndef _SC_Str4_
+#define _SC_Str4_
+
+#include "Hash.h"
+#include <stdio.h>
+#include <limits.h>
+
+#ifndef _LASTCHAR_
+#define _LASTCHAR_
+#if BYTE_ORDER == LITTLE_ENDIAN
+const int32 kLASTCHAR = 0xFF000000;
+#else
+const int32 kLASTCHAR = 0x000000FF;
+#endif
+#endif
+
+
+void str4cpy(int32 *dst, const char *src);
+void mem4cpy(int32 *dst, const char *src, int charlen);
+
+// returns the number of pad bytes to add to a string of a given length
+inline int str4padbytes(int charlen)
+{
+ return 4 - (charlen & 3);
+}
+
+// converts length in bytes to length in words
+inline int str4len(int charlen)
+{
+ return (charlen + 4) >> 2;
+}
+
+// returns length in words of a char *
+inline int str4len(const char *src)
+{
+ const char *src0 = src;
+ while (*src) { src++; }
+ return str4len(src - src0);
+}
+
+// returns length in words of a int32 *
+inline int str4len(const int32 *src)
+{
+ const int32 *src0 = src;
+ while (*src++ & kLASTCHAR) {}
+ int wordlen = src - src0;
+ return wordlen;
+}
+
+// returns length in words of a int32 *
+inline bool str4eq(const int32 *a, const int32 *b)
+{
+ while(true) {
+ if (*a != *b) return false;
+ if ((*a & kLASTCHAR) == 0) return true;
+ a++; b++;
+ }
+}
+
+// copy an int32 *
+inline void str4cpy(int32 *dst, const int32 *src)
+{
+ int32 c;
+ do {
+ *dst++ = c = *src++;
+ } while (c & kLASTCHAR);
+}
+
+inline int sc_atoi(char *string)
+{
+ int value = 0;
+ if (*string == 0) return -1;
+ uint32 c;
+ while ((c = *string++ - '0') <= 9) {
+ value = value * 10 + c;
+ }
+ return value;
+}
+
+
+#endif
diff --git a/sc4pd/headers/server/SC_SyncCondition.h b/sc4pd/headers/server/SC_SyncCondition.h
new file mode 100644
index 0000000..a75fbaa
--- /dev/null
+++ b/sc4pd/headers/server/SC_SyncCondition.h
@@ -0,0 +1,45 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_SyncCondition_
+#define _SC_SyncCondition_
+
+#include <pthread.h>
+
+class SC_SyncCondition
+{
+public:
+ SC_SyncCondition();
+ ~SC_SyncCondition();
+
+ void WaitEach();
+ void WaitOnce();
+ void WaitNext();
+ void Signal();
+
+private:
+ pthread_cond_t available;
+ pthread_mutex_t mutex;
+ int read, write;
+};
+
+#endif
+
diff --git a/sc4pd/headers/server/SC_SynthDef.h b/sc4pd/headers/server/SC_SynthDef.h
new file mode 100644
index 0000000..89d5e47
--- /dev/null
+++ b/sc4pd/headers/server/SC_SynthDef.h
@@ -0,0 +1,43 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SynthDef_
+#define _SynthDef_
+
+#include "SC_Types.h"
+#include "sc_msg_iter.h"
+
+typedef void (*NodeDtorFunc)(struct Node* inNode);
+
+struct NodeDef
+{
+ int32 mName[kSCNameLen];
+ int32 mHash;
+
+ size_t mAllocSize;
+};
+typedef struct NodeDef NodeDef;
+
+extern NodeDef gGroupNodeDef;
+
+void GroupNodeDef_Init();
+void NodeDef_Dump(NodeDef *inNodeDef);
+
+#endif
diff --git a/sc4pd/headers/server/SC_UnitDef.h b/sc4pd/headers/server/SC_UnitDef.h
new file mode 100644
index 0000000..0f75490
--- /dev/null
+++ b/sc4pd/headers/server/SC_UnitDef.h
@@ -0,0 +1,69 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _UnitDef_
+#define _UnitDef_
+
+#include "SC_Types.h"
+#include "SC_Unit.h"
+#include "HashTable.h"
+
+struct PlugInCmd
+{
+ int32 mCmdName[kSCNameLen];
+ int32 mHash;
+ PlugInCmdFunc mFunc;
+ void *mUserData;
+};
+
+struct UnitCmd
+{
+ int32 mCmdName[kSCNameLen];
+ int32 mHash;
+ UnitCmdFunc mFunc;
+};
+
+struct UnitDef
+{
+ int32 mUnitDefName[kSCNameLen];
+ int32 mHash;
+
+ size_t mAllocSize;
+ UnitCtorFunc mUnitCtorFunc;
+ UnitDtorFunc mUnitDtorFunc;
+
+ HashTable<UnitCmd, Malloc>* mCmds;
+ uint32 mFlags;
+};
+
+extern "C" {
+bool UnitDef_Create(char *inName, size_t inAllocSize,
+ UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags);
+bool UnitDef_AddCmd(char *inUnitDefName, char *inCmdName, UnitCmdFunc inFunc);
+bool PlugIn_DefineCmd(char *inCmdName, PlugInCmdFunc inFunc, void *inUserData);
+}
+
+int Unit_DoCmd(World *inWorld, int inSize, char *inData);
+
+inline int32* GetKey(UnitCmd *inCmd) { return inCmd->mCmdName; }
+inline int32 GetHash(UnitCmd *inCmd) { return inCmd->mHash; }
+
+
+#endif
diff --git a/sc4pd/headers/server/SC_UnitSpec.h b/sc4pd/headers/server/SC_UnitSpec.h
new file mode 100644
index 0000000..c72e103
--- /dev/null
+++ b/sc4pd/headers/server/SC_UnitSpec.h
@@ -0,0 +1,41 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_UnitSpec_
+#define _SC_UnitSpec_
+
+#include <ctype.h> // for size_t
+
+#include "SC_Unit.h"
+
+struct UnitSpec
+{
+ struct UnitDef* mUnitDef;
+ int16 mCalcRate;
+ uint16 mNumInputs, mNumOutputs;
+ int16 mSpecialIndex;
+ struct InputSpec* mInputSpec;
+ struct OutputSpec* mOutputSpec;
+ struct Rate* mRateInfo;
+ size_t mAllocSize;
+};
+typedef struct UnitSpec UnitSpec;
+
+#endif
diff --git a/sc4pd/headers/server/SC_WireSpec.h b/sc4pd/headers/server/SC_WireSpec.h
new file mode 100644
index 0000000..33ea15c
--- /dev/null
+++ b/sc4pd/headers/server/SC_WireSpec.h
@@ -0,0 +1,47 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_WireSpec_
+#define _SC_WireSpec_
+
+#include "SC_Types.h"
+
+struct InputSpec
+{
+ // read from file:
+ int16 mFromUnitIndex;
+ int16 mFromOutputIndex;
+ // computed:
+ int16 mWireIndex;
+};
+typedef struct InputSpec InputSpec;
+
+struct OutputSpec
+{
+ // read from file:
+ int16 mCalcRate;
+ // computed:
+ int16 mWireIndex;
+ int16 mBufferIndex;
+ int16 mNumConsumers;
+};
+typedef struct OutputSpec OutputSpec;
+
+#endif
diff --git a/sc4pd/make-files.txt b/sc4pd/make-files.txt
new file mode 100644
index 0000000..486674f
--- /dev/null
+++ b/sc4pd/make-files.txt
@@ -0,0 +1,19 @@
+# all the source files from the package
+SRCDIR = source
+SRCS= \
+ main.cpp Dust.cpp MantissaMask.cpp Hasher.cpp Median.cpp \
+ BrownNoise.cpp ClipNoise.cpp GrayNoise.cpp WhiteNoise.cpp \
+ PinkNoise.cpp Dust2.cpp Crackle.cpp Rand.cpp TRand.cpp TExpRand.cpp \
+ IRand.cpp TIRand.cpp CoinGate.cpp support.cpp LinRand.cpp NRand.cpp\
+ ExpRand.cpp LFClipNoise.cpp LFNoise0.cpp LFNoise1.cpp LFNoise2.cpp \
+ Logistic.cpp Latoocarfian.cpp LinCong.cpp amclip.cpp scaleneg.cpp \
+ excess.cpp hypot.cpp ring1.cpp ring2.cpp ring3.cpp ring4.cpp \
+ difsqr.cpp sumsqr.cpp sqrdif.cpp sqrsum.cpp absdif.cpp LFSaw.cpp \
+ LFPulse.cpp Impulse.cpp Integrator.cpp Decay.cpp Decay2.cpp Lag.cpp \
+ Lag2.cpp Lag3.cpp LinExp.cpp DelayUnit.cpp DelayN.cpp DelayL.cpp \
+ DelayC.cpp CombN.cpp CombL.cpp CombC.cpp AllpassN.cpp AllpassL.cpp \
+ AllpassC.cpp PitchShift.cpp Resonz.cpp OnePole.cpp OneZero.cpp \
+ TwoPole.cpp TwoZero.cpp FOS.cpp SOS.cpp RLPF.cpp RHPF.cpp LPF.cpp \
+ HPF.cpp BPF.cpp BRF.cpp LPZ1.cpp HPZ1.cpp LPZ2.cpp HPZ2.cpp \
+ BPZ2.cpp BRZ2.cpp LFDNoise0.cpp LFDNoise1.cpp LFDNoise2.cpp \
+ sc+.cpp sc-.cpp scmul.cpp scdiv.cpp Convolution.cpp
diff --git a/sc4pd/makefile.max-msvc b/sc4pd/makefile.max-msvc
new file mode 100644
index 0000000..8a1225f
--- /dev/null
+++ b/sc4pd/makefile.max-msvc
@@ -0,0 +1,77 @@
+# makefile adapted from thomas grill's xsample makefile
+#
+# Makefile for MSVC++ 6 and .NET
+#
+# usage:
+# to build run "make -f makefile.max-msvc"
+#
+
+!include config-max-msvc.txt
+
+# includes
+INCPATH=/I$(MAXSDKPATH)\max-includes /I$(MAXSDKPATH)\msp-includes /I$(FLEXTPATH) /I./headers/plugin_interface /I./headers/common /I./headers/server /I./headers/app /I./headers/lang
+LDFLAGS=/LIBPATH:$(FLEXTPATH)
+
+!ifdef MSVCPATH
+INCPATH=$(INCPATH) /I$(MSVCPATH)\include
+LDFLAGS=$(LDFLAGS) /LIBPATH:$(MSVCPATH)\lib
+!endif
+
+!ifdef _DEBUG
+LIBS=flext_d-maxwin.lib
+!else
+LIBS=flext-maxwin.lib
+!endif
+
+LDFLAGS=$(LDFLAGS) /LIBPATH:$(MAXSDKPATH)\max-includes /LIBPATH:$(MAXSDKPATH)\msp-includes
+
+LIBS=$(LIBS) maxapi.lib maxaudio.lib
+
+# compiler definitions and flags
+DEFS=/DFLEXT_SYS=1 $(UFLAGS)
+
+CFLAGS=/ML /GR- /GD /Ox /GX /Zp2
+
+# the rest can stay untouched
+# ----------------------------------------------
+
+# all the source files from the package
+!include make-files.txt
+
+# -----------------------------------------------
+
+NAME=sc4pd
+EXT=mxe
+DIR=source
+
+all: $(OUTPATH) $(OUTPATH)\$(NAME).$(EXT)
+
+# remove build
+clean:
+ -del /q $(OUTPATH) > nul
+ -rmdir $(OUTPATH) > nul
+
+OBJS= $(SRCS:.c=.obj)
+OBJS= $(OBJS:.objpp=.obj)
+
+
+$(OUTPATH):
+ -mkdir $(OUTPATH) > nul
+
+{$(DIR)}.cpp{}.obj:
+ cl /c /LD $(CFLAGS) $(DEFS) $(INCPATH) $** /Fo$(OUTPATH)/$@
+
+{$(DIR)}.c{}.obj:
+ cl /c /LD $(CFLAGS) $(DEFS) $(INCPATH) $** /Fo$(OUTPATH)/$@
+
+
+$(OUTPATH)\$(NAME).$(EXT): $(OBJS)
+ cd $(OUTPATH)
+ link /DLL $(LDFLAGS) /out:$(NAME).$(EXT) /INCREMENTAL:NO $** $(LIBS) $(LIBPATH)
+ @-del *.exp
+ @-del *.lib
+ cd ..
+!ifdef INSTPATH
+ @-if not exist $(INSTPATH) mkdir $(INSTPATH)
+ copy $@ $(INSTPATH) > nul
+!endif
diff --git a/sc4pd/makefile.pd-bcc b/sc4pd/makefile.pd-bcc
new file mode 100644
index 0000000..41c06c2
--- /dev/null
+++ b/sc4pd/makefile.pd-bcc
@@ -0,0 +1,73 @@
+# makefile adapted from thomas grill's xsample makefile
+#
+# Makefile for BorlandC++
+#
+# usage: make -f makefile.pd-bcc
+#
+# ---------------------------------------------
+
+!include config-pd-bcc.txt
+
+# all the source files from the package
+!include make-files.txt
+
+SETUPFUNCTION=$(NAME)_setup
+
+# flext stuff
+TARGET=pdwin
+
+# includes, libs
+INCPATH=-I$(BCCPATH)\include -I$(PDPATH)\src -I$(FLEXTPATH) ./headers/plugin_interface ./headers/common ./headers/server ./headers/app ./headers/lang
+LIBPATH=-L$(BCCPATH)\lib -L$(PDPATH)\lib
+LIBS=cw32.lib import32.lib C0D32.OBJ
+
+# compiler definitions and flags
+DEFS=-DFLEXT_SYS=2
+CFLAGS=-tWD $(UFLAGS)
+
+
+# the rest can stay untouched
+# ----------------------------------------------
+
+# default target
+all: $(OUTPATH)\$(NAME).dll
+
+# remove build
+clean:
+ -del /s /q $(OUTPATH) > nul
+ rmdir $(OUTPATH)
+
+
+install:
+ cp $(OUTPATH)\$(NAME).dll $(INSTDIR)
+
+# ----------------------------------------------
+
+OBJS= $(SRCS:.cpp=.obj)
+
+#.PATH.OBJ=$(OUTPATH)
+
+#$(SRCS): $(HDRS)
+# -touch $<
+
+{$(SRCDIR)}.cpp.obj:
+ bcc32 -c $(CFLAGS) $(DEFS) $(INCPATH) -n$(OUTPATH) $<
+
+$(OUTPATH):
+ -@if not exist $< mkdir $<
+
+$(OUTPATH)\pd.lib: $(PDPATH)\bin\pd.dll
+ implib -a $< $**
+
+$(OUTPATH)\$(NAME).def:
+ @echo EXPORTS $(SETUPFUNCTION) = _$(SETUPFUNCTION) > $<
+# this next line fixes a strange problem with implib - lacking underscore?!
+ @echo IMPORTS _rtext_retext=PD.rtext_retext >> $<
+
+$(OUTPATH)\$(NAME).dll :: $(OUTPATH) $(OUTPATH)\$(NAME).def $(OUTPATH)\pd.lib
+
+$(OUTPATH)\$(NAME).dll :: $(OBJS)
+ cd $(OUTPATH)
+ ilink32 -C -Tpd $(LIBPATH) $** ,..\$<,,$(LIBS) pd.lib $(FLEXTPATH)\flext-$(TARGET).lib ,$(NAME).def
+ cd ..
+ \ No newline at end of file
diff --git a/sc4pd/makefile.pd-cygwin b/sc4pd/makefile.pd-cygwin
new file mode 100644
index 0000000..a04569d
--- /dev/null
+++ b/sc4pd/makefile.pd-cygwin
@@ -0,0 +1,86 @@
+# makefile adapted from thomas grill's xsample makefile
+#
+# Makefile for gcc @ cygwin
+#
+# usage:
+# to build run "make -f makefile.pd-cygwin"
+# to install (as root), do "make -f makefile.pd-cygwin install"
+#
+
+CONFIG=config-pd-cygwin.txt
+MAKEFILE=makefile.pd-cygwin
+
+include ${CONFIG}
+
+
+# compiler stuff
+# /usr/include holds the cygwin pthread headers and must be first!
+INCLUDES=/usr/include $(PDINC) ./headers/plugin_interface ./headers/common ./headers/server ./headers/app ./headers/lang
+
+FLAGS=-DFLEXT_SYS=2
+CFLAGS=-O2 -funroll-loops -fmove-all-movables -frerun-loop-opt -finline-functions -fno-rtti -fno-exceptions ${UFLAGS}
+
+PDLIBS=$(PD)/bin/pd.dll $(PD)/bin/pthreadVC.dll
+
+
+ifdef FLEXT_SHARED
+
+CFLAGS+=-DFLEXT_SHARED
+FLEXTLIB=$(FLEXTPATH)/flext.dll
+
+else
+
+FLEXTLIB=$(FLEXTPATH)/flext-pdwin.lib
+
+endif
+
+
+# ----------------------------------------------
+# the rest can stay untouched
+# ----------------------------------------------
+
+NAME=sc4pd
+
+include make-files.txt
+
+TARGET=$(TARGDIR)/$(NAME).dll
+
+# default target
+all: $(TARGDIR) $(TARGET)
+
+$(patsubst %,$(SRCDIR)/%,$(SRCS)): $(patsubst %,$(SRCDIR)/%,$(HDRS)) $(MAKEFILE) $(CONFIG)
+ touch $(patsubst %,$(SRCDIR)/%,$(SRCS))
+
+$(TARGDIR):
+ -mkdir $(TARGDIR)
+
+$(TARGDIR)/%.o : $(SRCDIR)/%.cpp
+ $(CXX) -c $(CFLAGS) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(FLEXTPATH)) $< -o $@
+
+$(TARGET) : $(patsubst %.cpp,$(TARGDIR)/%.o,$(SRCS)) $(FLEXTLIB)
+ $(CXX) -shared $(LDFLAGS) $^ ${PDLIBS} $(patsubst %,-l%,$(LIBS)) -o $@
+ strip --strip-unneeded $@
+ chmod 755 $@
+
+$(INSTDIR):
+ -mkdir $(INSTDIR)
+
+install:: $(INSTDIR)
+
+install:: $(TARGET)
+ cp $^ $(INSTDIR)
+# chown root.root $(patsubst %,$(INSTDIR)/%,$(notdir $^))
+
+$(HELPDIR):
+ -mkdir $(HELPDIR)
+
+install-help:: $(HELPDIR)
+
+install-help:: ./pd
+ chmod 644 $^/*.*
+ cp $^/*.* $(HELPDIR)
+
+
+.PHONY: clean
+clean:
+ rm -f $(TARGDIR)/*.o $(TARGET)
diff --git a/sc4pd/makefile.pd-darwin b/sc4pd/makefile.pd-darwin
new file mode 100755
index 0000000..9523425
--- /dev/null
+++ b/sc4pd/makefile.pd-darwin
@@ -0,0 +1,77 @@
+# makefile adapted from thomas grill's xsample makefile
+#
+# Makefile for gcc @ OSX (darwin)
+#
+# usage:
+# to build run "make -f makefile.pd-darwin"
+# to install (as root), do "make -f makefile.pd-darwin install"
+# to install help, do "make -f makefile.pd-darwin install-help"
+#
+
+CONFIG=config-pd-darwin.txt
+
+include ${CONFIG}
+
+FLEXTLIB=$(FLEXTPATH)/libflext.a
+
+# compiler stuff
+INCLUDES=$(PDINC) ./headers/plugin_interface ./headers/common ./headers/server ./headers/app ./headers/lang /usr/include/machine/
+FLAGS=-DFLEXT_SYS=2
+CFLAGS=${UFLAGS} -dynamic -O2 -Wno-unused -Wno-parentheses -Wno-switch -Wstrict-prototypes -funroll-loops -fmove-all-movables -frerun-loop-opt -fno-rtti -fno-exceptions
+LIBS=m gcc
+LDFLAGS=$(FLEXTLIB) -bundle -bundle_loader $(PDBIN)
+FRAMEWORKS=Carbon veclib
+
+# ----------------------------------------------
+# the rest can stay untouched
+# ----------------------------------------------
+
+NAME=sc4pd
+
+include make-files.txt
+
+MAKEFILE=makefile.pd-darwin
+TARGET=$(TARGDIR)/$(NAME).pd_darwin
+
+
+# default target
+all: $(TARGDIR) $(TARGET)
+
+$(patsubst %,$(SRCDIR)/%,$(SRCS)): $(patsubst %,$(SRCDIR)/%,$(HDRS)) $(MAKEFILE) $(CONFIG)
+ touch $(patsubst %,$(SRCDIR)/%,$(SRCS))
+
+$(TARGDIR):
+ -mkdir $(TARGDIR)
+
+$(TARGDIR)/%.o : $(SRCDIR)/%.cpp
+ $(CXX) -c $(CFLAGS) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(FLEXTPATH)) $< -o $@
+
+$(TARGET) : $(patsubst %.cpp,$(TARGDIR)/%.o,$(SRCS))
+ $(CXX) $(LDFLAGS) $^ $(patsubst %,-framework %,$(FRAMEWORKS)) $(patsubst %,-L%,$(LIBPATH)) $(patsubst %,-l%,$(LIBS)) -o $@
+ chmod 755 $@
+
+
+$(INSTDIR):
+ -mkdir $(INSTDIR)
+
+install:: $(INSTDIR)
+
+install:: $(TARGET)
+ cp -R $^ $(INSTDIR)
+# chown -R root.root $(INSTDIR)
+
+
+$(HELPDIR):
+ -mkdir $(HELPDIR)
+
+install-help:: $(HELPDIR)
+
+install-help:: ./pd
+ cp $^/*.* $(HELPDIR)
+# chown -R root.root $(HELPDIR)
+
+
+.PHONY: clean
+clean:
+ rm -f $(TARGDIR)/*.o $(TARGET)
+
diff --git a/sc4pd/makefile.pd-linux b/sc4pd/makefile.pd-linux
new file mode 100644
index 0000000..f1deedb
--- /dev/null
+++ b/sc4pd/makefile.pd-linux
@@ -0,0 +1,94 @@
+# makefile adapted from thomas grill's xsample makefile
+#
+# Makefile for gcc @ linux
+#
+# usage:
+# to build run "make -f makefile.pd-linux"
+# to install (as root), do "make -f makefile.pd-linux install"
+#
+
+CONFIG=config-pd-linux.txt
+
+include ${CONFIG}
+
+FLEXTLIB=$(FLEXTPATH)/flext.a
+
+# compiler stuff
+INCLUDES=$(PDINC) ./headers/plugin_interface ./headers/common \
+ ./headers/server ./headers/app ./headers/lang
+FLAGS=-DFLEXT_SYS=2
+CFLAGS=${UFLAGS} -O3 -I/home/tim/pd/externals/grill/flext/source -funroll-loops -fmove-all-movables -frerun-loop-opt -finline-functions -fno-rtti -fno-exceptions
+
+LIBS=m
+
+ifdef FLEXT_SHARED
+CFLAGS+=-DFLEXT_SHARED -DFLEXT_THREADS
+LDFLAGS+=-Bdynamic
+LINKFLEXT=-lflext_d
+else
+LINKFLEXT=$(FLEXTLIB)
+endif
+
+
+# ----------------------------------------------
+# the rest can stay untouched
+# ----------------------------------------------
+
+NAME=sc4pd
+
+include make-files.txt
+
+MAKEFILE=makefile.pd-linux
+TARGET=$(TARGDIR)/$(NAME).pd_linux
+
+# default target
+all: $(TARGDIR) $(TARGET)
+
+$(patsubst %,$(SRCDIR)/%,$(SRCS)): $(patsubst %,$(SRCDIR)/%,$(HDRS)) $(MAKEFILE) $(CONFIG)
+# touch $(patsubst %,$(SRCDIR)/%,$(SRCS))
+
+$(TARGDIR):
+ -mkdir $(TARGDIR)
+
+$(TARGDIR)/%.o : $(SRCDIR)/%.cpp
+ $(CXX) -c $(CFLAGS) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(FLEXTPATH)) $< -o $@
+
+$(TARGET) : $(patsubst %.cpp,$(TARGDIR)/%.o,$(SRCS))
+ $(CXX) $(LDFLAGS) -shared $^ $(patsubst %,-l%,$(LIBS)) -L$(FLEXTPATH) $(LINKFLEXT) -o $@
+ strip --strip-unneeded $@
+ chmod 755 $@
+
+$(INSTDIR):
+ -mkdir $(INSTDIR)
+
+install:: $(INSTDIR)
+
+install:: $(TARGET)
+ cp $^ $(INSTDIR)
+ chown root.root $(patsubst %,$(INSTDIR)/%,$(notdir $^))
+
+$(HELPDIR):
+ -mkdir $(HELPDIR)
+
+install-help:: $(HELPDIR)
+
+install-help:: ./pd
+ chmod 644 $^/*.*
+ cp $^/*.* $(HELPDIR)
+
+
+.PHONY: clean
+clean:
+ rm -f $(TARGDIR)/*.o $(TARGET)
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc4pd/makefile.pd-mingw b/sc4pd/makefile.pd-mingw
new file mode 100644
index 0000000..62cf1ae
--- /dev/null
+++ b/sc4pd/makefile.pd-mingw
@@ -0,0 +1,85 @@
+# makefile adapted from thomas grill's xsample makefile
+#
+# Makefile for gcc @ minGW
+#
+# usage:
+# to build run "make -f makefile.pd-mingw"
+# to install (as root), do "make -f makefile.pd-mingw install"
+#
+
+CONFIG=config-pd-mingw.txt
+MAKEFILE=makefile.pd-mingw
+
+include ${CONFIG}
+
+
+# compiler stuff
+INCLUDES=$(PDINC) ./headers/plugin_interface ./headers/common ./headers/server ./headers/app ./headers/lang
+
+FLAGS=-DFLEXT_SYS=2
+CFLAGS=-O2 -funroll-loops -fmove-all-movables -frerun-loop-opt -finline-functions -fno-rtti -fno-exceptions ${UFLAGS}
+
+PDLIBS=$(PD)/bin/pd.dll $(PD)/bin/pthreadVC.dll
+
+
+ifdef FLEXT_SHARED
+
+CFLAGS+=-DFLEXT_SHARED
+FLEXTLIB=$(FLEXTPATH)/flext.dll
+
+else
+
+FLEXTLIB=$(FLEXTPATH)/flext-pdwin.lib
+
+endif
+
+
+# ----------------------------------------------
+# the rest can stay untouched
+# ----------------------------------------------
+
+NAME=sc4pd
+
+include make-files.txt
+
+TARGET=$(TARGDIR)/$(NAME).dll
+
+# default target
+all: $(TARGDIR) $(TARGET)
+
+$(patsubst %,$(SRCDIR)/%,$(SRCS)): $(patsubst %,$(SRCDIR)/%,$(HDRS)) $(MAKEFILE) $(CONFIG)
+# echo touch $(patsubst %,$(SRCDIR)/%,$(SRCS)) # minGW has no touch
+
+$(TARGDIR):
+ -mkdir $(TARGDIR)
+
+$(TARGDIR)/%.o : $(SRCDIR)/%.cpp
+ $(CXX) -c $(CFLAGS) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(FLEXTPATH)) $< -o $@
+
+$(TARGET) : $(patsubst %.cpp,$(TARGDIR)/%.o,$(SRCS)) $(FLEXTLIB)
+ $(CXX) -shared $(LDFLAGS) $^ ${PDLIBS} $(patsubst %,-l%,$(LIBS)) -o $@
+ strip --strip-unneeded $@
+ chmod 755 $@
+
+$(INSTDIR):
+ -mkdir $(INSTDIR)
+
+install:: $(INSTDIR)
+
+install:: $(TARGET)
+ cp $^ $(INSTDIR)
+# chown root.root $(patsubst %,$(INSTDIR)/%,$(notdir $^))
+
+$(HELPDIR):
+ -mkdir $(HELPDIR)
+
+install-help:: $(HELPDIR)
+
+install-help:: ./pd
+ chmod 644 $^/*.*
+ cp $^/*.* $(HELPDIR)
+
+
+.PHONY: clean
+clean:
+ rm -f $(TARGDIR)/*.o $(TARGET)
diff --git a/sc4pd/makefile.pd-msvc b/sc4pd/makefile.pd-msvc
new file mode 100644
index 0000000..11ccda9
--- /dev/null
+++ b/sc4pd/makefile.pd-msvc
@@ -0,0 +1,53 @@
+# makefile adapted from thomas grill's xsample makefile
+#
+# Makefile for MSVC++ 6
+#
+# usage:
+# to build run "make -f makefile.pd-msvc"
+#
+
+!include config-pd-msvc.txt
+
+# includes
+INCPATH=/I"$(MSVCPATH)\include" /I"$(PDPATH)\src" /I"$(FLEXTPATH)" /I"./headers/plugin_interface" /I"./headers/common" /I"/headers/server" /I"./headers/app" /I"./headers/lang
+LIBPATH=/LIBPATH:"$(MSVCPATH)\lib" /LIBPATH:"$(PDPATH)\bin" /LIBPATH:"$(FLEXTPATH)"
+LIBS=pd.lib pthreadVC.lib flext-pdwin.lib
+
+# compiler definitions and flags
+DEFS=/DFLEXT_SYS=2
+
+CFLAGS=/GR- /GX- /GD /G6 /Ox /EHsc /ML
+
+# the rest can stay untouched
+# ----------------------------------------------
+
+NAME=sc4pd
+
+!include make-files.txt
+
+
+all: $(OUTPATH) $(OUTPATH)\$(NAME).dll
+
+# remove build
+clean:
+ -del /q $(OUTPATH) > nul
+ -rmdir $(OUTPATH) > nul
+
+OBJS= $(SRCS:.cpp=.obj)
+
+$(OUTPATH):
+ -mkdir $(OUTPATH) > nul
+
+{$(SRCDIR)}.cpp{}.obj:
+ cl /c /LD $(CFLAGS) $(DEFS) $(INCPATH) $** /Fo$(OUTPATH)\$@
+
+$(OUTPATH)\$(NAME).dll: $(OBJS)
+ cd $(OUTPATH)
+ link /DLL /out:$(NAME).dll /INCREMENTAL:NO $** $(LIBS) $(LIBPATH)
+ @-del *.exp
+ @-del *.lib
+ cd ..
+!ifdef INSTPATH
+ @-if not exist $(INSTPATH) mkdir $(INSTPATH)
+ copy $@ $(INSTPATH) > nul
+!endif
diff --git a/sc4pd/package.txt b/sc4pd/package.txt
new file mode 100644
index 0000000..c366fee
--- /dev/null
+++ b/sc4pd/package.txt
@@ -0,0 +1,24 @@
+NAME=sc4pd
+
+SRCDIR=source
+
+SRCS=main.cpp Dust.cpp MantissaMask.cpp Hasher.cpp Median.cpp \
+ BrownNoise.cpp ClipNoise.cpp GrayNoise.cpp WhiteNoise.cpp \
+ PinkNoise.cpp Dust2.cpp Crackle.cpp Rand.cpp TRand.cpp TExpRand.cpp \
+ IRand.cpp TIRand.cpp CoinGate.cpp support.cpp LinRand.cpp NRand.cpp\
+ ExpRand.cpp LFClipNoise.cpp LFNoise0.cpp LFNoise1.cpp LFNoise2.cpp \
+ Logistic.cpp Latoocarfian.cpp LinCong.cpp amclip.cpp scaleneg.cpp \
+ excess.cpp hypot.cpp ring1.cpp ring2.cpp ring3.cpp ring4.cpp \
+ difsqr.cpp sumsqr.cpp sqrdif.cpp sqrsum.cpp absdif.cpp LFSaw.cpp \
+ LFPulse.cpp Impulse.cpp Integrator.cpp Decay.cpp Decay2.cpp Lag.cpp \
+ Lag2.cpp Lag3.cpp LinExp.cpp DelayUnit.cpp DelayN.cpp DelayL.cpp \
+ DelayC.cpp CombN.cpp CombL.cpp CombC.cpp AllpassN.cpp AllpassL.cpp \
+ AllpassC.cpp PitchShift.cpp Resonz.cpp OnePole.cpp OneZero.cpp \
+ TwoPole.cpp TwoZero.cpp FOS.cpp SOS.cpp RLPF.cpp RHPF.cpp LPF.cpp \
+ HPF.cpp BPF.cpp BRF.cpp LPZ1.cpp HPZ1.cpp LPZ2.cpp HPZ2.cpp \
+ BPZ2.cpp BRZ2.cpp LFDNoise0.cpp LFDNoise1.cpp LFDNoise2.cpp \
+ sc+.cpp sc-.cpp scmul.cpp scdiv.cpp Convolution.cpp
+
+HDRS=DelayUnit.hpp fftlib.h sc4pd.hpp support.hpp
+
+INCPATH=-I./headers/plugin_interface -I./headers/common -I./headers/server \ No newline at end of file
diff --git a/sc4pd/pd/LinRand.pd b/sc4pd/pd/LinRand.pd
new file mode 100644
index 0000000..30c610f
--- /dev/null
+++ b/sc4pd/pd/LinRand.pd
@@ -0,0 +1,4 @@
+#N canvas 0 0 450 300 10;
+#X obj 226 70 LinRand 1 2 3;
+#X floatatom 226 95 5 0 0 0 - - -;
+#X connect 0 0 1 0;
diff --git a/sc4pd/pd/allpassc.pd b/sc4pd/pd/allpassc.pd
new file mode 100644
index 0000000..297cb91
--- /dev/null
+++ b/sc4pd/pd/allpassc.pd
@@ -0,0 +1,20 @@
+#N canvas 0 0 450 300 10;
+#X floatatom 188 40 5 0 0 0 - - -;
+#X obj 67 187 dac~;
+#X msg 185 88 delaytime \$1;
+#X obj 111 190 print~;
+#X obj 128 170 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 316 83 5 0 0 0 - - -;
+#X msg 316 107 decaytime \$1;
+#X obj 77 138 AllpassC~ 1 0.001 0.2;
+#X obj 79 57 Dust~ 55;
+#X connect 0 0 2 0;
+#X connect 2 0 7 0;
+#X connect 4 0 3 0;
+#X connect 5 0 6 0;
+#X connect 6 0 7 0;
+#X connect 7 0 1 0;
+#X connect 7 0 1 1;
+#X connect 7 0 3 0;
+#X connect 8 0 7 0;
diff --git a/sc4pd/pd/allpassl.pd b/sc4pd/pd/allpassl.pd
new file mode 100644
index 0000000..e2f3251
--- /dev/null
+++ b/sc4pd/pd/allpassl.pd
@@ -0,0 +1,20 @@
+#N canvas 0 0 450 300 10;
+#X floatatom 188 40 5 0 0 0 - - -;
+#X obj 67 187 dac~;
+#X msg 185 88 delaytime \$1;
+#X obj 111 190 print~;
+#X obj 128 170 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 316 83 5 0 0 0 - - -;
+#X msg 316 107 decaytime \$1;
+#X obj 79 57 Dust~ 4;
+#X obj 77 138 AllpassL~ 1 0.001 0.2;
+#X connect 0 0 2 0;
+#X connect 2 0 8 0;
+#X connect 4 0 3 0;
+#X connect 5 0 6 0;
+#X connect 6 0 8 0;
+#X connect 7 0 8 0;
+#X connect 8 0 1 0;
+#X connect 8 0 1 1;
+#X connect 8 0 3 0;
diff --git a/sc4pd/pd/allpassn.pd b/sc4pd/pd/allpassn.pd
new file mode 100644
index 0000000..c0406b9
--- /dev/null
+++ b/sc4pd/pd/allpassn.pd
@@ -0,0 +1,20 @@
+#N canvas 0 0 450 300 10;
+#X floatatom 188 40 5 0 0 0 - - -;
+#X obj 67 187 dac~;
+#X msg 185 88 delaytime \$1;
+#X obj 111 190 print~;
+#X obj 128 170 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 316 83 5 0 0 0 - - -;
+#X msg 316 107 decaytime \$1;
+#X obj 77 138 AllpassN~ 1 0.001 0.2;
+#X obj 79 57 Dust~ 4;
+#X connect 0 0 2 0;
+#X connect 2 0 7 0;
+#X connect 4 0 3 0;
+#X connect 5 0 6 0;
+#X connect 6 0 7 0;
+#X connect 7 0 1 0;
+#X connect 7 0 1 1;
+#X connect 7 0 3 0;
+#X connect 8 0 7 0;
diff --git a/sc4pd/pd/amclip.pd b/sc4pd/pd/amclip.pd
new file mode 100644
index 0000000..21cfb91
--- /dev/null
+++ b/sc4pd/pd/amclip.pd
@@ -0,0 +1,16 @@
+#N canvas 0 0 450 300 10;
+#X obj 33 137 amclip~;
+#X obj 26 88 osc~ 440;
+#X obj 22 176 dac~;
+#X floatatom 327 136 5 0 0 0 - - -;
+#X obj 96 113 osc~ 40;
+#X floatatom 222 99 5 0 0 0 - - -;
+#X floatatom 263 228 5 0 0 0 - - -;
+#X obj 263 181 amclip;
+#X connect 0 0 2 0;
+#X connect 0 0 2 1;
+#X connect 1 0 0 0;
+#X connect 3 0 7 1;
+#X connect 4 0 0 1;
+#X connect 5 0 7 0;
+#X connect 7 0 6 0;
diff --git a/sc4pd/pd/bpf.pd b/sc4pd/pd/bpf.pd
new file mode 100644
index 0000000..5255af9
--- /dev/null
+++ b/sc4pd/pd/bpf.pd
@@ -0,0 +1,15 @@
+#N canvas 0 0 450 300 10;
+#X obj 124 220 dac~;
+#X floatatom 224 81 5 0 0 0 - - -;
+#X obj 130 89 WhiteNoise~;
+#X msg 201 121 kfreq \$1;
+#X floatatom 294 81 5 0 0 0 - - -;
+#X obj 130 147 BPF~ 440 0.5;
+#X msg 271 121 krq \$1;
+#X connect 1 0 3 0;
+#X connect 2 0 5 0;
+#X connect 3 0 5 0;
+#X connect 4 0 6 0;
+#X connect 5 0 0 0;
+#X connect 5 0 0 1;
+#X connect 6 0 5 0;
diff --git a/sc4pd/pd/bpz2.pd b/sc4pd/pd/bpz2.pd
new file mode 100644
index 0000000..ffa4c77
--- /dev/null
+++ b/sc4pd/pd/bpz2.pd
@@ -0,0 +1,12 @@
+#N canvas 0 0 450 300 10;
+#X obj 12 159 dac~;
+#X floatatom 265 37 9 0 0 0 - - -;
+#X floatatom 266 110 9 0 0 0 - - -;
+#X obj 18 28 WhiteNoise~;
+#X obj 266 78 HPZ2;
+#X obj 18 86 BPZ2~;
+#X connect 1 0 4 0;
+#X connect 3 0 5 0;
+#X connect 4 0 2 0;
+#X connect 5 0 0 0;
+#X connect 5 0 0 1;
diff --git a/sc4pd/pd/brf.pd b/sc4pd/pd/brf.pd
new file mode 100644
index 0000000..df92c7c
--- /dev/null
+++ b/sc4pd/pd/brf.pd
@@ -0,0 +1,15 @@
+#N canvas 0 0 450 300 10;
+#X obj 124 220 dac~;
+#X floatatom 224 81 5 0 0 0 - - -;
+#X obj 130 89 WhiteNoise~;
+#X msg 201 121 kfreq \$1;
+#X floatatom 294 81 5 0 0 0 - - -;
+#X msg 271 121 krq \$1;
+#X obj 130 147 BRF~ 4440 4.3;
+#X connect 1 0 3 0;
+#X connect 2 0 6 0;
+#X connect 3 0 6 0;
+#X connect 4 0 5 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 6 0 0 1;
diff --git a/sc4pd/pd/brz2.pd b/sc4pd/pd/brz2.pd
new file mode 100644
index 0000000..5e61752
--- /dev/null
+++ b/sc4pd/pd/brz2.pd
@@ -0,0 +1,12 @@
+#N canvas 0 0 450 300 10;
+#X obj 12 159 dac~;
+#X floatatom 265 37 9 0 0 0 - - -;
+#X floatatom 266 110 9 0 0 0 - - -;
+#X obj 18 28 WhiteNoise~;
+#X obj 18 86 BRZ2~;
+#X obj 266 78 BRZ2;
+#X connect 1 0 5 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 4 0 0 1;
+#X connect 5 0 2 0;
diff --git a/sc4pd/pd/clipnoise.pd b/sc4pd/pd/clipnoise.pd
new file mode 100644
index 0000000..5a685b0
--- /dev/null
+++ b/sc4pd/pd/clipnoise.pd
@@ -0,0 +1,13 @@
+#N canvas 0 0 450 300 10;
+#X obj 89 48 ClipNoise~;
+#X obj 89 115 print~;
+#X obj 141 88 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 246 55 ClipNoise;
+#X floatatom 246 97 5 0 0 0 - - -;
+#X obj 251 27 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X connect 0 0 1 0;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 5 0 3 0;
diff --git a/sc4pd/pd/combc.pd b/sc4pd/pd/combc.pd
new file mode 100644
index 0000000..4baf6ef
--- /dev/null
+++ b/sc4pd/pd/combc.pd
@@ -0,0 +1,20 @@
+#N canvas 0 0 450 300 10;
+#X floatatom 188 40 5 0 0 0 - - -;
+#X obj 67 187 dac~;
+#X msg 185 88 delaytime \$1;
+#X obj 111 190 print~;
+#X obj 128 170 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 316 83 5 0 0 0 - - -;
+#X msg 316 107 decaytime \$1;
+#X obj 79 57 WhiteNoise~;
+#X obj 77 138 CombN~ 1 0.001 0.2;
+#X connect 0 0 2 0;
+#X connect 2 0 8 0;
+#X connect 4 0 3 0;
+#X connect 5 0 6 0;
+#X connect 6 0 8 0;
+#X connect 7 0 8 0;
+#X connect 8 0 1 0;
+#X connect 8 0 1 1;
+#X connect 8 0 3 0;
diff --git a/sc4pd/pd/combl.pd b/sc4pd/pd/combl.pd
new file mode 100644
index 0000000..b8fb0d2
--- /dev/null
+++ b/sc4pd/pd/combl.pd
@@ -0,0 +1,20 @@
+#N canvas 0 0 450 300 10;
+#X floatatom 188 40 5 0 0 0 - - -;
+#X obj 67 187 dac~;
+#X msg 185 88 delaytime \$1;
+#X obj 111 190 print~;
+#X obj 128 170 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 316 83 5 0 0 0 - - -;
+#X msg 316 107 decaytime \$1;
+#X obj 79 57 WhiteNoise~;
+#X obj 77 138 CombL~ 1 0.001 0.2;
+#X connect 0 0 2 0;
+#X connect 2 0 8 0;
+#X connect 4 0 3 0;
+#X connect 5 0 6 0;
+#X connect 6 0 8 0;
+#X connect 7 0 8 0;
+#X connect 8 0 1 0;
+#X connect 8 0 1 1;
+#X connect 8 0 3 0;
diff --git a/sc4pd/pd/combn.pd b/sc4pd/pd/combn.pd
new file mode 100644
index 0000000..4baf6ef
--- /dev/null
+++ b/sc4pd/pd/combn.pd
@@ -0,0 +1,20 @@
+#N canvas 0 0 450 300 10;
+#X floatatom 188 40 5 0 0 0 - - -;
+#X obj 67 187 dac~;
+#X msg 185 88 delaytime \$1;
+#X obj 111 190 print~;
+#X obj 128 170 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 316 83 5 0 0 0 - - -;
+#X msg 316 107 decaytime \$1;
+#X obj 79 57 WhiteNoise~;
+#X obj 77 138 CombN~ 1 0.001 0.2;
+#X connect 0 0 2 0;
+#X connect 2 0 8 0;
+#X connect 4 0 3 0;
+#X connect 5 0 6 0;
+#X connect 6 0 8 0;
+#X connect 7 0 8 0;
+#X connect 8 0 1 0;
+#X connect 8 0 1 1;
+#X connect 8 0 3 0;
diff --git a/sc4pd/pd/crackle.pd b/sc4pd/pd/crackle.pd
new file mode 100644
index 0000000..7cbb5a0
--- /dev/null
+++ b/sc4pd/pd/crackle.pd
@@ -0,0 +1,10 @@
+#N canvas 0 0 450 300 10;
+#X obj 266 210 dac~;
+#X obj 279 128 Crackle~ 2;
+#X obj 369 196 print~;
+#X obj 378 161 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X connect 1 0 0 0;
+#X connect 1 0 0 1;
+#X connect 1 0 2 0;
+#X connect 3 0 2 0;
diff --git a/sc4pd/pd/decay.pd b/sc4pd/pd/decay.pd
new file mode 100644
index 0000000..4d54e30
--- /dev/null
+++ b/sc4pd/pd/decay.pd
@@ -0,0 +1,12 @@
+#N canvas 0 0 450 300 10;
+#X obj 159 205 dac~;
+#X obj 239 198 print~;
+#X obj 244 171 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 149 72 Dust~ 440;
+#X obj 156 130 Decay~ 0.01;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 4 0 0 1;
+#X connect 4 0 1 0;
diff --git a/sc4pd/pd/decay2.pd b/sc4pd/pd/decay2.pd
new file mode 100644
index 0000000..98260f6
--- /dev/null
+++ b/sc4pd/pd/decay2.pd
@@ -0,0 +1,12 @@
+#N canvas 0 0 450 300 10;
+#X obj 159 205 dac~;
+#X obj 239 198 print~;
+#X obj 244 171 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 149 72 Dust~ 440;
+#X obj 156 130 Decay2~ 0.01 0.002;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 4 0 0 1;
+#X connect 4 0 1 0;
diff --git a/sc4pd/pd/delayc.pd b/sc4pd/pd/delayc.pd
new file mode 100644
index 0000000..2f539ff
--- /dev/null
+++ b/sc4pd/pd/delayc.pd
@@ -0,0 +1,11 @@
+#N canvas 0 0 450 300 10;
+#X floatatom 188 40 5 0 0 0 - - -;
+#X obj 67 187 dac~;
+#X msg 185 88 delaytime \$1;
+#X obj 77 138 CombN~ 0.01 0.003 3;
+#X obj 79 57 Dust~ 440;
+#X connect 0 0 2 0;
+#X connect 2 0 3 0;
+#X connect 3 0 1 0;
+#X connect 3 0 1 1;
+#X connect 4 0 3 0;
diff --git a/sc4pd/pd/delayl.pd b/sc4pd/pd/delayl.pd
new file mode 100644
index 0000000..690063b
--- /dev/null
+++ b/sc4pd/pd/delayl.pd
@@ -0,0 +1,11 @@
+#N canvas 0 0 450 300 10;
+#X floatatom 188 40 5 0 0 0 - - -;
+#X obj 90 233 dac~;
+#X msg 185 88 delaytime \$1;
+#X obj 79 57 Dust~ 4;
+#X obj 77 138 DelayL~ 1 3;
+#X connect 0 0 2 0;
+#X connect 2 0 4 0;
+#X connect 3 0 1 1;
+#X connect 3 0 4 0;
+#X connect 4 0 1 0;
diff --git a/sc4pd/pd/delayn.pd b/sc4pd/pd/delayn.pd
new file mode 100644
index 0000000..37b0c29
--- /dev/null
+++ b/sc4pd/pd/delayn.pd
@@ -0,0 +1,11 @@
+#N canvas 0 0 450 300 10;
+#X obj 77 138 DelayN~ 1 3;
+#X floatatom 188 40 5 0 0 0 - - -;
+#X obj 90 233 dac~;
+#X msg 185 88 delaytime \$1;
+#X obj 79 57 Dust~ 4;
+#X connect 0 0 2 0;
+#X connect 1 0 3 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 4 0 2 1;
diff --git a/sc4pd/pd/dust.pd b/sc4pd/pd/dust.pd
new file mode 100644
index 0000000..6a709ec
--- /dev/null
+++ b/sc4pd/pd/dust.pd
@@ -0,0 +1,11 @@
+#N canvas 0 0 450 300 10;
+#X obj 96 130 dac~;
+#X floatatom 264 119 5 0 0 0 - - -;
+#X obj 123 109 Median~ 20;
+#X obj 72 51 Dust~ 600;
+#X obj 123 82 Dust~ 1000;
+#X obj 264 82 Dust 1;
+#X connect 2 0 0 1;
+#X connect 3 0 0 0;
+#X connect 4 0 2 0;
+#X connect 5 0 1 0;
diff --git a/sc4pd/pd/excess.pd b/sc4pd/pd/excess.pd
new file mode 100644
index 0000000..3edde5e
--- /dev/null
+++ b/sc4pd/pd/excess.pd
@@ -0,0 +1,16 @@
+#N canvas 0 0 450 300 10;
+#X obj 26 88 osc~ 440;
+#X obj 22 176 dac~;
+#X floatatom 327 136 5 0 0 0 - - -;
+#X floatatom 222 99 5 0 0 0 - - -;
+#X floatatom 263 228 5 0 0 0 - - -;
+#X obj 33 137 excess~;
+#X obj 96 113 osc~ 45;
+#X obj 263 181 excess;
+#X connect 0 0 5 0;
+#X connect 2 0 7 1;
+#X connect 3 0 7 0;
+#X connect 5 0 1 0;
+#X connect 5 0 1 1;
+#X connect 6 0 5 1;
+#X connect 7 0 4 0;
diff --git a/sc4pd/pd/fos.pd b/sc4pd/pd/fos.pd
new file mode 100644
index 0000000..f03f45b
--- /dev/null
+++ b/sc4pd/pd/fos.pd
@@ -0,0 +1,45 @@
+#N canvas 0 0 539 300 10;
+#X obj 12 159 dac~;
+#X floatatom 112 20 5 0 0 0 - - -;
+#X obj 18 28 WhiteNoise~;
+#X obj 37 269 dac~;
+#X obj 95 174 Dust~ 444;
+#X obj 18 86 FOS~ 0.3 0.3 0.3;
+#X msg 89 60 a0 \$1;
+#X floatatom 161 20 5 0 0 0 - - -;
+#X msg 138 60 a1 \$1;
+#X floatatom 215 20 5 0 0 0 - - -;
+#X msg 192 60 b1 \$1;
+#X obj 46 229 FOS~ 0.3 0.3 0.3 ar;
+#X floatatom 374 26 5 0 0 0 - - -;
+#X msg 351 66 a0 \$1;
+#X floatatom 423 26 5 0 0 0 - - -;
+#X msg 400 66 a1 \$1;
+#X floatatom 477 26 5 0 0 0 - - -;
+#X msg 454 66 b1 \$1;
+#X obj 280 92 FOS 0.3 0.3 0.3;
+#X floatatom 282 129 5 0 0 0 - - -;
+#X floatatom 283 36 5 0 0 0 - - -;
+#X connect 1 0 6 0;
+#X connect 2 0 5 0;
+#X connect 4 0 11 1;
+#X connect 4 0 11 0;
+#X connect 4 0 11 2;
+#X connect 4 0 11 3;
+#X connect 5 0 0 0;
+#X connect 5 0 0 1;
+#X connect 6 0 5 0;
+#X connect 7 0 8 0;
+#X connect 8 0 5 0;
+#X connect 9 0 10 0;
+#X connect 10 0 5 0;
+#X connect 11 0 3 0;
+#X connect 11 0 3 1;
+#X connect 12 0 13 0;
+#X connect 13 0 18 0;
+#X connect 14 0 15 0;
+#X connect 15 0 18 0;
+#X connect 16 0 17 0;
+#X connect 17 0 18 0;
+#X connect 18 0 19 0;
+#X connect 20 0 18 0;
diff --git a/sc4pd/pd/hasher.pd b/sc4pd/pd/hasher.pd
new file mode 100644
index 0000000..532f032
--- /dev/null
+++ b/sc4pd/pd/hasher.pd
@@ -0,0 +1,17 @@
+#N canvas 0 0 450 300 10;
+#X obj 18 28 osc~ 441;
+#X obj 12 159 dac~;
+#X obj 89 131 print~;
+#X obj 144 112 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 265 37 9 0 0 0 - - -;
+#X floatatom 266 110 9 0 0 0 - - -;
+#X obj 266 78 Hasher;
+#X obj 18 86 Hasher~;
+#X connect 0 0 7 0;
+#X connect 3 0 2 0;
+#X connect 4 0 6 0;
+#X connect 6 0 5 0;
+#X connect 7 0 2 0;
+#X connect 7 0 1 0;
+#X connect 7 0 1 1;
diff --git a/sc4pd/pd/hpf.pd b/sc4pd/pd/hpf.pd
new file mode 100644
index 0000000..82de175
--- /dev/null
+++ b/sc4pd/pd/hpf.pd
@@ -0,0 +1,11 @@
+#N canvas 0 0 450 300 10;
+#X obj 124 220 dac~;
+#X floatatom 224 81 5 0 0 0 - - -;
+#X obj 130 89 WhiteNoise~;
+#X msg 201 121 kfreq \$1;
+#X obj 130 147 HPF~ 10000;
+#X connect 1 0 3 0;
+#X connect 2 0 4 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 4 0 0 1;
diff --git a/sc4pd/pd/hpz1.pd b/sc4pd/pd/hpz1.pd
new file mode 100644
index 0000000..1396d40
--- /dev/null
+++ b/sc4pd/pd/hpz1.pd
@@ -0,0 +1,12 @@
+#N canvas 0 0 450 300 10;
+#X obj 12 159 dac~;
+#X floatatom 265 37 9 0 0 0 - - -;
+#X floatatom 266 110 9 0 0 0 - - -;
+#X obj 266 78 HPZ1;
+#X obj 18 86 HPZ1~;
+#X obj 18 28 WhiteNoise~;
+#X connect 1 0 3 0;
+#X connect 3 0 2 0;
+#X connect 4 0 0 0;
+#X connect 4 0 0 1;
+#X connect 5 0 4 0;
diff --git a/sc4pd/pd/impulse.pd b/sc4pd/pd/impulse.pd
new file mode 100644
index 0000000..5381863
--- /dev/null
+++ b/sc4pd/pd/impulse.pd
@@ -0,0 +1,31 @@
+#N canvas 0 0 782 300 10;
+#X obj 93 170 dac~;
+#X obj 108 75 sig~ 440;
+#X floatatom 227 53 5 0 0 0 - - -;
+#X msg 20 31 kr;
+#X msg 62 30 ar;
+#X floatatom 363 150 5 0 0 0 - - -;
+#X obj 343 235 timer;
+#X floatatom 343 267 5 0 0 0 - - -;
+#X obj 353 197 t b b;
+#X msg 402 29 0.1;
+#X msg 451 39 kr 10;
+#X msg 223 88 freq \$1;
+#X obj 373 128 change;
+#X obj 107 117 Impulse~ 440 ar;
+#X obj 376 89 Impulse 1 20;
+#X connect 1 0 13 0;
+#X connect 2 0 11 0;
+#X connect 3 0 13 0;
+#X connect 4 0 13 0;
+#X connect 5 0 8 0;
+#X connect 6 0 7 0;
+#X connect 8 0 6 0;
+#X connect 8 1 6 1;
+#X connect 9 0 14 0;
+#X connect 10 0 14 0;
+#X connect 11 0 13 0;
+#X connect 12 0 5 0;
+#X connect 13 0 0 0;
+#X connect 13 0 0 1;
+#X connect 14 0 12 0;
diff --git a/sc4pd/pd/integrator.pd b/sc4pd/pd/integrator.pd
new file mode 100644
index 0000000..3c8719d
--- /dev/null
+++ b/sc4pd/pd/integrator.pd
@@ -0,0 +1,21 @@
+#N canvas 0 0 450 300 10;
+#X obj 12 159 dac~;
+#X obj 89 131 print~;
+#X obj 144 112 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 112 20 5 0 0 0 - - -;
+#X floatatom 265 37 9 0 0 0 - - -;
+#X floatatom 266 110 9 0 0 0 - - -;
+#X obj 18 86 Integrator~ 0.3;
+#X msg 89 60 leak \$1;
+#X obj 18 28 Dust~ 441;
+#X obj 266 78 Integrator 0.5;
+#X connect 2 0 1 0;
+#X connect 3 0 7 0;
+#X connect 4 0 9 0;
+#X connect 6 0 1 0;
+#X connect 6 0 0 0;
+#X connect 6 0 0 1;
+#X connect 7 0 6 0;
+#X connect 8 0 6 0;
+#X connect 9 0 5 0;
diff --git a/sc4pd/pd/lag.pd b/sc4pd/pd/lag.pd
new file mode 100644
index 0000000..206a07b
--- /dev/null
+++ b/sc4pd/pd/lag.pd
@@ -0,0 +1,17 @@
+#N canvas 0 0 450 300 10;
+#X obj 159 205 dac~;
+#X obj 239 198 print~;
+#X obj 244 171 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 257 82 hsl 128 15 1e-04 1 1 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 0 0;
+#X msg 254 102 lagTime \$1;
+#X obj 155 61 WhiteNoise~;
+#X obj 156 130 Lag~ 0.0004;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 4 0 6 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 6 0 0 1;
+#X connect 6 0 1 0;
diff --git a/sc4pd/pd/lag2.pd b/sc4pd/pd/lag2.pd
new file mode 100644
index 0000000..0398109
--- /dev/null
+++ b/sc4pd/pd/lag2.pd
@@ -0,0 +1,17 @@
+#N canvas 0 0 450 300 10;
+#X obj 159 205 dac~;
+#X obj 239 198 print~;
+#X obj 244 171 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 257 82 hsl 128 15 1e-04 1 1 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 0 0;
+#X msg 254 102 lagTime \$1;
+#X obj 155 61 WhiteNoise~;
+#X obj 156 130 Lag2~ 0.0004;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 4 0 6 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 6 0 0 1;
+#X connect 6 0 1 0;
diff --git a/sc4pd/pd/lag3.pd b/sc4pd/pd/lag3.pd
new file mode 100644
index 0000000..206a07b
--- /dev/null
+++ b/sc4pd/pd/lag3.pd
@@ -0,0 +1,17 @@
+#N canvas 0 0 450 300 10;
+#X obj 159 205 dac~;
+#X obj 239 198 print~;
+#X obj 244 171 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 257 82 hsl 128 15 1e-04 1 1 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 0 0;
+#X msg 254 102 lagTime \$1;
+#X obj 155 61 WhiteNoise~;
+#X obj 156 130 Lag~ 0.0004;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 4 0 6 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 6 0 0 1;
+#X connect 6 0 1 0;
diff --git a/sc4pd/pd/latoocarfian.pd b/sc4pd/pd/latoocarfian.pd
new file mode 100644
index 0000000..a3fb7e1
--- /dev/null
+++ b/sc4pd/pd/latoocarfian.pd
@@ -0,0 +1,18 @@
+#N canvas 0 0 450 300 10;
+#X obj 89 115 print~;
+#X obj 141 88 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 128 161 dac~;
+#X obj 89 48 Latoocarfian~ 0.88 1.8 1.2 1.3;
+#X obj 231 125 Latoocarfian 0.88 1.8 1.2 1.3;
+#X floatatom 247 154 5 0 0 0 - - -;
+#X floatatom 410 152 5 0 0 0 - - -;
+#X obj 275 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X connect 1 0 0 0;
+#X connect 3 0 0 0;
+#X connect 3 0 2 0;
+#X connect 3 1 2 1;
+#X connect 4 0 5 0;
+#X connect 4 1 6 0;
+#X connect 7 0 4 0;
diff --git a/sc4pd/pd/lfclipnoise.pd b/sc4pd/pd/lfclipnoise.pd
new file mode 100644
index 0000000..63f2eb7
--- /dev/null
+++ b/sc4pd/pd/lfclipnoise.pd
@@ -0,0 +1,13 @@
+#N canvas 0 0 450 300 10;
+#X floatatom 246 97 5 0 0 0 - - -;
+#X obj 246 55 LFClipNoise 10;
+#X obj 139 179 dac~;
+#X obj 89 154 *~ 0.1;
+#X obj 161 124 LFClipNoise~ 1001;
+#X obj 89 48 LFClipNoise~ 999;
+#X obj 161 151 *~ 0.1;
+#X connect 1 0 0 0;
+#X connect 3 0 2 0;
+#X connect 4 0 6 0;
+#X connect 5 0 3 0;
+#X connect 6 0 2 1;
diff --git a/sc4pd/pd/lfdnoise0.pd b/sc4pd/pd/lfdnoise0.pd
new file mode 100644
index 0000000..138cd66
--- /dev/null
+++ b/sc4pd/pd/lfdnoise0.pd
@@ -0,0 +1,5 @@
+#N canvas 0 0 450 300 10;
+#X obj 133 22 LFDNoise0~ 100;
+#X obj 131 56 dac~;
+#X connect 0 0 1 0;
+#X connect 0 0 1 1;
diff --git a/sc4pd/pd/lfnoise0.pd b/sc4pd/pd/lfnoise0.pd
new file mode 100644
index 0000000..afcc0a3
--- /dev/null
+++ b/sc4pd/pd/lfnoise0.pd
@@ -0,0 +1,17 @@
+#N canvas 0 0 450 300 10;
+#X obj 89 115 print~;
+#X obj 141 88 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 246 97 5 0 0 0 - - -;
+#X obj 89 48 LFNoise0~ 1000;
+#X obj 246 143 timer;
+#X obj 246 123 t b b;
+#X floatatom 246 168 5 0 0 0 - - -;
+#X obj 246 55 LFNoise0 10;
+#X connect 1 0 0 0;
+#X connect 2 0 5 0;
+#X connect 3 0 0 0;
+#X connect 4 0 6 0;
+#X connect 5 0 4 0;
+#X connect 5 1 4 1;
+#X connect 7 0 2 0;
diff --git a/sc4pd/pd/lfnoise1.pd b/sc4pd/pd/lfnoise1.pd
new file mode 100644
index 0000000..6e401f1
--- /dev/null
+++ b/sc4pd/pd/lfnoise1.pd
@@ -0,0 +1,17 @@
+#N canvas 0 0 450 300 10;
+#X obj 89 115 print~;
+#X obj 141 88 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 246 97 5 0 0 0 - - -;
+#X obj 246 143 timer;
+#X obj 246 123 t b b;
+#X floatatom 246 168 5 0 0 0 - - -;
+#X obj 89 48 LFNoise1~ 100;
+#X obj 246 55 LFNoise1 10;
+#X connect 1 0 0 0;
+#X connect 2 0 4 0;
+#X connect 3 0 5 0;
+#X connect 4 0 3 0;
+#X connect 4 1 3 1;
+#X connect 6 0 0 0;
+#X connect 7 0 2 0;
diff --git a/sc4pd/pd/lfnoise2.pd b/sc4pd/pd/lfnoise2.pd
new file mode 100644
index 0000000..3874d41
--- /dev/null
+++ b/sc4pd/pd/lfnoise2.pd
@@ -0,0 +1,17 @@
+#N canvas 0 0 450 300 10;
+#X obj 89 115 print~;
+#X obj 141 88 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 246 97 5 0 0 0 - - -;
+#X obj 246 143 timer;
+#X obj 246 123 t b b;
+#X floatatom 246 168 5 0 0 0 - - -;
+#X obj 246 55 LFNoise2 10;
+#X obj 89 48 LFNoise2~ 100;
+#X connect 1 0 0 0;
+#X connect 2 0 4 0;
+#X connect 3 0 5 0;
+#X connect 4 0 3 0;
+#X connect 4 1 3 1;
+#X connect 6 0 2 0;
+#X connect 7 0 0 0;
diff --git a/sc4pd/pd/lfpulse.pd b/sc4pd/pd/lfpulse.pd
new file mode 100644
index 0000000..f8cdec5
--- /dev/null
+++ b/sc4pd/pd/lfpulse.pd
@@ -0,0 +1,42 @@
+#N canvas 0 0 782 300 10;
+#X obj 93 170 dac~;
+#X obj 108 75 sig~ 440;
+#X floatatom 227 53 5 0 0 0 - - -;
+#X msg 20 31 kr;
+#X msg 62 30 ar;
+#X floatatom 363 150 5 0 0 0 - - -;
+#X obj 343 235 timer;
+#X floatatom 343 267 5 0 0 0 - - -;
+#X obj 353 197 t b b;
+#X msg 402 29 0.1;
+#X msg 451 39 kr 10;
+#X msg 223 88 freq \$1;
+#X obj 107 117 LFPulse~ 440 0.3 ar;
+#X msg 162 48 width \$1;
+#X floatatom 162 20 5 0 0 0 - - -;
+#X obj 373 128 change;
+#X obj 376 89 LFPulse 1 0.5 20;
+#X msg 162 48 width \$1;
+#X floatatom 162 20 5 0 0 0 - - -;
+#X msg 598 46 width \$1;
+#X floatatom 598 18 5 0 0 0 - - -;
+#X connect 1 0 12 0;
+#X connect 2 0 11 0;
+#X connect 3 0 12 0;
+#X connect 4 0 12 0;
+#X connect 5 0 8 0;
+#X connect 6 0 7 0;
+#X connect 8 0 6 0;
+#X connect 8 1 6 1;
+#X connect 9 0 16 0;
+#X connect 10 0 16 0;
+#X connect 11 0 12 0;
+#X connect 12 0 0 0;
+#X connect 12 0 0 1;
+#X connect 13 0 12 0;
+#X connect 14 0 13 0;
+#X connect 15 0 5 0;
+#X connect 16 0 15 0;
+#X connect 18 0 17 0;
+#X connect 19 0 16 0;
+#X connect 20 0 19 0;
diff --git a/sc4pd/pd/lfsaw.pd b/sc4pd/pd/lfsaw.pd
new file mode 100644
index 0000000..ed3f7b3
--- /dev/null
+++ b/sc4pd/pd/lfsaw.pd
@@ -0,0 +1,29 @@
+#N canvas 0 0 782 300 10;
+#X obj 93 170 dac~;
+#X obj 107 117 LFSaw~ 440 ar;
+#X obj 108 75 sig~ 440;
+#X floatatom 227 53 5 0 0 0 - - -;
+#X msg 20 31 kr;
+#X msg 62 30 ar;
+#X floatatom 349 176 5 0 0 0 - - -;
+#X obj 343 235 timer;
+#X floatatom 343 267 5 0 0 0 - - -;
+#X obj 353 197 t b b;
+#X obj 376 89 LFSaw 2 50;
+#X msg 402 29 0.1;
+#X msg 451 39 kr 10;
+#X msg 223 88 freq \$1;
+#X connect 1 0 0 0;
+#X connect 1 0 0 1;
+#X connect 2 0 1 0;
+#X connect 3 0 13 0;
+#X connect 4 0 1 0;
+#X connect 5 0 1 0;
+#X connect 6 0 9 0;
+#X connect 7 0 8 0;
+#X connect 9 0 7 0;
+#X connect 9 1 7 1;
+#X connect 10 0 6 0;
+#X connect 11 0 10 0;
+#X connect 12 0 10 0;
+#X connect 13 0 1 0;
diff --git a/sc4pd/pd/lincong.pd b/sc4pd/pd/lincong.pd
new file mode 100644
index 0000000..c777695
--- /dev/null
+++ b/sc4pd/pd/lincong.pd
@@ -0,0 +1,17 @@
+#N canvas 257 167 708 300 10;
+#X obj 132 247 dac~;
+#X obj 228 253 print~;
+#X obj 309 229 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 286 73 LinCong 100 103 140 120002;
+#X obj 267 32 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 295 110 10 0 0 0 - - -;
+#X obj 577 226 block~ 64;
+#X obj 22 142 LinCong~ 13437 1433.34 1.34233e+06 4.33243e+09;
+#X connect 2 0 1 0;
+#X connect 3 0 5 0;
+#X connect 4 0 3 0;
+#X connect 7 0 0 0;
+#X connect 7 0 0 1;
+#X connect 7 0 1 0;
diff --git a/sc4pd/pd/linexp.pd b/sc4pd/pd/linexp.pd
new file mode 100644
index 0000000..5a7fc04
--- /dev/null
+++ b/sc4pd/pd/linexp.pd
@@ -0,0 +1,17 @@
+#N canvas 0 0 450 300 10;
+#X obj 31 230 dac~;
+#X obj 111 223 print~;
+#X obj 116 196 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 27 86 osc~ 440;
+#X obj 27 142 LinExp~ 0 1 0.001 2;
+#X floatatom 252 204 5 0 0 0 - - -;
+#X obj 246 151 LinExp 0 100 0.001 2;
+#X floatatom 248 123 5 0 0 0 - - -;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 4 0 0 1;
+#X connect 4 0 1 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 0;
diff --git a/sc4pd/pd/logistic.pd b/sc4pd/pd/logistic.pd
new file mode 100644
index 0000000..2bb42d6
--- /dev/null
+++ b/sc4pd/pd/logistic.pd
@@ -0,0 +1,24 @@
+#N canvas 0 0 450 300 10;
+#X obj 89 115 print~;
+#X floatatom 246 97 5 0 0 0 - - -;
+#X obj 246 143 timer;
+#X obj 246 123 t b b;
+#X floatatom 246 168 5 0 0 0 - - -;
+#X obj 246 55 Logistic 1 0.5;
+#X obj 246 17 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 74 159 dac~;
+#X obj 89 134 Logistic~ 1000 4 0.4;
+#X obj 116 90 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 89 48 Logistic~ 1000 4 0.4;
+#X connect 1 0 3 0;
+#X connect 2 0 4 0;
+#X connect 3 0 2 0;
+#X connect 3 1 2 1;
+#X connect 5 0 1 0;
+#X connect 6 0 5 0;
+#X connect 8 0 7 1;
+#X connect 9 0 0 0;
+#X connect 10 0 0 0;
+#X connect 10 0 7 0;
diff --git a/sc4pd/pd/lpf.pd b/sc4pd/pd/lpf.pd
new file mode 100644
index 0000000..1b952d6
--- /dev/null
+++ b/sc4pd/pd/lpf.pd
@@ -0,0 +1,11 @@
+#N canvas 0 0 450 300 10;
+#X obj 124 220 dac~;
+#X floatatom 224 81 5 0 0 0 - - -;
+#X obj 130 89 WhiteNoise~;
+#X msg 201 121 kfreq \$1;
+#X obj 130 147 LPF~ 440;
+#X connect 1 0 3 0;
+#X connect 2 0 4 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 4 0 0 1;
diff --git a/sc4pd/pd/lpz1.pd b/sc4pd/pd/lpz1.pd
new file mode 100644
index 0000000..fa413b3
--- /dev/null
+++ b/sc4pd/pd/lpz1.pd
@@ -0,0 +1,12 @@
+#N canvas 0 0 450 300 10;
+#X obj 12 159 dac~;
+#X floatatom 265 37 9 0 0 0 - - -;
+#X floatatom 266 110 9 0 0 0 - - -;
+#X obj 18 86 LPZ1~;
+#X obj 266 78 LPZ1;
+#X obj 18 28 WhiteNoise~;
+#X connect 1 0 4 0;
+#X connect 3 0 0 0;
+#X connect 3 0 0 1;
+#X connect 4 0 2 0;
+#X connect 5 0 3 0;
diff --git a/sc4pd/pd/lpz2.pd b/sc4pd/pd/lpz2.pd
new file mode 100644
index 0000000..a665b96
--- /dev/null
+++ b/sc4pd/pd/lpz2.pd
@@ -0,0 +1,12 @@
+#N canvas 0 0 450 300 10;
+#X obj 12 159 dac~;
+#X floatatom 265 37 9 0 0 0 - - -;
+#X floatatom 266 110 9 0 0 0 - - -;
+#X obj 18 28 WhiteNoise~;
+#X obj 18 86 LPZ2~;
+#X obj 266 78 LPZ2;
+#X connect 1 0 5 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 4 0 0 1;
+#X connect 5 0 2 0;
diff --git a/sc4pd/pd/mantissamask.pd b/sc4pd/pd/mantissamask.pd
new file mode 100644
index 0000000..b99ca00
--- /dev/null
+++ b/sc4pd/pd/mantissamask.pd
@@ -0,0 +1,21 @@
+#N canvas 0 0 450 300 10;
+#X obj 18 28 osc~ 441;
+#X obj 12 159 dac~;
+#X obj 89 131 print~;
+#X obj 144 112 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 112 20 5 0 0 0 - - -;
+#X floatatom 265 37 9 0 0 0 - - -;
+#X floatatom 266 110 9 0 0 0 - - -;
+#X obj 266 78 MantissaMask 0;
+#X obj 18 86 MantissaMask~ 3;
+#X msg 89 60 set \$1;
+#X connect 0 0 8 0;
+#X connect 3 0 2 0;
+#X connect 4 0 9 0;
+#X connect 5 0 7 0;
+#X connect 7 0 6 0;
+#X connect 8 0 2 0;
+#X connect 8 0 1 0;
+#X connect 8 0 1 1;
+#X connect 9 0 8 0;
diff --git a/sc4pd/pd/onepole.pd b/sc4pd/pd/onepole.pd
new file mode 100644
index 0000000..cd816f5
--- /dev/null
+++ b/sc4pd/pd/onepole.pd
@@ -0,0 +1,28 @@
+#N canvas 0 0 450 300 10;
+#X obj 12 159 dac~;
+#X obj 89 131 print~;
+#X obj 144 112 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 112 20 5 0 0 0 - - -;
+#X floatatom 265 37 9 0 0 0 - - -;
+#X floatatom 266 110 9 0 0 0 - - -;
+#X obj 18 28 WhiteNoise~;
+#X msg 89 60 coef \$1;
+#X obj 18 86 OnePole~ 0.3;
+#X obj 85 251 dac~;
+#X obj 94 211 OnePole~ 0.3 ar;
+#X obj 94 171 Dust~ 444;
+#X obj 266 78 OnePole 0.3;
+#X connect 2 0 1 0;
+#X connect 3 0 7 0;
+#X connect 4 0 12 0;
+#X connect 6 0 8 0;
+#X connect 7 0 8 0;
+#X connect 8 0 1 0;
+#X connect 8 0 0 0;
+#X connect 8 0 0 1;
+#X connect 10 0 9 0;
+#X connect 10 0 9 1;
+#X connect 11 0 10 1;
+#X connect 11 0 10 0;
+#X connect 12 0 5 0;
diff --git a/sc4pd/pd/onezero.pd b/sc4pd/pd/onezero.pd
new file mode 100644
index 0000000..2d68a0b
--- /dev/null
+++ b/sc4pd/pd/onezero.pd
@@ -0,0 +1,21 @@
+#N canvas 0 0 450 300 10;
+#X obj 12 159 dac~;
+#X obj 89 131 print~;
+#X obj 144 112 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 112 20 5 0 0 0 - - -;
+#X floatatom 265 37 9 0 0 0 - - -;
+#X floatatom 266 110 9 0 0 0 - - -;
+#X obj 18 28 WhiteNoise~;
+#X msg 89 60 coef \$1;
+#X obj 18 86 OneZero~ 0.3;
+#X obj 266 78 OneZero 0.3;
+#X connect 2 0 1 0;
+#X connect 3 0 7 0;
+#X connect 4 0 9 0;
+#X connect 6 0 8 0;
+#X connect 7 0 8 0;
+#X connect 8 0 1 0;
+#X connect 8 0 0 0;
+#X connect 8 0 0 1;
+#X connect 9 0 5 0;
diff --git a/sc4pd/pd/pitchshift.pd b/sc4pd/pd/pitchshift.pd
new file mode 100644
index 0000000..e7653bc
--- /dev/null
+++ b/sc4pd/pd/pitchshift.pd
@@ -0,0 +1,19 @@
+#N canvas 317 183 450 300 10;
+#X floatatom 152 51 5 0 0 0 - - -;
+#X obj 67 187 dac~;
+#X floatatom 264 55 5 0 0 0 - - -;
+#X obj 76 55 osc~ 440;
+#X msg 152 80 pitchRatio \$1;
+#X msg 264 79 pitchDispersion \$1;
+#X floatatom 264 101 5 0 0 0 - - -;
+#X msg 264 125 timeDispersion \$1;
+#X obj 62 129 PitchShift~ 0.02 0.5 0 0;
+#X connect 0 0 4 0;
+#X connect 2 0 5 0;
+#X connect 3 0 8 0;
+#X connect 4 0 8 0;
+#X connect 5 0 8 0;
+#X connect 6 0 7 0;
+#X connect 7 0 8 0;
+#X connect 8 0 1 0;
+#X connect 8 0 1 1;
diff --git a/sc4pd/pd/resonz.pd b/sc4pd/pd/resonz.pd
new file mode 100644
index 0000000..e23cf4e
--- /dev/null
+++ b/sc4pd/pd/resonz.pd
@@ -0,0 +1,15 @@
+#N canvas 0 0 450 300 10;
+#X floatatom 188 40 5 0 0 0 - - -;
+#X obj 67 187 dac~;
+#X floatatom 316 83 5 0 0 0 - - -;
+#X msg 185 88 freq \$1;
+#X msg 316 107 rq \$1;
+#X obj 79 57 Dust~ 44;
+#X obj 77 138 Resonz~ 440 20;
+#X connect 0 0 3 0;
+#X connect 2 0 4 0;
+#X connect 3 0 6 0;
+#X connect 4 0 6 0;
+#X connect 5 0 6 0;
+#X connect 6 0 1 0;
+#X connect 6 0 1 1;
diff --git a/sc4pd/pd/rhpf.pd b/sc4pd/pd/rhpf.pd
new file mode 100644
index 0000000..228f368
--- /dev/null
+++ b/sc4pd/pd/rhpf.pd
@@ -0,0 +1,15 @@
+#N canvas 0 0 450 300 10;
+#X obj 124 220 dac~;
+#X floatatom 224 81 5 0 0 0 - - -;
+#X obj 130 89 WhiteNoise~;
+#X msg 201 121 kfreq \$1;
+#X floatatom 294 81 5 0 0 0 - - -;
+#X msg 271 121 kradius \$1;
+#X obj 130 147 RHPF~ 10000 0;
+#X connect 1 0 3 0;
+#X connect 2 0 6 0;
+#X connect 3 0 6 0;
+#X connect 4 0 5 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 6 0 0 1;
diff --git a/sc4pd/pd/rlpf.pd b/sc4pd/pd/rlpf.pd
new file mode 100644
index 0000000..1203edb
--- /dev/null
+++ b/sc4pd/pd/rlpf.pd
@@ -0,0 +1,15 @@
+#N canvas 0 0 450 300 10;
+#X obj 124 220 dac~;
+#X floatatom 224 81 5 0 0 0 - - -;
+#X obj 130 89 WhiteNoise~;
+#X msg 201 121 kfreq \$1;
+#X floatatom 294 81 5 0 0 0 - - -;
+#X msg 271 121 kradius \$1;
+#X obj 130 147 RLPF~ 440 0.5;
+#X connect 1 0 3 0;
+#X connect 2 0 6 0;
+#X connect 3 0 6 0;
+#X connect 4 0 5 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 6 0 0 1;
diff --git a/sc4pd/pd/scaleneg.pd b/sc4pd/pd/scaleneg.pd
new file mode 100644
index 0000000..70e6f14
--- /dev/null
+++ b/sc4pd/pd/scaleneg.pd
@@ -0,0 +1,16 @@
+#N canvas 0 0 450 300 10;
+#X obj 26 88 osc~ 440;
+#X obj 22 176 dac~;
+#X floatatom 327 136 5 0 0 0 - - -;
+#X floatatom 222 99 5 0 0 0 - - -;
+#X floatatom 263 228 5 0 0 0 - - -;
+#X obj 33 137 scaleneg~;
+#X obj 263 181 scaleneg;
+#X obj 96 113 osc~ 230;
+#X connect 0 0 5 0;
+#X connect 2 0 6 1;
+#X connect 3 0 6 0;
+#X connect 5 0 1 0;
+#X connect 5 0 1 1;
+#X connect 6 0 4 0;
+#X connect 7 0 5 1;
diff --git a/sc4pd/pd/sos.pd b/sc4pd/pd/sos.pd
new file mode 100644
index 0000000..b09be69
--- /dev/null
+++ b/sc4pd/pd/sos.pd
@@ -0,0 +1,38 @@
+#N canvas 0 0 539 300 10;
+#X obj 12 159 dac~;
+#X floatatom 112 20 5 0 0 0 - - -;
+#X obj 18 28 WhiteNoise~;
+#X obj 90 262 dac~;
+#X obj 206 145 Dust~ 444;
+#X msg 89 60 a0 \$1;
+#X floatatom 161 20 5 0 0 0 - - -;
+#X msg 138 60 a1 \$1;
+#X floatatom 262 20 5 0 0 0 - - -;
+#X msg 239 60 b1 \$1;
+#X obj 18 87 SOS~ 0.3 0.3 0.3 0.3 0.3;
+#X floatatom 212 20 5 0 0 0 - - -;
+#X floatatom 313 20 5 0 0 0 - - -;
+#X msg 189 60 a2 \$1;
+#X msg 290 60 b2 \$1;
+#X obj 85 208 SOS~ 0.3 0.3 0.3 0.3 0.3 ar;
+#X connect 1 0 5 0;
+#X connect 2 0 10 0;
+#X connect 4 0 15 0;
+#X connect 4 0 15 1;
+#X connect 4 0 15 2;
+#X connect 4 0 15 3;
+#X connect 4 0 15 4;
+#X connect 4 0 15 5;
+#X connect 5 0 10 0;
+#X connect 6 0 7 0;
+#X connect 7 0 10 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 0 0;
+#X connect 10 0 0 1;
+#X connect 11 0 13 0;
+#X connect 12 0 14 0;
+#X connect 13 0 10 0;
+#X connect 14 0 10 0;
+#X connect 15 0 3 1;
+#X connect 15 0 3 0;
diff --git a/sc4pd/pd/trand.pd b/sc4pd/pd/trand.pd
new file mode 100644
index 0000000..3f9cbde
--- /dev/null
+++ b/sc4pd/pd/trand.pd
@@ -0,0 +1,16 @@
+#N canvas 0 0 450 300 10;
+#X obj 277 115 TRand 2 3;
+#X floatatom 280 143 6 0 0 0 - - -;
+#X obj 275 88 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 144 74 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 144 96 t b b;
+#X obj 144 154 print~;
+#X obj 174 118 TRand~ 1 3;
+#X connect 0 0 1 0;
+#X connect 2 0 0 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 4 1 6 0;
+#X connect 6 0 5 0;
diff --git a/sc4pd/pd/twopole.pd b/sc4pd/pd/twopole.pd
new file mode 100644
index 0000000..b781655
--- /dev/null
+++ b/sc4pd/pd/twopole.pd
@@ -0,0 +1,15 @@
+#N canvas 0 0 450 300 10;
+#X obj 124 220 dac~;
+#X floatatom 224 81 5 0 0 0 - - -;
+#X obj 130 89 WhiteNoise~;
+#X obj 130 147 TwoPole~ 440 0.5;
+#X msg 201 121 kfreq \$1;
+#X floatatom 294 81 5 0 0 0 - - -;
+#X msg 271 121 kradius \$1;
+#X connect 1 0 4 0;
+#X connect 2 0 3 0;
+#X connect 3 0 0 0;
+#X connect 3 0 0 1;
+#X connect 4 0 3 0;
+#X connect 5 0 6 0;
+#X connect 6 0 3 0;
diff --git a/sc4pd/pd/twozero.pd b/sc4pd/pd/twozero.pd
new file mode 100644
index 0000000..3cd2c63
--- /dev/null
+++ b/sc4pd/pd/twozero.pd
@@ -0,0 +1,15 @@
+#N canvas 0 0 450 300 10;
+#X obj 124 220 dac~;
+#X floatatom 224 81 5 0 0 0 - - -;
+#X obj 130 89 WhiteNoise~;
+#X msg 201 121 kfreq \$1;
+#X floatatom 294 81 5 0 0 0 - - -;
+#X msg 271 121 kradius \$1;
+#X obj 130 160 TwoZero~ 440 0.5;
+#X connect 1 0 3 0;
+#X connect 2 0 6 0;
+#X connect 3 0 6 0;
+#X connect 4 0 5 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 6 0 0 1;
diff --git a/sc4pd/readme.txt b/sc4pd/readme.txt
new file mode 100644
index 0000000..9a09b43
--- /dev/null
+++ b/sc4pd/readme.txt
@@ -0,0 +1,26 @@
+sc4pd: SuperCollider for PureData
+(c) 2004 Tim Blechmann
+
+sc4pd includes the SuperCollider header files and is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+Both SuperCollider and sc4pd are released under the GPL
+
+
+sc4pd is a port of some SuperCollider UGens to PD objects. If you want to link
+both applications, it's better to use jack.
+sc4pd is using thomas grill's flext and should be portable to max/msp.
+
+
+thanks to:
+ James McCartney for SuperCollider
+ Miller Puckette for PureData
+ Thomas Grill for Flext
+ three great pieces of software...
+
+ thanks for bug reports:
+ Gerard (0001@ooo000ooo.org)
+
+bugs, suggestions, complains to: TimBlechmann@gmx.de \ No newline at end of file
diff --git a/sc4pd/source/AllpassC.cpp b/sc4pd/source/AllpassC.cpp
new file mode 100644
index 0000000..72c05f5
--- /dev/null
+++ b/sc4pd/source/AllpassC.cpp
@@ -0,0 +1,315 @@
+/* sc4pd
+ AllpassC~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Rashid Ali & Frank Lowe: Duo Exchange
+
+*/
+
+#include "sc4pd.hpp"
+#include "DelayUnit.hpp"
+
+class AllpassC_ar : public FeedbackDelay_ar
+{
+ FLEXT_HEADER(AllpassC_ar,FeedbackDelay_ar);
+
+ AllpassC_ar (int argc, t_atom *argv);
+ ~AllpassC_ar ();
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ delay_changed = decay_changed = false;
+ FeedbackDelay_Reset();
+ }
+
+ void m_delay(float f)
+ {
+ m_delaytime=f;
+ delay_changed = true;
+ }
+
+ void m_decay(float f)
+ {
+ m_decaytime=f;
+ decay_changed = true;
+ }
+
+private:
+ bool delay_changed, decay_changed;
+ DEFSIGCALL(m_signal_fun);
+ DEFSIGFUN(m_signal_);
+ DEFSIGFUN(m_signal_z);
+
+ FLEXT_CALLBACK_F(m_delay);
+ FLEXT_CALLBACK_F(m_decay);
+};
+
+FLEXT_LIB_DSP_V("AllpassC~",AllpassC_ar);
+
+AllpassC_ar::AllpassC_ar (int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"delaytime",m_delay);
+ FLEXT_ADDMETHOD_(0,"decaytime",m_decay);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 3)
+ {
+ post("3 arguments are needed");
+ return;
+ }
+
+ m_maxdelaytime = sc_getfloatarg(Args,0);
+ m_delaytime = sc_getfloatarg(Args,1);
+ m_decaytime = sc_getfloatarg(Args,2);
+
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z));
+
+ AddOutSignal();
+}
+
+AllpassC_ar::~AllpassC_ar ()
+{
+ DelayUnit_Dtor();
+}
+
+void AllpassC_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ float feedbk = m_feedbk;
+ long mask = m_mask;
+ float d0, d1, d2, d3;
+
+ if (delay_changed || decay_changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+
+ for (int i = 0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ long irdphase1 = iwrphase - idsamp;
+ long irdphase2 = irdphase1 - 1;
+ long irdphase3 = irdphase1 - 2;
+ long irdphase0 = irdphase1 + 1;
+
+ if (irdphase0 < 0)
+ {
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ ZXP(nout) = 0.f;
+ }
+ else
+ {
+ if (irdphase1 < 0)
+ {
+ d1 = d2 = d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ }
+ else if (irdphase2 < 0)
+ {
+ d1 = d2 = d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ }
+ else if (irdphase3 < 0)
+ {
+ d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ d2 = dlybuf[irdphase2 & mask];
+ }
+ else
+ {
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ d2 = dlybuf[irdphase2 & mask];
+ d3 = dlybuf[irdphase3 & mask];
+ }
+ float value = cubicinterp(frac, d0, d1, d2, d3);
+ float dwr = ZXP(nin) + feedbk * value;
+ dlybuf[iwrphase & mask] = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ }
+ feedbk += feedbk_slope;
+ iwrphase++;
+ }
+ m_feedbk = feedbk;
+ m_dsamp = dsamp;
+ delay_changed = decay_changed = false;
+ }
+ else
+ {
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+
+ for (int i = 0; i!= n;++i)
+ {
+ long irdphase1 = iwrphase - idsamp;
+ long irdphase2 = irdphase1 - 1;
+ long irdphase3 = irdphase1 - 2;
+ long irdphase0 = irdphase1 + 1;
+
+ if (irdphase0 < 0)
+ {
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ ZXP(nout) = 0.f;
+ }
+ else
+ {
+ if (irdphase1 < 0)
+ {
+ d1 = d2 = d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ }
+ else if (irdphase2 < 0)
+ {
+ d1 = d2 = d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ }
+ else if (irdphase3 < 0)
+ {
+ d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ d2 = dlybuf[irdphase2 & mask];
+ }
+ else
+ {
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ d2 = dlybuf[irdphase2 & mask];
+ d3 = dlybuf[irdphase3 & mask];
+ }
+ float value = cubicinterp(frac, d0, d1, d2, d3);
+ float dwr = ZXP(nin) + feedbk * value;
+ dlybuf[iwrphase & mask] = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ }
+ iwrphase++;
+ }
+ }
+
+ m_iwrphase = iwrphase;
+ m_numoutput += n;
+ if (m_numoutput >= m_idelaylen)
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_));
+ }
+}
+
+void AllpassC_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ float feedbk = m_feedbk;
+ long mask = m_mask;
+ float d0, d1, d2, d3;
+
+ if(delay_changed || decay_changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+
+ for(int i=0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ long irdphase1 = iwrphase - idsamp;
+ long irdphase2 = irdphase1 - 1;
+ long irdphase3 = irdphase1 - 2;
+ long irdphase0 = irdphase1 + 1;
+ float d0 = dlybuf[irdphase0 & mask];
+ float d1 = dlybuf[irdphase1 & mask];
+ float d2 = dlybuf[irdphase2 & mask];
+ float d3 = dlybuf[irdphase3 & mask];
+ float value = cubicinterp(frac, d0, d1, d2, d3);
+ float dwr = ZXP(nin) + feedbk * value;
+ dlybuf[iwrphase & mask] = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ feedbk += feedbk_slope;
+ iwrphase++;
+ }
+ m_feedbk = feedbk;
+ m_dsamp = dsamp;
+ delay_changed = decay_changed = false;
+ }
+ else
+ {
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ for(int i=0; i!= n;++i)
+ {
+ long irdphase1 = iwrphase - idsamp;
+ long irdphase2 = irdphase1 - 1;
+ long irdphase3 = irdphase1 - 2;
+ long irdphase0 = irdphase1 + 1;
+ float d0 = dlybuf[irdphase0 & mask];
+ float d1 = dlybuf[irdphase1 & mask];
+ float d2 = dlybuf[irdphase2 & mask];
+ float d3 = dlybuf[irdphase3 & mask];
+ float value = cubicinterp(frac, d0, d1, d2, d3);
+ float dwr = ZXP(nin) + feedbk * value;
+ dlybuf[iwrphase & mask] = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ iwrphase++;
+ }
+ }
+ m_iwrphase = iwrphase;
+}
+
+/* todo: AllpassC for control rate ? */
diff --git a/sc4pd/source/AllpassL.cpp b/sc4pd/source/AllpassL.cpp
new file mode 100644
index 0000000..2353df3
--- /dev/null
+++ b/sc4pd/source/AllpassL.cpp
@@ -0,0 +1,276 @@
+/* sc4pd
+ AllpassL~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Rashid Ali & Frank Lowe: Duo Exchange
+
+*/
+
+#include "sc4pd.hpp"
+#include "DelayUnit.hpp"
+
+class AllpassL_ar : public FeedbackDelay_ar
+{
+ FLEXT_HEADER(AllpassL_ar,FeedbackDelay_ar);
+
+ AllpassL_ar (int argc, t_atom *argv);
+ ~AllpassL_ar ();
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ delay_changed = decay_changed = false;
+ FeedbackDelay_Reset();
+ }
+
+ void m_delay(float f)
+ {
+ m_delaytime=f;
+ delay_changed = true;
+ }
+
+ void m_decay(float f)
+ {
+ m_decaytime=f;
+ decay_changed = true;
+ }
+
+private:
+ bool delay_changed, decay_changed;
+ DEFSIGCALL(m_signal_fun);
+ DEFSIGFUN(m_signal_);
+ DEFSIGFUN(m_signal_z);
+
+ FLEXT_CALLBACK_F(m_delay);
+ FLEXT_CALLBACK_F(m_decay);
+};
+
+FLEXT_LIB_DSP_V("AllpassL~",AllpassL_ar);
+
+AllpassL_ar::AllpassL_ar (int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"delaytime",m_delay);
+ FLEXT_ADDMETHOD_(0,"decaytime",m_decay);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 3)
+ {
+ post("3 arguments are needed");
+ return;
+ }
+
+ m_maxdelaytime = sc_getfloatarg(Args,0);
+ m_delaytime = sc_getfloatarg(Args,1);
+ m_decaytime = sc_getfloatarg(Args,2);
+
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z));
+
+ AddOutSignal();
+}
+
+AllpassL_ar::~AllpassL_ar ()
+{
+ DelayUnit_Dtor();
+}
+
+void AllpassL_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ float feedbk = m_feedbk;
+ long mask = m_mask;
+
+ if (delay_changed || decay_changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+
+ for (int i = 0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ long irdphase = iwrphase - idsamp;
+ long irdphaseb = irdphase - 1;
+
+ float zin = ZXP(nin);
+ if (irdphase < 0)
+ {
+ dlybuf[iwrphase & mask] = zin;
+ ZXP(nout) = - feedbk * zin; //check: probably a bug = 0?
+ }
+ else if (irdphaseb < 0)
+ {
+ float d1 = dlybuf[irdphase & mask];
+ float value = d1 - frac * d1;
+ float dwr = zin + feedbk * value;
+ dlybuf[iwrphase & mask] = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ }
+ else
+ {
+ float d1 = dlybuf[irdphase & mask];
+ float d2 = dlybuf[irdphaseb & mask];
+ float value = lininterp(frac, d1, d2);
+ float dwr = zin + feedbk * value;
+ dlybuf[iwrphase & mask] = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ }
+
+ feedbk += feedbk_slope;
+ iwrphase++;
+ }
+ m_feedbk = feedbk;
+ m_dsamp = dsamp;
+ delay_changed = decay_changed = false;
+ }
+ else
+ {
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+
+ float zin = ZXP(nin);
+ for (int i = 0; i!= n;++i)
+ {
+ long irdphase = iwrphase - idsamp;
+ long irdphaseb = irdphase - 1;
+
+ float zin = ZXP(nin);
+ if (irdphase < 0)
+ {
+ dlybuf[iwrphase & mask] = zin;
+ ZXP(nout) = - feedbk * zin;
+ }
+ else if (irdphaseb < 0)
+ {
+ float d1 = dlybuf[irdphase & mask];
+ float value = d1 - frac * d1;
+ float dwr = zin + feedbk * value;
+ dlybuf[iwrphase & mask] = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ }
+ else
+ {
+ float d1 = dlybuf[irdphase & mask];
+ float d2 = dlybuf[irdphaseb & mask];
+ float value = lininterp(frac, d1, d2);
+ float dwr = zin + feedbk * value;
+ dlybuf[iwrphase & mask] = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ }
+ iwrphase++;
+ }
+ }
+
+ m_iwrphase = iwrphase;
+ m_numoutput += n;
+ if (m_numoutput >= m_idelaylen)
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_));
+ }
+}
+
+void AllpassL_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ float feedbk = m_feedbk;
+ long mask = m_mask;
+
+ if(delay_changed || decay_changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+
+ for(int i=0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ long irdphase = iwrphase - idsamp;
+ long irdphaseb = irdphase - 1;
+ float d1 = dlybuf[irdphase & mask];
+ float d2 = dlybuf[irdphaseb & mask];
+ float value = lininterp(frac, d1, d2);
+ float dwr = ZXP(nin) + feedbk * value;
+ dlybuf[iwrphase & mask] = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ feedbk += feedbk_slope;
+ iwrphase++;
+ }
+ m_feedbk = feedbk;
+ m_dsamp = dsamp;
+ delay_changed = decay_changed = false;
+ }
+ else
+ {
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+
+ for(int i=0; i!= n;++i)
+ {
+ long irdphase = iwrphase - idsamp;
+ long irdphaseb = irdphase - 1;
+ float d1 = dlybuf[irdphase & mask];
+ float d2 = dlybuf[irdphaseb & mask];
+ float value = lininterp(frac, d1, d2);
+ float dwr = ZXP(nin) + feedbk * value;
+ dlybuf[iwrphase & mask] = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ iwrphase++;
+ }
+ }
+ m_iwrphase = iwrphase;
+}
+
+/* todo: AllpassL for control rate ? */
diff --git a/sc4pd/source/AllpassN.cpp b/sc4pd/source/AllpassN.cpp
new file mode 100644
index 0000000..a03130b
--- /dev/null
+++ b/sc4pd/source/AllpassN.cpp
@@ -0,0 +1,348 @@
+/* sc4pd
+ AllpassN~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Efzeg: Boogie
+
+*/
+
+#include "sc4pd.hpp"
+#include "DelayUnit.hpp"
+
+class AllpassN_ar : public FeedbackDelay_ar
+{
+ FLEXT_HEADER(AllpassN_ar,FeedbackDelay_ar);
+
+ AllpassN_ar (int argc, t_atom *argv);
+ ~AllpassN_ar ();
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ delay_changed = decay_changed = false;
+ FeedbackDelay_Reset();
+ }
+
+ void m_delay(float f)
+ {
+ m_delaytime=f;
+ delay_changed = true;
+ }
+
+ void m_decay(float f)
+ {
+ m_decaytime=f;
+ decay_changed = true;
+ }
+
+private:
+ bool delay_changed, decay_changed;
+ DEFSIGCALL(m_signal_fun);
+ DEFSIGFUN(m_signal_);
+ DEFSIGFUN(m_signal_z);
+
+ FLEXT_CALLBACK_F(m_delay);
+ FLEXT_CALLBACK_F(m_decay);
+};
+
+FLEXT_LIB_DSP_V("AllpassN~",AllpassN_ar);
+
+AllpassN_ar::AllpassN_ar (int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"delaytime",m_delay);
+ FLEXT_ADDMETHOD_(0,"decaytime",m_decay);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 3)
+ {
+ post("3 arguments are needed");
+ return;
+ }
+
+ m_maxdelaytime = sc_getfloatarg(Args,0);
+ m_delaytime = sc_getfloatarg(Args,1);
+ m_decaytime = sc_getfloatarg(Args,2);
+
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z));
+
+ AddOutSignal();
+}
+
+AllpassN_ar::~AllpassN_ar ()
+{
+ DelayUnit_Dtor();
+}
+
+void AllpassN_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ float feedbk = m_feedbk;
+ long mask = m_mask;
+
+ if (delay_changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+
+ for (int i = 0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ long irdphase = iwrphase - (long)dsamp;
+
+ if (irdphase < 0)
+ {
+ float dwr = ZXP(nin);
+ dlybuf[iwrphase & mask] = dwr;
+ ZXP(nout) = -feedbk * dwr;
+ }
+ else
+ {
+ float value = dlybuf[irdphase & mask];
+ float dwr = feedbk * value + ZXP(nin);
+ dlybuf[iwrphase & mask] = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ }
+ feedbk += feedbk_slope;
+ iwrphase++;
+ }
+ m_feedbk = feedbk;
+ m_dsamp = dsamp;
+ delay_changed = decay_changed = false;
+ }
+ else
+ {
+ long irdphase = iwrphase - (long)dsamp;
+ float* dlybuf1 = dlybuf - ZOFF;
+ float* dlyN = dlybuf1 + m_idelaylen;
+ if (decay_changed)
+ {
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+ long remain = n;
+ while (remain)
+ {
+ float* dlywr = dlybuf1 + (iwrphase & mask);
+ float* dlyrd = dlybuf1 + (irdphase & mask);
+ long rdspace = dlyN - dlyrd;
+ long wrspace = dlyN - dlywr;
+ long nsmps = sc_min(rdspace, wrspace);
+ nsmps = sc_min(remain, nsmps);
+ remain -= nsmps;
+ if (irdphase < 0)
+ {
+ dlyrd += nsmps;
+ for (int i = 0; i!= nsmps;++i)
+ {
+ float dwr = ZXP(nin);
+ ZXP(dlywr) = dwr;
+ ZXP(nout) = -feedbk * dwr;
+ feedbk += feedbk_slope;
+ }
+ }
+ else
+ {
+ for (int i = 0; i!= nsmps;++i)
+ {
+ float x1 = ZXP(dlyrd);
+ float dwr = x1 * feedbk + ZXP(nin);
+ ZXP(dlywr) = dwr;
+ ZXP(nout) = x1 - feedbk * dwr;
+ feedbk += feedbk_slope;
+ }
+ }
+ iwrphase += nsmps;
+ irdphase += nsmps;
+ }
+ decay_changed=false;
+ }
+ else
+ {
+ long remain = n;
+ while (remain)
+ {
+ float* dlyrd = dlybuf1 + (irdphase & mask);
+ float* dlywr = dlybuf1 + (iwrphase & mask);
+ long rdspace = dlyN - dlyrd;
+ long wrspace = dlyN - dlywr;
+ long nsmps = sc_min(rdspace, wrspace);
+ nsmps = sc_min(remain, nsmps);
+ remain -= nsmps;
+
+ if (irdphase < 0)
+ {
+ feedbk = -feedbk;
+ for (int i = 0; i!= nsmps;++i)
+ {
+ float dwr = ZXP(nin);
+ ZXP(dlywr) = dwr;
+ ZXP(nout) = feedbk * dwr;
+ }
+ feedbk = -feedbk;
+ }
+ else
+ {
+ for (int i = 0; i!= nsmps;++i)
+ {
+ float x1 = ZXP(dlyrd);
+ float dwr = x1 * feedbk + ZXP(nin);
+ ZXP(dlywr) = dwr;
+ ZXP(nout) = x1 - feedbk * dwr;
+ }
+ }
+ iwrphase += nsmps;
+ irdphase += nsmps;
+ }
+ m_feedbk = feedbk;
+ }
+ }
+
+ m_iwrphase = iwrphase;
+ m_numoutput += n;
+ if (m_numoutput >= m_idelaylen)
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_));
+ }
+}
+
+void AllpassN_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ float feedbk = m_feedbk;
+ long mask = m_mask;
+
+ if(delay_changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+
+ for(int i=0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ ++iwrphase;
+ long irdphase = iwrphase - (long)dsamp;
+ float value = dlybuf[irdphase & mask];
+ float dwr = value * feedbk + ZXP(nin);
+ dlybuf[iwrphase & mask] = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ feedbk += feedbk_slope;
+ }
+ m_feedbk = feedbk;
+ m_dsamp = dsamp;
+ delay_changed = decay_changed = false;
+ }
+ else
+ {
+ long irdphase = iwrphase - (long)dsamp;
+ float* dlybuf1 = dlybuf - ZOFF;
+ float* dlyrd = dlybuf1 + (irdphase & mask);
+ float* dlywr = dlybuf1 + (iwrphase & mask);
+ float* dlyN = dlybuf1 + m_idelaylen;
+
+ if(decay_changed)
+ {
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+ long remain = n;
+ while (remain)
+ {
+ long rdspace = dlyN - dlyrd;
+ long wrspace = dlyN - dlywr;
+ long nsmps = sc_min(rdspace, wrspace);
+ nsmps = sc_min(remain, nsmps);
+ remain -= nsmps;
+
+ for(int i=0; i!= nsmps;++i)
+ {
+ float value = ZXP(dlyrd);
+ float dwr = value * feedbk + ZXP(nin);
+ ZXP(dlywr) = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ feedbk += feedbk_slope;
+ }
+ if (dlyrd == dlyN) dlyrd = dlybuf1;
+ if (dlywr == dlyN) dlywr = dlybuf1;
+ }
+ m_feedbk = feedbk;
+ decay_changed = false;
+ }
+ else
+ {
+ long remain = n;
+ while (remain)
+ {
+ long rdspace = dlyN - dlyrd;
+ long wrspace = dlyN - dlywr;
+ long nsmps = sc_min(rdspace, wrspace);
+ nsmps = sc_min(remain, nsmps);
+ remain -= nsmps;
+
+ for (int i = 0; i!= nsmps; ++i)
+ {
+ float value = ZXP(dlyrd);
+ float dwr = value * feedbk + ZXP(nin);
+ ZXP(dlywr) = dwr;
+ ZXP(nout) = value - feedbk * dwr;
+ }
+ if (dlyrd == dlyN) dlyrd = dlybuf1;
+ if (dlywr == dlyN) dlywr = dlybuf1;
+ }
+
+ }
+ iwrphase += n;
+ }
+ m_iwrphase = iwrphase;
+}
+
+/* todo: AllpassN for control rate ? */
diff --git a/sc4pd/source/BPF.cpp b/sc4pd/source/BPF.cpp
new file mode 100644
index 0000000..f998dd4
--- /dev/null
+++ b/sc4pd/source/BPF.cpp
@@ -0,0 +1,190 @@
+/* sc4pd
+ BPF~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Jo Kondo: Works For Piano
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ BPF~ -------------------------------*/
+
+class BPF_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(BPF_ar,sc4pd_dsp);
+
+public:
+ BPF_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ mRadiansPerSample = sc_radianspersample();
+ mFilterSlope = sc_filterslope();
+ mFilterLoops = sc_filterloops();
+ mFilterRemain = sc_filterremain();
+ }
+
+ void m_set_freq(float f)
+ {
+ m_freq=f;
+ changed = true;
+ }
+
+ void m_set_rq(float f)
+ {
+ m_bw=f;
+ changed = true;
+ }
+
+
+private:
+ float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq, m_bw;
+ bool changed;
+ float mRadiansPerSample, mFilterSlope;
+ int mFilterLoops, mFilterRemain;
+
+ FLEXT_CALLBACK_F(m_set_freq);
+ FLEXT_CALLBACK_F(m_set_rq);
+};
+
+FLEXT_LIB_DSP_V("BPF~",BPF_ar);
+
+BPF_ar::BPF_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq);
+ FLEXT_ADDMETHOD_(0,"krq",m_set_rq);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+ m_bw = sc_getfloatarg(Args,1);
+ changed = true;
+
+ AddOutSignal();
+
+ m_a0 = 0.f;
+ m_b1 = 0.f;
+ m_b2 = 0.f;
+ m_y1 = 0.f;
+ m_y2 = 0.f;
+}
+
+void BPF_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float y0;
+ float y1 = m_y1;
+ float y2 = m_y2;
+ float a0 = m_a0;
+ float b1 = m_b1;
+ float b2 = m_b2;
+
+ if (changed)
+ {
+ float pfreq = m_freq * mRadiansPerSample;
+ float pbw = m_bw * pfreq * 0.5;
+
+ float C = 1.f / tan(pbw);
+ float D = 2.f * cos(pfreq);
+
+ float next_a0 = 1.f / (1.f + C);
+ float next_b1 = C * D * next_a0 ;
+ float next_b2 = (1.f - C) * next_a0;
+
+ float a0_slope = (next_a0 - a0) * mFilterSlope;
+ float b1_slope = (next_b1 - b1) * mFilterSlope;
+ float b2_slope = (next_b2 - b2) * mFilterSlope;
+
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 - y2);
+
+ y2 = ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = a0 * (y2 - y1);
+
+ y1 = ZXP(nin) + b1 * y2 + b2 * y0;
+ ZXP(nout) = a0 * (y1 - y0);
+
+ a0 += a0_slope;
+ b1 += b1_slope;
+ b2 += b2_slope;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 - y2);
+ y2 = y1;
+ y1 = y0;
+ }
+
+ m_a0 = a0;
+ m_b1 = b1;
+ m_b2 = b2;
+ changed = false;
+ }
+ else
+ {
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 - y2);
+
+ y2 = ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = a0 * (y2 - y1);
+
+ y1 = ZXP(nin) + b1 * y2 + b2 * y0;
+ ZXP(nout) = a0 * (y1 - y0);
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 - y2);
+ y2 = y1;
+ y1 = y0;
+ }
+ }
+ m_y1 = zapgremlins(y1);
+ m_y2 = zapgremlins(y2);
+}
+
+/* no control rate BPF filter */
diff --git a/sc4pd/source/BPZ2.cpp b/sc4pd/source/BPZ2.cpp
new file mode 100644
index 0000000..a18a9dc
--- /dev/null
+++ b/sc4pd/source/BPZ2.cpp
@@ -0,0 +1,140 @@
+/* sc4pd
+ BPZ2~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: William Parker: Compassion Seizes Bed-Stuy
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ BPZ2~ -------------------------------*/
+
+class BPZ2_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(BPZ2_ar,sc4pd_dsp);
+
+public:
+ BPZ2_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ mFilterLoops=sc_filterloops();
+ mFilterRemain=sc_filterremain();
+ }
+
+private:
+ float m_x1, m_x2;
+ int mFilterLoops, mFilterRemain;
+};
+
+FLEXT_LIB_DSP_V("BPZ2~",BPZ2_ar);
+
+BPZ2_ar::BPZ2_ar(int argc, t_atom *argv)
+{
+ AddOutSignal();
+
+ m_x1=0;
+ m_x2=0;
+}
+
+void BPZ2_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float x0;
+ float x1 = m_x1;
+ float x2 = m_x2;
+
+ for (int i = 0; i!=mFilterLoops ;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = (x0 - x2) * 0.5f;
+ x2 = ZXP(nin);
+ ZXP(nout) = (x2 - x1) * 0.5f;
+ x1 = ZXP(nin);
+ ZXP(nout) = (x1 - x0) * 0.5f;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = (x0 - x2) * 0.5f;
+ x2 = x1;
+ x1 = x0;
+ }
+ m_x1 = x1;
+ m_x2 = x2;
+}
+
+/* ------------------------ BPZ2 -------------------------------*/
+
+class BPZ2_kr:
+ public flext_base
+{
+ FLEXT_HEADER(BPZ2_kr,flext_base);
+
+public:
+ BPZ2_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform (float f);
+
+private:
+ float m_x1;
+ float m_x2;
+ FLEXT_CALLBACK_F(m_perform);
+};
+
+FLEXT_LIB_V("BPZ2",BPZ2_kr);
+
+BPZ2_kr::BPZ2_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(0,m_perform);
+
+ AddOutFloat();
+
+ m_x2 = m_x1 = 0;
+}
+
+void BPZ2_kr::m_perform(float f)
+{
+ ToOutFloat(0,(f - m_x2) * 0.5f);
+ m_x2=m_x1;
+ m_x1=f;
+}
+
diff --git a/sc4pd/source/BRF.cpp b/sc4pd/source/BRF.cpp
new file mode 100644
index 0000000..e6db680
--- /dev/null
+++ b/sc4pd/source/BRF.cpp
@@ -0,0 +1,199 @@
+/* sc4pd
+ BRF~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Jo Kondo: Works For Piano
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ BRF~ -------------------------------*/
+
+class BRF_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(BRF_ar,sc4pd_dsp);
+
+public:
+ BRF_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ mRadiansPerSample = sc_radianspersample();
+ mFilterSlope = sc_filterslope();
+ mFilterLoops = sc_filterloops();
+ mFilterRemain = sc_filterremain();
+ }
+
+ void m_set_freq(float f)
+ {
+ m_freq=f;
+ changed = true;
+ }
+
+ void m_set_rq(float f)
+ {
+ m_bw=f;
+ changed = true;
+ }
+
+
+private:
+ float m_y1, m_y2, m_a0, m_a1, m_b2, m_freq, m_bw;
+ bool changed;
+ float mRadiansPerSample, mFilterSlope;
+ int mFilterLoops, mFilterRemain;
+
+ FLEXT_CALLBACK_F(m_set_freq);
+ FLEXT_CALLBACK_F(m_set_rq);
+};
+
+FLEXT_LIB_DSP_V("BRF~",BRF_ar);
+
+BRF_ar::BRF_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq);
+ FLEXT_ADDMETHOD_(0,"krq",m_set_rq);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+ m_bw = sc_getfloatarg(Args,1);
+ changed = true;
+
+ AddOutSignal();
+
+ m_a0 = 0.f;
+ m_a1 = 0.f;
+ m_b2 = 0.f;
+ m_y1 = 0.f;
+ m_y2 = 0.f;
+}
+
+void BRF_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float ay;
+ float y0;
+ float y1 = m_y1;
+ float y2 = m_y2;
+ float a0 = m_a0;
+ float a1 = m_a1;
+ float b2 = m_b2;
+
+ if (changed)
+ {
+ float pfreq = m_freq * mRadiansPerSample;
+ float pbw = m_bw * pfreq * 0.5;
+
+ float C = tan(pbw);
+ float D = 2.f * cos(pfreq);
+
+ float next_a0 = 1.f / (1.f + C);
+ float next_a1 = -D * next_a0;
+ float next_b2 = (1.f - C) * next_a0;
+
+ float a0_slope = (next_a0 - a0) * mFilterSlope;
+ float a1_slope = (next_a1 - a1) * mFilterSlope;
+ float b2_slope = (next_b2 - b2) * mFilterSlope;
+
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ ay = a1 * y1;
+ y0 = ZXP(nin) - ay - b2 * y2;
+ ZXP(nout) = a0 * (y0 + y2) + ay;
+
+ ay = a1 * y0;
+ y2 = ZXP(nin) - ay - b2 * y1;
+ ZXP(nout) = a0 * (y2 + y1) + ay;
+
+ ay = a1 * y2;
+ y1 = ZXP(nin) - ay - b2 * y0;
+ ZXP(nout) = a0 * (y1 + y0) + ay;
+
+ a0 += a0_slope;
+ a1 += a1_slope;
+ b2 += b2_slope;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ ay = a1 * y1;
+ y0 = ZXP(nin) - ay - b2 * y2;
+ ZXP(nout) = a0 * (y0 + y2) + ay;
+ y2 = y1;
+ y1 = y0;
+ }
+
+ m_a0 = a0;
+ m_a1 = a1;
+ m_b2 = b2;
+ changed = false;
+ }
+ else
+ {
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ ay = a1 * y1;
+ y0 = ZXP(nin) - ay - b2 * y2;
+ ZXP(nout) = a0 * (y0 + y2) + ay;
+
+ ay = a1 * y0;
+ y2 = ZXP(nin) - ay - b2 * y1;
+ ZXP(nout) = a0 * (y2 + y1) + ay;
+
+ ay = a1 * y2;
+ y1 = ZXP(nin) - ay - b2 * y0;
+ ZXP(nout) = a0 * (y1 + y0) + ay;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ ay = a1 * y1;
+ y0 = ZXP(nin) - ay - b2 * y2;
+ ZXP(nout) = a0 * (y0 + y2) + ay;
+ y2 = y1;
+ y1 = y0;
+ }
+ }
+ m_y1 = zapgremlins(y1);
+ m_y2 = zapgremlins(y2);
+}
+
+/* no control rate BRF filter */
diff --git a/sc4pd/source/BRZ2.cpp b/sc4pd/source/BRZ2.cpp
new file mode 100644
index 0000000..4c14fa2
--- /dev/null
+++ b/sc4pd/source/BRZ2.cpp
@@ -0,0 +1,140 @@
+/* sc4pd
+ BRZ2~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: William Parker: Compassion Seizes Bed-Stuy
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ BRZ2~ -------------------------------*/
+
+class BRZ2_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(BRZ2_ar,sc4pd_dsp);
+
+public:
+ BRZ2_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ mFilterLoops=sc_filterloops();
+ mFilterRemain=sc_filterremain();
+ }
+
+private:
+ float m_x1, m_x2;
+ int mFilterLoops, mFilterRemain;
+};
+
+FLEXT_LIB_DSP_V("BRZ2~",BRZ2_ar);
+
+BRZ2_ar::BRZ2_ar(int argc, t_atom *argv)
+{
+ AddOutSignal();
+
+ m_x1=0;
+ m_x2=0;
+}
+
+void BRZ2_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float x0;
+ float x1 = m_x1;
+ float x2 = m_x2;
+
+ for (int i = 0; i!=mFilterLoops ;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = (x0 + x2) * 0.5f;
+ x2 = ZXP(nin);
+ ZXP(nout) = (x2 + x1) * 0.5f;
+ x1 = ZXP(nin);
+ ZXP(nout) = (x1 + x0) * 0.5f;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = (x0 + x2) * 0.5f;
+ x2 = x1;
+ x1 = x0;
+ }
+ m_x1 = x1;
+ m_x2 = x2;
+}
+
+/* ------------------------ BRZ2 -------------------------------*/
+
+class BRZ2_kr:
+ public flext_base
+{
+ FLEXT_HEADER(BRZ2_kr,flext_base);
+
+public:
+ BRZ2_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform (float f);
+
+private:
+ float m_x1;
+ float m_x2;
+ FLEXT_CALLBACK_F(m_perform);
+};
+
+FLEXT_LIB_V("BRZ2",BRZ2_kr);
+
+BRZ2_kr::BRZ2_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(0,m_perform);
+
+ AddOutFloat();
+
+ m_x2 = m_x1 = 0;
+}
+
+void BRZ2_kr::m_perform(float f)
+{
+ ToOutFloat(0,(f + m_x2) * 0.5f);
+ m_x2=m_x1;
+ m_x1=f;
+}
+
diff --git a/sc4pd/source/BrownNoise.cpp b/sc4pd/source/BrownNoise.cpp
new file mode 100644
index 0000000..316ee42
--- /dev/null
+++ b/sc4pd/source/BrownNoise.cpp
@@ -0,0 +1,156 @@
+/* sc4pd
+ BrownNoise, BrownNoise~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: AMM: Laminal
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ BrownNoise~ -------------------------------*/
+
+class BrownNoise_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(BrownNoise_ar,sc4pd_dsp);
+
+public:
+ BrownNoise_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float m_level;
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_DSP_V("BrownNoise~",BrownNoise_ar);
+
+BrownNoise_ar::BrownNoise_ar(int argc, t_atom *argv)
+{
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ rgen.init(timeseed());
+ m_level=rgen.frand2();
+
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ AddOutSignal();
+}
+
+
+void BrownNoise_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ RGET;
+
+ float z = m_level;
+
+ for (int i = 0; i!= n;++i)
+ {
+ z += frand8(s1, s2, s3);
+ if (z > 1.f)
+ z = 2.f - z;
+ else
+ if (z < -1.f)
+ z = -2.f - z;
+ (*(nout)++) = z;
+ }
+ m_level = z;
+
+ RPUT;
+}
+
+
+/* ------------------------ BrownNoise ---------------------------------*/
+
+class BrownNoise_kr:
+ public flext_base
+{
+ FLEXT_HEADER(BrownNoise_kr,flext_base);
+
+public:
+ BrownNoise_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform();
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float m_level;
+ RGen rgen;
+ FLEXT_CALLBACK(m_perform);
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("BrownNoise",BrownNoise_kr);
+
+BrownNoise_kr::BrownNoise_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDBANG(0,m_perform);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ rgen.init(timeseed());
+ m_level=rgen.frand2();
+
+ AddOutFloat();
+}
+
+void BrownNoise_kr::m_perform()
+{
+ float z = m_level + rgen.frand8();
+ if (z > 1.f)
+ z = 2.f - z;
+ else
+ if (z < -1.f)
+ z = -2.f - z;
+ ToOutFloat(0,z);
+ m_level = z;
+}
diff --git a/sc4pd/source/ClipNoise.cpp b/sc4pd/source/ClipNoise.cpp
new file mode 100644
index 0000000..39c0d61
--- /dev/null
+++ b/sc4pd/source/ClipNoise.cpp
@@ -0,0 +1,136 @@
+/* sc4pd
+ ClipNoise, ClipNoise~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Henry Threadgill: Everybodys Mouth's A Book
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ ClipNoise~ -------------------------------*/
+
+class ClipNoise_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(ClipNoise_ar,sc4pd_dsp);
+
+public:
+ ClipNoise_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_DSP_V("ClipNoise~",ClipNoise_ar);
+
+ClipNoise_ar::ClipNoise_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+}
+
+
+void ClipNoise_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ RGET;
+
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++) = fcoin(s1, s2, s3);
+ }
+
+ RPUT;
+}
+
+
+/* ------------------------ ClipNoise ---------------------------------*/
+
+class ClipNoise_kr:
+ public flext_base
+{
+ FLEXT_HEADER(ClipNoise_kr,flext_base);
+
+public:
+ ClipNoise_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform();
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ RGen rgen;
+ FLEXT_CALLBACK(m_perform);
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("ClipNoise",ClipNoise_kr);
+
+ClipNoise_kr::ClipNoise_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDBANG(0,m_perform);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ rgen.init(timeseed());
+
+ AddOutInt();
+}
+
+void ClipNoise_kr::m_perform()
+{
+ ToOutInt(0,rgen.fcoin());
+}
diff --git a/sc4pd/source/CoinGate.cpp b/sc4pd/source/CoinGate.cpp
new file mode 100644
index 0000000..fc47aca
--- /dev/null
+++ b/sc4pd/source/CoinGate.cpp
@@ -0,0 +1,84 @@
+/* sc4pd
+ CoinGate
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: the sounds coming through my open window
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ CoinGate ---------------------------------*/
+
+class CoinGate_kr:
+ public flext_base
+{
+ FLEXT_HEADER(CoinGate_kr,flext_base);
+
+public:
+ CoinGate_kr(int argc, t_atom *argv);
+
+protected:
+ void m_bang();
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float prob;
+ FLEXT_CALLBACK(m_bang);
+ FLEXT_CALLBACK_I(m_seed);
+ RGen rgen;
+};
+
+FLEXT_LIB_V("CoinGate",CoinGate_kr);
+
+CoinGate_kr::CoinGate_kr(int argc, t_atom *argv)
+{
+ AtomList Args(argc,argv);
+
+ rgen.init(timeseed());
+
+ prob = sc_getfloatarg(Args,0);
+
+ FLEXT_ADDBANG(0,m_bang);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+ AddOutBang();
+}
+
+void CoinGate_kr::m_bang()
+{
+ if(rgen.frand() < prob)
+ ToOutBang(0);
+}
diff --git a/sc4pd/source/CombC.cpp b/sc4pd/source/CombC.cpp
new file mode 100644
index 0000000..bed7384
--- /dev/null
+++ b/sc4pd/source/CombC.cpp
@@ -0,0 +1,314 @@
+/* sc4pd
+ CombC~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Butcher/Charles/Doerner: The Contest Of Pleasures
+
+*/
+
+#include "sc4pd.hpp"
+#include "DelayUnit.hpp"
+
+class CombC_ar : public FeedbackDelay_ar
+{
+ FLEXT_HEADER(CombC_ar,FeedbackDelay_ar);
+
+ CombC_ar (int argc, t_atom *argv);
+ ~CombC_ar ();
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ delay_changed = decay_changed = false;
+ FeedbackDelay_Reset();
+ }
+
+ void m_delay(float f)
+ {
+ m_delaytime=f;
+ delay_changed = true;
+ }
+
+ void m_decay(float f)
+ {
+ m_decaytime=f;
+ decay_changed = true;
+ }
+
+private:
+ bool delay_changed, decay_changed;
+ DEFSIGCALL(m_signal_fun);
+ DEFSIGFUN(m_signal_);
+ DEFSIGFUN(m_signal_z);
+
+ FLEXT_CALLBACK_F(m_delay);
+ FLEXT_CALLBACK_F(m_decay);
+};
+
+FLEXT_LIB_DSP_V("CombC~",CombC_ar);
+
+CombC_ar::CombC_ar (int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"delaytime",m_delay);
+ FLEXT_ADDMETHOD_(0,"decaytime",m_decay);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 3)
+ {
+ post("3 arguments are needed");
+ return;
+ }
+
+ m_maxdelaytime = sc_getfloatarg(Args,0);
+ m_delaytime = sc_getfloatarg(Args,1);
+ m_decaytime = sc_getfloatarg(Args,2);
+
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z));
+
+ AddOutSignal();
+}
+
+CombC_ar::~CombC_ar ()
+{
+ DelayUnit_Dtor();
+}
+
+void CombC_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ float feedbk = m_feedbk;
+ long mask = m_mask;
+ float d0, d1, d2, d3;
+
+ if (delay_changed || decay_changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+
+ for (int i = 0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ long irdphase1 = iwrphase - idsamp;
+ long irdphase2 = irdphase1 - 1;
+ long irdphase3 = irdphase1 - 2;
+ long irdphase0 = irdphase1 + 1;
+
+
+ if (irdphase0 < 0)
+ {
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ ZXP(nout) = 0.f;
+ }
+ else
+ {
+ if (irdphase1 < 0)
+ {
+ d1 = d2 = d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ }
+ else if (irdphase2 < 0)
+ {
+ d1 = d2 = d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ }
+ else if (irdphase3 < 0)
+ {
+ d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ d2 = dlybuf[irdphase2 & mask];
+ }
+ else
+ {
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ d2 = dlybuf[irdphase2 & mask];
+ d3 = dlybuf[irdphase3 & mask];
+ }
+ float value = cubicinterp(frac, d0, d1, d2, d3);
+ dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value;
+ ZXP(nout) = value;
+ }
+
+ feedbk += feedbk_slope;
+ iwrphase++;
+ }
+ m_feedbk = feedbk;
+ m_dsamp = dsamp;
+ delay_changed = decay_changed = false;
+ }
+ else
+ {
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+
+ for (int i = 0; i!= n;++i)
+ {
+ long irdphase1 = iwrphase - idsamp;
+ long irdphase2 = irdphase1 - 1;
+ long irdphase3 = irdphase1 - 2;
+ long irdphase0 = irdphase1 + 1;
+
+ if (irdphase0 < 0)
+ {
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ ZXP(nout) = 0.f;
+ }
+ else
+ {
+ if (irdphase1 < 0)
+ {
+ d1 = d2 = d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ }
+ else if (irdphase2 < 0)
+ {
+ d1 = d2 = d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ }
+ else if (irdphase3 < 0)
+ {
+ d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ d2 = dlybuf[irdphase2 & mask];
+ }
+ else
+ {
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ d2 = dlybuf[irdphase2 & mask];
+ d3 = dlybuf[irdphase3 & mask];
+ }
+ float value = cubicinterp(frac, d0, d1, d2, d3);
+ dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value;
+ ZXP(nout) = value;
+ }
+ iwrphase++;
+ }
+ }
+
+ m_iwrphase = iwrphase;
+ m_numoutput += n;
+ if (m_numoutput >= m_idelaylen)
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_));
+ }
+}
+
+void CombC_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ float feedbk = m_feedbk;
+ long mask = m_mask;
+ float d0, d1, d2, d3;
+
+ if(delay_changed || decay_changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+
+ for(int i=0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ long irdphase1 = iwrphase - idsamp;
+ long irdphase2 = irdphase1 - 1;
+ long irdphase3 = irdphase1 - 2;
+ long irdphase0 = irdphase1 + 1;
+ float d0 = dlybuf[irdphase0 & mask];
+ float d1 = dlybuf[irdphase1 & mask];
+ float d2 = dlybuf[irdphase2 & mask];
+ float d3 = dlybuf[irdphase3 & mask];
+ float value = cubicinterp(frac, d0, d1, d2, d3);
+ dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value;
+ ZXP(nout) = value;
+ feedbk += feedbk_slope;
+ iwrphase++;
+ }
+ m_feedbk = feedbk;
+ m_dsamp = dsamp;
+ delay_changed = decay_changed = false;
+ }
+ else
+ {
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+
+ for(int i=0; i!= n;++i)
+ {
+ long irdphase1 = iwrphase - idsamp;
+ long irdphase2 = irdphase1 - 1;
+ long irdphase3 = irdphase1 - 2;
+ long irdphase0 = irdphase1 + 1;
+ float d0 = dlybuf[irdphase0 & mask];
+ float d1 = dlybuf[irdphase1 & mask];
+ float d2 = dlybuf[irdphase2 & mask];
+ float d3 = dlybuf[irdphase3 & mask];
+ float value = cubicinterp(frac, d0, d1, d2, d3);
+ dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value;
+ ZXP(nout) = value;
+ iwrphase++;
+ }
+ }
+ m_iwrphase = iwrphase;
+}
+
+/* todo: CombC for control rate ? */
diff --git a/sc4pd/source/CombL.cpp b/sc4pd/source/CombL.cpp
new file mode 100644
index 0000000..9af21ae
--- /dev/null
+++ b/sc4pd/source/CombL.cpp
@@ -0,0 +1,272 @@
+/* sc4pd
+ CombL~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Butcher/Charles/Doerner: The Contest Of Pleasures
+
+*/
+
+#include "sc4pd.hpp"
+#include "DelayUnit.hpp"
+
+class CombL_ar : public FeedbackDelay_ar
+{
+ FLEXT_HEADER(CombL_ar,FeedbackDelay_ar);
+
+ CombL_ar (int argc, t_atom *argv);
+ ~CombL_ar ();
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ delay_changed = decay_changed = false;
+ FeedbackDelay_Reset();
+ }
+
+ void m_delay(float f)
+ {
+ m_delaytime=f;
+ delay_changed = true;
+ }
+
+ void m_decay(float f)
+ {
+ m_decaytime=f;
+ decay_changed = true;
+ }
+
+private:
+ bool delay_changed, decay_changed;
+ DEFSIGCALL(m_signal_fun);
+ DEFSIGFUN(m_signal_);
+ DEFSIGFUN(m_signal_z);
+
+ FLEXT_CALLBACK_F(m_delay);
+ FLEXT_CALLBACK_F(m_decay);
+};
+
+FLEXT_LIB_DSP_V("CombL~",CombL_ar);
+
+CombL_ar::CombL_ar (int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"delaytime",m_delay);
+ FLEXT_ADDMETHOD_(0,"decaytime",m_decay);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 3)
+ {
+ post("3 arguments are needed");
+ return;
+ }
+
+ m_maxdelaytime = sc_getfloatarg(Args,0);
+ m_delaytime = sc_getfloatarg(Args,1);
+ m_decaytime = sc_getfloatarg(Args,2);
+
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z));
+
+ AddOutSignal();
+}
+
+CombL_ar::~CombL_ar ()
+{
+ DelayUnit_Dtor();
+}
+
+void CombL_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ float feedbk = m_feedbk;
+ long mask = m_mask;
+
+ if (delay_changed || decay_changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+
+ for (int i = 0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ long irdphase = iwrphase - idsamp;
+ long irdphaseb = irdphase - 1;
+
+ float zin = ZXP(nin);
+ if (irdphase < 0)
+ {
+ dlybuf[iwrphase & mask] = zin;
+ ZXP(nout) = 0.f;
+ }
+ else if (irdphaseb < 0)
+ {
+ float d1 = dlybuf[irdphase & mask];
+ float value = d1 - frac * d1;
+ dlybuf[iwrphase & mask] = zin + feedbk * value;
+ ZXP(nout) = value;
+ }
+ else
+ {
+ float d1 = dlybuf[irdphase & mask];
+ float d2 = dlybuf[irdphaseb & mask];
+ float value = lininterp(frac, d1, d2);
+ dlybuf[iwrphase & mask] = zin + feedbk * value;
+ ZXP(nout) = value;
+ }
+
+ feedbk += feedbk_slope;
+ iwrphase++;
+ }
+ m_feedbk = feedbk;
+ m_dsamp = dsamp;
+ delay_changed = decay_changed = false;
+ }
+ else
+ {
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+
+ for (int i = 0; i!= n;++i)
+ {
+ long irdphase = iwrphase - idsamp;
+ long irdphaseb = irdphase - 1;
+
+ float zin = ZXP(nin);
+ if (irdphase < 0)
+ {
+ dlybuf[iwrphase & mask] = zin;
+ ZXP(nout) = 0.f;
+ }
+ else if (irdphaseb < 0)
+ {
+ float d1 = dlybuf[irdphase & mask];
+ float value = d1 - frac * d1;
+ dlybuf[iwrphase & mask] = zin + feedbk * value;
+ ZXP(nout) = value;
+ }
+ else
+ {
+ float d1 = dlybuf[irdphase & mask];
+ float d2 = dlybuf[irdphaseb & mask];
+ float value = lininterp(frac, d1, d2);
+ dlybuf[iwrphase & mask] = zin + feedbk * value;
+ ZXP(nout) = value;
+ }
+ iwrphase++;
+ }
+
+
+ }
+
+ m_iwrphase = iwrphase;
+ m_numoutput += n;
+ if (m_numoutput >= m_idelaylen)
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_));
+ }
+}
+
+void CombL_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ float feedbk = m_feedbk;
+ long mask = m_mask;
+
+ if(delay_changed || decay_changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+
+ for(int i=0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ long irdphase = iwrphase - idsamp;
+ long irdphaseb = irdphase - 1;
+ float d1 = dlybuf[irdphase & mask];
+ float d2 = dlybuf[irdphaseb & mask];
+ float value = lininterp(frac, d1, d2);
+ dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value;
+ ZXP(nout) = value;
+ feedbk += feedbk_slope;
+ iwrphase++;
+ }
+ m_feedbk = feedbk;
+ m_dsamp = dsamp;
+ delay_changed = decay_changed = false;
+ }
+ else
+ {
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+
+ for(int i=0; i!= n;++i)
+ {
+ long irdphase = iwrphase - idsamp;
+ long irdphaseb = irdphase - 1;
+ float d1 = dlybuf[irdphase & mask];
+ float d2 = dlybuf[irdphaseb & mask];
+ float value = lininterp(frac, d1, d2);
+ dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value;
+ ZXP(nout) = value;
+ iwrphase++;
+
+ }
+ }
+ m_iwrphase = iwrphase;
+}
+
+/* todo: CombL for control rate ? */
diff --git a/sc4pd/source/CombN.cpp b/sc4pd/source/CombN.cpp
new file mode 100644
index 0000000..9c6f33e
--- /dev/null
+++ b/sc4pd/source/CombN.cpp
@@ -0,0 +1,341 @@
+/* sc4pd
+ CombN~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Keith Rowe & John Tilbury: Duos For Doris
+
+*/
+
+#include "sc4pd.hpp"
+#include "DelayUnit.hpp"
+
+class CombN_ar : public FeedbackDelay_ar
+{
+ FLEXT_HEADER(CombN_ar,FeedbackDelay_ar);
+
+ CombN_ar (int argc, t_atom *argv);
+ ~CombN_ar ();
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ delay_changed = decay_changed = false;
+ FeedbackDelay_Reset();
+ }
+
+ void m_delay(float f)
+ {
+ m_delaytime=f;
+ delay_changed = true;
+ }
+
+ void m_decay(float f)
+ {
+ m_decaytime=f;
+ decay_changed = true;
+ }
+
+private:
+ bool delay_changed, decay_changed;
+ DEFSIGCALL(m_signal_fun);
+ DEFSIGFUN(m_signal_);
+ DEFSIGFUN(m_signal_z);
+
+ FLEXT_CALLBACK_F(m_delay);
+ FLEXT_CALLBACK_F(m_decay);
+};
+
+FLEXT_LIB_DSP_V("CombN~",CombN_ar);
+
+CombN_ar::CombN_ar (int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"delaytime",m_delay);
+ FLEXT_ADDMETHOD_(0,"decaytime",m_decay);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 3)
+ {
+ post("3 arguments are needed");
+ return;
+ }
+
+ m_maxdelaytime = sc_getfloatarg(Args,0);
+ m_delaytime = sc_getfloatarg(Args,1);
+ m_decaytime = sc_getfloatarg(Args,2);
+
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z));
+
+ AddOutSignal();
+}
+
+CombN_ar::~CombN_ar ()
+{
+ DelayUnit_Dtor();
+}
+
+void CombN_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ float feedbk = m_feedbk;
+ long mask = m_mask;
+
+ if (delay_changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+
+ for (int i = 0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ long irdphase = iwrphase - (long)dsamp;
+
+ if (irdphase < 0)
+ {
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ ZXP(nout) = 0.f;
+ }
+ else
+ {
+ float value = dlybuf[irdphase & mask];
+ dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value;
+ ZXP(nout) = value;
+ }
+ feedbk += feedbk_slope;
+ iwrphase++;
+ }
+ m_feedbk = feedbk;
+ m_dsamp = dsamp;
+ delay_changed = decay_changed = false;
+ }
+ else
+ {
+ long irdphase = iwrphase - (long)dsamp;
+ float* dlybuf1 = dlybuf - ZOFF;
+ float* dlyN = dlybuf1 + m_idelaylen;
+ if (decay_changed)
+ {
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+ long remain = n;
+ while (remain)
+ {
+ float* dlyrd = dlybuf1 + (irdphase & mask);
+ float* dlywr = dlybuf1 + (iwrphase & mask);
+ long rdspace = dlyN - dlyrd;
+ long wrspace = dlyN - dlywr;
+ long nsmps = sc_min(rdspace, wrspace);
+ nsmps = sc_min(remain, nsmps);
+ remain -= nsmps;
+
+ if (irdphase < 0)
+ {
+ feedbk += nsmps * feedbk_slope;
+ dlyrd += nsmps;
+ for (int i = 0; i!= nsmps;++i)
+ {
+ ZXP(dlywr) = ZXP(nin);
+ ZXP(nout) = 0.f;
+ }
+ }
+ else
+ {
+ for (int i = 0; i!= nsmps;++i)
+ {
+ float value = ZXP(dlyrd);
+ ZXP(dlywr) = value * feedbk + ZXP(nin);
+ ZXP(nout) = value;
+ feedbk += feedbk_slope;
+ }
+ }
+ iwrphase += nsmps;
+ irdphase += nsmps;
+ }
+ m_feedbk = feedbk;
+ decay_changed=false;
+ }
+ else
+ {
+ long remain = n;
+ while (remain)
+ {
+ float* dlywr = dlybuf1 + (iwrphase & mask);
+ float* dlyrd = dlybuf1 + (irdphase & mask);
+ long rdspace = dlyN - dlyrd;
+ long wrspace = dlyN - dlywr;
+ long nsmps = sc_min(rdspace, wrspace);
+ nsmps = sc_min(remain, nsmps);
+ remain -= nsmps;
+ if (irdphase < 0)
+ {
+ for (int i = 0; i!= nsmps;++i)
+ {
+ ZXP(dlywr) = ZXP(nin);
+ ZXP(nout) = 0.f;
+ }
+ }
+ else
+ {
+ for (int i = 0; i!= nsmps;++i)
+ {
+ float value = ZXP(dlyrd);
+ ZXP(dlywr) = value * feedbk + ZXP(nin);
+ ZXP(nout) = value;
+ }
+ }
+ iwrphase += nsmps;
+ irdphase += nsmps;
+ }
+
+ }
+ }
+
+ m_iwrphase = iwrphase;
+ m_numoutput += n;
+ if (m_numoutput >= m_idelaylen)
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_));
+ }
+}
+
+void CombN_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ float feedbk = m_feedbk;
+ long mask = m_mask;
+
+ if(delay_changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+
+ for(int i=0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ ++iwrphase;
+ long irdphase = iwrphase - (long)dsamp;
+ float value = dlybuf[irdphase & mask];
+ dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value;
+ ZXP(nout) = value;
+ feedbk += feedbk_slope;
+
+ }
+ m_feedbk = feedbk;
+ m_dsamp = dsamp;
+ delay_changed = decay_changed = false;
+ }
+ else
+ {
+ long irdphase = iwrphase - (long)dsamp;
+ float* dlybuf1 = dlybuf - ZOFF;
+ float* dlyrd = dlybuf1 + (irdphase & mask);
+ float* dlywr = dlybuf1 + (iwrphase & mask);
+ float* dlyN = dlybuf1 + m_idelaylen;
+
+ if(decay_changed)
+ {
+ float next_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+ float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
+ long remain = n;
+ while (remain)
+ {
+ long rdspace = dlyN - dlyrd;
+ long wrspace = dlyN - dlywr;
+ long nsmps = sc_min(rdspace, wrspace);
+ nsmps = sc_min(remain, nsmps);
+ remain -= nsmps;
+
+ for(int i=0; i!= nsmps;++i)
+ {
+ float value = ZXP(dlyrd);
+ ZXP(dlywr) = value * feedbk + ZXP(nin);
+ ZXP(nout) = value;
+ feedbk += feedbk_slope;
+ }
+ if (dlyrd == dlyN) dlyrd = dlybuf1;
+ if (dlywr == dlyN) dlywr = dlybuf1;
+ }
+ m_feedbk = feedbk;
+ decay_changed = false;
+ }
+ else
+ {
+ long remain = n;
+ while (remain)
+ {
+ long rdspace = dlyN - dlyrd;
+ long wrspace = dlyN - dlywr;
+ long nsmps = sc_min(rdspace, wrspace);
+ nsmps = sc_min(remain, nsmps);
+ remain -= nsmps;
+
+ for (int i = 0; i!= nsmps; ++i)
+ {
+ float value = ZXP(dlyrd);
+ ZXP(dlywr) = value * feedbk + ZXP(nin);
+ ZXP(nout) = value;
+ }
+ if (dlyrd == dlyN) dlyrd = dlybuf1;
+ if (dlywr == dlyN) dlywr = dlybuf1;
+ }
+
+ }
+ iwrphase += n;
+
+
+ }
+ m_iwrphase = iwrphase;
+}
+
+/* todo: CombN for control rate ? */
diff --git a/sc4pd/source/Convolution.cpp b/sc4pd/source/Convolution.cpp
new file mode 100644
index 0000000..0026b01
--- /dev/null
+++ b/sc4pd/source/Convolution.cpp
@@ -0,0 +1,222 @@
+/* sc4pd
+ Convolution~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Ambarchi/Muller/Voice Crack: Oystered
+
+*/
+
+#include "sc4pd.hpp"
+#include "fftlib.h"
+
+/* ------------------------ Convolution~ -------------------------------*/
+
+class Convolution_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(Convolution_ar,sc4pd_dsp);
+
+public:
+ Convolution_ar(int argc, t_atom *argv);
+ ~Convolution_ar();
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+ int m_pos, m_insize, m_fftsize,m_mask;
+ int m_log2n;
+
+ float *m_inbuf1,*m_inbuf2, *m_fftbuf1, *m_fftbuf2, *m_outbuf,*m_overlapbuf;
+
+};
+
+FLEXT_LIB_DSP_V("Convolution~",Convolution_ar);
+
+Convolution_ar::Convolution_ar(int argc, t_atom *argv)
+{
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_insize = sc_getfloatarg(Args,0);
+
+ AddInSignal("signal");
+ AddInSignal("kernel");
+ AddOutSignal();
+
+
+ //require size N+M-1 to be a power of two
+
+ m_fftsize=2*(m_insize);
+
+ //just use memory for the input buffers and fft buffers
+ int insize = m_insize * sizeof(float);
+ int fftsize = m_fftsize * sizeof(float);
+
+ m_inbuf1 = new float[m_insize];
+ m_inbuf2 = new float[m_insize];
+
+ m_fftbuf1 = new float[m_fftsize];
+ m_fftbuf2 = new float[m_fftsize];
+
+ m_outbuf = new float[m_fftsize];
+ m_overlapbuf = new float[m_insize];
+
+ memset(m_outbuf, 0, fftsize);
+ memset(m_overlapbuf, 0, insize);
+
+ m_log2n = LOG2CEIL(m_fftsize);
+
+ //test for full input buffer
+ m_mask = m_insize;
+ m_pos = 0;
+}
+
+Convolution_ar::~Convolution_ar()
+{
+ delete m_inbuf1;
+ delete m_inbuf2;
+
+ delete m_fftbuf1;
+ delete m_fftbuf2;
+
+ delete m_outbuf;
+ delete m_overlapbuf;
+}
+
+void Convolution_ar::m_dsp(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+
+}
+
+extern float* cosTable[32];
+
+void Convolution_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ float *in1 = in[0];
+ float *in2 = in[1];
+
+ float *out1 = m_inbuf1 + m_pos;
+ float *out2 = m_inbuf2 + m_pos;
+
+ int numSamples = 2*n; //??? mWorld->mFullRate.mBufLength;
+
+ // copy input
+ CopySamples(out1, in1, numSamples);
+ CopySamples(out2, in2, numSamples);
+
+ m_pos += numSamples;
+
+ if (m_pos & m_insize)
+ {
+
+ //have collected enough samples to transform next frame
+ m_pos = 0; //reset collection counter
+
+ // copy to fftbuf
+
+ uint32 insize=m_insize * sizeof(float);
+ memcpy(m_fftbuf1, m_inbuf1, insize);
+ memcpy(m_fftbuf2, m_inbuf2, insize);
+
+ //zero pad second part of buffer to allow for convolution
+ memset(m_fftbuf1+m_insize, 0, insize);
+ memset(m_fftbuf2+m_insize, 0, insize);
+
+ int log2n = m_log2n;
+
+
+ // do windowing
+ DoWindowing(log2n, m_fftbuf1, m_fftsize);
+ DoWindowing(log2n, m_fftbuf2, m_fftsize);
+
+ // do fft
+/* #if __VEC__
+ ctoz(m_fftbuf1, 2, outbuf1, 1, 1L<<log2n); ctoz(m_fftbuf2, 2, outbuf2, 1, 1L<<log2n);
+ #else */
+
+//in place transform for now
+ rffts(m_fftbuf1, log2n, 1, cosTable[log2n]);
+ rffts(m_fftbuf2, log2n, 1, cosTable[log2n]);
+//#endif
+
+//complex multiply time
+ int numbins = m_fftsize >> 1; //m_fftsize - 2 >> 1;
+
+ float * p1= m_fftbuf1;
+ float * p2= m_fftbuf2;
+
+ p1[0] *= p2[0];
+ p1[1] *= p2[1];
+
+ //complex multiply
+ for (int i=1; i<numbins; ++i) {
+ float real,imag;
+ int realind,imagind;
+ realind= 2*i; imagind= realind+1;
+ real= p1[realind]*p2[realind]- p1[imagind]*p2[imagind];
+ imag= p1[realind]*p2[imagind]+ p1[imagind]*p2[realind];
+ p1[realind] = real; //p2->bin[i];
+ p1[imagind]= imag;
+ }
+
+ //copy second part from before to overlap
+ memcpy(m_overlapbuf, m_outbuf+m_insize, m_insize * sizeof(float));
+
+ //inverse fft into outbuf
+ memcpy(m_outbuf, m_fftbuf1, m_fftsize * sizeof(float));
+
+ //in place
+ riffts(m_outbuf, log2n, 1, cosTable[log2n]);
+
+ DoWindowing(log2n, m_outbuf, m_fftsize);
+ }
+
+ //write out samples copied from outbuf, with overlap added in
+
+ float *output = out[0];
+ float *nout= m_outbuf+m_pos;
+ float *overlap= m_overlapbuf+m_pos;
+
+ for (int i=0; i<numSamples; ++i)
+ {
+ *++output = *++nout + *++overlap;
+ }
+
+}
+
+
+
+
diff --git a/sc4pd/source/Crackle.cpp b/sc4pd/source/Crackle.cpp
new file mode 100644
index 0000000..8f6c28f
--- /dev/null
+++ b/sc4pd/source/Crackle.cpp
@@ -0,0 +1,153 @@
+/* sc4pd
+ Crackle, Crackle~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: David S. Ware: Threads
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ Crackle~ -------------------------------*/
+
+class Crackle_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(Crackle_ar,sc4pd_dsp);
+
+public:
+ Crackle_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set(float f)
+ {
+ m_paramf = f;
+ }
+
+private:
+ FLEXT_CALLBACK_F(m_set);
+ float m_paramf;
+ float m_y1, m_y2;
+};
+
+FLEXT_LIB_DSP_V("Crackle~",Crackle_ar);
+
+Crackle_ar::Crackle_ar(int argc, t_atom *argv)
+ : m_y1(0.3f),m_y2(0.f)
+{
+ FLEXT_ADDMETHOD_(0,"parameter",m_set);
+ //parse arguments
+ AtomList Args(argc,argv);
+ m_paramf=sc_getfloatarg(Args,0);
+
+ if (m_paramf == 0)
+ m_paramf = 1;
+
+ AddOutSignal();
+}
+
+
+void Crackle_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float paramf = m_paramf;
+ float y1 = m_y1;
+ float y2 = m_y2;
+ float y0;
+
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++) = y0 = fabs(y1 * paramf - y2 - 0.05f);
+ y2 = y1;
+ y1 = y0;
+ }
+
+ m_y1=y1;
+ m_y2=y2;
+}
+
+
+/* ------------------------ Crackle ---------------------------------*/
+
+class Crackle_kr:
+ public flext_base
+{
+ FLEXT_HEADER(Crackle_kr,flext_base);
+
+public:
+ Crackle_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform();
+
+ void m_set(float f)
+ {
+ m_paramf = f;
+ }
+
+private:
+ float m_paramf;
+ float m_y1, m_y2;
+ FLEXT_CALLBACK(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("Crackle",Crackle_kr);
+
+Crackle_kr::Crackle_kr(int argc, t_atom *argv)
+ : m_y1(0.3f),m_y2(0.f)
+{
+ FLEXT_ADDBANG(0,m_perform);
+ FLEXT_ADDMETHOD_(0,"parameter",m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+ m_paramf=sc_getfloatarg(Args,0);
+
+ if (m_paramf == 0)
+ m_paramf = 1;
+
+ AddOutFloat();
+}
+
+void Crackle_kr::m_perform()
+{
+ float y0 = fabs(m_y1 * m_paramf - m_y2 - 0.05f);
+ m_y2 = m_y1;
+ m_y1 = y0;
+
+ ToOutFloat(0,y0);
+}
diff --git a/sc4pd/source/Decay.cpp b/sc4pd/source/Decay.cpp
new file mode 100644
index 0000000..c11a7a8
--- /dev/null
+++ b/sc4pd/source/Decay.cpp
@@ -0,0 +1,212 @@
+/* sc4pd
+ Decay~, Decay
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: AMM: AMMMusic 1966
+
+*/
+
+#include "sc4pd.hpp"
+
+/* todo: linear interpolation is broken */
+/* ------------------------ Decay~ -----------------------------*/
+
+class Decay_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(Decay_ar,sc4pd_dsp);
+
+public:
+ Decay_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+ void m_set(float f);
+
+private:
+ FLEXT_CALLBACK_F(m_set);
+ float m_b1; //leak
+ float m_y1; //z-1
+ float decayTime;
+};
+
+FLEXT_LIB_DSP_V("Decay~",Decay_ar);
+
+Decay_ar::Decay_ar(int argc,t_atom * argv)
+{
+ FLEXT_ADDMETHOD_(0,"decayTime",m_set);
+
+ AtomList Args(argc,argv);
+
+ decayTime = sc_getfloatarg(Args,0);
+
+ AddOutSignal();
+
+ m_y1 = 0.f;
+}
+
+void Decay_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin = *in;
+
+ float b1 = m_b1;
+ float y1 = m_y1;
+
+ if (b1 == m_b1)
+ {
+ if (b1 == 1.f)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = (*(nin)++);
+ (*(nout)++) = y1 = y0 + y1;
+ }
+
+ }
+ else if (b1 == 0.f)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = (*(nin)++);
+ (*(nout)++) = y1 = y0;
+ }
+ }
+ else
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = (*(nin)++);
+ (*(nout)++) = y1 = y0 + b1 * y1;
+ }
+ }
+ }
+ else
+ {
+ float b1_slope = CALCSLOPE(m_b1, b1);
+ if (b1 >= 0.f && m_b1 >= 0)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = (*(nin)++);
+ (*(nout)++) = y1 = y0 + b1 * (y1 - y0);
+ b1 += b1_slope;
+ }
+ }
+ else if (b1 <= 0.f && m_b1 <= 0)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = (*(nin)++);
+ (*(nout)++) = y1 = y0 + b1 * (y1 + y0);
+ b1 += b1_slope;
+ }
+ }
+ else
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = (*(nin)++);
+ (*(nout)++) = y1 = (1.f - fabs(b1)) * y0 + b1 * y1;
+ b1 += b1_slope;
+ }
+ }
+ }
+ m_y1 = zapgremlins(y1);
+}
+
+void Decay_ar::m_set(float f)
+{
+ decayTime = f;
+ m_b1= f == 0.f ? 0.f : exp(log001 / (decayTime * Samplerate()));
+}
+
+void Decay_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ m_b1= decayTime == 0.f ? 0.f : exp(log001 / (decayTime * Samplerate()));
+}
+
+/* todo: does it make sense to implement a message-based Decay?
+ Probably not... */
+
+
+/* ------------------------ Decay ------------------------------*/
+
+// class Decay_kr
+// :public flext_base
+// {
+// FLEXT_HEADER(Decay_kr,flext_base);
+
+// public:
+// Decay_kr(int argc,t_atom * argv);
+
+// protected:
+// void m_set(float f);
+// void m_perform(float f);
+
+// private:
+// float m_b1; //leak
+// float m_y1; //z-1
+
+// FLEXT_CALLBACK_F(m_set);
+// FLEXT_CALLBACK_F(m_perform);
+// };
+
+// FLEXT_LIB_V("Decay",Decay_kr);
+
+// Decay_kr::Decay_kr(int argc,t_atom * argv)
+// {
+// AtomList Args(argc,argv);
+
+// m_b1 = sc_getfloatarg(Args,0);
+// m_y1 = 0.f;
+
+
+// AddInFloat();
+// AddOutFloat();
+
+// FLEXT_ADDMETHOD(0,m_perform);
+// FLEXT_ADDMETHOD_(0,"leak",m_set);
+// }
+
+// void Decay_kr::m_perform(float f)
+// {
+// m_y1 = f + m_y1 * m_b1;
+// ToOutFloat(0,m_y1);
+// }
+
+// void Decay_kr::m_set(float f)
+// {
+// m_b1=f;
+// }
diff --git a/sc4pd/source/Decay2.cpp b/sc4pd/source/Decay2.cpp
new file mode 100644
index 0000000..a78a180
--- /dev/null
+++ b/sc4pd/source/Decay2.cpp
@@ -0,0 +1,154 @@
+/* sc4pd
+ Decay2~, Decay2
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: AMM: AMMMusic 1966
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ Decay2~ -----------------------------*/
+
+class Decay2_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(Decay2_ar,sc4pd_dsp);
+
+public:
+ Decay2_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+ void m_attack(float f);
+ void m_decay(float f);
+
+private:
+ FLEXT_CALLBACK_F(m_decay);
+ FLEXT_CALLBACK_F(m_attack);
+ float m_attackTime, m_y1a, m_b1a, n_b1a;
+ float m_decayTime, m_y1b, m_b1b, n_b1b;
+ bool changed;
+};
+
+FLEXT_LIB_DSP_V("Decay2~",Decay2_ar);
+
+Decay2_ar::Decay2_ar(int argc,t_atom * argv)
+{
+ FLEXT_ADDMETHOD_(0,"decayTime",m_decay);
+ FLEXT_ADDMETHOD_(0,"attackTime",m_attack);
+
+ AtomList Args(argc,argv);
+
+ m_decayTime = sc_getfloatarg(Args,1); //decay
+ m_attackTime = sc_getfloatarg(Args,0);//attack
+
+ AddOutSignal();
+
+ m_y1a = m_y1b = 0.f; //different than in sc
+
+}
+
+void Decay2_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin = *in;
+
+ float y1a = m_y1a;
+ float y1b = m_y1b;
+ float b1a = m_b1a;
+ float b1b = m_b1b;
+
+ if(changed)
+ {
+ float b1a_slope = CALCSLOPE(n_b1a, b1a);
+ float b1b_slope = CALCSLOPE(n_b1b, b1b);
+ m_b1a = n_b1a;
+ m_b1b = n_b1b;
+
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = ZXP(nin);
+ y1a = y0 + b1a * y1a;
+ y1b = y0 + b1b * y1b;
+
+ ZXP (nout) = y1a - y1b;
+ b1a += b1a_slope;
+ b1b += b1b_slope;
+ }
+ changed = false;
+ }
+ else
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = ZXP(nin);
+ y1a = y0 + b1a * y1a;
+ y1b = y0 + b1b * y1b;
+
+ ZXP (nout) = y1a - y1b;
+ }
+ }
+
+ m_y1a = zapgremlins(y1a);
+ m_y1b = zapgremlins(y1b);
+}
+
+void Decay2_ar::m_decay(float f)
+{
+ m_decayTime = f;
+ n_b1a = f == 0.f ? 0.f : exp(log001 / (f * Samplerate()));
+ changed = true;
+}
+
+void Decay2_ar::m_attack(float f)
+{
+ m_attackTime = f;
+ n_b1b = f == 0.f ? 0.f : exp(log001 / (f * Samplerate()));
+ changed = true;
+}
+
+void Decay2_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ m_b1a = m_decayTime == 0.f ? 0.f : exp(log001 /
+ (m_decayTime * Samplerate()));
+ m_b1b = m_attackTime == 0.f ? 0.f : exp(log001 /
+ (m_attackTime * Samplerate()));
+ changed = false;
+}
+
+/* todo: does it make sense to implement a message-based Decay2?
+ Probably not... */
+
diff --git a/sc4pd/source/DelayC.cpp b/sc4pd/source/DelayC.cpp
new file mode 100644
index 0000000..50ab366
--- /dev/null
+++ b/sc4pd/source/DelayC.cpp
@@ -0,0 +1,287 @@
+/* sc4pd
+ DelayC~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Tom Cora: Halleluja, Anyway
+
+*/
+
+#include "sc4pd.hpp"
+#include "DelayUnit.hpp"
+
+class DelayC_ar : private DelayUnit_ar
+{
+ FLEXT_HEADER(DelayC_ar,DelayUnit_ar);
+
+ DelayC_ar (int argc, t_atom *argv);
+ ~DelayC_ar ();
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ changed = false;
+ DelayUnit_Reset();
+ }
+
+ void m_set(float f)
+ {
+ m_delaytime=f;
+ changed = true;
+ }
+
+private:
+ bool changed;
+ DEFSIGCALL(m_signal_fun);
+ DEFSIGFUN(m_signal_);
+ DEFSIGFUN(m_signal_z);
+
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_DSP_V("DelayC~",DelayC_ar);
+
+DelayC_ar::DelayC_ar (int argc, t_atom *argv)
+{
+
+ FLEXT_ADDMETHOD_(0,"delaytime",m_set);
+
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 2)
+ {
+ post("2 arguments are needed");
+ return;
+ }
+
+ m_delaytime = sc_getfloatarg(Args,0);
+ m_maxdelaytime = sc_getfloatarg(Args,1);
+
+
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z));
+
+ AddOutSignal();
+}
+
+DelayC_ar::~DelayC_ar ()
+{
+ DelayUnit_Dtor();
+}
+
+void DelayC_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ long mask = m_mask;
+ float d0, d1, d2, d3;
+
+ if (changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ for (int i = 0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ long irdphase1 = iwrphase - idsamp;
+ long irdphase2 = irdphase1 - 1;
+ long irdphase3 = irdphase1 - 2;
+ long irdphase0 = irdphase1 + 1;
+
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ if (irdphase0 < 0)
+ {
+ ZXP(nout) = 0.f;
+ }
+ else
+ {
+ if (irdphase1 < 0)
+ {
+ d1 = d2 = d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ }
+ else if (irdphase2 < 0)
+ {
+ d1 = d2 = d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ }
+ else if (irdphase3 < 0)
+ {
+ d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ d2 = dlybuf[irdphase2 & mask];
+ }
+ else
+ {
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ d2 = dlybuf[irdphase2 & mask];
+ d3 = dlybuf[irdphase3 & mask];
+ }
+ ZXP(nout) = cubicinterp(frac, d0, d1, d2, d3);
+ }
+ iwrphase++;
+ }
+ m_dsamp = dsamp;
+ changed = false;
+ }
+ else
+ {
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ for (int i = 0; i!= n;++i)
+ {
+ long irdphase1 = iwrphase - idsamp;
+ long irdphase2 = irdphase1 - 1;
+ long irdphase3 = irdphase1 - 2;
+ long irdphase0 = irdphase1 + 1;
+
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ if (irdphase0 < 0)
+ {
+ ZXP(nout) = 0.f;
+ }
+ else
+ {
+ if (irdphase1 < 0)
+ {
+ d1 = d2 = d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ }
+ else if (irdphase2 < 0)
+ {
+ d1 = d2 = d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ }
+ else if (irdphase3 < 0)
+ {
+ d3 = 0.f;
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ d2 = dlybuf[irdphase2 & mask];
+ }
+ else
+ {
+ d0 = dlybuf[irdphase0 & mask];
+ d1 = dlybuf[irdphase1 & mask];
+ d2 = dlybuf[irdphase2 & mask];
+ d3 = dlybuf[irdphase3 & mask];
+ }
+ ZXP(nout) = cubicinterp(frac, d0, d1, d2, d3);
+ }
+ iwrphase++;
+ }
+ }
+
+ m_iwrphase = iwrphase;
+
+ m_numoutput += n;
+
+ if (m_numoutput >= m_idelaylen)
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_));
+ }
+}
+
+void DelayC_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ long mask = m_mask;
+
+ if (changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ for (int i = 0; i!= n;++i)
+ {
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ dsamp += dsamp_slope;
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ long irdphase1 = iwrphase - idsamp;
+ long irdphase2 = irdphase1 - 1;
+ long irdphase3 = irdphase1 - 2;
+ long irdphase0 = irdphase1 + 1;
+ float d0 = dlybuf[irdphase0 & mask];
+ float d1 = dlybuf[irdphase1 & mask];
+ float d2 = dlybuf[irdphase2 & mask];
+ float d3 = dlybuf[irdphase3 & mask];
+ ZXP(nout) = cubicinterp(frac, d0, d1, d2, d3);
+ iwrphase++;
+ }
+ m_dsamp = dsamp;
+ changed = false;
+ }
+ else
+ {
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ for (int i = 0; i!= n;++i)
+ {
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ long irdphase1 = iwrphase - idsamp;
+ long irdphase2 = irdphase1 - 1;
+ long irdphase3 = irdphase1 - 2;
+ long irdphase0 = irdphase1 + 1;
+ float d0 = dlybuf[irdphase0 & mask];
+ float d1 = dlybuf[irdphase1 & mask];
+ float d2 = dlybuf[irdphase2 & mask];
+ float d3 = dlybuf[irdphase3 & mask];
+ ZXP(nout) = cubicinterp(frac, d0, d1, d2, d3);
+ iwrphase++;
+ }
+ }
+ m_iwrphase = iwrphase;
+}
+
+/* todo: DelayC for control rate ? */
diff --git a/sc4pd/source/DelayL.cpp b/sc4pd/source/DelayL.cpp
new file mode 100644
index 0000000..46b5458
--- /dev/null
+++ b/sc4pd/source/DelayL.cpp
@@ -0,0 +1,236 @@
+/* sc4pd
+ DelayL~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Tom Cora: Halleluja, Anyway
+
+*/
+
+#include "sc4pd.hpp"
+#include "DelayUnit.hpp"
+
+class DelayL_ar : private DelayUnit_ar
+{
+ FLEXT_HEADER(DelayL_ar,DelayUnit_ar);
+
+ DelayL_ar (int argc, t_atom *argv);
+ ~DelayL_ar ();
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ changed = false;
+ DelayUnit_Reset();
+ }
+
+ void m_set(float f)
+ {
+ m_delaytime=f;
+ changed = true;
+ }
+
+private:
+ bool changed;
+ DEFSIGCALL(m_signal_fun);
+ DEFSIGFUN(m_signal_);
+ DEFSIGFUN(m_signal_z);
+
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_DSP_V("DelayL~",DelayL_ar);
+
+DelayL_ar::DelayL_ar (int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"delaytime",m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 2)
+ {
+ post("2 arguments are needed");
+ return;
+ }
+
+ m_delaytime = sc_getfloatarg(Args,0);
+ m_maxdelaytime = sc_getfloatarg(Args,1);
+
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z));
+
+ AddOutSignal();
+}
+
+DelayL_ar::~DelayL_ar ()
+{
+ DelayUnit_Dtor();
+}
+
+void DelayL_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ long mask = m_mask;
+
+ if (changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ for (int i = 0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ long irdphase = iwrphase - idsamp;
+ long irdphaseb = irdphase - 1;
+
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ if (irdphase < 0)
+ {
+ ZXP(nout) = 0.f;
+ }
+ else if (irdphaseb < 0)
+ {
+ float d1 = dlybuf[irdphase & mask];
+ ZXP(nout) = d1 - frac * d1;
+ }
+ else
+ {
+ float d1 = dlybuf[irdphase & mask];
+ float d2 = dlybuf[irdphaseb & mask];
+ ZXP(nout) = lininterp(frac, d1, d2);
+ }
+ iwrphase++;
+ }
+ m_dsamp = dsamp;
+ changed = false;
+ }
+ else
+ {
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ for (int i = 0; i!= n;++i)
+ {
+ long irdphase = iwrphase - idsamp;
+ long irdphaseb = irdphase - 1;
+
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ if (irdphase < 0)
+ {
+ ZXP(nout) = 0.f;
+ }
+ else if (irdphaseb < 0)
+ {
+ float d1 = dlybuf[irdphase & mask];
+ ZXP(nout) = d1 - frac * d1;
+ }
+ else
+ {
+ float d1 = dlybuf[irdphase & mask];
+ float d2 = dlybuf[irdphaseb & mask];
+ ZXP(nout) = lininterp(frac, d1, d2);
+ }
+ iwrphase++;
+ }
+ }
+
+ m_iwrphase = iwrphase;
+
+ m_numoutput += n;
+
+ if (m_numoutput >= m_idelaylen)
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_));
+ }
+}
+
+void DelayL_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ long mask = m_mask;
+
+ if (changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ for (int i = 0; i!= n;++i)
+ {
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ dsamp += dsamp_slope;
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ long irdphase = iwrphase - idsamp;
+ long irdphaseb = irdphase - 1;
+ float d1 = dlybuf[irdphase & mask];
+ float d2 = dlybuf[irdphaseb & mask];
+ ZXP(nout) = lininterp(frac, d1, d2);
+ iwrphase++;
+ }
+ m_dsamp = dsamp;
+ changed = false;
+ }
+ else
+ {
+ long idsamp = (long)dsamp;
+ float frac = dsamp - idsamp;
+ for (int i = 0; i!= n;++i)
+ {
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ long irdphase = iwrphase - idsamp;
+ long irdphaseb = irdphase - 1;
+ float d1 = dlybuf[irdphase & mask];
+ float d2 = dlybuf[irdphaseb & mask];
+ ZXP(nout) = lininterp(frac, d1, d2);
+ iwrphase++;
+ }
+
+ }
+ m_iwrphase = iwrphase;
+}
+
+/* todo: DelayL for control rate ? */
diff --git a/sc4pd/source/DelayN.cpp b/sc4pd/source/DelayN.cpp
new file mode 100644
index 0000000..6bbbb18
--- /dev/null
+++ b/sc4pd/source/DelayN.cpp
@@ -0,0 +1,238 @@
+/* sc4pd
+ DelayN~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to:
+
+*/
+
+#include "sc4pd.hpp"
+#include "DelayUnit.hpp"
+
+class DelayN_ar : private DelayUnit_ar
+{
+ FLEXT_HEADER(DelayN_ar,DelayUnit_ar);
+
+ DelayN_ar (int argc, t_atom *argv);
+ ~DelayN_ar ();
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ changed = false;
+ DelayUnit_Reset();
+ }
+
+ void m_set(float f)
+ {
+ m_delaytime=f;
+ changed = true;
+ }
+
+private:
+ bool changed;
+ DEFSIGCALL(m_signal_fun);
+ DEFSIGFUN(m_signal_);
+ DEFSIGFUN(m_signal_z);
+
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_DSP_V("DelayN~",DelayN_ar);
+
+DelayN_ar::DelayN_ar (int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"delaytime",m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 2)
+ {
+ post("2 arguments are needed");
+ return;
+ }
+
+ m_delaytime = sc_getfloatarg(Args,0);
+ m_maxdelaytime = sc_getfloatarg(Args,1);
+
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z));
+
+ AddOutSignal();
+}
+
+DelayN_ar::~DelayN_ar ()
+{
+ DelayUnit_Dtor();
+}
+
+void DelayN_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ long mask = m_mask;
+
+ if (changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ for (int i = 0; i!= n;++i)
+ {
+ dsamp += dsamp_slope;
+ long irdphase = iwrphase - (long)dsamp;
+
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ if (irdphase < 0)
+ {
+ ZXP(nout) = 0.f;
+ }
+ else
+ {
+ ZXP(nout) = dlybuf[irdphase & mask];
+ }
+ iwrphase++;
+ }
+ m_dsamp = dsamp;
+ changed = false;
+ }
+ else
+ {
+ long irdphase = iwrphase - (long)dsamp;
+ float* dlybuf1 = dlybuf - ZOFF;
+ float* dlyN = dlybuf1 + m_idelaylen;
+ long remain = n;
+
+ while (remain)
+ {
+ float* dlywr = dlybuf1 + (iwrphase & mask);
+ float* dlyrd = dlybuf1 + (irdphase & mask);
+ long rdspace = dlyN - dlyrd;
+ long wrspace = dlyN - dlywr;
+ long nsmps = sc_min(rdspace, wrspace);
+ nsmps = sc_min(remain, nsmps);
+ remain -= nsmps;
+ if (irdphase < 0)
+ {
+ for (int i = 0; i!= nsmps;++i)
+ {
+ ZXP(dlywr) = ZXP(nin);
+ ZXP(nout) = 0.f;
+ }
+ }
+ else
+ {
+ for (int i = 0; i!= nsmps;++i)
+ {
+ ZXP(dlywr) = ZXP(nin);
+ ZXP(nout) = ZXP(dlyrd);
+ }
+ }
+ iwrphase += nsmps;
+ irdphase += nsmps;
+ }
+ }
+
+ m_iwrphase = iwrphase;
+
+ m_numoutput += n;
+
+ if (m_numoutput >= m_idelaylen)
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_));
+ }
+}
+
+void DelayN_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float *dlybuf = m_dlybuf;
+ long iwrphase = m_iwrphase;
+ float dsamp = m_dsamp;
+ long mask = m_mask;
+
+ if (changed)
+ {
+ float next_dsamp = CalcDelay(m_delaytime);
+ float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
+
+ for (int i = 0; i!= n;++i)
+ {
+ dlybuf[iwrphase & mask] = ZXP(nin);
+ dsamp += dsamp_slope;
+ ++iwrphase;
+ long irdphase = iwrphase - (long)dsamp;
+ ZXP(nout) = dlybuf[irdphase & mask];
+ }
+ m_dsamp = dsamp;
+ changed = false;
+ }
+ else
+ {
+ long irdphase = iwrphase - (long)dsamp;
+ float* dlybuf1 = dlybuf - ZOFF;
+ float* dlyrd = dlybuf1 + (irdphase & mask);
+ float* dlywr = dlybuf1 + (iwrphase & mask);
+ float* dlyN = dlybuf1 + m_idelaylen;
+ long remain = n;
+ while (remain)
+ {
+ long rdspace = dlyN - dlyrd;
+ long wrspace = dlyN - dlywr;
+ long nsmps = sc_min(rdspace, wrspace);
+ nsmps = sc_min(remain, nsmps);
+ remain -= nsmps;
+ for (int i = 0; i!= nsmps;++i)
+ {
+ ZXP(dlywr) = ZXP(nin);
+ ZXP(nout) = ZXP(dlyrd);
+ }
+ if (dlyrd == dlyN) dlyrd = dlybuf1;
+ if (dlywr == dlyN) dlywr = dlybuf1;
+ }
+ iwrphase += n;
+ }
+ m_iwrphase = iwrphase;
+}
+
+/* todo: DelayN for control rate ? */
diff --git a/sc4pd/source/DelayUnit.cpp b/sc4pd/source/DelayUnit.cpp
new file mode 100644
index 0000000..bd57f7d
--- /dev/null
+++ b/sc4pd/source/DelayUnit.cpp
@@ -0,0 +1,81 @@
+/* sc4pd
+ public class for several delay objects
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to:
+
+*/
+
+#include "sc4pd.hpp"
+#include "DelayUnit.hpp"
+
+void DelayUnit_ar::DelayUnit_AllocDelayLine()
+{
+ long delaybufsize = (long)ceil(m_maxdelaytime * Samplerate() + 1.f);
+ delaybufsize = delaybufsize + Blocksize();
+ delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two
+ m_fdelaylen = m_idelaylen = delaybufsize;
+
+ delete[] m_dlybuf;
+ m_dlybuf = new float[delaybufsize] ;
+ m_mask = delaybufsize - 1;
+}
+
+void DelayUnit_ar::DelayUnit_Dtor()
+{
+ delete[] m_dlybuf;
+}
+
+float DelayUnit_ar::CalcDelay(float delaytime)
+{
+ float next_dsamp = delaytime * Samplerate();
+ return sc_clip(next_dsamp, 1.f, m_fdelaylen);
+}
+
+void DelayUnit_ar::DelayUnit_Reset()
+{
+ m_dlybuf = 0;
+
+ DelayUnit_AllocDelayLine();
+
+ m_dsamp = CalcDelay(m_delaytime);
+
+ m_numoutput = 0;
+ m_iwrphase = 0;
+}
+
+void FeedbackDelay_ar::FeedbackDelay_Reset()
+{
+ DelayUnit_Reset();
+
+ m_feedbk = CalcFeedback(m_delaytime, m_decaytime);
+}
diff --git a/sc4pd/source/DelayUnit.hpp b/sc4pd/source/DelayUnit.hpp
new file mode 100644
index 0000000..a5951e5
--- /dev/null
+++ b/sc4pd/source/DelayUnit.hpp
@@ -0,0 +1,67 @@
+/* sc4pd
+ public class for several delay objects
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to:
+
+*/
+
+//#include "sc4pd.hpp"
+
+class DelayUnit_ar
+ : public sc4pd_dsp
+{
+ FLEXT_HEADER(DelayUnit_ar,sc4pd_dsp);
+
+public:
+ /* functions */
+ void DelayUnit_AllocDelayLine();
+ void DelayUnit_Reset();
+ float CalcDelay(float delaytime);
+ void DelayUnit_Dtor();
+
+ /* data */
+ float *m_dlybuf;
+ float m_dsamp, m_fdelaylen;
+ float m_delaytime, m_maxdelaytime;
+ long m_iwrphase, m_idelaylen, m_mask;
+ long m_numoutput;
+};
+
+/* todo: a delay for control messages? */
+
+class FeedbackDelay_ar : public DelayUnit_ar
+{
+ FLEXT_HEADER(FeedbackDelay_ar,DelayUnit_ar);
+ float m_feedbk, m_decaytime;
+ void FeedbackDelay_Reset();
+};
diff --git a/sc4pd/source/Dust.cpp b/sc4pd/source/Dust.cpp
new file mode 100644
index 0000000..f7b27a1
--- /dev/null
+++ b/sc4pd/source/Dust.cpp
@@ -0,0 +1,188 @@
+/* sc4pd:
+ Dust, Dust~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Assif Tsahar & Tatsuya Nakatani: Come Sunday
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ Dust~ -------------------------------------*/
+
+class Dust_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(Dust_ar,sc4pd_dsp);
+
+public:
+ Dust_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp (int n,t_signalvec const * insigs,
+ t_signalvec const * outsigs);
+
+ void m_set(float f)
+ {
+ m_density = f;
+ m_thresh = m_density/Samplerate();
+ m_scale = m_thresh > 0.f ? 1.f / m_thresh : 0.f;
+ }
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK_I(m_seed);
+ float m_density, m_thresh, m_scale;
+ RGen rgen;
+
+};
+
+FLEXT_LIB_DSP_V("Dust~",Dust_ar);
+
+Dust_ar::Dust_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+ m_density=sc_getfloatarg(Args,0);
+
+ rgen.init(timeseed());
+
+
+ AddOutSignal();
+}
+
+void Dust_ar::m_dsp(int n,t_signalvec const * insigs,
+ t_signalvec const * outsigs)
+{
+ m_thresh = m_density/Samplerate();
+ m_scale = m_thresh > 0.f ? 1.f / m_thresh : 0.f;
+}
+
+void Dust_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ RGET;
+ float thresh = m_thresh;
+ float scale = m_scale;
+
+ for (int i = 0; i!= n;++i)
+ {
+ float z = frand(s1,s2,s3);
+ if (z < thresh)
+ (*(nout)++) = z * scale;
+ else
+ (*(nout)++) = 0.f;
+ }
+
+ RPUT;
+}
+
+
+/* ------------------------ Dust ---------------------------------------*/
+
+class Dust_kr:
+ public flext_base
+{
+ FLEXT_HEADER(Dust_kr,flext_base);
+
+public:
+ Dust_kr(int argc, t_atom *argv);
+
+protected:
+ void m_set(float f);
+ Timer Dust_timer;
+ void m_doit(void*);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float m_density, m_scale;
+ float mtbt; //medium time between trigger
+ RGen rgen;
+ FLEXT_CALLBACK_1(m_set,float);
+ FLEXT_CALLBACK_T(m_doit);
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("Dust",Dust_kr);
+
+Dust_kr::Dust_kr(int argc, t_atom *argv)
+ : Dust_timer(false)
+{
+ FLEXT_ADDMETHOD(0,m_set);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+ m_density=sc_getfloatarg(Args,0);
+
+ rgen.init(timeseed());
+ AddOutFloat();
+
+ FLEXT_ADDTIMER(Dust_timer,m_doit);
+
+ m_set(m_density);
+}
+
+void Dust_kr::m_set(float f)
+{
+ Dust_timer.Reset();
+
+ if(f==0)
+ {
+ return;
+ }
+ m_density = f;
+ mtbt = 1/f*1000;
+
+ Dust_timer.Delay(mtbt * 0.002 * rgen.frand());
+}
+
+void Dust_kr::m_doit(void*)
+{
+ ToOutFloat(0,rgen.frand());
+
+ Dust_timer.Delay(mtbt * 0.002 * rgen.frand());
+}
diff --git a/sc4pd/source/Dust2.cpp b/sc4pd/source/Dust2.cpp
new file mode 100644
index 0000000..2db7981
--- /dev/null
+++ b/sc4pd/source/Dust2.cpp
@@ -0,0 +1,188 @@
+/* sc4pd:
+ Dust2, Dust2~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Herbert Eimert: Epitaph für Aikichi Kuboyama
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ Dust2~ -------------------------------------*/
+
+class Dust2_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(Dust2_ar,sc4pd_dsp);
+
+public:
+ Dust2_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp (int n,t_signalvec const * insigs,
+ t_signalvec const * outsigs);
+
+ void m_set(float f)
+ {
+ m_density = f;
+ m_thresh = m_density/Samplerate();
+ m_scale = m_thresh > 0.f ? 1.f / m_thresh : 0.f;
+ }
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK_I(m_seed);
+ float m_density, m_thresh, m_scale;
+ RGen rgen;
+
+};
+
+FLEXT_LIB_DSP_V("Dust2~",Dust2_ar);
+
+Dust2_ar::Dust2_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+ m_density=sc_getfloatarg(Args,0);
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+}
+
+void Dust2_ar::m_dsp(int n,t_signalvec const * insigs,
+ t_signalvec const * outsigs)
+{
+ m_thresh = m_density/Samplerate();
+ m_scale = m_thresh > 0.f ? 2.f / m_thresh : 0.f;
+}
+
+void Dust2_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ RGET;
+ float thresh = m_thresh;
+ float scale = m_scale;
+
+ for (int i = 0; i!= n;++i)
+ {
+ float z = frand(s1,s2,s3);
+ if (z < thresh)
+ (*(nout)++) = z * scale - 1.f;
+ else
+ (*(nout)++) = 0.f;
+ }
+
+ RPUT;
+}
+
+
+/* ------------------------ Dust2 ---------------------------------------*/
+
+class Dust2_kr:
+ public flext_base
+{
+ FLEXT_HEADER(Dust2_kr,flext_base);
+
+public:
+ Dust2_kr(int argc, t_atom *argv);
+
+protected:
+ void m_set(float f);
+ Timer Dust2_timer;
+ void m_doit(void*);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float m_density, m_scale;
+ float mtbt; //medium time between trigger
+ RGen rgen;
+ FLEXT_CALLBACK_1(m_set,float);
+ FLEXT_CALLBACK_I(m_seed);
+ FLEXT_CALLBACK_T(m_doit);
+};
+
+FLEXT_LIB_V("Dust2",Dust2_kr);
+
+Dust2_kr::Dust2_kr(int argc, t_atom *argv)
+ : Dust2_timer(false)
+{
+ FLEXT_ADDMETHOD(0,m_set);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+ m_density=sc_getfloatarg(Args,0);
+
+ rgen.init(timeseed());
+ AddOutFloat();
+
+ FLEXT_ADDTIMER(Dust2_timer,m_doit);
+
+ m_set(m_density);
+}
+
+void Dust2_kr::m_set(float f)
+{
+ Dust2_timer.Reset();
+
+ if(f==0)
+ {
+ return;
+ }
+ m_density = f;
+ mtbt = 1/f*1000;
+
+ Dust2_timer.Delay(mtbt * 0.002 * rgen.frand());
+}
+
+void Dust2_kr::m_doit(void*)
+{
+ ToOutFloat(0,2*rgen.frand() - 1 );
+
+ Dust2_timer.Delay(mtbt * 0.002 * rgen.frand());
+}
diff --git a/sc4pd/source/ExpRand.cpp b/sc4pd/source/ExpRand.cpp
new file mode 100644
index 0000000..a08f6fa
--- /dev/null
+++ b/sc4pd/source/ExpRand.cpp
@@ -0,0 +1,160 @@
+/* sc4pd
+ ExpRand, ExpRand~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Jim O'Rourke & Loren Mazzacane Connors: In Bern
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ ExpRand~ -------------------------------*/
+
+class ExpRand_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(ExpRand_ar,sc4pd_dsp);
+
+public:
+ ExpRand_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float m_sample;
+ float lo;
+ float hi;
+ int sc_n;
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_DSP_V("ExpRand~",ExpRand_ar);
+
+ExpRand_ar::ExpRand_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 2)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=sc_getfloatarg(Args,0);
+ hi=sc_getfloatarg(Args,1);
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+}
+
+void ExpRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ float ratio = hi / lo;
+ m_sample = pow(ratio,rgen.frand()) * lo;
+}
+
+
+void ExpRand_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float sample = m_sample;
+
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++) = sample;
+ }
+}
+
+
+/* ------------------------ ExpRand ---------------------------------*/
+
+class ExpRand_kr:
+ public flext_base
+{
+ FLEXT_HEADER(ExpRand_kr,flext_base);
+
+public:
+ ExpRand_kr(int argc, t_atom *argv);
+
+protected:
+ void m_loadbang();
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float lo;
+ float hi;
+ int sc_n;
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("ExpRand",ExpRand_kr);
+
+ExpRand_kr::ExpRand_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ AtomList Args(argc,argv);
+ if (Args.Count() != 2)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=sc_getfloatarg(Args,0);
+ hi=sc_getfloatarg(Args,1);
+
+ rgen.init(timeseed());
+
+ AddOutFloat();
+}
+
+void ExpRand_kr::m_loadbang()
+{
+ float ratio = hi / lo;
+ ToOutFloat(0,pow(ratio,rgen.frand()) * lo);
+}
diff --git a/sc4pd/source/FOS.cpp b/sc4pd/source/FOS.cpp
new file mode 100644
index 0000000..6bd3c26
--- /dev/null
+++ b/sc4pd/source/FOS.cpp
@@ -0,0 +1,258 @@
+/* sc4pd
+ FOS, FOS~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Susie Ibarra & Assif Tsahar: Home Cookin'
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ FOS~ -------------------------------*/
+
+class FOS_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(FOS_ar,sc4pd_dsp);
+
+public:
+ FOS_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+
+ void m_set_a0(float f)
+ {
+ next_a0=f;
+ }
+
+ void m_set_a1(float f)
+ {
+ next_a1=f;
+ }
+
+ void m_set_b1(float f)
+ {
+ next_b1=f;
+ }
+
+ void m_ar()
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar));
+ }
+
+ void m_kr()
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr));
+ }
+
+private:
+ float next_a0, next_a1, next_b1;
+ float m_y1, m_a0, m_a1, m_b1;
+
+ DEFSIGCALL (m_signal_fun);
+ DEFSIGFUN (m_signal_ar);
+ DEFSIGFUN (m_signal_kr);
+
+ FLEXT_CALLBACK_F(m_set_a0);
+ FLEXT_CALLBACK_F(m_set_a1);
+ FLEXT_CALLBACK_F(m_set_b1);
+ FLEXT_CALLBACK(m_ar);
+ FLEXT_CALLBACK(m_kr);
+};
+
+FLEXT_LIB_DSP_V("FOS~",FOS_ar);
+
+FOS_ar::FOS_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"a0",m_set_a0);
+ FLEXT_ADDMETHOD_(0,"a1",m_set_a1);
+ FLEXT_ADDMETHOD_(0,"b1",m_set_b1);
+ FLEXT_ADDMETHOD_(0,"ar",m_ar);
+ FLEXT_ADDMETHOD_(0,"kr",m_kr);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ if (Args.Count()<3)
+ {
+ post("needs at least 3 arguments");
+ return;
+ }
+ m_a0 = sc_getfloatarg(Args,0);
+ m_a1 = sc_getfloatarg(Args,1);
+ m_b1 = sc_getfloatarg(Args,2);
+
+ if(sc_ar(Args))
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar));
+ AddInSignal();
+ AddInSignal();
+ AddInSignal();
+ AddInSignal();
+ }
+ else // if not given, use control rate
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr));
+
+ AddOutSignal();
+
+ m_y1 = 0.f;
+ m_a0 = 0.f;
+ m_a1 = 0.f;
+ m_b1 = 0.f;
+}
+
+void FOS_ar::m_signal_ar(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+ float *a0 = *(in+1);
+ float *a1 = *(in+2);
+ float *b1 = *(in+3);
+
+ float y1 = m_y1;
+
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = ZXP(nin) + ZXP(b1) * y1;
+ ZXP(nout) = ZXP(a0) * y0 + ZXP(a1) * y1;
+ y1 = y0;
+ }
+ m_y1 = zapgremlins(y1);
+}
+
+
+void FOS_ar::m_signal_kr(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float y1 = m_y1;
+ float a0 = m_a0;
+ float a1 = m_a1;
+ float b1 = m_b1;
+ float a0_slope = CALCSLOPE(next_a0, a0);
+ float a1_slope = CALCSLOPE(next_a1, a1);
+ float b1_slope = CALCSLOPE(next_b1, b1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = ZXP(nin) + b1 * y1;
+ ZXP(nout) = a0 * y0 + a1 * y1;
+ y1 = y0;
+
+ a0 += a0_slope;
+ a1 += a1_slope;
+ b1 += b1_slope;
+ }
+}
+
+/* ------------------------ FOS ---------------------------------*/
+
+
+class FOS_kr:
+ public flext_base
+{
+ FLEXT_HEADER(FOS_kr,flext_base);
+
+public:
+ FOS_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform(float f);
+
+ void m_set_a0(float f)
+ {
+ m_a0=f;
+ }
+
+ void m_set_a1(float f)
+ {
+ m_a1=f;
+ }
+
+ void m_set_b1(float f)
+ {
+ m_b1=f;
+ }
+
+
+private:
+ float m_y1, m_a0, m_a1, m_b1;
+
+ FLEXT_CALLBACK_F(m_set_a0);
+ FLEXT_CALLBACK_F(m_set_a1);
+ FLEXT_CALLBACK_F(m_set_b1);
+ FLEXT_CALLBACK_F(m_perform);
+};
+
+
+FLEXT_LIB_V("FOS",FOS_kr);
+
+FOS_kr::FOS_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD_(0,"a0",m_set_a0);
+ FLEXT_ADDMETHOD_(0,"a1",m_set_a1);
+ FLEXT_ADDMETHOD_(0,"b1",m_set_b1);
+
+ AddOutFloat();
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ if (Args.Count()!=3)
+ {
+ post("needs 3 arguments");
+ return;
+ }
+
+ m_a0 = sc_getfloatarg(Args,0);
+ m_a1 = sc_getfloatarg(Args,1);
+ m_b1 = sc_getfloatarg(Args,2);
+
+ m_y1 = 0.f;
+ m_a0 = 0.f;
+ m_a1 = 0.f;
+ m_b1 = 0.f;
+}
+
+void FOS_kr::m_perform(float f)
+{
+ m_y1 = m_a0 * (f + m_b1 * m_y1) + m_a1 * m_y1;
+ ToOutFloat(0,m_y1);
+}
diff --git a/sc4pd/source/GrayNoise.cpp b/sc4pd/source/GrayNoise.cpp
new file mode 100644
index 0000000..b9c3e40
--- /dev/null
+++ b/sc4pd/source/GrayNoise.cpp
@@ -0,0 +1,143 @@
+/* sc4pd
+ GrayNoise, GrayNoise~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Keith Rowe: Harsh
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ GrayNoise~ -------------------------------*/
+
+class GrayNoise_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(GrayNoise_ar,sc4pd_dsp);
+
+public:
+ GrayNoise_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ int m_counter;
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_DSP_V("GrayNoise~",GrayNoise_ar);
+
+GrayNoise_ar::GrayNoise_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+}
+
+
+void GrayNoise_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ RGET;
+ int counter = m_counter;
+
+ for (int i = 0; i!= n;++i)
+ {
+ counter ^= 1L << (trand(s1,s2,s3) & 31);
+ (*(nout)++) = counter * 4.65661287308e-10f;
+ }
+
+ m_counter=counter;
+ RPUT;
+}
+
+
+/* ------------------------ GrayNoise ---------------------------------*/
+
+class GrayNoise_kr:
+ public flext_base
+{
+ FLEXT_HEADER(GrayNoise_kr,flext_base);
+
+public:
+ GrayNoise_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform();
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ int m_counter;
+ RGen rgen;
+ FLEXT_CALLBACK(m_perform);
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("GrayNoise",GrayNoise_kr);
+
+GrayNoise_kr::GrayNoise_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDBANG(0,m_perform);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ rgen.init(timeseed());
+
+ AddOutFloat();
+}
+
+void GrayNoise_kr::m_perform()
+{
+ m_counter ^= 1L << (rgen.trand() & 31);
+ m_counter * 4.65661287308e-10f;
+ ToOutFloat(0,m_counter * 4.65661287308e-10f);
+}
diff --git a/sc4pd/source/HPF.cpp b/sc4pd/source/HPF.cpp
new file mode 100644
index 0000000..85de643
--- /dev/null
+++ b/sc4pd/source/HPF.cpp
@@ -0,0 +1,180 @@
+/* sc4pd
+ HPF~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Peter Kowald & Tatsuya Nakatani:
+ 13 Definitions of Truth
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ HPF~ -------------------------------*/
+
+class HPF_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(HPF_ar,sc4pd_dsp);
+
+public:
+ HPF_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ mRadiansPerSample = sc_radianspersample();
+ mFilterSlope = sc_filterslope();
+ mFilterLoops = sc_filterloops();
+ mFilterRemain = sc_filterremain();
+ }
+
+ void m_set_freq(float f)
+ {
+ m_freq=f;
+ changed = true;
+ }
+
+private:
+ float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq;
+ bool changed;
+ float mRadiansPerSample, mFilterSlope;
+ int mFilterLoops, mFilterRemain;
+
+ FLEXT_CALLBACK_F(m_set_freq);
+};
+
+FLEXT_LIB_DSP_V("HPF~",HPF_ar);
+
+HPF_ar::HPF_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+ changed = true;
+
+ AddOutSignal();
+
+ m_a0 = 0.f;
+ m_b1 = 0.f;
+ m_b2 = 0.f;
+ m_y1 = 0.f;
+ m_y2 = 0.f;
+}
+
+void HPF_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float y0;
+ float y1 = m_y1;
+ float y2 = m_y2;
+ float a0 = m_a0;
+ float b1 = m_b1;
+ float b2 = m_b2;
+
+ if (changed)
+ {
+ float pfreq = m_freq * mRadiansPerSample * 0.5;
+
+ float C = tan(pfreq);
+ float C2 = C * C;
+ float sqrt2C = C * sqrt2;
+ float next_a0 = 1.f / (1.f + sqrt2C + C2);
+ float next_b1 = 2.f * (1.f - C2) * next_a0 ;
+ float next_b2 = -(1.f - sqrt2C + C2) * next_a0;
+
+ float a0_slope = (next_a0 - a0) * mFilterSlope;
+ float b1_slope = (next_b1 - b1) * mFilterSlope;
+ float b2_slope = (next_b2 - b2) * mFilterSlope;
+
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 - 2.f * y1 + y2);
+
+ y2 = ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = a0 * (y2 - 2.f * y0 + y1);
+
+ y1 = ZXP(nin) + b1 * y2 + b2 * y0;
+ ZXP(nout) = a0 * (y1 - 2.f * y2 + y0);
+
+ a0 += a0_slope;
+ b1 += b1_slope;
+ b2 += b2_slope;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 - 2.f * y1 + y2);
+ y2 = y1;
+ y1 = y0;
+ }
+
+ m_a0 = a0;
+ m_b1 = b1;
+ m_b2 = b2;
+ changed = false;
+ }
+ else
+ {
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 - 2.f * y1 + y2);
+
+ y2 = ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = a0 * (y2 - 2.f * y0 + y1);
+
+ y1 = ZXP(nin) + b1 * y2 + b2 * y0;
+ ZXP(nout) = a0 * (y1 - 2.f * y2 + y0);
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 - 2.f * y1 + y2);
+ y2 = y1;
+ y1 = y0;
+ }
+ }
+ m_y1 = zapgremlins(y1);
+ m_y2 = zapgremlins(y2);
+}
+
+/* no control rate HPF filter */
diff --git a/sc4pd/source/HPZ1.cpp b/sc4pd/source/HPZ1.cpp
new file mode 100644
index 0000000..0ab5f91
--- /dev/null
+++ b/sc4pd/source/HPZ1.cpp
@@ -0,0 +1,132 @@
+/* sc4pd
+ HPZ1~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: William Parker: Compassion Seizes Bed-Stuy
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ HPZ1~ -------------------------------*/
+
+class HPZ1_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(HPZ1_ar,sc4pd_dsp);
+
+public:
+ HPZ1_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+ float m_x1;
+};
+
+FLEXT_LIB_DSP_V("HPZ1~",HPZ1_ar);
+
+HPZ1_ar::HPZ1_ar(int argc, t_atom *argv)
+{
+ AddOutSignal();
+
+ m_x1=0;
+}
+
+void HPZ1_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float x0;
+ float x1 = m_x1;
+
+ int t = n >> 2;
+ for (int i = 0; i!= t;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = 0.5f * (x0 - x1);
+ x1 = ZXP(nin);
+ ZXP(nout) = 0.5f * (x1 - x0);
+ x0 = ZXP(nin);
+ ZXP(nout) = 0.5f * (x0 - x1);
+ x1 = ZXP(nin);
+ ZXP(nout) = 0.5f * (x1 - x0);
+ }
+
+ t = n & 3;
+ for (int i = 0; i!= t;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = 0.5f * (x0 - x1);
+ x1 = x0;
+ }
+ m_x1 = x1;
+}
+
+/* ------------------------ HPZ1 -------------------------------*/
+
+class HPZ1_kr:
+ public flext_base
+{
+ FLEXT_HEADER(HPZ1_kr,flext_base);
+
+public:
+ HPZ1_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform (float f);
+
+private:
+ float m_x1;
+ FLEXT_CALLBACK_F(m_perform);
+};
+
+FLEXT_LIB_V("HPZ1",HPZ1_kr);
+
+HPZ1_kr::HPZ1_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(0,m_perform);
+
+ AddOutFloat();
+
+ m_x1=0;
+}
+
+void HPZ1_kr::m_perform(float f)
+{
+ ToOutFloat(0,0.5f * (f - m_x1));
+ m_x1=f;
+}
+
diff --git a/sc4pd/source/HPZ2.cpp b/sc4pd/source/HPZ2.cpp
new file mode 100644
index 0000000..c561455
--- /dev/null
+++ b/sc4pd/source/HPZ2.cpp
@@ -0,0 +1,140 @@
+/* sc4pd
+ HPZ2~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: William Parker: Compassion Seizes Bed-Stuy
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ HPZ2~ -------------------------------*/
+
+class HPZ2_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(HPZ2_ar,sc4pd_dsp);
+
+public:
+ HPZ2_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ mFilterLoops=sc_filterloops();
+ mFilterRemain=sc_filterremain();
+ }
+
+private:
+ float m_x1, m_x2;
+ int mFilterLoops, mFilterRemain;
+};
+
+FLEXT_LIB_DSP_V("HPZ2~",HPZ2_ar);
+
+HPZ2_ar::HPZ2_ar(int argc, t_atom *argv)
+{
+ AddOutSignal();
+
+ m_x1=0;
+ m_x2=0;
+}
+
+void HPZ2_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float x0;
+ float x1 = m_x1;
+ float x2 = m_x2;
+
+ for (int i = 0; i!=mFilterLoops ;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = (x0 - 2.f * x1 + x2) * 0.25f;
+ x2 = ZXP(nin);
+ ZXP(nout) = (x2 - 2.f * x0 + x1) * 0.25f;
+ x1 = ZXP(nin);
+ ZXP(nout) = (x1 - 2.f * x2 + x0) * 0.25f;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = (x0 - 2.f * x1 + x2) * 0.25f;
+ x2 = x1;
+ x1 = x0;
+ }
+ m_x1 = x1;
+ m_x2 = x2;
+}
+
+/* ------------------------ HPZ2 -------------------------------*/
+
+class HPZ2_kr:
+ public flext_base
+{
+ FLEXT_HEADER(HPZ2_kr,flext_base);
+
+public:
+ HPZ2_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform (float f);
+
+private:
+ float m_x1;
+ float m_x2;
+ FLEXT_CALLBACK_F(m_perform);
+};
+
+FLEXT_LIB_V("HPZ2",HPZ2_kr);
+
+HPZ2_kr::HPZ2_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(0,m_perform);
+
+ AddOutFloat();
+
+ m_x2 = m_x1 = 0;
+}
+
+void HPZ2_kr::m_perform(float f)
+{
+ ToOutFloat(0,(f - 2.f * m_x1 + m_x2) * 0.25f);
+ m_x2=m_x1;
+ m_x1=f;
+}
+
diff --git a/sc4pd/source/Hasher.cpp b/sc4pd/source/Hasher.cpp
new file mode 100644
index 0000000..1fc8085
--- /dev/null
+++ b/sc4pd/source/Hasher.cpp
@@ -0,0 +1,115 @@
+/* sc4pd
+ Hasher~, Hasher
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Philip Jeck: Stoke
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ Hasher~ -----------------------------------*/
+
+class Hasher_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(Hasher_ar,sc4pd_dsp);
+
+public:
+ Hasher_ar();
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+private:
+
+};
+
+FLEXT_LIB_DSP("Hasher~",Hasher_ar);
+
+Hasher_ar::Hasher_ar()
+{
+ AddOutSignal();
+}
+
+void Hasher_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ int32 *nin = (int32*)*in;
+ t_sample *nout = *out;
+
+ for (int i = 0; i!= n;++i)
+ {
+ union { float f; int i; } u;
+ int z = (*(nin)++);
+ u.i = 0x40000000 | ((uint32)Hash(z) >> 9);
+ (*(nout)++) = u.f -3.f;
+ }
+}
+
+
+/* ------------------------ Hasher ------------------------------------*/
+
+class Hasher_kr
+ :public flext_base
+{
+ FLEXT_HEADER(Hasher_kr,flext_base);
+
+public:
+ Hasher_kr();
+
+protected:
+ void m_perform(float f);
+
+private:
+ FLEXT_CALLBACK_F(m_perform);
+};
+
+FLEXT_LIB("Hasher",Hasher_kr);
+
+Hasher_kr::Hasher_kr()
+{
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+}
+
+void Hasher_kr::m_perform(float f)
+{
+ int32 * fi = (int32*) &f;
+
+ union { float f; int i; } u;
+ int z = *fi;
+ u.i = 0x40000000 | ((uint32)Hash(z) >> 9);
+
+ ToOutFloat(0,u.f -3.f);
+}
diff --git a/sc4pd/source/IRand.cpp b/sc4pd/source/IRand.cpp
new file mode 100644
index 0000000..8b5c723
--- /dev/null
+++ b/sc4pd/source/IRand.cpp
@@ -0,0 +1,159 @@
+/* sc4pd
+ IRand, IRand~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Assif Tsahar: Open Systems
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ IRand~ -------------------------------*/
+
+class IRand_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(IRand_ar,sc4pd_dsp);
+
+public:
+ IRand_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float m_sample;
+ int lo;
+ int hi;
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_DSP_V("IRand~",IRand_ar);
+
+IRand_ar::IRand_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 2)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=int(sc_getfloatarg(Args,0));
+ hi=int(sc_getfloatarg(Args,1));
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+}
+
+void IRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ int range = hi - lo;
+ m_sample = float(rgen.irand(range) + lo);
+}
+
+
+void IRand_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float sample = m_sample;
+
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++) = sample;
+ }
+}
+
+
+/* ------------------------ IRand ---------------------------------*/
+
+class IRand_kr:
+ public flext_base
+{
+ FLEXT_HEADER(IRand_kr,flext_base);
+
+public:
+ IRand_kr(int argc, t_atom *argv);
+
+protected:
+ void m_loadbang();
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ int lo;
+ int hi;
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("IRand",IRand_kr);
+
+IRand_kr::IRand_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ AtomList Args(argc,argv);
+ if (Args.Count() != 2)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=int(sc_getfloatarg(Args,0));
+ hi=int(sc_getfloatarg(Args,1));
+
+ rgen.init(timeseed());
+
+ AddOutInt();
+}
+
+void IRand_kr::m_loadbang()
+{
+ int range = hi - lo;
+
+ ToOutInt(0,rgen.irand(range) + lo);
+}
diff --git a/sc4pd/source/Impulse.cpp b/sc4pd/source/Impulse.cpp
new file mode 100644
index 0000000..86ca165
--- /dev/null
+++ b/sc4pd/source/Impulse.cpp
@@ -0,0 +1,264 @@
+/* sc4pd
+ Impulse, Impulse~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: AMM: AMMMusic 1966
+
+*/
+
+#include "sc4pd.hpp"
+
+/* todo: implement phase offset as in sc3
+/* ------------------------ Impulse~ -------------------------------*/
+
+class Impulse_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(Impulse_ar,sc4pd_dsp);
+
+public:
+ Impulse_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set(float f)
+ {
+ m_freq=f;
+ }
+
+ void m_ar()
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar));
+ }
+
+ void m_kr()
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr));
+ }
+
+private:
+ double mPhase, mPhaseOffset;
+ float mFreqMul;
+ float m_freq; //for kr arguments
+
+ DEFSIGCALL (m_signal_fun);
+ DEFSIGFUN (m_signal_ar);
+ DEFSIGFUN (m_signal_kr);
+
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK(m_ar);
+ FLEXT_CALLBACK(m_kr);
+};
+
+FLEXT_LIB_DSP_V("Impulse~",Impulse_ar);
+
+Impulse_ar::Impulse_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"freq",m_set);
+ FLEXT_ADDMETHOD_(0,"ar",m_ar);
+ FLEXT_ADDMETHOD_(0,"kr",m_kr);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+
+ if(sc_ar(Args))
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar));
+ else // if not given, use control rate
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr));
+
+ AddOutSignal();
+}
+
+void Impulse_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ mFreqMul = 1 / Samplerate();
+
+}
+
+void Impulse_ar::m_signal_ar(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *freq = *in;
+ t_sample *xout = *out;
+
+ float freqmul = mFreqMul;
+ double phase = mPhase;
+
+ for (int i = 0; i!= n;++i)
+ {
+ float z;
+ if (phase >= 1.f)
+ {
+ phase -= 1.f;
+ z = 1.f;
+ }
+ else
+ {
+ z = 0.f;
+ }
+ phase += (*(freq)++) * freqmul;
+ (*(xout)++) = z;
+ }
+
+ mPhase=phase;
+}
+
+
+void Impulse_ar::m_signal_kr(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *xout = *out;
+
+ float freq = m_freq * mFreqMul;
+ float freqmul = mFreqMul;
+ double phase = mPhase;
+
+ for (int i = 0; i!= n;++i)
+ {
+ float z;
+ if (phase >= 1.f)
+ {
+ phase -= 1.f;
+ z = 1.f;
+ }
+ else
+ {
+ z = 0.f;
+ }
+ phase += freq;
+ (*(xout)++) = z;
+ }
+
+ mPhase=phase;
+}
+
+/* ------------------------ Impulse ---------------------------------*/
+
+/* todo: remove obsolete messages */
+
+class Impulse_kr:
+ public flext_base
+{
+ FLEXT_HEADER(Impulse_kr,flext_base);
+
+public:
+ Impulse_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform(void*);
+
+ void m_set(float f)
+ {
+ m_freq_set = f;
+ m_freq = f * mFreqMul;
+ }
+
+ void m_set_kr(float f)
+ {
+ if (f != 0)
+ {
+ dt = f * 0.001;
+ mFreqMul = dt;
+ m_freq = m_freq_set * mFreqMul;
+ m_timer.Reset();
+ m_timer.Periodic(dt);
+ }
+ }
+
+private:
+
+ double mPhase, mPhaseOffset;
+ float mFreqMul;
+ float m_freq; //for kr arguments
+
+ float dt;
+ float m_freq_set;
+
+ Timer m_timer;
+
+ FLEXT_CALLBACK_F(m_set_kr);
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK_T(m_perform);
+};
+
+
+FLEXT_LIB_V("Impulse",Impulse_kr);
+
+Impulse_kr::Impulse_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(0,m_set);
+ FLEXT_ADDMETHOD_(0,"kr",m_set_kr);
+
+ FLEXT_ADDTIMER(m_timer,m_perform);
+
+ AddOutFloat();
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq_set = sc_getfloatarg(Args,0);
+
+ dt = sc_getfloatarg(Args,1) * 0.001;
+
+ if (dt == 0)
+ dt = 0.02; // 20 ms as default control rate as in line
+ mFreqMul = dt;
+
+ m_freq = m_freq_set * mFreqMul;
+
+ m_timer.Periodic(dt);
+
+}
+
+void Impulse_kr::m_perform(void*)
+{
+ float z;
+ if (mPhase >= 1.f)
+ {
+ mPhase -= 1.f;
+ z = 1.f;
+ }
+ else
+ {
+ z = 0.f;
+ }
+
+ mPhase += m_freq;
+ ToOutFloat(0,z);
+}
diff --git a/sc4pd/source/Integrator.cpp b/sc4pd/source/Integrator.cpp
new file mode 100644
index 0000000..85253ee
--- /dev/null
+++ b/sc4pd/source/Integrator.cpp
@@ -0,0 +1,199 @@
+/* sc4pd
+ Integrator~, Integrator
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: AMM: AMMMusic 1966
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ Integrator~ -----------------------------*/
+
+class Integrator_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(Integrator_ar,sc4pd_dsp);
+
+public:
+ Integrator_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ void m_set(float f);
+
+private:
+ FLEXT_CALLBACK_F(m_set);
+ float m_b1; //leak
+ float m_y1; //z-1
+};
+
+FLEXT_LIB_DSP_V("Integrator~",Integrator_ar);
+
+Integrator_ar::Integrator_ar(int argc,t_atom * argv)
+{
+ FLEXT_ADDMETHOD_(0,"leak",m_set);
+
+ AtomList Args(argc,argv);
+
+ m_b1 = sc_getfloatarg(Args,0);
+
+ AddOutSignal();
+
+ m_y1 = 0.f;
+}
+
+void Integrator_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin = *in;
+
+ float b1 = m_b1;
+ float y1 = m_y1;
+
+ if (b1 == m_b1)
+ {
+ if (b1 == 1.f)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = (*(nin)++);
+ (*(nout)++) = y1 = y0 + y1;
+ }
+
+ }
+ else if (b1 == 0.f)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = (*(nin)++);
+ (*(nout)++) = y1 = y0;
+ }
+ }
+ else
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = (*(nin)++);
+ (*(nout)++) = y1 = y0 + b1 * y1;
+ }
+ }
+ }
+ else
+ {
+ float b1_slope = CALCSLOPE(m_b1, b1);
+ if (b1 >= 0.f && m_b1 >= 0)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = (*(nin)++);
+ (*(nout)++) = y1 = y0 + b1 * (y1 - y0);
+ b1 += b1_slope;
+ }
+ }
+ else if (b1 <= 0.f && m_b1 <= 0)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = (*(nin)++);
+ (*(nout)++) = y1 = y0 + b1 * (y1 + y0);
+ b1 += b1_slope;
+ }
+ }
+ else
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = (*(nin)++);
+ (*(nout)++) = y1 = (1.f - fabs(b1)) * y0 + b1 * y1;
+ b1 += b1_slope;
+ }
+ }
+ }
+ m_y1 = zapgremlins(y1);
+}
+
+void Integrator_ar::m_set(float f)
+{
+ m_b1=f;
+}
+
+/* ------------------------ Integrator ------------------------------*/
+
+class Integrator_kr
+ :public flext_base
+{
+ FLEXT_HEADER(Integrator_kr,flext_base);
+
+public:
+ Integrator_kr(int argc,t_atom * argv);
+
+protected:
+ void m_set(float f);
+ void m_perform(float f);
+
+private:
+ float m_b1; //leak
+ float m_y1; //z-1
+
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK_F(m_perform);
+};
+
+FLEXT_LIB_V("Integrator",Integrator_kr);
+
+Integrator_kr::Integrator_kr(int argc,t_atom * argv)
+{
+ AtomList Args(argc,argv);
+
+ m_b1 = sc_getfloatarg(Args,0);
+ m_y1 = 0.f;
+
+
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD_(0,"leak",m_set);
+}
+
+void Integrator_kr::m_perform(float f)
+{
+ m_y1 = f + m_y1 * m_b1;
+ ToOutFloat(0,m_y1);
+}
+
+void Integrator_kr::m_set(float f)
+{
+ m_b1=f;
+}
diff --git a/sc4pd/source/LFClipNoise.cpp b/sc4pd/source/LFClipNoise.cpp
new file mode 100644
index 0000000..1583431
--- /dev/null
+++ b/sc4pd/source/LFClipNoise.cpp
@@ -0,0 +1,195 @@
+/* sc4pd
+ LFClipNoise, LFClipNoise~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Elliott Sharp: Revenge Of The Stuttering Child
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ LFClipNoise~ -------------------------------*/
+
+class LFClipNoise_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LFClipNoise_ar,sc4pd_dsp);
+
+public:
+ LFClipNoise_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+ void m_set(float f)
+ {
+ m_freq = f;
+ }
+
+private:
+ RGen rgen;
+ float m_freq;
+ float m_level;
+ int m_counter;
+ int m_sr;
+ FLEXT_CALLBACK_I(m_seed);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_DSP_V("LFClipNoise~",LFClipNoise_ar);
+
+LFClipNoise_ar::LFClipNoise_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+
+ m_counter=0;
+ m_level=0;
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+}
+
+void LFClipNoise_ar::m_dsp(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ m_sr = Samplerate();
+}
+
+
+void LFClipNoise_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float level = m_level;
+ int32 counter = m_counter;
+
+ RGET;
+
+ int remain = n;
+ do
+ {
+ if (counter<=0)
+ {
+ counter = (int)(m_sr / sc_max(m_freq, .001f));
+ counter = sc_max(1, counter);
+ level = fcoin(s1,s2,s3);
+ }
+ int nsmps = sc_min(remain, counter);
+ remain -= nsmps;
+ counter -= nsmps;
+
+ for (int i = 0; i!= nsmps;++i)
+ {
+ (*(nout)++)=level;
+ }
+ }
+ while(remain);
+
+ m_level = level;
+ m_counter = counter;
+
+ RPUT;
+}
+
+
+/* ------------------------ LFClipNoise ---------------------------------*/
+
+class LFClipNoise_kr:
+ public flext_base
+{
+ FLEXT_HEADER(LFClipNoise_kr,flext_base);
+
+public:
+ LFClipNoise_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform(void*);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+ void m_set(float f)
+ {
+ double dt = sc_max(1/f, .001f);
+ m_timer.Reset();
+ m_timer.Periodic(dt);
+ }
+
+private:
+ RGen rgen;
+ Timer m_timer;
+ FLEXT_CALLBACK_I(m_seed);
+ FLEXT_CALLBACK_T(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("LFClipNoise",LFClipNoise_kr);
+
+LFClipNoise_kr::LFClipNoise_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+ FLEXT_ADDTIMER(m_timer,m_perform);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ double dt = sc_max(1/sc_getfloatarg(Args,0), .001f);
+
+ rgen.init(timeseed());
+
+ m_timer.Periodic(dt);
+
+ AddOutFloat();
+}
+
+void LFClipNoise_kr::m_perform(void*)
+{
+ ToOutFloat(0,rgen.fcoin());
+}
diff --git a/sc4pd/source/LFDNoise0.cpp b/sc4pd/source/LFDNoise0.cpp
new file mode 100644
index 0000000..316b5a4
--- /dev/null
+++ b/sc4pd/source/LFDNoise0.cpp
@@ -0,0 +1,166 @@
+/* sc4pd
+ LFDNoise0~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ *
+ * DynNoiseUGens.cpp
+ * xSC3plugins
+ *
+ * Created by Alberto de Campo, Sekhar Ramacrishnan, Julian Rohrhuber on Sun May 30 2004.
+ * Copyright (c) 2004 HfbK. All rights reserved.
+ *
+ *
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Phil Minton & Veryan Weston: Ways Past
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ LFDNoise0~ -------------------------------*/
+
+class LFDNoise0_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LFDNoise0_ar,sc4pd_dsp);
+
+public:
+ LFDNoise0_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+ void m_set(float f)
+ {
+ m_freq = f;
+ }
+
+private:
+ RGen rgen;
+ float m_freq;
+ float m_level;
+ float m_phase;
+ float m_smpdur;
+
+ bool m_ar;
+
+ FLEXT_CALLBACK_I(m_seed);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_DSP_V("LFDNoise0~",LFDNoise0_ar);
+
+LFDNoise0_ar::LFDNoise0_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+
+ m_phase=0.f;
+ m_level=0.f;
+
+ rgen.init(timeseed());
+
+ m_ar = sc_ar(Args);
+
+ if (m_ar)
+ AddInSignal("freqency");
+ else
+ AddInSignal("\"set\" frequency");
+ AddOutSignal();
+}
+
+void LFDNoise0_ar::m_dsp(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ m_smpdur = sc_sampledur();
+}
+
+
+void LFDNoise0_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float level = m_level;
+ float phase = m_phase;
+
+ RGET;
+
+ if (m_ar)
+ {
+ t_sample *nin = *in;
+ float smpdur = m_smpdur;
+ for (int i = 0; i!= n; ++i)
+ {
+ phase -= ZXP(nin) * smpdur;
+ if (phase <= 0)
+ {
+ phase = sc_wrap(phase, 0.f, 1.f);
+ level = frand2(s1,s2,s3);
+ }
+ ZXP(nout) = level;
+ }
+ }
+ else
+ {
+ float dphase = m_smpdur * m_freq;
+ for (int i = 0; i!= n; ++i)
+ {
+ phase -= dphase;
+ if (phase <= 0)
+ {
+ phase = sc_wrap(phase, 0.f, 1.f);
+ level = frand2(s1,s2,s3);
+ }
+ ZXP(nout) = level;
+ }
+ }
+
+
+ m_level = level;
+ m_phase = phase;
+
+ RPUT;
+}
+
+
diff --git a/sc4pd/source/LFDNoise1.cpp b/sc4pd/source/LFDNoise1.cpp
new file mode 100644
index 0000000..8336b80
--- /dev/null
+++ b/sc4pd/source/LFDNoise1.cpp
@@ -0,0 +1,172 @@
+/* sc4pd
+ LFDNoise1~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ *
+ * DynNoiseUGens.cpp
+ * xSC3plugins
+ *
+ * Created by Alberto de Campo, Sekhar Ramacrishnan, Julian Rohrhuber on Sun May 30 2004.
+ * Copyright (c) 2004 HfbK. All rights reserved.
+ *
+ *
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Phil Minton & Veryan Weston: Ways Past
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ LFDNoise1~ -------------------------------*/
+
+class LFDNoise1_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LFDNoise1_ar,sc4pd_dsp);
+
+public:
+ LFDNoise1_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+ void m_set(float f)
+ {
+ m_freq = f;
+ }
+
+private:
+ RGen rgen;
+ float m_freq;
+ float m_prevlevel;
+ float m_nextlevel;
+ float m_phase;
+ float m_smpdur;
+
+ bool m_ar;
+
+ FLEXT_CALLBACK_I(m_seed);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_DSP_V("LFDNoise1~",LFDNoise1_ar);
+
+LFDNoise1_ar::LFDNoise1_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+
+ rgen.init(timeseed());
+
+ m_phase=0.f;
+ m_prevlevel=0.f;
+ m_nextlevel = rgen.frand2();
+
+
+ m_ar = sc_ar(Args);
+
+ if (m_ar)
+ AddInSignal("freqency");
+ else
+ AddInSignal("\"set\" frequency");
+ AddOutSignal();
+}
+
+void LFDNoise1_ar::m_dsp(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ m_smpdur = sc_sampledur();
+}
+
+
+void LFDNoise1_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float prevLevel = m_prevlevel;
+ float nextLevel = m_nextlevel;
+ float phase = m_phase;
+
+ RGET;
+
+ if (m_ar)
+ {
+ t_sample *nin = *in;
+ float smpdur = m_smpdur;
+ for (int i = 0; i!= n; ++i)
+ {
+ phase -= ZXP(nin) * smpdur;
+ if (phase <= 0)
+ {
+ phase = sc_wrap(phase, 0.f, 1.f);
+ prevLevel = nextLevel;
+ nextLevel = frand2(s1,s2,s3);
+ }
+ ZXP(nout) = nextLevel + ( phase * (prevLevel - nextLevel) );
+ }
+ }
+ else
+ {
+ float dphase = m_smpdur * m_freq;
+ for (int i = 0; i!= n; ++i)
+ {
+ phase -= dphase;
+ if (phase <= 0)
+ {
+ phase = sc_wrap(phase, 0.f, 1.f);
+ prevLevel = nextLevel;
+ nextLevel = frand2(s1,s2,s3);
+ }
+ ZXP(nout) = nextLevel + ( phase * (prevLevel - nextLevel) );
+ }
+ }
+
+ m_prevlevel = prevLevel;
+ m_nextlevel = nextLevel;
+ m_phase = phase;
+
+ RPUT;
+}
+
+
diff --git a/sc4pd/source/LFDNoise2.cpp b/sc4pd/source/LFDNoise2.cpp
new file mode 100644
index 0000000..136b1c9
--- /dev/null
+++ b/sc4pd/source/LFDNoise2.cpp
@@ -0,0 +1,188 @@
+/* sc4pd
+ LFDNoise2~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ *
+ * DynNoiseUGens.cpp
+ * xSC3plugins
+ *
+ * Created by Alberto de Campo, Sekhar Ramacrishnan, Julian Rohrhuber on Sun May 30 2004.
+ * Copyright (c) 2004 HfbK. All rights reserved.
+ *
+ *
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Phil Minton & Veryan Weston: Ways Past
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ LFDNoise2~ -------------------------------*/
+
+class LFDNoise2_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LFDNoise2_ar,sc4pd_dsp);
+
+public:
+ LFDNoise2_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+ void m_set(float f)
+ {
+ m_freq = f;
+ }
+
+private:
+ RGen rgen;
+ float m_freq;
+ float m_levela, m_levelb, m_levelc, m_leveld;
+ float m_phase;
+ float m_smpdur;
+
+ bool m_ar;
+
+ FLEXT_CALLBACK_I(m_seed);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_DSP_V("LFDNoise2~",LFDNoise2_ar);
+
+LFDNoise2_ar::LFDNoise2_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+
+ rgen.init(timeseed());
+
+ RGET;
+
+ m_phase=0.f;
+ m_levela = frand2(s1, s2, s3) * 0.8f;// limits max interpol. overshoot to 1.
+ m_levelb = frand2(s1, s2, s3) * 0.8f;
+ m_levelc = frand2(s1, s2, s3) * 0.8f;
+ m_leveld = frand2(s1, s2, s3) * 0.8f;
+
+ RPUT;
+
+ m_ar = sc_ar(Args);
+
+ if (m_ar)
+ AddInSignal("freqency");
+ else
+ AddInSignal("\"set\" frequency");
+ AddOutSignal();
+}
+
+void LFDNoise2_ar::m_dsp(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ m_smpdur = sc_sampledur();
+}
+
+
+void LFDNoise2_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float a = m_levela;
+ float b = m_levelb;
+ float c = m_levelc;
+ float d = m_leveld;
+
+ float phase = m_phase;
+
+ RGET;
+
+ if (m_ar)
+ {
+ t_sample *nin = *in;
+ float smpdur = m_smpdur;
+ for (int i = 0; i!= n; ++i)
+ {
+ phase -= ZXP(nin) * smpdur;
+ if (phase <= 0)
+ {
+ phase = sc_wrap(phase, 0.f, 1.f);
+ a = b;
+ b = c;
+ c = d;
+ d = frand2(s1,s2,s3) * 0.8f; // limits max interpol. overshoot to 1.
+
+ }
+ ZXP(nout) = cubicinterp(1.f - phase, a, b, c, d);
+ }
+ }
+ else
+ {
+ float dphase = m_smpdur * m_freq;
+ for (int i = 0; i!= n; ++i)
+ {
+ phase -= dphase;
+ if (phase <= 0)
+ {
+ phase = sc_wrap(phase, 0.f, 1.f);
+ a = b;
+ b = c;
+ c = d;
+ d = frand2(s1,s2,s3) * 0.8f; // limits max interpol. overshoot to 1.
+ }
+ ZXP(nout) = cubicinterp(1.f - phase, a, b, c, d);
+ }
+ }
+
+
+ m_phase = phase;
+
+ m_levela = a;
+ m_levelb = b;
+ m_levelc = c;
+ m_leveld = d;
+
+ RPUT;
+}
+
+
diff --git a/sc4pd/source/LFNoise0.cpp b/sc4pd/source/LFNoise0.cpp
new file mode 100644
index 0000000..9ee9ff6
--- /dev/null
+++ b/sc4pd/source/LFNoise0.cpp
@@ -0,0 +1,195 @@
+/* sc4pd
+ LFNoise0, LFNoise0~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Elliott Sharp: Revenge Of The Stuttering Child
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ LFNoise0~ -------------------------------*/
+
+class LFNoise0_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LFNoise0_ar,sc4pd_dsp);
+
+public:
+ LFNoise0_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+ void m_set(float f)
+ {
+ m_freq = f;
+ }
+
+private:
+ RGen rgen;
+ float m_freq;
+ float m_level;
+ int m_counter;
+ int m_sr;
+ FLEXT_CALLBACK_I(m_seed);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_DSP_V("LFNoise0~",LFNoise0_ar);
+
+LFNoise0_ar::LFNoise0_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+
+ m_counter=0;
+ m_level=0;
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+}
+
+void LFNoise0_ar::m_dsp(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ m_sr = Samplerate();
+}
+
+
+void LFNoise0_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float level = m_level;
+ int32 counter = m_counter;
+
+ RGET;
+
+ int remain = n;
+ do
+ {
+ if (counter<=0)
+ {
+ counter = (int)(m_sr / sc_max(m_freq, .001f));
+ counter = sc_max(1, counter);
+ level = frand2(s1,s2,s3);
+ }
+ int nsmps = sc_min(remain, counter);
+ remain -= nsmps;
+ counter -= nsmps;
+
+ for (int i = 0; i!= nsmps;++i)
+ {
+ (*(nout)++)=level;
+ }
+ }
+ while(remain);
+
+ m_level = level;
+ m_counter = counter;
+
+ RPUT;
+}
+
+
+/* ------------------------ LFNoise0 ---------------------------------*/
+
+class LFNoise0_kr:
+ public flext_base
+{
+ FLEXT_HEADER(LFNoise0_kr,flext_base);
+
+public:
+ LFNoise0_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform(void*);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+ void m_set(float f)
+ {
+ double dt = sc_max(1/f, .001f);
+ m_timer.Reset();
+ m_timer.Periodic(dt);
+ }
+
+private:
+ RGen rgen;
+ Timer m_timer;
+ FLEXT_CALLBACK_I(m_seed);
+ FLEXT_CALLBACK_T(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("LFNoise0",LFNoise0_kr);
+
+LFNoise0_kr::LFNoise0_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+ FLEXT_ADDTIMER(m_timer,m_perform);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ double dt = sc_max(1/sc_getfloatarg(Args,0), .001f);
+
+ rgen.init(timeseed());
+
+ m_timer.Periodic(dt);
+
+ AddOutFloat();
+}
+
+void LFNoise0_kr::m_perform(void*)
+{
+ ToOutFloat(0,rgen.frand2());
+}
diff --git a/sc4pd/source/LFNoise1.cpp b/sc4pd/source/LFNoise1.cpp
new file mode 100644
index 0000000..c164942
--- /dev/null
+++ b/sc4pd/source/LFNoise1.cpp
@@ -0,0 +1,232 @@
+/* sc4pd
+ LFNoise1, LFNoise1~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Fred Frith: Gravity
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ LFNoise1~ -------------------------------*/
+
+class LFNoise1_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LFNoise1_ar,sc4pd_dsp);
+
+public:
+ LFNoise1_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+ void m_set(float f)
+ {
+ m_freq = f;
+ }
+
+private:
+ RGen rgen;
+ float m_freq;
+ float m_level;
+ float m_slope;
+ int m_counter;
+ int m_sr;
+ FLEXT_CALLBACK_I(m_seed);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_DSP_V("LFNoise1~",LFNoise1_ar);
+
+LFNoise1_ar::LFNoise1_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+
+ rgen.init(timeseed());
+
+ m_counter=0;
+ m_level=rgen.frand2();
+ m_slope=0;
+
+ AddOutSignal();
+}
+
+void LFNoise1_ar::m_dsp(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ m_sr = Samplerate();
+}
+
+
+void LFNoise1_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float level = m_level;
+ int32 counter = m_counter;
+ float slope = m_slope;
+
+ RGET;
+
+ int remain = n;
+ do
+ {
+ if (counter<=0)
+ {
+ counter = (int)(m_sr / sc_max(m_freq, .001f));
+ counter = sc_max(1, counter);
+ float nextlevel = frand2(s1,s2,s3);
+ slope = (nextlevel - level) / counter;
+ }
+ int nsmps = sc_min(remain, counter);
+ remain -= nsmps;
+ counter -= nsmps;
+
+ for (int i = 0; i!= nsmps;++i)
+ {
+ (*(nout)++)=level;
+ level+=slope;
+ }
+ }
+ while(remain);
+
+ m_level = level;
+ m_counter = counter;
+ m_slope = slope;
+
+ RPUT;
+}
+
+
+/* ------------------------ LFNoise1 ---------------------------------*/
+
+class LFNoise1_kr:
+ public flext_base
+{
+ FLEXT_HEADER(LFNoise1_kr,flext_base);
+
+public:
+ LFNoise1_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform(void*);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+ void m_set(float);
+
+private:
+ RGen rgen;
+ float m_level;
+ float m_slope;
+
+ float dt; //in s
+ float tick; //in s
+ int counter;
+
+ Timer m_timer;
+ FLEXT_CALLBACK_I(m_seed);
+ FLEXT_CALLBACK_T(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("LFNoise1",LFNoise1_kr);
+
+LFNoise1_kr::LFNoise1_kr(int argc, t_atom *argv)
+ : tick(0.01)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+ FLEXT_ADDTIMER(m_timer,m_perform);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ rgen.init(timeseed());
+
+ m_level=rgen.frand2();
+
+ AddOutFloat();
+
+ m_set(sc_getfloatarg(Args,0));
+}
+
+void LFNoise1_kr::m_set(float f)
+{
+ dt = sc_max(1/f, .001f);
+ counter = (dt/tick);
+
+ float nextlevel = rgen.frand2();
+ m_slope = (nextlevel - m_level) / counter;
+
+ m_timer.Reset();
+ m_timer.Delay(tick);
+}
+
+void LFNoise1_kr::m_perform(void*)
+{
+ m_level+=m_slope;
+ ToOutFloat(0,m_level);
+ if (--counter)
+ {
+ m_timer.Reset();
+ m_timer.Delay(tick);
+ }
+ else
+ {
+ counter = (dt/tick);
+ float nextlevel = rgen.frand2();
+ m_slope = (nextlevel - m_level) / counter;
+
+ m_timer.Reset();
+ m_timer.Delay(tick);
+
+ }
+}
diff --git a/sc4pd/source/LFNoise2.cpp b/sc4pd/source/LFNoise2.cpp
new file mode 100644
index 0000000..3b1fd37
--- /dev/null
+++ b/sc4pd/source/LFNoise2.cpp
@@ -0,0 +1,271 @@
+/* sc4pd
+ LFNoise2, LFNoise2~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Guenther Mueller & Toshimaru Nakamura: Tint
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ LFNoise2~ -------------------------------*/
+
+class LFNoise2_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LFNoise2_ar,sc4pd_dsp);
+
+public:
+ LFNoise2_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+ void m_set(float f)
+ {
+ m_freq = f;
+ }
+
+private:
+ RGen rgen;
+ float m_freq;
+ float m_level;
+ float m_slope;
+ float m_curve;
+ int m_counter;
+ int m_sr;
+ float m_nextvalue;
+ float m_nextmidpt;
+
+ FLEXT_CALLBACK_I(m_seed);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_DSP_V("LFNoise2~",LFNoise2_ar);
+
+LFNoise2_ar::LFNoise2_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+
+ rgen.init(timeseed());
+
+ m_counter=0;
+ m_level=rgen.frand2();
+ m_slope=0;
+ m_curve=0;
+ m_nextvalue=0;
+ m_nextmidpt=0;
+
+ AddOutSignal();
+}
+
+void LFNoise2_ar::m_dsp(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ m_sr = Samplerate();
+}
+
+
+void LFNoise2_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float level = m_level;
+ int32 counter = m_counter;
+ float slope = m_slope;
+ float curve = m_curve;
+
+ RGET;
+
+ int remain = n;
+ do
+ {
+ if (counter<=0)
+ {
+ float value = m_nextvalue;
+ m_nextvalue = frand2(s1,s2,s3);
+ level = m_nextmidpt;
+ m_nextmidpt = (m_nextvalue + value) * .5;
+
+ counter = (int32)(m_sr / sc_max(m_freq, .001f));
+ counter = sc_max(2, counter);
+ float fseglen = (float)counter;
+ curve = 2.f * (m_nextmidpt - level - fseglen * slope)
+ / (fseglen * fseglen + fseglen);
+ }
+ int nsmps = sc_min(remain, counter);
+ remain -= nsmps;
+ counter -= nsmps;
+
+ for (int i = 0; i!= nsmps;++i)
+ {
+ (*(nout)++)=level;
+ slope+=curve;
+ level+=slope;
+ }
+ }
+ while(remain);
+
+ m_level = level;
+ m_counter = counter;
+ m_slope = slope;
+ m_curve = curve;
+
+ RPUT;
+}
+
+
+/* ------------------------ LFNoise2 ---------------------------------*/
+
+class LFNoise2_kr:
+ public flext_base
+{
+ FLEXT_HEADER(LFNoise2_kr,flext_base);
+
+public:
+ LFNoise2_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform(void*);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+ void m_set(float);
+
+private:
+ RGen rgen;
+ float m_level;
+ float m_slope;
+ float m_curve;
+ float m_nextvalue;
+ float m_nextmidpt;
+
+ float dt; //in s
+ float tick; //in s
+ int counter;
+
+ Timer m_timer;
+ FLEXT_CALLBACK_I(m_seed);
+ FLEXT_CALLBACK_T(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("LFNoise2",LFNoise2_kr);
+
+LFNoise2_kr::LFNoise2_kr(int argc, t_atom *argv)
+ : tick(0.01)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+ FLEXT_ADDTIMER(m_timer,m_perform);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ rgen.init(timeseed());
+
+ m_level=rgen.frand2();
+
+ AddOutFloat();
+
+ m_set(sc_getfloatarg(Args,0));
+}
+
+
+void LFNoise2_kr::m_set(float f)
+{
+ dt = sc_max(1/f, .001f);
+ counter = (dt/tick);
+ counter = sc_max(2, counter);
+
+ float value = m_nextvalue;
+ m_nextvalue = rgen.frand2();
+ m_level = m_nextmidpt;
+ m_nextmidpt = (m_nextvalue + value) * .5;
+
+ float fseglen = (float)counter;
+ m_curve = 2.f * (m_nextmidpt - m_level - fseglen * m_slope)
+ / (fseglen * fseglen + fseglen);
+
+
+ m_timer.Reset();
+ m_timer.Delay(tick);
+}
+
+void LFNoise2_kr::m_perform(void*)
+{
+ m_slope+=m_curve;
+ m_level+=m_slope;
+ ToOutFloat(0,m_level);
+ if (--counter)
+ {
+ m_timer.Reset();
+ m_timer.Delay(tick);
+ }
+ else
+ {
+ counter = (dt/tick);
+
+ counter = sc_max(2, counter);
+
+ float value = m_nextvalue;
+ m_nextvalue = rgen.frand2();
+ m_level = m_nextmidpt;
+ m_nextmidpt = (m_nextvalue + value) * .5;
+
+ float fseglen = (float)counter;
+ m_curve = 2.f * (m_nextmidpt - m_level - fseglen * m_slope) /
+ (fseglen * fseglen + fseglen);
+
+ m_timer.Reset();
+ m_timer.Delay(tick);
+
+ }
+}
+
diff --git a/sc4pd/source/LFPulse.cpp b/sc4pd/source/LFPulse.cpp
new file mode 100644
index 0000000..ad16e65
--- /dev/null
+++ b/sc4pd/source/LFPulse.cpp
@@ -0,0 +1,292 @@
+/* sc4pd
+ LFPulse, LFPulse~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Keith Rowe & Oren Ambarchi: Flypaper
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ LFPulse~ -------------------------------*/
+
+class LFPulse_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LFPulse_ar,sc4pd_dsp);
+
+public:
+ LFPulse_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set(float f)
+ {
+ m_freq=f;
+ }
+
+ void m_ar()
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar));
+ }
+
+ void m_kr()
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr));
+ }
+
+ void m_width (float f)
+ {
+ nextDuty = f;
+ }
+
+
+private:
+ double mPhase;
+ float mFreqMul;
+ float m_freq; //for kr arguments
+ float mDuty;
+ float nextDuty;
+
+ DEFSIGCALL (m_signal_fun);
+ DEFSIGFUN (m_signal_ar);
+ DEFSIGFUN (m_signal_kr);
+
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK_F(m_width);
+ FLEXT_CALLBACK(m_ar);
+ FLEXT_CALLBACK(m_kr);
+};
+
+FLEXT_LIB_DSP_V("LFPulse~",LFPulse_ar);
+
+LFPulse_ar::LFPulse_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"freq",m_set);
+ FLEXT_ADDMETHOD_(0,"width",m_width);
+ FLEXT_ADDMETHOD_(0,"ar",m_ar);
+ FLEXT_ADDMETHOD_(0,"kr",m_kr);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+
+ nextDuty = sc_getfloatarg(Args,1);
+
+ if(sc_ar(Args))
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar));
+ else // if not given, use control rate
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr));
+
+ AddOutSignal();
+}
+
+void LFPulse_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ mFreqMul = 1 / Samplerate();
+
+}
+
+void LFPulse_ar::m_signal_ar(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *freq = *in;
+ t_sample *xout = *out;
+
+ float freqmul = mFreqMul;
+ double phase = mPhase;
+ float duty = mDuty;
+
+ for (int i = 0; i!= n;++i)
+ {
+ float z;
+ if (phase >= 1.f)
+ {
+ phase -= 1.f;
+ duty = mDuty = nextDuty;
+ // output at least one sample from the opposite polarity
+ z = duty < 0.5 ? 1.f : 0.f;
+ }
+ else
+ {
+ z = phase < duty ? 1.f : 0.f;
+ }
+
+ phase += (*(freq)++) * freqmul;
+ (*(xout)++) = z;
+ }
+
+ mPhase=phase;
+}
+
+
+void LFPulse_ar::m_signal_kr(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *xout = *out;
+
+ double phase = mPhase;
+ float duty = mDuty;
+ float freq = m_freq * mFreqMul;
+
+ for (int i = 0; i!= n;++i)
+ {
+ float z;
+ if (phase >= 1.f)
+ {
+ phase -= 1.f;
+ duty = mDuty = nextDuty;
+ // output at least one sample from the opposite polarity
+ z = duty < 0.5 ? 1.f : 0.f;
+ }
+ else
+ {
+ z = phase < duty ? 1.f : 0.f;
+ }
+
+ phase += freq;
+ (*(xout)++) = z;
+ }
+ mPhase=phase;
+}
+
+/* ------------------------ LFPulse ---------------------------------*/
+
+/* todo: remove obsolete messages */
+
+class LFPulse_kr:
+ public flext_base
+{
+ FLEXT_HEADER(LFPulse_kr,flext_base);
+
+public:
+ LFPulse_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform(void*);
+
+ void m_set(float f)
+ {
+ m_freq_set = f;
+ m_freq = f * mFreqMul;
+ }
+
+ void m_set_kr(float f)
+ {
+ if (f != 0)
+ {
+ dt = f * 0.001;
+ mFreqMul = dt;
+ m_freq = m_freq_set * mFreqMul;
+ m_timer.Reset();
+ m_timer.Periodic(dt);
+ }
+ }
+
+ void m_set_width(float f)
+ {
+ nextDuty=f;
+ }
+
+private:
+ double mPhase;
+ float mFreqMul;
+ float mDuty;
+ float nextDuty;
+ float m_freq;
+ float dt;
+ float m_freq_set;
+
+ Timer m_timer;
+
+ FLEXT_CALLBACK_F(m_set_kr);
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK_F(m_set_width);
+ FLEXT_CALLBACK_T(m_perform);
+};
+
+
+FLEXT_LIB_V("LFPulse",LFPulse_kr);
+
+LFPulse_kr::LFPulse_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(0,m_set);
+ FLEXT_ADDMETHOD_(0,"kr",m_set_kr);
+ FLEXT_ADDMETHOD_(0,"width",m_set_width);
+
+ FLEXT_ADDTIMER(m_timer,m_perform);
+
+ AddOutFloat();
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq_set = sc_getfloatarg(Args,0);
+
+ nextDuty = sc_getfloatarg(Args,1);
+
+ dt = sc_getfloatarg(Args,2) * 0.001;
+
+ if (dt == 0)
+ dt = 0.02; // 20 ms as default control rate as in line
+ mFreqMul = dt;
+
+ m_freq = m_freq_set * mFreqMul;
+
+ m_timer.Periodic(dt);
+
+}
+
+void LFPulse_kr::m_perform(void*)
+{
+ float z;
+ if (mPhase >= 1.f)
+ {
+ mPhase -= 1.f;
+ mDuty = nextDuty;
+ // output at least one sample from the opposite polarity
+ z = mDuty < 0.5 ? 1.f : 0.f;
+ }
+ else
+ {
+ z = mPhase < mDuty ? 1.f : 0.f;
+ }
+ mPhase += m_freq;
+ ToOutFloat(0,z);
+}
diff --git a/sc4pd/source/LFSaw.cpp b/sc4pd/source/LFSaw.cpp
new file mode 100644
index 0000000..0e406d0
--- /dev/null
+++ b/sc4pd/source/LFSaw.cpp
@@ -0,0 +1,256 @@
+/* sc4pd
+ LFSaw, LFSaw~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Keith Rowe & Oren Ambarchi: Flypaper
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ LFSaw~ -------------------------------*/
+
+class LFSaw_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LFSaw_ar,sc4pd_dsp);
+
+public:
+ LFSaw_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set(float f)
+ {
+ m_freq=f;
+ }
+
+ void m_ar()
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar));
+ }
+
+ void m_kr()
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr));
+ }
+
+private:
+ double mPhase;
+ float mFreqMul;
+ float m_freq; //for kr arguments
+
+ DEFSIGCALL (m_signal_fun);
+ DEFSIGFUN (m_signal_ar);
+ DEFSIGFUN (m_signal_kr);
+
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK(m_ar);
+ FLEXT_CALLBACK(m_kr);
+};
+
+FLEXT_LIB_DSP_V("LFSaw~",LFSaw_ar);
+
+LFSaw_ar::LFSaw_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"freq",m_set);
+ FLEXT_ADDMETHOD_(0,"ar",m_ar);
+ FLEXT_ADDMETHOD_(0,"kr",m_kr);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+
+ if(sc_ar(Args))
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar));
+ else // if not given, use control rate
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr));
+
+ AddOutSignal();
+}
+
+void LFSaw_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ mFreqMul = 2 / Samplerate();
+}
+
+void LFSaw_ar::m_signal_ar(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *freq = *in;
+ t_sample *xout = *out;
+
+ float freqmul = mFreqMul;
+ double phase = mPhase;
+
+ for (int i = 0; i!= n;++i)
+ {
+ float z = phase; // out must be written last for in place operation
+ phase += (*(freq)++) * freqmul;
+ if (phase >= 1.f)
+ phase -= 2.f;
+ else
+ if (phase <= -1.f)
+ phase += 2.f;
+ (*(xout)++) = z;
+ }
+
+ mPhase=phase;
+}
+
+
+void LFSaw_ar::m_signal_kr(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *xout = *out;
+
+ float freq = m_freq * mFreqMul;
+ double phase = mPhase;
+
+ if (freq >= 0.f)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ (*(xout)++) = phase;
+ phase += freq;
+ if (phase >= 1.f) phase -= 2.f;
+ }
+ }
+ else
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ (*(xout)++) = phase;
+ phase += freq;
+ if (phase <= -1.f) phase += 2.f;
+ }
+ }
+
+ mPhase=phase;
+}
+
+/* ------------------------ LFSaw ---------------------------------*/
+
+class LFSaw_kr:
+ public flext_base
+{
+ FLEXT_HEADER(LFSaw_kr,flext_base);
+
+public:
+ LFSaw_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform(void*);
+
+ void m_set(float f)
+ {
+ m_freq_set = f;
+ m_freq = f * mFreqMul;
+ }
+
+ void m_set_kr(float f)
+ {
+ if (f != 0)
+ {
+ dt = f * 0.001;
+ mFreqMul = 2*dt;
+ m_freq = m_freq_set * mFreqMul;
+ m_timer.Reset();
+ m_timer.Periodic(dt);
+ }
+ }
+
+private:
+ double mPhase;
+ float mFreqMul;
+ float m_freq;
+ float dt;
+ float m_freq_set;
+
+ Timer m_timer;
+
+ FLEXT_CALLBACK_F(m_set_kr);
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK_T(m_perform);
+};
+
+
+FLEXT_LIB_V("LFSaw",LFSaw_kr);
+
+LFSaw_kr::LFSaw_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(0,m_set);
+ FLEXT_ADDMETHOD_(0,"kr",m_set_kr);
+ // FLEXT_ADDBANG(0,m_perform);
+ FLEXT_ADDTIMER(m_timer,m_perform);
+
+ AddOutFloat();
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq_set = sc_getfloatarg(Args,0);
+
+ dt = sc_getfloatarg(Args,1) * 0.001;
+
+ if (dt == 0 )
+ dt = 0.02; // 20 ms as default control rate as in line
+ mFreqMul = 2 * dt; /* test this !!! */
+
+ m_freq = m_freq_set * mFreqMul;
+
+ m_timer.Periodic(dt);
+
+}
+
+void LFSaw_kr::m_perform(void*)
+{
+ if (m_freq >= 0.f)
+ {
+ ToOutFloat(0,mPhase);
+ mPhase += m_freq;
+ if (mPhase >= 1.f) mPhase -= 2.f;
+ }
+ else
+ {
+ ToOutFloat(0,mPhase);
+ mPhase += m_freq;
+ if (mPhase <= -1.f) mPhase += 2.f;
+ }
+}
diff --git a/sc4pd/source/LPF.cpp b/sc4pd/source/LPF.cpp
new file mode 100644
index 0000000..a11e784
--- /dev/null
+++ b/sc4pd/source/LPF.cpp
@@ -0,0 +1,180 @@
+/* sc4pd
+ LPF~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Peter Kowald & Tatsuya Nakatani:
+ 13 Definitions of Truth
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ LPF~ -------------------------------*/
+
+class LPF_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LPF_ar,sc4pd_dsp);
+
+public:
+ LPF_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ mRadiansPerSample = sc_radianspersample();
+ mFilterSlope = sc_filterslope();
+ mFilterLoops = sc_filterloops();
+ mFilterRemain = sc_filterremain();
+ }
+
+ void m_set_freq(float f)
+ {
+ m_freq=f;
+ changed = true;
+ }
+
+private:
+ float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq;
+ bool changed;
+ float mRadiansPerSample, mFilterSlope;
+ int mFilterLoops, mFilterRemain;
+
+ FLEXT_CALLBACK_F(m_set_freq);
+};
+
+FLEXT_LIB_DSP_V("LPF~",LPF_ar);
+
+LPF_ar::LPF_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+ changed = true;
+
+ AddOutSignal();
+
+ m_a0 = 0.f;
+ m_b1 = 0.f;
+ m_b2 = 0.f;
+ m_y1 = 0.f;
+ m_y2 = 0.f;
+}
+
+void LPF_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float y0;
+ float y1 = m_y1;
+ float y2 = m_y2;
+ float a0 = m_a0;
+ float b1 = m_b1;
+ float b2 = m_b2;
+
+ if (changed)
+ {
+ float pfreq = m_freq * mRadiansPerSample * 0.5;
+
+ float C = 1.f / tan(pfreq);
+ float C2 = C * C;
+ float sqrt2C = C * sqrt2;
+ float next_a0 = 1.f / (1.f + sqrt2C + C2);
+ float next_b1 = -2.f * (1.f - C2) * next_a0 ;
+ float next_b2 = -(1.f - sqrt2C + C2) * next_a0;
+
+ float a0_slope = (next_a0 - a0) * mFilterSlope;
+ float b1_slope = (next_b1 - b1) * mFilterSlope;
+ float b2_slope = (next_b2 - b2) * mFilterSlope;
+
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 + 2.f * y1 + y2);
+
+ y2 = ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = a0 * (y2 + 2.f * y0 + y1);
+
+ y1 = ZXP(nin) + b1 * y2 + b2 * y0;
+ ZXP(nout) = a0 * (y1 + 2.f * y2 + y0);
+
+ a0 += a0_slope;
+ b1 += b1_slope;
+ b2 += b2_slope;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 + 2.f * y1 + y2);
+ y2 = y1;
+ y1 = y0;
+ }
+
+ m_a0 = a0;
+ m_b1 = b1;
+ m_b2 = b2;
+ changed = false;
+ }
+ else
+ {
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 + 2.f * y1 + y2);
+
+ y2 = ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = a0 * (y2 + 2.f * y0 + y1);
+
+ y1 = ZXP(nin) + b1 * y2 + b2 * y0;
+ ZXP(nout) = a0 * (y1 + 2.f * y2 + y0);
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 + 2.f * y1 + y2);
+ y2 = y1;
+ y1 = y0;
+ }
+ }
+ m_y1 = zapgremlins(y1);
+ m_y2 = zapgremlins(y2);
+}
+
+/* no control rate LPF filter */
diff --git a/sc4pd/source/LPZ1.cpp b/sc4pd/source/LPZ1.cpp
new file mode 100644
index 0000000..70e495b
--- /dev/null
+++ b/sc4pd/source/LPZ1.cpp
@@ -0,0 +1,132 @@
+/* sc4pd
+ LPZ1~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: William Parker: Compassion Seizes Bed-Stuy
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ LPZ1~ -------------------------------*/
+
+class LPZ1_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LPZ1_ar,sc4pd_dsp);
+
+public:
+ LPZ1_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+ float m_x1;
+};
+
+FLEXT_LIB_DSP_V("LPZ1~",LPZ1_ar);
+
+LPZ1_ar::LPZ1_ar(int argc, t_atom *argv)
+{
+ AddOutSignal();
+
+ m_x1=0;
+}
+
+void LPZ1_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float x0;
+ float x1 = m_x1;
+
+ int t = n >> 2;
+ for (int i = 0; i!= t;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = 0.5f * (x0 + x1);
+ x1 = ZXP(nin);
+ ZXP(nout) = 0.5f * (x1 + x0);
+ x0 = ZXP(nin);
+ ZXP(nout) = 0.5f * (x0 + x1);
+ x1 = ZXP(nin);
+ ZXP(nout) = 0.5f * (x1 + x0);
+ }
+
+ t = n & 3;
+ for (int i = 0; i!= t;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = 0.5f * (x0 + x1);
+ x1 = x0;
+ }
+ m_x1 = x1;
+}
+
+/* ------------------------ LPZ1 -------------------------------*/
+
+class LPZ1_kr:
+ public flext_base
+{
+ FLEXT_HEADER(LPZ1_kr,flext_base);
+
+public:
+ LPZ1_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform (float f);
+
+private:
+ float m_x1;
+ FLEXT_CALLBACK_F(m_perform);
+};
+
+FLEXT_LIB_V("LPZ1",LPZ1_kr);
+
+LPZ1_kr::LPZ1_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(0,m_perform);
+
+ AddOutFloat();
+
+ m_x1=0;
+}
+
+void LPZ1_kr::m_perform(float f)
+{
+ ToOutFloat(0,0.5f * (f + m_x1));
+ m_x1=f;
+}
+
diff --git a/sc4pd/source/LPZ2.cpp b/sc4pd/source/LPZ2.cpp
new file mode 100644
index 0000000..4165690
--- /dev/null
+++ b/sc4pd/source/LPZ2.cpp
@@ -0,0 +1,140 @@
+/* sc4pd
+ LPZ2~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: William Parker: Compassion Seizes Bed-Stuy
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ LPZ2~ -------------------------------*/
+
+class LPZ2_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LPZ2_ar,sc4pd_dsp);
+
+public:
+ LPZ2_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ mFilterLoops=sc_filterloops();
+ mFilterRemain=sc_filterremain();
+ }
+
+private:
+ float m_x1, m_x2;
+ int mFilterLoops, mFilterRemain;
+};
+
+FLEXT_LIB_DSP_V("LPZ2~",LPZ2_ar);
+
+LPZ2_ar::LPZ2_ar(int argc, t_atom *argv)
+{
+ AddOutSignal();
+
+ m_x1=0;
+ m_x2=0;
+}
+
+void LPZ2_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float x0;
+ float x1 = m_x1;
+ float x2 = m_x2;
+
+ for (int i = 0; i!=mFilterLoops ;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = (x0 + 2.f * x1 + x2) * 0.25f;
+ x2 = ZXP(nin);
+ ZXP(nout) = (x2 + 2.f * x0 + x1) * 0.25f;
+ x1 = ZXP(nin);
+ ZXP(nout) = (x1 + 2.f * x2 + x0) * 0.25f;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = (x0 + 2.f * x1 + x2) * 0.25f;
+ x2 = x1;
+ x1 = x0;
+ }
+ m_x1 = x1;
+ m_x2 = x2;
+}
+
+/* ------------------------ LPZ2 -------------------------------*/
+
+class LPZ2_kr:
+ public flext_base
+{
+ FLEXT_HEADER(LPZ2_kr,flext_base);
+
+public:
+ LPZ2_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform (float f);
+
+private:
+ float m_x1;
+ float m_x2;
+ FLEXT_CALLBACK_F(m_perform);
+};
+
+FLEXT_LIB_V("LPZ2",LPZ2_kr);
+
+LPZ2_kr::LPZ2_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(0,m_perform);
+
+ AddOutFloat();
+
+ m_x2 = m_x1 = 0;
+}
+
+void LPZ2_kr::m_perform(float f)
+{
+ ToOutFloat(0,(f + 2.f * m_x1 + m_x2) * 0.25f);
+ m_x2=m_x1;
+ m_x1=f;
+}
+
diff --git a/sc4pd/source/Lag.cpp b/sc4pd/source/Lag.cpp
new file mode 100644
index 0000000..5daf6d1
--- /dev/null
+++ b/sc4pd/source/Lag.cpp
@@ -0,0 +1,124 @@
+/* sc4pd
+ Lag~, Lag
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: VA: Live from the Vision Festival
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ Lag~ -----------------------------*/
+
+class Lag_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(Lag_ar,sc4pd_dsp);
+
+public:
+ Lag_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+ void m_set(float f);
+
+private:
+ FLEXT_CALLBACK_F(m_set);
+ float m_b1, n_b1;
+ float m_y1;
+ float m_lag;
+ bool changed;
+};
+
+FLEXT_LIB_DSP_V("Lag~",Lag_ar);
+
+Lag_ar::Lag_ar(int argc,t_atom * argv)
+{
+ FLEXT_ADDMETHOD_(0,"lagTime",m_set);
+
+ AtomList Args(argc,argv);
+
+ m_lag = sc_getfloatarg(Args,0);
+
+ AddOutSignal();
+
+ m_y1 = 0.f;
+}
+
+void Lag_ar::m_dsp(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ changed = false;
+ m_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate()));
+}
+
+void Lag_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin = *in;
+
+ float y1 = m_y1;
+ float b1 = m_b1;
+
+ if (changed)
+ {
+ float b1_slope = CALCSLOPE(m_b1, n_b1);
+ m_b1 = n_b1;
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = ZXP(nin);
+ ZXP(nout) = y1 = y0 + b1 * (y1 - y0);
+ b1 += b1_slope;
+ }
+ changed = false;
+ }
+ else
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = ZXP(nin);
+ ZXP(nout) = y1 = y0 + b1 * (y1 - y0);
+ }
+ }
+ m_y1 = zapgremlins(y1);
+}
+
+void Lag_ar::m_set(float f)
+{
+ m_lag = f;
+ n_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate()));
+ changed = true;
+}
+
+/* todo: does a control rate Lag make sense? */
diff --git a/sc4pd/source/Lag2.cpp b/sc4pd/source/Lag2.cpp
new file mode 100644
index 0000000..dc85fcb
--- /dev/null
+++ b/sc4pd/source/Lag2.cpp
@@ -0,0 +1,132 @@
+/* sc4pd
+ Lag2~, Lag2
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: DKV Trio: Baraka
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ Lag2~ -----------------------------*/
+
+class Lag2_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(Lag2_ar,sc4pd_dsp);
+
+public:
+ Lag2_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+ void m_set(float f);
+
+private:
+ FLEXT_CALLBACK_F(m_set);
+ float m_b1, n_b1;
+ float m_y1a, m_y1b;
+ float m_lag;
+ bool changed;
+};
+
+FLEXT_LIB_DSP_V("Lag2~",Lag2_ar);
+
+Lag2_ar::Lag2_ar(int argc,t_atom * argv)
+{
+ FLEXT_ADDMETHOD_(0,"lagTime",m_set);
+
+ AtomList Args(argc,argv);
+
+ m_lag = sc_getfloatarg(Args,0);
+
+ AddOutSignal();
+
+ m_b1 = 0.f;
+ m_y1a = 0.f;
+ m_y1b = 0.f;
+}
+
+void Lag2_ar::m_dsp(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ changed = false;
+ m_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate()));
+}
+
+void Lag2_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin = *in;
+
+ float y1a = m_y1a;
+ float y1b = m_y1b;
+ float b1 = m_b1;
+
+ if (changed)
+ {
+ float b1_slope = CALCSLOPE(m_b1, n_b1);
+ m_b1 = n_b1;
+ for (int i = 0; i!= n;++i)
+ {
+ float y0a = ZXP(nin);
+ y1a = y0a + b1 * (y1a - y0a);
+ y1b = y1a + b1 * (y1b - y1a);
+ ZXP(nout) = y1b;
+ b1 += b1_slope;
+ }
+ changed = false;
+ }
+ else
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0a = ZXP(nin);
+ y1a = y0a + b1 * (y1a - y0a);
+ y1b = y1a + b1 * (y1b - y1a);
+ ZXP(nout) = y1b;
+ }
+ }
+ m_y1a = zapgremlins(y1a);
+ m_y1b = zapgremlins(y1b);
+}
+
+void Lag2_ar::m_set(float f)
+{
+ m_lag = f;
+ n_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate()));
+ changed = true;
+}
+
+/* todo: does a control rate Lag2 make sense? */
diff --git a/sc4pd/source/Lag3.cpp b/sc4pd/source/Lag3.cpp
new file mode 100644
index 0000000..8865555
--- /dev/null
+++ b/sc4pd/source/Lag3.cpp
@@ -0,0 +1,137 @@
+/* sc4pd
+ Lag3~, Lag3
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: DKV Trio: Baraka
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ Lag3~ -----------------------------*/
+
+class Lag3_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(Lag3_ar,sc4pd_dsp);
+
+public:
+ Lag3_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+ void m_set(float f);
+
+private:
+ FLEXT_CALLBACK_F(m_set);
+ float m_b1, n_b1;
+ float m_y1a, m_y1b,m_y1c;
+ float m_lag;
+ bool changed;
+};
+
+FLEXT_LIB_DSP_V("Lag3~",Lag3_ar);
+
+Lag3_ar::Lag3_ar(int argc,t_atom * argv)
+{
+ FLEXT_ADDMETHOD_(0,"lagTime",m_set);
+
+ AtomList Args(argc,argv);
+
+ m_lag = sc_getfloatarg(Args,0);
+
+ AddOutSignal();
+
+ m_b1 = 0.f;
+ m_y1a = 0.f;
+ m_y1b = 0.f;
+ m_y1c = 0.f;
+}
+
+void Lag3_ar::m_dsp(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ changed = false;
+ m_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate()));
+}
+
+void Lag3_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin = *in;
+
+ float y1a = m_y1a;
+ float y1b = m_y1b;
+ float y1c = m_y1c;
+ float b1 = m_b1;
+
+ if (changed)
+ {
+ float b1_slope = CALCSLOPE(m_b1, n_b1);
+ m_b1 = n_b1;
+ for (int i = 0; i!= n;++i)
+ {
+ float y0a = ZXP(nin);
+ y1a = y0a + b1 * (y1a - y0a);
+ y1b = y1a + b1 * (y1b - y1a);
+ y1c = y1b + b1 * (y1c - y1b);
+ ZXP(nout) = y1c;
+ b1 += b1_slope;
+ }
+ changed = false;
+ }
+ else
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0a = ZXP(nin);
+ y1a = y0a + b1 * (y1a - y0a);
+ y1b = y1a + b1 * (y1b - y1a);
+ y1c = y1b + b1 * (y1c - y1b);
+ ZXP(nout) = y1c;
+ }
+ }
+ m_y1a = zapgremlins(y1a);
+ m_y1b = zapgremlins(y1b);
+ m_y1b = zapgremlins(y1c);
+}
+
+void Lag3_ar::m_set(float f)
+{
+ m_lag = f;
+ n_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate()));
+ changed = true;
+}
+
+/* todo: does a control rate Lag3 make sense? */
diff --git a/sc4pd/source/Latoocarfian.cpp b/sc4pd/source/Latoocarfian.cpp
new file mode 100644
index 0000000..1e20632
--- /dev/null
+++ b/sc4pd/source/Latoocarfian.cpp
@@ -0,0 +1,217 @@
+/* sc4pd
+ Latoocarfian, Latoocarfian~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Keith Rowe & John Tilbury: Duos For Doris
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ Latoocarfian~ -------------------------------*/
+
+class Latoocarfian_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(Latoocarfian_ar,sc4pd_dsp);
+
+public:
+ Latoocarfian_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set_a(float f)
+ {
+ m_a = f;
+ }
+
+ void m_set_b(float f)
+ {
+ m_b = f;
+ }
+
+ void m_set_c(float f)
+ {
+ m_c = f;
+ }
+
+ void m_set_d(float f)
+ {
+ m_d = f;
+ }
+
+private:
+ float m_x, m_y; //state
+ float m_a, m_b, m_c, m_d; //parameters
+
+ FLEXT_CALLBACK_F(m_set_a);
+ FLEXT_CALLBACK_F(m_set_b);
+ FLEXT_CALLBACK_F(m_set_c);
+ FLEXT_CALLBACK_F(m_set_d);
+};
+
+FLEXT_LIB_DSP_V("Latoocarfian~",Latoocarfian_ar);
+
+Latoocarfian_ar::Latoocarfian_ar(int argc, t_atom *argv)
+ :m_x(4),m_y(1)
+{
+ FLEXT_ADDMETHOD_(0,"a",m_set_a);
+ FLEXT_ADDMETHOD_(0,"b",m_set_b);
+ FLEXT_ADDMETHOD_(0,"c",m_set_c);
+ FLEXT_ADDMETHOD_(0,"d",m_set_d);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+ if (Args.Count()!=4)
+ {
+ post("4 arguments needed");
+ }
+ m_a = sc_getfloatarg(Args,0);
+ m_b = sc_getfloatarg(Args,1);
+ m_c = sc_getfloatarg(Args,2);
+ m_d = sc_getfloatarg(Args,3);
+
+ AddOutSignal();
+ AddOutSignal(); // supercollider is only using the x coordinate
+}
+
+
+void Latoocarfian_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *xout = *out;
+ t_sample *yout = *(out+1);
+
+ float a = m_a;
+ float b = m_b;
+ float c = m_c;
+ float d = m_d;
+
+ float x = m_x;
+ float y = m_y;
+
+ for (int i = 0; i!= n;++i)
+ {
+ float x_new=sin(y*b)+c*sin(x*b);
+ float y_new=sin(x*a)+d*sin(y*a);
+ (*(xout)++)=x=x_new;
+ (*(yout)++)=y=y_new;
+ }
+ m_x = x;
+ m_y = y;
+}
+
+
+
+/* ------------------------ Latoocarfian ---------------------------------*/
+
+class Latoocarfian_kr:
+ public flext_base
+{
+ FLEXT_HEADER(Latoocarfian_kr,flext_base);
+
+public:
+ Latoocarfian_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform();
+
+ void m_set_a(float f)
+ {
+ m_a = f;
+ }
+
+ void m_set_b(float f)
+ {
+ m_b = f;
+ }
+
+ void m_set_c(float f)
+ {
+ m_c = f;
+ }
+
+ void m_set_d(float f)
+ {
+ m_d = f;
+ }
+
+private:
+ float m_x, m_y; //state
+ float m_a, m_b, m_c, m_d; //parameters
+
+ FLEXT_CALLBACK_F(m_set_a);
+ FLEXT_CALLBACK_F(m_set_b);
+ FLEXT_CALLBACK_F(m_set_c);
+ FLEXT_CALLBACK_F(m_set_d);
+ FLEXT_CALLBACK(m_perform);
+};
+
+
+FLEXT_LIB_V("Latoocarfian",Latoocarfian_kr);
+
+Latoocarfian_kr::Latoocarfian_kr(int argc, t_atom *argv)
+ :m_x(1),m_y(1)
+{
+ FLEXT_ADDMETHOD_(0,"a",m_set_a);
+ FLEXT_ADDMETHOD_(0,"b",m_set_b);
+ FLEXT_ADDMETHOD_(0,"c",m_set_c);
+ FLEXT_ADDMETHOD_(0,"d",m_set_d);
+
+ FLEXT_ADDBANG(0,m_perform);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+ if (Args.Count()!=4)
+ {
+ post("4 arguments needed");
+ }
+ m_a = sc_getfloatarg(Args,0);
+ m_b = sc_getfloatarg(Args,1);
+ m_c = sc_getfloatarg(Args,2);
+ m_d = sc_getfloatarg(Args,3);
+
+
+ AddOutFloat();
+ AddOutFloat(); // one outlet more than sc
+}
+
+void Latoocarfian_kr::m_perform()
+{
+ m_x=sin(m_y*m_b)+m_c*sin(m_x*m_b);
+ m_y=sin(m_x*m_a)+m_d*sin(m_y*m_a);
+
+ ToOutFloat(0,m_x);
+ ToOutFloat(1,m_y);
+}
diff --git a/sc4pd/source/LinCong.cpp b/sc4pd/source/LinCong.cpp
new file mode 100644
index 0000000..fdead9c
--- /dev/null
+++ b/sc4pd/source/LinCong.cpp
@@ -0,0 +1,211 @@
+/* sc4pd
+ LinCong, LinCong~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Keith Rowe & John Tilbury: Duos For Doris
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ LinCong~ -------------------------------*/
+
+class LinCong_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LinCong_ar,sc4pd_dsp);
+
+public:
+ LinCong_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set_seed(float f)
+ {
+ m_seed = (int)f;
+ }
+
+ void m_set_mul(float f)
+ {
+ m_mul = (int)f;
+ }
+
+ void m_set_add(float f)
+ {
+ m_add = (int)f;
+ }
+
+ void m_set_mod(float f)
+ {
+ m_mod = (int)f;
+ m_scale = 2/f; //output between -1 and 1
+ }
+
+private:
+ unsigned int m_seed; //seed
+ unsigned int m_mul, m_add, m_mod; //parameters
+
+ float m_scale;
+
+ FLEXT_CALLBACK_F(m_set_seed);
+ FLEXT_CALLBACK_F(m_set_mul);
+ FLEXT_CALLBACK_F(m_set_add);
+ FLEXT_CALLBACK_F(m_set_mod);
+};
+
+FLEXT_LIB_DSP_V("LinCong~",LinCong_ar);
+
+LinCong_ar::LinCong_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_set_seed);
+ FLEXT_ADDMETHOD_(0,"mul",m_set_mul);
+ FLEXT_ADDMETHOD_(0,"add",m_set_add);
+ FLEXT_ADDMETHOD_(0,"mod",m_set_mod);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+ if (Args.Count()!=4)
+ {
+ post("4 arguments needed");
+ }
+ m_seed = sc_getfloatarg(Args,0);
+ m_mul = sc_getfloatarg(Args,1);
+ m_add = sc_getfloatarg(Args,2);
+ m_set_mod(sc_getfloatarg(Args,3));
+
+ AddOutSignal();
+}
+
+
+void LinCong_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *xout = *out;
+
+
+ unsigned int seed = m_seed;
+ unsigned int mul = m_mul;
+ unsigned int add = m_add;
+ unsigned int mod = m_mod;
+
+ float scale = m_scale;
+
+ for (int i = 0; i!= n;++i)
+ {
+ seed=(seed * mul + add) % mod;
+ (*(xout)++)=float(seed)*scale - 1;
+ }
+
+ m_seed = seed;
+}
+
+
+
+/* ------------------------ LinCong ---------------------------------*/
+
+class LinCong_kr:
+ public flext_base
+{
+ FLEXT_HEADER(LinCong_kr,flext_base);
+
+public:
+ LinCong_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform();
+
+ void m_set_seed(float f)
+ {
+ m_seed = (int)f;
+ }
+
+ void m_set_mul(float f)
+ {
+ m_mul = (int)f;
+ }
+
+ void m_set_add(float f)
+ {
+ m_add = (int)f;
+ }
+
+ void m_set_mod(float f)
+ {
+ m_mod = (int)f;
+ m_scale = 2/f; //output between -1 and 1
+ }
+
+private:
+ unsigned int m_seed; //seed
+ unsigned int m_mul, m_add, m_mod; //parameters
+
+ float m_scale;
+
+ FLEXT_CALLBACK_F(m_set_seed);
+ FLEXT_CALLBACK_F(m_set_mul);
+ FLEXT_CALLBACK_F(m_set_add);
+ FLEXT_CALLBACK_F(m_set_mod);
+ FLEXT_CALLBACK(m_perform);
+};
+
+
+FLEXT_LIB_V("LinCong",LinCong_kr);
+
+LinCong_kr::LinCong_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_set_seed);
+ FLEXT_ADDMETHOD_(0,"mul",m_set_mul);
+ FLEXT_ADDMETHOD_(0,"add",m_set_add);
+ FLEXT_ADDMETHOD_(0,"mod",m_set_mod);
+ FLEXT_ADDBANG(0,m_perform);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+ if (Args.Count()!=4)
+ {
+ post("4 arguments needed");
+ }
+ m_seed = sc_getfloatarg(Args,0);
+ m_mul = sc_getfloatarg(Args,1);
+ m_add = sc_getfloatarg(Args,2);
+ m_set_mod(sc_getfloatarg(Args,3));
+
+ AddOutFloat();
+}
+
+void LinCong_kr::m_perform()
+{
+ m_seed=(m_seed * m_mul + m_add) % m_mod;
+ ToOutFloat(0,float(m_seed) * m_scale - 1);
+}
diff --git a/sc4pd/source/LinExp.cpp b/sc4pd/source/LinExp.cpp
new file mode 100644
index 0000000..69e9e0a
--- /dev/null
+++ b/sc4pd/source/LinExp.cpp
@@ -0,0 +1,223 @@
+/* sc4pd
+ LinExp~, LinExp
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: The Ex & Tom Cora - And The Weathermen Shrug
+ Their Shoulders
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ LinExp~ -----------------------------*/
+
+class LinExp_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(LinExp_ar,sc4pd_dsp);
+
+public:
+ LinExp_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set_srclo(float f)
+ {
+ m_srclo = f;
+ m_reset();
+ }
+
+ void m_set_srchi(float f)
+ {
+ m_srchi = f;
+ m_reset();
+ }
+
+ void m_set_dstlo(float f)
+ {
+ m_dstlo = f;
+ m_reset();
+ }
+
+ void m_set_dsthi(float f)
+ {
+ m_dsthi = f;
+ m_reset();
+ }
+
+ void m_reset()
+ {
+ m_dstratio = m_dsthi/m_dstlo;
+ m_rsrcrange = 1. / (m_srchi - m_srclo);
+ m_rrminuslo = m_rsrcrange * -m_srclo;
+ }
+
+private:
+ FLEXT_CALLBACK_F(m_set_srclo);
+ FLEXT_CALLBACK_F(m_set_srchi);
+ FLEXT_CALLBACK_F(m_set_dstlo);
+ FLEXT_CALLBACK_F(m_set_dsthi);
+ float m_dstratio, m_rsrcrange, m_rrminuslo, m_dstlo;
+ float m_srclo, m_srchi, m_dsthi; //we will be able to reset the values
+};
+
+FLEXT_LIB_DSP_V("LinExp~",LinExp_ar);
+
+LinExp_ar::LinExp_ar(int argc,t_atom * argv)
+{
+ FLEXT_ADDMETHOD_(0,"srclo",m_set_srclo);
+ FLEXT_ADDMETHOD_(0,"srchi",m_set_srchi);
+ FLEXT_ADDMETHOD_(0,"dstlo",m_set_dstlo);
+ FLEXT_ADDMETHOD_(0,"dsthi",m_set_dsthi);
+
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 4)
+ post("4 arguments are required");
+ else
+ {
+ m_srclo = sc_getfloatarg(Args,0);
+ m_srchi = sc_getfloatarg(Args,1);
+ m_dstlo = sc_getfloatarg(Args,2);
+ m_dsthi = sc_getfloatarg(Args,3);
+
+ m_reset();
+ AddOutSignal();
+ }
+}
+
+void LinExp_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin = *in;
+
+ float dstlo = m_dstlo;
+ float dstratio = m_dstratio;
+ float rsrcrange = m_rsrcrange;
+ float rrminuslo = m_rrminuslo;
+
+ for (int i = 0; i!= n;++i)
+ {
+ ZXP(nout) = dstlo * pow(dstratio, ZXP(nin) * rsrcrange + rrminuslo);
+ }
+}
+
+/* ------------------------ LinExp ------------------------------*/
+
+class LinExp_kr
+ :public flext_base
+{
+ FLEXT_HEADER(LinExp_kr,flext_base);
+
+public:
+ LinExp_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+
+ void m_set_srclo(float f)
+ {
+ m_srclo = f;
+ m_reset();
+ }
+
+ void m_set_srchi(float f)
+ {
+ m_srchi = f;
+ m_reset();
+ }
+
+ void m_set_dstlo(float f)
+ {
+ m_dstlo = f;
+ m_reset();
+ }
+
+ void m_set_dsthi(float f)
+ {
+ m_dsthi = f;
+ m_reset();
+ }
+
+ void m_reset()
+ {
+ m_dstratio = m_dsthi/m_dstlo;
+ m_rsrcrange = 1. / (m_srchi - m_srclo);
+ m_rrminuslo = m_rsrcrange * -m_srclo;
+ }
+
+private:
+ FLEXT_CALLBACK_F(m_set_srclo);
+ FLEXT_CALLBACK_F(m_set_srchi);
+ FLEXT_CALLBACK_F(m_set_dstlo);
+ FLEXT_CALLBACK_F(m_set_dsthi);
+ float m_dstratio, m_rsrcrange, m_rrminuslo, m_dstlo;
+ float m_srclo, m_srchi, m_dsthi; //we will be able to reset the values
+
+ FLEXT_CALLBACK_F(m_perform);
+};
+
+FLEXT_LIB_V("LinExp",LinExp_kr);
+
+LinExp_kr::LinExp_kr(int argc,t_atom * argv)
+{
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD_(0,"srclo",m_set_srclo);
+ FLEXT_ADDMETHOD_(0,"srchi",m_set_srchi);
+ FLEXT_ADDMETHOD_(0,"dstlo",m_set_dstlo);
+ FLEXT_ADDMETHOD_(0,"dsthi",m_set_dsthi);
+
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 4)
+ post("4 arguments are required");
+ else
+ {
+ m_srclo = sc_getfloatarg(Args,0);
+ m_srchi = sc_getfloatarg(Args,1);
+ m_dstlo = sc_getfloatarg(Args,2);
+ m_dsthi = sc_getfloatarg(Args,3);
+
+ m_reset();
+
+ AddInFloat();
+ AddOutFloat();
+ }
+}
+
+void LinExp_kr::m_perform(float f)
+{
+ ToOutFloat(0,m_dstlo * pow(m_dstratio, f * m_rsrcrange + m_rrminuslo));
+}
diff --git a/sc4pd/source/LinRand.cpp b/sc4pd/source/LinRand.cpp
new file mode 100644
index 0000000..80266f1
--- /dev/null
+++ b/sc4pd/source/LinRand.cpp
@@ -0,0 +1,177 @@
+/* sc4pd
+ LinRand, LinRand~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Jim O'Rourke & Loren Mazzacane Connors: In Bern
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ LinRand~ -------------------------------*/
+
+class LinRand_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(LinRand_ar,sc4pd_dsp);
+
+public:
+ LinRand_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float m_sample;
+ float lo;
+ float hi;
+ int sc_n;
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_DSP_V("LinRand~",LinRand_ar);
+
+LinRand_ar::LinRand_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 3)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=sc_getfloatarg(Args,0);
+ hi=sc_getfloatarg(Args,1);
+ sc_n=sc_getfloatarg(Args,2);
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+}
+
+void LinRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ float range = hi - lo;
+ float a, b;
+ a = rgen.frand();
+ b = rgen.frand();
+ if (sc_n <= 0) {
+ m_sample = sc_min(a, b) * range + lo;
+ } else {
+ m_sample = sc_max(a, b) * range + lo;
+ }
+}
+
+
+void LinRand_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float sample = m_sample;
+
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++) = sample;
+ }
+}
+
+
+/* ------------------------ LinRand ---------------------------------*/
+
+class LinRand_kr:
+ public flext_base
+{
+ FLEXT_HEADER(LinRand_kr,flext_base);
+
+public:
+ LinRand_kr(int argc, t_atom *argv);
+
+protected:
+ void m_loadbang();
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float lo;
+ float hi;
+ int sc_n;
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("LinRand",LinRand_kr);
+
+LinRand_kr::LinRand_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ AtomList Args(argc,argv);
+ if (Args.Count() != 3)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=sc_getfloatarg(Args,0);
+ hi=sc_getfloatarg(Args,1);
+ sc_n=sc_getfloatarg(Args,2);
+
+ rgen.init(timeseed());
+
+ AddOutFloat();
+}
+
+void LinRand_kr::m_loadbang()
+{
+ float range = hi - lo;
+ float a, b;
+ a = rgen.frand();
+ b = rgen.frand();
+ if (sc_n <= 0) {
+ ToOutFloat(0,sc_min(a, b) * range + lo);
+ } else {
+ ToOutFloat(0,sc_max(a, b) * range + lo);
+ }
+}
diff --git a/sc4pd/source/Logistic.cpp b/sc4pd/source/Logistic.cpp
new file mode 100644
index 0000000..a956fda
--- /dev/null
+++ b/sc4pd/source/Logistic.cpp
@@ -0,0 +1,198 @@
+/* sc4pd
+ Logistic, Logistic~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Fred Frith: Gravity
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ Logistic~ -------------------------------*/
+
+class Logistic_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(Logistic_ar,sc4pd_dsp);
+
+public:
+ Logistic_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set(float f)
+ {
+ m_freq = sc_min(f,m_sr);
+ }
+
+ void m_param(float f)
+ {
+ m_paramf = f;
+ }
+
+private:
+ int m_freq;
+ float m_paramf;
+
+ int m_sr;
+ double m_y1;
+ int m_counter;
+
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK_F(m_param);
+};
+
+FLEXT_LIB_DSP_V("Logistic~",Logistic_ar);
+
+Logistic_ar::Logistic_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+ FLEXT_ADDMETHOD_(0,"parameter",m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+ m_paramf = sc_getfloatarg(Args,1);
+ m_y1 = sc_getfloatarg(Args,2);
+
+ m_sr=48000; // this is just a guess (i'll think about this later)
+
+ AddOutSignal();
+}
+
+void Logistic_ar::m_dsp(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ m_sr = Samplerate();
+ m_paramf = sc_min(m_paramf,m_sr);
+}
+
+
+void Logistic_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ if(m_sr == m_paramf)
+ {
+ /* it might be possible to implement this without the branch */
+
+ double y1 = m_y1;
+ double paramf = m_paramf;
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++)= y1 = paramf * y1 * (1.0 - y1);
+ }
+ m_y1 = y1;
+ }
+ else
+ {
+ double y1 = m_y1;
+ double paramf = m_paramf;
+ int counter = m_counter;
+ int remain = n;
+ do
+ {
+ if (counter<=0)
+ {
+ counter = (int)(m_sr / sc_max(m_freq, .001f));
+ counter = sc_max(1, counter);
+ y1 = paramf * y1 * (1.0 - y1);
+ }
+
+ int nsmps = sc_min(remain, counter);
+ remain -= nsmps;
+ counter -= nsmps;
+
+ for (int i = 0; i!= nsmps;++i)
+ {
+ (*(nout)++)=y1;
+ }
+ }
+ while(remain);
+ m_y1 = y1;
+ m_counter = counter;
+ }
+}
+
+
+/* ------------------------ Logistic ---------------------------------*/
+
+class Logistic_kr:
+ public flext_base
+{
+ FLEXT_HEADER(Logistic_kr,flext_base);
+
+public:
+ Logistic_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform();
+
+ void m_param(float f)
+ {
+ m_paramf = f;
+ }
+
+private:
+ float m_paramf;
+ double m_y1;
+
+ FLEXT_CALLBACK(m_perform);
+ FLEXT_CALLBACK_F(m_param);
+};
+
+FLEXT_LIB_V("Logistic",Logistic_kr);
+
+Logistic_kr::Logistic_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"parameter",m_param);
+ FLEXT_ADDBANG(0,m_perform);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_paramf = sc_getfloatarg(Args,0);
+ m_y1 = sc_getfloatarg(Args,1);
+
+ AddOutFloat();
+}
+
+void Logistic_kr::m_perform()
+{
+ m_y1 = m_paramf * m_y1 * (1.0 - m_y1);
+ ToOutFloat(0,m_y1);
+}
diff --git a/sc4pd/source/MantissaMask.cpp b/sc4pd/source/MantissaMask.cpp
new file mode 100644
index 0000000..c7c70c2
--- /dev/null
+++ b/sc4pd/source/MantissaMask.cpp
@@ -0,0 +1,153 @@
+/* sc4pd
+ MantissaMask~, MantissaMask
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Wolfgang Mitterer: Amusie
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ MantissaMask~ -----------------------------*/
+
+class MantissaMask_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(MantissaMask_ar,sc4pd_dsp);
+
+public:
+ MantissaMask_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ void m_set(float f);
+
+private:
+ FLEXT_CALLBACK_F(m_set);
+ int32 mask;
+
+};
+
+FLEXT_LIB_DSP_V("MantissaMask~",MantissaMask_ar);
+
+MantissaMask_ar::MantissaMask_ar(int argc,t_atom * argv)
+{
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+
+ AtomList Args(argc,argv);
+ int bits = sc_getfloatarg(Args,0);
+
+ AddOutSignal();
+
+ mask = -1 << (23 - bits);
+
+}
+
+void MantissaMask_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ int32 *nout = (int32*)*out;
+ int32 *nin = (int32*)*in;
+
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++) = mask & (*(nin)++);
+ }
+}
+
+void MantissaMask_ar::m_set(float f)
+{
+ int bits = (int) f;
+ if ( bits < 0 || bits > 23)
+ {
+ post("value doesn't make sense");
+ return;
+ }
+ mask = -1 << (23 - bits);
+}
+
+/* ------------------------ MantissaMask ------------------------------*/
+
+class MantissaMask_kr
+ :public flext_base
+{
+ FLEXT_HEADER(MantissaMask_kr,flext_base);
+
+public:
+ MantissaMask_kr(int argc,t_atom * argv);
+
+protected:
+ void m_set(float f);
+ void m_perform(float f);
+
+private:
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK_F(m_perform);
+ int32 mask;
+};
+
+FLEXT_LIB_V("MantissaMask",MantissaMask_kr);
+
+MantissaMask_kr::MantissaMask_kr(int argc,t_atom * argv)
+{
+
+ AtomList Args(argc,argv);
+ int bits = sc_getfloatarg(Args,0);
+
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+ mask = -1 << (23 - bits);
+}
+
+void MantissaMask_kr::m_perform(float f)
+{
+ float g;
+ int32 *gp = (int32*) &g;
+
+ *(gp) = mask & *((int32*) &f);
+
+ ToOutFloat(0,g);
+}
+
+void MantissaMask_kr::m_set(float f)
+{
+ int bits = (int) f;
+ if ( bits < 0 || bits > 23)
+ {
+ post("value doesn't make sense");
+ return;
+ }
+ mask = -1 << (23 - bits);
+}
diff --git a/sc4pd/source/Median.cpp b/sc4pd/source/Median.cpp
new file mode 100644
index 0000000..4383a1b
--- /dev/null
+++ b/sc4pd/source/Median.cpp
@@ -0,0 +1,213 @@
+/* sc4pd
+ Median, Median~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Morton Feldman: For John Cage
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ Median(~) ---------------------------------*/
+
+
+const int kMAXMEDIANSIZE = 32;
+
+class median_shared
+{
+public:
+
+ inline void Init(long size, float value);
+ inline float Insert(float value);
+
+private:
+ float m_medianValue[kMAXMEDIANSIZE];
+ long m_medianAge[kMAXMEDIANSIZE];
+ long m_medianSize, m_medianIndex;
+};
+
+void median_shared::Init(long size, float value)
+{
+ // initialize the arrays with the first value
+ m_medianSize = size;
+ for (int i=0; i<size; ++i) {
+ m_medianValue[i] = value;
+ m_medianAge[i] = i;
+ }
+}
+
+inline float median_shared::Insert(float value)
+{
+ long i, last, pos=-1;
+
+ // keeps a sorted list of the previous n=size values
+ // the oldest is removed and the newest is inserted.
+ // values between the oldest and the newest are shifted over by one.
+
+ // values and ages are both arrays that are 'size' long.
+ // the median value is always values[size>>1]
+
+ last = m_medianSize - 1;
+ // find oldest bin and age the other bins.
+ for (i=0; i<m_medianSize; ++i) {
+ if (m_medianAge[i] == last) { // is it the oldest bin ?
+ pos = i;
+ } else {
+ m_medianAge[i]++; // age the bin
+ }
+ }
+ // move values to fill in place of the oldest and make a space for the newest
+ // search lower if value is too small for the open space
+ while (pos != 0 && value < m_medianValue[pos-1]) {
+ m_medianValue[pos] = m_medianValue[pos-1];
+ m_medianAge[pos] = m_medianAge[pos-1];
+ pos--;
+ }
+ // search higher if value is too big for the open space
+ while (pos != last && value > m_medianValue[pos+1]) {
+ m_medianValue[pos] = m_medianValue[pos+1];
+ m_medianAge[pos] = m_medianAge[pos+1];
+ pos++;
+ }
+ m_medianValue[pos] = value;
+ m_medianAge[pos] = 0; // this is the newest bin, age = 0
+ return m_medianValue[m_medianSize>>1];
+}
+
+
+/* ------------------------ Median~ -----------------------------------*/
+
+class Median_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(Median_ar,sc4pd_dsp);
+
+public:
+ Median_ar(int argc, t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp (int n,t_signalvec const * insigs,
+ t_signalvec const * outsigs);
+
+ void m_set(float f)
+ {
+ m_size=(int)f;
+ Median.Init(m_size,Median.Insert(0)); /* this is not beautiful, but i'm not
+ aware of a nicer way */
+ }
+
+private:
+ FLEXT_CALLBACK_F(m_set);
+
+ median_shared Median; //median
+ int m_size; //median size
+};
+
+FLEXT_LIB_DSP_V("Median~",Median_ar);
+
+Median_ar::Median_ar(int argc,t_atom * argv)
+{
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+
+ AtomList Args(argc,argv);
+ m_size=sc_getfloatarg(Args,0);
+
+ AddOutSignal();
+}
+
+void Median_ar::m_dsp(int n,t_signalvec const * insigs,
+ t_signalvec const * outsigs)
+{
+ Median.Init(m_size,0); //how is this done in SuperCollider?
+}
+
+void Median_ar::m_signal(int n, t_sample *const *in, t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin = *in;
+
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++) = Median.Insert(*(nin)++);
+ }
+}
+
+
+/* ------------------------ Median ------------------------------------*/
+
+class Median_kr
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(Median_kr,sc4pd_dsp);
+
+public:
+ Median_kr(int argc, t_atom * argv);
+
+protected:
+ void m_set(float f)
+ {
+ m_size=(int)f;
+ Median.Init(m_size,Median.Insert(0)); /* this is not beautiful, but i'm not
+ aware of a nicer way */
+ }
+ void m_perform(float f);
+
+private:
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK_F(m_perform);
+
+ median_shared Median; //median
+ int m_size; //median size
+};
+
+FLEXT_LIB_V("Median",Median_kr);
+
+Median_kr::Median_kr(int argc,t_atom * argv)
+{
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+ FLEXT_ADDMETHOD(0,m_perform);
+
+
+ AtomList Args(argc,argv);
+ m_size=(int)sc_getfloatarg(Args,0);
+
+ float m_set=sc_getfloatarg(Args,1);
+
+ Median.Init(m_size,m_set);
+ AddOutFloat();
+}
+
+void Median_kr::m_perform(float f)
+{
+ ToOutFloat(0,Median.Insert(f));
+}
diff --git a/sc4pd/source/NRand.cpp b/sc4pd/source/NRand.cpp
new file mode 100644
index 0000000..e91ad71
--- /dev/null
+++ b/sc4pd/source/NRand.cpp
@@ -0,0 +1,173 @@
+/* sc4pd
+ NRand, NRand~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Jim O'Rourke & Loren Mazzacane Connors: In Bern
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ NRand~ -------------------------------*/
+
+class NRand_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(NRand_ar,sc4pd_dsp);
+
+public:
+ NRand_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float m_sample;
+ float lo;
+ float hi;
+ int sc_n;
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_DSP_V("NRand~",NRand_ar);
+
+NRand_ar::NRand_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 3)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=sc_getfloatarg(Args,0);
+ hi=sc_getfloatarg(Args,1);
+ sc_n=sc_getfloatarg(Args,2);
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+}
+
+void NRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ float range = hi - lo;
+ float sum = 0;
+ for (int i=0; i<sc_n; ++i)
+ {
+ sum += rgen.frand();
+ }
+ m_sample = (sum/sc_n) * range + lo;
+}
+
+
+void NRand_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float sample = m_sample;
+
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++) = sample;
+ }
+}
+
+
+/* ------------------------ NRand ---------------------------------*/
+
+class NRand_kr:
+ public flext_base
+{
+ FLEXT_HEADER(NRand_kr,flext_base);
+
+public:
+ NRand_kr(int argc, t_atom *argv);
+
+protected:
+ void m_loadbang();
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float lo;
+ float hi;
+ int sc_n;
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("NRand",NRand_kr);
+
+NRand_kr::NRand_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ AtomList Args(argc,argv);
+ if (Args.Count() != 3)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=sc_getfloatarg(Args,0);
+ hi=sc_getfloatarg(Args,1);
+ sc_n=sc_getfloatarg(Args,2);
+
+ rgen.init(timeseed());
+
+ AddOutFloat();
+}
+
+void NRand_kr::m_loadbang()
+{
+ float range = hi - lo;
+ float sum = 0;
+ for (int i=0; i<sc_n; ++i)
+ {
+ sum += rgen.frand();
+ }
+ ToOutFloat(0,(sum/sc_n) * range + lo);
+}
diff --git a/sc4pd/source/OnePole.cpp b/sc4pd/source/OnePole.cpp
new file mode 100644
index 0000000..3de6ef4
--- /dev/null
+++ b/sc4pd/source/OnePole.cpp
@@ -0,0 +1,245 @@
+/* sc4pd
+ OnePole, OnePole~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Goh Lee Kwang: Internal Pleasures
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ OnePole~ -------------------------------*/
+
+class OnePole_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(OnePole_ar,sc4pd_dsp);
+
+public:
+ OnePole_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+
+ void m_set(float f)
+ {
+ n_b1=f;
+ changed = true;
+ }
+
+ void m_ar()
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar));
+ }
+
+ void m_kr()
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr));
+ }
+
+private:
+ float m_b1, m_y1;
+ float n_b1;
+ bool changed;
+
+ DEFSIGCALL (m_signal_fun);
+ DEFSIGFUN (m_signal_ar);
+ DEFSIGFUN (m_signal_kr);
+
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK(m_ar);
+ FLEXT_CALLBACK(m_kr);
+};
+
+FLEXT_LIB_DSP_V("OnePole~",OnePole_ar);
+
+OnePole_ar::OnePole_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"coef",m_set);
+ FLEXT_ADDMETHOD_(0,"ar",m_ar);
+ FLEXT_ADDMETHOD_(0,"kr",m_kr);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_b1 = sc_getfloatarg(Args,0);
+
+ if(sc_ar(Args))
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar));
+ AddInSignal();
+ AddInSignal();
+ }
+ else // if not given, use control rate
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr));
+
+ AddOutSignal();
+
+ m_y1 = 0.f;
+}
+
+void OnePole_ar::m_signal_ar(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+ float *b1p = *(in+1);
+
+ float y1 = m_y1;
+
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = ZXP(nin);
+ float b1 = ZXP(b1p);
+ ZXP(nout) = y1 = y0 + b1 * (y1 - y0);
+ }
+ m_y1 = zapgremlins(y1);
+}
+
+
+void OnePole_ar::m_signal_kr(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float b1 = m_b1;
+ float y1 = m_y1;
+
+ if (changed)
+ {
+ m_b1=n_b1;
+ float b1_slope = CALCSLOPE(m_b1, b1);
+ if (b1 >= 0.f && m_b1 >= 0)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = ZXP(nin);
+ ZXP(nout) = y1 = y0 + b1 * (y1 - y0);
+ b1 += b1_slope;
+ }
+ }
+ else if (b1 <= 0.f && m_b1 <= 0)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = ZXP(nin);
+ ZXP(nout) = y1 = y0 + b1 * (y1 + y0);
+ b1 += b1_slope;
+ }
+ }
+ else
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = ZXP(nin);
+ ZXP(nout) = y1 = (1.f - fabs(b1)) * y0 + b1 * y1;
+ b1 += b1_slope;
+ }
+ }
+ changed = false;
+ }
+ else
+ {
+ if (b1 >= 0.f)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = ZXP(nin);
+ ZXP(nout) = y1 = y0 + b1 * (y1 - y0);
+ }
+ }
+ else
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float y0 = ZXP(nin);
+ ZXP(nout) = y1 = y0 + b1 * (y1 + y0);
+ }
+ }
+
+ }
+ m_y1 = zapgremlins(y1);
+}
+
+/* ------------------------ OnePole ---------------------------------*/
+
+
+class OnePole_kr:
+ public flext_base
+{
+ FLEXT_HEADER(OnePole_kr,flext_base);
+
+public:
+ OnePole_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform(float f);
+
+ void m_set(float f)
+ {
+ m_b1=f;
+ }
+
+private:
+ float m_b1, m_y1;
+
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK_F(m_perform);
+};
+
+
+FLEXT_LIB_V("OnePole",OnePole_kr);
+
+OnePole_kr::OnePole_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+
+ AddOutFloat();
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_b1 = sc_getfloatarg(Args,0);
+
+ m_y1=0;
+}
+
+void OnePole_kr::m_perform(float f)
+{
+ m_y1= ((1-abs(m_b1))*f)+m_b1*m_y1;
+ ToOutFloat(0,m_y1);
+}
diff --git a/sc4pd/source/OneZero.cpp b/sc4pd/source/OneZero.cpp
new file mode 100644
index 0000000..82c9ad5
--- /dev/null
+++ b/sc4pd/source/OneZero.cpp
@@ -0,0 +1,200 @@
+/* sc4pd
+ OneZero, OneZero~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Goh Lee Kwang: Internal Pleasures
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ OneZero~ -------------------------------*/
+
+class OneZero_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(OneZero_ar,sc4pd_dsp);
+
+public:
+ OneZero_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set(float f)
+ {
+ n_b1=f;
+ changed = true;
+ }
+
+private:
+ float m_b1, m_x1;
+ float n_b1;
+ bool changed;
+
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_DSP_V("OneZero~",OneZero_ar);
+
+OneZero_ar::OneZero_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"coef",m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_b1 = sc_getfloatarg(Args,0);
+
+ AddOutSignal();
+
+ m_x1 = 0.f;
+}
+
+void OneZero_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float b1 = m_b1;
+ float x1 = m_x1;
+
+ if (changed)
+ {
+ m_b1=n_b1;
+ float b1_slope = CALCSLOPE(m_b1, b1);
+ if (b1 >= 0.f && m_b1 >= 0)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float x0 = ZXP(nin);
+ ZXP(nout) = x0 + b1 * (x1 - x0);
+ x1 = x0;
+ b1 += b1_slope;
+ }
+ }
+ else if (b1 <= 0.f && m_b1 <= 0)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float x0 = ZXP(nin);
+ ZXP(nout) = x0 + b1 * (x1 + x0);
+ x1 = x0;
+ b1 += b1_slope;
+ }
+ }
+ else
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float x0 = ZXP(nin);
+ ZXP(nout) = (1.f - fabs(b1)) * x0 + b1 * x1;
+ x1 = x0;
+ b1 += b1_slope;
+ }
+ }
+ changed = false;
+ }
+ else
+ {
+ if (b1 >= 0.f)
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float x0 = ZXP(nin);
+ ZXP(nout) = x0 + b1 * (x1 - x0);
+ x1 = x0;
+ }
+ }
+ else
+ {
+ for (int i = 0; i!= n;++i)
+ {
+ float x0 = ZXP(nin);
+ ZXP(nout) = x0 + b1 * (x1 + x0);
+ x1 = x0;
+ }
+ }
+ }
+ m_x1 = x1;
+}
+
+/* ------------------------ OneZero ---------------------------------*/
+
+
+class OneZero_kr:
+ public flext_base
+{
+ FLEXT_HEADER(OneZero_kr,flext_base);
+
+public:
+ OneZero_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform(float f);
+
+ void m_set(float f)
+ {
+ m_b1=f;
+ }
+
+private:
+ float m_b1, m_x1;
+
+ FLEXT_CALLBACK_F(m_set);
+ FLEXT_CALLBACK_F(m_perform);
+};
+
+
+FLEXT_LIB_V("OneZero",OneZero_kr);
+
+OneZero_kr::OneZero_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD_(0,"set",m_set);
+
+ AddOutFloat();
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_b1 = sc_getfloatarg(Args,0);
+
+ m_x1=0;
+}
+
+void OneZero_kr::m_perform(float f)
+{
+ ToOutFloat(0,((1-abs(m_b1))*f)+m_b1*m_x1);
+ m_x1=f;
+}
diff --git a/sc4pd/source/PinkNoise.cpp b/sc4pd/source/PinkNoise.cpp
new file mode 100644
index 0000000..296f383
--- /dev/null
+++ b/sc4pd/source/PinkNoise.cpp
@@ -0,0 +1,174 @@
+/* sc4pd
+ PinkNoise, PinkNoise~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Gottfried Michael Koenig: Klangfiguren II
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ PinkNoise~ -------------------------------*/
+
+class PinkNoise_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(PinkNoise_ar,sc4pd_dsp);
+
+public:
+ PinkNoise_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ uint32 m_dice[16];
+ int32 m_total;
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_DSP_V("PinkNoise~",PinkNoise_ar);
+
+PinkNoise_ar::PinkNoise_ar(int argc, t_atom *argv)
+ : m_total(0)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ rgen.init(timeseed());
+
+ for (int i=0; i<16; ++i)
+ {
+ uint32 newrand = rgen.trand() >> 13;
+ m_total += newrand;
+ m_dice[i] = newrand;
+ }
+
+ AddOutSignal();
+}
+
+
+void PinkNoise_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ RGET;
+ uint32 total = m_total;
+ uint32 *dice = m_dice;
+
+ for (int i = 0; i!= n;++i)
+ {
+ uint32 counter = trand(s1,s2,s3); // Magnus Jonsson's suggestion.
+ uint32 newrand = counter >> 13;
+ int k = (CTZ(counter)) & 15;
+ uint32 prevrand = dice[k];
+ dice[k] = newrand;
+ total += (newrand - prevrand);
+ newrand = trand(s1,s2,s3) >> 13;
+ uint32 ifval = (total + newrand) | 0x40000000;
+ (*(nout)++) = ((*(float*)&ifval) - 3.0f);
+ }
+ RPUT;
+}
+
+
+/* ------------------------ PinkNoise ---------------------------------*/
+
+class PinkNoise_kr:
+ public flext_base
+{
+ FLEXT_HEADER(PinkNoise_kr,flext_base);
+
+public:
+ PinkNoise_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform();
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ uint32 m_dice[16];
+ int32 m_total;
+ RGen rgen;
+ FLEXT_CALLBACK(m_perform);
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("PinkNoise",PinkNoise_kr);
+
+PinkNoise_kr::PinkNoise_kr(int argc, t_atom *argv)
+ : m_total(0)
+{
+ FLEXT_ADDBANG(0,m_perform);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ rgen.init(timeseed());
+
+ for (int i=0; i<16; ++i)
+ {
+ uint32 newrand = rgen.trand() >> 13;
+ m_total += newrand;
+ m_dice[i] = newrand;
+ }
+
+ AddOutFloat();
+}
+
+void PinkNoise_kr::m_perform()
+{
+ uint32 counter = rgen.trand(); // Magnus Jonsson's suggestion.
+ uint32 newrand = counter >> 13;
+ int k = (CTZ(counter)) & 15;
+ uint32 prevrand = m_dice[k];
+ m_dice[k] = newrand;
+ m_total += (newrand - prevrand);
+ newrand = rgen.trand() >> 13;
+ uint32 ifval = (m_total + newrand) | 0x40000000;
+
+ ToOutFloat(0,((*(float*)&ifval) - 3.0f));
+}
diff --git a/sc4pd/source/PitchShift.cpp b/sc4pd/source/PitchShift.cpp
new file mode 100644
index 0000000..8a3f265
--- /dev/null
+++ b/sc4pd/source/PitchShift.cpp
@@ -0,0 +1,629 @@
+/* sc4pd
+ PitchShift~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Bernhard Lang: Differenz / Wiederholung 2
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ PitchShift~ -----------------------------*/
+
+class PitchShift_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(PitchShift_ar,sc4pd_dsp);
+
+public:
+ PitchShift_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set_pitchratio (float f)
+ {
+ m_pitchratio = f;
+ }
+
+ void m_set_pitchdispersion (float f)
+ {
+ m_pitchdispersion = f;
+ }
+
+ void m_set_timedispersion (float f)
+ {
+ m_timedispersion = f;
+ }
+
+private:
+ float m_windowsize,m_pitchratio,m_pitchdispersion,m_timedispersion;
+ RGen rgen;
+
+
+ float *m_dlybuf;
+ float m_dsamp1, m_dsamp1_slope, m_ramp1, m_ramp1_slope;
+ float m_dsamp2, m_dsamp2_slope, m_ramp2, m_ramp2_slope;
+ float m_dsamp3, m_dsamp3_slope, m_ramp3, m_ramp3_slope;
+ float m_dsamp4, m_dsamp4_slope, m_ramp4, m_ramp4_slope;
+ float m_fdelaylen, m_slope;
+ long m_iwrphase, m_idelaylen, m_mask;
+ long m_counter, m_stage, m_numoutput, m_framesize;
+
+ DEFSIGCALL(m_signal_fun);
+ DEFSIGFUN(m_signal_);
+ DEFSIGFUN(m_signal_z);
+
+ FLEXT_CALLBACK_F(m_set_pitchratio);
+ FLEXT_CALLBACK_F(m_set_pitchdispersion);
+ FLEXT_CALLBACK_F(m_set_timedispersion);
+};
+
+FLEXT_LIB_DSP_V("PitchShift~",PitchShift_ar);
+
+PitchShift_ar::PitchShift_ar(int argc,t_atom * argv)
+{
+ FLEXT_ADDMETHOD_(0,"pitchRatio",m_set_pitchratio);
+ FLEXT_ADDMETHOD_(0,"pitchDispersion",m_set_pitchdispersion);
+ FLEXT_ADDMETHOD_(0,"timeDispersion",m_set_timedispersion);
+
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 4)
+ {
+ post("4 arguments needed");
+ return;
+ }
+
+ m_windowsize = sc_getfloatarg(Args,0);
+ m_pitchratio = sc_getfloatarg(Args,1);
+ m_pitchdispersion = sc_getfloatarg(Args,2);
+ m_timedispersion = sc_getfloatarg(Args,3);
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z));
+}
+
+void PitchShift_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ /* initialization from PitchShift_Ctor(PitchShift *unit) */
+
+ long delaybufsize;
+ float *dlybuf;
+ float pchratio;
+ float fdelaylen, slope;
+ long framesize, last;
+
+ //out = ZOUT(0);
+ //in = ZIN(0);
+ pchratio = m_pitchratio;
+
+ delaybufsize = (long)ceil(m_windowsize * SAMPLERATE * 3.f + 3.f);
+ fdelaylen = delaybufsize - 3;
+
+ delaybufsize = delaybufsize + BUFLENGTH;
+ delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two
+ dlybuf = new float[delaybufsize];
+ //(float*)RTAlloc(unit->mWorld, delaybufsize * sizeof(float));
+
+ *dlybuf = 0;
+
+ m_dlybuf = dlybuf;
+ m_idelaylen = delaybufsize;
+ m_fdelaylen = fdelaylen;
+ m_iwrphase = 0;
+ m_numoutput = 0;
+ m_mask = last = (delaybufsize - 1);
+
+ m_framesize = framesize = ((long)(m_windowsize * SAMPLERATE) + 2) & ~3;
+ m_slope = slope = 2.f / framesize;
+ m_stage = 3;
+ m_counter = framesize >> 2;
+ m_ramp1 = 0.5;
+ m_ramp2 = 1.0;
+ m_ramp3 = 0.5;
+ m_ramp4 = 0.0;
+
+ m_ramp1_slope = -slope;
+ m_ramp2_slope = -slope;
+ m_ramp3_slope = slope;
+ m_ramp4_slope = slope;
+
+ dlybuf[last ] = 0.f; // put a few zeroes where we start the read heads
+ dlybuf[last-1] = 0.f;
+ dlybuf[last-2] = 0.f;
+
+ m_numoutput = 0;
+
+ // start all read heads 2 samples behind the write head
+ m_dsamp1 = m_dsamp2 = m_dsamp3 = m_dsamp4 = 2.f;
+ // pch ratio is initially zero for the read heads
+ m_dsamp1_slope = m_dsamp2_slope = m_dsamp3_slope = m_dsamp4_slope = 1.f;
+}
+
+
+void PitchShift_ar::m_signal_z(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+
+ float *nout, *nin, *dlybuf;
+ float disppchratio, pchratio, pchratio1, value;
+ float dsamp1, dsamp1_slope, ramp1, ramp1_slope;
+ float dsamp2, dsamp2_slope, ramp2, ramp2_slope;
+ float dsamp3, dsamp3_slope, ramp3, ramp3_slope;
+ float dsamp4, dsamp4_slope, ramp4, ramp4_slope;
+ float fdelaylen, d1, d2, frac, slope, samp_slope, startpos,
+ pchdisp, timedisp;
+ long remain, nsmps, idelaylen, irdphase, irdphaseb, iwrphase;
+ long mask, idsamp;
+ long counter, stage, framesize, numoutput;
+
+ RGET;
+
+ nout = *out;
+ nin = *in;
+
+ pchratio = m_pitchratio;
+ pchdisp = m_pitchdispersion;
+ timedisp = m_timedispersion;
+ timedisp = sc_clip(timedisp, 0.f, m_windowsize) * SAMPLERATE;
+
+ dlybuf = m_dlybuf;
+ fdelaylen = m_fdelaylen;
+ idelaylen = m_idelaylen;
+ iwrphase = m_iwrphase;
+ numoutput = m_numoutput;
+
+ counter = m_counter;
+ stage = m_stage;
+ mask = m_mask;
+ framesize = m_framesize;
+
+ dsamp1 = m_dsamp1;
+ dsamp2 = m_dsamp2;
+ dsamp3 = m_dsamp3;
+ dsamp4 = m_dsamp4;
+
+ dsamp1_slope = m_dsamp1_slope;
+ dsamp2_slope = m_dsamp2_slope;
+ dsamp3_slope = m_dsamp3_slope;
+ dsamp4_slope = m_dsamp4_slope;
+
+ ramp1 = m_ramp1;
+ ramp2 = m_ramp2;
+ ramp3 = m_ramp3;
+ ramp4 = m_ramp4;
+
+ ramp1_slope = m_ramp1_slope;
+ ramp2_slope = m_ramp2_slope;
+ ramp3_slope = m_ramp3_slope;
+ ramp4_slope = m_ramp4_slope;
+
+ slope = m_slope;
+
+ remain = n;
+ while (remain)
+ {
+ if (counter <= 0)
+ {
+ counter = framesize >> 2;
+ m_stage = stage = (stage + 1) & 3;
+ disppchratio = pchratio;
+ if (pchdisp != 0.f)
+ {
+ disppchratio += (pchdisp * frand2(s1,s2,s3));
+ }
+ disppchratio = sc_clip(disppchratio, 0.f, 4.f);
+ pchratio1 = disppchratio - 1.f;
+ samp_slope = -pchratio1;
+ startpos = pchratio1 < 0.f ? 2.f : framesize * pchratio1 + 2.f;
+ startpos += (timedisp * frand(s1,s2,s3));
+ switch(stage)
+ {
+ case 0 :
+ m_dsamp1_slope = dsamp1_slope = samp_slope;
+ dsamp1 = startpos;
+ ramp1 = 0.0;
+ m_ramp1_slope = ramp1_slope = slope;
+ m_ramp3_slope = ramp3_slope = -slope;
+ break;
+ case 1 :
+ m_dsamp2_slope = dsamp2_slope = samp_slope;
+ dsamp2 = startpos;
+ ramp2 = 0.0;
+ m_ramp2_slope = ramp2_slope = slope;
+ m_ramp4_slope = ramp4_slope = -slope;
+ break;
+ case 2 :
+ m_dsamp3_slope = dsamp3_slope = samp_slope;
+ dsamp3 = startpos;
+ ramp3 = 0.0;
+ m_ramp3_slope = ramp3_slope = slope;
+ m_ramp1_slope = ramp1_slope = -slope;
+ break;
+ case 3 :
+ m_dsamp4_slope = dsamp4_slope = samp_slope;
+ dsamp4 = startpos;
+ ramp4 = 0.0;
+ m_ramp2_slope = ramp2_slope = -slope;
+ m_ramp4_slope = ramp4_slope = slope;
+ break;
+ }
+ }
+ nsmps = sc_min(remain, counter);
+ remain -= nsmps;
+ counter -= nsmps;
+
+ while (nsmps--) {
+ numoutput++;
+ iwrphase = (iwrphase + 1) & mask;
+
+ dsamp1 += dsamp1_slope;
+ idsamp = (long)dsamp1;
+ frac = dsamp1 - idsamp;
+ irdphase = (iwrphase - idsamp) & mask;
+ irdphaseb = (irdphase - 1) & mask;
+ if (numoutput < idelaylen)
+ {
+ if (irdphase > iwrphase)
+ {
+ value = 0.f;
+ }
+ else if (irdphaseb > iwrphase)
+ {
+ d1 = dlybuf[irdphase];
+ value = (d1 - frac * d1) * ramp1;
+ }
+ else
+ {
+ d1 = dlybuf[irdphase];
+ d2 = dlybuf[irdphaseb];
+ value = (d1 + frac * (d2 - d1)) * ramp1;
+ }
+ }
+ else
+ {
+ d1 = dlybuf[irdphase];
+ d2 = dlybuf[irdphaseb];
+ value = (d1 + frac * (d2 - d1)) * ramp1;
+ }
+ ramp1 += ramp1_slope;
+
+ dsamp2 += dsamp2_slope;
+ idsamp = (long)dsamp2;
+ frac = dsamp2 - idsamp;
+ irdphase = (iwrphase - idsamp) & mask;
+ irdphaseb = (irdphase - 1) & mask;
+ if (numoutput < idelaylen)
+ {
+ if (irdphase > iwrphase)
+ {
+ //value += 0.f;
+ }
+ else if (irdphaseb > iwrphase)
+ {
+ d1 = dlybuf[irdphase];
+ value += (d1 - frac * d1) * ramp2;
+ }
+ else
+ {
+ d1 = dlybuf[irdphase];
+ d2 = dlybuf[irdphaseb];
+ value += (d1 + frac * (d2 - d1)) * ramp2;
+
+ }
+ }
+ else
+ {
+ d1 = dlybuf[irdphase];
+ d2 = dlybuf[irdphaseb];
+ value += (d1 + frac * (d2 - d1)) * ramp2;
+ }
+ ramp2 += ramp2_slope;
+
+ dsamp3 += dsamp3_slope;
+ idsamp = (long)dsamp3;
+ frac = dsamp3 - idsamp;
+ irdphase = (iwrphase - idsamp) & mask;
+ irdphaseb = (irdphase - 1) & mask;
+ if (numoutput < idelaylen)
+ {
+ if (irdphase > iwrphase)
+ {
+ //value += 0.f;
+ }
+ else if (irdphaseb > iwrphase)
+ {
+ d1 = dlybuf[irdphase];
+ value += (d1 - frac * d1) * ramp3;
+ }
+ else
+ {
+ d1 = dlybuf[irdphase];
+ d2 = dlybuf[irdphaseb];
+ value += (d1 + frac * (d2 - d1)) * ramp3;
+ }
+ }
+ else
+ {
+ d1 = dlybuf[irdphase];
+ d2 = dlybuf[irdphaseb];
+ value += (d1 + frac * (d2 - d1)) * ramp3;
+ }
+ ramp3 += ramp3_slope;
+
+ dsamp4 += dsamp4_slope;
+ idsamp = (long)dsamp4;
+ frac = dsamp4 - idsamp;
+ irdphase = (iwrphase - idsamp) & mask;
+ irdphaseb = (irdphase - 1) & mask;
+
+ if (numoutput < idelaylen)
+ {
+ if (irdphase > iwrphase)
+ {
+ //value += 0.f;
+ } else if (irdphaseb > iwrphase) {
+ d1 = dlybuf[irdphase];
+ value += (d1 - frac * d1) * ramp4;
+ }
+ else
+ {
+ d1 = dlybuf[irdphase];
+ d2 = dlybuf[irdphaseb];
+ value += (d1 + frac * (d2 - d1)) * ramp4;
+ }
+ }
+ else
+ {
+ d1 = dlybuf[irdphase];
+ d2 = dlybuf[irdphaseb];
+ value += (d1 + frac * (d2 - d1)) * ramp4;
+ }
+ ramp4 += ramp4_slope;
+
+ dlybuf[iwrphase] = ZXP(nin);
+ ZXP(nout) = value *= 0.5;
+ }
+ }
+
+ m_counter = counter;
+ m_stage = stage;
+ m_mask = mask;
+
+ m_dsamp1 = dsamp1;
+ m_dsamp2 = dsamp2;
+ m_dsamp3 = dsamp3;
+ m_dsamp4 = dsamp4;
+
+ m_ramp1 = ramp1;
+ m_ramp2 = ramp2;
+ m_ramp3 = ramp3;
+ m_ramp4 = ramp4;
+
+ m_numoutput = numoutput;
+ m_iwrphase = iwrphase;
+
+ if (numoutput >= idelaylen)
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z));
+ }
+ RPUT;
+}
+
+void PitchShift_ar::m_signal_(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ float *nout, *nin, *dlybuf;
+ float disppchratio, pchratio, pchratio1, value;
+ float dsamp1, dsamp1_slope, ramp1, ramp1_slope;
+ float dsamp2, dsamp2_slope, ramp2, ramp2_slope;
+ float dsamp3, dsamp3_slope, ramp3, ramp3_slope;
+ float dsamp4, dsamp4_slope, ramp4, ramp4_slope;
+ float fdelaylen, d1, d2, frac, slope, samp_slope, startpos,
+ pchdisp, timedisp;
+ long remain, nsmps, idelaylen, irdphase, irdphaseb, iwrphase, mask, idsamp;
+ long counter, stage, framesize;
+
+ RGET;
+
+ nout = *out;
+ nin = *in;
+
+ pchratio = m_pitchratio;
+ pchdisp = m_pitchdispersion;
+ timedisp = m_timedispersion;
+
+ timedisp = sc_clip(timedisp, 0.f, m_windowsize) * SAMPLERATE;
+
+ dlybuf = m_dlybuf;
+ fdelaylen = m_fdelaylen;
+ idelaylen = m_idelaylen;
+ iwrphase = m_iwrphase;
+
+ counter = m_counter;
+ stage = m_stage;
+ mask = m_mask;
+ framesize = m_framesize;
+
+ dsamp1 = m_dsamp1;
+ dsamp2 = m_dsamp2;
+ dsamp3 = m_dsamp3;
+ dsamp4 = m_dsamp4;
+
+ dsamp1_slope = m_dsamp1_slope;
+ dsamp2_slope = m_dsamp2_slope;
+ dsamp3_slope = m_dsamp3_slope;
+ dsamp4_slope = m_dsamp4_slope;
+
+ ramp1 = m_ramp1;
+ ramp2 = m_ramp2;
+ ramp3 = m_ramp3;
+ ramp4 = m_ramp4;
+
+ ramp1_slope = m_ramp1_slope;
+ ramp2_slope = m_ramp2_slope;
+ ramp3_slope = m_ramp3_slope;
+ ramp4_slope = m_ramp4_slope;
+
+ slope = m_slope;
+
+ remain = n;
+ while (remain)
+ {
+ if (counter <= 0)
+ {
+ counter = framesize >> 2;
+ m_stage = stage = (stage + 1) & 3;
+ disppchratio = pchratio;
+ if (pchdisp != 0.f)
+ {
+ disppchratio += (pchdisp * frand2(s1,s2,s3));
+ }
+ disppchratio = sc_clip(disppchratio, 0.f, 4.f);
+ pchratio1 = disppchratio - 1.f;
+ samp_slope = -pchratio1;
+ startpos = pchratio1 < 0.f ? 2.f : framesize * pchratio1 + 2.f;
+ startpos += (timedisp * frand(s1,s2,s3));
+ switch(stage)
+ {
+ case 0 :
+ m_dsamp1_slope = dsamp1_slope = samp_slope;
+ dsamp1 = startpos;
+ ramp1 = 0.0;
+ m_ramp1_slope = ramp1_slope = slope;
+ m_ramp3_slope = ramp3_slope = -slope;
+ break;
+ case 1 :
+ m_dsamp2_slope = dsamp2_slope = samp_slope;
+ dsamp2 = startpos;
+ ramp2 = 0.0;
+ m_ramp2_slope = ramp2_slope = slope;
+ m_ramp4_slope = ramp4_slope = -slope;
+ break;
+ case 2 :
+ m_dsamp3_slope = dsamp3_slope = samp_slope;
+ dsamp3 = startpos;
+ ramp3 = 0.0;
+ m_ramp3_slope = ramp3_slope = slope;
+ m_ramp1_slope = ramp1_slope = -slope;
+ break;
+ case 3 :
+ m_dsamp4_slope = dsamp4_slope = samp_slope;
+ dsamp4 = startpos;
+ ramp4 = 0.0;
+ m_ramp2_slope = ramp2_slope = -slope;
+ m_ramp4_slope = ramp4_slope = slope;
+ break;
+ }
+ }
+
+ nsmps = sc_min(remain, counter);
+ remain -= nsmps;
+ counter -= nsmps;
+
+ for (int i = 0; i!= nsmps;++i)
+ {
+ iwrphase = (iwrphase + 1) & mask;
+
+ dsamp1 += dsamp1_slope;
+ idsamp = (long)dsamp1;
+ frac = dsamp1 - idsamp;
+ irdphase = (iwrphase - idsamp) & mask;
+ irdphaseb = (irdphase - 1) & mask;
+ d1 = dlybuf[irdphase];
+ d2 = dlybuf[irdphaseb];
+ value = (d1 + frac * (d2 - d1)) * ramp1;
+ ramp1 += ramp1_slope;
+
+ dsamp2 += dsamp2_slope;
+ idsamp = (long)dsamp2;
+ frac = dsamp2 - idsamp;
+ irdphase = (iwrphase - idsamp) & mask;
+ irdphaseb = (irdphase - 1) & mask;
+ d1 = dlybuf[irdphase];
+ d2 = dlybuf[irdphaseb];
+ value += (d1 + frac * (d2 - d1)) * ramp2;
+ ramp2 += ramp2_slope;
+
+ dsamp3 += dsamp3_slope;
+ idsamp = (long)dsamp3;
+ frac = dsamp3 - idsamp;
+ irdphase = (iwrphase - idsamp) & mask;
+ irdphaseb = (irdphase - 1) & mask;
+ d1 = dlybuf[irdphase];
+ d2 = dlybuf[irdphaseb];
+ value += (d1 + frac * (d2 - d1)) * ramp3;
+ ramp3 += ramp3_slope;
+
+ dsamp4 += dsamp4_slope;
+ idsamp = (long)dsamp4;
+ frac = dsamp4 - idsamp;
+ irdphase = (iwrphase - idsamp) & mask;
+ irdphaseb = (irdphase - 1) & mask;
+ d1 = dlybuf[irdphase];
+ d2 = dlybuf[irdphaseb];
+ value += (d1 + frac * (d2 - d1)) * ramp4;
+ ramp4 += ramp4_slope;
+
+ dlybuf[iwrphase] = ZXP(nin);
+ ZXP(nout) = value *= 0.5;
+ }
+ }
+
+ m_counter = counter;
+
+ m_dsamp1 = dsamp1;
+ m_dsamp2 = dsamp2;
+ m_dsamp3 = dsamp3;
+ m_dsamp4 = dsamp4;
+
+ m_ramp1 = ramp1;
+ m_ramp2 = ramp2;
+ m_ramp3 = ramp3;
+ m_ramp4 = ramp4;
+
+ m_iwrphase = iwrphase;
+
+ RPUT;
+}
+
+
+/* a control rate PitchShift doesn't make sense */
diff --git a/sc4pd/source/RHPF.cpp b/sc4pd/source/RHPF.cpp
new file mode 100644
index 0000000..fb79d2b
--- /dev/null
+++ b/sc4pd/source/RHPF.cpp
@@ -0,0 +1,192 @@
+/* sc4pd
+ RHPF~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Peter Kowald & Tatsuya Nakatani:
+ 13 Definitions of Truth
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ RHPF~ -------------------------------*/
+
+class RHPF_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(RHPF_ar,sc4pd_dsp);
+
+public:
+ RHPF_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ mRadiansPerSample = sc_radianspersample();
+ mFilterSlope = sc_filterslope();
+ mFilterLoops = sc_filterloops();
+ mFilterRemain = sc_filterremain();
+ }
+
+ void m_set_freq(float f)
+ {
+ m_freq=f;
+ changed = true;
+ }
+
+ void m_set_rq(float f)
+ {
+ m_reson=f;
+ changed = true;
+ }
+
+
+private:
+ float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq, m_reson;
+ bool changed;
+ float mRadiansPerSample, mFilterSlope;
+ int mFilterLoops, mFilterRemain;
+
+ FLEXT_CALLBACK_F(m_set_freq);
+ FLEXT_CALLBACK_F(m_set_rq);
+};
+
+FLEXT_LIB_DSP_V("RHPF~",RHPF_ar);
+
+RHPF_ar::RHPF_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq);
+ FLEXT_ADDMETHOD_(0,"krq",m_set_rq);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+ m_reson = sc_getfloatarg(Args,1);
+ changed = true;
+
+ AddOutSignal();
+
+ m_a0 = 0.f;
+ m_b1 = 0.f;
+ m_b2 = 0.f;
+ m_y1 = 0.f;
+ m_y2 = 0.f;
+}
+
+void RHPF_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float y0;
+ float y1 = m_y1;
+ float y2 = m_y2;
+ float a0 = m_a0;
+ float b1 = m_b1;
+ float b2 = m_b2;
+
+ if (changed)
+ {
+ float qres = sc_max(0.001, m_reson);
+ float pfreq = m_freq * mRadiansPerSample;
+
+ float D = tan(pfreq * qres * 0.5);
+ float C = ((1.f-D)/(1.f+D));
+ float cosf = cos(pfreq);
+
+ float next_b1 = (1.f + C) * cosf;
+ float next_b2 = -C;
+ float next_a0 = (1.f + C + next_b1) * .25;
+
+ float a0_slope = (next_a0 - a0) * mFilterSlope;
+ float b1_slope = (next_b1 - b1) * mFilterSlope;
+ float b2_slope = (next_b2 - b2) * mFilterSlope;
+
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = y0 - 2.f * y1 + y2;
+
+ y2 = a0 * ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = y2 - 2.f * y0 + y1;
+
+ y1 = a0 * ZXP(nin) + b1 * y2 + b2 * y0;
+ ZXP(nout) = y1 - 2.f * y2 + y0;
+
+ a0 += a0_slope;
+ b1 += b1_slope;
+ b2 += b2_slope;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = y0 - 2.f * y1 + y2;
+ y2 = y1;
+ y1 = y0;
+ }
+
+ m_a0 = a0;
+ m_b1 = b1;
+ m_b2 = b2;
+ changed = false;
+ }
+ else
+ {
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = y0 - 2.f * y1 + y2;
+
+ y2 = a0 * ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = y2 - 2.f * y0 + y1;
+
+ y1 = a0 * ZXP(nin) + b1 * y2 + b2 * y0;
+ ZXP(nout) = y1 - 2.f * y2 + y0;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = y0 - 2.f * y1 + y2;
+ y2 = y1;
+ y1 = y0;
+ }
+ }
+ m_y1 = zapgremlins(y1);
+ m_y2 = zapgremlins(y2);
+}
+
+/* no control rate RHPF filter */
diff --git a/sc4pd/source/RLPF.cpp b/sc4pd/source/RLPF.cpp
new file mode 100644
index 0000000..89fc46c
--- /dev/null
+++ b/sc4pd/source/RLPF.cpp
@@ -0,0 +1,192 @@
+/* sc4pd
+ RLPF~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Peter Kowald & Tatsuya Nakatani:
+ 13 Definitions of Truth
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ RLPF~ -------------------------------*/
+
+class RLPF_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(RLPF_ar,sc4pd_dsp);
+
+public:
+ RLPF_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ mRadiansPerSample = sc_radianspersample();
+ mFilterSlope = sc_filterslope();
+ mFilterLoops = sc_filterloops();
+ mFilterRemain = sc_filterremain();
+ }
+
+ void m_set_freq(float f)
+ {
+ m_freq=f;
+ changed = true;
+ }
+
+ void m_set_rq(float f)
+ {
+ m_reson=f;
+ changed = true;
+ }
+
+
+private:
+ float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq, m_reson;
+ bool changed;
+ float mRadiansPerSample, mFilterSlope;
+ int mFilterLoops, mFilterRemain;
+
+ FLEXT_CALLBACK_F(m_set_freq);
+ FLEXT_CALLBACK_F(m_set_rq);
+};
+
+FLEXT_LIB_DSP_V("RLPF~",RLPF_ar);
+
+RLPF_ar::RLPF_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq);
+ FLEXT_ADDMETHOD_(0,"rq",m_set_rq);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+ m_reson = sc_getfloatarg(Args,1);
+ changed = true;
+
+ AddOutSignal();
+
+ m_a0 = 0.f;
+ m_b1 = 0.f;
+ m_b2 = 0.f;
+ m_y1 = 0.f;
+ m_y2 = 0.f;
+}
+
+void RLPF_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float y0;
+ float y1 = m_y1;
+ float y2 = m_y2;
+ float a0 = m_a0;
+ float b1 = m_b1;
+ float b2 = m_b2;
+
+ if (changed)
+ {
+ float qres = sc_max(0.001, m_reson);
+ float pfreq = m_freq * mRadiansPerSample;
+
+ float D = tan(pfreq * qres * 0.5);
+ float C = ((1.f-D)/(1.f+D));
+ float cosf = cos(pfreq);
+
+ float next_b1 = (1.f + C) * cosf;
+ float next_b2 = -C;
+ float next_a0 = (1.f + C - next_b1) * .25;
+
+ float a0_slope = (next_a0 - a0) * mFilterSlope;
+ float b1_slope = (next_b1 - b1) * mFilterSlope;
+ float b2_slope = (next_b2 - b2) * mFilterSlope;
+
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = y0 + 2.f * y1 + y2;
+
+ y2 = a0 * ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = y2 + 2.f * y0 + y1;
+
+ y1 = a0 * ZXP(nin) + b1 * y2 + b2 * y0;
+ ZXP(nout) = y1 + 2.f * y2 + y0;
+
+ a0 += a0_slope;
+ b1 += b1_slope;
+ b2 += b2_slope;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = y0 + 2.f * y1 + y2;
+ y2 = y1;
+ y1 = y0;
+ }
+
+ m_a0 = a0;
+ m_b1 = b1;
+ m_b2 = b2;
+ changed = false;
+ }
+ else
+ {
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = y0 + 2.f * y1 + y2;
+
+ y2 = a0 * ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = y2 + 2.f * y0 + y1;
+
+ y1 = a0 * ZXP(nin) + b1 * y2 + b2 * y0;
+ ZXP(nout) = y1 + 2.f * y2 + y0;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = y0 + 2.f * y1 + y2;
+ y2 = y1;
+ y1 = y0;
+ }
+ }
+ m_y1 = zapgremlins(y1);
+ m_y2 = zapgremlins(y2);
+}
+
+/* no control rate RLPF filter */
diff --git a/sc4pd/source/Rand.cpp b/sc4pd/source/Rand.cpp
new file mode 100644
index 0000000..c310aa9
--- /dev/null
+++ b/sc4pd/source/Rand.cpp
@@ -0,0 +1,160 @@
+/* sc4pd
+ Rand, Rand~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: the sounds coming through my open window
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ Rand~ -------------------------------*/
+
+class Rand_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(Rand_ar,sc4pd_dsp);
+
+public:
+ Rand_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float m_sample;
+ float lo;
+ float hi;
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_DSP_V("Rand~",Rand_ar);
+
+Rand_ar::Rand_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 2)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=sc_getfloatarg(Args,0);
+ hi=sc_getfloatarg(Args,1);
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+}
+
+void Rand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ float range = hi - lo;
+ m_sample = rgen.frand() * range + lo;
+}
+
+
+void Rand_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float sample = m_sample;
+
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++) = sample;
+ }
+}
+
+
+/* ------------------------ Rand ---------------------------------*/
+
+class Rand_kr:
+ public flext_base
+{
+ FLEXT_HEADER(Rand_kr,flext_base);
+
+public:
+ Rand_kr(int argc, t_atom *argv);
+
+protected:
+ void m_loadbang();
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float lo;
+ float hi;
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("Rand",Rand_kr);
+
+Rand_kr::Rand_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ AtomList Args(argc,argv);
+ if (Args.Count() != 2)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=sc_getfloatarg(Args,0);
+ hi=sc_getfloatarg(Args,1);
+
+ rgen.init(timeseed());
+
+ AddOutFloat();
+}
+
+void Rand_kr::m_loadbang()
+{
+ float range = hi - lo;
+
+ ToOutFloat(0,rgen.frand() * range + lo);
+}
diff --git a/sc4pd/source/Resonz.cpp b/sc4pd/source/Resonz.cpp
new file mode 100644
index 0000000..4561b9a
--- /dev/null
+++ b/sc4pd/source/Resonz.cpp
@@ -0,0 +1,190 @@
+/* sc4pd
+ Resonz~, Resonz
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: MIMEO: Electric Chair And Table
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ Resonz~ -----------------------------*/
+
+class Resonz_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(Resonz_ar,sc4pd_dsp);
+
+public:
+ Resonz_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set_freq(float f)
+ {
+ m_freq = f;
+ m_ffreq = m_freq * mRadiansPerSample;
+ changed = true;
+ }
+ void m_set_rq(float f)
+ {
+ m_rq = f;
+ changed = true;
+ }
+
+private:
+ FLEXT_CALLBACK_F(m_set_freq);
+ FLEXT_CALLBACK_F(m_set_rq);
+ float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq, m_rq, m_ffreq;
+ bool changed;
+
+ float mRadiansPerSample, mFilterSlope, mFilterLoops, mFilterRemain;
+};
+
+FLEXT_LIB_DSP_V("Resonz~",Resonz_ar);
+
+Resonz_ar::Resonz_ar(int argc,t_atom * argv)
+{
+ FLEXT_ADDMETHOD_(0,"freq",m_set_freq);
+ FLEXT_ADDMETHOD_(0,"rq",m_set_rq);
+
+ AtomList Args(argc,argv);
+ m_freq = sc_getfloatarg(Args,0);
+ m_rq = sc_getfloatarg(Args,1);
+
+ AddOutSignal();
+
+ m_a0 = 0.f;
+ m_b1 = 0.f;
+ m_b2 = 0.f;
+ m_y1 = 0.f;
+ m_y2 = 0.f;
+ changed = false;
+}
+
+void Resonz_ar::m_dsp(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ mRadiansPerSample = sc_radianspersample();
+ mFilterSlope = sc_filterslope();
+ mFilterLoops = sc_filterloops();
+ mFilterRemain = sc_filterremain();
+
+ m_ffreq = m_freq * mRadiansPerSample;
+}
+
+void Resonz_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin = *in;
+
+ float y0;
+ float y1 = m_y1;
+ float y2 = m_y2;
+ float a0 = m_a0;
+ float b1 = m_b1;
+ float b2 = m_b2;
+
+ if (changed = true)
+ {
+ float B = m_ffreq * m_rq;
+ float R = 1.f - B * 0.5f;
+ float twoR = 2.f * R;
+ float R2 = R * R;
+ float cost = (twoR * cos(m_ffreq)) / (1.f + R2);
+ float b1_next = twoR * cost;
+ float b2_next = -R2;
+ float a0_next = (1.f - R2) * 0.5f;
+ float a0_slope = (a0_next - a0) * mFilterSlope;
+ float b1_slope = (b1_next - b1) * mFilterSlope;
+ float b2_slope = (b2_next - b2) * mFilterSlope;
+
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 - y2);
+
+ y2 = ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = a0 * (y2 - y1);
+
+ y1 = ZXP(nin) + b1 * y2 + b2 * y0;
+ ZXP(nout) = a0 * (y1 - y0);
+
+ a0 += a0_slope;
+ b1 += b1_slope;
+ b2 += b2_slope;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 - y2);
+ y2 = y1;
+ y1 = y0;
+ }
+
+ m_a0 = a0_next;
+ m_b1 = b1_next;
+ m_b2 = b2_next;
+ changed = false;
+ }
+ else
+ {
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 - y2);
+
+ y2 = ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = a0 * (y2 - y1);
+
+ y1 = ZXP(nin) + b1 * y2 + b2 * y0;
+ ZXP(nout) = a0 * (y1 - y0);
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * (y0 - y2);
+ y2 = y1;
+ y1 = y0;
+ }
+ }
+ m_y1 = zapgremlins(y1);
+ m_y2 = zapgremlins(y2);
+}
+
+
+/* no control rate resonz */
diff --git a/sc4pd/source/SOS.cpp b/sc4pd/source/SOS.cpp
new file mode 100644
index 0000000..29aaecb
--- /dev/null
+++ b/sc4pd/source/SOS.cpp
@@ -0,0 +1,258 @@
+/* sc4pd
+ SOS~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Susie Ibarra & Assif Tsahar: Home Cookin'
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ SOS~ -------------------------------*/
+
+class SOS_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(SOS_ar,sc4pd_dsp);
+
+public:
+ SOS_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out)
+ {
+ m_signal_fun(n,in,out);
+ }
+
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ mFilterLoops = sc_filterloops();
+ mFilterRemain = sc_filterremain();
+ mFilterSlope = sc_filterslope();
+ }
+
+ void m_set_a0(float f)
+ {
+ next_a0=f;
+ }
+
+ void m_set_a1(float f)
+ {
+ next_a1=f;
+ }
+
+ void m_set_a2(float f)
+ {
+ next_a2=f;
+ }
+
+ void m_set_b1(float f)
+ {
+ next_b1=f;
+ }
+
+ void m_set_b2(float f)
+ {
+ next_b2=f;
+ }
+
+ void m_ar()
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar));
+ }
+
+ void m_kr()
+ {
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr));
+ }
+
+private:
+ float next_a0, next_a1, next_a2, next_b1, next_b2;
+ float m_y1, m_y2, m_a0, m_a1, m_a2, m_b1, m_b2;
+
+ float mFilterSlope;
+ int mFilterLoops, mFilterRemain;
+
+ DEFSIGCALL (m_signal_fun);
+ DEFSIGFUN (m_signal_ar);
+ DEFSIGFUN (m_signal_kr);
+
+ FLEXT_CALLBACK_F(m_set_a0);
+ FLEXT_CALLBACK_F(m_set_a1);
+ FLEXT_CALLBACK_F(m_set_a2);
+ FLEXT_CALLBACK_F(m_set_b1);
+ FLEXT_CALLBACK_F(m_set_b2);
+ FLEXT_CALLBACK(m_ar);
+ FLEXT_CALLBACK(m_kr);
+};
+
+FLEXT_LIB_DSP_V("SOS~",SOS_ar);
+
+SOS_ar::SOS_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"a0",m_set_a0);
+ FLEXT_ADDMETHOD_(0,"a1",m_set_a1);
+ FLEXT_ADDMETHOD_(0,"a2",m_set_a2);
+ FLEXT_ADDMETHOD_(0,"b1",m_set_b1);
+ FLEXT_ADDMETHOD_(0,"b2",m_set_b2);
+ FLEXT_ADDMETHOD_(0,"ar",m_ar);
+ FLEXT_ADDMETHOD_(0,"kr",m_kr);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ if (Args.Count()<5)
+ {
+ post("needs at least 5 arguments");
+ return;
+ }
+ m_a0 = sc_getfloatarg(Args,0);
+ m_a1 = sc_getfloatarg(Args,1);
+ m_a2 = sc_getfloatarg(Args,2);
+ m_b1 = sc_getfloatarg(Args,3);
+ m_b2 = sc_getfloatarg(Args,4);
+
+ if(sc_ar(Args))
+ {
+ AddInSignal();
+ AddInSignal();
+ AddInSignal();
+ AddInSignal();
+ AddInSignal();
+ AddInSignal();
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar));
+ }
+ else // if not given, use control rate
+ SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr));
+
+ AddOutSignal();
+
+ m_y1 = 0.f;
+ m_a0 = 0.f;
+ m_a1 = 0.f;
+ m_a2 = 0.f;
+ m_b1 = 0.f;
+ m_b2 = 0.f;
+}
+
+void SOS_ar::m_signal_ar(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+ float *a0 = *(in+1);
+ float *a1 = *(in+2);
+ float *a2 = *(in+3);
+ float *b1 = *(in+4);
+ float *b2 = *(in+5);
+
+ float y0;
+ float y1 = m_y1;
+ float y2 = m_y2;
+
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = ZXP(nin) + ZXP(b1) * y1 + ZXP(b2) * y2;
+ ZXP(nout) = ZXP(a0) * y0 + ZXP(a1) * y1 + ZXP(a2) * y2;
+
+ y2 = ZXP(nin) + ZXP(b1) * y0 + ZXP(b2) * y1;
+ ZXP(nout) = ZXP(a0) * y2 + ZXP(a1) * y0 + ZXP(a2) * y1;
+
+ y1 = ZXP(nin) + ZXP(b1) * y2 + ZXP(b2) * y0;
+ ZXP(nout) = ZXP(a0) * y1 + ZXP(a1) * y2 + ZXP(a2) * y0;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = ZXP(nin) + ZXP(b1) * y1 + ZXP(b2) * y2;
+ ZXP(nout) = ZXP(a0) * y0 + ZXP(a1) * y1 + ZXP(a2) * y2;
+ y2 = y1;
+ y1 = y0;
+ }
+
+ m_y1 = zapgremlins(y1);
+ m_y2 = zapgremlins(y2);
+
+}
+
+
+void SOS_ar::m_signal_kr(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float y0;
+ float y1 = m_y1;
+ float y2 = m_y2;
+ float a0 = m_a0;
+ float a1 = m_a1;
+ float a2 = m_a2;
+ float b1 = m_b1;
+ float b2 = m_b2;
+ float a0_slope = (next_a0 - a0) * mFilterSlope;
+ float a1_slope = (next_a1 - a1) * mFilterSlope;
+ float a2_slope = (next_a2 - a2) * mFilterSlope;
+ float b1_slope = (next_b1 - b1) * mFilterSlope;
+ float b2_slope = (next_b2 - b2) * mFilterSlope;
+
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * y0 + a1 * y1 + a2 * y2;
+
+ y2 = ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = a0 * y2 + a1 * y0 + a2 * y1;
+
+ y1 = ZXP(nin) + b1 * y2 + b2 * y0;
+ ZXP(nout) = a0 * y1 + a1 * y2 + a2 * y0;
+
+ a0 += a0_slope;
+ a1 += a1_slope;
+ a2 += a2_slope;
+ b1 += b1_slope;
+ b2 += b2_slope;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = a0 * y0 + a1 * y1 + a2 * y2;
+ y2 = y1;
+ y1 = y0;
+ }
+
+ m_y1 = zapgremlins(y1);
+ m_y2 = zapgremlins(y2);
+}
+
+/* no kr SOS */
diff --git a/sc4pd/source/TExpRand.cpp b/sc4pd/source/TExpRand.cpp
new file mode 100644
index 0000000..a0087e7
--- /dev/null
+++ b/sc4pd/source/TExpRand.cpp
@@ -0,0 +1,210 @@
+/* sc4pd
+ TExpRand, TExpRand~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Assif Tsahar: Open Systems
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ TExpRand~ -------------------------------*/
+
+class TExpRand_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(TExpRand_ar,sc4pd_dsp);
+
+public:
+ TExpRand_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_bang();
+
+ void m_sethi(float f)
+ {
+ hi = f;
+ ratio = hi / lo;
+ }
+
+ void m_setlo(float f)
+ {
+ lo = f;
+ ratio = hi / lo;
+ }
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float m_sample;
+ float lo;
+ float hi;
+ float ratio;
+ RGen rgen;
+
+ FLEXT_CALLBACK(m_bang);
+ FLEXT_CALLBACK_F(m_setlo);
+ FLEXT_CALLBACK_F(m_sethi);
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_DSP_V("TExpRand~",TExpRand_ar);
+
+TExpRand_ar::TExpRand_ar(int argc, t_atom *argv)
+{
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 2)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=sc_getfloatarg(Args,0);
+ hi=sc_getfloatarg(Args,1);
+ ratio = hi / lo;
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+
+ FLEXT_ADDBANG(0,m_bang);
+ FLEXT_ADDMETHOD_(0,"setlo",m_setlo);
+ FLEXT_ADDMETHOD_(0,"sethi",m_sethi);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+}
+
+void TExpRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ m_sample = pow(ratio, rgen.frand()) * lo;
+}
+
+
+void TExpRand_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float sample = m_sample;
+
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++) = sample;
+ }
+}
+
+void TExpRand_ar::m_bang()
+{
+ m_sample = pow(ratio, rgen.frand()) * lo;
+}
+
+/* ------------------------ TExpRand ---------------------------------*/
+
+class TExpRand_kr:
+ public flext_base
+{
+ FLEXT_HEADER(TExpRand_kr,flext_base);
+
+public:
+ TExpRand_kr(int argc, t_atom *argv);
+
+protected:
+ void m_loadbang();
+ void m_bang();
+
+ void m_sethi(float f)
+ {
+ hi = f;
+ ratio = hi / lo;
+ }
+
+ void m_setlo(float f)
+ {
+ lo = f;
+ ratio = hi / lo;
+ }
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float lo;
+ float hi;
+ float ratio;
+ RGen rgen;
+ FLEXT_CALLBACK(m_bang);
+ FLEXT_CALLBACK_F(m_setlo);
+ FLEXT_CALLBACK_F(m_sethi);
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("TExpRand",TExpRand_kr);
+
+TExpRand_kr::TExpRand_kr(int argc, t_atom *argv)
+{
+ AtomList Args(argc,argv);
+ if (Args.Count() != 2)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=sc_getfloatarg(Args,0);
+ hi=sc_getfloatarg(Args,1);
+ ratio = hi / lo;
+
+ rgen.init(timeseed());
+
+ AddOutFloat();
+
+ FLEXT_ADDBANG(0,m_bang);
+ FLEXT_ADDMETHOD_(0,"setlo",m_setlo);
+ FLEXT_ADDMETHOD_(0,"sethi",m_sethi);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+}
+
+void TExpRand_kr::m_loadbang()
+{
+ ToOutFloat(0,pow(ratio, rgen.frand()) * lo);
+}
+
+void TExpRand_kr::m_bang()
+{
+ ToOutFloat(0,pow(ratio, rgen.frand()) * lo);
+}
diff --git a/sc4pd/source/TIRand.cpp b/sc4pd/source/TIRand.cpp
new file mode 100644
index 0000000..1c59a6e
--- /dev/null
+++ b/sc4pd/source/TIRand.cpp
@@ -0,0 +1,210 @@
+/* sc4pd
+ TIRand, TIRand~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Sachiko M: Debris
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ TIRand~ -------------------------------*/
+
+class TIRand_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(TIRand_ar,sc4pd_dsp);
+
+public:
+ TIRand_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_bang();
+
+ void m_sethi(int i)
+ {
+ hi = i;
+ range = hi - lo;
+ }
+
+ void m_setlo(int i)
+ {
+ lo = i;
+ range = hi - lo;
+ }
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float m_sample;
+ int lo;
+ int hi;
+ int range;
+ RGen rgen;
+
+ FLEXT_CALLBACK(m_bang);
+ FLEXT_CALLBACK_I(m_setlo);
+ FLEXT_CALLBACK_I(m_sethi);
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_DSP_V("TIRand~",TIRand_ar);
+
+TIRand_ar::TIRand_ar(int argc, t_atom *argv)
+{
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 2)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=int(sc_getfloatarg(Args,0));
+ hi=int(sc_getfloatarg(Args,1));
+ range = hi - lo;
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+
+ FLEXT_ADDBANG(0,m_bang);
+ FLEXT_ADDMETHOD_(0,"setlo",m_setlo);
+ FLEXT_ADDMETHOD_(0,"sethi",m_sethi);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+}
+
+void TIRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ m_sample = float(rgen.irand(range) + lo);
+}
+
+
+void TIRand_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float sample = m_sample;
+
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++) = sample;
+ }
+}
+
+void TIRand_ar::m_bang()
+{
+ m_sample = float(rgen.irand(range) + lo);
+}
+
+/* ------------------------ TIRand ---------------------------------*/
+
+class TIRand_kr:
+ public flext_base
+{
+ FLEXT_HEADER(TIRand_kr,flext_base);
+
+public:
+ TIRand_kr(int argc, t_atom *argv);
+
+protected:
+ void m_loadbang();
+ void m_bang();
+
+ void m_sethi(int i)
+ {
+ hi = i;
+ range = hi - lo;
+ }
+
+ void m_setlo(int i)
+ {
+ lo = i;
+ range = hi - lo;
+ }
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ int lo;
+ int hi;
+ int range;
+ RGen rgen;
+ FLEXT_CALLBACK(m_bang);
+ FLEXT_CALLBACK_I(m_setlo);
+ FLEXT_CALLBACK_I(m_sethi);
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("TIRand",TIRand_kr);
+
+TIRand_kr::TIRand_kr(int argc, t_atom *argv)
+{
+ AtomList Args(argc,argv);
+ if (Args.Count() != 2)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=int(sc_getfloatarg(Args,0));
+ hi=int(sc_getfloatarg(Args,1));
+ range = hi - lo;
+
+ rgen.init(timeseed());
+
+ AddOutInt();
+
+ FLEXT_ADDBANG(0,m_bang);
+ FLEXT_ADDMETHOD_(0,"setlo",m_setlo);
+ FLEXT_ADDMETHOD_(0,"sethi",m_sethi);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+}
+
+void TIRand_kr::m_loadbang()
+{
+ ToOutInt(0,rgen.irand(range) + lo);
+}
+
+void TIRand_kr::m_bang()
+{
+ ToOutInt(0,rgen.irand(range) + lo);
+}
diff --git a/sc4pd/source/TRand.cpp b/sc4pd/source/TRand.cpp
new file mode 100644
index 0000000..d54c196
--- /dev/null
+++ b/sc4pd/source/TRand.cpp
@@ -0,0 +1,210 @@
+/* sc4pd
+ TRand, TRand~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Annette Krebs & Taku Sugimoto: A Duo In Berlin
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ TRand~ -------------------------------*/
+
+class TRand_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(TRand_ar,sc4pd_dsp);
+
+public:
+ TRand_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_bang();
+
+ void m_sethi(float f)
+ {
+ hi = f;
+ range = hi - lo;
+ }
+
+ void m_setlo(float f)
+ {
+ lo = f;
+ range = hi - lo;
+ }
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float m_sample;
+ float lo;
+ float hi;
+ float range;
+ RGen rgen;
+
+ FLEXT_CALLBACK(m_bang);
+ FLEXT_CALLBACK_F(m_setlo);
+ FLEXT_CALLBACK_F(m_sethi);
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_DSP_V("TRand~",TRand_ar);
+
+TRand_ar::TRand_ar(int argc, t_atom *argv)
+{
+ AtomList Args(argc,argv);
+
+ if (Args.Count() != 2)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=sc_getfloatarg(Args,0);
+ hi=sc_getfloatarg(Args,1);
+ range = hi - lo;
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+
+ FLEXT_ADDBANG(0,m_bang);
+ FLEXT_ADDMETHOD_(0,"setlo",m_setlo);
+ FLEXT_ADDMETHOD_(0,"sethi",m_sethi);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+}
+
+void TRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out)
+{
+ m_sample = rgen.frand() * range + lo;
+}
+
+
+void TRand_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ float sample = m_sample;
+
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++) = sample;
+ }
+}
+
+void TRand_ar::m_bang()
+{
+ m_sample = rgen.frand() * range + lo;
+}
+
+/* ------------------------ TRand ---------------------------------*/
+
+class TRand_kr:
+ public flext_base
+{
+ FLEXT_HEADER(TRand_kr,flext_base);
+
+public:
+ TRand_kr(int argc, t_atom *argv);
+
+protected:
+ void m_loadbang();
+ void m_bang();
+
+ void m_sethi(float f)
+ {
+ hi = f;
+ range = hi - lo;
+ }
+
+ void m_setlo(float f)
+ {
+ lo = f;
+ range = hi - lo;
+ }
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ float lo;
+ float hi;
+ float range;
+ RGen rgen;
+ FLEXT_CALLBACK(m_bang);
+ FLEXT_CALLBACK_F(m_setlo);
+ FLEXT_CALLBACK_F(m_sethi);
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("TRand",TRand_kr);
+
+TRand_kr::TRand_kr(int argc, t_atom *argv)
+{
+ AtomList Args(argc,argv);
+ if (Args.Count() != 2)
+ {
+ post("not enough arguments");
+ return;
+ }
+ lo=sc_getfloatarg(Args,0);
+ hi=sc_getfloatarg(Args,1);
+ range = hi - lo;
+
+ rgen.init(timeseed());
+
+ AddOutFloat();
+
+ FLEXT_ADDBANG(0,m_bang);
+ FLEXT_ADDMETHOD_(0,"setlo",m_setlo);
+ FLEXT_ADDMETHOD_(0,"sethi",m_sethi);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+}
+
+void TRand_kr::m_loadbang()
+{
+ ToOutFloat(0,rgen.frand() * range + lo);
+}
+
+void TRand_kr::m_bang()
+{
+ ToOutFloat(0,rgen.frand() * range + lo);
+}
diff --git a/sc4pd/source/TwoPole.cpp b/sc4pd/source/TwoPole.cpp
new file mode 100644
index 0000000..b37d17f
--- /dev/null
+++ b/sc4pd/source/TwoPole.cpp
@@ -0,0 +1,167 @@
+/* sc4pd
+ TwoPole~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: VA: Insight
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ TwoPole~ -------------------------------*/
+
+class TwoPole_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(TwoPole_ar,sc4pd_dsp);
+
+public:
+ TwoPole_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ mRadiansPerSample = sc_radianspersample();
+ mFilterSlope = sc_filterslope();
+ mFilterLoops = sc_filterloops();
+ mFilterRemain = sc_filterremain();
+ }
+
+ void m_set_freq(float f)
+ {
+ m_freq=f;
+ changed = true;
+ }
+
+ void m_set_radius(float f)
+ {
+ m_reson=f;
+ changed = true;
+ }
+
+
+private:
+ float m_b1, m_b2, m_y1, m_y2, m_freq, m_reson;
+ bool changed;
+ float mRadiansPerSample, mFilterSlope;
+ int mFilterLoops, mFilterRemain;
+
+ FLEXT_CALLBACK_F(m_set_freq);
+ FLEXT_CALLBACK_F(m_set_radius);
+};
+
+FLEXT_LIB_DSP_V("TwoPole~",TwoPole_ar);
+
+TwoPole_ar::TwoPole_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq);
+ FLEXT_ADDMETHOD_(0,"kradius",m_set_radius);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+ m_reson = sc_getfloatarg(Args,1);
+ changed = false;
+
+ AddOutSignal();
+
+ m_b1 = 0.f;
+ m_b2 = 0.f;
+ m_y1 = 0.f;
+ m_y2 = 0.f;
+}
+
+void TwoPole_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float y0;
+ float y1 = m_y1;
+ float y2 = m_y2;
+
+ if (changed)
+ {
+ float b1 = m_b1;
+ float b2 = m_b2;
+ float b1_next = 2.f * m_reson * cos(m_freq * mRadiansPerSample);
+ float b2_next = -(m_reson * m_reson);
+ float b1_slope = (b1_next - b1) * mFilterSlope;
+ float b2_slope = (b2_next - b2) * mFilterSlope;
+
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ ZXP(nout) = y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = y2 = ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = y1 = ZXP(nin) + b1 * y2 + b2 * y0;
+
+ b1 += b1_slope;
+ b2 += b2_slope;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ ZXP(nout) = y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ y2 = y1;
+ y1 = y0;
+ }
+
+ m_b1 = b1;
+ m_b2 = b2;
+ changed = false;
+ }
+ else
+ {
+ float b1 = m_b1;
+ float b2 = m_b2;
+
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ ZXP(nout) = y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ ZXP(nout) = y2 = ZXP(nin) + b1 * y0 + b2 * y1;
+ ZXP(nout) = y1 = ZXP(nin) + b1 * y2 + b2 * y0;
+ }
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ ZXP(nout) = y0 = ZXP(nin) + b1 * y1 + b2 * y2;
+ y2 = y1;
+ y1 = y0;
+ }
+ }
+ m_y1 = zapgremlins(y1);
+ m_y2 = zapgremlins(y2);
+}
+
+/* no control rate two pole filter */
diff --git a/sc4pd/source/TwoZero.cpp b/sc4pd/source/TwoZero.cpp
new file mode 100644
index 0000000..85a7633
--- /dev/null
+++ b/sc4pd/source/TwoZero.cpp
@@ -0,0 +1,175 @@
+/* sc4pd
+ TwoZero~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: VA: Insight
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ TwoZero~ -------------------------------*/
+
+class TwoZero_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(TwoZero_ar,sc4pd_dsp);
+
+public:
+ TwoZero_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+ virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out)
+ {
+ mRadiansPerSample = sc_radianspersample();
+ mFilterSlope = sc_filterslope();
+ mFilterLoops = sc_filterloops();
+ mFilterRemain = sc_filterremain();
+ }
+
+ void m_set_freq(float f)
+ {
+ m_freq=f;
+ changed = true;
+ }
+
+ void m_set_radius(float f)
+ {
+ m_reson=f;
+ changed = true;
+ }
+
+
+private:
+ float m_b1, m_b2, m_x1, m_x2, m_freq, m_reson;
+ bool changed;
+ float mRadiansPerSample, mFilterSlope;
+ int mFilterLoops, mFilterRemain;
+
+ FLEXT_CALLBACK_F(m_set_freq);
+ FLEXT_CALLBACK_F(m_set_radius);
+};
+
+FLEXT_LIB_DSP_V("TwoZero~",TwoZero_ar);
+
+TwoZero_ar::TwoZero_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq);
+ FLEXT_ADDMETHOD_(0,"kradius",m_set_radius);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_freq = sc_getfloatarg(Args,0);
+ m_reson = sc_getfloatarg(Args,1);
+ changed = false;
+
+ AddOutSignal();
+
+ m_b1 = 0.f;
+ m_b2 = 0.f;
+ m_x1 = 0.f;
+ m_x2 = 0.f;
+}
+
+void TwoZero_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ float x0;
+ float x1 = m_x1;
+ float x2 = m_x2;
+
+ if (changed)
+ {
+ float b1 = m_b1;
+ float b2 = m_b2;
+ float b1_next = -2.f * m_reson * cos(m_freq * mRadiansPerSample);
+ float b2_next = (m_reson * m_reson);
+ float b1_slope = (b1_next - b1) * mFilterSlope;
+ float b2_slope = (b2_next - b2) * mFilterSlope;
+
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = x0 + b1 * x1 + b2 * x2;
+ x2 = ZXP(nin);
+ ZXP(nout) = x2 + b1 * x0 + b2 * x1;
+ x1 = ZXP(nin);
+ ZXP(nout) = x1 + b1 * x2 + b2 * x0;
+
+ b1 += b1_slope;
+ b2 += b2_slope;
+ }
+
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = x0 + b1 * x1 + b2 * x2;
+ x2 = x1;
+ x1 = x0;
+ }
+
+ m_b1 = b1;
+ m_b2 = b2;
+ changed = false;
+ }
+ else
+ {
+ float b1 = m_b1;
+ float b2 = m_b2;
+
+ for (int i = 0; i!= mFilterLoops;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = x0 + b1 * x1 + b2 * x2;
+ x2 = ZXP(nin);
+ ZXP(nout) = x2 + b1 * x0 + b2 * x1;
+ x1 = ZXP(nin);
+ ZXP(nout) = x1 + b1 * x2 + b2 * x0;
+ }
+ for (int i = 0; i!= mFilterRemain;++i)
+ {
+ x0 = ZXP(nin);
+ ZXP(nout) = x0 + b1 * x1 + b2 * x2;
+ x2 = x1;
+ x1 = x0;
+ }
+ }
+ m_x1 = x1;
+ m_x2 = x2;
+}
+
+/* no control rate twozero filter */
diff --git a/sc4pd/source/WhiteNoise.cpp b/sc4pd/source/WhiteNoise.cpp
new file mode 100644
index 0000000..5def735
--- /dev/null
+++ b/sc4pd/source/WhiteNoise.cpp
@@ -0,0 +1,137 @@
+/* sc4pd
+ WhiteNoise, WhiteNoise~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Otomo Yoshihide: Ensemble Cathode
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ WhiteNoise~ -------------------------------*/
+
+class WhiteNoise_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(WhiteNoise_ar,sc4pd_dsp);
+
+public:
+ WhiteNoise_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ RGen rgen;
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_DSP_V("WhiteNoise~",WhiteNoise_ar);
+
+WhiteNoise_ar::WhiteNoise_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ rgen.init(timeseed());
+
+ AddOutSignal();
+}
+
+
+void WhiteNoise_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+
+ RGET;
+
+ for (int i = 0; i!= n;++i)
+ {
+ (*(nout)++) = frand2(s1, s2, s3);
+ }
+
+ RPUT
+}
+
+
+/* ------------------------ WhiteNoise ---------------------------------*/
+
+class WhiteNoise_kr:
+ public flext_base
+{
+ FLEXT_HEADER(WhiteNoise_kr,flext_base);
+
+public:
+ WhiteNoise_kr(int argc, t_atom *argv);
+
+protected:
+ void m_perform();
+
+ void m_seed(int i)
+ {
+ rgen.init(i);
+ }
+
+private:
+ RGen rgen;
+ FLEXT_CALLBACK(m_perform);
+ FLEXT_CALLBACK_I(m_seed);
+};
+
+FLEXT_LIB_V("WhiteNoise",WhiteNoise_kr);
+
+WhiteNoise_kr::WhiteNoise_kr(int argc, t_atom *argv)
+{
+ FLEXT_ADDBANG(0,m_perform);
+ FLEXT_ADDMETHOD_(0,"seed",m_seed);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ rgen.init(timeseed());
+
+ AddOutFloat();
+}
+
+void WhiteNoise_kr::m_perform()
+{
+ ToOutFloat(0,rgen.frand2());
+}
diff --git a/sc4pd/source/absdif.cpp b/sc4pd/source/absdif.cpp
new file mode 100644
index 0000000..e31a3dd
--- /dev/null
+++ b/sc4pd/source/absdif.cpp
@@ -0,0 +1,132 @@
+/* sc4pd
+ absdif, absdif~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Evan Parker & Keith Rowe: Dark Rags
+
+*/
+
+#include "sc4pd.hpp"
+
+
+inline float sc_absdif (float a, float b)
+{
+ float f=a-b;
+ return fabsf(f);
+}
+
+
+/* ------------------------ absdif~ -----------------------------*/
+
+class absdif_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(absdif_ar,sc4pd_dsp);
+
+public:
+ absdif_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+
+};
+
+FLEXT_LIB_DSP_V("absdif~",absdif_ar);
+
+absdif_ar::absdif_ar(int argc,t_atom * argv)
+{
+ AddInSignal();
+ AddInSignal();
+ AddOutSignal();
+}
+
+void absdif_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin1 = *in;
+ t_sample *nin2 = *(in+1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ if( *nin2 > 0)
+ (*(nout)++) = sc_absdif( (*(nin1)++), (*(nin2)++) );
+ }
+}
+
+
+
+/* ------------------------ absdif ------------------------------*/
+
+class absdif_kr
+ :public flext_base
+{
+ FLEXT_HEADER(absdif_kr,flext_base);
+
+public:
+ absdif_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+ void m_set(float f);
+
+private:
+ float b;
+ FLEXT_CALLBACK_F(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("absdif",absdif_kr);
+
+absdif_kr::absdif_kr(int argc,t_atom * argv)
+ :b(0)
+{
+
+ AddInFloat();
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD(1,m_set);
+}
+
+void absdif_kr::m_perform(float f)
+{
+ ToOutFloat(0,sc_absdif(f,b));
+}
+
+void absdif_kr::m_set(float f)
+{
+ b=f;
+}
diff --git a/sc4pd/source/amclip.cpp b/sc4pd/source/amclip.cpp
new file mode 100644
index 0000000..8bd2edf
--- /dev/null
+++ b/sc4pd/source/amclip.cpp
@@ -0,0 +1,128 @@
+/* sc4pd
+ amclip, amclip(~)
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Keith Rowe & Toshimaru Nakamura: Weather Sky
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ amclip~ -----------------------------*/
+
+class amclip_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(amclip_ar,sc4pd_dsp);
+
+public:
+ amclip_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+
+};
+
+FLEXT_LIB_DSP_V("amclip~",amclip_ar);
+
+amclip_ar::amclip_ar(int argc,t_atom * argv)
+{
+ AddInSignal();
+ AddInSignal();
+ AddOutSignal();
+}
+
+void amclip_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin1 = *in;
+ t_sample *nin2 = *(in+1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ if( *nin2 > 0)
+ (*(nout)++) = sc_amclip( (*(nin1)++), (*(nin2)++) );
+ }
+}
+
+
+
+/* ------------------------ amclip ------------------------------*/
+
+class amclip_kr
+ :public flext_base
+{
+ FLEXT_HEADER(amclip_kr,flext_base);
+
+public:
+ amclip_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+ void m_set(float f);
+
+private:
+ float b;
+ FLEXT_CALLBACK_F(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("amclip",amclip_kr);
+
+amclip_kr::amclip_kr(int argc,t_atom * argv)
+ :b(0)
+{
+
+ AddInFloat();
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD(1,m_set);
+}
+
+void amclip_kr::m_perform(float f)
+{
+ ToOutFloat(0,f*b);
+}
+
+void amclip_kr::m_set(float f)
+{
+ if (f>0)
+ b=f;
+ else
+ b=0;
+}
diff --git a/sc4pd/source/difsqr.cpp b/sc4pd/source/difsqr.cpp
new file mode 100644
index 0000000..26051f4
--- /dev/null
+++ b/sc4pd/source/difsqr.cpp
@@ -0,0 +1,131 @@
+/* sc4pd
+ difsqr, difsqr~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Evan Parker & Keith Rowe: Dark Rags
+
+*/
+
+#include "sc4pd.hpp"
+
+
+inline float sc_difsqr (float a, float b)
+{
+ return a*a-b*b;
+}
+
+
+/* ------------------------ difsqr~ -----------------------------*/
+
+class difsqr_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(difsqr_ar,sc4pd_dsp);
+
+public:
+ difsqr_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+
+};
+
+FLEXT_LIB_DSP_V("difsqr~",difsqr_ar);
+
+difsqr_ar::difsqr_ar(int argc,t_atom * argv)
+{
+ AddInSignal();
+ AddInSignal();
+ AddOutSignal();
+}
+
+void difsqr_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin1 = *in;
+ t_sample *nin2 = *(in+1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ if( *nin2 > 0)
+ (*(nout)++) = sc_difsqr( (*(nin1)++), (*(nin2)++) );
+ }
+}
+
+
+
+/* ------------------------ difsqr ------------------------------*/
+
+class difsqr_kr
+ :public flext_base
+{
+ FLEXT_HEADER(difsqr_kr,flext_base);
+
+public:
+ difsqr_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+ void m_set(float f);
+
+private:
+ float b;
+ FLEXT_CALLBACK_F(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("difsqr",difsqr_kr);
+
+difsqr_kr::difsqr_kr(int argc,t_atom * argv)
+ :b(0)
+{
+
+ AddInFloat();
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD(1,m_set);
+}
+
+void difsqr_kr::m_perform(float f)
+{
+ ToOutFloat(0,sc_difsqr(f,b));
+}
+
+void difsqr_kr::m_set(float f)
+{
+ b=f;
+}
diff --git a/sc4pd/source/excess.cpp b/sc4pd/source/excess.cpp
new file mode 100644
index 0000000..eeefb3d
--- /dev/null
+++ b/sc4pd/source/excess.cpp
@@ -0,0 +1,124 @@
+/* sc4pd
+ excess, excess~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Keith Rowe & Toshimaru Nakamura: Weather Sky
+
+*/
+
+#include "sc4pd.hpp"
+
+/* ------------------------ excess~ -----------------------------*/
+
+class excess_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(excess_ar,sc4pd_dsp);
+
+public:
+ excess_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+
+};
+
+FLEXT_LIB_DSP_V("excess~",excess_ar);
+
+excess_ar::excess_ar(int argc,t_atom * argv)
+{
+ AddInSignal();
+ AddInSignal();
+ AddOutSignal();
+}
+
+void excess_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin1 = *in;
+ t_sample *nin2 = *(in+1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ if( *nin2 > 0)
+ (*(nout)++) = sc_excess( (*(nin1)++), (*(nin2)++) );
+ }
+}
+
+
+
+/* ------------------------ excess ------------------------------*/
+
+class excess_kr
+ :public flext_base
+{
+ FLEXT_HEADER(excess_kr,flext_base);
+
+public:
+ excess_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+ void m_set(float f);
+
+private:
+ float b;
+ FLEXT_CALLBACK_F(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("excess",excess_kr);
+
+excess_kr::excess_kr(int argc,t_atom * argv)
+ :b(0)
+{
+
+ AddInFloat();
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD(1,m_set);
+}
+
+void excess_kr::m_perform(float f)
+{
+ ToOutFloat(0,sc_excess(f,b));
+}
+
+void excess_kr::m_set(float f)
+{
+ b=f;
+}
diff --git a/sc4pd/source/fftlib.c b/sc4pd/source/fftlib.c
new file mode 100644
index 0000000..4bbdcb1
--- /dev/null
+++ b/sc4pd/source/fftlib.c
@@ -0,0 +1,3306 @@
+/* FFT library */
+/* Library of in-place fast fourier transforms */
+/* Forward and inverse complex transforms */
+/* and real forward transform */
+/* Optimized for RISC processors with many registers */
+/* Version 1.1 John Green NUWC New London CT January 96 */
+/* Version 1.1 renamed as fftlib from fftbig */
+/* Version 1.1 removed (float *)((char *) ptr) optimization */
+/* Version 1.0 John Green NUWC New London CT December 95 */
+/* (John Green) green_jt@vsdec.nl.nuwc.navy.mil */
+/* green_jt@vsdec.nl.nuwc.navy.mil */
+
+#include <math.h>
+#include "fftlib.h"
+
+#define MAXMROOT 9 /* 2^(MAXMROOT-1) = # of elements in BRcnt */
+
+/* Bit reversed counter */
+static const unsigned char BRcnt[256] = {
+ 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208,
+ 48, 176, 112, 240, 8, 136, 72, 200, 40, 168, 104, 232,
+ 24, 152, 88, 216, 56, 184, 120, 248, 4, 132, 68, 196,
+ 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
+ 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220,
+ 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226,
+ 18, 146, 82, 210, 50, 178, 114, 242, 10, 138, 74, 202,
+ 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,
+ 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214,
+ 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238,
+ 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193,
+ 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,
+ 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217,
+ 57, 185, 121, 249, 5, 133, 69, 197, 37, 165, 101, 229,
+ 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205,
+ 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
+ 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211,
+ 51, 179, 115, 243, 11, 139, 75, 203, 43, 171, 107, 235,
+ 27, 155, 91, 219, 59, 187, 123, 251, 7, 135, 71, 199,
+ 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
+ 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223,
+ 63, 191, 127, 255 };
+
+/* Table of powers of 2 */
+static const long Ntbl[21] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
+ 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576};
+
+long FFTInit(long *fftMptr, long fftN, float *Utbl){
+/* Compute cosine table and check size for complex ffts */
+/* INPUTS */
+/* fftN = size of fft */
+/* OUTPUTS */
+/* *fftMptr = log2 of fft size */
+/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */
+/* RETURNS */
+/* 1 if fftN is invalid, 0 otherwise */
+long i1, ErrVal;
+ErrVal = 0;
+*fftMptr = (long)(log(fftN)/log(2.0) + 0.5);
+if ((*fftMptr >= 3) & (*fftMptr <= 19) & (int)(pow(2,*fftMptr)+.5) == fftN)
+ for (i1 = 0; i1 <= fftN/4; i1++)
+ Utbl[i1] = cos( ( 3.1415926535897932384626433832795 * 2.0 * i1 ) / fftN );
+else
+ ErrVal = 1;
+return ErrVal;
+}
+
+long rFFTInit(long *fftMptr, long fftN, float *Utbl){
+/* Compute cosine table and check size for a real input fft */
+/* INPUTS */
+/* fftN = size of fft */
+/* OUTPUTS */
+/* *fftMptr = log2 of fft size */
+/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */
+/* RETURNS */
+/* 1 if fftN is invalid, 0 otherwise */
+long i1, ErrVal;
+ErrVal = 0;
+*fftMptr = (long)(log(fftN)/log(2.0) + 0.5);
+if ((*fftMptr >= 4) & (*fftMptr <= 20) & (int)(pow(2,*fftMptr)+.5) == fftN)
+
+ for (i1 = 0; i1 <= fftN/4; i1++)
+ Utbl[i1] = cos( ( 3.1415926535897932384626433832795 * 2.0 * i1 ) / fftN );
+else
+ ErrVal = 1;
+return ErrVal;
+}
+
+void ffts(float *ioptr, long M, long Rows, float *Utbl){
+/* Compute in-place complex fft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = input data array */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = output data array */
+
+long Flyinc;
+long FlyOffsetA;
+long FlyOffsetAIm;
+long FlyOffsetB;
+long FlyOffsetBIm;
+long NsameU1;
+long NsameU2;
+long NsameU4;
+long diffUcnt;
+long LoopCnt;
+
+float scale;
+float fly0r;
+float fly0i;
+float fly1r;
+float fly1i;
+float fly2r;
+float fly2i;
+float fly3r;
+float fly3i;
+float fly4r;
+float fly4i;
+float fly5r;
+float fly5i;
+float fly6r;
+float fly6i;
+float fly7r;
+float fly7i;
+float U0r;
+float U0i;
+float U1r;
+float U1i;
+float U2r;
+float U2i;
+float U3r;
+float U3i;
+float t0r;
+float t0i;
+float t1r;
+float t1i;
+
+float *fly0P;
+float *fly1P;
+float *fly2P;
+float *fly3P;
+
+float *U0rP;
+float *U0iP;
+float *U1rP;
+float *U1iP;
+float *U2rP;
+float *U2iP;
+float *IOP;
+long U3offset;
+
+long stage;
+long NdiffU;
+long LoopN;
+
+const long BRshift = MAXMROOT - (M>>1);
+const long Nrems2 = Ntbl[M-(M>>1)+1];
+const long Nroot_1_ColInc = (Ntbl[M-1]-Ntbl[M-(M>>1)])*2;
+
+scale = 2.0;
+for (;Rows>0;Rows--){
+
+FlyOffsetA = Ntbl[M] * (2/2);
+FlyOffsetAIm = FlyOffsetA + 1;
+FlyOffsetB = FlyOffsetA + 2;
+FlyOffsetBIm = FlyOffsetB + 1;
+
+/* BitrevR2 ** bit reverse and first radix 2 stage ******/
+
+for (stage = 0; stage < Ntbl[M-(M>>1)]*2; stage += Ntbl[M>>1]*2){
+ for (LoopN = (Ntbl[(M>>1)-1]-1); LoopN >= 0; LoopN--){
+ LoopCnt = (Ntbl[(M>>1)-1]-1);
+ fly0P = ioptr+ Nroot_1_ColInc + ((int)BRcnt[LoopN] >> BRshift)*(2*2) + stage;
+ IOP = ioptr + (LoopN<<(M+1)/2) * 2 + stage;
+ fly1P = IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2);
+ fly0r = *(fly0P);
+ fly0i = *(fly0P+1);
+ fly1r = *(fly0P+FlyOffsetA);
+ fly1i = *(fly0P+FlyOffsetAIm);
+ for (; LoopCnt > LoopN;){
+ fly2r = *(fly0P+2);
+ fly2i = *(fly0P+(2+1));
+ fly3r = *(fly0P+FlyOffsetB);
+ fly3i = *(fly0P+FlyOffsetBIm);
+ fly4r = *(fly1P);
+ fly4i = *(fly1P+1);
+ fly5r = *(fly1P+FlyOffsetA);
+ fly5i = *(fly1P+FlyOffsetAIm);
+ fly6r = *(fly1P+2);
+ fly6i = *(fly1P+(2+1));
+ fly7r = *(fly1P+FlyOffsetB);
+ fly7i = *(fly1P+FlyOffsetBIm);
+
+ t0r = fly0r + fly1r;
+ t0i = fly0i + fly1i;
+ fly1r = fly0r - fly1r;
+ fly1i = fly0i - fly1i;
+ t1r = fly2r + fly3r;
+ t1i = fly2i + fly3i;
+ fly3r = fly2r - fly3r;
+ fly3i = fly2i - fly3i;
+ fly0r = fly4r + fly5r;
+ fly0i = fly4i + fly5i;
+ fly5r = fly4r - fly5r;
+ fly5i = fly4i - fly5i;
+ fly2r = fly6r + fly7r;
+ fly2i = fly6i + fly7i;
+ fly7r = fly6r - fly7r;
+ fly7i = fly6i - fly7i;
+
+ *(fly1P) = t0r;
+ *(fly1P+1) = t0i;
+ *(fly1P+2) = fly1r;
+ *(fly1P+(2+1)) = fly1i;
+ *(fly1P+FlyOffsetA) = t1r;
+ *(fly1P+FlyOffsetAIm) = t1i;
+ *(fly1P+FlyOffsetB) = fly3r;
+ *(fly1P+FlyOffsetBIm) = fly3i;
+ *(fly0P) = fly0r;
+ *(fly0P+1) = fly0i;
+ *(fly0P+2) = fly5r;
+ *(fly0P+(2+1)) = fly5i;
+ *(fly0P+FlyOffsetA) = fly2r;
+ *(fly0P+FlyOffsetAIm) = fly2i;
+ *(fly0P+FlyOffsetB) = fly7r;
+ *(fly0P+FlyOffsetBIm) = fly7i;
+
+ fly0P -= Nrems2;
+ fly0r = *(fly0P);
+ fly0i = *(fly0P+1);
+ fly1r = *(fly0P+FlyOffsetA);
+ fly1i = *(fly0P+FlyOffsetAIm);
+ LoopCnt -= 1;
+ fly1P = (IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2));
+ };
+ fly2r = *(fly0P+2);
+ fly2i = *(fly0P+(2+1));
+ fly3r = *(fly0P+FlyOffsetB);
+ fly3i = *(fly0P+FlyOffsetBIm);
+
+ t0r = fly0r + fly1r;
+ t0i = fly0i + fly1i;
+ fly1r = fly0r - fly1r;
+ fly1i = fly0i - fly1i;
+ t1r = fly2r + fly3r;
+ t1i = fly2i + fly3i;
+ fly3r = fly2r - fly3r;
+ fly3i = fly2i - fly3i;
+
+ *(fly0P) = t0r;
+ *(fly0P+1) = t0i;
+ *(fly0P+2) = fly1r;
+ *(fly0P+(2+1)) = fly1i;
+ *(fly0P+FlyOffsetA) = t1r;
+ *(fly0P+FlyOffsetAIm) = t1i;
+ *(fly0P+FlyOffsetB) = fly3r;
+ *(fly0P+FlyOffsetBIm) = fly3i;
+
+ };
+};
+
+
+
+/**** FFTC **************/
+
+NdiffU = 2;
+Flyinc = (NdiffU);
+
+NsameU4 = Ntbl[M]/4;
+LoopN = Ntbl[M-3];
+
+stage = ((M-1)/3);
+if ( (M-1-(stage * 3)) != 0 ){
+ FlyOffsetA = Flyinc << 2;
+ FlyOffsetB = FlyOffsetA << 1;
+ FlyOffsetAIm = FlyOffsetA + 1;
+ FlyOffsetBIm = FlyOffsetB + 1;
+ if ( (M-1-(stage * 3)) == 1 ){
+ /* 1 radix 2 stage */
+
+ IOP = ioptr;
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+
+ /* Butterflys */
+ /*
+ t0 - - t0
+ t1 - - t1
+ f2 - 1- f5
+ f1 - -i- f7
+ f4 - - f4
+ f0 - - f0
+ f6 - 1- f2
+ f3 - -i- f1
+ */
+
+ for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){
+ t0r = *(fly0P);
+ t0i = *(fly0P + 1);
+ t1r = *(fly1P);
+ t1i = *(fly1P + 1);
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly1r = *(fly3P);
+ fly1i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly0r = *(fly1P + FlyOffsetA);
+ fly0i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly3r = *(fly3P + FlyOffsetA);
+ fly3i = *(fly3P + FlyOffsetAIm);
+
+ fly5r = t0r - fly2r;
+ fly5i = t0i - fly2i;
+ t0r = t0r + fly2r;
+ t0i = t0i + fly2i;
+
+ fly7r = t1r - fly1i;
+ fly7i = t1i + fly1r;
+ t1r = t1r + fly1i;
+ t1i = t1i - fly1r;
+
+ fly2r = fly4r - fly6r;
+ fly2i = fly4i - fly6i;
+ fly4r = fly4r + fly6r;
+ fly4i = fly4i + fly6i;
+
+ fly1r = fly0r - fly3i;
+ fly1i = fly0i + fly3r;
+ fly0r = fly0r + fly3i;
+ fly0i = fly0i - fly3r;
+
+ *(fly2P) = fly5r;
+ *(fly2P + 1) = fly5i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+ *(fly2P + FlyOffsetA) = fly2r;
+ *(fly2P + FlyOffsetAIm) = fly2i;
+ *(fly0P + FlyOffsetA) = fly4r;
+ *(fly0P + FlyOffsetAIm) = fly4i;
+ *(fly3P + FlyOffsetA) = fly1r;
+ *(fly3P + FlyOffsetAIm) = fly1i;
+ *(fly1P + FlyOffsetA) = fly0r;
+ *(fly1P + FlyOffsetAIm) = fly0i;
+
+ fly0P = (fly0P + FlyOffsetB);
+ fly1P = (fly1P + FlyOffsetB);
+ fly2P = (fly2P + FlyOffsetB);
+ fly3P = (fly3P + FlyOffsetB);
+ };
+
+ NsameU4 >>= 1;
+ LoopN >>= 1;
+ NdiffU <<= 1;
+ Flyinc = Flyinc << 1;
+ }
+ else{
+ /* 1 radix 4 stage */
+ IOP = ioptr;
+
+ U3r = 0.7071067811865475244008443621; /* sqrt(0.5); */
+ U3i = U3r;
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+
+ /* Butterflys */
+ /*
+ t0 - - t0 - - t0
+ t1 - - t1 - - t1
+ f2 - 1- f5 - - f5
+ f1 - -i- f7 - - f7
+ f4 - - f4 - 1- f6
+ f0 - - f0 -U3 - f3
+ f6 - 1- f2 - -i- f4
+ f3 - -i- f1 -U3a- f2
+ */
+
+ for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){
+ t0r = *(fly0P);
+ t0i = *(fly0P + 1);
+ t1r = *(fly1P);
+ t1i = *(fly1P + 1);
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly1r = *(fly3P);
+ fly1i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly0r = *(fly1P + FlyOffsetA);
+ fly0i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly3r = *(fly3P + FlyOffsetA);
+ fly3i = *(fly3P + FlyOffsetAIm);
+
+ fly5r = t0r - fly2r;
+ fly5i = t0i - fly2i;
+ t0r = t0r + fly2r;
+ t0i = t0i + fly2i;
+
+ fly7r = t1r - fly1i;
+ fly7i = t1i + fly1r;
+ t1r = t1r + fly1i;
+ t1i = t1i - fly1r;
+
+ fly2r = fly4r - fly6r;
+ fly2i = fly4i - fly6i;
+ fly4r = fly4r + fly6r;
+ fly4i = fly4i + fly6i;
+
+ fly1r = fly0r - fly3i;
+ fly1i = fly0i + fly3r;
+ fly0r = fly0r + fly3i;
+ fly0i = fly0i - fly3r;
+
+
+ fly6r = t0r - fly4r;
+ fly6i = t0i - fly4i;
+ t0r = t0r + fly4r;
+ t0i = t0i + fly4i;
+
+ fly3r = fly5r - fly2i;
+ fly3i = fly5i + fly2r;
+ fly5r = fly5r + fly2i;
+ fly5i = fly5i - fly2r;
+
+ fly4r = t1r - U3r * fly0r;
+ fly4r = fly4r - U3i * fly0i;
+ fly4i = t1i + U3i * fly0r;
+ fly4i = fly4i - U3r * fly0i;
+ t1r = scale * t1r - fly4r;
+ t1i = scale * t1i - fly4i;
+
+ fly2r = fly7r + U3i * fly1r;
+ fly2r = fly2r - U3r * fly1i;
+ fly2i = fly7i + U3r * fly1r;
+ fly2i = fly2i + U3i * fly1i;
+ fly7r = scale * fly7r - fly2r;
+ fly7i = scale * fly7i - fly2i;
+
+ *(fly0P + FlyOffsetA) = fly6r;
+ *(fly0P + FlyOffsetAIm) = fly6i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+ *(fly2P + FlyOffsetA) = fly3r;
+ *(fly2P + FlyOffsetAIm) = fly3i;
+ *(fly2P) = fly5r;
+ *(fly2P + 1) = fly5i;
+ *(fly1P + FlyOffsetA) = fly4r;
+ *(fly1P + FlyOffsetAIm) = fly4i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+ *(fly3P + FlyOffsetA) = fly2r;
+ *(fly3P + FlyOffsetAIm) = fly2i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+
+ fly0P = (fly0P + FlyOffsetB);
+ fly1P = (fly1P + FlyOffsetB);
+ fly2P = (fly2P + FlyOffsetB);
+ fly3P = (fly3P + FlyOffsetB);
+
+ };
+
+ NsameU4 >>= 2;
+ LoopN >>= 2;
+ NdiffU <<= 2;
+ Flyinc = Flyinc << 2;
+ };
+};
+
+NsameU2 = NsameU4 >> 1;
+NsameU1 = NsameU2 >> 1;
+Flyinc <<= 1;
+FlyOffsetA = Flyinc << 2;
+FlyOffsetB = FlyOffsetA << 1;
+FlyOffsetAIm = FlyOffsetA + 1;
+FlyOffsetBIm = FlyOffsetB + 1;
+LoopN >>= 1;
+/* ****** RADIX 8 Stages */
+for (stage = stage<<1; stage > 0 ; stage--){
+
+ /* an fft stage is done in two parts to ease use of the single quadrant cos table */
+
+/* fftcalc1(iobuf, Utbl, N, NdiffU, LoopN); */
+ if(!(stage&1)){
+ U0rP = &Utbl[0];
+ U0iP = &Utbl[Ntbl[M-2]];
+ U1rP = U0rP;
+ U1iP = U0iP;
+ U2rP = U0rP;
+ U2iP = U0iP;
+ U3offset = (Ntbl[M]) / 8;
+
+ IOP = ioptr;
+
+ U0r = *U0rP,
+ U0i = *U0iP;
+ U1r = *U1rP,
+ U1i = *U1iP;
+ U2r = *U2rP,
+ U2i = *U2iP;
+ U3r = *( U2rP + U3offset);
+ U3i = *( U2iP - U3offset);
+ }
+
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+
+ for (diffUcnt = (NdiffU)>>1; diffUcnt != 0; diffUcnt--){
+
+ /* Butterflys */
+ /*
+ f0 - - t0 - - t0 - - t0
+ f1 -U0 - t1 - - t1 - - t1
+ f2 - - f2 -U1 - f5 - - f3
+ f3 -U0 - f1 -U1a- f7 - - f7
+ f4 - - f4 - - f4 -U2 - f6
+ f5 -U0 - f0 - - f0 -U3 - f4
+ f6 - - f6 -U1 - f2 -U2a- f2
+ f7 -U0 - f3 -U1a- f1 -U3a- f5
+ */
+
+ fly0r = *(IOP);
+ fly0i = *(IOP+1);
+ fly1r = *(fly1P);
+ fly1i = *(fly1P+1);
+
+ for (LoopCnt = LoopN-1; LoopCnt > 0 ; LoopCnt--){
+
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly3r = *(fly3P);
+ fly3i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly5r = *(fly1P + FlyOffsetA);
+ fly5i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly7r = *(fly3P + FlyOffsetA);
+ fly7i = *(fly3P + FlyOffsetAIm);
+
+ t1r = fly0r - U0r * fly1r;
+ t1r = t1r - U0i * fly1i;
+ t1i = fly0i + U0i * fly1r;
+ t1i = t1i - U0r * fly1i;
+ t0r = scale * fly0r - t1r;
+ t0i = scale * fly0i - t1i;
+
+ fly1r = fly2r - U0r * fly3r;
+ fly1r = fly1r - U0i * fly3i;
+ fly1i = fly2i + U0i * fly3r;
+ fly1i = fly1i - U0r * fly3i;
+ fly2r = scale * fly2r - fly1r;
+ fly2i = scale * fly2i - fly1i;
+
+ fly0r = fly4r - U0r * fly5r;
+ fly0r = fly0r - U0i * fly5i;
+ fly0i = fly4i + U0i * fly5r;
+ fly0i = fly0i - U0r * fly5i;
+ fly4r = scale * fly4r - fly0r;
+ fly4i = scale * fly4i - fly0i;
+
+ fly3r = fly6r - U0r * fly7r;
+ fly3r = fly3r - U0i * fly7i;
+ fly3i = fly6i + U0i * fly7r;
+ fly3i = fly3i - U0r * fly7i;
+ fly6r = scale * fly6r - fly3r;
+ fly6i = scale * fly6i - fly3i;
+
+
+ fly5r = t0r - U1r * fly2r;
+ fly5r = fly5r - U1i * fly2i;
+ fly5i = t0i + U1i * fly2r;
+ fly5i = fly5i - U1r * fly2i;
+ t0r = scale * t0r - fly5r;
+ t0i = scale * t0i - fly5i;
+
+ fly7r = t1r + U1i * fly1r;
+ fly7r = fly7r - U1r * fly1i;
+ fly7i = t1i + U1r * fly1r;
+ fly7i = fly7i + U1i * fly1i;
+ t1r = scale * t1r - fly7r;
+ t1i = scale * t1i - fly7i;
+
+ fly2r = fly4r - U1r * fly6r;
+ fly2r = fly2r - U1i * fly6i;
+ fly2i = fly4i + U1i * fly6r;
+ fly2i = fly2i - U1r * fly6i;
+ fly4r = scale * fly4r - fly2r;
+ fly4i = scale * fly4i - fly2i;
+
+ fly1r = fly0r + U1i * fly3r;
+ fly1r = fly1r - U1r * fly3i;
+ fly1i = fly0i + U1r * fly3r;
+ fly1i = fly1i + U1i * fly3i;
+ fly0r = scale * fly0r - fly1r;
+ fly0i = scale * fly0i - fly1i;
+
+ fly6r = t0r - U2r * fly4r;
+ fly6r = fly6r - U2i * fly4i;
+ fly6i = t0i + U2i * fly4r;
+ fly6i = fly6i - U2r * fly4i;
+ t0r = scale * t0r - fly6r;
+ t0i = scale * t0i - fly6i;
+
+ fly3r = fly5r - U2i * fly2r;
+ fly3r = fly3r + U2r * fly2i;
+ fly3i = fly5i - U2r * fly2r;
+ fly3i = fly3i - U2i * fly2i;
+ fly2r = scale * fly5r - fly3r;
+ fly2i = scale * fly5i - fly3i;
+
+ fly4r = t1r - U3r * fly0r;
+ fly4r = fly4r - U3i * fly0i;
+ fly4i = t1i + U3i * fly0r;
+ fly4i = fly4i - U3r * fly0i;
+ t1r = scale * t1r - fly4r;
+ t1i = scale * t1i - fly4i;
+
+ fly5r = fly7r + U3i * fly1r;
+ fly5r = fly5r - U3r * fly1i;
+ fly5i = fly7i + U3r * fly1r;
+ fly5i = fly5i + U3i * fly1i;
+ fly7r = scale * fly7r - fly5r;
+ fly7i = scale * fly7i - fly5i;
+
+ *(fly0P + FlyOffsetA) = fly6r;
+ *(fly0P + FlyOffsetAIm) = fly6i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+ *(fly2P) = fly3r;
+ *(fly2P + 1) = fly3i;
+ *(fly2P + FlyOffsetA) = fly2r;
+ *(fly2P + FlyOffsetAIm) = fly2i;
+
+ fly0r = *(fly0P + FlyOffsetB);
+ fly0i = *(fly0P + FlyOffsetBIm);
+
+ *(fly1P + FlyOffsetA) = fly4r;
+ *(fly1P + FlyOffsetAIm) = fly4i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+
+ fly1r = *(fly1P + FlyOffsetB);
+ fly1i = *(fly1P + FlyOffsetBIm);
+
+ *(fly3P + FlyOffsetA) = fly5r;
+ *(fly3P + FlyOffsetAIm) = fly5i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+
+ fly0P = (fly0P + FlyOffsetB);
+ fly1P = (fly1P + FlyOffsetB);
+ fly2P = (fly2P + FlyOffsetB);
+ fly3P = (fly3P + FlyOffsetB);
+ };
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly3r = *(fly3P);
+ fly3i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly5r = *(fly1P + FlyOffsetA);
+ fly5i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly7r = *(fly3P + FlyOffsetA);
+ fly7i = *(fly3P + FlyOffsetAIm);
+
+ t1r = fly0r - U0r * fly1r;
+ t1r = t1r - U0i * fly1i;
+ t1i = fly0i + U0i * fly1r;
+ t1i = t1i - U0r * fly1i;
+ t0r = scale * fly0r - t1r;
+ t0i = scale * fly0i - t1i;
+
+ fly1r = fly2r - U0r * fly3r;
+ fly1r = fly1r - U0i * fly3i;
+ fly1i = fly2i + U0i * fly3r;
+ fly1i = fly1i - U0r * fly3i;
+ fly2r = scale * fly2r - fly1r;
+ fly2i = scale * fly2i - fly1i;
+
+ fly0r = fly4r - U0r * fly5r;
+ fly0r = fly0r - U0i * fly5i;
+ fly0i = fly4i + U0i * fly5r;
+ fly0i = fly0i - U0r * fly5i;
+ fly4r = scale * fly4r - fly0r;
+ fly4i = scale * fly4i - fly0i;
+
+ fly3r = fly6r - U0r * fly7r;
+ fly3r = fly3r - U0i * fly7i;
+ fly3i = fly6i + U0i * fly7r;
+ fly3i = fly3i - U0r * fly7i;
+ fly6r = scale * fly6r - fly3r;
+ fly6i = scale * fly6i - fly3i;
+
+ fly5r = t0r - U1r * fly2r;
+ fly5r = fly5r - U1i * fly2i;
+ fly5i = t0i + U1i * fly2r;
+ fly5i = fly5i - U1r * fly2i;
+ t0r = scale * t0r - fly5r;
+ t0i = scale * t0i - fly5i;
+
+ fly7r = t1r + U1i * fly1r;
+ fly7r = fly7r - U1r * fly1i;
+ fly7i = t1i + U1r * fly1r;
+ fly7i = fly7i + U1i * fly1i;
+ t1r = scale * t1r - fly7r;
+ t1i = scale * t1i - fly7i;
+
+ fly2r = fly4r - U1r * fly6r;
+ fly2r = fly2r - U1i * fly6i;
+ fly2i = fly4i + U1i * fly6r;
+ fly2i = fly2i - U1r * fly6i;
+ fly4r = scale * fly4r - fly2r;
+ fly4i = scale * fly4i - fly2i;
+
+ fly1r = fly0r + U1i * fly3r;
+ fly1r = fly1r - U1r * fly3i;
+ fly1i = fly0i + U1r * fly3r;
+ fly1i = fly1i + U1i * fly3i;
+ fly0r = scale * fly0r - fly1r;
+ fly0i = scale * fly0i - fly1i;
+
+ U0i = *(U0iP = (U0iP - NsameU4));
+ U0r = *(U0rP = (U0rP + NsameU4));
+ U1r = *(U1rP = (U1rP + NsameU2));
+ U1i = *(U1iP = (U1iP - NsameU2));
+ if(stage&1)
+ U0r = -U0r;
+
+ fly6r = t0r - U2r * fly4r;
+ fly6r = fly6r - U2i * fly4i;
+ fly6i = t0i + U2i * fly4r;
+ fly6i = fly6i - U2r * fly4i;
+ t0r = scale * t0r - fly6r;
+ t0i = scale * t0i - fly6i;
+
+ fly3r = fly5r - U2i * fly2r;
+ fly3r = fly3r + U2r * fly2i;
+ fly3i = fly5i - U2r * fly2r;
+ fly3i = fly3i - U2i * fly2i;
+ fly2r = scale * fly5r - fly3r;
+ fly2i = scale * fly5i - fly3i;
+
+ fly4r = t1r - U3r * fly0r;
+ fly4r = fly4r - U3i * fly0i;
+ fly4i = t1i + U3i * fly0r;
+ fly4i = fly4i - U3r * fly0i;
+ t1r = scale * t1r - fly4r;
+ t1i = scale * t1i - fly4i;
+
+ fly5r = fly7r + U3i * fly1r;
+ fly5r = fly5r - U3r * fly1i;
+ fly5i = fly7i + U3r * fly1r;
+ fly5i = fly5i + U3i * fly1i;
+ fly7r = scale * fly7r - fly5r;
+ fly7i = scale * fly7i - fly5i;
+
+ *(fly0P + FlyOffsetA) = fly6r;
+ *(fly0P + FlyOffsetAIm) = fly6i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+
+ U2r = *(U2rP = (U2rP + NsameU1));
+ U2i = *(U2iP = (U2iP - NsameU1));
+
+ *(fly2P) = fly3r;
+ *(fly2P + 1) = fly3i;
+ *(fly2P + FlyOffsetA) = fly2r;
+ *(fly2P + FlyOffsetAIm) = fly2i;
+ *(fly1P + FlyOffsetA) = fly4r;
+ *(fly1P + FlyOffsetAIm) = fly4i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+
+ U3r = *( U2rP + U3offset);
+ U3i = *( U2iP - U3offset);
+
+ *(fly3P + FlyOffsetA) = fly5r;
+ *(fly3P + FlyOffsetAIm) = fly5i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+
+ IOP = IOP + 2;
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+ };
+ NsameU4 = -NsameU4;
+
+ if(stage&1){
+ LoopN >>= 3;
+ NsameU1 >>= 3;
+ NsameU2 >>= 3;
+ NsameU4 >>= 3;
+ NdiffU <<= 3;
+ Flyinc <<= 3;
+ FlyOffsetA <<= 3;
+ FlyOffsetB <<= 3;
+ FlyOffsetAIm = FlyOffsetA + 1;
+ FlyOffsetBIm = FlyOffsetB + 1;
+ }
+}
+ioptr += 2*Ntbl[M];
+}
+}
+
+void iffts(float *ioptr, long M, long Rows, float *Utbl){
+/* Compute in-place inverse complex fft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = input data array */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = output data array */
+
+long Flyinc;
+long FlyOffsetA;
+long FlyOffsetAIm;
+long FlyOffsetB;
+long FlyOffsetBIm;
+long NsameU1;
+long NsameU2;
+long NsameU4;
+long diffUcnt;
+long LoopCnt;
+
+float scale;
+float fly0r;
+float fly0i;
+float fly1r;
+float fly1i;
+float fly2r;
+float fly2i;
+float fly3r;
+float fly3i;
+float fly4r;
+float fly4i;
+float fly5r;
+float fly5i;
+float fly6r;
+float fly6i;
+float fly7r;
+float fly7i;
+float U0r;
+float U0i;
+float U1r;
+float U1i;
+float U2r;
+float U2i;
+float U3r;
+float U3i;
+float t0r;
+float t0i;
+float t1r;
+float t1i;
+
+float *fly0P;
+float *fly1P;
+float *fly2P;
+float *fly3P;
+float *U0rP;
+float *U0iP;
+float *U1rP;
+float *U1iP;
+float *U2rP;
+float *U2iP;
+float *IOP;
+long U3offset;
+
+long stage;
+long NdiffU;
+long LoopN;
+
+const long BRshift = MAXMROOT - (M>>1);
+const long Nrems2 = Ntbl[M-(M>>1)+1];
+const long Nroot_1_ColInc = (Ntbl[M-1]-Ntbl[M-(M>>1)])*2;
+
+for (;Rows>0;Rows--){
+
+FlyOffsetA = Ntbl[M] * 2/2;
+FlyOffsetAIm = FlyOffsetA + 1;
+FlyOffsetB = FlyOffsetA + 2;
+FlyOffsetBIm = FlyOffsetB + 1;
+
+/* BitrevR2 ** bit reverse and first radix 2 stage ******/
+
+scale = 1./Ntbl[M];
+for (stage = 0; stage < Ntbl[M-(M>>1)]*2; stage += Ntbl[M>>1]*2){
+ for (LoopN = (Ntbl[(M>>1)-1]-1); LoopN >= 0; LoopN--){
+ LoopCnt = (Ntbl[(M>>1)-1]-1);
+ fly0P = ioptr + Nroot_1_ColInc + ((int)BRcnt[LoopN] >> BRshift)*(2*2) + stage;
+ IOP = ioptr + (LoopN<<(M+1)/2) * 2 + stage;
+ fly1P = IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2);
+ fly0r = *(fly0P);
+ fly0i = *(fly0P+1);
+ fly1r = *(fly0P+FlyOffsetA);
+ fly1i = *(fly0P+FlyOffsetAIm);
+ for (; LoopCnt > LoopN;){
+ fly2r = *(fly0P+2);
+ fly2i = *(fly0P+(2+1));
+ fly3r = *(fly0P+FlyOffsetB);
+ fly3i = *(fly0P+FlyOffsetBIm);
+ fly4r = *(fly1P);
+ fly4i = *(fly1P+1);
+ fly5r = *(fly1P+FlyOffsetA);
+ fly5i = *(fly1P+FlyOffsetAIm);
+ fly6r = *(fly1P+2);
+ fly6i = *(fly1P+(2+1));
+ fly7r = *(fly1P+FlyOffsetB);
+ fly7i = *(fly1P+FlyOffsetBIm);
+
+ t0r = fly0r + fly1r;
+ t0i = fly0i + fly1i;
+ fly1r = fly0r - fly1r;
+ fly1i = fly0i - fly1i;
+ t1r = fly2r + fly3r;
+ t1i = fly2i + fly3i;
+ fly3r = fly2r - fly3r;
+ fly3i = fly2i - fly3i;
+ fly0r = fly4r + fly5r;
+ fly0i = fly4i + fly5i;
+ fly5r = fly4r - fly5r;
+ fly5i = fly4i - fly5i;
+ fly2r = fly6r + fly7r;
+ fly2i = fly6i + fly7i;
+ fly7r = fly6r - fly7r;
+ fly7i = fly6i - fly7i;
+
+ *(fly1P) = scale*t0r;
+ *(fly1P+1) = scale*t0i;
+ *(fly1P+2) = scale*fly1r;
+ *(fly1P+(2+1)) = scale*fly1i;
+ *(fly1P+FlyOffsetA) = scale*t1r;
+ *(fly1P+FlyOffsetAIm) = scale*t1i;
+ *(fly1P+FlyOffsetB) = scale*fly3r;
+ *(fly1P+FlyOffsetBIm) = scale*fly3i;
+ *(fly0P) = scale*fly0r;
+ *(fly0P+1) = scale*fly0i;
+ *(fly0P+2) = scale*fly5r;
+ *(fly0P+(2+1)) = scale*fly5i;
+ *(fly0P+FlyOffsetA) = scale*fly2r;
+ *(fly0P+FlyOffsetAIm) = scale*fly2i;
+ *(fly0P+FlyOffsetB) = scale*fly7r;
+ *(fly0P+FlyOffsetBIm) = scale*fly7i;
+
+ fly0P -= Nrems2;
+ fly0r = *(fly0P);
+ fly0i = *(fly0P+1);
+ fly1r = *(fly0P+FlyOffsetA);
+ fly1i = *(fly0P+FlyOffsetAIm);
+ LoopCnt -= 1;
+ fly1P = (IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2));
+ };
+ fly2r = *(fly0P+2);
+ fly2i = *(fly0P+(2+1));
+ fly3r = *(fly0P+FlyOffsetB);
+ fly3i = *(fly0P+FlyOffsetBIm);
+
+ t0r = fly0r + fly1r;
+ t0i = fly0i + fly1i;
+ fly1r = fly0r - fly1r;
+ fly1i = fly0i - fly1i;
+ t1r = fly2r + fly3r;
+ t1i = fly2i + fly3i;
+ fly3r = fly2r - fly3r;
+ fly3i = fly2i - fly3i;
+
+ *(fly0P) = scale*t0r;
+ *(fly0P+1) = scale*t0i;
+ *(fly0P+2) = scale*fly1r;
+ *(fly0P+(2+1)) = scale*fly1i;
+ *(fly0P+FlyOffsetA) = scale*t1r;
+ *(fly0P+FlyOffsetAIm) = scale*t1i;
+ *(fly0P+FlyOffsetB) = scale*fly3r;
+ *(fly0P+FlyOffsetBIm) = scale*fly3i;
+
+ };
+};
+
+/**** FFTC **************/
+
+scale = 2.0;
+
+NdiffU = 2;
+Flyinc = (NdiffU);
+
+NsameU4 = Ntbl[M]/4;
+LoopN = Ntbl[M-3];
+
+stage = ((M-1)/3);
+if ( (M-1-(stage * 3)) != 0 ){
+ FlyOffsetA = Flyinc << 2;
+ FlyOffsetB = FlyOffsetA << 1;
+ FlyOffsetAIm = FlyOffsetA + 1;
+ FlyOffsetBIm = FlyOffsetB + 1;
+ if ( (M-1-(stage * 3)) == 1 ){
+ /* 1 radix 2 stage */
+
+ IOP = ioptr;
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+
+ /* Butterflys */
+ /*
+ t0 - - t0
+ t1 - - t1
+ f2 - 1- f5
+ f1 - -i- f7
+ f4 - - f4
+ f0 - - f0
+ f6 - 1- f2
+ f3 - -i- f1
+ */
+
+ for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){
+ t0r = *(fly0P);
+ t0i = *(fly0P + 1);
+ t1r = *(fly1P);
+ t1i = *(fly1P + 1);
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly1r = *(fly3P);
+ fly1i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly0r = *(fly1P + FlyOffsetA);
+ fly0i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly3r = *(fly3P + FlyOffsetA);
+ fly3i = *(fly3P + FlyOffsetAIm);
+
+ fly5r = t0r - fly2r;
+ fly5i = t0i - fly2i;
+ t0r = t0r + fly2r;
+ t0i = t0i + fly2i;
+
+ fly7r = t1r + fly1i;
+ fly7i = t1i - fly1r;
+ t1r = t1r - fly1i;
+ t1i = t1i + fly1r;
+
+ fly2r = fly4r - fly6r;
+ fly2i = fly4i - fly6i;
+ fly4r = fly4r + fly6r;
+ fly4i = fly4i + fly6i;
+
+ fly1r = fly0r + fly3i;
+ fly1i = fly0i - fly3r;
+ fly0r = fly0r - fly3i;
+ fly0i = fly0i + fly3r;
+
+ *(fly2P) = fly5r;
+ *(fly2P + 1) = fly5i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+ *(fly2P + FlyOffsetA) = fly2r;
+ *(fly2P + FlyOffsetAIm) = fly2i;
+ *(fly0P + FlyOffsetA) = fly4r;
+ *(fly0P + FlyOffsetAIm) = fly4i;
+ *(fly3P + FlyOffsetA) = fly1r;
+ *(fly3P + FlyOffsetAIm) = fly1i;
+ *(fly1P + FlyOffsetA) = fly0r;
+ *(fly1P + FlyOffsetAIm) = fly0i;
+
+ fly0P = (fly0P + FlyOffsetB);
+ fly1P = (fly1P + FlyOffsetB);
+ fly2P = (fly2P + FlyOffsetB);
+ fly3P = (fly3P + FlyOffsetB);
+ };
+
+ NsameU4 >>= 1;
+ LoopN >>= 1;
+ NdiffU <<= 1;
+ Flyinc = Flyinc << 1;
+ }
+ else{
+ /* 1 radix 4 stage */
+ IOP = ioptr;
+
+ U3r = 0.7071067811865475244008443621; /* sqrt(0.5); */
+ U3i = U3r;
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+
+ /* Butterflys */
+ /*
+ t0 - - t0 - - t0
+ t1 - - t1 - - t1
+ f2 - 1- f5 - - f5
+ f1 - -i- f7 - - f7
+ f4 - - f4 - 1- f6
+ f0 - - f0 -U3 - f3
+ f6 - 1- f2 - -i- f4
+ f3 - -i- f1 -U3a- f2
+ */
+
+ for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){
+ t0r = *(fly0P);
+ t0i = *(fly0P + 1);
+ t1r = *(fly1P);
+ t1i = *(fly1P + 1);
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly1r = *(fly3P);
+ fly1i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly0r = *(fly1P + FlyOffsetA);
+ fly0i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly3r = *(fly3P + FlyOffsetA);
+ fly3i = *(fly3P + FlyOffsetAIm);
+
+ fly5r = t0r - fly2r;
+ fly5i = t0i - fly2i;
+ t0r = t0r + fly2r;
+ t0i = t0i + fly2i;
+
+ fly7r = t1r + fly1i;
+ fly7i = t1i - fly1r;
+ t1r = t1r - fly1i;
+ t1i = t1i + fly1r;
+
+ fly2r = fly4r - fly6r;
+ fly2i = fly4i - fly6i;
+ fly4r = fly4r + fly6r;
+ fly4i = fly4i + fly6i;
+
+ fly1r = fly0r + fly3i;
+ fly1i = fly0i - fly3r;
+ fly0r = fly0r - fly3i;
+ fly0i = fly0i + fly3r;
+
+ fly6r = t0r - fly4r;
+ fly6i = t0i - fly4i;
+ t0r = t0r + fly4r;
+ t0i = t0i + fly4i;
+
+ fly3r = fly5r + fly2i;
+ fly3i = fly5i - fly2r;
+ fly5r = fly5r - fly2i;
+ fly5i = fly5i + fly2r;
+
+ fly4r = t1r - U3r * fly0r;
+ fly4r = fly4r + U3i * fly0i;
+ fly4i = t1i - U3i * fly0r;
+ fly4i = fly4i - U3r * fly0i;
+ t1r = scale * t1r - fly4r;
+ t1i = scale * t1i - fly4i;
+
+ fly2r = fly7r + U3i * fly1r;
+ fly2r = fly2r + U3r * fly1i;
+ fly2i = fly7i - U3r * fly1r;
+ fly2i = fly2i + U3i * fly1i;
+ fly7r = scale * fly7r - fly2r;
+ fly7i = scale * fly7i - fly2i;
+
+ *(fly0P + FlyOffsetA) = fly6r;
+ *(fly0P + FlyOffsetAIm) = fly6i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+ *(fly2P + FlyOffsetA) = fly3r;
+ *(fly2P + FlyOffsetAIm) = fly3i;
+ *(fly2P) = fly5r;
+ *(fly2P + 1) = fly5i;
+ *(fly1P + FlyOffsetA) = fly4r;
+ *(fly1P + FlyOffsetAIm) = fly4i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+ *(fly3P + FlyOffsetA) = fly2r;
+ *(fly3P + FlyOffsetAIm) = fly2i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+
+ fly0P = (fly0P + FlyOffsetB);
+ fly1P = (fly1P + FlyOffsetB);
+ fly2P = (fly2P + FlyOffsetB);
+ fly3P = (fly3P + FlyOffsetB);
+
+ };
+
+ NsameU4 >>= 2;
+ LoopN >>= 2;
+ NdiffU <<= 2;
+ Flyinc = Flyinc << 2;
+ };
+};
+
+NsameU2 = NsameU4 >> 1;
+NsameU1 = NsameU2 >> 1;
+Flyinc <<= 1;
+FlyOffsetA = Flyinc << 2;
+FlyOffsetB = FlyOffsetA << 1;
+FlyOffsetAIm = FlyOffsetA + 1;
+FlyOffsetBIm = FlyOffsetB + 1;
+LoopN >>= 1;
+
+/* ****** RADIX 8 Stages */
+for (stage = stage<<1; stage > 0 ; stage--){
+
+ /* an fft stage is done in two parts to ease use of the single quadrant cos table */
+
+/* fftcalc1(iobuf, Utbl, N, NdiffU, LoopN); */
+ if(!(stage&1)){
+ U0rP = &Utbl[0];
+ U0iP = &Utbl[Ntbl[M-2]];
+ U1rP = U0rP;
+ U1iP = U0iP;
+ U2rP = U0rP;
+ U2iP = U0iP;
+ U3offset = (Ntbl[M]) / 8;
+
+ IOP = ioptr;
+
+ U0r = *U0rP,
+ U0i = *U0iP;
+ U1r = *U1rP,
+ U1i = *U1iP;
+ U2r = *U2rP,
+ U2i = *U2iP;
+ U3r = *( U2rP + U3offset);
+ U3i = *( U2iP - U3offset);
+ }
+
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+
+ for (diffUcnt = (NdiffU)>>1; diffUcnt > 0; diffUcnt--){
+
+ /* Butterflys */
+ /*
+ f0 - - t0 - - t0 - - t0
+ f1 -U0 - t1 - - t1 - - t1
+ f2 - - f2 -U1 - f5 - - f3
+ f3 -U0 - f1 -U1a- f7 - - f7
+ f4 - - f4 - - f4 -U2 - f6
+ f5 -U0 - f0 - - f0 -U3 - f4
+ f6 - - f6 -U1 - f2 -U2a- f2
+ f7 -U0 - f3 -U1a- f1 -U3a- f5
+ */
+
+ fly0r = *(IOP);
+ fly0i = *(IOP+1);
+ fly1r = *(fly1P);
+ fly1i = *(fly1P+1);
+
+ for (LoopCnt = LoopN-1; LoopCnt > 0 ; LoopCnt--){
+
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly3r = *(fly3P);
+ fly3i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly5r = *(fly1P + FlyOffsetA);
+ fly5i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly7r = *(fly3P + FlyOffsetA);
+ fly7i = *(fly3P + FlyOffsetAIm);
+
+ t1r = fly0r - U0r * fly1r;
+ t1r = t1r + U0i * fly1i;
+ t1i = fly0i - U0i * fly1r;
+ t1i = t1i - U0r * fly1i;
+ t0r = scale * fly0r - t1r;
+ t0i = scale * fly0i - t1i;
+
+ fly1r = fly2r - U0r * fly3r;
+ fly1r = fly1r + U0i * fly3i;
+ fly1i = fly2i - U0i * fly3r;
+ fly1i = fly1i - U0r * fly3i;
+ fly2r = scale * fly2r - fly1r;
+ fly2i = scale * fly2i - fly1i;
+
+ fly0r = fly4r - U0r * fly5r;
+ fly0r = fly0r + U0i * fly5i;
+ fly0i = fly4i - U0i * fly5r;
+ fly0i = fly0i - U0r * fly5i;
+ fly4r = scale * fly4r - fly0r;
+ fly4i = scale * fly4i - fly0i;
+
+ fly3r = fly6r - U0r * fly7r;
+ fly3r = fly3r + U0i * fly7i;
+ fly3i = fly6i - U0i * fly7r;
+ fly3i = fly3i - U0r * fly7i;
+ fly6r = scale * fly6r - fly3r;
+ fly6i = scale * fly6i - fly3i;
+
+
+ fly5r = t0r - U1r * fly2r;
+ fly5r = fly5r + U1i * fly2i;
+ fly5i = t0i - U1i * fly2r;
+ fly5i = fly5i - U1r * fly2i;
+ t0r = scale * t0r - fly5r;
+ t0i = scale * t0i - fly5i;
+
+ fly7r = t1r + U1i * fly1r;
+ fly7r = fly7r + U1r * fly1i;
+ fly7i = t1i - U1r * fly1r;
+ fly7i = fly7i + U1i * fly1i;
+ t1r = scale * t1r - fly7r;
+ t1i = scale * t1i - fly7i;
+
+ fly2r = fly4r - U1r * fly6r;
+ fly2r = fly2r + U1i * fly6i;
+ fly2i = fly4i - U1i * fly6r;
+ fly2i = fly2i - U1r * fly6i;
+ fly4r = scale * fly4r - fly2r;
+ fly4i = scale * fly4i - fly2i;
+
+ fly1r = fly0r + U1i * fly3r;
+ fly1r = fly1r + U1r * fly3i;
+ fly1i = fly0i - U1r * fly3r;
+ fly1i = fly1i + U1i * fly3i;
+ fly0r = scale * fly0r - fly1r;
+ fly0i = scale * fly0i - fly1i;
+
+ fly6r = t0r - U2r * fly4r;
+ fly6r = fly6r + U2i * fly4i;
+ fly6i = t0i - U2i * fly4r;
+ fly6i = fly6i - U2r * fly4i;
+ t0r = scale * t0r - fly6r;
+ t0i = scale * t0i - fly6i;
+
+ fly3r = fly5r - U2i * fly2r;
+ fly3r = fly3r - U2r * fly2i;
+ fly3i = fly5i + U2r * fly2r;
+ fly3i = fly3i - U2i * fly2i;
+ fly2r = scale * fly5r - fly3r;
+ fly2i = scale * fly5i - fly3i;
+
+ fly4r = t1r - U3r * fly0r;
+ fly4r = fly4r + U3i * fly0i;
+ fly4i = t1i - U3i * fly0r;
+ fly4i = fly4i - U3r * fly0i;
+ t1r = scale * t1r - fly4r;
+ t1i = scale * t1i - fly4i;
+
+ fly5r = fly7r + U3i * fly1r;
+ fly5r = fly5r + U3r * fly1i;
+ fly5i = fly7i - U3r * fly1r;
+ fly5i = fly5i + U3i * fly1i;
+ fly7r = scale * fly7r - fly5r;
+ fly7i = scale * fly7i - fly5i;
+
+ *(fly0P + FlyOffsetA) = fly6r;
+ *(fly0P + FlyOffsetAIm) = fly6i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+ *(fly2P) = fly3r;
+ *(fly2P + 1) = fly3i;
+ *(fly2P + FlyOffsetA) = fly2r;
+ *(fly2P + FlyOffsetAIm) = fly2i;
+
+ fly0r = *(fly0P + FlyOffsetB);
+ fly0i = *(fly0P + FlyOffsetBIm);
+
+ *(fly1P + FlyOffsetA) = fly4r;
+ *(fly1P + FlyOffsetAIm) = fly4i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+
+ fly1r = *(fly1P + FlyOffsetB);
+ fly1i = *(fly1P + FlyOffsetBIm);
+
+ *(fly3P + FlyOffsetA) = fly5r;
+ *(fly3P + FlyOffsetAIm) = fly5i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+
+ fly0P = (fly0P + FlyOffsetB);
+ fly1P = (fly1P + FlyOffsetB);
+ fly2P = (fly2P + FlyOffsetB);
+ fly3P = (fly3P + FlyOffsetB);
+
+ };
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly3r = *(fly3P);
+ fly3i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly5r = *(fly1P + FlyOffsetA);
+ fly5i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly7r = *(fly3P + FlyOffsetA);
+ fly7i = *(fly3P + FlyOffsetAIm);
+
+ t1r = fly0r - U0r * fly1r;
+ t1r = t1r + U0i * fly1i;
+ t1i = fly0i - U0i * fly1r;
+ t1i = t1i - U0r * fly1i;
+ t0r = scale * fly0r - t1r;
+ t0i = scale * fly0i - t1i;
+
+ fly1r = fly2r - U0r * fly3r;
+ fly1r = fly1r + U0i * fly3i;
+ fly1i = fly2i - U0i * fly3r;
+ fly1i = fly1i - U0r * fly3i;
+ fly2r = scale * fly2r - fly1r;
+ fly2i = scale * fly2i - fly1i;
+
+ fly0r = fly4r - U0r * fly5r;
+ fly0r = fly0r + U0i * fly5i;
+ fly0i = fly4i - U0i * fly5r;
+ fly0i = fly0i - U0r * fly5i;
+ fly4r = scale * fly4r - fly0r;
+ fly4i = scale * fly4i - fly0i;
+
+ fly3r = fly6r - U0r * fly7r;
+ fly3r = fly3r + U0i * fly7i;
+ fly3i = fly6i - U0i * fly7r;
+ fly3i = fly3i - U0r * fly7i;
+ fly6r = scale * fly6r - fly3r;
+ fly6i = scale * fly6i - fly3i;
+
+ fly5r = t0r - U1r * fly2r;
+ fly5r = fly5r + U1i * fly2i;
+ fly5i = t0i - U1i * fly2r;
+ fly5i = fly5i - U1r * fly2i;
+ t0r = scale * t0r - fly5r;
+ t0i = scale * t0i - fly5i;
+
+ fly7r = t1r + U1i * fly1r;
+ fly7r = fly7r + U1r * fly1i;
+ fly7i = t1i - U1r * fly1r;
+ fly7i = fly7i + U1i * fly1i;
+ t1r = scale * t1r - fly7r;
+ t1i = scale * t1i - fly7i;
+
+ fly2r = fly4r - U1r * fly6r;
+ fly2r = fly2r + U1i * fly6i;
+ fly2i = fly4i - U1i * fly6r;
+ fly2i = fly2i - U1r * fly6i;
+ fly4r = scale * fly4r - fly2r;
+ fly4i = scale * fly4i - fly2i;
+
+ fly1r = fly0r + U1i * fly3r;
+ fly1r = fly1r + U1r * fly3i;
+ fly1i = fly0i - U1r * fly3r;
+ fly1i = fly1i + U1i * fly3i;
+ fly0r = scale * fly0r - fly1r;
+ fly0i = scale * fly0i - fly1i;
+
+ U0i = *(U0iP = (U0iP - NsameU4));
+ U0r = *(U0rP = (U0rP + NsameU4));
+ U1r = *(U1rP = (U1rP + NsameU2));
+ U1i = *(U1iP = (U1iP - NsameU2));
+ if(stage&1)
+ U0r = - U0r;
+
+ fly6r = t0r - U2r * fly4r;
+ fly6r = fly6r + U2i * fly4i;
+ fly6i = t0i - U2i * fly4r;
+ fly6i = fly6i - U2r * fly4i;
+ t0r = scale * t0r - fly6r;
+ t0i = scale * t0i - fly6i;
+
+ fly3r = fly5r - U2i * fly2r;
+ fly3r = fly3r - U2r * fly2i;
+ fly3i = fly5i + U2r * fly2r;
+ fly3i = fly3i - U2i * fly2i;
+ fly2r = scale * fly5r - fly3r;
+ fly2i = scale * fly5i - fly3i;
+
+ fly4r = t1r - U3r * fly0r;
+ fly4r = fly4r + U3i * fly0i;
+ fly4i = t1i - U3i * fly0r;
+ fly4i = fly4i - U3r * fly0i;
+ t1r = scale * t1r - fly4r;
+ t1i = scale * t1i - fly4i;
+
+ fly5r = fly7r + U3i * fly1r;
+ fly5r = fly5r + U3r * fly1i;
+ fly5i = fly7i - U3r * fly1r;
+ fly5i = fly5i + U3i * fly1i;
+ fly7r = scale * fly7r - fly5r;
+ fly7i = scale * fly7i - fly5i;
+
+ *(fly0P + FlyOffsetA) = fly6r;
+ *(fly0P + FlyOffsetAIm) = fly6i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+
+ U2r = *(U2rP = (U2rP + NsameU1));
+ U2i = *(U2iP = (U2iP - NsameU1));
+
+ *(fly2P) = fly3r;
+ *(fly2P + 1) = fly3i;
+ *(fly2P + FlyOffsetA) = fly2r;
+ *(fly2P + FlyOffsetAIm) = fly2i;
+ *(fly1P + FlyOffsetA) = fly4r;
+ *(fly1P + FlyOffsetAIm) = fly4i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+
+ U3r = *( U2rP + U3offset);
+ U3i = *( U2iP - U3offset);
+
+ *(fly3P + FlyOffsetA) = fly5r;
+ *(fly3P + FlyOffsetAIm) = fly5i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+
+ IOP = IOP + 2;
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+ };
+ NsameU4 = -NsameU4;
+
+ if(stage&1){
+ LoopN >>= 3;
+ NsameU1 >>= 3;
+ NsameU2 >>= 3;
+ NsameU4 >>= 3;
+ NdiffU <<= 3;
+ Flyinc = Flyinc << 3;
+ FlyOffsetA <<= 3;
+ FlyOffsetB <<= 3;
+ FlyOffsetAIm = FlyOffsetA + 1;
+ FlyOffsetBIm = FlyOffsetB + 1;
+ }
+}
+ioptr += 2*Ntbl[M];
+}
+}
+
+/* rffts */
+/* compute multiple real input FFTs on 'Rows' consecutively stored arrays */
+/* ioptr = pointer to the data in and out */
+/* M = log2 of fft size */
+/* Rows = number of FFTs to compute */
+/* Utbl = Pointer to cosine table */
+
+void rffts(float *ioptr, long M, long Rows, float *Utbl){
+/* Compute in-place real fft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = real input data array */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = output data array in the following order */
+/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */
+
+long Flyinc;
+long FlyOffsetA;
+long FlyOffsetAIm;
+long FlyOffsetB;
+long FlyOffsetBIm;
+long NsameU1;
+long NsameU2;
+long NsameU4;
+long diffUcnt;
+long LoopCnt;
+float scale;
+float fly0r;
+float fly0i;
+float fly1r;
+float fly1i;
+float fly2r;
+float fly2i;
+float fly3r;
+float fly3i;
+float fly4r;
+float fly4i;
+float fly5r;
+float fly5i;
+float fly6r;
+float fly6i;
+float fly7r;
+float fly7i;
+float U0r;
+float U0i;
+float U1r;
+float U1i;
+float U2r;
+float U2i;
+float U3r;
+float U3i;
+float t0r;
+float t0i;
+float t1r;
+float t1i;
+
+float *fly0P;
+float *fly1P;
+float *fly2P;
+float *fly3P;
+
+float *U0rP;
+float *U0iP;
+float *U1rP;
+float *U1iP;
+float *U2rP;
+float *U2iP;
+float *IOP;
+long U3offset;
+
+long stage;
+long NdiffU;
+long LoopN;
+
+const long BRshift = MAXMROOT - ((M-1)>>1); /* for RFFT */
+const long Nrems2 = Ntbl[(M-1)-((M-1)>>1)+1]; /* for RFFT */
+const long Nroot_1_ColInc = (Ntbl[(M-1)-1]-Ntbl[(M-1)-((M-1)>>1)])*2; /* for RFFT */
+
+for (;Rows>0;Rows--){
+
+M=M-1; /* for RFFT */
+
+FlyOffsetA = Ntbl[M] * 2/2;
+FlyOffsetAIm = FlyOffsetA + 1;
+FlyOffsetB = FlyOffsetA + 2;
+FlyOffsetBIm = FlyOffsetB + 1;
+
+/* BitrevR2 ** bit reverse shuffle and first radix 2 stage ******/
+
+scale = 0.5;
+for (stage = 0; stage < Ntbl[M-(M>>1)]*2; stage += Ntbl[M>>1]*2){
+ for (LoopN = (Ntbl[(M>>1)-1]-1); LoopN >= 0; LoopN--){
+ LoopCnt = (Ntbl[(M>>1)-1]-1);
+ fly0P = ioptr + Nroot_1_ColInc + ((int)BRcnt[LoopN] >> BRshift)*(2*2) + stage;
+ IOP = ioptr + (LoopN<<(M+1)/2) * 2 + stage;
+ fly1P = IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2);
+ fly0r = *fly0P;
+ fly0i = *(fly0P+1);
+ fly1r = *(fly0P+FlyOffsetA);
+ fly1i = *(fly0P+FlyOffsetAIm);
+ for (; LoopCnt > LoopN;){
+ fly2r = *(fly0P+2);
+ fly2i = *(fly0P+(2+1));
+ fly3r = *(fly0P+FlyOffsetB);
+ fly3i = *(fly0P+FlyOffsetBIm);
+ fly4r = *fly1P;
+ fly4i = *(fly1P+1);
+ fly5r = *(fly1P+FlyOffsetA);
+ fly5i = *(fly1P+FlyOffsetAIm);
+ fly6r = *(fly1P+2);
+ fly6i = *(fly1P+(2+1));
+ fly7r = *(fly1P+FlyOffsetB);
+ fly7i = *(fly1P+FlyOffsetBIm);
+
+ t0r = fly0r + fly1r;
+ t0i = fly0i + fly1i;
+ fly1r = fly0r - fly1r;
+ fly1i = fly0i - fly1i;
+ t1r = fly2r + fly3r;
+ t1i = fly2i + fly3i;
+ fly3r = fly2r - fly3r;
+ fly3i = fly2i - fly3i;
+ fly0r = fly4r + fly5r;
+ fly0i = fly4i + fly5i;
+ fly5r = fly4r - fly5r;
+ fly5i = fly4i - fly5i;
+ fly2r = fly6r + fly7r;
+ fly2i = fly6i + fly7i;
+ fly7r = fly6r - fly7r;
+ fly7i = fly6i - fly7i;
+
+ *fly1P = scale*t0r;
+ *(fly1P+1) = scale*t0i;
+ *(fly1P+2) = scale*fly1r;
+ *(fly1P+(2+1)) = scale*fly1i;
+ *(fly1P+FlyOffsetA) = scale*t1r;
+ *(fly1P+FlyOffsetAIm) = scale*t1i;
+ *(fly1P+FlyOffsetB) = scale*fly3r;
+ *(fly1P+FlyOffsetBIm) = scale*fly3i;
+ *fly0P = scale*fly0r;
+ *(fly0P+1) = scale*fly0i;
+ *(fly0P+2) = scale*fly5r;
+ *(fly0P+(2+1)) = scale*fly5i;
+ *(fly0P+FlyOffsetA) = scale*fly2r;
+ *(fly0P+FlyOffsetAIm) = scale*fly2i;
+ *(fly0P+FlyOffsetB) = scale*fly7r;
+ *(fly0P+FlyOffsetBIm) = scale*fly7i;
+
+ fly0P -= Nrems2;
+ fly0r = *fly0P;
+ fly0i = *(fly0P+1);
+ fly1r = *(fly0P+FlyOffsetA);
+ fly1i = *(fly0P+FlyOffsetAIm);
+ LoopCnt -= 1;
+ fly1P = (IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2));
+ };
+ fly2r = *(fly0P+2);
+ fly2i = *(fly0P+(2+1));
+ fly3r = *(fly0P+FlyOffsetB);
+ fly3i = *(fly0P+FlyOffsetBIm);
+
+ t0r = fly0r + fly1r;
+ t0i = fly0i + fly1i;
+ fly1r = fly0r - fly1r;
+ fly1i = fly0i - fly1i;
+ t1r = fly2r + fly3r;
+ t1i = fly2i + fly3i;
+ fly3r = fly2r - fly3r;
+ fly3i = fly2i - fly3i;
+
+ *fly0P = scale*t0r;
+ *(fly0P+1) = scale*t0i;
+ *(fly0P+2) = scale*fly1r;
+ *(fly0P+(2+1)) = scale*fly1i;
+ *(fly0P+FlyOffsetA) = scale*t1r;
+ *(fly0P+FlyOffsetAIm) = scale*t1i;
+ *(fly0P+FlyOffsetB) = scale*fly3r;
+ *(fly0P+FlyOffsetBIm) = scale*fly3i;
+
+ };
+};
+
+
+
+/**** FFTC **************/
+
+scale = 2.0;
+
+NdiffU = 2;
+Flyinc = (NdiffU);
+
+NsameU4 = Ntbl[M+1]/4; /* for RFFT */
+LoopN = Ntbl[M-3];
+
+stage = ((M-1)/3);
+if ( (M-1-(stage * 3)) != 0 ){
+ FlyOffsetA = Flyinc << 2;
+ FlyOffsetB = FlyOffsetA << 1;
+ FlyOffsetAIm = FlyOffsetA + 1;
+ FlyOffsetBIm = FlyOffsetB + 1;
+ if ( (M-1-(stage * 3)) == 1 ){
+ /* 1 radix 2 stage */
+
+ IOP = ioptr;
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+
+ /* Butterflys */
+ /*
+ t0 - - t0
+ t1 - - t1
+ f2 - 1- f5
+ f1 - -i- f7
+ f4 - - f4
+ f0 - - f0
+ f6 - 1- f2
+ f3 - -i- f1
+ */
+
+ for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){
+ t0r = *(fly0P);
+ t0i = *(fly0P + 1);
+ t1r = *(fly1P);
+ t1i = *(fly1P + 1);
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly1r = *(fly3P);
+ fly1i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly0r = *(fly1P + FlyOffsetA);
+ fly0i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly3r = *(fly3P + FlyOffsetA);
+ fly3i = *(fly3P + FlyOffsetAIm);
+
+ fly5r = t0r - fly2r;
+ fly5i = t0i - fly2i;
+ t0r = t0r + fly2r;
+ t0i = t0i + fly2i;
+
+ fly7r = t1r - fly1i;
+ fly7i = t1i + fly1r;
+ t1r = t1r + fly1i;
+ t1i = t1i - fly1r;
+
+ fly2r = fly4r - fly6r;
+ fly2i = fly4i - fly6i;
+ fly4r = fly4r + fly6r;
+ fly4i = fly4i + fly6i;
+
+ fly1r = fly0r - fly3i;
+ fly1i = fly0i + fly3r;
+ fly0r = fly0r + fly3i;
+ fly0i = fly0i - fly3r;
+
+ *(fly2P) = fly5r;
+ *(fly2P + 1) = fly5i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+ *(fly2P + FlyOffsetA) = fly2r;
+ *(fly2P + FlyOffsetAIm) = fly2i;
+ *(fly0P + FlyOffsetA) = fly4r;
+ *(fly0P + FlyOffsetAIm) = fly4i;
+ *(fly3P + FlyOffsetA) = fly1r;
+ *(fly3P + FlyOffsetAIm) = fly1i;
+ *(fly1P + FlyOffsetA) = fly0r;
+ *(fly1P + FlyOffsetAIm) = fly0i;
+
+ fly0P = (fly0P + FlyOffsetB);
+ fly1P = (fly1P + FlyOffsetB);
+ fly2P = (fly2P + FlyOffsetB);
+ fly3P = (fly3P + FlyOffsetB);
+ };
+
+ NsameU4 >>= 1;
+ LoopN >>= 1;
+ NdiffU <<= 1;
+ Flyinc = Flyinc << 1;
+ }
+ else{
+ /* 1 radix 4 stage */
+ IOP = ioptr;
+
+ U3r = 0.7071067811865475244008443621; /* sqrt(0.5); */
+ U3i = U3r;
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+
+ /* Butterflys */
+ /*
+ t0 - - t0 - - t0
+ t1 - - t1 - - t1
+ f2 - 1- f5 - - f5
+ f1 - -i- f7 - - f7
+ f4 - - f4 - 1- f6
+ f0 - - f0 -U3 - f3
+ f6 - 1- f2 - -i- f4
+ f3 - -i- f1 -U3a- f2
+ */
+
+ for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){
+ t0r = *(fly0P);
+ t0i = *(fly0P + 1);
+ t1r = *(fly1P);
+ t1i = *(fly1P + 1);
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly1r = *(fly3P);
+ fly1i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly0r = *(fly1P + FlyOffsetA);
+ fly0i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly3r = *(fly3P + FlyOffsetA);
+ fly3i = *(fly3P + FlyOffsetAIm);
+
+ fly5r = t0r - fly2r;
+ fly5i = t0i - fly2i;
+ t0r = t0r + fly2r;
+ t0i = t0i + fly2i;
+
+ fly7r = t1r - fly1i;
+ fly7i = t1i + fly1r;
+ t1r = t1r + fly1i;
+ t1i = t1i - fly1r;
+
+ fly2r = fly4r - fly6r;
+ fly2i = fly4i - fly6i;
+ fly4r = fly4r + fly6r;
+ fly4i = fly4i + fly6i;
+
+ fly1r = fly0r - fly3i;
+ fly1i = fly0i + fly3r;
+ fly0r = fly0r + fly3i;
+ fly0i = fly0i - fly3r;
+
+ fly6r = t0r - fly4r;
+ fly6i = t0i - fly4i;
+ t0r = t0r + fly4r;
+ t0i = t0i + fly4i;
+
+ fly3r = fly5r - fly2i;
+ fly3i = fly5i + fly2r;
+ fly5r = fly5r + fly2i;
+ fly5i = fly5i - fly2r;
+
+ fly4r = t1r - U3r * fly0r;
+ fly4r = fly4r - U3i * fly0i;
+ fly4i = t1i + U3i * fly0r;
+ fly4i = fly4i - U3r * fly0i;
+ t1r = scale * t1r - fly4r;
+ t1i = scale * t1i - fly4i;
+
+ fly2r = fly7r + U3i * fly1r;
+ fly2r = fly2r - U3r * fly1i;
+ fly2i = fly7i + U3r * fly1r;
+ fly2i = fly2i + U3i * fly1i;
+ fly7r = scale * fly7r - fly2r;
+ fly7i = scale * fly7i - fly2i;
+
+ *(fly0P + FlyOffsetA) = fly6r;
+ *(fly0P + FlyOffsetAIm) = fly6i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+ *(fly2P + FlyOffsetA) = fly3r;
+ *(fly2P + FlyOffsetAIm) = fly3i;
+ *(fly2P) = fly5r;
+ *(fly2P + 1) = fly5i;
+ *(fly1P + FlyOffsetA) = fly4r;
+ *(fly1P + FlyOffsetAIm) = fly4i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+ *(fly3P + FlyOffsetA) = fly2r;
+ *(fly3P + FlyOffsetAIm) = fly2i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+
+ fly0P = (fly0P + FlyOffsetB);
+ fly1P = (fly1P + FlyOffsetB);
+ fly2P = (fly2P + FlyOffsetB);
+ fly3P = (fly3P + FlyOffsetB);
+
+ };
+
+ NsameU4 >>= 2;
+ LoopN >>= 2;
+ NdiffU <<= 2;
+ Flyinc = Flyinc << 2;
+ };
+};
+
+NsameU2 = NsameU4 >> 1;
+NsameU1 = NsameU2 >> 1;
+Flyinc <<= 1;
+FlyOffsetA = Flyinc << 2;
+FlyOffsetB = FlyOffsetA << 1;
+FlyOffsetAIm = FlyOffsetA + 1;
+FlyOffsetBIm = FlyOffsetB + 1;
+LoopN >>= 1;
+
+/* ****** RADIX 8 Stages */
+for (stage = stage<<1; stage > 0 ; stage--){
+
+ /* an fft stage is done in two parts to ease use of the single quadrant cos table */
+
+/* fftcalc1(iobuf, Utbl, N, NdiffU, LoopN); */
+ if(!(stage&1)){
+ U0rP = &Utbl[0];
+ U0iP = &Utbl[Ntbl[M-1]]; /* for RFFT */
+ U1rP = U0rP;
+ U1iP = U0iP;
+ U2rP = U0rP;
+ U2iP = U0iP;
+ U3offset = (Ntbl[M+1]) / 8; /* for RFFT */
+
+ IOP = ioptr;
+
+ U0r = *U0rP,
+ U0i = *U0iP;
+ U1r = *U1rP,
+ U1i = *U1iP;
+ U2r = *U2rP,
+ U2i = *U2iP;
+ U3r = *( U2rP + U3offset);
+ U3i = *( U2iP - U3offset);
+ }
+
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+
+ for (diffUcnt = (NdiffU)>>1; diffUcnt > 0; diffUcnt--){
+
+ /* Butterflys */
+ /*
+ f0 - - t0 - - t0 - - t0
+ f1 -U0 - t1 - - t1 - - t1
+ f2 - - f2 -U1 - f5 - - f3
+ f3 -U0 - f1 -U1a- f7 - - f7
+ f4 - - f4 - - f4 -U2 - f6
+ f5 -U0 - f0 - - f0 -U3 - f4
+ f6 - - f6 -U1 - f2 -U2a- f2
+ f7 -U0 - f3 -U1a- f1 -U3a- f5
+ */
+
+ fly0r = *(IOP);
+ fly0i = *(IOP+1);
+ fly1r = *(fly1P);
+ fly1i = *(fly1P+1);
+
+ for (LoopCnt = LoopN-1; LoopCnt > 0 ; LoopCnt--){
+
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly3r = *(fly3P);
+ fly3i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly5r = *(fly1P + FlyOffsetA);
+ fly5i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly7r = *(fly3P + FlyOffsetA);
+ fly7i = *(fly3P + FlyOffsetAIm);
+
+ t1r = fly0r - U0r * fly1r;
+ t1r = t1r - U0i * fly1i;
+ t1i = fly0i + U0i * fly1r;
+ t1i = t1i - U0r * fly1i;
+ t0r = scale * fly0r - t1r;
+ t0i = scale * fly0i - t1i;
+
+ fly1r = fly2r - U0r * fly3r;
+ fly1r = fly1r - U0i * fly3i;
+ fly1i = fly2i + U0i * fly3r;
+ fly1i = fly1i - U0r * fly3i;
+ fly2r = scale * fly2r - fly1r;
+ fly2i = scale * fly2i - fly1i;
+
+ fly0r = fly4r - U0r * fly5r;
+ fly0r = fly0r - U0i * fly5i;
+ fly0i = fly4i + U0i * fly5r;
+ fly0i = fly0i - U0r * fly5i;
+ fly4r = scale * fly4r - fly0r;
+ fly4i = scale * fly4i - fly0i;
+
+ fly3r = fly6r - U0r * fly7r;
+ fly3r = fly3r - U0i * fly7i;
+ fly3i = fly6i + U0i * fly7r;
+ fly3i = fly3i - U0r * fly7i;
+ fly6r = scale * fly6r - fly3r;
+ fly6i = scale * fly6i - fly3i;
+
+
+ fly5r = t0r - U1r * fly2r;
+ fly5r = fly5r - U1i * fly2i;
+ fly5i = t0i + U1i * fly2r;
+ fly5i = fly5i - U1r * fly2i;
+ t0r = scale * t0r - fly5r;
+ t0i = scale * t0i - fly5i;
+
+ fly7r = t1r + U1i * fly1r;
+ fly7r = fly7r - U1r * fly1i;
+ fly7i = t1i + U1r * fly1r;
+ fly7i = fly7i + U1i * fly1i;
+ t1r = scale * t1r - fly7r;
+ t1i = scale * t1i - fly7i;
+
+ fly2r = fly4r - U1r * fly6r;
+ fly2r = fly2r - U1i * fly6i;
+ fly2i = fly4i + U1i * fly6r;
+ fly2i = fly2i - U1r * fly6i;
+ fly4r = scale * fly4r - fly2r;
+ fly4i = scale * fly4i - fly2i;
+
+ fly1r = fly0r + U1i * fly3r;
+ fly1r = fly1r - U1r * fly3i;
+ fly1i = fly0i + U1r * fly3r;
+ fly1i = fly1i + U1i * fly3i;
+ fly0r = scale * fly0r - fly1r;
+ fly0i = scale * fly0i - fly1i;
+
+ fly6r = t0r - U2r * fly4r;
+ fly6r = fly6r - U2i * fly4i;
+ fly6i = t0i + U2i * fly4r;
+ fly6i = fly6i - U2r * fly4i;
+ t0r = scale * t0r - fly6r;
+ t0i = scale * t0i - fly6i;
+
+ fly3r = fly5r - U2i * fly2r;
+ fly3r = fly3r + U2r * fly2i;
+ fly3i = fly5i - U2r * fly2r;
+ fly3i = fly3i - U2i * fly2i;
+ fly2r = scale * fly5r - fly3r;
+ fly2i = scale * fly5i - fly3i;
+
+ fly4r = t1r - U3r * fly0r;
+ fly4r = fly4r - U3i * fly0i;
+ fly4i = t1i + U3i * fly0r;
+ fly4i = fly4i - U3r * fly0i;
+ t1r = scale * t1r - fly4r;
+ t1i = scale * t1i - fly4i;
+
+ fly5r = fly7r + U3i * fly1r;
+ fly5r = fly5r - U3r * fly1i;
+ fly5i = fly7i + U3r * fly1r;
+ fly5i = fly5i + U3i * fly1i;
+ fly7r = scale * fly7r - fly5r;
+ fly7i = scale * fly7i - fly5i;
+
+ *(fly0P + FlyOffsetA) = fly6r;
+ *(fly0P + FlyOffsetAIm) = fly6i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+ *(fly2P) = fly3r;
+ *(fly2P + 1) = fly3i;
+ *(fly2P + FlyOffsetA) = fly2r;
+ *(fly2P + FlyOffsetAIm) = fly2i;
+
+ fly0r = *(fly0P + FlyOffsetB);
+ fly0i = *(fly0P + FlyOffsetBIm);
+
+ *(fly1P + FlyOffsetA) = fly4r;
+ *(fly1P + FlyOffsetAIm) = fly4i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+
+ fly1r = *(fly1P + FlyOffsetB);
+ fly1i = *(fly1P + FlyOffsetBIm);
+
+ *(fly3P + FlyOffsetA) = fly5r;
+ *(fly3P + FlyOffsetAIm) = fly5i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+
+ fly0P = (fly0P + FlyOffsetB);
+ fly1P = (fly1P + FlyOffsetB);
+ fly2P = (fly2P + FlyOffsetB);
+ fly3P = (fly3P + FlyOffsetB);
+ };
+
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly3r = *(fly3P);
+ fly3i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly5r = *(fly1P + FlyOffsetA);
+ fly5i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly7r = *(fly3P + FlyOffsetA);
+ fly7i = *(fly3P + FlyOffsetAIm);
+
+ t1r = fly0r - U0r * fly1r;
+ t1r = t1r - U0i * fly1i;
+ t1i = fly0i + U0i * fly1r;
+ t1i = t1i - U0r * fly1i;
+ t0r = scale * fly0r - t1r;
+ t0i = scale * fly0i - t1i;
+
+ fly1r = fly2r - U0r * fly3r;
+ fly1r = fly1r - U0i * fly3i;
+ fly1i = fly2i + U0i * fly3r;
+ fly1i = fly1i - U0r * fly3i;
+ fly2r = scale * fly2r - fly1r;
+ fly2i = scale * fly2i - fly1i;
+
+ fly0r = fly4r - U0r * fly5r;
+ fly0r = fly0r - U0i * fly5i;
+ fly0i = fly4i + U0i * fly5r;
+ fly0i = fly0i - U0r * fly5i;
+ fly4r = scale * fly4r - fly0r;
+ fly4i = scale * fly4i - fly0i;
+
+ fly3r = fly6r - U0r * fly7r;
+ fly3r = fly3r - U0i * fly7i;
+ fly3i = fly6i + U0i * fly7r;
+ fly3i = fly3i - U0r * fly7i;
+ fly6r = scale * fly6r - fly3r;
+ fly6i = scale * fly6i - fly3i;
+
+
+ fly5r = t0r - U1r * fly2r;
+ fly5r = fly5r - U1i * fly2i;
+ fly5i = t0i + U1i * fly2r;
+ fly5i = fly5i - U1r * fly2i;
+ t0r = scale * t0r - fly5r;
+ t0i = scale * t0i - fly5i;
+
+ fly7r = t1r + U1i * fly1r;
+ fly7r = fly7r - U1r * fly1i;
+ fly7i = t1i + U1r * fly1r;
+ fly7i = fly7i + U1i * fly1i;
+ t1r = scale * t1r - fly7r;
+ t1i = scale * t1i - fly7i;
+
+ fly2r = fly4r - U1r * fly6r;
+ fly2r = fly2r - U1i * fly6i;
+ fly2i = fly4i + U1i * fly6r;
+ fly2i = fly2i - U1r * fly6i;
+ fly4r = scale * fly4r - fly2r;
+ fly4i = scale * fly4i - fly2i;
+
+ fly1r = fly0r + U1i * fly3r;
+ fly1r = fly1r - U1r * fly3i;
+ fly1i = fly0i + U1r * fly3r;
+ fly1i = fly1i + U1i * fly3i;
+ fly0r = scale * fly0r - fly1r;
+ fly0i = scale * fly0i - fly1i;
+
+ U0i = *(U0iP = (U0iP - NsameU4));
+ U0r = *(U0rP = (U0rP + NsameU4));
+ U1r = *(U1rP = (U1rP + NsameU2));
+ U1i = *(U1iP = (U1iP - NsameU2));
+ if(stage&1)
+ U0r = -U0r;
+
+ fly6r = t0r - U2r * fly4r;
+ fly6r = fly6r - U2i * fly4i;
+ fly6i = t0i + U2i * fly4r;
+ fly6i = fly6i - U2r * fly4i;
+ t0r = scale * t0r - fly6r;
+ t0i = scale * t0i - fly6i;
+
+ fly3r = fly5r - U2i * fly2r;
+ fly3r = fly3r + U2r * fly2i;
+ fly3i = fly5i - U2r * fly2r;
+ fly3i = fly3i - U2i * fly2i;
+ fly2r = scale * fly5r - fly3r;
+ fly2i = scale * fly5i - fly3i;
+
+ fly4r = t1r - U3r * fly0r;
+ fly4r = fly4r - U3i * fly0i;
+ fly4i = t1i + U3i * fly0r;
+ fly4i = fly4i - U3r * fly0i;
+ t1r = scale * t1r - fly4r;
+ t1i = scale * t1i - fly4i;
+
+ fly5r = fly7r + U3i * fly1r;
+ fly5r = fly5r - U3r * fly1i;
+ fly5i = fly7i + U3r * fly1r;
+ fly5i = fly5i + U3i * fly1i;
+ fly7r = scale * fly7r - fly5r;
+ fly7i = scale * fly7i - fly5i;
+
+ *(fly0P + FlyOffsetA) = fly6r;
+ *(fly0P + FlyOffsetAIm) = fly6i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+
+ U2r = *(U2rP = (U2rP + NsameU1));
+ U2i = *(U2iP = (U2iP - NsameU1));
+
+ *(fly2P) = fly3r;
+ *(fly2P + 1) = fly3i;
+ *(fly2P + FlyOffsetA) = fly2r;
+ *(fly2P + FlyOffsetAIm) = fly2i;
+ *(fly1P + FlyOffsetA) = fly4r;
+ *(fly1P + FlyOffsetAIm) = fly4i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+
+ U3r = *( U2rP + U3offset);
+ U3i = *( U2iP - U3offset);
+
+ *(fly3P + FlyOffsetA) = fly5r;
+ *(fly3P + FlyOffsetAIm) = fly5i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+
+ IOP = IOP + 2;
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+ };
+ NsameU4 = -NsameU4;
+
+ if(stage&1){
+ LoopN >>= 3;
+ NsameU1 >>= 3;
+ NsameU2 >>= 3;
+ NsameU4 >>= 3;
+ NdiffU <<= 3;
+ Flyinc = Flyinc << 3;
+ FlyOffsetA <<= 3;
+ FlyOffsetB <<= 3;
+ FlyOffsetAIm = FlyOffsetA + 1;
+ FlyOffsetBIm = FlyOffsetB + 1;
+ }
+}
+
+/* Finish RFFT */
+M=M+1;
+
+FlyOffsetA = Ntbl[M] * 2/4;
+FlyOffsetAIm = Ntbl[M] * 2/4 + 1;
+
+IOP = ioptr;
+
+fly0P = (IOP + Ntbl[M]*2/4);
+fly1P = (IOP + Ntbl[M]*2/8);
+
+U0rP = &Utbl[Ntbl[M-3]];
+
+U0r = *U0rP,
+
+fly0r = *(IOP);
+fly0i = *(IOP + 1);
+fly1r = *(fly0P);
+fly1i = *(fly0P + 1);
+fly2r = *(fly1P);
+fly2i = *(fly1P + 1);
+fly3r = *(fly1P + FlyOffsetA);
+fly3i = *(fly1P + FlyOffsetAIm);
+
+ t0r = scale * fly0r + scale * fly0i; /* compute Re(x[0]) */
+ t0i = scale * fly0r - scale * fly0i; /* compute Re(x[N/2]) */
+ t1r = scale * fly1r;
+ t1i = -scale * fly1i;
+
+ fly0r = fly2r + fly3r;
+ fly0i = fly2i - fly3i;
+ fly1r = fly2i + fly3i;
+ fly1i = fly3r - fly2r;
+
+ fly2r = fly0r + U0r * fly1r;
+ fly2r = fly2r + U0r * fly1i;
+ fly2i = fly0i - U0r * fly1r;
+ fly2i = fly2i + U0r * fly1i;
+ fly3r = scale * fly0r - fly2r;
+ fly3i = fly2i - scale * fly0i;
+
+*(IOP) = t0r;
+*(IOP + 1) = t0i;
+*(fly0P) = t1r;
+*(fly0P + 1) = t1i;
+*(fly1P) = fly2r;
+*(fly1P + 1) = fly2i;
+*(fly1P + FlyOffsetA) = fly3r;
+*(fly1P + FlyOffsetAIm) = fly3i;
+
+U0rP = &Utbl[1];
+U0iP = &Utbl[Ntbl[M-2]-1];
+
+U0r = *U0rP,
+U0i = *U0iP;
+
+fly0P = (IOP + 2);
+fly1P = (IOP + (Ntbl[M-2]-1)*2);
+
+ /* Butterflys */
+ /*
+ f0 - t0 - - f2
+ f1 - t1 -U0 - f3
+ f2 - f0 - - t0
+ f3 - f1 -U0a- t1
+ */
+
+for (diffUcnt = Ntbl[M-3]-1; diffUcnt > 0 ; diffUcnt--){
+
+ fly0r = *(fly0P);
+ fly0i = *(fly0P + 1);
+ fly1r = *(fly1P + FlyOffsetA);
+ fly1i = *(fly1P + FlyOffsetAIm);
+ fly2r = *(fly1P);
+ fly2i = *(fly1P + 1);
+ fly3r = *(fly0P + FlyOffsetA);
+ fly3i = *(fly0P + FlyOffsetAIm);
+
+ t0r = fly0r + fly1r;
+ t0i = fly0i - fly1i;
+ t1r = fly0i + fly1i;
+ t1i = fly1r - fly0r;
+
+ fly0r = fly2r + fly3r;
+ fly0i = fly2i - fly3i;
+ fly1r = fly2i + fly3i;
+ fly1i = fly3r - fly2r;
+
+ fly2r = t0r + U0r * t1r;
+ fly2r = fly2r + U0i * t1i;
+ fly2i = t0i - U0i * t1r;
+ fly2i = fly2i + U0r * t1i;
+ fly3r = scale * t0r - fly2r;
+ fly3i = fly2i - scale * t0i;
+
+ t0r = fly0r + U0i * fly1r;
+ t0r = t0r + U0r * fly1i;
+ t0i = fly0i - U0r * fly1r;
+ t0i = t0i + U0i * fly1i;
+ t1r = scale * fly0r - t0r;
+ t1i = t0i - scale * fly0i;
+
+ *(fly0P) = fly2r;
+ *(fly0P + 1) = fly2i;
+ *(fly1P + FlyOffsetA) = fly3r;
+ *(fly1P + FlyOffsetAIm) = fly3i;
+
+ U0r = *(U0rP = (U0rP + 1));
+ U0i = *(U0iP = (U0iP - 1));
+
+ *(fly1P) = t0r;
+ *(fly1P + 1) = t0i;
+ *(fly0P + FlyOffsetA) = t1r;
+ *(fly0P + FlyOffsetAIm) = t1i;
+
+ fly0P += 2;
+ fly1P -= 2;
+};
+
+ioptr += Ntbl[M];
+}
+}
+
+void riffts(float *ioptr, long M, long Rows, float *Utbl){
+/* Compute in-place real ifft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = input data array in the following order */
+/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = real output data array */
+
+long Flyinc;
+long FlyOffsetA;
+long FlyOffsetAIm;
+long FlyOffsetB;
+long FlyOffsetBIm;
+long NsameU1;
+long NsameU2;
+long NsameU4;
+long diffUcnt;
+long LoopCnt;
+float scale;
+float fly0r;
+float fly0i;
+float fly1r;
+float fly1i;
+float fly2r;
+float fly2i;
+float fly3r;
+float fly3i;
+float fly4r;
+float fly4i;
+float fly5r;
+float fly5i;
+float fly6r;
+float fly6i;
+float fly7r;
+float fly7i;
+float U0r;
+float U0i;
+float U1r;
+float U1i;
+float U2r;
+float U2i;
+float U3r;
+float U3i;
+float t0r;
+float t0i;
+float t1r;
+float t1i;
+
+float *fly0P;
+float *fly1P;
+float *fly2P;
+float *fly3P;
+
+float *U0rP;
+float *U0iP;
+float *U1rP;
+float *U1iP;
+float *U2rP;
+float *U2iP;
+float *IOP;
+long U3offset;
+
+long stage;
+long NdiffU;
+long LoopN;
+
+const long BRshift = MAXMROOT - ((M-1)>>1); /* for RIFFT */
+const long Nrems2 = Ntbl[(M-1)-((M-1)>>1)+1]; /* for RIFFT */
+const long Nroot_1_ColInc = (Ntbl[(M-1)-1]-Ntbl[(M-1)-((M-1)>>1)])*2; /* for RIFFT */
+
+for (;Rows>0;Rows--){
+
+/* Start RIFFT */
+
+FlyOffsetA = Ntbl[M] * 2/4;
+FlyOffsetAIm = Ntbl[M] * 2/4 + 1;
+
+IOP = ioptr;
+
+fly0P = (IOP + Ntbl[M]*2/4);
+fly1P = (IOP + Ntbl[M]*2/8);
+
+U0rP = &Utbl[Ntbl[M-3]];
+
+U0r = *U0rP,
+
+fly0r = *(IOP);
+fly0i = *(IOP + 1);
+fly1r = *(fly0P);
+fly1i = *(fly0P + 1);
+fly2r = *(fly1P);
+fly2i = *(fly1P + 1);
+fly3r = *(fly1P + FlyOffsetA);
+fly3i = *(fly1P + FlyOffsetAIm);
+
+ t0r = fly0r + fly0i;
+ t0i = fly0r - fly0i;
+ t1r = fly1r + fly1r;
+ t1i = -fly1i - fly1i;
+
+ fly0r = fly2r + fly3r;
+ fly0i = fly2i - fly3i;
+ fly1r = fly2r - fly3r;
+ fly1i = fly2i + fly3i;
+
+ fly3r = fly1r * U0r;
+ fly3r = fly3r - U0r * fly1i;
+ fly3i = fly1r * U0r;
+ fly3i = fly3i + U0r * fly1i;
+
+ fly2r = fly0r - fly3i;
+ fly2i = fly0i + fly3r;
+ fly1r = fly0r + fly3i;
+ fly1i = -fly0i + fly3r;
+
+*(IOP) = t0r;
+*(IOP + 1) = t0i;
+*(fly0P) = t1r;
+*(fly0P + 1) = t1i;
+*(fly1P) = fly2r;
+*(fly1P + 1) = fly2i;
+*(fly1P + FlyOffsetA) = fly1r;
+*(fly1P + FlyOffsetAIm) = fly1i;
+
+U0rP = &Utbl[1];
+U0iP = &Utbl[Ntbl[M-2]-1];
+
+U0r = *U0rP,
+U0i = *U0iP;
+
+fly0P = (IOP + 2);
+fly1P = (IOP + (Ntbl[M-2]-1)*2);
+
+ /* Butterflys */
+ /*
+ f0 - t0 - f2
+ f1 -t1 -U0- f3 - f1
+ f2 - f0 - t0
+ f3 -f1 -U0a t1 - f3
+ */
+
+for (diffUcnt = Ntbl[M-3]-1; diffUcnt > 0 ; diffUcnt--){
+
+ fly0r = *(fly0P);
+ fly0i = *(fly0P + 1);
+ fly1r = *(fly1P + FlyOffsetA);
+ fly1i = *(fly1P + FlyOffsetAIm);
+ fly2r = *(fly1P);
+ fly2i = *(fly1P + 1);
+ fly3r = *(fly0P + FlyOffsetA);
+ fly3i = *(fly0P + FlyOffsetAIm);
+
+ t0r = fly0r + fly1r;
+ t0i = fly0i - fly1i;
+ t1r = fly0r - fly1r;
+ t1i = fly0i + fly1i;
+
+ fly0r = fly2r + fly3r;
+ fly0i = fly2i - fly3i;
+ fly1r = fly2r - fly3r;
+ fly1i = fly2i + fly3i;
+
+
+ fly3r = t1r * U0r;
+ fly3r = fly3r - U0i * t1i;
+ fly3i = t1r * U0i;
+ fly3i = fly3i + U0r * t1i;
+
+ t1r = fly1r * U0i;
+ t1r = t1r - U0r * fly1i;
+ t1i = fly1r * U0r;
+ t1i = t1i + U0i * fly1i;
+
+
+ fly2r = t0r - fly3i;
+ fly2i = t0i + fly3r;
+ fly1r = t0r + fly3i;
+ fly1i = -t0i + fly3r;
+
+ t0r = fly0r - t1i;
+ t0i = fly0i + t1r;
+ fly3r = fly0r + t1i;
+ fly3i = -fly0i + t1r;
+
+
+ *(fly0P) = fly2r;
+ *(fly0P + 1) = fly2i;
+ *(fly1P + FlyOffsetA) = fly1r;
+ *(fly1P + FlyOffsetAIm) = fly1i;
+
+ U0r = *(U0rP = (U0rP + 1));
+ U0i = *(U0iP = (U0iP - 1));
+
+ *(fly1P) = t0r;
+ *(fly1P + 1) = t0i;
+ *(fly0P + FlyOffsetA) = fly3r;
+ *(fly0P + FlyOffsetAIm) = fly3i;
+
+ fly0P += 2;
+ fly1P -= 2;
+};
+
+M=M-1; /* for RIFFT */
+
+FlyOffsetA = Ntbl[M] * 2/2;
+FlyOffsetAIm = FlyOffsetA + 1;
+FlyOffsetB = FlyOffsetA + 2;
+FlyOffsetBIm = FlyOffsetB + 1;
+
+/* BitrevR2 ** bit reverse shuffle and first radix 2 stage ******/
+
+scale = 1./Ntbl[M+1];
+for (stage = 0; stage < Ntbl[M-(M>>1)]*2; stage += Ntbl[M>>1]*2){
+ for (LoopN = (Ntbl[(M>>1)-1]-1); LoopN >= 0; LoopN--){
+ LoopCnt = (Ntbl[(M>>1)-1]-1);
+ fly0P = ioptr + Nroot_1_ColInc + ((int)BRcnt[LoopN] >> BRshift)*(2*2) + stage;
+ IOP = ioptr + (LoopN<<(M+1)/2) * 2 + stage;
+ fly1P = IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2);
+ fly0r = *(fly0P);
+ fly0i = *(fly0P+1);
+ fly1r = *(fly0P+FlyOffsetA);
+ fly1i = *(fly0P+FlyOffsetAIm);
+ for (; LoopCnt > LoopN;){
+ fly2r = *(fly0P+2);
+ fly2i = *(fly0P+(2+1));
+ fly3r = *(fly0P+FlyOffsetB);
+ fly3i = *(fly0P+FlyOffsetBIm);
+ fly4r = *(fly1P);
+ fly4i = *(fly1P+1);
+ fly5r = *(fly1P+FlyOffsetA);
+ fly5i = *(fly1P+FlyOffsetAIm);
+ fly6r = *(fly1P+2);
+ fly6i = *(fly1P+(2+1));
+ fly7r = *(fly1P+FlyOffsetB);
+ fly7i = *(fly1P+FlyOffsetBIm);
+
+ t0r = fly0r + fly1r;
+ t0i = fly0i + fly1i;
+ fly1r = fly0r - fly1r;
+ fly1i = fly0i - fly1i;
+ t1r = fly2r + fly3r;
+ t1i = fly2i + fly3i;
+ fly3r = fly2r - fly3r;
+ fly3i = fly2i - fly3i;
+ fly0r = fly4r + fly5r;
+ fly0i = fly4i + fly5i;
+ fly5r = fly4r - fly5r;
+ fly5i = fly4i - fly5i;
+ fly2r = fly6r + fly7r;
+ fly2i = fly6i + fly7i;
+ fly7r = fly6r - fly7r;
+ fly7i = fly6i - fly7i;
+
+ *(fly1P) = scale*t0r;
+ *(fly1P+1) = scale*t0i;
+ *(fly1P+2) = scale*fly1r;
+ *(fly1P+(2+1)) = scale*fly1i;
+ *(fly1P+FlyOffsetA) = scale*t1r;
+ *(fly1P+FlyOffsetAIm) = scale*t1i;
+ *(fly1P+FlyOffsetB) = scale*fly3r;
+ *(fly1P+FlyOffsetBIm) = scale*fly3i;
+ *(fly0P) = scale*fly0r;
+ *(fly0P+1) = scale*fly0i;
+ *(fly0P+2) = scale*fly5r;
+ *(fly0P+(2+1)) = scale*fly5i;
+ *(fly0P+FlyOffsetA) = scale*fly2r;
+ *(fly0P+FlyOffsetAIm) = scale*fly2i;
+ *(fly0P+FlyOffsetB) = scale*fly7r;
+ *(fly0P+FlyOffsetBIm) = scale*fly7i;
+
+ fly0P -= Nrems2;
+ fly0r = *(fly0P);
+ fly0i = *(fly0P+1);
+ fly1r = *(fly0P+FlyOffsetA);
+ fly1i = *(fly0P+FlyOffsetAIm);
+ LoopCnt -= 1;
+ fly1P = (IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2));
+ };
+ fly2r = *(fly0P+2);
+ fly2i = *(fly0P+(2+1));
+ fly3r = *(fly0P+FlyOffsetB);
+ fly3i = *(fly0P+FlyOffsetBIm);
+
+ t0r = fly0r + fly1r;
+ t0i = fly0i + fly1i;
+ fly1r = fly0r - fly1r;
+ fly1i = fly0i - fly1i;
+ t1r = fly2r + fly3r;
+ t1i = fly2i + fly3i;
+ fly3r = fly2r - fly3r;
+ fly3i = fly2i - fly3i;
+
+ *(fly0P) = scale*t0r;
+ *(fly0P+1) = scale*t0i;
+ *(fly0P+2) = scale*fly1r;
+ *(fly0P+(2+1)) = scale*fly1i;
+ *(fly0P+FlyOffsetA) = scale*t1r;
+ *(fly0P+FlyOffsetAIm) = scale*t1i;
+ *(fly0P+FlyOffsetB) = scale*fly3r;
+ *(fly0P+FlyOffsetBIm) = scale*fly3i;
+
+ };
+};
+
+/**** FFTC **************/
+
+scale = 2.0;
+
+NdiffU = 2;
+Flyinc = (NdiffU);
+
+NsameU4 = Ntbl[M+1]/4; /* for RIFFT */
+LoopN = Ntbl[M-3];
+
+stage = ((M-1)/3);
+if ( (M-1-(stage * 3)) != 0 ){
+ FlyOffsetA = Flyinc << 2;
+ FlyOffsetB = FlyOffsetA << 1;
+ FlyOffsetAIm = FlyOffsetA + 1;
+ FlyOffsetBIm = FlyOffsetB + 1;
+ if ( (M-1-(stage * 3)) == 1 ){
+ /* 1 radix 2 stage */
+
+ IOP = ioptr;
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+
+ /* Butterflys */
+ /*
+ t0 - - t0
+ t1 - - t1
+ f2 - 1- f5
+ f1 - -i- f7
+ f4 - - f4
+ f0 - - f0
+ f6 - 1- f2
+ f3 - -i- f1
+ */
+
+ for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){
+ t0r = *(fly0P);
+ t0i = *(fly0P + 1);
+ t1r = *(fly1P);
+ t1i = *(fly1P + 1);
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly1r = *(fly3P);
+ fly1i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly0r = *(fly1P + FlyOffsetA);
+ fly0i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly3r = *(fly3P + FlyOffsetA);
+ fly3i = *(fly3P + FlyOffsetAIm);
+
+ fly5r = t0r - fly2r;
+ fly5i = t0i - fly2i;
+ t0r = t0r + fly2r;
+ t0i = t0i + fly2i;
+
+ fly7r = t1r + fly1i;
+ fly7i = t1i - fly1r;
+ t1r = t1r - fly1i;
+ t1i = t1i + fly1r;
+
+ fly2r = fly4r - fly6r;
+ fly2i = fly4i - fly6i;
+ fly4r = fly4r + fly6r;
+ fly4i = fly4i + fly6i;
+
+ fly1r = fly0r + fly3i;
+ fly1i = fly0i - fly3r;
+ fly0r = fly0r - fly3i;
+ fly0i = fly0i + fly3r;
+
+ *(fly2P) = fly5r;
+ *(fly2P + 1) = fly5i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+ *(fly2P + FlyOffsetA) = fly2r;
+ *(fly2P + FlyOffsetAIm) = fly2i;
+ *(fly0P + FlyOffsetA) = fly4r;
+ *(fly0P + FlyOffsetAIm) = fly4i;
+ *(fly3P + FlyOffsetA) = fly1r;
+ *(fly3P + FlyOffsetAIm) = fly1i;
+ *(fly1P + FlyOffsetA) = fly0r;
+ *(fly1P + FlyOffsetAIm) = fly0i;
+
+ fly0P = (fly0P + FlyOffsetB);
+ fly1P = (fly1P + FlyOffsetB);
+ fly2P = (fly2P + FlyOffsetB);
+ fly3P = (fly3P + FlyOffsetB);
+ };
+
+ NsameU4 >>= 1;
+ LoopN >>= 1;
+ NdiffU <<= 1;
+ Flyinc = Flyinc << 1;
+ }
+ else{
+ /* 1 radix 4 stage */
+ IOP = ioptr;
+
+ U3r = 0.7071067811865475244008443621; /* sqrt(0.5); */
+ U3i = U3r;
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+
+ /* Butterflys */
+ /*
+ t0 - - t0 - - t0
+ t1 - - t1 - - t1
+ f2 - 1- f5 - - f5
+ f1 - -i- f7 - - f7
+ f4 - - f4 - 1- f6
+ f0 - - f0 -U3 - f3
+ f6 - 1- f2 - -i- f4
+ f3 - -i- f1 -U3a- f2
+ */
+
+ for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){
+ t0r = *(fly0P);
+ t0i = *(fly0P + 1);
+ t1r = *(fly1P);
+ t1i = *(fly1P + 1);
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly1r = *(fly3P);
+ fly1i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly0r = *(fly1P + FlyOffsetA);
+ fly0i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly3r = *(fly3P + FlyOffsetA);
+ fly3i = *(fly3P + FlyOffsetAIm);
+
+ fly5r = t0r - fly2r;
+ fly5i = t0i - fly2i;
+ t0r = t0r + fly2r;
+ t0i = t0i + fly2i;
+
+ fly7r = t1r + fly1i;
+ fly7i = t1i - fly1r;
+ t1r = t1r - fly1i;
+ t1i = t1i + fly1r;
+
+ fly2r = fly4r - fly6r;
+ fly2i = fly4i - fly6i;
+ fly4r = fly4r + fly6r;
+ fly4i = fly4i + fly6i;
+
+ fly1r = fly0r + fly3i;
+ fly1i = fly0i - fly3r;
+ fly0r = fly0r - fly3i;
+ fly0i = fly0i + fly3r;
+
+ fly6r = t0r - fly4r;
+ fly6i = t0i - fly4i;
+ t0r = t0r + fly4r;
+ t0i = t0i + fly4i;
+
+ fly3r = fly5r + fly2i;
+ fly3i = fly5i - fly2r;
+ fly5r = fly5r - fly2i;
+ fly5i = fly5i + fly2r;
+
+ fly4r = t1r - U3r * fly0r;
+ fly4r = fly4r + U3i * fly0i;
+ fly4i = t1i - U3i * fly0r;
+ fly4i = fly4i - U3r * fly0i;
+ t1r = scale * t1r - fly4r;
+ t1i = scale * t1i - fly4i;
+
+ fly2r = fly7r + U3i * fly1r;
+ fly2r = fly2r + U3r * fly1i;
+ fly2i = fly7i - U3r * fly1r;
+ fly2i = fly2i + U3i * fly1i;
+ fly7r = scale * fly7r - fly2r;
+ fly7i = scale * fly7i - fly2i;
+
+ *(fly0P + FlyOffsetA) = fly6r;
+ *(fly0P + FlyOffsetAIm) = fly6i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+ *(fly2P + FlyOffsetA) = fly3r;
+ *(fly2P + FlyOffsetAIm) = fly3i;
+ *(fly2P) = fly5r;
+ *(fly2P + 1) = fly5i;
+ *(fly1P + FlyOffsetA) = fly4r;
+ *(fly1P + FlyOffsetAIm) = fly4i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+ *(fly3P + FlyOffsetA) = fly2r;
+ *(fly3P + FlyOffsetAIm) = fly2i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+
+ fly0P = (fly0P + FlyOffsetB);
+ fly1P = (fly1P + FlyOffsetB);
+ fly2P = (fly2P + FlyOffsetB);
+ fly3P = (fly3P + FlyOffsetB);
+
+ };
+
+ NsameU4 >>= 2;
+ LoopN >>= 2;
+ NdiffU <<= 2;
+ Flyinc = Flyinc << 2;
+ };
+};
+
+NsameU2 = NsameU4 >> 1;
+NsameU1 = NsameU2 >> 1;
+Flyinc <<= 1;
+FlyOffsetA = Flyinc << 2;
+FlyOffsetB = FlyOffsetA << 1;
+FlyOffsetAIm = FlyOffsetA + 1;
+FlyOffsetBIm = FlyOffsetB + 1;
+LoopN >>= 1;
+
+/* ****** RADIX 8 Stages */
+for (stage = stage<<1; stage > 0 ; stage--){
+
+ /* an fft stage is done in two parts to ease use of the single quadrant cos table */
+
+/* fftcalc1(iobuf, Utbl, N, NdiffU, LoopN); */
+ if(!(stage&1)){
+ U0rP = &Utbl[0];
+ U0iP = &Utbl[Ntbl[M-1]]; /* for RIFFT */
+ U1rP = U0rP;
+ U1iP = U0iP;
+ U2rP = U0rP;
+ U2iP = U0iP;
+ U3offset = (Ntbl[M+1]) / 8; /* for RIFFT */
+
+ IOP = ioptr;
+
+ U0r = *U0rP,
+ U0i = *U0iP;
+ U1r = *U1rP,
+ U1i = *U1iP;
+ U2r = *U2rP,
+ U2i = *U2iP;
+ U3r = *( U2rP + U3offset);
+ U3i = *( U2iP - U3offset);
+ }
+
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+
+ for (diffUcnt = (NdiffU)>>1; diffUcnt > 0; diffUcnt--){
+
+ /* Butterflys */
+ /*
+ f0 - - t0 - - t0 - - t0
+ f1 -U0 - t1 - - t1 - - t1
+ f2 - - f2 -U1 - f5 - - f3
+ f3 -U0 - f1 -U1a- f7 - - f7
+ f4 - - f4 - - f4 -U2 - f6
+ f5 -U0 - f0 - - f0 -U3 - f4
+ f6 - - f6 -U1 - f2 -U2a- f2
+ f7 -U0 - f3 -U1a- f1 -U3a- f5
+ */
+
+ fly0r = *(IOP);
+ fly0i = *(IOP+1);
+ fly1r = *(fly1P);
+ fly1i = *(fly1P+1);
+
+ for (LoopCnt = LoopN-1; LoopCnt > 0 ; LoopCnt--){
+
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly3r = *(fly3P);
+ fly3i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly5r = *(fly1P + FlyOffsetA);
+ fly5i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly7r = *(fly3P + FlyOffsetA);
+ fly7i = *(fly3P + FlyOffsetAIm);
+
+ t1r = fly0r - U0r * fly1r;
+ t1r = t1r + U0i * fly1i;
+ t1i = fly0i - U0i * fly1r;
+ t1i = t1i - U0r * fly1i;
+ t0r = scale * fly0r - t1r;
+ t0i = scale * fly0i - t1i;
+
+ fly1r = fly2r - U0r * fly3r;
+ fly1r = fly1r + U0i * fly3i;
+ fly1i = fly2i - U0i * fly3r;
+ fly1i = fly1i - U0r * fly3i;
+ fly2r = scale * fly2r - fly1r;
+ fly2i = scale * fly2i - fly1i;
+
+ fly0r = fly4r - U0r * fly5r;
+ fly0r = fly0r + U0i * fly5i;
+ fly0i = fly4i - U0i * fly5r;
+ fly0i = fly0i - U0r * fly5i;
+ fly4r = scale * fly4r - fly0r;
+ fly4i = scale * fly4i - fly0i;
+
+ fly3r = fly6r - U0r * fly7r;
+ fly3r = fly3r + U0i * fly7i;
+ fly3i = fly6i - U0i * fly7r;
+ fly3i = fly3i - U0r * fly7i;
+ fly6r = scale * fly6r - fly3r;
+ fly6i = scale * fly6i - fly3i;
+
+
+ fly5r = t0r - U1r * fly2r;
+ fly5r = fly5r + U1i * fly2i;
+ fly5i = t0i - U1i * fly2r;
+ fly5i = fly5i - U1r * fly2i;
+ t0r = scale * t0r - fly5r;
+ t0i = scale * t0i - fly5i;
+
+ fly7r = t1r + U1i * fly1r;
+ fly7r = fly7r + U1r * fly1i;
+ fly7i = t1i - U1r * fly1r;
+ fly7i = fly7i + U1i * fly1i;
+ t1r = scale * t1r - fly7r;
+ t1i = scale * t1i - fly7i;
+
+ fly2r = fly4r - U1r * fly6r;
+ fly2r = fly2r + U1i * fly6i;
+ fly2i = fly4i - U1i * fly6r;
+ fly2i = fly2i - U1r * fly6i;
+ fly4r = scale * fly4r - fly2r;
+ fly4i = scale * fly4i - fly2i;
+
+ fly1r = fly0r + U1i * fly3r;
+ fly1r = fly1r + U1r * fly3i;
+ fly1i = fly0i - U1r * fly3r;
+ fly1i = fly1i + U1i * fly3i;
+ fly0r = scale * fly0r - fly1r;
+ fly0i = scale * fly0i - fly1i;
+
+ fly6r = t0r - U2r * fly4r;
+ fly6r = fly6r + U2i * fly4i;
+ fly6i = t0i - U2i * fly4r;
+ fly6i = fly6i - U2r * fly4i;
+ t0r = scale * t0r - fly6r;
+ t0i = scale * t0i - fly6i;
+
+ fly3r = fly5r - U2i * fly2r;
+ fly3r = fly3r - U2r * fly2i;
+ fly3i = fly5i + U2r * fly2r;
+ fly3i = fly3i - U2i * fly2i;
+ fly2r = scale * fly5r - fly3r;
+ fly2i = scale * fly5i - fly3i;
+
+ fly4r = t1r - U3r * fly0r;
+ fly4r = fly4r + U3i * fly0i;
+ fly4i = t1i - U3i * fly0r;
+ fly4i = fly4i - U3r * fly0i;
+ t1r = scale * t1r - fly4r;
+ t1i = scale * t1i - fly4i;
+
+ fly5r = fly7r + U3i * fly1r;
+ fly5r = fly5r + U3r * fly1i;
+ fly5i = fly7i - U3r * fly1r;
+ fly5i = fly5i + U3i * fly1i;
+ fly7r = scale * fly7r - fly5r;
+ fly7i = scale * fly7i - fly5i;
+
+ *(fly0P + FlyOffsetA) = fly6r;
+ *(fly0P + FlyOffsetAIm) = fly6i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+ *(fly2P) = fly3r;
+ *(fly2P + 1) = fly3i;
+ *(fly2P + FlyOffsetA) = fly2r;
+ *(fly2P + FlyOffsetAIm) = fly2i;
+
+ fly0r = *(fly0P + FlyOffsetB);
+ fly0i = *(fly0P + FlyOffsetBIm);
+
+ *(fly1P + FlyOffsetA) = fly4r;
+ *(fly1P + FlyOffsetAIm) = fly4i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+
+ fly1r = *(fly1P + FlyOffsetB);
+ fly1i = *(fly1P + FlyOffsetBIm);
+
+ *(fly3P + FlyOffsetA) = fly5r;
+ *(fly3P + FlyOffsetAIm) = fly5i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+
+ fly0P = (fly0P + FlyOffsetB);
+ fly1P = (fly1P + FlyOffsetB);
+ fly2P = (fly2P + FlyOffsetB);
+ fly3P = (fly3P + FlyOffsetB);
+
+ };
+ fly2r = *(fly2P);
+ fly2i = *(fly2P + 1);
+ fly3r = *(fly3P);
+ fly3i = *(fly3P + 1);
+ fly4r = *(fly0P + FlyOffsetA);
+ fly4i = *(fly0P + FlyOffsetAIm);
+ fly5r = *(fly1P + FlyOffsetA);
+ fly5i = *(fly1P + FlyOffsetAIm);
+ fly6r = *(fly2P + FlyOffsetA);
+ fly6i = *(fly2P + FlyOffsetAIm);
+ fly7r = *(fly3P + FlyOffsetA);
+ fly7i = *(fly3P + FlyOffsetAIm);
+
+ t1r = fly0r - U0r * fly1r;
+ t1r = t1r + U0i * fly1i;
+ t1i = fly0i - U0i * fly1r;
+ t1i = t1i - U0r * fly1i;
+ t0r = scale * fly0r - t1r;
+ t0i = scale * fly0i - t1i;
+
+ fly1r = fly2r - U0r * fly3r;
+ fly1r = fly1r + U0i * fly3i;
+ fly1i = fly2i - U0i * fly3r;
+ fly1i = fly1i - U0r * fly3i;
+ fly2r = scale * fly2r - fly1r;
+ fly2i = scale * fly2i - fly1i;
+
+ fly0r = fly4r - U0r * fly5r;
+ fly0r = fly0r + U0i * fly5i;
+ fly0i = fly4i - U0i * fly5r;
+ fly0i = fly0i - U0r * fly5i;
+ fly4r = scale * fly4r - fly0r;
+ fly4i = scale * fly4i - fly0i;
+
+ fly3r = fly6r - U0r * fly7r;
+ fly3r = fly3r + U0i * fly7i;
+ fly3i = fly6i - U0i * fly7r;
+ fly3i = fly3i - U0r * fly7i;
+ fly6r = scale * fly6r - fly3r;
+ fly6i = scale * fly6i - fly3i;
+
+ fly5r = t0r - U1r * fly2r;
+ fly5r = fly5r + U1i * fly2i;
+ fly5i = t0i - U1i * fly2r;
+ fly5i = fly5i - U1r * fly2i;
+ t0r = scale * t0r - fly5r;
+ t0i = scale * t0i - fly5i;
+
+ fly7r = t1r + U1i * fly1r;
+ fly7r = fly7r + U1r * fly1i;
+ fly7i = t1i - U1r * fly1r;
+ fly7i = fly7i + U1i * fly1i;
+ t1r = scale * t1r - fly7r;
+ t1i = scale * t1i - fly7i;
+
+ fly2r = fly4r - U1r * fly6r;
+ fly2r = fly2r + U1i * fly6i;
+ fly2i = fly4i - U1i * fly6r;
+ fly2i = fly2i - U1r * fly6i;
+ fly4r = scale * fly4r - fly2r;
+ fly4i = scale * fly4i - fly2i;
+
+ fly1r = fly0r + U1i * fly3r;
+ fly1r = fly1r + U1r * fly3i;
+ fly1i = fly0i - U1r * fly3r;
+ fly1i = fly1i + U1i * fly3i;
+ fly0r = scale * fly0r - fly1r;
+ fly0i = scale * fly0i - fly1i;
+
+ U0i = *(U0iP = (U0iP - NsameU4));
+ U0r = *(U0rP = (U0rP + NsameU4));
+ U1r = *(U1rP = (U1rP + NsameU2));
+ U1i = *(U1iP = (U1iP - NsameU2));
+ if(stage&1)
+ U0r = - U0r;
+
+ fly6r = t0r - U2r * fly4r;
+ fly6r = fly6r + U2i * fly4i;
+ fly6i = t0i - U2i * fly4r;
+ fly6i = fly6i - U2r * fly4i;
+ t0r = scale * t0r - fly6r;
+ t0i = scale * t0i - fly6i;
+
+ fly3r = fly5r - U2i * fly2r;
+ fly3r = fly3r - U2r * fly2i;
+ fly3i = fly5i + U2r * fly2r;
+ fly3i = fly3i - U2i * fly2i;
+ fly2r = scale * fly5r - fly3r;
+ fly2i = scale * fly5i - fly3i;
+
+ fly4r = t1r - U3r * fly0r;
+ fly4r = fly4r + U3i * fly0i;
+ fly4i = t1i - U3i * fly0r;
+ fly4i = fly4i - U3r * fly0i;
+ t1r = scale * t1r - fly4r;
+ t1i = scale * t1i - fly4i;
+
+ fly5r = fly7r + U3i * fly1r;
+ fly5r = fly5r + U3r * fly1i;
+ fly5i = fly7i - U3r * fly1r;
+ fly5i = fly5i + U3i * fly1i;
+ fly7r = scale * fly7r - fly5r;
+ fly7i = scale * fly7i - fly5i;
+
+ *(fly0P + FlyOffsetA) = fly6r;
+ *(fly0P + FlyOffsetAIm) = fly6i;
+ *(fly0P) = t0r;
+ *(fly0P + 1) = t0i;
+
+ U2r = *(U2rP = (U2rP + NsameU1));
+ U2i = *(U2iP = (U2iP - NsameU1));
+
+ *(fly2P) = fly3r;
+ *(fly2P + 1) = fly3i;
+ *(fly2P + FlyOffsetA) = fly2r;
+ *(fly2P + FlyOffsetAIm) = fly2i;
+ *(fly1P + FlyOffsetA) = fly4r;
+ *(fly1P + FlyOffsetAIm) = fly4i;
+ *(fly1P) = t1r;
+ *(fly1P + 1) = t1i;
+
+ U3r = *( U2rP + U3offset);
+ U3i = *( U2iP - U3offset);
+
+ *(fly3P + FlyOffsetA) = fly5r;
+ *(fly3P + FlyOffsetAIm) = fly5i;
+ *(fly3P) = fly7r;
+ *(fly3P + 1) = fly7i;
+
+ IOP = IOP + 2;
+ fly0P = IOP;
+ fly1P = (IOP+Flyinc);
+ fly2P = (fly1P+Flyinc);
+ fly3P = (fly2P+Flyinc);
+ };
+ NsameU4 = -NsameU4;
+
+ if(stage&1){
+ LoopN >>= 3;
+ NsameU1 >>= 3;
+ NsameU2 >>= 3;
+ NsameU4 >>= 3;
+ NdiffU <<= 3;
+ Flyinc = Flyinc << 3;
+ FlyOffsetA <<= 3;
+ FlyOffsetB <<= 3;
+ FlyOffsetAIm = FlyOffsetA + 1;
+ FlyOffsetBIm = FlyOffsetB + 1;
+ }
+}
+M=M+1; /* for RIFFT */
+
+ioptr += Ntbl[M];
+}
+}
diff --git a/sc4pd/source/fftlib.h b/sc4pd/source/fftlib.h
new file mode 100644
index 0000000..b03317d
--- /dev/null
+++ b/sc4pd/source/fftlib.h
@@ -0,0 +1,62 @@
+long FFTInit(long *fftMptr, long fftN, float *Utbl);
+/* Compute cosine table and check size for complex ffts */
+/* INPUTS */
+/* fftN = size of fft */
+/* OUTPUTS */
+/* *fftMptr = log2 of fft size */
+/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */
+/* RETURNS */
+/* 1 if fftN is invalid, 0 otherwise */
+
+long rFFTInit(long *fftMptr, long fftN, float *Utbl);
+/* Compute cosine table and check size for a real input fft */
+/* INPUTS */
+/* fftN = size of fft */
+/* OUTPUTS */
+/* *fftMptr = log2 of fft size */
+/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */
+/* RETURNS */
+/* 1 if fftN is invalid, 0 otherwise */
+
+void ffts(float *ioptr, long M, long Rows, float *Utbl);
+/* Compute in-place complex fft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = input data array */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = output data array */
+
+void iffts(float *ioptr, long M, long Rows, float *Utbl);
+/* Compute in-place inverse complex fft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = input data array */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = output data array */
+
+void rffts(float *ioptr, long M, long Rows, float *Utbl);
+/* Compute in-place real fft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = real input data array */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = output data array in the following order */
+/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */
+
+
+void riffts(float *ioptr, long M, long Rows, float *Utbl);
+/* Compute in-place real ifft on the rows of the input array */
+/* INPUTS */
+/* M = log2 of fft size */
+/* *ioptr = input data array in the following order */
+/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */
+/* *Utbl = cosine table */
+/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */
+/* OUTPUTS */
+/* *ioptr = real output data array */
diff --git a/sc4pd/source/hypot.cpp b/sc4pd/source/hypot.cpp
new file mode 100644
index 0000000..83f9a89
--- /dev/null
+++ b/sc4pd/source/hypot.cpp
@@ -0,0 +1,125 @@
+/* sc4pd
+ hypot, hypot~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Keith Rowe & Toshimaru Nakamura: Weather Sky
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ hypot~ -----------------------------*/
+
+class hypot_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(hypot_ar,sc4pd_dsp);
+
+public:
+ hypot_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+
+};
+
+FLEXT_LIB_DSP_V("hypot~",hypot_ar);
+
+hypot_ar::hypot_ar(int argc,t_atom * argv)
+{
+ AddInSignal();
+ AddInSignal();
+ AddOutSignal();
+}
+
+void hypot_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin1 = *in;
+ t_sample *nin2 = *(in+1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ if( *nin2 > 0)
+ (*(nout)++) = hypot( (*(nin1)++), (*(nin2)++) );
+ }
+}
+
+
+
+/* ------------------------ hypot ------------------------------*/
+
+class hypot_kr
+ :public flext_base
+{
+ FLEXT_HEADER(hypot_kr,flext_base);
+
+public:
+ hypot_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+ void m_set(float f);
+
+private:
+ float b;
+ FLEXT_CALLBACK_F(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("hypot",hypot_kr);
+
+hypot_kr::hypot_kr(int argc,t_atom * argv)
+ :b(0)
+{
+
+ AddInFloat();
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD(1,m_set);
+}
+
+void hypot_kr::m_perform(float f)
+{
+ ToOutFloat(0,hypot(f,b));
+}
+
+void hypot_kr::m_set(float f)
+{
+ b=f;
+}
diff --git a/sc4pd/source/main.cpp b/sc4pd/source/main.cpp
new file mode 100644
index 0000000..fa81e2e
--- /dev/null
+++ b/sc4pd/source/main.cpp
@@ -0,0 +1,308 @@
+
+/* sc4pd
+ library initialization
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Phosphor
+*/
+
+#include "sc4pd.hpp"
+
+#define SC4PD_VERSION "0.01"
+
+
+void sc4pd_library_setup()
+{
+ post("\nsc4pd: by tim blechmann");
+ post("based on SuperCollider by James McCartney");
+ post("version "SC4PD_VERSION);
+ post("compiled on "__DATE__);
+ post("contains: Dust(~), MantissaMask(~), Hasher(~), Median(~), "
+ "BrownNoise(~),\n"
+ " ClipNoise(~), GrayNoise(~), Dust2(~), WhiteNoise(~), "
+ "PinkNoise(~), \n Crackle(~), Rand(~), TRand(~), "
+ "TExpRand(~), IRand(~), TIRand(~),\n CoinGate, "
+ "LinRand(~), NRand(~), ExpRand(~), LFClipNoise(~),\n"
+ " LFNoise0(~), LFNoise1(~), LFNoise2(~), Logistic(~), "
+ "Latoocarfian(~),\n"
+ " LinCong(~), amclip(~), scaleneg(~), excess(~), hypot(~), "
+ "ring1(~),\n"
+ " ring2(~), ring3(~), ring4(~), difsqr(~), sumsqr(~), "
+ "sqrdif(~),\n"
+ " sqrsum(~), absdif(~), LFSaw(~), LFPulse(~), Impulse(~),\n"
+ " Integrator(~), Decay~, Decay2~, Lag~, Lag2~, LinExp(~), "
+ "DelayN~,\n"
+ " DelayL~, DelayC~, CombN~, CombL~, CombC~, AllpassN~, "
+ "AllpassL~,\n"
+ " AllpassC~, PitchShift~, Resonz~, OnePole(~), OneZero(~), "
+ "TwoPole~, \n"
+ " TwoZero~, FOS(~), SOS~, RLPF~, RHPF~, LPF~, HPF~, BPF~, "
+ "BRF~,\n"
+ " LPZ1(~), HPZ1(~), LPZ2(~), HPZ2(~), BPZ2(~), BRZ2(~), "
+ "LFDNoise0~,\n"
+ " LFDNoise1~, LFDNoise2~, sc+~, sc-~, sc*~, sc/~, "
+ "Convolution~\n"
+ );
+
+ //initialize objects
+ FLEXT_DSP_SETUP(Dust_ar);
+ FLEXT_SETUP(Dust_kr);
+
+ FLEXT_DSP_SETUP(MantissaMask_ar);
+ FLEXT_SETUP(MantissaMask_kr);
+
+ FLEXT_DSP_SETUP(Hasher_ar);
+ FLEXT_SETUP(Hasher_kr);
+
+ FLEXT_DSP_SETUP(Median_ar);
+ FLEXT_SETUP(Median_kr);
+
+ FLEXT_DSP_SETUP(BrownNoise_ar);
+ FLEXT_SETUP(BrownNoise_kr);
+
+ FLEXT_DSP_SETUP(ClipNoise_ar);
+ FLEXT_SETUP(ClipNoise_kr);
+
+ FLEXT_DSP_SETUP(GrayNoise_ar);
+ FLEXT_SETUP(GrayNoise_kr);
+
+ FLEXT_DSP_SETUP(WhiteNoise_ar);
+ FLEXT_SETUP(WhiteNoise_kr);
+
+ FLEXT_DSP_SETUP(PinkNoise_ar);
+ FLEXT_SETUP(PinkNoise_kr);
+
+ FLEXT_DSP_SETUP(Dust2_ar);
+ FLEXT_SETUP(Dust2_kr);
+
+ FLEXT_DSP_SETUP(Crackle_ar);
+ FLEXT_SETUP(Crackle_kr);
+
+ FLEXT_DSP_SETUP(Rand_ar);
+ FLEXT_SETUP(Rand_kr);
+
+ FLEXT_DSP_SETUP(TRand_ar);
+ FLEXT_SETUP(TRand_kr);
+
+ FLEXT_DSP_SETUP(TExpRand_ar);
+ FLEXT_SETUP(TExpRand_kr);
+
+ FLEXT_DSP_SETUP(IRand_ar);
+ FLEXT_SETUP(IRand_kr);
+
+ FLEXT_DSP_SETUP(TIRand_ar);
+ FLEXT_SETUP(TIRand_kr);
+
+ FLEXT_SETUP(CoinGate_kr);
+
+ FLEXT_DSP_SETUP(LinRand_ar);
+ FLEXT_SETUP(LinRand_kr);
+
+ FLEXT_DSP_SETUP(NRand_ar);
+ FLEXT_SETUP(NRand_kr);
+
+ FLEXT_DSP_SETUP(ExpRand_ar);
+ FLEXT_SETUP(ExpRand_kr);
+
+ FLEXT_DSP_SETUP(LFClipNoise_ar);
+ FLEXT_SETUP(LFClipNoise_kr);
+
+ FLEXT_DSP_SETUP(LFNoise0_ar);
+ FLEXT_SETUP(LFNoise0_kr);
+
+ FLEXT_DSP_SETUP(LFNoise1_ar);
+ FLEXT_SETUP(LFNoise1_kr);
+
+ FLEXT_DSP_SETUP(LFNoise2_ar);
+ FLEXT_SETUP(LFNoise2_kr);
+
+ FLEXT_DSP_SETUP(Logistic_ar);
+ FLEXT_SETUP(Logistic_kr);
+
+ FLEXT_DSP_SETUP(Latoocarfian_ar);
+ FLEXT_SETUP(Latoocarfian_kr);
+
+ FLEXT_DSP_SETUP(LinCong_ar);
+ FLEXT_SETUP(LinCong_kr);
+
+ FLEXT_DSP_SETUP(amclip_ar);
+ FLEXT_SETUP(amclip_kr);
+
+ FLEXT_DSP_SETUP(scaleneg_ar);
+ FLEXT_SETUP(scaleneg_kr);
+
+ FLEXT_DSP_SETUP(excess_ar);
+ FLEXT_SETUP(excess_kr);
+
+ FLEXT_DSP_SETUP(hypot_ar);
+ FLEXT_SETUP(hypot_kr);
+
+ FLEXT_DSP_SETUP(ring1_ar);
+ FLEXT_SETUP(ring1_kr);
+
+ FLEXT_DSP_SETUP(ring2_ar);
+ FLEXT_SETUP(ring2_kr);
+
+ FLEXT_DSP_SETUP(ring3_ar);
+ FLEXT_SETUP(ring3_kr);
+
+ FLEXT_DSP_SETUP(ring4_ar);
+ FLEXT_SETUP(ring4_kr);
+
+ FLEXT_DSP_SETUP(difsqr_ar);
+ FLEXT_SETUP(difsqr_kr);
+
+ FLEXT_DSP_SETUP(sumsqr_ar);
+ FLEXT_SETUP(sumsqr_kr);
+
+ FLEXT_DSP_SETUP(sqrsum_ar);
+ FLEXT_SETUP(sqrsum_kr);
+
+ FLEXT_DSP_SETUP(sqrdif_ar);
+ FLEXT_SETUP(sqrdif_kr);
+
+ FLEXT_DSP_SETUP(absdif_ar);
+ FLEXT_SETUP(absdif_kr);
+
+ FLEXT_DSP_SETUP(LFSaw_ar);
+ FLEXT_SETUP(LFSaw_kr);
+
+ FLEXT_DSP_SETUP(LFPulse_ar);
+ FLEXT_SETUP(LFPulse_kr);
+
+ FLEXT_DSP_SETUP(Impulse_ar);
+ FLEXT_SETUP(Impulse_kr);
+
+ FLEXT_DSP_SETUP(Integrator_ar);
+ FLEXT_SETUP(Integrator_kr);
+
+ FLEXT_DSP_SETUP(Decay_ar);
+
+ FLEXT_DSP_SETUP(Decay2_ar);
+
+ FLEXT_DSP_SETUP(Lag_ar);
+
+ FLEXT_DSP_SETUP(Lag2_ar);
+
+ FLEXT_DSP_SETUP(Lag3_ar);
+
+ FLEXT_DSP_SETUP(LinExp_ar);
+ FLEXT_SETUP(LinExp_kr);
+
+ FLEXT_DSP_SETUP(DelayN_ar);
+
+ FLEXT_DSP_SETUP(DelayL_ar);
+
+ FLEXT_DSP_SETUP(DelayC_ar);
+
+ FLEXT_DSP_SETUP(CombN_ar);
+
+ FLEXT_DSP_SETUP(CombL_ar);
+
+ FLEXT_DSP_SETUP(CombC_ar);
+
+ FLEXT_DSP_SETUP(AllpassN_ar);
+
+ FLEXT_DSP_SETUP(AllpassL_ar);
+
+ FLEXT_DSP_SETUP(AllpassC_ar);
+
+ FLEXT_DSP_SETUP(PitchShift_ar);
+
+ FLEXT_DSP_SETUP(Resonz_ar);
+
+ FLEXT_DSP_SETUP(OnePole_ar);
+ FLEXT_SETUP(OnePole_kr);
+
+ FLEXT_DSP_SETUP(OneZero_ar);
+ FLEXT_SETUP(OneZero_kr);
+
+ FLEXT_DSP_SETUP(TwoPole_ar);
+
+ FLEXT_DSP_SETUP(TwoZero_ar);
+
+ FLEXT_DSP_SETUP(FOS_ar);
+ FLEXT_SETUP(FOS_kr);
+
+ FLEXT_DSP_SETUP(SOS_ar);
+
+ FLEXT_DSP_SETUP(RLPF_ar);
+
+ FLEXT_DSP_SETUP(RHPF_ar);
+
+ FLEXT_DSP_SETUP(LPF_ar);
+
+ FLEXT_DSP_SETUP(HPF_ar);
+
+ FLEXT_DSP_SETUP(BPF_ar);
+
+ FLEXT_DSP_SETUP(BRF_ar);
+
+ FLEXT_DSP_SETUP(LPZ1_ar);
+ FLEXT_SETUP(LPZ1_kr);
+
+ FLEXT_DSP_SETUP(HPZ1_ar);
+ FLEXT_SETUP(HPZ1_kr);
+
+ FLEXT_DSP_SETUP(LPZ2_ar);
+ FLEXT_SETUP(LPZ2_kr);
+
+ FLEXT_DSP_SETUP(HPZ2_ar);
+ FLEXT_SETUP(HPZ2_kr);
+
+ FLEXT_DSP_SETUP(BRZ2_ar);
+ FLEXT_SETUP(BRZ2_kr);
+
+ FLEXT_DSP_SETUP(BPZ2_ar);
+ FLEXT_SETUP(BPZ2_kr);
+
+ FLEXT_DSP_SETUP(LFDNoise0_ar);
+
+ FLEXT_DSP_SETUP(LFDNoise1_ar);
+
+ FLEXT_DSP_SETUP(LFDNoise2_ar);
+
+ FLEXT_DSP_SETUP(scadd_ar);
+
+ FLEXT_DSP_SETUP(scsub_ar);
+
+ FLEXT_DSP_SETUP(scmul_ar);
+
+ FLEXT_DSP_SETUP(scdiv_ar);
+
+ FLEXT_DSP_SETUP(Convolution_ar);
+
+ //init ffts
+ init_ffts();
+}
+
+FLEXT_LIB_SETUP(sc4pd,sc4pd_library_setup);
diff --git a/sc4pd/source/ring1.cpp b/sc4pd/source/ring1.cpp
new file mode 100644
index 0000000..9c09e40
--- /dev/null
+++ b/sc4pd/source/ring1.cpp
@@ -0,0 +1,130 @@
+/* sc4pd
+ ring1, ring1~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Evan Parker & Keith Rowe: Dark Rags
+
+*/
+
+#include "sc4pd.hpp"
+
+inline float sc_ring1 (float a, float b)
+{
+ return a*b+a;
+}
+
+
+/* ------------------------ ring1~ -----------------------------*/
+
+class ring1_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(ring1_ar,sc4pd_dsp);
+
+public:
+ ring1_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+
+};
+
+FLEXT_LIB_DSP_V("ring1~",ring1_ar);
+
+ring1_ar::ring1_ar(int argc,t_atom * argv)
+{
+ AddInSignal();
+ AddInSignal();
+ AddOutSignal();
+}
+
+void ring1_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin1 = *in;
+ t_sample *nin2 = *(in+1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ if( *nin2 > 0)
+ (*(nout)++) = sc_ring1( (*(nin1)++), (*(nin2)++) );
+ }
+}
+
+
+
+/* ------------------------ ring1 ------------------------------*/
+
+class ring1_kr
+ :public flext_base
+{
+ FLEXT_HEADER(ring1_kr,flext_base);
+
+public:
+ ring1_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+ void m_set(float f);
+
+private:
+ float b;
+ FLEXT_CALLBACK_F(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("ring1",ring1_kr);
+
+ring1_kr::ring1_kr(int argc,t_atom * argv)
+ :b(0)
+{
+
+ AddInFloat();
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD(1,m_set);
+}
+
+void ring1_kr::m_perform(float f)
+{
+ ToOutFloat(0,sc_ring1(f,b));
+}
+
+void ring1_kr::m_set(float f)
+{
+ b=f;
+}
diff --git a/sc4pd/source/ring2.cpp b/sc4pd/source/ring2.cpp
new file mode 100644
index 0000000..c2432e9
--- /dev/null
+++ b/sc4pd/source/ring2.cpp
@@ -0,0 +1,130 @@
+/* sc4pd
+ ring2, ring2~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Evan Parker & Keith Rowe: Dark Rags
+
+*/
+
+#include "sc4pd.hpp"
+
+inline float sc_ring2 (float a, float b)
+{
+ return a*b+a+b;
+}
+
+
+/* ------------------------ ring2~ -----------------------------*/
+
+class ring2_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(ring2_ar,sc4pd_dsp);
+
+public:
+ ring2_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+
+};
+
+FLEXT_LIB_DSP_V("ring2~",ring2_ar);
+
+ring2_ar::ring2_ar(int argc,t_atom * argv)
+{
+ AddInSignal();
+ AddInSignal();
+ AddOutSignal();
+}
+
+void ring2_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin1 = *in;
+ t_sample *nin2 = *(in+1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ if( *nin2 > 0)
+ (*(nout)++) = sc_ring2( (*(nin1)++), (*(nin2)++) );
+ }
+}
+
+
+
+/* ------------------------ ring2 ------------------------------*/
+
+class ring2_kr
+ :public flext_base
+{
+ FLEXT_HEADER(ring2_kr,flext_base);
+
+public:
+ ring2_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+ void m_set(float f);
+
+private:
+ float b;
+ FLEXT_CALLBACK_F(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("ring2",ring2_kr);
+
+ring2_kr::ring2_kr(int argc,t_atom * argv)
+ :b(0)
+{
+
+ AddInFloat();
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD(1,m_set);
+}
+
+void ring2_kr::m_perform(float f)
+{
+ ToOutFloat(0,sc_ring2(f,b));
+}
+
+void ring2_kr::m_set(float f)
+{
+ b=f;
+}
diff --git a/sc4pd/source/ring3.cpp b/sc4pd/source/ring3.cpp
new file mode 100644
index 0000000..d8de166
--- /dev/null
+++ b/sc4pd/source/ring3.cpp
@@ -0,0 +1,130 @@
+/* sc4pd
+ ring3, ring3~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Evan Parker & Keith Rowe: Dark Rags
+
+*/
+
+#include "sc4pd.hpp"
+
+inline float sc_ring3 (float a, float b)
+{
+ return a*a*b;
+}
+
+
+/* ------------------------ ring3~ -----------------------------*/
+
+class ring3_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(ring3_ar,sc4pd_dsp);
+
+public:
+ ring3_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+
+};
+
+FLEXT_LIB_DSP_V("ring3~",ring3_ar);
+
+ring3_ar::ring3_ar(int argc,t_atom * argv)
+{
+ AddInSignal();
+ AddInSignal();
+ AddOutSignal();
+}
+
+void ring3_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin1 = *in;
+ t_sample *nin2 = *(in+1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ if( *nin2 > 0)
+ (*(nout)++) = sc_ring3( (*(nin1)++), (*(nin2)++) );
+ }
+}
+
+
+
+/* ------------------------ ring3 ------------------------------*/
+
+class ring3_kr
+ :public flext_base
+{
+ FLEXT_HEADER(ring3_kr,flext_base);
+
+public:
+ ring3_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+ void m_set(float f);
+
+private:
+ float b;
+ FLEXT_CALLBACK_F(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("ring3",ring3_kr);
+
+ring3_kr::ring3_kr(int argc,t_atom * argv)
+ :b(0)
+{
+
+ AddInFloat();
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD(1,m_set);
+}
+
+void ring3_kr::m_perform(float f)
+{
+ ToOutFloat(0,sc_ring3(f,b));
+}
+
+void ring3_kr::m_set(float f)
+{
+ b=f;
+}
diff --git a/sc4pd/source/ring4.cpp b/sc4pd/source/ring4.cpp
new file mode 100644
index 0000000..f9c6035
--- /dev/null
+++ b/sc4pd/source/ring4.cpp
@@ -0,0 +1,131 @@
+/* sc4pd
+ ring4, ring4~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Evan Parker & Keith Rowe: Dark Rags
+
+*/
+
+#include "sc4pd.hpp"
+
+
+inline float sc_ring4 (float a, float b)
+{
+ return (a*a*b)-(a*b*b);
+}
+
+
+/* ------------------------ ring4~ -----------------------------*/
+
+class ring4_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(ring4_ar,sc4pd_dsp);
+
+public:
+ ring4_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+
+};
+
+FLEXT_LIB_DSP_V("ring4~",ring4_ar);
+
+ring4_ar::ring4_ar(int argc,t_atom * argv)
+{
+ AddInSignal();
+ AddInSignal();
+ AddOutSignal();
+}
+
+void ring4_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin1 = *in;
+ t_sample *nin2 = *(in+1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ if( *nin2 > 0)
+ (*(nout)++) = sc_ring4( (*(nin1)++), (*(nin2)++) );
+ }
+}
+
+
+
+/* ------------------------ ring4 ------------------------------*/
+
+class ring4_kr
+ :public flext_base
+{
+ FLEXT_HEADER(ring4_kr,flext_base);
+
+public:
+ ring4_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+ void m_set(float f);
+
+private:
+ float b;
+ FLEXT_CALLBACK_F(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("ring4",ring4_kr);
+
+ring4_kr::ring4_kr(int argc,t_atom * argv)
+ :b(0)
+{
+
+ AddInFloat();
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD(1,m_set);
+}
+
+void ring4_kr::m_perform(float f)
+{
+ ToOutFloat(0,sc_ring4(f,b));
+}
+
+void ring4_kr::m_set(float f)
+{
+ b=f;
+}
diff --git a/sc4pd/source/sc+.cpp b/sc4pd/source/sc+.cpp
new file mode 100644
index 0000000..e1a7e26
--- /dev/null
+++ b/sc4pd/source/sc+.cpp
@@ -0,0 +1,113 @@
+/* sc4pd
+ sc+~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Phil Minton & Veryan Weston: Ways Past
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ sc+~ -------------------------------*/
+
+class scadd_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(scadd_ar,sc4pd_dsp);
+
+public:
+ scadd_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set(float f)
+ {
+ m_nextsummand = f;
+ changed = true;
+ }
+
+ float m_nextsummand, m_summand;
+ bool changed;
+
+private:
+ FLEXT_CALLBACK_1(m_set,float);
+};
+
+FLEXT_LIB_DSP_V("sc+~",scadd_ar);
+
+scadd_ar::scadd_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(1,m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_summand = sc_getfloatarg(Args,0);
+
+ AddInSignal("signal");
+ AddInFloat("scalar");
+ AddOutSignal();
+
+ changed = false;
+}
+
+void scadd_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ if (changed)
+ {
+ float xb = m_nextsummand;
+ float slope = CALCSLOPE(xb, m_summand);
+ for (int i = 0; i!=n; ++i)
+ {
+ ZXP(nout) = ZXP(nin) + xb;
+ xb += slope;
+ }
+ m_summand = xb;
+ changed = false;
+ }
+ else
+ {
+ float xb = m_summand;
+
+ for (int i = 0; i!=n; ++i)
+ {
+ ZXP(nout) = ZXP(nin) + xb;
+ }
+ }
+}
+
+
diff --git a/sc4pd/source/sc-.cpp b/sc4pd/source/sc-.cpp
new file mode 100644
index 0000000..0dfd2ce
--- /dev/null
+++ b/sc4pd/source/sc-.cpp
@@ -0,0 +1,142 @@
+/* sc4pd
+ sc-~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Phil Minton & Veryan Weston: Ways
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ sc-~ -------------------------------*/
+
+class scsub_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(scsub_ar,sc4pd_dsp);
+
+public:
+ scsub_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set(float f)
+ {
+ m_nextsubtrahend = f;
+ changed = true;
+ }
+
+ float m_nextsubtrahend, m_subtrahend;
+ bool changed;
+ bool invert;
+
+private:
+ FLEXT_CALLBACK_1(m_set,float);
+};
+
+FLEXT_LIB_DSP_V("sc-~",scsub_ar);
+
+scsub_ar::scsub_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(1,m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_subtrahend = sc_getfloatarg(Args,0);
+
+ invert = sc_inv(Args);
+
+ AddInSignal("signal");
+ AddInFloat("scalar");
+ AddOutSignal();
+
+ changed = false;
+}
+
+void scsub_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ if (invert)
+ {
+ if (changed)
+ {
+ float xb = m_nextsubtrahend;
+ float slope = CALCSLOPE(xb, m_subtrahend);
+ for (int i = 0; i!=n; ++i)
+ {
+ ZXP(nout) = xb - ZXP(nin);
+ xb += slope;
+ }
+ m_subtrahend = xb;
+ changed = false;
+ }
+ else
+ {
+ float xb = m_subtrahend;
+
+ for (int i = 0; i!=n; ++i)
+ {
+ ZXP(nout) = xb - ZXP(nin);
+ }
+ }
+ }
+ else
+ {
+ if (changed)
+ {
+ float xb = m_nextsubtrahend;
+ float slope = CALCSLOPE(xb, m_subtrahend);
+ for (int i = 0; i!=n; ++i)
+ {
+ ZXP(nout) = ZXP(nin) - xb;
+ xb += slope;
+ }
+ m_subtrahend = xb;
+ changed = false;
+ }
+ else
+ {
+ float xb = m_subtrahend;
+
+ for (int i = 0; i!=n; ++i)
+ {
+ ZXP(nout) = ZXP(nin) - xb;
+ }
+ }
+ }
+}
+
diff --git a/sc4pd/source/sc4pd.hpp b/sc4pd/source/sc4pd.hpp
new file mode 100644
index 0000000..13d82c0
--- /dev/null
+++ b/sc4pd/source/sc4pd.hpp
@@ -0,0 +1,128 @@
+/* sc4pd:
+ support functions
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Morton Feldman: For John Cage
+
+*/
+
+#ifndef _SC4PD_HPP
+
+#include <flext.h>
+
+#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 406)
+#error You need at least FLEXT version 0.4.6
+#endif
+
+#include "SC_PlugIn.h"
+#include "support.hpp"
+
+/* this macro has to be redefined to work with flext */
+
+// calculate a slope for control rate interpolation to audio rate.
+//#define CALCSLOPE(next,prev) ((next - prev) * unit->mRate->mSlopeFactor)
+#undef CALCSLOPE
+#define CALCSLOPE(next,prev) ((next - prev) * 1/ Blocksize())
+
+
+
+//#define SAMPLERATE (unit->mRate->mSampleRate)
+#undef SAMPLERATE
+#define SAMPLERATE Samplerate()
+
+//#define BUFLENGTH (unit->mBufLength)
+#undef BUFLENGTH
+#define BUFLENGTH Blocksize()
+
+/* to make sure the behaviour is consistent: */
+
+#undef ZXP
+#define ZXP(z) (*(z)++)
+
+
+
+class sc4pd_dsp
+ : public flext_dsp
+{
+ FLEXT_HEADER(sc4pd_dsp,flext_dsp);
+
+
+/* some initialisation functions, adapted from SC_Rate.cpp*/
+
+ inline float sc_sampledur()
+ {
+ return 1 / Samplerate();
+ }
+
+ inline float sc_radianspersample()
+ {
+ return twopi / Samplerate();
+ }
+
+ inline float sc_bufduration()
+ {
+ return Blocksize() / Samplerate();
+ }
+
+ inline float sc_bufrate()
+ {
+ return 1 / sc_bufduration();
+ }
+
+ inline float sc_slopefactor()
+ {
+ return 1 / Blocksize();
+ }
+
+ inline int sc_filterloops()
+ {
+ return Blocksize() / 3;
+ }
+
+ inline int sc_filterremain()
+ {
+ return Blocksize() % 3;
+ }
+
+ inline float sc_filterslope()
+ {
+ float f = sc_filterloops();
+ if (f == 0)
+ return 0;
+ else
+ return 1. / f;
+ }
+
+};
+
+
+#define _SC4PD_HPP
+#endif
diff --git a/sc4pd/source/scaleneg.cpp b/sc4pd/source/scaleneg.cpp
new file mode 100644
index 0000000..d91b324
--- /dev/null
+++ b/sc4pd/source/scaleneg.cpp
@@ -0,0 +1,125 @@
+/* sc4pd
+ scaleneg, scaleneg(~)
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Keith Rowe & Toshimaru Nakamura: Weather Sky
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ scaleneg~ -----------------------------*/
+
+class scaleneg_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(scaleneg_ar,sc4pd_dsp);
+
+public:
+ scaleneg_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+
+};
+
+FLEXT_LIB_DSP_V("scaleneg~",scaleneg_ar);
+
+scaleneg_ar::scaleneg_ar(int argc,t_atom * argv)
+{
+ AddInSignal();
+ AddInSignal();
+ AddOutSignal();
+}
+
+void scaleneg_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin1 = *in;
+ t_sample *nin2 = *(in+1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ if( *nin2 > 0)
+ (*(nout)++) = sc_scaleneg( (*(nin1)++), (*(nin2)++) );
+ }
+}
+
+
+
+/* ------------------------ scaleneg ------------------------------*/
+
+class scaleneg_kr
+ :public flext_base
+{
+ FLEXT_HEADER(scaleneg_kr,flext_base);
+
+public:
+ scaleneg_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+ void m_set(float f);
+
+private:
+ float b;
+ FLEXT_CALLBACK_F(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("scaleneg",scaleneg_kr);
+
+scaleneg_kr::scaleneg_kr(int argc,t_atom * argv)
+ :b(0)
+{
+
+ AddInFloat();
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD(1,m_set);
+}
+
+void scaleneg_kr::m_perform(float f)
+{
+ ToOutFloat(0,sc_scaleneg(f,b));
+}
+
+void scaleneg_kr::m_set(float f)
+{
+ b=f;
+}
diff --git a/sc4pd/source/scdiv.cpp b/sc4pd/source/scdiv.cpp
new file mode 100644
index 0000000..045d1b4
--- /dev/null
+++ b/sc4pd/source/scdiv.cpp
@@ -0,0 +1,142 @@
+/* sc4pd
+ sc/~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Phil Minton & Veryan Weston: Ways
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ sc/~ -------------------------------*/
+
+class scdiv_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(scdiv_ar,sc4pd_dsp);
+
+public:
+ scdiv_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set(float f)
+ {
+ m_nextdivisor = f;
+ changed = true;
+ }
+
+ float m_nextdivisor, m_divisor;
+ bool changed;
+ bool invert;
+
+private:
+ FLEXT_CALLBACK_1(m_set,float);
+};
+
+FLEXT_LIB_DSP_V("sc/~",scdiv_ar);
+
+scdiv_ar::scdiv_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(1,m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_divisor = sc_getfloatarg(Args,0);
+
+ invert = sc_inv(Args);
+
+ AddInSignal("signal");
+ AddInFloat("scalar");
+ AddOutSignal();
+
+ changed = false;
+}
+
+void scdiv_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ if (invert)
+ {
+ if (changed)
+ {
+ float xb = m_nextdivisor;
+ float slope = CALCSLOPE(xb, m_divisor);
+ for (int i = 0; i!=n; ++i)
+ {
+ ZXP(nout) = xb / ZXP(nin);
+ xb += slope;
+ }
+ m_divisor = xb;
+ changed = false;
+ }
+ else
+ {
+ float xb = m_divisor;
+
+ for (int i = 0; i!=n; ++i)
+ {
+ ZXP(nout) = xb / ZXP(nin);
+ }
+ }
+ }
+ else
+ {
+ if (changed)
+ {
+ float xb = m_nextdivisor;
+ float slope = CALCSLOPE(xb, m_divisor);
+ for (int i = 0; i!=n; ++i)
+ {
+ ZXP(nout) = ZXP(nin) / xb;
+ xb += slope;
+ }
+ m_divisor = xb;
+ changed = false;
+ }
+ else
+ {
+ float xb = m_divisor;
+
+ for (int i = 0; i!=n; ++i)
+ {
+ ZXP(nout) = ZXP(nin) / xb;
+ }
+ }
+ }
+}
+
diff --git a/sc4pd/source/scmul.cpp b/sc4pd/source/scmul.cpp
new file mode 100644
index 0000000..55ac074
--- /dev/null
+++ b/sc4pd/source/scmul.cpp
@@ -0,0 +1,113 @@
+/* sc4pd
+ sc*~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Phil Minton & Veryan Weston: Ways
+
+*/
+
+#include "sc4pd.hpp"
+
+
+/* ------------------------ sc*~ -------------------------------*/
+
+class scmul_ar:
+ public sc4pd_dsp
+{
+ FLEXT_HEADER(scmul_ar,sc4pd_dsp);
+
+public:
+ scmul_ar(int argc, t_atom *argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+ void m_set(float f)
+ {
+ m_nextfactor = f;
+ changed = true;
+ }
+
+ float m_nextfactor, m_factor;
+ bool changed;
+
+private:
+ FLEXT_CALLBACK_1(m_set,float);
+};
+
+FLEXT_LIB_DSP_V("sc*~",scmul_ar);
+
+scmul_ar::scmul_ar(int argc, t_atom *argv)
+{
+ FLEXT_ADDMETHOD(1,m_set);
+
+ //parse arguments
+ AtomList Args(argc,argv);
+
+ m_factor = sc_getfloatarg(Args,0);
+
+ AddInSignal("signal");
+ AddInFloat("scalar");
+ AddOutSignal();
+
+ changed = false;
+}
+
+void scmul_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nin = *in;
+ t_sample *nout = *out;
+
+ if (changed)
+ {
+ float xb = m_nextfactor;
+ float slope = CALCSLOPE(xb, m_factor);
+ for (int i = 0; i!=n; ++i)
+ {
+ ZXP(nout) = ZXP(nin) * xb;
+ xb += slope;
+ }
+ m_factor = xb;
+ changed = false;
+ }
+ else
+ {
+ float xb = m_factor;
+
+ for (int i = 0; i!=n; ++i)
+ {
+ ZXP(nout) = ZXP(nin) * xb;
+ }
+ }
+}
+
+
diff --git a/sc4pd/source/sqrdif.cpp b/sc4pd/source/sqrdif.cpp
new file mode 100644
index 0000000..165ee2b
--- /dev/null
+++ b/sc4pd/source/sqrdif.cpp
@@ -0,0 +1,132 @@
+/* sc4pd
+ sqrdif, sqrdif~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Evan Parker & Keith Rowe: Dark Rags
+
+*/
+
+#include "sc4pd.hpp"
+
+
+inline float sc_sqrdif (float a, float b)
+{
+ float f=a-b;
+ return f*f;
+}
+
+
+/* ------------------------ sqrdif~ -----------------------------*/
+
+class sqrdif_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(sqrdif_ar,sc4pd_dsp);
+
+public:
+ sqrdif_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+
+};
+
+FLEXT_LIB_DSP_V("sqrdif~",sqrdif_ar);
+
+sqrdif_ar::sqrdif_ar(int argc,t_atom * argv)
+{
+ AddInSignal();
+ AddInSignal();
+ AddOutSignal();
+}
+
+void sqrdif_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin1 = *in;
+ t_sample *nin2 = *(in+1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ if( *nin2 > 0)
+ (*(nout)++) = sc_sqrdif( (*(nin1)++), (*(nin2)++) );
+ }
+}
+
+
+
+/* ------------------------ sqrdif ------------------------------*/
+
+class sqrdif_kr
+ :public flext_base
+{
+ FLEXT_HEADER(sqrdif_kr,flext_base);
+
+public:
+ sqrdif_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+ void m_set(float f);
+
+private:
+ float b;
+ FLEXT_CALLBACK_F(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("sqrdif",sqrdif_kr);
+
+sqrdif_kr::sqrdif_kr(int argc,t_atom * argv)
+ :b(0)
+{
+
+ AddInFloat();
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD(1,m_set);
+}
+
+void sqrdif_kr::m_perform(float f)
+{
+ ToOutFloat(0,sc_sqrdif(f,b));
+}
+
+void sqrdif_kr::m_set(float f)
+{
+ b=f;
+}
diff --git a/sc4pd/source/sqrsum.cpp b/sc4pd/source/sqrsum.cpp
new file mode 100644
index 0000000..756c07e
--- /dev/null
+++ b/sc4pd/source/sqrsum.cpp
@@ -0,0 +1,132 @@
+/* sc4pd
+ sqrsum, sqrsum~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Evan Parker & Keith Rowe: Dark Rags
+
+*/
+
+#include "sc4pd.hpp"
+
+
+inline float sc_sqrsum (float a, float b)
+{
+ float f=a+b;
+ return f*f;
+}
+
+
+/* ------------------------ sqrsum~ -----------------------------*/
+
+class sqrsum_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(sqrsum_ar,sc4pd_dsp);
+
+public:
+ sqrsum_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+
+};
+
+FLEXT_LIB_DSP_V("sqrsum~",sqrsum_ar);
+
+sqrsum_ar::sqrsum_ar(int argc,t_atom * argv)
+{
+ AddInSignal();
+ AddInSignal();
+ AddOutSignal();
+}
+
+void sqrsum_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin1 = *in;
+ t_sample *nin2 = *(in+1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ if( *nin2 > 0)
+ (*(nout)++) = sc_sqrsum( (*(nin1)++), (*(nin2)++) );
+ }
+}
+
+
+
+/* ------------------------ sqrsum ------------------------------*/
+
+class sqrsum_kr
+ :public flext_base
+{
+ FLEXT_HEADER(sqrsum_kr,flext_base);
+
+public:
+ sqrsum_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+ void m_set(float f);
+
+private:
+ float b;
+ FLEXT_CALLBACK_F(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("sqrsum",sqrsum_kr);
+
+sqrsum_kr::sqrsum_kr(int argc,t_atom * argv)
+ :b(0)
+{
+
+ AddInFloat();
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD(1,m_set);
+}
+
+void sqrsum_kr::m_perform(float f)
+{
+ ToOutFloat(0,sc_sqrsum(f,b));
+}
+
+void sqrsum_kr::m_set(float f)
+{
+ b=f;
+}
diff --git a/sc4pd/source/sumsqr.cpp b/sc4pd/source/sumsqr.cpp
new file mode 100644
index 0000000..518eb01
--- /dev/null
+++ b/sc4pd/source/sumsqr.cpp
@@ -0,0 +1,131 @@
+/* sc4pd
+ sumsqr, sumsqr~
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Evan Parker & Keith Rowe: Dark Rags
+
+*/
+
+#include "sc4pd.hpp"
+
+
+inline float sc_sumsqr (float a, float b)
+{
+ return a*a+b*b;
+}
+
+
+/* ------------------------ sumsqr~ -----------------------------*/
+
+class sumsqr_ar
+ :public sc4pd_dsp
+{
+ FLEXT_HEADER(sumsqr_ar,sc4pd_dsp);
+
+public:
+ sumsqr_ar(int argc,t_atom * argv);
+
+protected:
+ virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
+
+private:
+
+};
+
+FLEXT_LIB_DSP_V("sumsqr~",sumsqr_ar);
+
+sumsqr_ar::sumsqr_ar(int argc,t_atom * argv)
+{
+ AddInSignal();
+ AddInSignal();
+ AddOutSignal();
+}
+
+void sumsqr_ar::m_signal(int n, t_sample *const *in,
+ t_sample *const *out)
+{
+ t_sample *nout = *out;
+ t_sample *nin1 = *in;
+ t_sample *nin2 = *(in+1);
+
+ for (int i = 0; i!= n;++i)
+ {
+ if( *nin2 > 0)
+ (*(nout)++) = sc_sumsqr( (*(nin1)++), (*(nin2)++) );
+ }
+}
+
+
+
+/* ------------------------ sumsqr ------------------------------*/
+
+class sumsqr_kr
+ :public flext_base
+{
+ FLEXT_HEADER(sumsqr_kr,flext_base);
+
+public:
+ sumsqr_kr(int argc,t_atom * argv);
+
+protected:
+ void m_perform(float f);
+ void m_set(float f);
+
+private:
+ float b;
+ FLEXT_CALLBACK_F(m_perform);
+ FLEXT_CALLBACK_F(m_set);
+};
+
+FLEXT_LIB_V("sumsqr",sumsqr_kr);
+
+sumsqr_kr::sumsqr_kr(int argc,t_atom * argv)
+ :b(0)
+{
+
+ AddInFloat();
+ AddInFloat();
+ AddOutFloat();
+
+ FLEXT_ADDMETHOD(0,m_perform);
+ FLEXT_ADDMETHOD(1,m_set);
+}
+
+void sumsqr_kr::m_perform(float f)
+{
+ ToOutFloat(0,sc_sumsqr(f,b));
+}
+
+void sumsqr_kr::m_set(float f)
+{
+ b=f;
+}
diff --git a/sc4pd/source/support.cpp b/sc4pd/source/support.cpp
new file mode 100644
index 0000000..e753056
--- /dev/null
+++ b/sc4pd/source/support.cpp
@@ -0,0 +1,184 @@
+/* sc4pd:
+ support functions
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Nmperign & Guenter Mueller: More Gloom, More Light
+
+*/
+
+#include "sc4pd.hpp"
+
+#include <flsupport.h>
+
+
+bool sc_add (flext::AtomList& a)
+{
+ for (int i = 0; i!=a.Count();++i)
+ {
+ if ( flext::IsSymbol(a[i]) )
+ {
+ const char * teststring;
+ teststring = flext::GetString(a[i]);
+ if((strcmp(teststring,"add"))==0)
+ return true;
+ }
+ }
+ return false;
+}
+
+float sc_getfloatarg (flext::AtomList& a,int i)
+{
+ if (a.Count() > 0 && a.Count() > i)
+ return flext::GetAFloat(a[i]);
+ else
+ return 0;
+}
+
+bool sc_ar(flext::AtomList& a)
+{
+ for (int i = 0; i!=a.Count();++i)
+ {
+ if ( flext::IsSymbol(a[i]) )
+ {
+ const char * teststring;
+ teststring = flext::GetString(a[i]);
+ if((strcmp(teststring,"ar"))==0)
+ return true;
+ }
+ }
+ return false;
+}
+
+bool sc_inv(flext::AtomList& a)
+{
+ for (int i = 0; i!=a.Count();++i)
+ {
+ if ( flext::IsSymbol(a[i]) )
+ {
+ const char * teststring;
+ teststring = flext::GetString(a[i]);
+ if((strcmp(teststring,"inv"))==0)
+ return true;
+ }
+ }
+ return false;
+}
+
+int32 timeseed()
+{
+ static int32 count = 0;
+
+ double time = flext::GetOSTime();
+
+ double sec = trunc(time);
+ double usec = (time-sec)*1e6;
+
+ time_t tsec = sec;
+ useconds_t tusec =usec; /* not exacty the way, it's calculated
+ in SuperCollider, but it's only
+ the seed */
+
+ return (int32)tsec ^ (int32)tusec ^ count--;
+}
+
+/* from Convolution.cpp */
+extern "C"
+{
+ float *cosTable[32];
+ float *fftWindow[32];
+}
+
+
+float* create_cosTable(int log2n)
+{
+ int size = 1 << log2n;
+ int size2 = size / 4 + 1;
+ float *win = (float*)malloc(size2 * sizeof(float));
+ double winc = twopi / size;
+ for (int i=0; i<size2; ++i) {
+ double w = i * winc;
+ win[i] = cos(w);
+ }
+ return win;
+}
+
+float* create_fftwindow(int log2n)
+{
+ int size = 1 << log2n;
+ float *win = (float*)malloc(size * sizeof(float));
+ //double winc = twopi / size;
+ double winc = pi / size;
+ for (int i=0; i<size; ++i) {
+ double w = i * winc;
+ //win[i] = 0.5 - 0.5 * cos(w);
+ win[i] = sin(w);
+ }
+ return win;
+}
+
+void init_ffts()
+{
+#if __VEC__
+
+ for (int i=0; i<32; ++i) {
+ fftsetup[i] = 0;
+ }
+ for (int i=0; i<15; ++i) {
+ fftsetup[i] = create_fftsetup(i, kFFTRadix2);
+ }
+#else
+ for (int i=0; i<32; ++i) {
+ cosTable[i] = 0;
+ fftWindow[i] = 0;
+ }
+ for (int i=3; i<15; ++i) {
+ cosTable[i] = create_cosTable(i);
+ fftWindow[i] = create_fftwindow(i);
+ }
+#endif
+}
+
+void DoWindowing(int log2n, float * fftbuf, int bufsize)
+{
+ float *win = fftWindow[log2n];
+
+ //printf("fail? %i %d /n", log2n, win);
+
+ if (!win) return;
+ float *in = fftbuf - 1;
+ win--;
+
+ for (int i=0; i<bufsize; ++i) {
+ *++in *= *++win;
+ }
+}
+
+#include "fftlib.c"
diff --git a/sc4pd/source/support.hpp b/sc4pd/source/support.hpp
new file mode 100644
index 0000000..12885cb
--- /dev/null
+++ b/sc4pd/source/support.hpp
@@ -0,0 +1,124 @@
+/* sc4pd:
+ support functions
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to: Phosphor
+
+*/
+
+#ifndef _SUPPORT_HPP
+#define _SUPPORT_HPP
+
+#include <flext.h>
+#include "SC_PlugIn.h"
+
+
+#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 406)
+#error You need at least FLEXT version 0.4.6
+#endif
+
+
+/* for argument parsing */
+bool sc_add (flext::AtomList& a);
+float sc_getfloatarg (flext::AtomList& a,int i);
+bool sc_ar(flext::AtomList& a);
+bool sc_inv(flext::AtomList& a);
+
+
+/* for rngs */
+
+// macros to put rgen state in registers
+#define RGET \
+ uint32 s1 = rgen.s1; \
+ uint32 s2 = rgen.s2; \
+ uint32 s3 = rgen.s3;
+
+#define RPUT \
+ rgen.s1 = s1; \
+ rgen.s2 = s2; \
+ rgen.s3 = s3;
+
+int32 timeseed();
+
+/* cubic interpolation from DelayUGens.cpp */
+inline float cubicinterp(float x, float y0, float y1, float y2, float y3)
+{
+ // 4-point, 3rd-order Hermite (x-form)
+ float c0 = y1;
+ float c1 = 0.5f * (y2 - y0);
+ float c2 = y0 - 2.5f * y1 + 2.f * y2 - 0.5f * y3;
+ float c3 = 0.5f * (y3 - y0) + 1.5f * (y1 - y2);
+
+ return ((c3 * x + c2) * x + c1) * x + c0;
+}
+
+/* feedback calculation from DelayUGens.cpp */
+inline float CalcFeedback(float delaytime, float decaytime)
+{
+ if (delaytime == 0.f) {
+ return 0.f;
+ } else if (decaytime > 0.f) {
+ return exp(log001 * delaytime / decaytime);
+ } else if (decaytime < 0.f) {
+ return -exp(log001 * delaytime / -decaytime);
+ } else {
+ return 0.f;
+ }
+}
+
+
+/* this is adapted from thomas grill's xsample:
+xsample - extended sample objects for Max/MSP and pd (pure data)
+
+Copyright (c) 2001-2004 Thomas Grill (xovo@gmx.net)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+*/
+
+#define SETSIGFUN(VAR,FUN) v_##VAR = FUN
+
+#define DEFSIGFUN(NAME) void NAME(int n,t_sample *const *in,t_sample *const *out)
+
+#define DEFSIGCALL(NAME) \
+ inline void NAME(int n,t_sample *const *in,t_sample *const *out) \
+ { (this->*v_##NAME)(n,in,out); } \
+ void (thisType::*v_##NAME)(int n,t_sample *const *invecs,t_sample *const *outvecs)
+
+#define SIGFUN(FUN) &thisType::FUN
+
+
+/* from Convolution.cpp */
+void init_ffts();
+float* create_fftwindow(int log2n);
+float* create_cosTable(int log2n);
+void DoWindowing(int log2n, float * fftbuf, int bufsize);
+
+#endif
diff --git a/sc4pd/source/template.cpp b/sc4pd/source/template.cpp
new file mode 100644
index 0000000..15d9f06
--- /dev/null
+++ b/sc4pd/source/template.cpp
@@ -0,0 +1,37 @@
+/* sc4pd
+
+ Copyright (c) 2004 Tim Blechmann.
+
+ This code is derived from:
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Based on:
+ PureData by Miller Puckette and others.
+ http://www.crca.ucsd.edu/~msp/software.html
+ FLEXT by Thomas Grill
+ http://www.parasitaere-kapazitaeten.net/ext
+ SuperCollider by James McCartney
+ http://www.audiosynth.com
+
+ Coded while listening to:
+
+*/
+
+#include "sc4pd.hpp"