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'); > > %read real > 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'); > > %read imag > 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 > > _______________________________________________ > Discuss-gnuradio mailing list > Discuss-gnuradio@gnu.org > http://lists.gnu.org/mailman/listinfo/discuss-gnuradio _______________________________________________ Discuss-gnuradio mailing list Discuss-gnuradio@gnu.org http://lists.gnu.org/mailman/listinfo/discuss-gnuradio