В «юбилейной» части цикла про SDR хочется рассказать об одном из протоколов, благодаря которому многие радиолюбители «невольно» приобщились к миру цифровых широкополосных сигналов. Этот стандарт также являлся первой (и насколько известно, единственной) попыткой передачи цифрового звука на коротких волнах.
Как многие наверное уже догадались, речь пойдет о стандарте DRM — Digital Radio Mondiale (не путать с другим DRM, Digital Rights Management).
Ну и т.к. мы будем говорить об SDR, то посмотрим не только как принимать DRM, но и как его передавать. Продолжение под катом.
История
История стандарта DRM весьма непроста. Впервые он был представлен в 2003м году, а тестовые передачи производились с 2007г, и с переменным успехом продолжаются периодически и до сих пор.
В основу DRM было заложено две основные идеи.
— Передача звука на коротких волнах с «цифровым качеством», без шумов и замираний, с битрейтом от 6 до 34КБит/с. Впрочем, «цифровое качество» тут можно написать лишь в кавычках, т.к. при битрейте в 12КБит звук получается весьма от… относительно низкого качества. К тому же, сигнал на КВ действительно подвержен и помехам, и замираниям, и чтобы «цифра» могла декодироваться, нужно весьма высокое соотношение сигнал/шум — такое, при котором обычный аналоговый сигнал будет звучать даже лучше. В общем, достаточно хоть раз попробовать в реале принять DRM, чтобы понять что идея «не взлетит». Но вещание все же периодически проводилось, в том числе и из России (см. КДПВ), а некоторые радиостанции иногда транслируют в DRM до сих пор.
— Передача звука в FM-диапазоне. Этот стандарт был назван DRM+. Здесь идея была в экономии частотного ресурса — благодаря цифровому сжатию, в полосе 100КГц можно передать сразу до 4х аудиопередач, что сулило неплохие плюсы в крупных городах типа Лондона, где свободных частот уже нет. С другой стороны, в Европе уже работал DAB, и еще один стандарт тут просто был не нужен. Если верить Википедии, тестовое вещание DRM+ осуществлялось в Шотландии в 2010м году, о каких-то реальных случая вещания DRM+ пока слышать не доводилось.
Стандарт DRM по сути является несколько сюрреалистичным — годами работают радиостанции, транслируются радиопередачи… А приемников этого стандарта в продаже нет. Вообще. Никаких. Понятное дело, что раз стандарт цифровой, то обычным приемником можно услышать лишь шипение, да и декодировать QAM на слух пока еще никто не научился. Так что прием DRM являлся развлечением лишь для радиолюбителей. Вроде бы 1-2 приемника таки существовали, о чем есть даже пара видео в youtube (1 и 2), но ни на Ebay, ни на Amazon ничего в продаже сейчас нет.
Вторая проблема приема DRM состоит в том, что в городах КВ вещание де-факто мертво — помех от бытовой аппаратуры и блоков питания сейчас столько, что даже если включить КВ-радио, то будет слышен один треск и шум. Можно конечно поставить антенну на балкон или на крышу, тщательно ее настроить, и в принципе, принять и декодировать DRM из городской квартиры для радиолюбителей вполне реально. Обычные же люди этим 100% заморачиваться не будут, никто не полезет на крышу вешать антенну, чтобы принять аудиосигнал с битрейтом 12КБит/с.
В общем, приемников нет, аудитории нет. А вещание есть. Суслик из фильма отдыхает…
Кстати, прямо сейчас, на момент написания статьи (июль 2019) тестовое вещание DRM+ проводится в Петербурге, так что желающие побыть сусликом могут попробовать принять сигнал (только слушать его нечем, ни приемников, ни даже софтовых SDR-декодеров для DRM+ нет). Для приема можно воспользоваться RTL-SDR, и если повезет, то в FM-диапазоне можно будет увидеть цифровой сигнал шириной около 100КГц. Декодеров, впрочем, как уже говорилось, для него найти не удалось.
Прием DRM
Первые сообщения о приеме радиолюбителями DRM на сайте radioscanner датируются 2008 годом. Прием цифрового сигнала шириной 10КГц невозможен на обычный бытовой (и даже радиолюбительский) приемник, так что желающим тогда приходилось паять конвертор для вывода ПЧ приемника к звуковой карте. После появления SDR проблема решилась сама собой, там можно выбрать любую ширину полосы в пределах возможностей приемника (для первых SDR на базе звуковой карты это обычно было 48КГц, что более чем достаточно). Само декодирование осуществлялось с помощью весьма удобной и качественной программы Dream.
Как уже говорилось выше, DRM-станции работают довольно-таки регулярно, и найти их в эфире не так уж сложно. Например, на websdr такой сигнал очень легко различим на спектре — если в широковещательном диапазоне виден цифровой сигнал шириной 10КГц, то это он и есть. Пример скриншота станции, работающей на 15МГц, сделанного во время написания статьи:
Только декодировать его с помощью websdr не выйдет, ширина полосы у онлайн-приемника слишком мала. Впрочем послушать DRM может любой желающий, записанный с реального эфира файл можно скачать здесь. Для декодирования можно воспользоваться уже упомянутой программой Dream, рабочую версию со всеми необходимыми DLL можно взять на сайте radioscanner.
Если говорить о «железных» приемниках, то анонсировался, например, приемник Gospell GR-216, но «вживую» его нет ни на eBay, ни на Amazon.
Передача DRM
Теперь перейдем к не менее интересному — возможности передачи DRM-сигналов (и если не ошибаюсь, в рунете это описывается впервые). Сделать это можно с помощью GNU Radio и модуля gr-drm.
Технически, DRM использует QAM-модуляцию, и имеет довольно много настроек битрейта и занимаемой полосы. Для КВ (режимы A-D) полоса может варьироваться от 4.5 до 20КГц, впрочем, на практике, встречались только 10КГц сигналы. Для УКВ (режим E), как уже говорилось, используется полоса в 100КГц. Более подробное описание стандарта есть в PDF, кратко можно почитать на Signalwiki.
Вернемся к нашему графу соединений. Как можно видеть, DRM-кодер формирует сигнал из нескольких компонентов.
— Fast Access Channel (FAC). Содержит информацию о свойствах ODFM-сигнала и конфигурации SDC/MSC. Информация о канале передается каждые 0.4с, что позволяет приемнику довольно быстро начать прием сигнала станции. Параметры сигнала можно настроить в блоке DRM Configuration.
— Service Description Channel (SDC). Содержит описание канала передачи MSC.
— Main Service Channel (MSC). Содержит фреймы данных, для передачи может использоваться QAM16 или QAM64.
Ну и самое интересное то, что всё это без проблем можно запустить на обычном ПК. Gr-drm включен в пакет PothosSDR для Windows, но там он увы, не работает — сигнал есть, но декодирование происходит с ошибками. Под Ubuntu все запускается нормально.
В качестве выхода можно использовать WAV-файл или полноценный SDR-трансивер, например HackRF. Для тех, кто захочет поэкспериментировать самостоятельно, GRC-файл под спойлером.
Tue Apr 29 11:37:08 2014 options author Felix Wunsch window_size 3000, 2000 category Custom comment description Generic DRM Transmitter. For the MSC, only SM and EEP is implemented. _enabled True _coordinate (1016, 16) _rotation 0 generate_options no_gui hier_block_src_path .: id drm_transmitter max_nouts 0 qt_qss_theme realtime_scheduling run_command {python} -u {filename} run_options run run True thread_safe_setters title DRM Transmitter variable comment _enabled True _coordinate (240, 60) _rotation 0 id file_dest value "D:\MyProjects\GNURadio\gr-drm-master\apps\sound_drm_out.wav" variable comment _enabled True _coordinate (56, 60) _rotation 0 id file_source value "D:\MyProjects\GNURadio\gr-drm-master\apps\sound.wav" variable_drm_config audio_sample_rate 12000 comment Before generating the flow graph, define the path to a 24 kHz wav-file and change the parameters of the UHD sink. Do not forget to set the correct audio_sample_rate. _enabled 1 _coordinate (1208, 12) _rotation 0 id tp long_interl True msc_mapping 2 msc_prot_level_2_16 1 msc_prot_level_2_64 0 RM 1 sdc_mapping 0 SO 3 station_label "Radioscanner Test" text_message "DRM transmission with GNU Radio" analog_sig_source_x amp 1 alias comment affinity _enabled 1 freq 7000 _coordinate (576, 624) _rotation 0 id analog_sig_source_x_0 maxoutbuf 0 minoutbuf 0 offset 0 type complex samp_rate drm.FS_SOUNDCARD waveform analog.GR_COS_WAVE audio_sink alias comment affinity device_name _enabled 0 _coordinate (1184, 556) _rotation 0 id audio_sink_0 num_inputs 1 ok_to_block True samp_rate 48000 audio_source alias comment affinity device_name _enabled 0 _coordinate (56, 156) _rotation 0 id audio_source_0 maxoutbuf 0 minoutbuf 0 num_outputs 1 ok_to_block True samp_rate 44100 blocks_complex_to_real alias comment affinity _enabled 1 _coordinate (1008, 640) _rotation 0 id blocks_complex_to_real_0 maxoutbuf 0 minoutbuf 0 vlen 1 blocks_multiply_const_vxx alias comment const 32768 affinity _enabled 1 _coordinate (272, 236) _rotation 0 id blocks_multiply_const_vxx_0 type float maxoutbuf 0 minoutbuf 0 vlen 1 blocks_multiply_const_vxx alias comment Prevent clipping const 7e-3 affinity _enabled True _coordinate (688, 468) _rotation 0 id blocks_multiply_const_vxx_1 type complex maxoutbuf 0 minoutbuf 0 vlen 1 blocks_multiply_xx alias comment affinity _enabled 1 _coordinate (864, 624) _rotation 0 id blocks_multiply_xx_0 type complex maxoutbuf 0 minoutbuf 0 num_inputs 2 vlen 1 blocks_wavfile_sink bits_per_sample 16 alias comment affinity _enabled 1 file file_dest _coordinate (1200, 620) _rotation 0 id blocks_wavfile_sink_0 nchan 1 samp_rate drm.FS_SOUNDCARD blocks_wavfile_source alias comment affinity _enabled 1 file file_source _coordinate (56, 228) _rotation 0 id blocks_wavfile_source_0 maxoutbuf 0 minoutbuf 0 nchan 1 repeat False cell_mapping_cc alias comment Multiplex the three logical channels and the pilot cells and create transmission frames. affinity _enabled True _coordinate (1184, 264) _rotation 0 id cell_mapping_cc_0 maxoutbuf 0 minoutbuf 0 tp tp digital_ofdm_cyclic_prefixer alias cp_len tp.ofdm().nfft()*tp.ofdm().cp_ratio_enum()/tp.ofdm().cp_ratio_denom() comment affinity _enabled True input_size tp.ofdm().nfft() _coordinate (456, 448) _rotation 0 id digital_ofdm_cyclic_prefixer_1 tagname maxoutbuf 0 minoutbuf 0 rolloff 0 drm_audio_encoder_sb alias comment affinity _enabled True _coordinate (456, 240) _rotation 0 id drm_audio_encoder_sb_0 maxoutbuf 0 minoutbuf 0 len_out tp.msc().L_MUX() tp tp drm_generate_fac_b alias comment affinity _enabled True _coordinate (56, 344) _rotation 0 id drm_generate_fac_b_0 maxoutbuf 0 minoutbuf 0 tp tp drm_generate_sdc_b alias comment affinity _enabled True _coordinate (56, 296) _rotation 0 id drm_generate_sdc_b_0 maxoutbuf 0 minoutbuf 0 tp tp drm_interleaver_cc alias comment Additional interleaving affinity _enabled True _coordinate (952, 240) _rotation 0 id drm_interleaver_cc_0 depth drm.INTL_DEPTH_DRM interl_seq tp.msc().cell_interl_seq() long_interl tp.cfg().long_interl() maxoutbuf 0 minoutbuf 0 drm_scrambler_bb alias block_len tp.msc().L_MUX() comment affinity _enabled True _coordinate (608, 240) _rotation 0 id drm_scrambler_bb_0 maxoutbuf 0 minoutbuf 0 drm_scrambler_bb alias block_len tp.fac().L() comment affinity _enabled True _coordinate (608, 344) _rotation 0 id drm_scrambler_bb_0_0 maxoutbuf 0 minoutbuf 0 drm_scrambler_bb alias block_len tp.sdc().L() comment affinity _enabled True _coordinate (608, 296) _rotation 0 id drm_scrambler_bb_0_1 maxoutbuf 0 minoutbuf 0 fft_vxx alias comment affinity _enabled True fft_size tp.ofdm().nfft() forward False _coordinate (232, 440) _rotation 0 id fft_vxx_0 type complex maxoutbuf 0 minoutbuf 0 nthreads 1 shift True window mlc_bc alias channel_type "FAC" comment Apply channel coding and interleaving affinity _enabled True _coordinate (744, 340) _rotation 0 id mlc_bc_0 maxoutbuf 0 minoutbuf 0 tp tp mlc_bc alias channel_type "MSC" comment affinity _enabled True _coordinate (744, 236) _rotation 0 id mlc_bc_0_0 maxoutbuf 0 minoutbuf 0 tp tp mlc_bc alias channel_type "SDC" comment affinity _enabled True _coordinate (744, 292) _rotation 0 id mlc_bc_0_1 maxoutbuf 0 minoutbuf 0 tp tp rational_resampler_xxx alias comment Ingoing sample rate is assumed to be 48 kHz. 250 kHz is one of the lowest achievable rates of the USRP. affinity decim drm.FS_SOUNDCARD / 1000 _enabled 0 fbw 0 _coordinate (864, 448) _rotation 0 id rational_resampler_xxx_0 interp 250 maxoutbuf 0 minoutbuf 0 taps type ccc rational_resampler_xxx alias comment affinity decim 441 _enabled 0 fbw 0 _coordinate (248, 136) _rotation 0 id rational_resampler_xxx_0_0 interp 240 maxoutbuf 0 minoutbuf 0 taps type fff virtual_source comment _enabled True _coordinate (56, 468) _rotation 0 id sym_in stream_id symbols virtual_sink comment _enabled True _coordinate (1408, 292) _rotation 0 id sym_out stream_id symbols uhd_usrp_sink alias ant0 TXA bw0 0 center_freq0 5e6 norm_gain0 False gain0 0 ant10 bw10 0 center_freq10 0 norm_gain10 False gain10 0 ant11 bw11 0 center_freq11 0 norm_gain11 False gain11 0 ant12 bw12 0 center_freq12 0 norm_gain12 False gain12 0 ant13 bw13 0 center_freq13 0 norm_gain13 False gain13 0 ant14 bw14 0 center_freq14 0 norm_gain14 False gain14 0 ant15 bw15 0 center_freq15 0 norm_gain15 False gain15 0 ant16 bw16 0 center_freq16 0 norm_gain16 False gain16 0 ant17 bw17 0 center_freq17 0 norm_gain17 False gain17 0 ant18 bw18 0 center_freq18 0 norm_gain18 False gain18 0 ant19 bw19 0 center_freq19 0 norm_gain19 False gain19 0 ant1 bw1 0 center_freq1 0 norm_gain1 False gain1 0 ant20 bw20 0 center_freq20 0 norm_gain20 False gain20 0 ant21 bw21 0 center_freq21 0 norm_gain21 False gain21 0 ant22 bw22 0 center_freq22 0 norm_gain22 False gain22 0 ant23 bw23 0 center_freq23 0 norm_gain23 False gain23 0 ant24 bw24 0 center_freq24 0 norm_gain24 False gain24 0 ant25 bw25 0 center_freq25 0 norm_gain25 False gain25 0 ant26 bw26 0 center_freq26 0 norm_gain26 False gain26 0 ant27 bw27 0 center_freq27 0 norm_gain27 False gain27 0 ant28 bw28 0 center_freq28 0 norm_gain28 False gain28 0 ant29 bw29 0 center_freq29 0 norm_gain29 False gain29 0 ant2 bw2 0 center_freq2 0 norm_gain2 False gain2 0 ant30 bw30 0 center_freq30 0 norm_gain30 False gain30 0 ant31 bw31 0 center_freq31 0 norm_gain31 False gain31 0 ant3 bw3 0 center_freq3 0 norm_gain3 False gain3 0 ant4 bw4 0 center_freq4 0 norm_gain4 False gain4 0 ant5 bw5 0 center_freq5 0 norm_gain5 False gain5 0 ant6 bw6 0 center_freq6 0 norm_gain6 False gain6 0 ant7 bw7 0 center_freq7 0 norm_gain7 False gain7 0 ant8 bw8 0 center_freq8 0 norm_gain8 False gain8 0 ant9 bw9 0 center_freq9 0 norm_gain9 False gain9 0 clock_rate 0.0 comment affinity dev_addr dev_args "" _enabled 0 _coordinate (1168, 424) _rotation 0 id uhd_usrp_sink_0 type fc32 clock_source0 sd_spec0 time_source0 clock_source1 sd_spec1 time_source1 clock_source2 sd_spec2 time_source2 clock_source3 sd_spec3 time_source3 clock_source4 sd_spec4 time_source4 clock_source5 sd_spec5 time_source5 clock_source6 sd_spec6 time_source6 clock_source7 sd_spec7 time_source7 nchan 1 num_mboards 1 samp_rate 48000 * 250 / 48 hide_cmd_port False hide_lo_controls True stream_args stream_chans [] sync len_tag_name otw analog_sig_source_x_0 blocks_multiply_xx_0 0 1 audio_source_0 rational_resampler_xxx_0_0 0 0 blocks_complex_to_real_0 audio_sink_0 0 0 blocks_complex_to_real_0 blocks_wavfile_sink_0 0 0 blocks_multiply_const_vxx_0 drm_audio_encoder_sb_0 0 0 blocks_multiply_const_vxx_1 blocks_multiply_xx_0 0 0 blocks_multiply_const_vxx_1 rational_resampler_xxx_0 0 0 blocks_multiply_xx_0 blocks_complex_to_real_0 0 0 blocks_wavfile_source_0 blocks_multiply_const_vxx_0 0 0 cell_mapping_cc_0 sym_out 0 0 digital_ofdm_cyclic_prefixer_1 blocks_multiply_const_vxx_1 0 0 drm_audio_encoder_sb_0 drm_scrambler_bb_0 0 0 drm_generate_fac_b_0 drm_scrambler_bb_0_0 0 0 drm_generate_sdc_b_0 drm_scrambler_bb_0_1 0 0 drm_interleaver_cc_0 cell_mapping_cc_0 0 0 drm_scrambler_bb_0 mlc_bc_0_0 0 0 drm_scrambler_bb_0_0 mlc_bc_0 0 0 drm_scrambler_bb_0_1 mlc_bc_0_1 0 0 fft_vxx_0 digital_ofdm_cyclic_prefixer_1 0 0 mlc_bc_0 cell_mapping_cc_0 0 2 mlc_bc_0_0 drm_interleaver_cc_0 0 0 mlc_bc_0_1 cell_mapping_cc_0 0 1 rational_resampler_xxx_0 uhd_usrp_sink_0 0 0 rational_resampler_xxx_0_0 drm_audio_encoder_sb_0 0 0 sym_in fft_vxx_0 0 0
Увы, USRP на КВ не передает, а HackRF у меня нет. Так что реальный эфирный тест сделать не удалось, впрочем могу подтвердить, что декодирование звука через Dream происходит без ошибок.
Заключение
Как ни странно, но несмотря на, казалось бы, 99% бесперспективность, стандарт DRM пока еще жив. Впрочем, вряд ли он будет успешным и уйдет дальше каких-либо локальных экспериментов — качество звука в DRM уже не отвечает современным нормам, да и приемников на рынке нет. С технической точки зрения, то, что казалось «прорывом» в 2003м, сейчас уже мало актуально.
Но с другой стороны, DRM содержит немало интересных идей, это был (и есть) достаточно интересный опыт, приобщиться к которому (пока еще) может любой желающий.
Источник