[SCM] python-pyo/master: New upstream release.
tiago at users.alioth.debian.org
tiago at users.alioth.debian.org
Tue Dec 13 20:35:47 UTC 2016
The following commit has been merged in the master branch:
commit 14ccf066f17510e555887c7fb0e2c0dd54002147
Author: Tiago Bortoletto Vaz <tiago at debian.org>
Date: Mon Mar 7 15:13:41 2016 -0500
New upstream release.
diff --git a/ChangeLog b/ChangeLog
index 4d9772e..27a003c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+2016-03-01 belangeo <belangeo at gmail.com>
+
+ * Final revision for version 0.7.9.
+ - SHA: 7ddbeacd14cd78ce4930c845a82745bb58f4a26c
+
+2016-03-01 belangeo <belangeo at gmail.com>
+
+ * Upgraded version number to 0.7.9.
+
+2016-03-01 belangeo <belangeo at gmail.com>
+
+ * Pyo now uses its own PRNG to avoid conflicts with other libs or
+ modules that use rand()/srand() in the same process. This fixed the
+ Server's global seed behaviour.
+
+2016-02-29 belangeo <belangeo at gmail.com>
+
+ * Fixed a bug, introduced by unicode addresses handler, in Open Sound
+ Control objects.
+
+2016-02-29 belangeo <belangeo at gmail.com>
+
+ * Exposed internal GUI widgets in the official API. New objects are
+ PyoGuiControlSlider, PyoGuiVuMeter, PyoGuiGrapher, PyoGuiMultiSlider,
+ PyoGuiSpectrum, PyoGuiScope and PyoGuiSndView.
+
+2016-02-17 belangeo <belangeo at gmail.com>
+
+ * E-Pyo: Added a warning before quitting the application.
+
+2016-02-12 belangeo <belangeo at gmail.com>
+
+ * Fixed a bug in Notein voice assignation.
+
+2016-02-12 belangeo <belangeo at gmail.com>
+
+ * Added readyToDetect() method to AttackDetector object.
+
+2016-01-29 belangeo <belangeo at gmail.com>
+
+ * Fixed segfault in Server dealloc function.
+
2016-01-08 belangeo <belangeo at gmail.com>
* Final revision for version 0.7.8.
diff --git a/debian/changelog b/debian/changelog
index 93f2b18..1075c0f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+python-pyo (0.7.9-1) unstable; urgency=medium
+
+ * New upstream release.
+
+ -- Tiago Bortoletto Vaz <tiago at debian.org> Mon, 07 Mar 2016 15:13:08 -0500
+
python-pyo (0.7.8+git20160129-1) unstable; urgency=medium
* Fix segfault when rendering.
diff --git a/doc-sphinx/source/api/classes/expression.rst b/doc-sphinx/source/api/classes/expression.rst
index c2e5e3a..4d544b6 100644
--- a/doc-sphinx/source/api/classes/expression.rst
+++ b/doc-sphinx/source/api/classes/expression.rst
@@ -94,7 +94,7 @@ Builtin functions
Comments
--------
-A comment start with two slashs ( // ) and ends at the end of the line::
+A comment starts with two slashs ( // ) and ends at the end of the line::
// This is a comment!
diff --git a/doc-sphinx/source/api/classes/index.rst b/doc-sphinx/source/api/classes/index.rst
index 3fb9d7c..95836a9 100644
--- a/doc-sphinx/source/api/classes/index.rst
+++ b/doc-sphinx/source/api/classes/index.rst
@@ -31,4 +31,5 @@ Classes by category
tables
matrices
map
+ wxgui
diff --git a/doc-sphinx/source/api/classes/wxgui.rst b/doc-sphinx/source/api/classes/wxgui.rst
new file mode 100644
index 0000000..2214a23
--- /dev/null
+++ b/doc-sphinx/source/api/classes/wxgui.rst
@@ -0,0 +1,52 @@
+Additional WxPython widgets
+===============================
+
+.. module:: pyo
+
+The classes in this module are based on internal classes that where
+originally designed to help the creation of graphical tools for the
+control and the visualization of audio signals. WxPython must be installed
+under the current Python distribution to access these classes.
+
+
+*PyoGuiControlSlider*
+-----------------------------------
+
+.. autoclass:: PyoGuiControlSlider
+ :members:
+
+*PyoGuiVuMeter*
+-----------------------------------
+
+.. autoclass:: PyoGuiVuMeter
+ :members:
+
+*PyoGuiGrapher*
+-----------------------------------
+
+.. autoclass:: PyoGuiGrapher
+ :members:
+
+*PyoGuiMultiSlider*
+-----------------------------------
+
+.. autoclass:: PyoGuiMultiSlider
+ :members:
+
+*PyoGuiSpectrum*
+-----------------------------------
+
+.. autoclass:: PyoGuiSpectrum
+ :members:
+
+*PyoGuiScope*
+-----------------------------------
+
+.. autoclass:: PyoGuiScope
+ :members:
+
+*PyoGuiSndView*
+-----------------------------------
+
+.. autoclass:: PyoGuiSndView
+ :members:
diff --git a/doc-sphinx/source/index.rst b/doc-sphinx/source/index.rst
index a07f281..64e0d41 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.7.8 documentation
+Welcome to the Pyo 0.7.9 documentation
===================================================
Pyo is a Python module written in C to help digital signal processing script
diff --git a/embedded/puredata/pyo~-help.pd b/embedded/puredata/pyo~-help.pd
index 9ba3bef..f2101a2 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 : October 2015;
-#X text 14 57 Version : 0.7.8;
+#X text 14 57 Version : 0.7.9;
#X text 15 108 pyo website : http://ajaxsoundstudio.com/software/pyo/
;
#X text 15 10 pyo~ : Embedded pyo scripting inside puredata.;
diff --git a/examples/effects/04_harmonizer.py b/examples/effects/04_harmonizer.py
index 98d9113..43676fc 100644
--- a/examples/effects/04_harmonizer.py
+++ b/examples/effects/04_harmonizer.py
@@ -10,7 +10,7 @@ s = Server(sr=44100, nchnls=2, buffersize=512, duplex=0).boot()
sf = SfPlayer('../snds/flute.aif', speed=1, loop=True, mul=.5).out()
-env = WinTable(7)
+env = WinTable(8)
wsize = .1
trans = -7
diff --git a/examples/effects/05_fuzz_disto.py b/examples/effects/05_fuzz_disto.py
index 1976ff8..e4f9a90 100644
--- a/examples/effects/05_fuzz_disto.py
+++ b/examples/effects/05_fuzz_disto.py
@@ -34,7 +34,7 @@ boost = Sig(bp, mul=BOOST)
sig = Lookup(table, boost)
# Lowpass filter on distorted signal
-lp = Tone(sig, freq=LP_CUTOFF_FREQ, mul=.7)
+lp = ButLP(sig, freq=LP_CUTOFF_FREQ, mul=.7)
# Balance between dry and wet signals
out = Interp(src, lp, interp=BALANCE).out()
diff --git a/examples/wxgui/01_gui_widgets_example.py b/examples/wxgui/01_gui_widgets_example.py
new file mode 100644
index 0000000..a196501
--- /dev/null
+++ b/examples/wxgui/01_gui_widgets_example.py
@@ -0,0 +1,236 @@
+"""
+Demo script for showing how GUI classes from pyo can be used to build
+audio programs with graphical interface.
+
+"""
+import wx, time, random
+from pyo import *
+
+NCHNLS = 2
+
+server = Server(nchnls=NCHNLS).boot().start()
+
+### A basic audio process ###
+snd = SndTable([SNDS_PATH+"/transparent.aif"]*NCHNLS)
+m = Metro(.125, poly=1).play()
+am = Iter(m, [1,0,0,0]*4)
+t2 = ExpTable([(0,1),(4096,10),(8191,10)], exp=4)
+q = TrigEnv(m, t2, m.time)
+pos = TrigLinseg(m, [(0.0,0.0), (m.time, 1,0)])
+n = Pointer(snd, pos, mul=am)
+fr = SigTo(1000, time=0.05, init=1000)
+f = ButBP(n, freq=fr, q=q).out()
+#pa = PeakAmp(f)
+sp = Spectrum(f)
+sc = Scope(f)
+
+class MyFrame(wx.Frame):
+ def __init__(self, parent, title, pos=(50, 50), size=(850, 600)):
+ wx.Frame.__init__(self, parent, -1, title, pos, size)
+ self.panel = wx.Panel(self)
+ vmainsizer = wx.BoxSizer(wx.VERTICAL)
+ mainsizer = wx.BoxSizer(wx.HORIZONTAL)
+ leftbox = wx.BoxSizer(wx.VERTICAL)
+ midbox = wx.BoxSizer(wx.VERTICAL)
+ rightbox = wx.BoxSizer(wx.VERTICAL)
+
+ ### PyoGuiControlSlider - logarithmic scale ###
+ sizer1 = self.createFreqSlider()
+
+ ### PyoGuiControlSlider - dB scale & VuMeter ###
+ sizer2 = self.createOutputBox()
+
+ ### PyoGuiGrapher - Filter's Q automation ###
+ sizer3 = self.createGrapher()
+
+ ### PyoGuiMultiSlider - Step Sequencer ###
+ sizer4 = self.createMultiSlider()
+
+ ### PyoGuiSpectrum - Frequency display ###
+ sizer5 = self.createSpectrum()
+
+ ### PyoGuiScope - oscilloscope display ###
+ sizer6 = self.createScope()
+
+ ### PyoGuiSndView - Soundfile display ###
+ sizer7 = self.createSndView()
+
+ leftbox.Add(sizer1, 0, wx.ALL | wx.EXPAND, 5)
+ leftbox.Add(sizer3, 1, wx.ALL | wx.EXPAND, 5)
+ leftbox.Add(sizer4, 1, wx.ALL | wx.EXPAND, 5)
+
+ midbox.Add(sizer5, 1, wx.ALL | wx.EXPAND, 5)
+ midbox.Add(sizer6, 1, wx.ALL | wx.EXPAND, 5)
+
+ rightbox.Add(sizer2, 1, wx.ALL | wx.EXPAND, 5)
+
+ mainsizer.Add(leftbox, 1, wx.ALL | wx.EXPAND, 5)
+ mainsizer.Add(midbox, 1, wx.ALL | wx.EXPAND, 5)
+ mainsizer.Add(rightbox, 0, wx.ALL | wx.EXPAND, 5)
+ vmainsizer.Add(mainsizer, 1, wx.ALL | wx.EXPAND, 5)
+ vmainsizer.Add(sizer7, 1, wx.ALL | wx.EXPAND, 5)
+ self.panel.SetSizerAndFit(vmainsizer)
+
+ def createFreqSlider(self):
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ label = wx.StaticText(self.panel, -1, "PyoGuiControlSlider: filter's center frequency (log scale)")
+ sizer.Add(label, 0, wx.CENTER|wx.ALL, 5)
+ self.freq = PyoGuiControlSlider(parent=self.panel,
+ minvalue=20,
+ maxvalue=20000,
+ init=1000,
+ pos=(0, 0),
+ size=(200, 16),
+ log=True,
+ integer=False,
+ powoftwo=False,
+ orient=wx.HORIZONTAL)
+ #print self.freq.getRange()
+ #print self.freq.isPowOfTwo()
+ self.freq.Bind(EVT_PYO_GUI_CONTROL_SLIDER, self.changeFreq)
+ sizer.Add(self.freq, 0, wx.ALL | wx.EXPAND, 5)
+ return sizer
+
+ def createOutputBox(self):
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ label = wx.StaticText(self.panel, -1, "dB slider - PyoGuiVuMeter")
+ sizer.Add(label, 0, wx.CENTER|wx.ALL, 5)
+ sizer1 = wx.BoxSizer(wx.HORIZONTAL)
+ self.amp = PyoGuiControlSlider(parent=self.panel,
+ minvalue=-60,
+ maxvalue=18,
+ init=-12,
+ pos=(0, 0),
+ size=(200, 16),
+ log=False,
+ integer=False,
+ powoftwo=False,
+ orient=wx.VERTICAL)
+ self.amp.Bind(EVT_PYO_GUI_CONTROL_SLIDER, self.changeGain)
+ self.meter = PyoGuiVuMeter(parent=self.panel,
+ nchnls=NCHNLS,
+ pos=(0, 0),
+ size=(5*NCHNLS, 200),
+ orient=wx.VERTICAL,
+ style=0)
+ self.meter.setNchnls(8)
+ # Register the VuMeter in the Server object.
+ server.setMeter(self.meter)
+ # or register its `setRms` method in a PeakAmp object.
+ # pa.setFunction(self.meter.setRms)
+
+ sizer1.Add(self.amp, 0, wx.ALL | wx.EXPAND, 5)
+ sizer1.Add(self.meter, 0, wx.ALL | wx.EXPAND, 5)
+ sizer.Add(sizer1, 1, wx.CENTER | wx.ALL, 5)
+ return sizer
+
+ def createGrapher(self):
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ label = wx.StaticText(self.panel, -1, "PyoGuiGrapher: Filter's Q automation")
+ sizer.Add(label, 0, wx.CENTER|wx.ALL, 5)
+ self.graph = PyoGuiGrapher(parent=self.panel,
+ xlen=8192,
+ yrange=(1.0, 10.0),
+ init=[(0.0, 0.0), (1.0, 1.0)],
+ mode=2,
+ exp=t2.exp,
+ inverse=True,
+ tension=0.75,
+ bias=8.0,
+ size=(300,100),
+ style=0)
+ self.graph.setValues(t2.getPoints())
+ self.graph.setYrange((0.1, 20))
+ self.graph.setInverse(False)
+ self.graph.Bind(EVT_PYO_GUI_GRAPHER, self.changeGraph)
+ sizer.Add(self.graph, 1, wx.ALL | wx.EXPAND, 5)
+ return sizer
+
+ def createMultiSlider(self):
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ label = wx.StaticText(self.panel, -1, "PyoGuiMultiSlider: Step Sequencer")
+ sizer.Add(label, 0, wx.CENTER|wx.ALL, 5)
+ self.steps = PyoGuiMultiSlider(parent=self.panel,
+ xlen=16,
+ yrange=(0, 1),
+ init=[1,0,0,0]*4,
+ size=(300,100),
+ style=0)
+ self.steps.setYrange((0, 2))
+ self.steps.setValues([random.uniform(0, 2) for i in range(16)])
+ self.steps.Bind(EVT_PYO_GUI_MULTI_SLIDER, self.changeSteps)
+ sizer.Add(self.steps, 1, wx.ALL | wx.EXPAND, 5)
+ return sizer
+
+ def createSpectrum(self):
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ label = wx.StaticText(self.panel, -1, "PyoGuiSpectrum: Frequency display")
+ sizer.Add(label, 0, wx.CENTER|wx.ALL, 5)
+ self.spectrum = PyoGuiSpectrum(parent=self.panel,
+ lowfreq=0,
+ highfreq=22050,
+ fscaling=1,
+ mscaling=1,
+ size=(300,150),
+ style=0)
+ self.spectrum.setAnalyzer(sp)
+ sizer.Add(self.spectrum, 1, wx.ALL | wx.EXPAND, 5)
+ return sizer
+
+ def createScope(self):
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ label = wx.StaticText(self.panel, -1, "PyoGuiScope: Oscilloscope display")
+ sizer.Add(label, 0, wx.CENTER|wx.ALL, 5)
+ self.scope = PyoGuiScope(parent=self.panel,
+ length=0.05,
+ gain=1,
+ size=(300,150),
+ style=0)
+ self.scope.setAnalyzer(sc)
+ self.scope.setLength(0.05)
+ self.scope.setGain(0.67)
+ sizer.Add(self.scope, 1, wx.ALL | wx.EXPAND, 5)
+ return sizer
+
+ def createSndView(self):
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ label = wx.StaticText(self.panel, -1, "PyoGuiSndView: Soundfile display")
+ sizer.Add(label, 0, wx.CENTER|wx.ALL, 5)
+ self.sndview = PyoGuiSndView(parent=self.panel,
+ size=(300,200),
+ style=0)
+ self.sndview.setTable(snd)
+ self.sndview.setSelection(0.51, 0.76)
+ self.sndview.Bind(EVT_PYO_GUI_SNDVIEW_MOUSE_POSITION, self.mousePos)
+ self.sndview.Bind(EVT_PYO_GUI_SNDVIEW_SELECTION, self.sndSelection)
+ sizer.Add(self.sndview, 1, wx.ALL | wx.EXPAND, 5)
+ return sizer
+
+ def changeFreq(self, evt):
+ fr.value = evt.value
+
+ def changeGain(self, evt):
+ am.mul = pow(10, evt.value * 0.05)
+
+ def changeGraph(self, evt):
+ t2.replace(evt.value)
+
+ def changeSteps(self, evt):
+ am.setChoice(evt.value)
+
+ def mousePos(self, evt):
+ print(evt.value)
+
+ def sndSelection(self, evt):
+ pos.replace([(0.0, evt.value[0]), (m.time, evt.value[1])])
+
+app = wx.App(False)
+mainFrame = MyFrame(None, title='Test Pyo GUI objects')
+mainFrame.Show()
+app.MainLoop()
+
+# Clean up...
+server.stop()
+time.sleep(0.25)
+server.shutdown()
+time.sleep(0.25)
\ No newline at end of file
diff --git a/include/pyomodule.h b/include/pyomodule.h
index b5ba8b5..4b61140 100644
--- a/include/pyomodule.h
+++ b/include/pyomodule.h
@@ -21,7 +21,7 @@
#include "Python.h"
#include <math.h>
-#define PYO_VERSION "0.7.8"
+#define PYO_VERSION "0.7.9"
#ifndef __MYFLT_DEF
#define __MYFLT_DEF
@@ -494,8 +494,10 @@ extern PyTypeObject ExprType;
#define PI M_PI
#define TWOPI (2 * M_PI)
+#define PYO_RAND_MAX 4294967295
+
/* random uniform (0.0 -> 1.0) */
-#define RANDOM_UNIFORM rand()/((MYFLT)(RAND_MAX)+1)
+#define RANDOM_UNIFORM (pyorand()/((MYFLT)(PYO_RAND_MAX)+1))
/* random objects identifier */
#define BEATER_ID 0
diff --git a/include/servermodule.h b/include/servermodule.h
index 31f22a1..255f674 100644
--- a/include/servermodule.h
+++ b/include/servermodule.h
@@ -141,10 +141,11 @@ typedef struct {
/* Properties */
int verbosity; /* a sum of values to display different levels: 1 = error */
/* 2 = message, 4 = warning , 8 = debug. Default 7.*/
- int globalSeed; /* initial seed for random objects. If -1, objects are seeded with the clock. */
+ int globalSeed; /* initial seed for random objects. If <= 0, objects are seeded with the clock. */
} Server;
PyObject * PyServer_get_server();
+extern unsigned int pyorand();
extern PyObject * Server_removeStream(Server *self, int sid);
extern MYFLT * Server_getInputBuffer(Server *self);
extern PmEvent * Server_getMidiEventBuffer(Server *self);
diff --git a/installers/osx/PkgResources_x86_64/ReadMe.rtf b/installers/osx/PkgResources_x86_64/ReadMe.rtf
index 4d01517..23774ec 100755
--- a/installers/osx/PkgResources_x86_64/ReadMe.rtf
+++ b/installers/osx/PkgResources_x86_64/ReadMe.rtf
@@ -1,84 +1,88 @@
-{\rtf1\ansi\deff3\adeflang1025
-{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f4\fswiss\fprq2\fcharset0 Liberation Sans{\*\falt Arial};}{\f5\froman\fprq2\fcharset0 LucidaGrande;}{\f6\fnil\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f7\fnil\fprq2\fcharset0 FreeSans;}{\f8\fswiss\fprq0\fcharset128 FreeSans;}}
-{\colortbl;\red0\green0\blue0;\red128\green128\blue128;}
-{\stylesheet{\s0\snext0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084 Normal;}
-{\s15\sbasedon0\snext16\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf1\kerning1\dbch\af7\langfe1081\dbch\af7\afs28\loch\f4\fs28\lang3084 Heading;}
-{\s16\sbasedon0\snext16\sl288\slmult1\ql\nowidctlpar\sb0\sa140\ltrpar\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\loch\f3\fs24\lang3084 Text Body;}
-{\s17\sbasedon16\snext17\sl288\slmult1\ql\nowidctlpar\sb0\sa140\ltrpar\cf1\kerning1\dbch\af7\langfe1081\dbch\af8\afs24\loch\f3\fs24\lang3084 List;}
-{\s18\sbasedon0\snext18\ql\nowidctlpar\sb120\sa120\noline\ltrpar\cf1\i\kerning1\dbch\af7\langfe1081\dbch\af8\afs24\ai\loch\f3\fs24\lang3084 Caption;}
-{\s19\sbasedon0\snext19\ql\nowidctlpar\noline\ltrpar\cf1\kerning1\dbch\af7\langfe1081\dbch\af8\afs24\loch\f3\fs24\lang3084 Index;}
-}{\info{\author olivier }{\creatim\yr0\mo0\dy0\hr0\min0}{\author olivier }{\revtim\yr2015\mo3\dy5\hr17\min29}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern67306242}}\deftab720
+{\rtf1\ansi\deff4\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\froman\fprq0\fcharset128 Times New Roman;}{\f5\froman\fprq0\fcharset128 Liberation Serif{\*\falt Times New Roman};}{\f6\froman\fprq0\fcharset128 LucidaGrande;}{\f7\froman\fprq0\fcharset128 Liberation Sans{\*\falt Arial};}{\f8\fnil\fprq2\fcharset0 FreeSans;}{\f9\fnil\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}}
+{\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\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084 Normal;}
+{\s1\sbasedon15\snext1\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf1\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\loch\f7\fs28\lang3084 Heading 1;}
+{\s2\sbasedon15\snext2\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf1\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\loch\f7\fs28\lang3084 Heading 2;}
+{\s3\sbasedon15\snext3\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf1\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\loch\f7\fs28\lang3084 Heading 3;}
+{\s15\sbasedon0\snext16\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf1\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\loch\f7\fs28\lang3084 Heading;}
+{\s16\sbasedon0\snext16\sl288\slmult1\ql\nowidctlpar\sb0\sa140\ltrpar\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\loch\f5\fs24\lang3084 Text Body;}
+{\s17\sbasedon16\snext17\sl288\slmult1\ql\nowidctlpar\sb0\sa140\ltrpar\cf1\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\loch\f5\fs24\lang3084 List;}
+{\s18\sbasedon0\snext18\ql\nowidctlpar\sb120\sa120\ltrpar\cf1\i\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\loch\f5\fs24\lang3084 Caption;}
+{\s19\sbasedon0\snext19\ql\nowidctlpar\ltrpar\cf1\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\loch\f5\fs24\lang3084 Index;}
+{\s20\sbasedon0\snext20\ql\nowidctlpar\ltrpar\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\loch\f5\fs24\lang3084 Quotations;}
+{\s21\sbasedon15\snext21\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf1\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\loch\f7\fs28\lang3084 Title;}
+{\s22\sbasedon15\snext22\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf1\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\loch\f7\fs28\lang3084 Subtitle;}
+}{\*\generator LibreOffice/5.0.2.2$Linux_X86_64 LibreOffice_project/00m0$Build-2}{\info{\author olivier }{\creatim\yr0\mo0\dy0\hr0\min0}{\author Olivier }{\revtim\yr2016\mo2\dy3\hr18\min50}{\printim\yr0\mo0\dy0\hr0\min0}}\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\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
-Python-pyo (version 0.7.}{\cf1\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
-5}{\cf1\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+{\*\ftnsep}\pgndec\pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\rtlch \ltrch\loch\fs26\loch\f6
+Python-pyo (version 0.7}{\rtlch \ltrch\loch\fs26\loch\f6
+.8}{\rtlch \ltrch\loch\fs26\loch\f6
)}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar\rtlch \ltrch\loch\fs26\loch\f6
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
-System requirements : OS X 10.6 to 10.}{\cf1\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
-10}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\rtlch \ltrch\loch\fs26\loch\f6
+System requirements : OS X 10.6 to 10.10}
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar\rtlch \ltrch\loch\fs26\loch\f6
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\rtlch \ltrch\loch\fs26\loch\f6
This package installs all the required components to run pyo inside your current Python installation. Python 2.6 or 2.7 (32/64 bit) must be already installed on your system.}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar\rtlch \ltrch\loch\fs26\loch\f6
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\rtlch \ltrch\loch\fs26\loch\f6
This package is divided into two separate installers. If you do not require one of them, please unselect the package in custom installation mode.}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar\rtlch \ltrch\loch\fs26\loch\f6
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b\rtlch \ltrch\loch\fs26\loch\f6
1. pyo extension:}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
The following components will be installed in the site-packages folder of the current Python Framework:}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar\b0\rtlch \ltrch\loch\fs26\loch\f6
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
_pyo.so}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
_pyo64.so}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
pyo.py}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
pyo64.py}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
pyolib (folder)}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar\b0\rtlch \ltrch\loch\fs26\loch\f6
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b\rtlch \ltrch\loch\fs26\loch\f6
2. Support libraries (i386 and x86_64):}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
This component will install a number of dynamic libraries on which pyo depends. If you already have these, then you can skip this installation.}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar\b0\rtlch \ltrch\loch\fs26\loch\f6
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
-Warning:}{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b\rtlch \ltrch\loch\fs26\loch\f6
+Warning:}{\b0\rtlch \ltrch\loch\fs26\loch\f6
this installation will overwrite any previously installed libraries. These are the libraries that will be installed in your /usr/local/lib directory:}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar\b0\rtlch \ltrch\loch\fs26\loch\f6
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
liblo.7.dylib}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
libportaudio.2.dylib}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
libportmidi.dylib}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
libsndfile.1.dylib}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
libFLAC.8.dylib}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
libvorbisenc.2.dylib}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
libvorbis.0.dylib}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
libogg.0.dylib}
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ltrpar\b0\rtlch \ltrch\loch\fs26\loch\f6
-\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf1\kerning1\dbch\af6\langfe1081\dbch\af6\afs24\alang1081\loch\f3\fs24\lang3084\ql\nowidctlpar{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
-Olivier B\u233\'e9langer, 201}{\cf1\b0\kerning1\dbch\af6\langfe1081\rtlch \ltrch\loch\fs26\lang3084\loch\f5
-5}
+\par \pard\plain \s0\ql\nowidctlpar\ltrpar\hyphpar0\cf1\kerning1\dbch\af9\langfe1081\dbch\af9\afs24\alang1081\loch\f5\fs24\lang3084\ql\nowidctlpar\ltrpar{\b0\rtlch \ltrch\loch\fs26\loch\f6
+Olivier B\u233\'3flanger, 2015}
\par }
\ No newline at end of file
diff --git a/installers/osx/release_x86_64.sh b/installers/osx/release_x86_64.sh
index 1a8eadb..bcd1103 100644
--- a/installers/osx/release_x86_64.sh
+++ b/installers/osx/release_x86_64.sh
@@ -7,9 +7,9 @@
# 3. cd utils and build E-Pyo
# 4. cd installers/osx and build the realease, only x86_64 version
-export PACKAGE_NAME=pyo_0.7.8_x86_64.pkg
-export DMG_DIR="pyo 0.7.8 Universal"
-export DMG_NAME="pyo_0.7.8_OSX-universal.dmg"
+export PACKAGE_NAME=pyo_0.7.9_x86_64.pkg
+export DMG_DIR="pyo 0.7.9 Universal"
+export DMG_NAME="pyo_0.7.9_OSX-universal.dmg"
export INSTALLER_DIR=`pwd`/installer
export PYO_MODULE_DIR=$INSTALLER_DIR/PyoModule/Package_Contents/tmp
export SUPPORT_LIBS_DIR=$INSTALLER_DIR/SupportLibs/Package_Contents/usr/local/lib
diff --git a/installers/win/win_installer_py26.iss b/installers/win/win_installer_py26.iss
index 3fe3d1c..e4ee877 100644
--- a/installers/win/win_installer_py26.iss
+++ b/installers/win/win_installer_py26.iss
@@ -3,7 +3,7 @@
#define appName "pyo"
#define pyVer "2.6"
-#define appVer "0.7.8"
+#define appVer "0.7.9"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
diff --git a/installers/win/win_installer_py27.iss b/installers/win/win_installer_py27.iss
index 2c55a83..809431f 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.7.8"
+#define appVer "0.7.9"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
diff --git a/pyo.py b/pyo.py
index b0fb79c..59f18b0 100644
--- a/pyo.py
+++ b/pyo.py
@@ -63,6 +63,8 @@ from pyolib.fourier import *
import pyolib.phasevoc as phasevoc
from pyolib.phasevoc import *
from pyolib._core import *
+from pyolib.wxgui import *
+import pyolib.wxgui as wxgui
if WITH_EXTERNALS:
import pyolib.external as external
from pyolib.external import *
@@ -119,11 +121,13 @@ OBJECTS_TREE = {'functions': sorted(['pa_count_devices', 'pa_get_default_input',
'TranspoToCents', 'MToF', 'FToM', 'MToT', 'TrackHold', 'Resample', 'Expr']),
'expression': sorted(['Expr']),
'fourier': sorted(['FFT', 'IFFT', 'CarToPol', 'PolToCar', 'FrameDelta', 'FrameAccum', 'Vectral', 'CvlVerb'])}},
- 'Map': {'SLMap': sorted(['SLMapFreq', 'SLMapMul', 'SLMapPhase', 'SLMapQ', 'SLMapDur', 'SLMapPan'])},
- 'Server': [],
- 'MidiListener': [],
- 'OscListener': [],
- 'Stream': [],
- 'TableStream': []}
+ 'Map': {'SLMap': sorted(['SLMapFreq', 'SLMapMul', 'SLMapPhase', 'SLMapQ', 'SLMapDur', 'SLMapPan'])},
+ 'Server': [],
+ 'MidiListener': [],
+ 'OscListener': [],
+ 'Stream': [],
+ 'TableStream': [],
+ 'PyoGui': ['PyoGuiControlSlider', 'PyoGuiVuMeter', 'PyoGuiGrapher', 'PyoGuiMultiSlider', 'PyoGuiSpectrum', 'PyoGuiScope',
+ 'PyoGuiSndView']}
DOC_KEYWORDS = ['Attributes', 'Examples', 'Parameters', 'Methods', 'Notes', 'Methods details', 'See also', 'Parentclass']
\ No newline at end of file
diff --git a/pyolib/_widgets.py b/pyolib/_widgets.py
index 2cfb089..63459eb 100644
--- a/pyolib/_widgets.py
+++ b/pyolib/_widgets.py
@@ -73,10 +73,8 @@ MATRIXWINDOWS = []
SPECTRUMWINDOWS = []
SCOPEWINDOWS = []
EXPREDITORWINDOWS = []
-WX_APP = False
def createRootWindow():
- global WX_APP
if not PYO_USE_WX:
if len(WINDOWS) == 0:
root = Tk()
@@ -85,9 +83,8 @@ def createRootWindow():
else:
return None
else:
- if not WX_APP:
- win = wx.App(False)
- WX_APP = True
+ if wx.GetApp() is None:
+ win = wx.App()
return win
else:
return None
@@ -130,7 +127,7 @@ def wxDisplayWindow(f, title):
def wxShowWindow(f, title, root):
f.SetTitle(title)
f.Show()
- if root != None:
+ if root is not None:
root.MainLoop()
def wxCreateDelayedCtrlWindows():
@@ -215,7 +212,7 @@ def createCtrlWindow(obj, map_list, title, wxnoserver=False):
if title == None: title = obj.__class__.__name__
win.title(title)
else:
- if wxnoserver or WX_APP:
+ if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = PyoObjectControl(None, obj, map_list)
if title == None: title = obj.__class__.__name__
@@ -227,7 +224,7 @@ def createGraphWindow(obj, mode, xlen, yrange, title, wxnoserver=False):
if not PYO_USE_WX:
print "WxPython must be installed to use the 'graph()' method."
else:
- if wxnoserver or WX_APP:
+ if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = TableGrapher(None, obj, mode, xlen, yrange)
if title == None: title = obj.__class__.__name__
@@ -239,12 +236,12 @@ def createDataGraphWindow(obj, yrange, title, wxnoserver=False):
if not PYO_USE_WX:
print "WxPython must be installed to use the 'graph()' method."
else:
- if wxnoserver or WX_APP:
+ if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = DataTableGrapher(None, obj, yrange)
if title == None: title = obj.__class__.__name__
- wxShowWindow(f, title, root)
obj._setGraphFrame(f)
+ wxShowWindow(f, title, root)
else:
DATAGRAPHWINDOWS.append([obj, yrange, title])
@@ -257,12 +254,12 @@ def createViewTableWindow(samples, title="Table waveform", wxnoserver=False, tab
win.resizable(False, False)
win.title(title)
else:
- if wxnoserver or WX_APP:
+ if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = ViewTable(None, samples, tableclass, object)
- wxShowWindow(f, title, root)
if object != None:
object._setViewFrame(f)
+ wxShowWindow(f, title, root)
else:
TABLEWINDOWS.append([samples, tableclass, title, object])
@@ -275,12 +272,12 @@ def createSndViewTableWindow(obj, title="Table waveform", wxnoserver=False, tabl
win.resizable(False, False)
win.title(title)
else:
- if wxnoserver or WX_APP:
+ if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = SndViewTable(None, obj, tableclass, mouse_callback)
if title == None: title = obj.__class__.__name__
- wxShowWindow(f, title, root)
obj._setViewFrame(f)
+ wxShowWindow(f, title, root)
else:
SNDTABLEWINDOWS.append([obj, tableclass, title, mouse_callback])
@@ -295,13 +292,13 @@ It helps a lot to speed up matrix drawing!"""
win.resizable(False, False)
win.title(title)
else:
- if wxnoserver or WX_APP:
+ if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
if WITH_PIL: f = ViewMatrix_withPIL(None, samples, size, object)
else: f = ViewMatrix_withoutPIL(None, samples, size, object)
- wxShowWindow(f, title, root)
if object != None:
object._setViewFrame(f)
+ wxShowWindow(f, title, root)
else:
MATRIXWINDOWS.append([samples,size,title, object])
@@ -309,13 +306,13 @@ def createSpectrumWindow(object, title, wxnoserver=False):
if not PYO_USE_WX:
print "WxPython must be installed to use the Spectrum display."
else:
- if wxnoserver or WX_APP:
+ if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = SpectrumDisplay(None, object)
if title == None: title = object.__class__.__name__
- wxShowWindow(f, title, root)
if object != None:
object._setViewFrame(f)
+ wxShowWindow(f, title, root)
else:
SPECTRUMWINDOWS.append([object, title])
@@ -323,13 +320,13 @@ def createScopeWindow(object, title, wxnoserver=False):
if not PYO_USE_WX:
print "WxPython must be installed to use the Scope display."
else:
- if wxnoserver or WX_APP:
+ if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = ScopeDisplay(None, object)
if title == None: title = object.__class__.__name__
- wxShowWindow(f, title, root)
if object != None:
object._setViewFrame(f)
+ wxShowWindow(f, title, root)
else:
SCOPEWINDOWS.append([object, title])
@@ -337,7 +334,7 @@ def createExprEditorWindow(object, title, wxnoserver=False):
if not PYO_USE_WX:
print "WxPython must be installed to use the Expr editor display."
else:
- if wxnoserver or WX_APP:
+ if wxnoserver or wx.GetApp() is not None:
root = createRootWindow()
f = ExprEditorFrame(None, object)
if title == None: title = object.__class__.__name__
diff --git a/pyolib/_wxwidgets.py b/pyolib/_wxwidgets.py
index 50a81b5..4f8a6d4 100644
--- a/pyolib/_wxwidgets.py
+++ b/pyolib/_wxwidgets.py
@@ -18,7 +18,7 @@ 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 wx, os, sys, math, time, random, unicodedata
-from types import ListType, FloatType, IntType, UnicodeType
+from types import ListType, FloatType, IntType, UnicodeType, TupleType
import wx.stc as stc
try:
@@ -400,6 +400,8 @@ class ControlSlider(wx.Panel):
evt.Skip()
+# TODO: key, command and slmap should be removed from the multislider widget.
+# It should work in the same way as the ControlSlider widget.
class MultiSlider(wx.Panel):
def __init__(self, parent, init, key, command, slmap):
wx.Panel.__init__(self, parent, size=(250,250))
@@ -480,12 +482,13 @@ class MultiSlider(wx.Panel):
self.Refresh()
class VuMeter(wx.Panel):
- def __init__(self, parent, size=(200,11), numSliders=2, orient=wx.HORIZONTAL):
+ def __init__(self, parent, size=(200,11), numSliders=2, orient=wx.HORIZONTAL,
+ pos=wx.DefaultPosition, style=0):
if orient == wx.HORIZONTAL:
size = (size[0], numSliders * 5 + 1)
else:
size = (numSliders * 5 + 1, size[1])
- wx.Panel.__init__(self, parent, -1, size=size)
+ wx.Panel.__init__(self, parent, -1, pos=pos, size=size, style=style)
self.parent = parent
self.orient = orient
self.SetBackgroundColour("#000000")
@@ -589,8 +592,11 @@ class VuMeter(wx.Panel):
height = 6
for i in range(self.numSliders):
y = i * (height - 1)
- db = math.log10(self.amplitude[i]+0.00001) * 0.2 + 1.
- width = int(db*w)
+ if i < len(self.amplitude):
+ db = math.log10(self.amplitude[i]+0.00001) * 0.2 + 1.
+ width = int(db*w)
+ else:
+ width = 0
dc.DrawBitmap(self.backBitmap, 0, y)
if width > 0:
dc.SetClippingRegion(0, y, width, height)
@@ -600,8 +606,11 @@ class VuMeter(wx.Panel):
width = 6
for i in range(self.numSliders):
y = i * (width - 1)
- db = math.log10(self.amplitude[i]+0.00001) * 0.2 + 1.
- height = int(db*h)
+ if i < len(self.amplitude):
+ db = math.log10(self.amplitude[i]+0.00001) * 0.2 + 1.
+ height = int(db*h)
+ else:
+ height = 0
dc.DrawBitmap(self.backBitmap, y, 0)
if height > 0:
dc.SetClippingRegion(y, h-height, width, height)
@@ -612,12 +621,17 @@ class VuMeter(wx.Panel):
def OnClose(self, evt):
self.Destroy()
+# TODO: BACKGROUND_COLOUR hard-coded all over the place in this class.
class RangeSlider(wx.Panel):
def __init__(self, parent, minvalue, maxvalue, init=None, pos=(0,0), size=(200,15),
- valtype='int', log=False, function=None):
+ valtype='int', log=False, function=None, backColour=None):
wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY, pos=pos, size=size, style=wx.NO_BORDER)
+ if backColour:
+ self.backgroundColour = backColour
+ else:
+ self.backgroundColour = BACKGROUND_COLOUR
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
- self.SetBackgroundColour(BACKGROUND_COLOUR)
+ self.SetBackgroundColour(self.backgroundColour)
self.SetMinSize(self.GetSize())
self.sliderHeight = 15
self.borderWidth = 1
@@ -653,8 +667,8 @@ class RangeSlider(wx.Panel):
w, h = self.GetSize()
b = wx.EmptyBitmap(w,h)
dc = wx.MemoryDC(b)
- dc.SetPen(wx.Pen(BACKGROUND_COLOUR, width=1))
- dc.SetBrush(wx.Brush(BACKGROUND_COLOUR))
+ dc.SetPen(wx.Pen(self.backgroundColour, width=1))
+ dc.SetBrush(wx.Brush(self.backgroundColour))
dc.DrawRectangle(0,0,w,h)
dc.SetBrush(wx.Brush("#777777"))
dc.SetPen(wx.Pen("#FFFFFF", width=1))
@@ -749,9 +763,10 @@ class RangeSlider(wx.Panel):
class HRangeSlider(RangeSlider):
def __init__(self, parent, minvalue, maxvalue, init=None, pos=(0,0), size=(200,15),
- valtype='int', log=False, function=None):
- RangeSlider.__init__(self, parent, minvalue, maxvalue, init, pos, size, valtype, log, function)
+ valtype='int', log=False, function=None, backColour=None):
+ RangeSlider.__init__(self, parent, minvalue, maxvalue, init, pos, size, valtype, log, function, backColour)
self.SetMinSize((50, 15))
+
self.createSliderBitmap()
#self.createBackgroundBitmap()
self.clampHandlePos()
@@ -767,11 +782,11 @@ class HRangeSlider(RangeSlider):
self.backgroundBitmap = wx.EmptyBitmap(w,h)
dc = wx.MemoryDC(self.backgroundBitmap)
- dc.SetBrush(wx.Brush(BACKGROUND_COLOUR, wx.SOLID))
+ dc.SetBrush(wx.Brush(self.backgroundColour, wx.SOLID))
dc.Clear()
# Draw background
- dc.SetPen(wx.Pen(BACKGROUND_COLOUR, width=self.borderWidth, style=wx.SOLID))
+ dc.SetPen(wx.Pen(self.backgroundColour, width=self.borderWidth, style=wx.SOLID))
dc.DrawRectangle(0, 0, w, h)
# Draw inner part
@@ -831,9 +846,9 @@ class HRangeSlider(RangeSlider):
dc = wx.AutoBufferedPaintDC(self)
# Draw background
- dc.SetBrush(wx.Brush(BACKGROUND_COLOUR))
+ dc.SetBrush(wx.Brush(self.backgroundColour))
dc.Clear()
- dc.SetPen(wx.Pen(BACKGROUND_COLOUR))
+ dc.SetPen(wx.Pen(self.backgroundColour))
dc.DrawRectangle(0, 0, w, h)
#dc.DrawBitmap(self.backgroundBitmap, 0, 0)
@@ -991,7 +1006,6 @@ class ViewTablePanel(wx.Panel):
else:
self.dcref = wx.PaintDC
-
def draw(self, samples):
self.samples = samples
self.Refresh()
@@ -1050,25 +1064,61 @@ class SndViewTable(wx.Frame):
self.Destroy()
class SndViewTablePanel(wx.Panel):
- def __init__(self, parent, obj, mouse_callback=None):
+ def __init__(self, parent, obj=None, mouse_callback=None, select_callback=None):
wx.Panel.__init__(self, parent)
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown)
self.Bind(wx.EVT_LEFT_UP, self.OnMouseUp)
+ self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
+ self.Bind(wx.EVT_RIGHT_UP, self.OnMouseUp)
self.Bind(wx.EVT_MOTION, self.OnMotion)
self.Bind(wx.EVT_SIZE, self.OnSize)
+ self.refresh_from_selection = False
+ self.background_bitmap = None
self.obj = obj
- self.chnls = len(self.obj)
+ self.selstart = self.selend = self.movepos = None
+ self.moveSelection = False
+ self.createSelection = False
self.begin = 0
- self.end = self.obj.getDur(False)
+ if self.obj is not None:
+ self.chnls = len(self.obj)
+ self.end = self.obj.getDur(False)
+ else:
+ self.chnls = 1
+ self.end = 1.0
+ self.img = [[]]
self.mouse_callback = mouse_callback
+ self.select_callback = select_callback
if sys.platform == "win32":
self.dcref = wx.BufferedPaintDC
else:
self.dcref = wx.PaintDC
self.setImage()
+ def getDur(self):
+ if self.obj is not None:
+ return self.obj.getDur(False)
+ else:
+ return 1.0
+
+ def resetSelection(self):
+ self.selstart = self.selend = None
+ if self.background_bitmap is not None:
+ self.refresh_from_selection = True
+ self.Refresh()
+ if self.select_callback != None:
+ self.select_callback((0.0, 1.0))
+
+ def setSelection(self, start, stop):
+ self.selstart = start
+ self.selend = stop
+ if self.background_bitmap is not None:
+ self.refresh_from_selection = True
+ self.Refresh()
+ if self.select_callback != None:
+ self.select_callback((self.selstart, self.selend))
+
def setBegin(self, x):
self.begin = x
@@ -1076,8 +1126,9 @@ class SndViewTablePanel(wx.Panel):
self.end = x
def setImage(self):
- self.img = self.obj.getViewTable(self.GetSize(), self.begin, self.end)
- self.Refresh()
+ if self.obj is not None:
+ self.img = self.obj.getViewTable(self.GetSize(), self.begin, self.end)
+ self.Refresh()
def clipPos(self, pos):
if pos[0] < 0.0: x = 0.0
@@ -1086,7 +1137,8 @@ class SndViewTablePanel(wx.Panel):
if pos[1] < 0.0: y = 0.0
elif pos[1] > 1.0: y = 1.0
else: y = pos[1]
- x = x * ((self.end - self.begin) / self.obj.getDur(False)) + (self.begin / self.obj.getDur(False))
+ if self.obj is not None:
+ x = x * ((self.end - self.begin) / self.obj.getDur(False)) + (self.begin / self.obj.getDur(False))
return (x, y)
def OnMouseDown(self, evt):
@@ -1101,6 +1153,29 @@ class SndViewTablePanel(wx.Panel):
self.mouse_callback(pos)
self.CaptureMouse()
+ def OnRightDown(self, evt):
+ size = self.GetSize()
+ pos = evt.GetPosition()
+ if pos[1] <= 0:
+ pos = (float(pos[0])/size[0], 1.0)
+ else:
+ pos = (float(pos[0])/size[0], 1.-(float(pos[1])/size[1]))
+ pos = self.clipPos(pos)
+ if evt.ShiftDown():
+ if self.selstart is not None and self.selend is not None:
+ self.moveSelection = True
+ self.movepos = pos[0]
+ elif evt.CmdDown():
+ self.selstart = self.selend = None
+ self.refresh_from_selection = True
+ self.Refresh()
+ if self.select_callback != None:
+ self.select_callback((0.0, 1.0))
+ else:
+ self.createSelection = True
+ self.selstart = pos[0]
+ self.CaptureMouse()
+
def OnMotion(self, evt):
if self.HasCapture():
size = self.GetSize()
@@ -1110,20 +1185,40 @@ class SndViewTablePanel(wx.Panel):
else:
pos = (float(pos[0])/size[0], 1.-(float(pos[1])/size[1]))
pos = self.clipPos(pos)
- if self.mouse_callback != None:
- self.mouse_callback(pos)
+ if evt.LeftIsDown():
+ if self.mouse_callback != None:
+ self.mouse_callback(pos)
+ elif evt.RightIsDown():
+ refresh = False
+ if self.createSelection:
+ self.selend = pos[0]
+ refresh = True
+ elif self.moveSelection:
+ diff = pos[0] - self.movepos
+ self.movepos = pos[0]
+ self.selstart += diff
+ self.selend += diff
+ refresh = True
+ if refresh:
+ self.refresh_from_selection = True
+ self.Refresh()
+ if self.select_callback != None:
+ self.select_callback((self.selstart, self.selend))
def OnMouseUp(self, evt):
if self.HasCapture():
self.ReleaseMouse()
+ self.createSelection = self.moveSelection = False
- def OnPaint(self, evt):
+ def create_background(self):
w,h = self.GetSize()
- dc = self.dcref(self)
+ self.background_bitmap = wx.EmptyBitmap(w, h)
+ dc = wx.MemoryDC(self.background_bitmap)
gc = wx.GraphicsContext_Create(dc)
dc.SetBrush(wx.Brush("#FFFFFF"))
dc.Clear()
dc.DrawRectangle(0,0,w,h)
+
off = h/self.chnls/2
gc.SetPen(wx.Pen('#000000', width=1, style=wx.SOLID))
gc.SetBrush(wx.Brush("#FFFFFF", style=wx.TRANSPARENT))
@@ -1132,7 +1227,7 @@ class SndViewTablePanel(wx.Panel):
font, ptsize = dc.GetFont(), dc.GetFont().GetPointSize()
font.SetPointSize(ptsize - 3)
dc.SetFont(font)
- elif sys.platform == "win32":
+ else:
font = dc.GetFont()
font.SetPointSize(8)
dc.SetFont(font)
@@ -1159,6 +1254,42 @@ class SndViewTablePanel(wx.Panel):
dc.SetPen(wx.Pen('#000000', width=1))
dc.DrawLine(0, h-y, w, h-y)
+ dc.SelectObject(wx.NullBitmap)
+
+ def OnPaint(self, evt):
+ w,h = self.GetSize()
+ dc = self.dcref(self)
+ gc = wx.GraphicsContext_Create(dc)
+ dc.SetBrush(wx.Brush("#FFFFFF"))
+ dc.Clear()
+ dc.DrawRectangle(0,0,w,h)
+
+ if not self.refresh_from_selection:
+ self.create_background()
+
+ dc.DrawBitmap(self.background_bitmap, 0, 0)
+
+ if self.selstart is not None and self.selend is not None:
+ gc.SetPen(wx.Pen(wx.Colour(0, 0, 0, 64)))
+ gc.SetBrush(wx.Brush(wx.Colour(0, 0, 0, 64)))
+ if self.obj is not None:
+ dur = self.obj.getDur(False)
+ else:
+ dur = 1.0
+ selstartabs = min(self.selstart, self.selend) * dur
+ selendabs = max(self.selstart, self.selend) * dur
+ if selstartabs < self.begin:
+ startpix = 0
+ else:
+ startpix = ((selstartabs - self.begin) / (self.end - self.begin)) * w
+ if selendabs > self.end:
+ endpix = w
+ else:
+ endpix = ((selendabs - self.begin) / (self.end - self.begin)) * w
+ gc.DrawRectangle(startpix, 0, endpix - startpix, h)
+
+ self.refresh_from_selection = False
+
def OnSize(self, evt):
wx.CallAfter(self.setImage)
@@ -1364,39 +1495,48 @@ class SpectrumDisplay(wx.Frame):
self.obj._setViewFrame(None)
self.Destroy()
+# TODO: Adjust the font size according to the size of the panel.
class SpectrumPanel(wx.Panel):
- def __init__(self, parent, chnls, lowfreq, highfreq, fscaling, mscaling):
- wx.Panel.__init__(self, parent)
+ def __init__(self, parent, chnls, lowfreq, highfreq, fscaling, mscaling,
+ pos=wx.DefaultPosition, size=wx.DefaultSize, style=0):
+ wx.Panel.__init__(self, parent, pos=pos, size=size, style=style)
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_SIZE, self.OnSize)
- self.chnls = chnls
+ #self.chnls = chnls
self.img = None
+ self.obj = None
self.lowfreq = lowfreq
self.highfreq = highfreq
self.fscaling = fscaling
self.mscaling = mscaling
- if self.chnls == 1:
- self.pens = [wx.Pen(wx.Colour(100,0,0))]
- self.brushes = [wx.Brush(wx.Colour(166,4,0))]
- else:
- self.pens = [wx.Pen(wx.Colour(166,4,0)), wx.Pen(wx.Colour(8,11,116)), wx.Pen(wx.Colour(0,204,0)),
- wx.Pen(wx.Colour(255,167,0)), wx.Pen(wx.Colour(133,0,75)), wx.Pen(wx.Colour(255,236,0)),
- wx.Pen(wx.Colour(1,147,154)), wx.Pen(wx.Colour(162,239,0))]
- self.brushes = [wx.Brush(wx.Colour(166,4,0,128)), wx.Brush(wx.Colour(8,11,116,128)), wx.Brush(wx.Colour(0,204,0,128)),
- wx.Brush(wx.Colour(255,167,0,128)), wx.Brush(wx.Colour(133,0,75,128)), wx.Brush(wx.Colour(255,236,0,128)),
- wx.Brush(wx.Colour(1,147,154,128)), wx.Brush(wx.Colour(162,239,0,128))]
+ self.pens = [wx.Pen(wx.Colour(166,4,0)), wx.Pen(wx.Colour(8,11,116)), wx.Pen(wx.Colour(0,204,0)),
+ wx.Pen(wx.Colour(255,167,0)), wx.Pen(wx.Colour(133,0,75)), wx.Pen(wx.Colour(255,236,0)),
+ wx.Pen(wx.Colour(1,147,154)), wx.Pen(wx.Colour(162,239,0))]
+ self.brushes = [wx.Brush(wx.Colour(166,4,0,128)), wx.Brush(wx.Colour(8,11,116,128)), wx.Brush(wx.Colour(0,204,0,128)),
+ wx.Brush(wx.Colour(255,167,0,128)), wx.Brush(wx.Colour(133,0,75,128)), wx.Brush(wx.Colour(255,236,0,128)),
+ wx.Brush(wx.Colour(1,147,154,128)), wx.Brush(wx.Colour(162,239,0,128))]
if sys.platform == "win32":
self.dcref = wx.BufferedPaintDC
else:
self.dcref = wx.PaintDC
def OnSize(self, evt):
- self.GetParent().GetParent().setDisplaySize(self.GetSize())
+ try:
+ self.GetParent().GetParent().setDisplaySize(self.GetSize())
+ except:
+ pass
+ try:
+ size = self.GetSize()
+ self.obj.setWidth(size[0])
+ self.obj.setHeight(size[1])
+ except:
+ pass
+
self.Refresh()
def setImage(self, points):
- self.img = [points[i] for i in range(self.chnls)]
+ self.img = [points[i] for i in range(len(points))]
self.Refresh()
def setFscaling(self, x):
@@ -1416,10 +1556,10 @@ class SpectrumPanel(wx.Panel):
dc = self.dcref(self)
gc = wx.GraphicsContext_Create(dc)
tw, th = dc.GetTextExtent("0")
-
+
# background
background = gc.CreatePath()
- background.AddRectangle(0,0,w,h)
+ background.AddRectangle(0,0,w-1,h-1)
gc.SetPen(wx.BLACK_PEN)
gc.SetBrush(wx.WHITE_BRUSH)
gc.DrawPath(background)
@@ -1531,18 +1671,18 @@ class SpectrumPanel(wx.Panel):
dc.DrawLine(0, pos, w-mw-6, pos)
i += 1
- last_tw = tw
- # legend
- tw, th = dc.GetTextExtent("chan 8")
- for i in range(self.chnls):
- dc.SetTextForeground(self.pens[i].GetColour())
- dc.DrawText("chan %d" % (i+1), w-tw-20-last_tw, i*th+th+7)
-
# spectrum
if self.img != None:
+ last_tw = tw
+ # legend
+ tw, th = dc.GetTextExtent("chan 8")
+ for i in range(len(self.img)):
+ dc.SetTextForeground(self.pens[i%8].GetColour())
+ dc.DrawText("chan %d" % (i+1), w-tw-20-last_tw, i*th+th+7)
+ # channel spectrums
for i, samples in enumerate(self.img):
- gc.SetPen(self.pens[i])
- gc.SetBrush(self.brushes[i])
+ gc.SetPen(self.pens[i%8])
+ gc.SetBrush(self.brushes[i%8])
gc.DrawLines(samples)
######################################################################
@@ -1613,22 +1753,24 @@ class ScopeDisplay(wx.Frame):
self.Destroy()
class ScopePanel(wx.Panel):
- def __init__(self, parent, obj):
- wx.Panel.__init__(self, parent)
+ def __init__(self, parent, obj=None, pos=wx.DefaultPosition,
+ size=wx.DefaultSize, style=0):
+ wx.Panel.__init__(self, parent, pos=pos, size=size, style=style)
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.img = [[]]
self.obj = obj
- self.gain = self.obj.gain
- self.length = self.obj.length
- self.chnls = len(self.obj)
- if self.chnls == 1:
- self.pens = [wx.Pen(wx.Colour(100,0,0), width=2)]
+ if self.obj is not None:
+ self.gain = self.obj.gain
+ self.length = self.obj.length
else:
- self.pens = [wx.Pen(wx.Colour(166,4,0), width=2), wx.Pen(wx.Colour(8,11,116), width=2), wx.Pen(wx.Colour(0,204,0), width=2),
- wx.Pen(wx.Colour(255,167,0), width=2), wx.Pen(wx.Colour(133,0,75), width=2), wx.Pen(wx.Colour(255,236,0), width=2),
- wx.Pen(wx.Colour(1,147,154), width=2), wx.Pen(wx.Colour(162,239,0), width=2)]
+ self.gain = 1
+ self.length = 0.05
+ #self.chnls = len(self.obj)
+ self.pens = [wx.Pen(wx.Colour(166,4,0), width=2), wx.Pen(wx.Colour(8,11,116), width=2), wx.Pen(wx.Colour(0,204,0), width=2),
+ wx.Pen(wx.Colour(255,167,0), width=2), wx.Pen(wx.Colour(133,0,75), width=2), wx.Pen(wx.Colour(255,236,0), width=2),
+ wx.Pen(wx.Colour(1,147,154), width=2), wx.Pen(wx.Colour(162,239,0), width=2)]
if sys.platform == "win32":
self.dcref = wx.BufferedPaintDC
@@ -1636,9 +1778,12 @@ class ScopePanel(wx.Panel):
self.dcref = wx.PaintDC
def OnSize(self, evt):
- size = self.GetSize()
- self.obj.setWidth(size[0])
- self.obj.setHeight(size[1])
+ try:
+ size = self.GetSize()
+ self.obj.setWidth(size[0])
+ self.obj.setHeight(size[1])
+ except:
+ pass
def setGain(self, gain):
self.gain = gain
@@ -1691,21 +1836,21 @@ class ScopePanel(wx.Panel):
dc.DrawText("%.3f" % (j*timestep), j*tickstep+2, h-12)
# draw waveforms
for i, samples in enumerate(self.img):
- gc.SetPen(self.pens[i])
+ gc.SetPen(self.pens[i%8])
if len(samples):
gc.DrawLines(samples)
# legend
last_tw = tw
tw, th = dc.GetTextExtent("chan 8")
- for i in range(self.chnls):
- dc.SetTextForeground(self.pens[i].GetColour())
+ for i in range(len(self.img)):
+ dc.SetTextForeground(self.pens[i%8].GetColour())
dc.DrawText("chan %d" % (i+1), w-tw-20-last_tw, i*th+10)
######################################################################
## Grapher window for PyoTableObject control
######################################################################
-OFF = 15
+OFF = 10
OFF2 = OFF*2
RAD = 3
RAD2 = RAD*2
@@ -1713,8 +1858,9 @@ AREA = RAD+2
AREA2 = AREA*2
class Grapher(wx.Panel):
def __init__(self, parent, xlen=8192, yrange=(0.0, 1.0), init=[(0.0,0.0),(1.0,1.0)], mode=0,
- exp=10.0, inverse=True, tension=0.0, bias=0.0, outFunction=None):
- wx.Panel.__init__(self, parent, size=(500,250), style=wx.SUNKEN_BORDER)
+ exp=10.0, inverse=True, tension=0.0, bias=0.0, outFunction=None, pos=(0, 0),
+ size=(300, 200), style=0):
+ wx.Panel.__init__(self, parent, pos=pos, size=size, style=style)
self.backgroundColour = BACKGROUND_COLOUR
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self.SetBackgroundColour(self.backgroundColour)
@@ -1736,7 +1882,7 @@ class Grapher(wx.Panel):
self.xlen = xlen
self.yrange = yrange
self.init = [tup for tup in init]
- self.points = init
+ self.points = [tup for tup in init]
self.outFunction = outFunction
if sys.platform == "win32":
@@ -1750,6 +1896,7 @@ class Grapher(wx.Panel):
self.init = [(p[0],p[1]) for p in pts]
self.points = [(p[0],p[1]) for p in pts]
self.selected = None
+ self.sendValues()
self.Refresh()
def pointToPixels(self, pt):
@@ -1773,6 +1920,11 @@ class Grapher(wx.Panel):
y = pt[1] * (self.yrange[1]-self.yrange[0]) + self.yrange[0]
return x, y
+ def valuesToPoint(self, val):
+ x = val[0] / float(self.xlen)
+ y = (val[1] - self.yrange[0]) / float(self.yrange[1]-self.yrange[0])
+ return x, y
+
def borderClip(self, pos):
w,h = self.GetSize()
if pos[0] < (OFF+RAD): pos[0] = (OFF+RAD)
@@ -1801,7 +1953,7 @@ class Grapher(wx.Panel):
return pos
def reset(self):
- self.points = self.init
+ self.points = [tup for tup in self.init]
self.Refresh()
def getPoints(self):
@@ -2046,10 +2198,10 @@ class Grapher(wx.Panel):
dc.DrawText(t, xpos+2, h-OFF-10)
if i < 9:
t = "%.2f" % ((9-i) * 0.1 * (self.yrange[1]-self.yrange[0]) + self.yrange[0])
- dc.DrawText(t, OFF+1, ypos+ystep-10)
+ dc.DrawText(t, OFF+2, ypos+ystep-10)
else:
t = "%.2f" % ((9-i) * 0.1 * (self.yrange[1]-self.yrange[0]) + self.yrange[0])
- dc.DrawText(t, OFF+1, h-OFF-10)
+ dc.DrawText(t, OFF+2, h-OFF-10)
dc.SetPen(wx.Pen("#000000", 1))
dc.SetBrush(wx.Brush("#000000"))
@@ -2229,8 +2381,9 @@ class TableGrapher(wx.Frame):
self.graph.reset()
class DataMultiSlider(wx.Panel):
- def __init__(self, parent, init, yrange=(0,1), outFunction=None):
- wx.Panel.__init__(self, parent, size=(250,250), style=wx.SUNKEN_BORDER)
+ def __init__(self, parent, init, yrange=(0,1), outFunction=None,
+ pos=(0, 0), size=(300, 200), style=0):
+ wx.Panel.__init__(self, parent, pos=pos, size=size, style=style)
self.backgroundColour = BACKGROUND_COLOUR
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self.SetBackgroundColour(self.backgroundColour)
@@ -2239,9 +2392,9 @@ class DataMultiSlider(wx.Panel):
self.Bind(wx.EVT_LEFT_DOWN, self.MouseDown)
self.Bind(wx.EVT_LEFT_UP, self.MouseUp)
self.Bind(wx.EVT_MOTION, self.MouseMotion)
- self.values = init
+ self.values = [v for v in init]
self.len = len(self.values)
- self.yrange = yrange
+ self.yrange = (float(yrange[0]), float(yrange[1]))
self.outFunction = outFunction
if sys.platform == "win32":
self.dcref = wx.BufferedPaintDC
diff --git a/pyolib/analysis.py b/pyolib/analysis.py
index 81f1db6..5188da3 100644
--- a/pyolib/analysis.py
+++ b/pyolib/analysis.py
@@ -726,6 +726,13 @@ class AttackDetector(PyoObject):
x, lmax = convertArgsToLists(x)
[obj.setReltime(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+ def readyToDetect(self):
+ """
+ Initializes variables in the ready state to detect an attack.
+
+ """
+ [obj.readyToDetect() for obj in self._base_objs]
+
def out(self, chnl=0, inc=1, dur=0, delay=0):
return self.play(dur, delay)
@@ -846,9 +853,9 @@ class Spectrum(PyoObject):
self._in_fader = InputFader(input)
in_fader, size, wintype, lmax = convertArgsToLists(self._in_fader, size, wintype)
self._base_objs = [Spectrum_base(wrap(in_fader,i), wrap(size,i), wrap(wintype,i)) for i in range(lmax)]
+ self._timer = Pattern(self.refreshView, 0.05).play()
if function == None:
self.view()
- self._timer = Pattern(self.refreshView, 0.05).play()
def setInput(self, x, fadetime=0.05):
"""
@@ -942,6 +949,38 @@ class Spectrum(PyoObject):
pyoArgsAssert(self, "N", time)
self._timer.time = time
+ def setLowFreq(self, x):
+ """
+ Sets the lower frequency, in Hz, returned by the analysis.
+
+ :Args:
+
+ x : float
+ New low frequency in Hz. Adjusts the `lowbound` attribute, as `x / sr`.
+
+ """
+ pyoArgsAssert(self, "n", x)
+ x /= self.getServer().getSamplingRate()
+ self._lowbound = x
+ x, lmax = convertArgsToLists(x)
+ tmp = [obj.setLowbound(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
+ def setHighFreq(self, x):
+ """
+ Sets the higher frequency, in Hz, returned by the analysis.
+
+ :Args:
+
+ x : float
+ New high frequency in Hz. Adjusts the `highbound` attribute, as `x / sr`.
+
+ """
+ pyoArgsAssert(self, "n", x)
+ x /= self.getServer().getSamplingRate()
+ self._highbound = x
+ x, lmax = convertArgsToLists(x)
+ tmp = [obj.setHighbound(wrap(x,i)) for i, obj in enumerate(self._base_objs)]
+
def setLowbound(self, x):
"""
Sets the lower frequency, as multiplier of sr, returned by the analysis.
@@ -1131,7 +1170,6 @@ class Spectrum(PyoObject):
if self.viewFrame != None:
self.viewFrame.update(self.points)
-
@property
def input(self):
"""PyoObject. Input signal to process."""
@@ -1221,6 +1259,11 @@ class Scope(PyoObject):
gain : float, optional
Linear gain applied to the signal to be displayed.
Can't be a list. Defaults to 0.67.
+ function : python callable, optional
+ If set, this function will be called with samples (as
+ list of lists, one list per channel). Useful if someone
+ wants to save the analysis data into a text file.
+ Defaults to None.
.. note::
@@ -1235,21 +1278,23 @@ class Scope(PyoObject):
>>> scope = Scope(a+b)
"""
- def __init__(self, input, length=0.05, gain=0.67):
- pyoArgsAssert(self, "oNN", input, length, gain)
+ def __init__(self, input, length=0.05, gain=0.67, function=None):
+ pyoArgsAssert(self, "oNNC", input, length, gain, function)
PyoObject.__init__(self)
self.points = None
self.viewFrame = None
self._input = input
self._length = length
self._gain = gain
+ self._function = function
self._width = 500
self._height = 400
self._in_fader = InputFader(input)
in_fader, lmax = convertArgsToLists(self._in_fader)
self._base_objs = [Scope_base(wrap(in_fader,i), length) for i in range(lmax)]
- self.view()
self._timer = Pattern(self.refreshView, length).play()
+ if function == None:
+ self.view()
def setInput(self, x, fadetime=0.05):
"""
@@ -1369,6 +1414,21 @@ class Scope(PyoObject):
pyoArgsAssert(self, "SB", title, wxnoserver)
createScopeWindow(self, title, wxnoserver)
+ def setFunction(self, function):
+ """
+ Sets the function to be called to retrieve the analysis data.
+
+ :Args:
+
+ function : python callable
+ The function called by the internal timer to retrieve the
+ analysis data. The function must be created with one argument
+ and will receive the data as a list of lists (one list per channel).
+
+ """
+ pyoArgsAssert(self, "C", function)
+ self._function = getWeakMethodRef(function)
+
def _setViewFrame(self, frame):
self.viewFrame = frame
@@ -1382,7 +1442,8 @@ class Scope(PyoObject):
self.points = [obj.display() for obj in self._base_objs]
if self.viewFrame != None:
self.viewFrame.update(self.points)
-
+ if self._function is not None:
+ self._function(self.points)
@property
def input(self):
diff --git a/pyolib/expression.py b/pyolib/expression.py
index 87369ca..f6adf66 100644
--- a/pyolib/expression.py
+++ b/pyolib/expression.py
@@ -86,7 +86,7 @@ Constants:
Comments
--------
-A comment start with two slashs ( // ) and ends at the end of the line:
+A comment starts with two slashs ( // ) and ends at the end of the line:
// This is a comment!
diff --git a/pyolib/tables.py b/pyolib/tables.py
index aeed3c1..e182910 100644
--- a/pyolib/tables.py
+++ b/pyolib/tables.py
@@ -1463,6 +1463,7 @@ class SndTable(PyoTableObject):
else:
[obj.setSound(path, (i%_snd_chnls), start, stop) for i, obj in enumerate(self._base_objs)]
self.refreshView()
+ self._resetView()
def append(self, path, crossfade=0, start=0, stop=None):
"""
@@ -1693,6 +1694,11 @@ class SndTable(PyoTableObject):
if self.viewFrame != None:
self.viewFrame.update()
+ def _resetView(self):
+ if self.viewFrame != None:
+ if hasattr(self.viewFrame, "_setZoom"):
+ self.viewFrame._setZoom()
+
@property
def sound(self):
"""string. Full path of the sound."""
diff --git a/pyolib/wxgui.py b/pyolib/wxgui.py
new file mode 100644
index 0000000..08bae20
--- /dev/null
+++ b/pyolib/wxgui.py
@@ -0,0 +1,968 @@
+"""
+The classes in this module are based on internal classes that where
+originally designed to help the creation of graphical tools for the
+control and the visualization of audio signals. WxPython must be installed
+under the current Python distribution to access these classes.
+
+"""
+from _widgets import PYO_USE_WX
+
+if not PYO_USE_WX:
+ NO_WX_MESSAGE = "WxPython must be installed on the system to use pyo's wx widgets."
+ class PyoGuiControlSlider:
+ def __init__(self, *args, **kwargs):
+ raise Exception(NO_WX_MESSAGE)
+ class PyoGuiVuMeter:
+ def __init__(self, *args, **kwargs):
+ raise Exception(NO_WX_MESSAGE)
+ class PyoGuiGrapher:
+ def __init__(self, *args, **kwargs):
+ raise Exception(NO_WX_MESSAGE)
+ class PyoGuiMultiSlider:
+ def __init__(self, *args, **kwargs):
+ raise Exception(NO_WX_MESSAGE)
+ class PyoGuiSpectrum:
+ def __init__(self, *args, **kwargs):
+ raise Exception(NO_WX_MESSAGE)
+ class PyoGuiScope:
+ def __init__(self, *args, **kwargs):
+ raise Exception(NO_WX_MESSAGE)
+ class PyoGuiSndView:
+ def __init__(self, *args, **kwargs):
+ raise Exception(NO_WX_MESSAGE)
+else:
+ import wx
+ import wx.lib.newevent
+ from _wxwidgets import ControlSlider, VuMeter, Grapher, DataMultiSlider
+ from _wxwidgets import SpectrumPanel, ScopePanel, SndViewTablePanel, HRangeSlider
+
+ # Custom events
+ PyoGuiControlSliderEvent, EVT_PYO_GUI_CONTROL_SLIDER = wx.lib.newevent.NewEvent()
+ PyoGuiGrapherEvent, EVT_PYO_GUI_GRAPHER = wx.lib.newevent.NewEvent()
+ PyoGuiMultiSliderEvent, EVT_PYO_GUI_MULTI_SLIDER = wx.lib.newevent.NewEvent()
+ PyoGuiSndViewMousePositionEvent, EVT_PYO_GUI_SNDVIEW_MOUSE_POSITION = wx.lib.newevent.NewEvent()
+ PyoGuiSndViewSelectionEvent, EVT_PYO_GUI_SNDVIEW_SELECTION = wx.lib.newevent.NewEvent()
+
+ class PyoGuiControlSlider(ControlSlider):
+ """
+ Floating-point control slider.
+
+ :Parent: wx.Panel
+
+ :Events:
+
+ EVT_PYO_GUI_CONTROL_SLIDER
+ Sent after any change of the slider position. The current
+ value of the slider can be retrieve with the `value`
+ attribute of the generated event.
+
+ :Args:
+
+ parent : wx.Window
+ The parent window.
+ minvalue : float
+ The minimum value of the slider.
+ maxvalue : float
+ The maximum value of the slider.
+ init : float, optional
+ The initial value of the slider. If None, the slider
+ inits to the minimum value. Defaults to None.
+ pos : tuple, optional
+ The slider's position in pixel (x, y). Defaults to (0, 0).
+ size : tuple, optional
+ The slider's size in pixel (x, y). Defaults to (200, 16).
+ log : boolean, optional
+ If True, creates a logarithmic slider (minvalue must be
+ greater than 0). Defaults to False.
+ integer : boolean, optional
+ If True, creates an integer slider. Defaults to False.
+ powoftwo : boolean, optional
+ If True, creates a power-of-two slider (log is automatically
+ False and integer is True). If True, minvalue and maxvalue
+ must be exponents to base 2 but init is a real power-of-two
+ value. Defaults to False.
+ orient : {wx.HORIZONTAL or wx.VERTICAL}, optional
+ The slider's orientation. Defaults to wx.HORIZONTAL.
+
+ """
+ def __init__(self, parent, minvalue, maxvalue, init=None, pos=(0, 0),
+ size=(200, 16), log=False, integer=False, powoftwo=False,
+ orient=wx.HORIZONTAL):
+ super(PyoGuiControlSlider, self).__init__(parent, minvalue, maxvalue,
+ init, pos, size, log,
+ self._outFunction, integer,
+ powoftwo,
+ parent.GetBackgroundColour(),
+ orient)
+
+ def _outFunction(self, value):
+ evt = PyoGuiControlSliderEvent(value=value)
+ wx.PostEvent(self, evt)
+
+ def enable(self):
+ """
+ Enable the slider for user input.
+
+ """
+ super(PyoGuiControlSlider, self).Enable()
+
+ def disable(self):
+ """
+ Disable the slider for user input.
+
+ """
+ super(PyoGuiControlSlider, self).Disable()
+
+ def setValue(self, x, propagate=True):
+ """
+ Sets a new value to the slider.
+
+ :Args:
+
+ x : int or float
+ The controller number.
+ propagate : boolean, optional
+ If True, an event will be sent after the call.
+
+ """
+ super(PyoGuiControlSlider, self).SetValue(x, propagate)
+
+ def setMidiCtl(self, x, propagate=True):
+ """
+ Sets the midi controller number to show on the slider.
+
+ :Args:
+
+ x : int
+ The controller number.
+ propagate : boolean, optional
+ If True, an event will be sent after the call.
+
+ """
+ super(PyoGuiControlSlider, self).setMidiCtl(x, propagate)
+
+ def setRange(self, minvalue, maxvalue):
+ """
+ Sets new minimum and maximum values.
+
+ :Args:
+
+ minvalue : int or float
+ The new minimum value.
+ maxvalue : int or float
+ The new maximum value.
+
+ """
+ super(PyoGuiControlSlider, self).setRange(minvalue, maxvalue)
+
+ def getValue(self):
+ """
+ Returns the current value of the slider.
+
+ """
+ return super(PyoGuiControlSlider, self).GetValue()
+
+ def getMidiCtl(self):
+ """
+ Returns the midi controller number, if any, assigned to the slider.
+
+ """
+ return super(PyoGuiControlSlider, self).getMidiCtl()
+
+ def getMinValue(self):
+ """
+ Returns the current minimum value.
+
+ """
+ return super(PyoGuiControlSlider, self).getMinValue()
+
+ def getMaxValue(self):
+ """
+ Returns the current maximum value.
+
+ """
+ return super(PyoGuiControlSlider, self).getMaxValue()
+
+ def getInit(self):
+ """
+ Returns the initial value.
+
+ """
+ return super(PyoGuiControlSlider, self).getInit()
+
+ def getRange(self):
+ """
+ Returns minimum and maximum values as a list.
+
+ """
+ return super(PyoGuiControlSlider, self).getRange()
+
+ def isInteger(self):
+ """
+ Returns True if the slider manage only integer, False otherwise.
+
+ """
+ return self.integer
+
+ def isLog(self):
+ """
+ Returns True if the slider is logarithmic, False otherwise.
+
+ """
+ return self.log
+
+ def isPowOfTwo(self):
+ """
+ Returns True if the slider manage only power-of-two values, False otherwise.
+
+ """
+ return self.powoftwo
+
+ class PyoGuiVuMeter(VuMeter):
+ """
+ Multi-channels Vu Meter.
+
+ When registered as the Server's meter, its internal method `setRms`
+ will be called each buffer size with a list of normalized amplitudes
+ as argument. The `setRms` method can also be registered as the
+ function callback of a PeakAmp object.
+
+ :Parent: wx.Panel
+
+ :Args:
+
+ parent : wx.Window
+ The parent window.
+ nchnls : int, optional
+ The initial number of channels of the meter. Defaults to 2.
+ pos : wx.Point, optional
+ Window position in pixels. Defaults to (0, 0).
+ size : tuple, optional
+ The meter's size in pixels (x, y). Defaults to (200, 11).
+ orient : {wx.HORIZONTAL or wx.VERTICAL}, optional
+ The meter's orientation. Defaults to wx.HORIZONTAL.
+ style : int, optional
+ Window style (see wx.Window documentation). Defaults to 0.
+
+ """
+ def __init__(self, parent, nchnls=2, pos=(0, 0), size=(200, 11),
+ orient=wx.HORIZONTAL, style=0):
+ super(PyoGuiVuMeter, self).__init__(parent, size, nchnls, orient,
+ pos, style)
+
+ def setNchnls(self, nchnls):
+ """
+ Sets the number of channels of the meter.
+
+ :Args:
+
+ nchnls : int
+ The number of channels.
+
+ """
+ super(PyoGuiVuMeter, self).setNumSliders(nchnls)
+
+ class PyoGuiGrapher(Grapher):
+ """
+ Multi-modes break-points function editor.
+
+ :Parent: wx.Panel
+
+ :Events:
+
+ EVT_PYO_GUI_GRAPHER
+ Sent after any change of the grapher function. The current
+ list of points of the grapher can be retrieve with the `value`
+ attribute of the generated event.
+
+ :Args:
+
+ parent : wx.Window
+ The parent window.
+ xlen : int, optional
+ The length, in samples, of the grapher. Defaults to 8192.
+ yrange : two-values tuple, optional
+ A tuple indicating the minimum and maximum values of the Y-axis.
+ Defaults to (0, 1).
+ init : list of two-values tuples, optional
+ The initial break-points function set as normalized values.
+ A point is defined with its X and Y positions as a tuple.
+ Defaults to [(0.0, 0.0), (1.0, 1.0)].
+ mode : int, optional
+ The grapher mode definning how line segments will be draw.
+ Possible modes are:
+ 0. linear (default)
+ 1. cosine
+ 2. exponential (uses `exp` and `inverse` arguments)
+ 3. curve (uses `tension` and `bias` arguments)
+ 4. logarithmic
+ 5. logarithmic cosine
+ exp : int or float, optional
+ The exponent factor for an exponential graph. Defaults to 10.0.
+ inverse : boolean, optional
+ If True, downward slope will be inversed. Useful to create
+ biexponential curves. Defaults to True.
+ tension : int or float, optional
+ Curvature at the known points. 1 is high, 0 normal, -1 is low.
+ Defaults to 0.
+ bias : int or float, optional
+ Curve attraction (for each segments) toward bundary points.
+ 0 is even, positive is towards first point, negative is towards
+ the second point. Defaults to 0.
+ pos : wx.Point, optional
+ Window position in pixels. Defaults to (0, 0).
+ size : wx.Size, optional
+ Window size in pixels. Defaults to (300, 200).
+ style : int, optional
+ Window style (see wx.Window documentation). Defaults to 0.
+
+ """
+ def __init__(self, parent, xlen=8192, yrange=(0, 1), init=[(0.0, 0.0), (1.0, 1.0)],
+ mode=0, exp=10, inverse=True, tension=0, bias=0, pos=(0, 0),
+ size=(300, 200), style=0):
+ super(PyoGuiGrapher, self).__init__(parent, xlen, yrange, init, mode,
+ exp, inverse, tension, bias,
+ self._outFunction, pos, size, style)
+
+ def _outFunction(self, value):
+ evt = PyoGuiGrapherEvent(value=value)
+ wx.PostEvent(self, evt)
+
+ def _refresh(self):
+ self.Refresh()
+ self.sendValues()
+
+ def reset(self):
+ """
+ Resets the points to the initial state.
+
+ """
+ super(PyoGuiGrapher, self).reset()
+
+ def getPoints(self):
+ """
+ Returns the current normalized points of the grapher.
+
+ """
+ return super(PyoGuiGrapher, self).getPoints()
+
+ def getValues(self):
+ """
+ Returns the current points, according to Y-axis range, of the grapher.
+
+ """
+ return super(PyoGuiGrapher, self).getValues()
+
+ def setPoints(self, pts):
+ """
+ Sets a new group of normalized points in the grapher.
+
+ :Args:
+
+ pts : list of two-values tuples
+ New normalized (between 0 and 1) points.
+
+ """
+ self.points = [pt for pt in pts]
+ self._refresh()
+
+ def setValues(self, vals):
+ """
+ Sets a new group of points, according to Y-axis range, in the grapher.
+
+ :Args:
+
+ vals : list of two-values tuples
+ New real points.
+
+ """
+ self.points = [self.valuesToPoint(val) for val in vals]
+ self._refresh()
+
+ def setYrange(self, yrange):
+ """
+ Sets a new Y-axis range to the grapher.
+
+ :Args:
+
+ yrange : two-values tuple
+ New Y-axis range.
+
+ """
+ vals = self.getValues()
+ self.yrange = yrange
+ self.setValues(vals)
+
+ def setInitPoints(self, pts):
+ """
+ Sets a new initial normalized points list to the grapher.
+
+ :Args:
+
+ pts : list of two-values tuples
+ New normalized (between 0 and 1) initial points.
+
+ """
+ super(PyoGuiGrapher, self).setInitPoints(pts)
+
+ def setMode(self, x):
+ """
+ Changes the grapher's mode.
+
+ :Args:
+
+ x : int
+ New mode. Possible modes are:
+ 0. linear (default)
+ 1. cosine
+ 2. exponential (uses `exp` and `inverse` arguments)
+ 3. curve (uses `tension` and `bias` arguments)
+ 4. logarithmic
+ 5. logarithmic cosine
+
+ """
+ self.mode = x
+ self._refresh()
+
+ def setExp(self, x):
+ """
+ Changes the grapher's exponent factor for exponential graph.
+
+ :Args:
+
+ x : float
+ New exponent factor.
+
+ """
+ self.exp = x
+ self._refresh()
+
+ def setInverse(self, x):
+ """
+ Changes the grapher's inverse boolean for exponential graph.
+
+ :Args:
+
+ x : boolean
+ New inverse factor.
+
+ """
+ self.inverse = x
+ self._refresh()
+
+ def setTension(self, x):
+ """
+ Changes the grapher's tension factor for curved graph.
+
+ :Args:
+
+ x : float
+ New tension factor.
+
+ """
+ self.tension = x
+ self._refresh()
+
+ def setBias(self, x):
+ """
+ Changes the grapher's bias factor for curved graph.
+
+ :Args:
+
+ x : float
+ New bias factor.
+
+ """
+ self.bias = x
+ self._refresh()
+
+ class PyoGuiMultiSlider(DataMultiSlider):
+ """
+ Data multi-sliders editor.
+
+ :Parent: wx.Panel
+
+ :Events:
+
+ EVT_PYO_GUI_MULTI_SLIDER
+ Sent after any change of the multi-sliders values. The current
+ list of values of the multi-sliders can be retrieve with the
+ `value` attribute of the generated event.
+
+ :Args:
+
+ parent : wx.Window
+ The parent window.
+ xlen : int, optional
+ The number of sliders in the multi-sliders. Defaults to 16.
+ yrange : two-values tuple
+ A tuple indicating the minimum and maximum values of the Y-axis.
+ Defaults to (0, 1).
+ init : list values, optional
+ The initial list of values of the multi-sliders.
+ Defaults to None, meaning all sliders initialized to the
+ minimum value.
+ pos : wx.Point, optional
+ Window position in pixels. Defaults to (0, 0).
+ size : wx.Size, optional
+ Window size in pixels. Defaults to (300, 200).
+ style : int, optional
+ Window style (see wx.Window documentation). Defaults to 0.
+
+ """
+ def __init__(self, parent, xlen=16, yrange=(0, 1), init=None,
+ pos=(0, 0), size=(300, 200), style=0):
+ if init is None:
+ init = [yrange[0]] * xlen
+ else:
+ if len(init) < xlen:
+ init += [yrange[0]] * (xlen - len(init))
+ elif len(init) > xlen:
+ init = init[:xlen]
+ super(PyoGuiMultiSlider, self).__init__(parent, init, yrange,
+ self._outFunction, pos,
+ size, style)
+
+ def _outFunction(self, value):
+ evt = PyoGuiMultiSliderEvent(value=value)
+ wx.PostEvent(self, evt)
+
+ def reset(self):
+ """
+ Resets the sliders to their initial state.
+
+ """
+ super(PyoGuiMultiSlider, self).reset()
+
+ def getValues(self):
+ """
+ Returns the current values of the sliders.
+
+ """
+ return [v for v in self.values]
+
+ def setValues(self, vals):
+ """
+ Sets new values to the sliders.
+
+ :Args:
+
+ vals : list of values
+ New values.
+
+ """
+ wx.CallAfter(super(PyoGuiMultiSlider, self).update, vals)
+
+ def setYrange(self, yrange):
+ """
+ Sets a new Y-axis range to the multi-sliders.
+
+ :Args:
+
+ yrange : two-values tuple
+ New Y-axis range.
+
+ """
+ self.yrange = (float(yrange[0]), float(yrange[1]))
+ self.Refresh()
+
+ class PyoGuiSpectrum(SpectrumPanel):
+ """
+ Frequency spectrum display.
+
+ This widget should be used with the Spectrum object, which measures
+ the magnitude of an input signal versus frequency within a user
+ defined range. It can show both magnitude and frequency on linear
+ or logarithmic scale.
+
+ To create the bridge between the analyzer and the display, the
+ Spectrum object must be registered in the PyoGuiSpectrum object
+ with the setAnalyzer(obj) method. The Spectrum object will
+ automatically call the update(points) method to refresh the display.
+
+ :Parent: wx.Panel
+
+ :Args:
+
+ parent : wx.Window
+ The parent window.
+ lowfreq : int or float, optional
+ The lowest frequency, in Hz, to display on the X-axis.
+ Defaults to 0.
+ highfreq : int or float, optional
+ The highest frequency, in Hz, to display on the X-axis.
+ Defaults to 22050.
+ fscaling : int, optional
+ The frequency scaling on the X-axis. 0 means linear, 1 means
+ logarithmic. Defaults to 0.
+ mscaling : int, optional
+ The magnitude scaling on the Y-axis. 0 means linear, 1 means
+ logarithmic. Defaults to 0.
+ pos : wx.Point, optional
+ Window position in pixels. Defaults to (0, 0).
+ size : wx.Size, optional
+ Window size in pixels. Defaults to (300, 200).
+ style : int, optional
+ Window style (see wx.Window documentation). Defaults to 0.
+
+ """
+ def __init__(self, parent, lowfreq=0, highfreq=22050, fscaling=0,
+ mscaling=0, pos=(0, 0), size=(300, 200), style=0):
+ super(PyoGuiSpectrum, self).__init__(parent, 1, lowfreq, highfreq,
+ fscaling, mscaling, pos, size, style)
+
+ def update(self, points):
+ """
+ Display updating method.
+
+ This method is automatically called by the audio analyzer
+ object (Spectrum) with points to draw as arguments. The points
+ are already formatted for the current drawing surface to save
+ CPU cycles.
+
+ The method setAnalyzer(obj) must be used to register the audio
+ analyzer object.
+
+ :Args:
+
+ points : list of list of tuples
+ A list containing n-channels list of tuples. A tuple
+ is a point (X-Y coordinates) to draw.
+
+ """
+ wx.CallAfter(self.setImage, points)
+
+ def setAnalyzer(self, object):
+ """
+ Register an audio analyzer object (Spectrum).
+
+ :Args:
+
+ object : Spectrum object
+ The audio object performing the frequency analysis.
+
+ """
+ self.obj = object
+ self.obj.setFunction(self.update)
+ self.obj.setLowFreq(self.lowfreq)
+ self.obj.setHighFreq(self.highfreq)
+ self.obj.setFscaling(self.fscaling)
+ self.obj.setMscaling(self.mscaling)
+
+ def setLowFreq(self, x):
+ """
+ Changes the lowest frequency of the display.
+
+ This method propagates the value to the audio analyzer.
+
+ :Args:
+
+ x : int or float
+ New lowest frequency.
+
+ """
+ if self.obj is not None:
+ self.obj.setLowFreq(x)
+ super(PyoGuiSpectrum, self).setLowFreq(x)
+
+ def setHighFreq(self, x):
+ """
+ Changes the highest frequency of the display.
+
+ This method propagates the value to the audio analyzer.
+
+ :Args:
+
+ x : int or float
+ New highest frequency.
+
+ """
+ if self.obj is not None:
+ self.obj.setHighFreq(x)
+ super(PyoGuiSpectrum, self).setHighFreq(x)
+
+ def setFscaling(self, x):
+ """
+ Changes the frequency scaling (X-axis) of the display.
+
+ This method propagates the value to the audio analyzer.
+
+ :Args:
+
+ x : int
+ 0 means linear scaling, 1 means logarithmic scaling.
+
+ """
+ if self.obj is not None:
+ self.obj.setFscaling(x)
+ super(PyoGuiSpectrum, self).setFscaling(x)
+
+ def setMscaling(self, x):
+ """
+ Changes the magnitude scaling (Y-axis) of the display.
+
+ This method propagates the value to the audio analyzer.
+
+ :Args:
+
+ x : int
+ 0 means linear scaling, 1 means logarithmic scaling.
+
+ """
+ if self.obj is not None:
+ self.obj.setMscaling(x)
+ super(PyoGuiSpectrum, self).setMscaling(x)
+
+ class PyoGuiScope(ScopePanel):
+ """
+ Oscilloscope display.
+
+ This widget should be used with the Scope object, which computes
+ the waveform of an input signal to display on a GUI.
+
+ To create the bridge between the analyzer and the display, the
+ Scope object must be registered in the PyoGuiScope object with
+ the setAnalyzer(obj) method. The Scope object will automatically
+ call the update(points) method to refresh the display.
+
+ :Parent: wx.Panel
+
+ :Args:
+
+ parent : wx.Window
+ The parent window.
+ length : float, optional
+ Length, in seconds, of the waveform segment displayed on
+ the window. Defaults to 0.05.
+ gain : float, optional
+ Linear gain applied to the signal to be displayed.
+ Defaults to 0.67.
+ pos : wx.Point, optional
+ Window position in pixels. Defaults to (0, 0).
+ size : wx.Size, optional
+ Window size in pixels. Defaults to (300, 200).
+ style : int, optional
+ Window style (see wx.Window documentation). Defaults to 0.
+
+ """
+ def __init__(self, parent, length=0.05, gain=0.67, pos=(0, 0),
+ size=(300, 200), style=0):
+ super(PyoGuiScope, self).__init__(parent, None, pos, size, style)
+ super(PyoGuiScope, self).setLength(length)
+ super(PyoGuiScope, self).setGain(gain)
+
+ def update(self, points):
+ """
+ Display updating method.
+
+ This method is automatically called by the audio analyzer
+ object (Scope) with points to draw as arguments. The points
+ are already formatted for the current drawing surface to save
+ CPU cycles.
+
+ The method setAnalyzer(obj) must be used to register the audio
+ analyzer object.
+
+ :Args:
+
+ points : list of list of tuples
+ A list containing n-channels list of tuples. A tuple
+ is a point (X-Y coordinates) to draw.
+
+ """
+ wx.CallAfter(self.setImage, points)
+
+ def setAnalyzer(self, object):
+ """
+ Register an audio analyzer object (Scope).
+
+ :Args:
+
+ object : Scope object
+ The audio object performing the waveform analysis.
+
+ """
+ self.obj = object
+ self.obj.setFunction(self.update)
+ self.obj.setLength(self.length)
+ self.obj.setGain(self.gain)
+
+ def setLength(self, x):
+ """
+ Changes the length, in seconds, of the displayed audio segment.
+
+ This method propagates the value to the audio analyzer.
+
+ :Args:
+
+ x : float
+ New segment length in seconds.
+
+ """
+ if self.obj is not None:
+ self.obj.setLength(x)
+ super(PyoGuiScope, self).setLength(x)
+
+ def setGain(self, x):
+ """
+ Changes the gain applied to the input signal.
+
+ This method propagates the value to the audio analyzer.
+
+ :Args:
+
+ x : float
+ New linear gain.
+
+ """
+ if self.obj is not None:
+ self.obj.setGain(x)
+ super(PyoGuiScope, self).setGain(x)
+
+ # left-click + drag ===> event position
+ # right-click + drag ===> highlight a selection + event selection (start, end)
+ # Shift + right-click + drag ===> move the selection + event selection (start, end)
+ # Ctrl + right-click ===> delete the selection + event selection (0.0, 1.0)
+ class PyoGuiSndView(wx.Panel):
+ """
+ Soundfile display.
+
+ This widget should be used with the SndTable object, which keeps
+ soundfile in memory and computes the waveform to display on the GUI.
+
+ To create the bridge between the audio memory and the display, the
+ SndTable object must be registered in the PyoGuiSndView object with
+ the setTable(object) method.
+
+ The SndTable object will automatically call the update() method to
+ refresh the display when the table is modified.
+
+ :Parent: wx.Panel
+
+ :Events:
+
+ EVT_PYO_GUI_SNDVIEW_MOUSE_POSITION
+ Sent when the mouse is moving on the panel with the left
+ button pressed. The `value` attribute of the event will
+ hold the normalized position of the mouse into the sound.
+ For X-axis value, 0.0 is the beginning of the sound and 1.0
+ is the end of the sound. For the Y-axis, 0.0 is the bottom
+ of the panel and 1.0 is the top.
+ EVT_PYO_GUI_SNDVIEW_SELECTION
+ Sent when a new region is selected on the panel. A new
+ selection is created with a Right-click and drag on the panel.
+ The current selection can be moved with Shift+Right-click and
+ drag. Ctrl+Right-click (Cmd on OSX) remove the selected region.
+ The `value` attribute of the event will hold the normalized
+ selection as a tuple (min, max). 0.0 means the beginning of
+ the sound and 1.0 means the end of the sound.
+
+ :Args:
+
+ parent : wx.Window
+ The parent window.
+ pos : wx.Point, optional
+ Window position in pixels. Defaults to (0, 0).
+ size : wx.Size, optional
+ Window size in pixels. Defaults to (300, 200).
+ style : int, optional
+ Window style (see wx.Window documentation). Defaults to 0.
+
+ """
+ def __init__(self, parent, pos=(0, 0), size=(300, 200), style=0):
+ wx.Panel.__init__(self, parent, pos=pos, size=size, style=style)
+ box = wx.BoxSizer(wx.VERTICAL)
+ self._curzoom = (0.0, 1.0)
+ self.sndview = SndViewTablePanel(self, None,
+ self._position_callback,
+ self._select_callback)
+ box.Add(self.sndview, 1, wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 5)
+ self.zoom = HRangeSlider(self, minvalue=0, maxvalue=1,
+ valtype='float', function=self._setZoom,
+ backColour=parent.GetBackgroundColour())
+ box.Add(self.zoom, 0, wx.EXPAND|wx.LEFT|wx.RIGHT, 5)
+ self.SetSizer(box)
+
+ def _setZoom(self, values=None):
+ if values is None:
+ values = self._curzoom
+ dur = self.sndview.getDur()
+ self.sndview.setBegin(dur * values[0])
+ self.sndview.setEnd(dur * values[1])
+ self._curzoom = values
+ self.update()
+
+ def _position_callback(self, pos):
+ evt = PyoGuiSndViewMousePositionEvent(value=pos)
+ wx.PostEvent(self, evt)
+
+ def _select_callback(self, selection):
+ selection = (max(0.0, min(selection)), min(max(selection), 1.0))
+ evt = PyoGuiSndViewSelectionEvent(value=selection)
+ wx.PostEvent(self, evt)
+
+ def __del__(self):
+ if self.sndview.obj is not None:
+ self.sndview.obj._setViewFrame(None)
+ self.Destroy()
+
+ def update(self):
+ """
+ Display updating method.
+
+ This method is automatically called by the audio memory
+ object (SndTable) when the table is modified.
+
+ The method setTable(obj) must be used to register the audio
+ memory object.
+
+ """
+ wx.CallAfter(self.sndview.setImage)
+
+ def setTable(self, object):
+ """
+ Register an audio memory object (SndTable).
+
+ :Args:
+
+ object : SndTable object
+ The audio table keeping the sound in memory.
+
+ """
+ object._setViewFrame(self)
+ self.sndview.obj = object
+ self.sndview.setBegin(0.0)
+ self.sndview.setEnd(object.getDur(False))
+ self.sndview.chnls = len(object)
+ self.update()
+
+ def setSelection(self, start, stop):
+ """
+ Changes the selected region.
+
+ This method will trigger a EVT_PYO_GUI_SNDVIEW_SELECTION event
+ with a tuple (start, stop) as value.
+
+ :Args:
+
+ start : float
+ The starting point of the selected region. This value
+ must be normalized between 0 and 1 (0 is the beginning
+ of the sound, 1 is the end).
+ stop : float
+ The ending point of the selected region. This value
+ must be normalized between 0 and 1 (0 is the beginning
+ of the sound, 1 is the end).
+
+ """
+ self.sndview.setSelection(start, stop)
+
+ def resetSelection(self):
+ """
+ Removes the selected region.
+
+ This method will trigger a EVT_PYO_GUI_SNDVIEW_SELECTION event
+ with a tuple (0.0, 1.0) as value.
+
+ """
+ self.sndview.resetSelection()
\ No newline at end of file
diff --git a/scripts/release_doc_src.sh b/scripts/release_doc_src.sh
index 320ea79..964ec49 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.7.8
+version=0.7.9
replace=XXX
doc_rep=pyo_XXX-doc
diff --git a/setup.py b/setup.py
index d770190..f9456f2 100644
--- a/setup.py
+++ b/setup.py
@@ -23,7 +23,7 @@ from distutils.core import setup, Extension
import os, sys, getopt
import time
-pyo_version = "0.7.8"
+pyo_version = "0.7.9"
build_osx_with_jack_support = False
compile_externals = False
diff --git a/src/engine/pyomodule.c b/src/engine/pyomodule.c
index f4a69d3..82db41b 100644
--- a/src/engine/pyomodule.c
+++ b/src/engine/pyomodule.c
@@ -30,7 +30,7 @@
#include "tablemodule.h"
#include "matrixmodule.h"
-/** Note :
+/** TODO:
** Add an argument to pa_get_* and pm_get_* functions to allow printing to the console
**/
diff --git a/src/engine/servermodule.c b/src/engine/servermodule.c
index a7b8e31..b020ff1 100644
--- a/src/engine/servermodule.c
+++ b/src/engine/servermodule.c
@@ -54,6 +54,12 @@ static int Server_start_rec_internal(Server *self, char *filename);
int rnd_objs_count[num_rnd_objs] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int rnd_objs_mult[num_rnd_objs] = {1993,1997,1999,2003,2011,2017,2027,2029,2039,2053,2063,2069,
2081,2083,2087,2089,2099,2111,2113,2129,2131,2137,2141,2143,2153,2161,2179,2203,2207};
+static unsigned int PYO_RAND_SEED = 1;
+/* Linear congruential pseudo-random generator. */
+unsigned int pyorand() {
+ PYO_RAND_SEED = (PYO_RAND_SEED * 1664525 + 1013904223) % PYO_RAND_MAX;
+ return PYO_RAND_SEED;
+}
#ifdef USE_COREAUDIO
static int coreaudio_stop_callback(Server *self);
@@ -1966,21 +1972,20 @@ Server_setGlobalSeed(Server *self, PyObject *arg)
int
Server_generateSeed(Server *self, int oid)
{
- int curseed, seed, count, mult;
- long ltime;
+ unsigned int curseed, count, mult, ltime;
count = ++rnd_objs_count[oid];
mult = rnd_objs_mult[oid];
if (self->globalSeed > 0) {
- curseed = self->globalSeed + ((count * mult) % 32768);
+ curseed = (self->globalSeed + count * mult) % PYO_RAND_MAX;
}
else {
- ltime = time(NULL);
- seed = (unsigned) (ltime / 2) % 32768;
- curseed = seed + ((count * mult) % 32768);
+ ltime = (unsigned int)time(NULL);
+ curseed = (ltime * ltime + count * mult) % PYO_RAND_MAX;
}
- srand(curseed);
+
+ PYO_RAND_SEED = curseed;
return 0;
}
diff --git a/src/objects/analysismodule.c b/src/objects/analysismodule.c
index 944570b..5244129 100644
--- a/src/objects/analysismodule.c
+++ b/src/objects/analysismodule.c
@@ -2289,6 +2289,14 @@ AttackDetector_setReltime(AttackDetector *self, PyObject *arg)
Py_RETURN_NONE;
}
+static PyObject *
+AttackDetector_readyToDetect(AttackDetector *self)
+{
+ self->overminok = 1;
+ self->timer = self->maxtime;
+ Py_RETURN_NONE;
+}
+
static PyMemberDef AttackDetector_members[] = {
{"server", T_OBJECT_EX, offsetof(AttackDetector, server), 0, "Pyo server."},
{"stream", T_OBJECT_EX, offsetof(AttackDetector, stream), 0, "Stream object."},
@@ -2308,6 +2316,7 @@ static PyMethodDef AttackDetector_methods[] = {
{"setMaxthresh", (PyCFunction)AttackDetector_setMaxthresh, METH_O, "Sets the higher threshold."},
{"setMinthresh", (PyCFunction)AttackDetector_setMinthresh, METH_O, "Sets the lower threshold."},
{"setReltime", (PyCFunction)AttackDetector_setReltime, METH_O, "Sets the release time (min time between two detected attacks)."},
+{"readyToDetect", (PyCFunction)AttackDetector_readyToDetect, METH_NOARGS, "Initializes thresholds."},
{"setMul", (PyCFunction)AttackDetector_setMul, METH_O, "Sets oscillator mul factor."},
{"setAdd", (PyCFunction)AttackDetector_setAdd, METH_O, "Sets oscillator add factor."},
{"setSub", (PyCFunction)AttackDetector_setSub, METH_O, "Sets inverse add factor."},
diff --git a/src/objects/freeverbmodule.c b/src/objects/freeverbmodule.c
index e2ef257..a0c6b0a 100644
--- a/src/objects/freeverbmodule.c
+++ b/src/objects/freeverbmodule.c
@@ -673,7 +673,7 @@ Freeverb_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Server_generateSeed((Server *)self->server, FREEVERB_ID);
- rndSamps = (rand()/(MYFLT)(RAND_MAX) * 20 + 10) / DEFAULT_SRATE;
+ rndSamps = (RANDOM_UNIFORM * 20 + 10) / DEFAULT_SRATE;
for(i=0; i<NUM_COMB; i++) {
nsamps = Freeverb_calc_nsamples((Freeverb *)self, comb_delays[i] + rndSamps);
self->comb_buf[i] = (MYFLT *)realloc(self->comb_buf[i], (nsamps+1) * sizeof(MYFLT));
diff --git a/src/objects/granulatormodule.c b/src/objects/granulatormodule.c
index 4470e82..f07b6cb 100644
--- a/src/objects/granulatormodule.c
+++ b/src/objects/granulatormodule.c
@@ -754,7 +754,7 @@ Granulator_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Server_generateSeed((Server *)self->server, GRANULATOR_ID);
for (i=0; i<self->ngrains; i++) {
- phase = ((MYFLT)i/self->ngrains) * (1.0 + ((rand()/((MYFLT)(RAND_MAX)+1)*2.0-1.0) * 0.01));
+ phase = ((MYFLT)i/self->ngrains) * (1.0 + ((RANDOM_UNIFORM * 2.0 - 1.0) * 0.01));
if (phase < 0.0)
phase = 0.0;
else if (phase >= 1.0)
@@ -949,7 +949,7 @@ Granulator_setGrains(Granulator *self, PyObject *arg)
self->lastppos = (MYFLT *)realloc(self->lastppos, self->ngrains * sizeof(MYFLT));
for (i=0; i<self->ngrains; i++) {
- phase = ((MYFLT)i/self->ngrains) * (1.0 + ((rand()/((MYFLT)(RAND_MAX)+1)*2.0-1.0) * 0.01));
+ phase = ((MYFLT)i/self->ngrains) * (1.0 + ((RANDOM_UNIFORM * 2.0 - 1.0) * 0.01));
if (phase < 0.0)
phase = 0.0;
else if (phase >= 1.0)
@@ -2246,7 +2246,7 @@ Granule_transform_i(Granule *self) {
}
} else {
/* asynchronous */
- if ((rand() * self->srOnRandMax) < dens)
+ if ((pyorand() * self->srOnRandMax) < dens)
flag = 1;
}
@@ -2337,7 +2337,7 @@ Granule_transform_a(Granule *self) {
}
} else {
/* asynchronous */
- if ((rand() * self->srOnRandMax) < density[i])
+ if ((pyorand() * self->srOnRandMax) < density[i])
flag = 1;
}
@@ -2537,7 +2537,7 @@ Granule_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
INIT_OBJECT_COMMON
self->oneOnSr = 1.0 / self->sr;
- self->srOnRandMax = self->sr / (MYFLT)RAND_MAX;
+ self->srOnRandMax = self->sr / (MYFLT)PYO_RAND_MAX;
Stream_setFunctionPtr(self->stream, Granule_compute_next_data_frame);
self->mode_func_ptr = Granule_setProcMode;
@@ -3029,7 +3029,7 @@ MainParticle_transform_mono_i(MainParticle *self) {
self->flags[j] = 0;
self->phase[j] = 0.0;
self->inc[j] = 1.0 / (dur * self->sr);
- self->devFactor = (rand() / (MYFLT)RAND_MAX * 2.0 - 1.0) * dev + 1.0;
+ self->devFactor = (RANDOM_UNIFORM * 2.0 - 1.0) * dev + 1.0;
break;
}
}
@@ -3129,7 +3129,7 @@ MainParticle_transform_mono_a(MainParticle *self) {
self->flags[j] = 0;
self->phase[j] = 0.0;
self->inc[j] = 1.0 / (dur * self->sr);
- self->devFactor = (rand() / (MYFLT)RAND_MAX * 2.0 - 1.0) * dev + 1.0;
+ self->devFactor = (RANDOM_UNIFORM * 2.0 - 1.0) * dev + 1.0;
break;
}
}
@@ -3237,7 +3237,7 @@ MainParticle_transform_i(MainParticle *self) {
self->flags[j] = 0;
self->phase[j] = 0.0;
self->inc[j] = 1.0 / (dur * self->sr);
- self->devFactor = (rand() / (MYFLT)RAND_MAX * 2.0 - 1.0) * dev + 1.0;
+ self->devFactor = (RANDOM_UNIFORM * 2.0 - 1.0) * dev + 1.0;
if (self->chnls == 2) {
self->k1[j] = 0;
self->k2[j] = self->bufsize;
@@ -3371,7 +3371,7 @@ MainParticle_transform_a(MainParticle *self) {
self->flags[j] = 0;
self->phase[j] = 0.0;
self->inc[j] = 1.0 / (dur * self->sr);
- self->devFactor = (rand() / (MYFLT)RAND_MAX * 2.0 - 1.0) * dev + 1.0;
+ self->devFactor = (RANDOM_UNIFORM * 2.0 - 1.0) * dev + 1.0;
if (self->chnls == 2) {
self->k1[j] = 0;
self->k2[j] = self->bufsize;
@@ -3548,7 +3548,7 @@ MainParticle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
INIT_OBJECT_COMMON
self->oneOnSr = 1.0 / self->sr;
- self->srOnRandMax = self->sr / (MYFLT)RAND_MAX;
+ self->srOnRandMax = self->sr / (MYFLT)PYO_RAND_MAX;
Stream_setFunctionPtr(self->stream, MainParticle_compute_next_data_frame);
self->mode_func_ptr = MainParticle_setProcMode;
diff --git a/src/objects/lfomodule.c b/src/objects/lfomodule.c
index ef9be04..1017756 100644
--- a/src/objects/lfomodule.c
+++ b/src/objects/lfomodule.c
@@ -175,7 +175,7 @@ LFO_generates_ii(LFO *self) {
self->pointerPos -= 1.0;
self->sahPointerPos = 0.0;
self->sahLastValue = self->sahCurrentValue;
- self->sahCurrentValue = rand()/((MYFLT)(RAND_MAX)*0.5) - 1.0;
+ self->sahCurrentValue = RANDOM_UNIFORM * 2.0 - 1.0;
}
if (self->sahPointerPos < 1.0) {
fade = 0.5 * MYSIN(PI * (self->sahPointerPos+0.5)) + 0.5;
@@ -354,7 +354,7 @@ LFO_generates_ai(LFO *self) {
self->pointerPos -= 1.0;
self->sahPointerPos = 0.0;
self->sahLastValue = self->sahCurrentValue;
- self->sahCurrentValue = rand()/((MYFLT)(RAND_MAX)*0.5) - 1.0;
+ self->sahCurrentValue = RANDOM_UNIFORM * 2.0 - 1.0;
}
if (self->sahPointerPos < 1.0) {
fade = 0.5 * MYSIN(PI * (self->sahPointerPos+0.5)) + 0.5;
@@ -553,7 +553,7 @@ LFO_generates_ia(LFO *self) {
self->pointerPos -= 1.0;
self->sahPointerPos = 0.0;
self->sahLastValue = self->sahCurrentValue;
- self->sahCurrentValue = rand()/((MYFLT)(RAND_MAX)*0.5) - 1.0;
+ self->sahCurrentValue = RANDOM_UNIFORM * 2.0 - 1.0;
}
if (self->sahPointerPos < 1.0) {
fade = 0.5 * MYSIN(PI * (self->sahPointerPos+0.5)) + 0.5;
@@ -768,7 +768,7 @@ LFO_generates_aa(LFO *self) {
self->pointerPos -= 1.0;
self->sahPointerPos = 0.0;
self->sahLastValue = self->sahCurrentValue;
- self->sahCurrentValue = rand()/((MYFLT)(RAND_MAX)*0.5) - 1.0;
+ self->sahCurrentValue = RANDOM_UNIFORM * 2.0 - 1.0;
}
if (self->sahPointerPos < 1.0) {
fade = 0.5 * MYSIN(PI * (self->sahPointerPos+0.5)) + 0.5;
@@ -961,7 +961,7 @@ LFO_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Server_generateSeed((Server *)self->server, LFO_ID);
- self->sahCurrentValue = self->sahLastValue = rand()/((MYFLT)(RAND_MAX)*0.5) - 1.0;
+ self->sahCurrentValue = self->sahLastValue = RANDOM_UNIFORM * 2.0 - 1.0;
(*self->mode_func_ptr)(self);
diff --git a/src/objects/metromodule.c b/src/objects/metromodule.c
index 4913b0b..57dec3f 100644
--- a/src/objects/metromodule.c
+++ b/src/objects/metromodule.c
@@ -992,7 +992,7 @@ Clouder_generate_i(Clouder *self) {
dens *= 0.5;
for (i=0; i<self->bufsize; i++) {
- rnd = (int)(rand() / (MYFLT)RAND_MAX * self->sr);
+ rnd = (int)(RANDOM_UNIFORM * self->sr);
if (rnd < dens) {
self->buffer_streams[i + self->voiceCount++ * self->bufsize] = 1.0;
if (self->voiceCount == self->poly)
@@ -1020,7 +1020,7 @@ Clouder_generate_a(Clouder *self) {
dens = self->sr;
dens *= 0.5;
- rnd = (int)(rand() / (MYFLT)RAND_MAX * self->sr);
+ rnd = (int)(RANDOM_UNIFORM * self->sr);
if (rnd < dens) {
self->buffer_streams[i + self->voiceCount++ * self->bufsize] = 1.0;
if (self->voiceCount == self->poly)
@@ -1759,11 +1759,11 @@ typedef struct {
static MYFLT
Beater_defineAccent(int n) {
if (n == 1)
- return (MYFLT)((rand() % 15) + 112) / 127.; // 112 -> 127
+ return (MYFLT)((pyorand() % 15) + 112) / 127.; // 112 -> 127
else if (n == 2)
- return (MYFLT)((rand() % 20) + 70) / 127.; // 70 -> 90
+ return (MYFLT)((pyorand() % 20) + 70) / 127.; // 70 -> 90
else if (n == 3)
- return (MYFLT)((rand() % 20) + 40) / 127.; // 40 -> 60
+ return (MYFLT)((pyorand() % 20) + 40) / 127.; // 40 -> 60
else
return 0.5;
}
@@ -1906,7 +1906,7 @@ Beater_makeSequence(Beater *self) {
j = 0;
for (i=0; i < self->taps; i++) {
- if ((rand() % 100) < self->tapProb[i]) {
+ if ((pyorand() % 100) < self->tapProb[i]) {
self->sequence[i] = 1;
self->tapList[j++] = i;
}
diff --git a/src/objects/midimodule.c b/src/objects/midimodule.c
index 6849296..480c982 100644
--- a/src/objects/midimodule.c
+++ b/src/objects/midimodule.c
@@ -1919,7 +1919,7 @@ int firstEmpty(int *buf, int len) {
int nextEmptyVoice(int *buf, int voice, int len) {
int i, tmp;
int next = -1;
- for (i=0; i<len; i++) {
+ for (i=1; i<=len; i++) {
tmp = (i + voice) % len;
if (buf[tmp*2+1] == 0) {
next = tmp;
diff --git a/src/objects/noisemodule.c b/src/objects/noisemodule.c
index 728e3b8..9cfad4d 100644
--- a/src/objects/noisemodule.c
+++ b/src/objects/noisemodule.c
@@ -37,7 +37,7 @@ Noise_generate(Noise *self) {
int i;
for (i=0; i<self->bufsize; i++) {
- self->data[i] = rand()/((MYFLT)(RAND_MAX)+1)*1.98-0.99;
+ self->data[i] = RANDOM_UNIFORM * 1.98 - 0.99;
}
}
@@ -168,7 +168,7 @@ Noise_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Server_generateSeed((Server *)self->server, NOISE_ID);
- self->seed = rand();
+ self->seed = pyorand();
(*self->mode_func_ptr)(self);
@@ -335,7 +335,7 @@ PinkNoise_generate(PinkNoise *self) {
int i;
for (i=0; i<self->bufsize; i++) {
- in = rand()/((MYFLT)(RAND_MAX)+1)*1.98-0.99;
+ in = RANDOM_UNIFORM * 1.98 - 0.99;
self->c0 = self->c0 * 0.99886 + in * 0.0555179;
self->c1 = self->c1 * 0.99332 + in * 0.0750759;
self->c2 = self->c2 * 0.96900 + in * 0.1538520;
@@ -601,7 +601,7 @@ BrownNoise_generate(BrownNoise *self) {
int i;
for (i=0; i<self->bufsize; i++) {
- rnd = rand()/((MYFLT)(RAND_MAX)+1)*1.98-0.99;
+ rnd = RANDOM_UNIFORM * 1.98 - 0.99;
val = self->c1 * rnd + self->c2 * self->y1;
self->y1 = val;
self->data[i] = val * 20.0; /* gain compensation */
diff --git a/src/objects/oscbankmodule.c b/src/objects/oscbankmodule.c
index bc0bee1..ccf5f91 100644
--- a/src/objects/oscbankmodule.c
+++ b/src/objects/oscbankmodule.c
@@ -89,7 +89,7 @@ OscBank_setFrequencies(OscBank *self, MYFLT freq, MYFLT spread) {
MYFLT scl = freq * spread;
if (self->fjit == 1) {
- seed = rand();
+ seed = pyorand();
for (i=0; i<self->stages; i++) {
seed = (seed * 15625 + 1) & 0xFFFF;
rnd = seed * 1.52587890625e-07 - 0.005 + 1.0;
@@ -115,7 +115,7 @@ OscBank_pickNewFrnds(OscBank *self, MYFLT frndf, MYFLT frnda) {
else if (frnda > 1.0)
frnda = 1.0;
- seed = rand();
+ seed = pyorand();
for (i=0; i<self->stages; i++) {
self->fOldValues[i] = self->fValues[i];
seed = (seed * 15625 + 1) & 0xFFFF;
@@ -134,7 +134,7 @@ OscBank_pickNewArnds(OscBank *self, MYFLT arndf, MYFLT arnda) {
else if (arnda > 1.0)
arnda = 1.0;
- seed = rand();
+ seed = pyorand();
for (i=0; i<self->stages; i++) {
self->aOldValues[i] = self->aValues[i];
seed = (seed * 15625 + 1) & 0xFFFF;
diff --git a/src/objects/oscmodule.c b/src/objects/oscmodule.c
index 9f28225..937a395 100644
--- a/src/objects/oscmodule.c
+++ b/src/objects/oscmodule.c
@@ -970,7 +970,7 @@ int OscDataReceive_handler(const char *path, const char *types, lo_arg **argv, i
void *data, void *user_data)
{
OscDataReceive *self = user_data;
- PyObject *tup, *result=NULL, *address=NULL;
+ PyObject *tup, *result=NULL;
lo_blob *blob = NULL;
char *blobdata = NULL;
uint32_t blobsize = 0;
@@ -980,13 +980,17 @@ int OscDataReceive_handler(const char *path, const char *types, lo_arg **argv, i
Py_ssize_t lsize = PyList_Size(self->address_path);
for (i=0; i<lsize; i++) {
- if (PyString_Check(PyList_GET_ITEM(self->address_path, i)))
- address = PyList_GET_ITEM(self->address_path, i);
- else
- address = PyUnicode_AsASCIIString(PyList_GET_ITEM(self->address_path, i));
- if (lo_pattern_match(path, PyString_AsString(address))) {
- ok = 1;
- break;
+ if (PyString_Check(PyList_GET_ITEM(self->address_path, i))) {
+ if (lo_pattern_match(path, PyString_AsString(PyList_GET_ITEM(self->address_path, i)))) {
+ ok = 1;
+ break;
+ }
+ }
+ else {
+ if (lo_pattern_match(path, PyString_AsString(PyUnicode_AsASCIIString(PyList_GET_ITEM(self->address_path, i))))) {
+ ok = 1;
+ break;
+ }
}
}
if (ok) {
@@ -1051,7 +1055,6 @@ int OscDataReceive_handler(const char *path, const char *types, lo_arg **argv, i
Py_XDECREF(tup);
Py_XDECREF(result);
Py_XDECREF(charlist);
- Py_XDECREF(address);
return 0;
}
diff --git a/src/objects/randommodule.c b/src/objects/randommodule.c
index aa3e085..fc25ac6 100644
--- a/src/objects/randommodule.c
+++ b/src/objects/randommodule.c
@@ -58,7 +58,7 @@ Randi_generate_iii(Randi *self) {
else if (self->time >= 1.0) {
self->time -= 1.0;
self->oldValue = self->value;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
self->diff = self->value - self->oldValue;
}
self->data[i] = self->oldValue + self->diff * self->time;
@@ -82,7 +82,7 @@ Randi_generate_aii(Randi *self) {
else if (self->time >= 1.0) {
self->time -= 1.0;
self->oldValue = self->value;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi[i];
+ self->value = range * RANDOM_UNIFORM + mi[i];
self->diff = self->value - self->oldValue;
}
self->data[i] = self->oldValue + self->diff * self->time;
@@ -106,7 +106,7 @@ Randi_generate_iai(Randi *self) {
else if (self->time >= 1.0) {
self->time -= 1.0;
self->oldValue = self->value;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
self->diff = self->value - self->oldValue;
}
self->data[i] = self->oldValue + self->diff * self->time;
@@ -130,7 +130,7 @@ Randi_generate_aai(Randi *self) {
else if (self->time >= 1.0) {
self->time -= 1.0;
self->oldValue = self->value;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi[i];
+ self->value = range * RANDOM_UNIFORM + mi[i];
self->diff = self->value - self->oldValue;
}
self->data[i] = self->oldValue + self->diff * self->time;
@@ -154,7 +154,7 @@ Randi_generate_iia(Randi *self) {
else if (self->time >= 1.0) {
self->time -= 1.0;
self->oldValue = self->value;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
self->diff = self->value - self->oldValue;
}
self->data[i] = self->oldValue + self->diff * self->time;
@@ -178,7 +178,7 @@ Randi_generate_aia(Randi *self) {
else if (self->time >= 1.0) {
self->time -= 1.0;
self->oldValue = self->value;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi[i];
+ self->value = range * RANDOM_UNIFORM + mi[i];
self->diff = self->value - self->oldValue;
}
self->data[i] = self->oldValue + self->diff * self->time;
@@ -202,7 +202,7 @@ Randi_generate_iaa(Randi *self) {
else if (self->time >= 1.0) {
self->time -= 1.0;
self->oldValue = self->value;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
self->diff = self->value - self->oldValue;
}
self->data[i] = self->oldValue + self->diff * self->time;
@@ -226,7 +226,7 @@ Randi_generate_aaa(Randi *self) {
else if (self->time >= 1.0) {
self->time -= 1.0;
self->oldValue = self->value;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi[i];
+ self->value = range * RANDOM_UNIFORM + mi[i];
self->diff = self->value - self->oldValue;
}
self->data[i] = self->oldValue + self->diff * self->time;
@@ -673,7 +673,7 @@ Randh_generate_iii(Randh *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
}
self->data[i] = self->value;
}
@@ -695,7 +695,7 @@ Randh_generate_aii(Randh *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi[i];
+ self->value = range * RANDOM_UNIFORM + mi[i];
}
self->data[i] = self->value;
}
@@ -717,7 +717,7 @@ Randh_generate_iai(Randh *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
}
self->data[i] = self->value;
}
@@ -739,7 +739,7 @@ Randh_generate_aai(Randh *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi[i];
+ self->value = range * RANDOM_UNIFORM + mi[i];
}
self->data[i] = self->value;
}
@@ -761,7 +761,7 @@ Randh_generate_iia(Randh *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
}
self->data[i] = self->value;
}
@@ -783,7 +783,7 @@ Randh_generate_aia(Randh *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi[i];
+ self->value = range * RANDOM_UNIFORM + mi[i];
}
self->data[i] = self->value;
}
@@ -805,7 +805,7 @@ Randh_generate_iaa(Randh *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
}
self->data[i] = self->value;
}
@@ -827,7 +827,7 @@ Randh_generate_aaa(Randh *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi[i];
+ self->value = range * RANDOM_UNIFORM + mi[i];
}
self->data[i] = self->value;
}
@@ -1268,7 +1268,7 @@ Choice_generate_i(Choice *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = self->choice[(int)((rand()/((MYFLT)(RAND_MAX))) * self->chSize)];
+ self->value = self->choice[(int)(RANDOM_UNIFORM * self->chSize)];
}
self->data[i] = self->value;
}
@@ -1287,7 +1287,7 @@ Choice_generate_a(Choice *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = self->choice[(int)((rand()/((MYFLT)(RAND_MAX))) * self->chSize)];
+ self->value = self->choice[(int)(RANDOM_UNIFORM * self->chSize)];
}
self->data[i] = self->value;
}
@@ -1644,7 +1644,7 @@ RandInt_generate_ii(RandInt *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = (MYFLT)((int)(rand()/((MYFLT)(RAND_MAX)+1)*ma));
+ self->value = (MYFLT)((int)(RANDOM_UNIFORM * ma));
}
self->data[i] = self->value;
}
@@ -1664,7 +1664,7 @@ RandInt_generate_ai(RandInt *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = (MYFLT)((int)(rand()/((MYFLT)(RAND_MAX)+1)*ma[i]));
+ self->value = (MYFLT)((int)(RANDOM_UNIFORM * ma[i]));
}
self->data[i] = self->value;
}
@@ -1684,7 +1684,7 @@ RandInt_generate_ia(RandInt *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = (MYFLT)((int)(rand()/((MYFLT)(RAND_MAX)+1)*ma));
+ self->value = (MYFLT)((int)(RANDOM_UNIFORM * ma));
}
self->data[i] = self->value;
}
@@ -1704,7 +1704,7 @@ RandInt_generate_aa(RandInt *self) {
self->time += 1.0;
else if (self->time >= 1.0) {
self->time -= 1.0;
- self->value = (MYFLT)((int)(rand()/((MYFLT)(RAND_MAX)+1)*ma[i]));
+ self->value = (MYFLT)((int)(RANDOM_UNIFORM * ma[i]));
}
self->data[i] = self->value;
}
@@ -2084,7 +2084,7 @@ RandDur_generate_ii(RandDur *self) {
range = ma - mi;
if (range < 0.0)
range = 0.0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
self->inc = (1.0 / self->value) / self->sr;
}
self->data[i] = self->value;
@@ -2110,7 +2110,7 @@ RandDur_generate_ai(RandDur *self) {
range = ma - mi;
if (range < 0.0)
range = 0.0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
self->inc = (1.0 / self->value) / self->sr;
}
self->data[i] = self->value;
@@ -2135,7 +2135,7 @@ RandDur_generate_ia(RandDur *self) {
range = ma[i] - mi;
if (range < 0.0)
range = 0.0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
self->inc = (1.0 / self->value) / self->sr;
}
self->data[i] = self->value;
@@ -2161,7 +2161,7 @@ RandDur_generate_aa(RandDur *self) {
range = ma[i] - mi;
if (range < 0.0)
range = 0.0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
self->inc = (1.0 / self->value) / self->sr;
}
self->data[i] = self->value;
@@ -2633,7 +2633,7 @@ Xnoise_cauchy(Xnoise *self) {
}
while (rnd == 0.5);
- if (rand() < (RAND_MAX / 2))
+ if (pyorand() < (PYO_RAND_MAX / 2))
dir = -1;
else
dir = 1;
@@ -2694,7 +2694,7 @@ Xnoise_poisson(Xnoise *self) {
}
}
}
- val = self->poisson_buffer[rand() % self->poisson_tab] / 12.0 * self->xx2;
+ val = self->poisson_buffer[pyorand() % self->poisson_tab] / 12.0 * self->xx2;
if (val < 0.0) return 0.0;
else if (val > 1.0) return 1.0;
@@ -2709,12 +2709,12 @@ Xnoise_walker(Xnoise *self) {
if (self->xx2 < 0.002) self->xx2 = 0.002;
modulo = (int)(self->xx2 * 1000.0);
- dir = rand() % 2;
+ dir = pyorand() % 2;
if (dir == 0)
- self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue + (((pyorand() % modulo) - (modulo / 2)) * 0.001);
else
- self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue - (((pyorand() % modulo) - (modulo / 2)) * 0.001);
if (self->walkerValue > self->xx1)
self->walkerValue = self->xx1;
@@ -2736,12 +2736,12 @@ Xnoise_loopseg(Xnoise *self) {
if (self->xx2 < 0.002) self->xx2 = 0.002;
modulo = (int)(self->xx2 * 1000.0);
- dir = rand() % 2;
+ dir = pyorand() % 2;
if (dir == 0)
- self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue + (((pyorand() % modulo) - (modulo / 2)) * 0.001);
else
- self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue - (((pyorand() % modulo) - (modulo / 2)) * 0.001);
if (self->walkerValue > self->xx1)
self->walkerValue = self->xx1;
@@ -2754,7 +2754,7 @@ Xnoise_loopseg(Xnoise *self) {
self->loopChoice = 0;
else {
self->loopChoice = 1;
- self->loopStop = (rand() % 4) + 1;
+ self->loopStop = (pyorand() % 4) + 1;
}
}
else {
@@ -2771,7 +2771,7 @@ Xnoise_loopseg(Xnoise *self) {
if (self->loopTime == self->loopStop) {
self->loopChoice = 0;
- self->loopLen = (rand() % 10) + 3;
+ self->loopLen = (pyorand() % 10) + 3;
}
}
@@ -3149,7 +3149,7 @@ Xnoise_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->loop_buffer[i] = 0.0;
}
self->loopChoice = self->loopCountPlay = self->loopTime = self->loopCountRec = self->loopStop = 0;
- self->loopLen = (rand() % 10) + 3;
+ self->loopLen = (pyorand() % 10) + 3;
Stream_setFunctionPtr(self->stream, Xnoise_compute_next_data_frame);
self->mode_func_ptr = Xnoise_setProcMode;
@@ -3565,7 +3565,7 @@ XnoiseMidi_cauchy(XnoiseMidi *self) {
}
while (rnd == 0.5);
- if (rand() < (RAND_MAX / 2))
+ if (pyorand() < (PYO_RAND_MAX / 2))
dir = -1;
else
dir = 1;
@@ -3626,7 +3626,7 @@ XnoiseMidi_poisson(XnoiseMidi *self) {
}
}
}
- val = self->poisson_buffer[rand() % self->poisson_tab] / 12.0 * self->xx2;
+ val = self->poisson_buffer[pyorand() % self->poisson_tab] / 12.0 * self->xx2;
if (val < 0.0) return 0.0;
else if (val > 1.0) return 1.0;
@@ -3641,12 +3641,12 @@ XnoiseMidi_walker(XnoiseMidi *self) {
if (self->xx2 < 0.002) self->xx2 = 0.002;
modulo = (int)(self->xx2 * 1000.0);
- dir = rand() % 2;
+ dir = pyorand() % 2;
if (dir == 0)
- self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue + (((pyorand() % modulo) - (modulo / 2)) * 0.001);
else
- self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue - (((pyorand() % modulo) - (modulo / 2)) * 0.001);
if (self->walkerValue > self->xx1)
self->walkerValue = self->xx1;
@@ -3668,12 +3668,12 @@ XnoiseMidi_loopseg(XnoiseMidi *self) {
if (self->xx2 < 0.002) self->xx2 = 0.002;
modulo = (int)(self->xx2 * 1000.0);
- dir = rand() % 2;
+ dir = pyorand() % 2;
if (dir == 0)
- self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue + (((pyorand() % modulo) - (modulo / 2)) * 0.001);
else
- self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue - (((pyorand() % modulo) - (modulo / 2)) * 0.001);
if (self->walkerValue > self->xx1)
self->walkerValue = self->xx1;
@@ -3686,7 +3686,7 @@ XnoiseMidi_loopseg(XnoiseMidi *self) {
self->loopChoice = 0;
else {
self->loopChoice = 1;
- self->loopStop = (rand() % 4) + 1;
+ self->loopStop = (pyorand() % 4) + 1;
}
}
else {
@@ -3703,7 +3703,7 @@ XnoiseMidi_loopseg(XnoiseMidi *self) {
if (self->loopTime == self->loopStop) {
self->loopChoice = 0;
- self->loopLen = (rand() % 10) + 3;
+ self->loopLen = (pyorand() % 10) + 3;
}
}
@@ -4093,7 +4093,7 @@ XnoiseMidi_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->loop_buffer[i] = 0.0;
}
self->loopChoice = self->loopCountPlay = self->loopTime = self->loopCountRec = self->loopStop = 0;
- self->loopLen = (rand() % 10) + 3;
+ self->loopLen = (pyorand() % 10) + 3;
Stream_setFunctionPtr(self->stream, XnoiseMidi_compute_next_data_frame);
self->mode_func_ptr = XnoiseMidi_setProcMode;
@@ -4531,7 +4531,7 @@ XnoiseDur_cauchy(XnoiseDur *self) {
}
while (rnd == 0.5);
- if (rand() < (RAND_MAX / 2))
+ if (pyorand() < (PYO_RAND_MAX / 2))
dir = -1;
else
dir = 1;
@@ -4592,7 +4592,7 @@ XnoiseDur_poisson(XnoiseDur *self) {
}
}
}
- val = self->poisson_buffer[rand() % self->poisson_tab] / 12.0 * self->xx2;
+ val = self->poisson_buffer[pyorand() % self->poisson_tab] / 12.0 * self->xx2;
if (val < 0.0) return 0.0;
else if (val > 1.0) return 1.0;
@@ -4607,12 +4607,12 @@ XnoiseDur_walker(XnoiseDur *self) {
if (self->xx2 < 0.002) self->xx2 = 0.002;
modulo = (int)(self->xx2 * 1000.0);
- dir = rand() % 2;
+ dir = pyorand() % 2;
if (dir == 0)
- self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue + (((pyorand() % modulo) - (modulo / 2)) * 0.001);
else
- self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue - (((pyorand() % modulo) - (modulo / 2)) * 0.001);
if (self->walkerValue > self->xx1)
self->walkerValue = self->xx1;
@@ -4634,12 +4634,12 @@ XnoiseDur_loopseg(XnoiseDur *self) {
if (self->xx2 < 0.002) self->xx2 = 0.002;
modulo = (int)(self->xx2 * 1000.0);
- dir = rand() % 2;
+ dir = pyorand() % 2;
if (dir == 0)
- self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue + (((pyorand() % modulo) - (modulo / 2)) * 0.001);
else
- self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue - (((pyorand() % modulo) - (modulo / 2)) * 0.001);
if (self->walkerValue > self->xx1)
self->walkerValue = self->xx1;
@@ -4652,7 +4652,7 @@ XnoiseDur_loopseg(XnoiseDur *self) {
self->loopChoice = 0;
else {
self->loopChoice = 1;
- self->loopStop = (rand() % 4) + 1;
+ self->loopStop = (pyorand() % 4) + 1;
}
}
else {
@@ -4669,7 +4669,7 @@ XnoiseDur_loopseg(XnoiseDur *self) {
if (self->loopTime == self->loopStop) {
self->loopChoice = 0;
- self->loopLen = (rand() % 10) + 3;
+ self->loopLen = (pyorand() % 10) + 3;
}
}
@@ -4891,7 +4891,7 @@ XnoiseDur_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->loop_buffer[i] = 0.0;
}
self->loopChoice = self->loopCountPlay = self->loopTime = self->loopCountRec = self->loopStop = 0;
- self->loopLen = (rand() % 10) + 3;
+ self->loopLen = (pyorand() % 10) + 3;
Stream_setFunctionPtr(self->stream, XnoiseDur_compute_next_data_frame);
self->mode_func_ptr = XnoiseDur_setProcMode;
@@ -5258,9 +5258,9 @@ Urn_choose(Urn *self) {
int value = 0;
int i, pick;
- pick = rand() % self->length;
+ pick = pyorand() % self->length;
while (pick == self->lastvalue)
- pick = rand() % self->length;
+ pick = pyorand() % self->length;
for (i=0; i<self->length; i++) {
if (i != pick)
diff --git a/src/objects/sfplayermodule.c b/src/objects/sfplayermodule.c
index f9f332a..50b1e9e 100644
--- a/src/objects/sfplayermodule.c
+++ b/src/objects/sfplayermodule.c
@@ -1015,7 +1015,7 @@ SfMarkerShuffler_chooseNewMark(SfMarkerShuffler *self, int dir)
int mark;
if (dir == 1) {
if (self->startPos == -1) {
- mark = (int)(self->markers_size * (rand()/((MYFLT)(RAND_MAX)+1)));
+ mark = (int)(self->markers_size * RANDOM_UNIFORM);
self->startPos = self->markers[mark] * self->srScale;
self->endPos = self->markers[mark+1] * self->srScale;
}
@@ -1024,13 +1024,13 @@ SfMarkerShuffler_chooseNewMark(SfMarkerShuffler *self, int dir)
self->endPos = self->nextEndPos;
}
- mark = (int)(self->markers_size * (rand()/((MYFLT)(RAND_MAX)+1)));
+ mark = (int)(self->markers_size * RANDOM_UNIFORM);
self->nextStartPos = self->markers[mark] * self->srScale;
self->nextEndPos = self->markers[mark+1] * self->srScale;
}
else {
if (self->startPos == -1) {
- mark = self->markers_size - (int)(self->markers_size * (rand()/((MYFLT)(RAND_MAX)+1)));
+ mark = self->markers_size - (int)(self->markers_size * RANDOM_UNIFORM);
self->startPos = self->markers[mark] * self->srScale;
self->endPos = self->markers[mark-1] * self->srScale;
}
@@ -1039,7 +1039,7 @@ SfMarkerShuffler_chooseNewMark(SfMarkerShuffler *self, int dir)
self->endPos = self->nextEndPos;
}
- mark = self->markers_size - (int)(self->markers_size * (rand()/((MYFLT)(RAND_MAX)+1)));
+ mark = self->markers_size - (int)(self->markers_size * RANDOM_UNIFORM);
self->nextStartPos = self->markers[mark] * self->srScale;
self->nextEndPos = self->markers[mark-1] * self->srScale;
}
diff --git a/src/objects/trigmodule.c b/src/objects/trigmodule.c
index df50c6d..c00d825 100644
--- a/src/objects/trigmodule.c
+++ b/src/objects/trigmodule.c
@@ -45,7 +45,7 @@ TrigRandInt_generate_i(TrigRandInt *self) {
for (i=0; i<self->bufsize; i++) {
if (in[i] == 1)
- self->value = (MYFLT)((int)(rand()/((MYFLT)(RAND_MAX)+1)*ma));
+ self->value = (MYFLT)((int)(RANDOM_UNIFORM * ma));
self->data[i] = self->value;
}
@@ -59,7 +59,7 @@ TrigRandInt_generate_a(TrigRandInt *self) {
for (i=0; i<self->bufsize; i++) {
if (in[i] == 1)
- self->value = (MYFLT)((int)(rand()/((MYFLT)(RAND_MAX)+1)*ma[i]));
+ self->value = (MYFLT)((int)(RANDOM_UNIFORM * ma[i]));
self->data[i] = self->value;
}
@@ -204,7 +204,7 @@ TrigRandInt_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
ma = PyFloat_AsDouble(self->max);
else
ma = Stream_getData((Stream *)self->max_stream)[0];
- self->value = (MYFLT)((int)(rand()/((MYFLT)(RAND_MAX)+1)*ma));
+ self->value = (MYFLT)((int)(RANDOM_UNIFORM * ma));
(*self->mode_func_ptr)(self);
@@ -398,7 +398,7 @@ TrigRand_generate_ii(TrigRand *self) {
for (i=0; i<self->bufsize; i++) {
if (in[i] == 1) {
self->timeCount = 0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
if (self->time <= 0.0)
self->currentValue = self->value;
else
@@ -429,7 +429,7 @@ TrigRand_generate_ai(TrigRand *self) {
MYFLT range = ma - mi[i];
if (in[i] == 1) {
self->timeCount = 0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi[i];
+ self->value = range * RANDOM_UNIFORM + mi[i];
if (self->time <= 0.0)
self->currentValue = self->value;
else
@@ -460,7 +460,7 @@ TrigRand_generate_ia(TrigRand *self) {
MYFLT range = ma[i] - mi;
if (in[i] == 1) {
self->timeCount = 0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
+ self->value = range * RANDOM_UNIFORM + mi;
if (self->time <= 0.0)
self->currentValue = self->value;
else
@@ -491,7 +491,7 @@ TrigRand_generate_aa(TrigRand *self) {
MYFLT range = ma[i] - mi[i];
if (in[i] == 1) {
self->timeCount = 0;
- self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi[i];
+ self->value = range * RANDOM_UNIFORM + mi[i];
if (self->time <= 0.0)
self->currentValue = self->value;
else
@@ -912,7 +912,7 @@ TrigChoice_generate(TrigChoice *self) {
for (i=0; i<self->bufsize; i++) {
if (in[i] == 1) {
self->timeCount = 0;
- self->value = self->choice[(int)((rand()/((MYFLT)(RAND_MAX))) * self->chSize)];
+ self->value = self->choice[(int)(RANDOM_UNIFORM * self->chSize)];
if (self->time <= 0.0)
self->currentValue = self->value;
else
@@ -2830,7 +2830,7 @@ TrigXnoise_cauchy(TrigXnoise *self) {
}
while (rnd == 0.5);
- if (rand() < (RAND_MAX / 2))
+ if (pyorand() < (PYO_RAND_MAX / 2))
dir = -1;
else
dir = 1;
@@ -2891,7 +2891,7 @@ TrigXnoise_poisson(TrigXnoise *self) {
}
}
}
- val = self->poisson_buffer[rand() % self->poisson_tab] / 12.0 * self->xx2;
+ val = self->poisson_buffer[pyorand() % self->poisson_tab] / 12.0 * self->xx2;
if (val < 0.0) return 0.0;
else if (val > 1.0) return 1.0;
@@ -2906,12 +2906,12 @@ TrigXnoise_walker(TrigXnoise *self) {
if (self->xx2 < 0.002) self->xx2 = 0.002;
modulo = (int)(self->xx2 * 1000.0);
- dir = rand() % 2;
+ dir = pyorand() % 2;
if (dir == 0)
- self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue + (((pyorand() % modulo) - (modulo / 2)) * 0.001);
else
- self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue - (((pyorand() % modulo) - (modulo / 2)) * 0.001);
if (self->walkerValue > self->xx1)
self->walkerValue = self->xx1;
@@ -2933,12 +2933,12 @@ TrigXnoise_loopseg(TrigXnoise *self) {
if (self->xx2 < 0.002) self->xx2 = 0.002;
modulo = (int)(self->xx2 * 1000.0);
- dir = rand() % 2;
+ dir = pyorand() % 2;
if (dir == 0)
- self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue + (((pyorand() % modulo) - (modulo / 2)) * 0.001);
else
- self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue - (((pyorand() % modulo) - (modulo / 2)) * 0.001);
if (self->walkerValue > self->xx1)
self->walkerValue = self->xx1;
@@ -2951,7 +2951,7 @@ TrigXnoise_loopseg(TrigXnoise *self) {
self->loopChoice = 0;
else {
self->loopChoice = 1;
- self->loopStop = (rand() % 4) + 1;
+ self->loopStop = (pyorand() % 4) + 1;
}
}
else {
@@ -2968,7 +2968,7 @@ TrigXnoise_loopseg(TrigXnoise *self) {
if (self->loopTime == self->loopStop) {
self->loopChoice = 0;
- self->loopLen = (rand() % 10) + 3;
+ self->loopLen = (pyorand() % 10) + 3;
}
}
@@ -3218,7 +3218,7 @@ TrigXnoise_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->loop_buffer[i] = 0.0;
}
self->loopChoice = self->loopCountPlay = self->loopTime = self->loopCountRec = self->loopStop = 0;
- self->loopLen = (rand() % 10) + 3;
+ self->loopLen = (pyorand() % 10) + 3;
Stream_setFunctionPtr(self->stream, TrigXnoise_compute_next_data_frame);
self->mode_func_ptr = TrigXnoise_setProcMode;
@@ -3600,7 +3600,7 @@ TrigXnoiseMidi_cauchy(TrigXnoiseMidi *self) {
}
while (rnd == 0.5);
- if (rand() < (RAND_MAX / 2))
+ if (pyorand() < (PYO_RAND_MAX / 2))
dir = -1;
else
dir = 1;
@@ -3661,7 +3661,7 @@ TrigXnoiseMidi_poisson(TrigXnoiseMidi *self) {
}
}
}
- val = self->poisson_buffer[rand() % self->poisson_tab] / 12.0 * self->xx2;
+ val = self->poisson_buffer[pyorand() % self->poisson_tab] / 12.0 * self->xx2;
if (val < 0.0) return 0.0;
else if (val > 1.0) return 1.0;
@@ -3676,12 +3676,12 @@ TrigXnoiseMidi_walker(TrigXnoiseMidi *self) {
if (self->xx2 < 0.002) self->xx2 = 0.002;
modulo = (int)(self->xx2 * 1000.0);
- dir = rand() % 2;
+ dir = pyorand() % 2;
if (dir == 0)
- self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue + (((pyorand() % modulo) - (modulo / 2)) * 0.001);
else
- self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue - (((pyorand() % modulo) - (modulo / 2)) * 0.001);
if (self->walkerValue > self->xx1)
self->walkerValue = self->xx1;
@@ -3703,12 +3703,12 @@ TrigXnoiseMidi_loopseg(TrigXnoiseMidi *self) {
if (self->xx2 < 0.002) self->xx2 = 0.002;
modulo = (int)(self->xx2 * 1000.0);
- dir = rand() % 2;
+ dir = pyorand() % 2;
if (dir == 0)
- self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue + (((pyorand() % modulo) - (modulo / 2)) * 0.001);
else
- self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
+ self->walkerValue = self->walkerValue - (((pyorand() % modulo) - (modulo / 2)) * 0.001);
if (self->walkerValue > self->xx1)
self->walkerValue = self->xx1;
@@ -3721,7 +3721,7 @@ TrigXnoiseMidi_loopseg(TrigXnoiseMidi *self) {
self->loopChoice = 0;
else {
self->loopChoice = 1;
- self->loopStop = (rand() % 4) + 1;
+ self->loopStop = (pyorand() % 4) + 1;
}
}
else {
@@ -3738,7 +3738,7 @@ TrigXnoiseMidi_loopseg(TrigXnoiseMidi *self) {
if (self->loopTime == self->loopStop) {
self->loopChoice = 0;
- self->loopLen = (rand() % 10) + 3;
+ self->loopLen = (pyorand() % 10) + 3;
}
}
@@ -3997,7 +3997,7 @@ TrigXnoiseMidi_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->loop_buffer[i] = 0.0;
}
self->loopChoice = self->loopCountPlay = self->loopTime = self->loopCountRec = self->loopStop = 0;
- self->loopLen = (rand() % 10) + 3;
+ self->loopLen = (pyorand() % 10) + 3;
Stream_setFunctionPtr(self->stream, TrigXnoiseMidi_compute_next_data_frame);
self->mode_func_ptr = TrigXnoiseMidi_setProcMode;
@@ -5088,7 +5088,7 @@ Percent_generates_i(Percent *self) {
for (i=0; i<self->bufsize; i++) {
self->data[i] = 0.0;
if (in[i] == 1.0) {
- guess = (rand()/((MYFLT)(RAND_MAX)+1)) * 100.0;
+ guess = RANDOM_UNIFORM * 100.0;
if (guess <= perc)
self->data[i] = 1.0;
}
@@ -5105,7 +5105,7 @@ Percent_generates_a(Percent *self) {
for (i=0; i<self->bufsize; i++) {
self->data[i] = 0.0;
if (in[i] == 1.0) {
- guess = (rand()/((MYFLT)(RAND_MAX)+1)) * 100.0;
+ guess = RANDOM_UNIFORM * 100.0;
if (guess <= perc[i])
self->data[i] = 1.0;
}
diff --git a/src/objects/utilsmodule.c b/src/objects/utilsmodule.c
index 390622d..6442876 100644
--- a/src/objects/utilsmodule.c
+++ b/src/objects/utilsmodule.c
@@ -2580,9 +2580,9 @@ PyTypeObject BetweenType = {
/* Denorm */
/************/
#ifndef USE_DOUBLE
-#define DENORM_RAND ((MYFLT) ((rand()/((MYFLT)(RAND_MAX)*0.5+1) - 1.0) * (MYFLT)(1.0e-24)))
+#define DENORM_RAND ((MYFLT) ((pyorand()/((MYFLT)(PYO_RAND_MAX)*0.5+1) - 1.0) * (MYFLT)(1.0e-24)))
#else
-#define DENORM_RAND ((MYFLT) ((rand()/((MYFLT)(RAND_MAX)*0.5+1) - 1.0) * (MYFLT)(1.0e-60)))
+#define DENORM_RAND ((MYFLT) ((pyorand()/((MYFLT)(PYO_RAND_MAX)*0.5+1) - 1.0) * (MYFLT)(1.0e-60)))
#endif
typedef struct {
diff --git a/src/objects/wgverbmodule.c b/src/objects/wgverbmodule.c
index 3b55070..ba280e4 100644
--- a/src/objects/wgverbmodule.c
+++ b/src/objects/wgverbmodule.c
@@ -105,7 +105,7 @@ WGVerb_process_ii(WGVerb *self) {
else if (self->rnd_time[j] >= 1.0) {
self->rnd_time[j] -= 1.0;
self->rnd_oldValue[j] = self->rnd_value[j];
- self->rnd_value[j] = self->rnd_range[j] * (rand()/((MYFLT)(RAND_MAX)+1)) - self->rnd_halfRange[j];
+ self->rnd_value[j] = self->rnd_range[j] * RANDOM_UNIFORM - self->rnd_halfRange[j];
self->rnd_diff[j] = self->rnd_value[j] - self->rnd_oldValue[j];
}
self->rnd[j] = self->rnd_oldValue[j] + self->rnd_diff[j] * self->rnd_time[j];
@@ -165,7 +165,7 @@ WGVerb_process_ai(WGVerb *self) {
else if (self->rnd_time[j] >= 1.0) {
self->rnd_time[j] -= 1.0;
self->rnd_oldValue[j] = self->rnd_value[j];
- self->rnd_value[j] = self->rnd_range[j] * (rand()/((MYFLT)(RAND_MAX)+1)) - self->rnd_halfRange[j];
+ self->rnd_value[j] = self->rnd_range[j] * RANDOM_UNIFORM - self->rnd_halfRange[j];
self->rnd_diff[j] = self->rnd_value[j] - self->rnd_oldValue[j];
}
self->rnd[j] = self->rnd_oldValue[j] + self->rnd_diff[j] * self->rnd_time[j];
@@ -225,7 +225,7 @@ WGVerb_process_ia(WGVerb *self) {
else if (self->rnd_time[j] >= 1.0) {
self->rnd_time[j] -= 1.0;
self->rnd_oldValue[j] = self->rnd_value[j];
- self->rnd_value[j] = self->rnd_range[j] * (rand()/((MYFLT)(RAND_MAX)+1)) - self->rnd_halfRange[j];
+ self->rnd_value[j] = self->rnd_range[j] * RANDOM_UNIFORM - self->rnd_halfRange[j];
self->rnd_diff[j] = self->rnd_value[j] - self->rnd_oldValue[j];
}
self->rnd[j] = self->rnd_oldValue[j] + self->rnd_diff[j] * self->rnd_time[j];
@@ -285,7 +285,7 @@ WGVerb_process_aa(WGVerb *self) {
else if (self->rnd_time[j] >= 1.0) {
self->rnd_time[j] -= 1.0;
self->rnd_oldValue[j] = self->rnd_value[j];
- self->rnd_value[j] = self->rnd_range[j] * (rand()/((MYFLT)(RAND_MAX)+1)) - self->rnd_halfRange[j];
+ self->rnd_value[j] = self->rnd_range[j] * RANDOM_UNIFORM - self->rnd_halfRange[j];
self->rnd_diff[j] = self->rnd_value[j] - self->rnd_oldValue[j];
}
self->rnd[j] = self->rnd_oldValue[j] + self->rnd_diff[j] * self->rnd_time[j];
@@ -916,7 +916,7 @@ STReverb_process_ii(STReverb *self) {
else if (self->rnd_time[k][j] >= 1.0) {
self->rnd_time[k][j] -= 1.0;
self->rnd_oldValue[k][j] = self->rnd_value[k][j];
- self->rnd_value[k][j] = self->rnd_range[k][j] * (rand()/((MYFLT)(RAND_MAX)+1)) - self->rnd_halfRange[k][j];
+ self->rnd_value[k][j] = self->rnd_range[k][j] * RANDOM_UNIFORM - self->rnd_halfRange[k][j];
self->rnd_diff[k][j] = self->rnd_value[k][j] - self->rnd_oldValue[k][j];
}
self->rnd[k][j] = self->rnd_oldValue[k][j] + self->rnd_diff[k][j] * self->rnd_time[k][j];
@@ -1037,7 +1037,7 @@ STReverb_process_ai(STReverb *self) {
else if (self->rnd_time[k][j] >= 1.0) {
self->rnd_time[k][j] -= 1.0;
self->rnd_oldValue[k][j] = self->rnd_value[k][j];
- self->rnd_value[k][j] = self->rnd_range[k][j] * (rand()/((MYFLT)(RAND_MAX)+1)) - self->rnd_halfRange[k][j];
+ self->rnd_value[k][j] = self->rnd_range[k][j] * RANDOM_UNIFORM - self->rnd_halfRange[k][j];
self->rnd_diff[k][j] = self->rnd_value[k][j] - self->rnd_oldValue[k][j];
}
self->rnd[k][j] = self->rnd_oldValue[k][j] + self->rnd_diff[k][j] * self->rnd_time[k][j];
@@ -1159,7 +1159,7 @@ STReverb_process_ia(STReverb *self) {
else if (self->rnd_time[k][j] >= 1.0) {
self->rnd_time[k][j] -= 1.0;
self->rnd_oldValue[k][j] = self->rnd_value[k][j];
- self->rnd_value[k][j] = self->rnd_range[k][j] * (rand()/((MYFLT)(RAND_MAX)+1)) - self->rnd_halfRange[k][j];
+ self->rnd_value[k][j] = self->rnd_range[k][j] * RANDOM_UNIFORM - self->rnd_halfRange[k][j];
self->rnd_diff[k][j] = self->rnd_value[k][j] - self->rnd_oldValue[k][j];
}
self->rnd[k][j] = self->rnd_oldValue[k][j] + self->rnd_diff[k][j] * self->rnd_time[k][j];
@@ -1281,7 +1281,7 @@ STReverb_process_aa(STReverb *self) {
else if (self->rnd_time[k][j] >= 1.0) {
self->rnd_time[k][j] -= 1.0;
self->rnd_oldValue[k][j] = self->rnd_value[k][j];
- self->rnd_value[k][j] = self->rnd_range[k][j] * (rand()/((MYFLT)(RAND_MAX)+1)) - self->rnd_halfRange[k][j];
+ self->rnd_value[k][j] = self->rnd_range[k][j] * RANDOM_UNIFORM - self->rnd_halfRange[k][j];
self->rnd_diff[k][j] = self->rnd_value[k][j] - self->rnd_oldValue[k][j];
}
self->rnd[k][j] = self->rnd_oldValue[k][j] + self->rnd_diff[k][j] * self->rnd_time[k][j];
diff --git a/utils/E-Pyo.py b/utils/E-Pyo.py
index dc85faa..203c256 100755
--- a/utils/E-Pyo.py
+++ b/utils/E-Pyo.py
@@ -3316,6 +3316,11 @@ class MainFrame(wx.Frame):
wx.AboutBox(info)
def OnClose(self, event):
+ msg = "You are about to leave E-Pyo. Is this really what you want to do?"
+ dlg = wx.MessageDialog(self, msg, "Warning!", wx.YES_NO|wx.ICON_QUESTION)
+ if dlg.ShowModal() != wx.ID_YES:
+ event.StopPropagation()
+ return
if self.back_server_started == True:
try:
self.startStopBackgroundServer(None)
diff --git a/utils/PyoDoc.py b/utils/PyoDoc.py
index 9628f9a..262891d 100644
--- a/utils/PyoDoc.py
+++ b/utils/PyoDoc.py
@@ -209,9 +209,17 @@ functions : Miscellaneous functions.
""" % PYO_VERSION
+PYOGUI_DOC = """
+The classes in this module are based on internal classes that where
+originally designed to help the creation of graphical tools for the
+control and the visualization of audio signals. WxPython must be installed
+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"]
+_HEADERS = ["Server", "PyoObjectBase", "Map", "Stream", "TableStream", "functions", "PyoGui"]
_KEYWORDS_LIST = ['SLMap']
_KEYWORDS_LIST.extend(_HEADERS)
_NUM_PAGES = 1
@@ -240,6 +248,7 @@ PYOTABLEOBJECT_METHODS_FILTER = [x[0] for x in inspect.getmembers(PyoTableObject
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 _ed_set_style(editor, searchKey=None):
editor.SetLexer(stc.STC_LEX_PYTHON)
@@ -623,13 +632,18 @@ class ManualPanel(wx.Treebook):
else:
try:
text = eval(obj).__doc__
- text = text.replace(".. note::", "Notes:").replace(".. seealso::", "See also:").replace(":Args:", "Parameters:")
+ text = text.replace(".. note::", "Notes:").replace(".. seealso::", "See also:").replace(":Args:", "Parameters:").replace(":Events:", "Events:")
except:
if obj == "functions":
text = "Miscellaneous functions...\n\n"
text += "\nOverview:\n"
for o in OBJECTS_TREE["functions"]:
text += o + ": " + self.getDocFirstLine(o)
+ elif obj == "PyoGui":
+ text = PYOGUI_DOC
+ text += "\nOverview:\n"
+ for o in OBJECTS_TREE["PyoGui"]:
+ text += o + ": " + self.getDocFirstLine(o)
else:
text = "\nNot documented yet...\n\n"
if obj in OBJECTS_TREE["PyoObjectBase"]["PyoObject"].keys():
@@ -711,6 +725,8 @@ class ManualPanel(wx.Treebook):
filter = MAP_METHODS_FILTER
elif parentclass == "SLMap":
filter = SLMAP_METHODS_FILTER
+ elif parentclass == "wx.Panel":
+ 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]
diff --git a/utils/info.plist b/utils/info.plist
index 843e284..fd258f1 100644
--- a/utils/info.plist
+++ b/utils/info.plist
@@ -32,17 +32,17 @@
<key>CFBundleIdentifier</key>
<string>org.pythonmac.unspecified.E-Pyo</string>
<key>CFBundleInfoDictionaryVersion</key>
- <string>0.7.8</string>
+ <string>0.7.9</string>
<key>CFBundleName</key>
<string>E-Pyo</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>0.7.8</string>
+ <string>0.7.9</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>0.7.8</string>
+ <string>0.7.9</string>
<key>LSHasLocalizedDisplayName</key>
<false/>
<key>NSAppleScriptEnabled</key>
--
python-pyo packaging
More information about the pkg-multimedia-commits
mailing list