📄 a_filter_design.m
字号:
if noChannel ~= 1
37
% large or small case
plot(W/(2*pi),mag),axis([0 0.5 -12 6]),title('Channel Magnitude Response')
xlabel('Digital Frequency'),ylabel('Magnitude (dB)')
else
% none case
plot(0:.05:.5,zeros(1,11)),axis([0 0.5 -12 6]),title('Channel Magnitude Response')
xlabel('Digital Frequency'),ylabel('Magnitude (dB)')
end
case 'close' %---------------------------------------
clear global COUNTER
close(gcbf)
case 'PlayOriginal' %-----------------------------------
sound(wavread('shortest.wav'),11025)
case 'PlayQAM' %---------------------------------------
sound(wavread('QAM_out.wav'),11025)
case 'PlayOFDM' %---------------------------------------
sound(wavread('OFDM_out.wav'),11025)
case 'PlayOriginalLong' %-----------------------------------
if strcmp('Student Edition',hostid)
sound(wavread('Long.wav',16384),11025) % check for student array size limit
else
sound(wavread('Long.wav'),11025)
end
case 'PlayQAMLong' %---------------------------------------
if strcmp('Student Edition',hostid)
sound(wavread('QAM_Long.wav',16384),11025) % check for student array size limit
else
sound(wavread('QAM_Long.wav'),11025)
end
case 'PlayOFDMLong' %---------------------------------------
if strcmp('Student Edition',hostid)
sound(wavread('OFDM_Long.wav',16384),11025) % check for student array size limit
else
sound(wavread('OFDM_Long.wav'),11025)
end
case 'figure' %---------------------------------------
% this is called whenever the figure is first created -or NOT???
% textHnd1=findobj('Tag','StaticTextFeedback');
% axisHnd1=findobj('Tag','Axes1');
% set(textHnd1,'String','Sound OFDM Demo') % default text message
% set(axisHnd1,'Visible','off') % hide Axis to begin
end
% pol2bin.m
function y = pol2bin(x)
% pol2bin
%
% Converts polar numbers (-1,1) to binary numbers (0,1)
% Accepts a 1-D array of polar numbers
% Removes trailing zeros, since they are not valid data
% % Remove zeros - not needed with intelligent decoding
% last_data=length(x);
% while x(last_data) == 0
% last_data = last_data - 1;
% end
y = ones(1,length(x));
for i = 1:length(x)
if x(i) == -1
y(i) = 0;
end
end
38
% QAM.m
% QAM.m compares OFDM (multicarrier) to multi-level QAM (single carrier)
% when they transmit the same # of bits in a given time period
read % read data for QAM - does not affect OFDM
data_in_pol = bin2pol(data_in); % Converts binary data to polar data
% check to see if num_carriers is a power of 2
is_pow_2 = num_carriers;
temp_do_QAM = 0;
if is_pow_2 ~= 2
while temp_do_QAM == 0
temp_do_QAM = rem(is_pow_2,2);
is_pow_2 = is_pow_2/2;
if is_pow_2 == 2
temp_do_QAM = -99; % it is a power of 2 -> can do QAM
end
end
else
temp_do_QAM = -99; % 2 is a power of 2
end
if temp_do_QAM ~= -99
do_QAM = 0; % don't do it if it's not possible
disp(' '),disp('ERROR: Cannot run QAM because num_carriers is not valid.')
disp(' Please see "setup.m" for details.')
end
if do_QAM == 1
tic % Start stopwatch to calculate how long QAM simulation takes
disp(' '), disp('------------------------------------------------------------')
disp('QAM simulation'), disp('Transmitting')
% Pad with zeros so data can be divided evenly
data_length = length(data_in_pol);
r = rem(data_length,num_carriers);
if r ~= 0
for i = 1:num_carriers-r
data_in_pol(data_length+i) = 0; %pad input with zeros to complete last data set
end %speed improve possible
end
data_length = length(data_in_pol); %update after padding
num_OFDM_symbols = ceil(data_length / (2*num_carriers));
% num QAM symbols that represent equal amount of data to one OFDM symbol
num_QAM_symbols = num_carriers / 2;
% num samples per QAM symbol
num_symbol_samples = fft_size / num_QAM_symbols;
% convert polar data [-1, 1] to 4 level data [-3, -1, 1, 3]
data_in_4 = zeros(1,data_length/2);
for i = 1:2:data_length
data_in_4(i - (i-1)/2) = data_in_pol(i)*2 + data_in_pol(i+1);
end
% define sample points between 0 and 2*pi
ts = linspace(0, 2*pi*QAM_periods, num_symbol_samples+1);
% Generate 16-QAM data
% total length of 16-QAM transmission
tx_length = num_OFDM_symbols * num_QAM_symbols * num_symbol_samples;
QAM_tx_data = zeros(1,tx_length);
for i = 1:2:data_length/2
for k = 1:num_symbol_samples
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));
end
end
% Do channel simulation on QAM data
xmit = QAM_tx_data; % ch uses 'xmit' data and returns 'recv'
ch
QAM_rx_data = recv; % save QAM data after channel
clear recv % remove 'recv' so it won't interfere with OFDM
clear xmit % remove 'xmit' so it won't interfere with OFDM
disp('Receiving') % Recover Binary data (Decode QAM)
cos_temp = zeros(1,num_symbol_samples); %
sin_temp = cos_temp; %
39
xxx = zeros(1,data_length/4); % Initialize to zeros for speed
yyy = xxx; %
QAM_data_out_4 = zeros(1,data_length/2); %
for i = 1:2:data_length/2 % "cheating"
for k = 1:num_symbol_samples
% multiply by carriers to produce high frequency term and original data
cos_temp(k) = QAM_rx_data(k+((i-1)/2)*num_symbol_samples) * cos(ts(k));
sin_temp(k) = QAM_rx_data(k+((i-1)/2)*num_symbol_samples) * sin(ts(k));
end
% LPF and decide - we will do very simple LPF by averaging
xxx(1+(i-1)/2) = mean(cos_temp);
yyy(1+(i-1)/2) = mean(sin_temp);
% Reconstruct data in serial form
QAM_data_out_4(i) = xxx(1+(i-1)/2);
QAM_data_out_4(i+1) = yyy(1+(i-1)/2);
end
% Make decision between [-3, -1, 1, 3]
for i = 1:data_length/2
if QAM_data_out_4(i) >= 1, QAM_data_out_4(i) = 3;
elseif QAM_data_out_4(i) >= 0, QAM_data_out_4(i) = 1;
elseif QAM_data_out_4(i) >= -1, QAM_data_out_4(i) = -1;
else QAM_data_out_4(i) = -3;
end
end
% Convert 4 level data [-3, -1, 1, 3] back to polar data [-1, 1]
QAM_data_out_pol = zeros(1,data_length); % "cheating"
for i = 1:2:data_length
switch QAM_data_out_4(1 + (i-1)/2)
case -3
QAM_data_out_pol(i) = -1;
QAM_data_out_pol(i+1) = -1;
case -1
QAM_data_out_pol(i) = -1;
QAM_data_out_pol(i+1) = 1;
case 1
QAM_data_out_pol(i) = 1;
QAM_data_out_pol(i+1) = -1;
case 3
QAM_data_out_pol(i) = 1;
QAM_data_out_pol(i+1) = 1;
otherwise
disp('Error detected in switch statment - This should not be happening.');
end
end
QAM_data_out = pol2bin(QAM_data_out_pol); % convert back to binary
% Stop stopwatch to calculate how long QAM simulation takes
QAM_simulation_time = toc;
if QAM_simulation_time > 60
disp(strcat('Time for QAM simulation=', num2str(QAM_simulation_time/60), ' minutes.'));
else
disp(strcat('Time for QAM simulation=', num2str(QAM_simulation_time), ' seconds.'));
end
end
% read.m
% read
% ******************FILE INPUT SETUP*********************************
if input_type == 2
if file_input_type == 1
%binary file input
end
if file_input_type == 2
%text file input
file = fopen(file_name,'rt');
data_samples = fread(file,'char');
fclose(file);
data_in = zeros(1,8*length(data_samples));
for i = 1:length(data_samples)
data_in(1 + (i-1)*8:(i-1)*8 + 8) = eight2bin(data_samples(i));
end
end
40
if file_input_type == 3
%sound file input
data_samples=wavread(file_name);
%needs to be normalized from -1:1 to 0:255 for 8 bit conversion
data_samples_resized = round(128*data_samples +127);
data_in = zeros(1,8*length(data_samples_resized));
for i = 1:length(data_samples_resized)
data_in(1 + (i-1)*8:(i-1)*8 + 8) = eight2bin(data_samples_resized(i));
end
end
if file_input_type == 4
%image file input
[data_in,map]=imread(file_name); % read image and corresponding color map for display
end
end
% rx.m
% rx
disp('Receiving')
rx_chunk
% perform fft to recover original data from time domain sets
recv_spaced_chunks = zeros(num_chunks,fft_size);
for i = 1:num_chunks
recv_spaced_chunks(i,1:fft_size) = fft(recv_td_sets(i,1:fft_size));
% Note: 'round()' gets rid of small numerical error in Matlab but a threshold will be needed for a practical system
% 2001-4-17 -- Got rid of 'round()' to do decoding more intelligently
end
rx_dechunk
output = pol2bin(output); % Converts polar to binary
write
% rx_chunk.m
% rx_chunk
% break received signal into parellel sets for demodulation
recv_td_sets = zeros(num_chunks,fft_size);
for i = 1:num_chunks
for k = 1:fft_size
recv_td_sets(i,k) = recv(k + (i-1)*fft_size);
end
end
% rx_dechunk.m
% rx_dechunk
% take out zeros_between from recv_spaced_chunks --> recv_padded_chunks
recv_padded_chunks = zeros(num_chunks, num_carriers+num_zeros);
i = 1;
for k = zeros_between +1:zeros_between +1:fft_size/2
recv_padded_chunks(1:num_chunks,i) = recv_spaced_chunks(1:num_chunks,k);
i = i+1;
end
% take out num_zeros from padded chunks --> recv_chunks
recv_chunks = zeros(num_chunks, num_carriers);
recv_chunks = recv_padded_chunks(1:num_chunks, num_zeros+1:num_carriers+num_zeros);
% Recover bit stream by placing reconstructed frequency domain data in series
recv_dechunked = zeros(1, num_chunks*num_carriers);
for i = 1:num_chunks
for k = 1:num_carriers
recv_dechunked(k + (i-1)*num_carriers*2) = real(recv_chunks(i,k));
recv_dechunked(k + (i-1)*num_carriers*2 + num_carriers) = imag(recv_chunks(i,k));
end
end
41
% take out trailing zeros from output --> output
output_analog = recv_dechunked(1:data_length);
output = sign(output_analog);
% setup.m
% setup
disp(' '), disp('------------------------------------------------------------')
disp('Simulation Setup')
% OFDM Setup -----------------------------------------------------------
fft_size = 128 % should be a power of 2 for fast computation
% more points = more time domain samples (smoother & more cycles)
num_carriers = 32 % should be <= fft_size/4
% number of carriers used for each data chunk
% new var - denotes even spacing or variations of carriers among fft points
input_type = 2;
% 1 = test input
test_input_type = 1;
% 1 = bit specified (binary)
binary_data = [0 1 0 1 0 1 0 1];
% 2 = random data stream (samples in the range of 0-255)
num_symbols = 9;
% 3 = sinusoidal
frequency = 2;
num_samples = 50;
% 2 = external file input
file_name = 'shortest.wav'; % Name of input file
file_input_type = 3;
% 1 = binary (not implemented)
% 2 = text % Demo file: 'text.txt'
% 3 = sound % Demo files: 'shortest.wav' & 'shorter.wav'
% 4 = image (not implemented)
% QAM Setup ------------------------------------------------------------
do_QAM = 1; % (1=on, 0=off)
QAM_periods = 10; % defines the number of periods per QAM Symbos (1=2*pi)
% Channel Simulation Parameters --------------------------------------------
channel_on = 1; % 1=on, 0=off
clip_level = 1.0; % 0.0 - 1.0 (0-100%)
% Max magnitude of the signal is 'clip_level' times the full magnitude of the signal
noise_level = 0.0; % 0.0 - 1.0 (0-100%)
% Magnitude of noise is 'noise_level' times the magnitude of the signal
% Multipath Channel Simulation
% Good defaults when fft_size = 128 and num_carriers = 32:
% d1=6; a1=0.30; d2=10; a2=0.25
d1 = 6; % delay in units
a1 = 0.32; % attenuation factor - multipath signal is x% of size or original signal
d2 = 10; % delay for second multipath signal
a2 = 0.28; % attenuation factor for second multipath signal
% ****************** TEST INPUT SETUP - DO NOT MODIFY **************************
if input_type == 1
if test_input_type == 1
%specify BINARY input bit-by-bit
data_in = binary_data;
end
if test_input_type == 2
%random input defined by parameters
num_levels = 255; %number of possible levels of a symbol
%must be integer between 1-255
data_samples = round(rand(1,num_symbols)*(num_levels-1));
data_in = zeros(1,8*length(data_samples));
for i = 1:length(data_samples)
data_in(1 + (i-1)*8:(i-1)*8 + 8) = eight2bin(data_samples(i));
end
end
if test_input_type == 3
%data stream represents sine wave samples
t = linspace(0,1,num_symbols); %evenly space number of samples
%take 8-bit samples of sine wave
data_samples = round(127.5*sin(frequency*2*pi*t) +127.5);
data_in = zeros(1,8*length(data_samples));
42
for i = 1:length(data_samples)
data_in(1 + (i-1)*8:(i-1)*8 + 8) = eight2bin(data_samples(i));
end
end
end
already_made_noise = 0; % initialization (don't change)
% SetupGUI.m
% SetupGUI.m sets up the basicGUI variables
% Initialize the appropriate setup.m variables
fft_size = 64;
num_carriers = 4;
input_type = 1; test_input_type = 1;
channel_on = 0;
do_QAM = 0;
data_samples = [0 0 0 1 1 0 1 1]; % data to be transmitted
data_in = data_samples;
% SetupSoundGUI.m
% SetupSoundGUI.m sets up the SoundGUI variables
% Initialize the appropriate setup.m variables
fft_size = 128;
num_carriers = 32;
input_type = 2; file_input_type = 3; file_name = 'shortest.wav';
channel_on = 1;
do_QAM = 1;
QAM_periods = 10;
clip_level = 1.0; % 0.0 - 1.0 (0-100%)
noise_level = 0.0;
already_made_noise = 0;
ComputeChannelGUI
% SoundGUI.m
function SoundGUI()
% This is the machine-generated representation of a MATLAB object
% and its children. Note that handle values may change when these
% objects are re-created. This may cause problems with some callbacks.
% The command syntax may be supported in the future, but is currently
% incomplete and subject to change.
%
% To re-open this system, just type the name of the m-file at the MATLAB
% prompt. The M-file and its associtated MAT-file must be on your path.
load SoundGUI
a = figure('Color',[0.9 0.9 0.9], ...
'Colormap',mat0, ...
'CreateFcn','OFDMguiFn figure', ...
'Position',[376 239 624 480], ...
'Resize','off', ...
'Tag','Fig1');
b = uicontrol('Parent',a, ...
'Units','points', ...
'BackgroundColor',[1 1 1], ...
'FontName','Monaco', ...
'HorizontalAlignment','left', ...
'Position',[59 2 340 94], ...
'String','Sound OFDM Demo', ...
'Style','text', ...
'Tag','StaticTextFeedback');
b = uicontrol('Parent',a, ...
'Units','points', ...
'BackgroundColor',[0.3 0.3 0.3], ...
'Position',[472 -1 152 481], ...
'Style','frame', ...
'Tag','Frame1');
b = uicontrol('Parent',a, ...
'Units','points', ...
'BackgroundColor',[0.733333 0.733333 0.733333], ...
'Callback','OFDMguiFnSound next', ...
'FontSize',14, ...
43
'Position',[493 435 102 32], ...
'String','Begin', ...
'Tag','PushbuttonNext');
b = uicontrol('Parent',a, ...
'Units','points', ...
'BackgroundColor',[0.733333 0.733333 0.733333], ...
'Callback','OFDMguiFnSound close', ...
'FontSize',14, ...
'Position',[493 10 102 32], ...
'String','Close', ...
'Tag','PushbuttonClose');
b = uicontrol('Parent',a, ...
'Units','points', ...
'BackgroundColor',[0.733333 0.733333 0.733333], ...
'Callback','OFDMguiFnSound mp_channel', ...
'Enable','off', ...
'Position',[489 209 87 30], ...
'String',mat1, ...
'Style','popupmenu', ...
'Tag','PopupMenuMultipath', ...
'Value',2, ...
'Visible','off');
b = uicontrol('Parent',a, ...
'Units','points', ...
'BackgroundColor',[0.733333 0.733333 0.733333], ...
'Enable','off', ...
'FontWeight','bold', ...
'Position',[489 251 129 17], ...
'String','Multipath Channel', ...
'Style','text', ...
'Tag','StaticTextMultipath', ...
'Visible','off');
b = uicontrol('Parent',a, ...
'Units','points', ...
'BackgroundColor',[0.733333 0.733333 0.733333], ...
'FontWeight','bold', ...
'Position',[489 398 129 18], ...
'String','Generated Sounds', ...
'Style','text', ...
'Tag','StaticTextGenSounds', ...
'Visible','off');
b = uicontrol('Parent',a, ...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -