Пишем Аудиоразведчик Своими Руками

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

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

Попробуем написать такую программу самостоятельно, тем более, что это, оказывается, не так уж и сложно.

Содержание:

  • Описание
  • Алгоритм записи и воспроизведения звука
  • Установка необходимых библиотек
  • Пишем сервер: запись звука
    • Шаг 1. Получите удобный интерфейс для работы с аудиоподсистемой
    • Шаг 2. Создайте буфер и привяжите его к аудиоустройству.

    • Шаг 3. Чтение аудиопотока из аудиобуфера
    • Представление аудиоданных
    • Шаг 4. Закройте аудиобуфер и звуковую подсистему
  • Создать сервер
  • Пишем клиент
  • сеть
    • Сервер
    • Клиент
  • Давайте проверим, что произошло
  • Закончить с файлом
  • Полученные результаты


Описание

Что мы в конечном итоге хотим получить и какой алгоритм работы реализовать:
  • Сервер, работающий на машине, которую мы хотим прослушивать.

    Он спокойно ждет, пока к нему подключится клиент. Затем он открывает аудиорекордер по умолчанию, настроенный в системе, и начинает передачу аудиопотока на клиентский компьютер.

    Когда клиент отключается от сервера, аудиоустройство закрывается, чтобы избежать бесполезной траты ресурсов.

  • Клиент, который подключается к серверу и начинает принимать аудиопоток и воспроизводить его в режиме реального времени.

    Чтобы клиент корректно (в нужном формате) открыл устройство воспроизведения звука, он получает от сервера необходимую метаинформацию в сообщении Hello.



Пишем аудиоразведчик своими руками

Единственное, что следует иметь в виду, это то, что не все устройства поддерживают одинаковые аудиоконфигурации.

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

Какие аудиоподсистемы будет поддерживать наша программа:

  • АЛСА (Линукс)
  • CoreAudio (macOS)
  • DirectSound (Windows)
  • ОСС (FreeBSD)
  • ПульсАудио (Linux)
  • ВАСАПИ (Windows)
Сервер и клиент будут кроссплатформенными и будут поддерживать Windows, Linux, FreeBSD и macOS. И само собой разумеется, что, например, сервер может работать на Windows, а клиентом для него будет программа для Linux, или как-то еще.

Какие пакеты для Linux потребуются (на примере Fedora):

  • libalsa-devel (для ALSA)
  • libpulse-devel (для PulseAudio)
Для других операционных систем ничего дополнительно устанавливать не нужно.



Алгоритм записи и воспроизведения звука

Прежде чем мы приступим к кодированию, я кратко объясню принцип работы со звуковой подсистемой.

Первым шагом является выбор звукового устройства.

В системе можно зарегистрировать несколько устройств.

Они делятся на 2 типа: устройства записи и воспроизведения.

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

Любая программа может через API звука определить количество таких устройств, их свойства, в т.ч.

иногда список всех аудиоформатов, поддерживаемых данным устройством.

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

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

Это создает и привязывает аудиобуфер к этому устройству.

Наиболее важными характеристиками здесь являются аудиоформат, а именно: ширина одного аудиосэмпла (обычно 16 или 24 бита), частота дискретизации (например, 44100 или 48000 Гц) и количество каналов.

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

Бывает и так, что устройство в данный момент занято другим системным процессом.

Это легко может произойти, например, в Linux, если мы попытаемся открыть устройство напрямую через ALSA, в то время как оно также используется системным процессом PulseAudio. Еще один важный параметр при открытии устройства — размер внутреннего аудиобуфера.

Чем меньше этот буфер, тем меньше задержка, что очень важно для некоторых приложений.

Просто нужно помнить, что маленький размер буфера увеличивает нагрузку на процессор, к тому же у каждого устройства есть свои внутренние ограничения по этому параметру.

Обычно для большинства приложений достаточно размера буфера 250 или 500 мс.

Открыв устройство, мы можем начать работу с аудиопотоком.

Конечно, если это звукозаписывающее устройство, то мы считываем с него данные; если это устройство воспроизведения, мы записываем на него данные.

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



Пишем аудиоразведчик своими руками

Но есть одна проблема: центральный процессор все время хочет бежать вперед, а вот звуковое устройство с данными работает ровно.

И здесь важно вовремя остановиться и подождать некоторое время, чтобы данные в кольцевом буфере не были повреждены.

В режиме записи, если мы вычли все доступные данные, то надо подождать, пока не станет доступен следующий кусок.

А в режиме воспроизведения, если буфер устройства заполнен на 100%, то надо дождаться, пока он опустеет. В режиме воспроизведения есть еще одна особенность - после того, как все доступные данные были успешно добавлены в звуковой буфер устройства, некорректно сразу закрывать используемое устройство, а нужно дождаться, пока оно закончит воспроизведение всех доступных данных.

.

Для этого в буфер добавляется тишина необходимой длины, и только теперь после одного оборота кольцевого буфера устройство можно закрыть.

Что ж, слишком много теории скучно, поэтому приступим к практике.



Установка необходимых библиотек

Скачайте или клонируйте с GitHub репозитории с нужными нам библиотеками:
   

git clone https://github.com/stsaz/ffbase git clone https://github.com/stsaz/ffaudio git clone https://github.com/stsaz/ffos

Для чего они нужны:
  • ffbase — здесь хранится набор вспомогательных функций и базовых алгоритмов для C; без этого программировать на C очень неудобно
  • ffaudio — библиотека для работы со звуком
  • ffos — чтобы нам было удобно писать кроссплатформенный код


Пишем сервер: запись звука



Шаг 1. Получаем удобный интерфейс для работы с аудиоподсистемой.

Т.

к.

мы используем кроссплатформенную библиотеку ffaudio, то о каких-то различиях между разными API здесь нам вообще думать не нужно.

Мы пишем код один раз, и он работает одинаково в любой конфигурации.

Сначала подключаем заголовок со всеми необходимыми интерфейсами и перечислениями: Теги: #Разработка для Linux #Разработка для Windows #Звук #программирование #C++ #si #интеллект #аудио

Вместе с данным постом часто просматривают: