function [nest,sigest] = heNoiseEstimate(x,chanEstSSPilots,cfg,varargin) %heNoiseEstimate Estimate noise power using HE data field pilots % % NEST = heNoiseEstimate(x,CHANESTSSPILOTS,CFGHE) estimates the mean % noise power in watts using the demodulated pilot symbols in the HE data % field and single-stream channel estimates at pilot subcarriers. The % noise estimate is averaged over the number of symbols and receive % antennas. % % X is a complex Nsp-by-Nsym-by-Nr array containing demodulated pilot % subcarrier in HE data field. Nsym is the number of demodulated HE-Data % symbols. % % CHANESTSSPILOTS is a complex Nsp-by-Nltf-by-Nr array containing the % channel gains at pilot subcarrier locations for each symbol, assuming % one space-time stream at the transmitter. Nltf is the number of HE-LTF % symbols. % % CFGHE is a format configuration object of type wlanHESUConfig, % wlanHETBConfig or wlanHERecoveryConfig. % % NEST = heNoiseEstimate(X,CHANESTSSPILOTS,CFGMU,RUIDX) performs noise % power estimation for the multi user HE format input X. % % CFGMU is the format configuration object of type wlanHEMUConfig or % heTBSystemConfig. % % RUIDX is the RU (resource unit) index. % % [NEST,SIGEST] = heNoiseEstimate(...) additionally returns an estimate % of the signal power. % Copyright 2018-2019 The MathWorks, Inc. %#codegen validateattributes(cfg,{'wlanHESUConfig','wlanHEMUConfig','wlanHETBConfig','wlanHERecoveryConfig','heTBSystemConfig'},{'scalar'},mfilename,'format configuration object'); numOFDMSym = size(x,2); n = (0:numOFDMSym-1); ruIdx = 1; if isa(cfg,'wlanHEMUConfig') narginchk(4,4) ruIdx = varargin{1}; sigbInfo = wlan.internal.heSIGBCodingInfo(cfg); numHESIGB = sigbInfo.NumSymbols; pktFormat = packetFormat(cfg); allocInfo = ruInfo(cfg); ruSize = allocInfo.RUSizes(ruIdx); elseif isa(cfg,'heTBSystemConfig') numHESIGB = 0; ruIdx = varargin{1}; pktFormat = packetFormat(cfg); allocInfo = ruInfo(cfg); ruSize = allocInfo.RUSizes(ruIdx); elseif isa(cfg,'wlanHERecoveryConfig') ruSize = cfg.RUSize; pktFormat = cfg.PacketFormat; if strcmp(pktFormat,'HE-MU') s = getSIGBLength(cfg); numHESIGB = s.NumSIGBSymbols; else numHESIGB = 0; end else % SU, EXT SU, TB numHESIGB = 0; pktFormat = packetFormat(cfg); allocInfo = ruInfo(cfg); ruSize = allocInfo.RUSizes(ruIdx); end if strcmp(pktFormat,'HE-EXT-SU') numHESIGA = 4; else % SU or MU numHESIGA = 2; end z = 2+numHESIGA+numHESIGB; % Pilot symbol offset % Get the reference pilots for one space-time stream, pilot sequence same % for all space-time streams refPilots = wlan.internal.hePilots(ruSize,1,n,z); % Nsp-by-Nsym-by-1 % Average single-stream pilot estimates over symbols (2nd dimension) avChanEstSSPilots = mean(chanEstSSPilots,2); % Nsp-by-1-by-Nrx % Estimate channel at pilot location using least square estimates chanEstPilotsLoc = bsxfun(@rdivide,x,refPilots); % Nsp-by-Nsym-by-Nrx % Subtract the noisy least squares estimates of the channel at pilot symbol % locations from the noise averaged single stream pilot symbol estimates of % the channel error = bsxfun(@minus,chanEstPilotsLoc,avChanEstSSPilots); % Nsp-by-Nsym-by-Nrx % Get power of error and average over pilot symbols, subcarriers and % receive antennas useIdx = ~isnan(error); % NaNs may exist in 1xHELTF nest = real(mean(error(useIdx).*conj(error(useIdx)),'all')); % For codegen if nargout>1 % Get power of channel estimate at pilot locations sigest = real(mean(chanEstPilotsLoc(:).*conj(chanEstPilotsLoc(:)))); % For codegen end end