# comm.OFDMModulator

Modulate signal using OFDM method

## Description

The `OFDMModulator`

object modulates a signal using the
orthogonal frequency division modulation method. The output is a baseband representation of
the modulated signal.

To modulate a signal using OFDM:

Create the

`comm.OFDMModulator`

object and set its properties.Call the object with arguments, as if it were a function.

To learn more about how System objects work, see What Are System Objects?

## Creation

### Syntax

### Description

creates an OFDM
modulator System object™.`hMod`

= comm.OFDMModulator

specifies Properties using one of more
name-value pair arguments. Enclose each property name in quotes. For example,
`hMod`

= comm.OFDMModulator(`Name`

,`Value`

)`comm.OFDMModulator('NumSymbols',8)`

specifies eight OFDM symbols in
the time-frequency grid.

sets the OFDM modulator system object properties based on the specified OFDM demodulator
system object `hMod`

= comm.OFDMModulator(`hDemod`

)`comm.OFDMDemodulator`

.

## Properties

Unless otherwise indicated, properties are *nontunable*, which means you cannot change their
values after calling the object. Objects lock when you call them, and the
`release`

function unlocks them.

If a property is *tunable*, you can change its value at
any time.

For more information on changing property values, see System Design in MATLAB Using System Objects.

`FFTLength`

— Number of FFT points

`64`

(default) | positive integer

Number of Fast Fourier Transform (FFT) points, specified as a positive integer. The
length of the FFT, *N*_{FFT}, must be greater than or equal to 8 and is equivalent to the number of
subcarriers.

**Data Types: **`double`

`NumGuardBandCarriers`

— Number of subcarriers to the left and right guard bands

`[6;5]`

(default) | two-element column vector of integers

Number of subcarriers allocated to the left and right guard bands, specified as a
two-element column vector of integers. The number of subcarriers must fall within [0, ⌊*N*_{FFT}/2⌋ − 1]. This vector has the form
[*N*_{leftG},
*N*_{rightG}], where
*N*_{leftG} and
*N*_{rightG} specify the left and right guard
bands, respectively.

**Data Types: **`double`

`InsertDCNull`

— Option to insert DC null

`false`

or `0`

(default) | `true`

or `1`

Option to insert DC null, specified as a numeric or logical `0`

(`false`

) or `1`

(`true`

). The DC
subcarrier is the center of the frequency band and has the index value:

(

`FFTLength`

/ 2) + 1 when`FFTLength`

is even(

`FFTLength`

+ 1) / 2 when`FFTLength`

is odd

`PilotInputPort`

— Option to specify pilot input

`false`

or `0`

(default) | `true`

or `1`

Option to specify pilot input, specified as a numeric or logical
`0`

(`false`

) or `1`

(`true`

). If this property is `1`

(`true`

), you can assign individual subcarriers for pilot
transmission. If this property is `0`

(`false`

), pilot
information is assumed to be embedded in the input data.

`PilotCarrierIndices`

— Pilot subcarrier indices

`[12; 26; 40; 54]`

(default) | column vector

Pilot subcarrier indices, specified as a column vector. If the PilotCarrierIndices property is set to `1`

(`true`

), you can specify the indices of the pilot subcarriers. You
can assign the indices to the same or different subcarriers for each symbol. Similarly,
the pilot carrier indices can differ across multiple transmit antennas. Depending on the
desired level of control for index assignments, the dimensions of the property vary.
Valid pilot indices fall in the range

$$\left[{N}_{\text{leftG}}+1,\text{\hspace{0.17em}}{N}_{\text{FFT}}/2\right]\cup \left[{N}_{\text{FFT}}/2+2,\text{\hspace{0.17em}}{N}_{\text{FFT}}-{N}_{\text{rightG}}\right],$$

where the index value cannot exceed the number of subcarriers. When
the pilot indices are the same for every symbol and transmit antenna, the property has
dimensions *N*_{pilot}-by-1. When the pilot indices vary across symbols, the property has
dimensions *N*_{pilot}-by-*N*_{sym}. If you transmit only one symbol but multiple transmit antennas, the
property has dimensions *N*_{pilot}-by-1-by-*N*_{t}., where *N*_{t}. is the number of transmit antennas. If the indices vary across the
number of symbols and transmit antennas, the property has dimensions *N*_{pilot}-by-*N*_{sym}-by-*N*_{t}. If the number of transmit antennas is greater than one, ensure that
the indices per symbol must be mutually distinct across antennas to minimize
interference.

To enable this property, set the `PilotInputPort`

property to
`1`

(`true`

).

`CyclicPrefixLength`

— Length of cyclic prefix

`16`

(default) | positive integer | row vector

Length of cyclic prefix, specified as a positive integer. If you specify a scalar,
the prefix length is the same for all symbols through all antennas. If you specify a row
vector of length *N*_{sym}, the prefix length can vary across symbols but remains the same
through all antennas.

**Data Types: **`double`

`Windowing`

— Option to apply raised cosine window between OFDM symbols

`false`

or `0`

(default) | `true`

or `1`

Option to apply raised cosine window between OFDM symbols, specified as
`true`

or `false`

. Windowing is the process in which
the OFDM symbol is multiplied by a raised cosine window before transmission to more
quickly reduce the power of out-of-band subcarriers. Windowing reduces spectral
regrowth.

`WindowLength`

— Length of raised cosine window

`1`

(default) | positive scalar

Length of raised cosine window, specified as a positive scalar. This value must be less than or equal to the minimum cyclic prefix length. For example, in a configuration of four symbols with cyclic prefix lengths 12, 14, 16, and 18, the window length must be less than or equal to 12.

To enable this property, set the `Windowing`

property to
`1`

(`true`

).

`NumSymbols`

— Number of OFDM symbols

`1`

(default) | positive integer

Number of OFDM symbols in the time-frequency grid, specified as a positive integer.

`NumTransmitAntennnas`

— Number of transmit antennas

`1`

(default) | positive integer

Number of transmit antennas, used to transmit the OFDM modulated signal, specified as a positive integer.

## Usage

### Description

assigns the pilot signal, `waveform`

= hMod(`data`

,`pilot`

)`pilot`

, into the frequency subcarriers
specified by the PilotCarrierIndices property value of the `hMod`

system
object. To enable this syntax set the PilotCarrierIndices property to `true`

.

### Input Arguments

`insignal`

— Input baseband signal

matrix | 3-D array

Input baseband signal, specified as a matrix or 3-D array of numeric values. The
input baseband signal must be of size *N*_{f}-by-*N*_{sym}-by-*N*_{t}. where *N*_{f} is the number of frequency subcarriers excluding guard bands and DC
null.

**Data Types: **`double`

**Complex Number Support: **Yes

`data`

— Input data

matrix | 3-D array

Input data, specified as a matrix or 3-D array. The input must be a numeric of
size *N*_{d}-by-*N*_{sym}-by-*N*_{t}. where *N*_{d} is the number of data subcarriers in each symbol. For more
information on how *N*_{d} is calculated, see the PilotCarrierIndices property.

**Data Types: **`double`

**Complex Number Support: **Yes

`pilot`

— Pilot signal

3-D array

Pilot signal, specified as a 3-D array of numeric values. The pilot signal must be
of size *N*_{pilot}-by-*N*_{sym}-by-N_{t}.

**Data Types: **`double`

**Complex Number Support: **Yes

### Output Arguments

`waveform`

— OFDM Modulated baseband signal

2-D array

OFDM Modulated baseband signal, returned as a 2-D array. If the
`CyclicPrefixLength`

property is a scalar, the output
`waveform`

is of size ((N_{FFT}+CP_{len})⁎N_{sym})-by-N_{t}. Otherwise, the size is (N_{FFT}⁎N_{sym}+∑(CP_{len}))-by-N_{t}.

**Data Types: **`double`

**Complex Number Support: **Yes

## Object Functions

To use an object function, specify the
System object as the first input argument. For
example, to release system resources of a System object named `obj`

, use
this syntax:

release(obj)

### Specific to `comm.OFDMModulator`

`info` | Provide dimensioning information for OFDM modulator |

`showResourceMapping` | Show the subcarrier mapping of the OFDM symbols created by the OFDM modulator System object |

## Examples

### Create and Modify OFDM Modulator

Create and display an OFDM modulator System object™ with default property values.

hMod = comm.OFDMModulator

hMod = comm.OFDMModulator with properties: FFTLength: 64 NumGuardBandCarriers: [2x1 double] InsertDCNull: false PilotInputPort: false CyclicPrefixLength: 16 Windowing: false NumSymbols: 1 NumTransmitAntennas: 1

Modify the number of subcarriers and symbols.

hMod.FFTLength = 128; hMod.NumSymbols = 2;

Verify that the number of subcarriers and the number of symbols changed.

disp(hMod)

comm.OFDMModulator with properties: FFTLength: 128 NumGuardBandCarriers: [2x1 double] InsertDCNull: false PilotInputPort: false CyclicPrefixLength: 16 Windowing: false NumSymbols: 2 NumTransmitAntennas: 1

Use the `showResourceMapping`

object function to show the mapping of data, pilot, and null subcarriers in the time-frequency space.

showResourceMapping(hMod)

### Create OFDM Modulator from OFDM Demodulator

Create an OFDM demodulator System object™ with default property values. Then, specify pilot indices for a single symbol and two transmit antennas.

Setting the `PilotCarrierIndices`

property of the demodulator affects the number of transmit antennas in the OFDM modulator when you use the demodulator in the creation of the modulator. The number of receive antennas in the demodulator is uncorrelated with the number of transmit antennas.

```
ofdmDemod = comm.OFDMDemodulator;
ofdmDemod.PilotOutputPort = true;
ofdmDemod.PilotCarrierIndices = ...
cat(3,[12; 26; 40; 54],[13; 27; 41; 55]);
```

Use the OFDM demodulator to construct the OFDM modulator.

ofdmMod = comm.OFDMModulator(ofdmDemod);

Display the properties of the OFDM modulator and demodulator, verifying that the applicable properties match.

disp(ofdmMod)

comm.OFDMModulator with properties: FFTLength: 64 NumGuardBandCarriers: [2x1 double] InsertDCNull: false PilotInputPort: true PilotCarrierIndices: [4x1x2 double] CyclicPrefixLength: 16 Windowing: false NumSymbols: 1 NumTransmitAntennas: 2

disp(ofdmDemod)

comm.OFDMDemodulator with properties: FFTLength: 64 NumGuardBandCarriers: [2x1 double] RemoveDCCarrier: false PilotOutputPort: true PilotCarrierIndices: [4x1x2 double] CyclicPrefixLength: 16 NumSymbols: 1 NumReceiveAntennas: 1

### Visualize Time-Frequency Resource Assignments for OFDM Modulator

The `showResourceMapping`

method displays the time-frequency resource mapping for each transmit antenna.

Construct an OFDM modulator.

mod = comm.OFDMModulator;

Apply the `showResourceMapping`

method.

showResourceMapping(mod)

Insert a DC null.

mod.InsertDCNull = true;

Show the resource mapping after adding the DC null.

showResourceMapping(mod)

### Create OFDM Modulator and Specify Pilots

Create an OFDM modulator and specify the subcarrier indices for the pilot signals. Specify the indices for each symbol and transmit antenna. When the number of transmit antennas is greater than one, set different pilot indices for each symbol between antennas.

Create an OFDM modulator System object, specifying two symbols and inserting a DC null.

mod = comm.OFDMModulator('FFTLength',128,'NumSymbols',2,... 'InsertDCNull',true);

Enable the pilot input port so you can specify the pilot indices.

mod.PilotInputPort = true;

Specify the same pilot indices for both symbols.

mod.PilotCarrierIndices = [12; 56; 89; 100];

Visualize the placement of the pilot signals and nulls in the OFDM time-frequency grid by using the `showResourceMapping`

object function.

showResourceMapping(mod)

Specify different indices for the second symbol by concatenating a second column of pilot indices to the `PilotCarrierIndices`

property.

```
mod.PilotCarrierIndices = cat(2,mod.PilotCarrierIndices, ...
[17; 61; 94; 105]);
```

Verify that the pilot subcarrier indices differ between the two symbols.

showResourceMapping(mod)

Increase the number of transmit antennas to two.

mod.NumTransmitAntennas = 2;

Specify the pilot indices for each of the two transmit antennas. To provide indices for multiple antennas while minimizing interference among the antennas, set the `PilotCarrierIndices`

property as a 3-D array such that the indices for each symbol differ among antennas.

mod.PilotCarrierIndices = cat(3,[20; 50; 70; 110], [15; 60; 75; 105]);

Display the resource mapping for the two transmit antennas. The gray lines denote the insertion of custom nulls. The nulls are created by the object to minimize interference among the pilot symbols from different antennas.

showResourceMapping(mod)

### Create OFDM Modulator with Varying Cyclic Prefix Lengths

Specify the length of the cyclic prefix for each OFDM symbol.

Create an OFDM modulator, specifying five symbols, four left and three right guard-band subcarriers, and the cyclic prefix length for each OFDM symbol.

mod = comm.OFDMModulator('NumGuardBandCarriers',[4;3],... 'NumSymbols',5,... 'CyclicPrefixLength',[12 10 14 11 13]);

Display the properties of the OFDM modulator, verifying that the cyclic prefix length changes across symbols.

disp(mod)

comm.OFDMModulator with properties: FFTLength: 64 NumGuardBandCarriers: [2x1 double] InsertDCNull: false PilotInputPort: false CyclicPrefixLength: [12 10 14 11 13] Windowing: false NumSymbols: 5 NumTransmitAntennas: 1

### Determine OFDM Modulator Data Dimensions

Get the OFDM modulator data dimensions by using the `info`

object function.

Construct an OFDM modulator System object™ with user-specified pilot indices, an inserted DC null, and specify two transmit antennas.

hMod = comm.OFDMModulator('NumGuardBandCarriers',[4;3], ... 'PilotInputPort',true, ... 'PilotCarrierIndices',cat(3,[12; 26; 40; 54], ... [11; 25; 39; 53]), ... 'InsertDCNull',true, ... 'NumTransmitAntennas',2);

Use the `info`

object function to get the modulator input data, pilot input data, and output data sizes.

info(hMod)

`ans = `*struct with fields:*
DataInputSize: [48 1 2]
PilotInputSize: [4 1 2]
OutputSize: [80 2]

### Create OFDM Modulated Data

Generate OFDM modulated symbols for use in link-level simulations.

Construct an OFDM modulator with an inserted DC null, seven guard-band subcarriers, and two symbols having different pilot indices for each symbol.

mod = comm.OFDMModulator( ... 'NumGuardBandCarriers',[4;3], ... 'PilotInputPort',true, ... 'PilotCarrierIndices',[12 11; 26 27; 40 39; 54 55], ... 'NumSymbols',2, ... 'InsertDCNull',true);

Determine input data, pilot, and output data dimensions.

modDim = info(mod);

Generate random data symbols for the OFDM modulator. The structure variable, `modDim`

, determines the number of data symbols.

```
dataIn = complex( ...
randn(modDim.DataInputSize),randn(modDim.DataInputSize));
```

Create a pilot signal that has the correct dimensions.

```
pilotIn = complex( ...
rand(modDim.PilotInputSize),rand(modDim.PilotInputSize));
```

Apply OFDM modulation to the data and pilot signals.

modData = mod(dataIn,pilotIn);

Use the OFDM modulator object to create the corresponding OFDM demodulator.

demod = comm.OFDMDemodulator(mod);

Demodulate the OFDM signal and output the data and pilot signals.

[dataOut, pilotOut] = demod(modData);

Verify that, within a tight tolerance, the input data and pilot symbols match the output data and pilot symbols.

```
isSame = (max(abs([dataIn(:) - dataOut(:); ...
pilotIn(:) - pilotOut(:)])) < 1e-10)
```

`isSame = `*logical*
1

## More About

### Orthogonal Frequency Division Modulation

OFDM operation divides a high-rate data stream into lower data rate substreams by decomposing
the transmission frequency band into *N* contiguous individually modulated
subcarriers. Multiple parallel and orthogonal subcarriers carry the samples with almost the
same bandwidth as a wideband channel. By using narrow orthogonal subcarriers, the OFDM
signal gains robustness over a frequency-selective fading channel and eliminates adjacent
subcarrier interference. Intersymbol interference (ISI) is reduced because the lower data
rate substreams have symbol durations larger than the channel delay spread.

The Frequency domain representation of orthogonal subcarriers in an OFDM waveform looks as follows:

The transmitter applies inverse fast Fourier transform (IFFT) to *N* symbols
at a time. The output of the IFFT is the sum of the *N* orthogonal
sinusoids:

$$x(t)={\displaystyle \sum _{k=0}^{N-1}{X}_{k}{e}^{j2\pi k\Delta ft}},\text{\hspace{1em}}0\le t\le T,$$

where {*X*_{k}} are data symbols, and
*T* is the OFDM symbol time. The data symbols
*X*_{k} are typically complex and can be from any
digital modulation alphabet (for example, QPSK, 16-QAM, 64-QAM).

The subcarrier spacing is Δ*f* = 1/*T*; ensuring that
the subcarriers are orthogonal over each symbol period, as shown below:

$$\frac{1}{T}{\displaystyle {\int}_{0}^{T}{\left({e}^{j2\pi m\Delta ft}\right)}^{*}\left({e}^{j2\pi n\Delta ft}\right)}\text{\hspace{0.17em}}dt=\frac{1}{T}{\displaystyle {\int}_{0}^{T}{e}^{j2\pi (m-n)\Delta ft}}\text{\hspace{0.17em}}dt=0\text{\hspace{1em}}\text{for}\text{\hspace{0.17em}}m\ne n.$$

An OFDM modulator consists of a serial-to-parallel conversion followed by a bank of
*N* complex modulators, individually corresponding to each OFDM subcarrier.

### Subcarrier Allocation, Guard Bands and Guard Intervals

Individual OFDM subcarriers are allocated as data, pilot, or null subcarriers.

As shown here, subcarriers are designated as data, DC, pilot, or guard band subcarriers.

Data subcarriers transmit user data.

Pilot subcarriers are used for channel estimation.

Null subcarriers transmit no data. Subcarriers with no data are used to provide a DC null and serve as buffers between OFDM resource blocks.

The null DC subcarrier is the center of the frequency band with an index value of (

`nfft`

/2 + 1) if`nfft`

is even, or ((`nfft`

+ 1) / 2) if`nfft`

is odd.The guard bands provide buffers between consecutive OFDM symbols to protect the integrity of transmitted signals by reducing intersymbol interference.

Null subcarriers enable you to model guard bands and DC subcarrier locations for specific standards, such as the various 802.11 formats, LTE, WiMAX, or for custom allocations. You can allocate the location of nulls by assigning a vector of null subcarrier indices.

Similar to guard bands, guard intervals are used in OFDM to protect the integrity of transmitted signals by reducing intersymbol interference.

Assignment of guard intervals is analogous to the assignment of guard bands. You can model guard intervals to provide temporal separation between OFDM symbols. The guard intervals help preserve intersymbol orthogonality after the signal passes through time-dispersive channels. Guard intervals are created by using cyclic prefixes. Cyclic prefix insertion copies the last part of an OFDM symbol as the first part of the OFDM symbol.

As long as the span of the time dispersion does not exceed the duration of the cyclic prefix, the benefit of cyclic prefix insertion is maintained.

Inserting a cyclic prefix results in a fractional reduction of user data throughput because the cyclic prefix occupies bandwidth that could be used for data transmission.

### Raised Cosine Windowing

While the cyclic prefix creates a guard period in time domain to preserve orthogonality, an OFDM symbol rarely begins with the same amplitude and phase exhibited at the end of the prior OFDM symbol causing spectral regrowth and therefore, spreading of signal bandwidth due to intermodulation distortion. To limit this spectral regrowth, it is desired to create a smooth transition between the last sample of a symbol and the first sample of the next symbol. This can be done by using a cyclic suffix and raised cosine windowing.

To create the cyclic suffix, the first *N*_{WIN} samples
of a given symbol are appended to the end of that symbol. However, in order to comply
with the 802.11g standard, for example, the length of a symbol cannot be arbitrarily
lengthened. Instead, the cyclic suffix must overlap in time and is effectively summed
with the cyclic prefix of the following symbol. This overlapped segment is where
windowing is applied. Two windows are applied, one of which is the mathematical inverse
of the other. The first raised cosine window is applied to the cyclic suffix of symbol
*k* and decreases from 1 to 0 over its duration. The second raised
cosine window is applied to the cyclic prefix of symbol *k*+1 and
increases from 0 to 1 over its duration. This process provides a smooth transition from
one symbol to the next.

The raised cosine window, *w*(*t*), in the time domain can
be expressed as:

$$w(t)=\{\begin{array}{l}1,\text{\hspace{0.17em}}\text{}0\le \left|t\right|<\frac{T-{T}_{W}}{2}\\ \frac{1}{2}\left\{1+\mathrm{cos}\left[\frac{\pi}{{T}_{W}}\left(\left|t\right|-\frac{T-{T}_{W}}{2}\right)\right]\right\},\text{}\frac{T-{T}_{W}}{2}\le \left|t\right|\le \frac{T+{T}_{W}}{2}\\ 0,\text{}\text{otherwise}\end{array}$$

where:

*T*is the OFDM symbol duration including the guard interval.*T*_{W}is the duration of the window.

Adjust the length of the cyclic suffix via the window length setting property, with suffix lengths set between 1 and the minimum cyclic prefix length. While windowing improves spectral regrowth, it does so at the expense of multipath fading immunity. This occurs because redundancy in the guard band is reduced because the guard band sample values are compromised by the smoothing.

The following figures display the application of raised cosine windowing.

## References

[1] Dahlman, Erik, Stefan Parkvall, and Johan Sköld. 4G LTE/LTE-Advanced for Mobile Broadband. Amsterdam: Elsevier, Acad. Press, 2011.

[2] Andrews, J. G., A. Ghosh, and R.
Muhamed. *Fundamentals of WiMAX*. Upper Saddle River, NJ: Prentice Hall,
2007.

[3] Agilent Technologies, Inc., "OFDM Raised Cosine Windowing", https://rfmw.em.keysight.com/wireless/helpfiles/n7617a/ofdm_raised_cosine_windowing.htm.

[4] Montreuil, L., R. Prodan, and T. Kolze. "OFDM TX Symbol Shaping 802.3bn", https://www.ieee802.org/3/bn/public/jan13/montreuil_01a_0113.pdf. Broadcom, 2013.

[5] "IEEE Standard 802.16™-2009." New York: IEEE, 2009.

## Extended Capabilities

### C/C++ Code Generation

Generate C and C++ code using MATLAB® Coder™.

Usage notes and limitations:

See System Objects in MATLAB Code Generation (MATLAB Coder).

## Version History

**Introduced in R2014a**

## See Also

### Functions

### Objects

### Blocks

## Open Example

You have a modified version of this example. Do you want to open this example with your edits?

## MATLAB Command

You clicked a link that corresponds to this MATLAB command:

Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.

# Select a Web Site

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

You can also select a web site from the following list:

## How to Get Best Site Performance

Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.

### Americas

- América Latina (Español)
- Canada (English)
- United States (English)

### Europe

- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)

- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)