You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
IoT-For-Beginners/translations/ja/6-consumer/lessons/1-speech-recognition/pi-audio.md

11 KiB

オーディオの録音 - Raspberry Pi

このレッスンでは、Raspberry Piでオーディオを録音するコードを書きます。オーディオ録音はボタンで制御されます。

ハードウェア

Raspberry Piには、オーディオ録音を制御するためのボタンが必要です。

使用するボタンはGroveボタンです。これは信号をオンまたはオフに切り替えるデジタルセンサーです。このボタンは、押されたときに高信号を送信し、押されていないときに低信号を送信するように設定できます。または、押されたときに低信号、押されていないときに高信号を送信するようにも設定できます。

もしReSpeaker 2-Mics Pi HATをマイクとして使用している場合、ボタンを接続する必要はありません。このHATにはすでにボタンが付いているため、次のセクションに進んでください。

ボタンを接続する

ボタンはGroveベースハットに接続できます。

タスク - ボタンを接続する

Groveボタン

  1. Groveケーブルの片方の端をボタンモジュールのソケットに差し込みます。このケーブルは一方向にしか差し込めません。

  2. Raspberry Piの電源をオフにした状態で、Groveケーブルのもう一方の端を、Piに接続されたGroveベースハットのデジタルソケットD5に接続します。このソケットは、GPIOピンの隣のソケット列の左から2番目にあります。

D5ソケットに接続されたGroveボタン

オーディオの録音

Pythonコードを使用してマイクからオーディオを録音できます。

タスク - オーディオを録音する

  1. Piの電源を入れ、起動を待ちます。

  2. VS Codeを起動します。Pi上で直接起動するか、Remote SSH拡張機能を使用して接続します。

  3. PyAudio Pipパッケージには、オーディオの録音と再生のための関数が含まれています。このパッケージは、いくつかのオーディオライブラリに依存しているため、まず以下のコマンドをターミナルで実行してこれらをインストールします。

    sudo apt update
    sudo apt install libportaudio0 libportaudio2 libportaudiocpp0 portaudio19-dev libasound2-plugins --yes 
    
  4. PyAudio Pipパッケージをインストールします。

    pip3 install pyaudio
    
  5. smart-timerという新しいフォルダを作成し、このフォルダにapp.pyというファイルを追加します。

  6. このファイルの先頭に以下のインポートを追加します。

    import io
    import pyaudio
    import time
    import wave
    
    from grove.factory import Factory
    

    これにより、pyaudioモジュール、WAVファイルを処理するための標準Pythonモジュール、およびgrove.factoryモジュールがインポートされ、ボタンクラスを作成するためのFactoryが使用可能になります。

  7. この下に、Groveボタンを作成するコードを追加します。

    ReSpeaker 2-Mics Pi HATを使用している場合は、以下のコードを使用します。

    # The button on the ReSpeaker 2-Mics Pi HAT
    button = Factory.getButton("GPIO-LOW", 17)
    

    これにより、ReSpeaker 2-Mics Pi HATに接続されたボタンポートD17)が作成されます。このボタンは、押されたときに低信号を送信するように設定されています。

    ReSpeaker 2-Mics Pi HATを使用していない場合で、Groveベースハットに接続されたGroveボタンを使用している場合は、以下のコードを使用します。

    button = Factory.getButton("GPIO-HIGH", 5)
    

    これにより、ポートD5に接続されたボタンが作成されます。このボタンは、押されたときに高信号を送信するように設定されています。

  8. この下に、オーディオを処理するためのPyAudioクラスのインスタンスを作成します。

    audio = pyaudio.PyAudio()
    
  9. マイクとスピーカーのハードウェアカード番号を宣言します。これは、このレッスンの前半でarecord -laplay -lを実行して確認した番号です。

    microphone_card_number = <microphone card number>
    speaker_card_number = <speaker card number>
    

    <microphone card number>をマイクのカード番号に置き換えます。

    <speaker card number>をスピーカーのカード番号に置き換えます。この番号はalsa.confファイルで設定した番号と同じです。

  10. この下に、オーディオ録音と再生に使用するサンプルレートを宣言します。使用しているハードウェアによって、この値を変更する必要がある場合があります。

    rate = 48000 #48KHz
    

    後でこのコードを実行した際にサンプルレートエラーが発生した場合、この値を44100または16000に変更してください。値が高いほど、音質が向上します。

  11. この下に、capture_audioという新しい関数を作成します。この関数は、マイクからオーディオを録音するために呼び出されます。

    def capture_audio():
    
  12. この関数内に、以下のコードを追加してオーディオを録音します。

    stream = audio.open(format = pyaudio.paInt16,
                        rate = rate,
                        channels = 1, 
                        input_device_index = microphone_card_number,
                        input = True,
                        frames_per_buffer = 4096)
    
    frames = []
    
    while button.is_pressed():
        frames.append(stream.read(4096))
    
    stream.stop_stream()
    stream.close()
    

    このコードは、PyAudioオブジェクトを使用してオーディオ入力ストリームを開きます。このストリームは、16KHzでマイクからオーディオを録音し、4096バイトのバッファサイズでキャプチャします。

    コードは、Groveボタンが押されている間ループし、4096バイトのバッファを毎回配列に読み込みます。

    💁 openメソッドに渡されるオプションの詳細については、PyAudioのドキュメントを参照してください。

    ボタンが離されたら、ストリームは停止して閉じられます。

  13. この関数の最後に以下を追加します。

    wav_buffer = io.BytesIO()
    with wave.open(wav_buffer, 'wb') as wavefile:
        wavefile.setnchannels(1)
        wavefile.setsampwidth(audio.get_sample_size(pyaudio.paInt16))
        wavefile.setframerate(rate)
        wavefile.writeframes(b''.join(frames))
        wav_buffer.seek(0)
    
    return wav_buffer
    

    このコードはバイナリバッファを作成し、キャプチャしたすべてのオーディオをWAVファイルとして書き込みます。これは、非圧縮オーディオをファイルに書き込む標準的な方法です。このバッファはその後返されます。

  14. オーディオバッファを再生するためのplay_audio関数を以下に追加します。

    def play_audio(buffer):
        stream = audio.open(format = pyaudio.paInt16,
                            rate = rate,
                            channels = 1,
                            output_device_index = speaker_card_number,
                            output = True)
    
        with wave.open(buffer, 'rb') as wf:
            data = wf.readframes(4096)
    
            while len(data) > 0:
                stream.write(data)
                data = wf.readframes(4096)
    
            stream.close()
    

    この関数は、出力用の別のオーディオストリームを開きます。このストリームは、入力ストリームと同じ設定を使用します。バッファはWAVファイルとして開かれ、4096バイトのチャンクで出力ストリームに書き込まれ、オーディオが再生されます。その後、ストリームは閉じられます。

  15. capture_audio関数の下に以下のコードを追加して、ボタンが押されるまでループします。ボタンが押されると、オーディオが録音され、その後再生されます。

    while True:
        while not button.is_pressed():
            time.sleep(.1)
    
        buffer = capture_audio()
        play_audio(buffer)
    
  16. コードを実行します。ボタンを押してマイクに向かって話します。話し終えたらボタンを離すと、録音が再生されます。

    PyAudioインスタンスが作成される際に、ALSAエラーが発生する場合があります。これは、Pi上で存在しないオーディオデバイスの設定が原因です。これらのエラーは無視して構いません。

    pi@raspberrypi:~/smart-timer $ python3 app.py 
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.front
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
    

    以下のエラーが発生した場合:

    OSError: [Errno -9997] Invalid sample rate
    

    rate44100または16000に変更してください。

💁 このコードはcode-record/piフォルダにあります。

😀 オーディオ録音プログラムが成功しました!

免責事項:
この文書は、AI翻訳サービス Co-op Translator を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知おきください。元の言語で記載された文書が公式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。