Делаем радио из Cyberpunk 2077

srrcqlj-ptyvmtk1p6yvb80nw00.png


Я не ждал Cyberpunk 2077 десять лет, я даже не смотрел презентации на Е3 и трейлеров, а переносы меня не огорчали — мой компьютер все равно не удовлетворял системным требованиям. Так уж произошло, что через два месяца после релиза я обновил компьютер, а друг подарил мне цифровую копию игры.

С первых часов я проникся миром игры, противоречивым и жестоким, но по-своему красивым и привлекательным. Я наиграл уже более двух сотен часов, разведал, кажется, каждый уголок, пока выход сюжетных DLC задерживается. Значит, есть время «перенести» технику из игры в реальную жизнь. Я давно хотел сделать интернет-радио…

Все описанное ниже — мое личное творчество, которым я занимался в свободное от работы в Selectel время. Официальное руководство по фан-контенту CD Projekt Red позволяет свободно творить по вселенным Cyberpunk 2077 и «Ведьмака», пока это не выставлено на продажу. Полный список используемых деталей и ссылки на ресурсы в конце статьи.


Эталон


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

xmyecxo6f-pzyuzzdggpufhvto8.png

Радио в квартире Ви

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

ba_emes5yh9cfddcv60mui-hury.pngПродвинутая версия

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

1lwwzmfiz7cx20azqvfx1umrxim.png

Версия 2023 года

Однако не стоит расстраиваться: радиоприемники встречаются в воспоминаниях Джонни Сильверхенда в 2023 году. В квесте «Красота не умирает» в клинике рипера Милта Наумана можно увидеть радио без «магических» дисплеев и подсветки. Далее по квесту в технических помещениях клуба «Атлантис» можно увидеть бумбокс-версию.

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

Маленькое красное радио покорило меня с первого взгляда. Значит, надо делать.

Моделирование корпуса


Следующий шаг в процессе воссоздания радио — моделирование корпуса. Это позволит оценить количество свободного места внутри устройства и в дальнейшем определиться с «начинкой».

В квесте «Стражи беспорядка» вам предстоит зайти на Джапан-Таун и допросить продавщицу на рынке. В этот момент она разбирает радио. Это единственная возможность увидеть радио изнутри, так как вне квеста устройство стоит собранным.


Я решил создать корпус самостоятельно, чтобы можно было легко адаптировать к технике, которая будет внутри. Для упрощения моделирования я немного схитрил. Все ресурсы игры спрятаны в нескольких объемных .archive-файлах. Помимо этого, не все ресурсы представлены в общеизвестных форматах. К счастью, существует инструмент WolvenKit, созданный для мододелов. Он позволяет распаковывать архивы и конвертировать ресурсы из проприетарных форматов в общеизвестные.

i5qjcouyo7ux7vpzkvzevln4mlc.png

Mesh-модель

Поиск радио занял некоторое время, так как искал в файлах что-то со словом radio. Но оказалось, что в терминах игры это электроника бедняков (poor_electronics — плохая электроника). Я экспортировал mesh-модель, загрузил в 3D-редактор и обнаружил, что модель «битая». Впрочем, она изначально была нужна для «срисовывания» основных пропорций, поэтому проблема незначительна.

Mesh-модель, как и скриншот из игры, не позволяет точно определить размер устройства. Но и тут есть решение. Вернемся в квартиру Ви. Рядом с радио стоит жестяная банка, визуально напоминающая банку на 500 мл. К счастью, у меня в холодильнике нашлась аналогичная банка, линейные размеры которой были измерены. Получилось, что радио должно быть 75 мм в ширину и 300 мм в длину.

Такие размеры чуть-чуть выходят за рамки области печати распространенных 3D-принтеров. Перспектива собирать из частей не радовала, поэтому я пропорционально уменьшил радио до 250 мм в длину.

ct3vrzwt_kla4a_900spttu9iim.png

Модель радио в Fusion360

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

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

Однако верхняя часть радио не бесполезна, над кнопками в модели есть панель неизвестного назначения. Хотя в эталоне отображение информации о станции производится поверх динамика, в реальности в эту неизвестную панель можно установить дисплей 128×32.

Отвлечемся от корпуса и обратимся к электронной составляющей радио.

А что внутри?


Изначально были мысли сделать радио технологичным минимальными действиями: купить дешевые колонки, разобрать их и поместить в корпус вместе с Raspberry Pi. Недостатки этого способа были фатальны:

  • колонки с питанием от USB микрокомпьютера «шипят»;
  • колонки с питанием от 220В добавляют второй шнур питания к радио;
  • колонки из дешевого ценового сегмента не отличаются качеством звука, а разбирать дорогие экономически нецелесообразно.


Цифровой шум и шипение колонок вынудили меня на время забросить проект. Лучиком надежды стал проект Wi-Fi-радио от AlexGyver. Я сразу понял, что именно это я и искал:

  1. ESP32 дешевле Raspberry Pi.
  2. Динамик на видео сравним по цене (1 000 руб. за пару) с готовыми колонками, которые есть у меня, но качество звука лучше.
  3. Мне не нужно погружаться в работу с программным обеспечением микроконтроллера.
  4. Автор замечал, что в схеме присутствует цифровой шум, но регулировкой громкости динамика и аккуратной пайкой его можно свести на нет.


g1_jh5ogqxxpyfhp_2h_4jdeqxc.png

Схема подключения компонентов радио (источник alexgyver.ru)

Я воспрял духом и пошел покупать все необходимые комплектующие будущего радио. Сначала я собрал схему на макетной плате без пайки. Цифровой шум был ужасен. Я пересобрал схему навесным монтажом, пропаял все соединения питания и передачи звука, но шум сохранился. Добавил электролитический конденсатор на 630 uF, но и это несильно помогло. Я решил убрать потенциометр, который выполняет функцию регулирования громкости, и чудо произошло: цифровой шум стих.

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

8hv8vnopebs-afdiblkiv0vmaau.png

Три модификации PAM8403

Решение пришло внезапно. Усилитель PAM8403 существует в трех версиях. Первая версия, минималистичная, представлена в оригинальном проекте. Две других же заслуживают внимания.

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

Третья же версия, с регулировкой громкости, лишена цифрового шума. Потенциометр можно настроить на комфортную максимальную громкость и спрятать схему внутри корпуса.

Что касается пинов MUTE и SHUTDOWN, подача на них логического нуля отключает усилитель. Это можно использовать, если вас раздражает даже совсем тихое шипение, когда радио отключено. У karadio32 есть пин для светодиода (status led), который светится, когда радио работает. На первой и третьей версии PAM8403 на печатной плате пины замкнуты на VDD, поэтому потребуется доработка «напильником». В этом поможет спецификация PAM8403.

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

Сборка


kjpu8b139lbfa3wkpxrciwpo8ju.png

Вид радио изнутри

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

  1. Электронные компоненты фиксируются термосоплямиклеем.
  2. Неэлектронные компоненты (части корпуса) тоже фиксируются термоклеем, так как в чертежах отсутствуют крепления.
  3. Линии питания от блока питания до «звуковых» элементов и канал передачи звука между VS1053 и усилителем должны быть пропаяны. Остальные линии могут быть соединены перемычками для прототипирования.


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

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

Настройка прошивки


kjcjlhso-3fbapbgse2287jbsew.png

Заполненные поля 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+.

8hm5xvpooct_rxglr_trcpl5ski.png

Далее все представленные команды актуальны для 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. Если эту строчку упустить, то источник может запуститься раньше ретранслятора, вывести ошибку и не завершиться. И сервис работает, и трансляции нет.

Ну вот, радио стоит и играет. Время подсчитать, сколько деталей ушло на проект.

r1h49l7ze_ughqoqyqcju_ayuwm.jpeg

Вот так радио выглядит вблизи

Исходники и затраты


Корпус печатался на 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), который дает ровное и мягкое свечение. К сожалению, меня не устраивал писк инвертора для этого провода, поэтому от подсветки я отказался.

Цены не указываю ввиду постоянных изменений в мире.

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

Расскажите в комментариях, какую вещь из любимой игры или фильма вы бы хотели воспроизвести? А может, вы уже это сделали? Поделитесь!

© Habrahabr.ru