|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 House 于 2020-4-21 14:03 编辑 1 g6 Q/ B; Q- B5 \) a) h) E0 G* K
2 z/ z) e: {" g6 g {: ^+ `6 v, I% {OFDM的仿真程序,并且包括详细的WORD说明。有误码率和各种性能分析的做图程序。有需要的可以看看。
$ Q1 X1 M' P) _; K
" Z1 T" d' o" O N%a_run_design.m文件
. F0 W' s: L& _2 K& T1 X9 [setup %系统设置0 f/ T! T( I; Q y m- a) k, l% m
QAM %QAM调制方式" [7 D+ J. M1 O7 R& z' @! E! k2 y- j
OFDM %OFDM调制方式
2 t+ `/ }) w4 IAnalysis %QAM和OFDM两种方式对比+ y/ R8 _ _4 [' c. R* J$ h
2 B, w% l' K L5 t1setup %初始化部分9 `8 Y# J( h% T8 l j! w
% setup0 i. ]" N. i" u3 v( c
disp(' '), disp('------------------------------------------------------------')
9 L6 f3 ? ?8 ^: D6 N# J4 cdisp('Simulation Setup')
X: N ?. W' [7 R! D
! u# u3 n i, R8 _& e8 }: e% OFDM Setup -----------------------------------------------------------
5 y& r% \; _+ b/ C3 Tfft_size = 128 % should be a power of 2 for fast computation$ j' I) e. J7 N2 Y" T
% more points = more time domain samples (smoother & more cycles)- u+ X. F2 s; R& t; l8 g& Z+ Z
num_carriers = 32 % should be <= fft_size/4
5 I6 T- S! G. ^: M; c P % number of carriers used for each data chunk1 P1 u' z- D7 F+ W/ C: t
% new var - denotes even spacing or variations of carriers among fft points
0 }& Q( P* d$ U) `3 n0 K) b' Ginput_type = 2;8 [0 ` G$ C. a+ `! J' F( ?
% 1 = test input* g: c4 L7 Q/ J0 T) M' {
test_input_type = 1;
# m) R4 ~/ b2 h4 J: k % 1 = bit specified (binary)" g* V* o0 L$ ?2 w+ ^4 L8 f3 A
binary_data = [0 1 0 1 0 1 0 1];
; ~0 V. d0 K8 v, r % 2 = random data stream (samples in the range of 0-255)
" y+ F. c/ Y Q; Y2 [! U num_symbols = 9;
- E6 H$ R$ _! ?, W, w4 d% C, r- f % 3 = sinusoidal
6 Q! s7 I9 [7 O6 F frequency = 2;
) h B# X) P! o( d num_samples = 50;
% x2 e" |: U2 S5 }8 M' K6 n% 2 = external file input
6 s# q. ?' L) X! Z file_name = 'shortest.wav'; % Name of input file0 _( w k: n+ h+ J
file_input_type = 3;
6 u \8 ?2 k y, T7 P % 1 = binary (not implemented)
. q4 Z; |* z" d# N. f % 2 = text % Demo file: 'text.txt'
/ X. y. H- ~( p6 o % 3 = sound % Demo files: 'shortest.wav' & 'shorter.wav'
, h( ~0 g# R( t& D% s % 4 = image (not implemented)
' k; x6 n9 x/ i5 ^5 M6 y1 c$ c$ g! p9 n0 X
% QAM Setup ------------------------------------------------------------
- ]7 p6 k$ |0 R. y: wdo_QAM = 1; % (1=on, 0=off)
- i, l1 T8 R n; }QAM_periods = 10; % defines the number of periods per QAM Symbos (1=2*pi)
, `5 T& _3 e- i- t3 M3 V) I# m0 r+ e# X5 I
% Channel Simulation Parameters --------------------------------------------
4 c- Q3 n! |, i2 Schannel_on = 1; % 1=on, 0=off
- k# F4 b; Z9 ^0 @0 K% gclip_level = 1.0; % 0.0 - 1.0 (0-100%)' y; B2 L5 o2 U3 x0 M- v" U. v
% Max magnitude of the signal is 'clip_level' times the full magnitude of the signal
- Y/ F+ v/ u4 P3 Dnoise_level = 0.0; % 0.0 - 1.0 (0-100%)8 @' m" t0 E, O* o
% Magnitude of noise is 'noise_level' times the magnitude of the signal
8 E4 H# `7 f% N& w& i0 b, p$ ~+ ^5 E2 j% Multipath Channel Simulation
8 ] W# m. I1 e. x % Good defaults when fft_size = 128 and num_carriers = 32:& ^/ V, z U& e8 n! [4 W
% d1=6; a1=0.30; d2=10; a2=0.25
8 H+ R$ u" f3 a% K! j0 a- K! r d1 = 6; % delay in units( |5 |+ }# q5 k1 X/ K% i R
a1 = 0.30; % attenuation factor - multipath signal is x% of size or original signal
# W4 x% R! z- D1 E X5 n! p5 N1 h8 s d2 = 10; % delay for second multipath signal
. ?' \9 z# y4 t3 I) B8 _' u8 Y( F a2 = 0.25; % attenuation factor for second multipath signal
l+ e v9 e7 \% F+ M/ s
, `( j- A, i- W) m( h1 b* v6 y2 n: p' ~2 g' _
% ****************** TEST INPUT SETUP - DO NOT MODIFY ************************** ]0 e. }4 |: w: t
if input_type == 1
3 A; R, Q) z9 y: l3 V# d if test_input_type == 1/ a1 I8 z( ]7 V
%specify BINARY input bit-by-bit
" a, m7 T: U5 c, D5 K( w data_in = binary_data;
/ {; M% r1 x! g8 w9 `9 J/ M end
2 t- Q5 }, D& j i if test_input_type == 2' w+ v. t& {$ ?: e
%random input defined by parameters' z& `& H( ]0 L- H4 V" y1 f& u5 R
num_levels = 255; %number of possible levels of a symbol3 t8 O d7 b; n2 q
%must be integer between 1-255; D' j: |) s- d1 j2 o2 f
data_samples = round(rand(1,num_symbols)*(num_levels-1));
# }/ s, }# R! I( p J data_in = zeros(1,8*length(data_samples));
( u+ ~: E \6 ^ for i = 1:length(data_samples)
. E& F6 s/ }$ Z6 L9 j6 l data_in(1 + (i-1)*8: (i-1)*8 + 8) = eight2bin(data_samples(i));
* P& n- o4 h% y! [$ ~0 @ end
8 Q8 h* w2 O [; K4 F/ p9 w end
$ t" {3 r( h! {5 j( u4 }% @# t if test_input_type == 37 l# g6 a3 A( Z( ^4 l
%data stream represents sine wave samples6 V. S- ]7 j) G0 K3 e
t = linspace(0,1,num_symbols); %evenly space number of samples, U: `' C K! r4 f% T- n5 H
%take 8-bit samples of sine wave7 P3 o9 A9 O2 k6 t
data_samples = round(127.5*sin(frequency*2*pi*t) +127.5);
* O, A( ~, ]+ n- R& y$ m( V data_in = zeros(1,8*length(data_samples));7 K% X( Q3 C5 b; o
for i = 1:length(data_samples)
8 W: h; w& _: L4 t data_in(1 + (i-1)*8: (i-1)*8 + 8) = eight2bin(data_samples(i));
5 S6 j8 G8 {: j/ h* \ ?/ P3 l end _9 s! z) ?2 \: d0 G
end: a1 `( h5 g2 S/ @* Y- o
end
2 ?( @ I! z& G7 l: r4 y& D: d/ j; v3 w% }
already_made_noise = 0; % initialization (don't change)
: W. e3 q ~& C2 P* o
( m0 ?+ ?. f4 A+ T# r2、QAM.m4 R% R) p% Y- z+ W3 C& U
% QAM.m compares OFDM (multicarrier) to multi-level QAM (single carrier)
6 ^& f9 A. K8 G9 I% when they transmit the same # of bits in a given time period* [- [$ Z' N- K; C
: @) O1 O6 z% B+ R0 a6 l: o1 P: Xread % read data for QAM - does not affect OFDM1 n9 B0 f1 ~+ j/ a8 o, R
data_in_pol = bin2pol(data_in); % Converts binary data to polar data
* g- R W& n3 L1 M* o/ K
- x; R3 m9 b! H6 T% check to see if num_carriers is a power of 2* W+ }' I& ?8 `1 h3 A
is_pow_2 = num_carriers;- X* I, ` L9 C* J) @/ Z. F
temp_do_QAM = 0;
% c) S1 `( Z0 \5 n/ t Mif is_pow_2 ~= 21 x+ M z9 p( D, {; L L: N
while temp_do_QAM == 0
1 k0 P: D- u# \# t' I temp_do_QAM = rem(is_pow_2,2);7 R/ @4 M" a4 k2 l0 `' \3 L
is_pow_2 = is_pow_2/2;
% k T( f, \+ }! S3 { if is_pow_2 == 2) f/ t1 P$ W4 I: \# m, a5 W
temp_do_QAM = -99; % it is a power of 2 -> can do QAM& C# Z; ^9 n( g& t
end
" s* A; u; g8 g) J/ _9 t end
1 h4 \: l; ]6 H$ eelse3 O0 ~, f/ T1 J( u( @
temp_do_QAM = -99; % 2 is a power of 2" W' S3 m5 N9 D5 g' ?
end
; H. j5 N0 A' l) D1 Y9 Gif temp_do_QAM ~= -99( H) M3 m) |6 { Z
do_QAM = 0; % don't do it if it's not possible
. J1 |! Y9 X% x2 J disp(' '),disp('ERROR: Cannot run QAM because num_carriers is not valid.')7 U4 H- ^% q6 q9 R3 @. M3 a6 A
disp(' Please see "setup.m" for details.')
/ j$ v1 A- x5 ^7 k0 z' p' Iend- y* w$ U* U! \- C0 w4 H1 t
1 y% Q4 N5 L, W( H5 F2 f7 `
5 @* R i9 u) Y% e9 t& ?$ s$ Q/ Jif do_QAM == 1
2 s1 S8 w8 I4 d/ p8 E tic % Start stopwatch to calculate how long QAM simulation takes ?; z) C3 d2 v+ i" l, S+ `8 }" |3 y9 G, H
$ z, g! ^9 I6 \: E6 ~" e! t disp(' '), disp('------------------------------------------------------------'). E) S& @3 _/ g5 O6 I$ x3 W
disp('QAM simulation'), disp('Transmitting'); h4 l0 Z1 a2 k6 [0 [/ b& B! K, x% w
4 z, f0 Z5 N2 A. _
% Pad with zeros so data can be divided evenly
_/ I. Q- e# G( S" ^3 D' x/ y data_length = length(data_in_pol);+ q$ Y1 i, r. O) s
r = rem(data_length,num_carriers);. Q! F& f4 o) p3 [+ W- [# {* h* j+ U
if r ~= 0
5 s, A. y! S' p+ C5 `. K8 } for i = 1:num_carriers-r
. h0 ?# p' s" |1 k, C data_in_pol(data_length+i) = 0; %pad input with zeros to complete last data set4 Z/ K, ? K' S. G2 C" y& E3 Y
end %speed improve possible3 v, G! a* ^5 b$ R, v$ P$ I. p9 D
end
) k- y8 E( I |9 \/ I3 w: s- R8 x data_length = length(data_in_pol); %update after padding
6 d- n1 B' v; e& v0 M- ?# J. W 2 j9 |1 c9 d& }' _8 ~* w B" w
num_OFDM_symbols = ceil(data_length / (2*num_carriers));- h1 h7 ^, E' d3 k9 j
% num QAM symbols that represent equal amount of data to one OFDM symbol
; a$ Y, l( ]2 I' U" Z) M num_QAM_symbols = num_carriers / 2;8 N- n4 R6 j; `" C* ~
% num samples per QAM symbol/ ~3 {; X4 ]& o8 B3 j: I
num_symbol_samples = fft_size / num_QAM_symbols;' l. R% e2 _# X
& p$ b/ z9 C& a* P1 C" \" L
% convert polar data [-1, 1] to 4 level data [-3, -1, 1, 3]
9 X( }9 @. h0 y; ]) Y2 _$ x7 o data_in_4 = zeros(1,data_length/2);
4 |* v' J. E; w: w1 G for i = 1:2:data_length) `+ n. L- P' B4 r8 }; R/ N" k
data_in_4(i - (i-1)/2) = data_in_pol(i)*2 + data_in_pol(i+1);( m3 S+ Q8 y4 {0 H6 }4 `
end
. t! @7 P7 X9 @& j) a % l2 h- G& o y" ~/ W4 {* O
% define sample points between 0 and 2*pi. g" G/ X- ^# V U9 S
ts = linspace(0, 2*pi*QAM_periods, num_symbol_samples+1);
! V G. ^. X. e! M+ F
8 O; g# p( |8 C' f }! [- ` % Generate 16-QAM data
! e# e* ~! N" z3 l % total length of 16-QAM transmission
4 ?/ [4 \; q. l, k* p6 ~ tx_length = num_OFDM_symbols * num_QAM_symbols * num_symbol_samples;( X2 E. X, E2 u! E+ x
QAM_tx_data = zeros(1,tx_length);# v3 W/ s& f' p, u: N7 R% j
for i = 1:2:data_length/26 Q7 {9 K0 d$ Q; w
for k = 1:num_symbol_samples
. Y* c% V5 Q& _, L6 P7 u% ? QAM_tx_data(k+((i-1)/2)*num_symbol_samples) = data_in_4(i)*cos(ts(k)) + data_in_4(i+1)*sin(ts(k));+ m6 f3 g# d/ N
end
# h! F2 I7 M# N3 C end
, n X5 ~0 T8 y $ W5 ]0 a' [; M, u- t
% Do channel simulation on QAM data }. Z& z# ^, J( ]
xmit = QAM_tx_data; % ch uses 'xmit' data and returns 'recv'
x+ W" n+ q0 K ch ^' T% P+ H4 M
QAM_rx_data = recv; % save QAM data after channel
# w' n7 t: q7 {( ?$ e$ p3 | clear recv % remove 'recv' so it won't inteRFere with OFDM
: m; L: @6 n$ }3 r; g clear xmit % remove 'xmit' so it won't interfere with OFDM
( }3 E# u8 A, G3 F; h
" o) X/ z& B3 [# Y- U disp('Receiving') % Recover Binary data (Decode QAM)7 b: x" C% \3 _8 }, G1 g/ T
cos_temp = zeros(1,num_symbol_samples); %
% A5 `7 ~, e9 ^0 I sin_temp = cos_temp; %1 a4 v+ a% r! w$ ?/ Z
xxx = zeros(1,data_length/4); % Initialize to zeros for speed
/ ~+ z/ {0 z5 x. R1 |1 b# t: `4 c( o yyy = xxx; %( i4 R4 a. k! i
QAM_data_out_4 = zeros(1,data_length/2); %- B( [7 i! ]4 X0 t+ K- \
$ ]( V. y' J' f% E4 W0 u: ~9 U for i = 1:2:data_length/2 % "cheating"
/ t t9 T- y" j+ X6 H for k = 1:num_symbol_samples8 q1 R- f6 L3 W8 {
% multiply by carriers to produce high frequency term and original data E! R; Z' F9 \
cos_temp(k) = QAM_rx_data(k+((i-1)/2)*num_symbol_samples) * cos(ts(k));, x' i( ]7 c7 x E7 G
sin_temp(k) = QAM_rx_data(k+((i-1)/2)*num_symbol_samples) * sin(ts(k));/ V& K) P$ g2 o; b" p9 L3 M
end
. f% R0 F- k Q' X % LPF and decide - we will do very simple LPF by averaging
: {# _$ f+ f5 H2 }5 }- b4 z7 X! Q4 h xxx(1+(i-1)/2) = mean(cos_temp);0 M& c. j) m+ [1 x$ X
yyy(1+(i-1)/2) = mean(sin_temp);/ B* j5 h. }4 y9 R
% Reconstruct data in serial form
" x+ \/ A- \& M5 k# l. _' i2 X QAM_data_out_4(i) = xxx(1+(i-1)/2);' o, x& Q* T$ ]6 @
QAM_data_out_4(i+1) = yyy(1+(i-1)/2);, K( M8 c! q4 I) W$ D9 H( ^
end
a; m C! g) [" S S @" m7 L
/ h+ Z# c( _, F1 ~# @* H! I % Make decision between [-3, -1, 1, 3]
1 Y! d5 y9 q' l" U$ m& C, t6 R for i = 1:data_length/2
% G/ h, o6 _# b/ O& ]8 s8 H if QAM_data_out_4(i) >= 1, QAM_data_out_4(i) = 3;
6 } k3 I" B, [+ ]! @: y elseif QAM_data_out_4(i) >= 0, QAM_data_out_4(i) = 1;+ Y: W, ?+ ]. d, |
elseif QAM_data_out_4(i) >= -1, QAM_data_out_4(i) = -1;
1 L- R1 F/ U" O) X# [ else QAM_data_out_4(i) = -3;
& b, x# ?* v. g0 J end! @8 D3 ^# H/ Y0 P# B* p, J
end
h9 R1 R3 d9 T/ c
, i( m. j) G) q: j& g. D' D % Convert 4 level data [-3, -1, 1, 3] back to polar data [-1, 1]8 E% S5 w9 J/ L: ^, @
QAM_data_out_pol = zeros(1,data_length); % "cheating"; M9 ~/ L4 p y
for i = 1:2:data_length4 {; s( V' l3 d: Q U' g7 f. I3 P) W
switch QAM_data_out_4(1 + (i-1)/2)
! x0 U6 W3 P" @; E! j case -3: V; Y7 |9 Y/ Y' A, `! C% p3 G
QAM_data_out_pol(i) = -1;3 n4 w0 k! W( w7 w
QAM_data_out_pol(i+1) = -1;0 y" V0 j- x; Q
case -1* c7 s1 ^$ c- H# p
QAM_data_out_pol(i) = -1;
( r0 n! K7 Q& j7 y/ f9 @# Q QAM_data_out_pol(i+1) = 1;& ~4 ~/ c8 ~, k$ {9 E
case 1/ R2 o' F& j5 ]" w9 F4 z* i, D
QAM_data_out_pol(i) = 1;
% f+ {# ]# n& Q7 W QAM_data_out_pol(i+1) = -1;# G5 `% a0 ~3 F q
case 38 `0 N' S( }& X6 }8 v
QAM_data_out_pol(i) = 1;
9 ?2 Z: {! |# `; x7 h( M QAM_data_out_pol(i+1) = 1;
3 o! S" c/ g% Y* N0 e- T, e2 N! e# N otherwise5 `$ C9 T, k j4 V
disp('Error detected in switch statment - This should not be happening.');: I- p! [6 u; ^' Z3 T4 F" _' N
end( y0 E, S: S2 b
end
. q8 Y- f- j) H8 R( n' ]% S) s QAM_data_out = pol2bin(QAM_data_out_pol); % convert back to binary
n6 D! j3 u& J+ I- ]4 s
7 _. ?0 E: |/ Q. V* L" E o % Stop stopwatch to calculate how long QAM simulation takes
9 A( _# B4 d, E2 ]2 P QAM_simulation_time = toc;" R1 I! D* m3 K* {3 u9 m+ ^: x4 X/ P7 l
if QAM_simulation_time > 60( U0 R4 G" B4 j1 }
disp(strcat('Time for QAM simulation=', num2str(QAM_simulation_time/60), ' minutes.'));' C e: F; {" d+ d
else" [0 q7 {+ r) H. d
disp(strcat('Time for QAM simulation=', num2str(QAM_simulation_time), ' seconds.'));
& r2 M5 X: m/ [; i, C1 {0 I7 F end
. D* p$ K0 X6 qend3 ^# b* p* W0 c- X5 r$ o
. t. o- N$ C' z: [+ i* W6 ~3 % Run OFDM simulation% Y6 t9 z7 ]- h) B8 k0 J6 r
tic % Start stopwatch to calculate how long QAM simulation takes
6 q0 Y9 w, _% M2 g/ z0 f: mdisp(' '),disp('------------------------------------------------------------')# o- }' r2 Z) m$ b6 Q' _
disp('OFDM Simulation')* _3 y; }+ ^) r: X9 j8 a) l
tx 9 z: k I) t6 e/ q( w( Z
ch4 V+ u# t( H2 y8 B
rx
# B# O% r& G7 y4 Y0 _% Stop stopwatch to calculate how long QAM simulation takes( S; n2 D2 ]0 Z! |8 a2 n' o6 {
OFDM_simulation_time = toc;' j6 r2 Z6 N3 S- H8 U3 k. g
if OFDM_simulation_time > 60
$ Y s$ \+ a6 I" ~: a' ` disp(strcat('Time for OFDM simulation=', num2str(OFDM_simulation_time/60), ' minutes.'));
# n4 b1 E+ ~/ kelse4 V% ]$ J/ T7 ?- t
disp(strcat('Time for OFDM simulation=', num2str(OFDM_simulation_time), ' seconds.'));- D& ~0 F' Z! J2 d9 M
end
/ Q/ W; J5 d6 H% Y% _$ b. y% E; W. h* O' {+ ^, C) K7 \6 ` r
3.1发送
% V6 Y3 H) e4 I, H. r* A% tx
) u/ s% i, w/ a8 Wdisp('Transmitting')
7 P9 k7 ~5 f& x, A7 [5 eread %read original data
. {# l* }1 b1 h) W5 ]7 Tdata_in_pol = bin2pol(data_in); % Converts binary data to polar data
, q! U: Y5 L5 K/ htx_chunk %convert polar data into chunks.
, h( Z- ~$ x5 q- Z6 B5 i& p& _& r0 P( w$ f
% perform ifft to create time domain waveform representing data1 H1 w9 V. F1 ^: s6 l* t
td_sets = zeros(num_chunks,fft_size);& K F2 k% l2 r0 `- u
for i = 1:num_chunks, u+ u# O* b3 e* Y% f' z+ k' r' X8 o
td_sets(i,1:fft_size) = real(ifft(spaced_chunks(i,1:fft_size)));
3 D* p0 g3 F; c8 @4 g% i% gend6 i. e" j% g' I8 ^! a( {7 M: l# E
: k$ T9 O+ F, J+ i0 E v
tx_dechunk % Construct signal to transmit by placing time domain sets in series
+ p( M0 A: d5 c# @7 }2 T1 e4 p: z% E6 ~) y1 Q) x4 C
3.1.1 % tx_chunk %双极性数组转化成OFDM字符串8 F, \( I1 \: ]# k7 ~' c
data_length = length(data_in_pol) %number of symbols in original input: R& w { R1 F5 K. t
num_carriers
4 X4 n6 o5 e% y9 {) `( s8 u& Anum_chunks = ceil(data_length/(2*num_carriers)) %2 data on each carrier (real and imaginary)# ^) C7 m+ O, C. X, ^+ L
r = rem(data_length,2*num_carriers)
& Q: l7 F' B& H1 H' x3 @4 j( Tif r ~= 0, @) u/ L6 Z! O: t4 L3 {
for i = 1:num_carriers*2-r
+ D/ o" N9 _, D& z9 y( ? data_in_pol(data_length+i) = 0; %pad input with zeros to complete last data set
$ c+ r ^( S5 I9 O6 v end %speed improve possible
' A9 A& r7 A) D1 ~' `end
& W+ Z1 W9 n) \0 u
7 Z/ x' Y, p+ {8 F! [2 i% L' u- ?% break data into chunks
) X: v/ i8 w( v9 e" bchunks = zeros(num_chunks,num_carriers); % for speed2 u9 t- R/ s: }0 s6 I5 L& {
for i = 1:num_chunks
, K# e7 [. @* a" v, m, X! D$ n1 { % *********************chunk done
0 u, K/ ?- j6 I! Q for k = 1:num_carriers
& f' c# g" ]2 N* r8 }$ H8 y chunks(i,k) = data_in_pol(2*num_carriers*(i-1)+k) + data_in_pol(2*num_carriers*(i-1)+k+num_carriers)*j;; f) l7 h# u( i% D' `- G2 B3 R
end
! z+ g/ y# R! P3 @5 j) j% M- Tend' @2 B0 D( R6 M! s( f
# @7 Y8 E, N1 J$ v1 G6 L9 U# @chunks
" I, u+ ~! p3 [1 A% Padding chunks with zeros so num_carriers and fft_size are compatible
% t$ K% n( z/ u! H' u% Once compatible, further spacing is simplified3 {1 R' \" U3 E/ S+ f9 h
num_desired_carriers = num_carriers;
1 l9 i4 Q/ L8 Y% J3 hnum_zeros = 0;
8 H1 V7 X' T" y! G! G$ zthinking = 1;
, r, c, {+ G! ^) B3 p3 Nwhile thinking == 1 % Continue if num_carriers and fft_size are not compatible- x* r' t, m0 `3 l" { T2 N$ v3 \: z
if rem(fft_size/2,num_desired_carriers) == 06 x* K* |3 |2 ?
thinking = 0;
0 k- j& p& \; q) o! }# z else' n0 s; O. M- O6 Z; [
num_desired_carriers = num_desired_carriers + 1;
" A1 v" d0 T/ A! Q! d1 j num_zeros = num_zeros + 1;
: L. I! m2 \6 O8 J end1 M& P4 Q" j. X( @- g
end
5 l' p( c. x. l7 @, M6 \* j( o/ B8 q8 B% F, W6 V. x/ y
padded_chunks = zeros(num_chunks,num_carriers + num_zeros); % for speed5 f3 B- ]' n8 H% O
padded_chunks(1:num_chunks,num_zeros + 1:num_carriers + num_zeros) = chunks;; b/ s0 S/ m; w) v
) q, u1 O `8 V0 H; A. V+ I1 h7 H6 d$ @7 L
%compute zeros_between3 L# G% t# W/ u7 {$ L3 C
zeros_between = ((fft_size/2) - (num_carriers + num_zeros))/(num_carriers + num_zeros);% b" d x) o- X, x; S* ^
9 {3 ? v! a9 Nspaced_chunks = zeros(num_chunks,fft_size); % for speed - extra room for folding later
r0 J8 U6 s% m# i2 L) b%add zeros_between) b. A- u3 u9 }( O' @
i = 1;
! x$ { e% Q/ e, t4 g- F( nfor k = zeros_between +1:zeros_between +1:fft_size/2 S2 O v2 f8 P1 B7 K* E7 Y
spaced_chunks(1:num_chunks,k) = padded_chunks(1:num_chunks,i);
0 q6 j! d& Z, {% U8 k* l- x' N' @ i = i+1;
4 g4 z# W9 c0 x9 send
' r. K% }5 W: k8 W! R: v
6 F) z, B, {4 C% a# m0 X% folding data to produce an odd function for ifft input, v! ]3 {$ V; T2 ?. X% U8 L! Y$ Q
for i = 1:num_chunks
3 v! D/ m) b* [# Z. J% j % Note: index = 1 is actually DC freq for ifft -> it does not get copied over y-axis
( n1 f5 P7 @* j6 f& l3 | spaced_chunks(i,fft_size:-1:fft_size/2+2) = conj(spaced_chunks(i,2:fft_size/2));
/ |# i" G; d8 |" H z Nend
7 Q( P: L* t' \: D- ?4 l' d$ s, R! m5 K% b( Z1 d
3.1.2 tx_dechunk
: ^; D! w2 w V! l% tx_dechunk5 T2 F: [9 Z7 k$ A% b) s) k9 _( p! y$ T
+ `- S; d; P+ v" P( _; F
% Construct signal to transmit by placing time domain sets in series9 Z2 k2 e# {4 g$ w4 ~% C6 ~
xmit = zeros(1,num_chunks*fft_size);/ c- {* K8 z z3 w& x- J' C
for i = 1:num_chunks% f2 N! u! a4 T! O3 R2 R
for k = 1:fft_size5 J6 m% d1 O p. v
xmit(k + (i-1)*fft_size) = td_sets(i,k);/ y5 R+ s. `3 c
end6 _2 O9 Q4 a Y) P
end
4 f% _/ I) T0 v( d, H2 p1 K/ j O9 |1 S4 Q4 i% n( |
3.2 %ch.m2 ]' A5 O' v' }3 S" V% M6 B8 c
% ch
6 l6 h, Z0 X6 o8 ~; crecv = xmit; % channel is applied to recv, don't modify transmitted data8 G5 I, A. p3 s, D
if channel_on == 1
/ S c% z5 d# ]8 M- Z/ K. h disp('Simulating Channel')
2 i. a, e( a8 J norm_factor = max(abs(recv)); % Normalize all data before applying
0 K$ L) U) F$ {. o3 r+ m: I. W2 N recv = (1/norm_factor) * recv; % channel for a fair comparison5 m1 L6 a- y1 _1 E1 F
ch_clipping %clipp data
: G4 c- `2 @. w9 C" v+ u( i3 ~ ch_multipath %* b0 M) `8 U" z3 @4 ^4 _+ Y: }
ch_noise %- `) I$ _* l a: k. s
recv = norm_factor * recv; % Restore data magnitude for proper decoding+ v2 y/ H1 v' J# _% [
end
4 t$ i ]& D6 X1 D. M* b v f
6 |% j* O( i* R3.2.1 %ch_clipping.m/ g" ]9 q& w" E" }/ }3 g, Q# ?
% ch_clipping$ X6 |+ `2 F" T( I# [9 a/ w
for i = 1:length(recv)
6 E: ]) _7 v9 S if recv(i) > clip_level* [5 _ p5 G8 `+ s
recv(i) = clip_level;
8 i. i( m9 x# f6 I' P$ S( f M6 X end
. Z$ Z5 F+ z- j3 k) K9 ]7 @ if recv(i) < -clip_level
- E+ |2 k/ j& z1 z: c! _! D recv(i) = -clip_level;( M9 r F: H. t
end. D2 O1 P; C8 ?$ [/ w
end7 H% r% }( c. \! S( _9 I5 L9 t
/ O( Q2 S: E# L1 Z+ k8 O' H, n$ A3.2.2 % ch_multipath % 产生多经的方法
( P2 S) V) Y+ Ecopy1=zeros(size(recv));& k. b* o$ l2 I
for i=1+d1: length(recv)1 J- {! a9 B8 i/ J2 p
copy1(i)=a1*recv(i-d1);
+ j+ C6 |! m' L0 `( Zend
7 [' p* ~& u0 d$ t* V9 Z9 Y% ocopy2=zeros(size(recv));
9 N) J- \0 c5 m2 M! {: ~for i=1+d2: length(recv)
$ O; Y2 C7 f3 `$ w T: H* e copy2(i)=a2*recv(i-d2);9 ?( o3 f$ ]' h& J' z8 D
end
" k% u" A, N0 k% p/ Xrecv=recv+copy1+copy2;* b9 [, ~. B8 _& C1 W3 r& |
{/ o' V5 {0 h! Q' q3 d3.2.3、%ch_noise %施加信道噪声
" ?8 h2 R1 ?8 [% ch_noise (operate on recv)
2 u# m! z9 ]- r0 R+ S* p, q% random noise defined by noise_level amplitude% B9 A$ O6 R Z3 T' [
if already_made_noise == 0 % only generate once and use for both QAM and OFDM$ b% ~: r z/ e, M% [6 L
noise = (rand(1,length(recv))-0.5)*2*noise_level;8 O- T* |/ U* s8 A6 s+ w
already_made_noise = 1;
5 ]3 }9 {' M: s7 O/ fend
3 G" a) l/ G! xrecv = recv + noise;
8 k* [) j' S# q7 }1 c# |
6 n' z# x, ~6 Z% r3.3 %rx.m %接收程序4 p1 U- X! m% m2 \# s5 b9 |
% rx
3 B8 j% x' `0 D. }# \disp('Receiving'); U1 q% e4 `$ j) \ A' A
rx_chunk% V% N# M* n0 X/ k: X; h
1 B2 \( k7 v( ~" Q* O* b% perform fft to recover original data from time domain sets: z0 ^' E" T% X2 f3 N
recv_spaced_chunks = zeros(num_chunks,fft_size);1 I* p' G7 E- V# t. r) L
for i = 1:num_chunks( f/ F. x" q( J7 ]9 g$ W
recv_spaced_chunks(i,1: fft_size) = fft(recv_td_sets(i,1: fft_size));+ W G- n: @7 E# c1 K
% Note: 'round()' gets rid of small numerical error in Matlab but a threshold will be needed for a practical system
6 p0 g& w4 f% P6 s& `( u+ X % 2001-4-17 -- Got rid of 'round()' to do decoding more intelligently Y( F! c, y2 j4 k/ l" {
end
* I- `6 L8 k1 ]4 ]rx_dechunk
. Z6 j9 ^9 e8 n& w6 ooutput = pol2bin(output); % Converts polar to binary
1 C! }$ ?" e5 ewrite( k- h1 K% K/ y" a1 D& u6 e( u
1 B8 T' h: l5 }- u6 D: ~! F& _2 H3.3.1 %rx_chunk.m
7 e+ g$ \# n6 v) b: h; d% rx_chunk
5 |2 N2 N+ s5 L7 ~# j7 }% break received signal into parellel sets for demodulation
0 u0 x0 y9 T) v5 zrecv_td_sets = zeros(num_chunks,fft_size);. A, n$ M( w0 P: h
for i = 1:num_chunks' H. [# w2 a* F+ F
for k = 1: fft_size) H6 v! w; S' S8 J1 E
recv_td_sets(i,k) = recv(k + (i-1)*fft_size);
- d$ O" [) [- e* @' p6 d end+ [/ D9 _/ ^, [7 E- D( P2 P
end; U# g9 ~& Y" E. S; I
e( K. C' K7 ?. l
3.3.2 % rx_dechunk %并串转换
) P( o- f$ R' o7 n! h% rx_dechunk
1 T$ K s- j3 W$ Y2 l5 K% take out zeros_between from recv_spaced_chunks --> recv_padded_chunks
$ {! _$ O. D: m4 M2 Srecv_padded_chunks = zeros(num_chunks, num_carriers+num_zeros);
, t4 U* x5 i$ fi = 1;+ Q t5 m/ l2 [ S% I# X; n& e
for k = zeros_between +1:zeros_between +1:fft_size/2
0 [" x+ q o' s* a recv_padded_chunks(1:num_chunks,i) = recv_spaced_chunks(1:num_chunks,k);
2 r+ N& V8 G5 s Q1 D, [" J5 }/ q i = i+1;
( k+ P5 q$ v) Z$ Pend8 e$ K' Y2 X. P6 @6 a: D8 S' i
5 ~, S3 G5 ^0 {/ Q/ O% r+ B
% take out num_zeros from padded chunks --> recv_chunks
7 W/ U4 U- t% f% O0 ~/ G Zrecv_chunks = zeros(num_chunks, num_carriers);
( I+ N5 f! j6 U& H" t" frecv_chunks = recv_padded_chunks(1:num_chunks, num_zeros+1:num_carriers+num_zeros);. R6 }; N3 `7 k! j3 w9 |; y* P
1 P' Q# L8 S, o Y1 X% Recover bit stream by placing reconstructed frequency domain data in series0 e0 C- C( y! `/ f
recv_dechunked = zeros(1, num_chunks*num_carriers);
# _! e9 v# m/ B' W( i: c# Qfor i = 1:num_chunks3 I* |3 H% n- q% x% Q
for k = 1:num_carriers9 a! i' D# k) E! e5 ?' w% j; s
recv_dechunked(k + (i-1)*num_carriers*2) = real(recv_chunks(i,k));
% @- r% m0 \) p+ y6 P2 \4 z recv_dechunked(k + (i-1)*num_carriers*2 + num_carriers) = imag(recv_chunks(i,k));+ J* b+ C! C* p# u- a" Y# [
end
. H, [/ m* h6 bend
6 s+ g2 k8 k% @& O
; U/ }4 k7 e. x7 V- p' N# L7 E/ _% take out trailing zeros from output --> output' c8 r3 H; |6 {, t F
output_analog = recv_dechunked(1:data_length);4 C6 k6 K! m9 W3 f3 g$ W6 h5 F
output = sign(output_analog);5 @6 M) T( F' h+ \2 g5 z( U2 X0 h
# q$ c+ S8 l- M+ v+ e
3.3.3 %write %save received data# O6 O8 E3 A; J1 F
% write
& ]. m& A2 `4 l% ******************TEST OUTPUT*********************************! @* i; N8 d8 r. W& y& l2 g
if input_type == 19 \; d. |/ j. D5 t# P: U
if test_input_type == 1
3 V2 V7 {9 S9 {4 p( {' N %already binary - do nothing1 I& Z- _( i1 c6 t( x
end9 D5 j& a' r( d6 f6 V5 }$ g: v
7 P+ x9 b) g) _1 g, ^. h if (test_input_type == 2) | (test_input_type == 3)
3 c4 z9 N1 J& V9 ~ %random input OR sine wave samples+ T" L9 @( E$ e! {
output_samples = zeros(1,floor(length(output)/8)); %extra zeros are not original data# P% o. D E7 l( I s
for i = 1:length(output_samples)0 P5 V1 ?: B3 O9 x% P- Q# _7 q
output_samples(i) = bin2eight(output(1 + (i-1)*8: (i-1)*8 + 8));
y' v. W" y8 K" i end
! J0 Z0 n7 H( l1 k8 H if do_QAM == 1) }$ [: n+ I% E1 @2 ~9 z
QAM_output_samples = zeros(1,floor(length(QAM_data_out)/8));
# w5 K# i. _0 t0 h9 A for i = 1:length(QAM_output_samples)( u6 x( }( X* r; X5 v0 F
QAM_output_samples(i) = bin2eight(QAM_data_out(1 + (i-1)*8: (i-1)*8 + 8));
/ J* A- ^! n3 {' l: ^/ D& q end9 v- v6 {& S+ x) x5 ?5 H$ W, m
end( T0 w0 ?6 Y8 X- h- V
end
1 @( ~( v3 n9 `2 t# P4 a3 i1 @end, j7 \" H5 W: [4 r0 P( W* Y/ e
) K# |# z; F' r. T9 u% ******************FILE OUTPUT*********************************
! t: t9 `7 K* f: C, gif input_type == 2
! m/ v! Q% r0 j& c9 b
1 H4 C' m8 t# ]& R if file_input_type == 14 Q8 O1 g: F3 D3 q: m- r) G
%binary file output - not implemented6 R' A2 T& ~1 D; c* u# U4 U/ f# ^. G
end
5 V) _! I$ c0 S$ k a3 {& p7 v4 H& e5 i7 A% a
if file_input_type == 2
6 m0 q7 K3 B( N/ x %text file output
0 R* T0 {1 p# k! Z' z/ \4 g7 D/ R, b output_samples = zeros(1,floor(length(output)/8)); %extra zeros are not original data
' i* g' c" @: c; l; W$ l* @ for i = 1:length(output_samples)6 }7 p) q- Z/ K
output_samples(i) = bin2eight(output(1 + (i-1)*8: (i-1)*8 + 8));
8 r' D' w$ @. L* n( M end
1 @2 W5 V4 R, f6 }# @: v h0 M9 O file = fopen('OFDM_text_out.txt','wt+');
' \0 j: l1 @- u4 ^% z' i fwrite(file,output_samples,'char');
1 K$ N! E; j) I. F6 F: x fclose(file);
U( D9 F s, D/ E. b1 c8 V; h! [; t) q% N1 C# s
if do_QAM == 11 v/ Z" {% Q4 _
%extra zeros are not original data
/ k: I$ s$ @: u) K QAM_output_samples = zeros(1,floor(length(QAM_data_out)/8));
4 Z, n) c# v& G* D: G( ^( [3 d3 a! q% P
1 ^/ _6 U; ]" T, ~" ^for i = 1:length(QAM_output_samples)$ n- y5 @! z! J1 d
QAM_output_samples(i) = bin2eight(QAM_data_out(1 + (i-1)*8: (i-1)*8 + 8));
+ B; o* g$ }7 a: x, ~ end
- `0 n- T# g' l2 D" G$ X& ]; o file = fopen('QAM_text_out.txt','wt+');
. f! g' c# w4 u- {5 o& G fwrite(file,QAM_output_samples,'char');. ~9 R t8 ?5 z; d. T2 D* B
fclose(file);" J, b: n4 w: o5 J
end
" o& T' u% E s8 K: N% E$ n end
0 g* N! |' i2 S# p: y& H1 i. K( v+ q: u9 P* e
if file_input_type == 36 e9 q' T1 n) W) b) A
output_samples_big = zeros(1,floor(length(output)/8)); %extra zeros are not original data. U# H# J) z0 `: d* i& g- j
for i = 1:length(output_samples_big)% ?& b/ ^5 L7 C! d' }; z
output_samples_big(i) = bin2eight(output(1 + (i-1)*8: (i-1)*8 + 8));
: \1 k% a: n8 z8 @- n( u* X! O end8 j) g- C$ O3 L% P4 ?
%convert dynamic range from 0:255 to -1:1' Q5 g! }4 H5 A4 m
output_samples = (output_samples_big-127)/128;
# d( T6 R' t0 Q+ f$ b %sound file output
4 w0 C( f! u) U( u9 ]" n wavwrite(output_samples, 11025, 8, 'OFDM_out.wav')/ z" {* d5 X) ]2 H% z
if do_QAM == 1) k0 e" Z9 O! x4 G! s+ H c
QAM_data_out_big = zeros(1,floor(length(QAM_data_out)/8));
) B! U% M4 G7 ^2 g0 U* v for i = 1:length(QAM_data_out_big)
9 M0 l3 H1 J: h# @ QAM_data_out_big(i) = bin2eight(QAM_data_out(1 + (i-1)*8: (i-1)*8 + 8));
& ]( B; N( z- a2 e& O: S |4 ?" P end( @$ S# u$ J5 C
%convert dynamic range from 0:255 to -1: 1% T' Q; G# ~+ V. G
QAM_output_samples = (QAM_data_out_big-127)/128;" M6 ]" b9 e6 f
%sound file output
& s/ u9 O" A& M3 V$ E wavwrite(QAM_output_samples, 11025, 8, 'QAM_out.wav')
8 [1 ?! P- h6 Y q* ~/ ~' v end
' R6 ]* \6 a8 K3 _, F7 q$ ?* r end
) g! j1 B1 ?9 P9 M 3 B' x* n& Z1 ]( V, `+ Z- Z
if file_input_type == 4' I( H9 l5 Y% R9 b+ ]) ^* z
%image file output - not implemented
* x/ [8 h8 \6 G0 r2 ^ end% g- |% K% S% C7 v5 ^9 r* |# r
end. b# o$ M" O* ]$ O- y. Q/ E
) \0 i7 G. b; V% J: [
4、%Analysis.m8 J4 t$ w% r1 X9 G5 j
% Analysis
2 O1 a9 l2 a( m! V. fdisp(' '), disp('------------------------------------------------------------')- \8 Q/ B8 K$ }: o$ k3 C
disp('Preparing Analysis')/ J; m) B" H2 n6 U! C8 D- Q3 |
figure(1), clf5 G: s/ ^& n+ }. q" G8 O
if (input_type == 1) & (test_input_type == 1)
0 K' K! g; f0 a4 H subplot(221), stem(data_in), title('OFDM Binary Input Data');; k. t- o; D+ L/ R7 j/ Q0 s
subplot(223), stem(output), title('OFDM Recovered Binary Data')3 q7 c# i7 C$ j: `4 o
else9 l( H, u$ @3 M7 |# A( P. E# z
subplot(221), plot(data_samples), title('OFDM Symbol Input Data');6 ^4 ]% A' C; l
subplot(223), plot(output_samples), title('OFDM Recovered Symbols');
3 T6 i! ~. C/ T: P4 vend8 E8 t1 T- g7 w: l1 A
subplot(222), plot(xmit), title('Transmitted OFDM');* u/ M ?. q( R0 v$ I" E* E
subplot(224), plot(recv), title('Received OFDM');0 s, t! N1 U% i$ t; I# [* q
) o _" h- N; B
6 c! ~% j/ k4 B( i" @: m* Q
% dig_x_axis = (1:length(QAM_tx_data))/length(QAM_tx_data);: p) m% Z( V4 C( D( ?
% figure(4), clf, subplot(212); V# F) d8 i+ Z5 l% V6 k$ i
% freq_data = abs(fft(QAM_rx_data));
( D) L" R9 J! B6 k q% L = length(freq_data)/2;6 o, |) q; [* x
0 k8 _! o2 B$ U1 e& H
dig_x_axis = (1: length(xmit))/length(xmit);
% _& r' b! p6 q ?figure(2), clf
! ^4 U7 h9 _) x0 S- u; H, ^4 a- n7 u- }! ?% j) ^
if channel_on ==1
/ |! V4 Q! f; X; w' |6 r& d7 B2 o num = [1, zeros(1, d1-1), a1, zeros(1, d2-d1-1), a2];
4 I+ t5 t2 |( \' Z6 [9 u den = [1];4 l/ m- p3 E% O7 j. F& B
[H, W] = freqz(num, den, 512);) `0 r! {, T5 O' l7 n5 T+ h5 }
mag = 20*log10(abs(H));' v8 o& Q2 c) Y6 |; |) `
phase = angle(H) * 180/pi;( ?3 S) }6 g' Y7 z1 m& v4 C
7 w0 m$ f7 @) ^, { W7 I- e; T9 Q subplot(313)
& O6 g& l0 `" ` \. S, T7 m3 f& e freq_data = abs(fft(recv));
1 X. b0 d$ R0 _7 g L = length(freq_data)/2;
8 t. r. g4 y/ E plot(dig_x_axis(1: L), freq_data(1: L))- S. [3 z: V3 O' E
xlabel('FFT of Received OFDM'). J# v% T7 L6 P8 B2 J
axis_temp = axis;3 C0 ^) s, H9 c% Q$ @1 {" X' p
i0 C7 u8 a1 O; Q! I! j1 t subplot(311),
6 ?4 ]4 Y5 i7 }' _% ~: S freq_data = abs(fft(xmit));
7 A0 O. {% r H# q. r% Y# I) i/ D plot(dig_x_axis(1: L), freq_data(1: L)), axis(axis_temp) b( m$ z. G" B# A; p" `; ], o
title('FFT of Transmitted OFDM')7 D4 N4 f3 ~$ H7 ]
7 {4 w$ T' x/ b, B1 w. \& t0 Q- O subplot(312)$ D, c9 i' S' B) p+ `
plot(W/(2*pi),mag),
" U s6 Y' i; i3 X ylabel('Channel Magnitude Response')7 ?5 q* v( o$ C7 c' t, N3 X
else
3 B' L2 a! Q( p: L! m8 \ subplot(212)
4 [( f0 B! S- f/ p* F freq_data = abs(fft(recv));
. H% Z1 v7 q: U0 } L = length(freq_data)/2;& k2 Q5 f# n$ C# \. V
plot(dig_x_axis(1: L), freq_data(1: L))1 t: s! O2 c# J! f9 N/ U
xlabel('FFT of Received OFDM')9 x6 [; @" B9 [' v) T- g& L
axis_temp = axis;2 @, o4 |: `+ M" K
- a: \5 D( Q7 Y: T6 @
subplot(211),7 {7 N6 F' ^& ?! i: Y3 P( @' x+ S
freq_data = abs(fft(xmit));
5 U" A7 u* ~0 G1 W- d ] plot(dig_x_axis(1: L), freq_data(1: L)), axis(axis_temp)* A' Y* {& t$ e; G1 _& [- i
title('FFT of Transmitted OFDM'): S& O: @9 ^. M3 x; ~
end6 `2 U+ W9 T \' P
- r! V& Q9 ]- W7 q& Y( ~( n% if file_input_type == 4
) Z* Y* s C5 ^% figure(5)
* g, S+ v5 G3 T+ w% subplot(211)2 X2 x7 @: ^" h& c
% image(data_in);* s- ]+ a r& t( y
% colormap(map);8 H2 ~: k8 d' g( \
% subplot(212)
- C& G" v' m7 O) u- C% image(output); }# j: x3 U0 O: T2 `8 S1 r2 m
% colormap(map);4 b# O# U" d: g2 N5 n& y
% end. }! Z" s: K' V/ m# N
0 G1 c& }7 k0 J5 [, D' _4 qif do_QAM == 1 % analyze if QAM was done
+ p, `/ Z2 Q3 {) K3 q. N4 V6 e ' {/ K+ ~1 c: L# a* h
figure(3), clf
" \# L. ~% I" V if (input_type == 1) & (test_input_type == 1)6 }: M; Y5 ?/ Y- W% {. ^ ]
subplot(221), stem(data_in), title('QAM Binary Input Data');
, W, u L; x% Y$ Y) L subplot(223), stem(QAM_data_out), title('QAM Recovered Binary Data')
6 E7 q/ Z; Y" E1 A8 | else
+ a+ l1 I+ \2 d: t* O subplot(221), plot(data_samples), title('QAM Symbol Input Data');
2 r. F- P" Z; W: U) W7 f subplot(223), plot(QAM_output_samples), title('QAM Recovered Symbols');
& z4 h+ V$ w" _5 F5 Q3 K3 U end$ T7 a o" F% F( J; }; ~
subplot(222), plot(QAM_tx_data), title('Transmitted QAM');
% \# |! n4 s% D subplot(224), plot(QAM_rx_data), title('Received QAM');
; V7 b- t4 K- F: q9 F* u* y 0 O& f% V+ l B) a
dig_x_axis = (1: length(QAM_tx_data))/length(QAM_tx_data);! U' {+ ]. i) e S0 L# N4 J
figure(4), clf: a- F% m! \2 x8 c
) ]) } P; L4 C3 \) e if channel_on ==1$ r8 m4 F5 B2 r3 _% F
subplot(313)( m! }2 ?% f: E2 }; v# f
freq_data = abs(fft(QAM_rx_data));4 y1 k- J6 y8 ]& q' H& a
L = length(freq_data)/2;& _. p* b2 J: v7 o
plot(dig_x_axis(1: L), freq_data(1: L)): \* j6 M7 |3 F& M% y
xlabel('FFT of Received QAM')* T( |! C8 b) A( H$ F; Q% `
axis_temp = axis;
$ m1 m: `8 j* c- L
# u2 P7 @& I4 ^( W subplot(311),
! D0 F6 L3 \( N* Z freq_data = abs(fft(QAM_tx_data));6 f+ Z9 ?9 C8 I0 M
plot(dig_x_axis(1: L),freq_data(1: L)), axis(axis_temp)* ]* X4 b6 S8 C" e6 i* z/ Q1 S
title('FFT of Transmitted QAM')
+ E, K" ]1 Z3 w. S8 B% e+ \$ p5 J
" i4 d/ f6 v" X1 S1 {) L subplot(312)6 y% y T; C J
plot(W/(2*pi),mag)
# O: y+ b9 g7 A, z/ T. m ylabel('Channel Magnitude Response')
1 T a) f* o6 }0 V" s, n else- a* D4 W0 T7 ^% y( [
subplot(212)1 n8 w- J% s0 H9 P" m$ b
freq_data = abs(fft(QAM_rx_data));
+ v8 l( g+ }; f* z! L L = length(freq_data)/2;& I, d" o# S& e. S: k
plot(dig_x_axis(1: L), freq_data(1: L))8 K# N1 V% a" l
title('FFT of Received QAM')
1 a' P p/ v) o) E0 Y axis_temp = axis;9 y6 B% e0 x6 |1 q5 _" m/ Z
& n* E! [4 w* b g" {0 p; e
subplot(211),& T0 s7 c! Q1 \
freq_data = abs(fft(QAM_tx_data));
' a2 \5 y9 A6 A4 `( `# }0 P% R plot(dig_x_axis(1: L),freq_data(1: L)), axis(axis_temp)
$ b( e7 n8 S- t3 ~ title('FFT of Transmitted QAM')8 P( g: A! _( o9 z/ M' Z
end9 F7 s2 A* E2 q; \; @
, y I* m2 |# c; q8 K
% Plots the QAM Received Signal Constellation3 y! Y9 G- ^$ ^- E$ o
figure(5), clf, plot(xxx,yyy,'ro'), grid on, axis([-2.5 2.5 -2.5 2.5]), hold on
+ K. i+ _, \( j8 B C6 T: m- x! ^6 J. a
% % Overlay plot of transmitted constellation
/ N( \- U9 A1 ~8 g) q' ]% x_const = [-1.5 -0.5 0.5 1.5 -1.5 -0.5 0.5 1.5 -1.5 -0.5 0.5 1.5 -1.5 -0.5 0.5 1.5];# S% Q+ t! a% G9 t- I' W" C: b+ ^/ M
% y_const = [-1.5 -1.5 -1.5 -1.5 -0.5 -0.5 -0.5 -0.5 0.5 0.5 0.5 0.5 1.5 1.5 1.5 1.5];
- m1 p" S7 N3 `$ e0 q. h* o% plot(x_const, y_const, 'b*') [+ a3 t$ e! p& P2 ?
0 l5 ^( j1 {. Z8 k9 z % Overlay of constellation boundarys+ q, C& M: M1 z3 R% f! g
x1 = [-2 -2]; x2 = [-1 -1]; x3 = [0 0]; x4 = [1 1]; x5 = [2 2]; x6 = [-2 2];
+ y- b \% ^8 q2 |0 u- `: E y1 = [-2 -2]; y2 = [-1 -1]; y3 = [0 0]; y4 = [1 1]; y5 = [2 2]; y6 = [-2 2];4 i1 ]/ E5 v' v+ K" @* ~
plot(x1,y6), plot(x2,y6), plot(x3,y6), plot(x4,y6), plot(x5,y6)/ ~1 }) r n, k) P/ K
plot(x6,y1), plot(x6,y2), plot(x6,y3), plot(x6,y4), plot(x6,y5)
) [# ~5 R$ l# a8 u0 R
& \, _1 G6 P. y4 X* L, j- f hold off1 w3 P1 m: D/ l' Q8 x# \! U* S5 ?
title('16-QAM Received Signal Constellation and Decision Boundarys')$ i2 N6 l6 k/ f. V/ G& P0 u. ?" _- D% R( l
% W u8 E' ~# V. L, Q0 k
binary_err_bits_QAM = 0;
A+ U3 |+ T$ J- a' e/ X4 d2 Z+ X for i = 1:length(data_in)- G4 `; U3 ]7 J3 H1 F9 C
err = abs(data_in(i)-QAM_data_out(i));
3 d# P& _% j" ^0 h1 e* t/ Y2 u) p if err > 03 Q9 s7 d5 P4 {* V
binary_err_bits_QAM = binary_err_bits_QAM + 1;8 F+ E! J! X2 c
end1 I# g$ U+ u; F+ f/ q4 e! F8 r
end
6 U# |" m, ?) O& t BER_QAM = 100 * binary_err_bits_QAM/data_length;6 V- w1 H$ y2 M+ e7 z
end
2 L# J& k7 T' ^( e) h& [3 W, U3 ]6 E, Z" @, d2 }0 L5 m1 m3 H
figure(6), clf2 m6 f7 B9 S: e0 r, _0 u
if channel_on == 12 j- D9 A9 s4 L$ F& |" P
subplot(211), plot(W/(2*pi),mag),title('Channel Magnitude Response')6 T3 b0 ~) v: R' k2 l( P
xlabel('Digital Frequency'),ylabel('Magnitude in dB')0 {; w) ^9 J$ M$ C8 M
subplot(212), plot(W/(2*pi),phase),title('Channel Phase Response')3 U3 |2 {7 F/ J& g" c6 U
xlabel('Digital Frequency'),ylabel('Phase in Degrees')
5 m' e/ d0 K5 U! Ielse7 _; J% i. X( L! p k/ W
title('Channel is turned off - No frequency response to plot')) n; D" g+ v8 }3 h/ u
end( k; {/ T% j& F9 p" j3 d# ]
$ [$ [7 ~6 g7 L8 A: C; w
% Compare output to input and count errors* I" t; k. l+ g$ C" Q9 w: @, f" ^
binary_err_bits_OFDM = 0;+ L: M* P% @/ C( T
for i = 1:length(data_in)
, g3 _$ U5 _! t; F9 \/ Q5 ^ err = abs(data_in(i)-output(i));6 n9 M& Z' v W# ?7 i4 V& ?, a
if err > 0
# a$ o3 }# F7 H' C% R6 I' L binary_err_bits_OFDM = binary_err_bits_OFDM +1;4 c9 ~) q$ t, [) X3 P/ K2 C0 Q1 t
end
$ V2 u7 I# R! g/ }( l. D, Cend* g- ?) W f7 N7 a9 C9 T9 \. Z9 i
BER_OFDM = 100 * binary_err_bits_OFDM/data_length;
$ V) i0 [: H1 E2 Xdisp(strcat('OFDM: BER=', num2str(BER_OFDM,3), ' %'))
: h4 O- j+ h7 W. Ydisp(strcat(' Number of error bits=', num2str(binary_err_bits_OFDM)))
% B" d3 \: f- V# D) H& c7 |# V3 }6 g3 h6 A3 B7 N5 p4 ?
if (do_QAM == 1)$ _" f: M! l8 B& h$ @* t% }: J
disp(strcat('QAM: BER=', num2str(BER_QAM,3), ' %'))
$ s2 ?8 A0 R) _ O, Y( C4 J disp(strcat(' Number of error bits=', num2str(binary_err_bits_QAM)))) N! r5 ], g6 W3 y" ?! K7 L
end
6 A" c' Z- X: D, a8 r! X
8 p2 L" k; ~4 @9 Y% Display text file before and after modulation2 c! T P9 x! i& V( _9 j: Z
if (input_type == 2) & (file_input_type == 2)0 C. A3 l) D' A- ~
original_text_file = char(data_samples')$ t7 u9 t s+ e# E
if do_QAM ==1- g4 F2 a" q. w4 O( e. |! s, _
edit QAM_text_out.txt! v) U/ e% \% {( N% y* }4 b0 R
end/ ^( q: G0 c" a) a) t, u
edit OFDM_text_out.txt& f' d1 C5 L/ L
end
2 I( ^8 w7 n- w( l- f) k1 E0 r) x7 ]+ Y l+ f/ d! y' T7 ^
% Listen to sounds; Z0 c- u# h' ]
if (input_type == 2) & (file_input_type == 3) @6 L2 c7 b* H1 K/ E# ~% z# U1 e
do_again = '1';0 o# @1 L( o9 X$ b- ~
while ( ~(isempty(do_again)) )2 @7 ?; {! E1 p7 V# l
disp(' ')# D2 p7 k, G* }6 t R8 |' k
disp('Press any key to hear the original sound'), pause
. ?+ X, [5 j }& [1 A$ R" n sound(data_samples,11025)8 Q( d9 ^2 P( m; [+ K3 x# k; O
disp('Press any key to hear the sound after OFDM transmission'), pause# Q7 ]* \) \0 A% o* I: ~
sound(output_samples,11025)
Y" u# S0 \: e2 R1 {1 P8 q8 w( X if do_QAM == 1
( m) A. @* B3 H disp('Press any key to hear the sound after QAM transmission'), pause9 N- V( C: o* J8 C9 ?0 b+ y
sound(QAM_output_samples,11025): k/ s: G# P* }$ Q) o
end
# q9 C7 x0 p7 j0 j* t) Y# M+ T. ` do_again = '';
8 V% e8 q6 R) v0 t! l do_again = input('Enter "1" to hear the sounds again or press "Return" to end ', 's');
9 V2 }5 K+ [0 r3 U5 u( M. q3 I end$ K( S. g: s6 I: F5 W) H
end
. l& @& R2 B, P& c+ @! q/ `+ ^! J$ `% p% P3 g3 Y, `9 s
4 T2 W' m6 h# Y+ h |
|