function [sym_out, H, W] = ofdm_rx(filename, foff, SNR, with_cir) % % Example: ofdm_rx('drm-15435-if.wav', -174.65, -400, 0) % Example: ofdm_tx(40, 1) % ofdm_rx('xv.wav', 0, -400, 0) % or ofdm_rx('yv.wav', 0, -400, 0) close all; drm_mode = 'B'; drm_bw = '10k'; [ofdm_drm_params, ofdm_spec_occ] = drm_params(drm_mode, drm_bw); pre_mix = 0; fs = 12000; N = 256; Ng = 64; [carrier_pilot, phi_pilot, mag_pilot] = getRefFreq(drm_mode); [carrier_time, phi_time, mag_time] = getRefTime(drm_mode); h_cir = [0 0 .1 -.2 .5 .2 -.1 0 0 ]; % Generate signal [xwav fs_ nbits] = wavread(filename); [len ndim] = size(xwav); if (ndim == 2) fprintf('Mode: Baseband\n'); x = xwav(:, 1) + j*xwav(:, 2); x = x.*exp(-j*(2*pi*(foff/fs_)*(0:len-1)')); elseif (ndim == 1) fprintf('Mode: Passband\n'); x = xwav.*exp(-j*(2*pi*(0.25-foff/fs_)*(0:len-1)')); hlp = FIRCalcLowpass(12000/fs_, 15); x = filter(hlp, 1, x); % Downsample x = x(1:4:length(x)); else error('Cannot read file!'); end if with_cir x = filter(h_cir, 1, x); end x = x - mean(x); x = x./max(abs(x)); xout = [real(x) imag(x)]; wavwrite(xout,fs,nbits,'ofdm_rx.wav'); x = awgn(x, SNR, 'measured'); K = fix((length(x))/(N+Ng))-1; % Timing coarse cp_off = 0; cp_off_ = []; if 1 fprintf('Coarse timing estimation\n'); Z = 0; for k=1:20 xp = x((k-1)*(N+Ng)+1:k*(N+Ng)); [cp_off, Nd, valid, Z] = timing_coarse(xp, N, Ng, Ng, Z); if (valid) cp_off_ = [cp_off_ cp_off]; end end; cp_off = round(median(cp_off_)) Nd = Nd end fdet_coarse_Z = 0; Z_cfa_pre = 0; df_i_ = []; valid_latency_count = 20; if 1 fprintf('Coarse integer CFO estimation\n'); % Integer CFO coarse for k=1:200 xp = x((k-1)*(N+Ng)+cp_off+1:k*(N+Ng)+cp_off); [d_bin, valid, fdet_coarse_Z] = cfo_coarse_int(xp(Ng+1:N+Ng), N, carrier_pilot, 11, fdet_coarse_Z); if valid df_i = -d_bin(1)/N*fs; if valid_latency_count > 0 valid_latency_count = valid_latency_count - 1; else break; end end end; end fprintf('Coarse fractional CFO estimation\n'); % CFO coarse df_f_ = []; for k=1:200 xp = x((k-1)*(N+Ng)+cp_off+1:k*(N+Ng)+cp_off); [domega_f, Z_cfa_pre] = cfo_coarse_fract(xp, N, Ng, Ng, Nd, Z_cfa_pre); df_f_ = [df_f_ domega_f*fs]; end; df_coarse = df_i + mean(df_f_(10:200)) df_coarse_ = df_i + df_f_; if pre_mix x1 = x.*exp(j*(2*pi*df_coarse/fs.*(0:length(x)-1)')); df_track = 0; else x1 = x; df_track = df_coarse; end % CFO Fine fprintf('Fine CFO estimation\n'); fprintf('Receive Symbols\n'); Xlast = []; df_fine = 0; df_fine_ = []; df_track_ = []; kn = fs/(2*pi*(1+Ng/N))/N; x_ = []; Hp_ = []; Z_ = []; phi = 0.0; bin_track = 1; sym_pilot = exp(j*2*pi*phi_pilot'/1024); bin_pilot = c2i(N, carrier_pilot); for k=1:K, xp = x1((k-1)*(N+Ng)+cp_off+1:k*(N+Ng)+cp_off); xp = xp.*exp(j*(2*pi*df_track/fs*(0:N+Ng-1)' + phi)); phi = phi + 2*pi*df_track/fs*(N+Ng); xp = xp(Ng+1:N+Ng); x_ = [x_' xp']'; X = fft(xp); if (~isempty(Xlast)) Z = Xlast .* conj(X); df_fine = kn*angle(Z(bin_pilot)); df_fine_ = [df_fine_ df_fine]; phi_p = angle(X(bin_pilot)); mag_p = abs(X(bin_pilot)); df_track = df_track + 0.1*mean(df_fine(bin_track)); df_track_ = [df_track_ df_track]; Hp = X(bin_pilot)./conj(sym_pilot); Hp_ = [Hp_ Hp]; Z_ = [Z_ X]; end Xlast = X; end if ~isempty(cp_off_) figure; plot(0:length(cp_off_)-1, cp_off_, 0:length(cp_off_)-1, cp_off*ones(size(cp_off_)), 'r-'); grid; title('cp_{off}') end df_track_ = df_track_'; figure; subplot(3, 1, 1) plot(0:length(df_coarse_)-1, df_coarse_); grid; title('df_{coarse}') subplot(3, 1, 2) plot(0:length(df_track_)-1, df_track_); grid; title('df_{track}') subplot(3, 1, 3) plot(0:length(df_fine_)-1, df_fine_); grid; title('df_{fine}') figure; Z_pilot = Z_(bin_pilot, 200:length(Z_))'; plot(real(Z_pilot), imag(Z_pilot), '+'); grid; title('SymPilot_{Freq}'); maxZ = max(max(abs(Z_pilot))); if (maxZ < 1) axis([-1 1 -1 1]); else axis([-maxZ maxZ -maxZ maxZ]); end %% Detect start of DRM frame bins = c2i(N, carrier_time); kc_max = -1000; n_max = 0; skip_syms = 15*4; for n=0:15-1 frame_timing_Z = 0; k = skip_syms+n; for m=1:2 [kc valid frame_timing_Z] = timing_frame(Z_(bins, k)', bins, 15, frame_timing_Z); k = k + 15; end if valid if kc > kc_max n_max = n; kc_max = kc; end end end frame_start = n_max figure; start = skip_syms+frame_start; Z_timing = Z_(bins, start:15:length(Z_))'; plot(real(Z_timing), imag(Z_timing), '+'); grid; title('SymPilot_{Time}'); maxZ = max(max(abs(Z_timing))); if (maxZ < 1) axis([-1 1 -1 1]); else axis([-maxZ maxZ -maxZ maxZ]); end W = calcWiener(drm_mode, drm_bw); figure; % Detect scattered gain pilots symbol_counter = 0; win_count = 0; H = []; sym_H = []; sym_out = []; kk = 1; symbols_per_frame = ofdm_drm_params.nspf; symbols_to_delay = ofdm_drm_params.y; frames_per_window = 2*ofdm_drm_params.y; H_gain_cell = cell (frames_per_window, 1); H_gain_carriers_cell = cell (frames_per_window, 1); H_raw = zeros(length(ofdm_spec_occ.kmin:ofdm_spec_occ.kmax),1); fac_cell_list = ... { [], [], [13, 25, 43, 55, 67], [15, 27, 45, 57, 69], [17, 29, 47, 59, 71], [19, 31, 49, 61, 73], [9, 21, 33, 51, 63, 75], [11, 23, 35, 53, 65, 77], [13, 25, 37, 55, 67, 79], [15, 27, 39, 57, 69, 81], [17, 29, 41, 59, 71, 83], [19, 31, 43, 61, 73], [21, 33, 45, 63, 75], [23, 35, 47, 65, 77], [] }; carriers = ofdm_spec_occ.kmin:ofdm_spec_occ.kmax; carrier_indexes = c2i(N, carriers); for k=start:length(Z_) %shifted symbol index nn = rem(k-1-symbols_to_delay + symbols_per_frame, symbols_per_frame); n = rem(nn, ofdm_drm_params.y); m = floor(nn/ofdm_drm_params.y); [carrier_gain, phi_gain, mag_gain] = getRefGain(ofdm_drm_params, ofdm_spec_occ, symbol_counter); carrier_gain_bins = c2i(N, carrier_gain); Hp = Z_(carrier_gain_bins, k)./(mag_gain.*exp(j*2*pi*phi_gain/1024)).'; H_raw(carrier_gain_bins) = Hp; H_gain_cell{win_count+1} = transpose(Z_(carrier_gain_bins, k)./(mag_gain.*exp(j*2*pi*phi_gain/1024)).'); ii = 1+mod(n+(0:frames_per_window-1), frames_per_window); H_gain = [H_gain_cell{ii}]; H_gain_carriers_cell{win_count+1} = carrier_gain; str = sprintf('Frame %d, SymCount %d, winCount %d, n=%d', k, symbol_counter, win_count, n); if length(H_gain) == 208 H = H_gain*W{n+1}; ZZ = Z_(carrier_indexes, k).'; sym_eq = ZZ ./ H; sym_out(:, kk) = sym_eq; if 1 H_raw(1:2:N) = H_raw(2:2:N); subplot(2, 1, 1) plot(carriers, abs(H_raw(carrier_indexes)), 'b-', carriers, abs(H), 'r-'); grid; title('abs(H)'); axis([ofdm_spec_occ.kmin ofdm_spec_occ.kmax 0 15+0*max(abs(H))]); title(str); subplot(2, 1, 2) plot(carriers, angle(H_raw(carrier_indexes)), 'b-', carriers, angle(H), 'r-'); grid; title('phi(H)'); axis([ofdm_spec_occ.kmin ofdm_spec_occ.kmax -4 4]); title(str); pause(0.01); else fac_c = fac_cell_list{symbol_counter+1}; if (~isempty(fac_c)) fac_i = fac_c - ofdm_spec_occ.kmin + 1; hold on; plot(sym_eq(fac_i), '.', 'MarkerSize', 4); pause(0.01); hold off; grid; title('FAC'); axis([-1.5 1.5 -1.5 1.5]); end end end kk = kk + 1; win_count = mod(win_count+1, frames_per_window); symbol_counter = mod(symbol_counter + 1, symbols_per_frame); end function Y = spec_order(N, X) Y = [X(N/2+1:N)' X(1:N/2)']';