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