### Updated MATLAB files

parent c9d842b5
 function rxSigFreq = F_Apply_RX_Filter(distSigFreq,params) % This function calculates the transfer function (Hrrc) of the root raised % cosine function in the frequency domain and applies it to the Baseband % Reference Waveform. This is discussed in IEEE P1765 document Section % 5.1.2.1 and Annex A. % % Inputs: % distSigFreq: Baseband version of reference signal in frequency domain % params: Structure containing all the basic communication parameters % % Outputs: % rxSigFreq: The filtered spectrum in the frequency domain using the % matched filter intended for the modulation type being used. global structGlobal % Calculate Root Raised Cosine Filter's Transfer Function in Frequency Domain % Hrrc based on Joost's paper Hrrc = F_freqSqrtRaisedCosine(1/params.fsym, params.rolloff, 1/params.fsamp, params.numseg*length(params.t1)); % To match the length of the Hrrc vector with the other previously defined vectors Hrrc = [zeros(round((params.numSamp-length(Hrrc))/2),1);Hrrc;zeros(round((params.numSamp-length(Hrrc))/2),1)]; Hrrc = Hrrc(1:length(Hrrc) - 1); % Removing endpoint to match with numSamp Hrrc = circshift(Hrrc,length(Hrrc)/2); % For baseband Hrrc = transpose(Hrrc)/max(Hrrc); % Ensuring unit gain in passband % Apply Ideal Matched Filtering to Baseband Reference Waveform rxSigFreq = distSigFreq.*Hrrc; % Ideal matched filtering in frequency domain rxSig = ifft(rxSigFreq); % Transform match-filtered Baseband Reference Waveform to the time domain structGlobal.rxSigAve = abs(sum(rxSig)/length(distSigFreq)); % Signal Average Value (should be small) end \ No newline at end of file
 function params = F_Basic_Communication_Parameters() % This function defines the basic communication parameters for the P1765 % Baseline EVM Algorithm code including the root raised cosine filter % params is the structure which will store all the defined parameters params.QAM = 64; % N-QAM params.N = abs(sqrt(params.QAM)); % N-QAM params.fcarr = 4; % RF carrier frequency in GHz params.fsamp = 20; % Sample rate in GSsamples/s params.numSym = 511; % Number of symbols params.fsym = 1; % Symbol rate in GSymbols/s params.numSampSym = round(params.fsamp / params.fsym); % Number of samples/symbol params.numSamp = params.numSym * params.numSampSym; % Number of time samples params.dt1 = 1/params.fsamp; % Time sample spacing (ns) params.t1 = (0:params.numSamp-1) * params.dt1; % Time sampling grid (ns) params.tinterval = params.dt1*params.numSamp; % Time length of grid (ns) params.df1 = params.fsamp/params.numSamp; % Frequency grid spacing (GHz) params.f1 = (-(params.numSamp/2):(params.numSamp/2)-1) * params.df1; % Standard frequency grid (GHz) params.finterval = params.df1*params.numSamp; % Frequency length of grid (GHz) = time-domain record DFT BW params.rolloff = 0.35; % Filter rolloff params.span = params.numSym; % Filter span (symbols) params.sps = round(params.fsamp/params.fsym); % Samples per symbol end
 function F_Plot_Constellation_Diagram(refSym,rxSym,params) % This function plots the reference and received signal constellation % diagrams and saves it in the evm_results_folder which was taken as % input from the user in F_UserInputs(). % The constellation diagram is saved with the filename which was taken as % input from the user in F_UserInputs(). % This version has been tested on several monitors and resolutions to % ensure that it plots reliable constellation diagrams without any adjustment. % % Inputs: % refSym: Reference Symbols % rxSym: Received Symbols % params: Structure containing all the basic communication parameters global structGlobal % Create figure figure1 = figure('NumberTitle','off'); % Create axes axes1 = axes('Parent',figure1); hold(axes1,'on'); % Create reference signal constellation plot X1 = real(refSym); Y1 = imag(refSym); plot(X1,Y1,'DisplayName','Reference Symbols','MarkerSize',8,'Marker','o','LineWidth',1,'LineStyle','none','Color',[0 0 1]); % Create receiver signal constellation plot X2 = real(rxSym); Y2 = imag(rxSym); plot(X2,Y2,'DisplayName','Received Symbols','MarkerSize',8,'Marker','x','LineWidth',1,'LineStyle','none','Color',[1 0 0]); % Create xlabel xlabel('In-Phase (I)','HorizontalAlignment','center','FontSize',24); % Create ylabel ylabel('Quadrature (Q)','HorizontalAlignment','center','FontSize',24); % Create title stri = strcat(structGlobal.SISmn,' 64-QAM Constellation'); title(stri,'VerticalAlignment','bottom','HorizontalAlignment','center','FontWeight','bold','FontSize',24); % Create legend legend1 = legend(axes1,'show'); % Placement of plot legend in MATLAB plot window set(legend1,'Position',[0.60 0.02 0.35 0.08],'FontSize',14); % Set the remaining axes/figure properties axis square box(axes1,'on'); set(axes1,'XLim',[-params.N params.N]); set(axes1,'xtick',(-params.N:2:params.N)); set(axes1,'YLim',[-params.N params.N]); set(axes1,'ytick',(-params.N:2:params.N)); set(axes1,'FontSize',24,'GridAlpha',1,'XGrid','on','YGrid','on'); % Move the plot box up to accomodate the legend current_position = get(gca, 'Position'); set(gca, 'Position', current_position + [0, +0.02, 0, +0.02]); % Set the actual height and width of the box width = 5; height = 5; set(gcf, 'Units', 'Inches', 'Position', [1, 1, width+1, height+1], 'PaperUnits', 'Inches', 'PaperSize', [width, height]) set(gca, 'Fontsize', 14); % Saving figure as graphic file in current directory (plot must still be present in MATLAB plot window) stri_fig = fullfile(structGlobal.evm_results_folder,strcat(structGlobal.filename_constellation,'.jpg')); set(figure1,'PaperPositionMode','auto'); print(figure1,stri_fig,'-djpeg','-r300'); end \ No newline at end of file
 function [EVMrms_pct,G_OPT] = F_Sample_Normalize_EVM(refSig,rxSig,params) % This function performs symbol sampling, determines the complex gain % G_OPT and normalization and calculates EVM as mentioned in the IEEE % P1765 document in Sections 5.1.2.3, 5.1.2.4, and 5.1.2.5 respectively. % % Inputs: % refSig: Time-domain waveform from 64-QAM ideal constellation % rxSig: Optimal time-delayed and waveform normalized version of XOut % where XOut = fft shifted version of match-filtered reference signal spectrum % params: Structure containing all the basic communication parameters % % Outputs: % EVMrms_pct: Baseline rms EVM in percent % G_OPT: Optimal complex gain/ normalization factor for symbol samples % G_OPTamp: abs(G_OPT) % G_OPTphase: angle(G_OPT) in degrees % % Extra outputs: % EVMpeak_pct: Baseline peak EVM in percent global structGlobal % Sampling symbols (Section 5.1.2.3) from optimally aligned/normalized waveforms refSym = refSig(1:params.numSampSym:params.numSamp); rxSym = rxSig(1:params.numSampSym:params.numSamp); % Optimal Normalization (Section 5.1.2.4) for Symbol Samples rxSymPower = dot(rxSym,rxSym); rxrefSymCorr = dot(rxSym,refSym); G_OPT = rxrefSymCorr/rxSymPower; rxSym = G_OPT*rxSym; % Optimal symbol normalization of received signal constellation % RMS EVM Calculation (Section 5.1.2.5) EV = rxSym - refSym; EVMrms_pct = 100*sqrt(dot(EV,EV)/dot(refSym,refSym)) % Peak EVM Calculation EVMp = max(abs(EV)); refSymPower = dot(refSym,refSym)/params.numSym; structGlobal.EVMpeak_pct = 100*EVMp/sqrt(refSymPower); F_Plot_Constellation_Diagram(refSym,rxSym,params); end
 function F_Save_Results(EVMrms_pct, tau0, G_OPT) % This function saves the IEEE P1765 Baseline EVM Algorithm's official outputs % EVMrms_pct: Baseline rms EVM in percent % tau0: Optimal time delay before same sampling/calculation % G_OPT: Optimal complex gain / normalization factor for symbol samples % (saved as absolute and phase parts) % % It also saves the extra outputs in the same file for users % rxSigAve: Received signal average value % optTolerance: Absolute tolerance determined for iterative delay calculation convergence (ns) % iterindx: Number of iterations for optimal delay loop convergence (= 10000 if convergence fails) % G_0: Optimal complex gain to be applied before symbol sampling/EVM calculation saved as % G_0amp: abs(G_0) % G_0phase: angle(G_0) in degrees % EVMpeak_pct: Peak EVM (in %) global structGlobal G_OPTamp = abs(G_OPT); G_OPTphase = angle(G_OPT)*180/pi; % degrees fname = strcat(structGlobal.filename_results,'.txt'); fid = fopen(fullfile(structGlobal.evm_results_folder,fname),'w'); fprintf(fid,'\n\n'); fprintf(fid,'%s\n','OFFICIAL RESULTS'); Official_Quantity = [{'EVM_rms%', 'Optimal Delay (ns)','G_OPT Amp', 'G_OPT Phase (deg)'}]; Official_Value = [EVMrms_pct; tau0; G_OPTamp; G_OPTphase]; fprintf(fid,'%s\n','------------------------------------------------'); fprintf(fid, '%s \t %s\r\n', 'Official Quantity', 'Value'); fprintf(fid,'%s\n','------------------------------------------------'); for n =1:length(Official_Value) fprintf(fid, '%-23s %1.15g\r\n', Official_Quantity{n}, Official_Value(n)); end fprintf(fid,'\n\n'); fprintf(fid,'%s\n','Official Quantity Definition:'); fprintf(fid,'%s\n','-----------------------------'); fprintf(fid,'%s\n','> EVM_rms% = RMS EVM as a percentage'); fprintf(fid,'%s\n','> Optimal Delay (ns) = Optimal time delay to be applied in the phase of XOut before symbol sampling/EVM calculation'); fprintf(fid,'%s\n',' where XOut is fftshifted match filtered baseband version of reference signal in frequency domain'); fprintf(fid,'%s\n','> G_OPT Amp = Symbol Norm Amp = abs(G_OPT), where G_OPT is optimal complex gain/normalization factor for symbol samples'); fprintf(fid,'%s\n','> G_OPT Phase = Symbol Norm Phase = angle(G_OPT) in degrees'); fprintf(fid,'\n\n'); Extra_Quantity = [{'DC Value', 'Delay Tolerance (ns)', 'Delay Iterations', 'Wvfrm Gain Amp', 'Wvfrm Gain Phase (deg)','EVM_peak%'}]; Extra_Value = [structGlobal.rxSigAve; structGlobal.optTolerance; structGlobal.iterindx; structGlobal.G_0amp; structGlobal.G_0phase; structGlobal.EVMpeak_pct]; fprintf(fid,'%s\n','------------------------------------------------'); fprintf(fid, '%s \t\t %s\r\n', 'Extra Quantity', 'Value'); fprintf(fid,'%s\n','------------------------------------------------'); for n =1:length(Extra_Value) fprintf(fid, '%-23s %1.15g\r\n', Extra_Quantity{n}, Extra_Value(n)); end fprintf(fid,'\n\n'); fprintf(fid,'%s\n','Extra Quantity Definition:'); fprintf(fid,'%s\n','--------------------------'); fprintf(fid,'%s\n','> DC Value = Received signal average value'); fprintf(fid,'%s\n','> Delay Tolerance (ns) = Absolute tolerance determined for iterative delay calculation convergence'); fprintf(fid,'%s\n','> Delay Iterations = Number of iterations for optimal delay loop convergence (= 10000 if convergence fails'); fprintf(fid,'%s\n','> Wvfrm Gain Amp = abs(G_0), where G_0 = Optimal complex gain is applied to XOut before symbol sampling/EVM calculation'); fprintf(fid,'%s\n',' where XOut = fft shifted version of match-filtered reference signal spectrum'); fprintf(fid,'%s\n','> Wvfrm Gain Phase = angle(G_0) in degrees'); fprintf(fid,'%s\n','> EVM_peak% = Peak EVM as a percentage'); fclose(fid); end
 function F_UserInputs() global structGlobal % Select the folder where these programs reside uiwait(msgbox({'In order for the program to run correctly,'... 'the parent program folder needs to be selected'... 'as the working directory in the next window.'})); pause(0.001); program_folder = uigetdir(pwd,'Select the folder where these programs reside'); cd(program_folder); % Select a folder to save the EVM results based on user input'); structGlobal.evm_results_folder = uigetdir(pwd,'Select a folder to save EVM calculation results'); % Read in ASCII Baseband Reference Waveform file disp('__________________________________________________________________'); disp('The user’s selection will be based on the P1765 Signal Impairment Sets'); disp('defined in Section 6.1 and Annex A of IEEE P1765'); disp('Read in ASCII Baseband Reference Waveform file'); disp('__________________________________________________________________'); [filename,path] = uigetfile([pwd,'\P1765 Reference Waveforms\Baseband\Waveform_SIS01_BB.txt'],'Select the signal text file'); structGlobal.file = fullfile(path,filename); % Find the starting index of SIS in the filename for default filenaming convention % SIS = Signal Impairment Sets. % The filenames have SIS followed by two digits from 01 through 21 SISmn_index_start = strfind(filename,'SIS'); SISmn_index_end = SISmn_index_start + 4; % Extract the SISmn from the waveform file structGlobal.SISmn = filename(SISmn_index_start:SISmn_index_end); %% Enter filename to use for saving results or choose to use the default name list = {'DEFAULT filename','CUSTOM filename'}; [filename_choice,~] = listdlg('PromptString',... {'Would you like to set a default or custom filename','for EVM results?'},... 'SelectionMode','single','ListSize',[250,100],'ListString',list); if filename_choice == 1 structGlobal.filename_results = strcat('EVM_',structGlobal.SISmn); else prompt = {'Enter filename (without extension):'}; dlgtitle = 'Custom filename'; dims = [1 50]; definput = {'evm_results_file'}; response = inputdlg(prompt,dlgtitle,dims,definput); structGlobal.filename_results = response{1}; end %% Enter filename to use for saving constellation diagram or choose to use the default name list = {'DEFAULT filename','CUSTOM filename'}; [filename_choice,~] = listdlg('PromptString',... {'Would you like to set a default or custom filename','for constellation diagram?'},... 'SelectionMode','single','ListSize',[250,100],'ListString',list); if filename_choice == 1 structGlobal.filename_constellation = strcat('Constellation_',structGlobal.SISmn); else prompt = {'Enter filename (without extension):'}; dlgtitle = 'Custom filename'; dims = [1 50]; definput = {'constellation_diagram_file'}; response = inputdlg(prompt,dlgtitle,dims,definput); structGlobal.filename_constellation = response{1}; end disp(['EVM results will be saved in the following folder: ',structGlobal.evm_results_folder]); disp(['Filename for the storing the EVM results: ',structGlobal.filename_results]); disp(['Filename for the saving the constellation diagram: ',structGlobal.filename_constellation]); disp('__________________________________________________________________'); end \ No newline at end of file
 function [tau0, XOutopt] = F_calculateOptimal(XIn, XOut, Ts) % Version: 8.27.2020 % % % Function to calculate baseline EVM receiver optimal time delay and % complex normalization based on all time samples (carried out in frequency domain). % See Section 5.1.2.2 Optimal Time Alignment of Waveform 2 to Waveform 1 % and Removal of Constant Phase Offset, and Annex B of IEEE P1765 document. % % Inputs: % XIn: Discrete uniform spectra of input waveform with frequency spacing 1/Ts % XOut: Same but for output waveform % Ts: Time duration (ns) of input/output time-domain waveforms corresponding to XIn and XOut % % Outputs: % tau0: Optimal time delay to be applied in the phase of XOut before same sampling/calculation % XOutopt: XOut after optimal time-shifting/normalization % % Extra outputs: % G_0: Optimal complex gain to be applied to XOut before symbol sampling/EVM calculation % G_0amp: abs(G_0) % G_0phase: angle(G_0)*180/pi % optTolerance: Absolute tolerance determined for iterative delay calculation convergence % iterindx: Number of iterations for optimal delay loop convergence (= 10000 if convergence fails) global structGlobal K = length(XIn); % K is the number of sampling intervals in XIn (which must equal that in XOut) % and also equal to number of time sampling points in Xin and Xout minus one % (last end-sample identified with first one due to periodicity) P0 = conj(XIn).*XOut; P1 = P0.*(0:K - 1); P2 = P1.*(0:K - 1); domega = 2*pi/Ts; % Angular frequency spacing of XIn and XOut dt = Ts/K; % Time sampling interval % First coarse alignment based on cross-correlation % See Section 5.1.2.2(1) of IEEE P1765 document: Coarse time alignment R = abs(ifft(P0)); [Rmax, Icoarse] = max(R); T0init = (Icoarse - 1)*dt; % Coarse delay (within one time sampling interval dt) % Fine time alignment % See Section 5.1.2.2(2) of IEEE P1765 document: Fine time alignment % Parabolic fit refinement if Icoarse ==1 Rleft = R(K); Rright = R(2); elseif Icoarse == K Rleft = R(K - 1); Rright = R(1); else Rleft = R(Icoarse - 1); Rright = R(Icoarse + 1); end T = T0init + (dt/2)*(Rleft - Rright)/(Rleft + Rright - 2*Rmax); % Parabolic fit refined delay estimate % Iterative optimal refinement structGlobal.optTolerance = 10*eps(T); % MATLAB eps function giving distance from T to nearest double floating % point number (margin factor of 10 added to reach usable tolerance) domegaT = domega*T; domegadT = 1; domegadTtol = domega*structGlobal.optTolerance; % Iterative tolerance for domegaT index = 1; while (abs(domegadT) > domegadTtol) && (index < 10001) % Failsafe loop exit criteria Mc = exp(-1i*(0:K - 1)*domegaT); C0 = dot(Mc,P0); C1 = dot(Mc,P1); C2 = dot(Mc,P2); num = imag(C1*conj(C0)); den = real(abs(C1)^2 - C2*conj(C0)); domegadT = num/den; domegaT = domegaT + domegadT; index = index + 1; end G_0 = dot(XOut,(XIn.*Mc))/dot(XOut,XOut); % Optimal complex gain, this variable is not used further per Section 5.1.2.2 tau0 = domegaT/domega; % Optimal time delay XOutopt = G_0*(XOut.*conj(Mc)); % Optimal time delayed/normalized version of XOut errvecopt = XIn - XOutopt; % Error vector of optimal alignment/normalization errmin = dot(errvecopt,errvecopt); % Minimum error power between XIn and XOut structGlobal.iterindx = index - 1; % Number of domegaT loop iterations (= 10000 if convergence fails) structGlobal.G_0amp = abs(G_0); structGlobal.G_0phase = angle(G_0)*180/pi; end \ No newline at end of file
 function Hrrc = F_freqSqrtRaisedCosine(Tsym, alpha, deltaT, N) % This function generates the frequency response of a root raised cosine % filter using the definition in the following reference: % M. Joost, "Theory of Root-Raised Cosine Filter," published online at % www.michael-joost.de/rrcfilter.pdf % See Section 5.2.1 of IEEE P1765 document: Filter the Baseband Signals % INPUTS: % Tsym: Symbol duration in ns, inverse of symbol rate % alpha: Root raised cosine filter rolloff % deltaT: Point spacing in ns, inverse of sample rate % N: Total number of points % OUTPUTS: % Hrrc: Transfer function of the root-raised cosine filter % The Hrrc is defined in three frequency ranges % At lower frequencies, f < f1, constant spectrum % For frequencies, f1 > f > f2, root raised cosine function % At higher frequencies, f > f2, zero % Calculate the frequencies f1 and f2: f2 = ((1.0 + alpha) / 2.0) / double(Tsym); % Maximum filter frequency f1 = ((1.0 - alpha) / 2.0) / double(Tsym); % Start of rolloff deltaF = 1.0 / (double(N) * deltaT); % Frequency spacing ns = floor(f2 / deltaF); % Set of frequencies in the passband of the filter Ntotal = 1 + 2 * ns; Hrrc = complex(zeros(Ntotal,1)); B = sqrt(Tsym); % Create the filter values k = 0; for kFreq = -ns:ns Freq = double(kFreq) * deltaF; k = k + 1; if abs(Freq) <= f1 Hrrc(k) = B; elseif abs(Freq) <= f2 Hrrc(k) = (B / sqrt(2.0)) * sqrt(1.0 + cos(pi * (Tsym/alpha) * ((abs(Freq) - f1)))); end end end \ No newline at end of file
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % IEEE P1765 baseline EVM receiver/calculation code (user distributable) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This code is implementing the IEEE P1765 Baseline EVM Algorithm as % defined in Section 5.2 and Figure 5 of the P1765 document. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Authors: % Christopher P. Silva - Original code Version 04.30.2021 % Paritosh Manurkar - Modularization of the code into a main program and subroutines Version 06.28.2021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % > Define global structure (instead of global variables) and initialize extra output variables % > Create a structure to save all the basic communication parameters % > Define the root raised cosine (RRC) filter transfer function in frequency domain % > Use the correct waveforms generated using the frequency domain RRC filter % > Downconversion from RF to baseband is not a part of the P1765 Baseline EVM Algorithm % > A function to perform downconversion has been supplied for pre-processing % > Downsampling an oversampled signal is not a part of the P1765 Baseline EVM Algorithm % > A function to perform downsampling has been supplied for pre-processing % > Regenerate ideal reference constellation (Single Carrier) % > Read in baseband ASCII time-domain waveform file % > Time-domain waveform alignment and normalization % > Symbol sampling and constellation normalization % > EVM RMS/peak (in %) calculation % > Automated plotting of ideal/processed signal constellation and saving plot graphic % > Save the official and extra outputs and their descriptions in a text file: % OFFICIAL OUTPUTS % > RMS EVM (in %) % > Optimal delay tau0 (ns) % > Optimal complex gain/ normalization factor for symbol samples G_OPT % >> G_OPTamp: abs(G_OPT) % >> G_OPTphase: angle(G_OPT) in degrees % EXTRA OUTPUTS % > Received signal average value % > Absolute tolerance determined for iterative delay calculation convergence (ns) % > Number of iterations for optimal delay loop convergence (= 10000 if convergence fails) % > Optimal complex gain G_0 to be applied before symbol sampling/EVM calculation % >> G_0amp: abs(G_0) % >> G_0phase: angle(G_0) in degrees % > Peak EVM (in %) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clear; close all; clc; %% Define Global Structure and Initialize Variables global structGlobal structGlobal.rxSigAve = 0; % Received signal average value structGlobal.optTolerance = 0; % Absolute tolerance (ns) structGlobal.iterindx = 0; % Number of iterations for optimal delay loop convergence structGlobal.G_0amp = 0; % Amplitude of optimal complex gain structGlobal.G_0phase = 0; % Phase of optimal complex gain structGlobal.EVMpeak_pct = 0; % Peak EVM (in %) structGlobal.evm_results_folder = 'placeholder'; % Folder in which results will be saved structGlobal.filename_results = 'placeholder'; % Base filename for saving results structGlobal.filename_constellation = 'placeholder';% Base filename for saving constellation diagram structGlobal.SISmn = 'placeholder'; % Extract impairment set information from waveform filename %% User Inputs for Folder and Filename F_UserInputs(); %% Define Basic Communication Parameters and save in structure params params = F_Basic_Communication_Parameters(); %% Read in ASCII Baseband Reference Waveform File distSig = transpose(dlmread(structGlobal.file)); sigSize = length(distSig); params.numseg = sigSize/params.numSamp; % Integer number of consecutive waveform segments of basic length numSamp if params.numseg > 1 params.numSamp = params.numseg*params.numSamp; % New numSamp = number of segments times old numSamp params.numSym = params.numseg*params.numSym; % New numSym = number of segments times old numSym params.df1a = params.fsamp/params.numSamp; % New frequency grid spacing (Hz) params.f1a = [-(params.numSamp/2):(params.numSamp/2)-1] * params.df1a; % New frequency grid (Hz) params.t1a = [0:params.numSamp-1] * params.dt1; % New time sampling grid (sec) — note dt1a = dt1 end distSigFreq = fft(distSig); bw_mod = (1 + params.rolloff)*params.fsym; % Modulation bandwidth (GHz) %% Load the Reference Constellation Supplied with this Package refConst = transpose(dlmread(fullfile(pwd,'Constellation _ Pulse Shaping Files','RefSymbolsConst.txt'))); refSym = repmat(refConst,1,params.numseg); % Edit to make numseg copies of basic symbol sequence refConst = refSym; %% Create Time-Domain Waveform from Ideal Constellation refSig = zeros(1,params.numSamp); refSig(1:params.numSampSym:params.numSamp) = refSym(1:params.numSym); refSigFreq = fft(refSig); %% Apply Ideal Matched Filtering to Baseband Reference Waveform rxSigFreq = F_Apply_RX_Filter(distSigFreq,params); %% Optimal Time Delay and Normalization Algorithm for Waveform Samples (Official) % Shift zero-frequency component to center of spectrum for baseband signals XIn = fftshift(refSigFreq);