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