[SCM] python-pyo/master: Imported Upstream version 0.6.9

tiago at users.alioth.debian.org tiago at users.alioth.debian.org
Sun Apr 13 04:14:14 UTC 2014


The following commit has been merged in the master branch:
commit da14e9b15dca57a5131d683f8cbfb975354dece8
Author: Tiago Bortoletto Vaz <tiago at debian.org>
Date:   Sun Apr 13 00:12:46 2014 -0400

    Imported Upstream version 0.6.9

diff --git a/ChangeLog b/ChangeLog
index ef1d32f..e792be3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,48 @@
 
 2013-10-16 belangeo <belangeo at gmail.com>
 
+    * Release tag: 0.6.9.
+    - rev 1185
+
+2014-04-11 belangeo <belangeo at gmail.com>
+
+    * Added lot of methods to PyoTableObject (retify, bipolarGain, invert, lowpass, fadein, fadeout, pow).
+    - rev 1182
+
+2014-04-04 belangeo <belangeo at gmail.com>
+
+    * Added new object: PartialTable, generates waveforms made of inharmonic components.
+    - rev 1177
+
+2014-03-12 belangeo <belangeo at gmail.com>
+
+    * Added a Scope example in examples/utilities.
+    - rev 1168
+
+2013-12-24 belangeo <belangeo at gmail.com>
+
+    * Added new object: STRev, Stereo reverb.
+    - rev 1154
+
+2013-12-24 belangeo <belangeo at gmail.com>
+
+    * Added dataOnly argument to SLMap. User can now control parameters, in ctrl window, that do not accept audio signal but discreet values.
+    - rev 1153
+
+2013-12-10 belangeo <belangeo at gmail.com>
+
+    * Added new object: ComplexRes, Complex one-pole resonator filter.
+    - rev 1148
+
+2013-10-18 belangeo <belangeo at gmail.com>
+
+    * Added new object: TrackHold, Performs a 'thru' and hold on its input signal.
+    - rev 1143
+
+-------------------------------------------------------------------------------------
+
+2013-10-16 belangeo <belangeo at gmail.com>
+
     * Release tag: 0.6.8.
     - rev 1142
 
diff --git a/doc-sphinx/source/api/alphabetical.rst b/doc-sphinx/source/api/alphabetical.rst
index 3b2862b..3ad686f 100644
--- a/doc-sphinx/source/api/alphabetical.rst
+++ b/doc-sphinx/source/api/alphabetical.rst
@@ -39,6 +39,7 @@ Alphabetical class reference
 - :py:class:`Clip` :     Clips a signal to a predefined limit.
 - :py:class:`Cloud` :     Generates random triggers.
 - :py:class:`Compare` :     Comparison object.
+- :py:class:`ComplexRes` :     Complex one-pole resonator filter. 
 - :py:class:`Compress` :     Reduces the dynamic range of an audio signal.
 - :py:class:`ControlRead` :     Reads control values previously stored in text files.
 - :py:class:`ControlRec` :     Records control values and writes them in a text file.
@@ -153,11 +154,13 @@ Alphabetical class reference
 - :py:class:`PVVerb` :     Spectral domain reverberation.
 - :py:class:`Pan` :     Cosinus panner with control on the spread factor.
 - :py:class:`ParaTable` :     Generates parabola window function. 
+- :py:class:`PartialTable` :     Inharmonic waveform generator.
 - :py:class:`Pattern` :     Periodically calls a Python function.
 - :py:class:`Percent` :     Lets pass a certain percentage of the input triggers.
 - :py:class:`Phaser` :     Multi-stages second-order phase shifter allpass filters. 
 - :py:class:`Phasor` :     A simple phase incrementor.
 - :py:class:`PinkNoise` :     A pink noise generator.
+- :py:class:`Pointer2` :     High quality table reader with control on the pointer position.
 - :py:class:`Pointer` :     Table reader with control on the pointer position.
 - :py:class:`PolToCar` :     Performs the polar to cartesian conversion.
 - :py:class:`Port` :     Exponential portamento.
@@ -183,6 +186,7 @@ Alphabetical class reference
 - :py:class:`SLMapPhase` :     SLMap with normalized values for a 'phase' slider.
 - :py:class:`SLMapQ` :     SLMap with normalized values for a 'q' slider.
 - :py:class:`SPan` :     Simple equal power panner.
+- :py:class:`STRev` :     Stereo reverb.
 - :py:class:`SVF` :     Fourth-order state variable filter allowing continuous change of the filter type. 
 - :py:class:`SampHold` :     Performs a sample-and-hold operation on its input. 
 - :py:class:`SawTable` :     Sawtooth waveform generator.
@@ -219,6 +223,7 @@ Alphabetical class reference
 - :py:class:`Timer` :     Reports elapsed time between two trigs.
 - :py:class:`Tone` :     A first-order recursive low-pass filter with variable frequency response.
 - :py:class:`Touchin` :     Get the current value of an after-touch Midi controller.
+- :py:class:`TrackHold` :     Performs a track-and-hold operation on its input. 
 - :py:class:`TranspoToCents` :     Returns the cents value equivalent of a transposition factor.
 - :py:class:`TrigChoice` :     Random generator from user's defined values.
 - :py:class:`TrigEnv` :     Envelope reader generator.
diff --git a/doc-sphinx/source/api/classes/effects.rst b/doc-sphinx/source/api/classes/effects.rst
index be32c61..4a3ce41 100644
--- a/doc-sphinx/source/api/classes/effects.rst
+++ b/doc-sphinx/source/api/classes/effects.rst
@@ -78,3 +78,9 @@ as distortions, delays, chorus and reverbs.
 .. autoclass:: FreqShift
    :members:
 
+*STRev*
+------------
+
+.. autoclass:: STRev
+   :members:
+
diff --git a/doc-sphinx/source/api/classes/filters.rst b/doc-sphinx/source/api/classes/filters.rst
index 865fb9a..358744b 100644
--- a/doc-sphinx/source/api/classes/filters.rst
+++ b/doc-sphinx/source/api/classes/filters.rst
@@ -180,4 +180,9 @@ sinusoidal component according to its frequency.
 .. autoclass:: ButBR
    :members:
 
+*ComplexRes*
+------------
+
+.. autoclass:: ComplexRes
+   :members:
 
diff --git a/doc-sphinx/source/api/classes/tableprocess.rst b/doc-sphinx/source/api/classes/tableprocess.rst
index 3ad98e6..bbb09d2 100644
--- a/doc-sphinx/source/api/classes/tableprocess.rst
+++ b/doc-sphinx/source/api/classes/tableprocess.rst
@@ -62,6 +62,12 @@ store audio samples or algorithmic sequences for future uses.
 .. autoclass:: Pointer
    :members:
 
+*Pointer2*
+-----------------------------------
+
+.. autoclass:: Pointer2
+   :members:
+
 *Pulsar*
 -----------------------------------
 
diff --git a/doc-sphinx/source/api/classes/utils.rst b/doc-sphinx/source/api/classes/utils.rst
index 58ebb12..c84bbab 100644
--- a/doc-sphinx/source/api/classes/utils.rst
+++ b/doc-sphinx/source/api/classes/utils.rst
@@ -125,3 +125,9 @@ Miscellaneous objects.
 .. autoclass:: TranspoToCents
    :members:
 
+*TrackHold*
+-----------------------------------
+
+.. autoclass:: TrackHold
+   :members:
+
diff --git a/doc-sphinx/source/api/functions/audio.rst b/doc-sphinx/source/api/functions/audio.rst
index d9b36ec..eeff482 100644
--- a/doc-sphinx/source/api/functions/audio.rst
+++ b/doc-sphinx/source/api/functions/audio.rst
@@ -3,6 +3,16 @@ Audio Setup
 
 .. module:: pyo
 
+*pa_get_version*
+---------------------------------
+
+.. autofunction:: pa_get_version
+
+*pa_get_version_text*
+---------------------------------
+
+.. autofunction:: pa_get_version_text
+
 *pa_count_host_apis*
 ---------------------------------
 
diff --git a/doc-sphinx/source/conf.py b/doc-sphinx/source/conf.py
index 55ad51d..413f581 100644
--- a/doc-sphinx/source/conf.py
+++ b/doc-sphinx/source/conf.py
@@ -49,9 +49,9 @@ copyright = u'2013, Olivier Bélanger'
 # built documents.
 #
 # The short X.Y version.
-version = '0.6.8'
+version = '0.6.9'
 # The full version, including alpha/beta/rc tags.
-release = '0.6.8'
+release = '0.6.9'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/doc-sphinx/source/index.rst b/doc-sphinx/source/index.rst
index abf1888..0698ad1 100644
--- a/doc-sphinx/source/index.rst
+++ b/doc-sphinx/source/index.rst
@@ -3,7 +3,7 @@
    You can adapt this file completely to your liking, but it should at least
    contain the root `toctree` directive.
 
-Welcome to the Pyo 0.6.8 documentation
+Welcome to the Pyo 0.6.9 documentation
 ===================================================
 
 .. toctree::
diff --git a/embedded/m_pyo.h b/embedded/m_pyo.h
new file mode 100644
index 0000000..c0a5235
--- /dev/null
+++ b/embedded/m_pyo.h
@@ -0,0 +1,312 @@
+#include <stdlib.h>
+#include "Python.h"
+
+#ifndef __m_pyo_h_
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+** Creates a new python interpreter and starts a pyo server in it.
+** Each instance of pyo, in order to be fully independent of other
+** instances, must be started in its own interpreter. An instance
+** can be an object in a programming language or a plugin in a daw.
+**
+** arguments:
+**  chnls : int, number of in/out channels of the pyo server.
+**
+** returns the new python thread's interpreter state.
+*/
+inline PyThreadState * pyo_new_interpreter(int chnls) {
+    char msg[64];
+    PyThreadState *interp;
+    if(!Py_IsInitialized()) {
+        Py_Initialize();
+        PyEval_InitThreads();
+        PyEval_ReleaseLock();
+    }
+    PyEval_AcquireLock();              /* get the GIL */
+    interp = Py_NewInterpreter();      /* add a new sub-interpreter */
+    PyRun_SimpleString("from pyo import *");
+    sprintf(msg, "_s_ = Server(44100, %d, 256, 1, 'embedded')", chnls);
+    PyRun_SimpleString(msg);
+    PyRun_SimpleString("_s_.boot()\n_s_.start()\n_s_.setServer()");
+    PyRun_SimpleString("_in_address_ = _s_.getInputAddr()");
+    PyRun_SimpleString("_out_address_ = _s_.getOutputAddr()");
+    PyRun_SimpleString("_server_id_ = _s_.getServerID()");
+    PyRun_SimpleString("_emb_callback_ = _s_.getEmbedICallbackAddr()");
+    PyEval_ReleaseThread(interp);
+    return interp;
+}
+
+/*
+** Returns the address, as unsigned long, of the pyo input buffer.
+** Used this function if pyo's audio samples resolution is 32-bit.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**
+** returns an "unsigned long" that should be recast to a float pointer.
+*/
+inline unsigned long pyo_get_input_buffer_address(PyThreadState *interp) {
+    PyObject *module, *obj;
+    char *address;
+    unsigned long uadd;
+    PyEval_AcquireThread(interp);
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "_in_address_");
+    address = PyString_AsString(obj);
+    uadd = strtoul(address, NULL, 0);
+    PyEval_ReleaseThread(interp);
+    return uadd;
+}
+
+/*
+** Returns the address, as unsigned long long, of the pyo input buffer.
+** Used this function if pyo's audio samples resolution is 64-bit.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**
+** returns an "unsigned long long" that should be recast to a double pointer.
+*/
+inline unsigned long long pyo_get_input_buffer_address_64(PyThreadState *interp) {
+    PyObject *module, *obj;
+    char *address;
+    unsigned long long uadd;
+    PyEval_AcquireThread(interp);
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "_in_address_");
+    address = PyString_AsString(obj);
+    uadd = strtoull(address, NULL, 0);
+    PyEval_ReleaseThread(interp);
+    return uadd;
+}
+
+/*
+** Returns the address, as unsigned long, of the pyo output buffer.
+** Used this function if pyo's audio samples resolution is 32-bit.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**
+** returns an "unsigned long" that should be recast to a float pointer.
+*/
+inline unsigned long pyo_get_output_buffer_address(PyThreadState *interp) {
+    PyObject *module, *obj;
+    char *address;
+    unsigned long uadd;
+    PyEval_AcquireThread(interp);
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "_out_address_");
+    address = PyString_AsString(obj);
+    uadd = strtoul(address, NULL, 0);
+    PyEval_ReleaseThread(interp);
+    return uadd;
+}
+
+/*
+** Returns the address, as unsigned long, of the pyo embedded callback.
+** This callback must be called in the host's perform routine whenever
+** pyo has to compute a new buffer of samples.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**
+** returns an "unsigned long" that should be recast to a void pointer.
+**
+** The callback should be called with the server id (int) as argument.
+**
+** Prototype:
+** void (*callback)(int);
+*/
+inline unsigned long pyo_get_embedded_callback_address(PyThreadState *interp) {
+    PyObject *module, *obj;
+    char *address;
+    unsigned long uadd;
+    PyEval_AcquireThread(interp);
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "_emb_callback_");
+    address = PyString_AsString(obj);
+    uadd = strtoul(address, NULL, 0);
+    PyEval_ReleaseThread(interp);
+    return uadd;
+}
+
+/*
+** Returns the pyo server id of this thread, as an integer.
+** The id must be pass as argument to the callback function.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**
+** returns an integer.
+*/
+inline int pyo_get_server_id(PyThreadState *interp) {
+    PyObject *module, *obj;
+    int id;
+    PyEval_AcquireThread(interp);
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "_server_id_");
+    id = PyInt_AsLong(obj);
+    PyEval_ReleaseThread(interp);
+    return id;
+}
+
+/*
+** Closes the interpreter linked to the thread state given as argument.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+*/
+inline void pyo_end_interpreter(PyThreadState *interp) {
+    PyEval_AcquireThread(interp);
+    Py_EndInterpreter(interp);
+    PyEval_ReleaseLock();
+}
+
+/*
+** Shutdown and reboot the pyo server while keeping current in/out buffers.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+*/
+inline void pyo_server_reboot(PyThreadState *interp) {
+    PyEval_AcquireThread(interp);
+    PyRun_SimpleString("_s_.setServer()\n_s_.stop()\n_s_.shutdown()");
+    PyRun_SimpleString("_s_.boot(newBuffer=False).start()");
+    PyEval_ReleaseThread(interp);
+}
+
+/*
+** Reboot the pyo server with new sampling rate and buffer size.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**  sr : float, host sampling rate.
+**  bufsize : int, host buffer size.
+*/
+inline void pyo_set_server_params(PyThreadState *interp, float sr, int bufsize) {
+    char msg[64];
+    PyEval_AcquireThread(interp);
+    PyRun_SimpleString("_s_.setServer()\n_s_.stop()\n_s_.shutdown()");
+    sprintf(msg, "_s_.setSamplingRate(%f)", sr);
+    PyRun_SimpleString(msg);
+    sprintf(msg, "_s_.setBufferSize(%d)", bufsize);
+    PyRun_SimpleString(msg);
+    PyRun_SimpleString("_s_.boot(newBuffer=False).start()");
+    PyEval_ReleaseThread(interp);
+}
+
+/*
+** Returns 1 if the pyo server is started for the given thread,
+** Otherwise returns 0.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+*/
+inline int pyo_is_server_started(PyThreadState *interp) {
+    int started;
+    PyObject *module, *obj;
+    PyEval_AcquireThread(interp);
+    PyRun_SimpleString("started = _s_.getIsStarted()");
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "started");
+    started = PyInt_AsLong(obj);
+    PyEval_ReleaseThread(interp);
+    return started;
+}
+
+/*
+** Execute a python script "file" in the given thread's interpreter (interp).
+** A pre-allocated string "msg" must be given to create the python command
+** used for error handling. An integer "add" is needed to indicate if the
+** pyo server should be reboot or not.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**  file : char *, filename to execute as a python script. The file is first
+**                 searched in the current working directory. If not found,
+**                 the module will try to open it as an absolute path.
+**  msg : char *, pre-allocated string used to create the python command
+**                used for error handling.
+**  add, int, if positive, the commands in the file will be added to whatever
+**            is already running in the pyo server. If 0, the server will be
+**            shutdown and reboot before executing the file.
+*/
+inline int pyo_exec_file(PyThreadState *interp, const char *file, char *msg, int add) {
+    int ok, err = 0;
+    PyObject *module, *obj;
+    PyEval_AcquireThread(interp);
+    sprintf(msg, "import os\n_ok_ = os.path.isfile('./%s')", file);
+    PyRun_SimpleString(msg);
+    sprintf(msg, "if not _ok_:\n    _ok_ = os.path.isfile('%s')", file);
+    PyRun_SimpleString(msg);
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "_ok_");
+    ok = PyInt_AsLong(obj);
+    if (ok) {
+        sprintf(msg, "try:\n    execfile('./%s')\nexcept:\n    execfile('%s')",
+                file, file);
+        if (!add) {
+            PyRun_SimpleString("_s_.setServer()\n_s_.stop()\n_s_.shutdown()");
+            PyRun_SimpleString("_s_.boot(newBuffer=False).start()");
+        }
+        PyRun_SimpleString(msg);
+    }
+    else
+        err = 1;
+    PyEval_ReleaseThread(interp);
+    return err;
+}
+
+/*
+** Execute a python statement "msg" in the thread's interpreter "interp".
+** If "debug" is true, the statement will be executed in a try - except
+** block. The error message, if any, will be write back in the *msg
+** pointer and the function will return 1. If no error occured, the
+** function returned 0. If debug is false, the statement is executed
+** without any error checking (unsafe but faster).
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**  msg : char *, pointer to a string containing the statement to execute.
+**                In debug mode, if an error occured, the output log will
+**                be write back in this string.
+**  debug, int, if positive, the commands will be executed in a try-except
+**              statement. If 0, there will be no error checking, which is
+**              much faster.
+*/
+inline int pyo_exec_statement(PyThreadState *interp, char *msg, int debug) {
+    int err = 0;
+    if (debug) {
+        PyObject *module, *obj;
+        char pp[26] = "_error_=None\ntry:\n    ";
+        memmove(msg + strlen(pp), msg, strlen(msg)+1);
+        memmove(msg, pp, strlen(pp));
+        strcat(msg, "\nexcept Exception, _e_:\n    _error_=str(_e_)");
+        PyEval_AcquireThread(interp);
+        PyRun_SimpleString(msg);
+        module = PyImport_AddModule("__main__");
+        obj = PyObject_GetAttrString(module, "_error_");
+        if (obj != Py_None) {
+            strcpy(msg, PyString_AsString(obj));
+            err = 1;
+        }
+        PyEval_ReleaseThread(interp);
+    }
+    else {
+        PyEval_AcquireThread(interp);
+        PyRun_SimpleString(msg);
+        PyEval_ReleaseThread(interp);
+    }
+    return err;
+}
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+}
+#endif
+
+#define __m_pyo_h_
+#endif /* __m_pyo_h_  */
diff --git a/embedded/openframeworks/PyoClass.cpp b/embedded/openframeworks/PyoClass.cpp
new file mode 100644
index 0000000..972541c
--- /dev/null
+++ b/embedded/openframeworks/PyoClass.cpp
@@ -0,0 +1,204 @@
+#include "PyoClass.h"
+
+/*
+** Creates a python interpreter and initialize a pyo server inside it.
+** This function must be called, once per Pyo object, before any other
+** calls.
+**
+** arguments:
+**   nChannels : int, number of in/out channels.
+**   bufferSize : int, number of samples per buffer.
+**   sampleRate : int, sample rate frequency.
+**
+** All arguments should be equal to the host audio settings.
+*/
+void Pyo::setup(int _nChannels, int _bufferSize, int _sampleRate) {
+    nChannels = _nChannels;
+    bufferSize = _bufferSize;
+    sampleRate = _sampleRate;
+    interpreter = pyo_new_interpreter(nChannels);
+    pyoInBuffer = reinterpret_cast<float*>(pyo_get_input_buffer_address(interpreter));
+    pyoOutBuffer = reinterpret_cast<float*>(pyo_get_output_buffer_address(interpreter));
+    pyoCallback = reinterpret_cast<callPtr*>(pyo_get_embedded_callback_address(interpreter));
+    pyoId = pyo_get_server_id(interpreter);
+    pyo_set_server_params(interpreter, sampleRate, bufferSize);
+}
+
+/*
+** Terminates this object's interpreter.
+*/
+Pyo::~Pyo() {
+    pyo_end_interpreter(interpreter);
+}
+
+/*
+** This function fills pyo's input buffers with new samples. Should be called
+** once per process block, inside the host's audioIn function.
+**
+** arguments:
+**   *buffer : float *, float pointer pointing to the host's input buffers.
+*/
+void Pyo::fillin(float *buffer) {
+    for (int i=0; i<(bufferSize*nChannels); i++) pyoInBuffer[i] = buffer[i];
+}
+
+
+/*
+** This function tells pyo to process a buffer of samples and fills the host's
+** output buffer with new samples. Should be called once per process block,
+** inside the host's audioOut function.
+**
+** arguments:
+**   *buffer : float *, float pointer pointing to the host's output buffers.
+*/
+void Pyo::process(float *buffer) {
+    pyoCallback(pyoId);
+    for (int i=0; i<(bufferSize*nChannels); i++) buffer[i] = pyoOutBuffer[i];
+}
+
+/*
+** Execute a python script "file" in the objectès thread's interpreter.
+** An integer "add" is needed to indicate if the pyo server should be
+** reboot or not.
+**
+** arguments:
+**   file : char *, filename to execute as a python script. The file is first
+**                  searched in the current working directory. If not found,
+**                  the module will try to open it as an absolute path.
+**   add, int, if positive, the commands in the file will be added to whatever
+**             is already running in the pyo server. If 0, the server will be
+**             shutdown and reboot before executing the file.
+*/
+int Pyo::loadfile(const char *file, int add) {
+    return pyo_exec_file(interpreter, file, pyoMsg, add);
+}
+
+/*
+** Sends a numerical value to an existing Sig or SigTo object.
+**
+** arguments:
+**   name : const char *, variable name of the object.
+**   value : float, value to be assign.
+**
+** Example:
+**
+** inside the script file:
+**
+** freq = SigTo(value=440, time=0.1, init=440)
+**
+** Inside OpenFrameworks (for a Pyo object named `pyo`):
+**
+** pyo.value("freq", 880);
+*/
+int Pyo::value(const char *name, float value) {
+    sprintf(pyoMsg, "%s.value=%f", name, value);
+    return pyo_exec_statement(interpreter, pyoMsg, 0);
+}
+
+/*
+** Sends an array of numerical values to an existing Sig or SigTo object.
+**
+** arguments:
+**   name : const char *, variable name of the object.
+**   value : float *, array of floats.
+**   len : int, number of elements in the array.
+**
+** Example:
+**
+** inside the script file:
+**
+** freq = SigTo(value=[100,200,300,400], time=0.1, init=[100,200,300,400])
+**
+** Inside OpenFrameworks (for a Pyo object named `pyo`):
+**
+** float frequencies[4] = {150, 250, 350, 450};
+** pyo.value("freq", frequencies, 4);
+*/
+int Pyo::value(const char *name, float *value, int len) {
+    char fchar[32];
+    sprintf(pyoMsg, "%s.value=[", name);
+    for (int i=0; i<len; i++) {
+        sprintf(fchar, "%f,", value[i]);
+        strcat(pyoMsg, fchar);
+    }
+    strcat(pyoMsg, "]");
+    return pyo_exec_statement(interpreter, pyoMsg, 0);
+}
+
+/*
+** Sends a numerical value to a Pyo object's attribute.
+**
+** arguments:
+**   name : const char *, object name and attribute separated by a point.
+**   value : float, value to be assign.
+**
+** Example:
+**
+** inside the script file:
+**
+** filter = Biquad(input=Noise(0.5), freq=1000, q=4, type=2)
+**
+** Inside OpenFrameworks (for a Pyo object named `pyo`):
+**
+** pyo.set("filter.freq", 2000);
+*/
+int Pyo::set(const char *name, float value) {
+    sprintf(pyoMsg, "%s=%f", name, value);
+    return pyo_exec_statement(interpreter, pyoMsg, 0);
+}
+
+/*
+** Sends an array of numerical values to a Pyo object's attribute.
+**
+** arguments:
+**   name : const char *, object name and attribute separated by a point.
+**   value : float *, array of floats.
+**   len : int, number of elements in the array.
+**
+** Example:
+**
+** inside the script file:
+**
+** filters = Biquad(input=Noise(0.5), freq=[250, 500, 1000, 2000], q=5, type=2)
+**
+** Inside OpenFrameworks (for a Pyo object named `pyo`):
+**
+** float frequencies[4] = {350, 700, 1400, 2800};
+** pyo.set("filters.freq", frequencies, 4);
+*/
+int Pyo::set(const char *name, float *value, int len) {
+    char fchar[32];
+    sprintf(pyoMsg, "%s=[", name);
+    for (int i=0; i<len; i++) {
+        sprintf(fchar, "%f,", value[i]);
+        strcat(pyoMsg, fchar);
+    }
+    strcat(pyoMsg, "]");
+    return pyo_exec_statement(interpreter, pyoMsg, 0);
+}
+
+/*
+** Executes any raw valid python statement. With this function, one can dynamically
+** creates and manipulates audio objects and algorithms.
+**
+** arguments:
+**   msg : const char *, pointer to a string containing the statement to execute.
+**
+** Example (for a Pyo object named `pyo`):
+**
+** pyo.exec("pits = [0.001, 0.002, 0.003, 0.004]")
+** pyo.exec("fr = Rossler(pitch=pits, chaos=0.9, mul=250, add=500)")
+** pyo.exec("b = SumOsc(freq=fr, ratio=0.499, index=0.4, mul=0.2).out()")
+*/
+int Pyo::exec(const char *_msg) {
+    strcpy(pyoMsg, _msg);
+    return pyo_exec_statement(interpreter, pyoMsg, 0);
+}
+
+/*
+** Shutdown and reboot the pyo server while keeping current in/out buffers.
+** This will erase audio objects currently active within the server.
+**
+*/void Pyo::clear() {
+    pyo_server_reboot(interpreter);
+}
diff --git a/embedded/openframeworks/PyoClass.h b/embedded/openframeworks/PyoClass.h
new file mode 100644
index 0000000..2ca65b4
--- /dev/null
+++ b/embedded/openframeworks/PyoClass.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "m_pyo.h"
+
+typedef int callPtr(int);
+
+class Pyo {
+    public:
+        ~Pyo();
+        void setup(int nChannels, int bufferSize, int sampleRate);
+        void process(float *buffer);
+        void fillin(float *buffer);
+        void clear();
+        int loadfile(const char *file, int add);
+        int exec(const char *msg);
+        int value(const char *name, float value);
+        int value(const char *name, float *value, int len);
+        int set(const char *name, float value);
+        int set(const char *name, float *value, int len);
+
+    private:
+        int nChannels;
+        int bufferSize;
+        int sampleRate;
+        PyThreadState *interpreter;
+        float *pyoInBuffer;
+        float *pyoOutBuffer;
+        callPtr *pyoCallback;
+        int pyoId;
+        char pyoMsg[262144];
+};
diff --git a/embedded/openframeworks/PyoTemplate/Makefile b/embedded/openframeworks/PyoTemplate/Makefile
new file mode 100644
index 0000000..7a7fe8b
--- /dev/null
+++ b/embedded/openframeworks/PyoTemplate/Makefile
@@ -0,0 +1,13 @@
+# Attempt to load a config.make file.
+# If none is found, project defaults in config.project.make will be used.
+ifneq ($(wildcard config.make),)
+	include config.make
+endif
+
+# make sure the the OF_ROOT location is defined
+ifndef OF_ROOT
+    OF_ROOT=../../..
+endif
+
+# call the project makefile!
+include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
diff --git a/embedded/openframeworks/PyoTemplate/config.make b/embedded/openframeworks/PyoTemplate/config.make
new file mode 100644
index 0000000..2a5b520
--- /dev/null
+++ b/embedded/openframeworks/PyoTemplate/config.make
@@ -0,0 +1,141 @@
+################################################################################
+# CONFIGURE PROJECT MAKEFILE (optional)
+#   This file is where we make project specific configurations.
+################################################################################
+
+################################################################################
+# OF ROOT
+#   The location of your root openFrameworks installation
+#       (default) OF_ROOT = ../../.. 
+################################################################################
+# OF_ROOT = ../../..
+
+################################################################################
+# PROJECT ROOT
+#   The location of the project - a starting place for searching for files
+#       (default) PROJECT_ROOT = . (this directory)
+#    
+################################################################################
+# PROJECT_ROOT = .
+
+################################################################################
+# PROJECT SPECIFIC CHECKS
+#   This is a project defined section to create internal makefile flags to 
+#   conditionally enable or disable the addition of various features within 
+#   this makefile.  For instance, if you want to make changes based on whether
+#   GTK is installed, one might test that here and create a variable to check. 
+################################################################################
+# None
+
+################################################################################
+# PROJECT EXTERNAL SOURCE PATHS
+#   These are fully qualified paths that are not within the PROJECT_ROOT folder.
+#   Like source folders in the PROJECT_ROOT, these paths are subject to 
+#   exlclusion via the PROJECT_EXLCUSIONS list.
+#
+#     (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank) 
+#
+#   Note: Leave a leading space when adding list items with the += operator
+################################################################################
+# PROJECT_EXTERNAL_SOURCE_PATHS = 
+
+################################################################################
+# PROJECT EXCLUSIONS
+#   These makefiles assume that all folders in your current project directory 
+#   and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations
+#   to look for source code. The any folders or files that match any of the 
+#   items in the PROJECT_EXCLUSIONS list below will be ignored.
+#
+#   Each item in the PROJECT_EXCLUSIONS list will be treated as a complete 
+#   string unless teh user adds a wildcard (%) operator to match subdirectories.
+#   GNU make only allows one wildcard for matching.  The second wildcard (%) is
+#   treated literally.
+#
+#      (default) PROJECT_EXCLUSIONS = (blank)
+#
+#		Will automatically exclude the following:
+#
+#			$(PROJECT_ROOT)/bin%
+#			$(PROJECT_ROOT)/obj%
+#			$(PROJECT_ROOT)/%.xcodeproj
+#
+#   Note: Leave a leading space when adding list items with the += operator
+################################################################################
+# PROJECT_EXCLUSIONS =
+
+################################################################################
+# PROJECT LINKER FLAGS
+#	These flags will be sent to the linker when compiling the executable.
+#
+#		(default) PROJECT_LDFLAGS = -Wl,-rpath=./libs
+#
+#   Note: Leave a leading space when adding list items with the += operator
+#
+# Currently, shared libraries that are needed are copied to the 
+# $(PROJECT_ROOT)/bin/libs directory.  The following LDFLAGS tell the linker to
+# add a runtime path to search for those shared libraries, since they aren't 
+# incorporated directly into the final executable application binary.
+################################################################################
+PROJECT_LDFLAGS = `python-config --ldflags`
+
+################################################################################
+# PROJECT DEFINES
+#   Create a space-delimited list of DEFINES. The list will be converted into 
+#   CFLAGS with the "-D" flag later in the makefile.
+#
+#		(default) PROJECT_DEFINES = (blank)
+#
+#   Note: Leave a leading space when adding list items with the += operator
+################################################################################
+# PROJECT_DEFINES = 
+
+################################################################################
+# PROJECT CFLAGS
+#   This is a list of fully qualified CFLAGS required when compiling for this 
+#   project.  These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS 
+#   defined in your platform specific core configuration files. These flags are
+#   presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below. 
+#
+#		(default) PROJECT_CFLAGS = (blank)
+#
+#   Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in 
+#   your platform specific configuration file will be applied by default and 
+#   further flags here may not be needed.
+#
+#   Note: Leave a leading space when adding list items with the += operator
+################################################################################
+PROJECT_CFLAGS = `python-config --cflags`
+
+################################################################################
+# PROJECT OPTIMIZATION CFLAGS
+#   These are lists of CFLAGS that are target-specific.  While any flags could 
+#   be conditionally added, they are usually limited to optimization flags. 
+#   These flags are added BEFORE the PROJECT_CFLAGS.
+#
+#   PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets.
+#
+#		(default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank)
+#
+#   PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets.
+#
+#		(default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank)
+#
+#   Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the 
+#   PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration 
+#   file will be applied by default and further optimization flags here may not 
+#   be needed.
+#
+#   Note: Leave a leading space when adding list items with the += operator
+################################################################################
+# PROJECT_OPTIMIZATION_CFLAGS_RELEASE = 
+# PROJECT_OPTIMIZATION_CFLAGS_DEBUG = 
+
+################################################################################
+# PROJECT COMPILERS
+#   Custom compilers can be set for CC and CXX
+#		(default) PROJECT_CXX = (blank)
+#		(default) PROJECT_CC = (blank)
+#   Note: Leave a leading space when adding list items with the += operator
+################################################################################
+# PROJECT_CXX = 
+# PROJECT_CC = 
diff --git a/embedded/openframeworks/PyoTemplate/scripts/stereoDelay.py b/embedded/openframeworks/PyoTemplate/scripts/stereoDelay.py
new file mode 100644
index 0000000..0d98f4e
--- /dev/null
+++ b/embedded/openframeworks/PyoTemplate/scripts/stereoDelay.py
@@ -0,0 +1,5 @@
+# Get the input sound and apply a stereo delay + reverb on it.
+st_input = Input([0,1])
+st_delay = Delay(st_input, delay=[.4, .5], feedback=0.7)
+st_rev = WGVerb(st_delay, feedback=0.8, cutoff=4000, bal=0.25).out()
+
diff --git a/embedded/openframeworks/PyoTemplate/src/PyoClass.cpp b/embedded/openframeworks/PyoTemplate/src/PyoClass.cpp
new file mode 100644
index 0000000..972541c
--- /dev/null
+++ b/embedded/openframeworks/PyoTemplate/src/PyoClass.cpp
@@ -0,0 +1,204 @@
+#include "PyoClass.h"
+
+/*
+** Creates a python interpreter and initialize a pyo server inside it.
+** This function must be called, once per Pyo object, before any other
+** calls.
+**
+** arguments:
+**   nChannels : int, number of in/out channels.
+**   bufferSize : int, number of samples per buffer.
+**   sampleRate : int, sample rate frequency.
+**
+** All arguments should be equal to the host audio settings.
+*/
+void Pyo::setup(int _nChannels, int _bufferSize, int _sampleRate) {
+    nChannels = _nChannels;
+    bufferSize = _bufferSize;
+    sampleRate = _sampleRate;
+    interpreter = pyo_new_interpreter(nChannels);
+    pyoInBuffer = reinterpret_cast<float*>(pyo_get_input_buffer_address(interpreter));
+    pyoOutBuffer = reinterpret_cast<float*>(pyo_get_output_buffer_address(interpreter));
+    pyoCallback = reinterpret_cast<callPtr*>(pyo_get_embedded_callback_address(interpreter));
+    pyoId = pyo_get_server_id(interpreter);
+    pyo_set_server_params(interpreter, sampleRate, bufferSize);
+}
+
+/*
+** Terminates this object's interpreter.
+*/
+Pyo::~Pyo() {
+    pyo_end_interpreter(interpreter);
+}
+
+/*
+** This function fills pyo's input buffers with new samples. Should be called
+** once per process block, inside the host's audioIn function.
+**
+** arguments:
+**   *buffer : float *, float pointer pointing to the host's input buffers.
+*/
+void Pyo::fillin(float *buffer) {
+    for (int i=0; i<(bufferSize*nChannels); i++) pyoInBuffer[i] = buffer[i];
+}
+
+
+/*
+** This function tells pyo to process a buffer of samples and fills the host's
+** output buffer with new samples. Should be called once per process block,
+** inside the host's audioOut function.
+**
+** arguments:
+**   *buffer : float *, float pointer pointing to the host's output buffers.
+*/
+void Pyo::process(float *buffer) {
+    pyoCallback(pyoId);
+    for (int i=0; i<(bufferSize*nChannels); i++) buffer[i] = pyoOutBuffer[i];
+}
+
+/*
+** Execute a python script "file" in the objectès thread's interpreter.
+** An integer "add" is needed to indicate if the pyo server should be
+** reboot or not.
+**
+** arguments:
+**   file : char *, filename to execute as a python script. The file is first
+**                  searched in the current working directory. If not found,
+**                  the module will try to open it as an absolute path.
+**   add, int, if positive, the commands in the file will be added to whatever
+**             is already running in the pyo server. If 0, the server will be
+**             shutdown and reboot before executing the file.
+*/
+int Pyo::loadfile(const char *file, int add) {
+    return pyo_exec_file(interpreter, file, pyoMsg, add);
+}
+
+/*
+** Sends a numerical value to an existing Sig or SigTo object.
+**
+** arguments:
+**   name : const char *, variable name of the object.
+**   value : float, value to be assign.
+**
+** Example:
+**
+** inside the script file:
+**
+** freq = SigTo(value=440, time=0.1, init=440)
+**
+** Inside OpenFrameworks (for a Pyo object named `pyo`):
+**
+** pyo.value("freq", 880);
+*/
+int Pyo::value(const char *name, float value) {
+    sprintf(pyoMsg, "%s.value=%f", name, value);
+    return pyo_exec_statement(interpreter, pyoMsg, 0);
+}
+
+/*
+** Sends an array of numerical values to an existing Sig or SigTo object.
+**
+** arguments:
+**   name : const char *, variable name of the object.
+**   value : float *, array of floats.
+**   len : int, number of elements in the array.
+**
+** Example:
+**
+** inside the script file:
+**
+** freq = SigTo(value=[100,200,300,400], time=0.1, init=[100,200,300,400])
+**
+** Inside OpenFrameworks (for a Pyo object named `pyo`):
+**
+** float frequencies[4] = {150, 250, 350, 450};
+** pyo.value("freq", frequencies, 4);
+*/
+int Pyo::value(const char *name, float *value, int len) {
+    char fchar[32];
+    sprintf(pyoMsg, "%s.value=[", name);
+    for (int i=0; i<len; i++) {
+        sprintf(fchar, "%f,", value[i]);
+        strcat(pyoMsg, fchar);
+    }
+    strcat(pyoMsg, "]");
+    return pyo_exec_statement(interpreter, pyoMsg, 0);
+}
+
+/*
+** Sends a numerical value to a Pyo object's attribute.
+**
+** arguments:
+**   name : const char *, object name and attribute separated by a point.
+**   value : float, value to be assign.
+**
+** Example:
+**
+** inside the script file:
+**
+** filter = Biquad(input=Noise(0.5), freq=1000, q=4, type=2)
+**
+** Inside OpenFrameworks (for a Pyo object named `pyo`):
+**
+** pyo.set("filter.freq", 2000);
+*/
+int Pyo::set(const char *name, float value) {
+    sprintf(pyoMsg, "%s=%f", name, value);
+    return pyo_exec_statement(interpreter, pyoMsg, 0);
+}
+
+/*
+** Sends an array of numerical values to a Pyo object's attribute.
+**
+** arguments:
+**   name : const char *, object name and attribute separated by a point.
+**   value : float *, array of floats.
+**   len : int, number of elements in the array.
+**
+** Example:
+**
+** inside the script file:
+**
+** filters = Biquad(input=Noise(0.5), freq=[250, 500, 1000, 2000], q=5, type=2)
+**
+** Inside OpenFrameworks (for a Pyo object named `pyo`):
+**
+** float frequencies[4] = {350, 700, 1400, 2800};
+** pyo.set("filters.freq", frequencies, 4);
+*/
+int Pyo::set(const char *name, float *value, int len) {
+    char fchar[32];
+    sprintf(pyoMsg, "%s=[", name);
+    for (int i=0; i<len; i++) {
+        sprintf(fchar, "%f,", value[i]);
+        strcat(pyoMsg, fchar);
+    }
+    strcat(pyoMsg, "]");
+    return pyo_exec_statement(interpreter, pyoMsg, 0);
+}
+
+/*
+** Executes any raw valid python statement. With this function, one can dynamically
+** creates and manipulates audio objects and algorithms.
+**
+** arguments:
+**   msg : const char *, pointer to a string containing the statement to execute.
+**
+** Example (for a Pyo object named `pyo`):
+**
+** pyo.exec("pits = [0.001, 0.002, 0.003, 0.004]")
+** pyo.exec("fr = Rossler(pitch=pits, chaos=0.9, mul=250, add=500)")
+** pyo.exec("b = SumOsc(freq=fr, ratio=0.499, index=0.4, mul=0.2).out()")
+*/
+int Pyo::exec(const char *_msg) {
+    strcpy(pyoMsg, _msg);
+    return pyo_exec_statement(interpreter, pyoMsg, 0);
+}
+
+/*
+** Shutdown and reboot the pyo server while keeping current in/out buffers.
+** This will erase audio objects currently active within the server.
+**
+*/void Pyo::clear() {
+    pyo_server_reboot(interpreter);
+}
diff --git a/embedded/openframeworks/PyoTemplate/src/PyoClass.h b/embedded/openframeworks/PyoTemplate/src/PyoClass.h
new file mode 100644
index 0000000..2ca65b4
--- /dev/null
+++ b/embedded/openframeworks/PyoTemplate/src/PyoClass.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "m_pyo.h"
+
+typedef int callPtr(int);
+
+class Pyo {
+    public:
+        ~Pyo();
+        void setup(int nChannels, int bufferSize, int sampleRate);
+        void process(float *buffer);
+        void fillin(float *buffer);
+        void clear();
+        int loadfile(const char *file, int add);
+        int exec(const char *msg);
+        int value(const char *name, float value);
+        int value(const char *name, float *value, int len);
+        int set(const char *name, float value);
+        int set(const char *name, float *value, int len);
+
+    private:
+        int nChannels;
+        int bufferSize;
+        int sampleRate;
+        PyThreadState *interpreter;
+        float *pyoInBuffer;
+        float *pyoOutBuffer;
+        callPtr *pyoCallback;
+        int pyoId;
+        char pyoMsg[262144];
+};
diff --git a/embedded/openframeworks/PyoTemplate/src/m_pyo.h b/embedded/openframeworks/PyoTemplate/src/m_pyo.h
new file mode 100644
index 0000000..c0a5235
--- /dev/null
+++ b/embedded/openframeworks/PyoTemplate/src/m_pyo.h
@@ -0,0 +1,312 @@
+#include <stdlib.h>
+#include "Python.h"
+
+#ifndef __m_pyo_h_
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+** Creates a new python interpreter and starts a pyo server in it.
+** Each instance of pyo, in order to be fully independent of other
+** instances, must be started in its own interpreter. An instance
+** can be an object in a programming language or a plugin in a daw.
+**
+** arguments:
+**  chnls : int, number of in/out channels of the pyo server.
+**
+** returns the new python thread's interpreter state.
+*/
+inline PyThreadState * pyo_new_interpreter(int chnls) {
+    char msg[64];
+    PyThreadState *interp;
+    if(!Py_IsInitialized()) {
+        Py_Initialize();
+        PyEval_InitThreads();
+        PyEval_ReleaseLock();
+    }
+    PyEval_AcquireLock();              /* get the GIL */
+    interp = Py_NewInterpreter();      /* add a new sub-interpreter */
+    PyRun_SimpleString("from pyo import *");
+    sprintf(msg, "_s_ = Server(44100, %d, 256, 1, 'embedded')", chnls);
+    PyRun_SimpleString(msg);
+    PyRun_SimpleString("_s_.boot()\n_s_.start()\n_s_.setServer()");
+    PyRun_SimpleString("_in_address_ = _s_.getInputAddr()");
+    PyRun_SimpleString("_out_address_ = _s_.getOutputAddr()");
+    PyRun_SimpleString("_server_id_ = _s_.getServerID()");
+    PyRun_SimpleString("_emb_callback_ = _s_.getEmbedICallbackAddr()");
+    PyEval_ReleaseThread(interp);
+    return interp;
+}
+
+/*
+** Returns the address, as unsigned long, of the pyo input buffer.
+** Used this function if pyo's audio samples resolution is 32-bit.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**
+** returns an "unsigned long" that should be recast to a float pointer.
+*/
+inline unsigned long pyo_get_input_buffer_address(PyThreadState *interp) {
+    PyObject *module, *obj;
+    char *address;
+    unsigned long uadd;
+    PyEval_AcquireThread(interp);
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "_in_address_");
+    address = PyString_AsString(obj);
+    uadd = strtoul(address, NULL, 0);
+    PyEval_ReleaseThread(interp);
+    return uadd;
+}
+
+/*
+** Returns the address, as unsigned long long, of the pyo input buffer.
+** Used this function if pyo's audio samples resolution is 64-bit.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**
+** returns an "unsigned long long" that should be recast to a double pointer.
+*/
+inline unsigned long long pyo_get_input_buffer_address_64(PyThreadState *interp) {
+    PyObject *module, *obj;
+    char *address;
+    unsigned long long uadd;
+    PyEval_AcquireThread(interp);
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "_in_address_");
+    address = PyString_AsString(obj);
+    uadd = strtoull(address, NULL, 0);
+    PyEval_ReleaseThread(interp);
+    return uadd;
+}
+
+/*
+** Returns the address, as unsigned long, of the pyo output buffer.
+** Used this function if pyo's audio samples resolution is 32-bit.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**
+** returns an "unsigned long" that should be recast to a float pointer.
+*/
+inline unsigned long pyo_get_output_buffer_address(PyThreadState *interp) {
+    PyObject *module, *obj;
+    char *address;
+    unsigned long uadd;
+    PyEval_AcquireThread(interp);
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "_out_address_");
+    address = PyString_AsString(obj);
+    uadd = strtoul(address, NULL, 0);
+    PyEval_ReleaseThread(interp);
+    return uadd;
+}
+
+/*
+** Returns the address, as unsigned long, of the pyo embedded callback.
+** This callback must be called in the host's perform routine whenever
+** pyo has to compute a new buffer of samples.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**
+** returns an "unsigned long" that should be recast to a void pointer.
+**
+** The callback should be called with the server id (int) as argument.
+**
+** Prototype:
+** void (*callback)(int);
+*/
+inline unsigned long pyo_get_embedded_callback_address(PyThreadState *interp) {
+    PyObject *module, *obj;
+    char *address;
+    unsigned long uadd;
+    PyEval_AcquireThread(interp);
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "_emb_callback_");
+    address = PyString_AsString(obj);
+    uadd = strtoul(address, NULL, 0);
+    PyEval_ReleaseThread(interp);
+    return uadd;
+}
+
+/*
+** Returns the pyo server id of this thread, as an integer.
+** The id must be pass as argument to the callback function.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**
+** returns an integer.
+*/
+inline int pyo_get_server_id(PyThreadState *interp) {
+    PyObject *module, *obj;
+    int id;
+    PyEval_AcquireThread(interp);
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "_server_id_");
+    id = PyInt_AsLong(obj);
+    PyEval_ReleaseThread(interp);
+    return id;
+}
+
+/*
+** Closes the interpreter linked to the thread state given as argument.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+*/
+inline void pyo_end_interpreter(PyThreadState *interp) {
+    PyEval_AcquireThread(interp);
+    Py_EndInterpreter(interp);
+    PyEval_ReleaseLock();
+}
+
+/*
+** Shutdown and reboot the pyo server while keeping current in/out buffers.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+*/
+inline void pyo_server_reboot(PyThreadState *interp) {
+    PyEval_AcquireThread(interp);
+    PyRun_SimpleString("_s_.setServer()\n_s_.stop()\n_s_.shutdown()");
+    PyRun_SimpleString("_s_.boot(newBuffer=False).start()");
+    PyEval_ReleaseThread(interp);
+}
+
+/*
+** Reboot the pyo server with new sampling rate and buffer size.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**  sr : float, host sampling rate.
+**  bufsize : int, host buffer size.
+*/
+inline void pyo_set_server_params(PyThreadState *interp, float sr, int bufsize) {
+    char msg[64];
+    PyEval_AcquireThread(interp);
+    PyRun_SimpleString("_s_.setServer()\n_s_.stop()\n_s_.shutdown()");
+    sprintf(msg, "_s_.setSamplingRate(%f)", sr);
+    PyRun_SimpleString(msg);
+    sprintf(msg, "_s_.setBufferSize(%d)", bufsize);
+    PyRun_SimpleString(msg);
+    PyRun_SimpleString("_s_.boot(newBuffer=False).start()");
+    PyEval_ReleaseThread(interp);
+}
+
+/*
+** Returns 1 if the pyo server is started for the given thread,
+** Otherwise returns 0.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+*/
+inline int pyo_is_server_started(PyThreadState *interp) {
+    int started;
+    PyObject *module, *obj;
+    PyEval_AcquireThread(interp);
+    PyRun_SimpleString("started = _s_.getIsStarted()");
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "started");
+    started = PyInt_AsLong(obj);
+    PyEval_ReleaseThread(interp);
+    return started;
+}
+
+/*
+** Execute a python script "file" in the given thread's interpreter (interp).
+** A pre-allocated string "msg" must be given to create the python command
+** used for error handling. An integer "add" is needed to indicate if the
+** pyo server should be reboot or not.
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**  file : char *, filename to execute as a python script. The file is first
+**                 searched in the current working directory. If not found,
+**                 the module will try to open it as an absolute path.
+**  msg : char *, pre-allocated string used to create the python command
+**                used for error handling.
+**  add, int, if positive, the commands in the file will be added to whatever
+**            is already running in the pyo server. If 0, the server will be
+**            shutdown and reboot before executing the file.
+*/
+inline int pyo_exec_file(PyThreadState *interp, const char *file, char *msg, int add) {
+    int ok, err = 0;
+    PyObject *module, *obj;
+    PyEval_AcquireThread(interp);
+    sprintf(msg, "import os\n_ok_ = os.path.isfile('./%s')", file);
+    PyRun_SimpleString(msg);
+    sprintf(msg, "if not _ok_:\n    _ok_ = os.path.isfile('%s')", file);
+    PyRun_SimpleString(msg);
+    module = PyImport_AddModule("__main__");
+    obj = PyObject_GetAttrString(module, "_ok_");
+    ok = PyInt_AsLong(obj);
+    if (ok) {
+        sprintf(msg, "try:\n    execfile('./%s')\nexcept:\n    execfile('%s')",
+                file, file);
+        if (!add) {
+            PyRun_SimpleString("_s_.setServer()\n_s_.stop()\n_s_.shutdown()");
+            PyRun_SimpleString("_s_.boot(newBuffer=False).start()");
+        }
+        PyRun_SimpleString(msg);
+    }
+    else
+        err = 1;
+    PyEval_ReleaseThread(interp);
+    return err;
+}
+
+/*
+** Execute a python statement "msg" in the thread's interpreter "interp".
+** If "debug" is true, the statement will be executed in a try - except
+** block. The error message, if any, will be write back in the *msg
+** pointer and the function will return 1. If no error occured, the
+** function returned 0. If debug is false, the statement is executed
+** without any error checking (unsafe but faster).
+**
+** arguments:
+**  interp : pointer, pointer to the targeted Python thread state.
+**  msg : char *, pointer to a string containing the statement to execute.
+**                In debug mode, if an error occured, the output log will
+**                be write back in this string.
+**  debug, int, if positive, the commands will be executed in a try-except
+**              statement. If 0, there will be no error checking, which is
+**              much faster.
+*/
+inline int pyo_exec_statement(PyThreadState *interp, char *msg, int debug) {
+    int err = 0;
+    if (debug) {
+        PyObject *module, *obj;
+        char pp[26] = "_error_=None\ntry:\n    ";
+        memmove(msg + strlen(pp), msg, strlen(msg)+1);
+        memmove(msg, pp, strlen(pp));
+        strcat(msg, "\nexcept Exception, _e_:\n    _error_=str(_e_)");
+        PyEval_AcquireThread(interp);
+        PyRun_SimpleString(msg);
+        module = PyImport_AddModule("__main__");
+        obj = PyObject_GetAttrString(module, "_error_");
+        if (obj != Py_None) {
+            strcpy(msg, PyString_AsString(obj));
+            err = 1;
+        }
+        PyEval_ReleaseThread(interp);
+    }
+    else {
+        PyEval_AcquireThread(interp);
+        PyRun_SimpleString(msg);
+        PyEval_ReleaseThread(interp);
+    }
+    return err;
+}
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+}
+#endif
+
+#define __m_pyo_h_
+#endif /* __m_pyo_h_  */
diff --git a/embedded/openframeworks/PyoTemplate/src/main.cpp b/embedded/openframeworks/PyoTemplate/src/main.cpp
new file mode 100644
index 0000000..a7d241d
--- /dev/null
+++ b/embedded/openframeworks/PyoTemplate/src/main.cpp
@@ -0,0 +1,13 @@
+#include "ofMain.h"
+#include "testApp.h"
+
+//========================================================================
+int main( ){
+	ofSetupOpenGL(1024,768,OF_WINDOW);			// <-------- setup the GL context
+
+	// this kicks off the running of my app
+	// can be OF_WINDOW or OF_FULLSCREEN
+	// pass in width and height too:
+	ofRunApp(new testApp());
+
+}
diff --git a/embedded/openframeworks/PyoTemplate/src/testApp.cpp b/embedded/openframeworks/PyoTemplate/src/testApp.cpp
new file mode 100644
index 0000000..882cec7
--- /dev/null
+++ b/embedded/openframeworks/PyoTemplate/src/testApp.cpp
@@ -0,0 +1,80 @@
+#include "testApp.h"
+
+//--------------------------------------------------------------
+void testApp::setup(){
+    // define audio properties
+    int sampleRate = 44100;
+    int bufferSize = 256;
+    int nChannels = 2;
+    // initialize a pyo server
+    pyo.setup(nChannels, bufferSize, sampleRate);
+    // load a python file
+    pyo.loadfile("../scripts/stereoDelay.py", 0);
+    // initialize OpenFrameworks audio streaming channels
+	soundStream.setup(this, nChannels, nChannels, sampleRate, bufferSize, 4);
+}
+
+void testApp::audioIn(float * input, int bufferSize, int nChannels){
+    // send audio samples to pyo
+    pyo.fillin(input);
+}
+
+void testApp::audioOut(float * output, int bufferSize, int nChannels){
+    // process and get new audio samples from pyo
+    pyo.process(output);
+}
+
+//--------------------------------------------------------------
+void testApp::update(){
+
+}
+
+//--------------------------------------------------------------
+void testApp::draw(){
+
+}
+
+//--------------------------------------------------------------
+void testApp::keyPressed(int key){
+
+}
+
+//--------------------------------------------------------------
+void testApp::keyReleased(int key){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseMoved(int x, int y ){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseDragged(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mousePressed(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseReleased(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void testApp::windowResized(int w, int h){
+
+}
+
+//--------------------------------------------------------------
+void testApp::gotMessage(ofMessage msg){
+
+}
+
+//--------------------------------------------------------------
+void testApp::dragEvent(ofDragInfo dragInfo){
+
+}
diff --git a/embedded/openframeworks/PyoTemplate/src/testApp.h b/embedded/openframeworks/PyoTemplate/src/testApp.h
new file mode 100644
index 0000000..4a98213
--- /dev/null
+++ b/embedded/openframeworks/PyoTemplate/src/testApp.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "ofMain.h"
+#include "PyoClass.h"
+
+class testApp : public ofBaseApp{
+	public:
+		void setup();
+		void update();
+		void draw();
+
+		void keyPressed(int key);
+		void keyReleased(int key);
+		void mouseMoved(int x, int y );
+		void mouseDragged(int x, int y, int button);
+		void mousePressed(int x, int y, int button);
+		void mouseReleased(int x, int y, int button);
+		void windowResized(int w, int h);
+		void dragEvent(ofDragInfo dragInfo);
+		void gotMessage(ofMessage msg);
+
+		void audioIn(float * input, int bufferSize, int nChannels);
+		void audioOut(float * input, int bufferSize, int nChannels);
+		ofSoundStream soundStream;
+        Pyo pyo;
+};
diff --git a/embedded/openframeworks/README b/embedded/openframeworks/README
new file mode 100644
index 0000000..7879578
--- /dev/null
+++ b/embedded/openframeworks/README
@@ -0,0 +1,101 @@
+Introduction on how to use pyo inside an OpenFrameworks project.
+================================================================ 
+
+To use pyo inside an OpenFrameworks project, first you need a 
+working install of pyo on your system. After installing pyo,
+you can go and create an OpenFrameworks project.
+
+------------------------------------------------------------------------
+Step 1 - Create a default project with project generator.
+
+------------------------------------------------------------------------
+Step 2 - Add pyo files to your project. You only need to copy 
+these files in your project's src folder:
+
+- from this folder:
+PyoClass.cpp
+PyoClass.h
+
+- from the folder "embedded":
+m_pyo.h
+
+------------------------------------------------------------------------
+Step 3 - Make sure that your project includes flags for compiling 
+and linking against Python. On Unix systems, you can set the Python 
+flags in the file config.make. Uncomment and complete these lines:
+
+PROJECT_LDFLAGS = `python-config --ldflags` # linker flags for Python
+PROJECT_CFLAGS = `python-config --cflags` # compiler flags for Python
+
+------------------------------------------------------------------------
+Step 4 - Make a scripts folder at the root level of your project and 
+create a python file, named "stereoDelay.py", with these lines in it:
+
+# Get the input sound and apply a stereo delay + reverb on it.
+st_input = Input([0,1])
+st_delay = Delay(st_input, delay=[.4, .5], feedback=0.7)
+st_rev = WGVerb(st_delay, feedback=0.8, cutoff=4000, bal=0.25).out()
+
+------------------------------------------------------------------------
+Step 5 - Edit src/testApp.h.
+
+- Include PyoClass definition:
+
+#include "PyoClass.h"
+
+- Add audio in/out callbacks to the public attributes of the testApp class:
+
+void audioIn(float * input, int bufferSize, int nChannels);
+void audioOut(float * input, int bufferSize, int nChannels);
+
+- Add an ofSoundStream object to the public attributes of the testApp class:
+
+ofSoundStream soundStream;
+
+- Add a Pyo object to the public attributes of the testApp class:
+
+Pyo pyo;
+
+------------------------------------------------------------------------
+Step 6 - Edit src/testApp.cpp.
+
+- Creates the setup() function:
+
+void testApp::setup(){
+    // define audio properties
+    int sampleRate = 44100;
+    int bufferSize = 256;
+    int nChannels = 2;
+    // initialize a pyo server
+    pyo.setup(nChannels, bufferSize, sampleRate);
+    // load a python file
+    pyo.loadfile("../scripts/stereoDelay.py", 0);
+    // initialize OpenFrameworks audio streaming channels 
+	soundStream.setup(this, nChannels, nChannels, sampleRate, bufferSize, 4);
+}
+
+- Creates audio in/out functions:
+
+void testApp::audioIn(float * input, int bufferSize, int nChannels){
+    // send audio samples to pyo
+    pyo.fillin(input);
+}
+
+void testApp::audioOut(float * output, int bufferSize, int nChannels){
+    // process and get new audio samples from pyo
+    pyo.process(output);
+}
+
+------------------------------------------------------------------------
+Here you go! Compile, Run and Enjoy!
+
+Documentation
+=============
+
+For a complete description of functions that can be used to communicate 
+with the pyo embedded processes, see documentation comments in the file 
+PyoClass.cpp.
+
+belangeo
+
+
diff --git a/embedded/puredata/Makefile b/embedded/puredata/Makefile
new file mode 100644
index 0000000..6637883
--- /dev/null
+++ b/embedded/puredata/Makefile
@@ -0,0 +1,467 @@
+## Pd library template version 1.0.13
+# For instructions on how to use this template, see:
+#  http://puredata.info/docs/developer/MakefileTemplate
+LIBRARY_NAME = pyo~
+
+# add your .c source files, one object per file, to the SOURCES
+# variable, help files will be included automatically, and for GUI
+# objects, the matching .tcl file too
+SOURCES = pyo~.c
+
+# list all pd objects (i.e. myobject.pd) files here, and their helpfiles will
+# be included automatically
+PDOBJECTS = pyo~.pd
+
+# example patches and related files, in the 'examples' subfolder
+EXAMPLES = 
+
+# manuals and related files, in the 'manual' subfolder
+MANUAL = manual.txt
+
+# if you want to include any other files in the source and binary tarballs,
+# list them here.  This can be anything from header files, test patches,
+# documentation, etc.  README.txt and LICENSE.txt are required and therefore
+# automatically included
+EXTRA_DIST = m_pyo.h
+
+# unit tests and related files here, in the 'unittests' subfolder
+UNITTESTS = 
+
+# added to support the multiple shared source files
+SHARED_SOURCE = 
+SHARED_LIB = lib$(LIBRARY_NAME).$(SHARED_EXTENSION)
+
+
+#------------------------------------------------------------------------------#
+#
+# things you might need to edit if you are using other C libraries
+#
+#------------------------------------------------------------------------------#
+UNAME := $(shell uname -s)
+ifeq (MINGW,$(findstring MINGW,$(UNAME)))
+    ALL_CFLAGS = -I"$(PD_INCLUDE)" -I.. -Wno-unused-parameter -I/c/Python27/include
+    ALL_LDFLAGS =  -lpython27
+    SHARED_LDFLAGS =
+    ALL_LIBS = -L/c/Python27/libs
+endif
+ifeq ($(UNAME),Darwin)
+    MAC_SDK =                # put the path to your base SDK if you have problem to compile with the one given by python (ex: /Developer/SDKs/MacOSX10.6.sdk)
+    ARCH_TYPE = i386         # can put multiple architectures if they are available with your environment (ex: ppc i386)
+    ifeq ($(MAC_SDK),)
+        PYTHONFLAGS = $(shell python-config --cflags)
+    else
+        PYTHONFLAGS = $(patsubst /%, $(MAC_SDK), $(shell python-config --cflags))
+    endif
+    ALL_CFLAGS = -I"$(PD_INCLUDE)" -I.. -Wno-unused-parameter $(PYTHONFLAGS)
+    ALL_LDFLAGS = $(shell python-config --ldflags)
+    SHARED_LDFLAGS =
+    # ALL_LIBS = $(shell python-config --libs)
+    ALL_LIBS = -ldl -framework CoreFoundation -framework Python
+endif
+ifeq ($(UNAME),Linux)
+    ALL_CFLAGS = -I"$(PD_INCLUDE)" -I.. -Wno-unused-parameter $(shell python-config --cflags)
+    ALL_LDFLAGS =  $(shell python-config --ldflags)
+    SHARED_LDFLAGS =
+    ALL_LIBS = $(shell python-config --libs)
+endif
+
+#------------------------------------------------------------------------------#
+#
+# you shouldn't need to edit anything below here, if we did it right :)
+#
+#------------------------------------------------------------------------------#
+
+# these can be set from outside without (usually) breaking the build
+CFLAGS = -Wall -W -g
+LDFLAGS =
+LIBS =
+
+# get library version from meta file
+LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_NAME)-meta.pd)
+
+ALL_CFLAGS += -DPD -DVERSION='"$(LIBRARY_VERSION)"'
+
+PD_INCLUDE = $(PD_PATH)/include/pd
+# where to install the library, overridden below depending on platform
+prefix = /usr/local
+libdir = $(prefix)/lib
+pkglibdir = $(libdir)/pd-externals
+objectsdir = $(pkglibdir)
+
+INSTALL = install
+INSTALL_PROGRAM = $(INSTALL) -p -m 644
+INSTALL_DATA = $(INSTALL) -p -m 644
+INSTALL_DIR     = $(INSTALL) -p -m 755 -d
+
+ALLSOURCES := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \
+	         $(SOURCES_iphoneos) $(SOURCES_linux) $(SOURCES_windows)
+
+DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION)
+ORIGDIR=pd-$(LIBRARY_NAME:~=)_$(LIBRARY_VERSION)
+
+UNAME := $(shell uname -s)
+ifeq ($(UNAME),Darwin)
+  CPU := $(shell uname -p)
+  ifeq ($(CPU),arm) # iPhone/iPod Touch
+    SOURCES += $(SOURCES_iphoneos)
+    EXTENSION = pd_darwin
+    SHARED_EXTENSION = dylib
+    OS = iphoneos
+    PD_PATH = /Applications/Pd-extended.app/Contents/Resources
+    IPHONE_BASE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin
+    CC=$(IPHONE_BASE)/gcc
+    CPP=$(IPHONE_BASE)/cpp
+    CXX=$(IPHONE_BASE)/g++
+    ISYSROOT = -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk
+    IPHONE_CFLAGS = -miphoneos-version-min=3.0 $(ISYSROOT) -arch armv6
+    OPT_CFLAGS = -fast -funroll-loops -fomit-frame-pointer
+    ALL_CFLAGS := $(IPHONE_CFLAGS) $(ALL_CFLAGS)
+    ALL_LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT)
+    SHARED_LDFLAGS += -arch armv6 -dynamiclib -undefined dynamic_lookup $(ISYSROOT)
+    ALL_LIBS += -lc $(LIBS_iphoneos)
+    STRIP = strip -x
+    DISTBINDIR=$(DISTDIR)-$(OS)
+  else # Mac OS X
+    SOURCES += $(SOURCES_macosx)
+    EXTENSION = pd_darwin
+    SHARED_EXTENSION = dylib
+    OS = macosx
+    PD_PATH = /Applications/Pd-extended.app/Contents/Resources
+    OPT_CFLAGS = -ftree-vectorize -ftree-vectorizer-verbose=2 -fast
+# build universal 32-bit on 10.4 and 32/64 on newer
+    ifeq ($(shell uname -r | sed 's|\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*|\1|'), 8)
+      # FAT_FLAGS = -arch ppc -arch i386 -mmacosx-version-min=10.5
+      ARCHWITHOUT64 := $(filter-out x86_64,$(ARCH_TYPE))
+      FAT_FLAGS = $(patsubst %,-arch %, $(ARCHWITHOUT64)) -mmacosx-version-min=10.5
+    else
+      # FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.5
+      FAT_FLAGS = $(patsubst %,-arch %, $(ARCH_TYPE)) -mmacosx-version-min=10.5
+      SOURCES += $(SOURCES_iphoneos)
+    endif
+    ALL_CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include
+    # if the 'pd' binary exists, check the linking against it to aid with stripping
+    BUNDLE_LOADER = $(shell test ! -e $(PD_PATH)/bin/pd || echo -bundle_loader $(PD_PATH)/bin/pd)
+    ALL_LDFLAGS += $(FAT_FLAGS) -headerpad_max_install_names -bundle $(BUNDLE_LOADER) \
+	-undefined dynamic_lookup -L/sw/lib
+    SHARED_LDFLAGS += $(FAT_FLAGS) -dynamiclib -undefined dynamic_lookup \
+	-install_name @loader_path/$(SHARED_LIB) -compatibility_version 1 -current_version 1.0
+    ALL_LIBS += -lc $(LIBS_macosx)
+    STRIP = strip -x
+    DISTBINDIR=$(DISTDIR)-$(OS)
+# install into ~/Library/Pd on Mac OS X since /usr/local isn't used much
+    pkglibdir=$(HOME)/Library/Pd
+  endif
+endif
+# Tho Android uses Linux, we use this fake uname to provide an easy way to
+# setup all this things needed to cross-compile for Android using the NDK
+ifeq ($(UNAME),ANDROID)
+  CPU := arm
+  SOURCES += $(SOURCES_android)
+  EXTENSION = pd_linux
+  SHARED_EXTENSION = so
+  OS = android
+  PD_PATH = /usr
+  NDK_BASE := /usr/local/android-ndk
+  NDK_PLATFORM_VERSION := 5
+  NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_VERSION)/arch-arm
+  NDK_UNAME := $(shell uname -s | tr '[A-Z]' '[a-z]')
+  NDK_TOOLCHAIN_BASE=$(NDK_BASE)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/$(NDK_UNAME)-x86
+  CC := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-gcc --sysroot=$(NDK_SYSROOT)
+  OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
+  CFLAGS += 
+  LDFLAGS += -rdynamic -shared
+  SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared
+  LIBS += -lc $(LIBS_android)
+  STRIP := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-strip \
+	--strip-unneeded -R .note -R .comment
+  DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
+endif
+ifeq ($(UNAME),Linux)
+  CPU := $(shell uname -m)
+  SOURCES += $(SOURCES_linux)
+  EXTENSION = pd_linux
+  SHARED_EXTENSION = so
+  OS = linux
+  PD_PATH = /usr
+  OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
+  ALL_CFLAGS += -fPIC
+  ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
+  SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared
+  ALL_LIBS += -lc $(LIBS_linux)
+  STRIP = strip --strip-unneeded -R .note -R .comment
+  DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
+endif
+ifeq ($(UNAME),GNU)
+  # GNU/Hurd, should work like GNU/Linux for basically all externals
+  CPU := $(shell uname -m)
+  SOURCES += $(SOURCES_linux)
+  EXTENSION = pd_linux
+  SHARED_EXTENSION = so
+  OS = linux
+  PD_PATH = /usr
+  OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
+  ALL_CFLAGS += -fPIC
+  ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
+  SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB)
+  ALL_LIBS += -lc $(LIBS_linux)
+  STRIP = strip --strip-unneeded -R .note -R .comment
+  DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
+endif
+ifeq ($(UNAME),GNU/kFreeBSD)
+  # Debian GNU/kFreeBSD, should work like GNU/Linux for basically all externals
+  CPU := $(shell uname -m)
+  SOURCES += $(SOURCES_linux)
+  EXTENSION = pd_linux
+  SHARED_EXTENSION = so
+  OS = linux
+  PD_PATH = /usr
+  OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
+  ALL_CFLAGS += -fPIC
+  ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
+  SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB)
+  ALL_LIBS += -lc $(LIBS_linux)
+  STRIP = strip --strip-unneeded -R .note -R .comment
+  DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
+endif
+ifeq (CYGWIN,$(findstring CYGWIN,$(UNAME)))
+  CPU := $(shell uname -m)
+  SOURCES += $(SOURCES_cygwin)
+  EXTENSION = dll
+  SHARED_EXTENSION = dll
+  OS = cygwin
+  PD_PATH = $(shell cygpath $$PROGRAMFILES)/pd
+  OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
+  ALL_CFLAGS += 
+  ALL_LDFLAGS += -rdynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin"
+  SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB)
+  ALL_LIBS += -lc -lpd $(LIBS_cygwin)
+  STRIP = strip --strip-unneeded -R .note -R .comment
+  DISTBINDIR=$(DISTDIR)-$(OS)
+endif
+ifeq (MINGW,$(findstring MINGW,$(UNAME)))
+  CPU := $(shell uname -m)
+  SOURCES += $(SOURCES_windows)
+  EXTENSION = dll
+  SHARED_EXTENSION = dll
+  OS = windows
+  PD_PATH = $(shell cd "$$PROGRAMFILES/pd" && pwd)
+  # MinGW doesn't seem to include cc so force gcc
+  CC=gcc
+  OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer
+  ALL_CFLAGS += -mms-bitfields
+  ALL_LDFLAGS += -s -shared -Wl,--enable-auto-import
+  SHARED_LDFLAGS += -shared
+  ALL_LIBS += -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" \
+	-lpd -lwsock32 -lkernel32 -luser32 -lgdi32 -liberty $(LIBS_windows)
+  STRIP = strip --strip-unneeded -R .note -R .comment
+  DISTBINDIR=$(DISTDIR)-$(OS)
+endif
+
+# in case somebody manually set the HELPPATCHES above
+HELPPATCHES ?= $(SOURCES:.c=-help.pd) $(PDOBJECTS:.pd=-help.pd)
+
+ALL_CFLAGS := $(ALL_CFLAGS) $(CFLAGS) $(OPT_CFLAGS)
+ALL_LDFLAGS := $(LDFLAGS) $(ALL_LDFLAGS)
+ALL_LIBS := $(LIBS) $(ALL_LIBS)
+
+SHARED_SOURCE ?= $(wildcard lib$(LIBRARY_NAME).c)
+SHARED_HEADER ?= $(shell test ! -e $(LIBRARY_NAME).h || echo $(LIBRARY_NAME).h)
+SHARED_LIB ?= $(SHARED_SOURCE:.c=.$(SHARED_EXTENSION))
+SHARED_TCL_LIB = $(wildcard lib$(LIBRARY_NAME).tcl)
+
+.PHONY = install libdir_install single_install install-doc install-examples install-manual install-unittests clean distclean dist etags $(LIBRARY_NAME)
+
+all: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB)
+
+%.o: %.c
+	$(CC) $(ALL_CFLAGS) -o "$*.o" -c "$*.c"
+
+%.$(EXTENSION): %.o $(SHARED_LIB)
+	$(CC) $(ALL_LDFLAGS) -o "$*.$(EXTENSION)" "$*.o"  $(ALL_LIBS) $(SHARED_LIB)
+	chmod a-x "$*.$(EXTENSION)"
+
+# this links everything into a single binary file
+$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o lib$(LIBRARY_NAME).o
+	$(CC) $(ALL_LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) \
+		$(LIBRARY_NAME).o lib$(LIBRARY_NAME).o $(ALL_LIBS)
+	chmod a-x $(LIBRARY_NAME).$(EXTENSION)
+
+$(SHARED_LIB): $(SHARED_SOURCE:.c=.o)
+	$(CC) $(SHARED_LDFLAGS) -o $(SHARED_LIB) $(SHARED_SOURCE:.c=.o) $(ALL_LIBS)
+
+install: single_install
+
+# The meta and help files are explicitly installed to make sure they are
+# actually there.  Those files are not optional, then need to be there.
+libdir_install: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) install-doc install-examples install-manual install-unittests
+	$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+	$(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd \
+		$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+	test -z "$(strip $(SOURCES))" || (\
+		$(INSTALL_PROGRAM) $(SOURCES:.c=.$(EXTENSION)) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) && \
+		$(STRIP) $(addprefix $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/,$(SOURCES:.c=.$(EXTENSION))))
+	test -z "$(strip $(SHARED_LIB))" || \
+		$(INSTALL_DATA) $(SHARED_LIB) \
+			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+	test -z "$(strip $(wildcard $(SOURCES:.c=.tcl)))" || \
+		$(INSTALL_DATA) $(wildcard $(SOURCES:.c=.tcl)) \
+			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+	test -z "$(strip $(PDOBJECTS))" || \
+		$(INSTALL_DATA) $(PDOBJECTS) \
+			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+	test -z "$(strip $(SHARED_TCL_LIB))" || \
+		$(INSTALL_DATA) $(SHARED_TCL_LIB) \
+			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+
+# install library linked as single binary
+single_install: $(LIBRARY_NAME) install-doc install-examples install-manual install-unittests
+	$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+	$(INSTALL_PROGRAM) $(LIBRARY_NAME).$(EXTENSION) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+	$(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION)
+
+install-doc:
+	$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+	test -z "$(strip $(SOURCES) $(PDOBJECTS))" || \
+		$(INSTALL_DATA) $(HELPPATCHES) \
+			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+	$(INSTALL_DATA) README.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt
+	$(INSTALL_DATA) LICENSE.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt
+
+install-examples:
+	test -z "$(strip $(EXAMPLES))" || \
+		$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples && \
+		for file in $(EXAMPLES); do \
+			$(INSTALL_DATA) examples/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples; \
+		done
+
+install-manual:
+	test -z "$(strip $(MANUAL))" || \
+		$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual && \
+		for file in $(MANUAL); do \
+			$(INSTALL_DATA) manual/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual; \
+		done
+
+install-unittests:
+	test -z "$(strip $(UNITTESTS))" || \
+		$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/unittests && \
+		for file in $(UNITTESTS); do \
+			$(INSTALL_DATA) unittests/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/unittests; \
+		done
+
+clean:
+	-rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o) $(SHARED_SOURCE:.c=.o)
+	-rm -f -- $(SOURCES:.c=.$(EXTENSION))
+	-rm -f -- $(LIBRARY_NAME).o
+	-rm -f -- $(LIBRARY_NAME).$(EXTENSION)
+	-rm -f -- $(SHARED_LIB)
+
+distclean: clean
+	-rm -f -- $(DISTBINDIR).tar.gz
+	-rm -rf -- $(DISTBINDIR)
+	-rm -f -- $(DISTDIR).tar.gz
+	-rm -rf -- $(DISTDIR)
+	-rm -f -- $(ORIGDIR).tar.gz
+	-rm -rf -- $(ORIGDIR)
+
+
+$(DISTBINDIR):
+	$(INSTALL_DIR) $(DISTBINDIR)
+
+libdir: all $(DISTBINDIR)
+	$(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd  $(DISTBINDIR)
+	$(INSTALL_DATA) $(SOURCES) $(SHARED_SOURCE) $(SHARED_HEADER) $(DISTBINDIR)
+	$(INSTALL_DATA) $(HELPPATCHES) $(DISTBINDIR)
+	test -z "$(strip $(EXTRA_DIST))" || \
+		$(INSTALL_DATA) $(EXTRA_DIST)    $(DISTBINDIR)
+#	tar --exclude-vcs -czpf $(DISTBINDIR).tar.gz $(DISTBINDIR)
+
+$(DISTDIR):
+	$(INSTALL_DIR) $(DISTDIR)
+
+$(ORIGDIR):
+	$(INSTALL_DIR) $(ORIGDIR)
+
+dist: $(DISTDIR)
+	$(INSTALL_DATA) Makefile  $(DISTDIR)
+	$(INSTALL_DATA) README.txt $(DISTDIR)
+	$(INSTALL_DATA) LICENSE.txt $(DISTDIR)
+	$(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd  $(DISTDIR)
+	test -z "$(strip $(ALLSOURCES))" || \
+		$(INSTALL_DATA) $(ALLSOURCES)  $(DISTDIR)
+	test -z "$(strip $(wildcard $(ALLSOURCES:.c=.tcl)))" || \
+		$(INSTALL_DATA) $(wildcard $(ALLSOURCES:.c=.tcl))  $(DISTDIR)
+	test -z "$(strip $(wildcard $(LIBRARY_NAME).c))" || \
+		$(INSTALL_DATA) $(LIBRARY_NAME).c  $(DISTDIR)
+	test -z "$(strip $(SHARED_HEADER))" || \
+		$(INSTALL_DATA) $(SHARED_HEADER)  $(DISTDIR)
+	test -z "$(strip $(SHARED_SOURCE))" || \
+		$(INSTALL_DATA) $(SHARED_SOURCE)  $(DISTDIR)
+	test -z "$(strip $(SHARED_TCL_LIB))" || \
+		$(INSTALL_DATA) $(SHARED_TCL_LIB)  $(DISTDIR)
+	test -z "$(strip $(PDOBJECTS))" || \
+		$(INSTALL_DATA) $(PDOBJECTS)  $(DISTDIR)
+	test -z "$(strip $(HELPPATCHES))" || \
+		$(INSTALL_DATA) $(HELPPATCHES) $(DISTDIR)
+	test -z "$(strip $(EXTRA_DIST))" || \
+		$(INSTALL_DATA) $(EXTRA_DIST)    $(DISTDIR)
+	test -z "$(strip $(EXAMPLES))" || \
+		$(INSTALL_DIR) $(DISTDIR)/examples && \
+		for file in $(EXAMPLES); do \
+			$(INSTALL_DATA) examples/$$file $(DISTDIR)/examples; \
+		done
+	test -z "$(strip $(MANUAL))" || \
+		$(INSTALL_DIR) $(DISTDIR)/manual && \
+		for file in $(MANUAL); do \
+			$(INSTALL_DATA) manual/$$file $(DISTDIR)/manual; \
+		done
+	test -z "$(strip $(UNITTESTS))" || \
+		$(INSTALL_DIR) $(DISTDIR)/unittests && \
+		for file in $(UNITTESTS); do \
+			$(INSTALL_DATA) unittests/$$file $(DISTDIR)/unittests; \
+		done
+	tar --exclude-vcs -czpf $(DISTDIR).tar.gz $(DISTDIR)
+
+# make a Debian source package
+dpkg-source:
+	debclean
+	make distclean dist
+	mv $(DISTDIR) $(ORIGDIR)
+	tar --exclude-vcs -czpf ../$(ORIGDIR).orig.tar.gz $(ORIGDIR)
+	rm -f -- $(DISTDIR).tar.gz
+	rm -rf -- $(DISTDIR) $(ORIGDIR)
+	cd .. && dpkg-source -b $(LIBRARY_NAME)
+
+etags: TAGS
+
+TAGS: $(wildcard $(PD_INCLUDE)/*.h) $(SOURCES) $(SHARED_SOURCE) $(SHARED_HEADER)
+	etags $(wildcard $(PD_INCLUDE)/*.h)
+	etags -a *.h $(SOURCES) $(SHARED_SOURCE) $(SHARED_HEADER)
+	etags -a --language=none --regex="/proc[ \t]+\([^ \t]+\)/\1/" *.tcl
+
+showsetup:
+	@echo "CC: $(CC)"
+	@echo "CFLAGS: $(CFLAGS)"
+	@echo "LDFLAGS: $(LDFLAGS)"
+	@echo "LIBS: $(LIBS)"
+	@echo "ALL_CFLAGS: $(ALL_CFLAGS)"
+	@echo "ALL_LDFLAGS: $(ALL_LDFLAGS)"
+	@echo "ALL_LIBS: $(ALL_LIBS)"
+	@echo "PD_INCLUDE: $(PD_INCLUDE)"
+	@echo "PD_PATH: $(PD_PATH)"
+	@echo "objectsdir: $(objectsdir)"
+	@echo "LIBRARY_NAME: $(LIBRARY_NAME)"
+	@echo "LIBRARY_VERSION: $(LIBRARY_VERSION)"
+	@echo "SOURCES: $(SOURCES)"
+	@echo "SHARED_HEADER: $(SHARED_HEADER)"
+	@echo "SHARED_SOURCE: $(SHARED_SOURCE)"
+	@echo "SHARED_LIB: $(SHARED_LIB)"
+	@echo "SHARED_TCL_LIB: $(SHARED_TCL_LIB)"
+	@echo "PDOBJECTS: $(PDOBJECTS)"
+	@echo "ALLSOURCES: $(ALLSOURCES)"
+	@echo "ALLSOURCES TCL: $(wildcard $(ALLSOURCES:.c=.tcl))"
+	@echo "UNAME: $(UNAME)"
+	@echo "CPU: $(CPU)"
+	@echo "pkglibdir: $(pkglibdir)"
+	@echo "DISTDIR: $(DISTDIR)"
+	@echo "ORIGDIR: $(ORIGDIR)"
+
diff --git a/embedded/puredata/examples/cvlverb.py b/embedded/puredata/examples/cvlverb.py
new file mode 100644
index 0000000..739e176
--- /dev/null
+++ b/embedded/puredata/examples/cvlverb.py
@@ -0,0 +1,3 @@
+bal = SigTo(0.25, 0.005, 0.25)
+ins = Input([0,1])
+dist = CvlVerb(ins, size=512, bal=bal, mul=0.3).out()
\ No newline at end of file
diff --git a/embedded/puredata/examples/random_waves.py b/embedded/puredata/examples/random_waves.py
new file mode 100644
index 0000000..6b9cc90
--- /dev/null
+++ b/embedded/puredata/examples/random_waves.py
@@ -0,0 +1,13 @@
+import random
+
+feed = SigTo(0.05, 0.05, 0.05)
+amp = Fader(fadein=0.005, fadeout=0.12, dur=0.125)
+syn = SineLoop(freq=[500,510], feedback=feed, mul=amp*amp)
+rev = WGVerb(syn, feedback=0.85, cutoff=4500, bal=0.1).out()
+
+def choose(a, b):
+    x = random.randint(a, b)
+    deg = [0,2,3,5,7,8,11][x%7]
+    hz = midiToHz(deg + (x / 7 * 12 + 36))
+    syn.freq = [hz,hz*1.005]
+    amp.play()
diff --git a/embedded/puredata/examples/resonators.py b/embedded/puredata/examples/resonators.py
new file mode 100644
index 0000000..233ae54
--- /dev/null
+++ b/embedded/puredata/examples/resonators.py
@@ -0,0 +1,8 @@
+reson = SigTo(2, 0.005, 2)
+freqs = SigTo([50,100,150,200,250,300,350,400], time=0.2)
+
+ins = Input([0,1])
+wgs = Waveguide(ins, freq=freqs, dur=reson, mul=0.1)
+wgss = wgs.mix(2)
+wgss.out()
+
diff --git a/embedded/puredata/examples/resonators_add_delays.py b/embedded/puredata/examples/resonators_add_delays.py
new file mode 100644
index 0000000..554ecce
--- /dev/null
+++ b/embedded/puredata/examples/resonators_add_delays.py
@@ -0,0 +1,3 @@
+deltime = SigTo(.25, 0.005, 0.25)
+delfeed = SigTo(.25, 0.005, 0.25)
+dd = Delay(wgs, delay=deltime, feedback=delfeed).out(0)
diff --git a/embedded/puredata/m_pd.h b/embedded/puredata/m_pd.h
new file mode 100755
index 0000000..71bd28e
--- /dev/null
+++ b/embedded/puredata/m_pd.h
@@ -0,0 +1,665 @@
+/* Copyright (c) 1997-1999 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */
+
+#ifndef __m_pd_h_
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+extern "C" {
+#endif
+
+#define PD_MAJOR_VERSION 0
+#define PD_MINOR_VERSION 41
+#define PD_BUGFIX_VERSION 4
+#define PD_TEST_VERSION "extended"
+
+/* old name for "MSW" flag -- we have to take it for the sake of many old
+"nmakefiles" for externs, which will define NT and not MSW */
+#if defined(NT) && !defined(MSW)
+#define MSW
+#endif
+
+/* These pragmas are only used for MSVC, not MinGW or Cygwin <hans at at.or.at> */
+#ifdef _MSC_VER
+/* #pragma warning( disable : 4091 ) */
+#pragma warning( disable : 4305 )  /* uncast const double to float */
+#pragma warning( disable : 4244 )  /* uncast float/int conversion etc. */
+#pragma warning( disable : 4101 )  /* unused automatic variables */
+#endif /* _MSC_VER */
+
+    /* the external storage class is "extern" in UNIX; in MSW it's ugly. */
+#ifdef MSW
+#ifdef PD_INTERNAL
+#define EXTERN __declspec(dllexport) extern
+#else
+#define EXTERN __declspec(dllimport) extern
+#endif /* PD_INTERNAL */
+#else
+#define EXTERN extern
+#endif /* MSW */
+
+    /* and depending on the compiler, hidden data structures are
+    declared differently: */
+#if defined( __GNUC__) || defined( __BORLANDC__ ) || defined( __MWERKS__ )
+#define EXTERN_STRUCT struct
+#else
+#define EXTERN_STRUCT extern struct
+#endif
+
+
+#if !defined(_SIZE_T) && !defined(_SIZE_T_)
+#include <stddef.h>     /* just for size_t -- how lame! */
+#endif
+
+#define MAXPDSTRING 1000        /* must be >= FILENAME_MAX */
+#define MAXPDARG 5              /* max number of args we can typecheck today */
+
+/* signed and unsigned integer types the size of a pointer:  */
+/* GG: long is the size of a pointer */
+typedef long t_int;
+
+typedef float t_float;  /* a floating-point number at most the same size */
+typedef float t_floatarg;  /* floating-point type for function calls */
+
+typedef struct _symbol
+{
+    char *s_name;
+    struct _class **s_thing;
+    struct _symbol *s_next;
+} t_symbol;
+
+EXTERN_STRUCT _array;
+#define t_array struct _array       /* g_canvas.h */
+
+/* pointers to glist and array elements go through a "stub" which sticks
+around after the glist or array is freed.  The stub itself is deleted when
+both the glist/array is gone and the refcount is zero, ensuring that no
+gpointers are pointing here. */
+
+#define GP_NONE 0       /* the stub points nowhere (has been cut off) */
+#define GP_GLIST 1      /* the stub points to a glist element */
+#define GP_ARRAY 2      /* ... or array */
+
+typedef struct _gstub
+{
+    union
+    {
+        struct _glist *gs_glist;    /* glist we're in */
+        struct _array *gs_array;    /* array we're in */
+    } gs_un;
+    int gs_which;                   /* GP_GLIST/GP_ARRAY */
+    int gs_refcount;                /* number of gpointers pointing here */
+} t_gstub;
+
+typedef struct _gpointer           /* pointer to a gobj in a glist */
+{
+    union
+    {   
+        struct _scalar *gp_scalar;  /* scalar we're in (if glist) */
+        union word *gp_w;           /* raw data (if array) */
+    } gp_un;
+    int gp_valid;                   /* number which must match gpointee */
+    t_gstub *gp_stub;               /* stub which points to glist/array */
+} t_gpointer;
+
+#define PD_BLOBS 1 /* MP20070211 Use this to test for blob capability */
+/* MP20061223 blob type: */
+typedef struct _blob /* pointer to a blob */
+{
+   unsigned long s_length; /* length of blob in bytes */
+   unsigned char *s_data; /* pointer to 1st byte of blob */
+} t_blob;
+/* ...MP20061223 blob type */
+
+
+typedef union word
+{
+    t_float w_float;
+    t_symbol *w_symbol;
+    t_gpointer *w_gpointer;
+    t_array *w_array;
+    struct _glist *w_list;
+    int w_index;
+    t_blob *w_blob; /* MP20061223 blob type */
+} t_word;
+
+typedef enum
+{
+    A_NULL,
+    A_FLOAT,
+    A_SYMBOL,
+    A_POINTER,
+    A_SEMI,
+    A_COMMA,
+    A_DEFFLOAT,
+    A_DEFSYM,
+    A_DOLLAR, 
+    A_DOLLSYM,
+    A_GIMME,
+    A_CANT,
+    A_BLOB /* MP20061223 blob type */
+}  t_atomtype;
+
+#define A_DEFSYMBOL A_DEFSYM    /* better name for this */
+
+typedef struct _atom
+{
+    t_atomtype a_type;
+    union word a_w;
+} t_atom;
+
+EXTERN_STRUCT _class;
+#define t_class struct _class
+
+EXTERN_STRUCT _outlet;
+#define t_outlet struct _outlet
+
+EXTERN_STRUCT _inlet;
+#define t_inlet struct _inlet
+
+EXTERN_STRUCT _binbuf;
+#define t_binbuf struct _binbuf
+
+EXTERN_STRUCT _clock;
+#define t_clock struct _clock
+
+EXTERN_STRUCT _outconnect;
+#define t_outconnect struct _outconnect
+
+EXTERN_STRUCT _glist;
+#define t_glist struct _glist
+#define t_canvas struct _glist  /* LATER lose this */
+
+typedef t_class *t_pd;      /* pure datum: nothing but a class pointer */
+
+typedef struct _gobj        /* a graphical object */
+{
+    t_pd g_pd;              /* pure datum header (class) */
+    struct _gobj *g_next;   /* next in list */
+} t_gobj;
+
+typedef struct _scalar      /* a graphical object holding data */
+{
+    t_gobj sc_gobj;         /* header for graphical object */
+    t_symbol *sc_template;  /* template name (LATER replace with pointer) */
+    t_word sc_vec[1];       /* indeterminate-length array of words */
+} t_scalar;
+
+typedef struct _text        /* patchable object - graphical, with text */
+{
+    t_gobj te_g;                /* header for graphical object */
+    t_binbuf *te_binbuf;        /* holder for the text */
+    t_outlet *te_outlet;        /* linked list of outlets */
+    t_inlet *te_inlet;          /* linked list of inlets */
+    short te_xpix;              /* x&y location (within the toplevel) */
+    short te_ypix;
+    short te_width;             /* requested width in chars, 0 if auto */
+    unsigned int te_type:2;     /* from defs below */
+} t_text;
+
+#define T_TEXT 0        /* just a textual comment */
+#define T_OBJECT 1      /* a MAX style patchable object */
+#define T_MESSAGE 2     /* a MAX stype message */
+#define T_ATOM 3        /* a cell to display a number or symbol */
+
+#define te_pd te_g.g_pd
+
+   /* t_object is synonym for t_text (LATER unify them) */
+
+typedef struct _text t_object;
+
+#define ob_outlet te_outlet
+#define ob_inlet te_inlet
+#define ob_binbuf te_binbuf
+#define ob_pd te_g.g_pd
+#define ob_g te_g
+
+typedef void (*t_method)(void);
+typedef void *(*t_newmethod)( void);
+typedef void (*t_gotfn)(void *x, ...);
+
+/* ---------------- pre-defined objects and symbols --------------*/
+EXTERN t_pd pd_objectmaker;     /* factory for creating "object" boxes */
+EXTERN t_pd pd_canvasmaker;     /* factory for creating canvases */
+EXTERN t_symbol s_pointer;
+EXTERN t_symbol s_float;
+EXTERN t_symbol s_symbol;
+EXTERN t_symbol s_blob;
+EXTERN t_symbol s_bang;
+EXTERN t_symbol s_list;
+EXTERN t_symbol s_anything;
+EXTERN t_symbol s_signal;
+EXTERN t_symbol s__N;
+EXTERN t_symbol s__X;
+EXTERN t_symbol s_x;
+EXTERN t_symbol s_y;
+EXTERN t_symbol s_;
+
+/* --------- prototypes from the central message system ----------- */
+EXTERN void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void pd_forwardmess(t_pd *x, int argc, t_atom *argv);
+EXTERN t_symbol *gensym(const char *s);
+EXTERN t_gotfn getfn(t_pd *x, t_symbol *s);
+EXTERN t_gotfn zgetfn(t_pd *x, t_symbol *s);
+EXTERN void nullfn(void);
+EXTERN void pd_vmess(t_pd *x, t_symbol *s, char *fmt, ...);
+#define mess0(x, s) ((*getfn((x), (s)))((x)))
+#define mess1(x, s, a) ((*getfn((x), (s)))((x), (a)))
+#define mess2(x, s, a,b) ((*getfn((x), (s)))((x), (a),(b)))
+#define mess3(x, s, a,b,c) ((*getfn((x), (s)))((x), (a),(b),(c)))
+#define mess4(x, s, a,b,c,d) ((*getfn((x), (s)))((x), (a),(b),(c),(d)))
+#define mess5(x, s, a,b,c,d,e) ((*getfn((x), (s)))((x), (a),(b),(c),(d),(e)))
+EXTERN void obj_list(t_object *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN t_pd *pd_newest(void);
+
+/* --------------- memory management -------------------- */
+EXTERN void *getbytes(size_t nbytes);
+EXTERN void *getzbytes(size_t nbytes);
+EXTERN void *copybytes(void *src, size_t nbytes);
+EXTERN void freebytes(void *x, size_t nbytes);
+EXTERN void *resizebytes(void *x, size_t oldsize, size_t newsize);
+
+/* -------------------- atoms ----------------------------- */
+
+#define SETSEMI(atom) ((atom)->a_type = A_SEMI, (atom)->a_w.w_index = 0)
+#define SETCOMMA(atom) ((atom)->a_type = A_COMMA, (atom)->a_w.w_index = 0)
+#define SETPOINTER(atom, gp) ((atom)->a_type = A_POINTER, \
+    (atom)->a_w.w_gpointer = (gp))
+#define SETFLOAT(atom, f) ((atom)->a_type = A_FLOAT, (atom)->a_w.w_float = (f))
+#define SETSYMBOL(atom, s) ((atom)->a_type = A_SYMBOL, \
+    (atom)->a_w.w_symbol = (s))
+#define SETBLOB(atom, st) ((atom)->a_type = A_BLOB, (atom)->a_w.w_blob = (st)) /* MP 20061226 blob type */
+#define SETDOLLAR(atom, n) ((atom)->a_type = A_DOLLAR, \
+    (atom)->a_w.w_index = (n))
+#define SETDOLLSYM(atom, s) ((atom)->a_type = A_DOLLSYM, \
+    (atom)->a_w.w_symbol= (s))
+
+EXTERN t_float atom_getfloat(t_atom *a);
+EXTERN t_int atom_getint(t_atom *a);
+EXTERN t_symbol *atom_getsymbol(t_atom *a);
+EXTERN t_blob *atom_getblob(t_atom *a);/* MP 20070108 blob type */
+EXTERN t_symbol *atom_gensym(t_atom *a);
+EXTERN t_float atom_getfloatarg(int which, int argc, t_atom *argv);
+EXTERN t_int atom_getintarg(int which, int argc, t_atom *argv);
+EXTERN t_symbol *atom_getsymbolarg(int which, int argc, t_atom *argv);
+
+EXTERN void atom_string(t_atom *a, char *buf, unsigned int bufsize);
+
+/* ------------------  binbufs --------------- */
+
+EXTERN t_binbuf *binbuf_new(void);
+EXTERN void binbuf_free(t_binbuf *x);
+EXTERN t_binbuf *binbuf_duplicate(t_binbuf *y);
+
+EXTERN void binbuf_text(t_binbuf *x, char *text, size_t size);
+EXTERN void binbuf_gettext(t_binbuf *x, char **bufp, int *lengthp);
+EXTERN void binbuf_clear(t_binbuf *x);
+EXTERN void binbuf_add(t_binbuf *x, int argc, t_atom *argv);
+EXTERN void binbuf_addv(t_binbuf *x, char *fmt, ...);
+EXTERN void binbuf_addbinbuf(t_binbuf *x, t_binbuf *y);
+EXTERN void binbuf_addsemi(t_binbuf *x);
+EXTERN void binbuf_restore(t_binbuf *x, int argc, t_atom *argv);
+EXTERN void binbuf_print(t_binbuf *x);
+EXTERN int binbuf_getnatom(t_binbuf *x);
+EXTERN t_atom *binbuf_getvec(t_binbuf *x);
+EXTERN void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv);
+EXTERN int binbuf_read(t_binbuf *b, char *filename, char *dirname,
+    int crflag);
+EXTERN int binbuf_read_via_canvas(t_binbuf *b, char *filename, t_canvas *canvas,
+    int crflag);
+EXTERN int binbuf_read_via_path(t_binbuf *b, char *filename, char *dirname,
+    int crflag);
+EXTERN int binbuf_write(t_binbuf *x, char *filename, char *dir,
+    int crflag);
+EXTERN void binbuf_evalfile(t_symbol *name, t_symbol *dir);
+EXTERN t_symbol *binbuf_realizedollsym(t_symbol *s, int ac, t_atom *av,
+    int tonew);
+
+/* ------------------  clocks --------------- */
+
+EXTERN t_clock *clock_new(void *owner, t_method fn);
+EXTERN void clock_set(t_clock *x, double systime);
+EXTERN void clock_delay(t_clock *x, double delaytime);
+EXTERN void clock_unset(t_clock *x);
+EXTERN double clock_getlogicaltime(void);
+EXTERN double clock_getsystime(void); /* OBSOLETE; use clock_getlogicaltime() */
+EXTERN double clock_gettimesince(double prevsystime);
+EXTERN double clock_getsystimeafter(double delaytime);
+EXTERN void clock_free(t_clock *x);
+
+/* ----------------- pure data ---------------- */
+EXTERN t_pd *pd_new(t_class *cls);
+EXTERN void pd_free(t_pd *x);
+EXTERN void pd_bind(t_pd *x, t_symbol *s);
+EXTERN void pd_unbind(t_pd *x, t_symbol *s);
+EXTERN t_pd *pd_findbyclass(t_symbol *s, t_class *c);
+EXTERN void pd_pushsym(t_pd *x);
+EXTERN void pd_popsym(t_pd *x);
+EXTERN t_symbol *pd_getfilename(void);
+EXTERN t_symbol *pd_getdirname(void);
+EXTERN void pd_bang(t_pd *x);
+EXTERN void pd_pointer(t_pd *x, t_gpointer *gp);
+EXTERN void pd_float(t_pd *x, t_float f);
+EXTERN void pd_symbol(t_pd *x, t_symbol *s);
+EXTERN void pd_blob(t_pd *x, t_blob *st); /* MP 20061226 blob type */
+EXTERN void pd_list(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void pd_anything(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+#define pd_class(x) (*(x))
+
+/* ----------------- pointers ---------------- */
+EXTERN void gpointer_init(t_gpointer *gp);
+EXTERN void gpointer_copy(const t_gpointer *gpfrom, t_gpointer *gpto);
+EXTERN void gpointer_unset(t_gpointer *gp);
+EXTERN int gpointer_check(const t_gpointer *gp, int headok);
+
+/* ----------------- patchable "objects" -------------- */
+EXTERN t_inlet *inlet_new(t_object *owner, t_pd *dest, t_symbol *s1,
+    t_symbol *s2);
+EXTERN t_inlet *pointerinlet_new(t_object *owner, t_gpointer *gp);
+EXTERN t_inlet *floatinlet_new(t_object *owner, t_float *fp);
+EXTERN t_inlet *symbolinlet_new(t_object *owner, t_symbol **sp);
+EXTERN t_inlet *signalinlet_new(t_object *owner, t_float f);
+EXTERN void inlet_free(t_inlet *x);
+
+EXTERN t_outlet *outlet_new(t_object *owner, t_symbol *s);
+EXTERN void outlet_bang(t_outlet *x);
+EXTERN void outlet_pointer(t_outlet *x, t_gpointer *gp);
+EXTERN void outlet_float(t_outlet *x, t_float f);
+EXTERN void outlet_symbol(t_outlet *x, t_symbol *s);
+EXTERN void outlet_blob(t_outlet *x, t_blob *st); /* MP 20061226 blob type */
+EXTERN void outlet_list(t_outlet *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void outlet_anything(t_outlet *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN t_symbol *outlet_getsymbol(t_outlet *x);
+EXTERN void outlet_free(t_outlet *x);
+EXTERN t_object *pd_checkobject(t_pd *x);
+
+
+/* -------------------- canvases -------------- */
+
+EXTERN void glob_setfilename(void *dummy, t_symbol *name, t_symbol *dir);
+
+EXTERN void canvas_setargs(int argc, t_atom *argv);
+EXTERN void canvas_getargs(int *argcp, t_atom **argvp);
+EXTERN t_symbol *canvas_getcurrentdir(void);
+EXTERN t_glist *canvas_getcurrent(void);
+EXTERN void canvas_makefilename(t_glist *c, char *file,
+    char *result,int resultsize);
+EXTERN t_symbol *canvas_getdir(t_glist *x);
+EXTERN char sys_font[]; /* default typeface set in s_main.c */
+EXTERN char sys_fontweight[]; /* default font weight set in s_main.c */
+EXTERN int sys_fontwidth(int fontsize);
+EXTERN int sys_fontheight(int fontsize);
+EXTERN void canvas_dataproperties(t_glist *x, t_scalar *sc, t_binbuf *b);
+EXTERN int canvas_open(t_canvas *x, const char *name, const char *ext,
+    char *dirresult, char **nameresult, unsigned int size, int bin);
+
+/* ---------------- widget behaviors ---------------------- */
+
+EXTERN_STRUCT _widgetbehavior;
+#define t_widgetbehavior struct _widgetbehavior
+
+EXTERN_STRUCT _parentwidgetbehavior;
+#define t_parentwidgetbehavior struct _parentwidgetbehavior
+EXTERN t_parentwidgetbehavior *pd_getparentwidget(t_pd *x);
+
+/* -------------------- classes -------------- */
+
+#define CLASS_DEFAULT 0         /* flags for new classes below */
+#define CLASS_PD 1
+#define CLASS_GOBJ 2
+#define CLASS_PATCHABLE 3
+#define CLASS_NOINLET 8
+
+#define CLASS_TYPEMASK 3
+
+
+EXTERN t_class *class_new(t_symbol *name, t_newmethod newmethod,
+    t_method freemethod, size_t size, int flags, t_atomtype arg1, ...);
+EXTERN void class_addcreator(t_newmethod newmethod, t_symbol *s, 
+    t_atomtype type1, ...);
+EXTERN void class_addmethod(t_class *c, t_method fn, t_symbol *sel,
+    t_atomtype arg1, ...);
+EXTERN void class_addbang(t_class *c, t_method fn);
+EXTERN void class_addpointer(t_class *c, t_method fn);
+EXTERN void class_doaddfloat(t_class *c, t_method fn);
+EXTERN void class_addsymbol(t_class *c, t_method fn);
+EXTERN void class_addblob(t_class *c, t_method fn);/* MP 20061226 blob type */
+EXTERN void class_addlist(t_class *c, t_method fn);
+EXTERN void class_addanything(t_class *c, t_method fn);
+EXTERN void class_sethelpsymbol(t_class *c, t_symbol *s);
+EXTERN void class_setwidget(t_class *c, t_widgetbehavior *w);
+EXTERN void class_setparentwidget(t_class *c, t_parentwidgetbehavior *w);
+EXTERN t_parentwidgetbehavior *class_parentwidget(t_class *c);
+EXTERN char *class_getname(t_class *c);
+EXTERN char *class_gethelpname(t_class *c);
+EXTERN void class_setdrawcommand(t_class *c);
+EXTERN int class_isdrawcommand(t_class *c);
+EXTERN void class_domainsignalin(t_class *c, int onset);
+EXTERN void class_set_extern_dir(t_symbol *s);
+#define CLASS_MAINSIGNALIN(c, type, field) \
+    class_domainsignalin(c, (char *)(&((type *)0)->field) - (char *)0)
+
+         /* prototype for functions to save Pd's to a binbuf */
+typedef void (*t_savefn)(t_gobj *x, t_binbuf *b);
+EXTERN void class_setsavefn(t_class *c, t_savefn f);
+EXTERN t_savefn class_getsavefn(t_class *c);
+        /* prototype for functions to open properties dialogs */
+typedef void (*t_propertiesfn)(t_gobj *x, struct _glist *glist);
+EXTERN void class_setpropertiesfn(t_class *c, t_propertiesfn f);
+EXTERN t_propertiesfn class_getpropertiesfn(t_class *c);
+
+#ifndef PD_CLASS_DEF
+#define class_addbang(x, y) class_addbang((x), (t_method)(y))
+#define class_addpointer(x, y) class_addpointer((x), (t_method)(y))
+#define class_addfloat(x, y) class_doaddfloat((x), (t_method)(y))
+#define class_addsymbol(x, y) class_addsymbol((x), (t_method)(y))
+#define class_addblob(x, y) class_addblob((x), (t_method)(y)) /* MP20061226 blob type */
+#define class_addlist(x, y) class_addlist((x), (t_method)(y))
+#define class_addanything(x, y) class_addanything((x), (t_method)(y))
+#endif
+
+/* ------------   printing --------------------------------- */
+EXTERN void post(const char *fmt, ...);
+EXTERN void startpost(const char *fmt, ...);
+EXTERN void poststring(const char *s);
+EXTERN void postfloat(float f);
+EXTERN void postatom(int argc, t_atom *argv);
+EXTERN void endpost(void);
+EXTERN void error(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+EXTERN void verbose(int level, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+EXTERN void bug(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+EXTERN void pd_error(void *object, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+EXTERN void sys_logerror(const char *object, const char *s);
+EXTERN void sys_unixerror(const char *object);
+EXTERN void sys_ouch(void);
+
+
+/* ------------  system interface routines ------------------- */
+EXTERN int sys_isreadablefile(const char *name);
+EXTERN int sys_isabsolutepath(const char *dir);
+EXTERN void sys_bashfilename(const char *from, char *to);
+EXTERN void sys_unbashfilename(const char *from, char *to);
+EXTERN int open_via_path(const char *name, const char *ext, const char *dir,
+    char *dirresult, char **nameresult, unsigned int size, int bin);
+EXTERN int sched_geteventno(void);
+EXTERN double sys_getrealtime(void);
+EXTERN int (*sys_idlehook)(void);   /* hook to add idle time computation */
+
+
+/* ------------  threading ------------------- */ 
+EXTERN void sys_lock(void);
+EXTERN void sys_unlock(void);
+EXTERN int sys_trylock(void);
+
+
+/* --------------- signals ----------------------------------- */
+
+typedef float t_sample;
+#define MAXLOGSIG 32
+#define MAXSIGSIZE (1 << MAXLOGSIG)
+
+typedef struct _signal
+{
+    int s_n;            /* number of points in the array */
+    t_sample *s_vec;    /* the array */
+    t_float s_sr;         /* sample rate */
+    int s_refcount;     /* number of times used */
+    int s_isborrowed;   /* whether we're going to borrow our array */
+    struct _signal *s_borrowedfrom;     /* signal to borrow it from */
+    struct _signal *s_nextfree;         /* next in freelist */
+    struct _signal *s_nextused;         /* next in used list */
+    int s_vecsize;      /* allocated size of array in points */
+} t_signal;
+
+typedef t_int *(*t_perfroutine)(t_int *args);
+
+EXTERN t_int *plus_perform(t_int *args);
+EXTERN t_int *zero_perform(t_int *args);
+EXTERN t_int *copy_perform(t_int *args);
+
+EXTERN void dsp_add_plus(t_sample *in1, t_sample *in2, t_sample *out, int n);
+EXTERN void dsp_add_copy(t_sample *in, t_sample *out, int n);
+EXTERN void dsp_add_scalarcopy(t_float *in, t_sample *out, int n);
+EXTERN void dsp_add_zero(t_sample *out, int n);
+
+EXTERN int sys_getblksize(void);
+EXTERN t_float sys_getsr(void);
+EXTERN int sys_get_inchannels(void);
+EXTERN int sys_get_outchannels(void);
+
+EXTERN void dsp_add(t_perfroutine f, int n, ...);
+EXTERN void dsp_addv(t_perfroutine f, int n, t_int *vec);
+EXTERN void pd_fft(t_float *buf, int npoints, int inverse);
+EXTERN int ilog2(int n);
+
+EXTERN void mayer_fht(t_sample *fz, int n);
+EXTERN void mayer_fft(int n, t_sample *real, t_sample *imag);
+EXTERN void mayer_ifft(int n, t_sample *real, t_sample *imag);
+EXTERN void mayer_realfft(int n, t_sample *real);
+EXTERN void mayer_realifft(int n, t_sample *real);
+
+EXTERN float *cos_table;
+#define LOGCOSTABSIZE 9
+#define COSTABSIZE (1<<LOGCOSTABSIZE)
+
+EXTERN int canvas_suspend_dsp(void);
+EXTERN void canvas_resume_dsp(int oldstate);
+EXTERN void canvas_update_dsp(void);
+EXTERN int canvas_dspstate;
+
+/*   up/downsampling */
+typedef struct _resample
+{
+  int method;       /* up/downsampling method ID */
+
+  t_int downsample; /* downsampling factor */
+  t_int upsample;   /* upsampling factor */
+
+  t_sample *s_vec;   /* here we hold the resampled data */
+  int      s_n;
+
+  t_sample *coeffs;  /* coefficients for filtering... */
+  int      coefsize;
+
+  t_sample *buffer;  /* buffer for filtering */
+  int      bufsize;
+} t_resample;
+
+EXTERN void resample_init(t_resample *x);
+EXTERN void resample_free(t_resample *x);
+
+EXTERN void resample_dsp(t_resample *x, t_sample *in, int insize, t_sample *out, int outsize, int method);
+EXTERN void resamplefrom_dsp(t_resample *x, t_sample *in, int insize, int outsize, int method);
+EXTERN void resampleto_dsp(t_resample *x, t_sample *out, int insize, int outsize, int method);
+
+/* ----------------------- utility functions for signals -------------- */
+EXTERN t_float mtof(t_float);
+EXTERN t_float ftom(t_float);
+EXTERN t_float rmstodb(t_float);
+EXTERN t_float powtodb(t_float);
+EXTERN t_float dbtorms(t_float);
+EXTERN t_float dbtopow(t_float);
+
+EXTERN t_float q8_sqrt(t_float);
+EXTERN t_float q8_rsqrt(t_float);
+#ifndef N32     
+EXTERN t_float qsqrt(t_float);  /* old names kept for extern compatibility */
+EXTERN t_float qrsqrt(t_float);
+#endif
+/* --------------------- data --------------------------------- */
+
+    /* graphical arrays */
+EXTERN_STRUCT _garray;
+#define t_garray struct _garray
+
+EXTERN t_class *garray_class;
+EXTERN int garray_getfloatarray(t_garray *x, int *size, t_float **vec);
+EXTERN int garray_getfloatwords(t_garray *x, int *size, t_word **vec);
+EXTERN t_float garray_get(t_garray *x, t_symbol *s, t_int indx);
+EXTERN void garray_redraw(t_garray *x);
+EXTERN int garray_npoints(t_garray *x);
+EXTERN char *garray_vec(t_garray *x);
+EXTERN void garray_resize(t_garray *x, t_floatarg f);
+EXTERN void garray_usedindsp(t_garray *x);
+EXTERN void garray_setsaveit(t_garray *x, int saveit);
+EXTERN t_class *scalar_class;
+
+EXTERN t_float *value_get(t_symbol *s);
+EXTERN void value_release(t_symbol *s);
+EXTERN int value_getfloat(t_symbol *s, t_float *f);
+EXTERN int value_setfloat(t_symbol *s, t_float f);
+
+/* ------- GUI interface - functions to send strings to TK --------- */
+typedef void (*t_guicallbackfn)(t_gobj *client, t_glist *glist);
+
+EXTERN void sys_vgui(char *fmt, ...);
+EXTERN void sys_gui(char *s);
+EXTERN void sys_pretendguibytes(int n);
+EXTERN void sys_queuegui(void *client, t_glist *glist, t_guicallbackfn f);
+EXTERN void sys_unqueuegui(void *client);
+    /* dialog window creation and destruction */
+EXTERN void gfxstub_new(t_pd *owner, void *key, const char *cmd);
+EXTERN void gfxstub_deleteforkey(void *key);
+
+extern t_class *glob_pdobject;  /* object to send "pd" messages */
+
+/*-------------  Max 0.26 compatibility --------------------*/
+
+/* the following reflects the new way classes are laid out, with the class
+   pointing to the messlist and not vice versa. Externs shouldn't feel it. */
+typedef t_class *t_externclass;
+
+EXTERN void c_extern(t_externclass *cls, t_newmethod newroutine,
+    t_method freeroutine, t_symbol *name, size_t size, int tiny, \
+    t_atomtype arg1, ...);
+EXTERN void c_addmess(t_method fn, t_symbol *sel, t_atomtype arg1, ...);
+
+#define t_getbytes getbytes
+#define t_freebytes freebytes
+#define t_resizebytes resizebytes
+#define typedmess pd_typedmess
+#define vmess pd_vmess
+
+/* A definition to help gui objects straddle 0.34-0.35 changes.  If this is
+defined, there is a "te_xpix" field in objects, not a "te_xpos" as before: */
+
+#define PD_USE_TE_XPIX
+
+#if defined(__i386__) || defined(__x86_64__)
+/* a test for NANs and denormals.  Should only be necessary on i386. */
+#define PD_BADFLOAT(f) ((((*(unsigned int*)&(f))&0x7f800000)==0) || \
+    (((*(unsigned int*)&(f))&0x7f800000)==0x7f800000))
+/* more stringent test: anything not between 1e-19 and 1e19 in absolute val */
+#define PD_BIGORSMALL(f) ((((*(unsigned int*)&(f))&0x60000000)==0) || \
+    (((*(unsigned int*)&(f))&0x60000000)==0x60000000))
+#else
+#define PD_BADFLOAT(f) 0
+#define PD_BIGORSMALL(f) 0
+#endif
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+}
+#endif
+
+#define __m_pd_h_
+#endif /* __m_pd_h_ */
diff --git a/embedded/puredata/pyo~-help.pd b/embedded/puredata/pyo~-help.pd
new file mode 100644
index 0000000..e8c9c8a
--- /dev/null
+++ b/embedded/puredata/pyo~-help.pd
@@ -0,0 +1,311 @@
+#N canvas 296 140 952 365 10;
+#X obj 28 108 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 144 108 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
+1;
+#X obj 13 234 *~;
+#X obj 51 234 *~;
+#X obj 13 256 dac~;
+#X obj 72 213 hsl 128 15 0 1 0 1 empty empty master_gain -2 -8 0 10
+-262144 -1 -1 6200 1;
+#X obj 274 223 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
+1;
+#X msg 274 243 \; pd dsp \$1;
+#X obj 13 59 r msg_to_pyo;
+#X text 161 107 play;
+#X obj 13 166 pyo~ 2;
+#X text 66 168 argument sets the number of audio ins/outs (defaults
+to 2).;
+#N canvas 1 75 824 583 resonators_example 0;
+#X obj 35 103 hsl 128 15 0.01 30 1 0 empty empty resonance -2 -8 0
+10 -262144 -1 -1 11200 0;
+#X floatatom 32 120 5 0 0 0 - - -;
+#X obj 21 530 s msg_to_pyo;
+#X obj 98 387 hsl 128 15 0 1 0 0 empty empty delay_time -2 -8 0 10
+-262144 -1 -1 1300 0;
+#X floatatom 95 403 5 0 0 0 - - -;
+#X msg 95 418 value deltime \$1;
+#X obj 111 454 hsl 128 15 0 1 0 0 empty empty delay_feedback -2 -8
+0 10 -262144 -1 -1 10800 0;
+#X floatatom 108 470 5 0 0 0 - - -;
+#X msg 108 485 value delfeed \$1;
+#X msg 32 136 value reson \$1;
+#X obj 52 177 vsl 15 80 50 500 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 4700 0;
+#X obj 71 177 vsl 15 80 50 500 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 3200 0;
+#X obj 91 177 vsl 15 80 50 500 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 5800 0;
+#X obj 110 177 vsl 15 80 50 500 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 7100 0;
+#X obj 130 177 vsl 15 80 50 500 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 5500 0;
+#X obj 149 177 vsl 15 80 50 500 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 7100 0;
+#X obj 169 177 vsl 15 80 50 500 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 4400 0;
+#X obj 189 177 vsl 15 80 50 500 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 1800 0;
+#X msg 52 306 value freqs \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8;
+#X obj 52 264 bondo 8 ____________;
+#X obj 52 285 pack f f f f f f f f;
+#X msg 21 66 read examples/resonators.py;
+#X msg 73 351 read -a examples/resonators_add_delays.py;
+#X text 52 159 resonator frequencies;
+#X text 20 30 load pyo processing file (audio signal must be given
+in pyo~ inputs).;
+#X text 168 103 adjust resonance in seconds;
+#X text 214 209 play with resonator frequencies;
+#X text 380 352 add a stereo delay taking resonator outputs as its
+input;
+#X text 234 387 adjust delay time;
+#X text 246 453 adjust delay feedback;
+#X connect 0 0 1 0;
+#X connect 1 0 9 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 5 0 2 0;
+#X connect 6 0 7 0;
+#X connect 7 0 8 0;
+#X connect 8 0 2 0;
+#X connect 9 0 2 0;
+#X connect 10 0 19 0;
+#X connect 11 0 19 1;
+#X connect 12 0 19 2;
+#X connect 13 0 19 3;
+#X connect 14 0 19 4;
+#X connect 15 0 19 5;
+#X connect 16 0 19 6;
+#X connect 17 0 19 7;
+#X connect 18 0 2 0;
+#X connect 19 0 20 0;
+#X connect 19 1 20 1;
+#X connect 19 2 20 2;
+#X connect 19 3 20 3;
+#X connect 19 4 20 4;
+#X connect 19 5 20 5;
+#X connect 19 6 20 6;
+#X connect 19 7 20 7;
+#X connect 20 0 18 0;
+#X connect 21 0 2 0;
+#X connect 22 0 2 0;
+#X restore 531 60 pd resonators_example;
+#X msg 553 171 clear;
+#X obj 531 199 s msg_to_pyo;
+#X text 598 172 shutdown and reboot the server;
+#N canvas 1 75 450 300 synthesis_example 0;
+#N canvas 1 75 375 358 choose_sines 0;
+#X obj 57 77 metro 125;
+#X obj 78 109 hsl 128 15 0 36 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 4233 1;
+#X obj 127 144 hsl 128 15 0 36 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 4233 1;
+#X floatatom 75 125 5 0 0 0 - - -;
+#X floatatom 124 160 5 0 0 0 - - -;
+#X obj 124 209 +;
+#X obj 124 179 t b f;
+#X obj 75 144 t f f;
+#X obj 57 240 int;
+#X obj 124 232 int;
+#X msg 57 288 call choose \$1 \$2;
+#X obj 57 311 outlet;
+#X obj 57 54 inlet;
+#X obj 57 265 pack 24 24;
+#X text 7 3 Choose a random midi pitch between x and x+y;
+#X text 213 109 x;
+#X text 263 142 y;
+#X obj 224 42 loadbang;
+#X msg 224 64 12;
+#X obj 117 54 inlet speed;
+#X connect 0 0 8 0;
+#X connect 1 0 3 0;
+#X connect 2 0 4 0;
+#X connect 3 0 7 0;
+#X connect 4 0 6 0;
+#X connect 5 0 9 0;
+#X connect 6 0 5 0;
+#X connect 6 1 5 1;
+#X connect 7 0 8 1;
+#X connect 7 1 5 0;
+#X connect 8 0 13 0;
+#X connect 9 0 13 1;
+#X connect 10 0 11 0;
+#X connect 12 0 0 0;
+#X connect 13 0 10 0;
+#X connect 17 0 18 0;
+#X connect 18 0 1 0;
+#X connect 18 0 2 0;
+#X connect 19 0 0 1;
+#X restore 53 130 pd choose_sines;
+#X obj 41 246 s msg_to_pyo;
+#X obj 53 96 tgl 25 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1
+;
+#X obj 67 172 hsl 128 15 0 0.25 0 0 empty empty brightness -2 -8 0
+10 -262144 -1 -1 0 0;
+#X floatatom 64 188 5 0 0 0 - - -;
+#X msg 64 203 value feed \$1;
+#X obj 158 75 hsl 128 15 50 500 0 0 empty empty metro_speed -2 -8 0
+10 -262144 -1 -1 0 1;
+#X floatatom 155 93 5 0 0 0 - - -;
+#X floatatom 222 186 5 0 0 0 - - -;
+#X msg 222 216 set amp.fadeout \$1;
+#X msg 281 184 set amp.dur \$1;
+#X floatatom 281 165 5 0 0 0 - - -;
+#X obj 222 132 * 0.001;
+#X obj 221 111 - 20;
+#X obj 222 165 - 0.005;
+#X msg 41 33 read -a examples/random_waves.py;
+#X text 54 80 GO!;
+#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 5 0 1 0;
+#X connect 6 0 7 0;
+#X connect 7 0 0 1;
+#X connect 7 0 13 0;
+#X connect 8 0 9 0;
+#X connect 9 0 1 0;
+#X connect 10 0 1 0;
+#X connect 11 0 10 0;
+#X connect 12 0 11 0;
+#X connect 12 0 14 0;
+#X connect 13 0 12 0;
+#X connect 14 0 8 0;
+#X connect 15 0 1 0;
+#X restore 531 84 pd synthesis_example;
+#N canvas 1 75 629 295 loop_soundfile 0;
+#X obj 43 42 openpanel;
+#X obj 43 64 t a b;
+#X obj 43 170 soundfiler;
+#X obj 236 80 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 43 20 inlet open file;
+#X obj 392 16 inlet start;
+#X obj 236 52 sel 1;
+#X obj 236 205 outlet~;
+#X obj 347 163 spigot 1;
+#X obj 43 126 pack s s s;
+#X obj 71 86 symbol \$0-table_l;
+#X obj 100 105 symbol \$0-table_r;
+#X msg 43 148 read -resize \$1 \$2 \$3;
+#X obj 44 200 table \$0-table_l;
+#X obj 44 223 table \$0-table_r;
+#X obj 423 206 outlet~;
+#X obj 236 140 tabplay~ \$0-table_l;
+#X obj 424 140 tabplay~ \$0-table_r;
+#X connect 0 0 1 0;
+#X connect 1 0 9 0;
+#X connect 1 1 10 0;
+#X connect 1 1 11 0;
+#X connect 3 0 16 0;
+#X connect 3 0 17 0;
+#X connect 4 0 0 0;
+#X connect 5 0 6 0;
+#X connect 5 0 8 1;
+#X connect 6 0 3 0;
+#X connect 8 0 16 0;
+#X connect 8 0 17 0;
+#X connect 9 0 12 0;
+#X connect 10 0 9 1;
+#X connect 11 0 9 2;
+#X connect 12 0 2 0;
+#X connect 16 0 7 0;
+#X connect 16 1 8 0;
+#X connect 17 0 15 0;
+#X restore 28 126 pd loop_soundfile;
+#X text 44 108 load file;
+#N canvas 1 75 532 224 conv_reverb_example 0;
+#X obj 24 110 hsl 128 15 0 1 0 0 empty empty balance -2 -8 0 10 -262144
+-1 -1 0 0;
+#X floatatom 21 127 5 0 0 0 - - -;
+#X msg 21 143 value bal \$1;
+#X obj -3 170 s msg_to_pyo;
+#X msg -3 74 read examples/cvlverb.py;
+#X text -5 38 load pyo processing file (audio signal must be given
+in pyo~ inputs).;
+#X text 162 110 balance between dry and wet signal;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X connect 4 0 3 0;
+#X restore 531 36 pd conv_reverb_example;
+#X text 26 86 play a soundfile to send audio signals to pyo;
+#N canvas 114 140 450 300 README 0;
+#X restore 406 227 pd README;
+#N canvas 198 75 1001 402 MESSAGES 0;
+#X text 20 53 read [-a] path/to/python/script;
+#X text 37 74 The message "read" executes the commands contained in
+the specified python script into the object's internal interpreter.
+If the "-a" flag is given \, new commands will be added to previously
+executed ones. Without the flag \, the server is shut down (this will
+erase actual processing) before the execution of the script.;
+#X text 18 164 value varname \$1 [\$2 \$3 ...];
+#X text 19 250 set varname.attribute \$1 [\$2 \$3 ...];
+#X text 499 43 call function [arg1 arg2 ...];
+#X text 499 229 clear;
+#X text 516 250 Shutdown and reboot pyo's server. This message will
+erase the current processing loaded into the object.;
+#X text 36 185 The messsage "value" sends value(s) to a pyo's Sig or
+SigTo object (with variable name "varname"). Values can be pyo's variables
+(already created in the loaded file) \, float or list (composed of
+floats and/or pyo objects).;
+#X text 516 63 The message "call" executes the function (or object's
+method) with optional arguments. If the callable is a method \, the
+syntax will looks like:;
+#X text 515 103 call varname.method [arg1 arg2 ...];
+#X text 36 351 set frequencies 100 200 300 400 500 600;
+#X text 499 130 create varname object [\$1 \$2 ...];
+#X text -16 3 Here are the messages that can be used to control the
+internal processing of the pyo~ object.;
+#X text 513 149 The message "create" creates a new python object of
+the class "object" \, stored in variable "varname" \, with optional
+initialization arguments. Arguments can be of the form freq=500 or
+mul=0.3 \, without spaces. Named arguments can't be followed by unamed
+arguments.;
+#X text 36 272 The messsage "set" sends value(s) to an attribute of
+any pyo object (with variable name "varname"). Values can be pyo's
+variables (already created in the loaded file) \, float or list (composed
+of floats and/or pyo objects). This message can be used to create a
+standard python variable like (to create a list of floats in variable
+"frequencies"):;
+#X text 499 291 debug \$1;
+#X text 516 312 If \$1 is positive \, messages to pyo will be sent
+through an Exception handler. This is safer and can help to debug messages
+to pyo but it is slower. For a faster execution \, turn off debug mode.
+;
+#X restore 406 248 pd MESSAGES;
+#X msg 553 297 call b.out;
+#X text 11 7 pyo~ object allows to execute processing with pyo (python
+dsp module) inside a puredata patch \, with any number of audio in/out
+channels.;
+#X obj 531 121 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X msg 531 144 debug \$1;
+#X text 549 113 Verbose mode. If on \, error messages from pyo will
+be printed to the Pd window.;
+#X obj 518 323 s msg_to_pyo;
+#X msg 553 234 set pits 0.001 0.002 0.003 0.004;
+#X msg 553 255 create fr Rossler pitch=pits chaos=0.9 mul=250 add=500
+;
+#X msg 553 276 create b SumOsc freq=fr ratio=0.499 index=0.4 mul=0.2
+;
+#X connect 0 0 17 0;
+#X connect 1 0 17 1;
+#X connect 2 0 4 0;
+#X connect 3 0 4 1;
+#X connect 5 0 3 1;
+#X connect 5 0 2 1;
+#X connect 6 0 7 0;
+#X connect 8 0 10 0;
+#X connect 10 0 2 0;
+#X connect 10 1 3 0;
+#X connect 13 0 14 0;
+#X connect 17 0 10 0;
+#X connect 17 1 10 1;
+#X connect 23 0 28 0;
+#X connect 25 0 26 0;
+#X connect 26 0 14 0;
+#X connect 29 0 28 0;
+#X connect 30 0 28 0;
+#X connect 31 0 28 0;
diff --git a/embedded/puredata/pyo~-meta.pd b/embedded/puredata/pyo~-meta.pd
new file mode 100644
index 0000000..18a355f
--- /dev/null
+++ b/embedded/puredata/pyo~-meta.pd
@@ -0,0 +1,6 @@
+#N canvas 15 49 200 200 10;
+#N canvas 25 49 420 300 META 1;
+#X text 13 41 NAME pyo~;
+#X text 10 25 AUTHOR belangeo at gmail.com;
+#X text 10 10 VERSION 0.1;
+#X restore 10 10 pd META;
diff --git a/embedded/puredata/pyo~.c b/embedded/puredata/pyo~.c
new file mode 100644
index 0000000..1e675b1
--- /dev/null
+++ b/embedded/puredata/pyo~.c
@@ -0,0 +1,250 @@
+#include <stdlib.h>
+#include "m_pd.h"
+#include "Python.h"
+#include "m_pyo.h"
+
+static t_class *pyo_tilde_class;
+
+typedef struct _pyo_tilde {
+    t_object  obj;
+    t_sample  f;
+    int debug;
+    int bs;
+    int add;
+    int chnls;
+    float sr;
+    char *file;
+    t_sample **in;
+    t_sample **out;
+    int id;                 /* pyo server id */
+    float *inbuf;           /* pyo input buffer */
+    float *outbuf;          /* pyo output buffer */
+    char *msg;              /* preallocated string to construct message for pyo */
+    void (*callback)(int);  /* pointer to pyo embedded server callback */
+    PyThreadState *interp;  /* Python thread state linked to this sub interpreter */
+} t_pyo_tilde;
+
+t_int *pyo_tilde_perform(t_int *w) {
+    int i, j, n;
+    t_pyo_tilde *x = (t_pyo_tilde *)(w[1]); /* pointer to instance struct */
+    n = (int)(w[2]);                        /* vector size */
+    t_sample **in = x->in;
+    t_sample **out = x->out;
+    for (i=0; i<n; i++) {
+        for (j=0; j<x->chnls; j++) {
+            x->inbuf[i*x->chnls+j] = in[j][i];
+        }
+    }
+    (*x->callback)(x->id);
+    for (i=0; i<n; i++) {
+        for (j=0; j<x->chnls; j++) {
+            out[j][i] = x->outbuf[i*x->chnls+j];
+        }
+    }
+    return (w+3);
+}
+
+void pyo_tilde_dsp(t_pyo_tilde *x, t_signal **sp) {
+    int i, err;
+    t_sample **dummy = x->in;
+    for (i=0; i<x->chnls; i++)
+        *dummy++ = sp[i]->s_vec;
+    dummy = x->out;
+    for (i=x->chnls; i<x->chnls*2; i++)
+        *dummy++ = sp[i]->s_vec;
+    /* reset pyo only if sampling rate or buffer size have changed */
+    if ((float)sp[0]->s_sr != x->sr || (int)sp[0]->s_n != x->bs) {
+        x->sr = (float)sp[0]->s_sr;
+        x->bs = (int)sp[0]->s_n;
+        pyo_set_server_params(x->interp, x->sr, x->bs);
+        if (x->file != NULL) {
+            err = pyo_exec_file(x->interp, x->file, x->msg, x->add);
+            if (err) {
+                post("Unable to open file < %s >", x->file);
+                x->file = NULL;
+            }
+        }
+    }
+    dsp_add(pyo_tilde_perform, 2, x, sp[0]->s_n);
+}
+
+void *pyo_tilde_new(t_floatarg f) {
+    int i;
+    t_pyo_tilde *x = (t_pyo_tilde *)pd_new(pyo_tilde_class);
+
+    x->chnls = (f) ? f : 2;
+    x->bs = -1;
+    x->sr = -1.0;
+    x->file = NULL;
+    x->add = 0;
+    x->debug = 0;
+
+    /* create signal inlets (first is done in pyo_tilde_setup) */
+    for (i=1; i<x->chnls; i++)
+        inlet_new(&x->obj, &x->obj.ob_pd, &s_signal, &s_signal);
+    /* create signal outlets */
+    for (i=0; i<x->chnls; i++)
+        outlet_new(&x->obj, &s_signal);
+
+    x->in = (t_sample **)getbytes(x->chnls * sizeof(t_sample **));
+    x->out = (t_sample **)getbytes(x->chnls * sizeof(t_sample **));
+    x->msg = (char *)getbytes(262144 * sizeof(char *));
+
+    for (i=0; i<x->chnls; i++)
+        x->in[i] = x->out[i] = 0;
+
+    x->interp = pyo_new_interpreter(x->chnls);
+    
+    x->inbuf = (float *)pyo_get_input_buffer_address(x->interp);
+    x->outbuf = (float *)pyo_get_output_buffer_address(x->interp);
+    x->callback = (void *)pyo_get_embedded_callback_address(x->interp);
+    x->id = pyo_get_server_id(x->interp);
+
+    return (void *)x;
+}
+
+void pyo_tilde_free(t_pyo_tilde *x) {
+    freebytes(x->in, sizeof(x->in));
+    freebytes(x->out, sizeof(x->out));
+    freebytes(x->msg, sizeof(x->msg));
+    pyo_end_interpreter(x->interp);
+}
+
+void pyo_tilde_set_value(t_pyo_tilde *x, char *att, int argc, t_atom *argv) {
+    int err, bracket = 0;
+    char fchar[32];
+    t_symbol *c = atom_getsymbol(argv);
+    argc--; argv++;
+    sprintf(x->msg, "%s%s=", c->s_name, att);
+    if (argc > 1) {
+        strcat(x->msg, "[");
+        bracket = 1;    
+    }
+    while (argc-- > 0) {
+        if (argv->a_type == A_SYMBOL) {
+            strcat(x->msg, atom_getsymbol(argv)->s_name);
+        }
+        else if (argv->a_type == A_FLOAT) {
+            sprintf(fchar, "%.6f", atom_getfloat(argv));
+            strcat(x->msg, fchar);
+        }
+        if (argc > 0)
+            strcat(x->msg, ",");
+        argv++;
+    }
+    if (bracket)
+        strcat(x->msg, "]");
+    err = pyo_exec_statement(x->interp, x->msg, x->debug);
+    if (err)
+        post("pyo~: %s", x->msg);
+}
+
+void pyo_tilde_value(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
+    char *att = ".value";
+    pyo_tilde_set_value(x, att, argc, argv);
+}
+void pyo_tilde_set(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
+    char *att = "";
+    pyo_tilde_set_value(x, att, argc, argv);
+}
+
+void pyo_tilde_create(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
+    int err;
+    char *varname, *object;
+    char fchar[32];
+    t_symbol *c = atom_getsymbol(argv);
+    varname = c->s_name;
+    argc--; argv++;
+    c = atom_getsymbol(argv);
+    object = c->s_name;
+    argc--; argv++;
+    sprintf(x->msg, "%s=%s(", varname, object);
+    while (argc-- > 0) {
+        if (argv->a_type == A_SYMBOL) {
+            strcat(x->msg, atom_getsymbol(argv)->s_name);
+        }
+        else if (argv->a_type == A_FLOAT) {
+            sprintf(fchar, "%f", atom_getfloat(argv));
+            strcat(x->msg, fchar);
+        }
+        if (argc > 0)
+            strcat(x->msg, ",");
+        argv++;
+    }
+    strcat(x->msg, ")");
+    err = pyo_exec_statement(x->interp, x->msg, x->debug);
+    if (err)
+        post("pyo~: %s", x->msg);
+}
+
+void pyo_tilde_clear(t_pyo_tilde *x) {
+    pyo_server_reboot(x->interp);
+}
+
+void pyo_tilde_debug(t_pyo_tilde *x, t_float debug) {
+    x->debug = debug <= 0 ? 0 : 1;
+}
+
+void pyo_tilde_read(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
+    int err;
+    switch (argc) {
+        case 1:
+            x->add = 0;
+            x->file = atom_getsymbol(argv)->s_name;
+            break;
+        case 2:
+            x->add = strcmp(atom_getsymbol(argv++)->s_name, "-a") == 0 ? 1 : 0;
+            x->file = atom_getsymbol(argv)->s_name;
+            break;
+    }
+    if (pyo_is_server_started(x->interp)) { 
+        err = pyo_exec_file(x->interp, x->file, x->msg, x->add);
+        if (err) {
+            post("Unable to open file < %s >", x->file);
+            x->file = NULL;
+        }
+    }
+}
+
+void pyo_tilde_call(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
+    int err;
+    char fchar[32];
+    sprintf(x->msg, "%s(", atom_getsymbol(argv)->s_name);
+    argc--; argv++;
+    while (argc-- > 0) {
+        if (argv->a_type == A_SYMBOL) {
+            strcat(x->msg, atom_getsymbol(argv)->s_name);
+        }
+        else if (argv->a_type == A_FLOAT) {
+            sprintf(fchar, "%f", atom_getfloat(argv));
+            strcat(x->msg, fchar);
+        }
+        if (argc > 0)
+            strcat(x->msg, ", ");
+        argv++;
+    }
+    strcat(x->msg, ")");
+    err = pyo_exec_statement(x->interp, x->msg, x->debug);
+    if (err)
+        post("pyo~: %s", x->msg);
+}
+
+void pyo_tilde_setup(void) {
+    pyo_tilde_class = class_new(gensym("pyo~"), (t_newmethod)pyo_tilde_new,
+        (t_method)pyo_tilde_free, sizeof(t_pyo_tilde), CLASS_DEFAULT, A_DEFFLOAT, 0);
+    class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_dsp, gensym("dsp"), 0);
+    class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_clear, gensym("clear"), 0);
+    class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_value, gensym("value"), 
+                    A_GIMME, 0); /* send value(s) to a Sig or SigTo object */
+    class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_set, gensym("set"), 
+                    A_GIMME, 0); /* send value(s) to any object's attribute */
+    class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_read, gensym("read"), 
+                    A_GIMME, 0); /* read a script file */
+    class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_call, gensym("call"), 
+                    A_GIMME, 0); /* call a function or a method */
+    class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_create, gensym("create"), 
+                    A_GIMME, 0); /* create a python object */
+    class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_debug, gensym("debug"), 
+                    A_DEFFLOAT, 0); /* set the debug (verbose) mode */
+    CLASS_MAINSIGNALIN(pyo_tilde_class, t_pyo_tilde, f);
+}
diff --git a/examples/utilities/02_osc_scan.py b/examples/utilities/02_osc_scan.py
new file mode 100644
index 0000000..442247e
--- /dev/null
+++ b/examples/utilities/02_osc_scan.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+# encoding: utf-8
+"""
+Scan Open Sound Control inputs. Launch this script from a terminal.
+
+"""
+from pyo import *
+import time
+
+port = input("Enter the incoming port number : ")
+
+s = Server().boot().start()
+
+print "Play with your OSC interface..."
+
+go = True
+def pp(address, *args): 
+    if go:
+        print "Address =", address
+        print "Values =", args
+        print "---------------"
+
+scan = OscDataReceive(port, "*", pp)
+
+again = "y"
+while again == "y":
+    time.sleep(10)
+    go = False
+    again = raw_input("Do you want to continue ? (y/n) : ")
+    if again == "y":
+        print "Continue..."
+        go = True
+    
+s.stop()
+time.sleep(1)
+exit()
+    
\ No newline at end of file
diff --git a/examples/utilities/04_batch_processing.py b/examples/utilities/04_batch_processing.py
index fa7b094..fa1f6b6 100644
--- a/examples/utilities/04_batch_processing.py
+++ b/examples/utilities/04_batch_processing.py
@@ -4,37 +4,46 @@
 This script demonstrates how to use pyo to do offline batch processing.
 
 """
-import os
 from pyo import *
-s = Server(duplex=0, audio="offline").boot()
-
-# input sound
-sndpath = SNDS_PATH + "/accord.aif"
-# output folder
-recpath = os.path.join(os.path.expanduser("~"), "Desktop", "pyo_batch")
-if not os.path.isdir(recpath):
-    os.mkdir(recpath)
-
-# output file duration
-dur = sndinfo(sndpath)[1]
-
-NUM = 10
-for i in range(NUM):
-    note = 12 + i
-    noteFreq = midiToHz(note)
-    s.recordOptions(dur=dur+.1, filename=os.path.join(recpath, "file_%02d.wav" % note), fileformat=0, sampletype=0)
-
-    ### processing goes here ###
-    osc = Sine(freq=noteFreq, mul=i*0.01+.02, add=1)
-    a = SfPlayer(sndpath, speed=osc, loop=False, mul=0.7).mix(2).out()
-
-    ############################
-
-    s.start() # s.stop() is automatically called when rendering is done
-    # do not reboot the server after the last pass
-    if i < (NUM-1):
-        s.shutdown()
-        s.boot()
-
-print "Batch processing done"
+import os
 
+s = Server(audio="offline")
+
+# path to your sound folder
+folder_path = SNDS_PATH
+# path to the processed sounds folder (user's home directory/batch)
+output_folder = os.path.join(os.path.expanduser("~"), "pyo_batch_fx")
+# create it if it does not exist
+if not os.path.isdir(output_folder):
+    os.mkdir(output_folder)
+
+# get the list of files to process
+sounds = [file for file in os.listdir(folder_path) if sndinfo(os.path.join(folder_path, file)) != None]
+
+# enter the batch processing loop
+for sound in sounds:
+    # retrieve info about the sound
+    path = os.path.join(folder_path, sound)
+    info = sndinfo(path)
+    dur, sr, chnls = info[1], info[2], info[3]
+    fformat = ['WAVE', 'AIFF', 'AU', 'RAW', 'SD2', 'FLAC', 'CAF', 'OGG'].index(info[4])
+    samptype = ['16 bit int', '24 bit int', '32 bit int', '32 bit float', 
+                '64 bits float', 'U-Law encoded', 'A-Law encoded'].index(info[5])
+
+    # set server parameters
+    s.setSamplingRate(sr)
+    s.setNchnls(chnls)
+    s.boot()
+    s.recordOptions(dur=dur, filename=os.path.join(output_folder, sound), 
+                    fileformat=fformat, sampletype=samptype)
+    
+    # processing
+    sf = SfPlayer(path)
+    bp = ButBP(sf, 1000, 2)
+    dt = Disto(bp, drive=0.9, slope=0.8)
+    mx = Interp(sf, dt, interp=0.5, mul=0.5).out()
+    
+    # start the render
+    s.start()
+    # cleanup
+    s.shutdown()
diff --git a/examples/utilities/04_batch_synthesis.py b/examples/utilities/04_batch_synthesis.py
new file mode 100644
index 0000000..8b32246
--- /dev/null
+++ b/examples/utilities/04_batch_synthesis.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+# encoding: utf-8
+"""
+This script demonstrates how to use pyo to do synthesis batch generation.
+
+"""
+import os
+from pyo import *
+s = Server(duplex=0, audio="offline")
+
+# output folder
+output_folder = os.path.join(os.path.expanduser("~"), "pyo_batch_synth")
+if not os.path.isdir(output_folder):
+    os.mkdir(output_folder)
+
+# output file duration
+dur = 2
+
+NUM = 12
+for i in range(NUM):
+    s.boot()
+    note = 60 + i
+    noteFreq = midiToHz(note)
+    s.recordOptions(dur=dur+.1, filename=os.path.join(output_folder, "file_%02d.wav" % note), 
+                    fileformat=0, sampletype=0)
+
+    ### processing goes here ###
+    env = Adsr(attack=0.005, decay=0.15, sustain=0.7, release=1.7, dur=dur).play()
+    qenv = Pow(env, 4, mul=0.8)
+    osc1 = SineLoop(freq=noteFreq, feedback=0.075, mul=qenv).out()
+    osc2 = SineLoop(freq=noteFreq*1.01, feedback=0.075, mul=qenv).out(1)
+
+    # start th render
+    s.start()
+    # cleanup
+    s.shutdown()
+
+print "Batch processing done"
+
diff --git a/examples/utilities/07_scope.py b/examples/utilities/07_scope.py
new file mode 100644
index 0000000..4af4ec3
--- /dev/null
+++ b/examples/utilities/07_scope.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# encoding: utf-8
+"""
+Simple scope example.
+
+"""
+from pyo import *
+
+class Scope:
+    def __init__(self, input, length=0.05):
+        self.input = input
+        self.table = NewTable(length=length, chnls=len(input))
+        self.table.view(title="Signal Scope")
+        self.trig = Metro(time=length).play()
+        self.rec = TrigTableRec(self.input, self.trig, self.table)
+        self.trf = TrigFunc(self.trig, function=self.update)
+
+    def start(self, x):
+        if x: self.trig.play()
+        else: self.trig.stop()
+
+    def update(self):
+        self.table.refreshView()
+
+s = Server(duplex=1).boot()
+
+CHNLS = 2
+LENGTH = 0.05
+
+inp = Input(chnl=range(CHNLS))
+scope = Scope(inp, LENGTH)
+
+s.gui(locals())
diff --git a/externals/external-template.py b/externals/external-template.py
index 1ee8e92..3cdca10 100644
--- a/externals/external-template.py
+++ b/externals/external-template.py
@@ -41,12 +41,10 @@ class Gain(PyoObject):
     """
     # Do not forget "mul" and "add" attributes.
     def __init__(self, input, db=-3, mul=1, add=0):
-        PyoObject.__init__(self)
+        PyoObject.__init__(self, mul, add)
         # Keep trace of arguments (same name preceded by an underscore)
         self._input = input
         self._db = db
-        self._mul = mul
-        self._add = add
         # Always use InputFader for the input sound. That allows crossfade on input changes.  
         self._in_fader = InputFader(input)
         # Converts every arguments to lists (for multi-channel expansion).
diff --git a/include/pyomodule.h b/include/pyomodule.h
index ce4ba6c..d83f8f7 100644
--- a/include/pyomodule.h
+++ b/include/pyomodule.h
@@ -21,7 +21,7 @@
 #include "Python.h"
 #include <math.h>
 
-#define PYO_VERSION "0.6.8"
+#define PYO_VERSION "0.6.9"
 
 #ifndef __MYFLT_DEF
 #define __MYFLT_DEF
@@ -73,6 +73,7 @@
 #define TYPE__OFII "|Ofii"
 #define TYPE__FIIOO "|fiiOO"
 #define TYPE_O_OFOO "O|OfOO"
+#define TYPE_O_OOOOFF "O|OOOOff"
 #define TYPE_O_IFFO "O|iffO"
 #define TYPE_O_OOIF "O|OOif"
 #define TYPE_O_FFFFIOO "O|ffffiOO"
@@ -153,6 +154,7 @@
 #define TYPE__OFII "|Odii"
 #define TYPE__FIIOO "|diiOO"
 #define TYPE_O_OFOO "O|OdOO"
+#define TYPE_O_OOOOFF "O|OOOOdd"
 #define TYPE_O_IFFO "O|iddO"
 #define TYPE_O_OOIF "O|OOid"
 #define TYPE_O_FFFFIOO "O|ddddiOO"
@@ -455,6 +457,11 @@ extern PyTypeObject PVBufTabLoopsType;
 extern PyTypeObject PVMixType;
 extern PyTypeObject GranuleType;
 extern PyTypeObject TableScaleType;
+extern PyTypeObject TrackHoldType;
+extern PyTypeObject ComplexResType;
+extern PyTypeObject STReverbType;
+extern PyTypeObject STRevType;
+extern PyTypeObject Pointer2Type;
 
 /* Constants */
 #define E M_E
@@ -492,6 +499,7 @@ extern PyTypeObject TableScaleType;
 #define FREEVERB_ID 24
 #define XNOISEDUR_ID 25
 #define URN_ID 26
+/* Do not forget to modify Server_generateSeed function */
 
 /* object headers */
 #define pyo_audio_HEAD \
@@ -776,6 +784,128 @@ extern PyTypeObject TableScaleType;
     Py_INCREF(Py_None); \
     return Py_None; \
 
+/* Table amplitude reverse */
+#define INVERT \
+    int i; \
+    for (i=0; i<self->size+1; i++) { \
+        self->data[i] = -self->data[i]; \
+    } \
+    Py_INCREF(Py_None); \
+    return Py_None; \
+
+/* Table positive rectify */
+#define RECTIFY \
+    int i; \
+    MYFLT x; \
+    for (i=0; i<self->size+1; i++) { \
+        x = self->data[i]; \
+        if (x < 0) \
+            self->data[i] = -x; \
+    } \
+    Py_INCREF(Py_None); \
+    return Py_None; \
+
+/* Table bipolar gain */
+#define TABLE_BIPOLAR_GAIN \
+    MYFLT gpos = 1.0, gneg = 1.0; \
+    int i; \
+    static char *kwlist[] = {"gpos", "gneg", NULL}; \
+ \
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE__FF, kwlist, &gpos, &gneg)) \
+        return PyInt_FromLong(-1); \
+ \
+    for (i=0; i<self->size+1; i++) { \
+        if (self->data[i] < 0) \
+            self->data[i] *= gneg; \
+        else \
+            self->data[i] *= gpos; \
+    } \
+ \
+    Py_RETURN_NONE;
+
+/* Table power function */
+#define TABLE_POWER \
+    MYFLT x, exp; \
+    int i, sign; \
+    static char *kwlist[] = {"exp", NULL}; \
+ \
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_F, kwlist, &exp)) \
+        return PyInt_FromLong(-1); \
+ \
+    for (i=0; i<self->size+1; i++) { \
+        x = self->data[i]; \
+        sign = 1; \
+        if (x < 0) \
+            sign = -1; \
+        x = MYPOW(x, exp); \
+        if (sign == -1 && x > 0) \
+            x = -x; \
+        self->data[i] = x; \
+    } \
+ \
+    Py_RETURN_NONE;
+
+/* Table one-pole lowpass filter */
+#define TABLE_LOWPASS \
+    MYFLT freq, b, c, x, y; \
+    int i; \
+    double sr = PyFloat_AsDouble(PyObject_CallMethod(PyServer_get_server(), "getSamplingRate", NULL)); \
+    static char *kwlist[] = {"freq", NULL}; \
+ \
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_F, kwlist, &freq)) \
+        return PyInt_FromLong(-1); \
+ \
+    b = 2.0 - MYCOS(TWOPI * freq / sr); \
+    c = b - MYSQRT(b * b - 1.0); \
+    y = 0; \
+    for (i=0; i<self->size+1; i++) { \
+        x = self->data[i]; \
+        self->data[i] = y = x + (y - x) * c; \
+    } \
+ \
+    Py_RETURN_NONE;
+
+/* FADE IN, FADE OUT */
+#define TABLE_FADEIN \
+    MYFLT dur, inc; \
+    int i, samp; \
+    double sr = PyFloat_AsDouble(PyObject_CallMethod(PyServer_get_server(), "getSamplingRate", NULL)); \
+    static char *kwlist[] = {"dur", NULL}; \
+ \
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_F, kwlist, &dur)) \
+        return PyInt_FromLong(-1); \
+ \
+    samp = (int)(dur * sr); \
+    if (samp < 0 || samp >= self->size) \
+        Py_RETURN_NONE; \
+ \
+    inc = 1.0 / samp; \
+    for (i=0; i<samp; i++) { \
+        self->data[i] = self->data[i] * MYSQRT(inc * i); \
+    } \
+ \
+    Py_RETURN_NONE;
+
+#define TABLE_FADEOUT \
+    MYFLT dur, inc; \
+    int i, samp; \
+    double sr = PyFloat_AsDouble(PyObject_CallMethod(PyServer_get_server(), "getSamplingRate", NULL)); \
+    static char *kwlist[] = {"dur", NULL}; \
+ \
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_F, kwlist, &dur)) \
+        return PyInt_FromLong(-1); \
+ \
+    samp = (int)(dur * sr); \
+    if (samp < 0 || samp >= self->size) \
+        Py_RETURN_NONE; \
+ \
+    inc = 1.0 / samp; \
+    for (i=self->size; i>(self->size-samp); i--) { \
+        self->data[i] = self->data[i] * MYSQRT(inc * (self->size - i)); \
+    } \
+ \
+    Py_RETURN_NONE;
+
 /* Normalize */
 #define NORMALIZE \
 	int i; \
diff --git a/installers/osx/PkgResources_i386/ReadMe.rtf b/installers/osx/PkgResources_i386/ReadMe.rtf
index da986d8..ab49df1 100755
--- a/installers/osx/PkgResources_i386/ReadMe.rtf
+++ b/installers/osx/PkgResources_i386/ReadMe.rtf
@@ -1,71 +1,92 @@
-{\rtf1\ansi\deff3\adeflang1025
-{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f4\fswiss\fprq2\fcharset0 Liberation Sans{\*\falt Arial};}{\f5\froman\fprq2\fcharset1 LucidaGrande;}{\f6\froman\fprq0\fcharset1 LucidaGrande;}{\f7\fnil\fprq2\fcharset0 DejaVu Sans;}{\f8\fnil\fprq2\fcharset0 Lohit Hindi;}{\f9\fnil\fprq0\fcharset1 Lohit Hindi;}}
-{\colortbl;\red0\green0\blue0;\red128\green128\blue128;}
-{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105 Normal;}
-{\s15\sbasedon0\snext16\sb240\sa120\keepn\dbch\af7\dbch\af8\afs28\loch\f4\fs28 Heading;}
-{\s16\sbasedon0\snext16\sb0\sa120 Text body;}
-{\s17\sbasedon16\snext17\sb0\sa120\dbch\af9 List;}
-{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af9\afs24\ai\fs24 Caption;}
-{\s19\sbasedon0\snext19\noline\dbch\af9 Index;}
-}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab720
-\viewscale110
-{\*\pgdsctbl
-{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}}
-\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1440\margr1440\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc
-\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f6
-pyo (version 0.6.}{\cf1\rtlch \ltrch\loch\fs26\loch\f6
-6}{\cf1\rtlch \ltrch\loch\fs26\loch\f6
-)}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f6
-This package installs all the required components to run pyo inside your current Python installation. Python 2.5, 2.6 (preferred) or 2.7 (32-bit Mac OS X Installer) must be already installed on your system.}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f6
-This package is divided into two separate installers. If you do not require one of them, please unselect the package in custom installation mode.}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\rtlch \ltrch\loch\fs26\loch\f6
-1. pyo extension:}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-The following components will be installed in the site-packages folder of the current Python Framework:}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-_pyo.so}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-_pyo64.so}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-pyo.py}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-pyo64.py}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-pyolib (folder)}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\rtlch \ltrch\loch\fs26\loch\f6
-2. Support libraries (i386):}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-This component will install a number of dynamic libraries on which pyo depends. If you already have these, then you can skip this installation.}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\rtlch \ltrch\loch\fs26\loch\f6
-Warning:}{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
- this installation will overwrite any previously installed libraries. These are the libraries that will be installed in your /usr/local/lib directory:}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-liblo.0.dylib}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-libportaudio.2.dylib}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-libportmidi.dylib}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-libsndfile.1.dylib}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-Olivier B\u233\'e9langer, 201}{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-3}
-\par }
\ No newline at end of file
+{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 LucidaGrande;\f1\froman\fcharset0 Times-Roman;}
+{\colortbl;\red255\green255\blue255;}
+\margl1440\margr1440\vieww14120\viewh11700\viewkind0
+\deftab720
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720
+
+\f0\fs26 \cf0 pyo (version 0.6.6)
+\f1\fs24 \
+
+\f0\fs26 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720\ql\qnatural
+\cf0 System requirements : OS X 10.5 or higher
+\f1\fs24 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720
+
+\f0\fs26 \cf0 \
+This package installs all the required components to run pyo inside your current Python installation. Python 2.5, 2.6 (preferred) or 2.7 (32-bit Mac OS X Installer) must be already installed on your system.
+\f1\fs24 \
+
+\f0\fs26 \
+This package is divided into two separate installers. If you do not require one of them, please unselect the package in custom installation mode.
+\f1\fs24 \
+
+\f0\fs26 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720
+
+\b \cf0 1. pyo extension:
+\f1\b0\fs24 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720
+
+\f0\fs26 \cf0 The following components will be installed in the site-packages folder of the current Python Framework:
+\f1\fs24 \
+
+\f0\fs26 \
+_pyo.so
+\f1\fs24 \
+
+\f0\fs26 _pyo64.so
+\f1\fs24 \
+
+\f0\fs26 pyo.py
+\f1\fs24 \
+
+\f0\fs26 pyo64.py
+\f1\fs24 \
+
+\f0\fs26 pyolib (folder)
+\f1\fs24 \
+
+\f0\fs26 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720
+
+\b \cf0 2. Support libraries (i386):
+\f1\b0\fs24 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720
+
+\f0\fs26 \cf0 This component will install a number of dynamic libraries on which pyo depends. If you already have these, then you can skip this installation.
+\f1\fs24 \
+
+\f0\fs26 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720
+
+\b \cf0 Warning:
+\b0  this installation will overwrite any previously installed libraries. These are the libraries that will be installed in your /usr/local/lib directory:
+\f1\fs24 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720
+
+\f0\fs26 \cf0 \
+liblo.0.dylib
+\f1\fs24 \
+
+\f0\fs26 libportaudio.2.dylib
+\f1\fs24 \
+
+\f0\fs26 libportmidi.dylib
+\f1\fs24 \
+
+\f0\fs26 libsndfile.1.dylib
+\f1\fs24 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720\ql\qnatural
+
+\f0\fs26 \cf0 libFLAC.8.dylib\
+libvorbisenc.2.dylib\
+libvorbis.0.dylib\
+libogg.0.dylib\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720
+\cf0 \
+\pard\pardeftab720\ql\qnatural
+\cf0 Olivier B\'e9langer, 2013
+\f1\fs24 \
+}
\ No newline at end of file
diff --git a/installers/osx/PkgResources_x86_64/ReadMe.rtf b/installers/osx/PkgResources_x86_64/ReadMe.rtf
index d6db53b..511c18c 100755
--- a/installers/osx/PkgResources_x86_64/ReadMe.rtf
+++ b/installers/osx/PkgResources_x86_64/ReadMe.rtf
@@ -1,75 +1,88 @@
-{\rtf1\ansi\deff3\adeflang1025
-{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f4\fswiss\fprq2\fcharset0 Liberation Sans{\*\falt Arial};}{\f5\froman\fprq2\fcharset1 LucidaGrande;}{\f6\froman\fprq0\fcharset1 LucidaGrande;}{\f7\fnil\fprq2\fcharset0 DejaVu Sans;}{\f8\fnil\fprq2\fcharset0 Lohit Hindi;}{\f9\fnil\fprq0\fcharset1 Lohit Hindi;}}
-{\colortbl;\red0\green0\blue0;\red128\green128\blue128;}
-{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105 Normal;}
-{\s15\sbasedon0\snext16\sb240\sa120\keepn\dbch\af7\dbch\af8\afs28\loch\f4\fs28 Heading;}
-{\s16\sbasedon0\snext16\sb0\sa120 Text body;}
-{\s17\sbasedon16\snext17\sb0\sa120\dbch\af9 List;}
-{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af9\afs24\ai\fs24 Caption;}
-{\s19\sbasedon0\snext19\noline\dbch\af9 Index;}
-}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab720
-\viewscale110
-{\*\pgdsctbl
-{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}}
-\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1440\margr1440\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc
-\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f6
-pyo (version 0.6.}{\cf1\rtlch \ltrch\loch\fs26\loch\f6
-6}{\cf1\rtlch \ltrch\loch\fs26\loch\f6
-)}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f6
-System requirements : OS X 10.6 or 10.7}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f6
-This package installs all the required components to run pyo inside your current Python installation. Python 2.6 or 2.7 (64-bit) must be already installed on your system.}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f6
-This package is divided into two separate installers. If you do not require one of them, please unselect the package in custom installation mode.}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\rtlch \ltrch\loch\fs26\loch\f6
-1. pyo extension:}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-The following components will be installed in the site-packages folder of the current Python Framework:}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-_pyo.so}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-_pyo64.so}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-pyo.py}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-pyo64.py}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-pyolib (folder)}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\rtlch \ltrch\loch\fs26\loch\f6
-2. Support libraries (i386 and x86_64):}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-This component will install a number of dynamic libraries on which pyo depends. If you already have these, then you can skip this installation.}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\rtlch \ltrch\loch\fs26\loch\f6
-Warning:}{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
- this installation will overwrite any previously installed libraries. These are the libraries that will be installed in your /usr/local/lib directory:}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-liblo.7.dylib}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-libportaudio.2.dylib}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-libportmidi.dylib}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-libsndfile.1.dylib}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105\ql\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang4105{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-Olivier B\u233\'e9langer, 201}{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f6
-3}
-\par }
\ No newline at end of file
+{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 LucidaGrande;\f1\froman\fcharset0 Times-Roman;}
+{\colortbl;\red255\green255\blue255;}
+\margl1440\margr1440\vieww13160\viewh13300\viewkind0
+\deftab720
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720\ql\qnatural
+
+\f0\fs26 \cf0 pyo (version 0.6.6)
+\f1\fs24 \
+
+\f0\fs26 \
+System requirements : OS X 10.6 to 10.8
+\f1\fs24 \
+
+\f0\fs26 \
+This package installs all the required components to run pyo inside your current Python installation. Python 2.6 or 2.7 (32/64 bit) must be already installed on your system.
+\f1\fs24 \
+
+\f0\fs26 \
+This package is divided into two separate installers. If you do not require one of them, please unselect the package in custom installation mode.
+\f1\fs24 \
+
+\f0\fs26 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720\ql\qnatural
+
+\b \cf0 1. pyo extension:
+\f1\b0\fs24 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720\ql\qnatural
+
+\f0\fs26 \cf0 The following components will be installed in the site-packages folder of the current Python Framework:
+\f1\fs24 \
+
+\f0\fs26 \
+_pyo.so
+\f1\fs24 \
+
+\f0\fs26 _pyo64.so
+\f1\fs24 \
+
+\f0\fs26 pyo.py
+\f1\fs24 \
+
+\f0\fs26 pyo64.py
+\f1\fs24 \
+
+\f0\fs26 pyolib (folder)
+\f1\fs24 \
+
+\f0\fs26 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720\ql\qnatural
+
+\b \cf0 2. Support libraries (i386 and x86_64):
+\f1\b0\fs24 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720\ql\qnatural
+
+\f0\fs26 \cf0 This component will install a number of dynamic libraries on which pyo depends. If you already have these, then you can skip this installation.
+\f1\fs24 \
+
+\f0\fs26 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720\ql\qnatural
+
+\b \cf0 Warning:
+\b0  this installation will overwrite any previously installed libraries. These are the libraries that will be installed in your /usr/local/lib directory:
+\f1\fs24 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720\ql\qnatural
+
+\f0\fs26 \cf0 \
+liblo.7.dylib
+\f1\fs24 \
+
+\f0\fs26 libportaudio.2.dylib
+\f1\fs24 \
+
+\f0\fs26 libportmidi.dylib
+\f1\fs24 \
+
+\f0\fs26 libsndfile.1.dylib
+\f1\fs24 \
+
+\f0\fs26 libFLAC.8.dylib\
+libvorbisenc.2.dylib\
+libvorbis.0.dylib\
+libogg.0.dylib\
+\
+\pard\pardeftab720\ql\qnatural
+\cf0 Olivier B\'e9langer, 2013
+\f1\fs24 \
+}
\ No newline at end of file
diff --git a/installers/osx/release_i386.sh b/installers/osx/release_i386.sh
index 7fc5e31..3838604 100644
--- a/installers/osx/release_i386.sh
+++ b/installers/osx/release_i386.sh
@@ -7,9 +7,9 @@
 # 4. cd utils and build E-Pyo
 # 5. cd installer/osx and build the realease
 
-export PACKAGE_NAME=pyo_0.6.8_i386.pkg
-export DMG_DIR="pyo 0.6.8 Intel"
-export DMG_NAME="pyo_0.6.8_OSX-Intel.dmg"
+export PACKAGE_NAME=pyo_0.6.9_i386.pkg
+export DMG_DIR="pyo 0.6.9 Intel"
+export DMG_NAME="pyo_0.6.9_OSX-Intel.dmg"
 export INSTALLER_DIR=`pwd`/installer
 export PYO_MODULE_DIR=$INSTALLER_DIR/PyoModule/Package_Contents/tmp
 export SUPPORT_LIBS_DIR=$INSTALLER_DIR/SupportLibs/Package_Contents/usr/local/lib
@@ -37,6 +37,11 @@ sudo /usr/local/bin/python2.7 setup.py install --use-coreaudio --use-double
 
 sudo cp -R build/lib.macosx-10.3-fat-2.7 $PYO_MODULE_DIR/python27
 
+sudo install_name_tool -change libportmidi.dylib /usr/local/lib/libportmidi.dylib $PYO_MODULE_DIR/python26/_pyo.so
+sudo install_name_tool -change libportmidi.dylib /usr/local/lib/libportmidi.dylib $PYO_MODULE_DIR/python26/_pyo64.so
+sudo install_name_tool -change libportmidi.dylib /usr/local/lib/libportmidi.dylib $PYO_MODULE_DIR/python27/_pyo.so
+sudo install_name_tool -change libportmidi.dylib /usr/local/lib/libportmidi.dylib $PYO_MODULE_DIR/python27/_pyo64.so
+
 cd ..
 
 echo "copying support libs..."
@@ -45,9 +50,9 @@ sudo cp /usr/local/lib/libportaudio.2.dylib $SUPPORT_LIBS_DIR/libportaudio.2.dyl
 sudo cp /usr/local/lib/libportmidi.dylib $SUPPORT_LIBS_DIR/libportmidi.dylib
 sudo cp /usr/local/lib/libsndfile.1.dylib $SUPPORT_LIBS_DIR/libsndfile.1.dylib
 sudo cp /usr/local/lib/libFLAC.8.dylib $SUPPORT_LIBS_DIR/libFLAC.8.dylib
-sudo cp /usr/local/lib/libogg.0.dylib $SUPPORT_LIBS_DIR/libogg.0.dylib
-sudo cp /usr/local/lib/libvorbis.0.dylib $SUPPORT_LIBS_DIR/libvorbis.0.dylib
 sudo cp /usr/local/lib/libvorbisenc.2.dylib $SUPPORT_LIBS_DIR/libvorbisenc.2.dylib
+sudo cp /usr/local/lib/libvorbis.0.dylib $SUPPORT_LIBS_DIR/libvorbis.0.dylib
+sudo cp /usr/local/lib/libogg.0.dylib $SUPPORT_LIBS_DIR/libogg.0.dylib
 
 echo "setting permissions..."
 
diff --git a/installers/osx/release_x86_64.sh b/installers/osx/release_x86_64.sh
index 4c21d67..317badf 100644
--- a/installers/osx/release_x86_64.sh
+++ b/installers/osx/release_x86_64.sh
@@ -1,8 +1,8 @@
 #!/bin/sh
 
-export PACKAGE_NAME=pyo_0.6.8_x86_64.pkg
-export DMG_DIR="pyo 0.6.8 Universal"
-export DMG_NAME="pyo_0.6.8_OSX-universal.dmg"
+export PACKAGE_NAME=pyo_0.6.9_x86_64.pkg
+export DMG_DIR="pyo 0.6.9 Universal"
+export DMG_NAME="pyo_0.6.9_OSX-universal.dmg"
 export INSTALLER_DIR=`pwd`/installer
 export PYO_MODULE_DIR=$INSTALLER_DIR/PyoModule/Package_Contents/tmp
 export SUPPORT_LIBS_DIR=$INSTALLER_DIR/SupportLibs/Package_Contents/usr/local/lib
@@ -33,6 +33,11 @@ sudo /usr/local/bin/python2.7 setup.py install --use-coreaudio --use-double
 
 sudo cp -R build/lib.macosx-10.6-intel-2.7 $PYO_MODULE_DIR/python27
 
+sudo install_name_tool -change libportmidi.dylib /usr/local/lib/libportmidi.dylib $PYO_MODULE_DIR/python26/_pyo.so
+sudo install_name_tool -change libportmidi.dylib /usr/local/lib/libportmidi.dylib $PYO_MODULE_DIR/python26/_pyo64.so
+sudo install_name_tool -change libportmidi.dylib /usr/local/lib/libportmidi.dylib $PYO_MODULE_DIR/python27/_pyo.so
+sudo install_name_tool -change libportmidi.dylib /usr/local/lib/libportmidi.dylib $PYO_MODULE_DIR/python27/_pyo64.so
+
 cd ..
 
 echo "copying support libs..."
@@ -41,12 +46,11 @@ sudo cp /usr/local/lib/libportaudio.2.dylib $SUPPORT_LIBS_DIR/libportaudio.2.dyl
 sudo cp /usr/local/lib/libportmidi.dylib $SUPPORT_LIBS_DIR/libportmidi.dylib
 sudo cp /usr/local/lib/libsndfile.1.dylib $SUPPORT_LIBS_DIR/libsndfile.1.dylib
 sudo cp /usr/local/lib/libFLAC.8.dylib $SUPPORT_LIBS_DIR/libFLAC.8.dylib
-sudo cp /usr/local/lib/libogg.0.dylib $SUPPORT_LIBS_DIR/libogg.0.dylib
-sudo cp /usr/local/lib/libvorbis.0.dylib $SUPPORT_LIBS_DIR/libvorbis.0.dylib
 sudo cp /usr/local/lib/libvorbisenc.2.dylib $SUPPORT_LIBS_DIR/libvorbisenc.2.dylib
+sudo cp /usr/local/lib/libvorbis.0.dylib $SUPPORT_LIBS_DIR/libvorbis.0.dylib
+sudo cp /usr/local/lib/libogg.0.dylib $SUPPORT_LIBS_DIR/libogg.0.dylib
 
 echo "setting permissions..."
-
 sudo chgrp -R admin PyoModule/Package_Contents/tmp
 sudo chown -R root PyoModule/Package_Contents/tmp
 sudo chmod -R 755 PyoModule/Package_Contents/tmp
diff --git a/installers/win/win_installer_py26.iss b/installers/win/win_installer_py26.iss
index 1d24ca6..759d3d1 100644
--- a/installers/win/win_installer_py26.iss
+++ b/installers/win/win_installer_py26.iss
@@ -7,7 +7,7 @@
 ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
 AppId={{4F72B6EF-CFA0-434F-A2B4-B130F94F54EB}
 AppName=Pyo
-AppVersion=0.6.8
+AppVersion=0.6.9
 AppPublisher=iACT.umontreal.ca
 AppPublisherURL=http://code.google.com/p/pyo
 AppSupportURL=http://code.google.com/p/pyo
@@ -17,7 +17,7 @@ DisableDirPage=yes
 DefaultGroupName=pyo
 AllowNoIcons=yes
 InfoBeforeFile=C:\Documents and Settings\user\svn\pyo\installers\win\\README-win32-py26.txt
-OutputBaseFilename=pyo_0.6.8_py2.6_setup
+OutputBaseFilename=pyo_0.6.9_py2.6_setup
 Compression=lzma
 SolidCompression=yes
 ChangesAssociations=yes
@@ -42,7 +42,7 @@ Source: "C:\Python26\Lib\site-packages\pthreadVC2.dll"; DestDir: "{sd}\Python26\
 Source: "C:\Python26\Lib\site-packages\msvcr90.dll"; DestDir: "{sd}\Python26\Lib\site-packages"; Flags: ignoreversion
 Source: "C:\MinGW\bin\libgcc_s_dw2-1.dll"; DestDir: "{sd}\Python26\Lib\site-packages"; Flags: ignoreversion
 Source: "C:\MinGW\bin\libstdc++-6.dll"; DestDir: "{sd}\Python26\Lib\site-packages"; Flags: ignoreversion
-Source: "C:\Python26\Lib\site-packages\pyo-0.6.8-py2.6.egg-info"; DestDir: "{sd}\Python26\Lib\site-packages"; Flags: ignoreversion
+Source: "C:\Python26\Lib\site-packages\pyo-0.6.9-py2.6.egg-info"; DestDir: "{sd}\Python26\Lib\site-packages"; Flags: ignoreversion
 Source: "C:\Documents and Settings\user\svn\pyo\examples\*"; DestDir: "{userdesktop}\pyo_examples\"; Flags: ignoreversion recursesubdirs createallsubdirs
 Source: "C:\Documents and Settings\user\svn\pyo\installers\win\README-win32-py26.txt"; DestDir: "{userdesktop}"; Flags: ignoreversion
 ; NOTE: Don't use "Flags: ignoreversion" on any shared system files
diff --git a/installers/win/win_installer_py27.iss b/installers/win/win_installer_py27.iss
index 6b0cf86..e879227 100644
--- a/installers/win/win_installer_py27.iss
+++ b/installers/win/win_installer_py27.iss
@@ -7,7 +7,7 @@
 ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
 AppId={{244D309A-C251-481A-AD24-0602D392A634}
 AppName=Pyo
-AppVersion=0.6.8
+AppVersion=0.6.9
 AppPublisher=iACT.umontreal.ca
 AppPublisherURL=http://code.google.com/p/pyo
 AppSupportURL=http://code.google.com/p/pyo
@@ -17,7 +17,7 @@ DisableDirPage=yes
 DefaultGroupName=pyo
 AllowNoIcons=yes
 InfoBeforeFile=C:\Documents and Settings\user\svn\pyo\installers\win\\README-win32-py27.txt
-OutputBaseFilename=pyo_0.6.8_py2.7_setup
+OutputBaseFilename=pyo_0.6.9_py2.7_setup
 Compression=lzma
 SolidCompression=yes
 ChangesAssociations=yes
@@ -26,8 +26,11 @@ ChangesEnvironment=yes
 [Languages]
 Name: "english"; MessagesFile: "compiler:Default.isl"
 
+; One installer for both python version
+; functions to set which python directory in Setup section
+; Check: DirExists(ExpandConstant('{sd}\Python27')) 
 [Files]
-Source: "C:\Python27\Lib\site-packages\pyo.py"; DestDir: "{sd}\Python27\Lib\site-packages"; Flags: ignoreversion
+Source: "C:\Python27\Lib\site-packages\pyo.py"; DestDir: "{sd}\Python27\Lib\site-packages"; Flags: ignoreversion 
 Source: "C:\Python27\Lib\site-packages\pyo64.py"; DestDir: "{sd}\Python27\Lib\site-packages"; Flags: ignoreversion
 Source: "C:\Python27\Lib\site-packages\pyolib\*"; DestDir: "{sd}\Python27\Lib\site-packages\pyolib"; Flags: ignoreversion recursesubdirs createallsubdirs
 Source: "C:\Python27\Lib\site-packages\_pyo.pyd"; DestDir: "{sd}\Python27\Lib\site-packages"; Flags: ignoreversion
@@ -41,7 +44,7 @@ Source: "C:\Python27\Lib\site-packages\pthreadVC2.dll"; DestDir: "{sd}\Python27\
 Source: "C:\Python27\Lib\site-packages\msvcr90.dll"; DestDir: "{sd}\Python27\Lib\site-packages"; Flags: ignoreversion
 Source: "C:\MinGW\bin\libgcc_s_dw2-1.dll"; DestDir: "{sd}\Python27\Lib\site-packages"; Flags: ignoreversion
 Source: "C:\MinGW\bin\libstdc++-6.dll"; DestDir: "{sd}\Python27\Lib\site-packages"; Flags: ignoreversion
-Source: "C:\Python27\Lib\site-packages\pyo-0.6.8-py2.7.egg-info"; DestDir: "{sd}\Python27\Lib\site-packages"; Flags: ignoreversion
+Source: "C:\Python27\Lib\site-packages\pyo-0.6.9-py2.7.egg-info"; DestDir: "{sd}\Python27\Lib\site-packages"; Flags: ignoreversion
 Source: "C:\Documents and Settings\user\svn\pyo\examples\*"; DestDir: "{userdesktop}\pyo_examples\"; Flags: ignoreversion recursesubdirs createallsubdirs
 Source: "C:\Documents and Settings\user\svn\pyo\installers\win\README-win32-py27.txt"; DestDir: "{userdesktop}"; Flags: ignoreversion
 ; NOTE: Don't use "Flags: ignoreversion" on any shared system files
diff --git a/pyo.py b/pyo.py
index f7a865f..081056d 100644
--- a/pyo.py
+++ b/pyo.py
@@ -99,7 +99,6 @@ if WITH_EXTERNALS:
     import pyolib.external as external
     from pyolib.external import *
 
-# Temporary objects, need to be coded in C
 class FreqShift(PyoObject):
     """
     Frequency shifting using single sideband amplitude modulation.
@@ -110,26 +109,14 @@ class FreqShift(PyoObject):
     100, 200, 300, 400 and 500 Hz, shifted up by 50 Hz, will have harmonics 
     at 150, 250, 350, 450, and 550 Hz.
 
-    Parent class : PyoObject
+    :Parent: :py:class:`PyoObject`
 
-    Parameters:
+    :Args:
 
-    input : PyoObject
-        Input signal to process.
-    shift : float or PyoObject, optional
-        Amount of shifting in Hertz. Defaults to 100.
-
-    Methods:
-
-    setInput(x, fadetime) : Replace the `input` attribute.
-    setShift(x) : Replace the `shift` attribute.
-
-    Attributes:
-
-    input : PyoObject. Input signal to process.
-    shift : float or PyoObject. Amount of shifting in Hertz.
-
-    Examples:
+        input : PyoObject
+            Input signal to process.
+        shift : float or PyoObject, optional
+            Amount of shifting in Hertz. Defaults to 100.
 
     >>> s = Server().boot()
     >>> s.start()
@@ -141,11 +128,9 @@ class FreqShift(PyoObject):
 
     """
     def __init__(self, input, shift=100, mul=1, add=0):
-        PyoObject.__init__(self)
+        PyoObject.__init__(self, mul, add)
         self._input = input
         self._shift = shift
-        self._mul = mul
-        self._add = add
         self._in_fader = InputFader(input)
         in_fader, shift, mul, add, lmax = convertArgsToLists(self._in_fader, shift, mul, add)
 
@@ -162,25 +147,20 @@ class FreqShift(PyoObject):
                                       mul=wrap(mul,i), add=wrap(add,i)))
             self._base_objs.extend(self._mod_objs[-1].getBaseObjects())
 
-    def __dir__(self):
-        return ["input", "shift", "mul", "add"]
-
     def play(self, dur=0, delay=0):
         dur, delay, lmax = convertArgsToLists(dur, delay)
         [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._hilb_objs)]
         [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._sin_objs)]
         [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._cos_objs)]
         [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._mod_objs)]
-        self._base_objs = [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._base_objs)]
-        return self
+        return PyoObject.play(self, dur, delay)
 
     def stop(self):
         [obj.stop() for obj in self._hilb_objs]
         [obj.stop() for obj in self._sin_objs]
         [obj.stop() for obj in self._cos_objs]
         [obj.stop() for obj in self._mod_objs]
-        [obj.stop() for obj in self._base_objs]
-        return self
+        return PyoObject.stop(self)
 
     def out(self, chnl=0, inc=1, dur=0, delay=0):
         dur, delay, lmax = convertArgsToLists(dur, delay)
@@ -188,14 +168,7 @@ class FreqShift(PyoObject):
         [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._sin_objs)]
         [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._cos_objs)]
         [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._mod_objs)]
-        if type(chnl) == ListType:
-            self._base_objs = [obj.out(wrap(chnl,i), wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._base_objs)]
-        else:
-            if chnl < 0:    
-                self._base_objs = [obj.out(i*inc, wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(random.sample(self._base_objs, len(self._base_objs)))]
-            else:
-                self._base_objs = [obj.out(chnl+i*inc, wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._base_objs)]
-        return self
+        return PyoObject.out(self, chnl, inc, dur, delay)
 
     def setInput(self, x, fadetime=0.05):
         """
@@ -245,6 +218,98 @@ class FreqShift(PyoObject):
     @shift.setter
     def shift(self, x): self.setShift(x)
 
+class PartialTable(PyoTableObject):
+    """
+    Inharmonic waveform generator.
+
+    Generates waveforms made of inharmonic components. Partials are
+    given as a list of 2-values tuple, where the first one is the
+    partial number (can be float) and the second one is the strength
+    of the partial.
+    
+    The object uses the first two decimal values of each partial to 
+    compute a higher harmonic at a multiple of 100 (so each component
+    is in reality truly harmonic). If the oscillator has a frequency
+    divided by 100, the real desired partials will be restituted.
+    
+    The list:
+        
+    [(1, 1), (1.1, 0.7), (1.15, 0.5)] will draw a table with:
+        
+    harmonic 100 : amplitude = 1
+    harmonic 110 : amplitude = 0.7
+    harmonic 115 : amplitude = 0.5
+    
+    To listen to a signal composed of 200, 220 and 230 Hz, one should
+    declared an oscillator like this (frequency of 200Hz divided by 100):
+        
+    a = Osc(t, freq=2, mul=0.5).out()
+
+    :Parent: :py:class:`PyoTableObject`
+
+    :Args:
+
+        list : list of tuple, optional
+            List of 2-values tuples. First value is the partial number (float up 
+            to two decimal values) and second value is its amplitude (relative to
+            the other harmonics). Defaults to [(1,1), (1.33,0.5),(1.67,0.3)].
+        size : int, optional
+            Table size in samples. Because computed harmonics are very high in
+            frequency, the table size must be bigger than a classic HarmTable.
+            Defaults to 65536.
+
+    >>> s = Server().boot()
+    >>> s.start()
+    >>> t = PartialTable([(1,1), (2.37, 0.5), (4.55, 0.3)]).normalize()
+    >>> # Play with fundamentals 199 and 200 Hz
+    >>> a = Osc(table=t, freq=[1.99,2], mul=.2).out()
+
+    """
+    def __init__(self, list=[(1,1), (1.33,0.5),(1.67,0.3)], size=65536):
+        PyoTableObject.__init__(self, size)
+        self._list = list
+        self._par_table = HarmTable(self._create_list(), size)
+        self._base_objs = self._par_table.getBaseObjects()
+        self.normalize()
+
+    def _create_list(self):
+        # internal method used to compute the harmonics's weight
+        hrms = [(int(x*100.), y) for x, y in self._list]
+        l = []
+        ind = 0
+        for i in range(10000):
+            if i == hrms[ind][0]:
+                l.append(hrms[ind][1])
+                ind += 1
+                if ind == len(hrms):
+                    break
+            else:
+                l.append(0)
+        return l
+    
+    def replace(self, list):
+        """
+        Redraw the waveform according to a new set of harmonics 
+        relative strengths.
+        
+        :Args:
+        
+            list : list of tuples
+                Each tuple contains the partial number, as a float,
+                and its strength.
+
+        """      
+        self._list = list
+        [obj.replace(self._create_list()) for obj in self._base_objs]
+        self.normalize()
+        self.refreshView()
+
+    @property
+    def list(self): 
+        """list. List of partial numbers and strength."""
+        return self._list
+    @list.setter
+    def list(self, x): self.replace(x)
 
 OBJECTS_TREE = {'functions': sorted(['pa_count_devices', 'pa_get_default_input', 'pa_get_default_output', 'pm_get_input_devices',
                                     'pa_list_devices', 'pa_count_host_apis', 'pa_list_host_apis', 'pa_get_default_host_api', 
@@ -253,11 +318,12 @@ OBJECTS_TREE = {'functions': sorted(['pa_count_devices', 'pa_get_default_input',
                                     'pm_get_default_input', 'pm_get_output_devices', 'pm_get_default_output', 'midiToTranspo',
                                      'getVersion', 'reducePoints', 'serverCreated', 'serverBooted', 'distanceToSegment', 'rescale',
                                      'upsamp', 'downsamp', 'linToCosCurve', 'convertStringToSysEncoding', 'savefileFromTable',
-                                    'pa_get_input_max_channels', 'pa_get_output_max_channels', 'pa_get_devices_infos']),
+                                    'pa_get_input_max_channels', 'pa_get_output_max_channels', 'pa_get_devices_infos', 'pa_get_version',
+                                    'pa_get_version_text']),
                 'PyoObjectBase': {
                     'PyoMatrixObject': sorted(['NewMatrix']),                        
                     'PyoTableObject': sorted(['LinTable', 'NewTable', 'SndTable', 'HannTable', 'HarmTable', 'SawTable', 'ParaTable', 'LogTable', 'CosLogTable',
-                                            'SquareTable', 'ChebyTable', 'CosTable', 'CurveTable', 'ExpTable', 'DataTable', 'WinTable', 'SincTable']),
+                                            'SquareTable', 'ChebyTable', 'CosTable', 'CurveTable', 'ExpTable', 'DataTable', 'WinTable', 'SincTable', 'PartialTable']),
                     'PyoPVObject' : sorted(['PVAnal', 'PVSynth', 'PVTranspose', 'PVVerb', 'PVGate', 'PVAddSynth', 'PVCross', 'PVMult', 'PVMorph', 'PVFilter', 'PVDelay', 'PVBuffer', 'PVShift', 'PVAmpMod', 'PVFreqMod', 'PVBufLoops', 'PVBufTabLoops', 'PVMix']),
                     'PyoObject': {'analysis': sorted(['Follower', 'Follower2', 'ZCross', 'Yin']),
                                   'arithmetic': sorted(['Sin', 'Cos', 'Tan', 'Abs', 'Sqrt', 'Log', 'Log2', 'Log10', 'Pow', 'Atan2', 'Floor', 'Round',
@@ -265,10 +331,10 @@ OBJECTS_TREE = {'functions': sorted(['pa_count_devices', 'pa_get_default_input',
                                   'controls': sorted(['Fader', 'Sig', 'SigTo', 'Adsr', 'Linseg', 'Expseg']),
                                   'dynamics': sorted(['Clip', 'Compress', 'Degrade', 'Mirror', 'Wrap', 'Gate', 'Balance', 'Min', 'Max']),
                                   'effects': sorted(['Delay', 'SDelay', 'Disto', 'Freeverb', 'Waveguide', 'Convolve', 'WGVerb', 
-                                                     'Harmonizer', 'Chorus', 'AllpassWG', 'FreqShift', 'Vocoder', 'Delay1']),
+                                                     'Harmonizer', 'Chorus', 'AllpassWG', 'FreqShift', 'Vocoder', 'Delay1', 'STRev']),
                                   'filters': sorted(['Biquad', 'BandSplit', 'Port', 'Hilbert', 'Tone', 'DCBlock', 'EQ', 'Allpass',
                                                      'Allpass2', 'Phaser', 'Biquadx', 'IRWinSinc', 'IRAverage', 'IRPulse', 'IRFM', 'FourBand',
-                                                     'Biquada', 'Atone', 'SVF', 'Average', 'Reson', 'Resonx', 'ButLP', 'ButHP', 'ButBP', 'ButBR']),
+                                                     'Biquada', 'Atone', 'SVF', 'Average', 'Reson', 'Resonx', 'ButLP', 'ButHP', 'ButBP', 'ButBR', 'ComplexRes']),
                                   'generators': sorted(['Noise', 'Phasor', 'Sine', 'Input', 'FM', 'SineLoop', 'Blit', 'PinkNoise', 'CrossFM',
                                                         'BrownNoise', 'Rossler', 'Lorenz', 'LFO', 'SumOsc', 'SuperSaw', 'RCOsc']),
                                   'internals': sorted(['Dummy', 'InputFader', 'Mix', 'VarPort']),
@@ -278,7 +344,7 @@ OBJECTS_TREE = {'functions': sorted(['pa_count_devices', 'pa_get_default_input',
                                   'pattern': sorted(['Pattern', 'Score', 'CallAfter']),
                                   'randoms': sorted(['Randi', 'Randh', 'Choice', 'RandInt', 'Xnoise', 'XnoiseMidi', 'RandDur', 'XnoiseDur', 'Urn']),
                                   'players': sorted(['SfMarkerShuffler', 'SfPlayer', 'SfMarkerLooper']),
-                                  'tableprocess': sorted(['TableRec', 'Osc', 'Pointer', 'Lookup', 'Granulator', 'Pulsar', 'OscLoop', 'Granule',
+                                  'tableprocess': sorted(['TableRec', 'Osc', 'Pointer', 'Pointer2', 'Lookup', 'Granulator', 'Pulsar', 'OscLoop', 'Granule',
                                                         'TableRead', 'TableMorph', 'Looper', 'TableIndex', 'OscBank', 'OscTrig', 'TablePut', 'TableScale']),
                                   'matrixprocess': sorted(['MatrixRec', 'MatrixPointer', 'MatrixMorph', 'MatrixRecLoop']), 
                                   'triggers': sorted(['Metro', 'Beat', 'TrigEnv', 'TrigRand', 'TrigRandInt', 'Select', 'Counter', 'TrigChoice', 
@@ -287,7 +353,7 @@ OBJECTS_TREE = {'functions': sorted(['pa_count_devices', 'pa_get_default_input',
                                                     'TrigVal']),
                                   'utils': sorted(['Clean_objects', 'Print', 'Snap', 'Interp', 'SampHold', 'Compare', 'Record', 'Between', 'Denorm',
                                                     'ControlRec', 'ControlRead', 'NoteinRec', 'NoteinRead', 'DBToA', 'AToDB', 'Scale', 'CentsToTranspo',
-                                                    'TranspoToCents', 'MToF', 'MToT']),
+                                                    'TranspoToCents', 'MToF', 'MToT', 'TrackHold']),
                                   'fourier': sorted(['FFT', 'IFFT', 'CarToPol', 'PolToCar', 'FrameDelta', 'FrameAccum', 'Vectral', 'CvlVerb', 'Spectrum'])}},
         'Map': {'SLMap': sorted(['SLMapFreq', 'SLMapMul', 'SLMapPhase', 'SLMapQ', 'SLMapDur', 'SLMapPan'])},
         'Server': [], 
@@ -295,5 +361,4 @@ OBJECTS_TREE = {'functions': sorted(['pa_count_devices', 'pa_get_default_input',
         'TableStream': []}
 
 DOC_KEYWORDS = ['Attributes', 'Examples', 'Parameters', 'Methods', 'Notes', 'Methods details', 'See also', 'Parentclass']
-
 DEMOS_PATH = SNDS_PATH
diff --git a/pyolib/_core.py b/pyolib/_core.py
index 0a643c6..aea4c02 100644
--- a/pyolib/_core.py
+++ b/pyolib/_core.py
@@ -46,6 +46,7 @@ FILE_FORMATS = {'wav': 0, 'wave': 0, 'aif': 1, 'aiff': 1, 'au': 2, '': 3, 'sd2':
 FUNCTIONS_INIT_LINES = {"pa_count_host_apis": "pa_count_host_apis()", "pa_list_host_apis": "pa_list_host_apis()",
                         "pa_get_default_host_api": "pa_get_default_host_api()", "pa_count_devices": "pa_count_devices()",
                         "pa_list_devices": "pa_list_devices()", "pa_get_devices_infos": "pa_get_devices_infos()",
+                        "pa_get_version": "pa_get_version()", "pa_get_version_text": "pa_get_version_text()",
                         "pa_get_input_devices": "pa_get_input_devices()", "pa_get_output_devices": "pa_get_output_devices()",
                         "pa_get_default_input": "pa_get_default_input()", "pa_get_default_output": "pa_get_default_output()",
                         "pa_get_input_max_channels": "pa_get_input_max_channels(x)", "pa_get_output_max_channels": "pa_get_output_max_channels(x)",
@@ -223,6 +224,9 @@ def getVersion():
     major, minor, rev = PYO_VERSION.split('.')
     return (int(major), int(minor), int(rev))
 
+def dumpref():
+    pass
+
 class PyoError(Exception):
     """Base class for all pyo exceptions."""
 
@@ -286,6 +290,20 @@ class PyoObjectBase(object):
         """
         return self._base_objs
 
+    def cleanFuncRefs(self):
+        """
+        Method used to remove internal references to callback functions.
+        
+        An internal reference to a callback function (ex. the function
+        called by the TrigFunc object) may prevent the object to be
+        properly deleted when its reference count drop to zero. Calling
+        this function just before deleting the last reference will replace
+        the callback reference by a dump ref.
+
+        """
+        if hasattr(self, "_function"):
+            self.setFunction(dumpref)
+
     def __getitem__(self, i):
         if i == 'trig':
             return self._trig_objs
@@ -1123,13 +1141,103 @@ class PyoTableObject(PyoObjectBase):
 
     def reverse(self):
         """
-        Reverse the table's data.
+        Reverse the table's data in time.
 
         """
         [obj.reverse() for obj in self._base_objs]
         self.refreshView()
         return self
 
+    def invert(self):
+        """
+        Reverse the table's data in amplitude.
+
+        """
+        [obj.invert() for obj in self._base_objs]
+        self.refreshView()
+        return self
+
+    def rectify(self):
+        """
+        Positive rectification of the table's data.
+
+        """
+        [obj.rectify() for obj in self._base_objs]
+        self.refreshView()
+        return self
+
+    def pow(self, exp=10):
+        """
+        Apply a power function on each sample in the table.
+
+        :Args:
+
+            exp : float, optional
+                Exponent factor. Defaults to 10.
+
+        """
+        [obj.pow(exp) for obj in self._base_objs]
+        self.refreshView()
+        return self
+
+    def bipolarGain(self, gpos=1, gneg=1):
+        """
+        Apply different gain factor for positive and negative samples.
+
+        :Args:
+
+            gpos : float, optional
+                Gain factor for positive samples. Defaults to 1.
+            gneg : float, optional
+                Gain factor for negative samples. Defaults to 1.
+
+        """
+        [obj.bipolarGain(gpos, gneg) for obj in self._base_objs]
+        self.refreshView()
+        return self
+
+    def lowpass(self, freq=1000):
+        """
+        Apply a one-pole lowpass filter on table's samples.
+
+        :Args:
+
+            freq : float, optional
+                Filter's cutoff, in Hertz. Defaults to 1000.
+
+        """
+        [obj.lowpass(freq) for obj in self._base_objs]
+        self.refreshView()
+        return self
+
+    def fadein(self, dur=0.1):
+        """
+        Apply a gradual increase in the level of the table's samples.
+
+        :Args:
+
+            dur : float, optional
+                Fade in duration, in seconds. Defaults to 0.1.
+
+        """
+        [obj.fadein(dur) for obj in self._base_objs]
+        self.refreshView()
+        return self
+
+    def fadeout(self, dur=0.1):
+        """
+        Apply a gradual decrease in the level of the table's samples.
+
+        :Args:
+
+            dur : float, optional
+                Fade out duration, in seconds. Defaults to 0.1.
+
+        """
+        [obj.fadeout(dur) for obj in self._base_objs]
+        self.refreshView()
+        return self
+
     def copy(self):
         """
         Returns a deep copy of the object.
@@ -1779,6 +1887,7 @@ class VarPort(PyoObject):
         PyoObject.__init__(self, mul, add)
         self._value = value
         self._time = time
+        self._function = function
         value, time, init, function, arg, mul ,add, lmax = convertArgsToLists(value, time, init, function, arg, mul, add)
         self._base_objs = [VarPort_base(wrap(value,i), wrap(time,i), wrap(init,i), wrap(function,i), wrap(arg,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
 
@@ -1810,6 +1919,20 @@ class VarPort(PyoObject):
         x, lmax = convertArgsToLists(x)
         [obj.setTime(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
+    def setFunction(self, x):
+        """
+        Replace the `function` attribute.
+        
+        :Args:
+
+            x : Python function
+                new `function` attribute.
+        
+        """
+        self._function = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setFunction(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
     @property
     def value(self):
         """float. Numerical value to convert.""" 
@@ -1824,6 +1947,13 @@ class VarPort(PyoObject):
     @time.setter
     def time(self, x): self.setTime(x)
 
+    @property
+    def function(self): 
+        """Python callable. Function to be called."""
+        return self._function
+    @function.setter
+    def function(self, x): self.setFunction(x)
+
 class Pow(PyoObject):
     """
     Performs a power function on audio signal.
diff --git a/pyolib/_maps.py b/pyolib/_maps.py
index 9845c77..7005918 100644
--- a/pyolib/_maps.py
+++ b/pyolib/_maps.py
@@ -158,17 +158,22 @@ class SLMap(Map):
         ramp : float, optional
             Ramp time, in seconds, used to smooth the signal sent from slider 
             to object's attribute. Defaults to 0.025.
+        dataOnly : boolean, optional
+            Set this argument to True if the parameter does not accept audio 
+            signal as control but discreet values. If True, label will be 
+            marked with a star symbol (*). Defaults to False. 
 
     >>> s = Server().boot()
+    >>> s.start()
     >>> ifs = [350,360,375,388]
     >>> maps = [SLMap(20., 2000., 'log', 'freq', ifs), SLMap(0, 0.25, 'lin', 'feedback', 0), SLMapMul(.1)]
     >>> a = SineLoop(freq=ifs, mul=.1).out()
     >>> a.ctrl(maps)
 
     """
-    def __init__(self, min, max, scale, name, init, res='float', ramp=0.025):
+    def __init__(self, min, max, scale, name, init, res='float', ramp=0.025, dataOnly=False):
         Map.__init__(self, min, max, scale)
-        self._name, self._init, self._res, self._ramp = name, init, res, ramp
+        self._name, self._init, self._res, self._ramp, self._dataOnly = name, init, res, ramp, dataOnly
 
     @property
     def name(self): 
@@ -186,6 +191,10 @@ class SLMap(Map):
     def ramp(self): 
         """float. Ramp time in seconds."""
         return self._ramp
+    @property
+    def dataOnly(self): 
+        """boolean. True if argument does not accept audio stream."""
+        return self._dataOnly
 
 class SLMapFreq(SLMap):
     """
diff --git a/pyolib/_widgets.py b/pyolib/_widgets.py
index 518299c..1eb1db9 100644
--- a/pyolib/_widgets.py
+++ b/pyolib/_widgets.py
@@ -151,8 +151,7 @@ def wxCreateDelayedTableWindows():
 def wxCreateDelayedSndTableWindows():
     global CURRENT_X, MAX_X, NEXT_Y
     for win in SNDTABLEWINDOWS:
-        if WITH_PIL: f = SndViewTable_withPIL(None, win[0], win[1], win[3])
-        else: f = SndViewTable_withoutPIL(None, win[0], win[1], win[3])
+        f = SndViewTable(None, win[0], win[1], win[3])
         win[0]._setViewFrame(f)
         wxDisplayWindow(f, win[2])
 
@@ -227,8 +226,8 @@ def createViewTableWindow(samples, title="Table waveform", wxnoserver=False, tab
     else:
         if wxnoserver or wx.GetApp() != None:
             root = createRootWindow()
-            if WITH_PIL: f = ViewTable_withPIL(None, samples, tableclass)
-            else: f = ViewTable_withoutPIL(None, samples, tableclass)
+            if WITH_PIL: f = ViewTable_withPIL(None, samples, tableclass, object)
+            else: f = ViewTable_withoutPIL(None, samples, tableclass, object)
             wxShowWindow(f, title, root)
             if object != None:
                 object._setViewFrame(f)
@@ -246,8 +245,7 @@ def createSndViewTableWindow(obj, title="Table waveform", wxnoserver=False, tabl
     else:
         if wxnoserver or wx.GetApp() != None:
             root = createRootWindow()
-            if WITH_PIL: f = SndViewTable_withPIL(None, obj, tableclass, mouse_callback)
-            else: f = SndViewTable_withoutPIL(None, obj, tableclass, mouse_callback)
+            f = SndViewTable(None, obj, tableclass, mouse_callback)
             if title == None: title = obj.__class__.__name__
             wxShowWindow(f, title, root)
             obj._setViewFrame(f)
@@ -267,8 +265,8 @@ It helps a lot to speed up matrix drawing!"""
     else:
         if wxnoserver or wx.GetApp() != None:
             root = createRootWindow()
-            if WITH_PIL: f = ViewMatrix_withPIL(None, samples, size)
-            else: f = ViewMatrix_withoutPIL(None, samples, size)
+            if WITH_PIL: f = ViewMatrix_withPIL(None, samples, size, object)
+            else: f = ViewMatrix_withoutPIL(None, samples, size, object)
             wxShowWindow(f, title, root)
             if object != None:
                 object._setViewFrame(f)
diff --git a/pyolib/_wxwidgets.py b/pyolib/_wxwidgets.py
index 4e85080..5651072 100644
--- a/pyolib/_wxwidgets.py
+++ b/pyolib/_wxwidgets.py
@@ -887,14 +887,17 @@ class PyoObjectControl(wx.Frame):
         self.box = wx.FlexGridSizer(10,2,5,5)
         
         for i, m in enumerate(self._map_list):
-            key, init, mini, maxi, scl, res = m.name, m.init, m.min, m.max, m.scale, m.res
+            key, init, mini, maxi, scl, res, dataOnly = m.name, m.init, m.min, m.max, m.scale, m.res, m.dataOnly
             # filters PyoObjects
             if type(init) not in [ListType, FloatType, IntType]:
                 self._excluded.append(key)
             else:    
                 self._maps[key] = m
                 # label (param name)
-                label = wx.StaticText(panel, -1, key)
+                if dataOnly:
+                    label = wx.StaticText(panel, -1, key+" *")
+                else:
+                    label = wx.StaticText(panel, -1, key)
                 # create and pack slider
                 if type(init) != ListType:
                     if scl == 'log': scl = True
@@ -907,15 +910,16 @@ class PyoObjectControl(wx.Frame):
                 else:
                     self._sliders.append(MultiSlider(panel, init, key, self.setval, m))
                     self.box.AddMany([(label, 0, wx.LEFT, 5), (self._sliders[-1], 1, wx.EXPAND | wx.LEFT, 5)])   
-                # set obj attribute to PyoObject SigTo  
-                self._values[key] = init
-                self._sigs[key] = SigTo(init, .025, init)
-                refStream = self._obj.getBaseObjects()[0]._getStream()
-                server = self._obj.getBaseObjects()[0].getServer()
-                for k in range(len(self._sigs[key].getBaseObjects())):
-                    curStream = self._sigs[key].getBaseObjects()[k]._getStream()
-                    server.changeStreamPosition(refStream, curStream)
-                setattr(self._obj, key, self._sigs[key])
+                # set obj attribute to PyoObject SigTo
+                if not dataOnly:
+                    self._values[key] = init
+                    self._sigs[key] = SigTo(init, .025, init)
+                    refStream = self._obj.getBaseObjects()[0]._getStream()
+                    server = self._obj.getBaseObjects()[0].getServer()
+                    for k in range(len(self._sigs[key].getBaseObjects())):
+                        curStream = self._sigs[key].getBaseObjects()[k]._getStream()
+                        server.changeStreamPosition(refStream, curStream)
+                    setattr(self._obj, key, self._sigs[key])
         self.box.AddGrowableCol(1, 1) 
         mainBox.Add(self.box, 1, wx.EXPAND | wx.TOP | wx.BOTTOM | wx.RIGHT, 10)
 
@@ -927,14 +931,17 @@ class PyoObjectControl(wx.Frame):
     def _destroy(self, event):
         for m in self._map_list:
             key = m.name
-            if key not in self._excluded:
+            if key not in self._excluded and key in self._values:
                 setattr(self._obj, key, self._values[key])
                 del self._sigs[key]
         self.Destroy()        
 
     def setval(self, key, x):
-        self._values[key] = x
-        setattr(self._sigs[key], "value", x)
+        if key in self._values:
+            self._values[key] = x
+            setattr(self._sigs[key], "value", x)
+        else:
+            setattr(self._obj, key, x)
 
 ######################################################################
 ### View window for PyoTableObject
@@ -1021,7 +1028,7 @@ class ViewTable_withoutPIL(ViewTable):
 class SndViewTable(wx.Frame):
     def __init__(self, parent, obj=None, tableclass=None, mouse_callback=None):
         wx.Frame.__init__(self, parent, size=(500,250))
-        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
+        self.SetMinSize((300, 150))
         self.menubar = wx.MenuBar()        
         self.fileMenu = wx.Menu()
         closeItem = self.fileMenu.Append(-1, 'Close\tCtrl+W', kind=wx.ITEM_NORMAL)
@@ -1029,24 +1036,59 @@ class SndViewTable(wx.Frame):
         self.menubar.Append(self.fileMenu, "&File")
         self.SetMenuBar(self.menubar)
         self.Bind(wx.EVT_CLOSE, self._destroy)
-        self.Bind(wx.EVT_PAINT, self.OnPaint)
-        self.Bind(wx.EVT_SIZE, self.OnSize)
-        self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown)
-        self.Bind(wx.EVT_LEFT_UP, self.OnMouseUp)
-        self.Bind(wx.EVT_MOTION, self.OnMotion)
         self.obj = obj
         self.chnls = len(self.obj)
-        self.mouse_callback = mouse_callback
+        self.dur = self.obj.getDur(False)
+        self.panel = wx.Panel(self)
+        self.panel.SetBackgroundColour(BACKGROUND_COLOUR)
+        self.box = wx.BoxSizer(wx.VERTICAL)
+        self.wavePanel = SndViewTablePanel(self.panel, obj, mouse_callback)
+        self.box.Add(self.wavePanel, 1, wx.EXPAND|wx.ALL, 5)
+        self.zoomH = HRangeSlider(self.panel, minvalue=0, maxvalue=1, init=None, pos=(0,0), size=(200,15), 
+                 valtype='float', log=False, function=self.setZoomH)
+        self.box.Add(self.zoomH, 0, wx.EXPAND|wx.LEFT|wx.RIGHT, 5)
+        self.panel.SetSizer(self.box)
+
+    def setZoomH(self, values):
+        self.wavePanel.setBegin(self.dur * values[0])
+        self.wavePanel.setEnd(self.dur * values[1])
+        self.update()
 
     def update(self):
-        wx.CallAfter(self.setImage)
+        wx.CallAfter(self.wavePanel.setImage)
 
     def _destroy(self, evt):
         self.obj._setViewFrame(None)
         self.Destroy()
 
-    def OnSize(self, evt):
+class SndViewTablePanel(wx.Panel):
+    def __init__(self, parent, obj, mouse_callback=None):
+        wx.Panel.__init__(self, parent)
+        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
+        self.Bind(wx.EVT_PAINT, self.OnPaint)
+        self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown)
+        self.Bind(wx.EVT_LEFT_UP, self.OnMouseUp)
+        self.Bind(wx.EVT_MOTION, self.OnMotion)
+        self.Bind(wx.EVT_SIZE, self.OnSize)
+        self.obj = obj
+        self.chnls = len(self.obj)
+        self.begin = 0
+        self.end = self.obj.getDur(False)
+        self.mouse_callback = mouse_callback
+        if sys.platform == "win32":
+            self.dcref = wx.BufferedPaintDC
+        else:
+            self.dcref = wx.PaintDC
         self.setImage()
+
+    def setBegin(self, x):
+        self.begin = x
+
+    def setEnd(self, x):
+        self.end = x
+
+    def setImage(self):
+        self.img = self.obj.getViewTable(self.GetSize(), self.begin, self.end)
         self.Refresh()
 
     def clipPos(self, pos):
@@ -1056,6 +1098,7 @@ class SndViewTable(wx.Frame):
         if pos[1] < 0.0: y = 0.0
         elif pos[1] > 1.0: y = 1.0
         else: y = pos[1]
+        x = x * ((self.end - self.begin) / self.obj.getDur(False)) + (self.begin / self.obj.getDur(False))
         return (x, y)
 
     def OnMouseDown(self, evt):
@@ -1086,77 +1129,50 @@ class SndViewTable(wx.Frame):
         if self.HasCapture():
             self.ReleaseMouse()
 
-class SndViewTable_withPIL(SndViewTable):
-    def __init__(self, parent, obj=None, tableclass=None, mouse_callback=None):
-        SndViewTable.__init__(self, parent, obj, tableclass, mouse_callback)
-        self.setImage()
-
-    def setImage(self):
-        w, h = self.GetSize()
-        self.img = []
-        imgHeight = h/self.chnls
-        for i in range(self.chnls):
-            im = Image.new("L", (w, imgHeight), 255)
-            draw = ImageDraw.Draw(im)
-            samples = self.obj._base_objs[i].getViewTable((w, imgHeight))
-            draw.line(samples, fill=0, width=1)
-            image = wx.EmptyImage(w, imgHeight)
-            image.SetData(im.convert("RGB").tostring())
-            self.img.append(wx.BitmapFromImage(image))
-        self.Refresh()
-
-    def OnPaint(self, evt):
-        w, h = self.GetSize()
-        dc = wx.AutoBufferedPaintDC(self)
-        dc.SetPen(wx.Pen('#444444', width=1, style=wx.SHORT_DASH))
-        off = h/self.chnls/2
-        for i, img in enumerate(self.img):
-            y = h/self.chnls*i
-            dc.DrawBitmap(img, 0, y)
-            dc.DrawLine(0, y+off, w, y+off)
-
-class SndViewTable_withoutPIL(SndViewTable):
-    def __init__(self, parent, obj=None, tableclass=None, mouse_callback=None):
-        SndViewTable.__init__(self, parent, obj, tableclass, mouse_callback)
-        self.tableclass = tableclass
-        self.setImage()
-
-    def setImage(self):
-        w, h = self.GetSize()
-        self.img = []
-        imgHeight = h/self.chnls
-        for j in range(self.chnls):
-            off = h/self.chnls*j
-            samples = self.obj._base_objs[j].getViewTable((w, imgHeight))
-            if sys.platform == 'win32':
-                if self.tableclass == 'SndTable':
-                    samples = [(samples[i], samples[i+1]+off, samples[i+2], samples[i+3]+off) for i in range(0, len(samples), 4)]
-                else:
-                    samples = [(samples[i], samples[i+1]+off) for i in range(0, len(samples), 2)]
-            else:
-                samples = [(samples[i], samples[i+1]+off, samples[i+2], samples[i+3]+off) for i in range(0, len(samples), 4)]
-            self.img.append(samples)
-        self.Refresh()
-
     def OnPaint(self, evt):
         w,h = self.GetSize()
-        dc = wx.AutoBufferedPaintDC(self)
+        dc = self.dcref(self)
+        gc = wx.GraphicsContext_Create(dc)
         dc.SetBrush(wx.Brush("#FFFFFF"))
         dc.Clear()
         dc.DrawRectangle(0,0,w,h)
         off = h/self.chnls/2
+        gc.SetPen(wx.Pen('#000000', width=1, style=wx.SOLID))
+        gc.SetBrush(wx.Brush("#FFFFFF", style=wx.TRANSPARENT))
+        dc.SetTextForeground("#444444")
+        if sys.platform in "darwin":
+            font, ptsize = dc.GetFont(), dc.GetFont().GetPointSize()
+            font.SetPointSize(ptsize - 3)
+            dc.SetFont(font)
+        elif sys.platform == "win32":
+            font = dc.GetFont()
+            font.SetPointSize(8)
+            dc.SetFont(font)
+        tickstep = w / 10
+        if tickstep < 40:
+            timelabel = "%.1f"
+        elif tickstep < 80:
+            timelabel = "%.2f"
+        elif tickstep < 120:
+            timelabel = "%.3f"
+        else:
+            timelabel = "%.4f"
+        timestep = (self.end - self.begin) * 0.1
         for i, samples in enumerate(self.img):
-            dc.SetPen(wx.Pen('#000000', width=1, style=wx.SOLID))  
             y = h/self.chnls*i
-            if sys.platform == 'win32':
-                if self.tableclass == 'SndTable':
-                    dc.DrawLineList(samples)
-                else:
-                    dc.DrawPointList(samples)
-            else:
-                dc.DrawLineList(samples)
-            dc.SetPen(wx.Pen('#444444', width=1, style=wx.SHORT_DASH))  
+            if len(samples):
+                gc.DrawLines(samples)
+            dc.SetPen(wx.Pen('#888888', width=1, style=wx.DOT))  
             dc.DrawLine(0, y+off, w, y+off)
+            for j in range(10):
+                dc.SetPen(wx.Pen('#888888', width=1, style=wx.DOT))  
+                dc.DrawLine(j*tickstep, 0, j*tickstep, h)
+                dc.DrawText(timelabel % (self.begin+j*timestep), j*tickstep+2, h-y-12)
+            dc.SetPen(wx.Pen('#000000', width=1))  
+            dc.DrawLine(0, h-y, w, h-y)            
+
+    def OnSize(self, evt):
+        wx.CallAfter(self.setImage)
 
 ######################################################################
 ## View window for PyoMatrixObject
@@ -2281,13 +2297,13 @@ class ServerGUI(wx.Frame):
             if not justSet:
                 self.startf()
             self._started = True
-            self.startButton.SetLabel('Stop')
-            self.quitButton.Disable()
+            wx.CallAfter(self.startButton.SetLabel, 'Stop')
+            wx.CallAfter(self.quitButton.Disable)
         else:
             self.stopf()
             self._started = False
-            self.startButton.SetLabel('Start')
-            self.quitButton.Enable()
+            wx.CallAfter(self.startButton.SetLabel, 'Start')
+            wx.CallAfter(self.quitButton.Enable)
 
     def record(self, evt):
         if self._recstarted == False:
diff --git a/pyolib/analysis.py b/pyolib/analysis.py
index ffcdc53..7ba6fd8 100644
--- a/pyolib/analysis.py
+++ b/pyolib/analysis.py
@@ -246,7 +246,7 @@ class ZCross(PyoObject):
         The out() method is bypassed. ZCross's signal can not be sent to 
         audio outs.
     
-    >>> s = Server(duplex=1).boot()
+    >>> s = Server().boot()
     >>> s.start()
     >>> a = SfPlayer(SNDS_PATH + "/transparent.aif", loop=True, mul=.4).out()
     >>> b = ZCross(a, thresh=.02)
@@ -292,6 +292,10 @@ class ZCross(PyoObject):
 
     def out(self, chnl=0, inc=1, dur=0, delay=0):
         return self.play(dur, delay)
+
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMap(0., 0.5, 'lin', 'thresh', self._thresh)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
      
     @property
     def input(self):
@@ -440,6 +444,13 @@ class Yin(PyoObject):
 
     def out(self, chnl=0, inc=1, dur=0, delay=0):
         return self.play(dur, delay)
+
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMap(0, 1, 'lin', 'tolerance', self._tolerance, dataOnly=True),
+                          SLMap(20, 400, 'log', 'minfreq', self._minfreq, dataOnly=True),
+                          SLMap(500, 5000, 'log', 'maxfreq', self._maxfreq, dataOnly=True),
+                          SLMap(200, 15000, 'log', 'cutoff', self._cutoff, dataOnly=True)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
      
     @property
     def input(self):
diff --git a/pyolib/controls.py b/pyolib/controls.py
index d993bbc..28dca81 100644
--- a/pyolib/controls.py
+++ b/pyolib/controls.py
@@ -129,6 +129,12 @@ class Fader(PyoObject):
         x, lmax = convertArgsToLists(x)
         [obj.setDur(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMap(0, 10., 'lin', 'fadein', self._fadein, dataOnly=True),
+                          SLMap(0, 10., 'lin', 'fadeout', self._fadeout, dataOnly=True),
+                          SLMap(0, 20., 'lin', 'dur', self._dur, dataOnly=True)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
+
     @property
     def fadein(self):
         """float. Rising time of the envelope in seconds.""" 
@@ -281,6 +287,14 @@ class Adsr(PyoObject):
         x, lmax = convertArgsToLists(x)
         [obj.setDur(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMap(0, 5, 'lin', 'attack', self._attack, dataOnly=True),
+                          SLMap(0, 5, 'lin', 'decay', self._decay, dataOnly=True),
+                          SLMap(0, 1, 'lin', 'sustain', self._sustain, dataOnly=True),
+                          SLMap(0, 10, 'lin', 'release', self._release, dataOnly=True),
+                          SLMap(0, 20., 'lin', 'dur', self._dur, dataOnly=True)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
+
     @property
     def attack(self):
         """float. Duration of the attack phase in seconds.""" 
@@ -749,6 +763,10 @@ class SigTo(PyoObject):
         x, lmax = convertArgsToLists(x)
         [obj.setTime(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMap(0, 10, 'lin', 'time', self._time, dataOnly=True)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
+
     @property
     def value(self):
         """float or PyoObject. Numerical value to convert.""" 
diff --git a/pyolib/dynamics.py b/pyolib/dynamics.py
index 9e6abd8..f4d6a88 100644
--- a/pyolib/dynamics.py
+++ b/pyolib/dynamics.py
@@ -511,6 +511,8 @@ class Compress(PyoObject):
                           SLMap(1., 10., 'lin', 'ratio',  self._ratio),
                           SLMap(0.001, .3, 'lin', 'risetime',  self._risetime),
                           SLMap(0.001, .3, 'lin', 'falltime',  self._falltime),
+                          SLMap(0, 25, 'lin', 'lookahead',  self._lookahead, dataOnly=True),
+                          SLMap(0, 1, 'lin', 'knee',  self._knee, dataOnly=True),
                           SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
@@ -690,6 +692,7 @@ class Gate(PyoObject):
         self._map_list = [SLMap(-100., 0., 'lin', 'thresh',  self._thresh),
                           SLMap(0.0001, .3, 'lin', 'risetime',  self._risetime),
                           SLMap(0.0001, .3, 'lin', 'falltime',  self._falltime),
+                          SLMap(0, 25, 'lin', 'lookahead',  self._lookahead, dataOnly=True),
                           SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
diff --git a/pyolib/effects.py b/pyolib/effects.py
index 09024ed..068206c 100644
--- a/pyolib/effects.py
+++ b/pyolib/effects.py
@@ -150,6 +150,17 @@ class Delay(PyoObject):
             Maximum delay length in seconds. Available only at initialization. 
             Defaults to 1.
 
+    .. note::
+
+        The minimum delay time allowed with Delay is one sample. It can be computed
+        with :
+            
+        onesamp = 1.0 / s.getSamplingRate()
+        
+    .. seealso::
+        
+        :py:class:`SDelay`, :py:class:`Waveguide`
+
     >>> s = Server().boot()
     >>> s.start()
     >>> a = SfPlayer(SNDS_PATH + "/transparent.aif", loop=True, mul=.3).mix(2).out()
@@ -259,6 +270,10 @@ class SDelay(PyoObject):
             Maximum delay length in seconds. Available only at initialization. 
             Defaults to 1.
 
+    .. seealso::
+        
+        :py:class:`Delay`, :py:class:`Delay1`
+
     >>> s = Server().boot()
     >>> s.start()
     >>> srPeriod = 1. / s.getSamplingRate()
@@ -313,7 +328,7 @@ class SDelay(PyoObject):
         [obj.reset() for obj in self._base_objs]
 
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
-        self._map_list = [SLMap(0.001, self._maxdelay, 'log', 'delay',  self._delay),
+        self._map_list = [SLMap(0.0001, self._maxdelay, 'log', 'delay',  self._delay),
                           SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
@@ -1166,6 +1181,7 @@ class Harmonizer(PyoObject):
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
         self._map_list = [SLMap(-24.0, 24.0, 'lin', 'transpo',  self._transpo),
                           SLMap(0., 1., 'lin', 'feedback', self._feedback),
+                          SLMap(0.001, 1, 'log', 'winsize',  self._winsize, dataOnly=True),
                           SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
@@ -1247,3 +1263,220 @@ class Delay1(PyoObject):
         return self._input
     @input.setter
     def input(self, x): self.setInput(x)
+
+class STRev(PyoObject):
+    """
+    Stereo reverb.
+
+    Stereo reverb based on WGVerb (8 delay line FDN reverb). A mono
+    input will produce two audio streams, left and right channels.
+    Therefore, a stereo input will produce four audio streams, left
+    and right channels for each input channel. Position of input 
+    streams can be set with the `inpos` argument. To achieve a stereo
+    reverb, delay line lengths are slightly differents on both channels,
+    but also, pre-delays length and filter cutoff of both channels will 
+    be affected to reflect the input position. 
+
+    :Parent: :py:class:`PyoObject`
+
+    :Args:
+
+        input : PyoObject
+            Input signal to process.
+        inpos : float or PyoObject, optional
+            Position of the source, between 0 and 1. 0 means fully left
+            and 1 means fully right. Defaults to 0.5.
+        revtime : float or PyoObject, optional
+            Duration, in seconds, of the reverberated sound, defined as 
+            the time needed to the sound to drop 40 dB below its peak. 
+            Defaults to 1.
+        cutoff : float or PyoObject, optional
+            cutoff frequency, in Hz, of a first order lowpass filters in the 
+            feedback loop of delay lines. Defaults to 5000.
+        bal : float or PyoObject, optional
+            Balance between wet and dry signal, between 0 and 1. 0 means no 
+            reverb. Defaults to 0.5.
+        roomSize : float, optional
+            Delay line length scaler, between 0.25 and 4. Values higher than
+            1 make the delay lines longer and simulate larger rooms. Defaults to 1.
+        firstRefGain : float, optional
+            Gain, in dB, of the first reflexions of the room. Defaults to -3.
+
+    >>> s = Server().boot()
+    >>> s.start()
+    >>> t = SndTable(SNDS_PATH + "/transparent.aif")
+    >>> sf = Looper(t, dur=t.getDur()*2, xfade=0, mul=0.5)
+    >>> rev = STRev(sf, inpos=0.25, revtime=2, cutoff=5000, bal=0.25, roomSize=1).out()
+
+    """
+    def __init__(self, input, inpos=0.5, revtime=1, cutoff=5000, bal=.5, roomSize=1, firstRefGain=-3, mul=1, add=0):
+        PyoObject.__init__(self, mul, add)
+        self._input = input
+        self._inpos = inpos
+        self._revtime = revtime
+        self._cutoff = cutoff
+        self._bal = bal
+        self._roomSize = roomSize
+        self._firstRefGain = firstRefGain
+        self._in_fader = InputFader(input)
+        in_fader, inpos, revtime, cutoff, bal, roomSize, firstRefGain, mul, add, lmax = convertArgsToLists(self._in_fader, inpos, revtime, cutoff, bal, roomSize, firstRefGain, mul, add)
+        self._base_players = [STReverb_base(wrap(in_fader,i), wrap(inpos,i), wrap(revtime,i), wrap(cutoff,i), wrap(bal,i), wrap(roomSize,i), wrap(firstRefGain,i)) for i in range(lmax)]
+        self._base_objs = [STRev_base(wrap(self._base_players,i), j, wrap(mul,i), wrap(add,i)) for i in range(lmax) for j in range(2)]
+
+    def setInput(self, x, fadetime=0.05):
+        """
+        Replace the `input` attribute.
+        
+        :Args:
+
+            x : PyoObject
+                New signal to process.
+            fadetime : float, optional
+                Crossfade time between old and new input. Defaults to 0.05.
+
+        """
+        self._input = x
+        self._in_fader.setInput(x, fadetime)
+
+    def setInpos(self, x):
+        """
+        Replace the `inpos` attribute.
+        
+        :Args:
+
+            x : float or PyoObject
+                New `inpos` attribute.
+
+        """
+        self._inpos = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setInpos(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+ 
+    def setRevtime(self, x):
+        """
+        Replace the `revtime` attribute.
+        
+        :Args:
+
+            x : float or PyoObject
+                New `revtime` attribute.
+
+        """
+        self._revtime = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setRevtime(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+    def setCutoff(self, x):
+        """
+        Replace the `cutoff` attribute.
+        
+        :Args:
+
+            x : float or PyoObject
+                New `cutoff` attribute.
+
+        """
+        self._cutoff = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setCutoff(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+    def setBal(self, x):
+        """
+        Replace the `bal` attribute.
+        
+        :Args:
+
+            x : float or PyoObject
+                New `bal` attribute.
+
+        """
+        self._bal = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setMix(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+    def setRoomSize(self, x):
+        """
+        Set the room size scaler, between 0.25 and 4.
+        
+        :Args:
+
+            x : float
+                Room size scaler, between 0.25 and 4.0.
+
+        """
+        self._roomSize = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setRoomSize(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+    def setFirstRefGain(self, x):
+        """
+        Set the gain of the first reflexions.
+        
+        :Args:
+
+            x : float
+                Gain, in dB, of the first reflexions.
+
+        """
+        self._firstRefGain = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setFirstRefGain(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMap(0., 1., 'lin', 'inpos',  self._inpos),
+                          SLMap(0.01, 120., 'log', 'revtime',  self._revtime),
+                          SLMap(500., 15000., 'log', 'cutoff',  self._cutoff),
+                          SLMap(0., 1., 'lin', 'bal',  self._bal),
+                          SLMap(0.25, 4., 'lin', 'roomSize',  self._roomSize, dataOnly=True),
+                          SLMap(-48, 12, 'lin', 'firstRefGain', self._firstRefGain, dataOnly=True),
+                          SLMapMul(self._mul)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
+
+    @property
+    def input(self):
+        """PyoObject. Input signal to process.""" 
+        return self._input
+    @input.setter
+    def input(self, x): self.setInput(x)
+
+    @property
+    def inpos(self):
+        """float or PyoObject. Position of the source.""" 
+        return self._inpos
+    @inpos.setter
+    def inpos(self, x): self.setInpos(x)
+
+    @property
+    def revtime(self):
+        """float or PyoObject. Room size.""" 
+        return self._revtime
+    @revtime.setter
+    def revtime(self, x): self.setRevtime(x)
+
+    @property
+    def cutoff(self):
+        """float or PyoObject. High frequency damping.""" 
+        return self._cutoff
+    @cutoff.setter
+    def cutoff(self, x): self.setCutoff(x)
+
+    @property
+    def bal(self):
+        """float or PyoObject. Balance between wet and dry signal.""" 
+        return self._bal
+    @bal.setter
+    def bal(self, x): self.setBal(x)
+
+    @property
+    def roomSize(self):
+        """float. Room size scaler, between 0.25 and 4.0.""" 
+        return self._roomSize
+    @roomSize.setter
+    def roomSize(self, x): self.setRoomSize(x)
+
+    @property
+    def firstRefGain(self):
+        """float. Gain, in dB, of the first reflexions.""" 
+        return self._firstRefGain
+    @firstRefGain.setter
+    def firstRefGain(self, x): self.setFirstRefGain(x)
diff --git a/pyolib/filters.py b/pyolib/filters.py
index 1feb485..89d60cb 100644
--- a/pyolib/filters.py
+++ b/pyolib/filters.py
@@ -141,7 +141,9 @@ class Biquad(PyoObject):
         [obj.setType(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
-        self._map_list = [SLMapFreq(self._freq), SLMapQ(self._q), SLMapMul(self._mul)]
+        self._map_list = [SLMapFreq(self._freq), SLMapQ(self._q), 
+                          SLMap(0, 4, 'lin', 'type', self._type, res="int", dataOnly=True),
+                          SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
     @property
@@ -297,7 +299,9 @@ class Biquadx(PyoObject):
         [obj.setStages(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
-        self._map_list = [SLMapFreq(self._freq), SLMapQ(self._q), SLMapMul(self._mul)]
+        self._map_list = [SLMapFreq(self._freq), SLMapQ(self._q), 
+                          SLMap(0, 4, 'lin', 'type', self._type, res="int", dataOnly=True),
+                          SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
     @property
@@ -684,6 +688,7 @@ class EQ(PyoObject):
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
         self._map_list = [SLMapFreq(self._freq), SLMapQ(self._q), 
                           SLMap(-40.0, 40.0, "lin", "boost", self._boost), 
+                          SLMap(0, 2, 'lin', 'type', self._type, res="int", dataOnly=True),
                           SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
@@ -1946,6 +1951,7 @@ class Vocoder(PyoObject):
                           SLMap(0.25, 2, "lin", "spread", self._spread),
                           SLMap(0.5, 200, "log", "q", self._q), 
                           SLMap(0, 1, "lin", "slope", self._slope),
+                          SLMap(2, 64, 'lin', 'stages',  self._stages, res="int", dataOnly=True),
                           SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
@@ -2125,7 +2131,8 @@ class IRWinSinc(PyoObject):
 
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
         self._map_list = [SLMapFreq(self._freq),
-                          SLMap(20., 10000., "log", "bw", self._bw)]
+                          SLMap(20., 10000., "log", "bw", self._bw),
+                          SLMap(0, 3, 'lin', 'type', self._type, res="int", dataOnly=True)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
     @property
@@ -2352,7 +2359,8 @@ class IRPulse(PyoObject):
 
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
         self._map_list = [SLMapFreq(self._freq),
-                          SLMap(20., 10000., "log", "bw", self._bw)]
+                          SLMap(20., 10000., "log", "bw", self._bw),
+                          SLMap(0, 3, 'lin', 'type', self._type, res="int", dataOnly=True)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
     @property
@@ -2738,7 +2746,8 @@ class Average(PyoObject):
         [obj.setSize(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
-        self._map_list = [SLMapMul(self._mul)]
+        self._map_list = [SLMap(2, 256, 'lin', 'size', self._size, res="int", dataOnly=True),
+                          SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
       
     @property
@@ -3361,3 +3370,109 @@ class ButBR(PyoObject):
         return self._q
     @q.setter
     def q(self, x): self.setQ(x)
+
+class ComplexRes(PyoObject):
+    """
+    Complex one-pole resonator filter. 
+    
+    ComplexRes implements a resonator derived from a complex 
+    multiplication, which is very similar to a digital filter.
+    
+    :Parent: :py:class:`PyoObject`
+    
+    :Args:
+    
+        input : PyoObject
+            Input signal to process.
+        freq : float or PyoObject, optional
+            Center frequency of the filter. Defaults to 1000.
+        decay : float or PyoObject, optional
+            Decay time, in seconds, for the filter's response.
+            Defaults to 0.25.
+    
+    >>> s = Server().boot()
+    >>> s.start()
+    >>> env = HannTable()
+    >>> trigs = Metro(.2, poly=4).play()
+    >>> amp = TrigEnv(trigs, table=env, dur=0.005, mul=2)
+    >>> im = Noise(mul=amp)
+    >>> res = ComplexRes(im, freq=[950,530,780,1490], decay=1).out()
+
+    """
+    def __init__(self, input, freq=1000, decay=.25, mul=1, add=0):
+        PyoObject.__init__(self, mul, add)
+        self._input = input
+        self._freq = freq
+        self._decay = decay
+        self._in_fader = InputFader(input)
+        in_fader, freq, decay, mul, add, lmax = convertArgsToLists(self._in_fader, freq, decay, mul, add)
+        self._base_objs = [ComplexRes_base(wrap(in_fader,i), wrap(freq,i), wrap(decay,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+
+    def setInput(self, x, fadetime=0.05):
+        """
+        Replace the `input` attribute.
+        
+        :Args:
+
+            x : PyoObject
+                New signal to process.
+            fadetime : float, optional
+                Crossfade time between old and new input. Defaults to 0.05.
+
+        """
+        self._input = x
+        self._in_fader.setInput(x, fadetime)
+        
+    def setFreq(self, x):
+        """
+        Replace the `freq` attribute.
+        
+        :Args:
+
+            x : float or PyoObject
+                New `freq` attribute.
+
+        """
+        self._freq = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setFreq(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
+    def setDecay(self, x):
+        """
+        Replace the `decay` attribute.
+        
+        :Args:
+
+            x : float or PyoObject
+                New `decay` attribute.
+
+        """
+        self._decay = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setDecay(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMapFreq(self._freq), SLMap(0.0001, 10, "log", "decay", self._decay), 
+                          SLMapMul(self._mul)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
+
+    @property
+    def input(self):
+        """PyoObject. Input signal to filter.""" 
+        return self._input
+    @input.setter
+    def input(self, x): self.setInput(x)
+
+    @property
+    def freq(self):
+        """float or PyoObject. Center frequency of the filter.""" 
+        return self._freq
+    @freq.setter
+    def freq(self, x): self.setFreq(x)
+
+    @property
+    def decay(self):
+        """float or PyoObject. Decay time of the filter's response.""" 
+        return self._decay
+    @decay.setter
+    def decay(self, x): self.setDecay(x)
diff --git a/pyolib/generators.py b/pyolib/generators.py
index a24bb1e..d4731ca 100644
--- a/pyolib/generators.py
+++ b/pyolib/generators.py
@@ -1033,7 +1033,10 @@ class LFO(PyoObject):
 
 
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
-        self._map_list = [SLMapFreq(self._freq), SLMap(0., 1., "lin", "sharp", self._sharp), SLMapMul(self._mul)]
+        self._map_list = [SLMapFreq(self._freq), 
+                          SLMap(0., 1., "lin", "sharp", self._sharp), 
+                          SLMap(0, 7, "lin", "type", self._type, "int", dataOnly=True), 
+                          SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
     @property
diff --git a/pyolib/pan.py b/pyolib/pan.py
index 54b16d7..f66eb18 100644
--- a/pyolib/pan.py
+++ b/pyolib/pan.py
@@ -39,7 +39,8 @@ class Pan(PyoObject):
         input : PyoObject
             Input signal to process.
         outs : int, optional
-            Number of channels on the panning circle. Defaults to 2.
+            Number of channels on the panning circle. Available at 
+            initialization time only. Defaults to 2.
         pan : float or PyoObject
             Position of the sound on the panning circle, between 0 and 1. 
             Defaults to 0.5.
@@ -149,7 +150,8 @@ class SPan(PyoObject):
         input : PyoObject
             Input signal to process.
         outs : int, optional
-            Number of channels on the panning circle. Defaults to 2.
+            Number of channels on the panning circle. Available at 
+            initialization time only. Defaults to 2.
         pan : float or PyoObject
             Position of the sound on the panning circle, between 0 and 1. 
             Defaults to 0.5.
@@ -238,7 +240,8 @@ class Switch(PyoObject):
         input : PyoObject
             Input signal to process.
         outs : int, optional
-            Number of outputs. Defaults to 2.
+            Number of outputs. Available at initialization time only. 
+            Defaults to 2.
         voice : float or PyoObject
             Voice position pointer, between 0 and (outs-1) / len(input). 
             Defaults to 0.
@@ -684,7 +687,8 @@ class Mixer(PyoObject):
         return self._inputs.keys()
         
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
-        self._map_list = [SLMapMul(self._mul)]
+        self._map_list = [SLMap(0, 10, 'lin', 'time', self._time, dataOnly=True),
+                          SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
     @property
diff --git a/pyolib/phasevoc.py b/pyolib/phasevoc.py
index bb4f5e5..379b934 100644
--- a/pyolib/phasevoc.py
+++ b/pyolib/phasevoc.py
@@ -295,8 +295,8 @@ class PVAddSynth(PyoObject):
     >>> s = Server().boot()
     >>> s.start()
     >>> a = SfPlayer(SNDS_PATH+"/transparent.aif", loop=True, mul=0.7)
-    >>> pva = PVAnal(a, size=1024, overlaps=4, pitch=2)
-    >>> pvs = PVAddSynth(pva, pitch=1.25, num=100, first=0, inc=2)
+    >>> pva = PVAnal(a, size=1024, overlaps=4, wintype=2)
+    >>> pvs = PVAddSynth(pva, pitch=1.25, num=100, first=0, inc=2).out()
 
     """
     def __init__(self, input, pitch=1, num=100, first=0, inc=1, mul=1, add=0):
diff --git a/pyolib/players.py b/pyolib/players.py
index 98992ad..3a1f7a4 100644
--- a/pyolib/players.py
+++ b/pyolib/players.py
@@ -208,7 +208,9 @@ class SfPlayer(PyoObject):
         [obj.setInterp(wrap(x,i)) for i, obj in enumerate(self._base_players)]
 
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
-        self._map_list = [SLMap(-2., 2., 'lin', 'speed', self._speed), SLMapMul(self._mul)]
+        self._map_list = [SLMap(-2., 2., 'lin', 'speed', self._speed), 
+                          SLMap(1, 4, 'lin', 'interp', self._interp, res="int", dataOnly=True),
+                          SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
     @property
@@ -354,7 +356,9 @@ class SfMarkerShuffler(PyoObject):
         return self._markers
         
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
-        self._map_list = [SLMap(0.01, 2., 'lin', 'speed', self._speed), SLMapMul(self._mul)]
+        self._map_list = [SLMap(0.01, 2., 'lin', 'speed', self._speed), 
+                          SLMap(1, 4, 'lin', 'interp', self._interp, res="int", dataOnly=True),
+                          SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
                     
     @property
@@ -492,6 +496,7 @@ class SfMarkerLooper(PyoObject):
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
         self._map_list = [SLMap(0.01, 2., 'lin', 'speed', self._speed), 
                           SLMap(0, len(self._markers)-1, 'lin', 'mark', self._mark, 'int'),
+                          SLMap(1, 4, 'lin', 'interp', self._interp, res="int", dataOnly=True),
                           SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
diff --git a/pyolib/randoms.py b/pyolib/randoms.py
index 695ee21..737a0e6 100644
--- a/pyolib/randoms.py
+++ b/pyolib/randoms.py
@@ -627,7 +627,7 @@ class Xnoise(PyoObject):
                 new `x2` attribute.
 
         """
-        self._x2= x
+        self._x2 = x
         x, lmax = convertArgsToLists(x)
         [obj.setX2(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
@@ -645,6 +645,15 @@ class Xnoise(PyoObject):
         x, lmax = convertArgsToLists(x)
         [obj.setFreq(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMap(0, 12, 'lin', 'dist', self._dist, res="int", dataOnly=True),
+                          SLMap(0.001, 200., 'log', 'freq', self._freq),
+                          SLMap(0, 1, 'lin', 'x1', self._x1),
+                          SLMap(0, 1, 'lin', 'x2', self._x2),
+                          SLMap(0, 2500, 'lin', 'mul', self._mul),
+                          SLMap(0, 2500, 'lin', 'add', self._add)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
+
     @property
     def dist(self): 
         """string or int. Distribution type."""
@@ -880,6 +889,14 @@ class XnoiseMidi(PyoObject):
         x, lmax = convertArgsToLists(x)
         [obj.setFreq(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMap(0, 12, 'lin', 'dist', self._dist, res="int", dataOnly=True),
+                          SLMap(0.001, 200., 'log', 'freq', self._freq),
+                          SLMap(0, 1, 'lin', 'x1', self._x1),
+                          SLMap(0, 1, 'lin', 'x2', self._x2),
+                          SLMap(0, 2, 'lin', 'scale', self._scale, res="int", dataOnly=True)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
+
     @property
     def dist(self): 
         """string or int. Distribution type."""
@@ -1097,6 +1114,14 @@ class XnoiseDur(PyoObject):
         x, lmax = convertArgsToLists(x)
         [obj.setX2(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMap(0, 12, 'lin', 'dist', self._dist, res="int", dataOnly=True),
+                          SLMap(0, 20, 'lin', 'min', self._min),
+                          SLMap(0, 20, 'lin', 'max', self._max),
+                          SLMap(0, 1, 'lin', 'x1', self._x1),
+                          SLMap(0, 1, 'lin', 'x2', self._x2)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
+
     @property
     def dist(self): 
         """string or int. Distribution type."""
@@ -1208,7 +1233,7 @@ class Urn(PyoObject):
         [obj.setFreq(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
-        self._map_list = [SLMap(1., 2., 'lin', 'max', self._max),
+        self._map_list = [SLMap(1, 1000, 'lin', 'max', self._max, res="int", dataOnly=True),
                           SLMap(0.1, 20., 'lin', 'freq', self._freq),
                           SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
diff --git a/pyolib/server.py b/pyolib/server.py
index b7729a0..73af2ba 100644
--- a/pyolib/server.py
+++ b/pyolib/server.py
@@ -98,7 +98,7 @@ class Server(object):
         
     """
     def __init__(self, sr=44100, nchnls=2, buffersize=256, duplex=1, audio='portaudio', jackname='pyo'):
-        if os.environ.has_key("PYO_SERVER_AUDIO") and "offline" not in audio:
+        if os.environ.has_key("PYO_SERVER_AUDIO") and "offline" not in audio and "embedded" not in audio:
             audio = os.environ["PYO_SERVER_AUDIO"]
         self._time = time
         self._nchnls = nchnls
@@ -637,13 +637,6 @@ class Server(object):
         
         """
         return self._server.setServer()
-        
-    def flush(self):
-        """
-        Flush the server objects. Need a shutdown before working. This is useful if want to flush a script without freeing the buffers
-        
-        """
-        return self._server.flush()
     
     def getInputAddr(self):
         """
diff --git a/pyolib/tableprocess.py b/pyolib/tableprocess.py
index 2b4fb7c..042d01e 100644
--- a/pyolib/tableprocess.py
+++ b/pyolib/tableprocess.py
@@ -136,6 +136,7 @@ class Osc(PyoObject):
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
         self._map_list = [SLMapFreq(self._freq),
                           SLMapPhase(self._phase),
+                          SLMap(1, 4, 'lin', 'interp', self._interp, res="int", dataOnly=True),
                           SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
@@ -403,6 +404,7 @@ class OscTrig(PyoObject):
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
         self._map_list = [SLMapFreq(self._freq),
                           SLMapPhase(self._phase),
+                          SLMap(1, 4, 'lin', 'interp', self._interp, res="int", dataOnly=True),
                           SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
@@ -854,7 +856,10 @@ class TableRead(PyoObject):
 
 
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
-        self._map_list = [SLMapFreq(self._freq), SLMapMul(self._mul)]
+        self._map_list = [SLMap(0.0001, 1000, 'log', 'freq', self._freq), 
+                          SLMap(0, 1, 'lin', 'loop', self._loop, res="int", dataOnly=True),
+                          SLMap(1, 4, 'lin', 'interp', self._interp, res="int", dataOnly=True),
+                          SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
     @property
@@ -1019,7 +1024,11 @@ class Pulsar(PyoObject):
         :Args:
 
             x : int {1, 2, 3, 4}
-                new `interp` attribute.
+                Choice of the interpolation method.
+                    1. no interpolation
+                    2. linear
+                    3. cosinus
+                    4. cubic
         
         """
         self._interp = x
@@ -1030,6 +1039,7 @@ class Pulsar(PyoObject):
         self._map_list = [SLMapFreq(self._freq),
                           SLMap(0., 1., 'lin', 'frac', self._frac),
                           SLMapPhase(self._phase),
+                          SLMap(1, 4, 'lin', 'interp', self._interp, res="int", dataOnly=True),
                           SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
@@ -1149,6 +1159,144 @@ class Pointer(PyoObject):
     @index.setter
     def index(self, x): self.setIndex(x)
 
+class Pointer2(PyoObject):
+    """
+    High quality table reader with control on the pointer position.
+
+    :Parent: :py:class:`PyoObject`
+
+    :Args:
+
+        table : PyoTableObject
+            Table containing the waveform samples.
+        index : PyoObject
+            Normalized position in the table between 0 and 1.
+        interp : int {1, 2, 3, 4}, optional
+            Choice of the interpolation method. Defaults to 4.
+                1. no interpolation
+                2. linear
+                3. cosinus
+                4. cubic
+        autosmooth : boolean, optional
+            If True, a lowpass filter, following the pitch, is applied on 
+            
+            the output signal to reduce the quantization noise produced 
+            
+            by very low transpositions. Defaults to True.
+
+    >>> s = Server().boot()
+    >>> s.start()
+    >>> t = SndTable(SNDS_PATH + '/transparent.aif')
+    >>> freq = t.getRate()
+    >>> p = Phasor(freq=[freq*0.5, freq*0.45])
+    >>> a = Pointer2(table=t, index=p, mul=.3).out()
+
+    """
+    def __init__(self, table, index, interp=4, autosmooth=True, mul=1, add=0):
+        PyoObject.__init__(self, mul, add)
+        self._table = table
+        self._index = index
+        self._interp = interp
+        self._autosmooth = autosmooth
+        table, index, interp, autosmooth, mul, add, lmax = convertArgsToLists(table, index, interp, autosmooth, mul, add)
+        self._base_objs = [Pointer2_base(wrap(table,i), wrap(index,i), wrap(interp,i), wrap(autosmooth,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+
+    def setTable(self, x):
+        """
+        Replace the `table` attribute.
+        
+        :Args:
+
+            x : PyoTableObject
+                new `table` attribute.
+        
+        """
+        self._table = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setTable(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
+    def setIndex(self, x):
+        """
+        Replace the `index` attribute.
+        
+        :Args:
+
+            x : PyoObject
+                new `index` attribute.
+        
+        """
+        self._index = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setIndex(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
+    def setInterp(self, x):
+        """
+        Replace the `interp` attribute.
+        
+        :Args:
+
+            x : int {1, 2, 3, 4}
+                new `interp` attribute.
+                    1. no interpolation
+                    2. linear interpolation
+                    3. cosine interpolation
+                    4. cubic interpolation (default)
+        
+        """
+        self._interp = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setInterp(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
+    def setAutoSmooth(self, x):
+        """
+        Replace the `autosmooth` attribute.
+        
+        If True, a lowpass filter, following the playback speed, is applied on 
+        the output signal to reduce the quantization noise produced by very 
+        low transpositions.
+        
+        :Args:
+
+            x : boolean
+                new `autosmooth` attribute.
+        
+        """
+        self._autosmooth = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setAutoSmooth(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMapMul(self._mul)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
+
+    @property
+    def table(self):
+        """PyoTableObject. Table containing the waveform samples.""" 
+        return self._table
+    @table.setter
+    def table(self, x): self.setTable(x)
+
+    @property
+    def index(self):
+        """PyoObject. Index pointer position in the table.""" 
+        return self._index
+    @index.setter
+    def index(self, x): self.setIndex(x)
+
+    @property
+    def interp(self): 
+        """int {1, 2, 3, 4}. Interpolation method."""
+        return self._interp
+    @interp.setter
+    def interp(self, x): self.setInterp(x)
+
+    @property
+    def autosmooth(self): 
+        """boolean. Quantization noise filter."""
+        return self._autosmooth
+    @autosmooth.setter
+    def autosmooth(self, x): self.setAutoSmooth(x)
+
 class TableIndex(PyoObject):
     """
     Table reader by sample position without interpolation.
@@ -1710,6 +1858,8 @@ class Granulator(PyoObject):
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
         self._map_list = [SLMap(0.1, 2., 'lin', 'pitch', self._pitch),
                           SLMap(0.01, 1., 'lin', 'dur', self._dur),
+                          SLMap(1, 256, 'lin', 'grains', self._grains, res="int", dataOnly=True),
+                          SLMap(0.001, 1, 'log', 'basedur', self._basedur, dataOnly=True),
                           SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
@@ -2128,7 +2278,9 @@ class Looper(PyoObject):
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
         self._map_list = [SLMap(0.1, 2., 'lin', 'pitch', self._pitch),
                           SLMap(0., self._table.getDur(), 'lin', 'start', self._start),
-                          SLMap(0.01, 1., 'lin', 'dur', self._dur),
+                          SLMap(0.01, self._table.getDur(), 'lin', 'dur', self._dur),
+                          SLMap(0, 2, 'lin', 'xfadeshape', self._xfadeshape, res="int", dataOnly=True),
+                          SLMap(1, 4, 'lin', 'interp', self._interp, res="int", dataOnly=True),
                           SLMapMul(self._mul)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
diff --git a/pyolib/tables.py b/pyolib/tables.py
index f3a4a3f..4fc552a 100644
--- a/pyolib/tables.py
+++ b/pyolib/tables.py
@@ -1588,6 +1588,33 @@ class SndTable(PyoTableObject):
             else:
                 return _size
 
+    def getViewTable(self, size, begin=0, end=0):
+        """
+        Return a list of points (in X, Y pixel values) for each channel in the table.
+        These lists can be draw on a DC (WxPython) with a DrawLines method.
+
+        :Args:
+            
+            size : tuple
+                Size, (X, Y) pixel values, of the waveform container window.
+            begin : float, optional
+                First position in the the table, in seconds, where to get samples.
+                Defaults to 0.
+            end : float, optional
+                Last position in the table, in seconds, where to get samples. 
+                
+                if this value is set to 0, that means the end of the table. Defaults to 0.
+                 
+        """
+        w, h = size
+        chnls = len(self._base_objs)
+        img = []
+        imgHeight = h/chnls
+        for i in range(chnls):
+            off = h/chnls*i
+            img.append(self._base_objs[i].getViewTable((w, imgHeight), begin, end, off))
+        return img
+
     def getEnvelope(self, points):
         """
         Return the amplitude envelope of the table.
@@ -1759,10 +1786,13 @@ class NewTable(PyoTableObject):
         """
         return self._base_objs[0].getLength()
 
-    def getDur(self):
+    def getDur(self, all=True):
         """
         Returns the length of the table in seconds.
         
+        The `all` argument is there for compatibility with SndTable but
+        is not used for now.
+        
         """
         return self._base_objs[0].getLength()
         
@@ -1774,6 +1804,33 @@ class NewTable(PyoTableObject):
         """
         return self._base_objs[0].getRate()
 
+    def getViewTable(self, size, begin=0, end=0):
+        """
+        Return a list of points (in X, Y pixel values) for each channel in the table.
+        These lists can be draw on a DC (WxPython) with a DrawLines method.
+
+        :Args:
+            
+            size : tuple
+                Size, (X, Y) pixel values, of the waveform container window.
+            begin : float, optional
+                First position in the the table, in seconds, where to get samples.
+                Defaults to 0.
+            end : float, optional
+                Last position in the table, in seconds, where to get samples. 
+                
+                if this value is set to 0, that means the end of the table. Defaults to 0.
+
+        """
+        w, h = size
+        chnls = len(self._base_objs)
+        img = []
+        imgHeight = h/chnls
+        for i in range(chnls):
+            off = h/chnls*i
+            img.append(self._base_objs[i].getViewTable((w, imgHeight), begin, end, off))
+        return img
+
     def view(self, title="Sound waveform", wxnoserver=False, mouse_callback=None):
         """
         Opens a window showing the contents of the table.
diff --git a/pyolib/triggers.py b/pyolib/triggers.py
index dac00f0..e653171 100644
--- a/pyolib/triggers.py
+++ b/pyolib/triggers.py
@@ -676,7 +676,11 @@ class Beat(PyoObject):
         pass
 
     def ctrl(self, map_list=None, title=None, wxnoserver=False):
-        self._map_list = [SLMap(0.001, 1., 'lin', 'time', self._time)]
+        self._map_list = [SLMap(0.001, 1., 'lin', 'time', self._time),
+                          SLMap(2, 64, 'lin', 'taps', self._taps, res="int", dataOnly=True),
+                          SLMap(0, 100, 'lin', 'w1', self._w1, res="int", dataOnly=True),
+                          SLMap(0, 100, 'lin', 'w2', self._w2, res="int", dataOnly=True),
+                          SLMap(0, 100, 'lin', 'w3', self._w3, res="int", dataOnly=True)]
         PyoObject.ctrl(self, map_list, title, wxnoserver)
 
     @property
@@ -2261,6 +2265,14 @@ class Counter(PyoObject):
         value, lmax = convertArgsToLists(value)
         [obj.reset(wrap(value,i)) for i, obj in enumerate(self._base_objs)]
 
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMap(0, 100, 'lin', 'min', self._min, res="int", dataOnly=True),
+                          SLMap(0, 1000, 'lin', 'max', self._max, res="int", dataOnly=True),
+                          SLMap(0, 2, 'lin', 'dir', self._dir, res="int", dataOnly=True),
+                          SLMap(0, 1000, 'lin', 'mul', self._mul),
+                          SLMap(0, 1000, 'lin', 'add', self._add)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
+
     @property
     def input(self): 
         """PyoObject. Audio trigger signal."""
@@ -2367,6 +2379,10 @@ class Select(PyoObject):
         x, lmax = convertArgsToLists(x)
         [obj.setValue(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMap(0, 100, 'lin', 'value', self._value, res="int", dataOnly=True)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
+
     @property
     def input(self): 
         """PyoObject. Audio signal."""
@@ -2923,6 +2939,12 @@ class Count(PyoObject):
         x, lmax = convertArgsToLists(x)
         [obj.setMax(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
 
+    def ctrl(self, map_list=None, title=None, wxnoserver=False):
+        self._map_list = [SLMap(0, 10000, 'lin', 'min', self._min, res="int", dataOnly=True),
+                          SLMap(10000, 1000000, 'lin', 'max', self._max, res="int", dataOnly=True),
+                          SLMapMul(self._mul)]
+        PyoObject.ctrl(self, map_list, title, wxnoserver)
+
     @property
     def input(self): 
         """PyoObject. Trigger signal. Start/Restart the count."""
diff --git a/pyolib/utils.py b/pyolib/utils.py
index f1de462..ab68c0a 100644
--- a/pyolib/utils.py
+++ b/pyolib/utils.py
@@ -430,7 +430,7 @@ class SampHold(PyoObject):
 
     SampHold performs a sample-and-hold operation on its input according 
     to the value of `controlsig`. If `controlsig` equals `value`, the input 
-    is sampled and holded until next sampling.
+    is sampled and held until next sampling.
 
     :Parent: :py:class:`PyoObject`
 
@@ -441,7 +441,7 @@ class SampHold(PyoObject):
         controlsig : PyoObject
             Controls when to sample the signal.
         value : float or PyoObject, optional
-            Sampling targeted value. Default to 0.0.
+            Sampling target value. Default to 0.0.
 
     >>> s = Server().boot()
     >>> s.start()
@@ -521,7 +521,7 @@ class SampHold(PyoObject):
 
     @property
     def value(self):
-        """float or PyoObject. Targeted value.""" 
+        """float or PyoObject. Target value.""" 
         return self._value
     @value.setter
     def value(self, x): self.setValue(x)
@@ -1736,3 +1736,105 @@ class Between(PyoObject):
         return self._max
     @max.setter
     def max(self, x): self.setMax(x)
+
+class TrackHold(PyoObject):
+    """
+    Performs a track-and-hold operation on its input. 
+
+    TrackHold lets pass the signal in `input` without modification but hold
+    a sample according to the value of `controlsig`. If `controlsig` equals 
+    `value`, the input is sampled and held, otherwise, it passes thru.
+
+    :Parent: :py:class:`PyoObject`
+
+    :Args:
+
+        input : PyoObject
+            Input signal.
+        controlsig : PyoObject
+            Controls when to sample the signal.
+        value : float or PyoObject, optional
+            Sampling target value. Default to 0.0.
+
+    >>> s = Server().boot()
+    >>> s.start()
+    >>> ph = Phasor([3,4])
+    >>> lf = Sine(.2, mul=.5, add=.5)
+    >>> th = TrackHold(lf, ph > 0.5, 1, mul=500, add=300)
+    >>> a = Sine(th, mul=.3).out()
+
+    """
+    def __init__(self, input, controlsig, value=0.0, mul=1, add=0):
+        PyoObject.__init__(self, mul, add)
+        self._input = input
+        self._controlsig = controlsig
+        self._value = value
+        self._in_fader = InputFader(input)
+        self._in_fader2 = InputFader(controlsig)
+        in_fader, in_fader2, value, mul, add, lmax = convertArgsToLists(self._in_fader, self._in_fader2, value, mul, add)
+        self._base_objs = [TrackHold_base(wrap(in_fader,i), wrap(in_fader2,i), wrap(value,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+
+    def setInput(self, x, fadetime=0.05):
+        """
+        Replace the `input` attribute.
+        
+        :Args:
+
+            x : PyoObject
+                New signal to process.
+            fadetime : float, optional
+                Crossfade time between old and new input. Default to 0.05.
+
+        """
+        self._input = x
+        self._in_fader.setInput(x, fadetime)
+
+    def setControlsig(self, x, fadetime=0.05):
+        """
+        Replace the `controlsig` attribute.
+        
+        :Args:
+
+            x : PyoObject
+                New control signal.
+            fadetime : float, optional
+                Crossfade time between old and new input. Default to 0.05.
+
+        """
+        self._controlsig = x
+        self._in_fader2.setInput(x, fadetime)
+        
+    def setValue(self, x):
+        """
+        Replace the `value` attribute.
+        
+        :Args:
+
+            x : float or PyoObject
+                New `value` attribute.
+
+        """
+        self._value = x
+        x, lmax = convertArgsToLists(x)
+        [obj.setValue(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
+    @property
+    def input(self):
+        """PyoObject. Input signal.""" 
+        return self._input
+    @input.setter
+    def input(self, x): self.setInput(x)
+
+    @property
+    def controlsig(self):
+        """PyoObject. Control signal.""" 
+        return self._controlsig
+    @controlsig.setter
+    def controlsig(self, x): self.setControlsig(x)
+
+    @property
+    def value(self):
+        """float or PyoObject. Target value.""" 
+        return self._value
+    @value.setter
+    def value(self, x): self.setValue(x)
diff --git a/scripts/release_doc_src.sh b/scripts/release_doc_src.sh
index 9b8c344..2c2f029 100644
--- a/scripts/release_doc_src.sh
+++ b/scripts/release_doc_src.sh
@@ -6,7 +6,7 @@
 # 3. Execute from pyo folder : ./scripts/release_doc_src.sh
 #
 
-version=0.6.8
+version=0.6.9
 replace=XXX
 
 doc_rep=pyo_XXX-doc
diff --git a/setup.py b/setup.py
index 92bcd39..1777d95 100644
--- a/setup.py
+++ b/setup.py
@@ -23,7 +23,7 @@ from distutils.core import setup, Extension
 import os, sys, getopt
 import time
 
-pyo_version = "0.6.8"
+pyo_version = "0.6.9"
 build_osx_with_jack_support = False
 compile_externals = False
 
@@ -68,13 +68,14 @@ files = ['pyomodule.c', 'servermodule.c', 'pvstreammodule.c', 'streammodule.c',
 source_files = [path + f for f in files]
 
 path = 'src/objects/'
-files = ['phasevocmodule.c', 'fftmodule.c', 'oscilmodule.c', 'randommodule.c', 'oscmodule.c','analysismodule.c', 
-        'sfplayermodule.c', 'oscbankmodule.c', 'lfomodule.c', 'tablemodule.c',
+files = ['tablemodule.c', 'wgverbmodule.c', 'freeverbmodule.c', 'phasevocmodule.c', 'fftmodule.c', 
+        'oscilmodule.c', 'randommodule.c', 'oscmodule.c','analysismodule.c', 
+        'sfplayermodule.c', 'oscbankmodule.c', 'lfomodule.c', 
          'matrixmodule.c', 'filtremodule.c', 'noisemodule.c', 'distomodule.c',
         'inputmodule.c', 'fadermodule.c', 'midimodule.c', 'delaymodule.c','recordmodule.c', 'granulatormodule.c', 
         'metromodule.c', 'trigmodule.c', 'patternmodule.c', 'bandsplitmodule.c', 'hilbertmodule.c', 'panmodule.c',
-        'selectmodule.c', 'freeverbmodule.c', 'compressmodule.c', 'utilsmodule.c',
-        'convolvemodule.c', 'wgverbmodule.c', 'arithmeticmodule.c', 'sigmodule.c',
+        'selectmodule.c', 'compressmodule.c', 'utilsmodule.c',
+        'convolvemodule.c', 'arithmeticmodule.c', 'sigmodule.c',
         'matrixprocessmodule.c', 'harmonizermodule.c', 'chorusmodule.c']
 
 if compile_externals:
@@ -93,6 +94,8 @@ else:
     tsrt = time.strftime('"%d %b %Y %H:%M:%S"', time.localtime())
     macros.append(('TIMESTAMP', tsrt))
     include_dirs = ['include', '/usr/local/include']
+    if sys.platform == "darwin":
+        include_dirs.append('/opt/local/include')
     library_dirs = []
     libraries = ['portaudio', 'portmidi', 'sndfile', 'lo']
     if build_osx_with_jack_support:
diff --git a/src/engine/interpolation.c b/src/engine/interpolation.c
index a9ee2b5..00ee8c2 100644
--- a/src/engine/interpolation.c
+++ b/src/engine/interpolation.c
@@ -38,7 +38,7 @@ MYFLT cosine(MYFLT *buf, int index, MYFLT frac, int size) {
     MYFLT x2 = buf[index+1];
     
     frac2 = (1.0 - MYCOS(frac * M_PI)) * 0.5;
-    return (x1 * (1.0 - frac2) + x2 * frac2);
+    return (x1 + (x2 - x1) * frac2);
 }
 
 MYFLT cubic(MYFLT *buf, int index, MYFLT frac, int size) {
diff --git a/src/engine/pyomodule.c b/src/engine/pyomodule.c
index 208eff1..6de20d9 100644
--- a/src/engine/pyomodule.c
+++ b/src/engine/pyomodule.c
@@ -52,6 +52,28 @@ static void portaudio_assert(PaError ecode, const char* cmdName) {
 >>> print c\n\
 1\n\n"
 
+#define portaudio_get_version_info \
+"\nReturns the version number, as an integer, of the current portaudio installation.\n\n\
+>>> v = pa_get_version()\n\
+>>> print v\n\
+1899\n\n"
+
+static PyObject *
+portaudio_get_version() {
+    return PyInt_FromLong(Pa_GetVersion());
+}
+
+#define portaudio_get_version_text_info \
+"\nReturns the textual description of the current portaudio installation.\n\n\
+>>> desc = pa_get_version_text()\n\
+>>> print desc\n\
+PortAudio V19-devel (built Oct 8 2012 16:25:16)\n\n"
+
+static PyObject *
+portaudio_get_version_text() {
+    return PyString_FromString(Pa_GetVersionText());
+}
+
 static PyObject *
 portaudio_count_host_apis(){
     PaError err;
@@ -1296,7 +1318,7 @@ downsamp(PyObject *self, PyObject *args, PyObject *kwds)
 
     for (i=0; i<samples_per_channels; i++) {
         for (j=0; j<snd_chnls; j++) {
-            if (i < snd_size)
+            if (i*down < snd_size)
                 downsamples[j][i] = samples[j][i*down];
             else
                 downsamples[j][i] = 0.0;            
@@ -2077,6 +2099,8 @@ serverBooted(PyObject *self) {
 }
 
 static PyMethodDef pyo_functions[] = {
+{"pa_get_version", (PyCFunction)portaudio_get_version, METH_NOARGS, portaudio_get_version_info},
+{"pa_get_version_text", (PyCFunction)portaudio_get_version_text, METH_NOARGS, portaudio_get_version_text_info},
 {"pa_count_devices", (PyCFunction)portaudio_count_devices, METH_NOARGS, portaudio_count_devices_info},
 {"pa_count_host_apis", (PyCFunction)portaudio_count_host_apis, METH_NOARGS, portaudio_count_host_apis_info},
 {"pa_list_devices", (PyCFunction)portaudio_list_devices, METH_NOARGS, portaudio_list_devices_info},
@@ -2408,6 +2432,11 @@ init_pyo64(void)
     module_add_object(m, "PVMix_base", &PVMixType);
     module_add_object(m, "Granule_base", &GranuleType);
     module_add_object(m, "TableScale_base", &TableScaleType);
+    module_add_object(m, "TrackHold_base", &TrackHoldType);
+    module_add_object(m, "ComplexRes_base", &ComplexResType);
+    module_add_object(m, "STReverb_base", &STReverbType);
+    module_add_object(m, "STRev_base", &STRevType);
+    module_add_object(m, "Pointer2_base", &Pointer2Type);
 
     PyModule_AddStringConstant(m, "PYO_VERSION", PYO_VERSION);
 #ifdef COMPILE_EXTERNALS
diff --git a/src/engine/servermodule.c b/src/engine/servermodule.c
index 9148323..e7418c8 100644
--- a/src/engine/servermodule.c
+++ b/src/engine/servermodule.c
@@ -2136,85 +2136,6 @@ Server_boot(Server *self, PyObject *arg)
     return Py_None;
 }
 
-/* Like the Server_boot() but without reinitializing the buffers */
-static PyObject *
-Server_flush(Server *self)
-{
-    int audioerr = 0;
-    int i;
-    if (self->server_booted == 1) {
-        Server_error(self, "Server already booted!\n");
-        Py_INCREF(Py_None);
-        return Py_None;
-    }
-    self->server_started = 0;
-    self->stream_count = 0;
-    self->elapsedSamples = 0;
-
-    self->streams = PyList_New(0);
-    switch (self->audio_be_type) {
-        case PyoPortaudio:
-            audioerr = Server_pa_init(self);
-            break;
-        case PyoJack:
-#ifdef USE_JACK
-            audioerr = Server_jack_init(self);
-            if (audioerr < 0) {
-                Server_jack_deinit(self);
-            }
-#else
-            audioerr = -1;
-            Server_error(self, "Pyo built without Jack support\n");
-#endif
-            break;
-        case PyoCoreaudio:
-#ifdef USE_COREAUDIO
-            audioerr = Server_coreaudio_init(self);
-            if (audioerr < 0) {
-                Server_coreaudio_deinit(self);
-            }
-#else
-            audioerr = -1;
-            Server_error(self, "Pyo built without Coreaudio support\n");
-#endif
-            break;
-        case PyoOffline:
-            audioerr = Server_offline_init(self);
-            if (audioerr < 0) {
-                Server_offline_deinit(self);
-            }
-            break;
-        case PyoOfflineNB:
-            audioerr = Server_offline_init(self);
-            if (audioerr < 0) {
-                Server_offline_deinit(self);
-            }
-            break;
-        case PyoEmbedded:
-            audioerr = Server_embedded_init(self);
-            if (audioerr < 0) {
-                Server_embedded_deinit(self);
-            }
-            break;
-    }
-
-    for (i=0; i<self->bufferSize*self->nchnls; i++) {
-        self->input_buffer[i] = 0.0;
-        self->output_buffer[i] = 0.0;
-    }
-    
-    if (audioerr == 0) {
-        self->server_booted = 1;
-    }
-    else {
-        self->server_booted = 0;
-        Server_error(self, "\nServer not booted.\n");
-    }    
-    
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
 static PyObject *
 Server_start(Server *self)
 {
@@ -2240,7 +2161,7 @@ Server_start(Server *self)
     self->server_started = 1;
     self->timeStep = (int)(0.01 * self->samplingRate);
 
-    if (self->audio_be_type != PyoOffline && self->audio_be_type != PyoOfflineNB) {
+    if (self->audio_be_type != PyoOffline && self->audio_be_type != PyoOfflineNB && self->audio_be_type != PyoEmbedded) {
         midierr = Server_pm_init(self);
         Server_debug(self, "PortMidi initialization return code : %d.\n", midierr);
     }
@@ -2742,7 +2663,6 @@ static PyMethodDef Server_methods[] = {
     {"getMidiActive", (PyCFunction)Server_getMidiActive, METH_NOARGS, "Returns 1 if midi callback is active, otherwise returns 0."},
     {"_setDefaultRecPath", (PyCFunction)Server_setDefaultRecPath, METH_VARARGS|METH_KEYWORDS, "Sets the default recording path."},
     {"setServer", (PyCFunction)Server_setServer, METH_NOARGS, "Sets this server as the one to use for new objects when using the embedded device"},
-    {"flush", (PyCFunction)Server_flush, METH_NOARGS, "Flush the server objects"},
     {"getInputAddr", (PyCFunction)Server_getInputAddr, METH_NOARGS, "Get the embedded device input buffer memory address"},
     {"getOutputAddr", (PyCFunction)Server_getOutputAddr, METH_NOARGS, "Get the embedded device output buffer memory address"},
     {"getServerID", (PyCFunction)Server_getServerID, METH_NOARGS, "Get the embedded device server memory address"},
diff --git a/src/objects/delaymodule.c b/src/objects/delaymodule.c
index f4a0302..4114833 100644
--- a/src/objects/delaymodule.c
+++ b/src/objects/delaymodule.c
@@ -35,6 +35,7 @@ typedef struct {
     PyObject *feedback;
     Stream *feedback_stream;
     MYFLT maxdelay;
+    MYFLT oneOverSr;
     long size;
     long in_count;
     int modebuffer[4];
@@ -50,8 +51,8 @@ Delay_process_ii(Delay *self) {
     MYFLT del = PyFloat_AS_DOUBLE(self->delay);
     MYFLT feed = PyFloat_AS_DOUBLE(self->feedback);
     
-    if (del < 0.)
-        del = 0.;
+    if (del < self->oneOverSr)
+        del = self->oneOverSr;
     else if (del > self->maxdelay)
         del = self->maxdelay;
     MYFLT sampdel = del * self->sr;
@@ -99,8 +100,8 @@ Delay_process_ai(Delay *self) {
     
     for (i=0; i<self->bufsize; i++) {
         del = delobj[i];
-        if (del < 0.)
-            del = 0.;
+        if (del < self->oneOverSr)
+            del = self->oneOverSr;
         else if (del > self->maxdelay)
             del = self->maxdelay;
         sampdel = del * self->sr;
@@ -130,8 +131,8 @@ Delay_process_ia(Delay *self) {
     MYFLT del = PyFloat_AS_DOUBLE(self->delay);
     MYFLT *fdb = Stream_getData((Stream *)self->feedback_stream);    
     
-    if (del < 0.)
-        del = 0.;
+    if (del < self->oneOverSr)
+        del = self->oneOverSr;
     else if (del > self->maxdelay)
         del = self->maxdelay;
     MYFLT sampdel = del * self->sr;
@@ -175,8 +176,8 @@ Delay_process_aa(Delay *self) {
     
     for (i=0; i<self->bufsize; i++) {
         del = delobj[i];
-        if (del < 0.)
-            del = 0.;
+        if (del < self->oneOverSr)
+            del = self->oneOverSr;
         else if (del > self->maxdelay)
             del = self->maxdelay;
         sampdel = del * self->sr;
@@ -325,6 +326,9 @@ Delay_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 	self->modebuffer[3] = 0;
 
     INIT_OBJECT_COMMON
+    
+    self->oneOverSr = 1.0 / self->sr;
+
     Stream_setFunctionPtr(self->stream, Delay_compute_next_data_frame);
     self->mode_func_ptr = Delay_setProcMode;
 
@@ -615,7 +619,7 @@ SDelay_process_i(SDelay *self) {
         for (i=0; i<self->bufsize; i++) {
             ind = self->in_count - sampdel;
             if (ind < 0)
-                ind += (self->size-1);
+                ind += self->size;
             self->data[i] = self->buffer[ind];
         
             self->buffer[self->in_count] = in[i];
@@ -648,7 +652,7 @@ SDelay_process_a(SDelay *self) {
         else {
             ind = self->in_count - sampdel;
             if (ind < 0)
-                ind += (self->size-1);
+                ind += self->size;
             self->data[i] = self->buffer[ind];
         }
         self->buffer[self->in_count++] = in[i];
diff --git a/src/objects/fadermodule.c b/src/objects/fadermodule.c
index 906d3c8..98cf25b 100644
--- a/src/objects/fadermodule.c
+++ b/src/objects/fadermodule.c
@@ -55,8 +55,10 @@ Fader_generate_auto(Fader *self) {
     for (i=0; i<self->bufsize; i++) {
         if (self->currentTime <= self->attack)
             val = self->currentTime / self->attack;
-        else if (self->currentTime > self->duration)
+        else if (self->currentTime > self->duration) {
             val = 0.;
+            Fader_internal_stop((Fader *)self);
+        }
         else if (self->currentTime >= (self->duration - self->release))
             val = (self->duration - self->currentTime) / self->release;
         else
@@ -427,8 +429,10 @@ Adsr_generate_auto(Adsr *self) {
             val = self->currentTime * invatt;
         else if (self->currentTime <= (self->attack + self->decay))
             val = (self->decay - (self->currentTime - self->attack)) * invdec * (1. - self->sustain) + self->sustain;
-        else if (self->currentTime > self->duration)
+        else if (self->currentTime > self->duration) {
             val = 0.;
+            Adsr_internal_stop((Adsr *)self);
+        }
         else if (self->currentTime >= (self->duration - self->release))
             val = (self->duration - self->currentTime) * invrel * self->sustain;
         else
diff --git a/src/objects/filtremodule.c b/src/objects/filtremodule.c
index d848581..de7c575 100644
--- a/src/objects/filtremodule.c
+++ b/src/objects/filtremodule.c
@@ -5792,6 +5792,7 @@ typedef struct {
     MYFLT factor;
     int stages;
     int last_stages;
+    int flag;
     MYFLT nyquist;
     MYFLT twoPiOnSr;
     int modebuffer[6]; // need at least 2 slots for mul & add 
@@ -5829,9 +5830,9 @@ Vocoder_allocate_memories(Vocoder *self)
         for (j=0; j<2; j++) {
             i2j = i * 2 + j;
             self->yy1[i2j] = self->yy2[i2j] = self->y1[i2j] = self->y2[i2j] = 0.0;
-
         }
-    }    
+    }
+    self->flag = 1; 
 }
 
 static void
@@ -5887,11 +5888,12 @@ Vocoder_filters_iii(Vocoder *self) {
         self->factor = MYEXP(-1.0 / (self->sr / ((slope * 48.0) + 2.0)));
     }
 
-    if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages) {
+    if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages || self->flag) {
         self->last_freq = freq;
         self->last_spread = spread;
         self->last_q = q;
         self->last_stages = self->stages;
+        self->flag = 0;
         Vocoder_compute_variables(self, freq, spread, q);
     }
     
@@ -5971,11 +5973,12 @@ Vocoder_filters_aii(Vocoder *self) {
         else if (count >= maxcount)
             count = 0;
         count++;
-        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages) {
+        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages || self->flag) {
             self->last_freq = freq;
             self->last_spread = spread;
             self->last_q = q;
             self->last_stages = self->stages;
+            self->flag = 0;
             Vocoder_compute_variables(self, freq, spread, q);
         }
         output = 0.0;
@@ -6053,11 +6056,12 @@ Vocoder_filters_iai(Vocoder *self) {
         else if (count >= maxcount)
             count = 0;
         count++;
-        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages) {
+        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages || self->flag) {
             self->last_freq = freq;
             self->last_spread = spread;
             self->last_q = q;
             self->last_stages = self->stages;
+            self->flag = 0;
             Vocoder_compute_variables(self, freq, spread, q);
         }
         output = 0.0;
@@ -6138,11 +6142,12 @@ Vocoder_filters_aai(Vocoder *self) {
         else if (count >= maxcount)
             count = 0;
         count++;
-        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages) {
+        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages || self->flag) {
             self->last_freq = freq;
             self->last_spread = spread;
             self->last_q = q;
             self->last_stages = self->stages;
+            self->flag = 0;
             Vocoder_compute_variables(self, freq, spread, q);
         }
         output = 0.0;
@@ -6220,11 +6225,12 @@ Vocoder_filters_iia(Vocoder *self) {
         else if (count >= maxcount)
             count = 0;
         count++;
-        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages) {
+        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages || self->flag) {
             self->last_freq = freq;
             self->last_spread = spread;
             self->last_q = q;
             self->last_stages = self->stages;
+            self->flag = 0;
             Vocoder_compute_variables(self, freq, spread, q);
         }
         output = 0.0;
@@ -6304,11 +6310,12 @@ Vocoder_filters_aia(Vocoder *self) {
         else if (count >= maxcount)
             count = 0;
         count++;
-        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages) {
+        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages || self->flag) {
             self->last_freq = freq;
             self->last_spread = spread;
             self->last_q = q;
             self->last_stages = self->stages;
+            self->flag = 0;
             Vocoder_compute_variables(self, freq, spread, q);
         }
         output = 0.0;
@@ -6388,11 +6395,12 @@ Vocoder_filters_iaa(Vocoder *self) {
         else if (count >= maxcount)
             count = 0;
         count++;
-        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages) {
+        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages || self->flag) {
             self->last_freq = freq;
             self->last_spread = spread;
             self->last_q = q;
             self->last_stages = self->stages;
+            self->flag = 0;
             Vocoder_compute_variables(self, freq, spread, q);
         }
         output = 0.0;
@@ -6474,11 +6482,12 @@ Vocoder_filters_aaa(Vocoder *self) {
         else if (count >= maxcount)
             count = 0;
         count++;
-        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages) {
+        if (freq != self->last_freq || spread != self->last_spread || q != self->last_q || self->stages != self->last_stages || self->flag) {
             self->last_freq = freq;
             self->last_spread = spread;
             self->last_q = q;
             self->last_stages = self->stages;
+            self->flag = 0;
             Vocoder_compute_variables(self, freq, spread, q);
         }
         output = 0.0;
@@ -6674,6 +6683,7 @@ Vocoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     self->factor = 0.99;
     self->stages = 24;
     self->last_stages = -1;
+    self->flag = 0;
 	self->modebuffer[0] = 0;
 	self->modebuffer[1] = 0;
 	self->modebuffer[2] = 0;
@@ -11024,3 +11034,510 @@ PyTypeObject ButBRType = {
     0,                                              /* tp_alloc */
     ButBR_new,                                     /* tp_new */
 };
+
+/****************/
+/** ComplexRes **/
+/****************/
+typedef struct {
+    pyo_audio_HEAD
+    PyObject *input;
+    Stream *input_stream;
+    PyObject *freq;
+    Stream *freq_stream;
+    PyObject *decay;
+    Stream *decay_stream;
+    int modebuffer[4]; // need at least 2 slots for mul & add 
+    MYFLT last_freq;
+    MYFLT last_decay;
+    MYFLT oneOnSr;
+    // variables
+    MYFLT res;
+    MYFLT norm;
+    MYFLT coeffx;
+    MYFLT coeffy;
+    // sample memories
+    MYFLT x;
+    MYFLT y;
+} ComplexRes;
+
+static void
+ComplexRes_filters_ii(ComplexRes *self) {
+    int i;
+    MYFLT ang, x, y;
+    MYFLT *in = Stream_getData((Stream *)self->input_stream);
+    MYFLT freq = PyFloat_AS_DOUBLE(self->freq); 
+    MYFLT decay = PyFloat_AS_DOUBLE(self->decay);
+    
+    if (decay <= 0.0001)
+        decay = 0.0001;
+
+    if (decay != self->last_decay || freq != self->last_freq) {
+        self->res = MYEXP(-1.0/(decay*self->sr));
+        //self->norm = (1.0-self->res*self->res)/self->res;
+        self->last_decay = decay;
+        ang = (freq*self->oneOnSr)*TWOPI;
+        self->coeffx = self->res * MYCOS(ang);
+        self->coeffy = self->res * MYSIN(ang);
+        self->last_freq = freq;
+    }
+
+    for (i=0; i<self->bufsize; i++) {
+        x = self->coeffx * self->x - self->coeffy * self->y + in[i];
+        y = self->coeffy * self->x + self->coeffx * self->y;
+        self->data[i] = y * self->norm;        
+        self->x = x;
+        self->y = y;
+    }
+}
+
+static void
+ComplexRes_filters_ai(ComplexRes *self) {
+    int i, check = 0;
+    MYFLT freq, ang, x, y;
+    MYFLT *in = Stream_getData((Stream *)self->input_stream);
+    MYFLT *fr = Stream_getData((Stream *)self->freq_stream);
+    MYFLT decay = PyFloat_AS_DOUBLE(self->decay);
+
+    if (decay <= 0.0001)
+        decay = 0.0001;
+
+    if (decay != self->last_decay) {
+        self->res = MYEXP(-1.0/(decay*self->sr));
+        //self->norm = (1.0-self->res*self->res)/self->res;
+        self->last_decay = decay;
+        check = 1;
+    }
+    
+    for (i=0; i<self->bufsize; i++) {
+        freq = fr[i];
+        if (freq != self->last_freq || check) {
+            ang = (freq*self->oneOnSr)*TWOPI;
+            self->coeffx = self->res * MYCOS(ang);
+            self->coeffy = self->res * MYSIN(ang);
+            self->last_freq = freq;
+            check = 0;
+        }
+        x = self->coeffx * self->x - self->coeffy * self->y + in[i];
+        y = self->coeffy * self->x + self->coeffx * self->y;
+        self->data[i] = y * self->norm;        
+        self->x = x;
+        self->y = y;
+    }
+}
+
+static void
+ComplexRes_filters_ia(ComplexRes *self) {
+    int i;
+    MYFLT decay, ang, x, y;
+    MYFLT *in = Stream_getData((Stream *)self->input_stream);
+    MYFLT freq = PyFloat_AS_DOUBLE(self->freq);
+    MYFLT *dec = Stream_getData((Stream *)self->decay_stream);
+    
+    for (i=0; i<self->bufsize; i++) {
+        decay = dec[i];
+        if (decay <= 0.0001)
+            decay = 0.0001;
+        if (freq != self->last_freq || decay != self->last_decay) {
+            self->res = MYEXP(-1.0/(decay*self->sr));
+            //self->norm = (1.0-self->res*self->res)/self->res;
+            self->last_decay = decay;
+            ang = (freq*self->oneOnSr)*TWOPI;
+            self->coeffx = self->res * MYCOS(ang);
+            self->coeffy = self->res * MYSIN(ang);
+            self->last_freq = freq;
+        }
+        x = self->coeffx * self->x - self->coeffy * self->y + in[i];
+        y = self->coeffy * self->x + self->coeffx * self->y;
+        self->data[i] = y * self->norm;        
+        self->x = x;
+        self->y = y;
+    }
+}
+
+static void
+ComplexRes_filters_aa(ComplexRes *self) {
+    int i;
+    MYFLT freq, decay, ang, x, y;
+    MYFLT *in = Stream_getData((Stream *)self->input_stream);
+    MYFLT *fr = Stream_getData((Stream *)self->freq_stream);
+    MYFLT *dec = Stream_getData((Stream *)self->decay_stream);
+    
+    for (i=0; i<self->bufsize; i++) {
+        freq = fr[i];
+        decay = dec[i];
+        if (decay <= 0.0001)
+            decay = 0.0001;
+        if (freq != self->last_freq || decay != self->last_decay) {
+            self->res = MYEXP(-1.0/(decay*self->sr));
+            //self->norm = (1.0-self->res*self->res)/self->res;
+            self->last_decay = decay;
+            ang = (freq*self->oneOnSr)*TWOPI;
+            self->coeffx = self->res * MYCOS(ang);
+            self->coeffy = self->res * MYSIN(ang);
+            self->last_freq = freq;
+        }
+        x = self->coeffx * self->x - self->coeffy * self->y + in[i];
+        y = self->coeffy * self->x + self->coeffx * self->y;
+        self->data[i] = y * self->norm;        
+        self->x = x;
+        self->y = y;
+    }
+}
+
+static void ComplexRes_postprocessing_ii(ComplexRes *self) { POST_PROCESSING_II };
+static void ComplexRes_postprocessing_ai(ComplexRes *self) { POST_PROCESSING_AI };
+static void ComplexRes_postprocessing_ia(ComplexRes *self) { POST_PROCESSING_IA };
+static void ComplexRes_postprocessing_aa(ComplexRes *self) { POST_PROCESSING_AA };
+static void ComplexRes_postprocessing_ireva(ComplexRes *self) { POST_PROCESSING_IREVA };
+static void ComplexRes_postprocessing_areva(ComplexRes *self) { POST_PROCESSING_AREVA };
+static void ComplexRes_postprocessing_revai(ComplexRes *self) { POST_PROCESSING_REVAI };
+static void ComplexRes_postprocessing_revaa(ComplexRes *self) { POST_PROCESSING_REVAA };
+static void ComplexRes_postprocessing_revareva(ComplexRes *self) { POST_PROCESSING_REVAREVA };
+
+static void
+ComplexRes_setProcMode(ComplexRes *self)
+{
+    int procmode, muladdmode;
+    procmode = self->modebuffer[2] + self->modebuffer[3] * 10;
+    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
+
+	switch (procmode) {
+        case 0:    
+            self->proc_func_ptr = ComplexRes_filters_ii;
+            break;
+        case 1:    
+            self->proc_func_ptr = ComplexRes_filters_ai;
+            break;
+        case 10:        
+            self->proc_func_ptr = ComplexRes_filters_ia;
+            break;
+        case 11:    
+            self->proc_func_ptr = ComplexRes_filters_aa;
+            break;
+    } 
+	switch (muladdmode) {
+        case 0:        
+            self->muladd_func_ptr = ComplexRes_postprocessing_ii;
+            break;
+        case 1:    
+            self->muladd_func_ptr = ComplexRes_postprocessing_ai;
+            break;
+        case 2:    
+            self->muladd_func_ptr = ComplexRes_postprocessing_revai;
+            break;
+        case 10:        
+            self->muladd_func_ptr = ComplexRes_postprocessing_ia;
+            break;
+        case 11:    
+            self->muladd_func_ptr = ComplexRes_postprocessing_aa;
+            break;
+        case 12:    
+            self->muladd_func_ptr = ComplexRes_postprocessing_revaa;
+            break;
+        case 20:        
+            self->muladd_func_ptr = ComplexRes_postprocessing_ireva;
+            break;
+        case 21:    
+            self->muladd_func_ptr = ComplexRes_postprocessing_areva;
+            break;
+        case 22:    
+            self->muladd_func_ptr = ComplexRes_postprocessing_revareva;
+            break;
+    }   
+}
+
+static void
+ComplexRes_compute_next_data_frame(ComplexRes *self)
+{
+    (*self->proc_func_ptr)(self); 
+    (*self->muladd_func_ptr)(self);
+}
+
+static int
+ComplexRes_traverse(ComplexRes *self, visitproc visit, void *arg)
+{
+    pyo_VISIT
+    Py_VISIT(self->input);
+    Py_VISIT(self->input_stream);
+    Py_VISIT(self->freq);    
+    Py_VISIT(self->freq_stream);    
+    Py_VISIT(self->decay);    
+    Py_VISIT(self->decay_stream);    
+    return 0;
+}
+
+static int 
+ComplexRes_clear(ComplexRes *self)
+{
+    pyo_CLEAR
+    Py_CLEAR(self->input);
+    Py_CLEAR(self->input_stream);
+    Py_CLEAR(self->freq);    
+    Py_CLEAR(self->freq_stream);    
+    Py_CLEAR(self->decay);    
+    Py_CLEAR(self->decay_stream);    
+    return 0;
+}
+
+static void
+ComplexRes_dealloc(ComplexRes* self)
+{
+    pyo_DEALLOC
+    ComplexRes_clear(self);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+ComplexRes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    int i;
+    PyObject *inputtmp, *input_streamtmp, *freqtmp=NULL, *decaytmp=NULL, *multmp=NULL, *addtmp=NULL;
+    ComplexRes *self;
+    self = (ComplexRes *)type->tp_alloc(type, 0);
+    
+    self->freq = PyFloat_FromDouble(1000);
+    self->decay = PyFloat_FromDouble(.25);
+    self->last_freq = self->last_decay = -1.0;
+    self->x = self->y = 0.0;
+    self->res = 1.0;
+    self->norm = 0.01; /* normalization factor fixed at -40 dB */
+    self->coeffx = self->coeffy = 0.0;
+	self->modebuffer[0] = 0;
+	self->modebuffer[1] = 0;
+	self->modebuffer[2] = 0;
+	self->modebuffer[3] = 0;
+    
+    INIT_OBJECT_COMMON
+    
+    self->oneOnSr = 1.0 / self->sr;
+
+    Stream_setFunctionPtr(self->stream, ComplexRes_compute_next_data_frame);
+    self->mode_func_ptr = ComplexRes_setProcMode;
+
+    static char *kwlist[] = {"input", "freq", "decay", "mul", "add", NULL};
+    
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|OOOO", kwlist, &inputtmp, &freqtmp, &decaytmp, &multmp, &addtmp))
+        Py_RETURN_NONE;
+    
+    INIT_INPUT_STREAM
+    
+    if (freqtmp) {
+        PyObject_CallMethod((PyObject *)self, "setFreq", "O", freqtmp);
+    }
+    
+    if (decaytmp) {
+        PyObject_CallMethod((PyObject *)self, "setDecay", "O", decaytmp);
+    }
+    
+    if (multmp) {
+        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
+    }
+    
+    if (addtmp) {
+        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
+    }
+    
+    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
+    
+    (*self->mode_func_ptr)(self);
+
+    return (PyObject *)self;
+}
+
+static PyObject * ComplexRes_getServer(ComplexRes* self) { GET_SERVER };
+static PyObject * ComplexRes_getStream(ComplexRes* self) { GET_STREAM };
+static PyObject * ComplexRes_setMul(ComplexRes *self, PyObject *arg) { SET_MUL };	
+static PyObject * ComplexRes_setAdd(ComplexRes *self, PyObject *arg) { SET_ADD };	
+static PyObject * ComplexRes_setSub(ComplexRes *self, PyObject *arg) { SET_SUB };	
+static PyObject * ComplexRes_setDiv(ComplexRes *self, PyObject *arg) { SET_DIV };	
+
+static PyObject * ComplexRes_play(ComplexRes *self, PyObject *args, PyObject *kwds) { PLAY };
+static PyObject * ComplexRes_out(ComplexRes *self, PyObject *args, PyObject *kwds) { OUT };
+static PyObject * ComplexRes_stop(ComplexRes *self) { STOP };
+
+static PyObject * ComplexRes_multiply(ComplexRes *self, PyObject *arg) { MULTIPLY };
+static PyObject * ComplexRes_inplace_multiply(ComplexRes *self, PyObject *arg) { INPLACE_MULTIPLY };
+static PyObject * ComplexRes_add(ComplexRes *self, PyObject *arg) { ADD };
+static PyObject * ComplexRes_inplace_add(ComplexRes *self, PyObject *arg) { INPLACE_ADD };
+static PyObject * ComplexRes_sub(ComplexRes *self, PyObject *arg) { SUB };
+static PyObject * ComplexRes_inplace_sub(ComplexRes *self, PyObject *arg) { INPLACE_SUB };
+static PyObject * ComplexRes_div(ComplexRes *self, PyObject *arg) { DIV };
+static PyObject * ComplexRes_inplace_div(ComplexRes *self, PyObject *arg) { INPLACE_DIV };
+
+static PyObject *
+ComplexRes_setFreq(ComplexRes *self, PyObject *arg)
+{
+	PyObject *tmp, *streamtmp;
+	
+	if (arg == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+	int isNumber = PyNumber_Check(arg);
+	
+	tmp = arg;
+	Py_INCREF(tmp);
+	Py_DECREF(self->freq);
+	if (isNumber == 1) {
+		self->freq = PyNumber_Float(tmp);
+        self->modebuffer[2] = 0;
+	}
+	else {
+		self->freq = tmp;
+        streamtmp = PyObject_CallMethod((PyObject *)self->freq, "_getStream", NULL);
+        Py_INCREF(streamtmp);
+        Py_XDECREF(self->freq_stream);
+        self->freq_stream = (Stream *)streamtmp;
+		self->modebuffer[2] = 1;
+	}
+    
+    (*self->mode_func_ptr)(self);
+    
+	Py_INCREF(Py_None);
+	return Py_None;
+}	
+
+static PyObject *
+ComplexRes_setDecay(ComplexRes *self, PyObject *arg)
+{
+	PyObject *tmp, *streamtmp;
+	
+	if (arg == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+	int isNumber = PyNumber_Check(arg);
+	
+	tmp = arg;
+	Py_INCREF(tmp);
+	Py_DECREF(self->decay);
+	if (isNumber == 1) {
+		self->decay = PyNumber_Float(tmp);
+        self->modebuffer[3] = 0;
+	}
+	else {
+		self->decay = tmp;
+        streamtmp = PyObject_CallMethod((PyObject *)self->decay, "_getStream", NULL);
+        Py_INCREF(streamtmp);
+        Py_XDECREF(self->decay_stream);
+        self->decay_stream = (Stream *)streamtmp;
+		self->modebuffer[3] = 1;
+	}
+    
+    (*self->mode_func_ptr)(self);
+    
+	Py_INCREF(Py_None);
+	return Py_None;
+}	
+
+static PyMemberDef ComplexRes_members[] = {
+{"server", T_OBJECT_EX, offsetof(ComplexRes, server), 0, "Pyo server."},
+{"stream", T_OBJECT_EX, offsetof(ComplexRes, stream), 0, "Stream object."},
+{"input", T_OBJECT_EX, offsetof(ComplexRes, input), 0, "Input sound object."},
+{"freq", T_OBJECT_EX, offsetof(ComplexRes, freq), 0, "Center frequency in cycle per second."},
+{"decay", T_OBJECT_EX, offsetof(ComplexRes, decay), 0, "Decaying envelope time in seconds."},
+{"mul", T_OBJECT_EX, offsetof(ComplexRes, mul), 0, "Mul factor."},
+{"add", T_OBJECT_EX, offsetof(ComplexRes, add), 0, "Add factor."},
+{NULL}  /* Sentinel */
+};
+
+static PyMethodDef ComplexRes_methods[] = {
+{"getServer", (PyCFunction)ComplexRes_getServer, METH_NOARGS, "Returns server object."},
+{"_getStream", (PyCFunction)ComplexRes_getStream, METH_NOARGS, "Returns stream object."},
+{"play", (PyCFunction)ComplexRes_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
+{"out", (PyCFunction)ComplexRes_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
+{"stop", (PyCFunction)ComplexRes_stop, METH_NOARGS, "Stops computing."},
+{"setFreq", (PyCFunction)ComplexRes_setFreq, METH_O, "Sets filter center frequency in cycle per second."},
+{"setDecay", (PyCFunction)ComplexRes_setDecay, METH_O, "Sets filter decaying envelope time."},
+{"setMul", (PyCFunction)ComplexRes_setMul, METH_O, "Sets oscillator mul factor."},
+{"setAdd", (PyCFunction)ComplexRes_setAdd, METH_O, "Sets oscillator add factor."},
+{"setSub", (PyCFunction)ComplexRes_setSub, METH_O, "Sets inverse add factor."},
+{"setDiv", (PyCFunction)ComplexRes_setDiv, METH_O, "Sets inverse mul factor."},
+{NULL}  /* Sentinel */
+};
+
+static PyNumberMethods ComplexRes_as_number = {
+(binaryfunc)ComplexRes_add,                         /*nb_add*/
+(binaryfunc)ComplexRes_sub,                         /*nb_subtract*/
+(binaryfunc)ComplexRes_multiply,                    /*nb_multiply*/
+(binaryfunc)ComplexRes_div,                                              /*nb_divide*/
+0,                                              /*nb_remainder*/
+0,                                              /*nb_divmod*/
+0,                                              /*nb_power*/
+0,                                              /*nb_neg*/
+0,                                              /*nb_pos*/
+0,                                              /*(unaryfunc)array_abs,*/
+0,                                              /*nb_nonzero*/
+0,                                              /*nb_invert*/
+0,                                              /*nb_lshift*/
+0,                                              /*nb_rshift*/
+0,                                              /*nb_and*/
+0,                                              /*nb_xor*/
+0,                                              /*nb_or*/
+0,                                              /*nb_coerce*/
+0,                                              /*nb_int*/
+0,                                              /*nb_long*/
+0,                                              /*nb_float*/
+0,                                              /*nb_oct*/
+0,                                              /*nb_hex*/
+(binaryfunc)ComplexRes_inplace_add,                 /*inplace_add*/
+(binaryfunc)ComplexRes_inplace_sub,                 /*inplace_subtract*/
+(binaryfunc)ComplexRes_inplace_multiply,            /*inplace_multiply*/
+(binaryfunc)ComplexRes_inplace_div,                                              /*inplace_divide*/
+0,                                              /*inplace_remainder*/
+0,                                              /*inplace_power*/
+0,                                              /*inplace_lshift*/
+0,                                              /*inplace_rshift*/
+0,                                              /*inplace_and*/
+0,                                              /*inplace_xor*/
+0,                                              /*inplace_or*/
+0,                                              /*nb_floor_divide*/
+0,                                              /*nb_true_divide*/
+0,                                              /*nb_inplace_floor_divide*/
+0,                                              /*nb_inplace_true_divide*/
+0,                                              /* nb_index */
+};
+
+PyTypeObject ComplexResType = {
+PyObject_HEAD_INIT(NULL)
+0,                                              /*ob_size*/
+"_pyo.ComplexRes_base",                                   /*tp_name*/
+sizeof(ComplexRes),                                 /*tp_basicsize*/
+0,                                              /*tp_itemsize*/
+(destructor)ComplexRes_dealloc,                     /*tp_dealloc*/
+0,                                              /*tp_print*/
+0,                                              /*tp_getattr*/
+0,                                              /*tp_setattr*/
+0,                                              /*tp_compare*/
+0,                                              /*tp_repr*/
+&ComplexRes_as_number,                              /*tp_as_number*/
+0,                                              /*tp_as_sequence*/
+0,                                              /*tp_as_mapping*/
+0,                                              /*tp_hash */
+0,                                              /*tp_call*/
+0,                                              /*tp_str*/
+0,                                              /*tp_getattro*/
+0,                                              /*tp_setattro*/
+0,                                              /*tp_as_buffer*/
+Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
+"ComplexRes objects. Second order allpass filter.",           /* tp_doc */
+(traverseproc)ComplexRes_traverse,                  /* tp_traverse */
+(inquiry)ComplexRes_clear,                          /* tp_clear */
+0,                                              /* tp_richcompare */
+0,                                              /* tp_weaklistoffset */
+0,                                              /* tp_iter */
+0,                                              /* tp_iternext */
+ComplexRes_methods,                                 /* tp_methods */
+ComplexRes_members,                                 /* tp_members */
+0,                                              /* tp_getset */
+0,                                              /* tp_base */
+0,                                              /* tp_dict */
+0,                                              /* tp_descr_get */
+0,                                              /* tp_descr_set */
+0,                                              /* tp_dictoffset */
+0,                          /* tp_init */
+0,                                              /* tp_alloc */
+ComplexRes_new,                                     /* tp_new */
+};
diff --git a/src/objects/freeverbmodule.c b/src/objects/freeverbmodule.c
index 8ba510b..9f98523 100644
--- a/src/objects/freeverbmodule.c
+++ b/src/objects/freeverbmodule.c
@@ -50,7 +50,7 @@ static const MYFLT allpass_delays[NUM_ALLPASS] = {
 
 static const MYFLT fixedGain   = 0.015;
 static const MYFLT scaleDamp   = 0.5;
-static const MYFLT scaleRoom   = 0.28;
+static const MYFLT scaleRoom   = 0.29;
 static const MYFLT offsetRoom  = 0.7;
 static const MYFLT allPassFeedBack = 0.5;
 
@@ -929,4 +929,3 @@ PyTypeObject FreeverbType = {
     0,                         /* tp_alloc */
     Freeverb_new,                 /* tp_new */
 };
-
diff --git a/src/objects/matrixmodule.c b/src/objects/matrixmodule.c
index dc1a8d6..9178518 100644
--- a/src/objects/matrixmodule.c
+++ b/src/objects/matrixmodule.c
@@ -595,6 +595,7 @@ MatrixRec_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     INIT_INPUT_STREAM
 
     Py_XDECREF(self->matrix);
+    Py_INCREF(matrixtmp);
     self->matrix = (NewMatrix *)matrixtmp;
     
     PyObject_CallMethod(self->server, "addStream", "O", self->stream);
@@ -801,6 +802,7 @@ MatrixRecLoop_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     INIT_INPUT_STREAM
 
     Py_XDECREF(self->matrix);
+    Py_INCREF(matrixtmp);
     self->matrix = (NewMatrix *)matrixtmp;
     
     PyObject_CallMethod(self->server, "addStream", "O", self->stream);
@@ -1013,6 +1015,7 @@ MatrixMorph_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     INIT_INPUT_STREAM
 
     Py_XDECREF(self->matrix);
+    Py_INCREF(matrixtmp);
     self->matrix = (PyObject *)matrixtmp;
 
     width = NewMatrix_getWidth((NewMatrix *)self->matrix);
@@ -1021,6 +1024,7 @@ MatrixMorph_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     self->buffer = (MYFLT *)realloc(self->buffer, (numsamps) * sizeof(MYFLT));
 
     Py_XDECREF(self->sources);
+    Py_INCREF(sourcestmp);
     self->sources = (PyObject *)sourcestmp;
     
     PyObject_CallMethod(self->server, "addStream", "O", self->stream);
diff --git a/src/objects/oscilmodule.c b/src/objects/oscilmodule.c
index 5c7f1e0..ca15b18 100644
--- a/src/objects/oscilmodule.c
+++ b/src/objects/oscilmodule.c
@@ -3084,13 +3084,12 @@ Pointer_readframes_a(Pointer *self) {
     int size = TableStream_getSize(self->table);
     
     MYFLT *pha = Stream_getData((Stream *)self->index_stream);
-    
+
     for (i=0; i<self->bufsize; i++) {
-        ph = Osc_clip(pha[i] * size, size);
-   
+        ph = Osc_clip(pha[i] * size, size);       
         ipart = (int)ph;
         fpart = ph - ipart;
-        self->data[i] = tablelist[ipart] * (1.0 - fpart) + tablelist[ipart+1] * fpart;
+        self->data[i] = tablelist[ipart] + (tablelist[ipart+1] - tablelist[ipart]) * fpart;
     }
 }
 
@@ -3221,7 +3220,7 @@ Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     PyObject_CallMethod(self->server, "addStream", "O", self->stream);
     
     (*self->mode_func_ptr)(self);
-    
+  
     return (PyObject *)self;
 }
 
@@ -3414,6 +3413,428 @@ Pointer_new,                 /* tp_new */
 };
 
 /**************/
+/* Pointer2 object */
+/**************/
+typedef struct {
+    pyo_audio_HEAD
+    PyObject *table;
+    PyObject *index;
+    Stream *index_stream;
+    int modebuffer[2];
+    int interp; /* 0 = default to 2, 1 = nointerp, 2 = linear, 3 = cos, 4 = cubic */
+    int autosmooth; /* 0 = off, > 0 = on */
+    MYFLT y1;
+    MYFLT y2;
+    MYFLT c;
+    MYFLT lastPh;
+    MYFLT (*interp_func_ptr)(MYFLT *, int, MYFLT, int);
+} Pointer2;
+
+static void
+Pointer2_readframes_a(Pointer2 *self) {
+    MYFLT fpart, phdiff, b, fr;
+    double ph;
+    int i, ipart;
+    MYFLT *tablelist = TableStream_getData(self->table);
+    int size = TableStream_getSize(self->table);
+    double tableSr = TableStream_getSamplingRate(self->table);
+    
+    MYFLT *pha = Stream_getData((Stream *)self->index_stream);
+
+    if (!self->autosmooth) {
+        for (i=0; i<self->bufsize; i++) {
+            ph = Osc_clip(pha[i] * size, size);       
+            ipart = (int)ph;
+            fpart = ph - ipart;
+            self->y1 = self->y2 = self->data[i] = (*self->interp_func_ptr)(tablelist, ipart, fpart, size);
+        }
+    }
+    else {
+        for (i=0; i<self->bufsize; i++) {
+            ph = Osc_clip(pha[i] * size, size);
+            ipart = (int)ph;
+            fpart = ph - ipart;
+            self->data[i] = (*self->interp_func_ptr)(tablelist, ipart, fpart, size);
+            phdiff = MYFABS(ph - self->lastPh);
+            self->lastPh = ph;
+            if (phdiff < 1) {
+                fr = phdiff * tableSr * 0.45;
+                b = 2.0 - MYCOS(TWOPI * fr / self->sr);
+                self->c = (b - MYSQRT(b * b - 1.0));
+                self->y1 = self->data[i] + (self->y1 - self->data[i]) * self->c;
+                self->data[i] = self->y2 = self->y1 + (self->y2 - self->y1) * self->c;
+            }
+            else
+                self->y1 = self->y2 = self->data[i];
+        }
+    }
+}
+
+static void Pointer2_postprocessing_ii(Pointer2 *self) { POST_PROCESSING_II };
+static void Pointer2_postprocessing_ai(Pointer2 *self) { POST_PROCESSING_AI };
+static void Pointer2_postprocessing_ia(Pointer2 *self) { POST_PROCESSING_IA };
+static void Pointer2_postprocessing_aa(Pointer2 *self) { POST_PROCESSING_AA };
+static void Pointer2_postprocessing_ireva(Pointer2 *self) { POST_PROCESSING_IREVA };
+static void Pointer2_postprocessing_areva(Pointer2 *self) { POST_PROCESSING_AREVA };
+static void Pointer2_postprocessing_revai(Pointer2 *self) { POST_PROCESSING_REVAI };
+static void Pointer2_postprocessing_revaa(Pointer2 *self) { POST_PROCESSING_REVAA };
+static void Pointer2_postprocessing_revareva(Pointer2 *self) { POST_PROCESSING_REVAREVA };
+
+static void
+Pointer2_setProcMode(Pointer2 *self)
+{
+    int muladdmode;
+    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
+
+    self->proc_func_ptr = Pointer2_readframes_a;
+
+	switch (muladdmode) {
+        case 0:        
+            self->muladd_func_ptr = Pointer2_postprocessing_ii;
+            break;
+        case 1:    
+            self->muladd_func_ptr = Pointer2_postprocessing_ai;
+            break;
+        case 2:    
+            self->muladd_func_ptr = Pointer2_postprocessing_revai;
+            break;
+        case 10:        
+            self->muladd_func_ptr = Pointer2_postprocessing_ia;
+            break;
+        case 11:    
+            self->muladd_func_ptr = Pointer2_postprocessing_aa;
+            break;
+        case 12:    
+            self->muladd_func_ptr = Pointer2_postprocessing_revaa;
+            break;
+        case 20:        
+            self->muladd_func_ptr = Pointer2_postprocessing_ireva;
+            break;
+        case 21:    
+            self->muladd_func_ptr = Pointer2_postprocessing_areva;
+            break;
+        case 22:    
+            self->muladd_func_ptr = Pointer2_postprocessing_revareva;
+            break;
+    } 
+}
+
+static void
+Pointer2_compute_next_data_frame(Pointer2 *self)
+{
+    (*self->proc_func_ptr)(self); 
+    (*self->muladd_func_ptr)(self);
+}
+
+static int
+Pointer2_traverse(Pointer2 *self, visitproc visit, void *arg)
+{
+    pyo_VISIT
+    Py_VISIT(self->table);
+    Py_VISIT(self->index);    
+    Py_VISIT(self->index_stream);    
+    return 0;
+}
+
+static int 
+Pointer2_clear(Pointer2 *self)
+{
+    pyo_CLEAR
+    Py_CLEAR(self->table);
+    Py_CLEAR(self->index);    
+    Py_CLEAR(self->index_stream);    
+    return 0;
+}
+
+static void
+Pointer2_dealloc(Pointer2* self)
+{
+    pyo_DEALLOC
+    Pointer2_clear(self);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+Pointer2_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    int i;
+    PyObject *tabletmp, *indextmp, *multmp=NULL, *addtmp=NULL;
+    Pointer2 *self;
+    self = (Pointer2 *)type->tp_alloc(type, 0);
+    
+	self->modebuffer[0] = 0;
+	self->modebuffer[1] = 0;
+    self->interp = 4;
+    self->autosmooth = 1;
+    self->y1 = self->y2 = self->c = self->lastPh = 0.0;
+    
+    INIT_OBJECT_COMMON
+    Stream_setFunctionPtr(self->stream, Pointer2_compute_next_data_frame);
+    self->mode_func_ptr = Pointer2_setProcMode;
+
+    static char *kwlist[] = {"table", "index", "interp", "autosmooth", "mul", "add", NULL};
+    
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|iiOO", kwlist, &tabletmp, &indextmp, &self->interp, &self->autosmooth, &multmp, &addtmp))
+        Py_RETURN_NONE;
+    
+    if ( PyObject_HasAttrString((PyObject *)tabletmp, "getTableStream") == 0 ) {
+        PySys_WriteStderr("TypeError: \"table\" argument of Pointer2 must be a PyoTableObject.\n");
+        if (PyInt_AsLong(PyObject_CallMethod(self->server, "getIsBooted", NULL))) {
+            PyObject_CallMethod(self->server, "shutdown", NULL);
+        }
+        Py_Exit(1);
+    }
+    Py_XDECREF(self->table);
+    self->table = PyObject_CallMethod((PyObject *)tabletmp, "getTableStream", "");
+    
+    if (indextmp) {
+        PyObject_CallMethod((PyObject *)self, "setIndex", "O", indextmp);
+    }
+
+    PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
+    
+    if (addtmp) {
+        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
+    }
+    
+    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
+    
+    (*self->mode_func_ptr)(self);
+  
+    SET_INTERP_POINTER
+  
+    return (PyObject *)self;
+}
+
+static PyObject * Pointer2_getServer(Pointer2* self) { GET_SERVER };
+static PyObject * Pointer2_getStream(Pointer2* self) { GET_STREAM };
+static PyObject * Pointer2_setMul(Pointer2 *self, PyObject *arg) { SET_MUL };	
+static PyObject * Pointer2_setAdd(Pointer2 *self, PyObject *arg) { SET_ADD };	
+static PyObject * Pointer2_setSub(Pointer2 *self, PyObject *arg) { SET_SUB };	
+static PyObject * Pointer2_setDiv(Pointer2 *self, PyObject *arg) { SET_DIV };	
+
+static PyObject * Pointer2_play(Pointer2 *self, PyObject *args, PyObject *kwds) { PLAY };
+static PyObject * Pointer2_out(Pointer2 *self, PyObject *args, PyObject *kwds) { OUT };
+static PyObject * Pointer2_stop(Pointer2 *self) { STOP };
+
+static PyObject * Pointer2_multiply(Pointer2 *self, PyObject *arg) { MULTIPLY };
+static PyObject * Pointer2_inplace_multiply(Pointer2 *self, PyObject *arg) { INPLACE_MULTIPLY };
+static PyObject * Pointer2_add(Pointer2 *self, PyObject *arg) { ADD };
+static PyObject * Pointer2_inplace_add(Pointer2 *self, PyObject *arg) { INPLACE_ADD };
+static PyObject * Pointer2_sub(Pointer2 *self, PyObject *arg) { SUB };
+static PyObject * Pointer2_inplace_sub(Pointer2 *self, PyObject *arg) { INPLACE_SUB };
+static PyObject * Pointer2_div(Pointer2 *self, PyObject *arg) { DIV };
+static PyObject * Pointer2_inplace_div(Pointer2 *self, PyObject *arg) { INPLACE_DIV };
+
+static PyObject *
+Pointer2_getTable(Pointer2* self)
+{
+    Py_INCREF(self->table);
+    return self->table;
+};
+
+static PyObject *
+Pointer2_setTable(Pointer2 *self, PyObject *arg)
+{
+	PyObject *tmp;
+	
+	if (arg == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+	tmp = arg;
+	Py_DECREF(self->table);
+    self->table = PyObject_CallMethod((PyObject *)tmp, "getTableStream", "");
+    
+	Py_INCREF(Py_None);
+	return Py_None;
+}	
+
+static PyObject *
+Pointer2_setIndex(Pointer2 *self, PyObject *arg)
+{
+	PyObject *tmp, *streamtmp;
+	
+	if (arg == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+	int isNumber = PyNumber_Check(arg);
+	if (isNumber == 1) {
+		PySys_WriteStderr("TypeError: \"index\" attribute of Pointer2 must be a PyoObject.\n");
+        if (PyInt_AsLong(PyObject_CallMethod(self->server, "getIsBooted", NULL))) {
+            PyObject_CallMethod(self->server, "shutdown", NULL);
+        }
+        Py_Exit(1);
+	}
+	
+	tmp = arg;
+	Py_INCREF(tmp);
+	Py_XDECREF(self->index);
+
+    self->index = tmp;
+    streamtmp = PyObject_CallMethod((PyObject *)self->index, "_getStream", NULL);
+    Py_INCREF(streamtmp);
+    Py_XDECREF(self->index_stream);
+    self->index_stream = (Stream *)streamtmp;
+    
+	Py_INCREF(Py_None);
+	return Py_None;
+}	
+
+static PyObject *
+Pointer2_setInterp(Pointer2 *self, PyObject *arg)
+{
+	if (arg == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+    int isNumber = PyNumber_Check(arg);
+    
+	if (isNumber == 1) {
+		self->interp = PyInt_AsLong(PyNumber_Int(arg));
+    }  
+    
+    SET_INTERP_POINTER
+    
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+Pointer2_setAutoSmooth(Pointer2 *self, PyObject *arg)
+{
+	if (arg == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+    int isNumber = PyNumber_Check(arg);
+    
+	if (isNumber == 1) {
+		self->autosmooth = PyInt_AsLong(PyNumber_Int(arg));
+    }  
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyMemberDef Pointer2_members[] = {
+{"server", T_OBJECT_EX, offsetof(Pointer2, server), 0, "Pyo server."},
+{"stream", T_OBJECT_EX, offsetof(Pointer2, stream), 0, "Stream object."},
+{"table", T_OBJECT_EX, offsetof(Pointer2, table), 0, "Waveform table."},
+{"index", T_OBJECT_EX, offsetof(Pointer2, index), 0, "Reader index."},
+{"mul", T_OBJECT_EX, offsetof(Pointer2, mul), 0, "Mul factor."},
+{"add", T_OBJECT_EX, offsetof(Pointer2, add), 0, "Add factor."},
+{NULL}  /* Sentinel */
+};
+
+static PyMethodDef Pointer2_methods[] = {
+{"getTable", (PyCFunction)Pointer2_getTable, METH_NOARGS, "Returns waveform table object."},
+{"getServer", (PyCFunction)Pointer2_getServer, METH_NOARGS, "Returns server object."},
+{"_getStream", (PyCFunction)Pointer2_getStream, METH_NOARGS, "Returns stream object."},
+{"play", (PyCFunction)Pointer2_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
+{"out", (PyCFunction)Pointer2_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
+{"stop", (PyCFunction)Pointer2_stop, METH_NOARGS, "Stops computing."},
+{"setTable", (PyCFunction)Pointer2_setTable, METH_O, "Sets oscillator table."},
+{"setIndex", (PyCFunction)Pointer2_setIndex, METH_O, "Sets reader index."},
+{"setInterp", (PyCFunction)Pointer2_setInterp, METH_O, "Sets oscillator interpolation mode."},
+{"setAutoSmooth", (PyCFunction)Pointer2_setAutoSmooth, METH_O, "Activates auto smoother filter."},
+{"setMul", (PyCFunction)Pointer2_setMul, METH_O, "Sets oscillator mul factor."},
+{"setAdd", (PyCFunction)Pointer2_setAdd, METH_O, "Sets oscillator add factor."},
+{"setSub", (PyCFunction)Pointer2_setSub, METH_O, "Sets oscillator inverse add factor."},
+{"setDiv", (PyCFunction)Pointer2_setDiv, METH_O, "Sets inverse mul factor."},
+{NULL}  /* Sentinel */
+};
+
+static PyNumberMethods Pointer2_as_number = {
+(binaryfunc)Pointer2_add,                      /*nb_add*/
+(binaryfunc)Pointer2_sub,                 /*nb_subtract*/
+(binaryfunc)Pointer2_multiply,                 /*nb_multiply*/
+(binaryfunc)Pointer2_div,                   /*nb_divide*/
+0,                /*nb_remainder*/
+0,                   /*nb_divmod*/
+0,                   /*nb_power*/
+0,                  /*nb_neg*/
+0,                /*nb_pos*/
+0,                  /*(unaryfunc)array_abs,*/
+0,                    /*nb_nonzero*/
+0,                    /*nb_invert*/
+0,               /*nb_lshift*/
+0,              /*nb_rshift*/
+0,              /*nb_and*/
+0,              /*nb_xor*/
+0,               /*nb_or*/
+0,                                          /*nb_coerce*/
+0,                       /*nb_int*/
+0,                      /*nb_long*/
+0,                     /*nb_float*/
+0,                       /*nb_oct*/
+0,                       /*nb_hex*/
+(binaryfunc)Pointer2_inplace_add,              /*inplace_add*/
+(binaryfunc)Pointer2_inplace_sub,         /*inplace_subtract*/
+(binaryfunc)Pointer2_inplace_multiply,         /*inplace_multiply*/
+(binaryfunc)Pointer2_inplace_div,           /*inplace_divide*/
+0,        /*inplace_remainder*/
+0,           /*inplace_power*/
+0,       /*inplace_lshift*/
+0,      /*inplace_rshift*/
+0,      /*inplace_and*/
+0,      /*inplace_xor*/
+0,       /*inplace_or*/
+0,             /*nb_floor_divide*/
+0,              /*nb_true_divide*/
+0,     /*nb_inplace_floor_divide*/
+0,      /*nb_inplace_true_divide*/
+0,                     /* nb_index */
+};
+
+PyTypeObject Pointer2Type = {
+PyObject_HEAD_INIT(NULL)
+0,                         /*ob_size*/
+"_pyo.Pointer2_base",         /*tp_name*/
+sizeof(Pointer2),         /*tp_basicsize*/
+0,                         /*tp_itemsize*/
+(destructor)Pointer2_dealloc, /*tp_dealloc*/
+0,                         /*tp_print*/
+0,                         /*tp_getattr*/
+0,                         /*tp_setattr*/
+0,                         /*tp_compare*/
+0,                         /*tp_repr*/
+&Pointer2_as_number,             /*tp_as_number*/
+0,                         /*tp_as_sequence*/
+0,                         /*tp_as_mapping*/
+0,                         /*tp_hash */
+0,                         /*tp_call*/
+0,                         /*tp_str*/
+0,                         /*tp_getattro*/
+0,                         /*tp_setattro*/
+0,                         /*tp_as_buffer*/
+Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
+"Pointer2 objects. High quality table reader with a pointer index.",           /* tp_doc */
+(traverseproc)Pointer2_traverse,   /* tp_traverse */
+(inquiry)Pointer2_clear,           /* tp_clear */
+0,		               /* tp_richcompare */
+0,		               /* tp_weaklistoffset */
+0,		               /* tp_iter */
+0,		               /* tp_iternext */
+Pointer2_methods,             /* tp_methods */
+Pointer2_members,             /* tp_members */
+0,                      /* tp_getset */
+0,                         /* tp_base */
+0,                         /* tp_dict */
+0,                         /* tp_descr_get */
+0,                         /* tp_descr_set */
+0,                         /* tp_dictoffset */
+0,      /* tp_init */
+0,                         /* tp_alloc */
+Pointer2_new,                 /* tp_new */
+};
+
+/**************/
 /* TableIndex object */
 /**************/
 typedef struct {
diff --git a/src/objects/oscmodule.c b/src/objects/oscmodule.c
index a8e8f05..51fb4ef 100644
--- a/src/objects/oscmodule.c
+++ b/src/objects/oscmodule.c
@@ -1054,6 +1054,8 @@ OscDataReceive_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
 static PyObject * OscDataReceive_getServer(OscDataReceive* self) { GET_SERVER };
 static PyObject * OscDataReceive_getStream(OscDataReceive* self) { GET_STREAM };
+static PyObject * OscDataReceive_play(OscDataReceive *self, PyObject *args, PyObject *kwds) { PLAY };
+static PyObject * OscDataReceive_stop(OscDataReceive *self) { STOP };
 
 static PyObject *
 OscDataReceive_addAddress(OscDataReceive *self, PyObject *arg) {
@@ -1094,6 +1096,8 @@ static PyMemberDef OscDataReceive_members[] = {
 static PyMethodDef OscDataReceive_methods[] = {
     {"getServer", (PyCFunction)OscDataReceive_getServer, METH_NOARGS, "Returns server object."},
     {"_getStream", (PyCFunction)OscDataReceive_getStream, METH_NOARGS, "Returns stream object."},
+    {"play", (PyCFunction)OscDataReceive_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
+    {"stop", (PyCFunction)OscDataReceive_stop, METH_NOARGS, "Stops computing."},
     {"addAddress", (PyCFunction)OscDataReceive_addAddress, METH_O, "Add new paths to the object."},
     {"delAddress", (PyCFunction)OscDataReceive_delAddress, METH_O, "Remove path from the object."},
     {NULL}  /* Sentinel */
diff --git a/src/objects/sigmodule.c b/src/objects/sigmodule.c
index 93e295e..7cd4cf0 100644
--- a/src/objects/sigmodule.c
+++ b/src/objects/sigmodule.c
@@ -333,9 +333,9 @@ typedef struct {
     pyo_audio_HEAD
     PyObject *value;
     Stream *value_stream;
-    MYFLT time;
     MYFLT lastValue;
     MYFLT currentValue;
+    MYFLT time;
     long timeStep;
     MYFLT stepVal;
     long timeCount;
@@ -346,20 +346,19 @@ static void
 SigTo_generates_i(SigTo *self) {
     int i;
     MYFLT value;
-    
     if (self->modebuffer[2] == 0) {
         value = PyFloat_AS_DOUBLE(self->value);
+        if (value != self->lastValue) {
+            self->timeCount = 0;
+            self->timeStep = (long)(self->time * self->sr);
+            self->stepVal = (value - self->currentValue) / self->timeStep;
+            self->lastValue = value;
+        }
         if (self->timeStep <= 0) {
             for (i=0; i<self->bufsize; i++)
                 self->data[i] = self->currentValue = self->lastValue = value;
         }
-        else {
-            if (value != self->lastValue) {
-                self->timeCount = 0;
-                self->stepVal = (value - self->currentValue) / self->timeStep;
-                self->lastValue = value;
-            }    
-        
+        else {        
             for (i=0; i<self->bufsize; i++) {
                 if (self->timeCount == (self->timeStep - 1)) {
                     self->currentValue = value;
@@ -386,6 +385,7 @@ SigTo_generates_i(SigTo *self) {
                 value = vals[i];
                 if (value != self->lastValue) {
                     self->timeCount = 0;
+                    self->timeStep = (long)(self->time * self->sr);
                     self->stepVal = (value - self->currentValue) / self->timeStep;
                     self->lastValue = value;
                 }    
@@ -497,7 +497,6 @@ SigTo_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
     self->value = PyFloat_FromDouble(0.0);
     self->time = 0.025;
-    self->timeStep = (long)(self->time * self->sr);
     self->timeCount = 0;
     self->stepVal = 0.0;
 	self->modebuffer[0] = 0;
@@ -532,6 +531,7 @@ SigTo_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     PyObject_CallMethod(self->server, "addStream", "O", self->stream);
     
     self->lastValue = self->currentValue = inittmp;
+    self->timeStep = (long)(self->time * self->sr);
     
     (*self->mode_func_ptr)(self);
 
@@ -590,7 +590,6 @@ SigTo_setTime(SigTo *self, PyObject *arg)
 	Py_INCREF(tmp);
 	if (isNumber == 1) {
 		self->time = PyFloat_AS_DOUBLE(PyNumber_Float(tmp));
-        self->timeStep = (long)(self->time * self->sr);
 	}
     
 	Py_INCREF(Py_None);
@@ -992,6 +991,26 @@ VarPort_setTime(VarPort *self, PyObject *arg)
 	return Py_None;
 }	
 
+static PyObject *
+VarPort_setFunction(VarPort *self, PyObject *arg)
+{
+	PyObject *tmp;
+	
+	if (! PyCallable_Check(arg)) {
+        PyErr_SetString(PyExc_TypeError, "The function attribute must be callable.");
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+    tmp = arg;
+    Py_XDECREF(self->callable);
+    Py_INCREF(tmp);
+    self->callable = tmp;
+  
+	Py_INCREF(Py_None);
+	return Py_None;
+}	
+
 static PyObject * VarPort_getServer(VarPort* self) { GET_SERVER };
 static PyObject * VarPort_getStream(VarPort* self) { GET_STREAM };
 static PyObject * VarPort_setMul(VarPort *self, PyObject *arg) { SET_MUL };	
@@ -1026,6 +1045,7 @@ static PyMethodDef VarPort_methods[] = {
     {"stop", (PyCFunction)VarPort_stop, METH_NOARGS, "Stops computing."},
     {"setValue", (PyCFunction)VarPort_setValue, METH_O, "Sets VarPort value."},
     {"setTime", (PyCFunction)VarPort_setTime, METH_O, "Sets ramp time in seconds."},
+    {"setFunction", (PyCFunction)VarPort_setFunction, METH_O, "Sets function to be called."},
     {"setMul", (PyCFunction)VarPort_setMul, METH_O, "Sets VarPort mul factor."},
     {"setAdd", (PyCFunction)VarPort_setAdd, METH_O, "Sets VarPort add factor."},
     {"setSub", (PyCFunction)VarPort_setSub, METH_O, "Sets inverse add factor."},
diff --git a/src/objects/tablemodule.c b/src/objects/tablemodule.c
index 0be9ea5..285deb9 100644
--- a/src/objects/tablemodule.c
+++ b/src/objects/tablemodule.c
@@ -231,6 +231,13 @@ static PyObject * HarmTable_reset(HarmTable *self) { TABLE_RESET };
 static PyObject * HarmTable_normalize(HarmTable *self) { NORMALIZE };
 static PyObject * HarmTable_removeDC(HarmTable *self) { REMOVE_DC };
 static PyObject * HarmTable_reverse(HarmTable *self) { REVERSE };
+static PyObject * HarmTable_invert(HarmTable *self) { INVERT };
+static PyObject * HarmTable_rectify(HarmTable *self) { RECTIFY };
+static PyObject * HarmTable_bipolarGain(HarmTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * HarmTable_lowpass(HarmTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * HarmTable_fadein(HarmTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * HarmTable_fadeout(HarmTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * HarmTable_pow(HarmTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * HarmTable_copy(HarmTable *self, PyObject *arg) { COPY };
 static PyObject * HarmTable_setTable(HarmTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * HarmTable_getTable(HarmTable *self) { GET_TABLE };
@@ -307,7 +314,14 @@ static PyMethodDef HarmTable_methods[] = {
 {"normalize", (PyCFunction)HarmTable_normalize, METH_NOARGS, "Normalize table samples between -1 and 1"},
 {"reset", (PyCFunction)HarmTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
 {"removeDC", (PyCFunction)HarmTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
-{"reverse", (PyCFunction)HarmTable_reverse, METH_NOARGS, "Reverse the table's data."},
+{"reverse", (PyCFunction)HarmTable_reverse, METH_NOARGS, "Reverse the table's data in time."},
+{"invert", (PyCFunction)HarmTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+{"rectify", (PyCFunction)HarmTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+{"bipolarGain", (PyCFunction)HarmTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+{"lowpass", (PyCFunction)HarmTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+{"fadein", (PyCFunction)HarmTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+{"fadeout", (PyCFunction)HarmTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+{"pow", (PyCFunction)HarmTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
 {"copy", (PyCFunction)HarmTable_copy, METH_O, "Copy data from table given in argument."},
 {"setData", (PyCFunction)HarmTable_setData, METH_O, "Sets the table from samples in a text file."},
 {"setSize", (PyCFunction)HarmTable_setSize, METH_O, "Sets the size of the table in samples"},
@@ -505,6 +519,13 @@ static PyObject * ChebyTable_normalize(ChebyTable *self) { NORMALIZE };
 static PyObject * ChebyTable_reset(ChebyTable *self) { TABLE_RESET };
 static PyObject * ChebyTable_removeDC(ChebyTable *self) { REMOVE_DC };
 static PyObject * ChebyTable_reverse(ChebyTable *self) { REVERSE };
+static PyObject * ChebyTable_invert(ChebyTable *self) { INVERT };
+static PyObject * ChebyTable_rectify(ChebyTable *self) { RECTIFY };
+static PyObject * ChebyTable_bipolarGain(ChebyTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * ChebyTable_lowpass(ChebyTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * ChebyTable_fadein(ChebyTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * ChebyTable_fadeout(ChebyTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * ChebyTable_pow(ChebyTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * ChebyTable_copy(ChebyTable *self, PyObject *arg) { COPY };
 static PyObject * ChebyTable_setTable(ChebyTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * ChebyTable_getTable(ChebyTable *self) { GET_TABLE };
@@ -657,6 +678,13 @@ static PyMethodDef ChebyTable_methods[] = {
 {"reset", (PyCFunction)ChebyTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
 {"removeDC", (PyCFunction)ChebyTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
 {"reverse", (PyCFunction)ChebyTable_reverse, METH_NOARGS, "Reverse the table's data."},
+{"invert", (PyCFunction)ChebyTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+{"rectify", (PyCFunction)ChebyTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+{"bipolarGain", (PyCFunction)ChebyTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+{"lowpass", (PyCFunction)ChebyTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+{"fadein", (PyCFunction)ChebyTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+{"fadeout", (PyCFunction)ChebyTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+{"pow", (PyCFunction)ChebyTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
 {"setSize", (PyCFunction)ChebyTable_setSize, METH_O, "Sets the size of the table in samples"},
 {"getSize", (PyCFunction)ChebyTable_getSize, METH_NOARGS, "Return the size of the table in samples"},
 {"put", (PyCFunction)ChebyTable_put, METH_VARARGS|METH_KEYWORDS, "Puts a value at specified position in the table."},
@@ -787,6 +815,13 @@ static PyObject * HannTable_normalize(HannTable *self) { NORMALIZE };
 static PyObject * HannTable_reset(HannTable *self) { TABLE_RESET };
 static PyObject * HannTable_removeDC(HannTable *self) { REMOVE_DC };
 static PyObject * HannTable_reverse(HannTable *self) { REVERSE };
+static PyObject * HannTable_invert(HannTable *self) { INVERT };
+static PyObject * HannTable_rectify(HannTable *self) { RECTIFY };
+static PyObject * HannTable_bipolarGain(HannTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * HannTable_lowpass(HannTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * HannTable_fadein(HannTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * HannTable_fadeout(HannTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * HannTable_pow(HannTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * HannTable_copy(HannTable *self, PyObject *arg) { COPY };
 static PyObject * HannTable_setTable(HannTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * HannTable_getTable(HannTable *self) { GET_TABLE };
@@ -842,6 +877,13 @@ static PyMethodDef HannTable_methods[] = {
 {"reset", (PyCFunction)HannTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
 {"removeDC", (PyCFunction)HannTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
 {"reverse", (PyCFunction)HannTable_reverse, METH_NOARGS, "Reverse the table's data."},
+{"invert", (PyCFunction)HannTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+{"rectify", (PyCFunction)HannTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+{"bipolarGain", (PyCFunction)HannTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+{"lowpass", (PyCFunction)HannTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+{"fadein", (PyCFunction)HannTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+{"fadeout", (PyCFunction)HannTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+{"pow", (PyCFunction)HannTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
 {"setSize", (PyCFunction)HannTable_setSize, METH_O, "Sets the size of the table in samples"},
 {"getSize", (PyCFunction)HannTable_getSize, METH_NOARGS, "Return the size of the table in samples"},
 {"put", (PyCFunction)HannTable_put, METH_VARARGS|METH_KEYWORDS, "Puts a value at specified position in the table."},
@@ -991,6 +1033,13 @@ static PyObject * SincTable_normalize(SincTable *self) { NORMALIZE };
 static PyObject * SincTable_reset(SincTable *self) { TABLE_RESET };
 static PyObject * SincTable_removeDC(SincTable *self) { REMOVE_DC };
 static PyObject * SincTable_reverse(SincTable *self) { REVERSE };
+static PyObject * SincTable_invert(SincTable *self) { INVERT };
+static PyObject * SincTable_rectify(SincTable *self) { RECTIFY };
+static PyObject * SincTable_bipolarGain(SincTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * SincTable_lowpass(SincTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * SincTable_fadein(SincTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * SincTable_fadeout(SincTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * SincTable_pow(SincTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * SincTable_copy(SincTable *self, PyObject *arg) { COPY };
 static PyObject * SincTable_setTable(SincTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * SincTable_getTable(SincTable *self) { GET_TABLE };
@@ -1080,6 +1129,13 @@ static PyMethodDef SincTable_methods[] = {
     {"reset", (PyCFunction)SincTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
     {"removeDC", (PyCFunction)SincTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
     {"reverse", (PyCFunction)SincTable_reverse, METH_NOARGS, "Reverse the table's data."},
+    {"invert", (PyCFunction)SincTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+    {"rectify", (PyCFunction)SincTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+    {"bipolarGain", (PyCFunction)SincTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+    {"lowpass", (PyCFunction)SincTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+    {"fadein", (PyCFunction)SincTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+    {"fadeout", (PyCFunction)SincTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+    {"pow", (PyCFunction)SincTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
     {"setSize", (PyCFunction)SincTable_setSize, METH_O, "Sets the size of the table in samples"},
     {"getSize", (PyCFunction)SincTable_getSize, METH_NOARGS, "Return the size of the table in samples"},
     {"setFreq", (PyCFunction)SincTable_setFreq, METH_O, "Sets the frequency, in radians, of the sinc function."},
@@ -1203,6 +1259,13 @@ static PyObject * WinTable_normalize(WinTable *self) { NORMALIZE };
 static PyObject * WinTable_reset(WinTable *self) { TABLE_RESET };
 static PyObject * WinTable_removeDC(WinTable *self) { REMOVE_DC };
 static PyObject * WinTable_reverse(WinTable *self) { REVERSE };
+static PyObject * WinTable_invert(WinTable *self) { INVERT };
+static PyObject * WinTable_rectify(WinTable *self) { RECTIFY };
+static PyObject * WinTable_bipolarGain(WinTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * WinTable_lowpass(WinTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * WinTable_fadein(WinTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * WinTable_fadeout(WinTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * WinTable_pow(WinTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * WinTable_copy(WinTable *self, PyObject *arg) { COPY };
 static PyObject * WinTable_setTable(WinTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * WinTable_getTable(WinTable *self) { GET_TABLE };
@@ -1279,6 +1342,13 @@ static PyMethodDef WinTable_methods[] = {
 {"reset", (PyCFunction)WinTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
 {"removeDC", (PyCFunction)WinTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
 {"reverse", (PyCFunction)WinTable_reverse, METH_NOARGS, "Reverse the table's data."},
+{"invert", (PyCFunction)WinTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+{"rectify", (PyCFunction)WinTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+{"bipolarGain", (PyCFunction)WinTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+{"lowpass", (PyCFunction)WinTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+{"fadein", (PyCFunction)WinTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+{"fadeout", (PyCFunction)WinTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+{"pow", (PyCFunction)WinTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
 {"setSize", (PyCFunction)WinTable_setSize, METH_O, "Sets the size of the table in samples"},
 {"getSize", (PyCFunction)WinTable_getSize, METH_NOARGS, "Return the size of the table in samples"},
 {"setType", (PyCFunction)WinTable_setType, METH_O, "Sets the type of the table."},
@@ -1415,6 +1485,13 @@ static PyObject * ParaTable_normalize(ParaTable *self) { NORMALIZE };
 static PyObject * ParaTable_reset(ParaTable *self) { TABLE_RESET };
 static PyObject * ParaTable_removeDC(ParaTable *self) { REMOVE_DC };
 static PyObject * ParaTable_reverse(ParaTable *self) { REVERSE };
+static PyObject * ParaTable_invert(ParaTable *self) { INVERT };
+static PyObject * ParaTable_rectify(ParaTable *self) { RECTIFY };
+static PyObject * ParaTable_bipolarGain(ParaTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * ParaTable_lowpass(ParaTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * ParaTable_fadein(ParaTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * ParaTable_fadeout(ParaTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * ParaTable_pow(ParaTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * ParaTable_copy(ParaTable *self, PyObject *arg) { COPY };
 static PyObject * ParaTable_setTable(ParaTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * ParaTable_getTable(ParaTable *self) { GET_TABLE };
@@ -1470,6 +1547,13 @@ static PyMethodDef ParaTable_methods[] = {
     {"reset", (PyCFunction)ParaTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
     {"removeDC", (PyCFunction)ParaTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
     {"reverse", (PyCFunction)ParaTable_reverse, METH_NOARGS, "Reverse the table's data."},
+    {"invert", (PyCFunction)ParaTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+    {"rectify", (PyCFunction)ParaTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+    {"bipolarGain", (PyCFunction)ParaTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+    {"lowpass", (PyCFunction)ParaTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+    {"fadein", (PyCFunction)ParaTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+    {"fadeout", (PyCFunction)ParaTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+    {"pow", (PyCFunction)ParaTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
     {"setSize", (PyCFunction)ParaTable_setSize, METH_O, "Sets the size of the table in samples"},
     {"getSize", (PyCFunction)ParaTable_getSize, METH_NOARGS, "Return the size of the table in samples"},
     {"put", (PyCFunction)ParaTable_put, METH_VARARGS|METH_KEYWORDS, "Puts a value at specified position in the table."},
@@ -1639,6 +1723,13 @@ static PyObject * LinTable_normalize(LinTable *self) { NORMALIZE };
 static PyObject * LinTable_reset(LinTable *self) { TABLE_RESET };
 static PyObject * LinTable_removeDC(LinTable *self) { REMOVE_DC };
 static PyObject * LinTable_reverse(LinTable *self) { REVERSE };
+static PyObject * LinTable_invert(LinTable *self) { INVERT };
+static PyObject * LinTable_rectify(LinTable *self) { RECTIFY };
+static PyObject * LinTable_bipolarGain(LinTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * LinTable_lowpass(LinTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * LinTable_fadein(LinTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * LinTable_fadeout(LinTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * LinTable_pow(LinTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * LinTable_copy(LinTable *self, PyObject *arg) { COPY };
 static PyObject * LinTable_setTable(LinTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * LinTable_getTable(LinTable *self) { GET_TABLE };
@@ -1748,6 +1839,13 @@ static PyMethodDef LinTable_methods[] = {
 {"reset", (PyCFunction)LinTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
 {"removeDC", (PyCFunction)LinTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
 {"reverse", (PyCFunction)LinTable_reverse, METH_NOARGS, "Reverse the table's data."},
+{"invert", (PyCFunction)LinTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+{"rectify", (PyCFunction)LinTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+{"bipolarGain", (PyCFunction)LinTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+{"lowpass", (PyCFunction)LinTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+{"fadein", (PyCFunction)LinTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+{"fadeout", (PyCFunction)LinTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+{"pow", (PyCFunction)LinTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
 {"setSize", (PyCFunction)LinTable_setSize, METH_O, "Sets the size of the table in samples"},
 {"getSize", (PyCFunction)LinTable_getSize, METH_NOARGS, "Return the size of the table in samples"},
 {"put", (PyCFunction)LinTable_put, METH_VARARGS|METH_KEYWORDS, "Puts a value at specified position in the table."},
@@ -1943,6 +2041,13 @@ static PyObject * LogTable_normalize(LogTable *self) { NORMALIZE };
 static PyObject * LogTable_reset(LogTable *self) { TABLE_RESET };
 static PyObject * LogTable_removeDC(LogTable *self) { REMOVE_DC };
 static PyObject * LogTable_reverse(LogTable *self) { REVERSE };
+static PyObject * LogTable_invert(LogTable *self) { INVERT };
+static PyObject * LogTable_rectify(LogTable *self) { RECTIFY };
+static PyObject * LogTable_bipolarGain(LogTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * LogTable_lowpass(LogTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * LogTable_fadein(LogTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * LogTable_fadeout(LogTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * LogTable_pow(LogTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * LogTable_copy(LogTable *self, PyObject *arg) { COPY };
 static PyObject * LogTable_setTable(LogTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * LogTable_getTable(LogTable *self) { GET_TABLE };
@@ -2052,6 +2157,13 @@ static PyMethodDef LogTable_methods[] = {
     {"reset", (PyCFunction)LogTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
     {"removeDC", (PyCFunction)LogTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
     {"reverse", (PyCFunction)LogTable_reverse, METH_NOARGS, "Reverse the table's data."},
+    {"invert", (PyCFunction)LogTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+    {"rectify", (PyCFunction)LogTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+    {"bipolarGain", (PyCFunction)LogTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+    {"lowpass", (PyCFunction)LogTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+    {"fadein", (PyCFunction)LogTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+    {"fadeout", (PyCFunction)LogTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+    {"pow", (PyCFunction)LogTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
     {"setSize", (PyCFunction)LogTable_setSize, METH_O, "Sets the size of the table in samples"},
     {"getSize", (PyCFunction)LogTable_getSize, METH_NOARGS, "Return the size of the table in samples"},
     {"put", (PyCFunction)LogTable_put, METH_VARARGS|METH_KEYWORDS, "Puts a value at specified position in the table."},
@@ -2225,6 +2337,13 @@ static PyObject * CosTable_normalize(CosTable *self) { NORMALIZE };
 static PyObject * CosTable_reset(CosTable *self) { TABLE_RESET };
 static PyObject * CosTable_removeDC(CosTable *self) { REMOVE_DC };
 static PyObject * CosTable_reverse(CosTable *self) { REVERSE };
+static PyObject * CosTable_invert(CosTable *self) { INVERT };
+static PyObject * CosTable_rectify(CosTable *self) { RECTIFY };
+static PyObject * CosTable_bipolarGain(CosTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * CosTable_lowpass(CosTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * CosTable_fadein(CosTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * CosTable_fadeout(CosTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * CosTable_pow(CosTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * CosTable_copy(CosTable *self, PyObject *arg) { COPY };
 static PyObject * CosTable_setTable(CosTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * CosTable_getTable(CosTable *self) { GET_TABLE };
@@ -2334,6 +2453,13 @@ static PyMethodDef CosTable_methods[] = {
 {"reset", (PyCFunction)CosTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
 {"removeDC", (PyCFunction)CosTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
 {"reverse", (PyCFunction)CosTable_reverse, METH_NOARGS, "Reverse the table's data."},
+{"invert", (PyCFunction)CosTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+{"rectify", (PyCFunction)CosTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+{"bipolarGain", (PyCFunction)CosTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+{"lowpass", (PyCFunction)CosTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+{"fadein", (PyCFunction)CosTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+{"fadeout", (PyCFunction)CosTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+{"pow", (PyCFunction)CosTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
 {"setSize", (PyCFunction)CosTable_setSize, METH_O, "Sets the size of the table in samples"},
 {"getSize", (PyCFunction)CosTable_getSize, METH_NOARGS, "Return the size of the table in samples"},
 {"put", (PyCFunction)CosTable_put, METH_VARARGS|METH_KEYWORDS, "Puts a value at specified position in the table."},
@@ -2531,6 +2657,13 @@ static PyObject * CosLogTable_normalize(CosLogTable *self) { NORMALIZE };
 static PyObject * CosLogTable_reset(CosLogTable *self) { TABLE_RESET };
 static PyObject * CosLogTable_removeDC(CosLogTable *self) { REMOVE_DC };
 static PyObject * CosLogTable_reverse(CosLogTable *self) { REVERSE };
+static PyObject * CosLogTable_invert(CosLogTable *self) { INVERT };
+static PyObject * CosLogTable_rectify(CosLogTable *self) { RECTIFY };
+static PyObject * CosLogTable_bipolarGain(CosLogTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * CosLogTable_lowpass(CosLogTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * CosLogTable_fadein(CosLogTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * CosLogTable_fadeout(CosLogTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * CosLogTable_pow(CosLogTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * CosLogTable_copy(CosLogTable *self, PyObject *arg) { COPY };
 static PyObject * CosLogTable_setTable(CosLogTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * CosLogTable_getTable(CosLogTable *self) { GET_TABLE };
@@ -2640,6 +2773,13 @@ static PyMethodDef CosLogTable_methods[] = {
     {"reset", (PyCFunction)CosLogTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
     {"removeDC", (PyCFunction)CosLogTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
     {"reverse", (PyCFunction)CosLogTable_reverse, METH_NOARGS, "Reverse the table's data."},
+    {"invert", (PyCFunction)CosLogTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+    {"rectify", (PyCFunction)CosLogTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+    {"bipolarGain", (PyCFunction)CosLogTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+    {"lowpass", (PyCFunction)CosLogTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+    {"fadein", (PyCFunction)CosLogTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+    {"fadeout", (PyCFunction)CosLogTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+    {"pow", (PyCFunction)CosLogTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
     {"setSize", (PyCFunction)CosLogTable_setSize, METH_O, "Sets the size of the table in samples"},
     {"getSize", (PyCFunction)CosLogTable_getSize, METH_NOARGS, "Return the size of the table in samples"},
     {"put", (PyCFunction)CosLogTable_put, METH_VARARGS|METH_KEYWORDS, "Puts a value at specified position in the table."},
@@ -2840,6 +2980,13 @@ static PyObject * CurveTable_normalize(CurveTable * self) { NORMALIZE };
 static PyObject * CurveTable_reset(CurveTable * self) { TABLE_RESET };
 static PyObject * CurveTable_removeDC(CurveTable *self) { REMOVE_DC };
 static PyObject * CurveTable_reverse(CurveTable *self) { REVERSE };
+static PyObject * CurveTable_invert(CurveTable *self) { INVERT };
+static PyObject * CurveTable_rectify(CurveTable *self) { RECTIFY };
+static PyObject * CurveTable_bipolarGain(CurveTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * CurveTable_lowpass(CurveTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * CurveTable_fadein(CurveTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * CurveTable_fadeout(CurveTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * CurveTable_pow(CurveTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * CurveTable_copy(CurveTable *self, PyObject *arg) { COPY };
 static PyObject * CurveTable_setTable(CurveTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * CurveTable_getTable(CurveTable *self) { GET_TABLE };
@@ -2999,6 +3146,13 @@ static PyMethodDef CurveTable_methods[] = {
 {"reset", (PyCFunction)CurveTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
 {"removeDC", (PyCFunction)CurveTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
 {"reverse", (PyCFunction)CurveTable_reverse, METH_NOARGS, "Reverse the table's data."},
+{"invert", (PyCFunction)CurveTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+{"rectify", (PyCFunction)CurveTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+{"bipolarGain", (PyCFunction)CurveTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+{"lowpass", (PyCFunction)CurveTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+{"fadein", (PyCFunction)CurveTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+{"fadeout", (PyCFunction)CurveTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+{"pow", (PyCFunction)CurveTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
 {NULL}  /* Sentinel */
 };
 
@@ -3190,6 +3344,13 @@ static PyObject * ExpTable_normalize(ExpTable * self) { NORMALIZE };
 static PyObject * ExpTable_reset(ExpTable * self) { TABLE_RESET };
 static PyObject * ExpTable_removeDC(ExpTable *self) { REMOVE_DC };
 static PyObject * ExpTable_reverse(ExpTable *self) { REVERSE };
+static PyObject * ExpTable_invert(ExpTable *self) { INVERT };
+static PyObject * ExpTable_rectify(ExpTable *self) { RECTIFY };
+static PyObject * ExpTable_bipolarGain(ExpTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * ExpTable_lowpass(ExpTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * ExpTable_fadein(ExpTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * ExpTable_fadeout(ExpTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * ExpTable_pow(ExpTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * ExpTable_copy(ExpTable *self, PyObject *arg) { COPY };
 static PyObject * ExpTable_setTable(ExpTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * ExpTable_getTable(ExpTable *self) { GET_TABLE };
@@ -3348,6 +3509,13 @@ static PyMethodDef ExpTable_methods[] = {
 {"reset", (PyCFunction)ExpTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
 {"removeDC", (PyCFunction)ExpTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
 {"reverse", (PyCFunction)ExpTable_reverse, METH_NOARGS, "Reverse the table's data."},
+{"invert", (PyCFunction)ExpTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+{"rectify", (PyCFunction)ExpTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+{"bipolarGain", (PyCFunction)ExpTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+{"lowpass", (PyCFunction)ExpTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+{"fadein", (PyCFunction)ExpTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+{"fadeout", (PyCFunction)ExpTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+{"pow", (PyCFunction)ExpTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
 {NULL}  /* Sentinel */
 };
 
@@ -3856,6 +4024,13 @@ static PyObject * SndTable_normalize(SndTable *self) { NORMALIZE };
 static PyObject * SndTable_reset(SndTable *self) { TABLE_RESET };
 static PyObject * SndTable_removeDC(SndTable *self) { REMOVE_DC };
 static PyObject * SndTable_reverse(SndTable *self) { REVERSE };
+static PyObject * SndTable_invert(SndTable *self) { INVERT };
+static PyObject * SndTable_rectify(SndTable *self) { RECTIFY };
+static PyObject * SndTable_bipolarGain(SndTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * SndTable_lowpass(SndTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * SndTable_fadein(SndTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * SndTable_fadeout(SndTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * SndTable_pow(SndTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * SndTable_copy(SndTable *self, PyObject *arg) { COPY };
 static PyObject * SndTable_setTable(SndTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * SndTable_getTable(SndTable *self) { GET_TABLE };
@@ -3864,17 +4039,37 @@ static PyObject * SndTable_get(SndTable *self, PyObject *args, PyObject *kwds) {
 
 static PyObject * 
 SndTable_getViewTable(SndTable *self, PyObject *args, PyObject *kwds) { 
-    int i, j, y, w, h, h2, step;
+    int i, j, y, w, h, h2, step, size;
     int count = 0;
-    MYFLT absin;
-    PyObject *samples;
+    int yOffset = 0;
+    MYFLT absin, fstep;
+    MYFLT begin = 0.0;
+    MYFLT end = -1.0;
+    PyObject *samples, *tuple;
     PyObject *sizetmp = NULL;
 
-    static char *kwlist[] = {"size", NULL};
+    static char *kwlist[] = {"size", "begin", "end", "yOffset", NULL};
     
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &sizetmp))
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE__OFFI, kwlist, &sizetmp, &begin, &end, &yOffset))
         return PyInt_FromLong(-1); 
     
+    if (end <= 0.0)
+        end = self->size;
+    else {
+        end = end * self->sr;
+        if (end > self->size)
+            end = self->size;
+    }
+
+    if (begin < 0.0)
+        begin = 0;
+    else {
+        begin = begin * self->sr;
+        if (begin >= end)
+            begin = 0;
+    }
+    size = (int)(end - begin);
+
     if (sizetmp) {
         if (PyTuple_Check(sizetmp)) {
             w = PyInt_AsLong(PyTuple_GET_ITEM(sizetmp, 0));
@@ -3894,20 +4089,52 @@ SndTable_getViewTable(SndTable *self, PyObject *args, PyObject *kwds) {
         h = 200;
     }
     h2 = h/2;
-    step = (int)(self->size / (MYFLT)(w));
-    
-    samples = PyList_New(w*4);
-    for(i=0; i<w; i++) {
-        absin = 0.0;
-        for (j=0; j<step; j++) {
-            if (MYFABS(self->data[count++]) > absin)
-                absin = self->data[count];
+    step = (int)(size / (MYFLT)(w));
+    fstep = (MYFLT)(w) / (size-1);
+    
+    if (step == 0) {
+        samples = PyList_New(size);
+        for (i=0; i<size; i++) {
+            tuple = PyTuple_New(2);
+            PyTuple_SetItem(tuple, 0, PyInt_FromLong((int)(i*fstep)));
+            PyTuple_SetItem(tuple, 1, PyInt_FromLong(-self->data[i+(int)(begin)]*h2+h2+yOffset));
+            PyList_SetItem(samples, i, tuple);
+        }
+    }
+    else if (step < 32) {
+        samples = PyList_New(w);
+        for(i=0; i<w; i++) {
+            absin = 0.0;
+            for (j=0; j<step; j++) {
+                absin += -self->data[(int)(begin)+count];
+                count++;
+            }
+            y = (int)(absin / step * h2);
+            tuple = PyTuple_New(2);
+            PyTuple_SetItem(tuple, 0, PyInt_FromLong(i));
+            PyTuple_SetItem(tuple, 1, PyInt_FromLong(h2+y+yOffset));
+            PyList_SetItem(samples, i, tuple);
+        }
+    }
+    else {
+        samples = PyList_New(w*2);
+        for(i=0; i<w; i++) {
+            absin = 0.0;
+            for (j=0; j<step; j++) {
+                if (MYFABS(self->data[(int)(begin)+count]) > absin)
+                    absin = -self->data[(int)(begin)+count];
+                count++;
+            }
+            y = (int)(absin * h2);
+            tuple = PyTuple_New(2);
+            PyTuple_SetItem(tuple, 0, PyInt_FromLong(i));
+            PyTuple_SetItem(tuple, 1, PyInt_FromLong(h2-y+yOffset));
+            PyList_SetItem(samples, i*2, tuple);
+            tuple = PyTuple_New(2);
+            PyTuple_SetItem(tuple, 0, PyInt_FromLong(i));
+            PyTuple_SetItem(tuple, 1, PyInt_FromLong(h2+y+yOffset));
+            PyList_SetItem(samples, i*2+1, tuple);
         }
-        y = (int)(absin * h2);
-        PyList_SetItem(samples, i*4, PyInt_FromLong(i));
-        PyList_SetItem(samples, i*4+1, PyInt_FromLong(h2-y));
-        PyList_SetItem(samples, i*4+2, PyInt_FromLong(i));
-        PyList_SetItem(samples, i*4+3, PyInt_FromLong(h2+y));
     }
     return samples;
 };
@@ -4080,6 +4307,13 @@ static PyMethodDef SndTable_methods[] = {
 {"reset", (PyCFunction)SndTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
 {"removeDC", (PyCFunction)SndTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
 {"reverse", (PyCFunction)SndTable_reverse, METH_NOARGS, "Reverse the table's data."},
+{"invert", (PyCFunction)SndTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+{"rectify", (PyCFunction)SndTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+{"bipolarGain", (PyCFunction)SndTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+{"lowpass", (PyCFunction)SndTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+{"fadein", (PyCFunction)SndTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+{"fadeout", (PyCFunction)SndTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+{"pow", (PyCFunction)SndTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
 {"put", (PyCFunction)SndTable_put, METH_VARARGS|METH_KEYWORDS, "Puts a value at specified position in the table."},
 {"get", (PyCFunction)SndTable_get, METH_VARARGS|METH_KEYWORDS, "Gets the value at specified position in the table."},
 {"setSound", (PyCFunction)SndTable_setSound, METH_VARARGS|METH_KEYWORDS, "Load a new sound in the table."},
@@ -4148,6 +4382,7 @@ typedef struct {
     pyo_table_HEAD
     MYFLT length;
     MYFLT feedback;
+    MYFLT sr;
     int pointer;
 } NewTable;
 
@@ -4222,8 +4457,8 @@ NewTable_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_F_OF, kwlist, &self->length, &inittmp, &self->feedback))
         Py_RETURN_NONE; 
 
-    double sr = PyFloat_AsDouble(PyObject_CallMethod(self->server, "getSamplingRate", NULL));
-    self->size = (int)(self->length * sr + 0.5);
+    self->sr = (MYFLT)PyFloat_AsDouble(PyObject_CallMethod(self->server, "getSamplingRate", NULL));
+    self->size = (int)(self->length * self->sr + 0.5);
     self->data = (MYFLT *)realloc(self->data, (self->size + 1) * sizeof(MYFLT));
 
     for (i=0; i<(self->size+1); i++) {
@@ -4237,7 +4472,7 @@ NewTable_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     }
     
     TableStream_setData(self->tablestream, self->data);
-    TableStream_setSamplingRate(self->tablestream, sr);
+    TableStream_setSamplingRate(self->tablestream, self->sr);
     
     return (PyObject *)self;
 }
@@ -4249,6 +4484,13 @@ static PyObject * NewTable_normalize(NewTable *self) { NORMALIZE };
 static PyObject * NewTable_reset(NewTable *self) { TABLE_RESET };
 static PyObject * NewTable_removeDC(NewTable *self) { REMOVE_DC };
 static PyObject * NewTable_reverse(NewTable *self) { REVERSE };
+static PyObject * NewTable_invert(NewTable *self) { INVERT };
+static PyObject * NewTable_rectify(NewTable *self) { RECTIFY };
+static PyObject * NewTable_bipolarGain(NewTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * NewTable_lowpass(NewTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * NewTable_fadein(NewTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * NewTable_fadeout(NewTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * NewTable_pow(NewTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * NewTable_copy(NewTable *self, PyObject *arg) { COPY };
 static PyObject * NewTable_setTable(NewTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * NewTable_getTable(NewTable *self) { GET_TABLE };
@@ -4257,17 +4499,37 @@ static PyObject * NewTable_get(NewTable *self, PyObject *args, PyObject *kwds) {
 
 static PyObject * 
 NewTable_getViewTable(NewTable *self, PyObject *args, PyObject *kwds) { 
-    int i, j, y, w, h, h2, step;
+    int i, j, y, w, h, h2, step, size;
     int count = 0;
-    MYFLT absin;
-    PyObject *samples;
+    int yOffset = 0;
+    MYFLT absin, fstep;
+    MYFLT begin = 0.0;
+    MYFLT end = -1.0;
+    PyObject *samples, *tuple;
     PyObject *sizetmp = NULL;
+
+    static char *kwlist[] = {"size", "begin", "end", "yOffset", NULL};
     
-    static char *kwlist[] = {"size", NULL};
-    
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &sizetmp))
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE__OFFI, kwlist, &sizetmp, &begin, &end, &yOffset))
         return PyInt_FromLong(-1); 
     
+    if (end <= 0.0)
+        end = self->size;
+    else {
+        end = end * self->sr;
+        if (end > self->size)
+            end = self->size;
+    }
+
+    if (begin < 0.0)
+        begin = 0;
+    else {
+        begin = begin * self->sr;
+        if (begin >= end)
+            begin = 0;
+    }
+    size = (int)(end - begin);
+
     if (sizetmp) {
         if (PyTuple_Check(sizetmp)) {
             w = PyInt_AsLong(PyTuple_GET_ITEM(sizetmp, 0));
@@ -4287,20 +4549,52 @@ NewTable_getViewTable(NewTable *self, PyObject *args, PyObject *kwds) {
         h = 200;
     }
     h2 = h/2;
-    step = (int)(self->size / (MYFLT)(w));
-    
-    samples = PyList_New(w*4);
-    for(i=0; i<w; i++) {
-        absin = 0.0;
-        for (j=0; j<step; j++) {
-            if (MYFABS(self->data[count++]) > absin)
-                absin = self->data[count];
+    step = (int)(size / (MYFLT)(w));
+    fstep = (MYFLT)(w) / (size-1);
+    
+    if (step == 0) {
+        samples = PyList_New(size);
+        for (i=0; i<size; i++) {
+            tuple = PyTuple_New(2);
+            PyTuple_SetItem(tuple, 0, PyInt_FromLong((int)(i*fstep)));
+            PyTuple_SetItem(tuple, 1, PyInt_FromLong(-self->data[i+(int)(begin)]*h2+h2+yOffset));
+            PyList_SetItem(samples, i, tuple);
+        }
+    }
+    else if (step < 32) {
+        samples = PyList_New(w);
+        for(i=0; i<w; i++) {
+            absin = 0.0;
+            for (j=0; j<step; j++) {
+                absin += -self->data[(int)(begin)+count];
+                count++;
+            }
+            y = (int)(absin / step * h2);
+            tuple = PyTuple_New(2);
+            PyTuple_SetItem(tuple, 0, PyInt_FromLong(i));
+            PyTuple_SetItem(tuple, 1, PyInt_FromLong(h2+y+yOffset));
+            PyList_SetItem(samples, i, tuple);
+        }
+    }
+    else {
+        samples = PyList_New(w*2);
+        for(i=0; i<w; i++) {
+            absin = 0.0;
+            for (j=0; j<step; j++) {
+                if (MYFABS(self->data[(int)(begin)+count]) > absin)
+                    absin = -self->data[(int)(begin)+count];
+                count++;
+            }
+            y = (int)(absin * h2);
+            tuple = PyTuple_New(2);
+            PyTuple_SetItem(tuple, 0, PyInt_FromLong(i));
+            PyTuple_SetItem(tuple, 1, PyInt_FromLong(h2-y+yOffset));
+            PyList_SetItem(samples, i*2, tuple);
+            tuple = PyTuple_New(2);
+            PyTuple_SetItem(tuple, 0, PyInt_FromLong(i));
+            PyTuple_SetItem(tuple, 1, PyInt_FromLong(h2+y+yOffset));
+            PyList_SetItem(samples, i*2+1, tuple);
         }
-        y = (int)(absin * h2);
-        PyList_SetItem(samples, i*4, PyInt_FromLong(i));
-        PyList_SetItem(samples, i*4+1, PyInt_FromLong(h2-y));
-        PyList_SetItem(samples, i*4+2, PyInt_FromLong(i));
-        PyList_SetItem(samples, i*4+3, PyInt_FromLong(h2+y));
     }
     return samples;
 };
@@ -4360,6 +4654,13 @@ static PyMethodDef NewTable_methods[] = {
 {"reset", (PyCFunction)NewTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
 {"removeDC", (PyCFunction)NewTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
 {"reverse", (PyCFunction)NewTable_reverse, METH_NOARGS, "Reverse the table's data."},
+{"invert", (PyCFunction)NewTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+{"rectify", (PyCFunction)NewTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+{"bipolarGain", (PyCFunction)NewTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+{"lowpass", (PyCFunction)NewTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+{"fadein", (PyCFunction)NewTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+{"fadeout", (PyCFunction)NewTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+{"pow", (PyCFunction)NewTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
 {"put", (PyCFunction)NewTable_put, METH_VARARGS|METH_KEYWORDS, "Puts a value at specified position in the table."},
 {"get", (PyCFunction)NewTable_get, METH_VARARGS|METH_KEYWORDS, "Gets the value at specified position in the table."},
 {"getSize", (PyCFunction)NewTable_getSize, METH_NOARGS, "Return the size of the table in samples."},
@@ -4492,6 +4793,13 @@ static PyObject * DataTable_normalize(DataTable *self) { NORMALIZE };
 static PyObject * DataTable_reset(DataTable *self) { TABLE_RESET };
 static PyObject * DataTable_removeDC(DataTable *self) { REMOVE_DC };
 static PyObject * DataTable_reverse(DataTable *self) { REVERSE };
+static PyObject * DataTable_invert(DataTable *self) { INVERT };
+static PyObject * DataTable_rectify(DataTable *self) { RECTIFY };
+static PyObject * DataTable_bipolarGain(DataTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * DataTable_lowpass(DataTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * DataTable_fadein(DataTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * DataTable_fadeout(DataTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * DataTable_pow(DataTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
 static PyObject * DataTable_copy(DataTable *self, PyObject *arg) { COPY };
 static PyObject * DataTable_setTable(DataTable *self, PyObject *arg) { SET_TABLE };
 static PyObject * DataTable_getTable(DataTable *self) { GET_TABLE };
@@ -4530,6 +4838,13 @@ static PyMethodDef DataTable_methods[] = {
     {"reset", (PyCFunction)DataTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
     {"removeDC", (PyCFunction)DataTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
     {"reverse", (PyCFunction)DataTable_reverse, METH_NOARGS, "Reverse the table's data."},
+    {"invert", (PyCFunction)DataTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+    {"rectify", (PyCFunction)DataTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+    {"bipolarGain", (PyCFunction)DataTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+    {"lowpass", (PyCFunction)DataTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+    {"fadein", (PyCFunction)DataTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+    {"fadeout", (PyCFunction)DataTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+    {"pow", (PyCFunction)DataTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
     {"put", (PyCFunction)DataTable_put, METH_VARARGS|METH_KEYWORDS, "Puts a value at specified position in the table."},
     {"get", (PyCFunction)DataTable_get, METH_VARARGS|METH_KEYWORDS, "Gets the value at specified position in the table."},
     {"getSize", (PyCFunction)DataTable_getSize, METH_NOARGS, "Return the size of the table in samples."},
@@ -4727,6 +5042,7 @@ TableRec_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         Py_Exit(1);
     }
     Py_XDECREF(self->table);
+    Py_INCREF(tabletmp);
     self->table = (NewTable *)tabletmp;
     
     PyObject_CallMethod(self->server, "addStream", "O", self->stream);
@@ -5217,9 +5533,11 @@ TableMorph_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         Py_Exit(1);
     }
     Py_XDECREF(self->table);
+    Py_INCREF(tabletmp);
     self->table = (PyObject *)tabletmp;
     
     Py_XDECREF(self->sources);
+    Py_INCREF(sourcestmp);
     self->sources = (PyObject *)sourcestmp;
     
     TableMorph_alloc_memories(self);
@@ -5521,6 +5839,7 @@ TrigTableRec_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     INIT_INPUT_STREAM
 
     Py_XDECREF(self->trigger);
+    Py_INCREF(trigtmp);
     self->trigger = trigtmp;
     trig_streamtmp = PyObject_CallMethod((PyObject *)self->trigger, "_getStream", NULL);
     Py_INCREF(trig_streamtmp);
@@ -5535,6 +5854,7 @@ TrigTableRec_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         Py_Exit(1);
     }
     Py_XDECREF(self->table);
+    Py_INCREF(tabletmp);
     self->table = (NewTable *)tabletmp;
     
     PyObject_CallMethod(self->server, "addStream", "O", self->stream);
@@ -5996,6 +6316,7 @@ TablePut_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         Py_Exit(1);
     }
     Py_XDECREF(self->table);
+    Py_INCREF(tabletmp);
     self->table = (DataTable *)tabletmp;
     
     PyObject_CallMethod(self->server, "addStream", "O", self->stream);
diff --git a/src/objects/trigmodule.c b/src/objects/trigmodule.c
index cdbcf85..29176d2 100644
--- a/src/objects/trigmodule.c
+++ b/src/objects/trigmodule.c
@@ -1394,7 +1394,7 @@ TrigFunc_setArg(TrigFunc *self, PyObject *arg)
 	PyObject *tmp;
 
     tmp = arg;
-    Py_DECREF(self->arg);
+    Py_XDECREF(self->arg);
     Py_INCREF(tmp);
     self->arg = tmp;
     
diff --git a/src/objects/utilsmodule.c b/src/objects/utilsmodule.c
index a82cec9..fe0bf39 100644
--- a/src/objects/utilsmodule.c
+++ b/src/objects/utilsmodule.c
@@ -1203,11 +1203,11 @@ SampHold_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     
     INIT_INPUT_STREAM
     
-    Py_XDECREF(self->controlsig); \
-    self->controlsig = controlsigtmp; \
-    controlsig_streamtmp = PyObject_CallMethod((PyObject *)self->controlsig, "_getStream", NULL); \
-    Py_INCREF(controlsig_streamtmp); \
-    Py_XDECREF(self->controlsig_stream); \
+    Py_XDECREF(self->controlsig);
+    self->controlsig = controlsigtmp;
+    controlsig_streamtmp = PyObject_CallMethod((PyObject *)self->controlsig, "_getStream", NULL);
+    Py_INCREF(controlsig_streamtmp);
+    Py_XDECREF(self->controlsig_stream);
     self->controlsig_stream = (Stream *)controlsig_streamtmp;
     
     if (valuetmp) {
@@ -1393,6 +1393,383 @@ SampHold_new,                                     /* tp_new */
 };
 
 /************/
+/* TrackHold */
+/************/
+typedef struct {
+    pyo_audio_HEAD
+    PyObject *input;
+    Stream *input_stream;
+    PyObject *controlsig;
+    Stream *controlsig_stream;
+    PyObject *value;
+    Stream *value_stream;
+    MYFLT currentValue;
+    int flag;
+    int modebuffer[3]; // need at least 2 slots for mul & add 
+} TrackHold;
+
+static void
+TrackHold_filters_i(TrackHold *self) {
+    MYFLT ctrl;
+    int i;
+    MYFLT *in = Stream_getData((Stream *)self->input_stream);
+    MYFLT *ctrlsig = Stream_getData((Stream *)self->controlsig_stream);
+    MYFLT val = PyFloat_AS_DOUBLE(self->value);
+
+    for (i=0; i<self->bufsize; i++) {
+        ctrl = ctrlsig[i];
+        if (ctrl > (val - 0.0001) && ctrl < (val + 0.0001)) {
+            if (self->flag == 1) {
+                self->currentValue = in[i];
+                self->flag = 0;
+            }    
+        }
+        else {
+            self->currentValue = in[i];
+            self->flag = 1;
+        }
+        self->data[i] = self->currentValue;
+    }
+}
+
+static void
+TrackHold_filters_a(TrackHold *self) {
+    MYFLT ctrl, val;
+    int i;
+    MYFLT *in = Stream_getData((Stream *)self->input_stream);
+    MYFLT *ctrlsig = Stream_getData((Stream *)self->controlsig_stream);
+    MYFLT *valsig = Stream_getData((Stream *)self->value_stream);
+    
+    for (i=0; i<self->bufsize; i++) {
+        ctrl = ctrlsig[i];
+        val = valsig[i];
+        if (ctrl > (val - 0.0001) && ctrl < (val + 0.0001)) {
+            if (self->flag == 1) {
+                self->currentValue = in[i];
+                self->flag = 0;
+            }    
+        }
+        else {
+            self->currentValue = in[i];
+            self->flag = 1;
+        }
+        self->data[i] = self->currentValue;
+    }
+}
+
+static void TrackHold_postprocessing_ii(TrackHold *self) { POST_PROCESSING_II };
+static void TrackHold_postprocessing_ai(TrackHold *self) { POST_PROCESSING_AI };
+static void TrackHold_postprocessing_ia(TrackHold *self) { POST_PROCESSING_IA };
+static void TrackHold_postprocessing_aa(TrackHold *self) { POST_PROCESSING_AA };
+static void TrackHold_postprocessing_ireva(TrackHold *self) { POST_PROCESSING_IREVA };
+static void TrackHold_postprocessing_areva(TrackHold *self) { POST_PROCESSING_AREVA };
+static void TrackHold_postprocessing_revai(TrackHold *self) { POST_PROCESSING_REVAI };
+static void TrackHold_postprocessing_revaa(TrackHold *self) { POST_PROCESSING_REVAA };
+static void TrackHold_postprocessing_revareva(TrackHold *self) { POST_PROCESSING_REVAREVA };
+
+static void
+TrackHold_setProcMode(TrackHold *self)
+{
+    int procmode, muladdmode;
+    procmode = self->modebuffer[2];
+    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
+    
+	switch (procmode) {
+        case 0:    
+            self->proc_func_ptr = TrackHold_filters_i;
+            break;
+        case 1:    
+            self->proc_func_ptr = TrackHold_filters_a;
+            break;
+    } 
+	switch (muladdmode) {
+        case 0:        
+            self->muladd_func_ptr = TrackHold_postprocessing_ii;
+            break;
+        case 1:    
+            self->muladd_func_ptr = TrackHold_postprocessing_ai;
+            break;
+        case 2:    
+            self->muladd_func_ptr = TrackHold_postprocessing_revai;
+            break;
+        case 10:        
+            self->muladd_func_ptr = TrackHold_postprocessing_ia;
+            break;
+        case 11:    
+            self->muladd_func_ptr = TrackHold_postprocessing_aa;
+            break;
+        case 12:    
+            self->muladd_func_ptr = TrackHold_postprocessing_revaa;
+            break;
+        case 20:        
+            self->muladd_func_ptr = TrackHold_postprocessing_ireva;
+            break;
+        case 21:    
+            self->muladd_func_ptr = TrackHold_postprocessing_areva;
+            break;
+        case 22:    
+            self->muladd_func_ptr = TrackHold_postprocessing_revareva;
+            break;
+    }   
+}
+
+static void
+TrackHold_compute_next_data_frame(TrackHold *self)
+{
+    (*self->proc_func_ptr)(self); 
+    (*self->muladd_func_ptr)(self);
+}
+
+static int
+TrackHold_traverse(TrackHold *self, visitproc visit, void *arg)
+{
+    pyo_VISIT
+    Py_VISIT(self->input);
+    Py_VISIT(self->input_stream);
+    Py_VISIT(self->controlsig);
+    Py_VISIT(self->controlsig_stream);
+    Py_VISIT(self->value);    
+    Py_VISIT(self->value_stream);    
+    return 0;
+}
+
+static int 
+TrackHold_clear(TrackHold *self)
+{
+    pyo_CLEAR
+    Py_CLEAR(self->input);
+    Py_CLEAR(self->input_stream);
+    Py_CLEAR(self->controlsig);
+    Py_CLEAR(self->controlsig_stream);
+    Py_CLEAR(self->value);    
+    Py_CLEAR(self->value_stream);    
+    return 0;
+}
+
+static void
+TrackHold_dealloc(TrackHold* self)
+{
+    pyo_DEALLOC
+    TrackHold_clear(self);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+TrackHold_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    int i;
+    PyObject *inputtmp, *input_streamtmp, *controlsigtmp, *controlsig_streamtmp, *valuetmp=NULL, *multmp=NULL, *addtmp=NULL;
+    TrackHold *self;
+    self = (TrackHold *)type->tp_alloc(type, 0);
+    
+    self->value = PyFloat_FromDouble(0.0);
+    self->currentValue = 0.0;
+    self->flag = 1;
+	self->modebuffer[0] = 0;
+	self->modebuffer[1] = 0;
+	self->modebuffer[2] = 0;
+    
+    INIT_OBJECT_COMMON
+    Stream_setFunctionPtr(self->stream, TrackHold_compute_next_data_frame);
+    self->mode_func_ptr = TrackHold_setProcMode;
+
+    static char *kwlist[] = {"input", "controlsig", "value", "mul", "add", NULL};
+    
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OOO", kwlist, &inputtmp, &controlsigtmp, &valuetmp, &multmp, &addtmp))
+        Py_RETURN_NONE;
+    
+    INIT_INPUT_STREAM
+    
+    Py_XDECREF(self->controlsig);
+    self->controlsig = controlsigtmp;
+    controlsig_streamtmp = PyObject_CallMethod((PyObject *)self->controlsig, "_getStream", NULL);
+    Py_INCREF(controlsig_streamtmp);
+    Py_XDECREF(self->controlsig_stream);
+    self->controlsig_stream = (Stream *)controlsig_streamtmp;
+    
+    if (valuetmp) {
+        PyObject_CallMethod((PyObject *)self, "setValue", "O", valuetmp);
+    }
+    
+    if (multmp) {
+        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
+    }
+    
+    if (addtmp) {
+        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
+    }
+    
+    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
+    
+    (*self->mode_func_ptr)(self);
+
+    return (PyObject *)self;
+}
+
+static PyObject * TrackHold_getServer(TrackHold* self) { GET_SERVER };
+static PyObject * TrackHold_getStream(TrackHold* self) { GET_STREAM };
+static PyObject * TrackHold_setMul(TrackHold *self, PyObject *arg) { SET_MUL };	
+static PyObject * TrackHold_setAdd(TrackHold *self, PyObject *arg) { SET_ADD };	
+static PyObject * TrackHold_setSub(TrackHold *self, PyObject *arg) { SET_SUB };	
+static PyObject * TrackHold_setDiv(TrackHold *self, PyObject *arg) { SET_DIV };	
+
+static PyObject * TrackHold_play(TrackHold *self, PyObject *args, PyObject *kwds) { PLAY };
+static PyObject * TrackHold_out(TrackHold *self, PyObject *args, PyObject *kwds) { OUT };
+static PyObject * TrackHold_stop(TrackHold *self) { STOP };
+
+static PyObject * TrackHold_multiply(TrackHold *self, PyObject *arg) { MULTIPLY };
+static PyObject * TrackHold_inplace_multiply(TrackHold *self, PyObject *arg) { INPLACE_MULTIPLY };
+static PyObject * TrackHold_add(TrackHold *self, PyObject *arg) { ADD };
+static PyObject * TrackHold_inplace_add(TrackHold *self, PyObject *arg) { INPLACE_ADD };
+static PyObject * TrackHold_sub(TrackHold *self, PyObject *arg) { SUB };
+static PyObject * TrackHold_inplace_sub(TrackHold *self, PyObject *arg) { INPLACE_SUB };
+static PyObject * TrackHold_div(TrackHold *self, PyObject *arg) { DIV };
+static PyObject * TrackHold_inplace_div(TrackHold *self, PyObject *arg) { INPLACE_DIV };
+
+static PyObject *
+TrackHold_setValue(TrackHold *self, PyObject *arg)
+{
+	PyObject *tmp, *streamtmp;
+	
+	if (arg == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+	int isNumber = PyNumber_Check(arg);
+	
+	tmp = arg;
+	Py_INCREF(tmp);
+	Py_DECREF(self->value);
+	if (isNumber == 1) {
+		self->value = PyNumber_Float(tmp);
+        self->modebuffer[2] = 0;
+	}
+	else {
+		self->value = tmp;
+        streamtmp = PyObject_CallMethod((PyObject *)self->value, "_getStream", NULL);
+        Py_INCREF(streamtmp);
+        Py_XDECREF(self->value_stream);
+        self->value_stream = (Stream *)streamtmp;
+		self->modebuffer[2] = 1;
+	}
+    
+    (*self->mode_func_ptr)(self);
+    
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyMemberDef TrackHold_members[] = {
+{"server", T_OBJECT_EX, offsetof(TrackHold, server), 0, "Pyo server."},
+{"stream", T_OBJECT_EX, offsetof(TrackHold, stream), 0, "Stream object."},
+{"input", T_OBJECT_EX, offsetof(TrackHold, input), 0, "Input sound object."},
+{"controlsig", T_OBJECT_EX, offsetof(TrackHold, controlsig), 0, "Control input object."},
+{"value", T_OBJECT_EX, offsetof(TrackHold, value), 0, "Trigger value."},
+{"mul", T_OBJECT_EX, offsetof(TrackHold, mul), 0, "Mul factor."},
+{"add", T_OBJECT_EX, offsetof(TrackHold, add), 0, "Add factor."},
+{NULL}  /* Sentinel */
+};
+
+static PyMethodDef TrackHold_methods[] = {
+{"getServer", (PyCFunction)TrackHold_getServer, METH_NOARGS, "Returns server object."},
+{"_getStream", (PyCFunction)TrackHold_getStream, METH_NOARGS, "Returns stream object."},
+{"play", (PyCFunction)TrackHold_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
+{"out", (PyCFunction)TrackHold_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
+{"stop", (PyCFunction)TrackHold_stop, METH_NOARGS, "Stops computing."},
+{"setValue", (PyCFunction)TrackHold_setValue, METH_O, "Sets trigger value."},
+{"setMul", (PyCFunction)TrackHold_setMul, METH_O, "Sets oscillator mul factor."},
+{"setAdd", (PyCFunction)TrackHold_setAdd, METH_O, "Sets oscillator add factor."},
+{"setSub", (PyCFunction)TrackHold_setSub, METH_O, "Sets inverse add factor."},
+{"setDiv", (PyCFunction)TrackHold_setDiv, METH_O, "Sets inverse mul factor."},
+{NULL}  /* Sentinel */
+};
+
+static PyNumberMethods TrackHold_as_number = {
+(binaryfunc)TrackHold_add,                         /*nb_add*/
+(binaryfunc)TrackHold_sub,                         /*nb_subtract*/
+(binaryfunc)TrackHold_multiply,                    /*nb_multiply*/
+(binaryfunc)TrackHold_div,                                              /*nb_divide*/
+0,                                              /*nb_remainder*/
+0,                                              /*nb_divmod*/
+0,                                              /*nb_power*/
+0,                                              /*nb_neg*/
+0,                                              /*nb_pos*/
+0,                                              /*(unaryfunc)array_abs,*/
+0,                                              /*nb_nonzero*/
+0,                                              /*nb_invert*/
+0,                                              /*nb_lshift*/
+0,                                              /*nb_rshift*/
+0,                                              /*nb_and*/
+0,                                              /*nb_xor*/
+0,                                              /*nb_or*/
+0,                                              /*nb_coerce*/
+0,                                              /*nb_int*/
+0,                                              /*nb_long*/
+0,                                              /*nb_float*/
+0,                                              /*nb_oct*/
+0,                                              /*nb_hex*/
+(binaryfunc)TrackHold_inplace_add,                 /*inplace_add*/
+(binaryfunc)TrackHold_inplace_sub,                 /*inplace_subtract*/
+(binaryfunc)TrackHold_inplace_multiply,            /*inplace_multiply*/
+(binaryfunc)TrackHold_inplace_div,                                              /*inplace_divide*/
+0,                                              /*inplace_remainder*/
+0,                                              /*inplace_power*/
+0,                                              /*inplace_lshift*/
+0,                                              /*inplace_rshift*/
+0,                                              /*inplace_and*/
+0,                                              /*inplace_xor*/
+0,                                              /*inplace_or*/
+0,                                              /*nb_floor_divide*/
+0,                                              /*nb_true_divide*/
+0,                                              /*nb_inplace_floor_divide*/
+0,                                              /*nb_inplace_true_divide*/
+0,                                              /* nb_index */
+};
+
+PyTypeObject TrackHoldType = {
+PyObject_HEAD_INIT(NULL)
+0,                                              /*ob_size*/
+"_pyo.TrackHold_base",                                   /*tp_name*/
+sizeof(TrackHold),                                 /*tp_basicsize*/
+0,                                              /*tp_itemsize*/
+(destructor)TrackHold_dealloc,                     /*tp_dealloc*/
+0,                                              /*tp_print*/
+0,                                              /*tp_getattr*/
+0,                                              /*tp_setattr*/
+0,                                              /*tp_compare*/
+0,                                              /*tp_repr*/
+&TrackHold_as_number,                              /*tp_as_number*/
+0,                                              /*tp_as_sequence*/
+0,                                              /*tp_as_mapping*/
+0,                                              /*tp_hash */
+0,                                              /*tp_call*/
+0,                                              /*tp_str*/
+0,                                              /*tp_getattro*/
+0,                                              /*tp_setattro*/
+0,                                              /*tp_as_buffer*/
+Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
+"TrackHold objects. Let pass and freeze an audio stream.",           /* tp_doc */
+(traverseproc)TrackHold_traverse,                  /* tp_traverse */
+(inquiry)TrackHold_clear,                          /* tp_clear */
+0,                                              /* tp_richcompare */
+0,                                              /* tp_weaklistoffset */
+0,                                              /* tp_iter */
+0,                                              /* tp_iternext */
+TrackHold_methods,                                 /* tp_methods */
+TrackHold_members,                                 /* tp_members */
+0,                                              /* tp_getset */
+0,                                              /* tp_base */
+0,                                              /* tp_dict */
+0,                                              /* tp_descr_get */
+0,                                              /* tp_descr_set */
+0,                                              /* tp_dictoffset */
+0,                          /* tp_init */
+0,                                              /* tp_alloc */
+TrackHold_new,                                     /* tp_new */
+};
+
+/************/
 /* Compare */
 /************/
 typedef struct {
diff --git a/src/objects/wgverbmodule.c b/src/objects/wgverbmodule.c
index 79970ce..1fa6d06 100644
--- a/src/objects/wgverbmodule.c
+++ b/src/objects/wgverbmodule.c
@@ -26,18 +26,20 @@
 #include "servermodule.h"
 #include "dummymodule.h"
 
+#define NUM_REFS  13
 
 static const MYFLT randomScaling = 0.5;
-static const MYFLT reverbParams[8][3] = {
-{ 2473.0, 0.0010, 3.100 },
-{ 2767.0, 0.0011, 3.500 },
-{ 3217.0, 0.0017, 1.110 },
-{ 3557.0, 0.0006, 3.973 },
-{ 3907.0, 0.0010, 2.341 },
-{ 4127.0, 0.0011, 1.897 },
-{ 2143.0, 0.0017, 0.891 },
-{ 1933.0, 0.0006, 3.221 }
-};
+static const MYFLT reverbParams[8][4] = {
+{ 2473.0, 0.0010, 3.100, 2503.0 },
+{ 2767.0, 0.0011, 3.500, 2749.0 },
+{ 3217.0, 0.0017, 1.110, 3187.0 },
+{ 3557.0, 0.0006, 3.973, 3583.0 },
+{ 3907.0, 0.0010, 2.341, 3929.0 },
+{ 4127.0, 0.0011, 1.897, 4093.0 },
+{ 2143.0, 0.0017, 0.891, 2131.0 },
+{ 1933.0, 0.0006, 3.221, 1951.0 }};
+
+static const MYFLT first_ref_delays[NUM_REFS] = {283, 467, 587, 677, 757, 911, 1117, 1223, 1307, 1429, 1553, 1613, 1783};
 
 typedef struct {
     pyo_audio_HEAD
@@ -486,12 +488,6 @@ WGVerb_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     self->mix = PyFloat_FromDouble(0.5);
     self->lastFreq = self->damp = 0.0;
     
-    for (i=0; i<8; i++) {
-        self->in_count[i] = 0;
-        self->lastSamples[i] = 0.0;
-        self->rnd_value[i] = self->rnd_oldValue[i] = self->rnd_diff[i] = 0.0;
-        self->rnd_time[i] = 1.0;
-    }    
     self->total_signal = 0.0;
 	self->modebuffer[0] = 0;
 	self->modebuffer[1] = 0;
@@ -770,7 +766,7 @@ sizeof(WGVerb),         /*tp_basicsize*/
 0,                         /*tp_setattro*/
 0,                         /*tp_as_buffer*/
 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
-"WGVerb objects. WGVerb signal by x samples.",           /* tp_doc */
+"WGVerb objects. Waveguide-based reverberation network.",           /* tp_doc */
 (traverseproc)WGVerb_traverse,   /* tp_traverse */
 (inquiry)WGVerb_clear,           /* tp_clear */
 0,		               /* tp_richcompare */
@@ -789,3 +785,1327 @@ WGVerb_members,             /* tp_members */
 0,                         /* tp_alloc */
 WGVerb_new,                 /* tp_new */
 };
+
+/***************/
+/**** STRev ****/
+/***************/
+typedef struct {
+    pyo_audio_HEAD
+    PyObject *input;
+    Stream *input_stream;
+    PyObject *inpos;
+    Stream *inpos_stream;
+    PyObject *revtime;
+    Stream *revtime_stream;
+    PyObject *cutoff;
+    Stream *cutoff_stream;
+    PyObject *mix;
+    Stream *mix_stream;
+    void (*mix_func_ptr)();
+    int modebuffer[4];
+    MYFLT firstRefGain;
+    MYFLT total_signal[2];
+    MYFLT delays[2][8];
+    long size[2][8];
+    int in_count[2][8];
+    MYFLT *buffer[2][8];
+    MYFLT *ref_buffer[NUM_REFS];
+    int ref_size[NUM_REFS];
+    int ref_in_count[NUM_REFS];
+    MYFLT avg_time;
+    MYFLT srfac;
+    // lowpass
+    MYFLT damp[2];
+    MYFLT lastFreq;
+    MYFLT nyquist;
+    MYFLT lastInpos;
+    // sample memories
+    MYFLT lastSamples[2][8];
+    // jitters
+    MYFLT rnd[2][8];
+    MYFLT rnd_value[2][8];
+    MYFLT rnd_oldValue[2][8];
+    MYFLT rnd_diff[2][8];
+    MYFLT rnd_time[2][8];
+    MYFLT rnd_timeInc[2][8];
+    MYFLT rnd_range[2][8];
+    MYFLT rnd_halfRange[2][8];
+    MYFLT *buffer_streams;
+    MYFLT *input_buffer[2];
+} STReverb;
+
+static void
+STReverb_process_ii(STReverb *self) {
+    int i, j, k, k2, ind, half;
+    MYFLT val, x, x1, xind, frac, junction, inval, filt, amp1, amp2, b, f, sum_ref, feed, step, invp;
+    MYFLT ref_amp_l[NUM_REFS];
+    MYFLT ref_amp_r[NUM_REFS];
+    MYFLT ref_buf[2];
+    
+    MYFLT *in = Stream_getData((Stream *)self->input_stream);
+    MYFLT inpos = PyFloat_AS_DOUBLE(self->inpos);
+    if (self->modebuffer[1] == 0)
+        feed = PyFloat_AS_DOUBLE(self->revtime);
+    else
+        feed = Stream_getData((Stream *)self->revtime_stream)[0];
+    MYFLT freq = PyFloat_AS_DOUBLE(self->cutoff);
+        
+    if (inpos < 0.0)
+        inpos = 0.0;
+    else if (inpos > 1.0)
+        inpos = 1.0;
+       
+    if (feed < 0.01)
+        feed = 0.01;
+    feed = MYPOW(100.0, -self->avg_time/feed);
+
+    if (freq < 20.0)
+        freq = 20.0;
+    else if (freq > self->nyquist)
+        freq = self->nyquist;
+
+    if (freq != self->lastFreq || inpos != self->lastInpos) {
+        self->lastFreq = freq;
+        self->lastInpos = inpos;
+        f = ((1.0 - inpos) * 0.3 + 0.7) * freq;
+        b = 2.0 - MYCOS(TWOPI * f / self->sr);
+        self->damp[0] = (b - MYSQRT(b * b - 1.0));
+        f = (inpos * 0.3 + 0.7) * freq;
+        b = 2.0 - MYCOS(TWOPI * f / self->sr);
+        self->damp[1] = (b - MYSQRT(b * b - 1.0));
+    }
+
+    /* position of the source and first reflexions */
+    amp1 = 1.0 - inpos;
+    amp2 = inpos;
+    half = (NUM_REFS - 1) / 2;
+    if (inpos <= 0.5) {
+        step = (0.5 - inpos) / half;
+        ref_amp_l[half] = ref_amp_r[half] = 0.5;
+        for (k=0; k<half; k++) {
+            k2 = NUM_REFS - 1 - k;
+            ref_amp_r[k] = ref_amp_l[k2] = inpos + step * k;
+            ref_amp_l[k] = ref_amp_r[k2] = 1.0 - ref_amp_r[k];
+            ref_amp_r[k2] *= inpos + 0.5;
+        }
+    }
+    else {
+        invp = 1.0 - inpos;
+        step = (0.5 - invp) / half;
+        ref_amp_l[half] = ref_amp_r[half] = 0.5;
+        for (k=0; k<half; k++) {
+            k2 = NUM_REFS - 1 - k;
+            ref_amp_l[k] = ref_amp_r[k2] = invp + step * k;
+            ref_amp_r[k] = ref_amp_l[k2] = 1.0 - ref_amp_l[k];
+            ref_amp_l[k2] *= invp + 0.5;
+        }
+    }
+
+    for (i=0; i<self->bufsize; i++) {
+        self->input_buffer[0][i] = in[i] * amp1;
+        self->input_buffer[1][i] = in[i] * amp2;
+        ref_buf[0] = ref_buf[1] = 0.0;
+        for (k=0; k<NUM_REFS; k++) {
+            sum_ref = self->ref_buffer[k][self->ref_in_count[k]];
+            self->ref_buffer[k][self->ref_in_count[k]] = in[i];
+            self->ref_in_count[k]++;
+            if (self->ref_in_count[k] == self->ref_size[k])
+                self->ref_in_count[k] = 0;
+            ref_buf[0] += sum_ref * ref_amp_l[k];
+            ref_buf[1] += sum_ref * ref_amp_r[k];
+        }
+        for (k=0; k<2; k++) {
+            inval = self->input_buffer[k][i] * 0.8 + self->input_buffer[1-k][i] * 0.2 + ref_buf[k] * 0.1;
+            junction = self->total_signal[k] * .25;
+            self->total_signal[k] = ref_buf[k] * self->firstRefGain;
+            for (j=0; j<8; j++) {
+                self->rnd_time[k][j] += self->rnd_timeInc[k][j];
+                if (self->rnd_time[k][j] < 0.0)
+                    self->rnd_time[k][j] += 1.0;
+                else if (self->rnd_time[k][j] >= 1.0) {
+                    self->rnd_time[k][j] -= 1.0;
+                    self->rnd_oldValue[k][j] = self->rnd_value[k][j];
+                    self->rnd_value[k][j] = self->rnd_range[k][j] * (rand()/((MYFLT)(RAND_MAX)+1)) - self->rnd_halfRange[k][j];
+                    self->rnd_diff[k][j] = self->rnd_value[k][j] - self->rnd_oldValue[k][j];
+                }
+                self->rnd[k][j] = self->rnd_oldValue[k][j] + self->rnd_diff[k][j] * self->rnd_time[k][j];
+                
+                xind = self->in_count[k][j] - (self->delays[k][j] + self->rnd[k][j]);
+                if (xind < 0)
+                    xind += self->size[k][j];
+                ind = (int)xind;
+                frac = xind - ind;
+                x = self->buffer[k][j][ind];
+                x1 = self->buffer[k][j][ind+1];
+                val = x + (x1 - x) * frac;
+                val *= feed;
+                filt = val + (self->lastSamples[k][j] - val) * self->damp[k];
+                self->total_signal[k] += filt;
+            
+                self->buffer[k][j][self->in_count[k][j]] = inval + junction - self->lastSamples[k][j];
+                self->lastSamples[k][j] = filt;
+                if(self->in_count[k][j] == 0)
+                    self->buffer[k][j][self->size[k][j]] = self->buffer[k][j][0];
+                self->in_count[k][j]++;
+                if (self->in_count[k][j] >= self->size[k][j])
+                    self->in_count[k][j] = 0;
+            } 
+            self->buffer_streams[i+k*self->bufsize] = self->total_signal[k] * 0.25;
+        }
+    }
+}
+
+static void
+STReverb_process_ai(STReverb *self) {
+    MYFLT val, x, x1, xind, frac, junction, inval, filt, amp1, amp2, b, f, sum_ref, inpos, feed, step, invp;
+    MYFLT ref_amp_l[NUM_REFS];
+    MYFLT ref_amp_r[NUM_REFS];
+    MYFLT ref_buf[2];
+    int i, j, k, k2, ind, half;
+    
+    MYFLT *in = Stream_getData((Stream *)self->input_stream);
+    MYFLT *pos = Stream_getData((Stream *)self->inpos_stream);
+    if (self->modebuffer[1] == 0)
+        feed = PyFloat_AS_DOUBLE(self->revtime);
+    else
+        feed = Stream_getData((Stream *)self->revtime_stream)[0];
+    MYFLT freq = PyFloat_AS_DOUBLE(self->cutoff);
+
+    if (feed < 0.01)
+        feed = 0.01;
+    feed = MYPOW(100.0, -self->avg_time/feed);
+
+    if (freq < 20.0)
+        freq = 20.0;
+    else if (freq > self->nyquist)
+        freq = self->nyquist;
+
+    for (i=0; i<self->bufsize; i++) {
+        inpos = pos[i];
+        if (inpos < 0.0)
+            inpos = 0.0;
+        else if (inpos > 1.0)
+            inpos = 1.0;
+        if (freq != self->lastFreq || inpos != self->lastInpos) {
+            self->lastFreq = freq;
+            self->lastInpos = inpos;
+            f = ((1.0 - inpos) * 0.3 + 0.7) * freq;
+            b = 2.0 - MYCOS(TWOPI * f / self->sr);
+            self->damp[0] = (b - MYSQRT(b * b - 1.0));
+            f = (inpos * 0.3 + 0.7) * freq;
+            b = 2.0 - MYCOS(TWOPI * f / self->sr);
+            self->damp[1] = (b - MYSQRT(b * b - 1.0));
+        }
+
+        /* position of the source and first reflexions */
+        amp1 = 1.0 - inpos;
+        amp2 = inpos;
+        half = (NUM_REFS - 1) / 2;
+        if (inpos <= 0.5) {
+            step = (0.5 - inpos) / half;
+            ref_amp_l[half] = ref_amp_r[half] = 0.5;
+            for (k=0; k<half; k++) {
+                k2 = NUM_REFS - 1 - k;
+                ref_amp_r[k] = ref_amp_l[k2] = inpos + step * k;
+                ref_amp_l[k] = ref_amp_r[k2] = 1.0 - ref_amp_r[k];
+                ref_amp_r[k2] *= inpos + 0.5;
+            }
+        }
+        else {
+            invp = 1.0 - inpos;
+            step = (0.5 - invp) / half;
+            ref_amp_l[half] = ref_amp_r[half] = 0.5;
+            for (k=0; k<half; k++) {
+                k2 = NUM_REFS - 1 - k;
+                ref_amp_l[k] = ref_amp_r[k2] = invp + step * k;
+                ref_amp_r[k] = ref_amp_l[k2] = 1.0 - ref_amp_l[k];
+                ref_amp_l[k2] *= invp + 0.5;
+            }
+        }
+
+        self->input_buffer[0][i] = in[i] * amp1;
+        self->input_buffer[1][i] = in[i] * amp2;
+        ref_buf[0] = ref_buf[1] = 0.0;
+        for (k=0; k<NUM_REFS; k++) {
+            sum_ref = self->ref_buffer[k][self->ref_in_count[k]];
+            self->ref_buffer[k][self->ref_in_count[k]] = in[i];
+            self->ref_in_count[k]++;
+            if (self->ref_in_count[k] == self->ref_size[k])
+                self->ref_in_count[k] = 0;
+            ref_buf[0] += sum_ref * ref_amp_l[k];
+            ref_buf[1] += sum_ref * ref_amp_r[k];
+        }
+        for (k=0; k<2; k++) {
+            inval = self->input_buffer[k][i] * 0.8 + self->input_buffer[1-k][i] * 0.2 + ref_buf[k] * 0.1;
+            junction = self->total_signal[k] * .25;
+            self->total_signal[k] = ref_buf[k] * self->firstRefGain;
+            for (j=0; j<8; j++) {
+                self->rnd_time[k][j] += self->rnd_timeInc[k][j];
+                if (self->rnd_time[k][j] < 0.0)
+                    self->rnd_time[k][j] += 1.0;
+                else if (self->rnd_time[k][j] >= 1.0) {
+                    self->rnd_time[k][j] -= 1.0;
+                    self->rnd_oldValue[k][j] = self->rnd_value[k][j];
+                    self->rnd_value[k][j] = self->rnd_range[k][j] * (rand()/((MYFLT)(RAND_MAX)+1)) - self->rnd_halfRange[k][j];
+                    self->rnd_diff[k][j] = self->rnd_value[k][j] - self->rnd_oldValue[k][j];
+                }
+                self->rnd[k][j] = self->rnd_oldValue[k][j] + self->rnd_diff[k][j] * self->rnd_time[k][j];
+                
+                xind = self->in_count[k][j] - (self->delays[k][j] + self->rnd[k][j]);
+                if (xind < 0)
+                    xind += self->size[k][j];
+                ind = (int)xind;
+                frac = xind - ind;
+                x = self->buffer[k][j][ind];
+                x1 = self->buffer[k][j][ind+1];
+                val = x + (x1 - x) * frac;
+                val *= feed;
+                filt = val + (self->lastSamples[k][j] - val) * self->damp[k];
+                self->total_signal[k] += filt;
+            
+                self->buffer[k][j][self->in_count[k][j]] = inval + junction - self->lastSamples[k][j];
+                self->lastSamples[k][j] = filt;
+                if(self->in_count[k][j] == 0)
+                    self->buffer[k][j][self->size[k][j]] = self->buffer[k][j][0];
+                self->in_count[k][j]++;
+                if (self->in_count[k][j] >= self->size[k][j])
+                    self->in_count[k][j] = 0;
+            } 
+            self->buffer_streams[i+k*self->bufsize] = self->total_signal[k] * 0.25;
+        }
+    }
+}
+
+static void
+STReverb_process_ia(STReverb *self) {
+    MYFLT val, x, x1, xind, frac, junction, inval, filt, amp1, amp2, b, f, sum_ref, feed, freq, step, invp;
+    MYFLT ref_amp_l[NUM_REFS];
+    MYFLT ref_amp_r[NUM_REFS];
+    MYFLT ref_buf[2];
+    int i, j, k, k2, ind, half;
+    
+    MYFLT *in = Stream_getData((Stream *)self->input_stream);
+    MYFLT inpos = PyFloat_AS_DOUBLE(self->inpos);
+    if (self->modebuffer[1] == 0)
+        feed = PyFloat_AS_DOUBLE(self->revtime);
+    else
+        feed = Stream_getData((Stream *)self->revtime_stream)[0];
+    MYFLT *fr = Stream_getData((Stream *)self->cutoff_stream);
+        
+    if (inpos < 0.0)
+        inpos = 0.0;
+    else if (inpos > 1.0)
+        inpos = 1.0;
+       
+    if (feed < 0.01)
+        feed = 0.01;
+    feed = MYPOW(100.0, -self->avg_time/feed);
+
+    /* position of the source and first reflexions */
+    amp1 = 1.0 - inpos;
+    amp2 = inpos;
+    half = (NUM_REFS - 1) / 2;
+    if (inpos <= 0.5) {
+        step = (0.5 - inpos) / half;
+        ref_amp_l[half] = ref_amp_r[half] = 0.5;
+        for (k=0; k<half; k++) {
+            k2 = NUM_REFS - 1 - k;
+            ref_amp_r[k] = ref_amp_l[k2] = inpos + step * k;
+            ref_amp_l[k] = ref_amp_r[k2] = 1.0 - ref_amp_r[k];
+            ref_amp_r[k2] *= inpos + 0.5;
+        }
+    }
+    else {
+        invp = 1.0 - inpos;
+        step = (0.5 - invp) / half;
+        ref_amp_l[half] = ref_amp_r[half] = 0.5;
+        for (k=0; k<half; k++) {
+            k2 = NUM_REFS - 1 - k;
+            ref_amp_l[k] = ref_amp_r[k2] = invp + step * k;
+            ref_amp_r[k] = ref_amp_l[k2] = 1.0 - ref_amp_l[k];
+            ref_amp_l[k2] *= invp + 0.5;
+        }
+    }
+
+    for (i=0; i<self->bufsize; i++) {
+        freq = fr[i];
+        if (freq < 20.0)
+            freq = 20.0;
+        else if (freq > self->nyquist)
+            freq = self->nyquist;
+
+        if (freq != self->lastFreq || inpos != self->lastInpos) {
+            self->lastFreq = freq;
+            self->lastInpos = inpos;
+            f = ((1.0 - inpos) * 0.3 + 0.7) * freq;
+            b = 2.0 - MYCOS(TWOPI * f / self->sr);
+            self->damp[0] = (b - MYSQRT(b * b - 1.0));
+            f = (inpos * 0.3 + 0.7) * freq;
+            b = 2.0 - MYCOS(TWOPI * f / self->sr);
+            self->damp[1] = (b - MYSQRT(b * b - 1.0));
+        }
+
+        self->input_buffer[0][i] = in[i] * amp1;
+        self->input_buffer[1][i] = in[i] * amp2;
+        ref_buf[0] = ref_buf[1] = 0.0;
+        for (k=0; k<NUM_REFS; k++) {
+            sum_ref = self->ref_buffer[k][self->ref_in_count[k]];
+            self->ref_buffer[k][self->ref_in_count[k]] = in[i];
+            self->ref_in_count[k]++;
+            if (self->ref_in_count[k] == self->ref_size[k])
+                self->ref_in_count[k] = 0;
+            ref_buf[0] += sum_ref * ref_amp_l[k];
+            ref_buf[1] += sum_ref * ref_amp_r[k];
+        }
+        for (k=0; k<2; k++) {
+            inval = self->input_buffer[k][i] * 0.8 + self->input_buffer[1-k][i] * 0.2 + ref_buf[k] * 0.1;
+            junction = self->total_signal[k] * .25;
+            self->total_signal[k] = ref_buf[k] * self->firstRefGain;
+            for (j=0; j<8; j++) {
+                self->rnd_time[k][j] += self->rnd_timeInc[k][j];
+                if (self->rnd_time[k][j] < 0.0)
+                    self->rnd_time[k][j] += 1.0;
+                else if (self->rnd_time[k][j] >= 1.0) {
+                    self->rnd_time[k][j] -= 1.0;
+                    self->rnd_oldValue[k][j] = self->rnd_value[k][j];
+                    self->rnd_value[k][j] = self->rnd_range[k][j] * (rand()/((MYFLT)(RAND_MAX)+1)) - self->rnd_halfRange[k][j];
+                    self->rnd_diff[k][j] = self->rnd_value[k][j] - self->rnd_oldValue[k][j];
+                }
+                self->rnd[k][j] = self->rnd_oldValue[k][j] + self->rnd_diff[k][j] * self->rnd_time[k][j];
+                
+                xind = self->in_count[k][j] - (self->delays[k][j] + self->rnd[k][j]);
+                if (xind < 0)
+                    xind += self->size[k][j];
+                ind = (int)xind;
+                frac = xind - ind;
+                x = self->buffer[k][j][ind];
+                x1 = self->buffer[k][j][ind+1];
+                val = x + (x1 - x) * frac;
+                val *= feed;
+                filt = val + (self->lastSamples[k][j] - val) * self->damp[k];
+                self->total_signal[k] += filt;
+            
+                self->buffer[k][j][self->in_count[k][j]] = inval + junction - self->lastSamples[k][j];
+                self->lastSamples[k][j] = filt;
+                if(self->in_count[k][j] == 0)
+                    self->buffer[k][j][self->size[k][j]] = self->buffer[k][j][0];
+                self->in_count[k][j]++;
+                if (self->in_count[k][j] >= self->size[k][j])
+                    self->in_count[k][j] = 0;
+            } 
+            self->buffer_streams[i+k*self->bufsize] = self->total_signal[k] * 0.25;
+        }
+    }
+}
+
+static void
+STReverb_process_aa(STReverb *self) {
+    MYFLT val, x, x1, xind, frac, junction, inval, filt, amp1, amp2, b, f, sum_ref, inpos, feed, freq, step, invp;
+    MYFLT ref_amp_l[NUM_REFS];
+    MYFLT ref_amp_r[NUM_REFS];
+    MYFLT ref_buf[2];
+    int i, j, k, k2, ind, half;
+    
+    MYFLT *in = Stream_getData((Stream *)self->input_stream);
+    MYFLT *pos = Stream_getData((Stream *)self->inpos_stream);
+    if (self->modebuffer[1] == 0)
+        feed = PyFloat_AS_DOUBLE(self->revtime);
+    else
+        feed = Stream_getData((Stream *)self->revtime_stream)[0];
+    MYFLT *fr = Stream_getData((Stream *)self->cutoff_stream);
+
+    if (feed < 0.01)
+        feed = 0.01;
+    feed = MYPOW(100.0, -self->avg_time/feed);
+
+    for (i=0; i<self->bufsize; i++) {
+        inpos = pos[i];
+        freq = fr[i];
+        if (inpos < 0.0)
+            inpos = 0.0;
+        else if (inpos > 1.0)
+            inpos = 1.0;
+        if (freq < 20.0)
+            freq = 20.0;
+        else if (freq > self->nyquist)
+            freq = self->nyquist;
+
+        if (freq != self->lastFreq || inpos != self->lastInpos) {
+            self->lastFreq = freq;
+            self->lastInpos = inpos;
+            f = ((1.0 - inpos) * 0.3 + 0.7) * freq;
+            b = 2.0 - MYCOS(TWOPI * f / self->sr);
+            self->damp[0] = (b - MYSQRT(b * b - 1.0));
+            f = (inpos * 0.3 + 0.7) * freq;
+            b = 2.0 - MYCOS(TWOPI * f / self->sr);
+            self->damp[1] = (b - MYSQRT(b * b - 1.0));
+        }
+
+        /* position of the source and first reflexions */
+        amp1 = 1.0 - inpos;
+        amp2 = inpos;
+        half = (NUM_REFS - 1) / 2;
+        if (inpos <= 0.5) {
+            step = (0.5 - inpos) / half;
+            ref_amp_l[half] = ref_amp_r[half] = 0.5;
+            for (k=0; k<half; k++) {
+                k2 = NUM_REFS - 1 - k;
+                ref_amp_r[k] = ref_amp_l[k2] = inpos + step * k;
+                ref_amp_l[k] = ref_amp_r[k2] = 1.0 - ref_amp_r[k];
+                ref_amp_r[k2] *= inpos + 0.5;
+            }
+        }
+        else {
+            invp = 1.0 - inpos;
+            step = (0.5 - invp) / half;
+            ref_amp_l[half] = ref_amp_r[half] = 0.5;
+            for (k=0; k<half; k++) {
+                k2 = NUM_REFS - 1 - k;
+                ref_amp_l[k] = ref_amp_r[k2] = invp + step * k;
+                ref_amp_r[k] = ref_amp_l[k2] = 1.0 - ref_amp_l[k];
+                ref_amp_l[k2] *= invp + 0.5;
+            }
+        }
+
+        self->input_buffer[0][i] = in[i] * amp1;
+        self->input_buffer[1][i] = in[i] * amp2;
+        ref_buf[0] = ref_buf[1] = 0.0;
+        for (k=0; k<NUM_REFS; k++) {
+            sum_ref = self->ref_buffer[k][self->ref_in_count[k]];
+            self->ref_buffer[k][self->ref_in_count[k]] = in[i];
+            self->ref_in_count[k]++;
+            if (self->ref_in_count[k] == self->ref_size[k])
+                self->ref_in_count[k] = 0;
+            ref_buf[0] += sum_ref * ref_amp_l[k];
+            ref_buf[1] += sum_ref * ref_amp_r[k];
+        }
+        for (k=0; k<2; k++) {
+            inval = self->input_buffer[k][i] * 0.8 + self->input_buffer[1-k][i] * 0.2 + ref_buf[k] * 0.1;
+            junction = self->total_signal[k] * .25;
+            self->total_signal[k] = ref_buf[k] * self->firstRefGain;
+            for (j=0; j<8; j++) {
+                self->rnd_time[k][j] += self->rnd_timeInc[k][j];
+                if (self->rnd_time[k][j] < 0.0)
+                    self->rnd_time[k][j] += 1.0;
+                else if (self->rnd_time[k][j] >= 1.0) {
+                    self->rnd_time[k][j] -= 1.0;
+                    self->rnd_oldValue[k][j] = self->rnd_value[k][j];
+                    self->rnd_value[k][j] = self->rnd_range[k][j] * (rand()/((MYFLT)(RAND_MAX)+1)) - self->rnd_halfRange[k][j];
+                    self->rnd_diff[k][j] = self->rnd_value[k][j] - self->rnd_oldValue[k][j];
+                }
+                self->rnd[k][j] = self->rnd_oldValue[k][j] + self->rnd_diff[k][j] * self->rnd_time[k][j];
+                
+                xind = self->in_count[k][j] - (self->delays[k][j] + self->rnd[k][j]);
+                if (xind < 0)
+                    xind += self->size[k][j];
+                ind = (int)xind;
+                frac = xind - ind;
+                x = self->buffer[k][j][ind];
+                x1 = self->buffer[k][j][ind+1];
+                val = x + (x1 - x) * frac;
+                val *= feed;
+                filt = val + (self->lastSamples[k][j] - val) * self->damp[k];
+                self->total_signal[k] += filt;
+            
+                self->buffer[k][j][self->in_count[k][j]] = inval + junction - self->lastSamples[k][j];
+                self->lastSamples[k][j] = filt;
+                if(self->in_count[k][j] == 0)
+                    self->buffer[k][j][self->size[k][j]] = self->buffer[k][j][0];
+                self->in_count[k][j]++;
+                if (self->in_count[k][j] >= self->size[k][j])
+                    self->in_count[k][j] = 0;
+            } 
+            self->buffer_streams[i+k*self->bufsize] = self->total_signal[k] * 0.25;
+        }
+    }
+}
+
+static void
+STReverb_mix_i(STReverb *self) {
+    int i, k;
+    MYFLT val;
+    
+    MYFLT mix = PyFloat_AS_DOUBLE(self->mix);
+    
+    if (mix < 0.0)
+        mix = 0.0;
+    else if (mix > 1.0)
+        mix = 1.0;
+    
+    for (i=0; i<self->bufsize; i++) {
+        for (k=0; k<2; k++) {
+            val = self->input_buffer[k][i] + (self->buffer_streams[i+k*self->bufsize] - self->input_buffer[k][i]) * mix;
+            self->buffer_streams[i+k*self->bufsize] = val;
+        }
+    }
+}
+
+static void
+STReverb_mix_a(STReverb *self) {
+    int i, k;
+    MYFLT mix, val;
+    
+    MYFLT *mi = Stream_getData((Stream *)self->mix_stream);
+    
+    for (i=0; i<self->bufsize; i++) {
+        mix = mi[i];
+        if (mix < 0.0)
+            mix = 0.0;
+        else if (mix > 1.0)
+            mix = 1.0;
+        
+        for (k=0; k<2; k++) {
+            val = self->input_buffer[k][i] + (self->buffer_streams[i+k*self->bufsize] - self->input_buffer[k][i]) * mix;
+            self->buffer_streams[i+k*self->bufsize] = val;
+        }
+    }
+}
+
+static void
+STReverb_setProcMode(STReverb *self)
+{
+    int procmode, mixmode;
+    procmode = self->modebuffer[0] + self->modebuffer[2] * 10;
+    mixmode = self->modebuffer[3];
+    
+	switch (procmode) {
+        case 0:    
+            self->proc_func_ptr = STReverb_process_ii;
+            break;
+        case 1:    
+            self->proc_func_ptr = STReverb_process_ai;
+            break;
+        case 10:    
+            self->proc_func_ptr = STReverb_process_ia;
+            break;
+        case 11:    
+            self->proc_func_ptr = STReverb_process_aa;
+            break;
+    } 
+    switch (mixmode) {
+        case 0:    
+            self->mix_func_ptr = STReverb_mix_i;
+            break;
+        case 1:    
+            self->mix_func_ptr = STReverb_mix_a;
+            break;
+    }
+}
+
+MYFLT *
+STReverb_getSamplesBuffer(STReverb *self)
+{
+    return (MYFLT *)self->buffer_streams;
+}    
+
+static void
+STReverb_compute_next_data_frame(STReverb *self)
+{
+    (*self->proc_func_ptr)(self); 
+    (*self->mix_func_ptr)(self); 
+}
+
+static int
+STReverb_traverse(STReverb *self, visitproc visit, void *arg)
+{
+    pyo_VISIT
+    Py_VISIT(self->input);
+    Py_VISIT(self->input_stream);    
+    Py_VISIT(self->inpos);    
+    Py_VISIT(self->inpos_stream);    
+    Py_VISIT(self->revtime);    
+    Py_VISIT(self->revtime_stream);    
+    Py_VISIT(self->cutoff);    
+    Py_VISIT(self->cutoff_stream);    
+    Py_VISIT(self->mix);    
+    Py_VISIT(self->mix_stream);    
+    return 0;
+}
+
+static int 
+STReverb_clear(STReverb *self)
+{
+    pyo_CLEAR
+    Py_CLEAR(self->input);
+    Py_CLEAR(self->input_stream);    
+    Py_CLEAR(self->inpos);    
+    Py_CLEAR(self->inpos_stream);    
+    Py_CLEAR(self->revtime);    
+    Py_CLEAR(self->revtime_stream);    
+    Py_CLEAR(self->cutoff);    
+    Py_CLEAR(self->cutoff_stream);    
+    Py_CLEAR(self->mix);    
+    Py_CLEAR(self->mix_stream);    
+    return 0;
+}
+
+static void
+STReverb_dealloc(STReverb* self)
+{
+    int i, k;
+    pyo_DEALLOC
+    for (k=0; k<2; k++) {
+            free(self->input_buffer[k]);
+        for (i=0; i<8; i++) {
+            free(self->buffer[k][i]);
+        }
+    }
+    for (i=0; i<NUM_REFS; i++) {
+        free(self->ref_buffer[i]);
+    }
+    free(self->buffer_streams);
+    STReverb_clear(self);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+STReverb_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    int i, j, k, din;
+    long maxsize;
+    MYFLT roomSize = 1.0;
+    MYFLT firstRefTmp = -3.0;
+    PyObject *inputtmp, *input_streamtmp, *inpostmp=NULL, *revtimetmp=NULL, *cutofftmp=NULL, *mixtmp=NULL;
+    STReverb *self;
+    self = (STReverb *)type->tp_alloc(type, 0);
+    
+    self->inpos = PyFloat_FromDouble(0.5);
+    self->revtime = PyFloat_FromDouble(0.5);
+    self->cutoff = PyFloat_FromDouble(5000.0);
+    self->mix = PyFloat_FromDouble(0.5);
+    self->total_signal[0] = self->total_signal[1] = self->lastFreq = self->damp[0] = self->damp[1] = 0.0;
+    self->lastInpos = -1.0;
+	self->modebuffer[0] = 0;
+	self->modebuffer[1] = 0;
+	self->modebuffer[2] = 0;
+    
+    INIT_OBJECT_COMMON
+    
+    self->nyquist = self->sr * 0.49;
+    self->srfac = self->sr / 44100.0;
+
+    Stream_setFunctionPtr(self->stream, STReverb_compute_next_data_frame);
+    self->mode_func_ptr = STReverb_setProcMode;
+
+    static char *kwlist[] = {"input", "inpos", "revtime", "cutoff", "mix", "roomSize", "firstRefGain", NULL};
+    
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_O_OOOOFF, kwlist, &inputtmp, &inpostmp, &revtimetmp, &cutofftmp, &mixtmp, &roomSize, &firstRefTmp))
+        Py_RETURN_NONE;
+    
+    INIT_INPUT_STREAM
+
+    if (inpostmp) {
+        PyObject_CallMethod((PyObject *)self, "setInpos", "O", inpostmp);
+    }
+       
+    if (revtimetmp) {
+        PyObject_CallMethod((PyObject *)self, "setRevtime", "O", revtimetmp);
+    }
+
+    if (cutofftmp) {
+        PyObject_CallMethod((PyObject *)self, "setCutoff", "O", cutofftmp);
+    }
+
+    if (mixtmp) {
+        PyObject_CallMethod((PyObject *)self, "setMix", "O", mixtmp);
+    }
+
+    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
+
+    self->firstRefGain = MYPOW(10.0, firstRefTmp * 0.05);
+    if (roomSize < 0.25)
+        roomSize = 0.25;
+    else if (roomSize > 4.0)
+        roomSize = 4.0;
+
+    self->avg_time = 0.0;
+    for (k=0; k<2; k++) {
+        din = k * 3;
+        for (i=0; i<8; i++) {
+            self->in_count[k][i] = 0;
+            self->lastSamples[k][i] = 0.0;
+            self->rnd[k][i] = self->rnd_value[k][i] = self->rnd_oldValue[k][i] = self->rnd_diff[k][i] = 0.0;
+            self->rnd_time[k][i] = 1.0;
+            self->rnd_timeInc[k][i] = reverbParams[i][2] * randomScaling / self->sr;
+            self->rnd_range[k][i] = reverbParams[i][1] * randomScaling * self->sr;
+            self->rnd_halfRange[k][i] = self->rnd_range[k][i] * 0.5;
+            self->delays[k][i] = reverbParams[i][din] * self->srfac * roomSize;
+            self->avg_time += self->delays[k][i] / self->sr;
+            self->size[k][i] = reverbParams[i][din] * self->srfac * roomSize + (int)(reverbParams[i][1] * self->sr + 0.5);
+            maxsize = reverbParams[i][din] * self->srfac * 4.0 + (int)(reverbParams[i][1] * self->sr + 0.5);
+            self->buffer[k][i] = (MYFLT *)realloc(self->buffer[k][i], (maxsize+1) * sizeof(MYFLT));
+            for (j=0; j<(maxsize+1); j++) {
+                self->buffer[k][i][j] = 0.;
+            }
+        }    
+    }
+    self->avg_time /= 16.0;
+
+    for (k=0; k<NUM_REFS; k++) {
+        self->ref_in_count[k] = 0;
+        self->ref_size[k] = (int)(first_ref_delays[k] * self->srfac * roomSize + 0.5);
+        maxsize = (int)(first_ref_delays[k] * self->srfac * 4.0 + 0.5);
+        self->ref_buffer[k] = (MYFLT *)realloc(self->ref_buffer[k], (maxsize+1) * sizeof(MYFLT));
+        for (i=0; i<(maxsize+1); i++) {
+            self->ref_buffer[k][i] = 0.0;
+        }
+    }
+
+    for (k=0; k<2; k++) {
+        self->input_buffer[k] = (MYFLT *)realloc(self->input_buffer[k], self->bufsize * sizeof(MYFLT));
+        for (i=0; i<self->bufsize; i++) {
+            self->input_buffer[k][i] = 0.0;
+        }
+    }
+
+    self->buffer_streams = (MYFLT *)realloc(self->buffer_streams, 2 * self->bufsize * sizeof(MYFLT));
+    for (i=0; i<(2 * self->bufsize); i++) {
+        self->buffer_streams[i] = 0.0;
+    }
+
+    (*self->mode_func_ptr)(self);
+
+    return (PyObject *)self;
+}
+
+static PyObject * STReverb_getServer(STReverb* self) { GET_SERVER };
+static PyObject * STReverb_getStream(STReverb* self) { GET_STREAM };
+
+static PyObject * STReverb_play(STReverb *self, PyObject *args, PyObject *kwds) { PLAY };
+static PyObject * STReverb_stop(STReverb *self) { STOP };
+
+static PyObject *
+STReverb_setInpos(STReverb *self, PyObject *arg)
+{
+	PyObject *tmp, *streamtmp;
+	
+	if (arg == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+	int isNumber = PyNumber_Check(arg);
+    
+	tmp = arg;
+	Py_INCREF(tmp);
+	Py_DECREF(self->inpos);
+	if (isNumber == 1) {
+		self->inpos = PyNumber_Float(tmp);
+        self->modebuffer[0] = 0;
+	}
+	else {
+		self->inpos = tmp;
+        streamtmp = PyObject_CallMethod((PyObject *)self->inpos, "_getStream", NULL);
+        Py_INCREF(streamtmp);
+        Py_XDECREF(self->inpos_stream);
+        self->inpos_stream = (Stream *)streamtmp;
+		self->modebuffer[0] = 1;
+	}
+    
+    (*self->mode_func_ptr)(self);
+    
+	Py_INCREF(Py_None);
+	return Py_None;
+}	
+
+static PyObject *
+STReverb_setRevtime(STReverb *self, PyObject *arg)
+{
+	PyObject *tmp, *streamtmp;
+	
+	if (arg == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+	int isNumber = PyNumber_Check(arg);
+    
+	tmp = arg;
+	Py_INCREF(tmp);
+	Py_DECREF(self->revtime);
+	if (isNumber == 1) {
+		self->revtime = PyNumber_Float(tmp);
+        self->modebuffer[1] = 0;
+	}
+	else {
+		self->revtime = tmp;
+        streamtmp = PyObject_CallMethod((PyObject *)self->revtime, "_getStream", NULL);
+        Py_INCREF(streamtmp);
+        Py_XDECREF(self->revtime_stream);
+        self->revtime_stream = (Stream *)streamtmp;
+		self->modebuffer[1] = 1;
+	}
+    
+    (*self->mode_func_ptr)(self);
+    
+	Py_INCREF(Py_None);
+	return Py_None;
+}	
+
+static PyObject *
+STReverb_setCutoff(STReverb *self, PyObject *arg)
+{
+	PyObject *tmp, *streamtmp;
+	
+	if (arg == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+	int isNumber = PyNumber_Check(arg);
+    
+	tmp = arg;
+	Py_INCREF(tmp);
+	Py_DECREF(self->cutoff);
+	if (isNumber == 1) {
+		self->cutoff = PyNumber_Float(tmp);
+        self->modebuffer[2] = 0;
+	}
+	else {
+		self->cutoff = tmp;
+        streamtmp = PyObject_CallMethod((PyObject *)self->cutoff, "_getStream", NULL);
+        Py_INCREF(streamtmp);
+        Py_XDECREF(self->cutoff_stream);
+        self->cutoff_stream = (Stream *)streamtmp;
+		self->modebuffer[2] = 1;
+	}
+    
+    (*self->mode_func_ptr)(self);
+    
+	Py_INCREF(Py_None);
+	return Py_None;
+}	
+
+static PyObject *
+STReverb_setMix(STReverb *self, PyObject *arg)
+{
+	PyObject *tmp, *streamtmp;
+	
+	if (arg == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+	int isNumber = PyNumber_Check(arg);
+    
+	tmp = arg;
+	Py_INCREF(tmp);
+	Py_DECREF(self->mix);
+	if (isNumber == 1) {
+		self->mix = PyNumber_Float(tmp);
+        self->modebuffer[3] = 0;
+	}
+	else {
+		self->mix = tmp;
+        streamtmp = PyObject_CallMethod((PyObject *)self->mix, "_getStream", NULL);
+        Py_INCREF(streamtmp);
+        Py_XDECREF(self->mix_stream);
+        self->mix_stream = (Stream *)streamtmp;
+		self->modebuffer[3] = 1;
+	}
+    
+    (*self->mode_func_ptr)(self);
+    
+	Py_INCREF(Py_None);
+	return Py_None;
+}	
+
+static PyObject *
+STReverb_setRoomSize(STReverb *self, PyObject *arg)
+{
+    int i, j, k, din;
+    long maxsize;
+	MYFLT roomSize;
+	
+	if (arg == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+	int isNumber = PyNumber_Check(arg);
+    
+	if (isNumber == 1) {
+        roomSize = PyFloat_AS_DOUBLE(PyNumber_Float(arg));
+        if (roomSize < 0.25)
+            roomSize = 0.25;
+        else if (roomSize > 4.0)
+            roomSize = 4.0;
+
+        self->avg_time = 0.0;
+        for (k=0; k<2; k++) {
+            din = k * 3;
+            for (i=0; i<8; i++) {
+                self->in_count[k][i] = 0;
+                self->lastSamples[k][i] = 0.0;
+                self->rnd[k][i] = self->rnd_value[k][i] = self->rnd_oldValue[k][i] = self->rnd_diff[k][i] = 0.0;
+                self->rnd_time[k][i] = 1.0;
+                self->delays[k][i] = reverbParams[i][din] * self->srfac * roomSize;
+                self->avg_time += self->delays[k][i] / self->sr;
+                self->size[k][i] = reverbParams[i][din] * self->srfac * roomSize + (int)(reverbParams[i][1] * self->sr + 0.5);
+                maxsize = reverbParams[i][din] * self->srfac * 2 + (int)(reverbParams[i][1] * self->sr + 0.5);
+                for (j=0; j<(maxsize+1); j++) {
+                    self->buffer[k][i][j] = 0.;
+                }
+            }    
+        }
+        self->avg_time /= 16.0;
+
+        for (k=0; k<NUM_REFS; k++) {
+            self->ref_in_count[k] = 0;
+            self->ref_size[k] = (int)(first_ref_delays[k] * self->srfac * roomSize + 0.5);
+            maxsize = (int)(first_ref_delays[k] * self->srfac * 2 + 0.5);
+            for (i=0; i<(maxsize+1); i++) {
+                self->ref_buffer[k][i] = 0.0;
+            }
+        }
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+STReverb_setFirstRefGain(STReverb *self, PyObject *arg)
+{
+	MYFLT tmp;
+	
+	if (arg == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+    
+	int isNumber = PyNumber_Check(arg);
+    
+	if (isNumber == 1) {
+        tmp = PyFloat_AS_DOUBLE(PyNumber_Float(arg));
+        self->firstRefGain = MYPOW(10.0, tmp * 0.05);
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}	
+
+static PyMemberDef STReverb_members[] = {
+{"server", T_OBJECT_EX, offsetof(STReverb, server), 0, "Pyo server."},
+{"stream", T_OBJECT_EX, offsetof(STReverb, stream), 0, "Stream object."},
+{"input", T_OBJECT_EX, offsetof(STReverb, input), 0, "Input sound object."},
+{"inpos", T_OBJECT_EX, offsetof(STReverb, inpos), 0, "Position left-right of the source."},
+{"revtime", T_OBJECT_EX, offsetof(STReverb, revtime), 0, "Reverb duration value."},
+{"cutoff", T_OBJECT_EX, offsetof(STReverb, cutoff), 0, "STReverb lowpass filter cutoff."},
+{"mix", T_OBJECT_EX, offsetof(STReverb, mix), 0, "Balance between dry and wet signals."},
+{NULL}  /* Sentinel */
+};
+
+static PyMethodDef STReverb_methods[] = {
+{"getServer", (PyCFunction)STReverb_getServer, METH_NOARGS, "Returns server object."},
+{"_getStream", (PyCFunction)STReverb_getStream, METH_NOARGS, "Returns stream object."},
+{"play", (PyCFunction)STReverb_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
+{"stop", (PyCFunction)STReverb_stop, METH_NOARGS, "Stops computing."},
+{"setInpos", (PyCFunction)STReverb_setInpos, METH_O, "Sets position of the source between 0 -> 1."},
+{"setRevtime", (PyCFunction)STReverb_setRevtime, METH_O, "Sets reverb duration in seconds."},
+{"setCutoff", (PyCFunction)STReverb_setCutoff, METH_O, "Sets lowpass filter cutoff."},
+{"setMix", (PyCFunction)STReverb_setMix, METH_O, "Sets balance between dry and wet signals."},
+{"setFirstRefGain", (PyCFunction)STReverb_setFirstRefGain, METH_O, "Sets gain of the first reflexions."},
+{"setRoomSize", (PyCFunction)STReverb_setRoomSize, METH_O, "Sets room size scaler."},
+{NULL}  /* Sentinel */
+};
+
+PyTypeObject STReverbType = {
+PyObject_HEAD_INIT(NULL)
+0,                         /*ob_size*/
+"_pyo.STReverb_base",         /*tp_name*/
+sizeof(STReverb),         /*tp_basicsize*/
+0,                         /*tp_itemsize*/
+(destructor)STReverb_dealloc, /*tp_dealloc*/
+0,                         /*tp_print*/
+0,                         /*tp_getattr*/
+0,                         /*tp_setattr*/
+0,                         /*tp_compare*/
+0,                         /*tp_repr*/
+0,             /*tp_as_number*/
+0,                         /*tp_as_sequence*/
+0,                         /*tp_as_mapping*/
+0,                         /*tp_hash */
+0,                         /*tp_call*/
+0,                         /*tp_str*/
+0,                         /*tp_getattro*/
+0,                         /*tp_setattro*/
+0,                         /*tp_as_buffer*/
+Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
+"STReverb objects. Waveguide-based reverberation network.",           /* tp_doc */
+(traverseproc)STReverb_traverse,   /* tp_traverse */
+(inquiry)STReverb_clear,           /* tp_clear */
+0,		               /* tp_richcompare */
+0,		               /* tp_weaklistoffset */
+0,		               /* tp_iter */
+0,		               /* tp_iternext */
+STReverb_methods,             /* tp_methods */
+STReverb_members,             /* tp_members */
+0,                      /* tp_getset */
+0,                         /* tp_base */
+0,                         /* tp_dict */
+0,                         /* tp_descr_get */
+0,                         /* tp_descr_set */
+0,                         /* tp_dictoffset */
+0,      /* tp_init */
+0,                         /* tp_alloc */
+STReverb_new,                 /* tp_new */
+};
+
+/************************************************************************************************/
+/* STReverb streamer object */
+/************************************************************************************************/
+typedef struct {
+    pyo_audio_HEAD
+    STReverb *mainSplitter;
+    int modebuffer[2];
+    int chnl; // STRev order
+} STRev;
+
+static void STRev_postprocessing_ii(STRev *self) { POST_PROCESSING_II };
+static void STRev_postprocessing_ai(STRev *self) { POST_PROCESSING_AI };
+static void STRev_postprocessing_ia(STRev *self) { POST_PROCESSING_IA };
+static void STRev_postprocessing_aa(STRev *self) { POST_PROCESSING_AA };
+static void STRev_postprocessing_ireva(STRev *self) { POST_PROCESSING_IREVA };
+static void STRev_postprocessing_areva(STRev *self) { POST_PROCESSING_AREVA };
+static void STRev_postprocessing_revai(STRev *self) { POST_PROCESSING_REVAI };
+static void STRev_postprocessing_revaa(STRev *self) { POST_PROCESSING_REVAA };
+static void STRev_postprocessing_revareva(STRev *self) { POST_PROCESSING_REVAREVA };
+
+static void
+STRev_setProcMode(STRev *self)
+{
+    int muladdmode;
+    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
+    
+	switch (muladdmode) {
+        case 0:        
+            self->muladd_func_ptr = STRev_postprocessing_ii;
+            break;
+        case 1:    
+            self->muladd_func_ptr = STRev_postprocessing_ai;
+            break;
+        case 2:    
+            self->muladd_func_ptr = STRev_postprocessing_revai;
+            break;
+        case 10:        
+            self->muladd_func_ptr = STRev_postprocessing_ia;
+            break;
+        case 11:    
+            self->muladd_func_ptr = STRev_postprocessing_aa;
+            break;
+        case 12:    
+            self->muladd_func_ptr = STRev_postprocessing_revaa;
+            break;
+        case 20:        
+            self->muladd_func_ptr = STRev_postprocessing_ireva;
+            break;
+        case 21:    
+            self->muladd_func_ptr = STRev_postprocessing_areva;
+            break;
+        case 22:    
+            self->muladd_func_ptr = STRev_postprocessing_revareva;
+            break;
+    }
+}
+
+static void
+STRev_compute_next_data_frame(STRev *self)
+{
+    int i;
+    MYFLT *tmp;
+    int offset = self->chnl * self->bufsize;
+    tmp = STReverb_getSamplesBuffer((STReverb *)self->mainSplitter);
+    for (i=0; i<self->bufsize; i++) {
+        self->data[i] = tmp[i + offset];
+    }    
+    (*self->muladd_func_ptr)(self);
+}
+
+static int
+STRev_traverse(STRev *self, visitproc visit, void *arg)
+{
+    pyo_VISIT
+    Py_VISIT(self->mainSplitter);
+    return 0;
+}
+
+static int 
+STRev_clear(STRev *self)
+{
+    pyo_CLEAR
+    Py_CLEAR(self->mainSplitter);    
+    return 0;
+}
+
+static void
+STRev_dealloc(STRev* self)
+{
+    pyo_DEALLOC
+    STRev_clear(self);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+STRev_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    int i;
+    PyObject *maintmp=NULL, *multmp=NULL, *addtmp=NULL;
+    STRev *self;
+    self = (STRev *)type->tp_alloc(type, 0);
+    
+	self->modebuffer[0] = 0;
+	self->modebuffer[1] = 0;
+    
+    INIT_OBJECT_COMMON
+    Stream_setFunctionPtr(self->stream, STRev_compute_next_data_frame);
+    self->mode_func_ptr = STRev_setProcMode;
+
+    static char *kwlist[] = {"mainSplitter", "chnl", "mul", "add", NULL};
+    
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "Oi|OO", kwlist, &maintmp, &self->chnl, &multmp, &addtmp))
+        Py_RETURN_NONE;
+
+    Py_XDECREF(self->mainSplitter);
+    Py_INCREF(maintmp);
+    self->mainSplitter = (STReverb *)maintmp;
+    
+    if (multmp) {
+        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
+    }
+    
+    if (addtmp) {
+        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
+    }
+    
+    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
+    
+    (*self->mode_func_ptr)(self);
+
+    return (PyObject *)self;
+}
+
+static PyObject * STRev_getServer(STRev* self) { GET_SERVER };
+static PyObject * STRev_getStream(STRev* self) { GET_STREAM };
+static PyObject * STRev_setMul(STRev *self, PyObject *arg) { SET_MUL };	
+static PyObject * STRev_setAdd(STRev *self, PyObject *arg) { SET_ADD };	
+static PyObject * STRev_setSub(STRev *self, PyObject *arg) { SET_SUB };	
+static PyObject * STRev_setDiv(STRev *self, PyObject *arg) { SET_DIV };	
+
+static PyObject * STRev_play(STRev *self, PyObject *args, PyObject *kwds) { PLAY };
+static PyObject * STRev_out(STRev *self, PyObject *args, PyObject *kwds) { OUT };
+static PyObject * STRev_stop(STRev *self) { STOP };
+
+static PyObject * STRev_multiply(STRev *self, PyObject *arg) { MULTIPLY };
+static PyObject * STRev_inplace_multiply(STRev *self, PyObject *arg) { INPLACE_MULTIPLY };
+static PyObject * STRev_add(STRev *self, PyObject *arg) { ADD };
+static PyObject * STRev_inplace_add(STRev *self, PyObject *arg) { INPLACE_ADD };
+static PyObject * STRev_sub(STRev *self, PyObject *arg) { SUB };
+static PyObject * STRev_inplace_sub(STRev *self, PyObject *arg) { INPLACE_SUB };
+static PyObject * STRev_div(STRev *self, PyObject *arg) { DIV };
+static PyObject * STRev_inplace_div(STRev *self, PyObject *arg) { INPLACE_DIV };
+
+static PyMemberDef STRev_members[] = {
+{"server", T_OBJECT_EX, offsetof(STRev, server), 0, "Pyo server."},
+{"stream", T_OBJECT_EX, offsetof(STRev, stream), 0, "Stream object."},
+{"mul", T_OBJECT_EX, offsetof(STRev, mul), 0, "Mul factor."},
+{"add", T_OBJECT_EX, offsetof(STRev, add), 0, "Add factor."},
+{NULL}  /* Sentinel */
+};
+
+static PyMethodDef STRev_methods[] = {
+{"getServer", (PyCFunction)STRev_getServer, METH_NOARGS, "Returns server object."},
+{"_getStream", (PyCFunction)STRev_getStream, METH_NOARGS, "Returns stream object."},
+{"play", (PyCFunction)STRev_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
+{"out", (PyCFunction)STRev_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
+{"stop", (PyCFunction)STRev_stop, METH_NOARGS, "Stops computing."},
+{"setMul", (PyCFunction)STRev_setMul, METH_O, "Sets STRev mul factor."},
+{"setAdd", (PyCFunction)STRev_setAdd, METH_O, "Sets STRev add factor."},
+{"setSub", (PyCFunction)STRev_setSub, METH_O, "Sets inverse add factor."},
+{"setDiv", (PyCFunction)STRev_setDiv, METH_O, "Sets inverse mul factor."},
+{NULL}  /* Sentinel */
+};
+
+static PyNumberMethods STRev_as_number = {
+(binaryfunc)STRev_add,                      /*nb_add*/
+(binaryfunc)STRev_sub,                 /*nb_subtract*/
+(binaryfunc)STRev_multiply,                 /*nb_multiply*/
+(binaryfunc)STRev_div,                   /*nb_divide*/
+0,                /*nb_remainder*/
+0,                   /*nb_divmod*/
+0,                   /*nb_power*/
+0,                  /*nb_neg*/
+0,                /*nb_pos*/
+0,                  /*(unaryfunc)array_abs,*/
+0,                    /*nb_nonzero*/
+0,                    /*nb_invert*/
+0,               /*nb_lshift*/
+0,              /*nb_rshift*/
+0,              /*nb_and*/
+0,              /*nb_xor*/
+0,               /*nb_or*/
+0,                                          /*nb_coerce*/
+0,                       /*nb_int*/
+0,                      /*nb_long*/
+0,                     /*nb_float*/
+0,                       /*nb_oct*/
+0,                       /*nb_hex*/
+(binaryfunc)STRev_inplace_add,              /*inplace_add*/
+(binaryfunc)STRev_inplace_sub,         /*inplace_subtract*/
+(binaryfunc)STRev_inplace_multiply,         /*inplace_multiply*/
+(binaryfunc)STRev_inplace_div,           /*inplace_divide*/
+0,        /*inplace_remainder*/
+0,           /*inplace_power*/
+0,       /*inplace_lshift*/
+0,      /*inplace_rshift*/
+0,      /*inplace_and*/
+0,      /*inplace_xor*/
+0,       /*inplace_or*/
+0,             /*nb_floor_divide*/
+0,              /*nb_true_divide*/
+0,     /*nb_inplace_floor_divide*/
+0,      /*nb_inplace_true_divide*/
+0,                     /* nb_index */
+};
+
+PyTypeObject STRevType = {
+PyObject_HEAD_INIT(NULL)
+0,                         /*ob_size*/
+"_pyo.STRev_base",         /*tp_name*/
+sizeof(STRev),         /*tp_basicsize*/
+0,                         /*tp_itemsize*/
+(destructor)STRev_dealloc, /*tp_dealloc*/
+0,                         /*tp_print*/
+0,                         /*tp_getattr*/
+0,                         /*tp_setattr*/
+0,                         /*tp_compare*/
+0,                         /*tp_repr*/
+&STRev_as_number,             /*tp_as_number*/
+0,                         /*tp_as_sequence*/
+0,                         /*tp_as_mapping*/
+0,                         /*tp_hash */
+0,                         /*tp_call*/
+0,                         /*tp_str*/
+0,                         /*tp_getattro*/
+0,                         /*tp_setattro*/
+0,                         /*tp_as_buffer*/
+Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES,  /*tp_flags*/
+"STRev objects. Reads one channel from a STReverb object.",           /* tp_doc */
+(traverseproc)STRev_traverse,   /* tp_traverse */
+(inquiry)STRev_clear,           /* tp_clear */
+0,		               /* tp_richcompare */
+0,		               /* tp_weaklistoffset */
+0,		               /* tp_iter */
+0,		               /* tp_iternext */
+STRev_methods,             /* tp_methods */
+STRev_members,             /* tp_members */
+0,                      /* tp_getset */
+0,                         /* tp_base */
+0,                         /* tp_dict */
+0,                         /* tp_descr_get */
+0,                         /* tp_descr_set */
+0,                         /* tp_dictoffset */
+0,      /* tp_init */
+0,                         /* tp_alloc */
+STRev_new,                 /* tp_new */
+};
diff --git a/utils/E-Pyo.py b/utils/E-Pyo.py
index e0b42f5..87656d1 100755
--- a/utils/E-Pyo.py
+++ b/utils/E-Pyo.py
@@ -40,6 +40,70 @@ APP_VERSION = PYO_VERSION
 OSX_APP_BUNDLED = False
 WIN_APP_BUNDLED = False
 
+################## Utility Functions ##################
+ at contextlib.contextmanager
+def stdoutIO(stdout=None):
+    old = sys.stdout
+    if stdout is None:
+        stdout = StringIO.StringIO()
+    sys.stdout = stdout
+    yield stdout
+    sys.stdout = old
+
+def convert_line_endings(temp, mode):
+    #modes:  0 - Unix, 1 - Mac, 2 - DOS
+    if mode == 0:
+        temp = string.replace(temp, '\r\n', '\n')
+        temp = string.replace(temp, '\r', '\n')
+    elif mode == 1:
+        temp = string.replace(temp, '\r\n', '\r')
+        temp = string.replace(temp, '\n', '\r')
+    elif mode == 2:
+        import re
+        temp = re.sub("\r(?!\n)|(?<!\r)\n", "\r\n", temp)
+    return temp
+
+def ensureNFD(unistr):
+    if PLATFORM in ['linux2', 'win32']:
+        encodings = [DEFAULT_ENCODING, ENCODING,
+                     'cp1252', 'iso-8859-1', 'utf-16']
+        format = 'NFC'
+    else:
+        encodings = [DEFAULT_ENCODING, ENCODING,
+                     'macroman', 'iso-8859-1', 'utf-16']
+        format = 'NFC'
+    decstr = unistr
+    if type(decstr) != UnicodeType:
+        for encoding in encodings:
+            try:
+                decstr = decstr.decode(encoding)
+                break
+            except UnicodeDecodeError:
+                continue
+            except:
+                decstr = "UnableToDecodeString"
+                print "Unicode encoding not in a recognized format..."
+                break
+    if decstr == "UnableToDecodeString":
+        return unistr
+    else:
+        return unicodedata.normalize(format, decstr)
+
+def toSysEncoding(unistr):
+    try:
+        if PLATFORM == "win32":
+            unistr = unistr.encode(ENCODING)
+        else:
+            unistr = unicode(unistr)
+    except:
+        pass
+    return unistr
+
+def hex_to_rgb(value):
+    value = value.lstrip('#')
+    lv = len(value)
+    return tuple(int(value[i:i+lv/3], 16) for i in range(0, lv, lv/3))
+
 TEMP_PATH = os.path.join(os.path.expanduser('~'), '.epyo')
 if not os.path.isdir(TEMP_PATH):
     os.mkdir(TEMP_PATH)
@@ -201,7 +265,7 @@ DEFAULT_STYLE = os.path.join(STYLES_PATH, "Default")
 if not os.path.isfile(os.path.join(STYLES_PATH, "Default")):
     shutil.copy(os.path.join(os.getcwd(), "styles", "Default"), DEFAULT_STYLE)
 if PREFERENCES.has_key("pref_style"):
-    PREF_STYLE = os.path.join(STYLES_PATH, PREFERENCES["pref_style"])
+    PREF_STYLE = os.path.join(ensureNFD(STYLES_PATH), PREFERENCES["pref_style"])
 else:
     PREF_STYLE = DEFAULT_STYLE
 
@@ -216,70 +280,6 @@ if not os.path.isfile(MARKERS_FILE):
 BACKGROUND_SERVER_DEFAULT_ARGS = 'sr=44100, nchnls=2, buffersize=256, duplex=1, audio="portaudio", jackname="pyo"'
 BACKGROUND_SERVER_ARGS = PREFERENCES.get("background_server_args", BACKGROUND_SERVER_DEFAULT_ARGS)
 
-################## Utility Functions ##################
- at contextlib.contextmanager
-def stdoutIO(stdout=None):
-    old = sys.stdout
-    if stdout is None:
-        stdout = StringIO.StringIO()
-    sys.stdout = stdout
-    yield stdout
-    sys.stdout = old
-
-def convert_line_endings(temp, mode):
-    #modes:  0 - Unix, 1 - Mac, 2 - DOS
-    if mode == 0:
-        temp = string.replace(temp, '\r\n', '\n')
-        temp = string.replace(temp, '\r', '\n')
-    elif mode == 1:
-        temp = string.replace(temp, '\r\n', '\r')
-        temp = string.replace(temp, '\n', '\r')
-    elif mode == 2:
-        import re
-        temp = re.sub("\r(?!\n)|(?<!\r)\n", "\r\n", temp)
-    return temp
-
-def ensureNFD(unistr):
-    if PLATFORM in ['linux2', 'win32']:
-        encodings = [DEFAULT_ENCODING, ENCODING,
-                     'cp1252', 'latin_1', 'utf-16']
-        format = 'NFC'
-    else:
-        encodings = [DEFAULT_ENCODING, ENCODING,
-                     'macroman', 'latin_1', 'utf-16']
-        format = 'NFC'
-    decstr = unistr
-    if type(decstr) != UnicodeType:
-        for encoding in encodings:
-            try:
-                decstr = decstr.decode(encoding)
-                break
-            except UnicodeDecodeError:
-                continue
-            except:
-                decstr = "UnableToDecodeString"
-                print "Unicode encoding not in a recognized format..."
-                break
-    if decstr == "UnableToDecodeString":
-        return unistr
-    else:
-        return unicodedata.normalize(format, decstr)
-
-def toSysEncoding(unistr):
-    try:
-        if PLATFORM == "win32":
-            unistr = unistr.encode(ENCODING)
-        else:
-            unistr = unicode(unistr)
-    except:
-        pass
-    return unistr
-
-def hex_to_rgb(value):
-    value = value.lstrip('#')
-    lv = len(value)
-    return tuple(int(value[i:i+lv/3], 16) for i in range(0, lv, lv/3))
-
 ################## TEMPLATES ##################
 HEADER_TEMPLATE = """#!/usr/bin/env python
 # encoding: utf-8
@@ -685,7 +685,7 @@ elif wx.Platform == '__WXMAC__':
 else:
     FONT_SIZE = 8
     FONT_SIZE2 = 7
-    DEFAULT_FONT_FACE = 'Courier New'
+    DEFAULT_FONT_FACE = 'Monospace'
 
 
 STYLES_GENERALS = ['default', 'background', 'selback', 'caret']
@@ -702,7 +702,31 @@ STYLES_LABELS = {'default': 'Foreground', 'background': 'Background', 'selback':
 with open(PREF_STYLE) as f:
     text = f.read()
 exec text in locals()
-STYLES = copy.deepcopy(style)
+try:
+    STYLES = copy.deepcopy(style)
+except:
+    STYLES = {'background': {'colour': '#FFFFFF'},
+ 'bracebad': {'colour': '#DD0000'},
+ 'bracelight': {'colour': '#AABBDD'},
+ 'caret': {'colour': '#000000'},
+ 'class': {'bold': 1, 'colour': '#000097', 'italic': 0, 'underline': 0},
+ 'comment': {'bold': 0, 'colour': '#0066FF', 'italic': 1, 'underline': 0},
+ 'commentblock': {'bold': 0, 'colour': u'#468EFF', 'italic': 1, 'underline': 0},
+ 'default': {'bold': 0, 'colour': '#000000', 'italic': 0, 'underline': 0},
+ 'foldmarginback': {'colour': '#D0D0D0'},
+ 'function': {'bold': 1, 'colour': '#0000A2', 'italic': 0, 'underline': 0},
+ 'keyword': {'bold': 1, 'colour': '#0000FF', 'italic': 0, 'underline': 0},
+ 'lineedge': {'colour': '#DDDDDD'},
+ 'linenumber': {'bold': 0, 'colour': '#000000', 'italic': 0, 'underline': 0},
+ 'marginback': {'colour': '#B0B0B0'},
+ 'markerbg': {'colour': '#000000'},
+ 'markerfg': {'colour': '#CCCCCC'},
+ 'number': {'bold': 1, 'colour': '#0000CD', 'italic': 0, 'underline': 0},
+ 'operator': {'bold': 1, 'colour': '#000000', 'italic': 0, 'underline': 0},
+ 'pyokeyword': {'bold': 1, 'colour': '#5555FF', 'italic': 0, 'underline': 0},
+ 'selback': {'colour': '#C0DFFF'},
+ 'string': {'bold': 0, 'colour': '#036A07', 'italic': 0, 'underline': 0},
+ 'triple': {'bold': 0, 'colour': '#03BA07', 'italic': 0, 'underline': 0}}
 if not STYLES.has_key('face'):
     STYLES['face'] = DEFAULT_FONT_FACE
 if not STYLES.has_key('size'):
@@ -1189,7 +1213,7 @@ class ColourEditor(wx.Frame):
         global STYLES
         stl = event.GetString()
         self.cur_style = stl
-        with open(os.path.join(STYLES_PATH, stl)) as f:
+        with open(os.path.join(ensureNFD(STYLES_PATH), stl)) as f:
             text = f.read()
         exec text in locals()
         STYLES = copy.deepcopy(style)
@@ -1550,10 +1574,10 @@ class SnippetFrame(wx.Frame):
             self.entry.InsertText(select[0], "`")
 
     def onLoad(self, name, category):
-        if os.path.isfile(os.path.join(SNIPPETS_PATH, category, name)):
+        if os.path.isfile(os.path.join(ensureNFD(SNIPPETS_PATH), category, name)):
             self.snippet_name = name
             self.category_name = category
-            with codecs.open(os.path.join(SNIPPETS_PATH, self.category_name, self.snippet_name), "r", encoding="utf-8") as f:
+            with codecs.open(os.path.join(ensureNFD(SNIPPETS_PATH), self.category_name, self.snippet_name), "r", encoding="utf-8") as f:
                 text = f.read()
             exec text in locals()
             try:
@@ -2444,9 +2468,13 @@ class MainFrame(wx.Frame):
             paths = dlg.GetPaths()
             if len(paths) == 1:
                 text = ensureNFD(paths[0])
+                if PLATFORM == "win32":
+                    text = text.replace("\\", "/")
                 self.panel.editor.ReplaceSelection("'" + text + "'")
             else:
                 text = ", ".join(["'"+ensureNFD(path)+"'" for path in paths])
+                if PLATFORM == "win32":
+                    text = text.replace("\\", "/")
                 self.panel.editor.ReplaceSelection("[" + text + "]")
             PREFERENCES["insert_path"] = os.path.split(paths[0])[0]
         dlg.Destroy()
@@ -2457,7 +2485,7 @@ class MainFrame(wx.Frame):
         item = menu.FindItemById(id)
         name = item.GetLabel()
         category = item.GetMenu().GetTitle()
-        with codecs.open(os.path.join(SNIPPETS_PATH, category, name), "r", encoding="utf-8") as f:
+        with codecs.open(os.path.join(ensureNFD(SNIPPETS_PATH), category, name), "r", encoding="utf-8") as f:
             text = f.read()
         exec text in locals()
         self.panel.editor.insertSnippet(snippet["value"])
@@ -2474,7 +2502,7 @@ class MainFrame(wx.Frame):
         
     def setStyle(self, st, fromMenu=False):
         global STYLES
-        with open(os.path.join(STYLES_PATH, st)) as f:
+        with open(os.path.join(ensureNFD(STYLES_PATH), st)) as f:
             text = f.read()
         exec text in locals()
         STYLES = copy.deepcopy(style)
@@ -2654,7 +2682,7 @@ class MainFrame(wx.Frame):
         item = menu.FindItemById(id)
         filename = item.GetLabel()
         folder = item.GetMenu().GetTitle()
-        path = os.path.join(EXAMPLE_PATH, folder, filename)
+        path = os.path.join(ensureNFD(EXAMPLE_PATH), folder, filename)
         self.panel.addPage(ensureNFD(path))
 
     def openTutorial(self, event):
@@ -4901,7 +4929,7 @@ class PreferencesDialog(wx.Dialog):
 
         res_folder = self.entry_res.GetValue()
         if os.path.isdir(res_folder):
-            if res_folder != RESOURCES_PATH:
+            if res_folder != ensureNFD(RESOURCES_PATH):
                 RESOURCES_PATH = PREFERENCES["resources_path"] = res_folder
                 # snippets
                 old_snippets_path = SNIPPETS_PATH
@@ -5381,7 +5409,7 @@ if __name__ == '__main__':
             else:
                 pass
 
-    app = wx.PySimpleApp()
+    app = wx.App(False)
     X,Y = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X), wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
     if X < 850: X -= 50
     else: X = 850
diff --git a/utils/E-PyoIcon.png b/utils/E-PyoIcon.png
new file mode 100644
index 0000000..f971f13
Binary files /dev/null and b/utils/E-PyoIcon.png differ
diff --git a/utils/PyoDoc.py b/utils/PyoDoc.py
index 03e145f..737c317 100644
--- a/utils/PyoDoc.py
+++ b/utils/PyoDoc.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # encoding: utf-8
 from __future__ import with_statement
-import subprocess, threading, os
+import subprocess, threading, os, sys, unicodedata
 import wx
 import wx.stc  as  stc
 from wx.lib.embeddedimage import PyEmbeddedImage
@@ -9,6 +9,10 @@ from pyo import *
 
 DOC_AS_SINGLE_APP = False
 
+PLATFORM = sys.platform
+DEFAULT_ENCODING = sys.getdefaultencoding()
+ENCODING = sys.getfilesystemencoding()
+
 TEMP_PATH = os.path.join(os.path.expanduser('~'), '.epyo')
 if not os.path.isdir(TEMP_PATH):
     os.mkdir(TEMP_PATH)
@@ -26,7 +30,7 @@ if wx.Platform == '__WXMSW__':
 elif wx.Platform == '__WXMAC__':
   DOC_FACES = {'face': 'Monaco', 'size' : 12, 'size2': 9}
 else:
-  DOC_FACES = {'face': 'Courier New', 'size' : 8, 'size2': 7}
+  DOC_FACES = {'face': 'Monospace', 'size' : 8, 'size2': 7}
 DOC_FACES['size3'] = DOC_FACES['size2'] + 4
 for key, value in DOC_STYLES['Default'].items():
   DOC_FACES[key] = value
@@ -206,11 +210,10 @@ functions : Miscellaneous functions.
 """ % PYO_VERSION
 
 _DOC_KEYWORDS = ['Attributes', 'Examples', 'Methods', 'Notes', 'Methods details', 
-                 'Parentclass', 'Overview', 'Initline', 'Description']
+                 'Parentclass', 'Overview', 'Initline', 'Description', 'Parameters']
 _HEADERS = ["Server", "PyoObjectBase", "Map", "Stream", "TableStream", "functions"]
-_KEYWORDS_LIST = ['Parameters']
+_KEYWORDS_LIST = ['SLMap']
 _KEYWORDS_LIST.extend(_HEADERS)
-_KEYWORDS_LIST.append("SLMap")
 _NUM_PAGES = 1
 _NUM_PAGES += len(_HEADERS)
 for k1 in _HEADERS:
@@ -786,7 +789,7 @@ class ManualPanel(wx.Treebook):
                 if not panel.isLoad:
                     panel.isLoad = True
                     panel.win = stc.StyledTextCtrl(panel, -1, size=panel.GetSize(), style=wx.SUNKEN_BORDER)
-                    panel.win.LoadFile(os.path.join(DOC_PATH, word))
+                    panel.win.LoadFile(os.path.join(ensureNFD(DOC_PATH), word))
                     panel.win.SetMarginWidth(1, 0)
                     panel.win.Bind(wx.EVT_LEFT_DOWN, self.MouseDown)
                     if self.searchKey != None:
@@ -1080,6 +1083,42 @@ class RunningThread(threading.Thread):
         while self.proc.poll() == None and not self.terminated:
             time.sleep(.25)
 
+def ensureNFD(unistr):
+    if PLATFORM in ['linux2', 'win32']:
+        encodings = [DEFAULT_ENCODING, ENCODING,
+                     'cp1252', 'iso-8859-1', 'utf-16']
+        format = 'NFC'
+    else:
+        encodings = [DEFAULT_ENCODING, ENCODING,
+                     'macroman', 'iso-8859-1', 'utf-16']
+        format = 'NFC'
+    decstr = unistr
+    if type(decstr) != UnicodeType:
+        for encoding in encodings:
+            try:
+                decstr = decstr.decode(encoding)
+                break
+            except UnicodeDecodeError:
+                continue
+            except:
+                decstr = "UnableToDecodeString"
+                print "Unicode encoding not in a recognized format..."
+                break
+    if decstr == "UnableToDecodeString":
+        return unistr
+    else:
+        return unicodedata.normalize(format, decstr)
+
+def toSysEncoding(unistr):
+    try:
+        if PLATFORM == "win32":
+            unistr = unistr.encode(ENCODING)
+        else:
+            unistr = unicode(unistr)
+    except:
+        pass
+    return unistr
+
 if __name__ == "__main__":
     DOC_AS_SINGLE_APP = True
     app = wx.PySimpleApp()
diff --git a/utils/info.plist b/utils/info.plist
index b43497a..cc6108e 100644
--- a/utils/info.plist
+++ b/utils/info.plist
@@ -32,17 +32,17 @@
 	<key>CFBundleIdentifier</key>
 	<string>org.pythonmac.unspecified.E-Pyo</string>
 	<key>CFBundleInfoDictionaryVersion</key>
-	<string>0.6.8</string>
+	<string>0.6.9</string>
 	<key>CFBundleName</key>
 	<string>E-Pyo</string>
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>0.6.8</string>
+	<string>0.6.9</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleVersion</key>
-	<string>0.6.8</string>
+	<string>0.6.9</string>
 	<key>LSHasLocalizedDisplayName</key>
 	<false/>
 	<key>NSAppleScriptEnabled</key>

-- 
python-pyo packaging



More information about the pkg-multimedia-commits mailing list