Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing libPD (Pure Data wrapper) in Python

I've created a simple text-based escape the room game in Python, with the intention of embedding a Pure Data patch (via libPd) in order to playback a different soundfile (this will later be replaced with an algorithm for generative music) for each of my different rooms.

The python code I'm currently working with was taken from one of the examples in the libPD github. It is as follows -

import pyaudio
import wave
import sys
from pylibpd import *

p = pyaudio.PyAudio()

ch = 2
sr = 48000
tpb = 16
bs = 64

stream = p.open(format = pyaudio.paInt16,
                channels = ch,
                rate = sr,
                input = True,
                output = True,
                frames_per_buffer = bs * tpb)

m = PdManager(ch, ch, sr, 1)
libpd_open_patch('wavfile.pd')

while 1:
    data = stream.read(bs)
    outp = m.process(data)
    stream.write(outp)

stream.close()
p.terminate()
libpd_release()

The pure data patch simply plays back a pre-rendered wav file, however the resulting output sounds almost as if it has been bitcrushed. I'm guessing the problem is to do with the block size but am not sure.

If anyone has experience in embedding lidPD within Python I'd be greatly appreciated as I'm sure what I'm trying to achieve is embarrassingly simple.

Thanks in advance, Cap

like image 564
CapricornOne Avatar asked Jul 03 '13 16:07

CapricornOne


2 Answers

I ended up using a workaround and imported pygame (as opposed to pyaudio) to handle the audio and initialise the patch. It works without a hitch.

Thanks for your help.

*For anyone that encounters a similar problem, check out "pygame_test.py" in the libPd github for python.

like image 179
CapricornOne Avatar answered Nov 20 '22 21:11

CapricornOne


I had similar problems. Using a callback fixed it for me.

Here is the python to play a sine wave.


    import pyaudio
    from pylibpd import *
    import time

    def callback(in_data,frame_count,time_info,status):
        outp = m.process(data)
        return (outp,pyaudio.paContinue)

    p  = pyaudio.PyAudio()
    bs = libpd_blocksize()

    stream = p.open(format = pyaudio.paInt16,
                    channels = 1,
                    rate = 44100,
                    input = False,
                    output = True,
                    frames_per_buffer = bs,
                    stream_callback=callback)

    m = PdManager(1, 1 , 44100, 1)

    libpd_open_patch('sine.pd')

    data=array.array('B',[0]*bs)

    while stream.is_active():
        time.sleep(.1)

    stream.close()
    p.terminate()
    libpd_release()

and the patch "sine.pd"


    #N canvas 647 301 450 300 10;
    #X obj 67 211 dac~;
    #X obj 24 126 osc~ 1000;
    #X obj 16 181 *~ 0.2;
    #X connect 1 0 2 0;
    #X connect 2 0 0 0;

like image 23
Paul John Leonard Avatar answered Nov 20 '22 23:11

Paul John Leonard