Translate

2022年4月6日水曜日

Raspberry Pi に接続したUSBマイクからの音声入力をpyaudioで操作する

Raspberry Piで音声を入力としたシステムを組もうとしたが、 音声出力用ジャックコネクタはあるけどマイクがないことにきづいた。

なのでUSBコネクタに「Sound Blaster Play! 3」をさしてコネクタにピンマイクをつけてみた。

このピンマイクから音声入力するとき、どうやってデバイスを認識するのか、ちょっとしらべてみた。

ここでの前提は Python プログラムで、とする。

まずPythonからこのマイクの入力を操作するには pyaudio パッケージがあるのでこれをインストールする。

ただし pyaudio は portaudio というライブラリを使っているらしいので先にapt-getしておく必要がある。

sudo apt install libportaudio0 libportaudio2 libportaudiocpp0 portaudio19-dev
pip install pyaudio


pyaudio でマイクデバイスを指定するには input_device_index が必要になる。

なので Raspberry Pi にSound Blaster Play! 3を刺して以下のコードを実行する。

import pyaudio
audio = pyaudio.PyAudio()
for i in range(audio.get_device_count()):
    print(audio.get_device_info_by_index(i))

するとずらずらっと、USB接続されたデバイスが表示される。以下実行例:

{'index': 0, 'structVersion': 2, 'name': 'bcm2835 Headphones: - (hw:0,0)', 'hostApi': 0, 'maxInputChannels': 0, 'maxOutputChannels': 8, 'defaultLowInputLatency': -1.0, 'defaultLowOutputLatency': 0.0016099773242630386, 'defaultHighInputLatency': -1.0, 'defaultHighOutputLatency': 0.034829931972789115, 'defaultSampleRate': 44100.0}
{'index': 1, 'structVersion': 2, 'name': 'Sound Blaster Play! 3: USB Audio (hw:1,0)', 'hostApi': 0, 'maxInputChannels': 2, 'maxOutputChannels': 2, 'defaultLowInputLatency': 0.008684807256235827, 'defaultLowOutputLatency': 0.008684807256235827, 'defaultHighInputLatency': 0.034829931972789115, 'defaultHighOutputLatency': 0.034829931972789115, 'defaultSampleRate': 44100.0}
:


上記の例だと、index1であるデバイスに「Sound Blaster Play! 3: USB Audio (hw:1,0)」とあるので、input_device_index1を指定すれば良い。

あとはいろんなブログ記事に乗っかっているサンプルを少し加工して実行してやれば良い。

import pyaudio
import wave
import sys
import time
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
CHUNK = 2**11
MIC_INDEX = 1 # ここに指定
RECORD_SECONDS = 5 # 録音秒数

try:
    WAVE_FILE = sys.argv[1]
except:
    print('no output file name')
    sys.exit(1)

audio = pyaudio.PyAudio()

frames = []

def callback(in_data, frame_count, time_info, status):
    frames.append(in_data)
    return(None, pyaudio.paContinue)
stream = audio.open(
    format=FORMAT,
    channels=CHANNELS,
    rate=RATE,
    input=True,
    input_device_index=MIC_INDEX,
    frames_per_buffer=CHUNK,
    start=False,
    stream_callback=callback
)

if __name__ == '__main__':
    stream.start_stream()
    time.sleep(RECORD_SECONDS)
    stream.stop_stream()
    stream.close()
    audio.terminate()
    wf = wave.open(WAVE_FILE, 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(audio.get_sample_size(FORMAT))
    wf.setframerate(RATE)
    wf.writeframes(b''.join(frames))
    wf.close()



マイクに「あー」といいながら以下のコマンドが終了するまでいいつづける。

python sample.py ah.wav


できあがったah.wavを再生し録音できていればOK。

 

#一応、Pi4/Bullseye 64bit で動作確認しました

0 件のコメント:

AWS Glueジョブ(Python/Spark)にPythonパッケージを追加する方法

 AWS Glueジョブには2つの種類が存在します。 ETLジョブ(Spark) PySparkコードが実行できるジョブ。 最低でも10並列で実行するので、DynamicFrame/DataFrame操作以外の処理はPython Shellジョブを使ったほうがよい。 Python...