用 Astrometa DVB-T2 聽 FM 廣播

算是接續「用 Astrometa DVB-T2 收數位無線電視台 (DVB-T)」這篇的內容,上篇有提到在台灣可以收 DVB-T 的數位電視內容,另外也有提到裡面的 RTL2832U 可以收 FM 廣播。

RTL2832U 在 Linux 下面的 FM 介面不是 /dev/radio0 這種 Radio Interface,而是透過 SDR 的方式,會產生出 /dev/swradio0 操作。

所以可以用 rtl_fm 這個工具從 SDR source 轉成 PulseAudio 吃的格式,像是要聽 107.7MHz 的台北之音,可以用這樣的指令聽:

sudo rtl_fm -f 107700000 -s 441000 -r 44100 | aplay -r 44100 -f S16_LE

但這樣做會是 mono (單聲道),這點可以從「Stereo FM receiving with RTL-SDR and Gnuradio - part 1」這邊的這張圖了解發生了什麼事情:

最低的地方會是左右聲道混在一起的 L+R 的單聲道訊號,這個方式可以讓很早期不支援兩聲道 (立體聲) 的 FM 收音機還是可以正常收聽,也剛好是 rtl_fm 時用到的地方。

而接下來是 19kHz 表示支援立體聲的訊號,然後從 23~53kHZ 的地方是 L-R 的訊號,最後面是 RDS 資料。

所以要把這包東西轉成 L 與 R 不是單純抽兩段 source 出來就解決了,而是需要在頻域上運算。

接著就是找看看有沒有已經做完的工具可以從 SDR source 運算然後播放,就找到 LuaRadio 這個專案,依照他的要求安裝 dependency,然後就可以直接跑了:

./luaradio examples/rtlsdr_wbfm_stereo.lua 107700000

在「rtlsdr_wbfm_stereo.lua」這頁的說明可以看到整個 flow 拉了很多處理。

不過在我的桌機上面,他會跳出三個 gnuplot 的視窗一直搶 window focus,要終止的話得按住 Ctrl-C 不放,然後點 terminal 想辦法讓 terminal 收到 Ctrl-C 才能停掉,看起來應該是 bug...

從 code 裡面可以看到他會偵測是否有 DISPLAY 這個環境變數來決定要怎麼做,所以本來以為改掉 DISPLAY 就可以了:

DISPLAY= ./luaradio examples/rtlsdr_wbfm_stereo.lua 107700000

不過看起來會卡住,還是得直接把相關的 code 都註解掉才行。

anyway,從官方給的圖可以看到整個收到的頻譜,以及 L+R 與 L-R 的樣子,也可以看到 19kHz 那邊有根訊號表示這是兩聲道:

這樣至少是有軟體可以聽立體聲了...

用 Astrometa DVB-T2 收數位無線電視台 (DVB-T)

以前用的 USB 電視棒壞掉了,去網拍上找了一隻新的來用,翻了一下跟 LinuxTVWiki 上的 Astrometa DVB-T2 這頁的圖片一樣 (2014 版本的圖):

先講一下重點,如果你買到的 USB 電視棒跟我一樣,應該可以看到兩個 source 可以收 DVB-T,而這兩個 source 都可以測試看看,在我家裡測試 Sony CXD2837ER 的收訊明顯好很多:

另外順便一提無關緊要的事情,本來在查資料的時候以為是 2013 的古董版本,但研究了一會兒發現 2013 版的「DVBT2」字比較大,所以不是 2013 版的:

插入到 Ubuntu 的時候可以看到幾個有趣的東西:

[Sat Dec 30 11:59:49 2023] usb 1-6.3: DVB: registering adapter 0 frontend 0 (Realtek RTL2832 (DVB-T))...
[Sat Dec 30 11:59:49 2023] dvbdev: dvb_create_media_entity: media entity 'Realtek RTL2832 (DVB-T)' registered.
[Sat Dec 30 11:59:49 2023] usb 1-6.3: DVB: registering adapter 0 frontend 1 (Sony CXD2837ER DVB-T/T2/C demodulator)...
[Sat Dec 30 11:59:49 2023] dvbdev: dvb_create_media_entity: media entity 'Sony CXD2837ER DVB-T/T2/C demodulator' registered.

意外的發現有兩個支援 DVB-T 的晶片,首先是 Realtek RTL2832 有被抓到,然後被註冊到 /dev/dvb/adapter0/frontend0 這邊。

Realtek 官網上只翻到了 RTL2832U 的資料,裡面比較有趣的是支援了 ISDB-T,不過如果在日本的話還需要 B-CAS 才能解:

Includes ISDB-T(SBTVD-T) 1-Seg

另外 RTL2832U 也支援 FM:

Includes Radio Support (FM/DAB/DAB+)

而第二個的 Sony CXD2837ER 被註冊到 /dev/dvb/adapter0/frontend1 這邊,另外在 LinuxTVWiki 可以看到 CXD2837ER 只被用在了 2018 版本,而且在外觀的部分提到了「or same as 2014 or 2017 revision」,所以看起來手上的版本應該是 2018 版的,但是殼長得跟舊的一樣。

翻了 Sony CXD2837ER 的 datasheet,可以看到支援 DVB-{T2,T,C}:

The Sony CXD2837ER is a combined DVB-T2 (incl.T2-Lite), DVB-T and DVB-C demodulator

看起來是為了 DVB-T2 而放進來的?不過台灣目前還是用 DVB-T 就是了。

Anyway,目前用起來唯一的缺點是看電視的時候同時跑 dvb-fe-tool --femon -f 1 會造成畫面破格,這點要再看看怎麼解決,不過不是大問題...