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