[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
This commit is contained in:
+130
-95
@@ -5,70 +5,18 @@ function ofdm_rx(filename, foff, flip_spec, SNR, show_H)
|
|||||||
% Example: ofdm_rx('xv.wav', 0, 0, 400, 1)
|
% Example: ofdm_rx('xv.wav', 0, 0, 400, 1)
|
||||||
% or ofdm_rx('yv.wav', 0, 0, 400, 1)
|
% or ofdm_rx('yv.wav', 0, 0, 400, 1)
|
||||||
|
|
||||||
|
% --------------------------------------------------------------
|
||||||
close all;
|
close all;
|
||||||
|
|
||||||
|
% --------------------------------------------------------------
|
||||||
|
% fixed stuff
|
||||||
|
% --------------------------------------------------------------
|
||||||
MIN_ABS_H = 1e-10;
|
MIN_ABS_H = 1e-10;
|
||||||
|
|
||||||
drm_mode = 'B';
|
drm_mode = 'B';
|
||||||
drm_bw = '10k';
|
drm_bw = '10k';
|
||||||
|
|
||||||
[ofdm_drm_params, ofdm_spec_occ] = drm_params(drm_mode, drm_bw);
|
% Mode 'B'
|
||||||
|
|
||||||
[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);
|
|
||||||
|
|
||||||
fac_cell_list = ...
|
fac_cell_list = ...
|
||||||
{
|
{
|
||||||
[],
|
[],
|
||||||
@@ -88,30 +36,106 @@ 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;
|
fileCunkCounter = 0;
|
||||||
phi_xwav = 0;
|
phi_mix = 0;
|
||||||
|
phi_foff = 0;
|
||||||
df_track = 0;
|
df_track = 0;
|
||||||
df_track_ = [];
|
df_track_ = [];
|
||||||
|
filter_z = [];
|
||||||
max_H_plot = 0;
|
max_H_plot = 0;
|
||||||
symbol_count = -1;
|
symbol_count = -1;
|
||||||
|
|
||||||
fileRemain = wav_size;
|
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;
|
n0 = fileCunkCounter*fileChunkSize+1;
|
||||||
n1 = (fileCunkCounter+1)*fileChunkSize;
|
n1 = (fileCunkCounter+1)*fileChunkSize;
|
||||||
[xwav] = wavread(filename, [n0 n1]);
|
[wav_x] = wavread(filename, [n0 n1]);
|
||||||
|
|
||||||
if (~isModePassband)
|
if (~isModePassband)
|
||||||
xwav = xwav(:, 1) + j*xwav(:, 2);
|
wav_x = wav_x(:, 1) + j*wav_x(:, 2);
|
||||||
end
|
end
|
||||||
xwav = xwav - mean(xwav);
|
|
||||||
|
|
||||||
x = xwav.*exp(-j*(2*pi*omega_xwav*(0:fileChunkSize-1)' + phi_xwav));
|
% ToDo: Remove DC
|
||||||
phi_xwav = mod(phi_xwav + 2*pi*omega_xwav*fileChunkSize, 2*pi);
|
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
|
if flip_spec
|
||||||
x = conj(x);
|
x = conj(x);
|
||||||
@@ -120,12 +144,8 @@ while(fileRemain > fileChunkSize)
|
|||||||
% add noise
|
% add noise
|
||||||
x = awgn(x, SNR);
|
x = awgn(x, SNR);
|
||||||
|
|
||||||
if (isModePassband)
|
% Write to buffer
|
||||||
[x, filter_z] = filter(filter_h, 1, x, filter_z);
|
buf_recv.write(x);
|
||||||
buf_recv.write(x(1:4:length(x)));
|
|
||||||
else
|
|
||||||
buf_recv.write(x);
|
|
||||||
end
|
|
||||||
|
|
||||||
% --------------------------------------------------------------
|
% --------------------------------------------------------------
|
||||||
% Timing coarse
|
% Timing coarse
|
||||||
@@ -136,22 +156,24 @@ while(fileRemain > fileChunkSize)
|
|||||||
end
|
end
|
||||||
|
|
||||||
x = buf_recv.read(N+Ng);
|
x = buf_recv.read(N+Ng);
|
||||||
[timingCoarse.cp_off, timingCoarse.Nd, valid, timingCoarse.Z] = timing_coarse(x, N, Ng, Ng, timingCoarse.Z);
|
if ~isempty(x)
|
||||||
if (valid)
|
[timingCoarse.cp_off, timingCoarse.Nd, valid, timingCoarse.Z] = timing_coarse(x, N, Ng, Ng, timingCoarse.Z);
|
||||||
timingCoarse.cp_off_ = [timingCoarse.cp_off_ timingCoarse.cp_off];
|
if (valid)
|
||||||
if (timingCoarse.sync_counter > 0)
|
timingCoarse.cp_off_ = [timingCoarse.cp_off_ timingCoarse.cp_off];
|
||||||
timingCoarse.sync_counter = timingCoarse.sync_counter - 1;
|
if (timingCoarse.sync_counter > 0)
|
||||||
else
|
timingCoarse.sync_counter = timingCoarse.sync_counter - 1;
|
||||||
timingCoarse.sync = 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
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -285,8 +307,6 @@ while(fileRemain > fileChunkSize)
|
|||||||
H_raw = zeros(length(carriers),1);
|
H_raw = zeros(length(carriers),1);
|
||||||
|
|
||||||
fprintf('Channel estimation and symbol reception\n');
|
fprintf('Channel estimation and symbol reception\n');
|
||||||
figure(100);
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Z = transpose(buf_Z.read(N));
|
Z = transpose(buf_Z.read(N));
|
||||||
@@ -313,6 +333,7 @@ while(fileRemain > fileChunkSize)
|
|||||||
|
|
||||||
% Get the correctly delayed symbols
|
% Get the correctly delayed symbols
|
||||||
Z = buf_Z.readAt(N, -N*(symbols_to_delay+1));
|
Z = buf_Z.readAt(N, -N*(symbols_to_delay+1));
|
||||||
|
|
||||||
sym = Z(carrier_indexes).';
|
sym = Z(carrier_indexes).';
|
||||||
|
|
||||||
% Get the correctly delayed raw channel estimate
|
% Get the correctly delayed raw channel estimate
|
||||||
@@ -368,7 +389,7 @@ while(fileRemain > fileChunkSize)
|
|||||||
hold off;
|
hold off;
|
||||||
|
|
||||||
pause(0.01);
|
pause(0.01);
|
||||||
else
|
elseif (equalizer.sync)
|
||||||
fac_c = fac_cell_list{mod(equalizer.s-symbols_to_delay, symbols_per_frame)+1};
|
fac_c = fac_cell_list{mod(equalizer.s-symbols_to_delay, symbols_per_frame)+1};
|
||||||
if (~isempty(fac_c))
|
if (~isempty(fac_c))
|
||||||
fac_i = fac_c - ofdm_spec_occ.kmin + 1;
|
fac_i = fac_c - ofdm_spec_occ.kmin + 1;
|
||||||
@@ -387,11 +408,13 @@ while(fileRemain > fileChunkSize)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
% --------------------------------------------------------------
|
|
||||||
fileRemain = fileRemain - fileChunkSize;
|
fileRemain = fileRemain - fileChunkSize;
|
||||||
fileCunkCounter = fileCunkCounter + 1;
|
fileCunkCounter = fileCunkCounter + 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
% --------------------------------------------------------------
|
||||||
|
% Output
|
||||||
|
% --------------------------------------------------------------
|
||||||
figure;
|
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}')
|
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-');
|
plot(x-1,y, 'r-');
|
||||||
hold off;
|
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)];
|
xout = [real(x) imag(x)];
|
||||||
wavwrite(xout,fs,nbits,'rx_x.wav');
|
wavwrite(xout,fs,nbits,'rx_x.wav');
|
||||||
|
|
||||||
% Modulate on carrier
|
% Modulate on carrier
|
||||||
|
fprintf('.');
|
||||||
xup = upsample(x, 4);
|
xup = upsample(x, 4);
|
||||||
hlp = FIRCalcLowpass(0.25, 129);
|
hlp = FIRCalcLowpass(0.25, 129);
|
||||||
|
|
||||||
|
fprintf('.');
|
||||||
xup = filter(hlp, 1, xup);
|
xup = filter(hlp, 1, xup);
|
||||||
|
|
||||||
y = exp(j*2*pi.*(0:length(xup)-1)'*0.25) .* xup;
|
y = exp(j*2*pi.*(0:length(xup)-1)'*0.25) .* xup;
|
||||||
|
|
||||||
wavwrite(y,fs4,nbits,'rx_y.wav');
|
fprintf('.');
|
||||||
|
wavwrite(y,4*fs,nbits,'rx_y.wav');
|
||||||
end
|
fprintf(' done\n');
|
||||||
|
|
||||||
|
% --------------------------------------------------------------
|
||||||
function Y = spec_order(N, X)
|
function Y = spec_order(N, X)
|
||||||
Y = [X(N/2+1:N)' X(1:N/2)']';
|
Y = [X(N/2+1:N)' X(1:N/2)']';
|
||||||
|
|||||||
Reference in New Issue
Block a user