gusucode.com > wlan工具箱matlab源码程序 > wlan/wlan/wlanHTDataRecover.m
function [bits, eqDataSym, varargout] = wlanHTDataRecover( ... rxHTData, chanEst, noiseVarEst, cfgHT, varargin) %wlanHTDataRecover Recover information bits from HT-Data field signal % % BITS = wlanHTDataRecover(RXHTDATA, CHANEST, NOISEVAREST, CFGHT) % recovers the information bits in the HT-Data field for a HT-Mixed % format transmission. % % BITS is an int8 column vector of length 8*CFGHT.PSDULength containing % the recovered information bits. % % RXHTDATA is the received time-domain HT-Data field signal. It is a % Ns-by-Nr matrix of real or complex values, where Ns represents the % number of time-domain samples in the HT-Data field and Nr represents % the number of receive antennas. Ns can be greater than the HT-Data % field length; in this case additional samples at the end of RXHTDATA % are not used. % % CHANEST is the estimated channel at data and pilot subcarriers based on % the HT-LTF. It is a real or complex array of size Nst-by-Nsts-by-Nr, % where Nst represents the total number of occupied subcarriers. % % NOISEVAREST is the noise variance estimate. It is a real, nonnegative % scalar. % % CFGHT is the format configuration object of type <a href="matlab:help('wlanHTConfig')">wlanHTConfig</a>, which % specifies the parameters for the HT-Mixed format. % % BITS = wlanHTDataRecover(..., CFGREC) allows different algorithm % options for data recovery via the input CFGREC, which is a % <a href="matlab:help('wlanRecoveryConfig')">wlanRecoveryConfig</a> configuration object. When the CFGREC input is not % specified, the default property values of the <a href="matlab:help('wlanRecoveryConfig')">wlanRecoveryConfig</a> object % are adopted in the recovery. % % [..., EQDATASYM, CPE] = wlanHTDataRecover(...) also returns the % equalized subcarriers and common phase error. % % EQDATASYM is a complex Nsd-by-Nsym-by-Nss array containing the % equalized symbols at data carrying subcarriers. Nsd represents the % number of data subcarriers, Nsym represents the number of OFDM symbols % in the HT-Data field, and Nss represents the number of spatial streams. % % CPE is a column vector of length Nsym containing the common phase error % between each received and expected OFDM symbol. % % Example: % % Recover a HT-Data field signal through a SISO AWGN channel using % % ZF equalization. % % cfgHT = wlanHTConfig('PSDULength', 1024); % HT format configuration % txBits = randi([0 1], 8*cfgHT.PSDULength, 1); % Payload bits % txHSig = wlanHTData(txBits, cfgHT); % Generate HT-Data signal % % % Pass through an AWGN channel with noise variance of 1 % rxHTSig = awgn(txHSig, 1, 1); % % % Configure recovery object % cfgRec = wlanRecoveryConfig('EqualizationMethod', 'ZF'); % % Recover payload bits % rxBits = wlanHTDataRecover(rxHTSig, ones(56,1), 1, cfgHT, cfgRec); % % [numerr, ber] = biterr(rxBits, txBits); % Compare bits % disp(ber) % % See also wlanHTConfig, wlanRecoveryConfig, wlanHTData. % Copyright 2015-2016 The MathWorks, Inc. %#codegen narginchk(4,5); nargoutchk(0,3); % Calculate CPE if requested if nargout>2 calculateCPE = true; else calculateCPE = false; end % HT configuration input self-validation validateattributes(cfgHT, {'wlanHTConfig'}, {'scalar'}, mfilename, ... 'HT-Mixed format configuration object'); s = validateConfig(cfgHT, 'MCS'); % Validate rxHTData validateattributes(rxHTData, {'double'}, {'2d','finite'}, ... 'rxHTData', 'HT-Data field signal'); % Validate chanEst validateattributes(chanEst, {'double'}, {'3d','finite'}, ... 'chanEst', 'channel estimates'); % Validate noiseVarEst validateattributes(noiseVarEst, {'double'}, ... {'real','scalar','nonnegative','finite'}, ... 'noiseVarEst', 'noise variance estimate'); numSTS = cfgHT.NumSpaceTimeStreams; numRx = size(rxHTData, 2); mcsTable = wlan.internal.getRateTable(cfgHT); pNcbpssi = mcsTable.NCBPS/mcsTable.Nss; numDBPS = mcsTable.NDBPS; rate = mcsTable.Rate; numOFDMSym = s.NumDataSymbols; numSS = mcsTable.Nss; STBC = numSTS - numSS; mSTBC = 1 + (STBC~=0); % If PSDU is empty there is no data to return if cfgHT.PSDULength == 0 bits = zeros(0, 1, 'int8'); eqDataSym = zeros(mcsTable.NSD, 0, mcsTable.Nss); if calculateCPE==true varargout{1} = []; % CPE end return; end % Optional recovery configuration input validation if nargin == 5 validateattributes(varargin{1}, {'wlanRecoveryConfig'}, {'scalar'}, ... mfilename, 'recovery configuration object'); symOffset = varargin{1}.OFDMSymbolOffset; pilotPhaseTracking = varargin{1}.PilotPhaseTracking; eqMethod = varargin{1}.EqualizationMethod; maxLDPCIterationCount = varargin{1}.MaximumLDPCIterationCount; earlyTermination = varargin{1}.EarlyTermination; else % use defaults symOffset = 0.75; pilotPhaseTracking = 'PreEQ'; eqMethod = 'MMSE'; maxLDPCIterationCount = 12; earlyTermination = false; end % Get OFDM related parameters [cfgOFDM,dataInd,pilotInd] = wlan.internal.wlanGetOFDMConfig( ... cfgHT.ChannelBandwidth, cfgHT.GuardInterval, 'HT', numSTS); % Cross validate input numST = numel([dataInd; pilotInd]); % Total number of occupied subcarriers coder.internal.errorIf(size(chanEst, 1) ~= numST, ... 'wlan:wlanHTDataRecover:InvalidHTChanEst1D', numST); coder.internal.errorIf(size(chanEst, 2) ~= numSTS, ... 'wlan:wlanHTDataRecover:InvalidHTChanEst2D', numSTS); coder.internal.errorIf(size(chanEst, 3) ~= numRx, ... 'wlan:wlanHTDataRecover:InvalidHTChanEst3D'); % Extract data and pilot subcarriers from channel estimate chanEstData = chanEst(dataInd,:,:); chanEstPilots = chanEst(pilotInd,:,:); % Cross-validation between inputs minInputLen = numOFDMSym*(cfgOFDM.FFTLength+cfgOFDM.CyclicPrefixLength); coder.internal.errorIf(size(rxHTData, 1) < minInputLen, ... 'wlan:wlanHTDataRecover:ShortHTDataInput', minInputLen); % Processing for all streams/numRx % OFDM demodulation [ofdmDemodData, ofdmDemodPilots] = wlan.internal.wlanOFDMDemodulate(... rxHTData(1:minInputLen, :), cfgOFDM, symOffset); if calculateCPE==true || strcmp(pilotPhaseTracking, 'PreEQ') % Get reference pilots, from IEEE Std 802.11-2012, Eqn 20-58/59 % For HT-MF, offset by 3 to allow for L-SIG and HT-SIG pilot symbols z = 3; refPilots = wlan.internal.htPilots(numOFDMSym, z, ... cfgHT.ChannelBandwidth, numSTS); % Estimate CPE and phase correct symbols cpe = wlan.internal.commonPhaseErrorEstimate(ofdmDemodPilots, ... chanEstPilots, refPilots); if strcmp(pilotPhaseTracking, 'PreEQ') ofdmDemodData = wlan.internal.commonPhaseErrorCorrect(ofdmDemodData, cpe); end if calculateCPE==true varargout{1} = cpe.'; % Permute to Nsym-by-1 end end % Equalization if mcsTable.Nss < numSTS [eqDataSym, csiData] = wlan.internal.wlanSTBCCombine(ofdmDemodData, ... chanEstData, mcsTable.Nss, eqMethod, noiseVarEst); else [eqDataSym, csiData] = wlan.internal.wlanEqualize(ofdmDemodData, ... chanEstData, eqMethod, noiseVarEst); end % LLR Demodulation: per Nss, account for nVar qamDemodOut = wlan.internal.wlanConstellationDemodulate(eqDataSym, ... mcsTable.NBPSCS, noiseVarEst); % Apply bit-wise CSI qamDemodOut = bsxfun(@times, ... reshape(qamDemodOut, mcsTable.NBPSCS, [], numOFDMSym, mcsTable.Nss), ... reshape(csiData, 1, [], 1, mcsTable.Nss)); % [Nbpscs Nsd Nsym Nss] % Deinterleave per OFDM symbol deintlvrOut = zeros(pNcbpssi*numOFDMSym, mcsTable.Nss); if strcmp(cfgHT.ChannelCoding,'BCC') for symIdx = 1:numOFDMSym deintlvrOut((symIdx-1)*pNcbpssi+(1:pNcbpssi), :) = ... wlan.internal.wlanBCCDeinterleave( ... reshape(qamDemodOut(:,:,symIdx,:), [], mcsTable.Nss), ... 'HT', pNcbpssi, mcsTable.NBPSCS, 20*cfgOFDM.FFTLength/64, mcsTable.Nss); end else % Deinterleaving is not required for LDPC deintlvrOut = reshape(real(qamDemodOut), [], numSS); end % Stream deparsing streamDeparserOut = wlan.internal.wlanStreamDeparser(deintlvrOut, ... mcsTable.NES, mcsTable.NBPSCS); % Channel decoding if strcmp(cfgHT.ChannelCoding,'BCC') % BCC Channel decoding per Nes htDataBits = zeros(round(size(streamDeparserOut, 1)*mcsTable.Rate), ... mcsTable.NES, 'int8'); for nesIdx = 1:mcsTable.NES htDataBits(:, nesIdx) = wlan.internal.wlanBCCDecode( ... streamDeparserOut(:, nesIdx), mcsTable.Rate); end descramMat = htDataBits.'; descramIn = descramMat(:); else % LDPC Channel decoding numPLD = cfgHT.PSDULength*8 + 16; % Number of payload bits % LDPC decoding parameters, IEEE Std 802.11-2012, Section % 20.3.11.17.5. cfg = wlan.internal.getLDPCparameters(numDBPS, rate, mSTBC, numPLD); descramIn = wlan.internal.wlanLDPCDecode(streamDeparserOut(:), cfg, ... maxLDPCIterationCount, earlyTermination); end % Combine bits from multiple decoders, descramble with derived initial state iniY = descramIn(1:7,1); % Extract the first 7 scrambler init bits scramInit = [iniY(3)+iniY(7) iniY(2)+iniY(6) iniY(1)+iniY(5) ... iniY(4)+iniY(3)+iniY(7) iniY(3)+iniY(2)+iniY(6) ... iniY(2)+iniY(1)+iniY(5) iniY(1)+iniY(4)+iniY(3)+iniY(7)]; scramInit = mod(scramInit, 2); % Remove the padded and tail bits to output only the data bits descramOutData = wlan.internal.wlanScramble( ... descramIn(1:(16+8*cfgHT.PSDULength),:), scramInit); % Remove the 16 service bits bits = descramOutData(17:end); end