Later edit: source code added here: https://github.com/BogdanDIA/gr-dvbt
Motivation for implementing DVB-T RX/TX:
I thought I should write about my work on implementing the ETSI 300 744 (DVB-T ) standard on GNUradio and what were the challenges I needed to overcome and challenges that still remained.
The entire work for DVB-T, both TX and RX, is going to be on github in the next couple of weeks.
The whole idea of the project was to provide a framework for researchers that want to play with various algorithms for synchronization, demodulation equalization, etc and none the less for individuals wanting to have a testing tool for real life implementation of the DVB-T standard.
The presentation here will be of low complexity and intended for understanding the principles that drive the digital broadcasting. I will write later on a more academic like paper with studies on effect of various SNR levels on the BER, MER and entire system together with further development directions. Given the complexity of the receiver, the tool can be used also as a benchmark to understand how different architectures can minimize the processing required together with lowering power consumption.
Quick start with a challenge:
Let’s get started by telling you that looking for sources of open source DVB-T implementation I found none that can work in real life or that can be used as a research in real life (TODO: insert OpenDVBT, Barruffa, Pellegrini, other). Therefore I decided to dig the ETSI 300 744 standard and implement it step by step.
Actually, the whole started when I wanted to use the cheap RTL2832U dvbt stick on ham radio frequencies like 1200Mhz band where I did not have a transmitter available. As you may probably know, the Elonics dvb-t stick has a driver for Linux kernel available. And also you may know that the chip inside can go up more than 1Ghz frequency. Modifying the driver to accept frequencyes above the regular DVB-T frequencyes is easy like this:
– .frequency_max = 862000000,
+ .frequency_max = 1700000000, //862000000
Now, let’s jump to some screenshots to show the functionality of the transmitter and the signal received with Elonics dvb-t stick. I am using Kaffeine in Ubuntu Linux:
Searching for the channel (see SNR):
Now the channel is found:
Display properties of the channel (see the frequency and the other parameters):
And finally a screenshot from Kaffeine playing the stream:
I used a MPEG2-TS file as an input file but also I did some tests with a webcamera Logitec C920 that is able to output H248 stream. I did not do many tests with the camera because an Ubuntu update changed the kernel and after that the whole USB system on my PC is failing (including USB mass storage) to sustain constant bitrate.
As you may know or imagine, the receiver was the most time consuming compared with the transmitter. I can say that implementing RX takes 3 times more time than implementing TX but that will be presented in the subsequent posts where I will dig into more technical details.
73, Bogdan – YO3IIU
20 thoughts on “DVB-T implementation in GNUradio – part 1”
The specification is designed primarily for fixed reception to roof-top antennas and has frequency spectrum channel characteristics that are compatible with with Geneva 2006 Agreement. DVB-T has been published as an ETSI standard, EN 300 744. It is built on top of MPEG standards for aiudio/video coding and multiplexing, which are used according to the MPEG guidelines technical specification ETSI TS 101 154. Many countries that have adopted DVB-T have published specifications for its implementation. including the D-Book in the UK, the Italian DGTVi, the ETSI E-Book and Scandivia NorDig.
The compiler keeps telling me, “SSe instruction set not enabled”, although my CPU reports the sse and sse2 flags. What may I miss? 🙂
It seems you need to explicitly enable SSE/AVX instructions with the following parameter to the cmake:
I do not need to do this on my system and in any case this will eventually go by using VOLK implementation.
I am getting following error when I tried to install from git clone. Please resolve my bug and thanks in advance.
CMake Error at CMakeLists.txt:90 (find_package):
Could not find module FindVolk.cmake or a configuration file for package
Adjust CMAKE_MODULE_PATH to find FindVolk.cmake or set Volk_DIR to the
directory containing a CMake configuration file for Volk. The file will
have one of the following names:
CMake Error at CMakeLists.txt:93 (message):
GnuRadio Core required to compile dvbt
— Configuring incomplete, errors occurred!
I the first glance it seems Volk is not found in the system by cmake.
Please tell your system specs in term of OS type. Also tell if you installed Volk when installing/building gnuradio.
There was a problem reported on Mac which I fixed by adding a search for Volk package which is a mandatory package, the problem you see may be related to that. See here: https://github.com/BogdanDIA/gr-dvbt/pull/6
Very nice work! Congratulations!
I am having some problems trying to execute your code
Traceback (most recent call last):
File “/home/ubuntu/Documents/gr-dvbt/apps/top_block.py”, line 22, in
File “/usr/local/lib/python2.7/dist-packages/dvbt/__init__.py”, line 45, in
from dvbt_swig import *
File “/usr/local/lib/python2.7/dist-packages/dvbt/dvbt_swig.py”, line 26, in
_dvbt_swig = swig_import_helper()
File “/usr/local/lib/python2.7/dist-packages/dvbt/dvbt_swig.py”, line 22, in swig_import_helper
_mod = imp.load_module(‘_dvbt_swig’, fp, pathname, description)
ImportError: libgnuradio-dvbt.so: cannot open shared object file: No such file or directory
Can you help with this error of the libgnuradio-dvbt.so ??
I think everything was correctly instaled.
thank you in advance!
Very nice work. Congratulations!
I am facing some problems to configure the USRP with your project…
I think I have installed everything correctly.
When I try to run the project with USRP I have an error regarding the libgnuradio-dvbt.so file.
It says that the file does not exist or can not be read. But the file exist and it can be read…
Thank you in advance!
I am also facing the same problem as AP. When I tried to run the code,I am getting an error as
“ImportError: libgnuradio-dvbt.so: cannot open shared object file: No such file or directory”.
Please give a solution as soon as possible.
We were also facing the same problem as your’s. We were able to find the solution for it.
Just update the system using the command “sudo ldconfig”.
Hope this will help you.
Thank you 🙂
Oh, this is indeed something to be done for the first time. Thanks for pointing it, I’ll add it to the docs on github.
I confuse that how 2048 point FFT perform on 1705 carrier in 2K MODE? pad (2048-1705) zeros? pad at which locations?ETSI EN300744 did not point out that.
and one more questrion, does gr-dvbt use USRP N210 as transmitter can emit the valid dvb-t singal that consumer dvb-t set-top-box(Sony “DVB-T/DVB-C” demodulator : CXD2817R) can receive?
The 1705 carriers needs to be centered on the spectrum so there is zero padding on left and right of the useful carriers.
Thanks, got it.
does this gr-dvbt use USRP N210 as transmitter can emit the valid dvb-t singal that consumer dvb-t set-top-box can receive and play live successfully?
The answer is yes, you can use USRP N210 to transmit live dvb-t signal that can be received with off the shelf dvb-t receivers. The USRP needs to tune TX frequency in the range of the commercial DVB-T frequencies/channels.
The above blog entry is just explaining how to do this with a regular RTL2832 based dvbt stick, though by using ham bands.
ahah, i see, i have two rtl2832 stick at hand, i will try to get it work. very appreciated for your guide 🙂
Hello again. question about the sink(USRP) rate and source(mpeg2ts clip file or mpeg2ts encoder output) rate adaptation;
the effective sink(USRP) bit rate is: (assumption that 2K mode, QAM64, CP 1/32, conv rate 7/8)
(10MSPS * 64/70 / (1+1/32) ) * (1512/2048) * (log64/log2) * (7/8 ) * (188/204) = 31.67 Mbps
(interpolation) (cyclic prefix) (data sub-carrier of 2K) (QAM64) (convolution rate) (RS encode)
it means that the USRP would pull 31.67 Mbit per second from the source, but what if the source rate is 4Mbps, 5Mbps …etc. that
shoud be need to do rate adaptation between the source and sink, but i did’n saw any block like that exist in the GNURADIO graph.
is that some where i misunderstood, pls point me out, thaks 🙂
Hi, the mpegts rate must match the calculated rate when sending and receiving real life signals.
However, if you transmit the mpegts from a file, it will just be consumed by the TX chain at the required rate (31.67Mbps in your case) no matter the rate at which the video in the file is. If your mpegts file is at 4Mbps it will just be consumed and sent faster. When receiving with RTL2832u like above, the received data is buffered by the system and then played at rate in the video file in Kaffeine so it still works normally.
In the case of sending video from a camera there should be a rate adaptation for the video to obtain the required rate but this is not in the gnuradion flowgraph as it is part of the video system an not part of the dvb-t standard.
Thanks for your very detailed answer, it make me clear:-)
in the dvbt_tx_demo.grc graph， there is a block call blocks_multiply_const_vxx， is it be use to constraint the IFFT output vaule to the USRP DAC dynamic range? and how it’s valule 0.0022097087 compute/come from?
Sorry for bother you again. I guess that multiply with 0.0022097087 is used to constraint the ifft output value range to [-1, 1], and then use the uhd/convert to convert this float32 to sc16 by multiply the scale factor 2^15-1 = 32767, witch match to the 16 DAC dynamic range. in other to prove my guess, i compose the matlab script below, and find that ifft output value’s real/image is no larger than 0.4, so 0.4 * 0.0022097087 = 0.00088388, this multiple resulte is more less than 1, but not approximate to 1. is there something wrong i have made in this guess?
%constraint the ofdm output to [-1.0, 1.0]
%then (sign short)(constrainted output * 32767) ->otw -> duc -> DAC
%QAM64 for example
REAL_MAX = 7;
IMAGE_MAX = 7;
SUB_CARRIER = 2048;
reality = randi([0, REAL_MAX], SUB_CARRIER, 1);
image = randi([0, IMAGE_MAX], SUB_CARRIER, 1);
reality = 2 * (reality – (REAL_MAX/2.0));
image = 2 * (image – (IMAGE_MAX/2.0));
complex = reality + j * image;
fcomponent = ifft(complex);
fcomponent_real = real(fcomponent);
fcomponent_image = imag(fcomponent);
[fcomponent_image_max, fcomponent_image_index] = max(fcomponent_image);
[fcomponent_real_max, fcomponent_real_index] = max(fcomponent_real);
%fcomponent_real_max < 0.4
%fcomponent_image_max < 0.4