audio
June 20, 2023

PyAudio

Вывод сигнала микрофона на экран

Вот пример кода, который открывает поток для записи звука с микрофона и выводит полученные цифровые данные на экран:

import pyaudio
import numpy as np

# настройки записи
FORMAT = pyaudio.paInt16 # формат звука
CHANNELS = 1 # количество каналов (моно)
RATE = 44100 # частота дискретизации
CHUNK = 1024 # размер блока записи

# создаем объект PyAudio
audio = pyaudio.PyAudio()

# открываем поток для записи звука
stream = audio.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    input=True,
                    frames_per_buffer=CHUNK)

print("Запись началась")

# читаем данные из потока, пока он не будет остановлен
while True:
    data = stream.read(CHUNK)
    # конвертируем байты в массив NumPy
    # используем dtype=int16 для корректного преобразования
    samples = np.frombuffer(data, dtype=np.int16)
    print(samples) # выводим значения на экран

# останавливаем поток записи
stream.stop_stream()
stream.close()
audio.terminate()

Этот код использует библиотеку PyAudio для открытия потока записи звука с микрофона и читает данные из потока в бесконечном цикле. Внутри цикла мы конвертируем полученные байты в массив NumPy и выводим его значения на экран. Вы можете использовать эти цифровые данные для анализа звука или обработки его с помощью программного обеспечения. Обратите внимание, что вы должны настроить соответствующую обработку данных в вашем коде, чтобы получить полезную информацию из потока звука.

Настройка устройства записи

В коде, который я дал, устройство по умолчанию выбирается для записи звука. Это обычно является первым доступным микрофоном на вашем компьютере.

Однако, если вы хотите использовать другое устройство для записи звука, вам нужно указать соответствующий идентификатор устройства при открытии потока записи звука.

Вы можете получить список доступных устройств для записи звука с помощью функции get_device_count() из библиотеки PyAudio, а затем распечатать информацию о каждом устройстве с помощью функций get_device_info_by_index() и get_default_input_device_info(). Вот пример кода:

import pyaudio

# создаем объект PyAudio
audio = pyaudio.PyAudio()

# получаем количество доступных устройств для записи звука
device_count = audio.get_device_count()

# выводим информацию об устройствах
for i in range(device_count):
    device_info = audio.get_device_info_by_index(i)
    print("Устройство #{}: {}".format(i, device_info["name"]))

# выводим информацию о текущем устройстве для записи звука
default_device_info = audio.get_default_input_device_info()
print("\nТекущее устройство для записи звука:", default_device_info["name"])

После выполнения этого кода вы получите список доступных устройств для записи звука и информацию о текущем устройстве по умолчанию. Вы можете использовать input_device_index параметр при открытии потока записи звука, чтобы указать нужное устройство для записи звука. Например, если вы хотите использовать устройство с индексом 1, вы можете изменить строку открытия потока записи звука на следующую:

pythonCopy Codestream = audio.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    input=True,
                    frames_per_buffer=CHUNK,
                    input_device_index=1)

Обратите внимание, что индексы устройств могут отличаться на разных компьютерах, поэтому вам необходимо выбрать правильный индекс для вашего конкретного устройства.

import tkinter as tk
import pyaudio
import numpy as np

class App:
    def __init__(self, master):
        self.master = master
        self.format = pyaudio.paInt16 # формат звука
        self.channels = 1 # количество каналов (моно)
        self.rate = 44100 # частота дискретизации
        self.chunk = 1024 # размер блока записи
        
        frame = tk.Frame(master)
        frame.pack()

        self.recording_button = tk.Button(frame, text="Запись", command=self.start_recording)
        self.recording_button.pack(side=tk.LEFT)

        self.stop_button = tk.Button(frame, text="Остановить", command=self.stop_recording)
        self.stop_button.pack(side=tk.LEFT)

    def start_recording(self):
        self.audio = pyaudio.PyAudio()
        self.stream = self.audio.open(format=self.format,
                        channels=self.channels,
                        rate=self.rate,
                        input=True,
                        frames_per_buffer=self.chunk)

        print("Запись началась")

        while True:
            data = self.stream.read(self.chunk)
            samples = np.frombuffer(data, dtype=np.int16)
            print(samples)

    def stop_recording(self):
        self.stream.stop_stream()
        self.stream.close()
        self.audio.terminate()

root = tk.Tk()
app = App(root)

root.mainloop()

Добавим GUI на PyQT5

Этот код довольно простой, но включает в себя использование нескольких библиотек и классов. Он позволяет записывать звук на ПК с помощью PyAudio и выводить его в консоль при условии, что кнопка "Запись" была нажата. Кнопка "Остановить" останавливает запись.

import sys
import numpy as np
import pyaudio
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton


class App(QMainWindow):
    def __init__(self):
        super().__init__()

        # Параметры записи звука
        self.format = pyaudio.PyAudio().get_format_from_width(2)  # Формат звука (16 бит)
        self.channels = 1  # Количество каналов (моно)
        self.rate = 44100  # Частота дискретизации
        self.chunk = 1024  # Размер блока записи

        # Создаем кнопки "Запись" и "Остановить"
        self.record_button = QPushButton('Запись', self)
        self.record_button.clicked.connect(self.start_recording)
        self.record_button.setGeometry(50, 50, 100, 50)

        self.stop_button = QPushButton('Остановить', self)
        self.stop_button.clicked.connect(self.stop_recording)
        self.stop_button.setGeometry(200, 50, 100, 50)

        self.is_recording = False  # Флаг, указывающий на состояние записи звука
        self.audio = pyaudio.PyAudio()  # Объект PyAudio для работы со звуком
        self.stream = None  # Объект потока записи звука

    def start_recording(self):
        if not self.is_recording:  # Если запись не происходит в настоящее время
            self.is_recording = True  # Устанавливаем флаг записи в состояние True
            self.stream = self.audio.open(format=self.format,  # Открываем поток записи звука с заданными параметрами
                                          channels=self.channels,
                                          rate=self.rate,
                                          input=True,
                                          frames_per_buffer=self.chunk)

            print("Запись началась")

            # Добавляем цикл обработки событий, чтобы приложение продолжало работать до закрытия окна
            while self.is_recording and self.stream.is_active():  # Добавляем проверку состояния потока записи звука
                QApplication.processEvents()

                if self.stream.get_read_available() >= self.chunk:  # Если доступно достаточно данных для чтения из потока
                    data = self.stream.read(self.chunk)  # Читаем данные из потока
                    samples = np.frombuffer(data, dtype=np.int16)  # Преобразуем байты в массив чисел
                    if self.is_recording:  # Проверяем состояние флага записи перед выводом данных в консоль
                        print(samples)  # Выводим данные на экран

            # Закрываем поток записи звука и освобождаем ресурсы PyAudio после завершения записи
            self.stream.stop_stream()
            self.stream.close()
            self.audio.terminate()

            print("Запись остановлена")
        else:
            print("Запись уже идет")

    def stop_recording(self):
        if self.is_recording:  # Если запись происходит в настоящее время
            self.is_recording = False  # Устанавливаем флаг записи в состояние False
        else:
            print("Запись уже остановлена")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    ex.setGeometry(100, 100, 350, 150)
    ex.show()
    sys.exit(app.exec_())

и не плохо бы автоматизировать установку зависимостей

import importlib
import subprocess

# Проверяем наличие библиотек
required_libraries = ['sys', 'numpy', 'pyaudio']
for library in required_libraries:
    try:
        importlib.import_module(library)
    except ImportError:
        print(f"Не найдена библиотека {library}. Установка...")
        subprocess.check_call(['pip', 'install', library])import importlib
import s'install', library])

С выводом

import sys
import numpy as np
import pyaudio
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QPlainTextEdit
class App(QMainWindow):
    def __init__(self):
        super().__init__()

        # Параметры записи звука
        self.format = pyaudio.PyAudio().get_format_from_width(2)  # Формат звука (16 бит)
        self.channels = 1  # Количество каналов (моно)
        self.rate = 44100  # Частота дискретизации
        self.chunk = 1024  # Размер блока записи

        # Создаем кнопки "Запись" и "Остановить"
        self.record_button = QPushButton('Запись', self)
        self.record_button.clicked.connect(self.start_recording)
        self.record_button.setGeometry(50, 50, 100, 50)

        self.stop_button = QPushButton('Остановить', self)
        self.stop_button.clicked.connect(self.stop_recording)
        self.stop_button.setGeometry(200, 50, 100, 50)

        # Создаем виджет для отображения текста
        self.text_edit = QPlainTextEdit(self)
        self.text_edit.setGeometry(50, 110, 250, 100)

        self.is_recording = False  # Флаг, указывающий на состояние записи звука
        self.audio = pyaudio.PyAudio()  # Объект PyAudio для работы со звуком
        self.stream = None  # Объект потока записи звука

    def start_recording(self):
        if not self.is_recording:  # Если запись не происходит в настоящее время
            self.is_recording = True  # Устанавливаем флаг записи в состояние True
            self.stream = self.audio.open(format=self.format,  # Открываем поток записи звука с заданными параметрами
                                          channels=self.channels,
                                          rate=self.rate,
                                          input=True,
                                          frames_per_buffer=self.chunk)

            self.text_edit.clear()  # Очищаем виджет перед началом записи
            self.text_edit.setPlainText("Запись началась")  # Выводим сообщение на экран

            while self.is_recording and self.stream.is_active():  # Добавляем проверку состояния потока записи звука
                QApplication.processEvents()

                if self.stream.get_read_available() >= self.chunk:  # Если доступно достаточно данных для чтения из потока
                    data = self.stream.read(self.chunk)  # Читаем данные из потока
                    samples = np.frombuffer(data, dtype=np.int16)  # Преобразуем байты в массив чисел
                    if self.is_recording:
                        self.text_edit.appendPlainText(str(samples))  # Выводим данные в виджет

            # Закрываем поток записи звука и освобождаем ресурсы PyAudio после завершения записи
            self.stream.stop_stream()
            self.stream.close()
            self.audio.terminate()

            self.text_edit.setPlainText("Запись остановлена")  # Выводим сообщение на экран
            self.is_recording = False

        else:
            self.text_edit.setPlainText("Запись уже идет")  # Выводим сообщение на экран

    def stop_recording(self):
        if self.is_recording:  # Если запись происходит в настоящее время
            self.is_recording = False
        else:
            self.text_edit.setPlainText("Запись уже остановлена")  # Выводим сообщение на экран


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    ex.setGeometry(100, 100, 350, 250)
    ex.show()
    sys.exit(app.exec_())