音入力は何度か取り上げてきたが、今回Rasipi4でも安定してずーっと入出力出来るようになったので、まとめることとしました。
肝心なことは以下の参考1.のとおりです。なお、昨年は参考2.のようなことやって遊んでいました。
今年はこのあと少し違うことやろうと思っています。
【参考】
1.PyAudio Input overflowed
2.【Scipy】FFT、STFTとwavelet変換で遊んでみた♬~⑦リアルタイム・スペクトログラム;高速化
###肝心なこと
つまり、読み込むとき以下のおまじないを記載するとオーバーフローが発生しなくなり、延々記録できるようになりました.
※この記事はRasipi4でもこれが解決できたというお話です
# -*- coding:utf-8 -*-
import pyaudio
import matplotlib.pyplot as plt
import numpy as np
import wave
import struct
読み込んだ音を以下の関数でwavファイルで保存する。
def savewav(sig,sk):
RATE = 44100 #サンプリング周波数
#サイン波を-32768から32767の整数値に変換(signed 16bit pcmへ)
swav = [(int(32767*x)) for x in sig] #32767
#バイナリ化
binwave = struct.pack("h" * len(swav), *swav)
#サイン波をwavファイルとして書き出し
w = wave.Wave_write("./wine/"+str(sk)+".wav")
params = (1, 2, RATE, len(binwave), 'NONE', 'not compressed')
w.setparams(params)
w.writeframes(binwave)
w.close()
音の入出力をTrueにしています。
音声(センテンス)を入力するので、長め(102400/44100=2.3sec)に録音します。
RATE=44100
p=pyaudio.PyAudio()
N=100
CHUNK=1024*N
stream=p.open(format = pyaudio.paInt16,
channels = 1,
rate = RATE,
frames_per_buffer = CHUNK,
input = True,
output = True) # inputとoutputを同時にTrueにする
そしていよいよ連続録音開始です。exception_on_overflowをFalseにしています。sigを32768で除しています。
sk=0
while stream.is_active():
input = stream.read(CHUNK, exception_on_overflow = False)
print(len(input))
sig =[]
sig = np.frombuffer(input, dtype="int16") / 32768
savewav(sig,sk)
fig, (ax1,ax2) = plt.subplots(2,1,figsize=(1.6180 * 4, 4*2))
lns1=ax1.plot(sig[0:1024] ,".-",color="red")
ax1.set_xticks(np.linspace(0, 882, 3))
ax1.set_ylabel("sig0")
ax1.set_title('short plot')
lns2=ax2.plot(sig[0:CHUNK], "-",color="blue")
ax2.set_xticks(np.linspace(0, 44100*2, 5))
ax2.set_ylabel("sig1")
ax2.set_title('long plot')
ax1.grid()
ax2.grid()
plt.pause(0.5)
plt.savefig("./wine/sound_{}.png".format(sk))
plt.close()
sk+=1
output = stream.write(input)
あー、えー、いー。。の連続測定結果
x-軸のメモリ;44100=1sec
###まとめ
・連続測定が可能になった
・音関係でR-python連携をしたいと思う