早送りやディレイは音楽の波形データを時間軸上で伸縮させることにより実現できる。
縮ませると早く、引き伸ばすとゆっくり再生できる。
すでに音楽データを数値の配列として扱うことが出来ているわけだから、データ間を補間したり逆にデータを間引くことによりこれらを実現することができる。
試しにコーディングしてみた。
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 件のコメント:
コメントを投稿