git-svn-id: http://moon:8086/svn/matlab/trunk@23 801c6759-fa7c-4059-a304-17956f83a07c
303 lines
9.6 KiB
Matlab
303 lines
9.6 KiB
Matlab
% function ofdm_tx(N_frames)
|
|
function [yv xv] = ofdm_tx(N_frames, withData)
|
|
|
|
close all;
|
|
|
|
WITH_RCWIN = 1;
|
|
WITH_FREQ_REF = 1;
|
|
WITH_TIME_REF = 0;
|
|
WITH_GAIN_REF = 0;
|
|
WITH_DATA = withData;
|
|
|
|
M_QAM = 4;
|
|
RCWIN_ROLLOFF = 0.1;
|
|
|
|
% Params
|
|
fa = 48000;
|
|
fc = fa/4;
|
|
F1 = 750;
|
|
F2 = 2250;
|
|
F3 = 3000;
|
|
|
|
SPEC_OCC_4k5 = 1;
|
|
SPEC_OCC_5k0 = 2;
|
|
SPEC_OCC_9k0 = 3;
|
|
SPEC_OCC_10k = 4;
|
|
SPEC_OCC_18k = 5;
|
|
SPEC_OCC_20k = 6;
|
|
|
|
DRM_MODE_A = 1;
|
|
DRM_MODE_B = 2;
|
|
DRM_MODE_C = 3;
|
|
DRM_MODE_D = 4;
|
|
DRM_MODE_E = 5;
|
|
|
|
ofdm_spec_occ_drm(DRM_MODE_A, SPEC_OCC_4k5) = struct('spec', SPEC_OCC_4k5, 'kmin', 2, 'kmax', 102);
|
|
ofdm_spec_occ_drm(DRM_MODE_A, SPEC_OCC_5k0) = struct('spec', SPEC_OCC_5k0, 'kmin', 2, 'kmax', 114);
|
|
ofdm_spec_occ_drm(DRM_MODE_A, SPEC_OCC_9k0) = struct('spec', SPEC_OCC_9k0, 'kmin', -102, 'kmax', 102);
|
|
ofdm_spec_occ_drm(DRM_MODE_A, SPEC_OCC_10k) = struct('spec', SPEC_OCC_10k, 'kmin', -114, 'kmax', 114);
|
|
ofdm_spec_occ_drm(DRM_MODE_A, SPEC_OCC_18k) = struct('spec', SPEC_OCC_18k, 'kmin', - 98, 'kmax', 314);
|
|
ofdm_spec_occ_drm(DRM_MODE_A, SPEC_OCC_20k) = struct('spec', SPEC_OCC_20k, 'kmin', -110, 'kmax', 350);
|
|
|
|
ofdm_spec_occ_drm(DRM_MODE_B, SPEC_OCC_4k5) = struct('spec', SPEC_OCC_4k5, 'kmin', 1, 'kmax', 91);
|
|
ofdm_spec_occ_drm(DRM_MODE_B, SPEC_OCC_5k0) = struct('spec', SPEC_OCC_5k0, 'kmin', 1, 'kmax', 103);
|
|
ofdm_spec_occ_drm(DRM_MODE_B, SPEC_OCC_9k0) = struct('spec', SPEC_OCC_9k0, 'kmin', - 91, 'kmax', 91);
|
|
ofdm_spec_occ_drm(DRM_MODE_B, SPEC_OCC_10k) = struct('spec', SPEC_OCC_10k, 'kmin', -103, 'kmax', 103);
|
|
ofdm_spec_occ_drm(DRM_MODE_B, SPEC_OCC_18k) = struct('spec', SPEC_OCC_18k, 'kmin', - 87, 'kmax', 279);
|
|
ofdm_spec_occ_drm(DRM_MODE_B, SPEC_OCC_20k) = struct('spec', SPEC_OCC_20k, 'kmin', - 99, 'kmax', 311);
|
|
|
|
ofdm_spec_occ_drm(DRM_MODE_C, SPEC_OCC_4k5) = struct('spec', SPEC_OCC_4k5, 'kmin', 0, 'kmax', 0);
|
|
ofdm_spec_occ_drm(DRM_MODE_C, SPEC_OCC_5k0) = struct('spec', SPEC_OCC_5k0, 'kmin', 0, 'kmax', 0);
|
|
ofdm_spec_occ_drm(DRM_MODE_C, SPEC_OCC_9k0) = struct('spec', SPEC_OCC_9k0, 'kmin', 0, 'kmax', 0);
|
|
ofdm_spec_occ_drm(DRM_MODE_C, SPEC_OCC_10k) = struct('spec', SPEC_OCC_10k, 'kmin', - 69, 'kmax', 69);
|
|
ofdm_spec_occ_drm(DRM_MODE_C, SPEC_OCC_18k) = struct('spec', SPEC_OCC_18k, 'kmin', 0, 'kmax', 0);
|
|
ofdm_spec_occ_drm(DRM_MODE_C, SPEC_OCC_20k) = struct('spec', SPEC_OCC_20k, 'kmin', - 67, 'kmax', 213);
|
|
|
|
ofdm_spec_occ_drm(DRM_MODE_D, SPEC_OCC_4k5) = struct('spec', SPEC_OCC_4k5, 'kmin', 0, 'kmax', 0);
|
|
ofdm_spec_occ_drm(DRM_MODE_D, SPEC_OCC_5k0) = struct('spec', SPEC_OCC_5k0, 'kmin', 0, 'kmax', 0);
|
|
ofdm_spec_occ_drm(DRM_MODE_D, SPEC_OCC_9k0) = struct('spec', SPEC_OCC_9k0, 'kmin', 0, 'kmax', 0);
|
|
ofdm_spec_occ_drm(DRM_MODE_D, SPEC_OCC_10k) = struct('spec', SPEC_OCC_10k, 'kmin', - 44, 'kmax', 44);
|
|
ofdm_spec_occ_drm(DRM_MODE_D, SPEC_OCC_18k) = struct('spec', SPEC_OCC_18k, 'kmin', 0, 'kmax', 0);
|
|
ofdm_spec_occ_drm(DRM_MODE_D, SPEC_OCC_20k) = struct('spec', SPEC_OCC_20k, 'kmin', - 43, 'kmax', 135);
|
|
|
|
ofdm_spec_occ_drm(DRM_MODE_E, SPEC_OCC_4k5) = struct('spec', SPEC_OCC_4k5, 'kmin', -106, 'kmax', 106);
|
|
ofdm_spec_occ_drm(DRM_MODE_E, SPEC_OCC_5k0) = struct('spec', SPEC_OCC_5k0, 'kmin', 0, 'kmax', 0);
|
|
ofdm_spec_occ_drm(DRM_MODE_E, SPEC_OCC_9k0) = struct('spec', SPEC_OCC_9k0, 'kmin', 0, 'kmax', 0);
|
|
ofdm_spec_occ_drm(DRM_MODE_E, SPEC_OCC_10k) = struct('spec', SPEC_OCC_10k, 'kmin', 0, 'kmax', 0);
|
|
ofdm_spec_occ_drm(DRM_MODE_E, SPEC_OCC_18k) = struct('spec', SPEC_OCC_18k, 'kmin', 0, 'kmax', 0);
|
|
ofdm_spec_occ_drm(DRM_MODE_E, SPEC_OCC_20k) = struct('spec', SPEC_OCC_20k, 'kmin', 0, 'kmax', 0);
|
|
|
|
W1024{DRM_MODE_A,:,:} = [228 341 455; 455 569 683; 683 796 910; 910 0 114; 114 228 341];
|
|
W1024{DRM_MODE_B,:,:} = [512 0 512 0 512; 0 512 0 512 0; 512 0 512 0 512];
|
|
W1024{DRM_MODE_C,:,:} = [465 372 279 186 93 0 931 838 745 652; 931 838 745 652 559 465 372 279 186 93];
|
|
W1024{DRM_MODE_D,:,:} = [366 439 512 585 658 731 805 878; 731 805 878 951 0 73 146 219; 73 146 219 293 366 439 512 585];
|
|
W1024{DRM_MODE_E,:,:} = [];
|
|
Z1024{DRM_MODE_A,:,:} = [0 81 248; 18 106 106; 122 116 31; 129 129 39; 33 32 111];
|
|
Z1024{DRM_MODE_B,:,:} = [0 57 164 64 12; 168 255 161 106 118; 25 232 132 233 38];
|
|
Z1024{DRM_MODE_C,:,:} = [0 76 29 76 9 190 161 248 33 108; 179 178 83 253 127 105 101 198 250 145];
|
|
Z1024{DRM_MODE_D,:,:} = [0 240 17 60 220 38 151 101; 110 70 78 82 175 150 106 25; 165 7 252 124 253 177 197 142];
|
|
Z1024{DRM_MODE_E,:,:} = [];
|
|
Q1024{DRM_MODE_A,:,:} = [36];
|
|
Q1024{DRM_MODE_B,:,:} = [12];
|
|
Q1024{DRM_MODE_C,:,:} = [12];
|
|
Q1024{DRM_MODE_D,:,:} = [14];
|
|
Q1024{DRM_MODE_E,:,:} = [];
|
|
|
|
ofdm_params_drm(DRM_MODE_A) = struct('mode', 'MODE_A', 'nu', 288, 'ng', 32, 'nspf', 15, 'W', W1024(DRM_MODE_A), 'Z', Z1024(DRM_MODE_A), 'Q', Q1024(DRM_MODE_A));
|
|
ofdm_params_drm(DRM_MODE_B) = struct('mode', 'MODE_B', 'nu', 256, 'ng', 64, 'nspf', 15, 'W', W1024(DRM_MODE_B), 'Z', Z1024(DRM_MODE_B), 'Q', Q1024(DRM_MODE_B));
|
|
ofdm_params_drm(DRM_MODE_C) = struct('mode', 'MODE_C', 'nu', 176, 'ng', 64, 'nspf', 20, 'W', W1024(DRM_MODE_C), 'Z', Z1024(DRM_MODE_C), 'Q', Q1024(DRM_MODE_C));
|
|
ofdm_params_drm(DRM_MODE_D) = struct('mode', 'MODE_D', 'nu', 112, 'ng', 88, 'nspf', 24, 'W', W1024(DRM_MODE_D), 'Z', Z1024(DRM_MODE_D), 'Q', Q1024(DRM_MODE_D));
|
|
ofdm_params_drm(DRM_MODE_E) = struct('mode', 'MODE_E', 'nu', 27, 'ng', 3, 'nspf', 40, 'W', W1024(DRM_MODE_E), 'Z', Z1024(DRM_MODE_E), 'Q', Q1024(DRM_MODE_E));
|
|
|
|
ofdm_params = ofdm_params_drm(DRM_MODE_B);
|
|
ofdm_spec_occ = ofdm_spec_occ_drm(DRM_MODE_B, SPEC_OCC_10k);
|
|
|
|
ofdm_params_mode = ofdm_params.mode
|
|
ofdm_spec_occ_kmin = ofdm_spec_occ.kmin
|
|
ofdm_spec_occ_kmax = ofdm_spec_occ.kmax
|
|
|
|
T = 4/fa;
|
|
Tu = ofdm_params.nu * T
|
|
Tg = ofdm_params.ng * T
|
|
Ts = Tu+Tg
|
|
Ng = round(Tg*fa)
|
|
Nu = round(Tu*fa)
|
|
Ns = round(Ts*fa)
|
|
N_fft = Nu
|
|
SubCarrierspacing_HZ = fa/N_fft
|
|
|
|
% TX window
|
|
[rcwin Nt] = txwin_eval(Nu, Ng, RCWIN_ROLLOFF);
|
|
|
|
% Source
|
|
qlut = qamtable(M_QAM);
|
|
|
|
k_fft = sqrt(N_fft);
|
|
xv = [];
|
|
xt = zeros(1, Nt);
|
|
|
|
ofdm_spec_occ.kmin
|
|
ofdm_spec_occ.kmax
|
|
figure;
|
|
for k=1:N_frames
|
|
for s=0:ofdm_params.nspf-1,
|
|
|
|
X = zeros(N_fft,1);
|
|
|
|
% Data
|
|
if WITH_DATA == 1
|
|
data_i = c2i(N_fft, ofdm_spec_occ.kmin:1:ofdm_spec_occ.kmax);
|
|
sym = round(M_QAM*rand(1, length(data_i))+0.5);
|
|
X(data_i) = 0.20*qlut(sym);
|
|
end;
|
|
|
|
if WITH_FREQ_REF == 1
|
|
[ref_c ref_p ref_a] = getRefFreq(ofdm_params.mode);
|
|
X(c2i(N_fft, ref_c)) = 0.20*ref_a.*(exp(2*pi*i*ref_p/1024));
|
|
end;
|
|
|
|
|
|
if (s==0) & (WITH_TIME_REF == 1)
|
|
[ref_c ref_p ref_a] = getRefTime(ofdm_params.mode);
|
|
X(c2i(N_fft, ref_c)) = 0.20*ref_a.*(exp(2*pi*i*ref_p/1024));
|
|
end;
|
|
|
|
if WITH_GAIN_REF == 1
|
|
[ref_c ref_p ref_a] = getRefGain(ofdm_spec_occ, ofdm_params, s);
|
|
X(c2i(N_fft, ref_c)) = 0.20*ref_a.*(exp(2*pi*i*ref_p/1024));
|
|
end;
|
|
|
|
% Modulate
|
|
xu = k_fft*ifft(X, N_fft)';
|
|
if WITH_RCWIN == 1
|
|
xs = [xu(Nu-Ng+1:Nu) xu xu(1:Nt)] .* rcwin;
|
|
xs(1:Nt) = xs(1:Nt) + xt(1:Nt);
|
|
xt = xs(Ng+Nu+1:Ng+Nu+Nt);
|
|
else
|
|
xs = [xu(Nu-Ng+1:Nu) xu];
|
|
end;
|
|
xv = [xv xs(1:Ng+Nu)];
|
|
Xs = fft(xs(Ng+1:Ng+Nu), N_fft)/k_fft;
|
|
plot(0:N_fft-1, abs(Xs(1:N_fft)), '-*'); grid;
|
|
pause (0.001);
|
|
end;
|
|
end;
|
|
|
|
% Modulate on carrier
|
|
yc = 0.5*exp(j*2*pi.*(0:length(xv)-1)*fc/fa) .* xv;
|
|
yv = real(yc) + imag(yc);
|
|
|
|
xv = conj(xv');
|
|
yv = yv';
|
|
|
|
wavwrite(0.9*yv,fa,16,'yv.wav')
|
|
wavwrite(0.9*[real(xv) imag(xv)],fa,16,'xv.wav')
|
|
|
|
function index = c2i(N_fft, carriers)
|
|
ri = [];
|
|
ri = [ri find(carriers == 0)];
|
|
carriers(ri) = [];
|
|
index = mod(-carriers, N_fft) + 1;
|
|
|
|
function [ref_c ref_p ref_a] = getRefFreq(drmMode)
|
|
|
|
ref_A_c = [18 54 72];
|
|
ref_A_p = [205 836 215];
|
|
ref_A_a = sqrt(2)*ones(1,3);
|
|
|
|
|
|
ref_B_c = [16 48 64];
|
|
ref_B_p = [331 651 555];
|
|
ref_B_a = sqrt(2)*ones(1,3);
|
|
|
|
ref_C_c = [11 33 44];
|
|
ref_C_p = [214 392 242];
|
|
ref_C_a = sqrt(2)*ones(1,3);
|
|
|
|
ref_D_c = [ 7 21 28];
|
|
ref_D_p = [788 1014 332];
|
|
ref_D_a = sqrt(2)*ones(1,3);
|
|
|
|
ref_E_c = [];
|
|
ref_E_p = [];
|
|
ref_E_a = [];
|
|
|
|
switch drmMode
|
|
case 'MODE_A'
|
|
ref_c = ref_A_c;
|
|
ref_p = ref_A_p;
|
|
ref_a = ref_A_a;
|
|
|
|
case 'MODE_B'
|
|
ref_c = ref_B_c;
|
|
ref_p = ref_B_p;
|
|
ref_a = ref_B_a;
|
|
|
|
case 'MODE_C'
|
|
ref_c = ref_C_c;
|
|
ref_p = ref_C_p;
|
|
ref_a = ref_C_a;
|
|
|
|
case 'MODE_D'
|
|
ref_c = ref_D_c;
|
|
ref_p = ref_D_p;
|
|
ref_a = ref_D_a;
|
|
|
|
case 'MODE_E'
|
|
ref_c = ref_E_c;
|
|
ref_p = ref_E_p;
|
|
ref_a = ref_E_a;
|
|
end;
|
|
|
|
function [ref_c ref_p ref_a] = getRefTime(drmMode)
|
|
|
|
ref_B_c = [14 18 20 24 26 32 36 42 44 49 50 54 56 62 66 68];
|
|
ref_B_p = [304 108 620 192 704 44 432 588 844 651 651 460 460 944 940 428];
|
|
ref_B_a = sqrt(2)*ones(1,16);
|
|
|
|
switch drmMode
|
|
case 'MODE_A'
|
|
ref_c = [];
|
|
ref_p = [];
|
|
ref_a = [];
|
|
|
|
case 'MODE_B'
|
|
ref_c = ref_B_c;
|
|
ref_p = ref_B_p;
|
|
ref_a = ref_B_a;
|
|
|
|
case 'MODE_C'
|
|
ref_c = [];
|
|
ref_p = [];
|
|
ref_a = [];
|
|
|
|
case 'MODE_D'
|
|
ref_c = [];
|
|
ref_p = [];
|
|
ref_a = [];
|
|
|
|
case 'MODE_E'
|
|
ref_c = [];
|
|
ref_p = [];
|
|
ref_a = [];
|
|
end;
|
|
|
|
function [ref_c ref_p ref_a] = getRefGain(spec_occ, ofdm_params, s)
|
|
|
|
switch ofdm_params.mode
|
|
case 'MODE_A'
|
|
ref_c = [];
|
|
ref_p = [];
|
|
ref_a = [];
|
|
|
|
case 'MODE_B'
|
|
k0 = 1;
|
|
x = 2;
|
|
y = 3;
|
|
k = (spec_occ.kmin:1:spec_occ.kmax);
|
|
ref_c = 1 + 2*mod(s,3)+6*k;
|
|
ref_c(find(ref_c > spec_occ.kmax)) = [];
|
|
ref_c(find(ref_c < spec_occ.kmin)) = [];
|
|
n = mod(s, y);
|
|
m = floor(s/y);
|
|
p = (ref_c - k0 - n*x)/(x*y);
|
|
ref_p = mod(4*ofdm_params.Z(n+1,m+1) + p*ofdm_params.W(n+1,m+1) + p.*p*(1+s)*ofdm_params.Q, 1024);
|
|
ref_a = sqrt(2)*ones(1,length(ref_c));
|
|
|
|
case 'MODE_C'
|
|
ref_c = [];
|
|
ref_p = [];
|
|
ref_a = [];
|
|
|
|
case 'MODE_D'
|
|
ref_c = [];
|
|
ref_p = [];
|
|
ref_a = [];
|
|
|
|
case 'MODE_E'
|
|
ref_c = [];
|
|
ref_p = [];
|
|
ref_a = [];
|
|
end;
|
|
|