13 KiB
Захоплення аудіо - Raspberry Pi
У цій частині уроку ви напишете код для захоплення аудіо на вашому Raspberry Pi. Захоплення аудіо буде контролюватися кнопкою.
Апаратне забезпечення
Raspberry Pi потребує кнопки для управління захопленням аудіо.
Кнопка, яку ви будете використовувати, — це кнопка Grove. Це цифровий датчик, який вмикає або вимикає сигнал. Ці кнопки можна налаштувати так, щоб вони надсилали високий сигнал, коли кнопка натиснута, і низький, коли ні, або низький, коли натиснута, і високий, коли ні.
Якщо ви використовуєте мікрофон ReSpeaker 2-Mics Pi HAT, то немає потреби підключати кнопку, оскільки ця плата вже має вбудовану кнопку. Перейдіть до наступного розділу.
Підключення кнопки
Кнопку можна підключити до базової плати Grove.
Завдання - підключити кнопку
-
Вставте один кінець кабелю Grove у роз'єм на модулі кнопки. Він вставляється лише в одному напрямку.
-
З вимкненим Raspberry Pi підключіть інший кінець кабелю Grove до цифрового роз'єму, позначеного D5, на базовій платі Grove, підключеній до Pi. Цей роз'єм є другим зліва в ряду роз'ємів поруч із GPIO-пінами.
Захоплення аудіо
Ви можете захоплювати аудіо з мікрофона за допомогою коду на Python.
Завдання - захопити аудіо
-
Увімкніть Pi і дочекайтеся його завантаження.
-
Запустіть VS Code, або безпосередньо на Pi, або підключіться через розширення Remote SSH.
-
Пакет PyAudio Pip має функції для запису та відтворення аудіо. Цей пакет залежить від деяких аудіо-бібліотек, які потрібно встановити спочатку. Виконайте наступні команди в терміналі для їх встановлення:
sudo apt update sudo apt install libportaudio0 libportaudio2 libportaudiocpp0 portaudio19-dev libasound2-plugins --yes
-
Встановіть пакет PyAudio Pip.
pip3 install pyaudio
-
Створіть нову папку під назвою
smart-timer
і додайте файл під назвоюapp.py
до цієї папки. -
Додайте наступні імпорти на початку цього файлу:
import io import pyaudio import time import wave from grove.factory import Factory
Це імпортує модуль
pyaudio
, деякі стандартні модулі Python для роботи з wave-файлами, а також модульgrove.factory
для імпортуFactory
для створення класу кнопки. -
Нижче цього додайте код для створення кнопки Grove.
Якщо ви використовуєте ReSpeaker 2-Mics Pi HAT, використовуйте наступний код:
# The button on the ReSpeaker 2-Mics Pi HAT button = Factory.getButton("GPIO-LOW", 17)
Це створює кнопку на порту D17, порту, до якого підключена кнопка на ReSpeaker 2-Mics Pi HAT. Ця кнопка налаштована на надсилання низького сигналу при натисканні.
Якщо ви не використовуєте ReSpeaker 2-Mics Pi HAT, а використовуєте кнопку Grove, підключену до базової плати, використовуйте цей код:
button = Factory.getButton("GPIO-HIGH", 5)
Це створює кнопку на порту D5, яка налаштована на надсилання високого сигналу при натисканні.
-
Нижче цього створіть екземпляр класу PyAudio для роботи з аудіо:
audio = pyaudio.PyAudio()
-
Вкажіть номер апаратної карти для мікрофона та динаміка. Це буде номер карти, який ви знайшли, виконавши
arecord -l
іaplay -l
раніше в цьому уроці.microphone_card_number = <microphone card number> speaker_card_number = <speaker card number>
Замініть
<microphone card number>
на номер карти вашого мікрофона.Замініть
<speaker card number>
на номер карти вашого динаміка, той самий номер, який ви встановили у файліalsa.conf
. -
Нижче цього вкажіть частоту вибірки для захоплення та відтворення аудіо. Можливо, вам доведеться змінити це залежно від апаратного забезпечення, яке ви використовуєте.
rate = 48000 #48KHz
Якщо ви отримаєте помилки частоти вибірки під час виконання цього коду, змініть це значення на
44100
або16000
. Чим вище значення, тим краща якість звуку. -
Нижче цього створіть нову функцію під назвою
capture_audio
. Вона буде викликатися для захоплення аудіо з мікрофона:def capture_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()
Цей код відкриває аудіо-вхідний потік за допомогою об'єкта PyAudio. Цей потік буде захоплювати аудіо з мікрофона на частоті 16 кГц, захоплюючи його в буфери розміром 4096 байт.
Код потім циклічно працює, поки кнопка Grove натиснута, зчитуючи ці буфери розміром 4096 байт у масив кожного разу.
💁 Ви можете дізнатися більше про параметри, передані методу
open
, у документації PyAudio.Після того, як кнопка відпущена, потік зупиняється і закривається.
-
Додайте наступне в кінці цієї функції:
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-файл. Це стандартний спосіб запису незжатого аудіо у файл. Потім цей буфер повертається.
-
Додайте наступну функцію
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()
Ця функція відкриває інший аудіо-потік, цього разу для виводу - для відтворення аудіо. Вона використовує ті ж налаштування, що й вхідний потік. Буфер відкривається як wave-файл і записується у вихідний потік шматками по 4096 байт, відтворюючи аудіо. Потік потім закривається.
-
Додайте наступний код нижче функції
capture_audio
, щоб виконувати цикл до натискання кнопки. Після натискання кнопки аудіо захоплюється, а потім відтворюється.while True: while not button.is_pressed(): time.sleep(.1) buffer = capture_audio() play_audio(buffer)
-
Запустіть код. Натисніть кнопку і говоріть у мікрофон. Відпустіть кнопку, коли закінчите, і ви почуєте запис.
Ви можете отримати деякі помилки ALSA при створенні екземпляра PyAudio. Це пов'язано з конфігурацією на 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
тоді змініть
rate
на 44100 або 16000.
💁 Ви можете знайти цей код у папці code-record/pi.
😀 Ваша програма для запису аудіо була успішною!
Відмова від відповідальності:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу Co-op Translator. Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають у результаті використання цього перекладу.