2013-07-03 12 views
6

Stworzyłem prosty tekstowy układ escape gry w Pythonie, z zamiarem osadzenia łatki Pure Data (via libPd) w celu odtworzenia innego pliku dźwiękowego (to zostanie później zastąpiony algorytmem dla muzyki generatywnej) dla każdego z moich różnych pokoi.Implementacja libPD (wrapper Pure Data) w Pythonie

Kod Pythona, z którym obecnie pracuję, został zaczerpnięty z jednego z przykładów w github libPD. To jest następująca -

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() 

Czysty łata dane po prostu odtwarza pre-renderowane wav, jednak Wynikiem brzmi prawie tak, jakby została bitcrushed. Zgaduję, że problem polega na rozmiarze bloku, ale nie jestem pewien.

Jeśli ktoś ma doświadczenie w osadzaniu lidPD w Pythonie, byłbym bardzo doceniony, ponieważ jestem pewien, że to, co próbuję osiągnąć, jest żenująco proste.

Dzięki z góry, Cap

Odpowiedz

3

skończyło się stosując obejście i importowane Pygame (w przeciwieństwie do pyaudio) do obsługi audio i inicjalizacji plastra. Działa bez żadnych problemów.

Dzięki za pomoc.

* Dla każdego, kto napotka podobny problem, sprawdź "pygame_test.py" w github libPd dla Pythona.

0

Istnieje kilka części do tego.

  1. Rozmiar bloku pliku audio jest błędne, ponieważ można ustawić TPB = 16 zamiast 1. Poprzez ustawienie go na 16 robicie rozmiar bloku 16 * 64 zamiast 64.

  2. Tam może być problemem z częstotliwością próbkowania. Czy jesteś pewien, że twój plik dźwiękowy ma pojemność 48 000 Hz, a nie 44100 Hz?

+0

Dzięki za odpowiedź Adama. Miałem wrażenie, że ustawiłem rozmiar bloku na 64 i ustawiając liczbę znaczników na bufor na 16, dałoby to 1024 ramki na bufor. Pierwotnie miałem ustawienie tpb na 1, ale "zgniatanie bitów" było nadal obecne. – CapricornOne

+0

Próbowałem również zarówno plików 44.1k i 48k podczas zmiany próbkowania w ramach kodu bez skutku. Myślę, że ma to coś wspólnego z paInt16, ponieważ zmiana go na paInt32 lub paInt8 zmienia w pewnym stopniu zgnieciony efekt, ale jak już powiedziałem, po prostu wyciągnąłem to z kodu przykładowego i nie wiem, co dokładnie powinien robić. – CapricornOne

+0

Próbowałem także innej trasy w postaci łaty puredata, która po prostu pomijała dźwięk sinusoidalny po wywołaniu w pythonie. Ten sam problem występuje. – CapricornOne

2

Miałem podobne problemy. Użycie wywołania zwrotnego naprawiło to za mnie.

Oto python, który odtwarza falę sinusoidalną.

 

    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() 

i łatka "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; 

+0

ładny. Powinien to być domyślny przykład dostarczony z pylibpd – Flint