Wizard Notes

Python, JavaScript を使った音楽信号分析の技術録、作曲活動に関する雑記

PyAudio でリアルタイム再生録音・音加工(モノラル録音⇒ステレオ再生)の実装テンプレート

概要

Python で音声や音楽をリアルタイム再生・録音するライブラリとしてはPyAudioが良く知られています。

今回は、PyAudio を使って再生と録音を同時に行う方法を紹介します。

このサンプルコードを使うことで、ディレイやリバーブ、声質変換といった音声加工・エフェクトのようなアプリが簡単に構築できます。

f:id:Kurene:20191029191218p:plain
実装のイメージ

実装

実装のポイントとして、PyAudioでは入出力のチャネル数が同じであれば入出力ストリームを同時に開くことができます

一方で、入出力チャネルが違う場合は、ストリームを別々に開くことで対応できます。今回はこちらのパターンで実装しています。

import pyaudio
import numpy as np

RATE = 44100
CHUNK = 1024
CHANNEL_IN = 1
CHANNEL_OUT = 2

def signal_proc(input_buff, dtype=np.int16):
    # Convert framebuffer into nd-array
    input_data = np.fromstring(input_buff, dtype=dtype)
    
    # Signal processing
    # Set output as L-ch
    output_data = np.zeros((CHANNEL_OUT, CHUNK))
    output_data[0] = input_data

    # Convert nd-array into framebuffer
    output_data = np.reshape(output_data.T, (CHUNK * CHANNEL_OUT))
    output_buff = output_data.astype(dtype).tostring()
    return output_buff


p = pyaudio.PyAudio()

stream_in = p.open( 
        format=pyaudio.paInt16,
        channels=CHANNEL_IN,
        rate = RATE,
        frames_per_buffer=CHUNK,
        input = True,
        output = False,
    )

stream_out = p.open(    
        format=pyaudio.paInt16,
        channels=CHANNEL_OUT,
        rate=RATE,
        frames_per_buffer=CHUNK,
        input=False,
        output=True,
    )

while stream_in.is_active() and stream_out.is_active():
    input_buff = stream_in.read(CHUNK)
    output_buff = signal_proc(input_buff)
    stream_out.write(output_buff)
    
stream_in.stop_stream()
stream_in.close()
stream_out.stop_stream()
stream_out.close()
p.terminate()

実行環境