# comm.CPMDemodulator

Demodulate signal using CPM method and Viterbi algorithm

## Description

The `comm.CPMDemodulator`

System object™ demodulates an input signal that was modulated using the continuous phase
modulation (CPM) method. The input is a baseband representation of the modulated signal. For
more information about the demodulation and filtering applied, see CPM Demodulation Method and Pulse Shape Filtering.

To demodulate a signal that was modulated using the CPM method:

Create the

`comm.CPMDemodulator`

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

`cpmdemod = comm.CPMDemodulator`

creates a demodulator System object to demodulate input CPM signals using the Viterbi algorithm.

`cpmdemod = comm.CPMDemodulator(`

sets properties using one or more name-value arguments. For example,
`Name`

,`Value`

)`'SymbolMapping','Gray'`

specifies gray-ordered symbol mapping for the
modulated symbols.

`cpmdemod = comm.CPMDemodulator(`

sets the `M`

,`Name`

,`Value`

)`ModulationOrder`

property to
`M`

and optional name-value arguments.

## 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.

`ModulationOrder`

— Modulation order

4 (default) | power of two scalar

Modulation order, specified as a power-of-two scalar. The modulation order,
*M* = 2^{k}
specifies the number of points in the signal constellation, where *k*
is a positive integer indicating the number of bits per symbol.

**Data Types: **`double`

`BitOutput`

— Option to output data as bits

`0`

or `false`

(default) | `1`

or `true`

Option to output data as bits, specified as a logical `0`

(`false`

) or `1`

(`true`

).

Set this property to

`false`

to output data as integers.Set this property to

`true`

to output data as bits.

For more information, see Integer-Valued and Binary-Valued Output Signals.

**Data Types: **`logical`

`SymbolMapping`

— Symbol encoding

`'Binary'`

(default) | `'Gray'`

Symbol encoding mapping of constellation bits, specified as
`'Binary'`

or `'Gray'`

.

Set this property to

`'Binary'`

to map symbols using natural binary-coded ordering.Set this property to

`'Gray'`

to map symbols using Gray-coded ordering.

For more information, see Integer-Valued and Binary-Valued Output Signals.

#### Dependencies

To enable this property, set the `BitOutput`

property to
`true`

.

`ModulationIndex`

— Modulation index

`0.5`

(default) | nonnegative scalar | column vector

Modulation index, specified as a nonnegative scalar or column vector. For more information, see CPM Demodulation Method.

**Data Types: **`double`

`FrequencyPulse`

— Type of frequency pulse shaping

`'Rectangular'`

(default) | `'Raised Cosine'`

| `'Spectral Raised Cosine'`

| `'Gaussian'`

| `'Tamed FM'`

Type of frequency pulse shaping used by the modulator to smooth the phase
transitions of the modulated signal, specified as `'Rectangular'`

,
`'Raised Cosine'`

, `'Spectral Raised Cosine'`

,
`'Gaussian'`

, or `'Tamed FM'`

. For more information,
see Pulse Shape Filtering.

`MainLobeDuration`

— Main lobe duration

`1`

(default) | positive integer

Main lobe duration of the largest lobe in the spectral raised cosine pulse, specified as a positive integer representing the number of symbol intervals used by the demodulator to pulse-shape the modulated signal.

#### Dependencies

To enable this property, set the `FrequencyPulse`

property to
`'Spectral Raised Cosine'`

.

**Data Types: **`double`

`RolloffFactor`

— Roll-off factor

`0.2`

(default) | scalar in the range [0, 1]

Roll-off factor of the spectral raised cosine pulse, specified as a scalar in the range [0, 1].

#### Dependencies

To enable this property, set the `FrequencyPulse`

property to
`'Spectral Raised Cosine'`

.

**Data Types: **`double`

`BandwidthTimeProduct`

— Product of bandwidth and symbol time of Gaussian pulse shape

`0.3`

(default) | positive scalar

Product of the bandwidth and symbol time of the Gaussian pulse shape, specified as a
positive scalar. Use `BandwidthTimeProduct`

to reduce the bandwidth,
at the expense of increased intersymbol interference.

#### Dependencies

To enable this property, set the `FrequencyPulse`

property to
`'Gaussian'`

.

**Data Types: **`double`

`PulseLength`

— Length of frequency pulse shape

`1`

(default) | positive integer

Length of the frequency pulse shape in symbol intervals, specified as a positive
integer. For more information on the frequency pulse length, refer to
*LT* in Pulse Shape Filtering.

**Data Types: **`double`

`SymbolPrehistory`

— Symbol prehistory

`1`

(default) | scalar | vector

Symbol prehistory, specified as scalar or vector with odd integer elements in the
range [– (`ModulationOrder`

– 1),
(`ModulationOrder`

– 1)]. This property defines the
data symbols used by the modulator prior to the first call of the object in reverse
chronological order. When you specify this property as a vector, the length must be
(`PulseLength`

– 1).

**Data Types: **`double`

`InitialPhaseOffset`

— Initial phase offset

`0`

(default) | scalar

Initial phase offset in radians of the modulated waveform, specified as a scalar.

**Data Types: **`double`

`SamplesPerSymbol`

— Number of samples per input symbol

`8`

(default) | positive integer

Number of samples per input symbol, specified as a positive integer. This property represents the number of samples input for each integer or binary word output. For all nonbinary schemes, as defined by the pulse shapes, this value must be greater than 1.

**Data Types: **`double`

`TracebackDepth`

— Traceback depth for Viterbi algorithm

`16`

(default) | positive integer

Traceback depth for the Viterbi algorithm, specified as a positive integer representing the number of trellis branches that the Viterbi algorithm uses to construct each traceback path. The value of this property is also the output delay and the number of zero symbols that precede the first meaningful demodulated symbol in the output. For more information, see Traceback Depth and Output Delays.

**Data Types: **`double`

`OutputDataType`

— Data type of output

`'double'`

(default) | `'logical'`

| `'int8'`

| `'int16'`

| `'int32'`

Data type of the output, specified as one of these values.

When you set the

`BitOutput`

property to`false`

, you can set the output data type to`'double'`

,`'int8'`

,`'int16'`

, or`'int32'`

.When you set the

`BitOutput`

property to`true`

, you can set the output data type to`'logical'`

or`'double'`

.

## Usage

### Syntax

### Description

### Input Arguments

`x`

— CPM-modulated signal

column vector

CPM-modulated signal, specified as a column vector with a length equal to an
integer multiple of the `SamplesPerSymbol`

property.

**Data Types: **`double`

| `single`

### Output Arguments

`y`

— Output signal

column vector | matrix

Output signal, returned as a column vector or matrix. To specify whether the
object outputs values as integers or bits, use the `BitOutput`

property. To specify
the output data type, use the `OutputDataType`

property.

## 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)

## Examples

### CPM Modulate and Demodulate Signal with Gray Mapping and Bit Inputs

Create CPM modulator, and CPM demodulator System objects.

cpmmodulator = comm.CPMModulator(8, ... 'BitInput',true, ... 'SymbolMapping','Gray'); cpmdemodulator = comm.CPMDemodulator(8, ... 'BitOutput',true, ... 'SymbolMapping','Gray');

Create an error rate calculator System object™, that accounts for the delay caused by the Viterbi algorithm.

delay = log2(cpmdemodulator.ModulationOrder) ... * cpmdemodulator.TracebackDepth; errorRate = comm.ErrorRate('ReceiveDelay',delay);

Transmit 100 3-bit words and print the error rate results.

for counter = 1:100 data = randi([0 1],300,1); modSignal = cpmmodulator(data); noisySignal = awgn(modSignal,0); receivedData = cpmdemodulator(noisySignal); errorStats = errorRate(data,receivedData); end fprintf('Error rate = %f\nNumber of errors = %d\n', ... errorStats(1),errorStats(2))

Error rate = 0.004006 Number of errors = 120

### Apply GFSK Modulation and Demodulation

Using the `comm.CPMModulator`

and `comm.CPMDemodulator`

System objects, apply Gaussian frequency-shift keying (GFSK) modulation and demodulation to random bit data.

Create a GFSK modulator and demodulator pair.

gfskMod = comm.CPMModulator( ... 'ModulationOrder',2, ... 'FrequencyPulse','Gaussian', ... 'BandwidthTimeProduct',0.5, ... 'ModulationIndex',1, ... 'BitInput',true); gfskDemod = comm.CPMDemodulator( ... 'ModulationOrder',2, ... 'FrequencyPulse','Gaussian', ... 'BandwidthTimeProduct',0.5, ... 'ModulationIndex',1, ... 'BitOutput',true);

Generate random bit data and apply GFSK modulation. Use a scatter plot to view the constellation.

numSym = 100; x = randi([0 1],numSym*gfskMod.SamplesPerSymbol,1); y = gfskMod(x); eyediagram(y,16)

Demodulate the GFSK-modulated data. To verify that the demodulated signal data is equal to the original data, account for the delay introduced by the Gaussian filtering in the GFSK modulation and demodulation processes.

z = gfskDemod(y); delay = finddelay(x,z); isequal(x(1:end-delay),z(delay+1:end))

`ans = `*logical*
1

## More About

### CPM Demodulation Method

The CPM demodulation method process consists of a correlator followed by a maximum-likelihood
sequence detector (MLSD) that searches the paths through the state trellis for the minimum
Euclidean distance path. When the modulation index is rational (*h* =
*m* / *p*), a finite number of phase states exist in
the symbol. The implementation uses the Viterbi algorithm to perform MLSD.

{*h*_{i}} is a sequence of modulation indices that moves cyclically through a set of indices {*h*_{0}, *h*_{1}, *h*_{2}, …,*h*_{H-1}}.

*h*_{i}=*m*_{i}/*p*_{i}is the modulation index in proper rational form.*m*_{i}is the numerator of the modulation index.*p*_{i}is the denominator of the modulation index.*m*_{i}and*p*_{i}are relatively prime positive numbers.The least common multiple (LCM) of {

*p*_{0},*p*_{1},*p*_{2}, …,*p*_{H-1}} is denoted as*p*.*h*_{i}=*m*'_{i}/*p*.

{*h*_{i}} determines the number of phase states,

$$numPhaseStates=\left\{\begin{array}{l}p,\text{\hspace{0.17em}}\text{\hspace{0.17em}}\text{for}\text{\hspace{0.17em}}\text{\hspace{0.17em}}\text{all}\text{\hspace{0.17em}}\text{\hspace{0.17em}}\text{even}\text{\hspace{0.17em}}\text{\hspace{0.17em}}m{\text{'}}_{i}\\ 2p,\text{\hspace{0.17em}}\text{\hspace{0.17em}}\text{for}\text{\hspace{0.17em}}\text{\hspace{0.17em}}\text{any}\text{\hspace{0.17em}}\text{\hspace{0.17em}}\text{odd}\text{\hspace{0.17em}}\text{\hspace{0.17em}}m{\text{'}}_{i}\end{array}\right\}\text{,}$$

and affects the number of trellis states,

*numStates* = *numPhaseStates*×*M*^{(L-1)},

*L*is the pulse length.*M*is the modulation order.

### CPM Method

The input to the demodulator is a baseband representation of the modulated signal:

$$\begin{array}{l}s(t)\text{\hspace{0.17em}}=\text{\hspace{0.17em}}\mathrm{exp}\left[j\text{\hspace{0.17em}}2\pi \text{\hspace{0.17em}}{\displaystyle \sum _{i\text{\hspace{0.17em}}=\text{\hspace{0.17em}}0}^{n}{\alpha}_{i}{h}_{i}q(t-iT)}\right],\text{and}\\ nT\text{\hspace{0.17em}}t(n+1)T.\end{array}$$

{

*α*_{i}} is a sequence of*M*-ary data symbols selected from the alphabet ±1, ±3, ±(*M*–1).*M*must have the form 2^{k}for some positive integer*k*, where*M*is the modulation order and specifies the size of the symbol alphabet.{

*h*_{i}} is a sequence of modulation indices, and*h*_{i}moves cyclically through a set of indices {*h*_{0},*h*_{i},*h*_{2}, ...,*h*_{H-1}}. When*H*=1, only one modulation index exists,*h*_{0}, which is denoted as*h*.

### Pulse Shape Filtering

The CPM method uses pulse shaping to smooth the phase transitions of the modulated signal. The
function *q*(*t*) is the phase response obtained from the
frequency pulse, *g*(*t*), through this relation: $$q(t)={\displaystyle {\int}_{-\text{\hspace{0.17em}}\infty}^{t}g(t)dt}$$.

The specified frequency pulse shape corresponds to these pulse shape expressions for
*g*(*t*).

Pulse Shape | Expression |
---|---|

Rectangular | $$g(t)=\{\begin{array}{cc}\frac{1}{2LT},& 0\le t\le LT\\ 0& \text{otherwise}\end{array}$$ |

Raised Cosine | $$g(t)=\{\begin{array}{cc}\frac{1}{2LT}\left[1-\mathrm{cos}\left(\frac{2\pi t}{LT}\right)\right],& 0\le t\le LT\\ 0& \text{otherwise}\end{array}$$ |

Spectral Raised Cosine | $$g(t)=\frac{1}{{L}_{\text{main}}T}\frac{\mathrm{sin}\left(\frac{2\pi t}{{L}_{\text{main}}T}\right)}{\frac{2\pi t}{{L}_{\text{main}}T}}\frac{\mathrm{cos}\left(\beta \frac{2\pi t}{{L}_{\text{main}}T}\right)}{1-{\left(\frac{4\beta}{{L}_{\text{main}}T}t\right)}^{2}},\text{\hspace{1em}}0\le \beta \le 1$$ |

Gaussian | $$\begin{array}{c}g(t)=\frac{1}{2T}\left\{Q\left[2\pi {B}_{b}\frac{t-{\scriptscriptstyle \frac{T}{2}}}{\sqrt{\mathrm{ln}2}}\right]-Q\left[2\pi {B}_{b}\frac{t+{\scriptscriptstyle \frac{T}{2}}}{\sqrt{\mathrm{ln}2}}\right]\right\},\text{\hspace{0.17em}}\text{where}\\ Q(t)={\displaystyle {\int}_{t}^{\infty}\frac{1}{\sqrt{2\pi}}{e}^{-{\tau}^{2}/2}d\tau}\end{array}$$ |

Tamed FM (tamed frequency modulation) | $$\begin{array}{l}g(t)={\scriptscriptstyle \frac{1}{8}}\left[{g}_{0}(t-T)+2{g}_{0}(t)+{g}_{0}(t+T)\right],\text{\hspace{0.17em}}\text{where}\\ {\text{g}}_{0}(t)\approx \frac{1}{T}\left[\frac{\mathrm{sin}({\scriptscriptstyle \frac{\pi t}{T}})}{{\scriptscriptstyle \frac{\pi t}{T}}}-\frac{{\pi}^{2}}{24}\frac{2\mathrm{sin}\left({\scriptscriptstyle \frac{\pi t}{T}}\right)-{\scriptscriptstyle \frac{2\pi t}{T}}\mathrm{cos}\left({\scriptscriptstyle \frac{\pi t}{T}}\right)-{\left({\scriptscriptstyle \frac{\pi t}{T}}\right)}^{2}\mathrm{sin}\left({\scriptscriptstyle \frac{\pi t}{T}}\right)}{{\left({\scriptscriptstyle \frac{\pi t}{T}}\right)}^{3}}\right]\end{array}$$ |

*L*_{main}is the main lobe pulse duration in symbol intervals.*β*is the roll-off factor of the spectral raised cosine.*B*_{b}is the product of the bandwidth and the Gaussian pulse.The duration of the pulse,

*LT*, is the pulse length in symbol intervals. As defined by the expressions, the spectral raised cosine, Gaussian, and tamed FM pulse shapes have infinite length. For all practical purposes,*LT*specifies the truncated finite length.

For more information on pulse shape filtering, see [1].

### Integer-Valued and Binary-Valued Output Signals

When you set the `BitOutput`

property to
`false`

:

The object outputs an integer column vector of length equal to

*N*/`SamplesPerSymbol`

, where*N*is the length of the input signal and indicates the number of input baseband modulated symbols. The output values are odd integers in the range [–(`ModulationOrder`

–1), (`ModulationOrder`

–1)].You cannot set the

`OutputDataType`

property to`'logical'`

.

When you set the `BitOutput`

property to
`true`

:

The object outputs a binary column vector of length equal to

*k*×(*N*/`SamplesPerSymbol`

), where*k*= log2(`ModulationOrder`

) and*N*is the number of input baseband modulated symbols (specifically, the length of the input signal).The

`SymbolMapping`

property determines how the object maps integers in the range [0,`ModulationOrder`

– 1] to*k*-length bit word. The binary word mapping options are natural binary-coded ordering or Gray-coded ordering.You can set the

`OutputDataType`

property to only`'double'`

or`'logical'`

.The object follows this process.

Map each demodulated symbol to an odd integer

*L*in the range [–(`ModulationOrder`

–1), (`ModulationOrder`

–1)].Map

*L*to the nonnegative integer (*L*+`ModulationOrder`

–1)/2.Map each nonnegative integer to a

*k*-length binary word. The binary word mapping options are natural binary-coded ordering or Gray-coded ordering, as specified by the`SymbolMapping`

property.

### Traceback Depth and Output Delays

The traceback depth is the number of trellis branches used to construct each traceback path. Traceback depth influences the output delay, which is the number of zero symbols that precede the first meaningful demodulated value in the output.

The optimal traceback depth setting depends on minimum squared Euclidean distance calculations. Alternatively, you can choose a typical value, dependent on the number of states, using the *five-times-the-constraint-length* rule, which corresponds to 5log_{2}(*numStates*).

For a binary raised cosine pulse shape with a pulse length of 3 and *h*=2/3, applying this rule (5log_{2}(3×2^{2}) = 18 gives a result that is close to the optimum value of 20.

## References

[1] Anderson, John B., Tor Aulin, and Carl-Erik Sundberg. *Digital Phase Modulation*. New York: Plenum Press, 1986.

## 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 R2012a**

## See Also

### 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)