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