В начале целью этого домашнего проекта было создание интернет-радиоприемника из Raspberry Pi. Мне хотелось найти или восстановить какой-нибудь старый деревянный приемник, или, хотя бы, корпус, поставить туда Raspberry, аккумулятор, блэкджек, и чтобы он раздавал вайфай. Из-за нехватки времени все это было благополучно отложено в долгий ящик, но, может быть, со временем реализую. Зато сделал программную часть проекта, о которой и хочу рассказать.
Делать старое радио, чтобы из него звучали кристально чистые современные битрейты – не комильфо, на мой взгляд. То есть, пусть они тоже звучат, но для меня было бы вдвойне приятно из старого радио слышать аутентичный звук тех времен, когда ещё не было импульсных преобразователей, а по улицам беспечно разгуливали единороги. Рецепт, как состарить звук я представляю себе так:
- 1...10 мкВ полезного сигнала,
- 0.3 мкВ эха, той же передачи на той же частоте, но из другого места,
- 0.2 мкВ сигнала другой станции, вещающей на той же частоте,
- капля интерференционного свиста, больше не надо, ибо напрягает,
- 0.1 мкВ шума входных цепей,
- секретный ингредиент – фединги, то есть замирания всех перечисленных сигналов, кроме шума входных цепей, они сделают своё дело вместе с АРУ – автоматической регулировкой услиения, в результате чего один из фоновых сигналов периодически будет выходить на передний план, как это бывает в настоящем радио,
- ну и по вкусу срезать верхние частоты.
Подразумевается, что радио работает на средних волнах, время вечернее, и сигнал проходит далеко. Список можно продолжить до бесконечности, но ресурсы у малинки ограничены, а хочется запустить много потоков и переключаться между ними. Поэтому ограничился выше перечисленным. Оформил все это в виде сервера на основе Icecast и ряда других полезных утилит. Этот сервер помогает мне создать праздничную атмосферу в новогодние праздники. Возможно, пригодится кому-нибудь ещё.
Принцип работы сервера такой: два входных аудиопотока, взятых из интернета, конвертируются в wav при помощи ffmpeg, здесь же снижается частота оцифровки, для того, чтобы убрать верхние частоты, а также облегчить работу процессору.
Далее потоки проходят через импровизированный звуковой процессор, написанный на си. Прошу спецов по системному программированию сильно меня не пинать за возможные ошибки, в обычной жизни я веб-разработчик, а си для меня – что-то вроде быстрой версии bash. Здесь каждому сигналу присваивается значение уровня с учетом замираний, сигналы суммируются с учетом уровней, затем суммарный сигнал делится на значение суммарного уровня, таким образом имитируется АРУ, и громкость полученного звука будет примерно постоянной.
Выходной поток кодируется oggenc и при помощи ezstream отправляется на Icecast сервер, где становится доступным для прослушивания.
Склонировать проект можно можно отсюда, там же инструкция по установке. Устанавливать сначала лучше не на Raspberry, а на обычные, настольные линуксы, так как, возможно, на малинке придется повозиться с ручной сборкой некоторых компонентов. Вместо скрипта stream-template-1206am, был скрипт с моими любимыми радиостанциями, чтобы уберечь их от возможного хабраэффекта, а совесть от угрызений, заменил заглушками. Поставьте вместо них аудиопотоки на ваш вкус и да пребудет с вами теплый ламповый звук.
Всем добра и с праздниками!
UPDATE: По совету юзера Logonoff добавил в проект образец того, как это звучит.
Комментарии (52)
konchok
04.01.2019 04:57Цепочка из 3-4 VST сделает такой же звук но лучше. Придётся правда брать что-то на x86 но зато программирование не надо городить.
saag
04.01.2019 09:23+3И индикатор уровня на 6Е5С воткнуть для полной аутентичности:-)
iig
04.01.2019 11:10На маленьком led дисплее можно нарисовать отличную имитацию.
saag
04.01.2019 11:15Тут есть над чем поработать — с лязгом переключающиеся клавиши, стрелка индикатора настройки радио:-)
iig
04.01.2019 11:43+2Да, клавиши это олдскульная механизма из железа и пружин… не то, чтобы это не решалось домашних условиях, но это те самые 10% фич, требующие 90% усилий. Авторская концепция наоборот, 90/10.
engine9
04.01.2019 12:58+1Готов её нарисовать, только скажите спецификации, выходной файл, размер в пикс и т.п.
jaiprakash
04.01.2019 11:52+20.3 мкВ эха, той же передачи на той же частоте, но из другого места,
В образце эта реверберация звучит незнакомо, такое было в реале? Отражение от большого парохода?
Идея для железной реализации: датчик удара для временного уменьшения «помех».PereNoel Автор
04.01.2019 13:17+2Это происходит, когда одна радиостанция на одной частоте вещает из двух и более передающих центров, например, такое эхо было на 549кГц, где вещал Маяк. Старожилы говорят, что раньше сигналы были синхронизированы, но я этого не застал.
yetanotherman
04.01.2019 23:06На самом деле эхо может быть из-за многолучевого распространения от одного источника. На средних волнах это бывает нечасто, но на коротких можно наткнуться и сейчас. Вообще вынужден признать, получилось правдоподобно. Кстати, АРУ немного не так работает, у него есть еще постоянная по времени, но так даже лучше для целей данного проекта — ибо появляются еще и нелинейные искажения.
muromdx
04.01.2019 13:19Честно говоря, скептически отношусь к подобной затее, но аудиофрагмент реально порадовал — очень похоже на короткие волны.
cadmi
04.01.2019 13:38+2Автор, что ты делаешь, прекрати! Я же раскурочу доставшуюся от бабушки радиолу! ;-)
PereNoel Автор
04.01.2019 13:51+1Зачем курочить? Разве малинка туда не влезет так? И там есть уже готовый теплый ламповый (или теплый транзисторный) усилитель звука.
cadmi
04.01.2019 14:58+1Конечно влезет, там внутри места вагон. Имел в виду, полезу внутрь :)
Да, теплый ламповый. Транзисторов там нет, три лампы и пять диодов.dlinyj
04.01.2019 23:28Только недавно такую ремонтировал. Конденсаторы надо заменить
cadmi
05.01.2019 14:58Как ни странно, рабочая пока. Осенью включал пластинки покрутить.
stalinets
05.01.2019 23:38Мне от деда достался Рекорд-311, но я будучи малым сломал в нём вертушку пластинок, а также сломалась одна петля крышки и что-то ещё по мелочи. И тут мы ехали по работе с напарником, и мне попалась на глаза выброшенная кем-то радиола Рекорд-310, почти то же самое, но немного в другом корпусе! Причём даже рабочая, просто в запущенном состоянии (видимо, много лет стояла где-нибудь в сыром неотапливаемом сарае).
Пришлось послушать ворчание напарника (что-то про бомжей и задротство), но я забрал её и, собрав из двух одну, восстановил дедушкину, достаточно аутентично. Ещё и запасной комплект ламп теперь лежит. =) А динамики пошли на самодельное FM-радио мне на работу.
saag
04.01.2019 16:12О, знакомая вещь, была именно такая когда то, потом мы из нее цветомузыку сделали, экран был из стеклянных трубок.
stalinets
04.01.2019 15:41+1Неплохо, но по мне так нужно точнее подкрутить тембр звука.
Самые низкие нужно ещё срезать: только самые большие и дорогие ламповые приёмники типа Фестиваля давали столь глубокие басы, как в тестовой записи. А типичные радиолы начала 70-х годов в парой одноваттных динамиков типа 1ГД-9 не давали такого баса.
Потом, ИМХО недостаточно точно передана общая картина тембра, нужно тонко и вдумчиво настроить эквалайзер, сравнивая звучание реальной радиолы с синтетическим с малинки. Чистота (кристальность) голоса и средних у реальной радиолы может быть и получше, чем в примере. Зато в реальной радиоле могут быть всякие резонансы и неравномерности АЧХ, из-за чего на некоторых частотах звук кричащий.
Что интересно, точно передать искажения старой несовершенной техники на современной и совершенной — не так и просто.
Короче, тонкая настойка этого дела — долгий и творческий процесс))
Ещё можно добавить изредка помехи, приходящие по электросети, типа кто-то включил свет и в динамиках щёлкнуло. Мы уже отвыкли от этого, но оно было.
И ещё тихий гул трансформатора. Не просто синусоида 50 Гц, а именно записанный в студии тихий гул трансформатора в реальной радиоле.
А ещё нужно сделать к этой малинке коробочку из советской лакированной фанеры, и в ней горящую в пол-накала лампочку Ильича, посыпанную комнатной пылью, чтобы имитировать запах тёплого лампового звука!)))PereNoel Автор
04.01.2019 16:33+1Подстраивать тембр можно, в теории ffmpeg умеет делать эквалайзер. Но лучше, наверно, с этим справится деревянный корпус и старые динамики.
АЧХ ещё заметно страдает при глубоких замираниях, но решил пожалеть ресурсы Raspberry. Отчасти это компенсируется сочетанием шума, эха и второй радиостанции, когда основной сигнал слаб.
FreeManOfPeace
04.01.2019 18:40+4Между тем вещание на средних и коротких волнах всё ещё ведётся.
Это я к тому, не лучше ли починить приёмник и попробовать использовать его по прямому назначению, а не делать из него колонку с эффектами.
СпойлерСейчас подремонтировал и кручу такого зверя, залипательная штука.
Есть мысли по модернизации его для приёма SSB.
cadmi
05.01.2019 15:00воу, у бати такой в гараже стоял, с совхозного радиоузла принесли. надо порыться, по-моему он до сих пор целый, просто с видного места убрали.
Londoner
04.01.2019 20:36Вопрос по старому радиоприёмнику на первой картинке — а что, раньше у каждого города была своя частота вещания?
FreeManOfPeace
04.01.2019 21:01Именно так, на длинных волнах были закреплённые частоты за странами и городами.
Сейчас уже неактуально т.к. вещание на длинных волнах прекращено.apple01
04.01.2019 21:16На первой картинке города подписаны и на средних волнах тоже.
Длинные волны распространяются на тысячи километров, средние на сотни.
apple01
04.01.2019 20:48Я тоже за то чтобы восстанавливать в оригинальном виде античные приемники, их скоро не так много останется, так что рука не поднимется переделывать.
А для этого проекта предлагаю разработать плоский корпус с деревянными элементами оформления имитирующий переднюю панель лампового приемника, которую можно будет вешать на стену, так он еще и места занимать не будет.PereNoel Автор
04.01.2019 21:39Переделывать, по большому счету, не нужно, только подключиться во входу усилителя звука, ну и организовать питание.
acklamterrace
04.01.2019 21:40+2Еще, как вариант — фильтрами самого ffmpeg-а. Получается write-only дичь, правда, но работает (без паразитного сигнала — сходу не нашел URL какого-нибудь говорящего радио):
[0]highpass=f=200, aecho=delays=$ECHO_LEVEL/1000.0, aeval=val(0) + $ECHO_LEVEL * val(0) * (0.4*sin(t*6.28/$ECHO_ELP) + 0.3*sin(t*6.28/$ECHO_LP) + 0.2*sin(t*6.28/$ECHO_MP) + 0.1*sin(t*6.28/$ECHO_FP))[ECHO], [0]highpass=f=500, aeval=val(0) + val(0) * (0.4*sin(t*6.28/$SF_ELP) + 0.3*sin(t*6.28/$SF_LP) + 0.2*sin(t*6.28/$SF_MP) + 0.1*sin(t*6.28/$SF_FP))[SF], [1]aeval=val(0)*0.1[NOISE], [SF][NOISE]amix[OUT], [OUT][ECHO]amix[OUT2], [OUT2]aeval=val(0) + $IF_LEVEL*sin(t*6.28*$IF_FREQ)*(0.4*sin(t*6.28/$IF_ELP) + 0.3*sin(t*6.28/$IF_LP) + 0.2*sin(t*6.28/$IF_MP) + 0.1*sin(t*6.28/$IF_FP)), lowpass=f=3000
Полный скрипт, играет в ffplay
Сэмпл
ErgoZru
05.01.2019 00:18+1Не удержался, сделал себе docker контейнер с немного измененным исходником (вынес 4 параметра в входные переменные — уровень шума, эхо, интерференс и уровень бэкграунд сигнала). В итоге получилось очень удобно))) Автору огромное спасибо! Уже договорился с товарищем, который отдаст радиолу под проект))) если будет интересно — сделаю пост, как реализую)))
Кому нужен готовый контейнер — hub.docker.com/r/riftbit/fallout-radio
Пользуйтесь на здоровье! По умолчанию настройки уже подобраны для лампового звучания (на мой вкус) и указаны основной стрим и бэкграунд (джаз, ибо он идеально подходит для такого звучания, имхо)cadmi
05.01.2019 16:03+1Большое спасибо! С…
-e STREAM_MAIN="http://stream128.melodiafm.spb.ru:8000/melodia128"
… звучит вообще прямо как в детстве :)ErgoZru
05.01.2019 19:33+1ООО!!! Это огонь!!! Спасибо за поток! Звучит просто шикарнейше!
Контейнеры изменились! ВАЖНО!кстати обновил контейнеры. Чуть позже дополню комментарий с указанием изменений. А они глобальные получились)))
sim2q
05.01.2019 01:49Интересно, управление АРУ, замирание и вот эти все огибающие для модуляции хорошо бы брать откуда то из реального, физического мира. Благо они не очень быстрые.
Думаю есть же real-time открытые данные интересные.
Это старого, ещё когда интересовался темой. Жаль там всего 2.5-минутное разрешение, если сложить три графика, можно получить минутные вариации, ещё бы на порядок чем-нибудь зарандомайзить… Не то что бы идея полностью эмулировать эфир, но есть мнение, что возмущения ЭМП тонко влияют на тушку в т.ч. :)Tema567
05.01.2019 14:02+1Как вариант ещё можно совмещать аудио дорожки с реальными шумами или loop-записи эфира, взятыми с RTL-SDR и ретранслированными Icecast. Возможно даже сделать несколько дорожек с разным уровнем промышленных помех, грозовых разрядов, тресков и фонового гула для большей правдоподобности.
Эмулировать дальнее прохождение, замирания и фединги из реального мира гораздо-гораздо сложнее, как минимум надо учитывать условия прохождения по пути радиосигнала от радиоцентра к слушателю, и для каждой радиостанции это разные наборы исходных данных. Вариант автора с использованием 4 заданных периодов выглядит логично для распологаемых ресурсов RPi и звучит очень правдоподобно.sim2q
05.01.2019 19:39+2Здесь ключевой момент — что бы была привязка к физическому миру в real-time, а не сэмплы. Кстати проще всего брать квантовый шум прям на месте с какого-нибудь обратносмещённого БЭ перехода. Но я не буду тут распространяться дальше, кто в теме — уже понял, а за дальнейшие подробности можно и минусов огрести :)
PereNoel Автор
06.01.2019 00:33Замирания связаны с вариациями магнитного поля только косвенно, если брать за основу что-то из реального мира, то проще всего взять уровень несущей какой-нибудь радиостанции.
ErgoZru
05.01.2019 21:26+1Для тех кто использовал мой первый контейнер из этого комментария — контейнер переделан. Теперь он на базе моего другого контейнера с Icecast2 на базе Alpine Linux, что сильно повлияло на размер образов (в лучшую сторону) и снизило немного потребление ресурсов.
Немного обмозговав прошлой ночью, понял что этот контейнер не самый удобный вариант, если нужно запускать несколько «волн», плюс довольно объемный.
В итоге было сделано следующее:
1) Создан чистый контейнер на базе ОС Alpine Linux с установленным Icecast2 с преднастройками для легкого старта — riftbit/icecast
2) Старый контейнер riftbit/fallout-radio — пересобран на базе контейнера из п.1
3) Сделал контейнер-стриммер (без установленного icecast) чисто для создания потока (с установленным ffmpeg+ezstream) — riftbit/icecast-retro-streamer.
4) У всех контейнеров более менее расписал документацию, имеющуюся обновил.
В результате, если у вас 1 стрим, то вполне можно дальше использовать контейнер из п.2.
Если вы хотите запустить более одного потока и сэкономить на портах и ресурсы системы — запускаете 1 контейнер из п.1 и сколько хотите из п.3 (в настройках этого контейнера указываете адрес и пароль для сервера из п.1, в общем смотрите доки, я думаю и так все понятно).
П.С. работу контейнера из п.2 проверил только что — всё ок, работает, играет. Работу связки контейнеров из п.1+п.3 не проверял! Но по идее должно работать.
П.П.С. Если контейнеры окажутся полезны — буду благодарен за звездочки на докер-хабе :)
П.П.П.С. Ещё раз большое спасибо автору данного топика. Второй день слушаю джаз в офигенном звучании )
Logonoff
Вам бы аудиосэмпл того как это все звучит воткнуть в пост.
bormotov
а еще лучше два сэмпла:
1. вот такое пришло на вход
2. такое будет на выходе
PereNoel Автор
На вход идут обычные аудиопотоки радиостанций, нормализованный звук относительно хорошего качества, а сэмпл того, что получается на выходе добавил.
vladkorotnev
Осталось добавить возможность динамически переключаться между потоками, ну и потоков в таком случае будет три (предыдущий, активный, следующий).
PereNoel Автор
Добавил.