Help me beta test a Python music system?

Hi all!

I’m still a ways off from a stable 1.0 of my python computer music system, but I have the opportunity to present it at a python conference this year and that seemed like a good excuse to try to focus on things like stability and documentation. :-p

Are there any python users hanging out here that would be willing to give it a try and help me out with some bug reports?

My goal is for this to be as easy to install, use and understand as other systems, but at this point you will probably need to at least be comfortable at the command line in a python environment to get things up and running.

Here’s the github repo: https://github.com/hecanjog/pippi

Here is the vastly out of date documentation: http://pippi.readthedocs.org

The version on Pypi is reasonably up to date but I’m in the midst of a bunch of fun updates regarding MIDI & OSC pattern sequencing that might be of interest to folks here so I’d recommend cloning the repo if you’d like to test.

I’ll write more about the system if there is interest but I just wanted to broach the subject here first!

Pippi is a crashy pile of duct tape in most ways, but I’ve been performing and recording with it nearly exclusively since around 2011 so it /is/ possible to make music with it, I promise. :slight_smile:

8 Likes

Is this still linux only?

Ah, thanks for pointing that out – I test and develop on linux, but there is a portaudio backend that could use some tire kicking on OSX and windows. Should only need to install portaudio / pyaudio.

So: no not linux-only! But cross-platform support badly needs testing since I don’t have OSX or windows setups myself!

I couldn’t use the published version on OS X 10.9.5 – “pip install pippi” failed with compilation errors. Cloning the repo and running “python setup.py install” (in a virtualenv) worked, though now I’m running into trouble that looks like this:

>>> from pippi import dsp
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pippi/dsp.py", line 41, in <module>
from pippi.timers import delay
File "pippi/timers.py", line 18, in <module>
librt = ctypes.CDLL('librt.so.1', use_errno=True)
File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 365, in __init__
self._handle = _dlopen(self._name, mode)
OSError: dlopen(librt.so.1, 6): image not found
>>>

I’ll let you know if I make it past this error. I’m using homebrew, FWIW.

1 Like

Awesome, this is super helpful!! I’m using a monotonic clock for timing but I totally forgot there’s a totally different API on OSX so I’ll start by falling back to the normal clock for now but adding monotonic support for OSX & windows is going on my todo list.

I’m cleaning up a few updates to the pattern sequencers but I’ll get this update in at some point today.

Just pushed a fallback for the monotonic clock to github.

I’ve also just added a simple interactive example to the readme: https://github.com/hecanjog/pippi#interactive-example

There are a million things to mention, but just regarding the example if you’re wondering about the way the scale sounds, pippi uses a set of ratios derived from Terry Riley’s piece Shri Camel by default.

To use plain old just intonation change the line creating the list of freqs to freqs = tune.fromdegrees([1,3,5,8], octave=3, root=key, ratios=tune.just)

There are other tuning systems built in and you can always just pass a list of ratios as tuples wherever the tune module accepts a ratios param.

Oh and for equal temperament there’s no shortcut, but I have an arbitrary EDO scale generator so you can get an equal tempered list of frequency ratios like this: tune.edoRatios(12)

Cool, thanks! I just pulled and reinstalled, and now see this:

>>> from pippi import dsp
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pippi/dsp.py", line 41, in <module>
from pippi.timers import delay
File "pippi/timers.py", line 34, in <module>
dsp.log('Monotonic clock disabled')
AttributeError: 'module' object has no attribute 'log'
>>>
1 Like

Whoops! I just pushed a fix for that a moment ago.

Thanks. Now I can run the examples and create .wav files, but they’re silent. Off to work soon, will take a look again this evening.

Hmmm. Might need to verify that the c extensions built & loaded correctly. When you have a chance could you look at the contents of pippi.log in your user directory? There may be some more clues there.

Thanks!

pippi.log just says “Monotonic clock disabled” –

Okay, that’s as expected since you’re using the fallback clock – did you see any errors when building the c extensions on installation? there will probably be a handful of warnings.

not totally sure how that would lead to silent renders though.

I just ran “pip uninstall pippi”, “python setup.py clean --all”, and “python setup.py install” again, and got these warnings, no errors:

clang -fno-strict-aliasing -fno-common -dynamic -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c src/pippi.c -o build/temp.macosx-10.9-x86_64-2.7/src/pippi.o
src/pippi.c:300:32: warning: variable 'indexWavetable' is uninitialized when used here [-Wuninitialized]
        cIndexWavetable = (int)indexWavetable % 1025; // Pad wtable with 1
                               ^~~~~~~~~~~~~~
src/pippi.c:286:26: note: initialize the variable 'indexWavetable' to silence this warning
    double indexWavetable, fracWavetable, valWavetable, valNextWavetable = 0;
                         ^
                          = 0.0
src/pippi.c:405:32: warning: variable 'indexWavetable' is uninitialized when used here [-Wuninitialized]
        cIndexWavetable = (int)indexWavetable % (1024 / chunk + 1); // Pad wtable with 1
                               ^~~~~~~~~~~~~~
src/pippi.c:378:26: note: initialize the variable 'indexWavetable' to silence this warning
    double indexWavetable, fracWavetable, valWavetable, valNextWavetable = 0;
                         ^
                          = 0.0
src/pippi.c:469:15: warning: unused variable 'right' [-Wunused-variable]
    int left, right;
              ^
src/pippi.c:469:9: warning: unused variable 'left' [-Wunused-variable]
    int left, right;
        ^
src/pippi.c:618:24: warning: unused variable 'inverted' [-Wunused-variable]
    int value, length, inverted;
                       ^
src/pippi.c:676:31: warning: variable 'indexWaveform' is uninitialized when used here [-Wuninitialized]
        cIndexWaveform = (int)indexWaveform % (lenWaveform - 1);
                              ^~~~~~~~~~~~~
src/pippi.c:656:25: note: initialize the variable 'indexWaveform' to silence this warning
    double indexWaveform, fracWaveform = 0;
                        ^
                         = 0.0
src/pippi.c:758:31: warning: variable 'indexWaveform' is uninitialized when used here [-Wuninitialized]
        cIndexWaveform = (int)indexWaveform % (lenWaveform - 1);
                              ^~~~~~~~~~~~~
src/pippi.c:723:25: note: initialize the variable 'indexWaveform' to silence this warning
    double indexWaveform, indexFactors = 0;
                        ^
                         = 0.0
src/pippi.c:885:31: warning: variable 'indexWaveform' is uninitialized when used here [-Wuninitialized]
        cIndexWaveform = (int)indexWaveform % (lenWaveform + paddingWaveform - 1);
                              ^~~~~~~~~~~~~
src/pippi.c:827:25: note: initialize the variable 'indexWaveform' to silence this warning
    double indexWaveform, fracWaveform = 0;
                        ^
                         = 0.0
src/pippi.c:886:29: warning: variable 'indexWindow' is uninitialized when used here [-Wuninitialized]
        cIndexWindow = (int)indexWindow % (lenWindow + paddingWindow - 1);
                            ^~~~~~~~~~~
src/pippi.c:830:23: note: initialize the variable 'indexWindow' to silence this warning
    double indexWindow, fracWindow = 0;
                      ^
                       = 0.0
src/pippi.c:887:26: warning: variable 'indexMod' is uninitialized when used here [-Wuninitialized]
        cIndexMod = (int)indexMod % (lenMod - 1);
                         ^~~~~~~~
src/pippi.c:833:20: note: initialize the variable 'indexMod' to silence this warning
    double indexMod, fracMod, modRange, freqMod, amp = 0;
                   ^
                    = 0.0
src/pippi.c:15:18: warning: unused variable 'PippiError' [-Wunused-variable]
static PyObject *PippiError;
                 ^
src/pippi.c:189:15: warning: unused function 'hermite' [-Wunused-function]
static double hermite(double x, double y0, double y1, double y2, double y3) {
              ^
src/pippi.c:198:15: warning: unused function 'get_double' [-Wunused-function]
static double get_double(int *input_buffer, int position) {
              ^
13 warnings generated.

Hm, okay thanks! Would you mind showing me the build log output? On my system:

building '_pippic' extension
creating build
creating build/temp.linux-x86_64-2.7
creating build/temp.linux-x86_64-2.7/src
gcc -pthread -fno-strict-aliasing -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -DNDEBUG -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fPIC -I/usr/include/python2.7 -c src/pippi.c -o build/temp.linux-x86_64-2.7/src/pippi.o
creating build/lib.linux-x86_64-2.7
gcc -pthread -shared -Wl,-O1,--sort-common,--as-needed,-z,relro build/temp.linux-x86_64-2.7/src/pippi.o -L/usr/lib -lpython2.7 -o build/lib.linux-x86_64-2.7/_pippic.so

Here goes, including the warnings again:

building '_pippic' extension
creating build/temp.macosx-10.9-x86_64-2.7
creating build/temp.macosx-10.9-x86_64-2.7/src
clang -fno-strict-aliasing -fno-common -dynamic -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c src/pippi.c -o build/temp.macosx-10.9-x86_64-2.7/src/pippi.o
src/pippi.c:300:32: warning: variable 'indexWavetable' is uninitialized when used here [-Wuninitialized]
        cIndexWavetable = (int)indexWavetable % 1025; // Pad wtable with 1
                               ^~~~~~~~~~~~~~
src/pippi.c:286:26: note: initialize the variable 'indexWavetable' to silence this warning
    double indexWavetable, fracWavetable, valWavetable, valNextWavetable = 0;
                         ^
                          = 0.0
src/pippi.c:405:32: warning: variable 'indexWavetable' is uninitialized when used here [-Wuninitialized]
        cIndexWavetable = (int)indexWavetable % (1024 / chunk + 1); // Pad wtable with 1
                               ^~~~~~~~~~~~~~
src/pippi.c:378:26: note: initialize the variable 'indexWavetable' to silence this warning
    double indexWavetable, fracWavetable, valWavetable, valNextWavetable = 0;
                         ^
                          = 0.0
src/pippi.c:469:15: warning: unused variable 'right' [-Wunused-variable]
    int left, right;
              ^
src/pippi.c:469:9: warning: unused variable 'left' [-Wunused-variable]
    int left, right;
        ^
src/pippi.c:618:24: warning: unused variable 'inverted' [-Wunused-variable]
    int value, length, inverted;
                       ^
src/pippi.c:676:31: warning: variable 'indexWaveform' is uninitialized when used here [-Wuninitialized]
        cIndexWaveform = (int)indexWaveform % (lenWaveform - 1);
                              ^~~~~~~~~~~~~
src/pippi.c:656:25: note: initialize the variable 'indexWaveform' to silence this warning
    double indexWaveform, fracWaveform = 0;
                        ^
                         = 0.0
src/pippi.c:758:31: warning: variable 'indexWaveform' is uninitialized when used here [-Wuninitialized]
        cIndexWaveform = (int)indexWaveform % (lenWaveform - 1);
                              ^~~~~~~~~~~~~
src/pippi.c:723:25: note: initialize the variable 'indexWaveform' to silence this warning
    double indexWaveform, indexFactors = 0;
                        ^
                         = 0.0
src/pippi.c:885:31: warning: variable 'indexWaveform' is uninitialized when used here [-Wuninitialized]
        cIndexWaveform = (int)indexWaveform % (lenWaveform + paddingWaveform - 1);
                              ^~~~~~~~~~~~~
src/pippi.c:827:25: note: initialize the variable 'indexWaveform' to silence this warning
    double indexWaveform, fracWaveform = 0;
                        ^
                         = 0.0
src/pippi.c:886:29: warning: variable 'indexWindow' is uninitialized when used here [-Wuninitialized]
        cIndexWindow = (int)indexWindow % (lenWindow + paddingWindow - 1);
                            ^~~~~~~~~~~
src/pippi.c:830:23: note: initialize the variable 'indexWindow' to silence this warning
    double indexWindow, fracWindow = 0;
                      ^
                       = 0.0
src/pippi.c:887:26: warning: variable 'indexMod' is uninitialized when used here [-Wuninitialized]
        cIndexMod = (int)indexMod % (lenMod - 1);
                         ^~~~~~~~
src/pippi.c:833:20: note: initialize the variable 'indexMod' to silence this warning
    double indexMod, fracMod, modRange, freqMod, amp = 0;
                   ^
                    = 0.0
src/pippi.c:15:18: warning: unused variable 'PippiError' [-Wunused-variable]
static PyObject *PippiError;
                 ^
src/pippi.c:189:15: warning: unused function 'hermite' [-Wunused-function]
static double hermite(double x, double y0, double y1, double y2, double y3) {
              ^
src/pippi.c:198:15: warning: unused function 'get_double' [-Wunused-function]
static double get_double(int *input_buffer, int position) {
              ^
13 warnings generated.
clang -bundle -undefined dynamic_lookup build/temp.macosx-10.9-x86_64-2.7/src/pippi.o -o build/lib.macosx-10.9-x86_64-2.7/_pippic.so

I (think I) just fixed most of the warnings clang was complaining about just in case.

Could you try running this and see if it produces silent audio too?

from pippi import dsp

freqs = [ dsp.rand(60, 1000) for _ in range(10) ]
length = dsp.stf(10)

layers = []

for freq in freqs:
    amp = dsp.rand(0.05, 0.1)
    speed = dsp.rand(0.1, 2)
    depth = dsp.rand(0, 0.03)
    pw = dsp.rand(0.3, 1)
    wf = dsp.wavetable('tri', 512)
    win = dsp.wavetable('sine', 512)
    mod = dsp.wavetable('random', 512)
    layer = dsp.pulsar(freq, length, pw, wf, win, mod, depth, speed, amp)
    layer = dsp.pan(layer, dsp.rand())

    layers += [ layer ]

out = dsp.mix(layers)

dsp.write(out, 'pulsar-test')

I pulled, rebuilt, and tried this, and it works! The two examples at https://github.com/hecanjog/pippi work too, now. Thanks! Looks like the three remaining warnings are not critical.

1 Like

Awesome! That’s great to hear – the only other big thing I’d be worried about testing on OSX would be streaming audio with portaudio. If you have a chance to try, would love to hear how it breaks!