Я не ждал 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. Я сразу понял, что именно это я и искал:

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

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

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

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

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

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

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

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

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

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

Сборка


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

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

  1. Электронные компоненты фиксируются термосоплямиклеем.
  2. Неэлектронные компоненты (части корпуса) тоже фиксируются термоклеем, так как в чертежах отсутствуют крепления.
  3. Линии питания от блока питания до «звуковых» элементов и канал передачи звука между 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-дисплей с разрешением 128x32, все константы доступны в 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 без перекодирования.

<ezstream>
    <!-- Имя потока задается источником -->
    <url>http://192.168.88.3:8000/vexelstrom</url>
    <!-- Имя пользователя по умолчанию -->
    <sourceuser>source</sourceuser>
    <!-- Пароль в настройках Icecast2 для пользователя source -->
    <sourcepassword>hackme</sourcepassword>
    <!-- Формат -->
    <format>MP3</format>
    <!-- Файл-плейлист, относительный путь, но можно указать абсолютный -->
    <filename>playlist.m3u</filename>
    <!-- Воспроизвести один раз? 0 – крутить по кругу -->
    <stream_once>0</stream_once>
    <!-- Включить перемешивание? -->
    <shuffle>1</shuffle>
    <!--
      Информация о потоке. Если заполняете поля с битрейтом,
      то следите за правильностью информации, либо используйте
      перекодирование.
     -->
    <svrinfoname>89.3 RADIO VEXELSTROM</svrinfoname>
    <svrinfogenre>Alternative</svrinfogenre>
    <svrinfodescription>89.3 RADIO VEXELSTROM</svrinfodescription>
    <svrinfobitrate>128</svrinfobitrate>
    <svrinfochannels>2</svrinfochannels>
    <svrinfosamplerate>44100</svrinfosamplerate>
</ezstream>

Для запуска в консоли достаточно вызвать 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" 128x32,
  • модуль энкодера EC11,
  • динамики AIYIMA, 2 шт., 2 дюйма, 4 Ом, 10 Вт, 53 мм (aliexpress);
  • блок питания 5В 3А, штекер 5.5x2.5;
  • разъем питания 5.5х2.5 с клеммными колодками.

Если вам захочется сделать светящиеся линии как в оригинале, стоит познакомиться с электролюминесцентным проводом (EL-wire), который дает ровное и мягкое свечение. К сожалению, меня не устраивал писк инвертора для этого провода, поэтому от подсветки я отказался.

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

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

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

Комментарии (4)


  1. dmitryrf
    17.06.2022 13:02
    +5

    И ни одной крупной фотки готового радио.


    1. Firemoon Автор
      17.06.2022 14:53
      +8

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


      1. dmitryrf
        17.06.2022 15:16
        +2

        Так намного интереснее, спасибо!


  1. vladysss
    17.06.2022 13:02
    +1

    Не хватает только видео с опытом использования!