Меню

andipanda.dev

CaRadio: звук, навигационные подсказки и последние доработки первой версии

В предыдущих статьях я рассказал, как удалось запустить CarPlay на Raspberry Pi, добиться стабильного подключения телефона и реализовать сенсорное управление.

Но оставалась ещё одна важная часть любой автомобильной мультимедийной системы — звук.

На первый взгляд задача кажется простой: получить аудиоданные от Carlinkit и отправить их на звуковой выход. Однако на практике именно работа со звуком оказалась одной из самых трудоёмких частей разработки CaRadio.

Особенно когда дело дошло до навигационных подсказок.

Регулировка громкости, для которой не нашлось места

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

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

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

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

Там же предусмотрел возможность перезагрузить систему, если что-то пойдёт не так.

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

Один PCM5102 для всего звука

Для вывода звука в CaRadio я использовал ЦАП PCM5102.

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

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

Дело в том, что CarPlay передаёт разные типы звука отдельными потоками.

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

Поэтому пришлось реализовать программное микширование.

В результате несколько аудиопотоков объединялись и отправлялись на один ЦАП.

Но, как выяснилось, само микширование было далеко не самой сложной частью работы.

Когда навигатор начинает говорить

Представим обычную ситуацию.

В автомобиле играет музыка, водитель приближается к перекрёстку, и навигатор сообщает, куда нужно повернуть.

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

Именно такого поведения я хотел добиться в CaRadio.

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

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

Я не могу утверждать, какой из вариантов был правильным.

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

Пришлось искать собственный способ управления.

Таймер вместо точной информации от CarPlay

Основой решения стало отслеживание поступления аудиопотока навигационных подсказок.

Когда начинала поступать голосовая подсказка, CaRadio могла приглушить музыку, чтобы голос навигатора не терялся на её фоне.

Но возникала другая проблема: как определить, что подсказка действительно закончилась?

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

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

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

После прекращения поступления потока подсказки запускался таймер примерно на 300–500 миллисекунд.

Если за это время поступали новые аудиоданные, восстановление громкости откладывалось.

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

Решение получилось не идеальным, но на практике оказалось достаточно эффективным.

Самая неудобная отладка

Наверное, именно этот этап разработки запомнился мне больше всего.

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

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

Для полноценной проверки приходилось устанавливать CaRadio в автомобиль и отправляться в поездку с запущенной навигацией.

Если во время движения обнаруживалась проблема, я старался запомнить, при каких обстоятельствах она возникла.

После поездки приходилось снова снимать магнитолу, нести её домой, изменять код и повторять проверку.

И так много раз.

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

После очередного изменения приходилось снова проверять поведение системы в реальных условиях.

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

Не идеально, зато работает

Постепенно удалось подобрать поведение, при котором музыка и навигационные подсказки перестали мешать друг другу.

Конечно, я не могу назвать эту реализацию идеальной.

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

Но главное — система начала работать стабильно.

Музыка воспроизводится, навигационные подсказки слышны, а после их завершения громкость восстанавливается.

Для меня это был тот результат, которого я добивался.

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

Я хотел пользоваться собственной магнитолой каждый день.

Первая версия CaRadio

На этом, пожалуй, можно завершить рассказ о разработке первой версии CaRadio.

За время работы над ней пришлось решить немало задач: от запуска CarPlay через Carlinkit до обработки сенсорного ввода, управления питанием и воспроизведения звука.

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

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

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

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

И это, пожалуй, главное достижение первой версии CaRadio.

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