From 7c1bd55a5ea3cf98ea910ed56185d488d4f8f6b1 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sun, 3 May 2015 16:51:25 +0000 Subject: [PATCH] [RX] - write wavs - disabled DC offset correction. Adds noise to baseband signal - cleaned up git-svn-id: http://moon:8086/svn/matlab/trunk@73 801c6759-fa7c-4059-a304-17956f83a07c --- ofdm/ofdm_rx.m | 227 ++++++++++++++++++++++++++++--------------------- 1 file changed, 131 insertions(+), 96 deletions(-) diff --git a/ofdm/ofdm_rx.m b/ofdm/ofdm_rx.m index b39cff9..6c01540 100644 --- a/ofdm/ofdm_rx.m +++ b/ofdm/ofdm_rx.m @@ -5,70 +5,18 @@ function ofdm_rx(filename, foff, flip_spec, SNR, show_H) % Example: ofdm_rx('xv.wav', 0, 0, 400, 1) % or ofdm_rx('yv.wav', 0, 0, 400, 1) +% -------------------------------------------------------------- close all; +% -------------------------------------------------------------- +% fixed stuff +% -------------------------------------------------------------- MIN_ABS_H = 1e-10; drm_mode = 'B'; drm_bw = '10k'; -[ofdm_drm_params, ofdm_spec_occ] = drm_params(drm_mode, drm_bw); - -[carrier_pilot, phi_pilot, mag_pilot] = getRefFreq(drm_mode); -[carrier_time, phi_time, mag_time] = getRefTime(drm_mode); -[W_syms, W_pilots] = calcWiener(drm_mode, drm_bw); -filter_h = FIRCalcLowpass(0.25, 15); - -N = ofdm_drm_params.nu; -Ng = ofdm_drm_params.ng; -symbols_per_frame = ofdm_drm_params.nspf; -symbols_to_delay = ofdm_drm_params.y; -frames_per_window = 2*ofdm_drm_params.y; -carriers = ofdm_spec_occ.kmin:ofdm_spec_occ.kmax; -carrier_indexes = c2i(N, carriers); - -% Read wav file -[fsize fs4] = wavread(filename, 'size'); -[xwav, fs4, nbits] = wavread(filename, 0); -wav_numCh = fsize(2); -wav_size = fsize(1); - -fs = fix(fs4/4); - -isModePassband = 0; -if (wav_numCh == 1) - fprintf('Mode: Passband\n'); - omega_xwav = (0.25-foff/fs4); - isModePassband = 1; -elseif (wav_numCh == 2) - fprintf('Mode: Baseband\n'); - omega_xwav = (foff/fs4); -else - error('Cannot read file'); -end - -buf_recv = buffer(); -buf_Z = buffer(); - - -% Timing coarse stuff -timingCoarse = struct('Z', 0, 'started', 0, 'sync_counter', 20, 'sync', 0, 'cp_off', 0, 'cp_off_', [], 'Nd', 0); - -% CFO coarse integer stuff -cfoCoarseInteger = struct('Z', 0, 'started', 0, 'sync_counter', 20, 'sync', 0, 'f_err', 0); - -% CFO coarse fractional stuff -cfoCoarseFractional = struct('Z', 0, 'started', 0, 'sync_counter', 20, 'sync', 0, 'f_err', 0, 'f_err_', [], 'df', 0, 'df_', []); - -% CFO Fine stuff -cfoFine = struct('Z', 0, 'started', 0, 'sync_counter', 20, 'sync', 0, 'f_err', 0, 'f_err_', [], 'df', 0, 'df_', [], 'Xlast', [], 'phi', 0, 'bin_track', 1); - -% Frame timing stuff -frameTiming = struct('Z', 0, 'started', 0, 'sync_counter', 20, 'sync', 0, 'kc_max', -1000, 'n', 0, 'n_max', 0); - -% Equalization stuff -equalizer = struct('Z', 0, 'started', 0, 'sync_counter', 20, 'sync', 0, 'sync_frame_num', 0, 'f_err', 1000, 'f_err_', [], 's', 0, 'm', 0, 'kk', 1, 'eps_abs_h', MIN_ABS_H); - +% Mode 'B' fac_cell_list = ... { [], @@ -88,44 +36,116 @@ fac_cell_list = ... [] }; -filter_z = []; -fileChunkSize = N; +% -------------------------------------------------------------- +% Precalculation +% -------------------------------------------------------------- +[ofdm_drm_params, ofdm_spec_occ] = drm_params(drm_mode, drm_bw); + +[carrier_pilot, phi_pilot, mag_pilot] = getRefFreq(drm_mode); +[carrier_time, phi_time, mag_time] = getRefTime(drm_mode); +[W_syms, W_pilots] = calcWiener(drm_mode, drm_bw); +filter_h = FIRCalcLowpass(0.25, 15); + +N = ofdm_drm_params.nu; +Ng = ofdm_drm_params.ng; +symbols_per_frame = ofdm_drm_params.nspf; +symbols_to_delay = ofdm_drm_params.y; +frames_per_window = 2*ofdm_drm_params.y; +carriers = ofdm_spec_occ.kmin:ofdm_spec_occ.kmax; +carrier_indexes = c2i(N, carriers); + +% Read wav file +[wav_size wav_fs] = wavread(filename, 'size'); +[wav_x, wav_fs, nbits] = wavread(filename, 0); +wav_numCh = wav_size(2); +wav_size = wav_size(1); + +% -------------------------------------------------------------- +% Determine data mode +% -------------------------------------------------------------- +isModePassband = 0; +if (wav_numCh == 1) + fprintf('Mode: Passband\n'); + isModePassband = 1; + fs = fix(wav_fs/4); + fileChunkSize = N; % Fix: don't leave loop, if file has been consumed. There may be samples left in buf_recv to process + +elseif (wav_numCh == 2) + fprintf('Mode: Baseband\n'); + fs = wav_fs; + fileChunkSize = N/4; % Fix: don't leave loop, if file has been consumed. There may be samples left in buf_recv to process +else + error('Cannot read file'); +end + +% -------------------------------------------------------------- +% Timing coarse stuff +timingCoarse = struct('Z', 0, 'started', 0, 'sync_counter', 20, 'sync', 0, 'cp_off', 0, 'cp_off_', [], 'Nd', 0); + +% CFO coarse integer stuff +cfoCoarseInteger = struct('Z', 0, 'started', 0, 'sync_counter', 20, 'sync', 0, 'f_err', 0); + +% CFO coarse fractional stuff +cfoCoarseFractional = struct('Z', 0, 'started', 0, 'sync_counter', 20, 'sync', 0, 'f_err', 0, 'f_err_', [], 'df', 0, 'df_', []); + +% CFO Fine stuff +cfoFine = struct('Z', 0, 'started', 0, 'sync_counter', 20, 'sync', 0, 'f_err', 0, 'f_err_', [], 'df', 0, 'df_', [], 'Xlast', [], 'phi', 0, 'bin_track', 1); + +% Frame timing stuff +frameTiming = struct('Z', 0, 'started', 0, 'sync_counter', 20, 'sync', 0, 'kc_max', -1000, 'n', 0, 'n_max', 0); + +% Equalization stuff +equalizer = struct('Z', 0, 'started', 0, 'sync_counter', 20, 'sync', 0, 'sync_frame_num', 0, 'f_err', 1000, 'f_err_', [], 's', 0, 'm', 0, 'kk', 1, 'eps_abs_h', MIN_ABS_H); + fileCunkCounter = 0; -phi_xwav = 0; +phi_mix = 0; +phi_foff = 0; df_track = 0; df_track_ = []; +filter_z = []; max_H_plot = 0; symbol_count = -1; fileRemain = wav_size; -while(fileRemain > fileChunkSize) +buf_recv = buffer(); +buf_Z = buffer(); + +% -------------------------------------------------------------- +% Main loop +% -------------------------------------------------------------- +while(fileRemain > fileChunkSize) % ToDo: don't leave loop, if file has been consumed. There may be samples left in buf_recv to process n0 = fileCunkCounter*fileChunkSize+1; n1 = (fileCunkCounter+1)*fileChunkSize; - [xwav] = wavread(filename, [n0 n1]); + [wav_x] = wavread(filename, [n0 n1]); if (~isModePassband) - xwav = xwav(:, 1) + j*xwav(:, 2); + wav_x = wav_x(:, 1) + j*wav_x(:, 2); end - xwav = xwav - mean(xwav); - x = xwav.*exp(-j*(2*pi*omega_xwav*(0:fileChunkSize-1)' + phi_xwav)); - phi_xwav = mod(phi_xwav + 2*pi*omega_xwav*fileChunkSize, 2*pi); + % ToDo: Remove DC + x = wav_x; + + if (isModePassband) + x = x.*exp(-j*(2*pi*0.25*(0:length(x)-1)' + phi_mix)); + phi_mix = mod(phi_mix + 2*pi*0.25*length(x), 2*pi); + [x, filter_z] = filter(filter_h, 1, x, filter_z); + x = x(1:4:length(x)); + end + + x = x.*exp(-j*(2*pi*(foff/fs)*(0:length(x)-1)' + phi_foff)); + phi_foff = mod(phi_foff + 2*pi*(foff/fs)*length(x), 2*pi); if flip_spec x = conj(x); end - + % add noise x = awgn(x, SNR); - if (isModePassband) - [x, filter_z] = filter(filter_h, 1, x, filter_z); - buf_recv.write(x(1:4:length(x))); - else - buf_recv.write(x); - end + % Write to buffer + buf_recv.write(x); % -------------------------------------------------------------- % Timing coarse @@ -136,22 +156,24 @@ while(fileRemain > fileChunkSize) end x = buf_recv.read(N+Ng); - [timingCoarse.cp_off, timingCoarse.Nd, valid, timingCoarse.Z] = timing_coarse(x, N, Ng, Ng, timingCoarse.Z); - if (valid) - timingCoarse.cp_off_ = [timingCoarse.cp_off_ timingCoarse.cp_off]; - if (timingCoarse.sync_counter > 0) - timingCoarse.sync_counter = timingCoarse.sync_counter - 1; - else - timingCoarse.sync = 1; + if ~isempty(x) + [timingCoarse.cp_off, timingCoarse.Nd, valid, timingCoarse.Z] = timing_coarse(x, N, Ng, Ng, timingCoarse.Z); + if (valid) + timingCoarse.cp_off_ = [timingCoarse.cp_off_ timingCoarse.cp_off]; + if (timingCoarse.sync_counter > 0) + timingCoarse.sync_counter = timingCoarse.sync_counter - 1; + else + timingCoarse.sync = 1; + end + end; + if (timingCoarse.sync) + timingCoarse.cp_off = round(median(timingCoarse.cp_off_)); + + % Reset buffer to Cp offset + buf_recv.setReadIndex(timingCoarse.cp_off); + + fprintf(' (cp_off=%d, Nd=%d)\n', timingCoarse.cp_off, timingCoarse.Nd); end - end; - if (timingCoarse.sync) - timingCoarse.cp_off = round(median(timingCoarse.cp_off_)); - - % Reset buffer to Cp offset - buf_recv.setReadIndex(timingCoarse.cp_off); - - fprintf(' (cp_off=%d, Nd=%d)\n', timingCoarse.cp_off, timingCoarse.Nd); end end @@ -285,8 +307,6 @@ while(fileRemain > fileChunkSize) H_raw = zeros(length(carriers),1); fprintf('Channel estimation and symbol reception\n'); - figure(100); - end Z = transpose(buf_Z.read(N)); @@ -313,6 +333,7 @@ while(fileRemain > fileChunkSize) % Get the correctly delayed symbols Z = buf_Z.readAt(N, -N*(symbols_to_delay+1)); + sym = Z(carrier_indexes).'; % Get the correctly delayed raw channel estimate @@ -368,7 +389,7 @@ while(fileRemain > fileChunkSize) hold off; pause(0.01); - else + elseif (equalizer.sync) fac_c = fac_cell_list{mod(equalizer.s-symbols_to_delay, symbols_per_frame)+1}; if (~isempty(fac_c)) fac_i = fac_c - ofdm_spec_occ.kmin + 1; @@ -387,11 +408,13 @@ while(fileRemain > fileChunkSize) end end end - % -------------------------------------------------------------- fileRemain = fileRemain - fileChunkSize; fileCunkCounter = fileCunkCounter + 1; end +% -------------------------------------------------------------- +% Output +% -------------------------------------------------------------- figure; plot(0:length(timingCoarse.cp_off_)-1, timingCoarse.cp_off_, 0:length(timingCoarse.cp_off_)-1, timingCoarse.cp_off*ones(size(timingCoarse.cp_off_)), 'r-'); grid; title('cp_{off}') @@ -420,20 +443,32 @@ y = [a(3) a(4)]; plot(x-1,y, 'r-'); hold off; -if 0 +% -------------------------------------------------------------- +% Write wave files +% -------------------------------------------------------------- +fprintf('Writing wav files '); + +buf_recv.setReadIndex(0); +x = buf_recv.read(buf_recv.len()); + +fprintf('.'); xout = [real(x) imag(x)]; wavwrite(xout,fs,nbits,'rx_x.wav'); % Modulate on carrier +fprintf('.'); xup = upsample(x, 4); hlp = FIRCalcLowpass(0.25, 129); + +fprintf('.'); xup = filter(hlp, 1, xup); y = exp(j*2*pi.*(0:length(xup)-1)'*0.25) .* xup; -wavwrite(y,fs4,nbits,'rx_y.wav'); - -end +fprintf('.'); +wavwrite(y,4*fs,nbits,'rx_y.wav'); +fprintf(' done\n'); +% -------------------------------------------------------------- function Y = spec_order(N, X) Y = [X(N/2+1:N)' X(1:N/2)']';