Делаем радио из Cyberpunk 2077
Я не ждал Cyberpunk 2077 десять лет, я даже не смотрел презентации на Е3 и трейлеров, а переносы меня не огорчали — мой компьютер все равно не удовлетворял системным требованиям. Так уж произошло, что через два месяца после релиза я обновил компьютер, а друг подарил мне цифровую копию игры.
С первых часов я проникся миром игры, противоречивым и жестоким, но по-своему красивым и привлекательным. Я наиграл уже более двух сотен часов, разведал, кажется, каждый уголок, пока выход сюжетных DLC задерживается. Значит, есть время «перенести» технику из игры в реальную жизнь. Я давно хотел сделать интернет-радио…
Все описанное ниже — мое личное творчество, которым я занимался в свободное от работы в Selectel время. Официальное руководство по фан-контенту CD Projekt Red позволяет свободно творить по вселенным Cyberpunk 2077 и «Ведьмака», пока это не выставлено на продажу. Полный список используемых деталей и ссылки на ресурсы в конце статьи.
Эталон
Действия игры развиваются в 2077 году, а мир изобилует множеством невозможных на данных момент технических устройств. В мире, где возможно проецирование чувств непосредственно в кору головного мозга, возможны и более технически причудливые решения. Поэтому условимся, что наш эталон должен выдерживать грань между аутентичностью и количеством допущений, которые позволят сделать устройство с нашим развитием технологий.
Радио в квартире Ви
Все предыстории заканчиваются в одном месте: в квартире Ви. Там же на столе можно найти первое радио. Эта модель приемника встречается в игре не единожды, чаще на улицах, у банд на улицах и в домах не самых состоятельных людей. У этой модели есть «старший брат», который выглядит как бумбокс.
Продвинутая версия
Крупная версия радио больше подходит для улиц, а маленькая — для дома. Тем не менее, обе версии содержат недоступные нам технологии: отображение информации о текущей станции и визуализация звука осуществляется поверх акустических решеток динамиков, буквально в воздухе.
Версия 2023 года
Однако не стоит расстраиваться: радиоприемники встречаются в воспоминаниях Джонни Сильверхенда в 2023 году. В квесте «Красота не умирает» в клинике рипера Милта Наумана можно увидеть радио без «магических» дисплеев и подсветки. Далее по квесту в технических помещениях клуба «Атлантис» можно увидеть бумбокс-версию.
Взаимодействие с этими радиоприемниками отключено, а сами приборы выглядят безжизненно. Скорее всего это связано с нежеланием показывать игроку радиостанции 2023 года минимальными усилиями. Так даже лучше, светящиеся линии на корпусе — не самый простой трюк.
Маленькое красное радио покорило меня с первого взгляда. Значит, надо делать.
Моделирование корпуса
Следующий шаг в процессе воссоздания радио — моделирование корпуса. Это позволит оценить количество свободного места внутри устройства и в дальнейшем определиться с «начинкой».
В квесте «Стражи беспорядка» вам предстоит зайти на Джапан-Таун и допросить продавщицу на рынке. В этот момент она разбирает радио. Это единственная возможность увидеть радио изнутри, так как вне квеста устройство стоит собранным.
Я решил создать корпус самостоятельно, чтобы можно было легко адаптировать к технике, которая будет внутри. Для упрощения моделирования я немного схитрил. Все ресурсы игры спрятаны в нескольких объемных .archive-файлах. Помимо этого, не все ресурсы представлены в общеизвестных форматах. К счастью, существует инструмент WolvenKit, созданный для мододелов. Он позволяет распаковывать архивы и конвертировать ресурсы из проприетарных форматов в общеизвестные.
Mesh-модель
Поиск радио занял некоторое время, так как искал в файлах что-то со словом radio. Но оказалось, что в терминах игры это электроника бедняков (poor_electronics — плохая электроника). Я экспортировал mesh-модель, загрузил в 3D-редактор и обнаружил, что модель «битая». Впрочем, она изначально была нужна для «срисовывания» основных пропорций, поэтому проблема незначительна.
Mesh-модель, как и скриншот из игры, не позволяет точно определить размер устройства. Но и тут есть решение. Вернемся в квартиру Ви. Рядом с радио стоит жестяная банка, визуально напоминающая банку на 500 мл. К счастью, у меня в холодильнике нашлась аналогичная банка, линейные размеры которой были измерены. Получилось, что радио должно быть 75 мм в ширину и 300 мм в длину.
Такие размеры чуть-чуть выходят за рамки области печати распространенных 3D-принтеров. Перспектива собирать из частей не радовала, поэтому я пропорционально уменьшил радио до 250 мм в длину.
Модель радио в Fusion360
Не имея значительного опыта в моделировании, я потратил не один десяток часов на воссоздание модели и «подгон» под «железо» внутри. Для минимизации возможных недоработок я выбрал путь наименьшего сопротивления: первая версия должна просто изготавливаться, а все сложные улучшения можно сделать позже.
В результате единственным органом управления радио стала «крутилка» на передней панели радио, а кнопки сверху остались муляжом. Вместо акустической решетки — сплошная стенка и отверстие под динамик, что, впрочем, не мешает купить решетку отдельно и поместить на положенное место.
Однако верхняя часть радио не бесполезна, над кнопками в модели есть панель неизвестного назначения. Хотя в эталоне отображение информации о станции производится поверх динамика, в реальности в эту неизвестную панель можно установить дисплей 128×32.
Отвлечемся от корпуса и обратимся к электронной составляющей радио.
А что внутри?
Изначально были мысли сделать радио технологичным минимальными действиями: купить дешевые колонки, разобрать их и поместить в корпус вместе с Raspberry Pi. Недостатки этого способа были фатальны:
- колонки с питанием от USB микрокомпьютера «шипят»;
- колонки с питанием от 220В добавляют второй шнур питания к радио;
- колонки из дешевого ценового сегмента не отличаются качеством звука, а разбирать дорогие экономически нецелесообразно.
Цифровой шум и шипение колонок вынудили меня на время забросить проект. Лучиком надежды стал проект Wi-Fi-радио от AlexGyver. Я сразу понял, что именно это я и искал:
- ESP32 дешевле Raspberry Pi.
- Динамик на видео сравним по цене (1 000 руб. за пару) с готовыми колонками, которые есть у меня, но качество звука лучше.
- Мне не нужно погружаться в работу с программным обеспечением микроконтроллера.
- Автор замечал, что в схеме присутствует цифровой шум, но регулировкой громкости динамика и аккуратной пайкой его можно свести на нет.
Схема подключения компонентов радио (источник alexgyver.ru)
Я воспрял духом и пошел покупать все необходимые комплектующие будущего радио. Сначала я собрал схему на макетной плате без пайки. Цифровой шум был ужасен. Я пересобрал схему навесным монтажом, пропаял все соединения питания и передачи звука, но шум сохранился. Добавил электролитический конденсатор на 630 uF, но и это несильно помогло. Я решил убрать потенциометр, который выполняет функцию регулирования громкости, и чудо произошло: цифровой шум стих.
В лучших традициях шутках программирования я исправил одну проблему и создал две. Во-первых, усилитель работал на максимум и динамик шипел. Во-вторых, ПО микроконтроллера умеет управлять громкостью, и ставить ползунок больше 25% мне было страшно. Таким образом, я избавился от цифрового шума, но добавил раздражающее в тишине шипение и потенциальную возможность убить схему или динамик высокой громкостью в ПО.
Три модификации PAM8403
Решение пришло внезапно. Усилитель PAM8403 существует в трех версиях. Первая версия, минималистичная, представлена в оригинальном проекте. Две других же заслуживают внимания.
Вторая версия, которую я нашел в ближайшем магазине, имеет пины для прототипирования и потенциометр. По собственным ощущениям потенциометр плохо регулирует громкость, но, как и в самодельной версии, является источником цифрового шума. Интересной особенностью этого усилителя являются выведенные пины MUTE и SHUTDOWN, о них мы поговорим позднее.
Третья же версия, с регулировкой громкости, лишена цифрового шума. Потенциометр можно настроить на комфортную максимальную громкость и спрятать схему внутри корпуса.
Что касается пинов MUTE и SHUTDOWN, подача на них логического нуля отключает усилитель. Это можно использовать, если вас раздражает даже совсем тихое шипение, когда радио отключено. У karadio32 есть пин для светодиода (status led), который светится, когда радио работает. На первой и третьей версии PAM8403 на печатной плате пины замкнуты на VDD, поэтому потребуется доработка «напильником». В этом поможет спецификация PAM8403.
Когда определились с корпусом и внутренностями, время собирать.
Сборка
Вид радио изнутри
Признаюсь сразу, при сборке я не преследовал цели сделать внутри красиво, будто изделие только сошло с конвейера. Наоборот, я понимал несовершенство своих рук, недостаток опыта и осознавал, что начинка может быть изменена несколько раз, в том числе и после выхода этой статьи. Это привело к следующим решениям:
- Электронные компоненты фиксируются термосоплямиклеем.
- Неэлектронные компоненты (части корпуса) тоже фиксируются термоклеем, так как в чертежах отсутствуют крепления.
- Линии питания от блока питания до «звуковых» элементов и канал передачи звука между VS1053 и усилителем должны быть пропаяны. Остальные линии могут быть соединены перемычками для прототипирования.
В ходе сборки несколько раз выяснялось, что распечатанная модель чуть больше заложенного допуска и все необходимо печатать сначала.
Как отмечалось ранее, «доработок» по физической и программной части не предполагается, однако используемое ПО имеет множество функций, о которых стоит поговорить.
Настройка прошивки
Заполненные поля ESP32 download tool. Источник
На микроконтроллере используется прошивка karadio32. Для первого запуска достаточно скачать архив со страницы релизов и прошить, как указано в README проекта.
Обратите внимание на файл standard_adb.bin. В репозитории есть каталог, где лежит csv-версия этого и аналогичных файлов. Данный файл — это описание используемых функций ПО и соответствующих портов платы. По умолчанию (standard_adb.csv) можно подключить следующее оборудования:
- один энкодер для включения/выключения, смены громкости и станций,
- I2C-дисплей для отображения информации,
- инфракрасный датчик для управления с пульта,
- светодиод состояния.
Дополнительно, если хватит выводов GPIO, можно добавить:
- сенсорную панель экрана,
- второй энкодер,
- два джойстика для навигации по меню,
- шесть кнопок через цифровые порты,
- до шести кнопок через аналоговый порт (ADC keyboard),
- отдельную подсветку дисплея.
После первого запуска karadio32 создаст точку доступа Wi-Fi с именем «WifiKaRadio», а адрес микроконтроллера в сети — 192.168.4.1. В веб-интерфейсе можно выставить сетевые и звуковые настройки.
Помимо веб-интерфейса, karadio32 предоставляет доступ через telnet и последовательный порт. При этом текстовые интерфейсы предоставляют больше конфигурируемых параметров. Полный список доступен на соответствующей странице, а я перечислю лишь действительно необходимые при первом запуске:
- sys.lcd (»6») — параметр обозначает LED-дисплей с разрешением 128×32, все константы доступны в addon.h;
- sys.lcdout (»20») — дисплей выключается через 20 секунд без команд;
- sys.ddmm (»1») — выбрать формат даты DD/MM.
Теперь можно подключаться к интернет-радиостанциям и слушать музыку. Но что если хочется запустить в эфир свою музыку?
Домашняя радиостанция
Когда хочется слушать музыку по своему вкусу, возникает потребность создать собственную радиостанцию. Как оказалось, это не самое простое дело. Для создания источника интернет-радио нужен сервис потоковой передачи аудио — Icecast2.
Icecast — это своеобразный ретранслятор. Источник (source) передает трансляцию серверу, а тот «раздает» желающим клиентам. В идеале ретранслятор должен быть размещен на мощном сервере, чтобы обслуживать большое количество параллельных подключений. На практике же для домашней трансляции хватило одной Raspberry Pi 3B+.
Далее все представленные команды актуальны для Raspbian 10. Устанавливаем Icecast:
sudo apt install icecast2
Интерактивная установка поможет задать адрес сервера и пароли для администратора и источника. Сервис запустится сам. Проверить состояние сервиса можно с помощью веб-интерфейса по адресу, который был задан в настройках. В моем случае:
http://192.168.88.3:8000/
При установке через пакетный менеджер Icecast2 устанавливается как сервис, так что перезагрузки не страшны. Интерактивный установщик попросит IP-адрес и пароли, но если их необходимо поменять, то конфигурационный файл ретранслятора располагается по пути /etc/icecast2/icecast.xml.
После настройки ретранслятора можно переходить к настройке источника. Для отправки данных на ретранслятор можно использовать любую программу, которая умеет работать с протоколом shoutcast. Я безуспешно попробовал IceS, VLC и python-shout.
Первым был IceS от создателей Icecast, но актуальная версия не поддерживает вещание из mp3-файлов, а старую версию нужно еще поискать. VLC потребовал вдумчивой настройки, трансляция даже запускалась через браузер, но karadio32 отказывался проигрывать такую станцию. Я совсем отчаялся и даже попытался взять пример для python-shout, но код умудрялся отправить пять минут аудио за секунду, что было неприемлемо для приемников.
Действительно простым и эффективным решением стала утилита ezstream. Эта программа не только работает с mp3, но и умеет перекодировать файлы в желаемый формат «на лету». Для утилиты нужен плейлист и файл конфигурации. Плейлист создается буквально в одну строчку:
ls *.mp3 > playlist.m3u
Примеры файлов конфигурации доступны по пути /usr/share/doc/ezstream/examples/ezstream*. Рассмотрим файл конфигурации для трансляции mp3 без перекодирования.
http://192.168.88.3:8000/vexelstrom
source
hackme
MP3
playlist.m3u
0
1
89.3 RADIO VEXELSTROM
Alternative
89.3 RADIO VEXELSTROM
128
2
44100
Для запуска в консоли достаточно вызвать ezstream с указанием на созданный файл конфигурации:
ezstream -c ezstream_mp3.xml
Так как ретранслятор работает как сервис, то и источник необходимо сделать сервисом. Создаем systemd-юнит с именем ezstream.service в каталоге /etc/systemd/system со следующим содержанием:
[Unit]
Description=EzStream Unit
After=syslog.target
After=network.target
After=icecast2.service
[Service]
Type=simple
WorkingDirectory=/home/pi/cp2077
User=pi
Group=pi
ExecStart=/usr/bin/ezstream -c /home/pi/cp2077/ezstream_mp3.xml
TimeoutSec=300
[Install]
WantedBy=multi-user.target
Обновляем список сервисов и запускаем источник:
sudo systemctl daemon-reload
sudo systemctl start ezstream
Конечно, не идеальный юнит, но самое важное в нем — запуск после icecast2.service. Если эту строчку упустить, то источник может запуститься раньше ретранслятора, вывести ошибку и не завершиться. И сервис работает, и трансляции нет.
Ну вот, радио стоит и играет. Время подсчитать, сколько деталей ушло на проект.
Вот так радио выглядит вблизи
Исходники и затраты
Корпус печатался на Flyingbear Ghost 5, PLA-пластиком, толщина слоя 0.32 мм, скорость печати 60 мм/с, для стенок — 30 мм/с. Заполнение 20%.
Модели (ссылка на stl-файлы):
- основа корпуса — 11 часов;
- верхняя крышка — 2 часа;
- задняя крышка — 1,5 часа;
- ручка — 30 минут.
Слайдер не был сделан ввиду отсутствия линейного потенциометра подходящего размера, а отверстие для мини-динамика справа осталось не прикрытым. Суммарно, включая все неуспешные попытки, мне хватило килограммовой катушки красного пластика и ста грамм серого пластика.
Электроника:
- микроконтроллер ESP-WROOM-32 DevKit v1,
- модуль VS1053,
- усилитель PAM8403,
- OLED-дисплей 0.91» 128×32,
- модуль энкодера EC11,
- динамики AIYIMA, 2 шт., 2 дюйма, 4 Ом, 10 Вт, 53 мм (aliexpress);
- блок питания 5В 3А, штекер 5.5×2.5;
- разъем питания 5.5×2.5 с клеммными колодками.
Если вам захочется сделать светящиеся линии как в оригинале, стоит познакомиться с электролюминесцентным проводом (EL-wire), который дает ровное и мягкое свечение. К сожалению, меня не устраивал писк инвертора для этого провода, поэтому от подсветки я отказался.
Цены не указываю ввиду постоянных изменений в мире.
На создание радио ушло более двух месяцев, в течение которых я получил увлекательный опыт и создал себе объект из понравившейся игровой вселенной.
Расскажите в комментариях, какую вещь из любимой игры или фильма вы бы хотели воспроизвести? А может, вы уже это сделали? Поделитесь!