You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
6.2 KiB
171 lines
6.2 KiB
function est = helperNoiseEstimate(rxSym,varargin)
|
|
%helperNoiseEstimate Estimate noise power using L-LTF (non-HT, HT, and VHT)
|
|
%and LTF1 in S1G
|
|
%
|
|
% EST = helperNoiseEstimate(RXSYM) estimates the mean noise power in
|
|
% watts using the demodulated L-LTF symbols (non-HT, HT, and VHT) or the
|
|
% demodulated S1G-LTF1 symbols in S1G, assuming 1ohm resistance. The
|
|
% estimated noise power in non-HT packet is averaged over the number of
|
|
% of receive antennas.
|
|
%
|
|
% RXSYM is the frequency-domain signal corresponding to the L-LTF or
|
|
% S1G-LTF1. It is a complex matrix or 3-D array of size Nst-by-2-by-Nr,
|
|
% where Nst represents the number of used subcarriers in the L-LTF or
|
|
% S1G-LTF1, and Nr represents the number of receive antennas. Two OFDM
|
|
% symbols in the L-LTF or S1G-LTF1 fields are used to estimate the noise
|
|
% power. Noise estimate from the S1G-LTF1 field for S1G 1MHz format is
|
|
% not supported.
|
|
%
|
|
% EST = helperNoiseEstimate(RXSYM,CHANBW,NUMSTS) returns the estimated
|
|
% noise power in beamformed fields using the specified channel bandwidth,
|
|
% CHANBW, and total number of space-time streams, NUMSTS. The number of
|
|
% subcarriers used within each field and the scaling applied during
|
|
% demodulation differs between the non-HT and HT/VHT fields for VHT, HT
|
|
% and non-HT. Therefore the estimated noise power after demodulation in
|
|
% HT/VHT fields is calculated by scaling the estimated noise power in the
|
|
% L-LTF. The number of space-time streams is required for scaling if the
|
|
% demodulated RXSYM is not scaled according to the number of space-time
|
|
% streams.
|
|
%
|
|
% EST = helperNoiseEstimate(...,'Per Antenna') specifies the option of
|
|
% estimating the noise for each receive antenna. When this option is
|
|
% specified EST is a row vector of length Nr.
|
|
%
|
|
% Example:
|
|
% % Estimate the noise variance of an HT packet.
|
|
%
|
|
% cfgHT = wlanHTConfig; % Create packet configuration
|
|
% chanBW = cfgHT.ChannelBandwidth;
|
|
% numSTS = cfgHT.NumSpaceTimeStreams;
|
|
% noisePower = -20;
|
|
% awgnChannel = comm.AWGNChannel;
|
|
% awgnChannel.NoiseMethod = 'Variance';
|
|
% awgnChannel.Variance = 10^(noisePower/10);
|
|
%
|
|
% Nst = 56; % Data and pilot OFDM subcarriers in 20MHz, HT format
|
|
% Nfft = 64; % FFT size for 20MHz bandwidth
|
|
% nVarHT = 10^(noisePower/10)*(Nst/Nfft); % non-HT noise variance
|
|
%
|
|
% NumRxAnts = 1;
|
|
% % Average noise estimate over 100 independent noise realization
|
|
% for n=1:100
|
|
% % Generate LLTF and add noise
|
|
% rxSym = awgnChannel(wlanLLTF(cfgHT));
|
|
% y = wlanLLTFDemodulate(rxSym,cfgHT);
|
|
% noiseEst(n) = helperNoiseEstimate(y,chanBW,numSTS);
|
|
% end
|
|
%
|
|
% % Check noise variance estimates without Channel
|
|
% noiseEstError = 10*log10(mean(noiseEst))-10*log10(nVarHT);
|
|
% disp(['Error between noise variance and mean estimated noise ', ...
|
|
% 'power(dB): ' num2str(noiseEstError,'%2.2f ')]);
|
|
%
|
|
% See also wlanLLTF, wlanLLTFDemodulate.
|
|
|
|
% Copyright 2015-2017 The MathWorks, Inc.
|
|
|
|
%#codegen
|
|
|
|
narginchk(1,4);
|
|
|
|
% Validate symbol type
|
|
validateattributes(rxSym,{'double'},{'3d','finite'},mfilename,'OFDM symbol(s)');
|
|
|
|
% Two L-LTF symbols (non-HT, HT, and VHT) or two S1G-LTF1 symbols (S1G) are
|
|
% required to estimate the noise
|
|
coder.internal.errorIf(size(rxSym,2)~=2,'wlan:helperNoiseEstimate:IncorrectNumSyms');
|
|
|
|
numSC = size(rxSym,1);
|
|
|
|
% Minimal optional parameter checks
|
|
if nargin == 2
|
|
% (rxSym,'Per Antenna')
|
|
validateNType(varargin{1});
|
|
average = false;
|
|
|
|
scalingFactor = 1; % Noise scaling factor
|
|
elseif nargin == 3
|
|
% (rxSym, chanBW, numSTSTotal)
|
|
chanBW = varargin{1}; % chanBW: CBW2/4/8/16/20/40/80/160
|
|
coder.internal.errorIf(strcmp(chanBW,'CBW1'),'wlan:helperNoiseEstimate:InvalidS1G1M');
|
|
validateInput(chanBW,numSC);
|
|
|
|
numSTSTotal = varargin{2}; % numSTSTotal: 1,...,8
|
|
average = true;
|
|
|
|
% Noise scaling factor
|
|
scalingFactor = noiseScaling(chanBW,numSC,numSTSTotal);
|
|
elseif nargin == 4
|
|
% (rxSym, chanBW, numSTSTotal, 'Per Antenna')
|
|
chanBW = varargin{1}; % chanBW: CBW2/4/8/16/20/40/80/160
|
|
coder.internal.errorIf(strcmp(chanBW,'CBW1'),'wlan:helperNoiseEstimate:InvalidS1G1M');
|
|
validateInput(chanBW,numSC);
|
|
|
|
numSTSTotal = varargin{2}; % numSTSTotal: 1,...,8
|
|
|
|
validateNType(varargin{3});
|
|
average = false;
|
|
|
|
% Noise scaling factor
|
|
scalingFactor = noiseScaling(chanBW,numSC,numSTSTotal);
|
|
else
|
|
% (rxSym)
|
|
average = true;
|
|
scalingFactor = 1;
|
|
end
|
|
|
|
% Noise estimate
|
|
noiseEst = sum(abs(rxSym(:,1,:)-rxSym(:,2,:)).^2,1)/(2*numSC);
|
|
if average
|
|
noise = mean(noiseEst);
|
|
else
|
|
noise = squeeze(noiseEst).';
|
|
end
|
|
|
|
% Scale
|
|
est = noise*scalingFactor;
|
|
|
|
end
|
|
|
|
%-------------------------------------------------------------------------
|
|
function out = noiseScaling(chanBW,numSC,numSTSTotal)
|
|
|
|
if any(strcmp(chanBW,{'CBW2','CBW4','CBW8','CBW16'}))
|
|
% In S1G, Data and LTF1 fields have the same number of occupied
|
|
% subcarriers. Only apply scaling by the number of space-time streams.
|
|
Nst = numSC;
|
|
else
|
|
% Get the number of occupied subcarriers in HT and VHT fields.
|
|
% The number of used subcarriers for HT and VHT are same therefore
|
|
% fix the character vector input of the following helper function to
|
|
% VHT. The guard type is not relevant for numbers alone.
|
|
[~,vhtData,vhtPilots] = wlan.internal.wlanGetOFDMConfig(chanBW,'Long','VHT');
|
|
Nst = numel(vhtData)+numel(vhtPilots);
|
|
end
|
|
out = (Nst/numSC)*numSTSTotal;
|
|
|
|
end
|
|
|
|
%-------------------------------------------------------------------------
|
|
function validateInput(chanBW,numSC)
|
|
|
|
if any(strcmp(chanBW,{'CBW2','CBW4','CBW8','CBW16'})) % S1G
|
|
[~,s1gData,s1gPilots] = wlan.internal.s1gOFDMConfig(chanBW,'Long','LTF1');
|
|
Nst = numel(s1gData)+numel(s1gPilots);
|
|
else % nonHT, HT, and VHT
|
|
% Get number of used subcarriers in NonHT format
|
|
[~,nonhtData,nonhtPilots] = wlan.internal.wlanGetOFDMConfig(chanBW,'Long','Legacy');
|
|
Nst = numel(nonhtData)+numel(nonhtPilots);
|
|
end
|
|
|
|
% Validate number of subcarriers in input
|
|
coder.internal.errorIf(numSC~=Nst,'wlan:helperNoiseEstimate:IncorrectNumSC',Nst,numSC);
|
|
|
|
end
|
|
|
|
%-------------------------------------------------------------------------
|
|
function validateNType(nType)
|
|
|
|
coder.internal.errorIf(~(strcmpi(nType,'Per Antenna')),'wlan:helperNoiseEstimate:InvalidNoiseEstType');
|
|
|
|
end
|
|
|