2010年9月26日日曜日

PyAudioで早送り再生とかディレイとか

PyAudioでwavファイルを早送り再生したりディレイで再生したりしてみた。

早送りやディレイは音楽の波形データを時間軸上で伸縮させることにより実現できる。
縮ませると早く、引き伸ばすとゆっくり再生できる。

すでに音楽データを数値の配列として扱うことが出来ているわけだから、データ間を補間したり逆にデータを間引くことによりこれらを実現することができる。

試しにコーディングしてみた。


def delay(inp,rate):
outp = []

for i in range(len(inp)):
for j in range(rate):
outp.append(inp[i])

return array(outp)

def fast(inp,rate):
outp = []

for i in range(len(inp) / rate):
outp.append(inp[i * rate])

return array(outp)



引数rateは何倍に遅くしたい(or早くしたい)かを決定するためのもの。

そのまま使うと整数倍でしか再生スピードを調整できないけど、二つを組み合わせると自在に変更可能(1.1倍再生ならfast(data,11)とdelay(data,10)の組み合わせ、とか)。

簡単なコードだけど試してみたら結構面白かった。
是非お試しあれ。

※追記:上の二つの関数を再生スピード変更関数として一元化、PyAudioでwav再生するプログラムを作ってみた。


from scipy import *
import pyaudio
import wave
import sys

def changePlaySpeed(inp,rate):
outp = []
for i in range(int(len(inp) / rate)):
outp.append(inp[int(i * float(rate))])
return array(outp)

chunk = 1024

wf = wave.open("hoge.wav", 'rb')

p = pyaudio.PyAudio()

# open stream
stream = p.open(format =
p.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = wf.getframerate(),
output = True)

# read data
data = wf.readframes(chunk)

# play stream
while data != '':
stream.write(data)
data = wf.readframes(chunk)
data = frombuffer(data,dtype = "int16")
if data != '':
data = changePlaySpeed(data,1.8)
data = int16(data).tostring()


stream.close()
p.terminate()



changePlaySpeed()の2番目の引数で再生スピードを変更できます(2.0だったら2倍速、0.5だったら半分のスピード)。

ゆっくり再生すると変な音が混ざった感じに聞こえる。
あまりイクナイ。

再生している音源が悪いのかしら?
データの補完方法に問題があるような気もするなぁ。

とりあえず試してみました、くらいの感覚で。

0 件のコメント:

コメントを投稿