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