gusucode.com > wlan工具箱matlab源码程序 > wlan/wlan/+wlan/+internal/wlanWindowing.m
function y = wlanWindowing(x, FFTLen, wLength, guardInterval, preambleLength) %wlanWindowing Window time-domain OFDM symbols % % Note: This is an internal undocumented function and its API and/or % functionality may change in subsequent releases. % % Y = wlanWindowing(X,FFTLEN,WLENGTH,GUARDINTERVAL,PREAMBLELENGTH) % returns the time-domain windowed signal for the OFDM signal. The % windowing function for OFDM waveform is defined in IEEE Std % 802.11-2012. % % Y is a complex Ns-by-Nt matrix containing the windowed signal, where Ns % is the number of time domain samples, and Nt is the number of transmit % antennas. % % X is a complex Ns-by-Nt matrix array containing the time-domain OFDM % signal. % % FFTLEN is the FFT length used to modulate the OFDM symbols. The FFT % length depends on channel bandwidth of the input signal and should be % equal to 32, 64, 128, 256 or 512. % % WLENGTH is the windowing length in samples to apply. The WLENGTH of % zero samples means no windowing. % % GUARDINTERVAL is the cyclic prefix for the data field within a packet, % specified as 'Long' or 'Short'. % % PREAMBLELENGTH is the number of samples in the preamble field of the % input signal. % % Example: % % Window a time domain waveform for an 802.11ac VHT transmission. % % cfgVHT = wlanVHTConfig; % Create format configuration % lstf = wlanLSTF(cfgVHT); % Preamble generation % lltf = wlanLLTF(cfgVHT); % lsig = wlanLSIG(cfgVHT); % vhtsiga = wlanVHTSIGA(cfgVHT); % vhtstf = wlanVHTSTF(cfgVHT); % vhtltf = wlanVHTSTF(cfgVHT); % vhtsigb = wlanVHTSIGB(cfgVHT); % preamble = [lstf;lltf;lsig;vhtsiga;vhtstf;vhtltf;vhtsigb]; % % Generate Data field % rng(0); % txPSDU = randi([0,1], cfgVHT.PSDULength*8,1); % data = wlanVHTData(txPSDU,cfgVHT); % txWaveform = [preamble; data]; % % Window transmit signal % wLength = 16; % Windowing samples for Transition time of 100nsec % sizeFFT = 256; % FFT size for 80MHz bandwidth % windowedWaveform = wlanWindowing(txWaveform,sizeFFT, ... % wLength,cfgVHT.GuardInterval,length(preamble)); % % Display the spectrum % spectrumAnalyzer = dsp.SpectrumAnalyzer('SampleRate',80e6, ... % 'ShowLegend',true,'Window','Flat Top','ChannelNames', ... % {'Transmit Waveform','Windowed waveform'}); % % Oversample the signal by a factor of 2 before the display % spectrumAnalyzer([resample([txWaveform;zeros(15,1)],2,1), ... % resample(windowedWaveform,2,1)]); % % See also wlanWaveformGenerator, wlanTGnChannel. % Copyright 2015-2016 The MathWorks, Inc. %#codegen validateattributes(x,{'double'},{'2d','finite','nonempty'}, ... mfilename,'signal input'); if wLength == 0 y = x; return; end % Initialize parameters switch FFTLen case 32 shortCyclicPrefix = 4; sampleRate = 10e6; case 128 shortCyclicPrefix = 16; sampleRate = 40e6; case 256 shortCyclicPrefix = 32; sampleRate = 80e6; case 512 shortCyclicPrefix = 64; sampleRate = 160e6; otherwise % 64 for 20/10/5 MHz shortCyclicPrefix = 8; sampleRate = 20e6; % nominal 20 MHz end longCyclicPrefix = FFTLen/4; longSymLength = 4e-6*sampleRate; % In samples, works for 5/10/20 MHz shortSymLength = 3.6e-6*sampleRate; % Number of transmit antennas numTx = size(x,2); y = complex(zeros(0,numTx)); % Standard defined windowing indices and magnitude for Long symbols [indLong, magLong] = windowingEquation(wLength,longSymLength); ofdmSymLen = FFTLen+longCyclicPrefix; % Check the wLength to be less than or equal to twice the CP if strcmp(guardInterval,'Long') coder.internal.errorIf(wLength>(2*longCyclicPrefix),'wlan:wlanWindowing:InvalidWindowLength'); else coder.internal.errorIf(wLength>(2*shortCyclicPrefix),'wlan:wlanWindowing:InvalidWindowLength'); end if FFTLen==32 % Special case for S1G 1 MHz mode packet structure % Window the STF (4 symbols) as one symbol stfSym = x(1:(4*ofdmSymLen),:); stfSymExtended = windowLSTFandLLTF(stfSym,FFTLen, ... 2*ofdmSymLen,2*longSymLength,wLength,numTx); suffixstfSym = stfSymExtended(end-(wLength)+2:end,:); % Window the first half of LTF (2 symbols) ltfSymPart1 = x((4*ofdmSymLen)+(1:(2*ofdmSymLen)),:); ltfSymPart1Extended = windowLSTFandLLTF(ltfSymPart1,FFTLen, ... ofdmSymLen,longSymLength,wLength,numTx); prefixltfSym = ltfSymPart1Extended(1:wLength-1,:); suffixltfSym = ltfSymPart1Extended(end-(wLength)+2:end,:); suffixTrainingSym = suffixltfSym; % Combine STF and LTF and overlap prefix and suffix trainingSymOut = [stfSymExtended(1:end-wLength+1,:); ... (suffixstfSym+prefixltfSym); .... ltfSymPart1Extended(wLength:end,:)]; remainingSym = x((6*ofdmSymLen)+1:end,:); preambleLessFirstTwoFields = x((6*ofdmSymLen)+1:preambleLength,:); else % All other bandwidths have the same packet structure % Windowing first two fields; the L-STF and L-LTF or STF and LTF1 (S1G) trainingSym = x(1:(4*ofdmSymLen),:); trainingSymExtended = windowLSTFandLLTF(trainingSym,FFTLen, ... ofdmSymLen,longSymLength,wLength,numTx); trainingSymOut = windowSym(trainingSymExtended,wLength); suffixTrainingSym = trainingSymOut(end-(wLength)+2:end,:); remainingSym = x((4*ofdmSymLen)+1:end,:); preambleLessFirstTwoFields = x(4*ofdmSymLen+1:preambleLength,:); end if strcmp(guardInterval,'Long') % Process remaining symbols numSym = length(remainingSym)/ofdmSymLen; % Check input length coder.internal.errorIf(mod(numSym,1)~=0,'wlan:wlanWindowing:IncorrectInputLength'); % Reshape by SymLength-NumSym-NumTx remainingSym = reshape(remainingSym,ofdmSymLen,numSym,numTx); % Extend symbol length before windowing remainingSymExt = [remainingSym(end-(abs(indLong(1))+FFTLen/4)+1:end-FFTLen/4,:,:); ... remainingSym; remainingSym(FFTLen/4+(1:wLength/2),:,:)]; % Apply windowing on the extended symbol portion remaingSymExtWin = bsxfun(@times,remainingSymExt,magLong); remaingSymOut = windowSym(remaingSymExtWin,wLength); prefixSym = remaingSymOut(1:wLength-1,:); y = [trainingSymOut(1:end-wLength+1,:); ... (suffixTrainingSym+prefixSym); .... remaingSymOut(wLength:end,:)]; elseif strcmp(guardInterval,'Short') % Extract data field data = x(preambleLength+1: end,:); % Reshape preamble (less L-LTF and L-STF) by SymLength-NumSym-NumTx numSym = size(preambleLessFirstTwoFields,1)/longSymLength; preambleSym = reshape(preambleLessFirstTwoFields,ofdmSymLen,numSym,numTx); % Extend symbol length preambleSymExt = [preambleSym(end-(abs(indLong(1))+FFTLen/4)+1:end-FFTLen/4,:,:); ... preambleSym; preambleSym(FFTLen/4+(1:wLength/2),:,:)]; % Apply windowing to all preamble symbols remaingSymExtWin = bsxfun(@times,preambleSymExt,magLong); preambleSym = windowSym(remaingSymExtWin,wLength); prefixPreambleSym = preambleSym(1:wLength-1,:); suffixPreambleSym = preambleSym(end-(wLength)+2:end,:); % Number of data symbols numDataSym = length(data)/(FFTLen+shortCyclicPrefix); % Check input length coder.internal.errorIf(mod(numDataSym,1)~=0,'wlan:wlanWindowing:IncorrectInputLength'); if isempty(data) % NDP % Only the preamble fields y = [trainingSymOut(1:end-wLength+1,:); ... (suffixTrainingSym+prefixPreambleSym); ... preambleSym(wLength:end-wLength+1,:); ... suffixPreambleSym]; else % Window the data symbols % Reshape data by SymLength x NumSym x NumTx dataSym = reshape(data,FFTLen+shortCyclicPrefix,numDataSym,numTx); % Standard defined windowing equations [index, magnitude] = windowingEquation(wLength,shortSymLength); % Extend symbol length dataSymExt = [dataSym(end-(abs(index(1))+FFTLen/8)+1:end-FFTLen/8,:,:); ... dataSym;dataSym(FFTLen/8+(1:wLength/2),:,:)]; % Apply windowing to all symbols dataSymExtWin = bsxfun(@times,dataSymExt,magnitude); dataSym = windowSym(dataSymExtWin,wLength); prefixdataSym = dataSym(1:wLength-1,:); y = [trainingSymOut(1:end-wLength+1,:); ... (suffixTrainingSym+prefixPreambleSym); ... preambleSym(wLength:end-wLength+1,:); ... (suffixPreambleSym+prefixdataSym);... dataSym(wLength:end,:)]; end end end function out = windowSym(inputSym, wlength) % This function is performing the overlap and add operation on the extended % window potion. % Set the windowing length equal to the preIndx window length. W = wlength-(wlength>0); firstRegion = inputSym(1:end-W,1,:); overlapRegion = inputSym(end-W+1:end,1:end-1,:)+inputSym(1:W,2:end,:); middleRegion = [overlapRegion; inputSym(W+1:end-W,2:end,:)]; lastRegion = inputSym(end-W+1:end,end,:); out = [firstRegion;reshape(middleRegion,[],1,size(inputSym,3));lastRegion]; end function [windowIdx,windowMag] = windowingEquation(TTR, symLength) % The windowing function for the OFDM symbols is defined in IEEE Std % 802.11-2012, Section 18.3.2.5, Equation 18-4. preIdx = -TTR/2+1:TTR/2-1; midIdx = TTR/2:(symLength-TTR/2)-1; postIdx = symLength-TTR/2:(symLength+TTR/2)-1; windowIdx = [preIdx midIdx postIdx].'; preMag = sin(pi/2*(0.5+(preIdx)/(TTR))).^2; midMag = ones(1,length(midIdx)); postMag = sin(pi/2*(0.5-((postIdx)-symLength)/TTR)).^2; windowMag = [preMag midMag postMag].'; end function out = windowLSTFandLLTF(sym,sizeFFT,ofdmSymLen, ... longSymLength,wLength,numTx) % Standard defined windowing equations [index,magnitude] = windowingEquation(wLength,2*longSymLength); % Number of initial symbols numSym = length(sym)/(2*ofdmSymLen); % Reshape by SymLength - NumSym - NumTx sym = reshape(sym,2*ofdmSymLen,numSym,numTx); % Extend symbol length initialSymExtended = [sym(end-(abs(index(1))+sizeFFT/2) ... + 1:end-sizeFFT/2,:,:);sym; ... sym(sizeFFT/2+(1:wLength/2),:,:)]; % Apply windowing to first two preamble symbols out = bsxfun(@times,initialSymExtended,magnitude); end % [EOF]