Было бы здорово иногда иметь под рукой программу, которая в наше отсутствие может записывать звук со встроенного микрофона нашего ноутбука и передавать его по сети на другой наш компьютер.
А он, в свою очередь, смог бы воспроизводить этот звук в реальном времени.
Попробуем написать такую программу самостоятельно, тем более, что это, оказывается, не так уж и сложно.
Содержание:
- Описание
- Алгоритм записи и воспроизведения звука
- Установка необходимых библиотек
- Пишем сервер: запись звука
- Шаг 1. Получите удобный интерфейс для работы с аудиоподсистемой
- Шаг 2. Создайте буфер и привяжите его к аудиоустройству.
- Шаг 3. Чтение аудиопотока из аудиобуфера
- Представление аудиоданных
- Шаг 4. Закройте аудиобуфер и звуковую подсистему
- Создать сервер
- Пишем клиент
- сеть
- Сервер
- Клиент
- Давайте проверим, что произошло
- Закончить с файлом
- Полученные результаты
Описание
Что мы в конечном итоге хотим получить и какой алгоритм работы реализовать:- Сервер, работающий на машине, которую мы хотим прослушивать.
Он спокойно ждет, пока к нему подключится клиент. Затем он открывает аудиорекордер по умолчанию, настроенный в системе, и начинает передачу аудиопотока на клиентский компьютер.
Когда клиент отключается от сервера, аудиоустройство закрывается, чтобы избежать бесполезной траты ресурсов.
- Клиент, который подключается к серверу и начинает принимать аудиопоток и воспроизводить его в режиме реального времени.
Чтобы клиент корректно (в нужном формате) открыл устройство воспроизведения звука, он получает от сервера необходимую метаинформацию в сообщении Hello.
Единственное, что следует иметь в виду, это то, что не все устройства поддерживают одинаковые аудиоконфигурации.
Теоретически может оказаться, что сервер открыл устройство в каком-то формате, но звуковое устройство на клиентской машине этот формат просто не поддерживает. В этом случае необходимо использовать алгоритмы преобразования аудиопотоков, но эта информация не включена в данную статью.
Какие аудиоподсистемы будет поддерживать наша программа:
- АЛСА (Линукс)
- CoreAudio (macOS)
- DirectSound (Windows)
- ОСС (FreeBSD)
- ПульсАудио (Linux)
- ВАСАПИ (Windows)
Какие пакеты для 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 #интеллект #аудио
-
Твердая Валюта
19 Oct, 24 -
Измерительные Инструменты
19 Oct, 24 -
Adium: Icq Не Работает
19 Oct, 24 -
Nixp.conf/2011
19 Oct, 24 -
Д3?
19 Oct, 24