This example shows the internal resampling filter design of the OFDM functions `nrOFDMModulate`, `nrOFDMInfo`, and `nrOFDMDemodulate`. These functions enable you to specify the OFDM sample rate and fast Fourier transform (FFT) size by using the `SampleRate` and `Nfft` name-value input arguments. When the specified sample rate and the nominal sample rate, corresponding to the FFT size, do not match, the OFDM functions resample the waveform using an internal multirate FIR filter.

### OFDM Sample Rate and Nominal Sample Rate

The value that you set for the `SampleRate` input determines the sample rate of the waveform.

The nominal sample rate corresponding to the FFT size used in the OFDM modulation, ${\mathit{FFT}}_{\mathrm{SR}}$, is equal to `Nfft*carrier.SubcarrierSpacing*1000`, where `carrier` is the input argument of the function call that specifies the carrier configuration.

When the specified sample rate and the nominal sample rate do not match, the OFDM functions resample the waveform using an internal resampling filter. Setting the sample rate to the nominal sample rate does not result in resampling during OFDM modulation.

### OFDM Modulation without Resampling

Create a carrier configuration object with 25 resource blocks.

```carrier = nrCarrierConfig; carrier.NSizeGrid = 25;```

Get OFDM information.

`ofdmInfo = nrOFDMInfo(carrier);`

Display nominal sample rate and the sample rate returned in the OFDM information.

`ofdmInfo.Nfft*carrier.SubcarrierSpacing*1000`
```ans = 7680000 ```
`ofdmInfo.SampleRate`
```ans = 7680000 ```

Verify that specifying a sample rate of `7.68e6` does not result in resampling during OFDM modulation.

```grid = nrResourceGrid(carrier); grid(:) = nrSymbolModulate(randi([0 1],numel(grid)*2,1),'QPSK'); waveform1 = nrOFDMModulate(carrier,grid); waveform2 = nrOFDMModulate(carrier,grid,'SampleRate',7.68e6); isequal(waveform1,waveform2)```
```ans = logical 1 ```

### Filter Design

The resampling filter is a function of these two ratios.

• The ratio of the transmission bandwidth (${\mathit{TX}}_{\mathrm{BW}}$) to the nominal sample rate: ${\mathit{TX}}_{\mathrm{BW}}$ / ${\mathit{FFT}}_{\mathrm{SR}}$, where ${\mathit{TX}}_{\mathrm{BW}}$ is equal to `carrier.NSizeGrid*12*carrier.SubcarrierSpacing*1000`.

• The ratio of the nominal sample rate to the specified sample rate: ${\mathit{FFT}}_{\mathrm{SR}}$ / `SampleRate`.

To design the resampling filter, the OFDM functions call the `designMultirateFIR` function with these input arguments.

• Interpolation factor, `L`, equal to `SampleRate/g`, where `g =` `gcd`(${\mathit{FFT}}_{\mathrm{SR}}$,`SampleRate`). Because the resampling of the OFDM-modulated waveform is by a factor of `SampleRate/`${\mathit{FFT}}_{\mathrm{SR}}$, the resampling is costly if `SampleRate` and ${\mathit{FFT}}_{\mathrm{SR}}$ do not have large common factors.

• Decimation factor, `M`, equal to ${\mathit{FFT}}_{\mathrm{SR}}$`/g`.

• Transition width, `TW`, such that the transition band starts at $±$${\mathit{TX}}_{\mathrm{BW}}$ / 2 (that is, the transition band starts at the edge of the occupied bandwidth).

• Stopband attenuation, `Astop`, equal to 70 dB.

If `SampleRate` > ${\mathit{FFT}}_{\mathrm{SR}}$, then:

• `L` > `M` and the transition band stops at $±$${\mathit{FFT}}_{\mathrm{SR}}$ / 2 (corresponding to a normalized frequency of 1/`L`).

• The filter acts as an anti-imaging filter after upsampling by `L`.

If `SampleRate` < ${\mathit{FFT}}_{\mathrm{SR}}$, then:

• `M` > `L` and the transition band stops at $±$`SampleRate/2` (corresponding to a normalized frequency of 1/`M`).

• The filter acts as an anti-aliasing filter before downsampling by `M`.

### OFDM Modulation with Resampling

Create a carrier configuration object with 25 resource blocks.

```carrier = nrCarrierConfig; carrier.NSizeGrid = 25;```

Compute the transmission bandwidth.

`txBW = carrier.NSizeGrid*12*carrier.SubcarrierSpacing*1000`
```txBW = 4500000 ```

Specify a custom sample rate. Obtain the corresponding OFDM information and calculate the nominal sample rate for the default FFT size.

```SampleRate = 6e6; ofdmInfo = nrOFDMInfo(carrier,'SampleRate',SampleRate); Nfft = ofdmInfo.Nfft```
```Nfft = 640 ```
`fftSR = Nfft*carrier.SubcarrierSpacing*1000`
```fftSR = 9600000 ```

Calculate `g`, `L`, and `M`.

`g = gcd(fftSR,SampleRate)`
```g = 1200000 ```
`L = SampleRate/g`
```L = 5 ```
`M = fftSR/g`
```M = 8 ```

Plot the spectrum of the OFDM waveform before resampling by setting the sample rate to the nominal sample rate.

```figure; hold on; [f,S] = measureSpectrum(carrier,Nfft,fftSR,1); plot(f,S,'LineWidth',2);```

Plot the spectrum of the OFDM waveform after upsampling by `L`, before applying the filter.

```[fL,S] = measureSpectrum(carrier,Nfft,fftSR,L); hL = plot(fL,S,':');```

Plot the spectrum of the OFDM waveform after applying the filter.

```[f,S] = measureSpectrum(carrier,Nfft,fftSR*L,1); plot(f,S);```

Plot the spectrum of the final OFDM waveform after downsampling.

```[f,S] = measureSpectrum(carrier,Nfft,SampleRate,1); plot(f,S,'Color',hL.Color,'LineWidth',2); hL.Color = [0.5 0.5 0.5];```

Overlay the filter design specification.

```fStop = fftSR/2*L/max([L M]); aStop = -70.0; spec = [fL(1) aStop; -fStop aStop; -txBW/2 0; txBW/2 0; fStop aStop; fL(end) aStop]; plot(spec(:,1),spec(:,2),'k--'); legend('Nominal SR','Upsampled','Filtered','Desired SR','Filter specification','Location','north'); xlabel('Frequency'); ylabel(['Power Spectral Density (dBw/' num2str(carrier.SubcarrierSpacing) 'kHz)']); axis([0 fftSR -120 10]);```

### Local Function

```function [f,S] = measureSpectrum(carrier,Nfft,SampleRate,L) % Subcarrier spacing in Hz SCS = carrier.SubcarrierSpacing*1e3; % Set up spectrum estimator spectrumEstimator = dsp.SpectrumEstimator; spectrumEstimator.SampleRate = SampleRate; spectrumEstimator.AveragingMethod = 'Exponential'; spectrumEstimator.ForgettingFactor = 0.99; spectrumEstimator.FrequencyRange = 'centered'; spectrumEstimator.PowerUnits = 'dBW'; spectrumEstimator.SpectrumType = 'Power density'; spectrumEstimator.FFTLengthSource = 'Property'; spectrumEstimator.FFTLength = floor(SampleRate*L/SCS); % For 100 slots rs = RandStream('mt19937ar','Seed',1); for nSlot = 0:99 % Create a slot grid filled with QPSK symbols and OFDM modulate grid = nrResourceGrid(carrier); grid(:) = nrSymbolModulate(rs.randi([0 1],numel(grid)*2,1),'QPSK'); waveform = nrOFDMModulate(carrier,grid,'Nfft',Nfft,'SampleRate',SampleRate); waveform = waveform * Nfft; % Apply interpolation if required if (L>1) T = size(waveform,1); waveform = reshape([waveform.'; zeros(L-1,T)],[],1)*sqrt(L); end % Measure the spectrum S = spectrumEstimator(waveform); end % Create frequency axis N = spectrumEstimator.FFTLength; f = (-N/2:(N/2 - 1))*SCS; % Translate from dBw/Hz to dBW/SCS S = S + 10*log10(SCS); end```