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