# Raised cosine filter taps implementation

I want to add a raised cosine filter to gr_firdes.* in
root-raised cosine there. After looking through a few sources, I have
the following time-domain response of an RC filter:

h(t) = [sin(pi * t / T_s) / (pi * t / T_s)] / [cos(pi * alpha * t / T_s)
/ (1 - (2 * alpha * t / T_s )^2 )]

As far as I can tell, I should be able to compute the taps using:

for n = -FLOOR(ntaps/2) to FLOOR(ntaps/2), do
h(n) = [sin(pi * n) / (pi * n)] / [cos(pi * alpha * n) / (1 - (2 *
alpha * n)^2 )]
end_for

The things I’ll have to worry about:

1. if n is 0: h(n) = 1
2. if n is +/- 1/(2 * alpha): h(n) = (1 / (8 * alpha) ) * sin(pi / (2 *
alpha) ) #I think I did this right…
3. rounding errors: not sure what to do here given we’re operating with
floats.

Any tips/suggestions?

Thanks,
Sean

On Sun, Nov 13, 2011 at 6:56 PM, Nowlan, Sean
[email protected]wrote:

for n = -FLOOR(ntaps/2) to FLOOR(ntaps/2), do

Any tips/suggestions?

Thanks,
Sean

Sean,
We’ve gotten this question before, and I’m again curious why you want a
raised cosine filter? If you really are using it for something, the
easiest
thing to do is just create a root raised cosine filter and convolve it
with
itself.

Tom

Because I need a raised cosine filter. If I convolve root raised cosine
filter coefficients with themselves (generated with gr_firdes), do I
need to apply a scaling factor?

From: Tom R. [mailto:[email protected]]
Sent: Monday, November 14, 2011 9:56 AM
To: Nowlan, Sean
Cc: [email protected]
Subject: Re: [Discuss-gnuradio] raised cosine filter taps implementation

On Sun, Nov 13, 2011 at 6:56 PM, Nowlan, Sean
<[email protected]mailto:[email protected]> wrote:
I want to add a raised cosine filter to gr_firdes.* in
root-raised cosine there. After looking through a few sources, I have
the following time-domain response of an RC filter:

h(t) = [sin(pi * t / T_s) / (pi * t / T_s)] / [cos(pi * alpha * t / T_s)
/ (1 - (2 * alpha * t / T_s )^2 )]

As far as I can tell, I should be able to compute the taps using:

for n = -FLOOR(ntaps/2) to FLOOR(ntaps/2), do
h(n) = [sin(pi * n) / (pi * n)] / [cos(pi * alpha * n) / (1 - (2 *
alpha * n)^2 )]
end_for

The things I’ll have to worry about:

1. if n is 0: h(n) = 1
2. if n is +/- 1/(2 * alpha): h(n) = (1 / (8 * alpha) ) * sin(pi / (2 *
alpha) ) #I think I did this right…
3. rounding errors: not sure what to do here given we’re operating with
floats.

Any tips/suggestions?

Thanks,
Sean

Sean,
We’ve gotten this question before, and I’m again curious why you want a
raised cosine filter? If you really are using it for something, the
easiest thing to do is just create a root raised cosine filter and
convolve it with itself.

Tom

PSK31 for ham radio uses a raised cosine filter rather than the RRC.

On Mon, Nov 14, 2011 at 12:01 PM, Ben R. [email protected] wrote:

PSK31 for ham radio uses a raised cosine filter rather than the RRC.

Interesting. Thanks.

Do you know why the do it? Do they just have the filter on one side?

Tom

On Mon, Nov 14, 2011 at 10:03 AM, Tom R. [email protected]
wrote:

On Mon, Nov 14, 2011 at 12:01 PM, Ben R. [email protected] wrote:

PSK31 for ham radio uses a raised cosine filter rather than the RRC.

Interesting. Thanks.
Do you know why the do it? Do they just have the filter on one side?
Tom

I don’t think it’s for any good reason. The raised cosine filter is
on the transmit side and I guess you can put whatever you want on the
receive side. I would have thought another raised cosine filter on
the receiver side was the best way to go to maximise the signal and
then deal with the ISI afterwards. I haven’t looked at other peoples
code to see how they’re doing it.

On Mon, Nov 14, 2011 at 10:40 AM, Nowlan, Sean
[email protected]wrote:

Because I need a raised cosine filter. If I convolve root raised cosine
filter coefficients with themselves (generated with gr_firdes), do I need
to apply a scaling factor?

Ok, but my question was Why do you need a raised cosine filter? I’m just
curious about what applications use this instead of RRC filters?

Tom

On Mon, Nov 14, 2011 at 1:09 PM, Ben R. [email protected] wrote:

I don’t think it’s for any good reason. The raised cosine filter is
on the transmit side and I guess you can put whatever you want on the
receive side. I would have thought another raised cosine filter on
the receiver side was the best way to go to maximise the signal and
then deal with the ISI afterwards. I haven’t looked at other peoples
code to see how they’re doing it.

I would have figured it was on the Tx side for bandwidth control, and
you
could do various things on the receiver side with that. It’s of course
why
we normally use RRC filters though; restrict the transmitted signal
bandwidth, then the receive RRC does both a matched filter and creates
Nyquist pulses (ignoring multipath).

Tom

On Mon, Nov 14, 2011 at 11:11 AM, Tom R. [email protected]
wrote:

Tom
we normally use RRC filters though; restrict the transmitted signal
bandwidth, then the receive RRC does both a matched filter and creates
Nyquist pulses (ignoring multipath).
Tom

Yep. I meant that I don’t think there was a good reason for the
author of PSK31 choosing raised cosine over RRC.

On Mon, Nov 14, 2011 at 10:21 AM, Ben R. [email protected] wrote:

Do you know why the do it? Do they just have the filter on one side?
could do various things on the receiver side with that. It’s of course why
we normally use RRC filters though; restrict the transmitted signal
bandwidth, then the receive RRC does both a matched filter and creates
Nyquist pulses (ignoring multipath).
Tom

Yep. I meant that I don’t think there was a good reason for the
author of PSK31 choosing raised cosine over RRC.

I spent some time looking at it when I was writing a PSK31 decoder for
GR. It seems like the transmit pulse-shaping filter is RC in order to
keep the transmitted bandwidth even lower than it would be with RRC.
In other words, narrow bandwidth and steep skirts were given priority
over ISI performance. PSK31 doesn’t specify a receive filter, but the
popular implementations (fldigi, G3PLX) seem to share the same filter,
which is some weird custom LPF. I can go find the taps if people are
interested.

I briefly looked into using fred harris’s class of “ISI-corrected”
filters designed with a modified Remez algorithm (harris p.92) for
both TX and RX, but it didn’t really net me any more performance than
just using a steep LPF, and I couldn’t get Remez to converge reliably
for the filters required. In any case, PSK31 is enough of a standard
that introducing different TX filters would likely result in
suboptimal performance for “standard” receivers.

–n

Is it just me, or does the gr_cpm::generate_cpm_lsrc_taps already
implement a Raised Cosine filter? No need for me to reinvent the wheel
then :c)

Sean

On Mon, Nov 14, 2011 at 11:21 AM, Ben R. [email protected] wrote:

Do you know why the do it? Do they just have the filter on one side?
could do various things on the receiver side with that. It’s of course why
we normally use RRC filters though; restrict the transmitted signal
bandwidth, then the receive RRC does both a matched filter and creates
Nyquist pulses (ignoring multipath).
Tom

Yep. I meant that I don’t think there was a good reason for the
author of PSK31 choosing raised cosine over RRC.

I just remembered it’s raised cosine in time not raised cosine in
frequency space, and so completely different from what the original
question was about. Oh well.
Cheers,
Ben

On Wed, Nov 16, 2011 at 10:07:23PM +0000, Nowlan, Sean wrote:

More in general, is there a reason why the CPM modulator in the gr-digital
package generates its own filter taps instead of using the functions in gr_cpm?

All of the modulators from digital_cpmmod_bc use the taps from gr_cpm,
so that’s fine–however, you could argue that gr_cpm belongs into
gr-digital.

Also, it seems that gr_cpm has other filters implemented through the
phase_response function that belong in gr_firdes (which I assume stands for FIR
design).

Personally, I would not like to see that happen. firdes already has a
lot of stuff which could be somewhere else (like window functions, which
have other uses than filter design) and the CPM phase response taps are
really specific and belong close to the appropriate modulator.

## MB

Karlsruhe Institute of Technology (KIT)
Communications Engineering Lab (CEL)

Dipl.-Ing. Martin B.
Research Associate

Kaiserstraße 12
Building 05.01
76131 Karlsruhe

Phone: +49 721 608-43790
Fax: +49 721 608-46071
www.cel.kit.edu

KIT – University of the State of Baden-Württemberg and
National Laboratory of the Helmholtz Association

More in general, is there a reason why the CPM modulator in the
gr-digital package generates its own filter taps instead of using the
functions in gr_cpm? Also, it seems that gr_cpm has other filters
implemented through the phase_response function that belong in gr_firdes
(which I assume stands for FIR design).

Thanks,
Sean

Yes, perhaps gr_cpm belongs in gr-digital. Still, there are modulators
implemented in C++ (gmskmod, cpmmod, etc.) in gr-digital that aren’t
even being used in the benchmark_tx/rx programs. It looks like the
filters taps are generated either by gr_firdes or using calls to numpy.
Is there a reason the C++ classes were not used?

Thanks,
Sean