[SCM] python-pyo/master: New upstream release.
tiago at users.alioth.debian.org
tiago at users.alioth.debian.org
Wed May 10 00:22:30 UTC 2017
The following commit has been merged in the master branch:
commit 34c253a8a952db98cfab531cbaebcdb3ada6718a
Author: Tiago Bortoletto Vaz <tiago at debian.org>
Date: Thu Mar 2 11:11:21 2017 -0500
New upstream release.
diff --git a/ChangeLog b/ChangeLog
index 9e0ab06..8ee28a6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,96 @@
+2017-02-13 belangeo <belangeo at gmail.com>
+
+ * Final revision for version 0.8.3.
+
+2017-02-13 belangeo <belangeo at gmail.com>
+
+ * Added new object: MidiDispatcher, self-contained midi dispatcher thread.
+ Updated MidiListener.
+
+2017-02-12 belangeo <belangeo at gmail.com>
+
+ * Upgraded version number to 0.8.3.
+
+2017-02-12 belangeo <belangeo at gmail.com>
+
+ * Prevents the creation of a SharedTable object on Windows (not implemented yet).
+
+2017-02-12 belangeo <belangeo at gmail.com>
+
+ * Fader and Adsr now start a new envelope from the current amplitude value
+ if the previous ramp has not finished yet.
+
+2017-02-12 belangeo <belangeo at gmail.com>
+
+ * Added new object: TableScan, Reads the content of a table in loop,
+ without interpolation.
+
+2017-02-11 belangeo <belangeo at gmail.com>
+
+ * Added setGlobalDur, setGlobalDel, getGlobalDur and getGlobalDel methods
+ to the Server object. These methods allow the user to manage starttime
+ and duration of audio objects globally.
+
+2017-02-09 belangeo <belangeo at gmail.com>
+
+ * Added shape argument to PVAmpMod and PVFreqMod objects.
+ It allows to change the modulation oscillator's waveform.
+
+2017-02-08 belangeo <belangeo at gmail.com>
+
+ * Added onlyonce argument to Beat object.
+
+2017-02-08 belangeo <belangeo at gmail.com>
+
+ * Seq now accepts floating-point values as time units.
+
+2017-02-07 belangeo <belangeo at gmail.com>
+
+ * Added maxwindow argument to TableWrite. This is the maximum number of samples
+ over which the object is allowed to interpolate. Useful to avoid interpolation
+ over the entire table when using a circular writing pointer.
+
+2017-02-05 belangeo <belangeo at gmail.com>
+
+ * Added new object: TableFill, continuously fills a table with incoming samples.
+
+2017-02-04 belangeo <belangeo at gmail.com>
+
+ * Added onlyonce argument to Seq object.
+
+2017-01-30 belangeo <belangeo at gmail.com>
+
+ * Added new object: Particle2, An even more full control granular synthesis generator.
+
+2017-01-08 belangeo <belangeo at gmail.com>
+
+ * Added new object: SharedTable, an inter-process shared memory table.
+
+2017-01-07 belangeo <belangeo at gmail.com>
+
+ * Jack ports activation and auto-connection now happen in the boot process.
+
+2016-12-17 belangeo <belangeo at gmail.com>
+
+ * Upgraded version number to 0.8.2.
+
+2016-12-17 belangeo <belangeo at gmail.com>
+
+ * Fixed bug in Bendin value. Fixed midi input events handling. Set
+ interpolation to off by default for midi continuous controllers.
+
+2016-12-17 belangeo <belangeo at gmail.com>
+
+ * E-Pyo: Fixed a bug in the documentation window.
+
+2016-12-17 belangeo <belangeo at gmail.com>
+
+ * TrigFunc and Pattern now accept tuple as arg argument (fixed issue #90).
+
+2016-12-15 belangeo <belangeo at gmail.com>
+
+ * Fixed portaudio suggested latency for realtime performance.
+
2016-12-08 belangeo <belangeo at gmail.com>
* Upgraded version number to 0.8.1.
@@ -1293,7 +1386,7 @@
2011-07-22 belangeo <belangeo at gmail.com>
- * Added new function : reducePoints(), apply a Douglas–Peucker curve reduction algorithm.
+ * Added new function : reducePoints(), apply a DouglasPeucker curve reduction algorithm.
Added loadRecFile() method to table objects.
- rev 688
diff --git a/TODO.md b/TODO.md
index b213785..c5d2807 100644
--- a/TODO.md
+++ b/TODO.md
@@ -56,6 +56,9 @@ GUI
- MixerGUI, an interface to control the routing of a Mixer object.
+- Keyboard, a virtual MIDI keyboard (adapted from Zyne's one).
+
+- Save item in ctrl() and DataTable graph() windows.
Tables
------
diff --git a/debian/changelog b/debian/changelog
index 03b30b6..0760fae 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,15 @@
+python-pyo (0.8.3-1) unstable; urgency=medium
+
+ * New upstream release.
+
+ -- Tiago Bortoletto Vaz <tiago at debian.org> Thu, 02 Mar 2017 11:08:16 -0500
+
+python-pyo (0.8.2-1) unstable; urgency=medium
+
+ * New upstream release.
+
+ -- Tiago Bortoletto Vaz <tiago at debian.org> Sat, 17 Dec 2016 22:02:35 -0500
+
python-pyo (0.8.1-1) unstable; urgency=medium
* New upstream release.
diff --git a/debian/patches/series b/debian/patches/series
index 96b96c0..a2dcd10 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,2 +1,2 @@
ePyo_paths.patch
-setup.patch
+setuphack.patch
diff --git a/debian/patches/setup.patch b/debian/patches/setuphack.patch
similarity index 95%
rename from debian/patches/setup.patch
rename to debian/patches/setuphack.patch
index ace104c..b3ce605 100644
--- a/debian/patches/setup.patch
+++ b/debian/patches/setuphack.patch
@@ -3,7 +3,7 @@
@@ -23,7 +23,7 @@
import os, sys, py_compile
- pyo_version = "0.8.1"
+ pyo_version = "0.8.2"
-build_with_jack_support = False
+build_with_jack_support = True
compile_externals = False
@@ -38,7 +38,7 @@
- macros.append(('USE_JACK',None))
- ad_files.append("ad_jack.c")
+#if '--use-jack' in sys.argv:
-+#sys.argv.remove('--use-jack')
++# sys.argv.remove('--use-jack')
+build_with_jack_support = True
+macros.append(('USE_JACK',None))
+ad_files.append("ad_jack.c")
diff --git a/doc-sphinx/source/api/alphabetical.rst b/doc-sphinx/source/api/alphabetical.rst
index 34878f3..3863799 100644
--- a/doc-sphinx/source/api/alphabetical.rst
+++ b/doc-sphinx/source/api/alphabetical.rst
@@ -170,6 +170,7 @@ Alphabetical class reference
- :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:`Particle2` : An even more full control granular synthesis generator.
- :py:class:`Particle` : A full control granular synthesis generator.
- :py:class:`Pattern` : Periodically calls a Python function.
- :py:class:`PeakAmp` : Peak amplitude follower.
@@ -225,6 +226,7 @@ Alphabetical class reference
- :py:class:`SfMarkerLooper` : AIFF with markers soundfile looper.
- :py:class:`SfMarkerShuffler` : AIFF with markers soundfile shuffler.
- :py:class:`SfPlayer` : Soundfile player.
+- :py:class:`SharedTable` : Create an inter-process shared memory table.
- :py:class:`SigTo` : Convert numeric value to PyoObject signal with portamento.
- :py:class:`Sig` : Convert numeric value to PyoObject signal.
- :py:class:`Sin` : Performs a sine function on audio signal.
@@ -240,12 +242,14 @@ Alphabetical class reference
- :py:class:`SumOsc` : Discrete summation formulae to produce complex spectra.
- :py:class:`SuperSaw` : Roland JP-8000 Supersaw emulator.
- :py:class:`Switch` : Audio switcher.
+- :py:class:`TableFill` : Continuously fills a table with incoming samples.
- :py:class:`TableIndex` : Table reader by sample position without interpolation.
- :py:class:`TableMorph` : Morphs between multiple PyoTableObjects.
- :py:class:`TablePut` : Writes values, without repetitions, from an audio stream into a DataTable.
- :py:class:`TableRead` : Simple waveform table reader.
- :py:class:`TableRec` : TableRec is for writing samples into a previously created NewTable.
- :py:class:`TableScale` : Scales all the values contained in a PyoTableObject.
+- :py:class:`TableScan` : Reads the content of a table in loop, without interpolation.
- :py:class:`TableWrite` : TableWrite writes samples into a previously created NewTable.
- :py:class:`Tan` : Performs a tangent function on audio signal.
- :py:class:`Tanh` : Performs a hyperbolic tangent function on audio signal.
diff --git a/doc-sphinx/source/api/classes/listener.rst b/doc-sphinx/source/api/classes/listener.rst
index c3406b6..d61ce3b 100644
--- a/doc-sphinx/source/api/classes/listener.rst
+++ b/doc-sphinx/source/api/classes/listener.rst
@@ -12,6 +12,12 @@ need to boot ands start an audio server before receiving messages.
.. autoclass:: MidiListener
:members:
+*MidiDispatcher*
+-----------------------------------
+
+.. autoclass:: MidiDispatcher
+ :members:
+
*OscListener*
-----------------------------------
diff --git a/doc-sphinx/source/api/classes/tableprocess.rst b/doc-sphinx/source/api/classes/tableprocess.rst
index 8e9da9e..25f7764 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:: Particle
:members:
+*Particle2*
+-----------------------------------
+
+.. autoclass:: Particle2
+ :members:
+
*Pointer*
-----------------------------------
@@ -122,3 +128,14 @@ store audio samples or algorithmic sequences for future uses.
.. autoclass:: TableScale
:members:
+*TableFill*
+-----------------------------------
+
+.. autoclass:: TableFill
+ :members:
+
+*TableScan*
+-----------------------------------
+
+.. autoclass:: TableScan
+ :members:
diff --git a/doc-sphinx/source/api/classes/tables.rst b/doc-sphinx/source/api/classes/tables.rst
index 653f2dc..fdc9b79 100644
--- a/doc-sphinx/source/api/classes/tables.rst
+++ b/doc-sphinx/source/api/classes/tables.rst
@@ -125,3 +125,9 @@ in memory and access them quickly.
.. autoclass:: PadSynthTable
:members:
+
+*SharedTable*
+-----------------------------------
+
+.. autoclass:: SharedTable
+ :members:
diff --git a/doc-sphinx/source/index.rst b/doc-sphinx/source/index.rst
index c5223e6..1053c53 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.8.1 documentation
+Welcome to the pyo 0.8.3 documentation
===================================================
.. image:: E-PyoIcon.png
diff --git a/doc-sphinx/source/perftips.rst b/doc-sphinx/source/perftips.rst
index ed66221..e52f048 100644
--- a/doc-sphinx/source/perftips.rst
+++ b/doc-sphinx/source/perftips.rst
@@ -42,34 +42,49 @@ sine wave computations to multiple processors.
Spawning lot of sine waves to multiple processes.
From the command line, run the script with -i flag.
+ Call quit() to stop the workers and quit the program.
+
"""
- from pyo import *
+ import time
+ import multiprocessing
from random import uniform
- import time, multiprocessing
+ from pyo import Server, SineLoop
class Group(multiprocessing.Process):
- def __init__(self, n):
+ def __init__(self, num_of_sines):
super(Group, self).__init__()
self.daemon = True
+ self._terminated = False
+ self.num_of_sines = num_of_sines
- self.s = Server()
- self.s.deactivateMidi()
- self.s.boot().start()
+ def run(self):
+ # All code that should run on a separated
+ # core must be created in the run() method.
+ self.server = Server()
+ self.server.deactivateMidi()
+ self.server.boot().start()
- freqs = [uniform(400,800) for i in range(n)]
- self.a = Sine(freq=freqs, mul=.005).out()
+ freqs = [uniform(400,800) for i in range(self.num_of_sines)]
+ self.oscs = SineLoop(freq=freqs, feedback=0.1, mul=.005).out()
- def run(self):
- while True:
+ # Keeps the process alive...
+ while not self._terminated:
time.sleep(0.001)
+ self.server.stop()
+
+ def stop(self):
+ self._terminated = True
+
if __name__ == '__main__':
- jobs = []
- # Starts four processes playing 500 sines each.
- for i in range(4):
- jobs.append(Group(500))
- for job in jobs:
- job.start()
+ # Starts four processes playing 500 oscillators each.
+ jobs = [Group(500) for i in range(4)]
+ [job.start() for job in jobs]
+
+ def quit():
+ "Stops the workers and quit the program."
+ [job.stop() for job in jobs]
+ exit()
Avoid memory allocation after initialization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/embedded/puredata/pyo~-help.pd b/embedded/puredata/pyo~-help.pd
index ef4257d..730d8c2 100644
--- a/embedded/puredata/pyo~-help.pd
+++ b/embedded/puredata/pyo~-help.pd
@@ -234,7 +234,7 @@ in pyo~ inputs).;
#N canvas 193 300 450 300 README 0;
#X text 14 33 Author : Olivier Belanger;
#X text 14 81 Last update : December 2016;
-#X text 14 57 Version : 0.8.1;
+#X text 14 57 Version : 0.8.2;
#X text 15 108 pyo website : http://ajaxsoundstudio.com/software/pyo/
;
#X text 15 10 pyo~ : Embedded pyo scripting inside puredata.;
diff --git a/include/pyomodule.h b/include/pyomodule.h
index c336f3e..ab23153 100644
--- a/include/pyomodule.h
+++ b/include/pyomodule.h
@@ -21,7 +21,7 @@
#include "Python.h"
#include <math.h>
-#define PYO_VERSION "0.8.1"
+#define PYO_VERSION "0.8.3"
#ifndef __MYFLT_DEF
#define __MYFLT_DEF
@@ -207,6 +207,7 @@
#ifdef USE_PORTMIDI
extern PyTypeObject MidiListenerType;
+extern PyTypeObject MidiDispatcherType;
#endif
#ifdef USE_OSC
extern PyTypeObject OscListenerType;
@@ -500,12 +501,17 @@ extern PyTypeObject ScopeType;
extern PyTypeObject PeakAmpType;
extern PyTypeObject MainParticleType;
extern PyTypeObject ParticleType;
+extern PyTypeObject MainParticle2Type;
+extern PyTypeObject Particle2Type;
extern PyTypeObject AtanTableType;
extern PyTypeObject RawMidiType;
extern PyTypeObject ResampleType;
extern PyTypeObject ExprType;
extern PyTypeObject PadSynthTableType;
extern PyTypeObject LogiMapType;
+extern PyTypeObject SharedTableType;
+extern PyTypeObject TableFillType;
+extern PyTypeObject TableScanType;
/* Constants */
#define E M_E
@@ -692,7 +698,7 @@ extern PyTypeObject LogiMapType;
else if (self->interp == 3) \
self->interp_func_ptr = cosine; \
else if (self->interp == 4) \
- self->interp_func_ptr = cubic; \
+ self->interp_func_ptr = cubic;
/* Set data */
#define SET_TABLE_DATA \
@@ -1567,6 +1573,8 @@ extern PyTypeObject LogiMapType;
#define PLAY \
float del = 0; \
float dur = 0; \
+ float globdel = 0; \
+ float globdur = 0; \
int nearestBuf = 0; \
int i; \
\
@@ -1575,6 +1583,14 @@ extern PyTypeObject LogiMapType;
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|ff", kwlist, &dur, &del)) \
return PyInt_FromLong(-1); \
\
+ globdel = PyFloat_AsDouble(PyObject_CallMethod(PyServer_get_server(), "getGlobalDel", NULL)); \
+ globdur = PyFloat_AsDouble(PyObject_CallMethod(PyServer_get_server(), "getGlobalDur", NULL)); \
+ \
+ if (globdel != 0) \
+ del = globdel; \
+ if (globdur != 0) \
+ dur = globdur; \
+ \
Stream_setStreamToDac(self->stream, 0); \
if (del == 0) { \
Stream_setBufferCountWait(self->stream, 0); \
@@ -1606,6 +1622,8 @@ extern PyTypeObject LogiMapType;
int chnltmp = 0; \
float del = 0; \
float dur = 0; \
+ float globdel = 0; \
+ float globdur = 0; \
int nearestBuf = 0; \
int i; \
\
@@ -1614,6 +1632,14 @@ extern PyTypeObject LogiMapType;
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|iff", kwlist, &chnltmp, &dur, &del)) \
return PyInt_FromLong(-1); \
\
+ globdel = PyFloat_AsDouble(PyObject_CallMethod(PyServer_get_server(), "getGlobalDel", NULL)); \
+ globdur = PyFloat_AsDouble(PyObject_CallMethod(PyServer_get_server(), "getGlobalDur", NULL)); \
+ \
+ if (globdel != 0) \
+ del = globdel; \
+ if (globdur != 0) \
+ dur = globdur; \
+ \
Stream_setStreamChnl(self->stream, chnltmp % self->nchnls); \
Stream_setStreamToDac(self->stream, 1); \
if (del == 0) { \
diff --git a/include/servermodule.h b/include/servermodule.h
index 2e2dd34..4b16f33 100644
--- a/include/servermodule.h
+++ b/include/servermodule.h
@@ -144,6 +144,10 @@ typedef struct {
/* custom callback */
PyObject *CALLBACK;
+ /* Globals dur and del times. */
+ float globalDur;
+ float globalDel;
+
/* Properties */
int verbosity; /* a sum of values to display different levels: 1 = error */
/* 2 = message, 4 = warning , 8 = debug. Default 7.*/
@@ -166,7 +170,7 @@ void Server_error(Server *self, char * format, ...);
void Server_message(Server *self, char * format, ...);
void Server_warning(Server *self, char * format, ...);
void Server_debug(Server *self, char * format, ...);
-PyObject * Server_shut_down(Server *self);
+PyObject * Server_shutdown(Server *self);
PyObject *Server_stop(Server *self);
void Server_process_gui(Server *server);
void Server_process_time(Server *server);
diff --git a/include/streammodule.h b/include/streammodule.h
index 78a8fa3..b19b0ce 100644
--- a/include/streammodule.h
+++ b/include/streammodule.h
@@ -56,9 +56,8 @@ extern PyTypeObject StreamType;
(self) = (Stream *)(type)->tp_alloc((type), 0); \
if ((self) == rt_error) { return rt_error; } \
\
- (self)->sid = (self)->chnl = (self)->todac = (self)->bufferCountWait = (self)->bufferCount = (self)->bufsize = (self)->duration = 0; \
- (self)->active = 1;
-
+ (self)->sid = (self)->chnl = (self)->todac = (self)->bufferCountWait = 0; \
+ (self)->bufferCount = (self)->bufsize = (self)->duration = (self)->active = 0;
typedef struct {
PyObject_HEAD
diff --git a/installers/osx/PkgResources_x86_64_py2/ReadMe.rtf b/installers/osx/PkgResources_x86_64_py2/ReadMe.rtf
index daa1aed..79476ad 100755
--- a/installers/osx/PkgResources_x86_64_py2/ReadMe.rtf
+++ b/installers/osx/PkgResources_x86_64_py2/ReadMe.rtf
@@ -1,84 +1,97 @@
-{\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\fcharset0 LucidaGrande;}{\f6\fnil\fprq2\fcharset0 WenQuanYi Micro Hei;}{\f7\fnil\fprq2\fcharset0 FreeSans;}{\f8\fswiss\fprq0\fcharset128 FreeSans;}}
-{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}
-{\stylesheet{\s0\snext0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105 Normal;}
-{\s15\sbasedon0\snext16\sb240\sa120\keepn\dbch\af6\dbch\af7\afs28\loch\f4\fs28 Heading;}
-{\s16\sbasedon0\snext16\sl288\slmult1\sb0\sa140 Text Body;}
-{\s17\sbasedon16\snext17\sl288\slmult1\sb0\sa140\dbch\af8 List;}
-{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af8\afs24\ai\fs24 Caption;}
-{\s19\sbasedon0\snext19\noline\dbch\af8 Index;}
-}{\*\generator LibreOffice/5.2.3.3$Linux_X86_64 LibreOffice_project/20m0$Build-3}{\info{\author Olivier }{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr2016\mo12\dy8\hr11\min16}{\printim\yr0\mo0\dy0\hr0\min0}}{\*\userprops}\deftab720
-\viewscale100
-{\*\pgdsctbl
-{\pgdsc0\pgdscuse451\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\pgdscnxt0 Default Style;}}
-\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
-{\*\ftnsep}\pgndec\pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-Python-pyo (version 0.8.}{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-1}{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-) for python 2.7}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-System requirements : }{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-macOS}{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
- 10.8 to 10.12}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-This package installs all the required components to run pyo inside your current Python installation. Python 2.7 (32/64 bit) must be already installed on your system.}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-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\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-1. pyo extension:}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-The following components will be installed in the site-packages folder of the current Python Framework:}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-_pyo.so}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-_pyo64.so}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-pyo.py}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-pyo64.py}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-pyolib (folder)}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-2. Support libraries (i386 and x86_64):}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-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\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-Warning:}{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
- 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\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-liblo.7.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libportaudio.2.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libportmidi.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libsndfile.1.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libFLAC.8.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libvorbisenc.2.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libvorbis.0.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libogg.0.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-Olivier B\u233\'e9langer, 2016}
-\par }
\ No newline at end of file
+{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf400
+{\fonttbl\f0\fnil\fcharset0 LucidaGrande;\f1\froman\fcharset0 Times-Roman;}
+{\colortbl;\red255\green255\blue255;}
+{\info
+{\author Olivier }}\margl1440\margr1440\vieww10800\viewh8400\viewkind0
+\deftab720
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720
+
+\f0\fs26 \cf0 Python-pyo (version 0.8.3) for python 2.7
+\f1\fs24 \
+
+\f0\fs26 \
+System requirements : macOS 10.6 to 10.12
+\f1\fs24 \
+
+\f0\fs26 \
+This package installs all the required components to run pyo inside your current Python installation. Python 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
+
+\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 and x86_64):
+\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.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
+\f1\fs24 \
+
+\f0\fs26 libvorbisenc.2.dylib
+\f1\fs24 \
+
+\f0\fs26 libvorbis.0.dylib
+\f1\fs24 \
+
+\f0\fs26 libogg.0.dylib
+\f1\fs24 \
+
+\f0\fs26 \
+\pard\pardeftab720
+\cf0 Olivier B\'e9langer, 2016
+\f1\fs24 \
+}
\ No newline at end of file
diff --git a/installers/osx/PkgResources_x86_64_py3/ReadMe.rtf b/installers/osx/PkgResources_x86_64_py3/ReadMe.rtf
index 1afd5e1..1a3f0e0 100755
--- a/installers/osx/PkgResources_x86_64_py3/ReadMe.rtf
+++ b/installers/osx/PkgResources_x86_64_py3/ReadMe.rtf
@@ -1,84 +1,97 @@
-{\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\fcharset0 LucidaGrande;}{\f6\fnil\fprq2\fcharset0 WenQuanYi Micro Hei;}{\f7\fnil\fprq2\fcharset0 FreeSans;}{\f8\fswiss\fprq0\fcharset128 FreeSans;}}
-{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}
-{\stylesheet{\s0\snext0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105 Normal;}
-{\s15\sbasedon0\snext16\sb240\sa120\keepn\dbch\af6\dbch\af7\afs28\loch\f4\fs28 Heading;}
-{\s16\sbasedon0\snext16\sl288\slmult1\sb0\sa140 Text Body;}
-{\s17\sbasedon16\snext17\sl288\slmult1\sb0\sa140\dbch\af8 List;}
-{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af8\afs24\ai\fs24 Caption;}
-{\s19\sbasedon0\snext19\noline\dbch\af8 Index;}
-}{\*\generator LibreOffice/5.2.3.3$Linux_X86_64 LibreOffice_project/20m0$Build-3}{\info{\author Olivier }{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr2016\mo12\dy8\hr11\min17}{\printim\yr0\mo0\dy0\hr0\min0}}{\*\userprops}\deftab720
-\viewscale100
-{\*\pgdsctbl
-{\pgdsc0\pgdscuse451\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\pgdscnxt0 Default Style;}}
-\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
-{\*\ftnsep}\pgndec\pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-Python-pyo (version 0.8.}{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-1}{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-) for python 3.5}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-System requirements : }{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-macOS}{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
- 10.8 to 10.12}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-This package installs all the required components to run pyo inside your current Python installation. Python 3.5 (32/64 bit) must be already installed on your system.}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-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\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-1. pyo extension:}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-The following components will be installed in the site-packages folder of the current Python Framework:}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-_pyo.cpython-35m-darwin.so}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-_pyo64.cpython-35m-darwin.so}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-pyo.py}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-pyo64.py}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-pyolib (folder)}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-2. Support libraries (i386 and x86_64):}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-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\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-Warning:}{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
- 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\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-liblo.7.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libportaudio.2.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libportmidi.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libsndfile.1.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libFLAC.8.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libvorbisenc.2.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libvorbis.0.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-libogg.0.dylib}
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-
-\par \pard\plain \s0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\hich\af3\fs24\lang4105{\cf1\b0\rtlch \ltrch\loch\fs26\loch\f5\hich\af5
-Olivier B\u233\'e9langer, 2016}
-\par }
\ No newline at end of file
+{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf400
+{\fonttbl\f0\fnil\fcharset0 LucidaGrande;\f1\froman\fcharset0 Times-Roman;}
+{\colortbl;\red255\green255\blue255;}
+{\info
+{\author Olivier }}\margl1440\margr1440\vieww10800\viewh8400\viewkind0
+\deftab720
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720
+
+\f0\fs26 \cf0 Python-pyo (version 0.8.3) for python 3.5
+\f1\fs24 \
+
+\f0\fs26 \
+System requirements : macOS 10.8 to 10.12
+\f1\fs24 \
+
+\f0\fs26 \
+This package installs all the required components to run pyo inside your current Python installation. Python 3.5 (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
+
+\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.cpython-35m-darwin.so
+\f1\fs24 \
+
+\f0\fs26 _pyo64.cpython-35m-darwin.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 and x86_64):
+\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.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
+\f1\fs24 \
+
+\f0\fs26 libvorbisenc.2.dylib
+\f1\fs24 \
+
+\f0\fs26 libvorbis.0.dylib
+\f1\fs24 \
+
+\f0\fs26 libogg.0.dylib
+\f1\fs24 \
+
+\f0\fs26 \
+\pard\pardeftab720
+\cf0 Olivier B\'e9langer, 2016
+\f1\fs24 \
+}
\ No newline at end of file
diff --git a/installers/osx/release_x86_64_py2.sh b/installers/osx/release_x86_64_py2.sh
index 0fec069..acf1b3f 100755
--- a/installers/osx/release_x86_64_py2.sh
+++ b/installers/osx/release_x86_64_py2.sh
@@ -8,9 +8,9 @@
# 3. cd utils and build E-Pyo for python2
# 4. cd installers/osx and build the release for python2
-export PACKAGE_NAME=pyo_0.8.1_x86_64_py2.pkg
-export DMG_DIR="pyo 0.8.1 py2 Universal"
-export DMG_NAME="pyo_0.8.1_OSX_py2-universal.dmg"
+export PACKAGE_NAME=pyo_0.8.3_x86_64_py2.pkg
+export DMG_DIR="pyo 0.8.3 py2 Universal"
+export DMG_NAME="pyo_0.8.3_OSX_py2-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
diff --git a/installers/osx/release_x86_64_py3.sh b/installers/osx/release_x86_64_py3.sh
index a7401a8..4abc0a7 100755
--- a/installers/osx/release_x86_64_py3.sh
+++ b/installers/osx/release_x86_64_py3.sh
@@ -8,9 +8,9 @@
# 3. cd utils and build E-Pyo for python3
# 4. cd installers/osx and build the release for python3
-export PACKAGE_NAME=pyo_0.8.1_x86_64_py3.pkg
-export DMG_DIR="pyo 0.8.1 py3 Universal"
-export DMG_NAME="pyo_0.8.1_OSX_py3-universal.dmg"
+export PACKAGE_NAME=pyo_0.8.3_x86_64_py3.pkg
+export DMG_DIR="pyo 0.8.3 py3 Universal"
+export DMG_NAME="pyo_0.8.3_OSX_py3-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
diff --git a/installers/win/win_installer_py27.iss b/installers/win/win_installer_py27.iss
index d34ab8a..a9eb776 100644
--- a/installers/win/win_installer_py27.iss
+++ b/installers/win/win_installer_py27.iss
@@ -3,7 +3,7 @@
#define appName "pyo"
#define pyVer "2.7"
-#define appVer "0.8.1"
+#define appVer "0.8.3"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
diff --git a/installers/win/win_installer_py35.iss b/installers/win/win_installer_py35.iss
index 8962ee9..d95583e 100644
--- a/installers/win/win_installer_py35.iss
+++ b/installers/win/win_installer_py35.iss
@@ -3,7 +3,7 @@
#define appName "pyo"
#define pyVer "3.5"
-#define appVer "0.8.1"
+#define appVer "0.8.3"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
diff --git a/pyo.py b/pyo.py
index 5791e4f..e93e6f2 100644
--- a/pyo.py
+++ b/pyo.py
@@ -94,7 +94,7 @@ OBJECTS_TREE = {
'SquareTable', 'ChebyTable', 'CosTable',
'CurveTable', 'ExpTable', 'DataTable',
'WinTable', 'SincTable', 'PartialTable',
- 'AtanTable', 'PadSynthTable']),
+ 'AtanTable', 'PadSynthTable', 'SharedTable']),
'PyoPVObject' : sorted(['PVAnal', 'PVSynth', 'PVTranspose', 'PVVerb',
'PVGate', 'PVAddSynth', 'PVCross', 'PVMult',
'PVMorph', 'PVFilter', 'PVDelay', 'PVBuffer',
@@ -143,7 +143,8 @@ OBJECTS_TREE = {
'Granule', 'TableRead', 'TableMorph',
'Looper', 'TableIndex', 'OscBank', 'OscTrig',
'TablePut', 'TableScale', 'Particle',
- 'TableWrite']),
+ 'Particle2', 'TableWrite', 'TableFill',
+ 'TableScan']),
'matrixprocess': sorted(['MatrixRec', 'MatrixPointer', 'MatrixMorph',
'MatrixRecLoop']),
'triggers': sorted(['Metro', 'Beat', 'TrigEnv', 'TrigRand', 'Trig',
@@ -168,6 +169,7 @@ OBJECTS_TREE = {
'SLMapQ', 'SLMapDur', 'SLMapPan'])},
'Server': [],
'MidiListener': [],
+ 'MidiDispatcher': [],
'OscListener': [],
'Stream': [],
'TableStream': [],
diff --git a/pyolib/_core.py b/pyolib/_core.py
index acf8a70..447ae92 100644
--- a/pyolib/_core.py
+++ b/pyolib/_core.py
@@ -1,9 +1,13 @@
-# -*- coding: utf-8 -*-
+# encoding: utf-8
+"""
+This module defines the base classes for all objects in the library.
+
+"""
from __future__ import division
from __future__ import print_function
from __future__ import absolute_import
"""
-Copyright 2009-2015 Olivier Belanger
+Copyright 2009-2016 Olivier Belanger
This file is part of pyo, a python module to help digital signal
processing script creation.
@@ -20,9 +24,13 @@ GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with pyo. If not, see <http://www.gnu.org/licenses/>.
+
"""
-import types
-import random, os, sys, inspect, tempfile
+import os
+import sys
+import random
+import inspect
+import tempfile
from subprocess import call
from weakref import proxy
@@ -31,86 +39,88 @@ if sys.version_info[0] < 3:
builtins = __builtin__
bytes_t = str
unicode_t = unicode
- def tobytes(str, encoding=None):
- return bytes(str)
+ def tobytes(strng, encoding=None):
+ "Convert unicode string to bytes."
+ return bytes(strng)
else:
import builtins
bytes_t = bytes
unicode_t = str
- def tobytes(str, encoding="utf-8"):
- return bytes(str, encoding=encoding)
+ def tobytes(strng, encoding="utf-8"):
+ "Convert unicode string to bytes."
+ return bytes(strng, encoding=encoding)
if hasattr(builtins, 'pyo_use_double'):
- import pyo64 as current_pyo
from _pyo64 import *
+ import pyo64 as current_pyo
else:
- import pyo as current_pyo
from _pyo import *
+ import pyo as current_pyo
-from ._maps import *
+from ._maps import SLMap, SLMapMul
from ._widgets import createCtrlWindow
from ._widgets import createViewTableWindow
from ._widgets import createViewMatrixWindow
-
+
######################################################################
### Utilities
######################################################################
current_pyo_path = os.path.dirname(current_pyo.__file__)
SNDS_PATH = os.path.join(current_pyo_path, "pyolib", "snds")
-XNOISE_DICT = {'uniform': 0, 'linear_min': 1, 'linear_max': 2, 'triangle': 3,
- 'expon_min': 4, 'expon_max': 5, 'biexpon': 6, 'cauchy': 7,
- 'weibull': 8, 'gaussian': 9, 'poisson': 10, 'walker': 11,
+XNOISE_DICT = {'uniform': 0, 'linear_min': 1, 'linear_max': 2, 'triangle': 3,
+ 'expon_min': 4, 'expon_max': 5, 'biexpon': 6, 'cauchy': 7,
+ 'weibull': 8, 'gaussian': 9, 'poisson': 10, 'walker': 11,
'loopseg': 12}
-FILE_FORMATS = {'wav': 0, 'wave': 0, 'aif': 1, 'aiff': 1, 'au': 2, '': 3,
+FILE_FORMATS = {'wav': 0, 'wave': 0, 'aif': 1, 'aiff': 1, 'au': 2, '': 3,
'sd2': 4, 'flac': 5, 'caf': 6, 'ogg': 7}
FUNCTIONS_INIT_LINES = {
- "pa_count_host_apis": "pa_count_host_apis()",
+ "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_get_default_host_api": "pa_get_default_host_api()",
"pa_count_devices": "pa_count_devices()",
- "pa_list_devices": "pa_list_devices()",
+ "pa_list_devices": "pa_list_devices()",
"pa_get_devices_infos": "pa_get_devices_infos()",
- "pa_get_version": "pa_get_version()",
+ "pa_get_version": "pa_get_version()",
"pa_get_version_text": "pa_get_version_text()",
- "pa_get_input_devices": "pa_get_input_devices()",
+ "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_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_input_max_channels": "pa_get_input_max_channels(x)",
"pa_get_output_max_channels": "pa_get_output_max_channels(x)",
- "pm_get_default_output": "pm_get_default_output()",
+ "pm_get_default_output": "pm_get_default_output()",
"pm_get_default_input": "pm_get_default_input()",
- "pm_get_output_devices": "pm_get_output_devices()",
+ "pm_get_output_devices": "pm_get_output_devices()",
"pm_get_input_devices": "pm_get_input_devices()",
- "pm_list_devices": "pm_list_devices()",
+ "pm_list_devices": "pm_list_devices()",
"pm_count_devices": "pm_count_devices()",
- "sndinfo": "sndinfo(path, print=False)",
- "savefile":
- "savefile(samples, path, sr=44100, channels=1, fileformat=0, sampletype=0)",
- "savefileFromTable":
- "savefileFromTable(table, path, fileformat=0, sampletype=0)",
- "upsamp": "upsamp(path, outfile, up=4, order=128)",
+ "sndinfo": "sndinfo(path, print=False)",
+ "savefile": "savefile(samples, path, sr=44100, channels=1, "
+ "fileformat=0, sampletype=0)",
+ "savefileFromTable": "savefileFromTable(table, path, fileformat=0, "
+ "sampletype=0)",
+ "upsamp": "upsamp(path, outfile, up=4, order=128)",
"downsamp": "downsamp(path, outfile, down=4, order=128)",
- "midiToHz": "midiToHz(x)",
- "hzToMidi": "hzToMidi(x)",
- "midiToTranspo": "midiToTranspo(x)",
+ "midiToHz": "midiToHz(x)",
+ "hzToMidi": "hzToMidi(x)",
+ "midiToTranspo": "midiToTranspo(x)",
"sampsToSec": "sampsToSec(x)",
- "secToSamps": "secToSamps(x)",
- "linToCosCurve":
- "linToCosCurve(data, yrange=[0, 1], totaldur=1, points=1024, log=False)",
- "rescale":
- "rescale(data, xmin=0.0, xmax=1.0, ymin=0.0, ymax=1.0, xlog=False, ylog=False)",
- "distanceToSegment":
- "distanceToSegment(p, p1, p2, xmin=0.0, xmax=1.0, ymin=0.0, ymax=1.0, xlog=False, ylog=False)",
- "reducePoints": "reducePoints(pointlist, tolerance=0.02)",
- "serverCreated": "serverCreated()",
+ "secToSamps": "secToSamps(x)",
+ "linToCosCurve": "linToCosCurve(data, yrange=[0, 1], totaldur=1, "
+ "points=1024, log=False)",
+ "rescale": "rescale(data, xmin=0.0, xmax=1.0, ymin=0.0, ymax=1.0, "
+ "xlog=False, ylog=False)",
+ "distanceToSegment": "distanceToSegment(p, p1, p2, xmin=0.0, xmax=1.0, "
+ "ymin=0.0, ymax=1.0, xlog=False, ylog=False)",
+ "reducePoints": "reducePoints(pointlist, tolerance=0.02)",
+ "serverCreated": "serverCreated()",
"serverBooted": "serverBooted()",
- "example": "example(cls, dur=5, toprint=True, double=False)",
- "class_args": "class_args(cls)",
+ "example": "example(cls, dur=5, toprint=True, double=False)",
+ "class_args": "class_args(cls)",
"getVersion": "getVersion()",
- "convertStringToSysEncoding": "convertStringToSysEncoding(str)",
+ "convertStringToSysEncoding": "convertStringToSysEncoding(str)",
"convertArgsToLists": "convertArgsToLists(*args)",
- "wrap": "wrap(arg, i)",
+ "wrap": "wrap(arg, i)",
"floatmap": "floatmap(x, min=0, max=1, exp=1)",
"getPyoKeywords": "getPyoKeywords()"
}
@@ -125,15 +135,19 @@ class PyoArgumentTypeError(PyoError):
"""Error raised when if an object got an invalid argument."""
def isAudioObject(obj):
+ "Return True if the argument is an audio object."
return isinstance(obj, PyoObject) or hasattr(obj, "stream")
def isTableObject(obj):
+ "Return True if the argument is a table object."
return isinstance(obj, PyoTableObject) or hasattr(obj, "tablestream")
def isMatrixObject(obj):
+ "Return True if the argument is a matrix object."
return isinstance(obj, PyoMatrixObject) or hasattr(obj, "matrixstream")
def isPVObject(obj):
+ "Return True if the argument is a PV object."
return isinstance(obj, PyoPVObject) or hasattr(obj, "pv_stream")
def pyoArgsAssert(obj, format, *args):
@@ -183,28 +197,29 @@ def pyoArgsAssert(obj, format, *args):
# Not used in Python 3, ignore it
longType = None
+ i = 0
expected = ""
- for i in range(len(args)):
+ for i, arg in enumerate(args):
f = format[i]
- argtype = type(args[i])
+ argtype = type(arg)
if f == "O":
- if not isAudioObject(args[i]) and \
- argtype not in [list, int, longType, float]:
+ atypes = [list, int, longType, float]
+ if not isAudioObject(arg) and argtype not in atypes:
expected = "float or PyoObject"
elif f == "o":
- if not isAudioObject(args[i]) and argtype not in [list]:
+ if not isAudioObject(arg) and argtype not in [list]:
expected = "PyoObject"
elif f == "T":
- if not isTableObject(args[i]) and argtype not in [float, list]:
+ if not isTableObject(arg) and argtype not in [float, list]:
expected = "float or PyoTableObject"
elif f == "t":
- if not isTableObject(args[i]) and argtype not in [list]:
+ if not isTableObject(arg) and argtype not in [list]:
expected = "PyoTableObject"
elif f == "m":
- if not isMatrixObject(args[i]) and argtype not in [list]:
+ if not isMatrixObject(arg) and argtype not in [list]:
expected = "PyoMatrixObject"
elif f == "p":
- if not isPVObject(args[i]) and argtype not in [list]:
+ if not isPVObject(arg) and argtype not in [list]:
expected = "PyoPVObject"
elif f == "n":
if argtype not in [list, int, longType, float]:
@@ -249,10 +264,10 @@ def pyoArgsAssert(obj, format, *args):
if argtype not in [list, tuple]:
expected = "list or tuple"
elif f == "c":
- if not callable(args[i]) and argtype not in [list, tuple, type(None)]:
+ if not callable(arg) and argtype not in [list, tuple, type(None)]:
expected = "callable"
elif f == "C":
- if not callable(args[i]) and argtype not in [type(None)]:
+ if not callable(arg) and argtype not in [type(None)]:
expected = "callable - list not allowed"
elif f == "z":
pass
@@ -265,7 +280,7 @@ def pyoArgsAssert(obj, format, *args):
err = 'bad argument at position %d to "%s" (%s expected, got %s)'
raise PyoArgumentTypeError(err % (i, name, expected, argtype))
-def convertStringToSysEncoding(str):
+def convertStringToSysEncoding(strng):
"""
Convert a string to the current platform file system encoding.
@@ -273,14 +288,14 @@ def convertStringToSysEncoding(str):
:Args:
- str: string
+ strng: string
String to convert.
"""
- if type(str) not in [bytes_t, unicode_t]:
- str = str.decode("utf-8")
- str = str.encode(sys.getfilesystemencoding())
- return str
+ if type(strng) not in [bytes_t, unicode_t]:
+ strng = strng.decode("utf-8")
+ strng = strng.encode(sys.getfilesystemencoding())
+ return strng
def convertArgsToLists(*args):
"""
@@ -290,7 +305,7 @@ def convertArgsToLists(*args):
"""
converted = []
for i in args:
- if isinstance(i, PyoObjectBase) or type(i) == list:
+ if isinstance(i, PyoObjectBase) or isinstance(i, list):
converted.append(i)
else:
converted.append([i])
@@ -311,7 +326,7 @@ def wrap(arg, i):
def example(cls, dur=5, toprint=True, double=False):
"""
- Execute the example given in the documentation of the object as an argument.
+ Execute the documentation example of the object given as an argument.
:Args:
@@ -332,7 +347,7 @@ def example(cls, dur=5, toprint=True, double=False):
doc = cls.__doc__.splitlines()
lines = []
store = False
- for i, line in enumerate(doc):
+ for line in doc:
if not store:
if ">>> s = Server" in line:
store = True
@@ -352,8 +367,10 @@ def example(cls, dur=5, toprint=True, double=False):
else:
ex = "import time\nfrom pyo import *\n"
for line in ex_lines:
- if ">>>" in line: line = line.lstrip(">>> ")
- if "..." in line: line = " " + line.lstrip("... ")
+ if ">>>" in line:
+ line = line.lstrip(">>> ")
+ if "..." in line:
+ line = " " + line.lstrip("... ")
ex += line + "\n"
ex += "time.sleep(%f)\ns.stop()\ntime.sleep(0.25)\ns.shutdown()\n" % dur
@@ -365,10 +382,11 @@ def example(cls, dur=5, toprint=True, double=False):
executable = sys.executable
if not executable or executable is None:
executable = "python"
- p = call([executable, f.name])
+ call([executable, f.name])
def removeExtraDecimals(x):
- if type(x) == float:
+ "Return a floating-point value as a string with only two digits."
+ if isinstance(x, float):
return "=%.2f" % x
elif type(x) in [bytes_t, unicode_t]:
return '="%s"' % x
@@ -394,8 +412,9 @@ def class_args(cls):
name = cls.__name__
try:
# Try for a class __init__ function
- arg, varargs, varkw, defaults = inspect.getargspec(getattr(cls, "__init__"))
- arg = inspect.formatargspec(arg, varargs, varkw, defaults,
+ init = getattr(cls, "__init__")
+ arg, varargs, varkw, defaults = inspect.getargspec(init)
+ arg = inspect.formatargspec(arg, varargs, varkw, defaults,
formatvalue=removeExtraDecimals)
arg = arg.replace("self, ", "")
return name + arg
@@ -426,6 +445,7 @@ def getVersion():
return (int(major), int(minor), int(rev))
def getWeakMethodRef(x):
+ "Return a callable object as a weak method reference."
if type(x) in [list, tuple]:
tmp = []
for y in x:
@@ -480,10 +500,10 @@ class PyoObjectBase(object):
**Operations allowed on all PyoObjectBase**
>>> len(obj) # Return the number of streams managed by the object.
- >>> obj[x] # Return stream `x` of the object.
+ >>> obj[x] # Return stream `x` of the object.
>>> # `x` is a number from 0 to len(obj)-1.
>>> dir(obj) # Return the list of attributes of the object.
- >>> for x in obj: # Can be used as an iterator (iterates over
+ >>> for x in obj: # Can be used as an iterator (iterates over
>>> # object's audio streams).
"""
@@ -493,6 +513,8 @@ class PyoObjectBase(object):
_STREAM_TYPE = ''
def __init__(self):
+ self._base_objs = []
+ self._trig_objs = None
self.__index = 0
if not serverCreated():
raise PyoServerStateException("You must create and boot a Server "
@@ -510,7 +532,7 @@ class PyoObjectBase(object):
"""
attrs = dir(self)
- pp = '< Instance of %s class >' % self.__class__.__name__
+ pp = '< Instance of %s class >' % self.__class__.__name__
pp += '\n-----------------------------'
pp += '\nNumber of %s streams: %d' % (self._STREAM_TYPE, len(self))
pp += '\n--- Attributes ---'
@@ -550,7 +572,7 @@ class PyoObjectBase(object):
def __iter__(self):
self.__index = 0
return self
-
+
def __next__(self):
if self.__index >= len(self):
raise StopIteration
@@ -559,19 +581,22 @@ class PyoObjectBase(object):
return x
def next(self):
+ "Alias for __next__ method."
# In Python 2.x, __next__() method is called next().
return self.__next__()
def __getitem__(self, i):
- if i == 'trig': # not safe...
+ if i == 'trig':
return self._trig_objs
if type(i) == slice or i < len(self._base_objs):
return self._base_objs[i]
else:
if type(i) in [bytes_t, unicode_t]:
- print("Object %s has no stream named '%s'!" % (self.__class__.__name__, i))
+ args = (self.__class__.__name__, i)
+ print("Object %s has no stream named '%s'!" % args)
else:
- print("'i' too large in slicing %s object %s!" % (self._STREAM_TYPE, self.__class__.__name__))
+ args = (self._STREAM_TYPE, self.__class__.__name__)
+ print("'i' too large in slicing %s object %s!" % args)
def __len__(self):
return len(self._base_objs)
@@ -580,7 +605,8 @@ class PyoObjectBase(object):
return '< Instance of %s class >' % self.__class__.__name__
def __dir__(self):
- args, varargs, varkw, defaults = inspect.getargspec(getattr(self.__class__, "__init__"))
+ init = getattr(self.__class__, "__init__")
+ args, _, _, _ = inspect.getargspec(init)
args = [a for a in args if hasattr(self.__class__, a) and a != "self"]
return args
@@ -610,7 +636,8 @@ class PyoObject(PyoObjectBase):
between pyo objects or between pyo objects and numbers. Doing so
returns a Dummy object with the result of the operation.
- >>> # creates a Dummy object `b` with `mul` set to 0.5 and leave `a` unchanged.
+ >>> # Creates a Dummy object `b` with `mul` set to 0.5.
+ >>> # Leaves `a` unchanged.
>>> b = a * 0.5
Inplace multiplication, addition, division and substraction can be
@@ -619,7 +646,8 @@ class PyoObject(PyoObjectBase):
>>> a *= 0.5 # replaces the `mul` attribute of `a`.
- The next operators can be used with PyoObject (not with XXX_base objects).
+ The next operators can only be used with PyoObject, not with
+ XXX_base objects.
**Exponent** and **modulo**
@@ -634,15 +662,16 @@ class PyoObject(PyoObjectBase):
**Comparison operators**
- >>> a < b # returns a Compare object created as: Compare(a, comp=b, mode="<")
- >>> a <= b # returns a Compare object created as: Compare(a, comp=b, mode="<=")
- >>> a == b # returns a Compare object created as: Compare(a, comp=b, mode="==")
- >>> a != b # returns a Compare object created as: Compare(a, comp=b, mode="!=")
- >>> a > b # returns a Compare object created as: Compare(a, comp=b, mode=">")
- >>> a >= b # returns a Compare object created as: Compare(a, comp=b, mode=">=")
+ >>> # Comparison operators return a Compare object.
+ >>> x = a < b # same as: x = Compare(a, comp=b, mode="<")
+ >>> x = a <= b # same as: Compare(a, comp=b, mode="<=")
+ >>> x = a == b # same as: Compare(a, comp=b, mode="==")
+ >>> x = a != b # same as: Compare(a, comp=b, mode="!=")
+ >>> x = a > b # same as: Compare(a, comp=b, mode=">")
+ >>> x = a >= b # same as: Compare(a, comp=b, mode=">=")
- A special case concerns the comparison of a PyoObject with None. All operators
- return False except `a != None`, which returns True.
+ A special case concerns the comparison of a PyoObject with None.
+ All operators return False except `a != None`, which returns True.
"""
@@ -659,25 +688,30 @@ class PyoObject(PyoObjectBase):
self._op_duplicate = 1
self._map_list = []
self._zeros = None
+ self._base_players = None
def __add__(self, x):
x, lmax = convertArgsToLists(x)
if self.__len__() >= lmax:
- _add_dummy = Dummy([obj + wrap(x,i//self._op_duplicate) for i, obj in enumerate(self._base_objs)])
+ _add_dummy = Dummy([obj + wrap(x, i//self._op_duplicate) \
+ for i, obj in enumerate(self._base_objs)])
else:
if isinstance(x, PyoObject):
_add_dummy = x + self
else:
- _add_dummy = Dummy([wrap(self._base_objs,i) + obj for i, obj in enumerate(x)])
+ _add_dummy = Dummy([wrap(self._base_objs, i) + obj \
+ for i, obj in enumerate(x)])
self._keep_trace.append(_add_dummy)
return _add_dummy
def __radd__(self, x):
x, lmax = convertArgsToLists(x)
if self.__len__() >= lmax:
- _add_dummy = Dummy([obj + wrap(x,i//self._op_duplicate) for i, obj in enumerate(self._base_objs)])
+ _add_dummy = Dummy([obj + wrap(x, i//self._op_duplicate) \
+ for i, obj in enumerate(self._base_objs)])
else:
- _add_dummy = Dummy([wrap(self._base_objs,i) + obj for i, obj in enumerate(x)])
+ _add_dummy = Dummy([wrap(self._base_objs, i) + obj \
+ for i, obj in enumerate(x)])
self._keep_trace.append(_add_dummy)
return _add_dummy
@@ -688,12 +722,15 @@ class PyoObject(PyoObjectBase):
def __sub__(self, x):
x, lmax = convertArgsToLists(x)
if self.__len__() >= lmax:
- _add_dummy = Dummy([obj - wrap(x,i//self._op_duplicate) for i, obj in enumerate(self._base_objs)])
+ _add_dummy = Dummy([obj - wrap(x, i//self._op_duplicate) \
+ for i, obj in enumerate(self._base_objs)])
else:
if isinstance(x, PyoObject):
- _add_dummy = Dummy([wrap(self._base_objs,i) - wrap(x,i) for i in range(lmax)])
+ _add_dummy = Dummy([wrap(self._base_objs, i) - wrap(x, i) \
+ for i in range(lmax)])
else:
- _add_dummy = Dummy([wrap(self._base_objs,i) - obj for i, obj in enumerate(x)])
+ _add_dummy = Dummy([wrap(self._base_objs, i) - obj \
+ for i, obj in enumerate(x)])
self._keep_trace.append(_add_dummy)
return _add_dummy
@@ -711,7 +748,7 @@ class PyoObject(PyoObjectBase):
for i, obj in enumerate(x):
sub_upsamp = Sig(obj)
self._keep_trace.append(sub_upsamp)
- tmp.append(sub_upsamp - wrap(self._base_objs,i))
+ tmp.append(sub_upsamp - wrap(self._base_objs, i))
_add_dummy = Dummy(tmp)
self._keep_trace.append(_add_dummy)
return _add_dummy
@@ -723,21 +760,25 @@ class PyoObject(PyoObjectBase):
def __mul__(self, x):
x, lmax = convertArgsToLists(x)
if self.__len__() >= lmax:
- _mul_dummy = Dummy([obj * wrap(x,i//self._op_duplicate) for i, obj in enumerate(self._base_objs)])
+ _mul_dummy = Dummy([obj * wrap(x, i//self._op_duplicate) \
+ for i, obj in enumerate(self._base_objs)])
else:
if isinstance(x, PyoObject):
_mul_dummy = x * self
else:
- _mul_dummy = Dummy([wrap(self._base_objs,i) * obj for i, obj in enumerate(x)])
+ _mul_dummy = Dummy([wrap(self._base_objs, i) * obj \
+ for i, obj in enumerate(x)])
self._keep_trace.append(_mul_dummy)
return _mul_dummy
def __rmul__(self, x):
x, lmax = convertArgsToLists(x)
if self.__len__() >= lmax:
- _mul_dummy = Dummy([obj * wrap(x,i//self._op_duplicate) for i, obj in enumerate(self._base_objs)])
+ _mul_dummy = Dummy([obj * wrap(x, i//self._op_duplicate) \
+ for i, obj in enumerate(self._base_objs)])
else:
- _mul_dummy = Dummy([wrap(self._base_objs,i) * obj for i, obj in enumerate(x)])
+ _mul_dummy = Dummy([wrap(self._base_objs, i) * obj \
+ for i, obj in enumerate(x)])
self._keep_trace.append(_mul_dummy)
return _mul_dummy
@@ -757,12 +798,15 @@ class PyoObject(PyoObjectBase):
def __div__(self, x):
x, lmax = convertArgsToLists(x)
if self.__len__() >= lmax:
- _mul_dummy = Dummy([obj / wrap(x,i//self._op_duplicate) for i, obj in enumerate(self._base_objs)])
+ _mul_dummy = Dummy([obj / wrap(x, i//self._op_duplicate) \
+ for i, obj in enumerate(self._base_objs)])
else:
if isinstance(x, PyoObject):
- _mul_dummy = Dummy([wrap(self._base_objs,i) / wrap(x,i) for i in range(lmax)])
+ _mul_dummy = Dummy([wrap(self._base_objs, i) / wrap(x, i) \
+ for i in range(lmax)])
else:
- _mul_dummy = Dummy([wrap(self._base_objs,i) / obj for i, obj in enumerate(x)])
+ _mul_dummy = Dummy([wrap(self._base_objs, i) / obj \
+ for i, obj in enumerate(x)])
self._keep_trace.append(_mul_dummy)
return _mul_dummy
@@ -780,7 +824,7 @@ class PyoObject(PyoObjectBase):
for i, obj in enumerate(x):
div_upsamp = Sig(obj)
self._keep_trace.append(div_upsamp)
- tmp.append(div_upsamp / wrap(self._base_objs,i))
+ tmp.append(div_upsamp / wrap(self._base_objs, i))
_mul_dummy = Dummy(tmp)
self._keep_trace.append(_mul_dummy)
return _mul_dummy
@@ -849,7 +893,10 @@ class PyoObject(PyoObjectBase):
def isOutputting(self, all=False):
"""
- Returns True if the object is sending samples to dac, otherwise, returns False.
+ Returns True if the object is outputting.
+
+ Returns True if the object is sending samples to dac,
+ otherwise, returns False.
:Args:
@@ -905,24 +952,26 @@ class PyoObject(PyoObjectBase):
:Args:
dur: float, optional
- Duration, in seconds, of the object's activation. The default is 0
- and means infinite duration.
+ Duration, in seconds, of the object's activation. The default
+ is 0 and means infinite duration.
delay: float, optional
Delay, in seconds, before the object's activation. Defaults to 0.
"""
pyoArgsAssert(self, "nn", dur, delay)
dur, delay, lmax = convertArgsToLists(dur, delay)
- if hasattr(self, "_trig_objs"):
- if type(self._trig_objs) == list:
+ if self._trig_objs is not None:
+ if isinstance(self._trig_objs, list):
for i in range(lmax):
for obj in self._trig_objs:
- obj.play(wrap(dur,i), wrap(delay,i))
+ obj.play(wrap(dur, i), wrap(delay, i))
else:
self._trig_objs.play(dur, delay)
- if hasattr(self, "_base_players"):
- [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._base_players)]
- [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._base_objs)]
+ if self._base_players is not None:
+ [obj.play(wrap(dur, i), wrap(delay, i)) \
+ for i, obj in enumerate(self._base_players)]
+ [obj.play(wrap(dur, i), wrap(delay, i)) \
+ for i, obj in enumerate(self._base_objs)]
return self
def out(self, chnl=0, inc=1, dur=0, delay=0):
@@ -935,15 +984,16 @@ class PyoObject(PyoObjectBase):
:Args:
chnl: int, optional
- Physical output assigned to the first audio stream of the object.
- Defaults to 0.
+ Physical output assigned to the first audio stream of the
+ object. Defaults to 0.
inc: int, optional
Output channel increment value. Defaults to 1.
dur: float, optional
- Duration, in seconds, of the object's activation. The default is 0
- and means infinite duration.
+ Duration, in seconds, of the object's activation. The default
+ is 0 and means infinite duration.
delay: float, optional
- Delay, in seconds, before the object's activation. Defaults to 0.
+ Delay, in seconds, before the object's activation.
+ Defaults to 0.
If `chnl` >= 0, successive streams increment the output number by
`inc` and wrap around the global number of channels.
@@ -958,22 +1008,27 @@ class PyoObject(PyoObjectBase):
"""
pyoArgsAssert(self, "iInn", chnl, inc, dur, delay)
dur, delay, lmax = convertArgsToLists(dur, delay)
- if hasattr(self, "_trig_objs"):
- if type(self._trig_objs) == list:
+ if self._trig_objs is not None:
+ if isinstance(self._trig_objs, list):
for i in range(lmax):
for obj in self._trig_objs:
- obj.play(wrap(dur,i), wrap(delay,i))
+ obj.play(wrap(dur, i), wrap(delay, i))
else:
self._trig_objs.play(dur, delay)
- if hasattr(self, "_base_players"):
- [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._base_players)]
- if type(chnl) == list:
- [obj.out(wrap(chnl,i), wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._base_objs)]
+ if self._base_players is not None:
+ [obj.play(wrap(dur, i), wrap(delay, i))
+ for i, obj in enumerate(self._base_players)]
+ if isinstance(chnl, list):
+ [obj.out(wrap(chnl, i), wrap(dur, i), wrap(delay, i)) \
+ for i, obj in enumerate(self._base_objs)]
else:
if chnl < 0:
- [obj.out(i*inc, wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(random.sample(self._base_objs, len(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:
- [obj.out(chnl+i*inc, wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._base_objs)]
+ [obj.out(chnl+i*inc, wrap(dur, i), wrap(delay, i)) \
+ for i, obj in enumerate(self._base_objs)]
return self
def stop(self):
@@ -984,12 +1039,12 @@ class PyoObject(PyoObjectBase):
creation.
"""
- if hasattr(self, "_trig_objs"):
- if type(self._trig_objs) == list:
+ if self._trig_objs is not None:
+ if isinstance(self._trig_objs, list):
[obj.stop() for obj in self._trig_objs]
else:
self._trig_objs.stop()
- if hasattr(self, "_base_players"):
+ if self._base_players is not None:
[obj.stop() for obj in self._base_players]
[obj.stop() for obj in self._base_objs]
return self
@@ -1002,8 +1057,8 @@ class PyoObject(PyoObjectBase):
:Args:
voices: int, optional
- Number of audio streams of the Mix object created by this method.
- Defaults to 1.
+ Number of audio streams of the Mix object created by this
+ method. Defaults to 1.
If more than 1, object's streams are alternated and added into
Mix object's streams.
@@ -1034,8 +1089,8 @@ class PyoObject(PyoObjectBase):
pyoArgsAssert(self, "nn", min, max)
min, max, lmax = convertArgsToLists(min, max)
if lmax > 1:
- mul = [(wrap(max,i) - wrap(min,i)) * 0.5 for i in range(lmax)]
- add = [(wrap(max,i) + wrap(min,i)) * 0.5 for i in range(lmax)]
+ mul = [(wrap(max, i) - wrap(min, i)) * 0.5 for i in range(lmax)]
+ add = [(wrap(max, i) + wrap(min, i)) * 0.5 for i in range(lmax)]
else:
mul = (max[0] - min[0]) * 0.5
add = (max[0] + min[0]) * 0.5
@@ -1055,8 +1110,9 @@ class PyoObject(PyoObjectBase):
"""
pyoArgsAssert(self, "O", x)
self._mul = x
- x, lmax = convertArgsToLists(x)
- [obj.setMul(wrap(x,i//self._op_duplicate)) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.setMul(wrap(x, i // self._op_duplicate)) \
+ for i, obj in enumerate(self._base_objs)]
def setAdd(self, x):
"""
@@ -1070,8 +1126,9 @@ class PyoObject(PyoObjectBase):
"""
pyoArgsAssert(self, "O", x)
self._add = x
- x, lmax = convertArgsToLists(x)
- [obj.setAdd(wrap(x,i//self._op_duplicate)) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.setAdd(wrap(x, i // self._op_duplicate)) \
+ for i, obj in enumerate(self._base_objs)]
def setSub(self, x):
"""
@@ -1085,8 +1142,9 @@ class PyoObject(PyoObjectBase):
"""
pyoArgsAssert(self, "O", x)
self._add = x
- x, lmax = convertArgsToLists(x)
- [obj.setSub(wrap(x,i//self._op_duplicate)) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.setSub(wrap(x, i // self._op_duplicate)) \
+ for i, obj in enumerate(self._base_objs)]
def setDiv(self, x):
"""
@@ -1100,8 +1158,9 @@ class PyoObject(PyoObjectBase):
"""
pyoArgsAssert(self, "O", x)
self._mul = x
- x, lmax = convertArgsToLists(x)
- [obj.setDiv(wrap(x,i//self._op_duplicate)) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.setDiv(wrap(x, i // self._op_duplicate)) \
+ for i, obj in enumerate(self._base_objs)]
def set(self, attr, value, port=0.025, callback=None):
"""
@@ -1122,7 +1181,7 @@ class PyoObject(PyoObjectBase):
callback: callable, optional
A python function to be called at the end of the ramp. If the
end of the ramp is not reached (ex.: called again before the
- end of the portamento), the callback will not be called.
+ end of the portamento), the callback will not be called.
"""
pyoArgsAssert(self, "SnnC", attr, value, port, callback)
@@ -1134,7 +1193,8 @@ class PyoObject(PyoObjectBase):
if self._signal_dict[attr].isPlaying():
init = self._signal_dict[attr].get(True)
self._signal_dict[attr].stop()
- self._signal_dict[attr] = VarPort(value, port, init, self._reset_from_set, attr)
+ self._signal_dict[attr] = VarPort(value, port, init,
+ self._reset_from_set, attr)
setattr(self, attr, self._signal_dict[attr])
def _reset_from_set(self, attr=None):
@@ -1173,7 +1233,8 @@ class PyoObject(PyoObjectBase):
if map_list is None:
map_list = self._map_list
if map_list == []:
- print(("There are no controls for %s object." % self.__class__.__name__))
+ clsname = self.__class__.__name__
+ print("There are no controls for %s object." % clsname)
return
createCtrlWindow(self, map_list, title, wxnoserver)
@@ -1182,14 +1243,16 @@ class PyoObject(PyoObjectBase):
"""float or PyoObject. Multiplication factor."""
return self._mul
@mul.setter
- def mul(self, x): self.setMul(x)
+ def mul(self, x):
+ self.setMul(x)
@property
def add(self):
"""float or PyoObject. Addition factor."""
return self._add
@add.setter
- def add(self, x): self.setAdd(x)
+ def add(self, x):
+ self.setAdd(x)
######################################################################
### PyoTableObject -> base class for pyo table objects
@@ -1207,7 +1270,8 @@ class PyoTableObject(PyoObjectBase):
:Args:
size: int
- Length of the table in samples. Usually provided by the child object.
+ Length of the table in samples. Usually provided by the
+ child object.
"""
@@ -1332,16 +1396,18 @@ class PyoTableObject(PyoObjectBase):
"""
Return a reference to the underlying object implementing the buffer protocol.
- With the buffer protocol, a table can be referenced and modified, without
- copying the data, with numpy functions. To create an array using the same
- memory as the table:
+ With the buffer protocol, a table can be referenced and modified,
+ without copying the data, with numpy functions. To create an array
+ using the same memory as the table:
t = SndTable(SNDS_PATH+"/transparent.aif")
arr = numpy.asarray(t.getBuffer())
- Now, every changes applied to the array will be reflected in the SndTable.
+ Now, every changes applied to the array will be reflected in
+ the SndTable.
- For more details about the buffer protocol, see PEP 3118 and python documentation.
+ For more details about the buffer protocol, see PEP 3118 and
+ python documentation.
"""
if chnl < 0 or chnl >= len(self):
@@ -1382,7 +1448,7 @@ class PyoTableObject(PyoObjectBase):
if all:
return [obj.getSize() for obj in self._base_objs]
else:
- if type(self._size) == list:
+ if isinstance(self._size, list):
return self._size[0]
else:
return self._size
@@ -1409,7 +1475,7 @@ class PyoTableObject(PyoObjectBase):
def get(self, pos):
"""
- Returns the value, as float, stored at a specified position in the table.
+ Returns the value, as float, stored at a specific position in the table.
If the object has more than 1 tablestream, the default is to
return a list with the value of each tablestream. User can call
@@ -1423,8 +1489,10 @@ class PyoTableObject(PyoObjectBase):
"""
pyoArgsAssert(self, "I", pos)
values = [obj.get(pos) for obj in self._base_objs]
- if len(values) == 1: return values[0]
- else: return values
+ if len(values) == 1:
+ return values[0]
+ else:
+ return values
def getTable(self, all=False):
"""
@@ -1591,14 +1659,14 @@ class PyoTableObject(PyoObjectBase):
"""
pyoArgsAssert(self, "T", x)
- if type(x) == list:
- if type(x[0]) == list:
- [obj.add(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ if isinstance(x, list):
+ if isinstance(x[0], list):
+ [obj.add(wrap(x, i)) for i, obj in enumerate(self._base_objs)]
else:
[obj.add(x) for obj in self._base_objs]
else:
- x, lmax = convertArgsToLists(x)
- [obj.add(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.add(wrap(x, i)) for i, obj in enumerate(self._base_objs)]
self.refreshView()
return self
@@ -1616,14 +1684,14 @@ class PyoTableObject(PyoObjectBase):
"""
pyoArgsAssert(self, "T", x)
- if type(x) == list:
- if type(x[0]) == list:
- [obj.sub(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ if isinstance(x, list):
+ if isinstance(x[0], list):
+ [obj.sub(wrap(x, i)) for i, obj in enumerate(self._base_objs)]
else:
[obj.sub(x) for obj in self._base_objs]
else:
- x, lmax = convertArgsToLists(x)
- [obj.sub(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.sub(wrap(x, i)) for i, obj in enumerate(self._base_objs)]
self.refreshView()
return self
@@ -1641,14 +1709,14 @@ class PyoTableObject(PyoObjectBase):
"""
pyoArgsAssert(self, "T", x)
- if type(x) == list:
- if type(x[0]) == list:
- [obj.mul(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ if isinstance(x, list):
+ if isinstance(x[0], list):
+ [obj.mul(wrap(x, i)) for i, obj in enumerate(self._base_objs)]
else:
[obj.mul(x) for obj in self._base_objs]
else:
- x, lmax = convertArgsToLists(x)
- [obj.mul(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.mul(wrap(x, i)) for i, obj in enumerate(self._base_objs)]
self.refreshView()
return self
@@ -1674,7 +1742,8 @@ class PyoTableObject(PyoObjectBase):
"""
pyoArgsAssert(self, "tIII", table, srcpos, destpos, length)
- [obj.copyData(table[i], srcpos, destpos, length) for i, obj in enumerate(self._base_objs)]
+ [obj.copyData(table[i], srcpos,
+ destpos, length) for i, obj in enumerate(self._base_objs)]
self.refreshView()
def rotate(self, pos):
@@ -1704,13 +1773,14 @@ class PyoTableObject(PyoObjectBase):
args = [getattr(self, att) for att in self.__dir__()]
if self.__class__.__name__ == "SndTable":
_size = self.getSize()
- if type(_size) != list:
+ if not isinstance(_size, list):
_size = [_size]
_chnls = len(self._base_objs)
args[0] = None
args.append(_chnls)
newtable = getattr(current_pyo, self.__class__.__name__)(*args)
- [obj.setSize(_size[i%len(_size)]) for i, obj in enumerate(newtable.getBaseObjects())]
+ baseobjs = newtable.getBaseObjects()
+ [obj.setSize(_size[i%len(_size)]) for i, obj in enumerate(baseobjs)]
[obj.copy(self[i]) for i, obj in enumerate(newtable.getBaseObjects())]
else:
newtable = getattr(current_pyo, self.__class__.__name__)(*args)
@@ -1734,8 +1804,9 @@ class PyoTableObject(PyoObjectBase):
"""
pyoArgsAssert(self, "SB", title, wxnoserver)
- samples = self._base_objs[0].getViewTable((500,200))
- createViewTableWindow(samples, title, wxnoserver, self.__class__.__name__, self)
+ samples = self._base_objs[0].getViewTable((500, 200))
+ createViewTableWindow(samples, title, wxnoserver,
+ self.__class__.__name__, self)
def _setViewFrame(self, frame):
self.viewFrame = frame
@@ -1743,6 +1814,10 @@ class PyoTableObject(PyoObjectBase):
def _setGraphFrame(self, frame):
self.graphFrame = frame
+ def _get_current_data(self):
+ # Thid method must be override by children.
+ return []
+
def refreshView(self):
"""
Updates the graphical display of the table, if applicable.
@@ -1767,7 +1842,8 @@ class PyoTableObject(PyoObjectBase):
"""int. Table size in samples."""
return self._size
@size.setter
- def size(self, x): self.setSize(x)
+ def size(self, x):
+ self.setSize(x)
######################################################################
### PyoMatrixObject -> base class for pyo matrix objects
@@ -1788,6 +1864,7 @@ class PyoMatrixObject(PyoObjectBase):
_STREAM_TYPE = 'matrix'
def __init__(self):
+ self._size = (0, 0)
PyoObjectBase.__init__(self)
self.viewFrame = None
@@ -1915,8 +1992,10 @@ class PyoMatrixObject(PyoObjectBase):
"""
pyoArgsAssert(self, "II", x, y)
values = [obj.get(x, y) for obj in self._base_objs]
- if len(values) == 1: return values[0]
- else: return values
+ if len(values) == 1:
+ return values[0]
+ else:
+ return values
def view(self, title="Matrix viewer", wxnoserver=False):
"""
@@ -1970,6 +2049,7 @@ class PyoPVObject(PyoObjectBase):
self._target_dict = {}
self._signal_dict = {}
self._map_list = []
+ self._base_players = None
def isPlaying(self, all=False):
"""
@@ -2002,19 +2082,22 @@ class PyoPVObject(PyoObjectBase):
:Args:
dur: float, optional
- Duration, in seconds, of the object's activation. The default is 0
- and means infinite duration.
+ Duration, in seconds, of the object's activation.
+ The default is 0 and means infinite duration.
delay: float, optional
- Delay, in seconds, before the object's activation. Defaults to 0.
+ Delay, in seconds, before the object's activation.
+ Defaults to 0.
"""
pyoArgsAssert(self, "nn", dur, delay)
- dur, delay, lmax = convertArgsToLists(dur, delay)
- if hasattr(self, "_trig_objs"):
+ dur, delay, _ = convertArgsToLists(dur, delay)
+ if self._trig_objs is not None:
self._trig_objs.play(dur, delay)
- if hasattr(self, "_base_players"):
- [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._base_players)]
- [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._base_objs)]
+ if self._base_players is not None:
+ [obj.play(wrap(dur, i), wrap(delay, i)) \
+ for i, obj in enumerate(self._base_players)]
+ [obj.play(wrap(dur, i), wrap(delay, i)) \
+ for i, obj in enumerate(self._base_objs)]
return self
def stop(self):
@@ -2025,9 +2108,9 @@ class PyoPVObject(PyoObjectBase):
creation.
"""
- if hasattr(self, "_trig_objs"):
+ if self._trig_objs is not None:
self._trig_objs.stop()
- if hasattr(self, "_base_players"):
+ if self._base_players is not None:
[obj.stop() for obj in self._base_players]
[obj.stop() for obj in self._base_objs]
return self
@@ -2058,7 +2141,8 @@ class PyoPVObject(PyoObjectBase):
if self._signal_dict[attr].isPlaying():
init = self._signal_dict[attr].get(True)
self._signal_dict[attr].stop()
- self._signal_dict[attr] = VarPort(value, port, init, self._reset_from_set, attr)
+ self._signal_dict[attr] = VarPort(value, port, init,
+ self._reset_from_set, attr)
setattr(self, attr, self._signal_dict[attr])
def _reset_from_set(self, attr=None):
@@ -2094,7 +2178,8 @@ class PyoPVObject(PyoObjectBase):
if map_list is None:
map_list = self._map_list
if map_list == []:
- print(("There are no controls for %s object." % self.__class__.__name__))
+ clsname = self.__class__.__name__
+ print("There are no controls for %s object." % clsname)
return
createCtrlWindow(self, map_list, title, wxnoserver)
@@ -2144,7 +2229,7 @@ class Mix(PyoObject):
PyoObject.__init__(self, mul, add)
self._input = input
mul, add, lmax = convertArgsToLists(mul, add)
- if type(input) == list:
+ if isinstance(input, list):
input_objs = []
input_objs = [obj for pyoObj in input for obj in pyoObj.getBaseObjects()]
else:
@@ -2165,7 +2250,9 @@ class Mix(PyoObject):
for i in range(num):
obj = input_objs[i % input_len]
sub_lists[i % voices].append(obj)
- self._base_objs = [Mix_base(l, wrap(mul,i), wrap(add,i)) for i, l in enumerate(sub_lists)]
+ self._base_objs = [Mix_base(l, wrap(mul, i),
+ wrap(add, i)) for i, l in enumerate(sub_lists)]
+ self.play()
class Dummy(PyoObject):
"""
@@ -2248,7 +2335,8 @@ class InputFader(PyoObject):
PyoObject.__init__(self)
self._input = input
input, lmax = convertArgsToLists(input)
- self._base_objs = [InputFader_base(wrap(input,i)) for i in range(lmax)]
+ self._base_objs = [InputFader_base(wrap(input, i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -2264,15 +2352,17 @@ class InputFader(PyoObject):
"""
pyoArgsAssert(self, "oN", x, fadetime)
self._input = x
- x, lmax = convertArgsToLists(x)
- [obj.setInput(wrap(x,i), fadetime) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.setInput(wrap(x, i),
+ fadetime) 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)
+ def input(self, x):
+ self.setInput(x)
class Sig(PyoObject):
"""
@@ -2301,8 +2391,10 @@ class Sig(PyoObject):
pyoArgsAssert(self, "OOO", value, mul, add)
PyoObject.__init__(self, mul, add)
self._value = value
- value, mul ,add, lmax = convertArgsToLists(value, mul, add)
- self._base_objs = [Sig_base(wrap(value,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ value, mul, add, lmax = convertArgsToLists(value, mul, add)
+ self._base_objs = [Sig_base(wrap(value, i), wrap(mul, i),
+ wrap(add, i)) for i in range(lmax)]
+ self.play()
def setValue(self, x):
"""
@@ -2316,8 +2408,8 @@ class Sig(PyoObject):
"""
pyoArgsAssert(self, "O", x)
self._value = x
- x, lmax = convertArgsToLists(x)
- [obj.setValue(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ x, _ = 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, 1, "lin", "value", self._value)]
@@ -2328,7 +2420,8 @@ class Sig(PyoObject):
"""float or PyoObject. Numerical value to convert."""
return self._value
@value.setter
- def value(self, x): self.setValue(x)
+ def value(self, x):
+ self.setValue(x)
class VarPort(PyoObject):
"""
@@ -2357,7 +2450,8 @@ class VarPort(PyoObject):
.. note::
- The out() method is bypassed. VarPort's signal can not be sent to audio outs.
+ The out() method is bypassed. VarPort's signal can not be sent to
+ audio outs.
>>> s = Server().boot()
>>> s.start()
@@ -2369,14 +2463,19 @@ class VarPort(PyoObject):
>>> a = SineLoop(freq=[fr,fr*1.01], feedback=0.05, mul=.2).out()
"""
- def __init__(self, value, time=0.025, init=0.0, function=None, arg=None, mul=1, add=0):
+ def __init__(self, value, time=0.025, init=0.0, function=None, arg=None,
+ mul=1, add=0):
pyoArgsAssert(self, "nnnczOO", value, time, init, function, arg, mul, add)
PyoObject.__init__(self, mul, add)
self._value = value
self._time = time
self._function = getWeakMethodRef(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), WeakMethod(wrap(function,i)), wrap(arg,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ 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),
+ WeakMethod(wrap(function, i)), wrap(arg, i),
+ wrap(mul, i), wrap(add, i)) for i in range(lmax)]
+ self.play()
def setValue(self, x):
"""
@@ -2390,8 +2489,8 @@ class VarPort(PyoObject):
"""
pyoArgsAssert(self, "n", x)
self._value = x
- x, lmax = convertArgsToLists(x)
- [obj.setValue(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.setValue(wrap(x, i)) for i, obj in enumerate(self._base_objs)]
def setTime(self, x):
"""
@@ -2405,8 +2504,8 @@ class VarPort(PyoObject):
"""
pyoArgsAssert(self, "n", x)
self._time = x
- x, lmax = convertArgsToLists(x)
- [obj.setTime(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.setTime(wrap(x, i)) for i, obj in enumerate(self._base_objs)]
def setFunction(self, x):
"""
@@ -2420,29 +2519,33 @@ class VarPort(PyoObject):
"""
pyoArgsAssert(self, "c", x)
self._function = getWeakMethodRef(x)
- x, lmax = convertArgsToLists(x)
- [obj.setFunction(WeakMethod(wrap(x,i))) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.setFunction(WeakMethod(wrap(x, i))) \
+ for i, obj in enumerate(self._base_objs)]
@property
def value(self):
"""float. Numerical value to convert."""
return self._value
@value.setter
- def value(self, x): self.setValue(x)
+ def value(self, x):
+ self.setValue(x)
@property
def time(self):
"""float. Ramp time."""
return self._time
@time.setter
- def time(self, x): self.setTime(x)
+ 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)
+ def function(self, x):
+ self.setFunction(x)
class Pow(PyoObject):
"""
@@ -2471,7 +2574,9 @@ class Pow(PyoObject):
self._base = base
self._exponent = exponent
base, exponent, mul, add, lmax = convertArgsToLists(base, exponent, mul, add)
- self._base_objs = [M_Pow_base(wrap(base,i), wrap(exponent,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self._base_objs = [M_Pow_base(wrap(base, i), wrap(exponent, i),
+ wrap(mul, i), wrap(add, i)) for i in range(lmax)]
+ self.play()
def setBase(self, x):
"""
@@ -2485,8 +2590,8 @@ class Pow(PyoObject):
"""
pyoArgsAssert(self, "O", x)
self._base = x
- x, lmax = convertArgsToLists(x)
- [obj.setBase(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.setBase(wrap(x, i)) for i, obj in enumerate(self._base_objs)]
def setExponent(self, x):
"""
@@ -2500,22 +2605,24 @@ class Pow(PyoObject):
"""
pyoArgsAssert(self, "O", x)
self._exponent = x
- x, lmax = convertArgsToLists(x)
- [obj.setExponent(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.setExponent(wrap(x, i)) for i, obj in enumerate(self._base_objs)]
@property
def base(self):
"""float or PyoObject. Base composant."""
return self._base
@base.setter
- def base(self, x): self.setBase(x)
+ def base(self, x):
+ self.setBase(x)
@property
def exponent(self):
"""float or PyoObject. Exponent composant."""
return self._exponent
@exponent.setter
- def exponent(self, x): self.setExponent(x)
+ def exponent(self, x):
+ self.setExponent(x)
class Wrap(PyoObject):
"""
@@ -2537,7 +2644,8 @@ class Wrap(PyoObject):
.. note::
- If `min` is higher than `max`, then the output will be the average of the two.
+ If `min` is higher than `max`, then the output will be the average
+ of the two.
>>> s = Server().boot()
>>> s.start()
@@ -2559,8 +2667,11 @@ class Wrap(PyoObject):
self._min = min
self._max = max
self._in_fader = InputFader(input)
- in_fader, min, max, mul, add, lmax = convertArgsToLists(self._in_fader, min, max, mul, add)
- self._base_objs = [Wrap_base(wrap(in_fader,i), wrap(min,i), wrap(max,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ in_fader, min, max, mul, add, lmax = convertArgsToLists(
+ self._in_fader, min, max, mul, add)
+ self._base_objs = [Wrap_base(wrap(in_fader, i), wrap(min, i), wrap(max, i),
+ wrap(mul, i), wrap(add, i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -2590,8 +2701,8 @@ class Wrap(PyoObject):
"""
pyoArgsAssert(self, "O", x)
self._min = x
- x, lmax = convertArgsToLists(x)
- [obj.setMin(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.setMin(wrap(x, i)) for i, obj in enumerate(self._base_objs)]
def setMax(self, x):
"""
@@ -2605,8 +2716,8 @@ class Wrap(PyoObject):
"""
pyoArgsAssert(self, "O", x)
self._max = x
- x, lmax = convertArgsToLists(x)
- [obj.setMax(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ x, _ = 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., 1., 'lin', 'min', self._min),
@@ -2619,21 +2730,24 @@ class Wrap(PyoObject):
"""PyoObject. Input signal to process."""
return self._input
@input.setter
- def input(self, x): self.setInput(x)
+ def input(self, x):
+ self.setInput(x)
@property
def min(self):
"""float or PyoObject. Minimum possible value."""
return self._min
@min.setter
- def min(self, x): self.setMin(x)
+ def min(self, x):
+ self.setMin(x)
@property
def max(self):
"""float or PyoObject. Maximum possible value."""
return self._max
@max.setter
- def max(self, x): self.setMax(x)
+ def max(self, x):
+ self.setMax(x)
class Compare(PyoObject):
"""
@@ -2672,8 +2786,14 @@ class Compare(PyoObject):
self._mode = mode
self._in_fader = InputFader(input)
self.comp_dict = {"<": 0, "<=": 1, ">": 2, ">=": 3, "==": 4, "!=": 5}
- in_fader, comp, mode, mul, add, lmax = convertArgsToLists(self._in_fader, comp, mode, mul, add)
- self._base_objs = [Compare_base(wrap(in_fader,i), wrap(comp,i), self.comp_dict[wrap(mode,i)], wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ in_fader, comp, mode, mul, add, lmax = convertArgsToLists(
+ self._in_fader, comp, mode, mul, add)
+ self._base_objs = [Compare_base(wrap(in_fader, i),
+ wrap(comp, i),
+ self.comp_dict[wrap(mode, i)],
+ wrap(mul, i),
+ wrap(add, i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -2706,8 +2826,8 @@ class Compare(PyoObject):
"""
pyoArgsAssert(self, "O", x)
self._comp = x
- x, lmax = convertArgsToLists(x)
- [obj.setComp(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.setComp(wrap(x, i)) for i, obj in enumerate(self._base_objs)]
def setMode(self, x):
"""
@@ -2723,26 +2843,30 @@ class Compare(PyoObject):
"""
pyoArgsAssert(self, "s", x)
self._mode = x
- x, lmax = convertArgsToLists(x)
- [obj.setMode(self.comp_dict[wrap(x,i)]) for i, obj in enumerate(self._base_objs)]
+ x, _ = convertArgsToLists(x)
+ [obj.setMode(self.comp_dict[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)
+ def input(self, x):
+ self.setInput(x)
@property
def comp(self):
"""PyoObject. Comparison signal."""
return self._comp
@comp.setter
- def comp(self, x): self.setComp(x)
+ def comp(self, x):
+ self.setComp(x)
@property
def mode(self):
"""string. Comparison operator."""
return self._mode
@mode.setter
- def mode(self, x): self.setMode(x)
+ def mode(self, x):
+ self.setMode(x)
diff --git a/pyolib/_maps.py b/pyolib/_maps.py
index fe2bf70..d7ddd29 100644
--- a/pyolib/_maps.py
+++ b/pyolib/_maps.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# encoding: utf-8
"""
Copyright 2009-2015 Olivier Belanger
@@ -23,7 +23,7 @@ from math import pow, log10
######################################################################
### Map -> rescale values from sliders
######################################################################
-class Map:
+class Map(object):
"""
Converts value between 0 and 1 on various scales.
@@ -53,8 +53,10 @@ class Map:
Takes `x` between 0 and 1 and returns scaled value.
"""
- if x < 0: x = 0.0
- elif x > 1: x = 1.0
+ if x < 0:
+ x = 0.0
+ elif x > 1:
+ x = 1.0
if self._scale == 'log':
return pow(10, x * log10(self._max / self._min) + log10(self._min))
@@ -151,8 +153,8 @@ class SLMap(Map):
name: string
Name of the attributes the slider is affected to.
init: int or float
- Initial value. Specified in the real range, not between 0 and 1. Use
- the `set` method to retreive the normalized corresponding value.
+ Initial value. Specified in the real range, not between 0 and 1.
+ Use `set` method to retreive the normalized corresponding value.
res: string {'int', 'float'}, optional
Sets the resolution of the slider. Defaults to 'float'.
ramp: float, optional
@@ -166,14 +168,21 @@ class SLMap(Map):
>>> 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)]
+ >>> slmapfreq = SLMap(20., 2000., 'log', 'freq', ifs)
+ >>> slmapfeed = SLMap(0, 0.25, 'lin', 'feedback', 0)
+ >>> maps = [slmapfreq, slmapfeed, 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, dataOnly=False):
+ 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, self._dataOnly = name, init, res, ramp, dataOnly
+ self._name = name
+ self._init = init
+ self._res = res
+ self._ramp = ramp
+ self._dataOnly = dataOnly
@property
def name(self):
diff --git a/pyolib/_tkwidgets.py b/pyolib/_tkwidgets.py
index 84e5b2a..854a2a7 100644
--- a/pyolib/_tkwidgets.py
+++ b/pyolib/_tkwidgets.py
@@ -1,3 +1,8 @@
+# encoding: utf-8
+"""
+This module defines GUI widgets built with tkinter.
+
+"""
from __future__ import division
from __future__ import print_function
from __future__ import absolute_import
@@ -20,11 +25,12 @@ GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with pyo. If not, see <http://www.gnu.org/licenses/>.
"""
-import math, sys, os
+import math
+import sys
if sys.version_info[0] < 3:
- from Tkinter import *
+ import Tkinter as tk
else:
- from tkinter import *
+ import tkinter as tk
# constants for platform displays with Tk
if sys.platform.startswith('linux'):
@@ -40,32 +46,47 @@ else:
######################################################################
### Multisliders
######################################################################
-class MultiSlider(Frame):
-
+class MultiSlider(tk.Frame):
+ """
+ Draw multiple sliders on a canvas.
+
+ :Args:
+ master: tk.Frame
+ Parent frame.
+ init: list of floats
+ Initial values.
+ key: str
+ Name of the attribute to control.
+ command: callable
+ Function called with values as argument.
+
+ """
def __init__(self, master, init, key, command):
- Frame.__init__(self, master, bd=0, relief=FLAT)
+ tk.Frame.__init__(self, master, bd=0, relief=tk.FLAT)
self._values = init
self._nchnls = len(init)
self._key = key
self._command = command
self._lines = []
self._height = 16
- self.canvas = Canvas(self, height=self._height*self._nchnls+1,
- width=225, relief=FLAT, bd=0, bg="#BCBCAA")
+ self.canvas = tk.Canvas(self, height=self._height*self._nchnls+1,
+ width=225, relief=tk.FLAT, bd=0, bg="#BCBCAA")
w = self.canvas.winfo_width()
for i in range(self._nchnls):
x = int(self._values[i] * w)
y = self._height * i + Y_OFFSET
- self._lines.append(self.canvas.create_rectangle(0, y, x,
- y+self._height-1, width=0, fill="#121212"))
+ rect = self.canvas.create_rectangle(0, y, x, y+self._height-1,
+ width=0, fill="#121212")
+ self._lines.append(rect)
self.canvas.bind("<Button-1>", self.clicked)
self.canvas.bind("<Motion>", self.move)
self.canvas.bind("<Configure>", self.size)
- self.canvas.grid(sticky=E+W)
+ self.canvas.grid(sticky=tk.E + tk.W)
self.columnconfigure(0, weight=1)
self.grid()
def size(self, event):
+ "Method called when resizing the window."
w = self.canvas.winfo_width()
for i in range(len(self._lines)):
y = self._height * i + Y_OFFSET
@@ -73,15 +94,18 @@ class MultiSlider(Frame):
self.canvas.coords(self._lines[i], 0, y, x, y+self._height-1)
def clicked(self, event):
+ "Method called when clicking on the window."
self.update(event)
def move(self, event):
+ "Method called on left mouse moion."
if event.state == 0x0100:
slide = (event.y - Y_OFFSET) // self._height
if 0 <= slide < len(self._lines):
self.update(event)
def update(self, event):
+ "Update and send current values."
w = self.canvas.winfo_width()
slide = (event.y - Y_OFFSET) // self._height
val = event.x / float(w)
@@ -93,8 +117,8 @@ class MultiSlider(Frame):
######################################################################
### Control window for PyoObject
######################################################################
-class Command:
-
+class Command(object):
+ "Command event used to control a slider value."
def __init__(self, func, key):
self.func = func
self.key = key
@@ -102,10 +126,21 @@ class Command:
def __call__(self, value):
self.func(self.key, value)
-class PyoObjectControl(Frame):
+class PyoObjectControl(tk.Frame):
+ """
+ Create a slider/multislider control window.
+ :Args:
+ master: tk.Frame
+ Parent frame.
+ obj: PyoObjectBase
+ The object to control attributes.
+ map_list: list of SLMap
+ The list of attribute definitions.
+
+ """
def __init__(self, master=None, obj=None, map_list=None):
- Frame.__init__(self, master, bd=1, relief=GROOVE)
+ tk.Frame.__init__(self, master, bd=1, relief=tk.GROOVE)
from .controls import SigTo
self.bind('<Destroy>', self._destroy)
self._obj = obj
@@ -124,25 +159,32 @@ class PyoObjectControl(Frame):
else:
self._maps[key] = m
# label (param name)
- label = Label(self, height=1, width=10, highlightthickness=0, text=key)
+ label = tk.Label(self, height=1, width=10, highlightthickness=0,
+ text=key)
label.grid(row=i, column=0)
# create and pack slider
- if type(init) != list:
- self._sliders.append(Scale(self, command=Command(self.setval, key),
- orient=HORIZONTAL, relief=GROOVE, from_=0., to=1., showvalue=False,
- resolution=.0001, bd=1, length=225, troughcolor="#BCBCAA", width=12))
+ if not isinstance(init, list):
+ slider = tk.Scale(self, command=Command(self.setval, key),
+ orient=tk.HORIZONTAL, relief=tk.GROOVE,
+ from_=0., to=1., showvalue=False,
+ resolution=.0001, bd=1, length=225,
+ troughcolor="#BCBCAA", width=12)
+ self._sliders.append(slider)
self._sliders[-1].set(m.set(init))
disp_height = 1
else:
- self._sliders.append(MultiSlider(self, [m.set(x) for x in init], key, self.setval))
+ self._sliders.append(MultiSlider(self,
+ [m.set(x) for x in init],
+ key, self.setval))
disp_height = len(init)
- self._sliders[-1].grid(row=i, column=1, sticky=E+W)
+ self._sliders[-1].grid(row=i, column=1, sticky=tk.E + tk.W)
# display of numeric values
- textvar = StringVar(self)
- display = Label(self, height=disp_height, width=10, highlightthickness=0, textvariable=textvar)
+ textvar = tk.StringVar(self)
+ display = tk.Label(self, height=disp_height, width=10,
+ highlightthickness=0, textvariable=textvar)
display.grid(row=i, column=2)
self._displays[key] = textvar
- if type(init) != list:
+ if not isinstance(init, list):
self._displays[key].set("%.4f" % init)
else:
self._displays[key].set("\n".join(["%.4f" % i for i in init]))
@@ -159,7 +201,7 @@ class PyoObjectControl(Frame):
top.rowconfigure(0, weight=1)
top.columnconfigure(0, weight=1)
self.columnconfigure(1, weight=1)
- self.grid(ipadx=5, ipady=5, sticky=E+W)
+ self.grid(ipadx=5, ipady=5, sticky=tk.E + tk.W)
def _destroy(self, event):
for m in self._map_list:
@@ -169,7 +211,8 @@ class PyoObjectControl(Frame):
del self._sigs[key]
def setval(self, key, x):
- if type(x) != list:
+ "Set a new value 'x' to attribute 'key'."
+ if not isinstance(x, list):
value = self._maps[key].get(float(x))
self._displays[key].set("%.4f" % value)
else:
@@ -182,15 +225,18 @@ class PyoObjectControl(Frame):
######################################################################
### View window for PyoTableObject
######################################################################
-class ViewTable(Frame):
-
+class ViewTable(tk.Frame):
+ "PyoTableObject display."
def __init__(self, master=None, samples=None):
- Frame.__init__(self, master, bd=1, relief=GROOVE)
+ tk.Frame.__init__(self, master, bd=1, relief=tk.GROOVE)
self.width = 500
self.height = 200
self.half_height = self.height // 2
- self.canvas = Canvas(self, height=self.height, width=self.width, relief=SUNKEN, bd=1, bg="#EFEFEF")
- self.canvas.create_line(0, self.half_height+Y_OFFSET, self.width, self.half_height+Y_OFFSET, fill='grey', dash=(4,2))
+ self.canvas = tk.Canvas(self, height=self.height, width=self.width,
+ relief=tk.SUNKEN, bd=1, bg="#EFEFEF")
+ self.canvas.create_line(0, self.half_height+Y_OFFSET, self.width,
+ self.half_height+Y_OFFSET, fill='grey',
+ dash=(4, 2))
self.canvas.create_line(*samples)
self.canvas.grid()
self.grid(ipadx=10, ipady=10)
@@ -198,13 +244,14 @@ class ViewTable(Frame):
######################################################################
## View window for PyoMatrixObject
#####################################################################
-class ViewMatrix(Frame):
-
+class ViewMatrix(tk.Frame):
+ "PyoMatrixObject display."
def __init__(self, master=None, samples=None, size=None):
- Frame.__init__(self, master, bd=1, relief=GROOVE)
+ tk.Frame.__init__(self, master, bd=1, relief=tk.GROOVE)
self.width = size[0]
self.height = size[1]
- self.canvas = Canvas(self, width=self.width, height=self.height, relief=SUNKEN, bd=1, bg="#EFEFEF")
+ self.canvas = tk.Canvas(self, width=self.width, height=self.height,
+ relief=tk.SUNKEN, bd=1, bg="#EFEFEF")
for i in range(self.width*self.height):
x = i % self.width
y = i // self.width
@@ -224,11 +271,12 @@ class ViewMatrix(Frame):
######################################################################
### Server Object User Interface (Tk)
######################################################################
-class ServerGUI(Frame):
-
- def __init__(self, master=None, nchnls=2, startf=None, stopf=None, recstartf=None,
- recstopf=None, ampf=None, started=0, locals=None, shutdown=None, meter=True, timer=True, amp=1.):
- Frame.__init__(self, master, padx=10, pady=10, bd=2, relief=GROOVE)
+class ServerGUI(tk.Frame):
+ "Server's graphical interface."
+ def __init__(self, master=None, nchnls=2, startf=None, stopf=None,
+ recstartf=None, recstopf=None, ampf=None, started=0,
+ locals=None, shutdown=None, meter=True, timer=True, amp=1.):
+ tk.Frame.__init__(self, master, padx=10, pady=10, bd=2, relief=tk.GROOVE)
self.shutdown = shutdown
self.locals = locals
self.meter = meter
@@ -254,67 +302,84 @@ class ServerGUI(Frame):
self.start(True)
def createWidgets(self):
+ "Interface builder."
row = 0
- self.startStringVar = StringVar(self)
+ self.startStringVar = tk.StringVar(self)
self.startStringVar.set('Start')
- self.startButton = Button(self, textvariable=self.startStringVar, command=self.start)
+ self.startButton = tk.Button(self, textvariable=self.startStringVar,
+ command=self.start)
self.startButton.grid(ipadx=5)
- self.recStringVar = StringVar(self)
+ self.recStringVar = tk.StringVar(self)
self.recStringVar.set('Rec Start')
- self.recButton = Button(self, textvariable=self.recStringVar, command=self.record)
+ self.recButton = tk.Button(self, textvariable=self.recStringVar,
+ command=self.record)
self.recButton.grid(ipadx=5, row=row, column=1)
- self.quitButton = Button(self, text='Quit', command=self.on_quit)
+ self.quitButton = tk.Button(self, text='Quit', command=self.on_quit)
self.quitButton.grid(ipadx=5, row=row, column=2)
row += 1
- self.ampScale = Scale(self, command=self.setAmp, digits=4, label='Amplitude (dB)',
- orient=HORIZONTAL, relief=GROOVE, from_=-60.0, to=18.0,
- resolution=.01, bd=1, length=250, troughcolor="#BCBCAA", width=10)
+ self.ampScale = tk.Scale(self, command=self.setAmp, digits=4,
+ label='Amplitude (dB)', orient=tk.HORIZONTAL,
+ relief=tk.GROOVE, from_=-60.0, to=18.0,
+ resolution=.01, bd=1, length=250,
+ troughcolor="#BCBCAA", width=10)
self.ampScale.set(20.0 * math.log10(self.amp))
self.ampScale.grid(ipadx=5, ipady=5, row=row, column=0, columnspan=3)
row += 1
if self.meter:
- self.vumeter = Canvas(self, height=5*self.nchnls+1, width=250, relief=FLAT, bd=0, bg="#323232")
+ self.vumeter = tk.Canvas(self, height=5*self.nchnls+1, width=250,
+ relief=tk.FLAT, bd=0, bg="#323232")
self.green = []
self.yellow = []
self.red = []
for i in range(self.nchnls):
y = 5 * (i + 1) + 1 - VM_OFFSET
- self.green.append(self.vumeter.create_line(0, y, 1, y, width=4, fill='green', dash=(9,1), dashoff=6+VM_OFFSET))
- self.yellow.append(self.vumeter.create_line(self.B1, y, self.B1, y, width=4, fill='yellow', dash=(9,1), dashoff=9))
- self.red.append(self.vumeter.create_line(self.B2, y, self.B2, y, width=4, fill='red', dash=(9,1), dashoff=0))
+ self.green.append(self.vumeter.create_line(0, y, 1, y, width=4,
+ fill='green',
+ dash=(9, 1),
+ dashoff=6+VM_OFFSET))
+ self.yellow.append(self.vumeter.create_line(self.B1, y, self.B1,
+ y, width=4,
+ fill='yellow',
+ dash=(9, 1),
+ dashoff=9))
+ self.red.append(self.vumeter.create_line(self.B2, y, self.B2, y,
+ width=4, fill='red',
+ dash=(9, 1), dashoff=0))
self.vumeter.grid(ipadx=5, row=row, column=0, columnspan=3)
row += 1
if self.timer:
- self.timer_label = Label(self, text='Elapsed time (h:m:s:ms)')
+ self.timer_label = tk.Label(self, text='Elapsed time (h:m:s:ms)')
self.timer_label.grid(ipadx=0, row=row, column=0, columnspan=3)
row += 1
- self.timer_strvar = StringVar(self, " 00 : 00 : 00 : 000")
- self.timetext = Label(self, textvariable=self.timer_strvar)
+ self.timer_strvar = tk.StringVar(self, " 00 : 00 : 00 : 000")
+ self.timetext = tk.Label(self, textvariable=self.timer_strvar)
self.timetext.grid(ipadx=5, row=row, column=0, columnspan=3)
row += 1
if self.locals is not None:
- self.interp_label = Label(self, text='Interpreter')
+ self.interp_label = tk.Label(self, text='Interpreter')
self.interp_label.grid(ipadx=0, row=row, column=0, columnspan=3)
row += 1
- self.text = Text(self, height=1, width=33, bd=1, relief=RIDGE, highlightthickness=0,
- spacing1=2, spacing3=2)
+ self.text = tk.Text(self, height=1, width=33, bd=1, relief=tk.RIDGE,
+ highlightthickness=0, spacing1=2, spacing3=2)
self.text.grid(ipadx=5, row=row, column=0, columnspan=3)
self.text.bind("<Return>", self.getText)
self.text.bind("<Up>", self.getPrev)
self.text.bind("<Down>", self.getNext)
def on_quit(self):
+ "Clean up on quit."
self.shutdown()
self.quit()
def getPrev(self, event):
- self.text.delete("1.0", END)
+ "Get previous command in history."
+ self.text.delete("1.0", tk.END)
self._histo_count -= 1
if self._histo_count < 0:
self._histo_count = 0
@@ -322,10 +387,13 @@ class ServerGUI(Frame):
return "break"
def setTime(self, *args):
- self.timer_strvar.set(" %02d : %02d : %02d : %03d" % (args[0], args[1], args[2], args[3]))
+ "Display the current server time."
+ txt = " %02d : %02d : %02d : %03d" % (args[0], args[1], args[2], args[3])
+ self.timer_strvar.set(txt)
def getNext(self, event):
- self.text.delete("1.0", END)
+ "Get next command in history."
+ self.text.delete("1.0", tk.END)
self._histo_count += 1
if self._histo_count >= len(self._history):
self._histo_count = len(self._history)
@@ -334,28 +402,31 @@ class ServerGUI(Frame):
return "break"
def getText(self, event):
- source = self.text.get("1.0", END)
- self.text.delete("1.0", END)
+ "Retrieve text from the interpreter widget."
+ source = self.text.get("1.0", tk.END)
+ self.text.delete("1.0", tk.END)
exec(source, self.locals)
self._history.append(source)
self._histo_count = len(self._history)
return "break"
def start(self, justSet=False):
- if self._started == False:
+ "Start/stop the server."
+ if self._started is False:
if not justSet:
self.startf()
self._started = True
self.startStringVar.set('Stop')
- self.quitButton.configure(state = DISABLED)
+ self.quitButton.configure(state=tk.DISABLED)
else:
self.stopf()
self._started = False
self.startStringVar.set('Start')
- self.quitButton.configure(state = NORMAL)
+ self.quitButton.configure(state=tk.NORMAL)
def record(self):
- if self._recstarted == False:
+ "Record sound on disk."
+ if self._recstarted is False:
self.recstartf()
self._recstarted = True
self.recStringVar.set('Rec Stop')
@@ -365,9 +436,11 @@ class ServerGUI(Frame):
self.recStringVar.set('Rec Start')
def setAmp(self, value):
+ "Update server's global amplitude value."
self.ampf(math.pow(10.0, float(value) * 0.05))
def setRms(self, *args):
+ "Update the vumeter."
for i in range(self.nchnls):
y = 5 * (i + 1) + 1 - VM_OFFSET
db = math.log10(args[i]+0.00001) * 0.2 + 1.
diff --git a/pyolib/_widgets.py b/pyolib/_widgets.py
index f4a32e6..a0b9dad 100644
--- a/pyolib/_widgets.py
+++ b/pyolib/_widgets.py
@@ -1,4 +1,9 @@
-# -*- coding: utf-8 -*-
+# encoding: utf-8
+"""
+This module is the interface between pyo's display demands and the different
+available GUI toolkits (wxpython of tkinter).
+
+"""
from __future__ import print_function
from __future__ import absolute_import
"""
@@ -20,7 +25,9 @@ GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with pyo. If not, see <http://www.gnu.org/licenses/>.
"""
-import math, sys, os, random
+import sys
+import os
+import random
use_wx = 1
if "PYO_GUI_WX" in os.environ:
@@ -48,9 +55,9 @@ PYO_USE_TK = False
if not PYO_USE_WX:
try:
if sys.version_info[0] < 3:
- from Tkinter import *
+ import Tkinter as tk
else:
- from tkinter import *
+ import tkinter as tk
from ._tkwidgets import *
PYO_USE_TK = True
except:
@@ -74,9 +81,10 @@ SCOPEWINDOWS = []
EXPREDITORWINDOWS = []
def createRootWindow():
+ "Creates the main window (app object)."
if not PYO_USE_WX:
if len(WINDOWS) == 0:
- root = Tk()
+ root = tk.Tk()
root.withdraw()
return None
else:
@@ -89,23 +97,29 @@ def createRootWindow():
return None
def tkCloseWindow(win):
+ "Closes a tkinter window."
win.destroy()
- if win in WINDOWS: WINDOWS.remove(win)
+ if win in WINDOWS:
+ WINDOWS.remove(win)
def tkCloseWindowFromKeyboard(event):
+ "Closes a tkinter window from a keyboard event."
win = event.widget
if not isinstance(win, ServerGUI):
win.destroy()
- if win in WINDOWS: WINDOWS.remove(win)
+ if win in WINDOWS:
+ WINDOWS.remove(win)
def tkCreateToplevelWindow():
- win = Toplevel()
+ "Creates a tkinter top level window."
+ win = tk.Toplevel()
WINDOWS.append(win)
win.protocol('WM_DELETE_WINDOW', lambda win=win: tkCloseWindow(win))
win.bind("<Escape>", tkCloseWindowFromKeyboard)
return win
def wxDisplayWindow(f, title):
+ "Displays a wxpython window on the screen."
global CURRENT_X, MAX_X, NEXT_Y
f.SetTitle(title)
x, y = f.GetSize()
@@ -113,46 +127,55 @@ def wxDisplayWindow(f, title):
y += 25
if y + NEXT_Y < Y:
px, py, NEXT_Y = CURRENT_X, NEXT_Y, NEXT_Y + y
- if x + CURRENT_X > MAX_X: MAX_X = x + CURRENT_X
+ if x + CURRENT_X > MAX_X:
+ MAX_X = x + CURRENT_X
f.SetPosition((px, py))
elif x + MAX_X < X:
px, py, NEXT_Y, CURRENT_X = MAX_X, 50, 50 + y, MAX_X
- if x + CURRENT_X > MAX_X: MAX_X = x + CURRENT_X
+ if x + CURRENT_X > MAX_X:
+ MAX_X = x + CURRENT_X
f.SetPosition((px, py))
else:
- f.SetPosition((random.randint(250,500), random.randint(200,400)))
+ f.SetPosition((random.randint(250, 500), random.randint(200, 400)))
f.Show()
def wxShowWindow(f, title, root):
+ "Shows a wxpython window on the screen."
f.SetTitle(title)
f.Show()
if root is not None:
root.MainLoop()
def wxCreateDelayedCtrlWindows():
+ "Postponed a wxpython window display."
for win in CTRLWINDOWS:
f = PyoObjectControl(None, win[0], win[1])
- if win[2] is None: title = win[0].__class__.__name__
+ if win[2] is None:
+ title = win[0].__class__.__name__
else: title = win[2]
wxDisplayWindow(f, title)
def wxCreateDelayedGraphWindows():
+ "Postponed a wxpython window display."
for win in GRAPHWINDOWS:
f = TableGrapher(None, win[0], win[1], win[2], win[3])
- if win[4] is None: title = win[0].__class__.__name__
+ if win[4] is None:
+ title = win[0].__class__.__name__
else: title = win[4]
wxDisplayWindow(f, title)
def wxCreateDelayedDataGraphWindows():
+ "Postponed a wxpython window display."
for win in DATAGRAPHWINDOWS:
f = DataTableGrapher(None, win[0], win[1])
win[0]._setGraphFrame(f)
- if win[2] is None: title = win[0].__class__.__name__
+ if win[2] is None:
+ title = win[0].__class__.__name__
else: title = win[2]
wxDisplayWindow(f, title)
def wxCreateDelayedTableWindows():
- global CURRENT_X, MAX_X, NEXT_Y
+ "Postponed a wxpython window display."
for win in TABLEWINDOWS:
object = win[3]
f = ViewTable(None, win[0], win[1], object)
@@ -161,14 +184,14 @@ def wxCreateDelayedTableWindows():
wxDisplayWindow(f, win[2])
def wxCreateDelayedSndTableWindows():
- global CURRENT_X, MAX_X, NEXT_Y
+ "Postponed a wxpython window display."
for win in SNDTABLEWINDOWS:
f = SndViewTable(None, win[0], win[1], win[3])
win[0]._setViewFrame(f)
wxDisplayWindow(f, win[2])
def wxCreateDelayedMatrixWindows():
- global CURRENT_X, MAX_X, NEXT_Y
+ "Postponed a wxpython window display."
for win in MATRIXWINDOWS:
object = win[3]
f = ViewMatrix(None, win[0], win[1], object)
@@ -177,73 +200,91 @@ def wxCreateDelayedMatrixWindows():
wxDisplayWindow(f, win[2])
def wxCreateDelayedSpectrumWindows():
+ "Postponed a wxpython window display."
for win in SPECTRUMWINDOWS:
f = SpectrumDisplay(None, win[0])
- if win[1] is None: title = win[0].__class__.__name__
- else: title = win[1]
+ if win[1] is None:
+ title = win[0].__class__.__name__
+ else:
+ title = win[1]
if win[0] is not None:
win[0]._setViewFrame(f)
wxDisplayWindow(f, title)
def wxCreateDelayedScopeWindows():
+ "Postponed a wxpython window display."
for win in SCOPEWINDOWS:
f = ScopeDisplay(None, win[0])
- if win[1] is None: title = win[0].__class__.__name__
- else: title = win[1]
+ if win[1] is None:
+ title = win[0].__class__.__name__
+ else:
+ title = win[1]
if win[0] is not None:
win[0]._setViewFrame(f)
wxDisplayWindow(f, title)
def wxCreateDelayedExprEditorWindows():
+ "Postponed a wxpython window display."
for win in EXPREDITORWINDOWS:
f = ExprEditorFrame(None, win[0])
- if win[1] is None: title = win[0].__class__.__name__
- else: title = win[1]
+ if win[1] is None:
+ title = win[0].__class__.__name__
+ else:
+ title = win[1]
wxDisplayWindow(f, title)
def createCtrlWindow(obj, map_list, title, wxnoserver=False):
+ "Creates a controller window (from a .ctrl() method."
if not PYO_USE_WX:
createRootWindow()
win = tkCreateToplevelWindow()
f = PyoObjectControl(win, obj, map_list)
win.resizable(True, False)
- if title is None: title = obj.__class__.__name__
+ if title is None:
+ title = obj.__class__.__name__
win.title(title)
else:
if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = PyoObjectControl(None, obj, map_list)
- if title is None: title = obj.__class__.__name__
+ if title is None:
+ title = obj.__class__.__name__
wxShowWindow(f, title, root)
else:
CTRLWINDOWS.append([obj, map_list, title])
def createGraphWindow(obj, mode, xlen, yrange, title, wxnoserver=False):
+ "Creates a grapher window (from a .graph() method."
if not PYO_USE_WX:
print("WxPython must be installed to use the 'graph()' method.")
else:
if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = TableGrapher(None, obj, mode, xlen, yrange)
- if title is None: title = obj.__class__.__name__
+ if title is None:
+ title = obj.__class__.__name__
wxShowWindow(f, title, root)
else:
GRAPHWINDOWS.append([obj, mode, xlen, yrange, title])
def createDataGraphWindow(obj, yrange, title, wxnoserver=False):
+ "Creates a data table grapher window (from a .graph() method."
if not PYO_USE_WX:
print("WxPython must be installed to use the 'graph()' method.")
else:
if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = DataTableGrapher(None, obj, yrange)
- if title is None: title = obj.__class__.__name__
+ if title is None:
+ title = obj.__class__.__name__
obj._setGraphFrame(f)
wxShowWindow(f, title, root)
else:
DATAGRAPHWINDOWS.append([obj, yrange, title])
-def createViewTableWindow(samples, title="Table waveform", wxnoserver=False, tableclass=None, object=None):
+def createViewTableWindow(samples, title="Table waveform", wxnoserver=False,
+ tableclass=None, object=None):
+ "Creates a table view window (from a .view() method."
if not PYO_USE_WX:
createRootWindow()
win = tkCreateToplevelWindow()
@@ -260,7 +301,9 @@ def createViewTableWindow(samples, title="Table waveform", wxnoserver=False, tab
else:
TABLEWINDOWS.append([samples, tableclass, title, object])
-def createSndViewTableWindow(obj, title="Table waveform", wxnoserver=False, tableclass=None, mouse_callback=None):
+def createSndViewTableWindow(obj, title="Table waveform", wxnoserver=False,
+ tableclass=None, mouse_callback=None):
+ "Creates a snd table view window (from a .view() method."
if not PYO_USE_WX:
createRootWindow()
win = tkCreateToplevelWindow()
@@ -271,13 +314,16 @@ def createSndViewTableWindow(obj, title="Table waveform", wxnoserver=False, tabl
if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = SndViewTable(None, obj, tableclass, mouse_callback)
- if title is None: title = obj.__class__.__name__
+ if title is None:
+ title = obj.__class__.__name__
obj._setViewFrame(f)
wxShowWindow(f, title, root)
else:
SNDTABLEWINDOWS.append([obj, tableclass, title, mouse_callback])
-def createViewMatrixWindow(samples, size, title="Matrix viewer", wxnoserver=False, object=None):
+def createViewMatrixWindow(samples, size, title="Matrix viewer",
+ wxnoserver=False, object=None):
+ "Creates a matrix view window (from a .view() method."
if not PYO_USE_WX:
createRootWindow()
win = tkCreateToplevelWindow()
@@ -292,16 +338,18 @@ def createViewMatrixWindow(samples, size, title="Matrix viewer", wxnoserver=Fals
object._setViewFrame(f)
wxShowWindow(f, title, root)
else:
- MATRIXWINDOWS.append([samples,size,title, object])
+ MATRIXWINDOWS.append([samples, size, title, object])
def createSpectrumWindow(object, title, wxnoserver=False):
+ "Creates a spectrum display."
if not PYO_USE_WX:
print("WxPython must be installed to use the Spectrum display.")
else:
if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = SpectrumDisplay(None, object)
- if title is None: title = object.__class__.__name__
+ if title is None:
+ title = object.__class__.__name__
if object is not None:
object._setViewFrame(f)
wxShowWindow(f, title, root)
@@ -309,13 +357,15 @@ def createSpectrumWindow(object, title, wxnoserver=False):
SPECTRUMWINDOWS.append([object, title])
def createScopeWindow(object, title, wxnoserver=False):
+ "Creates a scope display."
if not PYO_USE_WX:
print("WxPython must be installed to use the Scope display.")
else:
if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = ScopeDisplay(None, object)
- if title is None: title = object.__class__.__name__
+ if title is None:
+ title = object.__class__.__name__
if object is not None:
object._setViewFrame(f)
wxShowWindow(f, title, root)
@@ -323,32 +373,39 @@ def createScopeWindow(object, title, wxnoserver=False):
SCOPEWINDOWS.append([object, title])
def createExprEditorWindow(object, title, wxnoserver=False):
+ "Creates an expression editor window."
if not PYO_USE_WX:
print("WxPython must be installed to use the Expr editor display.")
else:
if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = ExprEditorFrame(None, object)
- if title is None: title = object.__class__.__name__
+ if title is None:
+ title = object.__class__.__name__
wxShowWindow(f, title, root)
else:
EXPREDITORWINDOWS.append([object, title])
-def createServerGUI(nchnls, start, stop, recstart, recstop, setAmp, started, locals, shutdown, meter, timer, amp, exit):
+def createServerGUI(nchnls, start, stop, recstart, recstop, setAmp, started,
+ locals, shutdown, meter, timer, amp, exit):
+ "Creates the server's GUI."
global X, Y, MAX_X, NEXT_Y
if not PYO_USE_WX:
createRootWindow()
win = tkCreateToplevelWindow()
- f = ServerGUI(win, nchnls, start, stop, recstart, recstop, setAmp, started, locals, shutdown, meter, timer, amp)
+ f = ServerGUI(win, nchnls, start, stop, recstart, recstop, setAmp,
+ started, locals, shutdown, meter, timer, amp)
f.master.title("pyo server")
f.focus_set()
else:
win = createRootWindow()
- f = ServerGUI(None, nchnls, start, stop, recstart, recstop, setAmp, started, locals, shutdown, meter, timer, amp, exit)
+ f = ServerGUI(None, nchnls, start, stop, recstart, recstop, setAmp,
+ started, locals, shutdown, meter, timer, amp, exit)
f.SetTitle("pyo server")
f.SetPosition((30, 30))
f.Show()
- X,Y = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X)-50, wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)-50
+ X, Y = (wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X) - 50,
+ wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y) - 50)
if sys.platform.startswith("linux"):
MAX_X, NEXT_Y = f.GetSize()[0]+30, f.GetSize()[1]+55
else:
diff --git a/pyolib/_wxwidgets.py b/pyolib/_wxwidgets.py
index 4ea6228..68d55c8 100644
--- a/pyolib/_wxwidgets.py
+++ b/pyolib/_wxwidgets.py
@@ -53,9 +53,11 @@ def toExp(t, v1, v2):
POWOFTWO = {2:1, 4:2, 8:3, 16:4, 32:5, 64:6, 128:7, 256:8, 512:9, 1024:10, 2048:11, 4096:12, 8192:13, 16384:14, 32768:15, 65536:16}
def powOfTwo(x):
+ "Return 2 raised to the power of x."
return 2**x
def powOfTwoToInt(x):
+ "Return the exponent of 2 correponding to the value x."
return POWOFTWO[x]
def GetRoundBitmap( w, h, r ):
diff --git a/pyolib/analysis.py b/pyolib/analysis.py
index 38b8ce6..4189cbf 100644
--- a/pyolib/analysis.py
+++ b/pyolib/analysis.py
@@ -73,6 +73,7 @@ class Follower(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, mul, add, lmax = convertArgsToLists(self._in_fader, freq, mul, add)
self._base_objs = [Follower_base(wrap(in_fader,i), wrap(freq,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -168,6 +169,7 @@ class Follower2(PyoObject):
self._in_fader = InputFader(input)
in_fader, risetime, falltime, mul, add, lmax = convertArgsToLists(self._in_fader, risetime, falltime, mul, add)
self._base_objs = [Follower2_base(wrap(in_fader,i), wrap(risetime,i), wrap(falltime, i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -280,6 +282,7 @@ class ZCross(PyoObject):
self._in_fader = InputFader(input)
in_fader, thresh, mul, add, lmax = convertArgsToLists(self._in_fader, thresh, mul, add)
self._base_objs = [ZCross_base(wrap(in_fader,i), wrap(thresh,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -393,6 +396,7 @@ class Yin(PyoObject):
self._in_fader = InputFader(input)
in_fader, tolerance, minfreq, maxfreq, cutoff, winsize, mul, add, lmax = convertArgsToLists(self._in_fader, tolerance, minfreq, maxfreq, cutoff, winsize, mul, add)
self._base_objs = [Yin_base(wrap(in_fader,i), wrap(tolerance,i), wrap(minfreq,i), wrap(maxfreq,i), wrap(cutoff,i), wrap(winsize,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -559,6 +563,7 @@ class Centroid(PyoObject):
self._in_fader = InputFader(input)
in_fader, size, mul, add, lmax = convertArgsToLists(self._in_fader, size, mul, add)
self._base_objs = [Centroid_base(wrap(in_fader,i), wrap(size,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -644,6 +649,7 @@ class AttackDetector(PyoObject):
self._in_fader = InputFader(input)
in_fader, deltime, cutoff, maxthresh, minthresh, reltime, mul, add, lmax = convertArgsToLists(self._in_fader, deltime, cutoff, maxthresh, minthresh, reltime, mul, add)
self._base_objs = [AttackDetector_base(wrap(in_fader,i), wrap(deltime,i), wrap(cutoff,i), wrap(maxthresh,i), wrap(minthresh,i), wrap(reltime,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -866,6 +872,7 @@ class Spectrum(PyoObject):
self._timer = Pattern(self.refreshView, 0.05).play()
if function is None:
self.view()
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1305,6 +1312,7 @@ class Scope(PyoObject):
self._timer = Pattern(self.refreshView, length).play()
if function is None:
self.view()
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1525,6 +1533,7 @@ class PeakAmp(PyoObject):
sr = self.getSamplingRate()
bs = self.getBufferSize()
self._timer = Pattern(self._buildList, 0.06).play()
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
diff --git a/pyolib/arithmetic.py b/pyolib/arithmetic.py
index e8d300e..f38e056 100644
--- a/pyolib/arithmetic.py
+++ b/pyolib/arithmetic.py
@@ -54,6 +54,7 @@ class Sin(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [M_Sin_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -105,6 +106,7 @@ class Cos(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [M_Cos_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -163,6 +165,7 @@ class Tan(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [M_Tan_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -216,6 +219,7 @@ class Abs(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [M_Abs_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -274,6 +278,7 @@ class Sqrt(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [M_Sqrt_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -328,6 +333,7 @@ class Log(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [M_Log_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -382,6 +388,7 @@ class Log2(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [M_Log2_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -436,6 +443,7 @@ class Log10(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [M_Log10_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -493,6 +501,7 @@ class Atan2(PyoObject):
self._a = a
b, a, mul, add, lmax = convertArgsToLists(b, a, mul, add)
self._base_objs = [M_Atan2_base(wrap(b,i), wrap(a,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setB(self, x):
"""
@@ -568,6 +577,7 @@ class Floor(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [M_Floor_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -622,6 +632,7 @@ class Ceil(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [M_Ceil_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -676,6 +687,7 @@ class Round(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [M_Round_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -728,6 +740,7 @@ class Tanh(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [M_Tanh_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -784,6 +797,7 @@ class Exp(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [M_Exp_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
diff --git a/pyolib/controls.py b/pyolib/controls.py
index 00b21bf..f1db3d9 100644
--- a/pyolib/controls.py
+++ b/pyolib/controls.py
@@ -814,6 +814,7 @@ class SigTo(PyoObject):
self._time = time
value, time, init, mul ,add, lmax = convertArgsToLists(value, time, init, mul, add)
self._base_objs = [SigTo_base(wrap(value,i), wrap(time,i), wrap(init,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setValue(self, x):
"""
diff --git a/pyolib/dynamics.py b/pyolib/dynamics.py
index 872f0d2..1b45e52 100644
--- a/pyolib/dynamics.py
+++ b/pyolib/dynamics.py
@@ -59,6 +59,7 @@ class Clip(PyoObject):
self._in_fader = InputFader(input)
in_fader, min, max, mul, add, lmax = convertArgsToLists(self._in_fader, min, max, mul, add)
self._base_objs = [Clip_base(wrap(in_fader,i), wrap(min,i), wrap(max,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -173,6 +174,7 @@ class Mirror(PyoObject):
self._in_fader = InputFader(input)
in_fader, min, max, mul, add, lmax = convertArgsToLists(self._in_fader, min, max, mul, add)
self._base_objs = [Mirror_base(wrap(in_fader,i), wrap(min,i), wrap(max,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -285,6 +287,7 @@ class Degrade(PyoObject):
self._in_fader = InputFader(input)
in_fader, bitdepth, srscale, mul, add, lmax = convertArgsToLists(self._in_fader, bitdepth, srscale, mul, add)
self._base_objs = [Degrade_base(wrap(in_fader,i), wrap(bitdepth,i), wrap(srscale,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -421,6 +424,7 @@ class Compress(PyoObject):
self._in_fader = InputFader(input)
in_fader, thresh, ratio, risetime, falltime, lookahead, knee, outputAmp, mul, add, lmax = convertArgsToLists(self._in_fader, thresh, ratio, risetime, falltime, lookahead, knee, outputAmp, mul, add)
self._base_objs = [Compress_base(wrap(in_fader,i), wrap(thresh,i), wrap(ratio,i), wrap(risetime,i), wrap(falltime,i), wrap(lookahead,i), wrap(knee,i), wrap(outputAmp,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -639,6 +643,7 @@ class Gate(PyoObject):
self._in_fader = InputFader(input)
in_fader, thresh, risetime, falltime, lookahead, outputAmp, mul, add, lmax = convertArgsToLists(self._in_fader, thresh, risetime, falltime, lookahead, outputAmp, mul, add)
self._base_objs = [Gate_base(wrap(in_fader,i), wrap(thresh,i), wrap(risetime,i), wrap(falltime,i), wrap(lookahead,i), wrap(outputAmp,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -793,6 +798,7 @@ class Balance(PyoObject):
self._in_fader2 = InputFader(input2)
in_fader, in_fader2, freq, mul, add, lmax = convertArgsToLists(self._in_fader, self._in_fader2, freq, mul, add)
self._base_objs = [Balance_base(wrap(in_fader,i), wrap(in_fader2,i), wrap(freq,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -902,6 +908,7 @@ class Min(PyoObject):
self._in_fader = InputFader(input)
in_fader, comp, mul, add, lmax = convertArgsToLists(self._in_fader, comp, mul, add)
self._base_objs = [Min_base(wrap(in_fader,i), wrap(comp,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -982,6 +989,7 @@ class Max(PyoObject):
self._in_fader = InputFader(input)
in_fader, comp, mul, add, lmax = convertArgsToLists(self._in_fader, comp, mul, add)
self._base_objs = [Max_base(wrap(in_fader,i), wrap(comp,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
diff --git a/pyolib/effects.py b/pyolib/effects.py
index a445139..221025b 100644
--- a/pyolib/effects.py
+++ b/pyolib/effects.py
@@ -79,6 +79,7 @@ class Disto(PyoObject):
self._in_fader = InputFader(input)
in_fader, drive, slope, mul, add, lmax = convertArgsToLists(self._in_fader, drive, slope, mul, add)
self._base_objs = [Disto_base(wrap(in_fader,i), wrap(drive,i), wrap(slope,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -199,6 +200,7 @@ class Delay(PyoObject):
self._in_fader = InputFader(input)
in_fader, delay, feedback, maxdelay, mul, add, lmax = convertArgsToLists(self._in_fader, delay, feedback, maxdelay, mul, add)
self._base_objs = [Delay_base(wrap(in_fader,i), wrap(delay,i), wrap(feedback,i), wrap(maxdelay,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -317,6 +319,7 @@ class SDelay(PyoObject):
self._in_fader = InputFader(input)
in_fader, delay, maxdelay, mul, add, lmax = convertArgsToLists(self._in_fader, delay, maxdelay, mul, add)
self._base_objs = [SDelay_base(wrap(in_fader,i), wrap(delay,i), wrap(maxdelay,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -414,6 +417,7 @@ class Waveguide(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, dur, minfreq, mul, add, lmax = convertArgsToLists(self._in_fader, freq, dur, minfreq, mul, add)
self._base_objs = [Waveguide_base(wrap(in_fader,i), wrap(freq,i), wrap(dur,i), wrap(minfreq,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -540,6 +544,7 @@ class AllpassWG(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, feed, detune, minfreq, mul, add, lmax = convertArgsToLists(self._in_fader, freq, feed, detune, minfreq, mul, add)
self._base_objs = [AllpassWG_base(wrap(in_fader,i), wrap(freq,i), wrap(feed,i), wrap(detune,i), wrap(minfreq,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -686,6 +691,7 @@ class Freeverb(PyoObject):
self._in_fader = InputFader(input)
in_fader, size, damp, bal, mul, add, lmax = convertArgsToLists(self._in_fader, size, damp, bal, mul, add)
self._base_objs = [Freeverb_base(wrap(in_fader,i), wrap(size,i), wrap(damp,i), wrap(bal,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -842,6 +848,7 @@ class Convolve(PyoObject):
self._in_fader = InputFader(input)
in_fader, table, size, mul, add, lmax = convertArgsToLists(self._in_fader, table, size, mul, add)
self._base_objs = [Convolve_base(wrap(in_fader,i), wrap(table,i), wrap(size,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -931,6 +938,7 @@ class WGVerb(PyoObject):
self._in_fader = InputFader(input)
in_fader, feedback, cutoff, bal, mul, add, lmax = convertArgsToLists(self._in_fader, feedback, cutoff, bal, mul, add)
self._base_objs = [WGVerb_base(wrap(in_fader,i), wrap(feedback,i), wrap(cutoff,i), wrap(bal,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1073,6 +1081,7 @@ class Chorus(PyoObject):
self._in_fader = InputFader(input)
in_fader, depth, feedback, bal, mul, add, lmax = convertArgsToLists(self._in_fader, depth, feedback, bal, mul, add)
self._base_objs = [Chorus_base(wrap(in_fader,i), wrap(depth,i), wrap(feedback,i), wrap(bal,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1212,6 +1221,7 @@ class Harmonizer(PyoObject):
self._in_fader = InputFader(input)
in_fader, transpo, feedback, winsize, mul, add, lmax = convertArgsToLists(self._in_fader, transpo, feedback, winsize, mul, add)
self._base_objs = [Harmonizer_base(wrap(in_fader,i), wrap(transpo,i), wrap(feedback,i), wrap(winsize,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1345,6 +1355,7 @@ class Delay1(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [Delay1_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1428,6 +1439,7 @@ class STRev(PyoObject):
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)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1655,6 +1667,7 @@ class SmoothDelay(PyoObject):
self._in_fader = InputFader(input)
in_fader, delay, feedback, crossfade, maxdelay, mul, add, lmax = convertArgsToLists(self._in_fader, delay, feedback, crossfade, maxdelay, mul, add)
self._base_objs = [SmoothDelay_base(wrap(in_fader,i), wrap(delay,i), wrap(feedback,i), wrap(crossfade,i), wrap(maxdelay,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1807,6 +1820,7 @@ class FreqShift(PyoObject):
self._mod_objs.append(Mix(self._hilb_objs[-1]['real'] * self._sin_objs[-1] + self._hilb_objs[-1]['imag'] * self._cos_objs[-1],
mul=wrap(mul,i), add=wrap(add,i)))
self._base_objs.extend(self._mod_objs[-1].getBaseObjects())
+ self.play()
def play(self, dur=0, delay=0):
dur, delay, lmax = convertArgsToLists(dur, delay)
diff --git a/pyolib/expression.py b/pyolib/expression.py
index e4cb58d..41f27ff 100644
--- a/pyolib/expression.py
+++ b/pyolib/expression.py
@@ -306,6 +306,7 @@ class Expr(PyoObject):
self._in_fader = InputFader(input)
in_fader, expr, mul, add, lmax = convertArgsToLists(self._in_fader, expr, mul, add)
self._base_objs = [Expr_base(wrap(in_fader,i), to_unicode(wrap(expr,i)), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
diff --git a/pyolib/filters.py b/pyolib/filters.py
index a280683..852f5af 100644
--- a/pyolib/filters.py
+++ b/pyolib/filters.py
@@ -80,6 +80,7 @@ class Biquad(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, q, type, mul, add, lmax = convertArgsToLists(self._in_fader, freq, q, type, mul, add)
self._base_objs = [Biquad_base(wrap(in_fader,i), wrap(freq,i), wrap(q,i), wrap(type,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -229,6 +230,7 @@ class Biquadx(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, q, type, stages, mul, add, lmax = convertArgsToLists(self._in_fader, freq, q, type, stages, mul, add)
self._base_objs = [Biquadx_base(wrap(in_fader,i), wrap(freq,i), wrap(q,i), wrap(type,i), wrap(stages,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -408,6 +410,7 @@ class Biquada(PyoObject):
self._in_fader = InputFader(input)
in_fader, b0, b1, b2, a0, a1, a2, mul, add, lmax = convertArgsToLists(self._in_fader, self._b0, self._b1, self._b2, self._a0, self._a1, self._a2, mul, add)
self._base_objs = [Biquada_base(wrap(in_fader,i), wrap(b0,i), wrap(b1,i), wrap(b2,i), wrap(a0,i), wrap(a1,i), wrap(a2,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -632,6 +635,7 @@ class EQ(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, q, boost, type, mul, add, lmax = convertArgsToLists(self._in_fader, freq, q, boost, type, mul, add)
self._base_objs = [EQ_base(wrap(in_fader,i), wrap(freq,i), wrap(q,i), wrap(boost,i), wrap(type,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -782,6 +786,7 @@ class Tone(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, mul, add, lmax = convertArgsToLists(self._in_fader, freq, mul, add)
self._base_objs = [Tone_base(wrap(in_fader,i), wrap(freq,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -860,6 +865,7 @@ class Atone(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, mul, add, lmax = convertArgsToLists(self._in_fader, freq, mul, add)
self._base_objs = [Atone_base(wrap(in_fader,i), wrap(freq,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -951,6 +957,7 @@ class Port(PyoObject):
self._in_fader = InputFader(input)
in_fader, risetime, falltime, init, mul, add, lmax = convertArgsToLists(self._in_fader, risetime, falltime, init, mul, add)
self._base_objs = [Port_base(wrap(in_fader,i), wrap(risetime,i), wrap(falltime,i), wrap(init,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1049,6 +1056,7 @@ class DCBlock(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [DCBlock_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1125,6 +1133,7 @@ class BandSplit(PyoObject):
for j in range(num):
for i in range(lmax):
self._base_objs.append(BandSplit_base(wrap(self._base_players,i), j, wrap(mul,j), wrap(add,j)))
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1226,6 +1235,7 @@ class FourBand(PyoObject):
for j in range(4):
for i in range(lmax):
self._base_objs.append(FourBand_base(wrap(self._base_players,i), j, wrap(mul,j), wrap(add,j)))
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1382,6 +1392,7 @@ class Hilbert(PyoObject):
for j in range(lmax):
self._base_objs.append(Hilbert_base(wrap(self._base_players,j), 0, wrap(mul,i), wrap(add,i)))
self._base_objs.append(Hilbert_base(wrap(self._base_players,j), 1, wrap(mul,i), wrap(add,i)))
+ self.play()
def __getitem__(self, str):
if str == 'real':
@@ -1487,6 +1498,7 @@ class Allpass(PyoObject):
self._in_fader = InputFader(input)
in_fader, delay, feedback, maxdelay, mul, add, lmax = convertArgsToLists(self._in_fader, delay, feedback, maxdelay, mul, add)
self._base_objs = [Allpass_base(wrap(in_fader,i), wrap(delay,i), wrap(feedback,i), wrap(maxdelay,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1601,6 +1613,7 @@ class Allpass2(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, bw, mul, add, lmax = convertArgsToLists(self._in_fader, freq, bw, mul, add)
self._base_objs = [Allpass2_base(wrap(in_fader,i), wrap(freq,i), wrap(bw,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1722,6 +1735,7 @@ class Phaser(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, spread, q, feedback, num, mul, add, lmax = convertArgsToLists(self._in_fader, freq, spread, q, feedback, num, mul, add)
self._base_objs = [Phaser_base(wrap(in_fader,i), wrap(freq,i), wrap(spread,i), wrap(q,i), wrap(feedback,i), wrap(num,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1909,6 +1923,7 @@ class Vocoder(PyoObject):
self._in_fader2 = InputFader(input2)
in_fader, in_fader2, freq, spread, q, slope, stages, mul, add, lmax = convertArgsToLists(self._in_fader, self._in_fader2, freq, spread, q, slope, stages, mul, add)
self._base_objs = [Vocoder_base(wrap(in_fader,i), wrap(in_fader2,i), wrap(freq,i), wrap(spread,i), wrap(q,i), wrap(slope,i), wrap(stages,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -2139,6 +2154,7 @@ class IRWinSinc(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, bw, type, order, mul, add, lmax = convertArgsToLists(self._in_fader, freq, bw, type, order, mul, add)
self._base_objs = [IRWinSinc_base(wrap(in_fader,i), wrap(freq,i), wrap(bw,i), wrap(type,i), wrap(order,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -2287,6 +2303,7 @@ class IRAverage(PyoObject):
self._in_fader = InputFader(input)
in_fader, order, mul, add, lmax = convertArgsToLists(self._in_fader, order, mul, add)
self._base_objs = [IRAverage_base(wrap(in_fader,i), wrap(order,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -2374,6 +2391,7 @@ class IRPulse(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, bw, type, order, mul, add, lmax = convertArgsToLists(self._in_fader, freq, bw, type, order, mul, add)
self._base_objs = [IRPulse_base(wrap(in_fader,i), wrap(freq,i), wrap(bw,i), wrap(type,i), wrap(order,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -2533,6 +2551,7 @@ class IRFM(PyoObject):
self._in_fader = InputFader(input)
in_fader, carrier, ratio, index, order, mul, add, lmax = convertArgsToLists(self._in_fader, carrier, ratio, index, order, mul, add)
self._base_objs = [IRFM_base(wrap(in_fader,i), wrap(carrier,i), wrap(ratio,i), wrap(index,i), wrap(order,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -2674,6 +2693,7 @@ class SVF(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, q, type, mul, add, lmax = convertArgsToLists(self._in_fader, freq, q, type, mul, add)
self._base_objs = [SVF_base(wrap(in_fader,i), wrap(freq,i), wrap(q,i), wrap(type,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -2809,6 +2829,7 @@ class Average(PyoObject):
self._in_fader = InputFader(input)
in_fader, size, mul, add, lmax = convertArgsToLists(self._in_fader, size, mul, add)
self._base_objs = [Average_base(wrap(in_fader,i), wrap(size,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -2898,6 +2919,7 @@ class Reson(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, q, mul, add, lmax = convertArgsToLists(self._in_fader, freq, q, mul, add)
self._base_objs = [Reson_base(wrap(in_fader,i), wrap(freq,i), wrap(q,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -3014,6 +3036,7 @@ class Resonx(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, q, stages, mul, add, lmax = convertArgsToLists(self._in_fader, freq, q, stages, mul, add)
self._base_objs = [Resonx_base(wrap(in_fader,i), wrap(freq,i), wrap(q,i), wrap(stages,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -3140,6 +3163,7 @@ class ButLP(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, mul, add, lmax = convertArgsToLists(self._in_fader, freq, mul, add)
self._base_objs = [ButLP_base(wrap(in_fader,i), wrap(freq,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -3222,6 +3246,7 @@ class ButHP(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, mul, add, lmax = convertArgsToLists(self._in_fader, freq, mul, add)
self._base_objs = [ButHP_base(wrap(in_fader,i), wrap(freq,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -3308,6 +3333,7 @@ class ButBP(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, q, mul, add, lmax = convertArgsToLists(self._in_fader, freq, q, mul, add)
self._base_objs = [ButBP_base(wrap(in_fader,i), wrap(freq,i), wrap(q,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -3417,6 +3443,7 @@ class ButBR(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, q, mul, add, lmax = convertArgsToLists(self._in_fader, freq, q, mul, add)
self._base_objs = [ButBR_base(wrap(in_fader,i), wrap(freq,i), wrap(q,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -3526,6 +3553,7 @@ class MoogLP(PyoObject):
self._in_fader = InputFader(input)
in_fader, freq, res, mul, add, lmax = convertArgsToLists(self._in_fader, freq, res, mul, add)
self._base_objs = [MoogLP_base(wrap(in_fader,i), wrap(freq,i), wrap(res,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -3637,6 +3665,7 @@ class ComplexRes(PyoObject):
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)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
diff --git a/pyolib/fourier.py b/pyolib/fourier.py
index ae8c0a7..ede6a75 100644
--- a/pyolib/fourier.py
+++ b/pyolib/fourier.py
@@ -124,6 +124,7 @@ class FFT(PyoObject):
self._real_objs.append(FFT_base(wrap(self._base_players,j), 0, self._mul, self._add))
self._imag_objs.append(FFT_base(wrap(self._base_players,j), 1, self._mul, self._add))
self._bin_objs.append(FFT_base(wrap(self._base_players,j), 2, self._mul, self._add))
+ self.play()
def __len__(self):
return len(self._real_objs)
@@ -335,6 +336,7 @@ class IFFT(PyoObject):
for i in range(lmax):
hopsize = wrap(size,i) * ((i // ratio) % overlaps) // overlaps
self._base_objs.append(IFFT_base(wrap(in_fader,i), wrap(in_fader2,i), wrap(size,i), hopsize, wrap(wintype,i), wrap(mul,i), wrap(add,i)))
+ self.play()
def __len__(self):
return len(self._inreal)
@@ -498,6 +500,7 @@ class CarToPol(PyoObject):
for i in range(lmax):
self._base_objs.append(CarToPol_base(wrap(in_fader,i), wrap(in_fader2,i), 0, wrap(mul,i), wrap(add,i)))
self._base_objs.append(CarToPol_base(wrap(in_fader,i), wrap(in_fader2,i), 1, wrap(mul,i), wrap(add,i)))
+ self.play()
def __len__(self):
return len(self._inreal)
@@ -644,6 +647,7 @@ class PolToCar(PyoObject):
for i in range(lmax):
self._base_objs.append(PolToCar_base(wrap(in_fader,i), wrap(in_fader2,i), 0, wrap(mul,i), wrap(add,i)))
self._base_objs.append(PolToCar_base(wrap(in_fader,i), wrap(in_fader2,i), 1, wrap(mul,i), wrap(add,i)))
+ self.play()
def __len__(self):
return len(self._inmag)
@@ -802,6 +806,7 @@ class FrameDelta(PyoObject):
base_player = i % num_of_mains
overlap = i // num_of_mains
self._base_objs.append(FrameDelta_base(self._base_players[base_player], overlap, wrap(mul,i), wrap(add,i)))
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -925,6 +930,7 @@ class FrameAccum(PyoObject):
base_player = i % num_of_mains
overlap = i // num_of_mains
self._base_objs.append(FrameAccum_base(self._base_players[base_player], overlap, wrap(mul,i), wrap(add,i)))
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -1046,6 +1052,7 @@ class Vectral(PyoObject):
base_player = i % num_of_mains
overlap = i // num_of_mains
self._base_objs.append(Vectral_base(self._base_players[base_player], overlap, wrap(mul,i), wrap(add,i)))
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -1218,6 +1225,7 @@ class CvlVerb(PyoObject):
_size, _dur, _snd_sr, _snd_chnls, _format, _type = sndinfo(file)
lmax3 = max(lmax, _snd_chnls)
self._base_objs.extend([CvlVerb_base(wrap(in_fader,i), file, wrap(bal,i), wrap(size,i), i%_snd_chnls, wrap(mul,i), wrap(add,i)) for i in range(lmax3)])
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
diff --git a/pyolib/generators.py b/pyolib/generators.py
index 22464ac..1df8932 100644
--- a/pyolib/generators.py
+++ b/pyolib/generators.py
@@ -62,6 +62,7 @@ class Sine(PyoObject):
self._phase = phase
freq, phase, mul, add, lmax = convertArgsToLists(freq, phase, mul, add)
self._base_objs = [Sine_base(wrap(freq,i), wrap(phase,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setFreq(self, x):
"""
@@ -161,6 +162,7 @@ class FastSine(PyoObject):
self._quality = quality
freq, initphase, quality, mul, add, lmax = convertArgsToLists(freq, initphase, quality, mul, add)
self._base_objs = [FastSine_base(wrap(freq,i), wrap(initphase,i), wrap(quality,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setFreq(self, x):
"""
@@ -253,6 +255,7 @@ class SineLoop(PyoObject):
self._feedback = feedback
freq, feedback, mul, add, lmax = convertArgsToLists(freq, feedback, mul, add)
self._base_objs = [SineLoop_base(wrap(freq,i), wrap(feedback,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setFreq(self, x):
"""
@@ -335,6 +338,7 @@ class Phasor(PyoObject):
self._phase = phase
freq, phase, mul, add, lmax = convertArgsToLists(freq, phase, mul, add)
self._base_objs = [Phasor_base(wrap(freq,i), wrap(phase,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setFreq(self, x):
"""
@@ -418,6 +422,7 @@ class Input(PyoObject):
self._chnl = chnl
chnl, mul, add, lmax = convertArgsToLists(chnl, mul, add)
self._base_objs = [Input_base(wrap(chnl,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def ctrl(self, map_list=None, title=None, wxnoserver=False):
self._map_list = [SLMapMul(self._mul)]
@@ -440,6 +445,7 @@ class Noise(PyoObject):
self._type = 0
mul, add, lmax = convertArgsToLists(mul, add)
self._base_objs = [Noise_base(wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setType(self, x):
"""
@@ -490,6 +496,7 @@ class PinkNoise(PyoObject):
PyoObject.__init__(self, mul, add)
mul, add, lmax = convertArgsToLists(mul, add)
self._base_objs = [PinkNoise_base(wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def ctrl(self, map_list=None, title=None, wxnoserver=False):
self._map_list = [SLMapMul(self._mul)]
@@ -514,6 +521,7 @@ class BrownNoise(PyoObject):
PyoObject.__init__(self, mul, add)
mul, add, lmax = convertArgsToLists(mul, add)
self._base_objs = [BrownNoise_base(wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def ctrl(self, map_list=None, title=None, wxnoserver=False):
self._map_list = [SLMapMul(self._mul)]
@@ -554,6 +562,7 @@ class FM(PyoObject):
self._index = index
carrier, ratio, index, mul, add, lmax = convertArgsToLists(carrier, ratio, index, mul, add)
self._base_objs = [Fm_base(wrap(carrier,i), wrap(ratio,i), wrap(index,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setCarrier(self, x):
"""
@@ -672,6 +681,7 @@ class CrossFM(PyoObject):
self._ind2 = ind2
carrier, ratio, ind1, ind2, mul, add, lmax = convertArgsToLists(carrier, ratio, ind1, ind2, mul, add)
self._base_objs = [CrossFm_base(wrap(carrier,i), wrap(ratio,i), wrap(ind1,i), wrap(ind2,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setCarrier(self, x):
"""
@@ -799,6 +809,7 @@ class Blit(PyoObject):
self._harms = harms
freq, harms, mul, add, lmax = convertArgsToLists(freq, harms, mul, add)
self._base_objs = [Blit_base(wrap(freq,i), wrap(harms,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setFreq(self, x):
"""
@@ -901,6 +912,7 @@ class Rossler(PyoObject):
self._base_objs.append(Rossler_base(wrap(pitch,i), wrap(chaos,i), wrap(mul,i), wrap(add,i)))
if self._stereo:
self._base_objs.append(RosslerAlt_base(self._base_objs[-1], wrap(mul,i), wrap(add,i)))
+ self.play()
def setPitch(self, x):
"""
@@ -1008,6 +1020,7 @@ class Lorenz(PyoObject):
self._base_objs.append(Lorenz_base(wrap(pitch,i), wrap(chaos,i), wrap(mul,i), wrap(add,i)))
if self._stereo:
self._base_objs.append(LorenzAlt_base(self._base_objs[-1], wrap(mul,i), wrap(add,i)))
+ self.play()
def setPitch(self, x):
"""
@@ -1115,6 +1128,7 @@ class ChenLee(PyoObject):
self._base_objs.append(ChenLee_base(wrap(pitch,i), wrap(chaos,i), wrap(mul,i), wrap(add,i)))
if self._stereo:
self._base_objs.append(ChenLeeAlt_base(self._base_objs[-1], wrap(mul,i), wrap(add,i)))
+ self.play()
def setPitch(self, x):
"""
@@ -1212,6 +1226,7 @@ class LFO(PyoObject):
self._type = type
freq, sharp, type, mul, add, lmax = convertArgsToLists(freq, sharp, type, mul, add)
self._base_objs = [LFO_base(wrap(freq,i), wrap(sharp,i), wrap(type,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setFreq(self, x):
"""
@@ -1352,6 +1367,7 @@ class SumOsc(PyoObject):
self._index = index
freq, ratio, index, mul, add, lmax = convertArgsToLists(freq, ratio, index, mul, add)
self._base_objs = [SumOsc_base(wrap(freq,i), wrap(ratio,i), wrap(index,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setFreq(self, x):
"""
@@ -1469,6 +1485,7 @@ class SuperSaw(PyoObject):
self._bal = bal
freq, detune, bal, mul, add, lmax = convertArgsToLists(freq, detune, bal, mul, add)
self._base_objs = [SuperSaw_base(wrap(freq,i), wrap(detune,i), wrap(bal,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setFreq(self, x):
"""
@@ -1577,6 +1594,7 @@ class RCOsc(PyoObject):
self._sharp = sharp
freq, sharp, mul, add, lmax = convertArgsToLists(freq, sharp, mul, add)
self._base_objs = [RCOsc_base(wrap(freq,i), wrap(sharp,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setFreq(self, x):
"""
diff --git a/pyolib/listener.py b/pyolib/listener.py
index b16b732..3fe6d32 100644
--- a/pyolib/listener.py
+++ b/pyolib/listener.py
@@ -25,11 +25,20 @@ class MidiListener(threading.Thread):
def myfunc(status, data1, data2)
- mididev: int, optional
+ mididev: int or list of ints, optional
Sets the midi input device (see `pm_list_devices()` for the
available devices). The default, -1, means the system default
device. A number greater than the highest portmidi device index
- will open all available input devices.
+ will open all available input devices. Specific devices can be
+ set with a list of integers.
+
+ reportdevice: boolean, optional
+ If True, the device ID will be reported as a fourth argument to
+ the callback. The signature will then be:
+
+ def myfunc(status, data1, data2, id)
+
+ Available at initialization only. Defaults to False.
.. note::
@@ -44,12 +53,15 @@ class MidiListener(threading.Thread):
>>> listen.start()
"""
- def __init__(self, function, mididev=-1):
+ def __init__(self, function, mididev=-1, reportdevice=False):
threading.Thread.__init__(self)
self.daemon = True
self._function = WeakMethod(function)
self._mididev = mididev
- self._listener = MidiListener_base(self._function, self._mididev)
+ if type(mididev) is not list:
+ mididev = [mididev]
+ self._reportdevice = reportdevice
+ self._listener = MidiListener_base(self._function, mididev, self._reportdevice)
def run(self):
"""
@@ -63,6 +75,140 @@ class MidiListener(threading.Thread):
except:
pass
+ def getDeviceInfos(self):
+ """
+ Returns infos about connected midi devices.
+
+ This method returns a list of dictionaries, one per device.
+
+ Dictionary format is:
+
+ {"id": device_id (int), "name": device_name (str), "interface": interface (str)}
+
+ """
+ infos = self._listener.getDeviceInfos()
+ if infos:
+ lst = []
+ for info in infos:
+ dct = {}
+ items = info.split(", ")
+ for item in items:
+ isplit = item.split(": ")
+ dct[isplit[0]] = isplit[1]
+ dct["id"] = int(dct["id"])
+ lst.append(dct)
+ return lst
+ return []
+
+class MidiDispatcher(threading.Thread):
+ """
+ Self-contained midi dispatcher thread.
+
+ This object allows to setup a Midi server that is independent
+ of the audio server (mainly to be able to send Midi data even
+ when the audio server is stopped). Although it runs in a separated
+ thread, the same device can't be used by this object and the audio
+ server at the same time. It is adviced to call the deactivateMidi()
+ method on the audio server to avoid conflicts.
+
+ Use the `send` method to send midi event to connected devices.
+
+ :Parent: threading.Thread
+
+ :Args:
+
+ mididev: int or list of ints, optional
+ Sets the midi output device (see `pm_list_devices()` for the
+ available devices). The default, -1, means the system default
+ device. A number greater than the highest portmidi device index
+ will open all available input devices. Specific devices can be
+ set with a list of integers.
+
+ .. note::
+
+ This object is available only if pyo is built with portmidi support
+ (see withPortmidi function).
+
+ >>> s = Server().boot()
+ >>> s.deactivateMidi()
+ >>> dispatch = MidiDispatcher(5)
+ >>> dispatch.start()
+ >>> dispatch.send(144, 60, 127)
+
+ """
+ def __init__(self, mididev=-1):
+ threading.Thread.__init__(self)
+ self.daemon = True
+ self._mididev = mididev
+ if type(mididev) is not list:
+ mididev = [mididev]
+ self._dispatcher = MidiDispatcher_base(mididev)
+
+ def run(self):
+ """
+ Starts the process. The thread runs as daemon, so no need to stop it.
+
+ """
+ self._dispatcher.play()
+ while True:
+ try:
+ time.sleep(0.001)
+ except:
+ pass
+
+ def send(self, status, data1, data2=0, timestamp=0, device=-1):
+ """
+ Send a MIDI message to the selected midi output device.
+
+ Arguments can be list of values to generate multiple events
+ in one call.
+
+ :Args:
+
+ status: int
+ Status byte.
+ data1: int
+ First data byte.
+ data2: int, optional
+ Second data byte. Defaults to 0.
+ timestamp: int, optional
+ The delay time, in milliseconds, before the note
+ is sent on the portmidi stream. A value of 0 means
+ to play the note now. Defaults to 0.
+ device: int, optional
+ The index of the device to which the message will
+ be sent. The default (-1) means all devices. See
+ `getDeviceInfos()` to retrieve device indexes.
+
+ """
+ status, data1, data2, timestamp, device, lmax = convertArgsToLists(status, data1, data2, timestamp, device)
+ [self._dispatcher.send(wrap(status,i), wrap(data1,i), wrap(data2,i), wrap(timestamp,i), wrap(device,i)) for i in range(lmax)]
+
+ def getDeviceInfos(self):
+ """
+ Returns infos about connected midi devices.
+
+ This method returns a list of dictionaries, one per device.
+
+ Dictionary format is:
+
+ {"id": device_id (int), "name": device_name (str), "interface": interface (str)}
+
+ """
+ infos = self._dispatcher.getDeviceInfos()
+ if infos:
+ lst = []
+ for info in infos:
+ dct = {}
+ items = info.split(", ")
+ for item in items:
+ isplit = item.split(": ")
+ dct[isplit[0]] = isplit[1]
+ dct["id"] = int(dct["id"])
+ lst.append(dct)
+ return lst
+ return []
+
OscListenerLock = threading.Lock()
class OscListener(threading.Thread):
diff --git a/pyolib/matrixprocess.py b/pyolib/matrixprocess.py
index 6b971b3..0c02422 100644
--- a/pyolib/matrixprocess.py
+++ b/pyolib/matrixprocess.py
@@ -205,6 +205,7 @@ class MatrixRecLoop(PyoObject):
in_fader, matrix, lmax = convertArgsToLists(self._in_fader, matrix)
self._base_objs = [MatrixRecLoop_base(wrap(in_fader,i), wrap(matrix,i)) for i in range(len(matrix))]
self._trig_objs = Dummy([TriggerDummy_base(obj) for obj in self._base_objs])
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -298,6 +299,7 @@ class MatrixPointer(PyoObject):
self._y = y
matrix, x, y, mul, add, lmax = convertArgsToLists(matrix, x, y, mul, add)
self._base_objs = [MatrixPointer_base(wrap(matrix,i), wrap(x,i), wrap(y,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setMatrix(self, x):
"""
@@ -420,6 +422,7 @@ class MatrixMorph(PyoObject):
in_fader, matrix, lmax = convertArgsToLists(self._in_fader, matrix)
self._base_sources = [source[0] for source in sources]
self._base_objs = [MatrixMorph_base(wrap(in_fader,i), wrap(matrix,i), self._base_sources) for i in range(len(matrix))]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
diff --git a/pyolib/midi.py b/pyolib/midi.py
index 549234d..be9e7c3 100644
--- a/pyolib/midi.py
+++ b/pyolib/midi.py
@@ -80,6 +80,7 @@ class Midictl(PyoObject):
self._channel = channel
ctlnumber, minscale, maxscale, init, channel, mul, add, lmax = convertArgsToLists(ctlnumber, minscale, maxscale, init, channel, mul, add)
self._base_objs = [Midictl_base(wrap(ctlnumber,i), wrap(minscale,i), wrap(maxscale,i), wrap(init,i), wrap(channel,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -160,7 +161,7 @@ class Midictl(PyoObject):
def setInterpolation(self, x):
"""
- Activate/Deactivate interpolation. Activated by default.
+ Activate/Deactivate interpolation. Off by default.
:Args:
@@ -255,6 +256,7 @@ class CtlScan(PyoObject):
self._function = WeakMethod(function)
self._toprint = toprint
self._base_objs = [CtlScan_base(self._function, self._toprint)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -366,6 +368,7 @@ class CtlScan2(PyoObject):
self._function = WeakMethod(function)
self._toprint = toprint
self._base_objs = [CtlScan2_base(self._function, self._toprint)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -514,6 +517,7 @@ class Notein(PyoObject):
self._base_objs.append(Notein_base(self._base_handler, i, 1, wrap(mul,i), wrap(add,i)))
self._trig_objs.append(NoteinTrig_base(self._base_handler, i, 0, 1, 0))
self._trig_objs.append(NoteinTrig_base(self._base_handler, i, 1, 1, 0))
+ self.play()
def __getitem__(self, str):
if str == 'pitch':
@@ -740,6 +744,7 @@ class Bendin(PyoObject):
self._channel = channel
brange, scale, channel, mul, add, lmax = convertArgsToLists(brange, scale, channel, mul, add)
self._base_objs = [Bendin_base(wrap(brange,i), wrap(scale,i), wrap(channel,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -789,6 +794,20 @@ class Bendin(PyoObject):
x, lmax = convertArgsToLists(x)
[obj.setChannel(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ def setInterpolation(self, x):
+ """
+ Activate/Deactivate interpolation. Off by default.
+
+ :Args:
+
+ x: boolean
+ True activates the interpolation, False deactivates it.
+
+ """
+ pyoArgsAssert(self, "b", x)
+ x, lmax = convertArgsToLists(x)
+ [obj.setInterpolation(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.0, 12.0, 'lin', 'brange', self._brange, dataOnly=True),
SLMap(0, 1, 'lin', 'scale', self._scale, res="int", dataOnly=True),
@@ -860,6 +879,7 @@ class Touchin(PyoObject):
self._channel = channel
minscale, maxscale, init, channel, mul, add, lmax = convertArgsToLists(minscale, maxscale, init, channel, mul, add)
self._base_objs = [Touchin_base(wrap(minscale,i), wrap(maxscale,i), wrap(init,i), wrap(channel,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -909,6 +929,20 @@ class Touchin(PyoObject):
x, lmax = convertArgsToLists(x)
[obj.setChannel(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ def setInterpolation(self, x):
+ """
+ Activate/Deactivate interpolation. Off by default.
+
+ :Args:
+
+ x: boolean
+ True activates the interpolation, False deactivates it.
+
+ """
+ pyoArgsAssert(self, "b", x)
+ x, lmax = convertArgsToLists(x)
+ [obj.setInterpolation(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.0, 0.0, 'lin', 'minscale', self._minscale, dataOnly=True),
SLMap(0.0, 1.0, 'lin', 'maxscale', self._maxscale, dataOnly=True),
@@ -974,6 +1008,7 @@ class Programin(PyoObject):
self._channel = channel
channel, mul, add, lmax = convertArgsToLists(channel, mul, add)
self._base_objs = [Programin_base(wrap(channel,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -1061,6 +1096,7 @@ class MidiAdsr(PyoObject):
self._in_fader = InputFader(input)
in_fader, attack, decay, sustain, release, mul, add, lmax = convertArgsToLists(self._in_fader, attack, decay, sustain, release, mul, add)
self._base_objs = [MidiAdsr_base(wrap(in_fader,i), wrap(attack,i), wrap(decay,i), wrap(sustain,i), wrap(release,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -1265,6 +1301,7 @@ class MidiDelAdsr(PyoObject):
self._in_fader = InputFader(input)
in_fader, delay, attack, decay, sustain, release, mul, add, lmax = convertArgsToLists(self._in_fader, delay, attack, decay, sustain, release, mul, add)
self._base_objs = [MidiDelAdsr_base(wrap(in_fader,i), wrap(delay,i), wrap(attack,i), wrap(decay,i), wrap(sustain,i), wrap(release,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -1469,6 +1506,7 @@ class RawMidi(PyoObject):
PyoObject.__init__(self)
self._function = WeakMethod(function)
self._base_objs = [RawMidi_base(self._function)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
diff --git a/pyolib/opensndctrl.py b/pyolib/opensndctrl.py
index 4860b01..9406a82 100644
--- a/pyolib/opensndctrl.py
+++ b/pyolib/opensndctrl.py
@@ -96,6 +96,7 @@ class OscSend(PyoObject):
self._in_fader = InputFader(input)
in_fader, port, address, host, lmax = convertArgsToLists(self._in_fader, port, address, host)
self._base_objs = [OscSend_base(wrap(in_fader,i), wrap(port,i), wrap(address,i), wrap(host,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -192,6 +193,7 @@ class OscReceive(PyoObject):
self._address = address
self._mainReceiver = OscReceiver_base(port, address)
self._base_objs = [OscReceive_base(self._mainReceiver, wrap(address,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def __getitem__(self, i):
if type(i) in [bytes_t, unicode_t]:
@@ -387,6 +389,7 @@ class OscDataSend(PyoObject):
self._addresses = {}
for i, adr in enumerate(address):
self._addresses[adr] = self._base_objs[i]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -552,6 +555,7 @@ class OscDataReceive(PyoObject):
self._address, lmax = convertArgsToLists(address)
# self._address is linked with list at C level
self._base_objs = [OscDataReceive_base(port, self._address, self._function)]
+ self.play()
def setMul(self, x):
pass
@@ -658,6 +662,7 @@ class OscListReceive(PyoObject):
self._address = address
self._mainReceiver = OscListReceiver_base(port, address, num)
self._base_objs = [OscListReceive_base(self._mainReceiver, wrap(address,i), j, wrap(mul,i), wrap(add,i)) for i in range(lmax) for j in range(self._num)]
+ self.play()
def __getitem__(self, i):
if type(i) in [bytes_t, unicode_t]:
diff --git a/pyolib/pan.py b/pyolib/pan.py
index a48549f..683b4ef 100644
--- a/pyolib/pan.py
+++ b/pyolib/pan.py
@@ -71,6 +71,7 @@ class Pan(PyoObject):
for i in range(lmax):
for j in range(outs):
self._base_objs.append(Pan_base(wrap(self._base_players,i), j, wrap(mul,i), wrap(add,i)))
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -182,6 +183,7 @@ class SPan(PyoObject):
for i in range(lmax):
for j in range(outs):
self._base_objs.append(SPan_base(wrap(self._base_players,i), j, wrap(mul,i), wrap(add,i)))
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -278,6 +280,7 @@ class Switch(PyoObject):
for j in range(outs):
for i in range(lmax):
self._base_objs.append(Switch_base(wrap(self._base_players,i), j, wrap(mul,i), wrap(add,i)))
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -376,6 +379,7 @@ class Selector(PyoObject):
except:
choice.append(obj)
self._base_objs.append(Selector_base(choice, wrap(voice,i), wrap(mul,i), wrap(add,i)))
+ self.play()
def setInputs(self, x):
"""
@@ -494,6 +498,7 @@ class VoiceManager(PyoObject):
else:
t_streams = None
self._base_objs = [VoiceManager_base(wrap(in_fader,i), t_streams, wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -604,6 +609,7 @@ class Mixer(PyoObject):
time, mul, add, lmax = convertArgsToLists(time, mul, add)
self._base_players = [Mixer_base(outs, wrap(time,i)) for i in range(chnls)]
self._base_objs = [MixerVoice_base(self._base_players[j], i, wrap(mul,i), wrap(add,i)) for i in range(outs) for j in range(chnls)]
+ self.play()
def __getitem__(self, x):
if type(x) == slice:
diff --git a/pyolib/pattern.py b/pyolib/pattern.py
index fd07313..63ce461 100644
--- a/pyolib/pattern.py
+++ b/pyolib/pattern.py
@@ -221,6 +221,7 @@ class Score(PyoObject):
self._in_fader = InputFader(input)
in_fader, fname, lmax = convertArgsToLists(self._in_fader, fname)
self._base_objs = [Score_base(wrap(in_fader,i), wrap(fname,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -304,6 +305,7 @@ class CallAfter(PyoObject):
self._function = getWeakMethodRef(function)
function, time, arg, lmax = convertArgsToLists(function, time, arg)
self._base_objs = [CallAfter_base(WeakMethod(wrap(function,i)), wrap(time,i), wrap(arg,i)) for i in range(lmax)]
+ self.play()
def out(self, x=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
diff --git a/pyolib/phasevoc.py b/pyolib/phasevoc.py
index 7997797..0bc1774 100644
--- a/pyolib/phasevoc.py
+++ b/pyolib/phasevoc.py
@@ -92,6 +92,7 @@ class PVAnal(PyoPVObject):
self._in_fader = InputFader(input)
in_fader, size, overlaps, wintype, lmax = convertArgsToLists(self._in_fader, size, overlaps, wintype)
self._base_objs = [PVAnal_base(wrap(in_fader,i), wrap(size,i), wrap(overlaps,i), wrap(wintype,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -223,6 +224,7 @@ class PVSynth(PyoObject):
self._wintype = wintype
input, wintype, mul, add, lmax = convertArgsToLists(self._input, wintype, mul, add)
self._base_objs = [PVSynth_base(wrap(input,i), wrap(wintype,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -317,6 +319,7 @@ class PVAddSynth(PyoObject):
self._inc = inc
input, pitch, num, first, inc, mul, add, lmax = convertArgsToLists(self._input, pitch, num, first, inc, mul, add)
self._base_objs = [PVAddSynth_base(wrap(input,i), wrap(pitch,i), wrap(num,i), wrap(first,i), wrap(inc,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -462,6 +465,7 @@ class PVTranspose(PyoPVObject):
self._transpo = transpo
input, transpo, lmax = convertArgsToLists(self._input, transpo)
self._base_objs = [PVTranspose_base(wrap(input,i), wrap(transpo,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -547,6 +551,7 @@ class PVVerb(PyoPVObject):
self._damp = damp
input, revtime, damp, lmax = convertArgsToLists(self._input, revtime, damp)
self._base_objs = [PVVerb_base(wrap(input,i), wrap(revtime,i), wrap(damp,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -657,6 +662,7 @@ class PVGate(PyoPVObject):
self._inverse = inverse
input, thresh, damp, inverse, lmax = convertArgsToLists(self._input, thresh, damp, inverse)
self._base_objs = [PVGate_base(wrap(input,i), wrap(thresh,i), wrap(damp,i), wrap(inverse,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -806,6 +812,7 @@ class PVCross(PyoPVObject):
self._fade = fade
input, input2, fade, lmax = convertArgsToLists(self._input, self._input2, fade)
self._base_objs = [PVCross_base(wrap(input,i), wrap(input2,i), wrap(fade,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -924,6 +931,7 @@ class PVMult(PyoPVObject):
self._input2 = input2
input, input2, lmax = convertArgsToLists(self._input, self._input2)
self._base_objs = [PVMult_base(wrap(input,i), wrap(input2,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -1024,6 +1032,7 @@ class PVMorph(PyoPVObject):
self._fade = fade
input, input2, fade, lmax = convertArgsToLists(self._input, self._input2, fade)
self._base_objs = [PVMorph_base(wrap(input,i), wrap(input2,i), wrap(fade,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -1140,6 +1149,7 @@ class PVFilter(PyoPVObject):
self._mode = mode
input, table, gain, mode, lmax = convertArgsToLists(self._input, table, gain, mode)
self._base_objs = [PVFilter_base(wrap(input,i), wrap(table,i), wrap(gain,i), wrap(mode,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -1293,6 +1303,7 @@ class PVDelay(PyoPVObject):
self._mode = mode
input, deltable, feedtable, maxdelay, mode, lmax = convertArgsToLists(self._input, deltable, feedtable, maxdelay, mode)
self._base_objs = [PVDelay_base(wrap(input,i), wrap(deltable,i), wrap(feedtable,i), wrap(maxdelay,i), wrap(mode,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -1429,6 +1440,7 @@ class PVBuffer(PyoPVObject):
self._length = length
input, index, pitch, length, lmax = convertArgsToLists(self._input, index, pitch, length)
self._base_objs = [PVBuffer_base(wrap(input,i), wrap(index,i), wrap(pitch,i), wrap(length,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -1531,6 +1543,7 @@ class PVShift(PyoPVObject):
self._shift = shift
input, shift, lmax = convertArgsToLists(self._input, shift)
self._base_objs = [PVShift_base(wrap(input,i), wrap(shift,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -1608,6 +1621,16 @@ class PVAmpMod(PyoPVObject):
spread: float or PyoObject, optional
Spreading factor for oscillator frequencies, between
-1 and 1. 0 means every oscillator has the same frequency.
+ shape: int, optional
+ Modulation oscillator waveform. Possible shapes are:
+ 0. Sine (default)
+ 1. Sawtooth
+ 2. Ramp (inverse sawtooth)
+ 3. Square
+ 4. Triangle
+ 5. Brown Noise
+ 6. Pink Noise
+ 7. White Noise
>>> s = Server().boot()
>>> s.start()
@@ -1617,14 +1640,16 @@ class PVAmpMod(PyoPVObject):
>>> pvs = PVSynth(pvm).out()
"""
- def __init__(self, input, basefreq=1, spread=0):
- pyoArgsAssert(self, "pOO", input, basefreq, spread)
+ def __init__(self, input, basefreq=1, spread=0, shape=0):
+ pyoArgsAssert(self, "pOOi", input, basefreq, spread, shape)
PyoPVObject.__init__(self)
self._input = input
self._basefreq = basefreq
self._spread = spread
- input, basefreq, spread, lmax = convertArgsToLists(self._input, basefreq, spread)
- self._base_objs = [PVAmpMod_base(wrap(input,i), wrap(basefreq,i), wrap(spread,i)) for i in range(lmax)]
+ self._shape = shape
+ input, basefreq, spread, shape, lmax = convertArgsToLists(self._input, basefreq, spread, shape)
+ self._base_objs = [PVAmpMod_base(wrap(input,i), wrap(basefreq,i), wrap(spread,i), wrap(shape,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -1671,6 +1696,29 @@ class PVAmpMod(PyoPVObject):
x, lmax = convertArgsToLists(x)
[obj.setSpread(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ def setShape(self, x):
+ """
+ Replace the `shape` attribute.
+
+ :Args:
+
+ x: int
+ new `shape` attribute. Possible shapes are:
+ 0. Sine (default)
+ 1. Sawtooth
+ 2. Ramp (inverse sawtooth)
+ 3. Square
+ 4. Triangle
+ 5. Brown Noise
+ 6. Pink Noise
+ 7. White Noise
+
+ """
+ pyoArgsAssert(self, "i", x)
+ self._shape = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setShape(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
def reset(self):
"""
Resets modulation pointers to 0.
@@ -1704,6 +1752,13 @@ class PVAmpMod(PyoPVObject):
@spread.setter
def spread(self, x): self.setSpread(x)
+ @property
+ def shape(self):
+ """int. Modulation oscillator waveform."""
+ return self._shape
+ @shape.setter
+ def shape(self, x): self.setShape(x)
+
class PVFreqMod(PyoPVObject):
"""
Performs frequency independent frequency modulations.
@@ -1735,6 +1790,16 @@ class PVFreqMod(PyoPVObject):
depth: float or PyoObject, optional
Amplitude of the modulating oscillators, between 0 and 1.
Defaults to 0.1.
+ shape: int, optional
+ Modulation oscillator waveform. Possible shapes are:
+ 0. Sine (default)
+ 1. Sawtooth
+ 2. Ramp (inverse sawtooth)
+ 3. Square
+ 4. Triangle
+ 5. Brown Noise
+ 6. Pink Noise
+ 7. White Noise
>>> s = Server().boot()
>>> s.start()
@@ -1744,15 +1809,17 @@ class PVFreqMod(PyoPVObject):
>>> pvs = PVSynth(pvm).out()
"""
- def __init__(self, input, basefreq=1, spread=0, depth=0.1):
- pyoArgsAssert(self, "pOOO", input, basefreq, spread, depth)
+ def __init__(self, input, basefreq=1, spread=0, depth=0.1, shape=0):
+ pyoArgsAssert(self, "pOOOi", input, basefreq, spread, depth, shape)
PyoPVObject.__init__(self)
self._input = input
self._basefreq = basefreq
self._spread = spread
self._depth = depth
- input, basefreq, spread, depth, lmax = convertArgsToLists(self._input, basefreq, spread, depth)
- self._base_objs = [PVFreqMod_base(wrap(input,i), wrap(basefreq,i), wrap(spread,i), wrap(depth,i)) for i in range(lmax)]
+ self._shape = shape
+ input, basefreq, spread, depth, shape, lmax = convertArgsToLists(self._input, basefreq, spread, depth, shape)
+ self._base_objs = [PVFreqMod_base(wrap(input,i), wrap(basefreq,i), wrap(spread,i), wrap(depth,i), wrap(shape,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -1814,6 +1881,29 @@ class PVFreqMod(PyoPVObject):
x, lmax = convertArgsToLists(x)
[obj.setDepth(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ def setShape(self, x):
+ """
+ Replace the `shape` attribute.
+
+ :Args:
+
+ x: int
+ new `shape` attribute. Possible shapes are:
+ 0. Sine (default)
+ 1. Sawtooth
+ 2. Ramp (inverse sawtooth)
+ 3. Square
+ 4. Triangle
+ 5. Brown Noise
+ 6. Pink Noise
+ 7. White Noise
+
+ """
+ pyoArgsAssert(self, "i", x)
+ self._shape = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setShape(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
def reset(self):
"""
Resets modulation pointers to 0.
@@ -1855,6 +1945,13 @@ class PVFreqMod(PyoPVObject):
@depth.setter
def depth(self, x): self.setDepth(x)
+ @property
+ def shape(self):
+ """int. Modulation oscillator waveform."""
+ return self._shape
+ @shape.setter
+ def shape(self, x): self.setShape(x)
+
class PVBufLoops(PyoPVObject):
"""
Phase vocoder buffer with bin independent speed playback.
@@ -1912,6 +2009,7 @@ class PVBufLoops(PyoPVObject):
self._length = length
input, low, high, mode, length, lmax = convertArgsToLists(self._input, low, high, mode, length)
self._base_objs = [PVBufLoops_base(wrap(input,i), wrap(low,i), wrap(high,i), wrap(mode,i), wrap(length,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -2057,6 +2155,7 @@ class PVBufTabLoops(PyoPVObject):
self._length = length
input, speed, length, lmax = convertArgsToLists(self._input, speed, length)
self._base_objs = [PVBufTabLoops_base(wrap(input,i), wrap(speed,i), wrap(length,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
@@ -2154,6 +2253,7 @@ class PVMix(PyoPVObject):
self._input2 = input2
input, input2, lmax = convertArgsToLists(self._input, self._input2)
self._base_objs = [PVMix_base(wrap(input,i), wrap(input2,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x):
"""
diff --git a/pyolib/players.py b/pyolib/players.py
index 8d4bd42..cde1780 100644
--- a/pyolib/players.py
+++ b/pyolib/players.py
@@ -112,6 +112,7 @@ class SfPlayer(PyoObject):
self._base_objs.append(SfPlay_base(self._base_players[-1], j, wrap(mul,i), wrap(add,i)))
_trig_objs_tmp.append(TriggerDummy_base(self._base_players[-1]))
self._trig_objs = Dummy(_trig_objs_tmp)
+ self.play()
def setPath(self, path):
"""
@@ -337,6 +338,7 @@ class SfMarkerShuffler(PyoObject):
for i in range(lmax * self._snd_chnls):
j = i // self._snd_chnls
self._base_objs.append(SfMarkerShuffle_base(wrap(self._base_players,j), i % self._snd_chnls, wrap(mul,j), wrap(add,j)))
+ self.play()
def setSpeed(self, x):
"""
@@ -464,6 +466,7 @@ class SfMarkerLooper(PyoObject):
for i in range(lmax * self._snd_chnls):
j = i // self._snd_chnls
self._base_objs.append(SfMarkerLoop_base(wrap(self._base_players,j), i % self._snd_chnls, wrap(mul,j), wrap(add,j)))
+ self.play()
def setSpeed(self, x):
"""
diff --git a/pyolib/randoms.py b/pyolib/randoms.py
index c39e6a0..a864aaa 100644
--- a/pyolib/randoms.py
+++ b/pyolib/randoms.py
@@ -59,6 +59,7 @@ class Randi(PyoObject):
self._freq = freq
min, max, freq, mul, add, lmax = convertArgsToLists(min, max, freq, mul, add)
self._base_objs = [Randi_base(wrap(min,i), wrap(max,i), wrap(freq,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setMin(self, x):
"""
@@ -168,6 +169,7 @@ class Randh(PyoObject):
self._freq = freq
min, max, freq, mul, add, lmax = convertArgsToLists(min, max, freq, mul, add)
self._base_objs = [Randh_base(wrap(min,i), wrap(max,i), wrap(freq,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setMin(self, x):
"""
@@ -279,6 +281,7 @@ class Choice(PyoObject):
choicelen = len(choice)
lmax = max(choicelen, lmax)
self._base_objs = [Choice_base(wrap(choice,i), wrap(freq,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setChoice(self, x):
"""
@@ -362,6 +365,7 @@ class RandInt(PyoObject):
self._freq = freq
max, freq, mul, add, lmax = convertArgsToLists(max, freq, mul, add)
self._base_objs = [RandInt_base(wrap(max,i), wrap(freq,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setMax(self, x):
"""
@@ -448,6 +452,7 @@ class RandDur(PyoObject):
self._max = max
min, max, mul, add, lmax = convertArgsToLists(min, max, mul, add)
self._base_objs = [RandDur_base(wrap(min,i), wrap(max,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setMin(self, x):
"""
@@ -600,6 +605,7 @@ class Xnoise(PyoObject):
for i, t in enumerate(dist):
if type(t) in [bytes_t, unicode_t]: dist[i] = XNOISE_DICT.get(t, 0)
self._base_objs = [Xnoise_base(wrap(dist,i), wrap(freq,i), wrap(x1,i), wrap(x2,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setDist(self, x):
"""
@@ -813,6 +819,7 @@ class XnoiseMidi(PyoObject):
for i, t in enumerate(dist):
if type(t) in [bytes_t, unicode_t]: dist[i] = XNOISE_DICT.get(t, 0)
self._base_objs = [XnoiseMidi_base(wrap(dist,i), wrap(freq,i), wrap(x1,i), wrap(x2,i), wrap(scale,i), wrap(mrange,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setDist(self, x):
"""
@@ -1065,6 +1072,7 @@ class XnoiseDur(PyoObject):
for i, t in enumerate(dist):
if type(t) in [bytes_t, unicode_t]: dist[i] = XNOISE_DICT.get(t, 0)
self._base_objs = [XnoiseDur_base(wrap(dist,i), wrap(min,i), wrap(max,i), wrap(x1,i), wrap(x2,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setDist(self, x):
"""
@@ -1229,6 +1237,7 @@ class Urn(PyoObject):
max, freq, mul, add, lmax = convertArgsToLists(max, freq, mul, add)
self._base_objs = [Urn_base(wrap(max,i), wrap(freq,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
self._trig_objs = Dummy([TriggerDummy_base(obj) for obj in self._base_objs])
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self
@@ -1331,6 +1340,7 @@ class LogiMap(PyoObject):
self._freq = freq
chaos, freq, init, mul, add, lmax = convertArgsToLists(chaos, freq, init, mul, add)
self._base_objs = [LogiMap_base(wrap(chaos,i), wrap(freq,i), wrap(init,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self
diff --git a/pyolib/server.py b/pyolib/server.py
index cce7050..63ea0e5 100644
--- a/pyolib/server.py
+++ b/pyolib/server.py
@@ -460,6 +460,36 @@ class Server(object):
self._verbosity = x
self._server.setVerbosity(x)
+ def setGlobalDur(self, x):
+ """
+ Set the global object duration (time to wait before stopping the object).
+
+ This value, if not 0, will override the `dur` argument of object's
+ play() and out() methods.
+
+ :Args:
+
+ x: float
+ New global duration.
+
+ """
+ self._server.setGlobalDur(x)
+
+ def setGlobalDel(self, x):
+ """
+ Set the global object delay time (time to wait before activating the object).
+
+ This value, if not 0, will override the `del` argument of object's
+ play() and out() methods.
+
+ :Args:
+
+ x: float
+ New global delay time.
+
+ """
+ self._server.setGlobalDel(x)
+
def setJackAuto(self, xin=True, xout=True):
"""
Tells the server to auto-connect (or not) Jack ports to System ports.
@@ -964,6 +994,20 @@ class Server(object):
"""
return self._server.getBufferSize()
+ def getGlobalDur(self):
+ """
+ Return the current global duration.
+
+ """
+ return self._server.getGlobalDur()
+
+ def getGlobalDel(self):
+ """
+ Return the current global delay time.
+
+ """
+ return self._server.getGlobalDel()
+
def getGlobalSeed(self):
"""
Return the current global seed.
diff --git a/pyolib/tableprocess.py b/pyolib/tableprocess.py
index e7c78aa..a897006 100644
--- a/pyolib/tableprocess.py
+++ b/pyolib/tableprocess.py
@@ -70,6 +70,7 @@ class Osc(PyoObject):
self._interp = interp
table, freq, phase, interp, mul, add, lmax = convertArgsToLists(table, freq, phase, interp, mul, add)
self._base_objs = [Osc_base(wrap(table,i), wrap(freq,i), wrap(phase,i), wrap(interp,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setTable(self, x):
"""
@@ -213,6 +214,7 @@ class OscLoop(PyoObject):
self._feedback = feedback
table, freq, feedback, mul, add, lmax = convertArgsToLists(table, freq, feedback, mul, add)
self._base_objs = [OscLoop_base(wrap(table,i), wrap(freq,i), wrap(feedback,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setTable(self, x):
"""
@@ -333,6 +335,7 @@ class OscTrig(PyoObject):
self._interp = interp
table, trig, freq, phase, interp, mul, add, lmax = convertArgsToLists(table, trig, freq, phase, interp, mul, add)
self._base_objs = [OscTrig_base(wrap(table,i), wrap(trig,i), wrap(freq,i), wrap(phase,i), wrap(interp,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setTable(self, x):
"""
@@ -549,6 +552,7 @@ class OscBank(PyoObject):
self._num = num
table, freq, spread, slope, frndf, frnda, arndf, arnda, num, fjit, mul, add, lmax = convertArgsToLists(table, freq, spread, slope, frndf, frnda, arndf, arnda, num, fjit, mul, add)
self._base_objs = [OscBank_base(wrap(table,i), wrap(freq,i), wrap(spread,i), wrap(slope,i), wrap(frndf,i), wrap(frnda,i), wrap(arndf,i), wrap(arnda,i), wrap(num,i), wrap(fjit,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setTable(self, x):
"""
@@ -976,6 +980,7 @@ class Pulsar(PyoObject):
self._interp = interp
table, env, freq, frac, phase, interp, mul, add, lmax = convertArgsToLists(table, env, freq, frac, phase, interp, mul, add)
self._base_objs = [Pulsar_base(wrap(table,i), wrap(env,i), wrap(freq,i), wrap(frac,i), wrap(phase,i), wrap(interp,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setTable(self, x):
"""
@@ -1149,6 +1154,7 @@ class Pointer(PyoObject):
self._index = index
table, index, mul, add, lmax = convertArgsToLists(table, index, mul, add)
self._base_objs = [Pointer_base(wrap(table,i), wrap(index,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setTable(self, x):
"""
@@ -1240,6 +1246,7 @@ class Pointer2(PyoObject):
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)]
+ self.play()
def setTable(self, x):
"""
@@ -1372,6 +1379,7 @@ class TableIndex(PyoObject):
self._index = index
table, index, mul, add, lmax = convertArgsToLists(table, index, mul, add)
self._base_objs = [TableIndex_base(wrap(table,i), wrap(index,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setTable(self, x):
"""
@@ -1455,6 +1463,7 @@ class Lookup(PyoObject):
self._index = index
table, index, mul, add, lmax = convertArgsToLists(table, index, mul, add)
self._base_objs = [Lookup_base(wrap(table,i), wrap(index,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setTable(self, x):
"""
@@ -1666,6 +1675,11 @@ class TableWrite(PyoObject):
of the table). For any other value, the position must be
in samples between 0 and the length of the table. Available
at initialization time only.
+ maxwindow: int optional
+ Maximum length, in samples, of the interpolated window when
+ the position is moving fast. Useful to avoid interpolation
+ over the entire table if using a circular writing position.
+ Available at initialization time only. Defaults to 1024.
.. note::
@@ -1687,16 +1701,18 @@ class TableWrite(PyoObject):
>>> pat = Pattern(tab.refreshView, 0.05).play()
"""
- def __init__(self, input, pos, table, mode=0):
- pyoArgsAssert(self, "ooti", input, pos, table, mode)
+ def __init__(self, input, pos, table, mode=0, maxwindow=1024):
+ pyoArgsAssert(self, "ootii", input, pos, table, mode, maxwindow)
PyoObject.__init__(self)
self._input = input
self._pos = pos
self._table = table
self._mode = mode
+ self._maxwindow = maxwindow
self._in_fader = InputFader(input)
- in_fader, pos, table, mode, lmax = convertArgsToLists(self._in_fader, pos, table, mode)
- self._base_objs = [TableWrite_base(wrap(in_fader,i), wrap(pos,i), wrap(table,i), wrap(mode,i)) for i in range(len(table))]
+ in_fader, pos, table, mode, maxwindow, lmax = convertArgsToLists(self._in_fader, pos, table, mode, maxwindow)
+ self._base_objs = [TableWrite_base(wrap(in_fader,i), wrap(pos,i), wrap(table,i), wrap(mode,i), wrap(maxwindow,i)) for i in range(len(table))]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -1821,6 +1837,7 @@ class TableMorph(PyoObject):
in_fader, table, lmax = convertArgsToLists(self._in_fader, table)
self._base_sources = [source[0] for source in sources]
self._base_objs = [TableMorph_base(wrap(in_fader,i), wrap(table,i), self._base_sources) for i in range(len(table))]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -1953,6 +1970,7 @@ class Granulator(PyoObject):
pos, dur, grains, basedur, mul, add)
self._base_objs = [Granulator_base(wrap(table,i), wrap(env,i), wrap(pitch,i), wrap(pos,i), wrap(dur,i),
wrap(grains,i), wrap(basedur,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setTable(self, x):
"""
@@ -2178,6 +2196,7 @@ class TrigTableRec(PyoObject):
self._base_objs = [TrigTableRec_base(wrap(in_fader,i), wrap(in_fader2,i), wrap(table,i), wrap(fadetime,i)) for i in range(len(table))]
self._trig_objs = Dummy([TriggerDummy_base(obj) for obj in self._base_objs])
self._time_objs = [TrigTableRecTimeStream_base(obj) for obj in self._base_objs]
+ self.play()
def __getitem__(self, i):
if i == 'time':
@@ -2359,6 +2378,7 @@ class Looper(PyoObject):
wrap(xfadeshape,i), wrap(startfromloop,i), wrap(interp,i), wrap(autosmooth,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
self._trig_objs = Dummy([TriggerDummy_base(obj) for obj in self._base_objs])
self._time_objs = [LooperTimeStream_base(obj) for obj in self._base_objs]
+ self.play()
def __getitem__(self, i):
if i == 'time':
@@ -2764,6 +2784,129 @@ class TablePut(PyoObject):
@table.setter
def table(self, x): self.setTable(x)
+class TableFill(PyoObject):
+ """
+ Continuously fills a table with incoming samples.
+
+ See :py:class:`DataTable` or :py:class:`NewTable` to create an empty table.
+
+ TableFill takes an audio input and writes values into a PyoTableObject,
+ samples by samples. It wraps around the table length when reaching the end
+ of the table.
+
+ Calling the play method reset the writing position to 0.
+
+ :Parent: :py:class:`PyoObject`
+
+ :Args:
+
+ input: PyoObject
+ Audio signal to write in the table.
+ table: PyoTableObject
+ The table where to write values.
+
+ .. note::
+
+ The out() method is bypassed. TableFill returns no signal.
+
+ TableFill has no `mul` and `add` attributes.
+
+ .. seealso::
+
+ :py:class:`TableWrite`, :py:class:`TablePut`, :py:class:`TableRec`
+
+ >>> s = Server().boot()
+ >>> s.start()
+ >>> table = DataTable(s.getBufferSize(), chnls=2)
+ >>> sig = Sine([400,500], mul=0.3)
+ >>> fill = TableFill(sig, table)
+ >>> read = TableRead(table, table.getRate(), loop=True).out()
+
+ """
+ def __init__(self, input, table):
+ pyoArgsAssert(self, "ot", input, table)
+ PyoObject.__init__(self)
+ self._input = input
+ self._table = table
+ self._in_fader = InputFader(input)
+ in_fader, table, lmax = convertArgsToLists(self._in_fader, table)
+ self._base_objs = [TableFill_base(wrap(in_fader,i), wrap(table,i)) for i in range(len(table))]
+ self.play()
+
+ def out(self, chnl=0, inc=1, dur=0, delay=0):
+ return self.play(dur, delay)
+
+ def setMul(self, x):
+ pass
+
+ def setAdd(self, x):
+ pass
+
+ 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.
+
+ """
+ pyoArgsAssert(self, "oN", x, fadetime)
+ self._input = x
+ self._in_fader.setInput(x, fadetime)
+
+ def setTable(self, x):
+ """
+ Replace the `table` attribute.
+
+ :Args:
+
+ x: PyoTableObject
+ new `table` attribute.
+
+ """
+ pyoArgsAssert(self, "t", x)
+ self._table = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setTable(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
+ def getCurrentPos(self, all=False):
+ """
+ Returns the current pointer position, in samples, in the table.
+
+ :Args:
+
+ all: boolean, optional
+ If True, returns the current position of all
+ internal objects as a list.
+
+ If False, only the current position of the first object's
+ stream will be returned as a float.
+
+ """
+ pyoArgsAssert(self, "B", all)
+ if not all:
+ return self._base_objs[0].getCurrentPos()
+ else:
+ return [obj.getCurrentPos() for obj in self._base_objs]
+
+ @property
+ def input(self):
+ """PyoObject. Audio signal to write in the table."""
+ return self._input
+ @input.setter
+ def input(self, x): self.setInput(x)
+
+ @property
+ def table(self):
+ """PyoTableObject. The table where to write values."""
+ return self._table
+ @table.setter
+ def table(self, x): self.setTable(x)
+
class Granule(PyoObject):
"""
Another granular synthesis generator.
@@ -2786,11 +2929,11 @@ class Granule(PyoObject):
of `pitch` as its reading speed. Defaults to 1.
pos: float or PyoObject, optional
Pointer position, in samples, in the waveform table. Each
- grain sampled the current value of this stream at the beginning
- of its envelope and hold it until the end of the grain.
+ grain samples the current value of this stream at the beginning
+ of its envelope and holds it until the end of the grain.
Defaults to 0.
dur: float or PyoObject, optional
- Duration, in seconds, of the grain. Each grain sampled the
+ Duration, in seconds, of the grain. Each grain samples the
current value of this stream at the beginning of its envelope
and hold it until the end of the grain. Defaults to 0.1.
@@ -2818,6 +2961,7 @@ class Granule(PyoObject):
table, env, dens, pitch, pos, dur, mul, add, lmax = convertArgsToLists(table, env, dens, pitch, pos, dur, mul, add)
self._base_objs = [Granule_base(wrap(table,i), wrap(env,i), wrap(dens,i), wrap(pitch,i), wrap(pos,i), wrap(dur,i),
wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setTable(self, x):
"""
@@ -3011,6 +3155,7 @@ class TableScale(PyoObject):
self._outtable = outtable
table, outtable, mul, add, lmax = convertArgsToLists(table, outtable, mul, add)
self._base_objs = [TableScale_base(wrap(table,i), wrap(outtable,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setTable(self, x):
"""
@@ -3075,27 +3220,27 @@ class Particle(PyoObject):
dens: float or PyoObject, optional
Density of grains per second. Defaults to 50.
pitch: float or PyoObject, optional
- Pitch of the grains. Each grain sampled the current value
- of this stream at the beginning of its envelope and hold
+ Pitch of the grains. Each grain samples the current value
+ of this stream at the beginning of its envelope and holds
it until the end of the grain. Defaults to 1.
pos: float or PyoObject, optional
Pointer position, in samples, in the waveform table. Each
grain sampled the current value of this stream at the beginning
- of its envelope and hold it until the end of the grain.
+ of its envelope and holds it until the end of the grain.
Defaults to 0.
dur: float or PyoObject, optional
- Duration, in seconds, of the grain. Each grain sampled the
+ Duration, in seconds, of the grain. Each grain samples the
current value of this stream at the beginning of its envelope
- and hold it until the end of the grain. Defaults to 0.1.
+ and holds it until the end of the grain. Defaults to 0.1.
dev: float or PyoObject, optional
Maximum deviation of the starting time of the grain, between 0 and
- 1 (relative to the current duration of the grain). Each grain sampled
+ 1 (relative to the current duration of the grain). Each grain samples
the current value of this stream at the beginning of its envelope
- and hold it until the end of the grain. Defaults to 0.01.
+ and holds it until the end of the grain. Defaults to 0.01.
pan: float or PyoObject, optional
Panning factor of the grain (if chnls=1, this value is skipped).
- Each grain sampled the current value of this stream at the beginning
- of its envelope and hold it until the end of the grain. Defaults to 0.5.
+ Each grain samples the current value of this stream at the beginning
+ of its envelope and holds it until the end of the grain. Defaults to 0.5.
chnls: integer, optional
Number of output channels per audio stream (if chnls=2 and a stereo sound
table is given at the table argument, the objet will create 4 output
@@ -3138,6 +3283,7 @@ class Particle(PyoObject):
for i in range(lmax):
for j in range(chnls):
self._base_objs.append(Particle_base(wrap(self._base_players,i), j, wrap(mul,i), wrap(add,i)))
+ self.play()
def setTable(self, x):
"""
@@ -3263,7 +3409,7 @@ class Particle(PyoObject):
tablesize = self._table.getSize(False)
self._map_list = [SLMap(1, 250, 'lin', 'dens', self._dens),
SLMap(0.25, 2., 'lin', 'pitch', self._pitch),
- SLMap(0, tablesize, 'lin', 'pos', self._pos),
+ SLMap(0, tablesize, 'lin', 'pos', self._pos, res="int"),
SLMap(0.001, 1., 'lin', 'dur', self._dur),
SLMap(0., 1., 'lin', 'dev', self._dev),
SLMap(0., 1., 'lin', 'pan', self._pan),
@@ -3325,3 +3471,432 @@ class Particle(PyoObject):
return self._pan
@pan.setter
def pan(self, x): self.setPan(x)
+
+class Particle2(PyoObject):
+ """
+ An even more full control granular synthesis generator.
+
+ This granulator object offers all the same controls as the
+ Particle object with additionally an independently controllable
+ filter per grain. The filters use the same implementation as the
+ Biquad object.
+
+ :Parent: :py:class:`PyoObject`
+
+ :Args:
+
+ table: PyoTableObject
+ Table containing the waveform samples.
+ env: PyoTableObject
+ Table containing the grain envelope.
+ dens: float or PyoObject, optional
+ Density of grains per second. Defaults to 50.
+ pitch: float or PyoObject, optional
+ Pitch of the grains. Each grain samples the current value
+ of this stream at the beginning of its envelope and holds
+ it until the end of the grain. Defaults to 1.
+ pos: float or PyoObject, optional
+ Pointer position, in samples, in the waveform table. Each
+ grain samples the current value of this stream at the beginning
+ of its envelope and holds it until the end of the grain.
+ Defaults to 0.
+ dur: float or PyoObject, optional
+ Duration, in seconds, of the grain. Each grain samples the
+ current value of this stream at the beginning of its envelope
+ and holds it until the end of the grain. Defaults to 0.1.
+ dev: float or PyoObject, optional
+ Maximum deviation of the starting time of the grain, between 0 and
+ 1 (relative to the current duration of the grain). Each grain samples
+ the current value of this stream at the beginning of its envelope
+ and holds it until the end of the grain. Defaults to 0.01.
+ pan: float or PyoObject, optional
+ Panning factor of the grain (if chnls=1, this value is skipped).
+ Each grain samples the current value of this stream at the beginning
+ of its envelope and holds it until the end of the grain. Defaults to 0.5.
+ filterfreq: float or PyoObject, optional
+ Center or cutoff frequency of the grain filter.
+ Each grain samples the current value of this stream at the beginning
+ of its envelope and hold it until the end of the grain. Defaults to 18000.
+ filterq: float or PyoObject, optional
+ Q of the grain filter.
+ Each grain samples the current value of this stream at the beginning
+ of its envelope and hold it until the end of the grain. Defaults to 0.7.
+ filtertype: float or PyoObject, optional
+ Type of the grain filter.
+ Each grain samples the current value of this stream at the beginning
+ of its envelope and hold it until the end of the grain. Thw value is
+ rounded to the nearest integer. Possible values are:
+ 0. lowpass (default)
+ 1. highpass
+ 2. bandpass
+ 3. bandstop
+ 4. allpass
+
+ chnls: integer, optional
+ Number of output channels per audio stream (if chnls=2 and a stereo sound
+ table is given at the table argument, the objet will create 4 output
+ streams, 2 per table channel). Available at initialization only. Defaults to 1.
+
+ .. note::
+
+ Particle object compensate for the difference between sampling rate of the
+ loaded sound and the current sampling rate of the Server.
+
+ >>> s = Server().boot()
+ >>> s.start()
+ >>> snd = SndTable(SNDS_PATH+"/transparent.aif")
+ >>> end = snd.getSize() - s.getSamplingRate() * 0.25
+ >>> env = HannTable()
+ >>> dns = Randi(min=8, max=24, freq=.1)
+ >>> pit = Randh(min=0.49, max=0.51, freq=100)
+ >>> pos = Sine(0.05).range(0, end)
+ >>> dur = Randi(min=0.05, max=0.15, freq=0.15)
+ >>> dev = 0.001
+ >>> pan = Noise(0.5, 0.5)
+ >>> cf = Sine(0.07).range(75, 125)
+ >>> fcf = Choice(list(range(1, 40)), freq=150, mul=cf)
+ >>> grn = Particle2(snd, env, dns, pit, pos, dur, dev, pan, fcf, 20, 2, chnls=2, mul=.3)
+ >>> grn.out()
+
+ """
+ def __init__(self, table, env, dens=50, pitch=1, pos=0, dur=.1, dev=0.01, pan=0.5, filterfreq=18000, filterq=0.7, filtertype=0, chnls=1, mul=1, add=0):
+ pyoArgsAssert(self, "ttOOOOOOOOOIOO", table, env, dens, pitch, pos, dur, dev, pan, filterfreq, filterq, filtertype, chnls, mul, add)
+ PyoObject.__init__(self, mul, add)
+ self._table = table
+ self._env = env
+ self._dens = dens
+ self._pitch = pitch
+ self._pos = pos
+ self._dur = dur
+ self._dev = dev
+ self._pan = pan
+ self._filterfreq = filterfreq
+ self._filterq = filterq
+ self._filtertype = filtertype
+ self._chnls = chnls
+ table, env, dens, pitch, pos, dur, dev, pan, filterfreq, filterq, filtertype, mul, add, lmax = convertArgsToLists(table, env, dens, pitch, pos, dur, dev, pan, filterfreq, filterq, filtertype, mul, add)
+ self._base_players = [MainParticle2_base(wrap(table,i), wrap(env,i), wrap(dens,i), wrap(pitch,i), wrap(pos,i), wrap(dur,i), wrap(dev,i), wrap(pan,i), wrap(filterfreq,i), wrap(filterq,i), wrap(filtertype,i), chnls) for i in range(lmax)]
+ self._base_objs = []
+ for i in range(lmax):
+ for j in range(chnls):
+ self._base_objs.append(Particle2_base(wrap(self._base_players,i), j, wrap(mul,i), wrap(add,i)))
+ self.play()
+
+ def setTable(self, x):
+ """
+ Replace the `table` attribute.
+
+ :Args:
+
+ x: PyoTableObject
+ new `table` attribute.
+
+ """
+ pyoArgsAssert(self, "t", x)
+ self._table = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setTable(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+ def setEnv(self, x):
+ """
+ Replace the `env` attribute.
+
+ :Args:
+
+ x: PyoTableObject
+ new `env` attribute.
+
+ """
+ pyoArgsAssert(self, "t", x)
+ self._env = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setEnv(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+ def setDens(self, x):
+ """
+ Replace the `dens` attribute.
+
+ :Args:
+
+ x: float or PyoObject
+ new `dens` attribute.
+
+ """
+ pyoArgsAssert(self, "O", x)
+ self._dens = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setDens(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+ def setPitch(self, x):
+ """
+ Replace the `pitch` attribute.
+
+ :Args:
+
+ x: float or PyoObject
+ new `pitch` attribute.
+
+ """
+ pyoArgsAssert(self, "O", x)
+ self._pitch = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setPitch(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+ def setPos(self, x):
+ """
+ Replace the `pos` attribute.
+
+ :Args:
+
+ x: float or PyoObject
+ new `pos` attribute.
+
+ """
+ pyoArgsAssert(self, "O", x)
+ self._pos = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setPos(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+ def setDur(self, x):
+ """
+ Replace the `dur` attribute.
+
+ :Args:
+
+ x: float or PyoObject
+ new `dur` attribute.
+
+ """
+ pyoArgsAssert(self, "O", x)
+ self._dur = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setDur(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+ def setDev(self, x):
+ """
+ Replace the `dev` attribute.
+
+ :Args:
+
+ x: float or PyoObject
+ new `dev` attribute.
+
+ """
+ pyoArgsAssert(self, "O", x)
+ self._dev = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setDev(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+ def setPan(self, x):
+ """
+ Replace the `pan` attribute.
+
+ :Args:
+
+ x: float or PyoObject
+ new `pan` attribute.
+
+ """
+ pyoArgsAssert(self, "O", x)
+ self._pan = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setPan(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+ def setFilterfreq(self, x):
+ """
+ Replace the `filterfreq` attribute.
+
+ :Args:
+
+ x: float or PyoObject
+ new `filterfreq` attribute.
+
+ """
+ pyoArgsAssert(self, "O", x)
+ self._filterfreq = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setFilterfreq(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+ def setFilterq(self, x):
+ """
+ Replace the `filterq` attribute.
+
+ :Args:
+
+ x: float or PyoObject
+ new `filterq` attribute.
+
+ """
+ pyoArgsAssert(self, "O", x)
+ self._filterq = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setFilterq(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+ def setFiltertype(self, x):
+ """
+ Replace the `filtertype` attribute.
+
+ :Args:
+
+ x: float or PyoObject
+ new `filtertype` attribute.
+
+ """
+ pyoArgsAssert(self, "O", x)
+ self._filtertype = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setFiltertype(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+
+ def ctrl(self, map_list=None, title=None, wxnoserver=False):
+ tablesize = self._table.getSize(False)
+ self._map_list = [SLMap(1, 250, 'lin', 'dens', self._dens),
+ SLMap(0.25, 2., 'lin', 'pitch', self._pitch),
+ SLMap(0, tablesize, 'lin', 'pos', self._pos, res="int"),
+ SLMap(0.001, 1., 'lin', 'dur', self._dur),
+ SLMap(0., 1., 'lin', 'dev', self._dev),
+ SLMap(0., 1., 'lin', 'pan', self._pan),
+ SLMap(50., 18000., 'log', 'filterfreq', self._filterfreq),
+ SLMap(0.25, 100., 'log', 'filterq', self._filterq),
+ SLMap(0, 4., 'lin', 'filtertype', self._filtertype, res="int"),
+ 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 env(self):
+ """PyoTableObject. Table containing the grain envelope."""
+ return self._env
+ @env.setter
+ def env(self, x): self.setEnv(x)
+
+ @property
+ def dens(self):
+ """float or PyoObject. Density of grains per second."""
+ return self._dens
+ @dens.setter
+ def dens(self, x): self.setDens(x)
+
+ @property
+ def pitch(self):
+ """float or PyoObject. Transposition factor of the grain."""
+ return self._pitch
+ @pitch.setter
+ def pitch(self, x): self.setPitch(x)
+
+ @property
+ def pos(self):
+ """float or PyoObject. Position of the pointer in the sound table."""
+ return self._pos
+ @pos.setter
+ def pos(self, x): self.setPos(x)
+
+ @property
+ def dur(self):
+ """float or PyoObject. Duration, in seconds, of the grain."""
+ return self._dur
+ @dur.setter
+ def dur(self, x): self.setDur(x)
+
+ @property
+ def dev(self):
+ """float or PyoObject. Deviation of the starting point of the grain in the table."""
+ return self._dev
+ @dev.setter
+ def dev(self, x): self.setDev(x)
+
+ @property
+ def pan(self):
+ """float or PyoObject.Panning of the grain."""
+ return self._pan
+ @pan.setter
+ def pan(self, x): self.setPan(x)
+
+ @property
+ def filterfreq(self):
+ """float or PyoObject.Grain's filter center/cutoff frequency."""
+ return self._filterfreq
+ @filterfreq.setter
+ def filterfreq(self, x): self.setFilterfreq(x)
+
+ @property
+ def filterq(self):
+ """float or PyoObject.Grain's filter Q."""
+ return self._filterq
+ @filterq.setter
+ def filterq(self, x): self.setFilterq(x)
+
+ @property
+ def filtertype(self):
+ """float or PyoObject.Grain's filter type."""
+ return self._filtertype
+ @filtertype.setter
+ def filtertype(self, x): self.setFiltertype(x)
+
+class TableScan(PyoObject):
+ """
+ Reads the content of a table in loop, without interpolation.
+
+ A simple table reader, sample by sample, with wrap-around when
+ reaching the end of the table.
+
+ :Parent: :py:class:`PyoObject`
+
+ :Args:
+
+ table: PyoTableObject
+ Table containing the waveform samples.
+
+ .. seealso::
+
+ :py:class:`Osc`, :py:class:`TableRead`
+
+ >>> s = Server().boot()
+ >>> s.start()
+ >>> tab = DataTable(s.getBufferSize(), 2)
+ >>> sig = Sine([500, 600], mul=0.3)
+ >>> fill = TableFill(sig, tab)
+ >>> scan = TableScan(tab).out()
+
+ """
+ def __init__(self, table, mul=1, add=0):
+ pyoArgsAssert(self, "tOO", table, mul, add)
+ PyoObject.__init__(self, mul, add)
+ self._table = table
+ table, mul, add, lmax = convertArgsToLists(table, mul, add)
+ self._base_objs = [TableScan_base(wrap(table,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
+
+ def setTable(self, x):
+ """
+ Replace the `table` attribute.
+
+ :Args:
+
+ x: PyoTableObject
+ new `table` attribute.
+
+ """
+ pyoArgsAssert(self, "t", x)
+ self._table = x
+ x, lmax = convertArgsToLists(x)
+ [obj.setTable(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
+ def reset(self):
+ """
+ Resets current phase to 0.
+
+ """
+ [obj.reset() for i, obj in enumerate(self._base_objs)]
+
+ @property
+ def table(self):
+ """PyoTableObject. Table containing the waveform samples."""
+ return self._table
+ @table.setter
+ def table(self, x): self.setTable(x)
diff --git a/pyolib/tables.py b/pyolib/tables.py
index 190786a..6e223f6 100644
--- a/pyolib/tables.py
+++ b/pyolib/tables.py
@@ -2338,7 +2338,7 @@ class PadSynthTable(PyoTableObject):
http://zynaddsubfx.sourceforge.net/doc/PADsynth/PADsynth.htm
- This algorithm generates some large wavetables that can played at
+ This algorithm generates some large wavetables that can be played at
different speeds to get the desired sound. This algorithm describes
only how these wavetables are generated. The result is a perfectly
looped wavetable.
@@ -2352,7 +2352,7 @@ class PadSynthTable(PyoTableObject):
:Args:
basefreq: float, optional
- The base frequencyof the algorithm in Hz. If the spreading factor
+ The base frequency of the algorithm in Hz. If the spreading factor
is near 1.0, this frequency is the fundamental of the spectrum.
Defaults to 440.
spread: float, optional
@@ -2571,3 +2571,73 @@ class PadSynthTable(PyoTableObject):
return self._damp
@damp.setter
def damp(self, x): self.setDamp(x)
+
+class SharedTable(PyoTableObject):
+ """
+ Create an inter-process shared memory table.
+
+ This table uses the given name to open an internal shared memory
+ object, used as the data memory of the table. Two or more tables
+ from different processes, if they use the same name, can read and
+ write to the same memory space.
+
+ .. note::
+
+ SharedTable is not implemented yet for Windows (unix only).
+
+ :Parent: :py:class:`PyoTableObject`
+
+ :Args:
+
+ name: string
+ Unique name in the system shared memory. Two or more tables created
+ with the same name will shared the same memory space. The name
+ must conform to the construction rules for a unix pathname (ie.
+ it must begin with a slash). Available at initialization time only.
+ create: loolean
+ If True, an entry will be create in the system shared memory.
+ If False, the object will use an already created shared memory.
+ Can't be a list. Available at initialization time only.
+ size: int
+ Size of the table in samples. Can't be a list.
+ Available at initialization time only.
+
+ >>> s = Server().boot()
+ >>> s.start()
+ >>> # Creating parent table.
+ >>> table = SharedTable(["/sharedl", "/sharedr"], True, s.getBufferSize())
+ >>> # Creating child table.
+ >>> shared = SharedTable(["/sharedl", "/sharedr"], False, s.getBufferSize())
+ >>> # Read and output the content of the parent table.
+ >>> tabread = TableRead(table, table.getRate(), True).out()
+ >>> # Record some signal signal in the child table.
+ >>> lfo = Sine(freq=[0.2, 0.25]).range(98, 102)
+ >>> wave = LFO(freq=lfo, type=4, sharp=0.7, mul=0.3)
+ >>> pos = Phasor(shared.getRate())
+ >>> record = TableWrite(wave, pos, shared)
+
+ """
+ def __init__(self, name, create, size):
+ if sys.platform == "win32":
+ raise Exception("SharedTable is not implemented yet for Windows.")
+ pyoArgsAssert(self, "sBI", name, create, size)
+ PyoTableObject.__init__(self, size)
+ self._name = name
+ self._create = create
+ name, lmax = convertArgsToLists(name)
+ self._base_objs = [SharedTable_base(wrap(name,i), create, size) for i in range(lmax)]
+
+ def getRate(self):
+ """
+ Returns the frequency (cycle per second) to give to an
+ oscillator to read the sound at its original pitch.
+
+ """
+ return self._base_objs[0].getRate()
+
+ @property
+ def size(self):
+ """int. Length of the table in samples."""
+ return self._size
+ @size.setter
+ def size(self, x): print("SharedTable 'size' attribute is read-only.")
diff --git a/pyolib/triggers.py b/pyolib/triggers.py
index b366178..438252b 100644
--- a/pyolib/triggers.py
+++ b/pyolib/triggers.py
@@ -61,6 +61,7 @@ class Trig(PyoObject):
def __init__(self):
PyoObject.__init__(self)
self._base_objs = [Trig_base()]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -177,13 +178,16 @@ class Seq(PyoObject):
time: float or PyoObject, optional
Base time between each trigger in seconds. Defaults to 1.
- seq: list of ints, optional
+ seq: list of floats, optional
Sequence of beat durations in time's unit. Defaults to [1].
poly: int, optional
Seq polyphony. Denotes how many independent streams are
generated by the metronome, allowing overlapping processes.
Available only at initialization. Defaults to 1.
+ onlyonce: boolean, optional
+ If True, the sequence will play only once and automatically stop.
+ Defaults to False.
.. note::
@@ -200,19 +204,20 @@ class Seq(PyoObject):
>>> a = SineLoop(tr, feedback=0.07, mul=amp).out()
"""
- def __init__(self, time=1, seq=[1], poly=1):
- pyoArgsAssert(self, "OlI", time, seq, poly)
+ def __init__(self, time=1, seq=[1], poly=1, onlyonce=False):
+ pyoArgsAssert(self, "OlIB", time, seq, poly)
PyoObject.__init__(self)
self._time = time
self._seq = seq
self._poly = poly
+ self._onlyonce = onlyonce
time, lmax = convertArgsToLists(time)
if type(seq[0]) != list:
- self._base_players = [Seqer_base(wrap(time,i), seq, poly) for i in range(lmax)]
+ self._base_players = [Seqer_base(wrap(time,i), seq, poly, onlyonce) for i in range(lmax)]
else:
seqlen = len(seq)
lmax = max(seqlen, lmax)
- self._base_players = [Seqer_base(wrap(time,i), wrap(seq,i), poly) for i in range(lmax)]
+ self._base_players = [Seqer_base(wrap(time,i), wrap(seq,i), poly, onlyonce) for i in range(lmax)]
self._base_objs = [Seq_base(wrap(self._base_players,j), i) for i in range(poly) for j in range(lmax)]
def setTime(self, x):
@@ -236,7 +241,7 @@ class Seq(PyoObject):
:Args:
- x: list of ints
+ x: list of floats
New `seq` attribute.
"""
@@ -247,6 +252,20 @@ class Seq(PyoObject):
else:
[obj.setSeq(wrap(x,i)) for i, obj in enumerate(self._base_players)]
+ def setOnlyonce(self, x):
+ """
+ Replace the `onlyonce` attribute.
+
+ :Args:
+
+ x: boolean
+ New `onlyonce` attribute.
+
+ """
+ pyoArgsAssert(self, "B", x)
+ self._onlyonce = x
+ [obj.setOnlyonce(x) for obj in self._base_players]
+
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -275,11 +294,18 @@ class Seq(PyoObject):
@property
def seq(self):
- """List of ints. Sequence of beat durations in time's unit."""
+ """List of floats. Sequence of beat durations in time's unit."""
return self._seq
@seq.setter
def seq(self, x): self.setSeq(x)
+ @property
+ def onlyonce(self):
+ """boolean. Trigger the sequence only once."""
+ return self._onlyonce
+ @onlyonce.setter
+ def onlyonce(self, x): self.setOnlyonce(x)
+
class Cloud(PyoObject):
"""
Generates random triggers.
@@ -408,6 +434,9 @@ class Beat(PyoObject):
generated by the object, allowing overlapping processes.
Available only at initialization. Defaults to 1.
+ onlyonce: boolean, optional
+ If True, the sequence will play only once and automatically stop.
+ Defaults to False.
.. note::
@@ -434,8 +463,8 @@ class Beat(PyoObject):
>>> a = Sine(freq=trhz, mul=tr2*0.3).out()
"""
- def __init__(self, time=.125, taps=16, w1=80, w2=50, w3=30, poly=1):
- pyoArgsAssert(self, "OinnnI", time, taps, w1, w2, w3, poly)
+ def __init__(self, time=.125, taps=16, w1=80, w2=50, w3=30, poly=1, onlyonce=False):
+ pyoArgsAssert(self, "OinnnIB", time, taps, w1, w2, w3, poly, onlyonce)
PyoObject.__init__(self)
self._tap_dummy = []
self._amp_dummy = []
@@ -447,8 +476,9 @@ class Beat(PyoObject):
self._w2 = w2
self._w3 = w3
self._poly = poly
+ self._onlyonce = onlyonce
time, taps, w1, w2, w3, lmax = convertArgsToLists(time, taps, w1, w2, w3)
- self._base_players = [Beater_base(wrap(time,i), wrap(taps,i), wrap(w1,i), wrap(w2,i), wrap(w3,i), poly) for i in range(lmax)]
+ self._base_players = [Beater_base(wrap(time,i), wrap(taps,i), wrap(w1,i), wrap(w2,i), wrap(w3,i), poly, onlyonce) for i in range(lmax)]
self._base_objs = [Beat_base(wrap(self._base_players,j), i) for i in range(poly) for j in range(lmax)]
self._tap_objs = [BeatTapStream_base(wrap(self._base_players,j), i) for i in range(poly) for j in range(lmax)]
self._amp_objs = [BeatAmpStream_base(wrap(self._base_players,j), i) for i in range(poly) for j in range(lmax)]
@@ -509,12 +539,19 @@ class Beat(PyoObject):
"""
[obj.reset() for obj in self._base_players]
- def new(self):
+ def new(self, now=False):
"""
Generates a new pattern with the current parameters.
+ :Args:
+
+ now: boolean
+ If True, the new sequence is immediately generated,
+ otherwise (the default), the new sequence is generated
+ after the current sequence is completed.
+
"""
- [obj.new() for i, obj in enumerate(self._base_players)]
+ [obj.new(now) for i, obj in enumerate(self._base_players)]
def fill(self):
"""
@@ -666,6 +703,20 @@ class Beat(PyoObject):
w1, w2, w3, lmax = convertArgsToLists(w1, w2, w3)
[obj.setWeights(wrap(w1,i), wrap(w2,i), wrap(w3,i)) for i, obj in enumerate(self._base_players)]
+ def setOnlyonce(self, x):
+ """
+ Replace the `onlyonce` attribute.
+
+ :Args:
+
+ x: boolean
+ New `onlyonce` attribute.
+
+ """
+ pyoArgsAssert(self, "B", x)
+ self._onlyonce = x
+ [obj.setOnlyonce(x) for obj in self._base_players]
+
def play(self, dur=0, delay=0):
dur, delay, lmax = convertArgsToLists(dur, delay)
self._tap_objs = [obj.play(wrap(dur,i), wrap(delay,i)) for i, obj in enumerate(self._tap_objs)]
@@ -739,6 +790,13 @@ class Beat(PyoObject):
@w3.setter
def w3(self, x): self.setW3(x)
+ @property
+ def onlyonce(self):
+ """boolean. Trigger the sequence only once."""
+ return self._onlyonce
+ @onlyonce.setter
+ def onlyonce(self, x): self.setOnlyonce(x)
+
class TrigRandInt(PyoObject):
"""
Pseudo-random integer generator.
@@ -778,6 +836,7 @@ class TrigRandInt(PyoObject):
self._in_fader = InputFader(input)
in_fader, max, mul, add, lmax = convertArgsToLists(self._in_fader, max, mul, add)
self._base_objs = [TrigRandInt_base(wrap(in_fader,i), wrap(max,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -876,6 +935,7 @@ class TrigRand(PyoObject):
self._in_fader = InputFader(input)
in_fader, min, max, port, init, mul, add, lmax = convertArgsToLists(self._in_fader, min, max, port, init, mul, add)
self._base_objs = [TrigRand_base(wrap(in_fader,i), wrap(min,i), wrap(max,i), wrap(port,i), wrap(init,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1018,6 +1078,7 @@ class TrigChoice(PyoObject):
choicelen = len(choice)
lmax = max(choicelen, lmax)
self._base_objs = [TrigChoice_base(wrap(in_fader,i), wrap(choice,i), wrap(port,i), wrap(init,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1140,6 +1201,7 @@ class TrigFunc(PyoObject):
self._in_fader = InputFader(input)
in_fader, function, arg, lmax = convertArgsToLists(self._in_fader, function, arg)
self._base_objs = [TrigFunc_base(wrap(in_fader,i), WeakMethod(wrap(function,i)), wrap(arg,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -1267,6 +1329,7 @@ class TrigEnv(PyoObject):
in_fader, table, dur, interp, mul, add, lmax = convertArgsToLists(self._in_fader, table, dur, interp, mul, add)
self._base_objs = [TrigEnv_base(wrap(in_fader,i), wrap(table,i), wrap(dur,i), wrap(interp,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
self._trig_objs = Dummy([TriggerDummy_base(obj) for obj in self._base_objs])
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1406,6 +1469,7 @@ class TrigLinseg(PyoObject):
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [TrigLinseg_base(wrap(in_fader,i), list, wrap(mul,i), wrap(add,i)) for i in range(lmax)]
self._trig_objs = Dummy([TriggerDummy_base(obj) for obj in self._base_objs])
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -1570,6 +1634,7 @@ class TrigExpseg(PyoObject):
in_fader, exp, inverse, mul, add, lmax = convertArgsToLists(self._in_fader, exp, inverse, mul, add)
self._base_objs = [TrigExpseg_base(wrap(in_fader,i), list, wrap(exp,i), wrap(inverse,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
self._trig_objs = Dummy([TriggerDummy_base(obj) for obj in self._base_objs])
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -1830,6 +1895,7 @@ class TrigXnoise(PyoObject):
for i, t in enumerate(dist):
if type(t) in [bytes_t, unicode_t]: dist[i] = XNOISE_DICT.get(t, 0)
self._base_objs = [TrigXnoise_base(wrap(in_fader,i), wrap(dist,i), wrap(x1,i), wrap(x2,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -2046,6 +2112,7 @@ class TrigXnoiseMidi(PyoObject):
for i, t in enumerate(dist):
if type(t) in [bytes_t, unicode_t]: dist[i] = XNOISE_DICT.get(t, 0)
self._base_objs = [TrigXnoiseMidi_base(wrap(in_fader,i), wrap(dist,i), wrap(x1,i), wrap(x2,i), wrap(scale,i), wrap(mrange,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -2241,6 +2308,7 @@ class Counter(PyoObject):
self._in_fader = InputFader(input)
in_fader, min, max, dir, mul, add, lmax = convertArgsToLists(self._in_fader, min, max, dir, mul, add)
self._base_objs = [Counter_base(wrap(in_fader,i), wrap(min,i), wrap(max,i), wrap(dir,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -2404,6 +2472,7 @@ class Select(PyoObject):
self._in_fader = InputFader(input)
in_fader, value, mul, add, lmax = convertArgsToLists(self._in_fader, value, mul, add)
self._base_objs = [Select_base(wrap(in_fader,i), wrap(value,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -2490,6 +2559,7 @@ class Change(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [Change_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -2570,6 +2640,7 @@ class Thresh(PyoObject):
self._in_fader = InputFader(input)
in_fader, threshold, dir, mul, add, lmax = convertArgsToLists(self._in_fader, threshold, dir, mul, add)
self._base_objs = [Thresh_base(wrap(in_fader,i), wrap(threshold,i), wrap(dir,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -2683,6 +2754,7 @@ class Percent(PyoObject):
self._in_fader = InputFader(input)
in_fader, percent, mul, add, lmax = convertArgsToLists(self._in_fader, percent, mul, add)
self._base_objs = [Percent_base(wrap(in_fader,i), wrap(percent,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -2780,6 +2852,7 @@ class Timer(PyoObject):
self._in_fader2 = InputFader(input2)
in_fader, in_fader2, mul, add, lmax = convertArgsToLists(self._in_fader, self._in_fader2, mul, add)
self._base_objs = [Timer_base(wrap(in_fader,i), wrap(in_fader2,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -2882,6 +2955,7 @@ class Iter(PyoObject):
lmax = max(choicelen, lmax)
self._base_objs = [Iter_base(wrap(in_fader,i), wrap(x,i), wrap(init,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
self._trig_objs = Dummy([TriggerDummy_base(obj) for obj in self._base_objs])
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -3012,6 +3086,7 @@ class Count(PyoObject):
self._in_fader = InputFader(input)
in_fader, min, max, mul, add, lmax = convertArgsToLists(self._in_fader, min, max, mul, add)
self._base_objs = [Count_base(wrap(in_fader,i), wrap(min,i), wrap(max,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -3127,6 +3202,7 @@ class NextTrig(PyoObject):
self._in_fader2 = InputFader(input2)
in_fader, in_fader2, mul, add, lmax = convertArgsToLists(self._in_fader, self._in_fader2, mul, add)
self._base_objs = [NextTrig_base(wrap(in_fader,i), wrap(in_fader2,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -3216,6 +3292,7 @@ class TrigVal(PyoObject):
self._in_fader = InputFader(input)
in_fader, value, init, mul, add, lmax = convertArgsToLists(self._in_fader, value, init, mul, add)
self._base_objs = [TrigVal_base(wrap(in_fader,i), wrap(value,i), wrap(init,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -3610,6 +3687,7 @@ class TrigBurst(PyoObject):
self._amp_objs = [TrigBurstAmpStream_base(wrap(self._base_players,j), i) for i in range(poly) for j in range(lmax)]
self._dur_objs = [TrigBurstDurStream_base(wrap(self._base_players,j), i) for i in range(poly) for j in range(lmax)]
self._end_objs = [TrigBurstEndStream_base(wrap(self._base_players,j), i) for i in range(poly) for j in range(lmax)]
+ self.play()
def __getitem__(self, i):
if i == 'tap':
diff --git a/pyolib/utils.py b/pyolib/utils.py
index 0e8b27d..c1abb5f 100644
--- a/pyolib/utils.py
+++ b/pyolib/utils.py
@@ -108,6 +108,7 @@ class Print(PyoObject):
self._in_fader = InputFader(input)
in_fader, method, interval, message, lmax = convertArgsToLists(self._in_fader, method, interval, message)
self._base_objs = [Print_base(wrap(in_fader,i), wrap(method,i), wrap(interval,i), wrap(message,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -255,6 +256,7 @@ class Snap(PyoObject):
choicelen = len(choice)
lmax = max(choicelen, lmax)
self._base_objs = [Snap_base(wrap(in_fader,i), wrap(choice,i), wrap(scale,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -362,6 +364,7 @@ class Interp(PyoObject):
self._in_fader2 = InputFader(input2)
in_fader, in_fader2, interp, mul, add, lmax = convertArgsToLists(self._in_fader, self._in_fader2, interp, mul, add)
self._base_objs = [Interp_base(wrap(in_fader,i), wrap(in_fader2,i), wrap(interp,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -472,6 +475,7 @@ class SampHold(PyoObject):
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 = [SampHold_base(wrap(in_fader,i), wrap(in_fader2,i), wrap(value,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -634,6 +638,7 @@ class Record(PyoObject):
else:
print('Warning: Filename has no extension. Using fileformat value.')
self._base_objs = [Record_base(self._in_fader.getBaseObjects(), filename, chnls, fileformat, sampletype, buffering, quality)]
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -691,6 +696,7 @@ class Denorm(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [Denorm_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -880,6 +886,7 @@ class ControlRead(PyoObject):
f.close()
self._base_objs.append(ControlRead_base(values, rate, loop, interp, wrap(mul,i), wrap(add,i)))
self._trig_objs = Dummy([TriggerDummy_base(obj) for obj in self._base_objs])
+ self.play()
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -1098,6 +1105,7 @@ class NoteinRead(PyoObject):
self._base_objs.append(NoteinRead_base(amps, timestamps, loop, wrap(mul,i), wrap(add,i)))
_trig_objs_tmp.append(TriggerDummy_base(self._base_objs[-1]))
self._trig_objs = Dummy(_trig_objs_tmp)
+ self.play()
def __getitem__(self, str):
if str == 'trig':
@@ -1192,6 +1200,7 @@ class DBToA(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [DBToA_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1248,6 +1257,7 @@ class AToDB(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [AToDB_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1320,6 +1330,7 @@ class Scale(PyoObject):
self._in_fader = InputFader(input)
in_fader, inmin, inmax, outmin, outmax, exp, mul, add, lmax = convertArgsToLists(self._in_fader, inmin, inmax, outmin, outmax, exp, mul, add)
self._base_objs = [Scale_base(wrap(in_fader,i), wrap(inmin,i), wrap(inmax,i), wrap(outmin,i), wrap(outmax,i), wrap(exp,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1492,6 +1503,7 @@ class CentsToTranspo(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [CentsToTranspo_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1546,6 +1558,7 @@ class TranspoToCents(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [TranspoToCents_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1600,6 +1613,7 @@ class MToF(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [MToF_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1657,6 +1671,7 @@ class FToM(PyoObject):
self._in_fader = InputFader(input)
in_fader, mul, add, lmax = convertArgsToLists(self._in_fader, mul, add)
self._base_objs = [FToM_base(wrap(in_fader,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1718,6 +1733,7 @@ class MToT(PyoObject):
self._in_fader = InputFader(input)
in_fader, centralkey, mul, add, lmax = convertArgsToLists(self._in_fader, centralkey, mul, add)
self._base_objs = [MToT_base(wrap(in_fader,i), wrap(centralkey,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1798,6 +1814,7 @@ class Between(PyoObject):
self._in_fader = InputFader(input)
in_fader, min, max, mul, add, lmax = convertArgsToLists(self._in_fader, min, max, mul, add)
self._base_objs = [Between_base(wrap(in_fader,i), wrap(min,i), wrap(max,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -1909,6 +1926,7 @@ class TrackHold(PyoObject):
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)]
+ self.play()
def setInput(self, x, fadetime=0.05):
"""
@@ -2037,3 +2055,4 @@ class Resample(PyoObject):
self._mode = mode
_input, mode, mul, add, lmax = convertArgsToLists(input, mode, mul, add)
self._base_objs = [Resample_base(wrap(_input,i), wrap(mode,i), wrap(mul,i), wrap(add,i)) for i in range(lmax)]
+ self.play()
diff --git a/scripts/release_doc_src.sh b/scripts/release_doc_src.sh
index 103c3bd..f908f09 100755
--- 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.8.1
+version=0.8.3
replace=XXX
doc_rep=pyo_XXX-doc
diff --git a/setup.py b/setup.py
index 664cb53..8bf6a36 100644
--- a/setup.py
+++ b/setup.py
@@ -22,7 +22,7 @@ from distutils.sysconfig import get_python_lib
from distutils.core import setup, Extension
import os, sys, py_compile
-pyo_version = "0.8.1"
+pyo_version = "0.8.3"
build_with_jack_support = False
compile_externals = False
diff --git a/src/engine/ad_jack.c b/src/engine/ad_jack.c
index 1e8996e..69e7734 100644
--- a/src/engine/ad_jack.c
+++ b/src/engine/ad_jack.c
@@ -25,12 +25,11 @@ int
jack_callback(jack_nframes_t nframes, void *arg) {
int i, j;
Server *server = (Server *) arg;
+
assert(nframes == server->bufferSize);
+
jack_default_audio_sample_t *in_buffers[server->ichnls], *out_buffers[server->nchnls];
- if (server->withPortMidi == 1) {
- pyoGetMidiEvents(server);
- }
PyoJackBackendData *be_data = (PyoJackBackendData *) server->audio_be_data;
for (i = 0; i < server->ichnls; i++) {
in_buffers[i] = jack_port_get_buffer(be_data->jack_in_ports[i+server->input_offset], server->bufferSize);
@@ -39,6 +38,21 @@ jack_callback(jack_nframes_t nframes, void *arg) {
out_buffers[i] = jack_port_get_buffer(be_data->jack_out_ports[i+server->output_offset], server->bufferSize);
}
+
+ /* Outputs zeros while the audio server is not started. */
+ if (!server->server_started) {
+ for (i=0; i<server->bufferSize; i++) {
+ for (j=0; j<server->nchnls; j++) {
+ out_buffers[j][i] = 0.0;
+ }
+ }
+ return 0;
+ }
+
+ if (server->withPortMidi == 1) {
+ pyoGetMidiEvents(server);
+ }
+
/* jack audio data is not interleaved */
if (server->duplex == 1) {
for (i=0; i<server->bufferSize; i++) {
@@ -81,7 +95,7 @@ jack_error_cb(const char *desc) {
void
jack_shutdown_cb(void *arg) {
Server *s = (Server *) arg;
- Server_shut_down(s);
+ Server_shutdown(s);
Server_warning(s, "JACK server shutdown. Pyo Server shut down.\n");
}
@@ -260,13 +274,27 @@ Server_jack_init(Server *self) {
jack_set_sample_rate_callback(be_data->jack_client, jack_srate_cb, (void *) self);
jack_on_shutdown(be_data->jack_client, jack_shutdown_cb, (void *) self);
jack_set_buffer_size_callback(be_data->jack_client, jack_bufsize_cb, (void *) self);
+ jack_set_process_callback(be_data->jack_client, jack_callback, (void *) self);
+
+ if (jack_activate(be_data->jack_client)) {
+ Server_error(self, "Jack error: cannot activate jack client.\n");
+ //Server_shutdown(self);
+ return -1;
+ }
+
+ Server_jack_autoconnect(self);
+
return 0;
}
int
Server_jack_deinit(Server *self) {
+ int ret;
PyoJackBackendData *be_data = (PyoJackBackendData *) self->audio_be_data;
- int ret = jack_client_close(be_data->jack_client);
+ ret = jack_deactivate(be_data->jack_client);
+ if (ret)
+ Server_error(self, "Jack error: cannot deactivate jack client.\n");
+ ret = jack_client_close(be_data->jack_client);
if (ret)
Server_error(self, "Jack error: cannot close client.\n");
free(be_data->jack_in_ports);
@@ -277,24 +305,10 @@ Server_jack_deinit(Server *self) {
int
Server_jack_start(Server *self) {
- PyoJackBackendData *be_data = (PyoJackBackendData *) self->audio_be_data;
- jack_set_process_callback(be_data->jack_client, jack_callback, (void *) self);
- if (jack_activate(be_data->jack_client)) {
- Server_error(self, "Jack error: cannot activate jack client.\n");
- jack_client_close(be_data->jack_client);
- Server_shut_down(self);
- return -1;
- }
- Server_jack_autoconnect(self);
return 0;
}
int
Server_jack_stop(Server *self) {
- PyoJackBackendData *be_data = (PyoJackBackendData *) self->audio_be_data;
- int ret = jack_deactivate(be_data->jack_client);
- if (ret)
- Server_error(self, "Jack error: cannot deactivate jack client.\n");
- self->server_started = 0;
- return ret;
+ return 0;
}
diff --git a/src/engine/ad_portaudio.c b/src/engine/ad_portaudio.c
index 20e714c..5e92703 100644
--- a/src/engine/ad_portaudio.c
+++ b/src/engine/ad_portaudio.c
@@ -198,7 +198,7 @@ Server_pa_init(Server *self)
outputParameters.device = outDevice;
outputParameters.channelCount = self->nchnls + self->output_offset;
outputParameters.sampleFormat = sampleFormat;
- outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
+ outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
if (self->duplex == 1) {
@@ -206,7 +206,7 @@ Server_pa_init(Server *self)
inputParameters.device = inDevice;
inputParameters.channelCount = self->ichnls + self->input_offset;
inputParameters.sampleFormat = sampleFormat;
- inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency ;
+ inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
}
diff --git a/src/engine/md_portmidi.c b/src/engine/md_portmidi.c
index 0c65f55..35a9d36 100644
--- a/src/engine/md_portmidi.c
+++ b/src/engine/md_portmidi.c
@@ -32,7 +32,7 @@ static PyoMidiEvent PmEventToPyoMidiEvent(PmEvent buffer)
void portmidiGetEvents(Server *self)
{
int i;
- PmError result;
+ PmError result, length;
PmEvent buffer;
PyoPmBackendData *be_data = (PyoPmBackendData *) self->midi_be_data;
@@ -41,9 +41,9 @@ void portmidiGetEvents(Server *self)
do {
result = Pm_Poll(be_data->midiin[i]);
if (result) {
- if (Pm_Read(be_data->midiin[i], &buffer, 1) == pmBufferOverflow)
- continue;
- self->midiEvents[self->midi_count++] = PmEventToPyoMidiEvent(buffer);
+ length = Pm_Read(be_data->midiin[i], &buffer, 1);
+ if (length > 0)
+ self->midiEvents[self->midi_count++] = PmEventToPyoMidiEvent(buffer);
}
} while (result);
}
@@ -147,7 +147,7 @@ Server_pm_init(Server *self)
if (outinfo != NULL) {
if (outinfo->output) {
Pt_Start(1, 0, 0); /* start a timer with millisecond accuracy */
- pmerr = Pm_OpenOutput(&be_data->midiout[0], self->midi_output, NULL, 0, NULL, NULL, 1);
+ pmerr = Pm_OpenOutput(&be_data->midiout[0], self->midi_output, NULL, 100, NULL, NULL, 1);
if (pmerr) {
Server_warning(self,
"Portmidi warning: could not open midi output %d (%s): %s\n",
diff --git a/src/engine/midilistenermodule.c b/src/engine/midilistenermodule.c
index 7039c3b..6b1a3f1 100644
--- a/src/engine/midilistenermodule.c
+++ b/src/engine/midilistenermodule.c
@@ -30,9 +30,11 @@ typedef struct {
PyObject_HEAD
PyObject *midicallable;
PmStream *midiin[64];
- int mididev;
+ PyObject *mididev;
+ int ids[64];
int midicount;
int active;
+ int reportdevice;
} MidiListener;
void process_midi(PtTimestamp timestamp, void *userData)
@@ -55,11 +57,21 @@ void process_midi(PtTimestamp timestamp, void *userData)
status = Pm_MessageStatus(buffer.message);
data1 = Pm_MessageData1(buffer.message);
data2 = Pm_MessageData2(buffer.message);
- tup = PyTuple_New(3);
- PyTuple_SetItem(tup, 0, PyInt_FromLong(status));
- PyTuple_SetItem(tup, 1, PyInt_FromLong(data1));
- PyTuple_SetItem(tup, 2, PyInt_FromLong(data2));
- PyObject_Call((PyObject *)server->midicallable, tup, NULL);
+ if (server->reportdevice) {
+ tup = PyTuple_New(4);
+ PyTuple_SetItem(tup, 0, PyInt_FromLong(status));
+ PyTuple_SetItem(tup, 1, PyInt_FromLong(data1));
+ PyTuple_SetItem(tup, 2, PyInt_FromLong(data2));
+ PyTuple_SetItem(tup, 3, PyInt_FromLong(server->ids[i]));
+ PyObject_Call((PyObject *)server->midicallable, tup, NULL);
+ }
+ else {
+ tup = PyTuple_New(3);
+ PyTuple_SetItem(tup, 0, PyInt_FromLong(status));
+ PyTuple_SetItem(tup, 1, PyInt_FromLong(data1));
+ PyTuple_SetItem(tup, 2, PyInt_FromLong(data2));
+ PyObject_Call((PyObject *)server->midicallable, tup, NULL);
+ }
}
}
} while (result);
@@ -72,6 +84,7 @@ static int
MidiListener_traverse(MidiListener *self, visitproc visit, void *arg)
{
Py_VISIT(self->midicallable);
+ Py_VISIT(self->mididev);
return 0;
}
@@ -79,6 +92,7 @@ static int
MidiListener_clear(MidiListener *self)
{
Py_CLEAR(self->midicallable);
+ Py_CLEAR(self->mididev);
return 0;
}
@@ -94,28 +108,33 @@ MidiListener_dealloc(MidiListener* self)
static PyObject *
MidiListener_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- PyObject *midicalltmp=NULL;
+ PyObject *midicalltmp=NULL, *mididevtmp=NULL;
MidiListener *self;
self = (MidiListener *)type->tp_alloc(type, 0);
- self->active = self->midicount = 0;
- self->mididev = -1;
+ self->active = self->midicount = self->reportdevice = 0;
- static char *kwlist[] = {"midicallable", "mididevice", NULL};
+ static char *kwlist[] = {"midicallable", "mididevice", "reportdevice", NULL};
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "Oi", kwlist, &midicalltmp, &self->mididev))
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "OOi", kwlist, &midicalltmp, &mididevtmp, &self->reportdevice))
Py_RETURN_NONE;
if (midicalltmp) {
PyObject_CallMethod((PyObject *)self, "setMidiFunction", "O", midicalltmp);
}
+ if (mididevtmp) {
+ Py_INCREF(mididevtmp);
+ Py_XDECREF(self->mididev);
+ self->mididev = mididevtmp;
+ }
+
return (PyObject *)self;
}
static PyObject * MidiListener_play(MidiListener *self) {
- int i, num_devices;
+ int i, num_devices, lsize, mididev;
PmError pmerr;
/* always start the timer before you start midi */
@@ -126,28 +145,55 @@ static PyObject * MidiListener_play(MidiListener *self) {
PySys_WriteStdout("Portmidi warning: could not initialize Portmidi: %s\n", Pm_GetErrorText(pmerr));
}
+ lsize = PyList_Size(self->mididev);
+
num_devices = Pm_CountDevices();
if (num_devices > 0) {
- if (self->mididev < num_devices) {
- if (self->mididev == -1)
- self->mididev = Pm_GetDefaultInputDeviceID();
- const PmDeviceInfo *info = Pm_GetDeviceInfo(self->mididev);
- if (info != NULL) {
- if (info->input) {
- pmerr = Pm_OpenInput(&self->midiin[0], self->mididev, NULL, 100, NULL, NULL);
- if (pmerr) {
- PySys_WriteStdout("Portmidi warning: could not open midi input %d (%s): %s\n",
- self->mididev, info->name, Pm_GetErrorText(pmerr));
+ if (lsize == 1) {
+ mididev = PyLong_AsLong(PyList_GetItem(self->mididev, 0));
+ if (mididev < num_devices) {
+ if (mididev == -1)
+ mididev = Pm_GetDefaultInputDeviceID();
+ const PmDeviceInfo *info = Pm_GetDeviceInfo(mididev);
+ if (info != NULL) {
+ if (info->input) {
+ pmerr = Pm_OpenInput(&self->midiin[0], mididev, NULL, 100, NULL, NULL);
+ if (pmerr) {
+ PySys_WriteStdout("Portmidi warning: could not open midi input %d (%s): %s\n",
+ mididev, info->name, Pm_GetErrorText(pmerr));
+ }
+ else {
+ self->midicount = 1;
+ self->ids[0] = mididev;
+ }
}
- else {
- self->midicount = 1;
+ }
+ }
+ else if (mididev >= num_devices) {
+ self->midicount = 0;
+ for (i=0; i<num_devices; i++) {
+ const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
+ if (info != NULL) {
+ if (info->input) {
+ pmerr = Pm_OpenInput(&self->midiin[self->midicount], i, NULL, 100, NULL, NULL);
+ if (pmerr) {
+ PySys_WriteStdout("Portmidi warning: could not open midi input %d (%s): %s\n",
+ i, info->name, Pm_GetErrorText(pmerr));
+ }
+ else {
+ self->ids[self->midicount] = i;
+ self->midicount++;
+ }
+ }
}
}
}
}
- else if (self->mididev >= num_devices) {
+ else {
self->midicount = 0;
for (i=0; i<num_devices; i++) {
+ if (PySequence_Contains(self->mididev, PyLong_FromLong(i)) == 0)
+ continue;
const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
if (info != NULL) {
if (info->input) {
@@ -157,6 +203,7 @@ static PyObject * MidiListener_play(MidiListener *self) {
i, info->name, Pm_GetErrorText(pmerr));
}
else {
+ self->ids[self->midicount] = i;
self->midicount++;
}
}
@@ -208,6 +255,19 @@ MidiListener_setMidiFunction(MidiListener *self, PyObject *arg)
return Py_None;
}
+PyObject *
+MidiListener_getDeviceInfos(MidiListener *self) {
+ int i;
+ PyObject *str;
+ PyObject *lst = PyList_New(0);
+ for (i = 0; i < self->midicount; i++) {
+ const PmDeviceInfo *info = Pm_GetDeviceInfo(self->ids[i]);
+ str = PyBytes_FromFormat("id: %d, name: %s, interface: %s\n", self->ids[i], info->name, info->interf);
+ PyList_Append(lst, str);
+ }
+ return lst;
+}
+
static PyMemberDef MidiListener_members[] = {
{NULL} /* Sentinel */
};
@@ -216,6 +276,7 @@ static PyMethodDef MidiListener_methods[] = {
{"play", (PyCFunction)MidiListener_play, METH_NOARGS, "Starts computing without sending sound to soundcard."},
{"stop", (PyCFunction)MidiListener_stop, METH_NOARGS, "Stops computing."},
{"setMidiFunction", (PyCFunction)MidiListener_setMidiFunction, METH_O, "Sets the function to be called."},
+ {"getDeviceInfos", (PyCFunction)MidiListener_getDeviceInfos, METH_NOARGS, "Returns a list of device infos."},
{NULL} /* Sentinel */
};
@@ -259,3 +320,253 @@ PyTypeObject MidiListenerType = {
0, /* tp_alloc */
MidiListener_new, /* tp_new */
};
+
+typedef struct {
+ PyObject_HEAD
+ PmStream *midiout[64];
+ PyObject *mididev;
+ int ids[64];
+ int midicount;
+ int active;
+} MidiDispatcher;
+
+static int
+MidiDispatcher_traverse(MidiDispatcher *self, visitproc visit, void *arg) {
+ return 0;
+}
+
+static int
+MidiDispatcher_clear(MidiDispatcher *self) {
+ return 0;
+}
+
+static void
+MidiDispatcher_dealloc(MidiDispatcher* self) {
+ if (self->active == 1)
+ PyObject_CallMethod((PyObject *)self, "stop", NULL);
+ MidiDispatcher_clear(self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+static PyObject *
+MidiDispatcher_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *mididevtmp=NULL;
+ MidiDispatcher *self;
+
+ self = (MidiDispatcher *)type->tp_alloc(type, 0);
+
+ self->active = self->midicount = 0;
+
+ static char *kwlist[] = {"mididevice", NULL};
+
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &mididevtmp))
+ Py_RETURN_NONE;
+
+ if (mididevtmp) {
+ Py_INCREF(mididevtmp);
+ Py_XDECREF(self->mididev);
+ self->mididev = mididevtmp;
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject * MidiDispatcher_play(MidiDispatcher *self) {
+ int i, num_devices, lsize, mididev;
+ PmError pmerr;
+
+ /* always start the timer before you start midi */
+ Pt_Start(1, 0, 0);
+
+ pmerr = Pm_Initialize();
+ if (pmerr) {
+ PySys_WriteStdout("Portmidi warning: could not initialize Portmidi: %s\n", Pm_GetErrorText(pmerr));
+ }
+
+ lsize = PyList_Size(self->mididev);
+
+ num_devices = Pm_CountDevices();
+ if (num_devices > 0) {
+ if (lsize == 1) {
+ mididev = PyLong_AsLong(PyList_GetItem(self->mididev, 0));
+ if (mididev < num_devices) {
+ if (mididev == -1)
+ mididev = Pm_GetDefaultOutputDeviceID();
+ const PmDeviceInfo *info = Pm_GetDeviceInfo(mididev);
+ if (info != NULL) {
+ if (info->output) {
+ pmerr = Pm_OpenOutput(&self->midiout[0], mididev, NULL, 100, NULL, NULL, 1);
+ if (pmerr) {
+ PySys_WriteStdout("Portmidi warning: could not open midi output %d (%s): %s\n",
+ mididev, info->name, Pm_GetErrorText(pmerr));
+ }
+ else {
+ self->midicount = 1;
+ self->ids[0] = mididev;
+ }
+ }
+ }
+ }
+ else if (mididev >= num_devices) {
+ self->midicount = 0;
+ for (i=0; i<num_devices; i++) {
+ const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
+ if (info != NULL) {
+ if (info->output) {
+ pmerr = Pm_OpenOutput(&self->midiout[self->midicount], i, NULL, 100, NULL, NULL, 1);
+ if (pmerr) {
+ PySys_WriteStdout("Portmidi warning: could not open midi output %d (%s): %s\n",
+ i, info->name, Pm_GetErrorText(pmerr));
+ }
+ else {
+ self->ids[self->midicount] = i;
+ self->midicount++;
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ self->midicount = 0;
+ for (i=0; i<num_devices; i++) {
+ if (PySequence_Contains(self->mididev, PyLong_FromLong(i)) == 0)
+ continue;
+ const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
+ if (info != NULL) {
+ if (info->output) {
+ pmerr = Pm_OpenOutput(&self->midiout[self->midicount], i, NULL, 100, NULL, NULL, 1);
+ if (pmerr) {
+ PySys_WriteStdout("Portmidi warning: could not open midi output %d (%s): %s\n",
+ i, info->name, Pm_GetErrorText(pmerr));
+ }
+ else {
+ self->ids[self->midicount] = i;
+ self->midicount++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (self->midicount > 0)
+ self->active = 1;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+};
+
+static PyObject * MidiDispatcher_stop(MidiDispatcher *self) {
+ int i;
+ Pt_Stop();
+ for (i=0; i<self->midicount; i++) {
+ Pm_Close(self->midiout[i]);
+ }
+ Pm_Terminate();
+ self->active = 0;
+ Py_INCREF(Py_None);
+ return Py_None;
+};
+
+PyObject *
+MidiDispatcher_send(MidiDispatcher *self, PyObject *args)
+{
+ int i, status, data1, data2, device, curtime;
+ PmTimestamp timestamp;
+ PmEvent buffer[1];
+
+ if (! PyArg_ParseTuple(args, "iiili", &status, &data1, &data2, ×tamp, &device))
+ return PyInt_FromLong(-1);
+
+ curtime = Pt_Time();
+ buffer[0].timestamp = curtime + timestamp;
+ buffer[0].message = Pm_Message(status, data1, data2);
+ if (device == -1 && self->midicount > 1) {
+ for (i=0; i<self->midicount; i++) {
+ Pm_Write(self->midiout[i], buffer, 1);
+ }
+ }
+ else if (self->midicount == 1)
+ Pm_Write(self->midiout[0], buffer, 1);
+ else {
+ for (i=0; i<self->midicount; i++) {
+ if (self->ids[i] == device) {
+ device = i;
+ break;
+ }
+ }
+ if (device < 0 || device >= self->midicount)
+ device = 0;
+ Pm_Write(self->midiout[device], buffer, 1);
+ }
+
+ Py_RETURN_NONE;
+}
+
+PyObject *
+MidiDispatcher_getDeviceInfos(MidiDispatcher *self) {
+ int i;
+ PyObject *str;
+ PyObject *lst = PyList_New(0);
+ for (i = 0; i < self->midicount; i++) {
+ const PmDeviceInfo *info = Pm_GetDeviceInfo(self->ids[i]);
+ str = PyBytes_FromFormat("id: %d, name: %s, interface: %s\n", self->ids[i], info->name, info->interf);
+ PyList_Append(lst, str);
+ }
+ return lst;
+}
+
+static PyMemberDef MidiDispatcher_members[] = {
+ {NULL} /* Sentinel */
+};
+
+static PyMethodDef MidiDispatcher_methods[] = {
+ {"play", (PyCFunction)MidiDispatcher_play, METH_NOARGS, "Starts computing without sending sound to soundcard."},
+ {"stop", (PyCFunction)MidiDispatcher_stop, METH_NOARGS, "Stops computing."},
+ {"getDeviceInfos", (PyCFunction)MidiDispatcher_getDeviceInfos, METH_NOARGS, "Returns a list of device infos."},
+ {"send", (PyCFunction)MidiDispatcher_send, METH_VARARGS, "Send a raw midi event."},
+ {NULL} /* Sentinel */
+};
+
+PyTypeObject MidiDispatcherType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "_pyo.MidiDispatcher_base", /*tp_name*/
+ sizeof(MidiDispatcher), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)MidiDispatcher_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_as_async (tp_compare in Python 2)*/
+ 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*/
+ "MidiDispatcher objects. Calls a function with midi data as arguments.", /* tp_doc */
+ (traverseproc)MidiDispatcher_traverse, /* tp_traverse */
+ (inquiry)MidiDispatcher_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ MidiDispatcher_methods, /* tp_methods */
+ MidiDispatcher_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 */
+ MidiDispatcher_new, /* tp_new */
+};
diff --git a/src/engine/pyomodule.c b/src/engine/pyomodule.c
index cdb1f59..7b3da65 100644
--- a/src/engine/pyomodule.c
+++ b/src/engine/pyomodule.c
@@ -1899,6 +1899,7 @@ init_pyo64(void)
module_add_object(m, "Server_base", &ServerType);
#ifdef USE_PORTMIDI
module_add_object(m, "MidiListener_base", &MidiListenerType);
+ module_add_object(m, "MidiDispatcher_base", &MidiDispatcherType);
#endif
#ifdef USE_OSC
module_add_object(m, "OscListener_base", &OscListenerType);
@@ -2197,12 +2198,17 @@ init_pyo64(void)
module_add_object(m, "PeakAmp_base", &PeakAmpType);
module_add_object(m, "MainParticle_base", &MainParticleType);
module_add_object(m, "Particle_base", &ParticleType);
+ module_add_object(m, "MainParticle2_base", &MainParticle2Type);
+ module_add_object(m, "Particle2_base", &Particle2Type);
module_add_object(m, "AtanTable_base", &AtanTableType);
module_add_object(m, "RawMidi_base", &RawMidiType);
module_add_object(m, "Resample_base", &ResampleType);
module_add_object(m, "Expr_base", &ExprType);
module_add_object(m, "PadSynthTable_base", &PadSynthTableType);
module_add_object(m, "LogiMap_base", &LogiMapType);
+ module_add_object(m, "SharedTable_base", &SharedTableType);
+ module_add_object(m, "TableFill_base", &TableFillType);
+ module_add_object(m, "TableScan_base", &TableScanType);
PyModule_AddStringConstant(m, "PYO_VERSION", PYO_VERSION);
#ifdef COMPILE_EXTERNALS
diff --git a/src/engine/servermodule.c b/src/engine/servermodule.c
index 3f8e329..82a00f7 100644
--- a/src/engine/servermodule.c
+++ b/src/engine/servermodule.c
@@ -485,60 +485,6 @@ Server_process_time(Server *server)
}
}
-PyObject *
-Server_shut_down(Server *self)
-{
- int i;
- int ret = -1;
- if (self->server_booted == 0) {
- Server_error(self, "The Server must be booted!\n");
- Py_RETURN_NONE;
- }
- if (self->server_started == 1) {
- Server_stop((Server *)self);
- }
-
- for (i=0; i<num_rnd_objs; i++) {
- rnd_objs_count[i] = 0;
- }
-
- switch (self->midi_be_type) {
- case PyoPortmidi:
- if (self->withPortMidi == 1 || self->withPortMidiOut == 1)
- ret = Server_pm_deinit(self);
- break;
- default:
- break;
- }
-
- switch (self->audio_be_type) {
- case PyoPortaudio:
- ret = Server_pa_deinit(self);
- break;
- case PyoCoreaudio:
- ret = Server_coreaudio_deinit(self);
- break;
- case PyoJack:
- ret = Server_jack_deinit(self);
- break;
- case PyoOffline:
- ret = Server_offline_deinit(self);
- break;
- case PyoOfflineNB:
- ret = Server_offline_deinit(self);
- break;
- case PyoEmbedded:
- ret = Server_embedded_deinit(self);
- break;
- }
- self->server_booted = 0;
- if (ret < 0) {
- Server_error(self, "Error closing audio backend.\n");
- }
-
- Py_RETURN_NONE;
-}
-
static int
Server_traverse(Server *self, visitproc visit, void *arg)
{
@@ -569,7 +515,7 @@ static void
Server_dealloc(Server* self)
{
if (self->server_booted == 1)
- Server_shut_down(self);
+ Server_shutdown(self);
Server_clear(self);
free(self->input_buffer);
free(self->output_buffer);
@@ -638,7 +584,7 @@ Server_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->midi_output = -1;
self->midiActive = 1;
self->amp = self->resetAmp = 1.;
- self->currentAmp = self->lastAmp = 0.;
+ self->currentAmp = self->lastAmp = 1.; // If set to 0, there is a 5ms fadein at server start.
self->withGUI = 0;
self->withTIME = 0;
self->verbosity = 7;
@@ -646,6 +592,8 @@ Server_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->recformat = 0;
self->rectype = 0;
self->recquality = 0.4;
+ self->globalDur = 0.0;
+ self->globalDel = 0.0;
self->startoffset = 0.0;
self->globalSeed = 0;
self->CALLBACK = NULL;
@@ -873,6 +821,24 @@ Server_setBufferSize(Server *self, PyObject *arg)
}
static PyObject *
+Server_setGlobalDur(Server *self, PyObject *arg)
+{
+ if (arg != NULL && PyNumber_Check(arg)) {
+ self->globalDur = PyFloat_AsDouble(arg);
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+Server_setGlobalDel(Server *self, PyObject *arg)
+{
+ if (arg != NULL && PyNumber_Check(arg)) {
+ self->globalDel = PyFloat_AsDouble(arg);
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *
Server_setDuplex(Server *self, PyObject *arg)
{
if (self->server_booted) {
@@ -1082,11 +1048,67 @@ Server_setStartOffset(Server *self, PyObject *arg)
Py_RETURN_NONE;
}
+/*******************************************/
+/** Server shutdown / boot / start / stop **/
+/*******************************************/
+
+PyObject *
+Server_shutdown(Server *self)
+{
+ int i, ret = -1;
+ if (self->server_booted == 0) {
+ Server_error(self, "The Server must be booted!\n");
+ Py_RETURN_NONE;
+ }
+ if (self->server_started == 1) {
+ Server_stop((Server *)self);
+ }
+
+ for (i=0; i<num_rnd_objs; i++) {
+ rnd_objs_count[i] = 0;
+ }
+
+ switch (self->midi_be_type) {
+ case PyoPortmidi:
+ if (self->withPortMidi == 1 || self->withPortMidiOut == 1)
+ ret = Server_pm_deinit(self);
+ break;
+ default:
+ break;
+ }
+
+ switch (self->audio_be_type) {
+ case PyoPortaudio:
+ ret = Server_pa_deinit(self);
+ break;
+ case PyoCoreaudio:
+ ret = Server_coreaudio_deinit(self);
+ break;
+ case PyoJack:
+ ret = Server_jack_deinit(self);
+ break;
+ case PyoOffline:
+ ret = Server_offline_deinit(self);
+ break;
+ case PyoOfflineNB:
+ ret = Server_offline_deinit(self);
+ break;
+ case PyoEmbedded:
+ ret = Server_embedded_deinit(self);
+ break;
+ }
+ self->server_booted = 0;
+ if (ret < 0) {
+ Server_error(self, "Error closing audio backend.\n");
+ }
+
+ Py_RETURN_NONE;
+}
+
static PyObject *
Server_boot(Server *self, PyObject *arg)
{
- int audioerr = 0, midierr = 0;
- int i;
+ int i, audioerr = 0, midierr = 0;
if (self->server_booted == 1) {
Server_error(self, "Server already booted!\n");
Py_RETURN_NONE;
@@ -1095,6 +1117,11 @@ Server_boot(Server *self, PyObject *arg)
self->stream_count = 0;
self->elapsedSamples = 0;
+ /* Ensure Python is set up for threading */
+ if (!PyEval_ThreadsInitialized()) {
+ PyEval_InitThreads();
+ }
+
int needNewBuffer = 0;
if (arg != NULL && PyBool_Check(arg)) {
needNewBuffer = PyObject_IsTrue(arg);
@@ -1205,14 +1232,9 @@ Server_start(Server *self)
Server_debug(self, "Server_start: number of streams %d\n", self->stream_count);
- /* Ensure Python is set up for threading */
- if (!PyEval_ThreadsInitialized()) {
- PyEval_InitThreads();
- }
-
self->server_stopped = 0;
self->server_started = 1;
- self->timeStep = (int)(0.01 * self->samplingRate);
+ self->timeStep = (int)(0.005 * self->samplingRate);
if (self->startoffset > 0.0) {
Server_message(self,"Rendering %.2f seconds offline...\n", self->startoffset);
@@ -1282,11 +1304,12 @@ Server_stop(Server *self)
}
else {
self->server_stopped = 1;
+ self->server_started = 0;
}
/* This call is needed to recover from thread fork with python3/jack on debian.*/
/* TODO: Need to be tested with other OSes and audio driver. */
- PyOS_AfterFork();
+ //PyOS_AfterFork();
Py_RETURN_NONE;
}
@@ -1735,6 +1758,18 @@ Server_getBufferSize(Server *self)
}
static PyObject *
+Server_getGlobalDur(Server *self)
+{
+ return PyFloat_FromDouble(self->globalDur);
+}
+
+static PyObject *
+Server_getGlobalDel(Server *self)
+{
+ return PyFloat_FromDouble(self->globalDel);
+}
+
+static PyObject *
Server_beginResamplingBlock(Server *self, PyObject *arg)
{
if (PyInt_Check(arg)) {
@@ -1894,6 +1929,8 @@ static PyMethodDef Server_methods[] = {
{"deactivateMidi", (PyCFunction)Server_deactivateMidi, METH_NOARGS, "Deactivates midi callback."},
{"setSamplingRate", (PyCFunction)Server_setSamplingRate, METH_O, "Sets the server's sampling rate."},
{"setBufferSize", (PyCFunction)Server_setBufferSize, METH_O, "Sets the server's buffer size."},
+ {"setGlobalDur", (PyCFunction)Server_setGlobalDur, METH_O, "Sets the server's globalDur attribute."},
+ {"setGlobalDel", (PyCFunction)Server_setGlobalDel, METH_O, "Sets the server's globalDel attribute."},
{"beginResamplingBlock", (PyCFunction)Server_beginResamplingBlock, METH_O, "Starts a resampling code block."},
{"endResamplingBlock", (PyCFunction)Server_endResamplingBlock, METH_NOARGS, "Stops a resampling code block."},
{"setNchnls", (PyCFunction)Server_setNchnls, METH_O, "Sets the server's number of output/input channels."},
@@ -1910,7 +1947,7 @@ static PyMethodDef Server_methods[] = {
{"setVerbosity", (PyCFunction)Server_setVerbosity, METH_O, "Sets the verbosity."},
{"setStartOffset", (PyCFunction)Server_setStartOffset, METH_O, "Sets starting time offset."},
{"boot", (PyCFunction)Server_boot, METH_O, "Setup and boot the server."},
- {"shutdown", (PyCFunction)Server_shut_down, METH_NOARGS, "Shut down the server."},
+ {"shutdown", (PyCFunction)Server_shutdown, METH_NOARGS, "Shut down the server."},
{"start", (PyCFunction)Server_start, METH_NOARGS, "Starts the server's callback loop."},
{"stop", (PyCFunction)Server_stop, METH_NOARGS, "Stops the server's callback loop."},
{"recordOptions", (PyCFunction)Server_recordOptions, METH_VARARGS|METH_KEYWORDS, "Sets format settings for offline rendering and global recording."},
@@ -1936,6 +1973,8 @@ static PyMethodDef Server_methods[] = {
{"getIchnls", (PyCFunction)Server_getIchnls, METH_NOARGS, "Returns the server's current number of input channels."},
{"getGlobalSeed", (PyCFunction)Server_getGlobalSeed, METH_NOARGS, "Returns the server's global seed."},
{"getBufferSize", (PyCFunction)Server_getBufferSize, METH_NOARGS, "Returns the server's buffer size."},
+ {"getGlobalDur", (PyCFunction)Server_getGlobalDur, METH_NOARGS, "Returns the server's globalDur attribute."},
+ {"getGlobalDel", (PyCFunction)Server_getGlobalDel, METH_NOARGS, "Returns the server's globalDel attribute."},
{"getIsBooted", (PyCFunction)Server_getIsBooted, METH_NOARGS, "Returns 1 if the server is booted, otherwise returns 0."},
{"getIsStarted", (PyCFunction)Server_getIsStarted, METH_NOARGS, "Returns 1 if the server is started, otherwise returns 0."},
{"getMidiActive", (PyCFunction)Server_getMidiActive, METH_NOARGS, "Returns 1 if midi callback is active, otherwise returns 0."},
diff --git a/src/objects/fadermodule.c b/src/objects/fadermodule.c
index b48c754..2a7519b 100644
--- a/src/objects/fadermodule.c
+++ b/src/objects/fadermodule.c
@@ -36,6 +36,8 @@ typedef struct {
MYFLT release;
MYFLT duration;
MYFLT exp;
+ MYFLT offset;
+ MYFLT currentVal;
double currentTime;
MYFLT sampleToSec;
} Fader;
@@ -65,7 +67,7 @@ Fader_generate_auto(Fader *self) {
for (i=0; i<self->bufsize; i++) {
if (self->currentTime <= self->attack)
- val = self->currentTime * iatt;
+ val = self->currentTime * iatt * (1.0 - self->offset) + self->offset;
else if (self->currentTime > self->duration) {
val = 0.;
self->ended = 1;
@@ -75,7 +77,7 @@ Fader_generate_auto(Fader *self) {
else
val = 1.;
- self->data[i] = val;
+ self->data[i] = self->currentVal = val;
self->currentTime += self->sampleToSec;
}
@@ -101,9 +103,8 @@ Fader_generate_wait(Fader *self) {
for (i=0; i<self->bufsize; i++) {
if (self->fademode == 0) {
-
if (self->currentTime <= self->attack)
- val = self->currentTime * iatt;
+ val = self->currentTime * iatt * (1.0 - self->offset) + self->offset;
else
val = 1.;
self->topValue = val;
@@ -114,7 +115,7 @@ Fader_generate_wait(Fader *self) {
else
val = 0.;
}
- self->data[i] = val;
+ self->data[i] = self->currentVal = val;
self->currentTime += self->sampleToSec;
}
@@ -224,13 +225,13 @@ Fader_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->duration = 0.0;
self->exp = 1.0;
self->currentTime = 0.0;
+ self->offset = 0.0;
+ self->currentVal = 0.0;
INIT_OBJECT_COMMON
Stream_setFunctionPtr(self->stream, Fader_compute_next_data_frame);
self->mode_func_ptr = Fader_setProcMode;
- Stream_setStreamActive(self->stream, 0);
-
self->sampleToSec = 1. / self->sr;
static char *kwlist[] = {"fadein", "fadeout", "dur", "mul", "add", NULL};
@@ -265,6 +266,7 @@ static PyObject * Fader_play(Fader *self, PyObject *args, PyObject *kwds)
self->fademode = 0;
self->ended = 0;
self->currentTime = 0.0;
+ self->offset = self->currentVal;
(*self->mode_func_ptr)(self);
PLAY
};
@@ -444,6 +446,8 @@ typedef struct {
MYFLT release;
MYFLT duration;
MYFLT exp;
+ MYFLT offset;
+ MYFLT currentVal;
double currentTime;
MYFLT sampleToSec;
} Adsr;
@@ -472,7 +476,7 @@ Adsr_generate_auto(Adsr *self) {
for (i=0; i<self->bufsize; i++) {
if (self->currentTime <= self->attack)
- val = self->currentTime * invatt;
+ val = self->currentTime * invatt * (1.0 - self->offset) + self->offset;
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)
@@ -482,7 +486,7 @@ Adsr_generate_auto(Adsr *self) {
else
val = self->sustain;
- self->data[i] = val;
+ self->data[i] = self->currentVal = val;
self->currentTime += self->sampleToSec;
}
@@ -507,9 +511,8 @@ Adsr_generate_wait(Adsr *self) {
for (i=0; i<self->bufsize; i++) {
if (self->fademode == 0) {
-
if (self->currentTime <= self->attack)
- val = self->currentTime * invatt;
+ val = self->currentTime * invatt * (1.0 - self->offset) + self->offset;
else if (self->currentTime <= (self->attack + self->decay))
val = (self->decay - (self->currentTime - self->attack)) * invdec * (1. - self->sustain) + self->sustain;
else
@@ -523,7 +526,7 @@ Adsr_generate_wait(Adsr *self) {
else
val = 0.;
}
- self->data[i] = val;
+ self->data[i] = self->currentVal = val;
self->currentTime += self->sampleToSec;
}
@@ -634,13 +637,13 @@ Adsr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->duration = 0.0;
self->exp = 1.0;
self->currentTime = 0.0;
+ self->offset = 0.0;
+ self->currentVal = 0.0;
INIT_OBJECT_COMMON
Stream_setFunctionPtr(self->stream, Adsr_compute_next_data_frame);
self->mode_func_ptr = Adsr_setProcMode;
- Stream_setStreamActive(self->stream, 0);
-
self->sampleToSec = 1. / self->sr;
static char *kwlist[] = {"attack", "decay", "sustain", "release", "dur", "mul", "add", NULL};
@@ -685,6 +688,7 @@ static PyObject * Adsr_play(Adsr *self, PyObject *args, PyObject *kwds)
{
self->fademode = 0;
self->currentTime = 0.0;
+ self->offset = self->currentVal;
(*self->mode_func_ptr)(self);
PLAY
};
@@ -1072,8 +1076,6 @@ Linseg_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Stream_setFunctionPtr(self->stream, Linseg_compute_next_data_frame);
self->mode_func_ptr = Linseg_setProcMode;
- Stream_setStreamActive(self->stream, 0);
-
self->sampleToSec = 1. / self->sr;
static char *kwlist[] = {"list", "loop", "initToFirstVal", "mul", "add", NULL};
@@ -1489,8 +1491,6 @@ Expseg_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Stream_setFunctionPtr(self->stream, Expseg_compute_next_data_frame);
self->mode_func_ptr = Expseg_setProcMode;
- Stream_setStreamActive(self->stream, 0);
-
self->sampleToSec = 1. / self->sr;
static char *kwlist[] = {"list", "loop", "exp", "inverse", "initToFirstVal", "mul", "add", NULL};
diff --git a/src/objects/granulatormodule.c b/src/objects/granulatormodule.c
index f459b22..78db68b 100644
--- a/src/objects/granulatormodule.c
+++ b/src/objects/granulatormodule.c
@@ -4578,4 +4578,1729 @@ Particle_members, /* tp_members */
0, /* tp_init */
0, /* tp_alloc */
Particle_new, /* tp_new */
+};
+
+typedef struct {
+ pyo_audio_HEAD
+ PyObject *table;
+ PyObject *env;
+ PyObject *dens;
+ Stream *dens_stream;
+ PyObject *pitch;
+ Stream *pitch_stream;
+ PyObject *pos;
+ Stream *pos_stream;
+ PyObject *dur;
+ Stream *dur_stream;
+ PyObject *dev;
+ Stream *dev_stream;
+ PyObject *pan;
+ Stream *pan_stream;
+
+ PyObject *filterfreq;
+ Stream *filterfreq_stream;
+ PyObject *filterq;
+ Stream *filterq_stream;
+ PyObject *filtertype;
+ Stream *filtertype_stream;
+ // filters last values
+ MYFLT *last_freq;
+ MYFLT *last_q;
+ MYFLT *last_type;
+ // sample memories
+ MYFLT *x1;
+ MYFLT *x2;
+ MYFLT *y1;
+ MYFLT *y2;
+ // variables
+ MYFLT *c;
+ MYFLT *w0;
+ MYFLT *alpha;
+ MYFLT *qcomp;
+ // coefficients
+ MYFLT *b0;
+ MYFLT *b1;
+ MYFLT *b2;
+ MYFLT *a0;
+ MYFLT *a1;
+ MYFLT *a2;
+
+ MYFLT *gpos;
+ MYFLT *glen;
+ MYFLT *inc;
+ MYFLT *phase;
+ MYFLT *amp1;
+ MYFLT *amp2;
+ int *flags;
+ int *k1;
+ int *k2;
+ int num;
+ int chnls;
+ double timer;
+ double devFactor;
+ double srScale;
+ MYFLT oneOnSr;
+ MYFLT nyquist;
+ MYFLT twopiOverSr;
+ MYFLT srOnRandMax;
+ MYFLT *buffer_streams;
+ int modebuffer[9];
+} MainParticle2;
+
+static void
+MainParticle2_compute_coeffs_lp(MainParticle2 *self, int which)
+{
+ self->b0[which] = self->b2[which] = (1 - self->c[which]) / 2;
+ self->b1[which] = 1 - self->c[which];
+ self->a0[which] = 1.0 / (1 + self->alpha[which]);
+ self->a1[which] = -2 * self->c[which];
+ self->a2[which] = 1 - self->alpha[which];
+}
+
+static void
+MainParticle2_compute_coeffs_hp(MainParticle2 *self, int which)
+{
+ self->b0[which] = self->b2[which] = (1 + self->c[which]) / 2;
+ self->b1[which] = -(1 + self->c[which]);
+ self->a0[which] = 1.0 / (1 + self->alpha[which]);
+ self->a1[which] = -2 * self->c[which];
+ self->a2[which] = 1 - self->alpha[which];
+}
+
+static void
+MainParticle2_compute_coeffs_bp(MainParticle2 *self, int which)
+{
+ self->b0[which] = self->alpha[which];
+ self->b1[which] = 0;
+ self->b2[which] = -self->alpha[which];
+ self->a0[which] = 1.0 / (1 + self->alpha[which]);
+ self->a1[which] = -2 * self->c[which];
+ self->a2[which] = 1 - self->alpha[which];
+}
+
+static void
+MainParticle2_compute_coeffs_bs(MainParticle2 *self, int which)
+{
+ self->b0[which] = self->b2[which] = 1;
+ self->b1[which] = self->a1[which] = -2 * self->c[which];
+ self->a0[which] = 1.0 / (1 + self->alpha[which]);
+ self->a2[which] = 1 - self->alpha[which];
+}
+
+static void
+MainParticle2_compute_coeffs_ap(MainParticle2 *self, int which)
+{
+ self->b0[which] = self->a2[which] = 1 - self->alpha[which];
+ self->b1[which] = self->a1[which] = -2 * self->c[which];
+ self->b2[which] = 1 + self->alpha[which];
+ self->a0[which] = 1.0 / (1 + self->alpha[which]);
+}
+
+static void
+MainParticle2_compute_variables(MainParticle2 *self, MYFLT freq, MYFLT q, int which)
+{
+ self->w0[which] = freq * self->twopiOverSr;
+ self->c[which] = MYCOS(self->w0[which]);
+ self->alpha[which] = MYSIN(self->w0[which]) / (2 * q);
+}
+
+static void
+MainParticle2_transform_mono_i(MainParticle2 *self) {
+ MYFLT dens, inc, index, amp, phase, val, fval;
+ int i, j, ipart, flag = 0;
+ MYFLT pit = 0, pos = 0, dur = 0, dev = 0, filterfreq = 0, filterq = 0, filtertype = 0;
+
+ MYFLT *tablelist = TableStream_getData(self->table);
+ int size = TableStream_getSize(self->table);
+
+ MYFLT *envlist = TableStream_getData(self->env);
+ int envsize = TableStream_getSize(self->env);
+
+ dens = PyFloat_AS_DOUBLE(self->dens);
+ if (dens < 0.0)
+ dens = 0.0;
+
+ inc = dens * self->oneOnSr * self->devFactor;
+
+ for (i=0; i<self->bufsize*self->chnls; i++) {
+ self->buffer_streams[i] = 0.0;
+ }
+
+ for (i=0; i<self->bufsize; i++) {
+ self->timer += inc;
+ if (self->timer >= 1.0) {
+ self->timer -= 1.0;
+ flag = 1;
+ }
+
+ /* need to start a new grain */
+ if (flag) {
+ for (j=0; j<MAINPARTICLE_MAX_GRAINS; j++) {
+ if (self->flags[j] == 0) {
+ self->flags[j] = 1;
+ if (j >= self->num)
+ self->num = j + 1;
+ if (self->modebuffer[1] == 0)
+ pit = PyFloat_AS_DOUBLE(self->pitch);
+ else
+ pit = Stream_getData((Stream *)self->pitch_stream)[i];
+ if (self->modebuffer[2] == 0)
+ pos = PyFloat_AS_DOUBLE(self->pos);
+ else
+ pos = Stream_getData((Stream *)self->pos_stream)[i];
+ if (self->modebuffer[3] == 0)
+ dur = PyFloat_AS_DOUBLE(self->dur);
+ else
+ dur = Stream_getData((Stream *)self->dur_stream)[i];
+ if (self->modebuffer[4] == 0)
+ dev = PyFloat_AS_DOUBLE(self->dev);
+ else
+ dev = Stream_getData((Stream *)self->dev_stream)[i];
+ if (self->modebuffer[6] == 0)
+ filterfreq = PyFloat_AS_DOUBLE(self->filterfreq);
+ else
+ filterfreq = Stream_getData((Stream *)self->filterfreq_stream)[i];
+ if (self->modebuffer[7] == 0)
+ filterq = PyFloat_AS_DOUBLE(self->filterq);
+ else
+ filterq = Stream_getData((Stream *)self->filterq_stream)[i];
+ if (self->modebuffer[8] == 0)
+ filtertype = PyFloat_AS_DOUBLE(self->filtertype);
+ else
+ filtertype = Stream_getData((Stream *)self->filtertype_stream)[i];
+ if (pit < 0.0)
+ pit = -pit;
+ if (pos < 0.0)
+ pos = 0.0;
+ else if (pos >= size)
+ pos = (MYFLT)size;
+ if (dur < 0.0001)
+ dur = 0.0001;
+ if (dev < 0.0)
+ dev = 0.0;
+ else if (dev > 1.0)
+ dev = 1.0;
+ if (filterfreq < 1.0)
+ filterfreq = 1.0;
+ else if (filterfreq > self->nyquist)
+ filterfreq = self->nyquist;
+ if (filterq < 0.1)
+ filterq = 0.1;
+ if (filtertype < 0)
+ filtertype = 0;
+ else if (filtertype > 4)
+ filtertype = 4;
+ filtertype = MYROUND(filtertype);
+ self->gpos[j] = pos;
+ self->glen[j] = dur * self->sr * pit * self->srScale;
+ if ((pos + self->glen[j]) >= size || (pos + self->glen[j]) < 0)
+ self->flags[j] = 0;
+ self->phase[j] = 0.0;
+ self->inc[j] = 1.0 / (dur * self->sr);
+ self->devFactor = (RANDOM_UNIFORM * 2.0 - 1.0) * dev + 1.0;
+ if (filtertype != self->last_type[j] || filterfreq != self->last_freq[j] || filterq != self->last_q[j]) {
+ self->last_freq[j] = filterfreq;
+ self->last_q[j] = filterq;
+ self->last_type[j] = filtertype;
+ MainParticle2_compute_variables(self, filterfreq, filterq, j);
+ self->qcomp[j] = 1.0;
+ self->b0[j] = self->b1[j] = self->b2[j] = self->a0[j] = self->a1[j] = self->a2[j] = 0.0;
+ if (filtertype == 0)
+ MainParticle2_compute_coeffs_lp(self, j);
+ else if (filtertype == 1)
+ MainParticle2_compute_coeffs_hp(self, j);
+ else if (filtertype == 2) {
+ MainParticle2_compute_coeffs_bp(self, j);
+ filterq = filterq < 10.0 ? filterq : 10.0;
+ self->qcomp[j] = MYPOW(10, (filterq - 1) * 0.1);
+ }
+ else if (filtertype == 3)
+ MainParticle2_compute_coeffs_bs(self, j);
+ else if (filtertype == 4)
+ MainParticle2_compute_coeffs_ap(self, j);
+ }
+ break;
+ }
+ }
+ }
+
+ /* compute active grains */
+ for (j=0; j<self->num; j++) {
+ if (self->flags[j]) {
+ phase = self->phase[j];
+ /* compute envelope */
+ index = phase * envsize;
+ ipart = (int)index;
+ amp = envlist[ipart] + (envlist[ipart+1] - envlist[ipart]) * (index - ipart);
+ /* compute sampling */
+ index = phase * self->glen[j] + self->gpos[j];
+ ipart = (int)index;
+ val = (tablelist[ipart] + (tablelist[ipart+1] - tablelist[ipart]) * (index - ipart));
+ /* filtering */
+ fval = ( (self->b0[j] * val) + (self->b1[j] * self->x1[j]) + (self->b2[j] * self->x2[j]) - (self->a1[j] * self->y1[j]) - (self->a2[j] * self->y2[j]) ) * self->a0[j];
+ self->y2[j] = self->y1[j];
+ self->y1[j] = fval;
+ self->x2[j] = self->x1[j];
+ self->x1[j] = val;
+ fval *= self->qcomp[j];
+ /* Add to output streams */
+ fval *= amp;
+ self->buffer_streams[i] += fval;
+ phase += self->inc[j];
+ if (phase >= 1.0)
+ self->flags[j] = 0;
+ else
+ self->phase[j] = phase;
+ }
+ }
+ flag = 0;
+ }
+}
+
+static void
+MainParticle2_transform_mono_a(MainParticle2 *self) {
+ MYFLT dens, index, amp, phase, val, fval;
+ int i, j, ipart, flag = 0;
+ MYFLT pit = 0, pos = 0, dur = 0, dev = 0, filterfreq = 0, filterq = 0, filtertype = 0;
+
+ MYFLT *tablelist = TableStream_getData(self->table);
+ int size = TableStream_getSize(self->table);
+
+ MYFLT *envlist = TableStream_getData(self->env);
+ int envsize = TableStream_getSize(self->env);
+
+ MYFLT *density = Stream_getData((Stream *)self->dens_stream);
+
+ for (i=0; i<self->bufsize*self->chnls; i++) {
+ self->buffer_streams[i] = 0.0;
+ }
+
+ for (i=0; i<self->bufsize; i++) {
+ if (density[i] < 0.0)
+ dens = 0.0;
+ else
+ dens = density[i];
+ self->timer += dens * self->oneOnSr * self->devFactor;
+ if (self->timer >= 1.0) {
+ self->timer -= 1.0;
+ flag = 1;
+ }
+
+ /* need to start a new grain */
+ if (flag) {
+ for (j=0; j<MAINPARTICLE_MAX_GRAINS; j++) {
+ if (self->flags[j] == 0) {
+ self->flags[j] = 1;
+ if (j >= self->num)
+ self->num = j + 1;
+ if (self->modebuffer[1] == 0)
+ pit = PyFloat_AS_DOUBLE(self->pitch);
+ else
+ pit = Stream_getData((Stream *)self->pitch_stream)[i];
+ if (self->modebuffer[2] == 0)
+ pos = PyFloat_AS_DOUBLE(self->pos);
+ else
+ pos = Stream_getData((Stream *)self->pos_stream)[i];
+ if (self->modebuffer[3] == 0)
+ dur = PyFloat_AS_DOUBLE(self->dur);
+ else
+ dur = Stream_getData((Stream *)self->dur_stream)[i];
+ if (self->modebuffer[4] == 0)
+ dev = PyFloat_AS_DOUBLE(self->dev);
+ else
+ dev = Stream_getData((Stream *)self->dev_stream)[i];
+ if (self->modebuffer[6] == 0)
+ filterfreq = PyFloat_AS_DOUBLE(self->filterfreq);
+ else
+ filterfreq = Stream_getData((Stream *)self->filterfreq_stream)[i];
+ if (self->modebuffer[7] == 0)
+ filterq = PyFloat_AS_DOUBLE(self->filterq);
+ else
+ filterq = Stream_getData((Stream *)self->filterq_stream)[i];
+ if (self->modebuffer[8] == 0)
+ filtertype = PyFloat_AS_DOUBLE(self->filtertype);
+ else
+ filtertype = Stream_getData((Stream *)self->filtertype_stream)[i];
+ if (pit < 0.0)
+ pit = -pit;
+ if (pos < 0.0)
+ pos = 0.0;
+ else if (pos >= size)
+ pos = (MYFLT)size;
+ if (dur < 0.0001)
+ dur = 0.0001;
+ if (dev < 0.0)
+ dev = 0.0;
+ else if (dev > 1.0)
+ dev = 1.0;
+ if (filterfreq < 1.0)
+ filterfreq = 1.0;
+ else if (filterfreq > self->nyquist)
+ filterfreq = self->nyquist;
+ if (filterq < 0.1)
+ filterq = 0.1;
+ if (filtertype < 0)
+ filtertype = 0;
+ else if (filtertype > 4)
+ filtertype = 4;
+ filtertype = MYROUND(filtertype);
+ self->gpos[j] = pos;
+ self->glen[j] = dur * self->sr * pit * self->srScale;
+ if ((pos + self->glen[j]) >= size || (pos + self->glen[j]) < 0)
+ self->flags[j] = 0;
+ self->phase[j] = 0.0;
+ self->inc[j] = 1.0 / (dur * self->sr);
+ self->devFactor = (RANDOM_UNIFORM * 2.0 - 1.0) * dev + 1.0;
+ if (filtertype != self->last_type[j] || filterfreq != self->last_freq[j] || filterq != self->last_q[j]) {
+ self->last_freq[j] = filterfreq;
+ self->last_q[j] = filterq;
+ self->last_type[j] = filtertype;
+ MainParticle2_compute_variables(self, filterfreq, filterq, j);
+ self->qcomp[j] = 1.0;
+ self->b0[j] = self->b1[j] = self->b2[j] = self->a0[j] = self->a1[j] = self->a2[j] = 0.0;
+ if (filtertype == 0)
+ MainParticle2_compute_coeffs_lp(self, j);
+ else if (filtertype == 1)
+ MainParticle2_compute_coeffs_hp(self, j);
+ else if (filtertype == 2) {
+ MainParticle2_compute_coeffs_bp(self, j);
+ filterq = filterq < 10.0 ? filterq : 10.0;
+ self->qcomp[j] = MYPOW(10, (filterq - 1) * 0.1);
+ }
+ else if (filtertype == 3)
+ MainParticle2_compute_coeffs_bs(self, j);
+ else if (filtertype == 4)
+ MainParticle2_compute_coeffs_ap(self, j);
+ }
+ break;
+ }
+ }
+ }
+
+ /* compute active grains */
+ for (j=0; j<self->num; j++) {
+ if (self->flags[j]) {
+ phase = self->phase[j];
+ /* compute envelope */
+ index = phase * envsize;
+ ipart = (int)index;
+ amp = envlist[ipart] + (envlist[ipart+1] - envlist[ipart]) * (index - ipart);
+ /* compute sampling */
+ index = phase * self->glen[j] + self->gpos[j];
+ ipart = (int)index;
+ val = (tablelist[ipart] + (tablelist[ipart+1] - tablelist[ipart]) * (index - ipart));
+ /* filtering */
+ fval = ( (self->b0[j] * val) + (self->b1[j] * self->x1[j]) + (self->b2[j] * self->x2[j]) - (self->a1[j] * self->y1[j]) - (self->a2[j] * self->y2[j]) ) * self->a0[j];
+ self->y2[j] = self->y1[j];
+ self->y1[j] = fval;
+ self->x2[j] = self->x1[j];
+ self->x1[j] = val;
+ fval *= self->qcomp[j];
+ /* Add to output streams */
+ fval *= amp;
+ self->buffer_streams[i] += fval;
+ phase += self->inc[j];
+ if (phase >= 1.0)
+ self->flags[j] = 0;
+ else
+ self->phase[j] = phase;
+ }
+ }
+ flag = 0;
+ }
+}
+
+static void
+MainParticle2_transform_i(MainParticle2 *self) {
+ MYFLT dens, inc, index, amp, phase, val, fval, min = 0;
+ int i, j, l, l1, ipart, flag = 0;
+ MYFLT pit = 0, pos = 0, dur = 0, dev = 0, pan = 0, filterfreq = 0, filterq = 0, filtertype = 0;
+
+ MYFLT *tablelist = TableStream_getData(self->table);
+ int size = TableStream_getSize(self->table);
+
+ MYFLT *envlist = TableStream_getData(self->env);
+ int envsize = TableStream_getSize(self->env);
+
+ dens = PyFloat_AS_DOUBLE(self->dens);
+ if (dens < 0.0)
+ dens = 0.0;
+
+ inc = dens * self->oneOnSr * self->devFactor;
+
+ for (i=0; i<self->bufsize*self->chnls; i++) {
+ self->buffer_streams[i] = 0.0;
+ }
+
+ for (i=0; i<self->bufsize; i++) {
+ self->timer += inc;
+ if (self->timer >= 1.0) {
+ self->timer -= 1.0;
+ flag = 1;
+ }
+
+ /* need to start a new grain */
+ if (flag) {
+ for (j=0; j<MAINPARTICLE_MAX_GRAINS; j++) {
+ if (self->flags[j] == 0) {
+ self->flags[j] = 1;
+ if (j >= self->num)
+ self->num = j + 1;
+ if (self->modebuffer[1] == 0)
+ pit = PyFloat_AS_DOUBLE(self->pitch);
+ else
+ pit = Stream_getData((Stream *)self->pitch_stream)[i];
+ if (self->modebuffer[2] == 0)
+ pos = PyFloat_AS_DOUBLE(self->pos);
+ else
+ pos = Stream_getData((Stream *)self->pos_stream)[i];
+ if (self->modebuffer[3] == 0)
+ dur = PyFloat_AS_DOUBLE(self->dur);
+ else
+ dur = Stream_getData((Stream *)self->dur_stream)[i];
+ if (self->modebuffer[4] == 0)
+ dev = PyFloat_AS_DOUBLE(self->dev);
+ else
+ dev = Stream_getData((Stream *)self->dev_stream)[i];
+ if (self->modebuffer[5] == 0)
+ pan = PyFloat_AS_DOUBLE(self->pan);
+ else
+ pan = Stream_getData((Stream *)self->pan_stream)[i];
+ if (self->modebuffer[6] == 0)
+ filterfreq = PyFloat_AS_DOUBLE(self->filterfreq);
+ else
+ filterfreq = Stream_getData((Stream *)self->filterfreq_stream)[i];
+ if (self->modebuffer[7] == 0)
+ filterq = PyFloat_AS_DOUBLE(self->filterq);
+ else
+ filterq = Stream_getData((Stream *)self->filterq_stream)[i];
+ if (self->modebuffer[8] == 0)
+ filtertype = PyFloat_AS_DOUBLE(self->filtertype);
+ else
+ filtertype = Stream_getData((Stream *)self->filtertype_stream)[i];
+ if (pit < 0.0)
+ pit = -pit;
+ if (pos < 0.0)
+ pos = 0.0;
+ else if (pos >= size)
+ pos = (MYFLT)size;
+ if (dur < 0.0001)
+ dur = 0.0001;
+ if (dev < 0.0)
+ dev = 0.0;
+ else if (dev > 1.0)
+ dev = 1.0;
+ if (pan < 0.0)
+ pan = 0.0;
+ else if (pan > 1.0)
+ pan = 1.0;
+ if (filterfreq < 1.0)
+ filterfreq = 1.0;
+ else if (filterfreq > self->nyquist)
+ filterfreq = self->nyquist;
+ if (filterq < 0.1)
+ filterq = 0.1;
+ if (filtertype < 0)
+ filtertype = 0;
+ else if (filtertype > 4)
+ filtertype = 4;
+ filtertype = MYROUND(filtertype);
+ self->gpos[j] = pos;
+ self->glen[j] = dur * self->sr * pit * self->srScale;
+ if ((pos + self->glen[j]) >= size || (pos + self->glen[j]) < 0)
+ self->flags[j] = 0;
+ self->phase[j] = 0.0;
+ self->inc[j] = 1.0 / (dur * self->sr);
+ self->devFactor = (RANDOM_UNIFORM * 2.0 - 1.0) * dev + 1.0;
+ if (self->chnls == 2) {
+ self->k1[j] = 0;
+ self->k2[j] = self->bufsize;
+ self->amp1[j] = MYSQRT(1.0 - pan);
+ self->amp2[j] = MYSQRT(pan);
+ }
+ else {
+ self->amp1[j] = MYSQRT(1.0 - pan);
+ self->amp2[j] = MYSQRT(pan);
+ min = 0;
+ self->k1[j] = 0;
+ self->k2[j] = self->bufsize;
+ for (l=self->chnls; l>0; l--) {
+ l1 = l - 1;
+ min = l1 / (MYFLT)self->chnls;
+ if (pan > min) {
+ self->k1[j] = l1 * self->bufsize;
+ if (l == self->chnls)
+ self->k2[j] = 0;
+ else
+ self->k2[j] = l * self->bufsize;
+ break;
+ }
+ }
+ }
+ if (filtertype != self->last_type[j] || filterfreq != self->last_freq[j] || filterq != self->last_q[j]) {
+ self->last_freq[j] = filterfreq;
+ self->last_q[j] = filterq;
+ self->last_type[j] = filtertype;
+ MainParticle2_compute_variables(self, filterfreq, filterq, j);
+ self->qcomp[j] = 1.0;
+ self->b0[j] = self->b1[j] = self->b2[j] = self->a0[j] = self->a1[j] = self->a2[j] = 0.0;
+ if (filtertype == 0)
+ MainParticle2_compute_coeffs_lp(self, j);
+ else if (filtertype == 1)
+ MainParticle2_compute_coeffs_hp(self, j);
+ else if (filtertype == 2) {
+ MainParticle2_compute_coeffs_bp(self, j);
+ filterq = filterq < 10.0 ? filterq : 10.0;
+ self->qcomp[j] = MYPOW(10, (filterq - 1) * 0.1);
+ }
+ else if (filtertype == 3)
+ MainParticle2_compute_coeffs_bs(self, j);
+ else if (filtertype == 4)
+ MainParticle2_compute_coeffs_ap(self, j);
+ }
+ break;
+ }
+ }
+ }
+
+ /* compute active grains */
+ for (j=0; j<self->num; j++) {
+ if (self->flags[j]) {
+ phase = self->phase[j];
+ /* compute envelope */
+ index = phase * envsize;
+ ipart = (int)index;
+ amp = envlist[ipart] + (envlist[ipart+1] - envlist[ipart]) * (index - ipart);
+ /* compute sampling */
+ index = phase * self->glen[j] + self->gpos[j];
+ ipart = (int)index;
+ val = (tablelist[ipart] + (tablelist[ipart+1] - tablelist[ipart]) * (index - ipart));
+ /* filtering */
+ fval = ( (self->b0[j] * val) + (self->b1[j] * self->x1[j]) + (self->b2[j] * self->x2[j]) - (self->a1[j] * self->y1[j]) - (self->a2[j] * self->y2[j]) ) * self->a0[j];
+ self->y2[j] = self->y1[j];
+ self->y1[j] = fval;
+ self->x2[j] = self->x1[j];
+ self->x1[j] = val;
+ fval *= self->qcomp[j];
+ /* Add to output streams */
+ fval *= amp;
+ self->buffer_streams[i+self->k1[j]] += fval * self->amp1[j];
+ self->buffer_streams[i+self->k2[j]] += fval * self->amp2[j];
+ phase += self->inc[j];
+ if (phase >= 1.0)
+ self->flags[j] = 0;
+ else
+ self->phase[j] = phase;
+ }
+ }
+ flag = 0;
+ }
+}
+
+static void
+MainParticle2_transform_a(MainParticle2 *self) {
+ MYFLT dens, index, amp, phase, val, fval, min = 0;
+ int i, j, l, l1, ipart, flag = 0;
+ MYFLT pit = 0, pos = 0, dur = 0, dev = 0, pan = 0, filterfreq = 0, filterq = 0, filtertype = 0;
+
+ MYFLT *tablelist = TableStream_getData(self->table);
+ int size = TableStream_getSize(self->table);
+
+ MYFLT *envlist = TableStream_getData(self->env);
+ int envsize = TableStream_getSize(self->env);
+
+ MYFLT *density = Stream_getData((Stream *)self->dens_stream);
+
+ for (i=0; i<self->bufsize*self->chnls; i++) {
+ self->buffer_streams[i] = 0.0;
+ }
+
+ for (i=0; i<self->bufsize; i++) {
+ if (density[i] < 0.0)
+ dens = 0.0;
+ else
+ dens = density[i];
+ self->timer += dens * self->oneOnSr * self->devFactor;
+ if (self->timer >= 1.0) {
+ self->timer -= 1.0;
+ flag = 1;
+ }
+
+ /* need to start a new grain */
+ if (flag) {
+ for (j=0; j<MAINPARTICLE_MAX_GRAINS; j++) {
+ if (self->flags[j] == 0) {
+ self->flags[j] = 1;
+ if (j >= self->num)
+ self->num = j + 1;
+ if (self->modebuffer[1] == 0)
+ pit = PyFloat_AS_DOUBLE(self->pitch);
+ else
+ pit = Stream_getData((Stream *)self->pitch_stream)[i];
+ if (self->modebuffer[2] == 0)
+ pos = PyFloat_AS_DOUBLE(self->pos);
+ else
+ pos = Stream_getData((Stream *)self->pos_stream)[i];
+ if (self->modebuffer[3] == 0)
+ dur = PyFloat_AS_DOUBLE(self->dur);
+ else
+ dur = Stream_getData((Stream *)self->dur_stream)[i];
+ if (self->modebuffer[4] == 0)
+ dev = PyFloat_AS_DOUBLE(self->dev);
+ else
+ dev = Stream_getData((Stream *)self->dev_stream)[i];
+ if (self->modebuffer[5] == 0)
+ pan = PyFloat_AS_DOUBLE(self->pan);
+ else
+ pan = Stream_getData((Stream *)self->pan_stream)[i];
+ if (self->modebuffer[6] == 0)
+ filterfreq = PyFloat_AS_DOUBLE(self->filterfreq);
+ else
+ filterfreq = Stream_getData((Stream *)self->filterfreq_stream)[i];
+ if (self->modebuffer[7] == 0)
+ filterq = PyFloat_AS_DOUBLE(self->filterq);
+ else
+ filterq = Stream_getData((Stream *)self->filterq_stream)[i];
+ if (self->modebuffer[8] == 0)
+ filtertype = PyFloat_AS_DOUBLE(self->filtertype);
+ else
+ filtertype = Stream_getData((Stream *)self->filtertype_stream)[i];
+ if (pit < 0.0)
+ pit = -pit;
+ if (pos < 0.0)
+ pos = 0.0;
+ else if (pos >= size)
+ pos = (MYFLT)size;
+ if (dur < 0.0001)
+ dur = 0.0001;
+ if (dev < 0.0)
+ dev = 0.0;
+ else if (dev > 1.0)
+ dev = 1.0;
+ if (pan < 0.0)
+ pan = 0.0;
+ else if (pan > 1.0)
+ pan = 1.0;
+ if (filterfreq < 1.0)
+ filterfreq = 1.0;
+ else if (filterfreq > self->nyquist)
+ filterfreq = self->nyquist;
+ if (filterq < 0.1)
+ filterq = 0.1;
+ if (filtertype < 0)
+ filtertype = 0;
+ else if (filtertype > 4)
+ filtertype = 4;
+ filtertype = MYROUND(filtertype);
+ self->gpos[j] = pos;
+ self->glen[j] = dur * self->sr * pit * self->srScale;
+ if ((pos + self->glen[j]) >= size || (pos + self->glen[j]) < 0)
+ self->flags[j] = 0;
+ self->phase[j] = 0.0;
+ self->inc[j] = 1.0 / (dur * self->sr);
+ self->devFactor = (RANDOM_UNIFORM * 2.0 - 1.0) * dev + 1.0;
+ if (self->chnls == 2) {
+ self->k1[j] = 0;
+ self->k2[j] = self->bufsize;
+ self->amp1[j] = MYSQRT(1.0 - pan);
+ self->amp2[j] = MYSQRT(pan);
+ }
+ else {
+ self->amp1[j] = MYSQRT(1.0 - pan);
+ self->amp2[j] = MYSQRT(pan);
+ min = 0;
+ self->k1[j] = 0;
+ self->k2[j] = self->bufsize;
+ for (l=self->chnls; l>0; l--) {
+ l1 = l - 1;
+ min = l1 / (MYFLT)self->chnls;
+ if (pan > min) {
+ self->k1[j] = l1 * self->bufsize;
+ if (l == self->chnls)
+ self->k2[j] = 0;
+ else
+ self->k2[j] = l * self->bufsize;
+ break;
+ }
+ }
+ }
+ if (filtertype != self->last_type[j] || filterfreq != self->last_freq[j] || filterq != self->last_q[j]) {
+ self->last_freq[j] = filterfreq;
+ self->last_q[j] = filterq;
+ self->last_type[j] = filtertype;
+ MainParticle2_compute_variables(self, filterfreq, filterq, j);
+ self->qcomp[j] = 1.0;
+ self->b0[j] = self->b1[j] = self->b2[j] = self->a0[j] = self->a1[j] = self->a2[j] = 0.0;
+ if (filtertype == 0)
+ MainParticle2_compute_coeffs_lp(self, j);
+ else if (filtertype == 1)
+ MainParticle2_compute_coeffs_hp(self, j);
+ else if (filtertype == 2) {
+ MainParticle2_compute_coeffs_bp(self, j);
+ filterq = filterq < 10.0 ? filterq : 10.0;
+ self->qcomp[j] = MYPOW(10, (filterq - 1) * 0.1);
+ }
+ else if (filtertype == 3)
+ MainParticle2_compute_coeffs_bs(self, j);
+ else if (filtertype == 4)
+ MainParticle2_compute_coeffs_ap(self, j);
+ }
+ break;
+ }
+ }
+ }
+
+ /* compute active grains */
+ for (j=0; j<self->num; j++) {
+ if (self->flags[j]) {
+ phase = self->phase[j];
+ /* compute envelope */
+ index = phase * envsize;
+ ipart = (int)index;
+ amp = envlist[ipart] + (envlist[ipart+1] - envlist[ipart]) * (index - ipart);
+ /* compute sampling */
+ index = phase * self->glen[j] + self->gpos[j];
+ ipart = (int)index;
+ val = (tablelist[ipart] + (tablelist[ipart+1] - tablelist[ipart]) * (index - ipart));
+ /* filtering */
+ fval = ( (self->b0[j] * val) + (self->b1[j] * self->x1[j]) + (self->b2[j] * self->x2[j]) - (self->a1[j] * self->y1[j]) - (self->a2[j] * self->y2[j]) ) * self->a0[j];
+ self->y2[j] = self->y1[j];
+ self->y1[j] = fval;
+ self->x2[j] = self->x1[j];
+ self->x1[j] = val;
+ fval *= self->qcomp[j];
+ /* Add to output streams */
+ fval *= amp;
+ self->buffer_streams[i+self->k1[j]] += fval * self->amp1[j];
+ self->buffer_streams[i+self->k2[j]] += fval * self->amp2[j];
+ phase += self->inc[j];
+ if (phase >= 1.0)
+ self->flags[j] = 0;
+ else
+ self->phase[j] = phase;
+ }
+ }
+ flag = 0;
+ }
+}
+
+static void
+MainParticle2_setProcMode(MainParticle2 *self)
+{
+ int procmode = self->modebuffer[0];
+
+ switch (procmode) {
+ case 0:
+ if (self->chnls == 1)
+ self->proc_func_ptr = MainParticle2_transform_mono_i;
+ else
+ self->proc_func_ptr = MainParticle2_transform_i;
+ break;
+ case 1:
+ if (self->chnls == 1)
+ self->proc_func_ptr = MainParticle2_transform_mono_a;
+ else
+ self->proc_func_ptr = MainParticle2_transform_a;
+ break;
+ }
+}
+
+static void
+MainParticle2_compute_next_data_frame(MainParticle2 *self)
+{
+ (*self->proc_func_ptr)(self);
+}
+
+static int
+MainParticle2_traverse(MainParticle2 *self, visitproc visit, void *arg)
+{
+ pyo_VISIT
+ Py_VISIT(self->table);
+ Py_VISIT(self->env);
+ Py_VISIT(self->dens);
+ Py_VISIT(self->dens_stream);
+ Py_VISIT(self->pitch);
+ Py_VISIT(self->pitch_stream);
+ Py_VISIT(self->pos);
+ Py_VISIT(self->pos_stream);
+ Py_VISIT(self->dur);
+ Py_VISIT(self->dur_stream);
+ Py_VISIT(self->dev);
+ Py_VISIT(self->dev_stream);
+ Py_VISIT(self->pan);
+ Py_VISIT(self->pan_stream);
+ Py_VISIT(self->filterfreq);
+ Py_VISIT(self->filterfreq_stream);
+ Py_VISIT(self->filterq);
+ Py_VISIT(self->filterq_stream);
+ Py_VISIT(self->filtertype);
+ Py_VISIT(self->filtertype_stream);
+ return 0;
+}
+
+static int
+MainParticle2_clear(MainParticle2 *self)
+{
+ pyo_CLEAR
+ Py_CLEAR(self->table);
+ Py_CLEAR(self->env);
+ Py_CLEAR(self->dens);
+ Py_CLEAR(self->dens_stream);
+ Py_CLEAR(self->pitch);
+ Py_CLEAR(self->pitch_stream);
+ Py_CLEAR(self->pos);
+ Py_CLEAR(self->pos_stream);
+ Py_CLEAR(self->dur);
+ Py_CLEAR(self->dur_stream);
+ Py_CLEAR(self->dev);
+ Py_CLEAR(self->dev_stream);
+ Py_CLEAR(self->pan);
+ Py_CLEAR(self->pan_stream);
+ Py_CLEAR(self->filterfreq);
+ Py_CLEAR(self->filterfreq_stream);
+ Py_CLEAR(self->filterq);
+ Py_CLEAR(self->filterq_stream);
+ Py_CLEAR(self->filtertype);
+ Py_CLEAR(self->filtertype_stream);
+ return 0;
+}
+
+static void
+MainParticle2_dealloc(MainParticle2* self)
+{
+ pyo_DEALLOC
+ free(self->gpos);
+ free(self->glen);
+ free(self->inc);
+ free(self->flags);
+ free(self->k1);
+ free(self->k2);
+ free(self->phase);
+ free(self->amp1);
+ free(self->amp2);
+ free(self->last_freq);
+ free(self->last_q);
+ free(self->last_type);
+ free(self->x1);
+ free(self->x2);
+ free(self->y1);
+ free(self->y2);
+ free(self->c);
+ free(self->w0);
+ free(self->alpha);
+ free(self->qcomp);
+ free(self->b0);
+ free(self->b1);
+ free(self->b2);
+ free(self->a0);
+ free(self->a1);
+ free(self->a2);
+ free(self->buffer_streams);
+ MainParticle2_clear(self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+MYFLT *
+MainParticle2_getSamplesBuffer(MainParticle2 *self)
+{
+ return (MYFLT *)self->buffer_streams;
+}
+
+static PyObject *
+MainParticle2_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ int i;
+ PyObject *tabletmp, *envtmp, *denstmp=NULL, *pitchtmp=NULL, *postmp=NULL, *durtmp=NULL;
+ PyObject *devtmp=NULL, *pantmp=NULL, *filterfreqtmp=NULL, *filterqtmp=NULL, *filtertypetmp=NULL;
+ MainParticle2 *self;
+ self = (MainParticle2 *)type->tp_alloc(type, 0);
+
+ self->dens = PyFloat_FromDouble(50);
+ self->pitch = PyFloat_FromDouble(1);
+ self->pos = PyFloat_FromDouble(0.0);
+ self->dur = PyFloat_FromDouble(0.1);
+ self->dev = PyFloat_FromDouble(0);
+ self->pan = PyFloat_FromDouble(0.5);
+ self->filterq = PyFloat_FromDouble(0.7);
+ self->filtertype = PyFloat_FromDouble(0);
+ self->timer = self->devFactor = 1.0;
+ self->srScale = 1.0;
+ self->num = 0;
+ self->chnls = 1;
+ self->modebuffer[0] = 0;
+ self->modebuffer[1] = 0;
+ self->modebuffer[2] = 0;
+ self->modebuffer[3] = 0;
+ self->modebuffer[4] = 0;
+ self->modebuffer[5] = 0;
+ self->modebuffer[6] = 0;
+ self->modebuffer[7] = 0;
+ self->modebuffer[8] = 0;
+
+ INIT_OBJECT_COMMON
+
+ self->oneOnSr = 1.0 / self->sr;
+ self->srOnRandMax = self->sr / (MYFLT)PYO_RAND_MAX;
+ self->nyquist = (MYFLT)self->sr * 0.49;
+ self->twopiOverSr = TWOPI / (MYFLT)self->sr;
+
+ self->filterfreq = PyFloat_FromDouble(self->nyquist);
+
+ Stream_setFunctionPtr(self->stream, MainParticle2_compute_next_data_frame);
+ self->mode_func_ptr = MainParticle2_setProcMode;
+
+ static char *kwlist[] = {"table", "env", "dens", "pitch", "pos", "dur", "dev", "pan", "filterfreq", "filterq", "filtertype", "chnls", NULL};
+
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OOOOOOOOOi", kwlist, &tabletmp, &envtmp, &denstmp, &pitchtmp, &postmp, &durtmp, &devtmp, &pantmp, &filterfreqtmp, &filterqtmp, &filtertypetmp, &self->chnls))
+ Py_RETURN_NONE;
+
+ if ( PyObject_HasAttrString((PyObject *)tabletmp, "getTableStream") == 0 ) {
+ PyErr_SetString(PyExc_TypeError, "\"table\" argument of MainParticle2 must be a PyoTableObject.\n");
+ Py_RETURN_NONE;
+ }
+ Py_XDECREF(self->table);
+ self->table = PyObject_CallMethod((PyObject *)tabletmp, "getTableStream", "");
+ self->srScale = TableStream_getSamplingRate(self->table) / self->sr;
+
+ if ( PyObject_HasAttrString((PyObject *)envtmp, "getTableStream") == 0 ) {
+ PyErr_SetString(PyExc_TypeError, "\"env\" argument of MainParticle2 must be a PyoTableObject.\n");
+ Py_RETURN_NONE;
+ }
+ Py_XDECREF(self->env);
+ self->env = PyObject_CallMethod((PyObject *)envtmp, "getTableStream", "");
+
+ if (denstmp) {
+ PyObject_CallMethod((PyObject *)self, "setDens", "O", denstmp);
+ }
+
+ if (pitchtmp) {
+ PyObject_CallMethod((PyObject *)self, "setPitch", "O", pitchtmp);
+ }
+
+ if (postmp) {
+ PyObject_CallMethod((PyObject *)self, "setPos", "O", postmp);
+ }
+
+ if (durtmp) {
+ PyObject_CallMethod((PyObject *)self, "setDur", "O", durtmp);
+ }
+
+ if (devtmp) {
+ PyObject_CallMethod((PyObject *)self, "setDev", "O", devtmp);
+ }
+
+ if (pantmp) {
+ PyObject_CallMethod((PyObject *)self, "setPan", "O", pantmp);
+ }
+
+ if (filterfreqtmp) {
+ PyObject_CallMethod((PyObject *)self, "setFilterfreq", "O", filterfreqtmp);
+ }
+
+ if (filterqtmp) {
+ PyObject_CallMethod((PyObject *)self, "setFilterq", "O", filterqtmp);
+ }
+
+ if (filtertypetmp) {
+ PyObject_CallMethod((PyObject *)self, "setFiltertype", "O", filtertypetmp);
+ }
+
+ PyObject_CallMethod(self->server, "addStream", "O", self->stream);
+
+ if (self->chnls < 1)
+ self->chnls = 1;
+
+ self->gpos = (MYFLT *)realloc(self->gpos, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->glen = (MYFLT *)realloc(self->glen, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->inc = (MYFLT *)realloc(self->inc, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->phase = (MYFLT *)realloc(self->phase, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->amp1 = (MYFLT *)realloc(self->amp1, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->amp2 = (MYFLT *)realloc(self->amp2, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->flags = (int *)realloc(self->flags, MAINPARTICLE_MAX_GRAINS * sizeof(int));
+ self->k1 = (int *)realloc(self->k1, MAINPARTICLE_MAX_GRAINS * sizeof(int));
+ self->k2 = (int *)realloc(self->k2, MAINPARTICLE_MAX_GRAINS * sizeof(int));
+ self->last_freq = (MYFLT *)realloc(self->last_freq, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->last_q = (MYFLT *)realloc(self->last_q, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->last_type = (MYFLT *)realloc(self->last_type, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->x1 = (MYFLT *)realloc(self->x1, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->x2 = (MYFLT *)realloc(self->x2, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->y1 = (MYFLT *)realloc(self->y1, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->y2 = (MYFLT *)realloc(self->y2, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->c = (MYFLT *)realloc(self->c, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->w0 = (MYFLT *)realloc(self->w0, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->alpha = (MYFLT *)realloc(self->alpha, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->qcomp = (MYFLT *)realloc(self->qcomp, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->b0 = (MYFLT *)realloc(self->b0, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->b1 = (MYFLT *)realloc(self->b1, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->b2 = (MYFLT *)realloc(self->b2, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->a0 = (MYFLT *)realloc(self->a0, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->a1 = (MYFLT *)realloc(self->a1, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+ self->a2 = (MYFLT *)realloc(self->a2, MAINPARTICLE_MAX_GRAINS * sizeof(MYFLT));
+
+ for (i=0; i<MAINPARTICLE_MAX_GRAINS; i++) {
+ self->gpos[i] = self->glen[i] = self->inc[i] = self->phase[i] = self->amp1[i] = self->amp2[i] = 0.0;
+ self->last_freq[i] = self->last_q[i] = self->x1[i] = self->x2[i] = self->y1[i] = self->y2[i] = 0.0;
+ self->last_type[i] = -1.0;
+ self->qcomp[i] = 1.0;
+ self->c[i] = self->w0[i] = self->alpha[i] = self->b0[i] = self->b1[i] = self->b2[i] = self->a0[i] = self->a1[i] = self->a2[i] = 0.0;
+ self->flags[i] = self->k1[i] = self->k2[i] = 0;
+ }
+
+ self->buffer_streams = (MYFLT *)realloc(self->buffer_streams, self->bufsize * self->chnls * sizeof(MYFLT));
+ for (i=0; i<self->bufsize*self->chnls; i++) {
+ self->buffer_streams[i] = 0.0;
+ }
+
+ Server_generateSeed((Server *)self->server, MAINPARTICLE_ID);
+
+ (*self->mode_func_ptr)(self);
+
+ return (PyObject *)self;
+}
+
+static PyObject * MainParticle2_getServer(MainParticle2* self) { GET_SERVER };
+static PyObject * MainParticle2_getStream(MainParticle2* self) { GET_STREAM };
+
+static PyObject * MainParticle2_play(MainParticle2 *self, PyObject *args, PyObject *kwds) { PLAY };
+static PyObject * MainParticle2_stop(MainParticle2 *self) { STOP };
+
+static PyObject *
+MainParticle2_setDens(MainParticle2 *self, PyObject *arg)
+{
+ PyObject *tmp, *streamtmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ int isNumber = PyNumber_Check(arg);
+
+ tmp = arg;
+ Py_INCREF(tmp);
+ Py_DECREF(self->dens);
+ if (isNumber == 1) {
+ self->dens = PyNumber_Float(tmp);
+ self->modebuffer[0] = 0;
+ }
+ else {
+ self->dens = tmp;
+ streamtmp = PyObject_CallMethod((PyObject *)self->dens, "_getStream", NULL);
+ Py_INCREF(streamtmp);
+ Py_XDECREF(self->dens_stream);
+ self->dens_stream = (Stream *)streamtmp;
+ self->modebuffer[0] = 1;
+ }
+
+ (*self->mode_func_ptr)(self);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+MainParticle2_setPitch(MainParticle2 *self, PyObject *arg)
+{
+ PyObject *tmp, *streamtmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ int isNumber = PyNumber_Check(arg);
+
+ tmp = arg;
+ Py_INCREF(tmp);
+ Py_DECREF(self->pitch);
+ if (isNumber == 1) {
+ self->pitch = PyNumber_Float(tmp);
+ self->modebuffer[1] = 0;
+ }
+ else {
+ self->pitch = tmp;
+ streamtmp = PyObject_CallMethod((PyObject *)self->pitch, "_getStream", NULL);
+ Py_INCREF(streamtmp);
+ Py_XDECREF(self->pitch_stream);
+ self->pitch_stream = (Stream *)streamtmp;
+ self->modebuffer[1] = 1;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+MainParticle2_setPos(MainParticle2 *self, PyObject *arg)
+{
+ PyObject *tmp, *streamtmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ int isNumber = PyNumber_Check(arg);
+
+ tmp = arg;
+ Py_INCREF(tmp);
+ Py_DECREF(self->pos);
+ if (isNumber == 1) {
+ self->pos = PyNumber_Float(tmp);
+ self->modebuffer[2] = 0;
+ }
+ else {
+ self->pos = tmp;
+ streamtmp = PyObject_CallMethod((PyObject *)self->pos, "_getStream", NULL);
+ Py_INCREF(streamtmp);
+ Py_XDECREF(self->pos_stream);
+ self->pos_stream = (Stream *)streamtmp;
+ self->modebuffer[2] = 1;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+MainParticle2_setDur(MainParticle2 *self, PyObject *arg)
+{
+ PyObject *tmp, *streamtmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ int isNumber = PyNumber_Check(arg);
+
+ tmp = arg;
+ Py_INCREF(tmp);
+ Py_DECREF(self->dur);
+ if (isNumber == 1) {
+ self->dur = PyNumber_Float(tmp);
+ self->modebuffer[3] = 0;
+ }
+ else {
+ self->dur = tmp;
+ streamtmp = PyObject_CallMethod((PyObject *)self->dur, "_getStream", NULL);
+ Py_INCREF(streamtmp);
+ Py_XDECREF(self->dur_stream);
+ self->dur_stream = (Stream *)streamtmp;
+ self->modebuffer[3] = 1;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+MainParticle2_setDev(MainParticle2 *self, PyObject *arg)
+{
+ PyObject *tmp, *streamtmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ int isNumber = PyNumber_Check(arg);
+
+ tmp = arg;
+ Py_INCREF(tmp);
+ Py_DECREF(self->dev);
+ if (isNumber == 1) {
+ self->dev = PyNumber_Float(tmp);
+ self->modebuffer[4] = 0;
+ }
+ else {
+ self->dev = tmp;
+ streamtmp = PyObject_CallMethod((PyObject *)self->dev, "_getStream", NULL);
+ Py_INCREF(streamtmp);
+ Py_XDECREF(self->dev_stream);
+ self->dev_stream = (Stream *)streamtmp;
+ self->modebuffer[4] = 1;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+MainParticle2_setPan(MainParticle2 *self, PyObject *arg)
+{
+ PyObject *tmp, *streamtmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ int isNumber = PyNumber_Check(arg);
+
+ tmp = arg;
+ Py_INCREF(tmp);
+ Py_DECREF(self->pan);
+ if (isNumber == 1) {
+ self->pan = PyNumber_Float(tmp);
+ self->modebuffer[5] = 0;
+ }
+ else {
+ self->pan = tmp;
+ streamtmp = PyObject_CallMethod((PyObject *)self->pan, "_getStream", NULL);
+ Py_INCREF(streamtmp);
+ Py_XDECREF(self->pan_stream);
+ self->pan_stream = (Stream *)streamtmp;
+ self->modebuffer[5] = 1;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+MainParticle2_setFilterfreq(MainParticle2 *self, PyObject *arg)
+{
+ PyObject *tmp, *streamtmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ int isNumber = PyNumber_Check(arg);
+
+ tmp = arg;
+ Py_INCREF(tmp);
+ Py_DECREF(self->filterfreq);
+ if (isNumber == 1) {
+ self->filterfreq = PyNumber_Float(tmp);
+ self->modebuffer[6] = 0;
+ }
+ else {
+ self->filterfreq = tmp;
+ streamtmp = PyObject_CallMethod((PyObject *)self->filterfreq, "_getStream", NULL);
+ Py_INCREF(streamtmp);
+ Py_XDECREF(self->filterfreq_stream);
+ self->filterfreq_stream = (Stream *)streamtmp;
+ self->modebuffer[6] = 1;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+MainParticle2_setFilterq(MainParticle2 *self, PyObject *arg)
+{
+ PyObject *tmp, *streamtmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ int isNumber = PyNumber_Check(arg);
+
+ tmp = arg;
+ Py_INCREF(tmp);
+ Py_DECREF(self->filterq);
+ if (isNumber == 1) {
+ self->filterq = PyNumber_Float(tmp);
+ self->modebuffer[7] = 0;
+ }
+ else {
+ self->filterq = tmp;
+ streamtmp = PyObject_CallMethod((PyObject *)self->filterq, "_getStream", NULL);
+ Py_INCREF(streamtmp);
+ Py_XDECREF(self->filterq_stream);
+ self->filterq_stream = (Stream *)streamtmp;
+ self->modebuffer[7] = 1;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+MainParticle2_setFiltertype(MainParticle2 *self, PyObject *arg)
+{
+ PyObject *tmp, *streamtmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ int isNumber = PyNumber_Check(arg);
+
+ tmp = arg;
+ Py_INCREF(tmp);
+ Py_DECREF(self->filtertype);
+ if (isNumber == 1) {
+ self->filtertype = PyNumber_Float(tmp);
+ self->modebuffer[8] = 0;
+ }
+ else {
+ self->filtertype = tmp;
+ streamtmp = PyObject_CallMethod((PyObject *)self->filtertype, "_getStream", NULL);
+ Py_INCREF(streamtmp);
+ Py_XDECREF(self->filtertype_stream);
+ self->filtertype_stream = (Stream *)streamtmp;
+ self->modebuffer[8] = 1;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+MainParticle2_getTable(MainParticle2* self)
+{
+ Py_INCREF(self->table);
+ return self->table;
+};
+
+static PyObject *
+MainParticle2_setTable(MainParticle2 *self, PyObject *arg)
+{
+ PyObject *tmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ tmp = arg;
+ Py_DECREF(self->table);
+ self->table = PyObject_CallMethod((PyObject *)tmp, "getTableStream", "");
+ self->srScale = TableStream_getSamplingRate(self->table) / self->sr;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+MainParticle2_getEnv(MainParticle2* self)
+{
+ Py_INCREF(self->env);
+ return self->env;
+};
+
+static PyObject *
+MainParticle2_setEnv(MainParticle2 *self, PyObject *arg)
+{
+ PyObject *tmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ tmp = arg;
+ Py_DECREF(self->env);
+ self->env = PyObject_CallMethod((PyObject *)tmp, "getTableStream", "");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMemberDef MainParticle2_members[] = {
+ {"server", T_OBJECT_EX, offsetof(MainParticle2, server), 0, "Pyo server."},
+ {"stream", T_OBJECT_EX, offsetof(MainParticle2, stream), 0, "Stream object."},
+ {"table", T_OBJECT_EX, offsetof(MainParticle2, table), 0, "Sound table."},
+ {"env", T_OBJECT_EX, offsetof(MainParticle2, env), 0, "Envelope table."},
+ {"dens", T_OBJECT_EX, offsetof(MainParticle2, dens), 0, "Density of grains per second."},
+ {"pitch", T_OBJECT_EX, offsetof(MainParticle2, pitch), 0, "Speed of the reading pointer."},
+ {"pos", T_OBJECT_EX, offsetof(MainParticle2, pos), 0, "Position in the sound table."},
+ {"dur", T_OBJECT_EX, offsetof(MainParticle2, dur), 0, "Duration of each grains."},
+ {"dev", T_OBJECT_EX, offsetof(MainParticle2, dev), 0, "Grain start point deviation factor."},
+ {"pan", T_OBJECT_EX, offsetof(MainParticle2, pan), 0, "Grain panning factor."},
+ {"filterfreq", T_OBJECT_EX, offsetof(MainParticle2, filterfreq), 0, "Grain filter center/cutoff frequency."},
+ {"filterq", T_OBJECT_EX, offsetof(MainParticle2, filterq), 0, "Grain filter Q."},
+ {"filtertype", T_OBJECT_EX, offsetof(MainParticle2, filtertype), 0, "Grain filter type."},
+ {NULL} /* Sentinel */
+};
+
+static PyMethodDef MainParticle2_methods[] = {
+ {"getTable", (PyCFunction)MainParticle2_getTable, METH_NOARGS, "Returns sound table object."},
+ {"setTable", (PyCFunction)MainParticle2_setTable, METH_O, "Sets sound table."},
+ {"getEnv", (PyCFunction)MainParticle2_getEnv, METH_NOARGS, "Returns envelope table object."},
+ {"setEnv", (PyCFunction)MainParticle2_setEnv, METH_O, "Sets envelope table."},
+ {"getServer", (PyCFunction)MainParticle2_getServer, METH_NOARGS, "Returns server object."},
+ {"_getStream", (PyCFunction)MainParticle2_getStream, METH_NOARGS, "Returns stream object."},
+ {"play", (PyCFunction)MainParticle2_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
+ {"stop", (PyCFunction)MainParticle2_stop, METH_NOARGS, "Stops computing."},
+ {"setDens", (PyCFunction)MainParticle2_setDens, METH_O, "Sets the density of grains per second."},
+ {"setPitch", (PyCFunction)MainParticle2_setPitch, METH_O, "Sets global pitch factor."},
+ {"setPos", (PyCFunction)MainParticle2_setPos, METH_O, "Sets position in the sound table."},
+ {"setDur", (PyCFunction)MainParticle2_setDur, METH_O, "Sets the grain duration."},
+ {"setDev", (PyCFunction)MainParticle2_setDev, METH_O, "Sets grain start point deviation factor."},
+ {"setPan", (PyCFunction)MainParticle2_setPan, METH_O, "Sets grain panning factor."},
+ {"setFilterfreq", (PyCFunction)MainParticle2_setFilterfreq, METH_O, "Sets grain filter center/cutoff frequency."},
+ {"setFilterq", (PyCFunction)MainParticle2_setFilterq, METH_O, "Sets grain filter Q."},
+ {"setFiltertype", (PyCFunction)MainParticle2_setFiltertype, METH_O, "Sets grain filter type."},
+ {NULL} /* Sentinel */
+};
+
+PyTypeObject MainParticle2Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "_pyo.MainParticle2_base", /*tp_name*/
+ sizeof(MainParticle2), /*tp_basicpitch*/
+ 0, /*tp_itempitch*/
+ (destructor)MainParticle2_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_as_async (tp_compare in Python 2)*/
+ 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*/
+ "MainParticle2 objects. Accumulation of multiples bandpass filtered grains of sound.", /* tp_doc */
+ (traverseproc)MainParticle2_traverse, /* tp_traverse */
+ (inquiry)MainParticle2_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ MainParticle2_methods, /* tp_methods */
+ MainParticle2_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 */
+ MainParticle2_new, /* tp_new */
+};
+
+typedef struct {
+ pyo_audio_HEAD
+ MainParticle2 *mainSplitter;
+ int modebuffer[2];
+ int chnl; // panning order
+} Particle2;
+
+static void Particle2_postprocessing_ii(Particle2 *self) { POST_PROCESSING_II };
+static void Particle2_postprocessing_ai(Particle2 *self) { POST_PROCESSING_AI };
+static void Particle2_postprocessing_ia(Particle2 *self) { POST_PROCESSING_IA };
+static void Particle2_postprocessing_aa(Particle2 *self) { POST_PROCESSING_AA };
+static void Particle2_postprocessing_ireva(Particle2 *self) { POST_PROCESSING_IREVA };
+static void Particle2_postprocessing_areva(Particle2 *self) { POST_PROCESSING_AREVA };
+static void Particle2_postprocessing_revai(Particle2 *self) { POST_PROCESSING_REVAI };
+static void Particle2_postprocessing_revaa(Particle2 *self) { POST_PROCESSING_REVAA };
+static void Particle2_postprocessing_revareva(Particle2 *self) { POST_PROCESSING_REVAREVA };
+
+static void
+Particle2_setProcMode(Particle2 *self)
+{
+ int muladdmode;
+ muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
+
+ switch (muladdmode) {
+ case 0:
+ self->muladd_func_ptr = Particle2_postprocessing_ii;
+ break;
+ case 1:
+ self->muladd_func_ptr = Particle2_postprocessing_ai;
+ break;
+ case 2:
+ self->muladd_func_ptr = Particle2_postprocessing_revai;
+ break;
+ case 10:
+ self->muladd_func_ptr = Particle2_postprocessing_ia;
+ break;
+ case 11:
+ self->muladd_func_ptr = Particle2_postprocessing_aa;
+ break;
+ case 12:
+ self->muladd_func_ptr = Particle2_postprocessing_revaa;
+ break;
+ case 20:
+ self->muladd_func_ptr = Particle2_postprocessing_ireva;
+ break;
+ case 21:
+ self->muladd_func_ptr = Particle2_postprocessing_areva;
+ break;
+ case 22:
+ self->muladd_func_ptr = Particle2_postprocessing_revareva;
+ break;
+ }
+}
+
+static void
+Particle2_compute_next_data_frame(Particle2 *self)
+{
+ int i;
+ MYFLT *tmp;
+ int offset = self->chnl * self->bufsize;
+ tmp = MainParticle2_getSamplesBuffer((MainParticle2 *)self->mainSplitter);
+ for (i=0; i<self->bufsize; i++) {
+ self->data[i] = tmp[i + offset];
+ }
+ (*self->muladd_func_ptr)(self);
+}
+
+static int
+Particle2_traverse(Particle2 *self, visitproc visit, void *arg)
+{
+ pyo_VISIT
+ Py_VISIT(self->mainSplitter);
+ return 0;
+}
+
+static int
+Particle2_clear(Particle2 *self)
+{
+ pyo_CLEAR
+ Py_CLEAR(self->mainSplitter);
+ return 0;
+}
+
+static void
+Particle2_dealloc(Particle2* self)
+{
+ pyo_DEALLOC
+ Particle2_clear(self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+static PyObject *
+Particle2_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ int i;
+ PyObject *maintmp=NULL, *multmp=NULL, *addtmp=NULL;
+ Particle2 *self;
+ self = (Particle2 *)type->tp_alloc(type, 0);
+
+ self->modebuffer[0] = 0;
+ self->modebuffer[1] = 0;
+
+ INIT_OBJECT_COMMON
+ Stream_setFunctionPtr(self->stream, Particle2_compute_next_data_frame);
+ self->mode_func_ptr = Particle2_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 = (MainParticle2 *)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 * Particle2_getServer(Particle2* self) { GET_SERVER };
+static PyObject * Particle2_getStream(Particle2* self) { GET_STREAM };
+static PyObject * Particle2_setMul(Particle2 *self, PyObject *arg) { SET_MUL };
+static PyObject * Particle2_setAdd(Particle2 *self, PyObject *arg) { SET_ADD };
+static PyObject * Particle2_setSub(Particle2 *self, PyObject *arg) { SET_SUB };
+static PyObject * Particle2_setDiv(Particle2 *self, PyObject *arg) { SET_DIV };
+
+static PyObject * Particle2_play(Particle2 *self, PyObject *args, PyObject *kwds) { PLAY };
+static PyObject * Particle2_out(Particle2 *self, PyObject *args, PyObject *kwds) { OUT };
+static PyObject * Particle2_stop(Particle2 *self) { STOP };
+
+static PyObject * Particle2_multiply(Particle2 *self, PyObject *arg) { MULTIPLY };
+static PyObject * Particle2_inplace_multiply(Particle2 *self, PyObject *arg) { INPLACE_MULTIPLY };
+static PyObject * Particle2_add(Particle2 *self, PyObject *arg) { ADD };
+static PyObject * Particle2_inplace_add(Particle2 *self, PyObject *arg) { INPLACE_ADD };
+static PyObject * Particle2_sub(Particle2 *self, PyObject *arg) { SUB };
+static PyObject * Particle2_inplace_sub(Particle2 *self, PyObject *arg) { INPLACE_SUB };
+static PyObject * Particle2_div(Particle2 *self, PyObject *arg) { DIV };
+static PyObject * Particle2_inplace_div(Particle2 *self, PyObject *arg) { INPLACE_DIV };
+
+static PyMemberDef Particle2_members[] = {
+{"server", T_OBJECT_EX, offsetof(Particle2, server), 0, "Pyo server."},
+{"stream", T_OBJECT_EX, offsetof(Particle2, stream), 0, "Stream object."},
+{"mul", T_OBJECT_EX, offsetof(Particle2, mul), 0, "Mul factor."},
+{"add", T_OBJECT_EX, offsetof(Particle2, add), 0, "Add factor."},
+{NULL} /* Sentinel */
+};
+
+static PyMethodDef Particle2_methods[] = {
+{"getServer", (PyCFunction)Particle2_getServer, METH_NOARGS, "Returns server object."},
+{"_getStream", (PyCFunction)Particle2_getStream, METH_NOARGS, "Returns stream object."},
+{"play", (PyCFunction)Particle2_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
+{"out", (PyCFunction)Particle2_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
+{"stop", (PyCFunction)Particle2_stop, METH_NOARGS, "Stops computing."},
+{"setMul", (PyCFunction)Particle2_setMul, METH_O, "Sets Particle2 mul factor."},
+{"setAdd", (PyCFunction)Particle2_setAdd, METH_O, "Sets Particle2 add factor."},
+{"setSub", (PyCFunction)Particle2_setSub, METH_O, "Sets inverse add factor."},
+{"setDiv", (PyCFunction)Particle2_setDiv, METH_O, "Sets inverse mul factor."},
+{NULL} /* Sentinel */
+};
+
+static PyNumberMethods Particle2_as_number = {
+(binaryfunc)Particle2_add, /*nb_add*/
+(binaryfunc)Particle2_sub, /*nb_subtract*/
+(binaryfunc)Particle2_multiply, /*nb_multiply*/
+INITIALIZE_NB_DIVIDE_ZERO /*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*/
+INITIALIZE_NB_COERCE_ZERO /*nb_coerce*/
+0, /*nb_int*/
+0, /*nb_long*/
+0, /*nb_float*/
+INITIALIZE_NB_OCT_ZERO /*nb_oct*/
+INITIALIZE_NB_HEX_ZERO /*nb_hex*/
+(binaryfunc)Particle2_inplace_add, /*inplace_add*/
+(binaryfunc)Particle2_inplace_sub, /*inplace_subtract*/
+(binaryfunc)Particle2_inplace_multiply, /*inplace_multiply*/
+INITIALIZE_NB_IN_PLACE_DIVIDE_ZERO /*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*/
+(binaryfunc)Particle2_div, /*nb_true_divide*/
+0, /*nb_inplace_floor_divide*/
+(binaryfunc)Particle2_inplace_div, /*nb_inplace_true_divide*/
+0, /* nb_index */
+};
+
+PyTypeObject Particle2Type = {
+PyVarObject_HEAD_INIT(NULL, 0)
+"_pyo.Particle2_base", /*tp_name*/
+sizeof(Particle2), /*tp_basicsize*/
+0, /*tp_itemsize*/
+(destructor)Particle2_dealloc, /*tp_dealloc*/
+0, /*tp_print*/
+0, /*tp_getattr*/
+0, /*tp_setattr*/
+0, /*tp_as_async (tp_compare in Python 2)*/
+0, /*tp_repr*/
+&Particle2_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*/
+"Particle2 objects. Reads one band from a MainParticle2 object.", /* tp_doc */
+(traverseproc)Particle2_traverse, /* tp_traverse */
+(inquiry)Particle2_clear, /* tp_clear */
+0, /* tp_richcompare */
+0, /* tp_weaklistoffset */
+0, /* tp_iter */
+0, /* tp_iternext */
+Particle2_methods, /* tp_methods */
+Particle2_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 */
+Particle2_new, /* tp_new */
};
\ No newline at end of file
diff --git a/src/objects/matrixmodule.c b/src/objects/matrixmodule.c
index a5d375b..38f0d28 100644
--- a/src/objects/matrixmodule.c
+++ b/src/objects/matrixmodule.c
@@ -604,7 +604,6 @@ MatrixRec_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
INIT_OBJECT_COMMON
Stream_setFunctionPtr(self->stream, MatrixRec_compute_next_data_frame);
- Stream_setStreamActive(self->stream, 0);
static char *kwlist[] = {"input", "matrix", "fadetime", "delay", NULL};
diff --git a/src/objects/metromodule.c b/src/objects/metromodule.c
index 1262243..adff001 100644
--- a/src/objects/metromodule.c
+++ b/src/objects/metromodule.c
@@ -389,16 +389,16 @@ typedef struct {
int modebuffer[1];
double sampleToSec;
double currentTime;
- double duration;
- int *seq;
- int count;
+ double *seq;
+ double when;
MYFLT *buffer_streams;
int seqsize;
int poly;
- int flag;
int tap;
int voiceCount;
int newseq;
+ int onlyonce;
+ int to_stop;
} Seqer;
static void
@@ -407,9 +407,9 @@ Seqer_reset(Seqer *self)
int i;
self->seqsize = PyList_Size(self->tmp);
- self->seq = (int *)realloc(self->seq, self->seqsize * sizeof(int));
+ self->seq = (double *)realloc(self->seq, self->seqsize * sizeof(double));
for (i=0; i<self->seqsize; i++) {
- self->seq[i] = PyInt_AS_LONG(PyNumber_Int(PyList_GET_ITEM(self->tmp, i)));
+ self->seq[i] = PyFloat_AsDouble(PyList_GET_ITEM(self->tmp, i));
}
self->newseq = 0;
}
@@ -421,30 +421,33 @@ Seqer_generate_i(Seqer *self) {
tm = PyFloat_AS_DOUBLE(self->time);
- if (self->currentTime == -1.0) {
- self->currentTime = tm;
- }
-
for (i=0; i<(self->poly*self->bufsize); i++) {
self->buffer_streams[i] = 0.0;
}
+ if (self->to_stop) {
+ PyObject_CallMethod((PyObject *)self, "stop", NULL);
+ self->to_stop = 0;
+ return;
+ }
+
for (i=0; i<self->bufsize; i++) {
self->currentTime += self->sampleToSec;
- if (self->currentTime >= tm) {
- self->currentTime -= tm;
- self->count++;
- if (self->count >= self->seq[self->tap]) {
- self->count = 0;
- self->buffer_streams[i + self->voiceCount * self->bufsize] = 1.0;
- self->voiceCount++;
- if (self->voiceCount >= self->poly)
- self->voiceCount = 0;
- self->tap++;
- if (self->tap >= self->seqsize) {
- self->tap = 0;
- if (self->newseq == 1)
- Seqer_reset(self);
+ if (self->currentTime >= self->when) {
+ self->currentTime -= self->when;
+ self->when = self->seq[self->tap] * tm;
+ self->buffer_streams[i + self->voiceCount * self->bufsize] = 1.0;
+ self->voiceCount++;
+ if (self->voiceCount >= self->poly)
+ self->voiceCount = 0;
+ self->tap++;
+ if (self->tap >= self->seqsize) {
+ self->tap = 0;
+ if (self->newseq == 1)
+ Seqer_reset(self);
+ if (self->onlyonce) {
+ self->to_stop = 1;
+ return;
}
}
}
@@ -453,36 +456,37 @@ Seqer_generate_i(Seqer *self) {
static void
Seqer_generate_a(Seqer *self) {
- double tm;
int i;
MYFLT *time = Stream_getData((Stream *)self->time_stream);
- if (self->currentTime == -1.0) {
- self->currentTime = time[0];
- }
-
for (i=0; i<(self->poly*self->bufsize); i++) {
self->buffer_streams[i] = 0.0;
}
+ if (self->to_stop) {
+ PyObject_CallMethod((PyObject *)self, "stop", NULL);
+ self->to_stop = 0;
+ return;
+ }
+
for (i=0; i<self->bufsize; i++) {
- tm = (double)time[i];
self->currentTime += self->sampleToSec;
- if (self->currentTime >= tm) {
- self->currentTime -= tm;
- self->count++;
- if (self->count >= self->seq[self->tap]) {
- self->count = 0;
- self->buffer_streams[i + self->voiceCount * self->bufsize] = 1.0;
- self->voiceCount++;
- if (self->voiceCount >= self->poly)
- self->voiceCount = 0;
- self->tap++;
- if (self->tap >= self->seqsize) {
- self->tap = 0;
- if (self->newseq == 1)
- Seqer_reset(self);
+ if (self->currentTime >= self->when) {
+ self->currentTime -= self->when;
+ self->when = self->seq[self->tap] * (double)time[i];
+ self->buffer_streams[i + self->voiceCount * self->bufsize] = 1.0;
+ self->voiceCount++;
+ if (self->voiceCount >= self->poly)
+ self->voiceCount = 0;
+ self->tap++;
+ if (self->tap >= self->seqsize) {
+ self->tap = 0;
+ if (self->newseq == 1)
+ Seqer_reset(self);
+ if (self->onlyonce) {
+ self->to_stop = 1;
+ return;
}
}
}
@@ -539,6 +543,7 @@ static void
Seqer_dealloc(Seqer* self)
{
pyo_DEALLOC
+ free(self->seq);
free(self->buffer_streams);
Seqer_clear(self);
Py_TYPE(self)->tp_free((PyObject*)self);
@@ -553,16 +558,15 @@ Seqer_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self = (Seqer *)type->tp_alloc(type, 0);
self->time = PyFloat_FromDouble(1.);
- self->flag = 1;
self->poly = 1;
self->seqsize = 1;
- self->seq = (int *)realloc(self->seq, self->seqsize * sizeof(int));
- self->seq[0] = 1;
+ self->seq = (double *)realloc(self->seq, self->seqsize * sizeof(double));
+ self->seq[0] = 1.0;
self->newseq = 0;
- self->duration = -1.0;
self->tap = 0;
- self->count = 0;
self->voiceCount = 0;
+ self->onlyonce = 0;
+ self->to_stop = 0;
self->modebuffer[0] = 0;
INIT_OBJECT_COMMON
@@ -572,11 +576,11 @@ Seqer_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Stream_setStreamActive(self->stream, 0);
self->sampleToSec = 1.0 / self->sr;
- self->currentTime = -1.0;
+ self->currentTime = 0.0;
- static char *kwlist[] = {"time", "seq", "poly", NULL};
+ static char *kwlist[] = {"time", "seq", "poly", "onlyonce", NULL};
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist, &timetmp, &seqtmp, &self->poly))
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOii", kwlist, &timetmp, &seqtmp, &self->poly, &self->onlyonce))
Py_RETURN_NONE;
if (timetmp) {
@@ -586,6 +590,7 @@ Seqer_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (seqtmp) {
PyObject_CallMethod((PyObject *)self, "setSeq", "O", seqtmp);
}
+ Seqer_reset(self);
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
@@ -599,7 +604,13 @@ Seqer_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static PyObject * Seqer_getServer(Seqer* self) { GET_SERVER };
static PyObject * Seqer_getStream(Seqer* self) { GET_STREAM };
-static PyObject * Seqer_play(Seqer *self, PyObject *args, PyObject *kwds) { PLAY };
+static PyObject * Seqer_play(Seqer *self, PyObject *args, PyObject *kwds) {
+ self->currentTime = 0.0;
+ self->when = 0.0;
+ self->tap = 0;
+ self->voiceCount = 0;
+ PLAY
+};
static PyObject * Seqer_stop(Seqer *self) { STOP };
static PyObject *
@@ -654,6 +665,21 @@ Seqer_setSeq(Seqer *self, PyObject *arg)
return Py_None;
}
+static PyObject *
+Seqer_setOnlyonce(Seqer *self, PyObject *arg)
+{
+ ASSERT_ARG_NOT_NULL
+
+ int isInt = PyInt_Check(arg);
+
+ if (isInt == 1) {
+ self->onlyonce = PyLong_AsLong(arg);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
static PyMemberDef Seqer_members[] = {
{"server", T_OBJECT_EX, offsetof(Seqer, server), 0, "Pyo server."},
{"stream", T_OBJECT_EX, offsetof(Seqer, stream), 0, "Stream object."},
@@ -668,6 +694,7 @@ static PyMethodDef Seqer_methods[] = {
{"stop", (PyCFunction)Seqer_stop, METH_NOARGS, "Stops computing."},
{"setTime", (PyCFunction)Seqer_setTime, METH_O, "Sets time factor."},
{"setSeq", (PyCFunction)Seqer_setSeq, METH_O, "Sets duration sequence."},
+ {"setOnlyonce", (PyCFunction)Seqer_setOnlyonce, METH_O, "Sets onlyonce attribute."},
{NULL} /* Sentinel */
};
@@ -1745,6 +1772,8 @@ typedef struct {
MYFLT tapDur;
double sampleToSec;
double currentTime;
+ int onlyonce;
+ int to_stop;
MYFLT *buffer_streams;
MYFLT *tap_buffer_streams;
MYFLT *amp_buffer_streams;
@@ -1964,6 +1993,12 @@ Beater_generate_i(Beater *self) {
self->buffer_streams[i] = self->end_buffer_streams[i] = 0.0;
}
+ if (self->to_stop) {
+ PyObject_CallMethod((PyObject *)self, "stop", NULL);
+ self->to_stop = 0;
+ return;
+ }
+
for (i=0; i<self->bufsize; i++) {
self->tap_buffer_streams[i + self->voiceCount * self->bufsize] = (MYFLT)self->currentTap;
for (j=0; j<self->poly; j++) {
@@ -1972,8 +2007,9 @@ Beater_generate_i(Beater *self) {
self->dur_buffer_streams[i + self->voiceCount * self->bufsize] = self->durations[self->tapCount];
if (self->currentTime >= tm) {
self->currentTime -= tm;
- if (self->tapCount == (self->last_taps-2))
+ if (self->tapCount == (self->last_taps-2)) {
self->end_buffer_streams[i + self->voiceCount * self->bufsize] = 1.0;
+ }
if (self->sequence[self->tapCount] == 1) {
self->currentTap = self->tapCount;
self->amplitudes[self->voiceCount] = self->accentTable[self->tapCount];
@@ -2009,6 +2045,10 @@ Beater_generate_i(Beater *self) {
Beater_makeTable(self, 0);
Beater_makeSequence(self);
}
+ if (self->onlyonce) {
+ self->to_stop = 1;
+ return;
+ }
}
}
self->currentTime += self->sampleToSec;
@@ -2033,6 +2073,12 @@ Beater_generate_a(Beater *self) {
self->buffer_streams[i] = self->end_buffer_streams[i] = 0.0;
}
+ if (self->to_stop) {
+ PyObject_CallMethod((PyObject *)self, "stop", NULL);
+ self->to_stop = 0;
+ return;
+ }
+
for (i=0; i<self->bufsize; i++) {
tm = (double)time[i];
self->tap_buffer_streams[i + self->voiceCount * self->bufsize] = (MYFLT)self->currentTap;
@@ -2080,6 +2126,10 @@ Beater_generate_a(Beater *self) {
Beater_makeTable(self, 0);
Beater_makeSequence(self);
}
+ if (self->onlyonce) {
+ self->to_stop = 1;
+ return;
+ }
}
}
self->currentTime += self->sampleToSec;
@@ -2186,6 +2236,8 @@ Beater_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->time = PyFloat_FromDouble(0.125);
self->tapDur = 0.125;
self->poly = 1;
+ self->onlyonce = 0;
+ self->to_stop = 0;
self->voiceCount = 0;
self->modebuffer[0] = 0;
@@ -2208,9 +2260,9 @@ Beater_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Stream_setStreamActive(self->stream, 0);
- static char *kwlist[] = {"time", "taps", "weight1", "weight2", "weight3", "poly", NULL};
+ static char *kwlist[] = {"time", "taps", "weight1", "weight2", "weight3", "poly", "onlyonce", NULL};
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|Oiiiii", kwlist, &timetmp, &self->taps, &self->weight1, &self->weight2, &self->weight3, &self->poly))
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "|Oiiiiii", kwlist, &timetmp, &self->taps, &self->weight1, &self->weight2, &self->weight3, &self->poly, &self->onlyonce))
Py_RETURN_NONE;
if (timetmp) {
@@ -2245,7 +2297,14 @@ Beater_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static PyObject * Beater_getServer(Beater* self) { GET_SERVER };
static PyObject * Beater_getStream(Beater* self) { GET_STREAM };
-static PyObject * Beater_play(Beater *self, PyObject *args, PyObject *kwds) { PLAY };
+static PyObject * Beater_play(Beater *self, PyObject *args, PyObject *kwds) {
+ self->to_stop = 0;
+ self->voiceCount = 0;
+ self->tapCount = 0;
+ self->currentTap = 0;
+ self->currentTime = -1.0;
+ PLAY
+};
static PyObject * Beater_stop(Beater *self) { STOP };
static PyObject *
@@ -2329,9 +2388,17 @@ Beater_setWeights(Beater *self, PyObject *args, PyObject *kwds)
}
static PyObject *
-Beater_newPattern(Beater *self)
+Beater_newPattern(Beater *self, PyObject *arg)
{
- self->newFlag = 1;
+ if (PyInt_Check(arg)) {
+ if (PyInt_AsLong(arg)) {
+ Beater_makeTable(self, 0);
+ Beater_makeSequence(self);
+ }
+ else {
+ self->newFlag = 1;
+ }
+ }
Py_INCREF(Py_None);
return Py_None;
}
@@ -2421,6 +2488,21 @@ Beater_setPresets(Beater *self, PyObject *arg) {
return Py_None;
}
+static PyObject *
+Beater_setOnlyonce(Beater *self, PyObject *arg)
+{
+ ASSERT_ARG_NOT_NULL
+
+ int isInt = PyInt_Check(arg);
+
+ if (isInt == 1) {
+ self->onlyonce = PyLong_AsLong(arg);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
static PyMemberDef Beater_members[] = {
{"server", T_OBJECT_EX, offsetof(Beater, server), 0, "Pyo server."},
{"stream", T_OBJECT_EX, offsetof(Beater, stream), 0, "Stream object."},
@@ -2436,12 +2518,13 @@ static PyMethodDef Beater_methods[] = {
{"setTime", (PyCFunction)Beater_setTime, METH_O, "Sets tap duration."},
{"setTaps", (PyCFunction)Beater_setTaps, METH_O, "Sets number of taps in the pattern."},
{"setWeights", (PyCFunction)Beater_setWeights, METH_VARARGS|METH_KEYWORDS, "Sets probabilities for time accents in the pattern."},
- {"new", (PyCFunction)Beater_newPattern, METH_NOARGS, "Generates a new pattern."},
+ {"new", (PyCFunction)Beater_newPattern, METH_O, "Generates a new pattern."},
{"fill", (PyCFunction)Beater_fillPattern, METH_NOARGS, "Generates a fillin pattern and then restore the current pattern."},
{"store", (PyCFunction)Beater_storePreset, METH_O, "Store the current pattern in a memory slot."},
{"recall", (PyCFunction)Beater_recallPreset, METH_O, "Recall a pattern previously stored in a memory slot."},
{"getPresets", (PyCFunction)Beater_getPresets, METH_NOARGS, "Returns the list of stored presets."},
{"setPresets", (PyCFunction)Beater_setPresets, METH_O, "Store a list of presets."},
+ {"setOnlyonce", (PyCFunction)Beater_setOnlyonce, METH_O, "Sets onlyonce attribute."},
{"reset", (PyCFunction)Beater_reset, METH_NOARGS, "Resets counters to 0."},
{NULL} /* Sentinel */
};
diff --git a/src/objects/midimodule.c b/src/objects/midimodule.c
index a07b7c6..f5d4f98 100644
--- a/src/objects/midimodule.c
+++ b/src/objects/midimodule.c
@@ -48,8 +48,8 @@ CtlScan_compute_next_data_frame(CtlScan *self)
if (count > 0) {
PyObject *tup;
- for (i=count-1; i>=0; i--) {
- int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
+ for (i=0; i<count; i++) {
+ int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
int number = PyoMidi_MessageData1(buffer[i].message);
int value = PyoMidi_MessageData2(buffer[i].message);
@@ -130,40 +130,40 @@ static PyObject *
CtlScan_reset(CtlScan *self)
{
self->ctlnumber = -1;
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
};
static PyObject *
CtlScan_setFunction(CtlScan *self, PyObject *arg)
{
- PyObject *tmp;
+ PyObject *tmp;
- if (! PyCallable_Check(arg)) {
+ if (! PyCallable_Check(arg)) {
PyErr_SetString(PyExc_TypeError, "The callable attribute must be a valid Python function.");
- Py_INCREF(Py_None);
- return Py_None;
- }
+ 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;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyObject *
CtlScan_setToprint(CtlScan *self, PyObject *arg)
{
- if (PyInt_Check(arg)) {
- self->toprint = PyInt_AsLong(arg);
+ if (PyInt_Check(arg)) {
+ self->toprint = PyInt_AsLong(arg);
}
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyMemberDef CtlScan_members[] = {
{"server", T_OBJECT_EX, offsetof(CtlScan, server), 0, "Pyo server."},
@@ -206,10 +206,10 @@ PyTypeObject CtlScanType = {
"CtlScan objects. Retreive controller numbers from a Midi input.", /* tp_doc */
(traverseproc)CtlScan_traverse, /* tp_traverse */
(inquiry)CtlScan_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
CtlScan_methods, /* tp_methods */
CtlScan_members, /* tp_members */
0, /* tp_getset */
@@ -245,8 +245,8 @@ CtlScan2_compute_next_data_frame(CtlScan2 *self)
if (count > 0) {
PyObject *tup;
- for (i=count-1; i>=0; i--) {
- int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
+ for (i=0; i<count; i++) {
+ int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
int number = PyoMidi_MessageData1(buffer[i].message);
int value = PyoMidi_MessageData2(buffer[i].message);
@@ -330,40 +330,40 @@ static PyObject *
CtlScan2_reset(CtlScan2 *self)
{
self->ctlnumber = self->midichnl = -1;
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
};
static PyObject *
CtlScan2_setFunction(CtlScan2 *self, PyObject *arg)
{
- PyObject *tmp;
+ PyObject *tmp;
- if (! PyCallable_Check(arg)) {
+ if (! PyCallable_Check(arg)) {
PyErr_SetString(PyExc_TypeError, "The callable attribute must be a valid Python function.");
- Py_INCREF(Py_None);
- return Py_None;
- }
+ 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;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyObject *
CtlScan2_setToprint(CtlScan2 *self, PyObject *arg)
{
- if (PyInt_Check(arg)) {
- self->toprint = PyInt_AsLong(arg);
+ if (PyInt_Check(arg)) {
+ self->toprint = PyInt_AsLong(arg);
}
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyMemberDef CtlScan2_members[] = {
{"server", T_OBJECT_EX, offsetof(CtlScan2, server), 0, "Pyo server."},
@@ -406,10 +406,10 @@ PyTypeObject CtlScan2Type = {
"CtlScan2 objects. Retreive midi channel and controller numbers from a midi input.", /* tp_doc */
(traverseproc)CtlScan2_traverse, /* tp_traverse */
(inquiry)CtlScan2_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
CtlScan2_methods, /* tp_methods */
CtlScan2_members, /* tp_members */
0, /* tp_getset */
@@ -453,7 +453,7 @@ Midictl_setProcMode(Midictl *self)
int muladdmode;
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
- switch (muladdmode) {
+ switch (muladdmode) {
case 0:
self->muladd_func_ptr = Midictl_postprocessing_ii;
break;
@@ -488,8 +488,8 @@ Midictl_setProcMode(Midictl *self)
void translateMidi(Midictl *self, PyoMidiEvent *buffer, int count)
{
int i, ok;
- for (i=count-1; i>=0; i--) {
- int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
+ for (i=0; i<count; i++) {
+ int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
int number = PyoMidi_MessageData1(buffer[i].message);
int value = PyoMidi_MessageData2(buffer[i].message);
@@ -507,11 +507,11 @@ void translateMidi(Midictl *self, PyoMidiEvent *buffer, int count)
}
if (ok == 1 && number == self->ctlnumber) {
- self->oldValue = self->value;
self->value = (value / 127.) * (self->maxscale - self->minscale) + self->minscale;
break;
}
}
+ self->oldValue = self->value;
}
static void
@@ -576,9 +576,9 @@ Midictl_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->oldValue = 0.;
self->minscale = 0.;
self->maxscale = 1.;
- self->interp = 1;
- self->modebuffer[0] = 0;
- self->modebuffer[1] = 0;
+ self->interp = 0;
+ self->modebuffer[0] = 0;
+ self->modebuffer[1] = 0;
INIT_OBJECT_COMMON
Stream_setFunctionPtr(self->stream, Midictl_compute_next_data_frame);
@@ -632,18 +632,18 @@ Midictl_setInterpolation(Midictl *self, PyObject *arg)
ASSERT_ARG_NOT_NULL
- int isNum = PyInt_Check(arg);
+ int isNum = PyInt_Check(arg);
- if (isNum == 1) {
- tmp = PyInt_AsLong(arg);
+ if (isNum == 1) {
+ tmp = PyInt_AsLong(arg);
if (tmp == 0)
self->interp = 0;
else
self->interp = 1;
- }
+ }
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyObject *
@@ -653,15 +653,15 @@ Midictl_setValue(Midictl *self, PyObject *arg)
ASSERT_ARG_NOT_NULL
- int isNum = PyNumber_Check(arg);
+ int isNum = PyNumber_Check(arg);
- if (isNum == 1) {
- tmp = PyFloat_AsDouble(arg);
+ if (isNum == 1) {
+ tmp = PyFloat_AsDouble(arg);
self->oldValue = self->value = tmp;
- }
+ }
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyObject *
@@ -671,15 +671,15 @@ Midictl_setMinScale(Midictl *self, PyObject *arg)
ASSERT_ARG_NOT_NULL
- int isNum = PyNumber_Check(arg);
+ int isNum = PyNumber_Check(arg);
- if (isNum == 1) {
- tmp = PyFloat_AsDouble(arg);
+ if (isNum == 1) {
+ tmp = PyFloat_AsDouble(arg);
self->minscale = tmp;
- }
+ }
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyObject *
@@ -689,15 +689,15 @@ Midictl_setMaxScale(Midictl *self, PyObject *arg)
ASSERT_ARG_NOT_NULL
- int isNum = PyNumber_Check(arg);
+ int isNum = PyNumber_Check(arg);
- if (isNum == 1) {
- tmp = PyFloat_AsDouble(arg);
+ if (isNum == 1) {
+ tmp = PyFloat_AsDouble(arg);
self->maxscale = tmp;
- }
+ }
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyObject *
@@ -707,16 +707,16 @@ Midictl_setCtlNumber(Midictl *self, PyObject *arg)
ASSERT_ARG_NOT_NULL
- int isInt = PyInt_Check(arg);
+ int isInt = PyInt_Check(arg);
- if (isInt == 1) {
- tmp = PyInt_AsLong(arg);
+ if (isInt == 1) {
+ tmp = PyInt_AsLong(arg);
if (tmp >= 0 && tmp < 128)
self->ctlnumber = tmp;
- }
+ }
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyObject *
@@ -726,16 +726,16 @@ Midictl_setChannel(Midictl *self, PyObject *arg)
ASSERT_ARG_NOT_NULL
- int isInt = PyInt_Check(arg);
+ int isInt = PyInt_Check(arg);
- if (isInt == 1) {
- tmp = PyInt_AsLong(arg);
+ if (isInt == 1) {
+ tmp = PyInt_AsLong(arg);
if (tmp >= 0 && tmp < 128)
self->channel = tmp;
- }
+ }
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyMemberDef Midictl_members[] = {
@@ -751,14 +751,14 @@ static PyMethodDef Midictl_methods[] = {
{"_getStream", (PyCFunction)Midictl_getStream, METH_NOARGS, "Returns stream object."},
{"play", (PyCFunction)Midictl_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
{"stop", (PyCFunction)Midictl_stop, METH_NOARGS, "Stops computing."},
- {"setInterpolation", (PyCFunction)Midictl_setInterpolation, METH_O, "Activate/Deactivate interpolation."},
- {"setValue", (PyCFunction)Midictl_setValue, METH_O, "Resets audio stream to value in argument."},
- {"setMinScale", (PyCFunction)Midictl_setMinScale, METH_O, "Sets the minimum value of scaling."},
- {"setMaxScale", (PyCFunction)Midictl_setMaxScale, METH_O, "Sets the maximum value of scaling."},
- {"setCtlNumber", (PyCFunction)Midictl_setCtlNumber, METH_O, "Sets the controller number."},
- {"setChannel", (PyCFunction)Midictl_setChannel, METH_O, "Sets the midi channel."},
- {"setMul", (PyCFunction)Midictl_setMul, METH_O, "Sets oscillator mul factor."},
- {"setAdd", (PyCFunction)Midictl_setAdd, METH_O, "Sets oscillator add factor."},
+ {"setInterpolation", (PyCFunction)Midictl_setInterpolation, METH_O, "Activate/Deactivate interpolation."},
+ {"setValue", (PyCFunction)Midictl_setValue, METH_O, "Resets audio stream to value in argument."},
+ {"setMinScale", (PyCFunction)Midictl_setMinScale, METH_O, "Sets the minimum value of scaling."},
+ {"setMaxScale", (PyCFunction)Midictl_setMaxScale, METH_O, "Sets the maximum value of scaling."},
+ {"setCtlNumber", (PyCFunction)Midictl_setCtlNumber, METH_O, "Sets the controller number."},
+ {"setChannel", (PyCFunction)Midictl_setChannel, METH_O, "Sets the midi channel."},
+ {"setMul", (PyCFunction)Midictl_setMul, METH_O, "Sets oscillator mul factor."},
+ {"setAdd", (PyCFunction)Midictl_setAdd, METH_O, "Sets oscillator add factor."},
{"setSub", (PyCFunction)Midictl_setSub, METH_O, "Sets inverse add factor."},
{"setDiv", (PyCFunction)Midictl_setDiv, METH_O, "Sets inverse mul factor."},
{NULL} /* Sentinel */
@@ -830,10 +830,10 @@ PyTypeObject MidictlType = {
"Midictl objects. Retreive audio from an input channel.", /* tp_doc */
(traverseproc)Midictl_traverse, /* tp_traverse */
(inquiry)Midictl_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
Midictl_methods, /* tp_methods */
Midictl_members, /* tp_members */
0, /* tp_getset */
@@ -851,6 +851,7 @@ typedef struct {
pyo_audio_HEAD
int channel;
int scale; /* 0 = midi, 1 = transpo */
+ int interp;
MYFLT range;
MYFLT value;
MYFLT oldValue;
@@ -874,7 +875,7 @@ Bendin_setProcMode(Bendin *self)
int muladdmode;
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
- switch (muladdmode) {
+ switch (muladdmode) {
case 0:
self->muladd_func_ptr = Bendin_postprocessing_ii;
break;
@@ -910,8 +911,8 @@ void Bendin_translateMidi(Bendin *self, PyoMidiEvent *buffer, int count)
{
int i, ok;
MYFLT val;
- for (i=count-1; i>=0; i--) {
- int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
+ for (i=0; i<count; i++) {
+ int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
int number = PyoMidi_MessageData1(buffer[i].message);
int value = PyoMidi_MessageData2(buffer[i].message);
@@ -929,7 +930,6 @@ void Bendin_translateMidi(Bendin *self, PyoMidiEvent *buffer, int count)
}
if (ok == 1) {
- self->oldValue = self->value;
val = (number + (value << 7) - 8192) / 8192.0 * self->range;
if (self->scale == 0)
self->value = val;
@@ -938,6 +938,7 @@ void Bendin_translateMidi(Bendin *self, PyoMidiEvent *buffer, int count)
break;
}
}
+ self->oldValue = self->value;
}
static void
@@ -948,13 +949,19 @@ Bendin_compute_next_data_frame(Bendin *self)
tmp = Server_getMidiEventBuffer((Server *)self->server);
count = Server_getMidiEventCount((Server *)self->server);
-
if (count > 0)
Bendin_translateMidi((Bendin *)self, tmp, count);
- MYFLT step = (self->value - self->oldValue) / self->bufsize;
- for (i=0; i<self->bufsize; i++) {
- self->data[i] = self->oldValue + step;
+ if (self->interp == 0) {
+ for (i=0; i<self->bufsize; i++) {
+ self->data[i] = self->value;
+ }
+ }
+ else {
+ MYFLT step = (self->value - self->oldValue) / self->bufsize;
+ for (i=0; i<self->bufsize; i++) {
+ self->data[i] = self->oldValue + step;
+ }
}
(*self->muladd_func_ptr)(self);
@@ -992,11 +999,12 @@ Bendin_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->channel = 0;
self->scale = 0;
+ self->interp = 0;
self->value = 0.;
self->oldValue = 0.;
self->range = 2.;
- self->modebuffer[0] = 0;
- self->modebuffer[1] = 0;
+ self->modebuffer[0] = 0;
+ self->modebuffer[1] = 0;
INIT_OBJECT_COMMON
Stream_setFunctionPtr(self->stream, Bendin_compute_next_data_frame);
@@ -1053,16 +1061,16 @@ Bendin_setBrange(Bendin *self, PyObject *arg)
ASSERT_ARG_NOT_NULL
- int isNum = PyNumber_Check(arg);
+ int isNum = PyNumber_Check(arg);
- if (isNum == 1) {
- tmp = PyFloat_AsDouble(arg);
+ if (isNum == 1) {
+ tmp = PyFloat_AsDouble(arg);
if (tmp >= 0.0 && tmp < 128.0)
self->range = tmp;
- }
+ }
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyObject *
@@ -1072,16 +1080,16 @@ Bendin_setChannel(Bendin *self, PyObject *arg)
ASSERT_ARG_NOT_NULL
- int isInt = PyInt_Check(arg);
+ int isInt = PyInt_Check(arg);
- if (isInt == 1) {
- tmp = PyInt_AsLong(arg);
+ if (isInt == 1) {
+ tmp = PyInt_AsLong(arg);
if (tmp >= 0 && tmp < 128)
self->channel = tmp;
- }
+ }
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyObject *
@@ -1105,6 +1113,26 @@ Bendin_setScale(Bendin *self, PyObject *arg)
return Py_None;
}
+static PyObject *
+Bendin_setInterpolation(Bendin *self, PyObject *arg)
+{
+ int tmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ int isNum = PyInt_Check(arg);
+
+ if (isNum == 1) {
+ tmp = PyInt_AsLong(arg);
+ if (tmp == 0)
+ self->interp = 0;
+ else
+ self->interp = 1;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
static PyMemberDef Bendin_members[] = {
{"server", T_OBJECT_EX, offsetof(Bendin, server), 0, "Pyo server."},
@@ -1119,11 +1147,12 @@ static PyMethodDef Bendin_methods[] = {
{"_getStream", (PyCFunction)Bendin_getStream, METH_NOARGS, "Returns stream object."},
{"play", (PyCFunction)Bendin_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
{"stop", (PyCFunction)Bendin_stop, METH_NOARGS, "Stops computing."},
- {"setBrange", (PyCFunction)Bendin_setBrange, METH_O, "Sets the bending bipolar range."},
- {"setScale", (PyCFunction)Bendin_setScale, METH_O, "Sets the output type, midi vs transpo."},
- {"setChannel", (PyCFunction)Bendin_setChannel, METH_O, "Sets the midi channel."},
- {"setMul", (PyCFunction)Bendin_setMul, METH_O, "Sets oscillator mul factor."},
- {"setAdd", (PyCFunction)Bendin_setAdd, METH_O, "Sets oscillator add factor."},
+ {"setBrange", (PyCFunction)Bendin_setBrange, METH_O, "Sets the bending bipolar range."},
+ {"setScale", (PyCFunction)Bendin_setScale, METH_O, "Sets the output type, midi vs transpo."},
+ {"setChannel", (PyCFunction)Bendin_setChannel, METH_O, "Sets the midi channel."},
+ {"setInterpolation", (PyCFunction)Bendin_setInterpolation, METH_O, "Activate/Deactivate interpolation."},
+ {"setMul", (PyCFunction)Bendin_setMul, METH_O, "Sets oscillator mul factor."},
+ {"setAdd", (PyCFunction)Bendin_setAdd, METH_O, "Sets oscillator add factor."},
{"setSub", (PyCFunction)Bendin_setSub, METH_O, "Sets inverse add factor."},
{"setDiv", (PyCFunction)Bendin_setDiv, METH_O, "Sets inverse mul factor."},
{NULL} /* Sentinel */
@@ -1195,10 +1224,10 @@ PyTypeObject BendinType = {
"Bendin objects. Retreive audio from an input channel.", /* tp_doc */
(traverseproc)Bendin_traverse, /* tp_traverse */
(inquiry)Bendin_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
Bendin_methods, /* tp_methods */
Bendin_members, /* tp_members */
0, /* tp_getset */
@@ -1217,6 +1246,7 @@ typedef struct {
int channel;
MYFLT minscale;
MYFLT maxscale;
+ int interp;
MYFLT value;
MYFLT oldValue;
MYFLT sampleToSec;
@@ -1239,7 +1269,7 @@ Touchin_setProcMode(Touchin *self)
int muladdmode;
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
- switch (muladdmode) {
+ switch (muladdmode) {
case 0:
self->muladd_func_ptr = Touchin_postprocessing_ii;
break;
@@ -1274,10 +1304,9 @@ Touchin_setProcMode(Touchin *self)
void Touchin_translateMidi(Touchin *self, PyoMidiEvent *buffer, int count)
{
int i, ok;
- for (i=count-1; i>=0; i--) {
- int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
+ for (i=0; i<count; i++) {
+ int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
int number = PyoMidi_MessageData1(buffer[i].message);
- /* int value = PyoMidi_MessageData2(buffer[i].message); */
if (self->channel == 0) {
if ((status & 0xF0) == 0xd0)
@@ -1293,11 +1322,11 @@ void Touchin_translateMidi(Touchin *self, PyoMidiEvent *buffer, int count)
}
if (ok == 1) {
- self->oldValue = self->value;
self->value = (number / 127.) * (self->maxscale - self->minscale) + self->minscale;
break;
}
}
+ self->oldValue = self->value;
}
static void
@@ -1311,10 +1340,17 @@ Touchin_compute_next_data_frame(Touchin *self)
if (count > 0)
Touchin_translateMidi((Touchin *)self, tmp, count);
- MYFLT step = (self->value - self->oldValue) / self->bufsize;
- for (i=0; i<self->bufsize; i++) {
- self->data[i] = self->oldValue + step;
+ if (self->interp == 0) {
+ for (i=0; i<self->bufsize; i++) {
+ self->data[i] = self->value;
+ }
+ }
+ else {
+ MYFLT step = (self->value - self->oldValue) / self->bufsize;
+ for (i=0; i<self->bufsize; i++) {
+ self->data[i] = self->oldValue + step;
+ }
}
(*self->muladd_func_ptr)(self);
@@ -1355,8 +1391,9 @@ Touchin_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->oldValue = 0.;
self->minscale = 0.;
self->maxscale = 1.;
- self->modebuffer[0] = 0;
- self->modebuffer[1] = 0;
+ self->interp = 0;
+ self->modebuffer[0] = 0;
+ self->modebuffer[1] = 0;
INIT_OBJECT_COMMON
Stream_setFunctionPtr(self->stream, Touchin_compute_next_data_frame);
@@ -1410,15 +1447,15 @@ Touchin_setMinScale(Touchin *self, PyObject *arg)
ASSERT_ARG_NOT_NULL
- int isNum = PyNumber_Check(arg);
+ int isNum = PyNumber_Check(arg);
- if (isNum == 1) {
- tmp = PyFloat_AsDouble(arg);
+ if (isNum == 1) {
+ tmp = PyFloat_AsDouble(arg);
self->minscale = tmp;
- }
+ }
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyObject *
@@ -1428,15 +1465,15 @@ Touchin_setMaxScale(Touchin *self, PyObject *arg)
ASSERT_ARG_NOT_NULL
- int isNum = PyNumber_Check(arg);
+ int isNum = PyNumber_Check(arg);
- if (isNum == 1) {
- tmp = PyFloat_AsDouble(arg);
+ if (isNum == 1) {
+ tmp = PyFloat_AsDouble(arg);
self->maxscale = tmp;
- }
+ }
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyObject *
@@ -1446,12 +1483,33 @@ Touchin_setChannel(Touchin *self, PyObject *arg)
ASSERT_ARG_NOT_NULL
- int isInt = PyInt_Check(arg);
+ int isInt = PyInt_Check(arg);
- if (isInt == 1) {
- tmp = PyInt_AsLong(arg);
+ if (isInt == 1) {
+ tmp = PyInt_AsLong(arg);
if (tmp >= 0 && tmp < 128)
self->channel = tmp;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Touchin_setInterpolation(Touchin *self, PyObject *arg)
+{
+ int tmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ int isNum = PyInt_Check(arg);
+
+ if (isNum == 1) {
+ tmp = PyInt_AsLong(arg);
+ if (tmp == 0)
+ self->interp = 0;
+ else
+ self->interp = 1;
}
Py_INCREF(Py_None);
@@ -1471,11 +1529,12 @@ static PyMethodDef Touchin_methods[] = {
{"_getStream", (PyCFunction)Touchin_getStream, METH_NOARGS, "Returns stream object."},
{"play", (PyCFunction)Touchin_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
{"stop", (PyCFunction)Touchin_stop, METH_NOARGS, "Stops computing."},
- {"setMinScale", (PyCFunction)Touchin_setMinScale, METH_O, "Sets the minimum value of scaling."},
- {"setMaxScale", (PyCFunction)Touchin_setMaxScale, METH_O, "Sets the maximum value of scaling."},
- {"setChannel", (PyCFunction)Touchin_setChannel, METH_O, "Sets the midi channel."},
- {"setMul", (PyCFunction)Touchin_setMul, METH_O, "Sets oscillator mul factor."},
- {"setAdd", (PyCFunction)Touchin_setAdd, METH_O, "Sets oscillator add factor."},
+ {"setMinScale", (PyCFunction)Touchin_setMinScale, METH_O, "Sets the minimum value of scaling."},
+ {"setMaxScale", (PyCFunction)Touchin_setMaxScale, METH_O, "Sets the maximum value of scaling."},
+ {"setChannel", (PyCFunction)Touchin_setChannel, METH_O, "Sets the midi channel."},
+ {"setInterpolation", (PyCFunction)Touchin_setInterpolation, METH_O, "Activate/Deactivate interpolation."},
+ {"setMul", (PyCFunction)Touchin_setMul, METH_O, "Sets oscillator mul factor."},
+ {"setAdd", (PyCFunction)Touchin_setAdd, METH_O, "Sets oscillator add factor."},
{"setSub", (PyCFunction)Touchin_setSub, METH_O, "Sets inverse add factor."},
{"setDiv", (PyCFunction)Touchin_setDiv, METH_O, "Sets inverse mul factor."},
{NULL} /* Sentinel */
@@ -1547,10 +1606,10 @@ PyTypeObject TouchinType = {
"Touchin objects. Retrieve the signal of an aftertouch midi controller.", /* tp_doc */
(traverseproc)Touchin_traverse, /* tp_traverse */
(inquiry)Touchin_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
Touchin_methods, /* tp_methods */
Touchin_members, /* tp_members */
0, /* tp_getset */
@@ -1587,7 +1646,7 @@ Programin_setProcMode(Programin *self)
int muladdmode;
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
- switch (muladdmode) {
+ switch (muladdmode) {
case 0:
self->muladd_func_ptr = Programin_postprocessing_ii;
break;
@@ -1623,8 +1682,8 @@ void Programin_translateMidi(Programin *self, PyoMidiEvent *buffer, int count)
{
int i, ok;
- for (i=count-1; i>=0; i--) {
- int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
+ for (i=0; i<count; i++) {
+ int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
int number = PyoMidi_MessageData1(buffer[i].message);
if (self->channel == 0) {
@@ -1698,8 +1757,8 @@ Programin_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->channel = 0;
self->value = 0.;
- self->modebuffer[0] = 0;
- self->modebuffer[1] = 0;
+ self->modebuffer[0] = 0;
+ self->modebuffer[1] = 0;
INIT_OBJECT_COMMON
Stream_setFunctionPtr(self->stream, Programin_compute_next_data_frame);
@@ -1751,16 +1810,16 @@ Programin_setChannel(Programin *self, PyObject *arg)
ASSERT_ARG_NOT_NULL
- int isInt = PyInt_Check(arg);
+ int isInt = PyInt_Check(arg);
- if (isInt == 1) {
- tmp = PyInt_AsLong(arg);
+ if (isInt == 1) {
+ tmp = PyInt_AsLong(arg);
if (tmp >= 0 && tmp < 128)
self->channel = tmp;
- }
+ }
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyMemberDef Programin_members[] = {
@@ -1776,9 +1835,9 @@ static PyMethodDef Programin_methods[] = {
{"_getStream", (PyCFunction)Programin_getStream, METH_NOARGS, "Returns stream object."},
{"play", (PyCFunction)Programin_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
{"stop", (PyCFunction)Programin_stop, METH_NOARGS, "Stops computing."},
- {"setChannel", (PyCFunction)Programin_setChannel, METH_O, "Sets the midi channel."},
- {"setMul", (PyCFunction)Programin_setMul, METH_O, "Sets oscillator mul factor."},
- {"setAdd", (PyCFunction)Programin_setAdd, METH_O, "Sets oscillator add factor."},
+ {"setChannel", (PyCFunction)Programin_setChannel, METH_O, "Sets the midi channel."},
+ {"setMul", (PyCFunction)Programin_setMul, METH_O, "Sets oscillator mul factor."},
+ {"setAdd", (PyCFunction)Programin_setAdd, METH_O, "Sets oscillator add factor."},
{"setSub", (PyCFunction)Programin_setSub, METH_O, "Sets inverse add factor."},
{"setDiv", (PyCFunction)Programin_setDiv, METH_O, "Sets inverse mul factor."},
{NULL} /* Sentinel */
@@ -1850,10 +1909,10 @@ PyTypeObject PrograminType = {
"Programin objects. Retrieve the signal of a program change midi controller.", /* tp_doc */
(traverseproc)Programin_traverse, /* tp_traverse */
(inquiry)Programin_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
Programin_methods, /* tp_methods */
Programin_members, /* tp_members */
0, /* tp_getset */
@@ -1941,7 +2000,7 @@ void grabMidiNotes(MidiNote *self, PyoMidiEvent *buffer, int count)
int i, ok, voice, kind;
for (i=0; i<count; i++) {
- int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
+ int status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
int pitch = PyoMidi_MessageData1(buffer[i].message);
int velocity = PyoMidi_MessageData2(buffer[i].message);
@@ -2117,12 +2176,12 @@ MidiNote_setScale(MidiNote *self, PyObject *arg)
{
ASSERT_ARG_NOT_NULL
- if (PyInt_Check(arg) == 1) {
- int tmp = PyInt_AsLong(arg);
+ if (PyInt_Check(arg) == 1) {
+ int tmp = PyInt_AsLong(arg);
if (tmp >= 0 && tmp < 3)
self->scale = tmp;
- }
- Py_RETURN_NONE;
+ }
+ Py_RETURN_NONE;
}
static PyObject *
@@ -2130,12 +2189,12 @@ MidiNote_setFirst(MidiNote *self, PyObject *arg)
{
ASSERT_ARG_NOT_NULL
- if (PyInt_Check(arg) == 1) {
- int tmp = PyInt_AsLong(arg);
+ if (PyInt_Check(arg) == 1) {
+ int tmp = PyInt_AsLong(arg);
if (tmp >= 0 && tmp < 128)
self->first = tmp;
- }
- Py_RETURN_NONE;
+ }
+ Py_RETURN_NONE;
}
static PyObject *
@@ -2143,12 +2202,12 @@ MidiNote_setLast(MidiNote *self, PyObject *arg)
{
ASSERT_ARG_NOT_NULL
- if (PyInt_Check(arg) == 1) {
- int tmp = PyInt_AsLong(arg);
+ if (PyInt_Check(arg) == 1) {
+ int tmp = PyInt_AsLong(arg);
if (tmp >= 0 && tmp < 128)
self->last = tmp;
- }
- Py_RETURN_NONE;
+ }
+ Py_RETURN_NONE;
}
static PyObject *
@@ -2156,12 +2215,12 @@ MidiNote_setChannel(MidiNote *self, PyObject *arg)
{
ASSERT_ARG_NOT_NULL
- if (PyInt_Check(arg) == 1) {
- int tmp = PyInt_AsLong(arg);
+ if (PyInt_Check(arg) == 1) {
+ int tmp = PyInt_AsLong(arg);
if (tmp >= 0 && tmp < 128)
self->channel = tmp;
- }
- Py_RETURN_NONE;
+ }
+ Py_RETURN_NONE;
}
static PyObject *
@@ -2171,16 +2230,16 @@ MidiNote_setCentralKey(MidiNote *self, PyObject *arg)
ASSERT_ARG_NOT_NULL
- int isInt = PyInt_Check(arg);
+ int isInt = PyInt_Check(arg);
- if (isInt == 1) {
- tmp = PyInt_AsLong(arg);
+ if (isInt == 1) {
+ tmp = PyInt_AsLong(arg);
if (tmp >= self->first && tmp <= self->last)
self->centralkey = tmp;
- }
+ }
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyObject *
@@ -2188,13 +2247,13 @@ MidiNote_setStealing(MidiNote *self, PyObject *arg)
{
ASSERT_ARG_NOT_NULL
- int isInt = PyInt_Check(arg);
+ int isInt = PyInt_Check(arg);
- if (isInt == 1)
- self->stealing = PyInt_AsLong(arg);
+ if (isInt == 1)
+ self->stealing = PyInt_AsLong(arg);
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyMemberDef MidiNote_members[] = {
@@ -2241,10 +2300,10 @@ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECK
"MidiNote objects. Retreive midi note from a midi input.", /* tp_doc */
(traverseproc)MidiNote_traverse, /* tp_traverse */
(inquiry)MidiNote_clear, /* tp_clear */
-0, /* tp_richcompare */
-0, /* tp_weaklistoffset */
-0, /* tp_iter */
-0, /* tp_iternext */
+0, /* tp_richcompare */
+0, /* tp_weaklistoffset */
+0, /* tp_iter */
+0, /* tp_iternext */
MidiNote_methods, /* tp_methods */
MidiNote_members, /* tp_members */
0, /* tp_getset */
@@ -2284,7 +2343,7 @@ Notein_setProcMode(Notein *self)
int muladdmode;
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
- switch (muladdmode) {
+ switch (muladdmode) {
case 0:
self->muladd_func_ptr = Notein_postprocessing_ii;
break;
@@ -2504,10 +2563,10 @@ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECK
"Notein objects. Stream pitch or velocity from a Notein voice.", /* tp_doc */
(traverseproc)Notein_traverse, /* tp_traverse */
(inquiry)Notein_clear, /* tp_clear */
-0, /* tp_richcompare */
-0, /* tp_weaklistoffset */
-0, /* tp_iter */
-0, /* tp_iternext */
+0, /* tp_richcompare */
+0, /* tp_weaklistoffset */
+0, /* tp_iter */
+0, /* tp_iternext */
Notein_methods, /* tp_methods */
Notein_members, /* tp_members */
0, /* tp_getset */
@@ -2546,7 +2605,7 @@ NoteinTrig_setProcMode(NoteinTrig *self)
int muladdmode;
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
- switch (muladdmode) {
+ switch (muladdmode) {
case 0:
self->muladd_func_ptr = NoteinTrig_postprocessing_ii;
break;
@@ -2759,10 +2818,10 @@ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECK
"NoteinTrig objects. Stream noteon or noteoff trigger from a Notein voice.", /* tp_doc */
(traverseproc)NoteinTrig_traverse, /* tp_traverse */
(inquiry)NoteinTrig_clear, /* tp_clear */
-0, /* tp_richcompare */
-0, /* tp_weaklistoffset */
-0, /* tp_iter */
-0, /* tp_iternext */
+0, /* tp_richcompare */
+0, /* tp_weaklistoffset */
+0, /* tp_iter */
+0, /* tp_iternext */
NoteinTrig_methods, /* tp_methods */
NoteinTrig_members, /* tp_members */
0, /* tp_getset */
@@ -2879,7 +2938,7 @@ MidiAdsr_setProcMode(MidiAdsr *self)
self->proc_func_ptr = MidiAdsr_generates;
- switch (muladdmode) {
+ switch (muladdmode) {
case 0:
self->muladd_func_ptr = MidiAdsr_postprocessing_ii;
break;
@@ -2952,8 +3011,8 @@ MidiAdsr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
MidiAdsr *self;
self = (MidiAdsr *)type->tp_alloc(type, 0);
- self->modebuffer[0] = 0;
- self->modebuffer[1] = 0;
+ self->modebuffer[0] = 0;
+ self->modebuffer[1] = 0;
self->topValue = 0.0;
self->fademode = 0;
self->changed = 0;
@@ -3030,7 +3089,7 @@ static PyObject * MidiAdsr_inplace_div(MidiAdsr *self, PyObject *arg) { INPLACE_
static PyObject *
MidiAdsr_setAttack(MidiAdsr *self, PyObject *arg)
{
- if (PyNumber_Check(arg)) {
+ if (PyNumber_Check(arg)) {
self->attack = PyFloat_AsDouble(arg);
if (self->attack < 0.000001)
self->attack = 0.000001;
@@ -3044,7 +3103,7 @@ MidiAdsr_setAttack(MidiAdsr *self, PyObject *arg)
static PyObject *
MidiAdsr_setDecay(MidiAdsr *self, PyObject *arg)
{
- if (PyNumber_Check(arg)) {
+ if (PyNumber_Check(arg)) {
self->decay = PyFloat_AsDouble(arg);
if (self->decay < 0.000001)
self->decay = 0.000001;
@@ -3058,7 +3117,7 @@ MidiAdsr_setDecay(MidiAdsr *self, PyObject *arg)
static PyObject *
MidiAdsr_setSustain(MidiAdsr *self, PyObject *arg)
{
- if (PyNumber_Check(arg)) {
+ if (PyNumber_Check(arg)) {
self->sustain = PyFloat_AsDouble(arg);
if (self->sustain < 0.0)
self->sustain = 0.0;
@@ -3072,7 +3131,7 @@ MidiAdsr_setSustain(MidiAdsr *self, PyObject *arg)
static PyObject *
MidiAdsr_setRelease(MidiAdsr *self, PyObject *arg)
{
- if (PyNumber_Check(arg)) {
+ if (PyNumber_Check(arg)) {
self->release = PyFloat_AsDouble(arg);
if (self->release < 0.000001)
self->release = 0.000001;
@@ -3085,7 +3144,7 @@ MidiAdsr_setRelease(MidiAdsr *self, PyObject *arg)
static PyObject *
MidiAdsr_setExp(MidiAdsr *self, PyObject *arg)
{
- if (PyNumber_Check(arg)) {
+ if (PyNumber_Check(arg)) {
MYFLT tmp = PyFloat_AsDouble(arg);
if (tmp > 0.0)
self->exp = tmp;
@@ -3186,10 +3245,10 @@ PyTypeObject MidiAdsrType = {
"MidiAdsr objects. Generates MidiAdsr envelope signal.", /* tp_doc */
(traverseproc)MidiAdsr_traverse, /* tp_traverse */
(inquiry)MidiAdsr_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
MidiAdsr_methods, /* tp_methods */
MidiAdsr_members, /* tp_members */
0, /* tp_getset */
@@ -3311,7 +3370,7 @@ MidiDelAdsr_setProcMode(MidiDelAdsr *self)
self->proc_func_ptr = MidiDelAdsr_generates;
- switch (muladdmode) {
+ switch (muladdmode) {
case 0:
self->muladd_func_ptr = MidiDelAdsr_postprocessing_ii;
break;
@@ -3384,8 +3443,8 @@ MidiDelAdsr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
MidiDelAdsr *self;
self = (MidiDelAdsr *)type->tp_alloc(type, 0);
- self->modebuffer[0] = 0;
- self->modebuffer[1] = 0;
+ self->modebuffer[0] = 0;
+ self->modebuffer[1] = 0;
self->topValue = 0.0;
self->fademode = 0;
self->changed = 0;
@@ -3463,7 +3522,7 @@ static PyObject * MidiDelAdsr_inplace_div(MidiDelAdsr *self, PyObject *arg) { IN
static PyObject *
MidiDelAdsr_setDelay(MidiDelAdsr *self, PyObject *arg)
{
- if (PyNumber_Check(arg)) {
+ if (PyNumber_Check(arg)) {
self->delay = PyFloat_AsDouble(arg);
self->delayPlusAttack = self->delay + self->attack;
self->delayPlusAttackPlusDecay = self->delay + self->attack + self->decay;
@@ -3475,7 +3534,7 @@ MidiDelAdsr_setDelay(MidiDelAdsr *self, PyObject *arg)
static PyObject *
MidiDelAdsr_setAttack(MidiDelAdsr *self, PyObject *arg)
{
- if (PyNumber_Check(arg)) {
+ if (PyNumber_Check(arg)) {
self->attack = PyFloat_AsDouble(arg);
if (self->attack < 0.000001)
self->attack = 0.000001;
@@ -3490,7 +3549,7 @@ MidiDelAdsr_setAttack(MidiDelAdsr *self, PyObject *arg)
static PyObject *
MidiDelAdsr_setDecay(MidiDelAdsr *self, PyObject *arg)
{
- if (PyNumber_Check(arg)) {
+ if (PyNumber_Check(arg)) {
self->decay = PyFloat_AsDouble(arg);
if (self->decay < 0.000001)
self->decay = 0.000001;
@@ -3504,7 +3563,7 @@ MidiDelAdsr_setDecay(MidiDelAdsr *self, PyObject *arg)
static PyObject *
MidiDelAdsr_setSustain(MidiDelAdsr *self, PyObject *arg)
{
- if (PyNumber_Check(arg)) {
+ if (PyNumber_Check(arg)) {
self->sustain = PyFloat_AsDouble(arg);
if (self->sustain < 0.0)
self->sustain = 0.0;
@@ -3518,7 +3577,7 @@ MidiDelAdsr_setSustain(MidiDelAdsr *self, PyObject *arg)
static PyObject *
MidiDelAdsr_setRelease(MidiDelAdsr *self, PyObject *arg)
{
- if (PyNumber_Check(arg)) {
+ if (PyNumber_Check(arg)) {
self->release = PyFloat_AsDouble(arg);
if (self->release < 0.000001)
self->release = 0.000001;
@@ -3531,7 +3590,7 @@ MidiDelAdsr_setRelease(MidiDelAdsr *self, PyObject *arg)
static PyObject *
MidiDelAdsr_setExp(MidiDelAdsr *self, PyObject *arg)
{
- if (PyNumber_Check(arg)) {
+ if (PyNumber_Check(arg)) {
MYFLT tmp = PyFloat_AsDouble(arg);
if (tmp > 0.0)
self->exp = tmp;
@@ -3633,10 +3692,10 @@ PyTypeObject MidiDelAdsrType = {
"MidiDelAdsr objects. Generates MidiDelAdsr envelope signal.", /* tp_doc */
(traverseproc)MidiDelAdsr_traverse, /* tp_traverse */
(inquiry)MidiDelAdsr_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
MidiDelAdsr_methods, /* tp_methods */
MidiDelAdsr_members, /* tp_members */
0, /* tp_getset */
@@ -3669,8 +3728,8 @@ RawMidi_compute_next_data_frame(RawMidi *self)
if (count > 0) {
PyObject *tup;
- for (i=count-1; i>=0; i--) {
- status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
+ for (i=0; i<count; i++) {
+ status = PyoMidi_MessageStatus(buffer[i].message); // Temp note event holders
data1 = PyoMidi_MessageData1(buffer[i].message);
data2 = PyoMidi_MessageData2(buffer[i].message);
tup = PyTuple_New(3);
@@ -3741,21 +3800,21 @@ static PyObject * RawMidi_stop(RawMidi *self) { STOP };
static PyObject *
RawMidi_setFunction(RawMidi *self, PyObject *arg)
{
- PyObject *tmp;
+ PyObject *tmp;
- if (! PyCallable_Check(arg)) {
+ if (! PyCallable_Check(arg)) {
PyErr_SetString(PyExc_TypeError, "The callable attribute must be a valid Python function.");
- Py_INCREF(Py_None);
- return Py_None;
- }
+ 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;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyMemberDef RawMidi_members[] = {
@@ -3797,10 +3856,10 @@ PyTypeObject RawMidiType = {
"RawMidi objects. Calls a function with midi data as arguments.", /* tp_doc */
(traverseproc)RawMidi_traverse, /* tp_traverse */
(inquiry)RawMidi_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
RawMidi_methods, /* tp_methods */
RawMidi_members, /* tp_members */
0, /* tp_getset */
diff --git a/src/objects/oscilmodule.c b/src/objects/oscilmodule.c
index 4380f24..3041548 100644
--- a/src/objects/oscilmodule.c
+++ b/src/objects/oscilmodule.c
@@ -12674,4 +12674,494 @@ TableScale_members, /* tp_members */
0, /* tp_init */
0, /* tp_alloc */
TableScale_new, /* tp_new */
-};
\ No newline at end of file
+};
+
+/******************************/
+/* TableFill object definition */
+/******************************/
+typedef struct {
+ pyo_audio_HEAD
+ PyObject *input;
+ Stream *input_stream;
+ PyObject *table;
+ int pointer;
+} TableFill;
+
+static void
+TableFill_compute_next_data_frame(TableFill *self)
+{
+ int i;
+ int size = TableStream_getSize(self->table);
+ MYFLT *tablelist = TableStream_getData(self->table);
+ MYFLT *in = Stream_getData((Stream *)self->input_stream);
+
+ for (i=0; i<self->bufsize; i++) {
+ tablelist[self->pointer++] = in[i];
+ if (self->pointer >= size)
+ self->pointer = 0;
+ }
+}
+
+static int
+TableFill_traverse(TableFill *self, visitproc visit, void *arg)
+{
+ pyo_VISIT
+ Py_VISIT(self->input);
+ Py_VISIT(self->input_stream);
+ Py_VISIT(self->table);
+ return 0;
+}
+
+static int
+TableFill_clear(TableFill *self)
+{
+ pyo_CLEAR
+ Py_CLEAR(self->input);
+ Py_CLEAR(self->input_stream);
+ Py_CLEAR(self->table);
+ return 0;
+}
+
+static void
+TableFill_dealloc(TableFill* self)
+{
+ pyo_DEALLOC
+ TableFill_clear(self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+static PyObject *
+TableFill_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ int i;
+ PyObject *inputtmp, *input_streamtmp, *tabletmp;
+ TableFill *self;
+ self = (TableFill *)type->tp_alloc(type, 0);
+
+ self->pointer = 0;
+
+ INIT_OBJECT_COMMON
+
+ Stream_setFunctionPtr(self->stream, TableFill_compute_next_data_frame);
+
+ static char *kwlist[] = {"input", "table", NULL};
+
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &inputtmp, &tabletmp))
+ Py_RETURN_NONE;
+
+ INIT_INPUT_STREAM
+
+ if ( PyObject_HasAttrString((PyObject *)tabletmp, "getTableStream") == 0 ) {
+ PyErr_SetString(PyExc_TypeError, "\"table\" argument of TableFill must be a PyoTableObject.\n");
+ Py_RETURN_NONE;
+ }
+ Py_XDECREF(self->table);
+ self->table = PyObject_CallMethod((PyObject *)tabletmp, "getTableStream", "");
+
+ PyObject_CallMethod(self->server, "addStream", "O", self->stream);
+
+ return (PyObject *)self;
+}
+
+static PyObject * TableFill_getServer(TableFill* self) { GET_SERVER };
+static PyObject * TableFill_getStream(TableFill* self) { GET_STREAM };
+
+static PyObject * TableFill_play(TableFill *self, PyObject *args, PyObject *kwds)
+{
+ self->pointer = 0;
+ PLAY
+};
+
+static PyObject * TableFill_stop(TableFill *self) { STOP };
+
+static PyObject *
+TableFill_setTable(TableFill *self, PyObject *arg)
+{
+ PyObject *tmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ tmp = arg;
+ Py_INCREF(tmp);
+ Py_DECREF(self->table);
+ self->table = PyObject_CallMethod((PyObject *)tmp, "getTableStream", "");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject * TableFill_getCurrentPos(TableFill *self) {
+ return PyLong_FromLong(self->pointer);
+};
+
+static PyMemberDef TableFill_members[] = {
+{"server", T_OBJECT_EX, offsetof(TableFill, server), 0, "Pyo server."},
+{"stream", T_OBJECT_EX, offsetof(TableFill, stream), 0, "Stream object."},
+{"input", T_OBJECT_EX, offsetof(TableFill, input), 0, "Input sound object."},
+{"table", T_OBJECT_EX, offsetof(TableFill, table), 0, "Table to record in."},
+{NULL} /* Sentinel */
+};
+
+static PyMethodDef TableFill_methods[] = {
+{"getServer", (PyCFunction)TableFill_getServer, METH_NOARGS, "Returns server object."},
+{"_getStream", (PyCFunction)TableFill_getStream, METH_NOARGS, "Returns stream object."},
+{"setTable", (PyCFunction)TableFill_setTable, METH_O, "Sets a new table to fill."},
+{"play", (PyCFunction)TableFill_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
+{"stop", (PyCFunction)TableFill_stop, METH_NOARGS, "Stops computing."},
+{"getCurrentPos", (PyCFunction)TableFill_getCurrentPos, METH_NOARGS, "Returns the current position."},
+{NULL} /* Sentinel */
+};
+
+PyTypeObject TableFillType = {
+PyVarObject_HEAD_INIT(NULL, 0)
+"_pyo.TableFill_base", /*tp_name*/
+sizeof(TableFill), /*tp_basicsize*/
+0, /*tp_itemsize*/
+(destructor)TableFill_dealloc, /*tp_dealloc*/
+0, /*tp_print*/
+0, /*tp_getattr*/
+0, /*tp_setattr*/
+0, /*tp_as_async (tp_compare in Python 2)*/
+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*/
+"TableFill objects. Fill a table object with values in input.", /* tp_doc */
+(traverseproc)TableFill_traverse, /* tp_traverse */
+(inquiry)TableFill_clear, /* tp_clear */
+0, /* tp_richcompare */
+0, /* tp_weaklistoffset */
+0, /* tp_iter */
+0, /* tp_iternext */
+TableFill_methods, /* tp_methods */
+TableFill_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 */
+TableFill_new, /* tp_new */
+};
+
+/**************/
+/* TableScan object */
+/**************/
+typedef struct {
+ pyo_audio_HEAD
+ PyObject *table;
+ int modebuffer[2];
+ int pointerPos;
+} TableScan;
+
+static void
+TableScan_readframes(TableScan *self) {
+ int i;
+ MYFLT *tablelist = TableStream_getData(self->table);
+ int size = TableStream_getSize(self->table);
+
+ for (i=0; i<self->bufsize; i++) {
+ self->data[i] = tablelist[self->pointerPos++];
+ if (self->pointerPos >= size)
+ self->pointerPos = 0;
+ }
+}
+
+static void TableScan_postprocessing_ii(TableScan *self) { POST_PROCESSING_II };
+static void TableScan_postprocessing_ai(TableScan *self) { POST_PROCESSING_AI };
+static void TableScan_postprocessing_ia(TableScan *self) { POST_PROCESSING_IA };
+static void TableScan_postprocessing_aa(TableScan *self) { POST_PROCESSING_AA };
+static void TableScan_postprocessing_ireva(TableScan *self) { POST_PROCESSING_IREVA };
+static void TableScan_postprocessing_areva(TableScan *self) { POST_PROCESSING_AREVA };
+static void TableScan_postprocessing_revai(TableScan *self) { POST_PROCESSING_REVAI };
+static void TableScan_postprocessing_revaa(TableScan *self) { POST_PROCESSING_REVAA };
+static void TableScan_postprocessing_revareva(TableScan *self) { POST_PROCESSING_REVAREVA };
+
+static void
+TableScan_setProcMode(TableScan *self)
+{
+ int muladdmode;
+ muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
+
+ self->proc_func_ptr = TableScan_readframes;
+
+ switch (muladdmode) {
+ case 0:
+ self->muladd_func_ptr = TableScan_postprocessing_ii;
+ break;
+ case 1:
+ self->muladd_func_ptr = TableScan_postprocessing_ai;
+ break;
+ case 2:
+ self->muladd_func_ptr = TableScan_postprocessing_revai;
+ break;
+ case 10:
+ self->muladd_func_ptr = TableScan_postprocessing_ia;
+ break;
+ case 11:
+ self->muladd_func_ptr = TableScan_postprocessing_aa;
+ break;
+ case 12:
+ self->muladd_func_ptr = TableScan_postprocessing_revaa;
+ break;
+ case 20:
+ self->muladd_func_ptr = TableScan_postprocessing_ireva;
+ break;
+ case 21:
+ self->muladd_func_ptr = TableScan_postprocessing_areva;
+ break;
+ case 22:
+ self->muladd_func_ptr = TableScan_postprocessing_revareva;
+ break;
+ }
+}
+
+static void
+TableScan_compute_next_data_frame(TableScan *self)
+{
+ (*self->proc_func_ptr)(self);
+ (*self->muladd_func_ptr)(self);
+}
+
+static int
+TableScan_traverse(TableScan *self, visitproc visit, void *arg)
+{
+ pyo_VISIT
+ Py_VISIT(self->table);
+ return 0;
+}
+
+static int
+TableScan_clear(TableScan *self)
+{
+ pyo_CLEAR
+ Py_CLEAR(self->table);
+ return 0;
+}
+
+static void
+TableScan_dealloc(TableScan* self)
+{
+ pyo_DEALLOC
+ TableScan_clear(self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+static PyObject *
+TableScan_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ int i;
+ PyObject *tabletmp, *multmp=NULL, *addtmp=NULL;
+ TableScan *self;
+ self = (TableScan *)type->tp_alloc(type, 0);
+
+ self->modebuffer[0] = 0;
+ self->modebuffer[1] = 0;
+ self->pointerPos = 0;
+
+ INIT_OBJECT_COMMON
+ Stream_setFunctionPtr(self->stream, TableScan_compute_next_data_frame);
+ self->mode_func_ptr = TableScan_setProcMode;
+
+ static char *kwlist[] = {"table", "mul", "add", NULL};
+
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|OO", kwlist, &tabletmp, &multmp, &addtmp))
+ Py_RETURN_NONE;
+
+ if ( PyObject_HasAttrString((PyObject *)tabletmp, "getTableStream") == 0 ) {
+ PyErr_SetString(PyExc_TypeError, "\"table\" argument of TableScan must be a PyoTableObject.\n");
+ Py_RETURN_NONE;
+ }
+ Py_XDECREF(self->table);
+ self->table = PyObject_CallMethod((PyObject *)tabletmp, "getTableStream", "");
+
+ 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 * TableScan_getServer(TableScan* self) { GET_SERVER };
+static PyObject * TableScan_getStream(TableScan* self) { GET_STREAM };
+static PyObject * TableScan_setMul(TableScan *self, PyObject *arg) { SET_MUL };
+static PyObject * TableScan_setAdd(TableScan *self, PyObject *arg) { SET_ADD };
+static PyObject * TableScan_setSub(TableScan *self, PyObject *arg) { SET_SUB };
+static PyObject * TableScan_setDiv(TableScan *self, PyObject *arg) { SET_DIV };
+
+static PyObject * TableScan_play(TableScan *self, PyObject *args, PyObject *kwds)
+{
+ self->pointerPos = 0;
+ PLAY
+};
+
+static PyObject * TableScan_out(TableScan *self, PyObject *args, PyObject *kwds)
+{
+ self->pointerPos = 0;
+ OUT
+};
+static PyObject * TableScan_stop(TableScan *self) { STOP };
+
+static PyObject * TableScan_multiply(TableScan *self, PyObject *arg) { MULTIPLY };
+static PyObject * TableScan_inplace_multiply(TableScan *self, PyObject *arg) { INPLACE_MULTIPLY };
+static PyObject * TableScan_add(TableScan *self, PyObject *arg) { ADD };
+static PyObject * TableScan_inplace_add(TableScan *self, PyObject *arg) { INPLACE_ADD };
+static PyObject * TableScan_sub(TableScan *self, PyObject *arg) { SUB };
+static PyObject * TableScan_inplace_sub(TableScan *self, PyObject *arg) { INPLACE_SUB };
+static PyObject * TableScan_div(TableScan *self, PyObject *arg) { DIV };
+static PyObject * TableScan_inplace_div(TableScan *self, PyObject *arg) { INPLACE_DIV };
+
+static PyObject *
+TableScan_getTable(TableScan* self)
+{
+ Py_INCREF(self->table);
+ return self->table;
+};
+
+static PyObject *
+TableScan_setTable(TableScan *self, PyObject *arg)
+{
+ PyObject *tmp;
+
+ ASSERT_ARG_NOT_NULL
+
+ tmp = arg;
+ Py_DECREF(self->table);
+ self->table = PyObject_CallMethod((PyObject *)tmp, "getTableStream", "");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+TableScan_reset(TableScan *self)
+{
+ self->pointerPos = 0;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMemberDef TableScan_members[] = {
+{"server", T_OBJECT_EX, offsetof(TableScan, server), 0, "Pyo server."},
+{"stream", T_OBJECT_EX, offsetof(TableScan, stream), 0, "Stream object."},
+{"table", T_OBJECT_EX, offsetof(TableScan, table), 0, "Waveform table."},
+{"mul", T_OBJECT_EX, offsetof(TableScan, mul), 0, "Mul factor."},
+{"add", T_OBJECT_EX, offsetof(TableScan, add), 0, "Add factor."},
+{NULL} /* Sentinel */
+};
+
+static PyMethodDef TableScan_methods[] = {
+{"getTable", (PyCFunction)TableScan_getTable, METH_NOARGS, "Returns waveform table object."},
+{"getServer", (PyCFunction)TableScan_getServer, METH_NOARGS, "Returns server object."},
+{"_getStream", (PyCFunction)TableScan_getStream, METH_NOARGS, "Returns stream object."},
+{"play", (PyCFunction)TableScan_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
+{"out", (PyCFunction)TableScan_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
+{"stop", (PyCFunction)TableScan_stop, METH_NOARGS, "Stops computing."},
+{"setTable", (PyCFunction)TableScan_setTable, METH_O, "Sets oscillator table."},
+{"reset", (PyCFunction)TableScan_reset, METH_NOARGS, "Resets pointer position to 0."},
+{"setMul", (PyCFunction)TableScan_setMul, METH_O, "Sets oscillator mul factor."},
+{"setAdd", (PyCFunction)TableScan_setAdd, METH_O, "Sets oscillator add factor."},
+{"setSub", (PyCFunction)TableScan_setSub, METH_O, "Sets oscillator inverse add factor."},
+{"setDiv", (PyCFunction)TableScan_setDiv, METH_O, "Sets inverse mul factor."},
+{NULL} /* Sentinel */
+};
+
+static PyNumberMethods TableScan_as_number = {
+(binaryfunc)TableScan_add, /*nb_add*/
+(binaryfunc)TableScan_sub, /*nb_subtract*/
+(binaryfunc)TableScan_multiply, /*nb_multiply*/
+INITIALIZE_NB_DIVIDE_ZERO /*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*/
+INITIALIZE_NB_COERCE_ZERO /*nb_coerce*/
+0, /*nb_int*/
+0, /*nb_long*/
+0, /*nb_float*/
+INITIALIZE_NB_OCT_ZERO /*nb_oct*/
+INITIALIZE_NB_HEX_ZERO /*nb_hex*/
+(binaryfunc)TableScan_inplace_add, /*inplace_add*/
+(binaryfunc)TableScan_inplace_sub, /*inplace_subtract*/
+(binaryfunc)TableScan_inplace_multiply, /*inplace_multiply*/
+INITIALIZE_NB_IN_PLACE_DIVIDE_ZERO /*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*/
+(binaryfunc)TableScan_div, /*nb_true_divide*/
+0, /*nb_inplace_floor_divide*/
+(binaryfunc)TableScan_inplace_div, /*nb_inplace_true_divide*/
+0, /* nb_index */
+};
+
+PyTypeObject TableScanType = {
+PyVarObject_HEAD_INIT(NULL, 0)
+"_pyo.TableScan_base", /*tp_name*/
+sizeof(TableScan), /*tp_basicsize*/
+0, /*tp_itemsize*/
+(destructor)TableScan_dealloc, /*tp_dealloc*/
+0, /*tp_print*/
+0, /*tp_getattr*/
+0, /*tp_setattr*/
+0, /*tp_as_async (tp_compare in Python 2)*/
+0, /*tp_repr*/
+&TableScan_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*/
+"TableScan objects. Scan the content of a table in loop.", /* tp_doc */
+(traverseproc)TableScan_traverse, /* tp_traverse */
+(inquiry)TableScan_clear, /* tp_clear */
+0, /* tp_richcompare */
+0, /* tp_weaklistoffset */
+0, /* tp_iter */
+0, /* tp_iternext */
+TableScan_methods, /* tp_methods */
+TableScan_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 */
+TableScan_new, /* tp_new */
+};
diff --git a/src/objects/patternmodule.c b/src/objects/patternmodule.c
index a54553f..db95d6e 100644
--- a/src/objects/patternmodule.c
+++ b/src/objects/patternmodule.c
@@ -176,8 +176,6 @@ Pattern_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Stream_setFunctionPtr(self->stream, Pattern_compute_next_data_frame);
self->mode_func_ptr = Pattern_setProcMode;
- Stream_setStreamActive(self->stream, 0);
-
self->sampleToSec = 1. / self->sr;
self->currentTime = 0.;
@@ -195,7 +193,14 @@ Pattern_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
if (argtmp) {
- PyObject_CallMethod((PyObject *)self, "setArg", "O", argtmp);
+ if (PyTuple_Check(argtmp)) {
+ PyObject *argument = PyTuple_New(1);
+ PyTuple_SetItem(argument, 0, argtmp);
+ PyObject_CallMethod((PyObject *)self, "setArg", "O", argument);
+ }
+ else {
+ PyObject_CallMethod((PyObject *)self, "setArg", "O", argtmp);
+ }
}
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
diff --git a/src/objects/phasevocmodule.c b/src/objects/phasevocmodule.c
index f2b9666..73b9d58 100644
--- a/src/objects/phasevocmodule.c
+++ b/src/objects/phasevocmodule.c
@@ -5623,6 +5623,71 @@ PVShift_new, /* tp_new */
/*****************/
/** PVAmpMod **/
/*****************/
+static void
+PVMod_setTable(MYFLT *table, int shape) {
+ int i;
+
+ if (shape < 0 || shape > 7)
+ shape = 0;
+
+ if (shape == 0) {
+ for (i=0; i<8192; i++)
+ table[i] = (MYFLT)(MYSIN(TWOPI * i / 8192.0) * 0.5 + 0.5);
+ }
+ else if (shape == 1) {
+ for (i=0; i<8192; i++)
+ table[i] = (MYFLT)(1.0 - (i / 8191.0));
+ }
+ else if (shape == 2) {
+ for (i=0; i<8192; i++)
+ table[i] = (MYFLT)(i / 8191.0);
+ }
+ else if (shape == 3) {
+ for (i=0; i<4096; i++)
+ table[i] = 1.0;
+ for (i=4096; i<8192; i++)
+ table[i] = 0.0;
+ }
+ else if (shape == 4) {
+ for (i=0; i<2048; i++)
+ table[i] = (MYFLT)(i / 4095.0) + 0.5;
+ for (i=2048; i<6144; i++)
+ table[i] = (MYFLT)(1.0 - ((i - 2048) / 4095.0));
+ for (i=6144; i<8192; i++)
+ table[i] = (MYFLT)((i - 6144) / 4095.0);
+ }
+ else if (shape == 5) {
+ MYFLT val = RANDOM_UNIFORM;
+ table[0] = val;
+ for (i=1; i<8192; i++) {
+ val += RANDOM_UNIFORM * 0.04 - 0.02;
+ if (val < 0)
+ val = -val;
+ else if (val >= 1.0)
+ val = 1.0 - (val - 1.0);
+ table[i] = val;
+ }
+ }
+ else if (shape == 6) {
+ MYFLT val = RANDOM_UNIFORM;
+ table[0] = val;
+ for (i=1; i<8192; i++) {
+ val += RANDOM_UNIFORM * 0.14 - 0.07;
+ if (val < 0)
+ val = -val;
+ else if (val >= 1.0)
+ val = 1.0 - (val - 1.0);
+ table[i] = val;
+ }
+ }
+ else if (shape == 7) {
+ for (i=0; i<8192; i++) {
+ table[i] = RANDOM_UNIFORM;
+ }
+ }
+ table[8192] = table[0];
+}
+
typedef struct {
pyo_audio_HEAD
PyObject *input;
@@ -5919,7 +5984,7 @@ PVAmpMod_dealloc(PVAmpMod* self)
static PyObject *
PVAmpMod_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- int i;
+ int i, shape = 0;
PyObject *inputtmp, *input_streamtmp, *basefreqtmp=NULL, *spreadtmp=NULL;
PVAmpMod *self;
self = (PVAmpMod *)type->tp_alloc(type, 0);
@@ -5932,9 +5997,9 @@ PVAmpMod_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Stream_setFunctionPtr(self->stream, PVAmpMod_compute_next_data_frame);
self->mode_func_ptr = PVAmpMod_setProcMode;
- static char *kwlist[] = {"input", "basefreq", "spread", NULL};
+ static char *kwlist[] = {"input", "basefreq", "spread", "shape", NULL};
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|OO", kwlist, &inputtmp, &basefreqtmp, &spreadtmp))
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|OOi", kwlist, &inputtmp, &basefreqtmp, &spreadtmp, &shape))
Py_RETURN_NONE;
if ( PyObject_HasAttrString((PyObject *)inputtmp, "pv_stream") == 0 ) {
@@ -5967,9 +6032,7 @@ PVAmpMod_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->count = (int *)realloc(self->count, self->bufsize * sizeof(int));
self->table = (MYFLT *)realloc(self->table, 8193 * sizeof(MYFLT));
- for (i=0; i<8192; i++)
- self->table[i] = (MYFLT)(MYSIN(TWOPI * i / 8192.0) * 0.5 + 0.5);
- self->table[8192] = 0.5;
+ PVMod_setTable(self->table, shape);
PVAmpMod_realloc_memories(self);
@@ -6071,6 +6134,19 @@ PVAmpMod_setSpread(PVAmpMod *self, PyObject *arg)
}
static PyObject *
+PVAmpMod_setShape(PVAmpMod *self, PyObject *arg)
+{
+ ASSERT_ARG_NOT_NULL
+
+ if (PyNumber_Check(arg)) {
+ PVMod_setTable(self->table, PyInt_AsLong(arg));
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
PVAmpMod_reset(PVAmpMod *self) {
int i;
for (i=0; i<self->hsize; i++)
@@ -6096,6 +6172,7 @@ static PyMethodDef PVAmpMod_methods[] = {
{"setInput", (PyCFunction)PVAmpMod_setInput, METH_O, "Sets a new input object."},
{"setBasefreq", (PyCFunction)PVAmpMod_setBasefreq, METH_O, "Sets the modulator's base frequency."},
{"setSpread", (PyCFunction)PVAmpMod_setSpread, METH_O, "Sets the high frequency spreading factor."},
+{"setShape", (PyCFunction)PVAmpMod_setShape, METH_O, "Sets the modulation oscillator waveform."},
{"reset", (PyCFunction)PVAmpMod_reset, METH_NOARGS, "Resets pointer positions."},
{"play", (PyCFunction)PVAmpMod_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
{"stop", (PyCFunction)PVAmpMod_stop, METH_NOARGS, "Stops computing."},
@@ -6516,7 +6593,7 @@ PVFreqMod_dealloc(PVFreqMod* self)
static PyObject *
PVFreqMod_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- int i;
+ int i, shape = 0;
PyObject *inputtmp, *input_streamtmp, *basefreqtmp=NULL, *spreadtmp=NULL, *depthtmp=NULL;
PVFreqMod *self;
self = (PVFreqMod *)type->tp_alloc(type, 0);
@@ -6530,9 +6607,9 @@ PVFreqMod_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Stream_setFunctionPtr(self->stream, PVFreqMod_compute_next_data_frame);
self->mode_func_ptr = PVFreqMod_setProcMode;
- static char *kwlist[] = {"input", "basefreq", "spread", "depth", NULL};
+ static char *kwlist[] = {"input", "basefreq", "spread", "depth", "shape", NULL};
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|OOO", kwlist, &inputtmp, &basefreqtmp, &spreadtmp, &depthtmp))
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|OOOi", kwlist, &inputtmp, &basefreqtmp, &spreadtmp, &depthtmp, &shape))
Py_RETURN_NONE;
if ( PyObject_HasAttrString((PyObject *)inputtmp, "pv_stream") == 0 ) {
@@ -6569,9 +6646,7 @@ PVFreqMod_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->count = (int *)realloc(self->count, self->bufsize * sizeof(int));
self->table = (MYFLT *)realloc(self->table, 8193 * sizeof(MYFLT));
- for (i=0; i<8192; i++)
- self->table[i] = (MYFLT)(MYSIN(TWOPI * i / 8192.0) * 0.5 + 0.5);
- self->table[8192] = 0.5;
+ PVMod_setTable(self->table, shape);
PVFreqMod_realloc_memories(self);
@@ -6704,6 +6779,19 @@ PVFreqMod_setDepth(PVFreqMod *self, PyObject *arg)
}
static PyObject *
+PVFreqMod_setShape(PVFreqMod *self, PyObject *arg)
+{
+ ASSERT_ARG_NOT_NULL
+
+ if (PyNumber_Check(arg)) {
+ PVMod_setTable(self->table, PyInt_AsLong(arg));
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
PVFreqMod_reset(PVFreqMod *self) {
int i;
for (i=0; i<self->hsize; i++)
@@ -6731,6 +6819,7 @@ static PyMethodDef PVFreqMod_methods[] = {
{"setBasefreq", (PyCFunction)PVFreqMod_setBasefreq, METH_O, "Sets the modulator's base frequency."},
{"setSpread", (PyCFunction)PVFreqMod_setSpread, METH_O, "Sets the high frequency spreading factor."},
{"setDepth", (PyCFunction)PVFreqMod_setDepth, METH_O, "Sets the modulator's depth."},
+{"setShape", (PyCFunction)PVFreqMod_setShape, METH_O, "Sets the modulation oscillator waveform."},
{"reset", (PyCFunction)PVFreqMod_reset, METH_NOARGS, "Resets pointer positions."},
{"play", (PyCFunction)PVFreqMod_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
{"stop", (PyCFunction)PVFreqMod_stop, METH_NOARGS, "Stops computing."},
diff --git a/src/objects/tablemodule.c b/src/objects/tablemodule.c
index c8514df..880a464 100644
--- a/src/objects/tablemodule.c
+++ b/src/objects/tablemodule.c
@@ -31,6 +31,11 @@
#include "wind.h"
#include "fft.h"
+#if !defined(_WIN32) && !defined(_WIN64)
+#include <fcntl.h>
+#include <sys/mman.h>
+#endif
+
#define __TABLE_MODULE
#include "tablemodule.h"
#undef __TABLE_MODULE
@@ -4866,7 +4871,6 @@ NewTable_new, /* tp_new */
/***********************/
typedef struct {
pyo_table_HEAD
- int pointer;
} DataTable;
static void
@@ -4907,8 +4911,6 @@ DataTable_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->server = PyServer_get_server();
- self->pointer = 0;
-
MAKE_NEW_TABLESTREAM(self->tablestream, &TableStreamType, NULL);
static char *kwlist[] = {"size", "init", NULL};
@@ -5827,7 +5829,6 @@ TableRec_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
INIT_OBJECT_COMMON
Stream_setFunctionPtr(self->stream, TableRec_compute_next_data_frame);
- Stream_setStreamActive(self->stream, 0);
static char *kwlist[] = {"input", "table", "fadetime", NULL};
@@ -7087,7 +7088,6 @@ TablePut_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
INIT_OBJECT_COMMON
Stream_setFunctionPtr(self->stream, TablePut_compute_next_data_frame);
- Stream_setStreamActive(self->stream, 0);
static char *kwlist[] = {"input", "table", NULL};
@@ -7218,6 +7218,7 @@ typedef struct {
Stream *pos_stream;
NewTable *table;
int mode;
+ int maxwindow;
int lastPos;
MYFLT lastValue;
int count;
@@ -7260,10 +7261,14 @@ TableWrite_compute_next_data_frame(TableWrite *self)
int steps, dir;
if (ipos > self->lastPos) { /* Move forward. */
steps = ipos - self->lastPos;
+ if (steps > self->maxwindow)
+ steps = 1;
dir = 1;
}
else { /* Move backward. */
steps = self->lastPos - ipos;
+ if (steps > self->maxwindow)
+ steps = 1;
dir = -1;
}
self->valInTable = tablelist[ipos];
@@ -7327,6 +7332,7 @@ TableWrite_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self = (TableWrite *)type->tp_alloc(type, 0);
self->mode = 0;
+ self->maxwindow = 1024;
self->lastPos = -1;
self->lastValue = 0.0;
self->count = 0;
@@ -7336,11 +7342,10 @@ TableWrite_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
INIT_OBJECT_COMMON
Stream_setFunctionPtr(self->stream, TableWrite_compute_next_data_frame);
- Stream_setStreamActive(self->stream, 1);
- static char *kwlist[] = {"input", "pos", "table", "mode", NULL};
+ static char *kwlist[] = {"input", "pos", "table", "mode", "maxwindow", NULL};
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "OOOi", kwlist, &inputtmp, &postmp, &tabletmp, &self->mode))
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "OOOii", kwlist, &inputtmp, &postmp, &tabletmp, &self->mode, &self->maxwindow))
Py_RETURN_NONE;
INIT_INPUT_STREAM
@@ -7469,3 +7474,224 @@ TableWrite_members, /* tp_members */
0, /* tp_alloc */
TableWrite_new, /* tp_new */
};
+
+/*************************/
+/* SharedTable structure */
+/*************************/
+typedef struct {
+ pyo_table_HEAD
+ char *name;
+ int create;
+ int fd;
+} SharedTable;
+
+static int
+SharedTable_traverse(SharedTable *self, visitproc visit, void *arg)
+{
+ pyo_table_VISIT
+ return 0;
+}
+
+static int
+SharedTable_clear(SharedTable *self)
+{
+ pyo_table_CLEAR
+ return 0;
+}
+
+static void
+SharedTable_dealloc(SharedTable* self)
+{
+#if !defined(_WIN32) && !defined(_WIN64)
+ close(self->fd);
+ if (self->create)
+ shm_unlink(self->name);
+#endif
+ SharedTable_clear(self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+static PyObject *
+SharedTable_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ int i;
+ SharedTable *self;
+ self = (SharedTable *)type->tp_alloc(type, 0);
+
+ self->server = PyServer_get_server();
+
+ MAKE_NEW_TABLESTREAM(self->tablestream, &TableStreamType, NULL);
+
+ static char *kwlist[] = {"name", "create", "size", NULL};
+
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "sii", kwlist, &self->name, &self->create, &self->size))
+ Py_RETURN_NONE;
+
+#if !defined(_WIN32) && !defined(_WIN64)
+ /* Open shared memory object. */
+ if (self->create) {
+ self->fd = shm_open(self->name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
+ if (self->fd == -1) {
+ PySys_WriteStdout("SharedTable: failed to create shared memory.\n");
+ Py_RETURN_NONE;
+ }
+
+ if (ftruncate(self->fd, sizeof(MYFLT) * (self->size + 1)) == -1) {
+ PySys_WriteStdout("SharedTable: failed to truncate shared memory.\n");
+ close(self->fd);
+ shm_unlink(self->name);
+ Py_RETURN_NONE;
+ }
+ }
+ else {
+ self->fd = shm_open(self->name, O_RDWR, 0);
+ if (self->fd == -1) {
+ PySys_WriteStdout("SharedTable: failed to create shared memory.\n");
+ Py_RETURN_NONE;
+ }
+ }
+
+ /* Map shared memory object. */
+ self->data = mmap(NULL, sizeof(MYFLT) * (self->size + 1),
+ PROT_READ | PROT_WRITE, MAP_SHARED, self->fd, 0);
+ if (self->data == MAP_FAILED) {
+ PySys_WriteStdout("SharedTable: failed to mmap shared memory.\n");
+ close(self->fd);
+ if (self->create)
+ shm_unlink(self->name);
+ Py_RETURN_NONE;
+ }
+
+ /* Initialize the memory. */
+ if (self->create) {
+ for (i=0; i<=self->size; i++) {
+ self->data[i] = 0.0;
+ }
+ }
+#endif
+
+ TableStream_setSize(self->tablestream, self->size);
+ TableStream_setData(self->tablestream, self->data);
+
+ double sr = PyFloat_AsDouble(PyObject_CallMethod(self->server, "getSamplingRate", NULL));
+ TableStream_setSamplingRate(self->tablestream, sr);
+
+ return (PyObject *)self;
+}
+
+static PyObject * SharedTable_getServer(SharedTable* self) { GET_SERVER };
+static PyObject * SharedTable_getTableStream(SharedTable* self) { GET_TABLE_STREAM };
+static PyObject * SharedTable_setData(SharedTable *self, PyObject *arg) { SET_TABLE_DATA };
+static PyObject * SharedTable_normalize(SharedTable *self) { NORMALIZE };
+static PyObject * SharedTable_reset(SharedTable *self) { TABLE_RESET };
+static PyObject * SharedTable_removeDC(SharedTable *self) { REMOVE_DC };
+static PyObject * SharedTable_reverse(SharedTable *self) { REVERSE };
+static PyObject * SharedTable_invert(SharedTable *self) { INVERT };
+static PyObject * SharedTable_rectify(SharedTable *self) { RECTIFY };
+static PyObject * SharedTable_bipolarGain(SharedTable *self, PyObject *args, PyObject *kwds) { TABLE_BIPOLAR_GAIN };
+static PyObject * SharedTable_lowpass(SharedTable *self, PyObject *args, PyObject *kwds) { TABLE_LOWPASS };
+static PyObject * SharedTable_fadein(SharedTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEIN };
+static PyObject * SharedTable_fadeout(SharedTable *self, PyObject *args, PyObject *kwds) { TABLE_FADEOUT };
+static PyObject * SharedTable_pow(SharedTable *self, PyObject *args, PyObject *kwds) { TABLE_POWER };
+static PyObject * SharedTable_copy(SharedTable *self, PyObject *arg) { COPY };
+static PyObject * SharedTable_copyData(SharedTable *self, PyObject *args, PyObject *kwds) { TABLE_COPYDATA };
+static PyObject * SharedTable_rotate(SharedTable *self, PyObject *args, PyObject *kwds) { TABLE_ROTATE };
+static PyObject * SharedTable_setTable(SharedTable *self, PyObject *arg) { SET_TABLE };
+static PyObject * SharedTable_getTable(SharedTable *self) { GET_TABLE };
+static PyObject * SharedTable_getViewTable(SharedTable *self, PyObject *args, PyObject *kwds) { GET_VIEW_TABLE };
+static PyObject * SharedTable_put(SharedTable *self, PyObject *args, PyObject *kwds) { TABLE_PUT };
+static PyObject * SharedTable_get(SharedTable *self, PyObject *args, PyObject *kwds) { TABLE_GET };
+static PyObject * SharedTable_add(SharedTable *self, PyObject *arg) { TABLE_ADD };
+static PyObject * SharedTable_sub(SharedTable *self, PyObject *arg) { TABLE_SUB };
+static PyObject * SharedTable_mul(SharedTable *self, PyObject *arg) { TABLE_MUL };
+
+static PyObject *
+SharedTable_getSize(SharedTable *self)
+{
+ return PyInt_FromLong(self->size);
+};
+
+static PyObject *
+SharedTable_getRate(SharedTable *self)
+{
+ MYFLT sr = PyFloat_AsDouble(PyObject_CallMethod(self->server, "getSamplingRate", NULL)); \
+ return PyFloat_FromDouble(sr / self->size);
+};
+
+static PyMemberDef SharedTable_members[] = {
+ {"server", T_OBJECT_EX, offsetof(SharedTable, server), 0, "Pyo server."},
+ {"tablestream", T_OBJECT_EX, offsetof(SharedTable, tablestream), 0, "Table stream object."},
+ {NULL} /* Sentinel */
+};
+
+static PyMethodDef SharedTable_methods[] = {
+ {"getServer", (PyCFunction)SharedTable_getServer, METH_NOARGS, "Returns server object."},
+ {"copy", (PyCFunction)SharedTable_copy, METH_O, "Copy data from table given in argument."},
+ {"copyData", (PyCFunction)SharedTable_copyData, METH_VARARGS|METH_KEYWORDS, "Copy data from table given in argument."},
+ {"rotate", (PyCFunction)SharedTable_rotate, METH_VARARGS|METH_KEYWORDS, "Rotate table around position as argument."},
+ {"setTable", (PyCFunction)SharedTable_setTable, METH_O, "Sets the table content from a list of floats (must be the same size as the object size)."},
+ {"getTable", (PyCFunction)SharedTable_getTable, METH_NOARGS, "Returns a list of table samples."},
+ {"getViewTable", (PyCFunction)SharedTable_getViewTable, METH_VARARGS|METH_KEYWORDS, "Returns a list of pixel coordinates for drawing the table."},
+ {"getTableStream", (PyCFunction)SharedTable_getTableStream, METH_NOARGS, "Returns table stream object created by this table."},
+ {"setData", (PyCFunction)SharedTable_setData, METH_O, "Sets the table from samples in a text file."},
+ {"normalize", (PyCFunction)SharedTable_normalize, METH_NOARGS, "Normalize table samples between -1 and 1"},
+ {"reset", (PyCFunction)SharedTable_reset, METH_NOARGS, "Resets table samples to 0.0"},
+ {"removeDC", (PyCFunction)SharedTable_removeDC, METH_NOARGS, "Filter out DC offset from the table's data."},
+ {"reverse", (PyCFunction)SharedTable_reverse, METH_NOARGS, "Reverse the table's data."},
+ {"invert", (PyCFunction)SharedTable_invert, METH_NOARGS, "Reverse the table's data in amplitude."},
+ {"rectify", (PyCFunction)SharedTable_rectify, METH_NOARGS, "Positive rectification of the table's data."},
+ {"bipolarGain", (PyCFunction)SharedTable_bipolarGain, METH_VARARGS|METH_KEYWORDS, "Apply different amp values to positive and negative samples."},
+ {"lowpass", (PyCFunction)SharedTable_lowpass, METH_VARARGS|METH_KEYWORDS, "Apply a one-pole lowpass filter on table's samples."},
+ {"fadein", (PyCFunction)SharedTable_fadein, METH_VARARGS|METH_KEYWORDS, "Apply a gradual increase in the level of the table's samples."},
+ {"fadeout", (PyCFunction)SharedTable_fadeout, METH_VARARGS|METH_KEYWORDS, "Apply a gradual decrease in the level of the table's samples."},
+ {"pow", (PyCFunction)SharedTable_pow, METH_VARARGS|METH_KEYWORDS, "Apply a power function on each sample in the table."},
+ {"put", (PyCFunction)SharedTable_put, METH_VARARGS|METH_KEYWORDS, "Puts a value at specified position in the table."},
+ {"get", (PyCFunction)SharedTable_get, METH_VARARGS|METH_KEYWORDS, "Gets the value at specified position in the table."},
+ {"getSize", (PyCFunction)SharedTable_getSize, METH_NOARGS, "Return the size of the table in samples."},
+ {"getRate", (PyCFunction)SharedTable_getRate, METH_NOARGS, "Return the frequency (in cps) that reads the sound without pitch transposition."},
+ {"add", (PyCFunction)SharedTable_add, METH_O, "Performs table addition."},
+ {"sub", (PyCFunction)SharedTable_sub, METH_O, "Performs table substraction."},
+ {"mul", (PyCFunction)SharedTable_mul, METH_O, "Performs table multiplication."},
+ {NULL} /* Sentinel */
+};
+
+PyTypeObject SharedTableType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "_pyo.SharedTable_base", /*tp_name*/
+ sizeof(SharedTable), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)SharedTable_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_as_async (tp_compare in Python 2)*/
+ 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, /*tp_flags*/
+ "SharedTable objects. Generates an empty table.", /* tp_doc */
+ (traverseproc)SharedTable_traverse, /* tp_traverse */
+ (inquiry)SharedTable_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ SharedTable_methods, /* tp_methods */
+ SharedTable_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 */
+ SharedTable_new, /* tp_new */
+};
diff --git a/src/objects/trigmodule.c b/src/objects/trigmodule.c
index 201696a..d17d070 100644
--- a/src/objects/trigmodule.c
+++ b/src/objects/trigmodule.c
@@ -1337,7 +1337,14 @@ TrigFunc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
if (argtmp) {
- PyObject_CallMethod((PyObject *)self, "setArg", "O", argtmp);
+ if (PyTuple_Check(argtmp)) {
+ PyObject *argument = PyTuple_New(1);
+ PyTuple_SetItem(argument, 0, argtmp);
+ PyObject_CallMethod((PyObject *)self, "setArg", "O", argument);
+ }
+ else {
+ PyObject_CallMethod((PyObject *)self, "setArg", "O", argtmp);
+ }
}
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
diff --git a/utils/E-Pyo.py b/utils/E-Pyo.py
index b7c05b9..eca8bd4 100755
--- a/utils/E-Pyo.py
+++ b/utils/E-Pyo.py
@@ -3784,7 +3784,7 @@ class Editor(stc.StyledTextCtrl):
if ext in ["py", "pyw", "c5"]:
self.SetLexer(stc.STC_LEX_PYTHON)
self.SetStyleBits(self.GetStyleBitsNeeded())
- self.SetKeyWords(0, " ".join(keyword.kwlist) + " None True False ")
+ self.SetKeyWords(0, " ".join(keyword.kwlist) + " None True False print ")
self.SetKeyWords(1, " ".join(PYO_WORDLIST))
self.StyleSetSpec(stc.STC_P_DEFAULT, buildStyle('default'))
self.StyleSetSpec(stc.STC_P_COMMENTLINE, buildStyle('comment'))
diff --git a/utils/PyoDoc.py b/utils/PyoDoc.py
old mode 100644
new mode 100755
index b88322b..6de22e7
--- a/utils/PyoDoc.py
+++ b/utils/PyoDoc.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# encoding: utf-8
from __future__ import print_function
-import subprocess, threading, os, sys, unicodedata
+import subprocess, threading, os, sys, unicodedata, inspect
import wx
import wx.stc as stc
from wx.lib.embeddedimage import PyEmbeddedImage
@@ -225,7 +225,7 @@ under the current Python distribution to access these classes.
_DOC_KEYWORDS = ['Attributes', 'Examples', 'Methods', 'Notes', 'Methods details',
'Parentclass', 'Overview', 'Initline', 'Description', 'Parameters']
_HEADERS = ["Server", "PyoObjectBase", "Map", "Stream", "TableStream", "functions",
- "MidiListener", "OscListener", "PyoGui"]
+ "MidiListener", "MidiDispatcher", "OscListener", "PyoGui"]
_KEYWORDS_LIST = ['SLMap']
_KEYWORDS_LIST.extend(_HEADERS)
_NUM_PAGES = 1
@@ -247,14 +247,21 @@ for k1 in _HEADERS:
_KEYWORDS_LIST.extend(OBJECTS_TREE[k1])
_NUM_PAGES += len(OBJECTS_TREE[k1])
-PYOOBJECTBASE_METHODS_FILTER = [x[0] for x in inspect.getmembers(PyoObjectBase, inspect.ismethod)]
-PYOOBJECT_METHODS_FILTER = [x[0] for x in inspect.getmembers(PyoObject, inspect.ismethod)]
-PYOMATRIXOBJECT_METHODS_FILTER = [x[0] for x in inspect.getmembers(PyoMatrixObject, inspect.ismethod)]
-PYOTABLEOBJECT_METHODS_FILTER = [x[0] for x in inspect.getmembers(PyoTableObject, inspect.ismethod)]
-PYOPVOBJECT_METHODS_FILTER = [x[0] for x in inspect.getmembers(PyoPVObject, inspect.ismethod)]
-MAP_METHODS_FILTER = [x[0] for x in inspect.getmembers(Map, inspect.ismethod)]
-SLMAP_METHODS_FILTER = [x[0] for x in inspect.getmembers(SLMap, inspect.ismethod)]
-WXPANEL_METHODS_FILTER = [x[0] for x in inspect.getmembers(wx.Panel, inspect.ismethod)]
+def get_object_methods(obj, filter=[]):
+ o = eval(obj)
+ meths = [f for f in dir(o) if callable(getattr(o, f))]
+ meths = [f for f in meths if not f.startswith("__") and not f.startswith("_")]
+ meths = [f for f in meths if f not in filter]
+ return meths
+
+PYOOBJECTBASE_METHODS_FILTER = get_object_methods("PyoObjectBase")
+PYOOBJECT_METHODS_FILTER = get_object_methods("PyoObject")
+PYOMATRIXOBJECT_METHODS_FILTER = get_object_methods("PyoMatrixObject")
+PYOTABLEOBJECT_METHODS_FILTER = get_object_methods("PyoTableObject")
+PYOPVOBJECT_METHODS_FILTER = get_object_methods("PyoPVObject")
+MAP_METHODS_FILTER = get_object_methods("Map")
+SLMAP_METHODS_FILTER = get_object_methods("SLMap")
+WXPANEL_METHODS_FILTER = get_object_methods("wx.Panel")
def _ed_set_style(editor, searchKey=None):
editor.SetLexer(stc.STC_LEX_PYTHON)
@@ -747,7 +754,7 @@ class ManualPanel(wx.Treebook):
filter = WXPANEL_METHODS_FILTER
else:
filter = []
- obj_meths = [x[0] for x in inspect.getmembers(eval(obj), inspect.ismethod) if x[0] not in filter]
+ obj_meths = get_object_methods(obj, filter)
methods = ''
for meth in obj_meths:
docstr = getattr(eval(obj), meth).__doc__
@@ -1065,7 +1072,15 @@ class RunningThread(threading.Thread):
def kill(self):
self.terminated = True
- self.proc.terminate()
+ if PLATFORM == "win32":
+ try:
+ os.system("Taskkill /PID %d /F" % self.proc.pid)
+ except:
+ print('"Taskkill" does not succeed to kill the process %d.' % self.proc.pid)
+ else:
+ self.proc.terminate()
+ if self.proc.poll() == None:
+ self.proc.kill()
def run(self):
if self.osx_app_bundled:
@@ -1073,23 +1088,23 @@ class RunningThread(threading.Thread):
prelude = "export -n %s;export PATH=/usr/local/bin:/usr/local/lib:$PATH;env;" % vars_to_remove
if self.caller_need_to_invoke_32_bit:
self.proc = subprocess.Popen(["%s%s%s %s" % (prelude, self.set_32_bit_arch, self.which_python, self.path)],
- shell=True, cwd=self.cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ universal_newlines=True, shell=True, cwd=self.cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
else:
self.proc = subprocess.Popen(["%s%s %s" % (prelude, self.which_python, self.path)], cwd=self.cwd,
- shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ universal_newlines=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
elif wx.Platform == '__WXMAC__':
if self.caller_need_to_invoke_32_bit:
self.proc = subprocess.Popen(["%s%s %s" % (self.set_32_bit_arch, self.which_python, self.path)],
- shell=True, cwd=self.cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ universal_newlines=True, shell=True, cwd=self.cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
else:
self.proc = subprocess.Popen(["%s %s" % (self.which_python, self.path)], cwd=self.cwd,
- shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ universal_newlines=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
elif wx.Platform == "__WXMSW__":
- self.proc = subprocess.Popen([self.which_python, self.path], cwd=self.cwd,
- shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ self.proc = subprocess.Popen([self.which_python, "-u", self.path], cwd=ensureNFD(self.cwd),
+ universal_newlines=True, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
else:
self.proc = subprocess.Popen([self.which_python, self.path], cwd=self.cwd,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while self.proc.poll() == None and not self.terminated:
diff --git a/utils/epyo_builder_win32.py b/utils/epyo_builder_win32.py
index 70fd483..b9856ad 100644
--- a/utils/epyo_builder_win32.py
+++ b/utils/epyo_builder_win32.py
@@ -14,8 +14,7 @@ shutil.copytree("snippets", "Resources/snippets")
shutil.copytree("styles", "Resources/styles")
if version[0] < 3:
- os.system('C:\Python%d%d\Scripts\pyi-makespec -F -c --icon=Resources\E-PyoIcon.ico "E-Pyo.py"' % version)
- os.system('C:\Python%d%d\Scripts\pyi-build "E-Pyo.spec"' % version)
+ os.system('C:\Python%d%d\Scripts\pyinstaller --clean -F -c --icon=Resources\E-PyoIcon.ico "E-Pyo.py"' % version)
else:
os.system('pyinstaller --clean -F -c --icon=Resources\E-PyoIcon.ico "E-Pyo.py"')
diff --git a/utils/setup.py b/utils/setup.py
index 165595d..e9e05e9 100644
--- a/utils/setup.py
+++ b/utils/setup.py
@@ -16,11 +16,11 @@ OPTIONS = {'argv_emulation': False,
'CFBundleExecutable': 'E-Pyo',
'CFBundleIconFile': 'E-PyoIcon.icns',
'CFBundleIdentifier': 'com.ajaxsoundstudio.E-Pyo',
- 'CFBundleInfoDictionaryVersion': '0.8.1',
+ 'CFBundleInfoDictionaryVersion': '0.8.3',
'CFBundleName': 'E-Pyo',
'CFBundlePackageType': 'APPL',
- 'CFBundleShortVersionString': '0.8.1',
- 'CFBundleVersion': '0.8.1',
+ 'CFBundleShortVersionString': '0.8.3',
+ 'CFBundleVersion': '0.8.3',
'CFBundleDocumentTypes': [{'CFBundleTypeOSTypes': ['TEXT'],
'CFBundleTypeExtensions': ['py'],
'CFBundleTypeRole': 'Editor',
--
python-pyo packaging
More information about the pkg-multimedia-commits
mailing list