web-dev-qa-db-ja.com

pythonを使用したリアルタイムオーディオ信号処理

Pythonで「pyAudio」モジュールを使用してリアルタイムのオーディオ信号処理を実行しようとしています。私が行ったのは、マイクからオーディオデータを読み取り、ヘッドフォンで再生するという単純なケースでした。私は次のコードを試してみました(PythonとCythonバージョンの両方)。それは機能すると思いますが、残念ながらそれはストールしていて十分にスムーズではありません。スムーズに実行できるようにコードを改善するにはどうすればよいですか。My PCはi7、8GB RAMです。

Pythonバージョン

import pyaudio
import numpy as np

RATE    = 16000
CHUNK   = 256

p               =   pyaudio.PyAudio()

player = p.open(format=pyaudio.Paint16, channels=1, rate=RATE, output=True, 
frames_per_buffer=CHUNK)
stream = p.open(format=pyaudio.Paint16, channels=1, rate=RATE, input=True, frames_per_buffer=CHUNK)

for i in range(int(20*RATE/CHUNK)): #do this for 10 seconds
player.write(np.fromstring(stream.read(CHUNK),dtype=np.int16))
stream.stop_stream()
stream.close()
p.terminate()

Cythonバージョン

import pyaudio
import numpy as np

cdef int RATE   = 16000
cdef int CHUNK  = 1024
cdef int i      
p               =   pyaudio.PyAudio()

player = p.open(format=pyaudio.Paint16, channels=1, rate=RATE, output=True, frames_per_buffer=CHUNK)
stream = p.open(format=pyaudio.Paint16, channels=1, rate=RATE, input=True, frames_per_buffer=CHUNK)

for i in range(500): #do this for 10 seconds
    player.write(np.fromstring(stream.read(CHUNK),dtype=np.int16))
stream.stop_stream()
stream.close()
p.terminate()
6
SAJIL C K

player.write呼び出しの2番目の引数としてCHUNKがないと思います。

player.write(np.fromstring(stream.read(CHUNK),dtype=np.int16),CHUNK)

また、フォーマットエラーかどうかは不明です。ただし、player.writeforループにタブで移動する必要があります

そして pyaudioサイト ごとにRATE / CHUNK * RECORD_SECONDSではなくRECORD *RATE/CHUNKが必要です。python*除算の前に/乗算を実行するためです。

for i in range(int(20*RATE/CHUNK)): #do this for 10 seconds
    player.write(np.fromstring(stream.read(CHUNK),dtype=np.int16),CHUNK)

stream.stop_stream()
stream.close()
p.terminate()

最後に、忠実度を高めるために、rate44100に、CHUNK1024に、CHANNEL2に増やすことができます。

2
Anil_M

私は同様のプロジェクトに取り組んでいます。私はあなたのコードを修正しました、そして、屋台は今なくなっています。チャンクが大きければ大きいほど、遅延も大きくなります。それが私がそれを低く保った理由です。

import pyaudio
import numpy as np

CHUNK = 2**5
RATE = 44100
LEN = 10

p = pyaudio.PyAudio()

stream = p.open(format=pyaudio.Paint16, channels=1, rate=RATE, input=True, frames_per_buffer=CHUNK)
player = p.open(format=pyaudio.Paint16, channels=1, rate=RATE, output=True, frames_per_buffer=CHUNK)


for i in range(int(LEN*RATE/CHUNK)): #go for a LEN seconds
    data = np.fromstring(stream.read(CHUNK),dtype=np.int16)
    player.write(data,CHUNK)


stream.stop_stream()
stream.close()
p.terminate()
1
Ra'w

以下のコードは、デフォルトの入力デバイスを取り、記録されたものをデフォルトの出力デバイスに出力します。

_import PyAudio
import numpy as np

p = pyaudio.PyAudio()

CHANNELS = 2
RATE = 44100

def callback(in_data, frame_count, time_info, flag):
    # using Numpy to convert to array for processing
    # audio_data = np.fromstring(in_data, dtype=np.float32)
    return in_data, pyaudio.paContinue

stream = p.open(format=pyaudio.paFloat32,
                channels=CHANNELS,
                rate=RATE,
                output=True,
                input=True,
                stream_callback=callback)

stream.start_stream()

while stream.is_active():
    time.sleep(20)
    stream.stop_stream()
    print("Stream is stopped")

stream.close()

p.terminate()
_

これは20秒間実行されて停止します。メソッドコールバックは、信号を処理できる場所です:audio_data = np.fromstring(in_data, dtype=np.float32)

_return in_data_は、後処理されたデータを出力デバイスに送り返す場所です。

PyAudioのドキュメントに記載されているように、チャンクのデフォルト引数は1024であることに注意してください。 http://people.csail.mit.edu/hubert/pyaudio/docs/#pyaudio.PyAudio.open

1
kckaiwei