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/pcm/6-consumer/lessons/1-speech-recognition/pi-audio.md

8.9 KiB

Capture audio - Raspberry Pi

For dis part of di lesson, you go write code wey go capture audio for your Raspberry Pi. Di audio capture go dey control by one button.

Hardware

Raspberry Pi need one button to control di audio capture.

Di button wey you go use na Grove button. Dis one na digital sensor wey dey turn signal on or off. Di button fit configure to send high signal wen you press am, and low wen you no press am, or low wen you press am and high wen you no press am.

If you dey use ReSpeaker 2-Mics Pi HAT as microphone, you no need connect button because di hat don already get button. Just move go di next section.

Connect di button

Di button fit connect to di Grove base hat.

Task - connect di button

A grove button

  1. Put one end of Grove cable inside di socket for di button module. E go only enter one way.

  2. Wen di Raspberry Pi dey off, connect di other end of di Grove cable to di digital socket wey dem mark D5 for di Grove Base hat wey dey attach to di Pi. Dis socket na di second one from di left, for di row of sockets wey dey near di GPIO pins.

Di grove button wey connect to socket D5

Capture audio

You fit capture audio from di microphone using Python code.

Task - capture audio

  1. Power di Pi and wait make e boot.

  2. Open VS Code, either directly for di Pi, or connect am through di Remote SSH extension.

  3. Di PyAudio Pip package get functions to record and play back audio. Dis package dey depend on some audio libraries wey you need install first. Run di commands wey dey below for terminal to install dem:

    sudo apt update
    sudo apt install libportaudio0 libportaudio2 libportaudiocpp0 portaudio19-dev libasound2-plugins --yes 
    
  4. Install di PyAudio Pip package.

    pip3 install pyaudio
    
  5. Create new folder wey you go call smart-timer and add one file wey you go call app.py inside di folder.

  6. Add di imports wey dey below to di top of dis file:

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

    Dis one dey import di pyaudio module, some standard Python modules to handle wave files, and di grove.factory module to import Factory wey go create button class.

  7. Under dis one, add code to create Grove button.

    If you dey use di ReSpeaker 2-Mics Pi HAT, use dis code:

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

    Dis one dey create button for port D17, di port wey di button for di ReSpeaker 2-Mics Pi HAT dey connect to. Dis button dey set to send low signal wen you press am.

    If you no dey use di ReSpeaker 2-Mics Pi HAT, and you dey use Grove button wey connect to di base hat, use dis code.

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

    Dis one dey create button for port D5 wey dem set to send high signal wen you press am.

  8. Under dis one, create instance of di PyAudio class wey go handle audio:

    audio = pyaudio.PyAudio()
    
  9. Declare di hardware card number for di microphone and speaker. Dis one go be di number of di card wey you find wen you run arecord -l and aplay -l earlier for dis lesson.

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

    Replace <microphone card number> with di number of your microphone card.

    Replace <speaker card number> with di number of your speaker card, di same number wey you set for di alsa.conf file.

  10. Under dis one, declare di sample rate wey you go use for di audio capture and playback. You fit need change dis one depending on di hardware wey you dey use.

    rate = 48000 #48KHz
    

    If you dey get sample rate errors wen you dey run dis code later, change dis value to 44100 or 16000. Di higher di value, di better di sound quality.

  11. Under dis one, create new function wey you go call capture_audio. Dis one go dey called to capture audio from di microphone:

    def capture_audio():
    
  12. Inside dis function, add di code wey dey below to capture di audio:

    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()
    

    Dis code dey open audio input stream using di PyAudio object. Dis stream go capture audio from di microphone at 16KHz, dey capture am inside buffers wey be 4096 bytes in size.

    Di code go dey loop wen di Grove button dey pressed, dey read dis 4096 byte buffers into array each time.

    💁 You fit read more about di options wey dem pass to di open method for di PyAudio documentation.

    Wen di button release, di stream go stop and close.

  13. Add di code wey dey below to di end of dis function:

    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
    

    Dis code dey create binary buffer, and dey write all di captured audio to am as WAV file. Dis one na standard way to write uncompressed audio to file. Di buffer go then return.

  14. Add di play_audio function wey dey below to play back di audio buffer:

    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()
    

    Dis function dey open another audio stream, dis time for output - to play di audio. E dey use di same settings as di input stream. Di buffer go then open as wave file and write am to di output stream in 4096 byte chunks, dey play di audio. Di stream go then close.

  15. Add di code wey dey below di capture_audio function to loop until di button dey pressed. Wen di button dey pressed, di audio go capture, then play.

    while True:
        while not button.is_pressed():
            time.sleep(.1)
    
        buffer = capture_audio()
        play_audio(buffer)
    
  16. Run di code. Press di button and talk inside di microphone. Release di button wen you don finish, and you go hear di recording.

    You fit get some ALSA errors wen di PyAudio instance dey created. Dis one dey happen because of di configuration for di Pi for audio devices wey you no get. You fit ignore dis errors.

    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
    

    If you get dis error:

    OSError: [Errno -9997] Invalid sample rate
    

    then change di rate to either 44100 or 16000.

💁 You fit find dis code for di code-record/pi folder.

😀 Your audio recording program don work well!


Disclaimer:
Dis document don use AI translation service Co-op Translator take translate am. Even though we dey try make e accurate, abeg sabi say automated translations fit get mistake or no correct well. Di original document for di native language na di main correct source. For important information, e better make una use professional human translation. We no go fit take blame for any misunderstanding or wrong interpretation wey fit happen because of dis translation.