[Top][All Lists]

## Re: [Discuss-gnuradio] OFDM demodulation problem / example video

 From: Jens Elsner Subject: Re: [Discuss-gnuradio] OFDM demodulation problem / example video Date: Wed, 5 Apr 2006 17:40:42 +0200 User-agent: Mutt/1.3.28i

```Achilleas,

my estimate is based on frequency domain correlation. Just count the
offset of the maximum (o). Then estimate the fractional offset (fo) by taking
the
value left (l) and right (r) of the maximum and calculate fo = (r-l)/(r+l).
To compensate substract the resulting frequency offset (o+fo) from the
received signal. Works as long the channel doesn't interfere too much.

Jens

On Tue, Apr 04, 2006 at 07:52:58PM -0400, Achilleas Anastasopoulos wrote:
> Jens,
>
> I used a complete ad-hoc method for automatic frequency estimation:
> tracing the minimum ratio of the power of DC over the total power of the
> remaining channels, averaged over all symbols in a frame.
> Your estimate seems quite good!
>
> I atatch the .m file
>
> I have not tried anything with the timing yet...
>
> Achilleas

> clear all;
> close all;
>
> % dab.dat contains data sampled from the USRP 2 MHz (decimation factor 32)
>
> fid = fopen('dab_ml.dat', 'r');
> %skip 50000 samples - bug in gnuradio?
> d = fread(fid, 50000, 'float32');
>
> d_re = fread(fid, 1000000, 'float32',4);
> fclose(fid);
>
> fid = fopen('dab_ml.dat', 'r');
> %skip 50001 samples - bug in gnuradio?
> d = fread(fid, 50001, 'float32');
>
> d_im = fread(fid, 1000000, 'float32', 4);
> fclose(fid);
>
> e = d_re + j*d_im;
> clear d*
>
> % not all data need, file too big
> chunk = e(1:700000);
>
> % Generate phase reference symbol, frequency domain
> p = prs;
>
> % resampling
> chunk_resamp = resample(chunk, 2048, 2000);
>
> % this code is used to look for the synch frame manually
> if 1==0
>
> glob_max = 0;
> for k = 3.6*105:length(chunk_resamp)
>     data = chunk_resamp(k:k+2048);
>     f = fftshift(fft(data,2048));
>
>     xc = abs(xcorr(p,f));
>
>     [m offset] = max(xc);
>     if m > 107
>         disp('found synch frame');
>         plot(xc);
>         axis([0 4000 0 2*107]);
>         drawnow
>         %pause
>         k
>     end
>     if m > glob_max
>         offset_max = offset
>         glob_max = m
>         glob_max_k = k
>         plot(xc);
>         axis([0 4000 0 2*107]);
>         drawnow
>         %pause
>     end
>     drawnow
> end
>
> end
>
> % decode one frame (75 symbols + synch symbol)
> for o = 0:75
>
> % start of frame (after the end of null period), found manually
> start_resamp = 168988;
> s0=start_resamp-2656-504; % my start (begining of NULL)
>
> %get the data for one OFDM symbol (2048 samples), skip guard intervall (504
> %samples)
> data_resamp =
> chunk_resamp(start_resamp+(504+2048)*o:start_resamp+2048-1+(504+2048)*o);
>
> % compensate frequency offset - done manually (how?)
> data2_resamp =
> data_resamp.*exp(j*linspace(0,2*pi*(0.385-8),length(data_resamp)).');
>
> % fft to decode data
> d_resamp = fftshift(fft(data2_resamp,2048));
>
> % only 1536 subcarriers + DC carrier to display
> %data = d_resamp(256:1792);
> data = d_resamp(257:1793);
>
> % first OFDM symbol is used for synchronization - no data.
> % if o == 0
> %     plot(abs(d_resamp).^2);
> %     drawnow
> %     pause
> % end
>
> % display decoded data symbols, including DC carrier
> if o ~= 0
>     dem = data ./ data_l ;
>     %dem = data .* conj(data_l) ;
>     %dem=dem./abs(dem);
>
>     plot(real(dem), imag(dem), 'o');
>     axis([-3 3 -3 3]);
>
>     drawnow
>
>     pause
> end
>
> % DAB uses pi/4 DPSK, last frame is reference (I only see DQPSK in the
> standard)
> data_l = data;
>
>
> end
>

> _______________________________________________