Teensy Convolution SDR (Software Defined Radio)

I uninstalled then re-installed Arduino/Teensy on my computer and followed Jan's instructions today, but I'm still getting some puzzling errors. While installing the CMSIS files I found that arm_math.h and arm_common_tables.h already existed in the teensy3/ folder, so I replaced them. I also discovered that libarm_cortexM4l_math.a and libarm_cortexM4lf_math.a already existed in the arduino arm-none-eabi/lib/ folder and also replaced them with new CMSIS files.

Here is the compiler output from a clean install + Jan's modifications:

Arduino: 1.8.2 (Windows 10), TD: 1.36, Board: "Teensy 3.6, Serial, 180 MHz, Faster, US English"

In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/analyze_fft256.h:32:0,

                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:61,

                 from C:\Users\John\Documents\Radio stuff\CS-40\Teensy-ConvolutionSDR-master\Teensy_Convolution_SDR\Teensy_Convolution_SDR.ino:114:

C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/arm_math.h:314:4: error: #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0"

   #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0"


C:\Users\John\Documents\Radio stuff\CS-40\Teensy-ConvolutionSDR-master\Teensy_Convolution_SDR\Teensy_Convolution_SDR.ino:127:50: fatal error: play_sd_mp3.h: No such file or directory

compilation terminated.

Multiple libraries were found for "SD.h"
 Used: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD
 Not used: C:\Program Files (x86)\Arduino\libraries\SD
Error compiling for board Teensy 3.6.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

After inserting the code suggested by Pete (#define ARM_MATH_CM4) I get the following errors:

Arduino: 1.8.2 (Windows 10), TD: 1.36, Board: "Teensy 3.6, Serial, 180 MHz, Faster, US English"

In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/arm_math.h:304:0,

                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/analyze_fft256.h:32,

                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:61,

                 from C:\Users\John\Documents\Radio stuff\CS-40\Teensy-ConvolutionSDR-master\Teensy_Convolution_SDR\Teensy_Convolution_SDR.ino:114:

C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/core_cm4.h:155:95: fatal error: core_cmFunc.h: No such file or directory

compilation terminated.

Error compiling for board Teensy 3.6.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

At this point my only thought is that I'm using a newer version of Arduino/Teensy that breaks the dependencies somehow. I'm not sure if anyone else can recreate these errors, but it would be nice to get to the bottom of this.


Hunting down the source of some of the errors I've discovered two things.

1) The error in audio.h leads to #include "analyze_fft256.h", and analyze_fft256.h traces back to #include "arm_math.h", which traces to #include "core_cm4.h"

2) After copying core_cmFunc.h from the CMSIS library into the teensy3/ folder I get an error about a missing cmsis_gcc.h file. I also copied that into the teensy3 folder, which brings us back to the errors found in this earlier post: https://forum.pjrc.com/threads/40590-Teensy-Convolution-SDR-(Software-Defined-Radio)?p=147325&viewfull=1#post147325

So we seem to have come full circle. I'm officially stumped.
Last edited:

It is with great relief, and no small amount of chagrin, that I can report that the source of these errors was in the unmodified arm_math.h file. As it turns out, Notepad++ will only turn administrator mode on and not automatically save without clicking the button again, which I had failed to do. So all of this was traced back to a permissions issue; Jan's modifications were simply never saved. Whew!

In other news, I had to overcome two more errors before getting a clean complie. The first was the same error regarding sincosf that has been encountered by other users.

error: 'sincosf' was not declared in this scope

This was overcome by inserting the following code just after the buttons are defined:
void sincosf(float err, float *s, float *c);

It may be that this function is not in the default Arduino/Teensy installation, but that's a matter for another time.

The next error had to do with another missing file, this time play_sd_mp3.h. This was fixed by installing the Arduino-Teensy-Codec-lib by Frank Boesing, available here: https://github.com/FrankBoesing/Arduino-Teensy-Codec-lib

Thanks to everyone for your support and I will hopefully have some results from my project in the next week or so!

Hi John,

that´s great news! Thank you also for providing the two solutions for sincosf and the excellent MP3 lib by Frank B.

Have fun with the Teensy Convolution SDR and would be nice to hear about your progress and potential improvements ;-).

73 de Frank DD4WH
It took me some time to implement the main filters in the Teensy Convolution SDR in a quite different way:

- they used to be implemented as filters with real coefficients, meaning that in the course of the convolution process during the complex multiply of the filter mask and the FFT results only half of the filter mask was filled with coefficients (real), the other half (imaginary) just contained zeros

- in Whiteley (2011, page 48) I found a very nice description of a convolution process which uses complex FIR filter coefficients, additionally using a frequency shift making it possible to not only lowpass filter the audio samples, but also implement bandpass filtering with the same amount of calculations!

So now the audio chain in the Teensy Convolution SDR has a "new" way of filtering using complex FIR filter coefficients making it possible to adjust filters in a totally flexible way, freely adjustable by the user: try receiving in SAM mode with 1.5khz lowpass in the lower sideband and 3.6kHz lowpass filter in the upper sideband or receive LSB with 300Hz to 2400Hz response :) [calculations are not more complicated, the same processor power is necessary!]

One surprise for me was, that you do not need any removal of bins prior to the complex multiply in order to choose sidebands (LSB, USB) any more, the new filter does all the magic for you: just choose HiCut frequency of 2300Hz and low cut frequency of 200Hz and you listen to USB, choose HiCut of -300Hz and LoCut of -2700Hz and listen to LSB ;-).

Source code -as usual- is on github: https://github.com/DD4WH/Teensy-ConvolutionSDR/blob/master/Teensy_Convolution_SDR.ino

Have fun with the Teensy Convolution SDR!

73 de Frank
After updating the (very) old Arduino and Teensyduino installations on my computer to the newest versions 1.8.5 and 1.40, I had to change some small things in the Teensy Convolution SDR code in order to compile it accurately.

Some more changes in the Teensy Convolution SDR:

* I took this opportunity to update the description of how to setup the software for the Teensy Convolution SDR (can be found on the github front page), so it should now be easier to set it up
* repaired the FM mono and FM stereo code, which was distorting heavily, but is now clean again
* Convolution FFT size was changed to 512 taps (was 1024 taps) in order to save a real lot of memory (this memory is needed, because I plan to implement morse code and RTTY decoding in the future)
* because of this change and freeing up of memory, now MP3 playing works again


Have fun with the Teensy,

Frank DD4WH
Hi all
I have the same configuration as frank arduino ide 1.85 and the teensyduino 1.40.
I have also install the new ARM CMSIS DSP library and modify the arm_math.h file
When I compiled the sketch I get next error :

Arduino: 1.8.5 (Windows 10), TD: 1.40, Board:"Teensy 3.6, Serial, 180 MHz, Faster, US English"
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/core_cmFunc.h:61:0,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/core_cm4.h:155,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/arm_math.h:315,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/analyze_fft256.h:32,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:61,
from C:\Users\PC Hellum\Documents\Arduino\Teensy-ConvolutionSDR-master\Teensy_Convolution_SDR\Teensy_Convolution_SDR.ino:124:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/cmsis_gcc.h:58:75: error: macro "__enable_irq" passed 1 arguments, but takes just 0
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/cmsis_gcc.h:69:76: error: macro "__disable_irq" passed 1 arguments, but takes just 0
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)

Meerdere bibliotheken gevonden voor "SD.h"
Gebruikt: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD
Niet gebruikt: C:\Program Files (x86)\Arduino\libraries\SD
Fout bij het compileren voor board Teensy 3.6[/SIZE]

what am I doing wrong ?
please help
jwsmid PE1RZM

sorry for late reply.

Well, I am really no expert in error interpretation, but I guess you did something wrong with installing the CMSIS lib. Did you follow EXACTLY Jans description here?:


Sorry, but cannot give you more help.

I installed a fresh copy of the newest Arduino and Teensyduino versions on my computer (1.8.5 and 1.40) and then followed exactly Jans description and it worked . . .

73 de Frank DD4WH
Hi Jan,

very nice to hear that it works now!

For all others it would be interesting to know how you got your problem solved, so others can learn from you.

Would be nice if you could post the solution!

All the best, have fun,

73 de Frank DD4WH
First, thanks Frank for letting us share the project. I am putting one together using a piece of hardware that might be of interest to others.

Before getting to that, let me explain how I got here. I have an out-of-date 2-meter transmit and receive SDR called the DSP-10, http://www.proaxis.com/~boblark/dsp10.htm
There are 300 or so of these around but end of life is here since, in part, the ADSP-2181 boards are no longer available. Plus the code for the DSP-10 is all in assembly language, and changes are a bit laborious. So, the first thought for dealing with the processor issues was to use a T3.6 and a Codec to make a drop in replacement for what Analog Devices called the "EZ-Kit."

Then I saw Frank's Convolution SDR and the use of floating point routines that looked like a great starting point for the DSP-10 project. Besides, it looked like a neat project by itself. So, I now have Frank's software compiling (except for the SD card that is commented out) and am ready to make up I-Q mixers, display and associated control stuff. It dawned on me that if I did a decent job of making a Control Box that had the T3.6 and knobs, buttons, the touch 360x240 display and assorted interfaces, it could be used with Frank's project, and by re-plugging the RF hardware, the DSP-10. The latter has always wanted a tuning knob, and the little display would make it capable of stand-alone operation.

So to get to the reason for this post, I put together a schematic diagram that (hopefully) is the super-set of things needed for both radios, as well as most anything that might reasonably come along. I have not yet laid out the board, but wanted to get community comments that might make this more useful. The board is posted:
It includes:
* Teensy 3.6 with an extender card to bring out the bottom pads under the SD card
* PJRC Touch Screen
* PJRC plug-in Codec or alternative with the same pinout
* 8 Buttons (including those on knobs)
* 3 Knobs
* The USB port on the Teensy
* Three RS-232 ports (DSP-10 historically needs this, PC control, GPS and Antenna Control)
* Two extra SPI ports
* 12 or so extra digital outputs
* Buffering and voltage shifting on lines to the RF hardware
* A single 25-pin D connector for control of the RF hardware
It is tough to figure out usage from the schematic, so my spread sheet tracking of pins is here:

Comments would be appreciated. My intention is to get this onto a compact PC board that would be shared through OSH Park. So, there are no promises, but if anyone else would be interested in this sort of control box, this is a chance to steer the functionality and/or implementation.

Thanks, Bob W7PUA
Hey, happiness is having things work! I finished the SDR control box to the point of being able to plug a soft-rock into the back and running Frank's Convolution SDR. It works, and I am receiving stations!

I will post more on the control box in a bit, probably on a separate thread. This is about the DD4WH radio.

Frank, thanks for the effort in getting this project going. It is a really interesting implementation and demonstrates the capability of the Teensy for some heavy duty DSP.

I have a question about levels. At this time am using headphones on the Audio Adaptor. The audio levels are too low. I measured the output of the SoftRock as 30 mV p-p (11 mV rms) on each of the I and Q outputs with -60 dBm input (0.22 mV rms). This was at a 4.1 MHz. This is a voltage gain of about 50. When I turn the Volume to 100, I see about 220 mV p-p at the 8-Ohm headphone. This is adequate, but for lower input signal levels it is challenging. A screen:
Is there a variable or another menu setting for software gain towards the audio output point?

Needless to say, I generally have lots of menus to explore! As an experimental SDR platform, this is great!

Also, for others, here are a couple of hints on getting started the first time. In the setup(), search for "EEPROM_LOAD();" and until an EEPROM save has been done through the menus, this needs to be commented out. Also, you need to have an SD card in the Teensy, even if you are not using the feature.

That screen is with the input at -80 dBm (not -60). Interestingly, it shows exactly -80!! The audio level on the headphone outputs was down around 20 mV p-p.
Hi Bob,

that looks/sounds great! Congratulations!

I am a bit puzzled about the gain, I will try to list my gain distribution here:

antenna -> optional attenuator (0 to -31dB) -> bandpass filters (-3dB) -> QSD & opamps (+36dB) -> Teensy audio board (up to 22.5dB of codec analog gain) --> codec ADC -> software processing -> Teensy audio board codec DAC -> Teensy audio board headphone amp

So, there is not much analog gain involved (36dB + 22.5dB + xdB headphone amp). I am not sure how much gain a Softrock has? But I remember having read reports about low gains in Softrock SDRs, maybe changing gain in the opamps after the QSD helps!? However, if I did the math correctly, voltage gain of 50 is 17dB compared to 36dB? But I am not sure whether my gain figure is voltage gain or power gain . . . (I have to learn a little more)

As you can see on the screen, the analog gain in the codec is displayed (in your picture: 22.5dB - 0db; the latter (0dB) is the attenuation by the optional digital step attenuator). So your machine seems to have the analog gain set to 22.5dB (in the software this gain is automatically controlled by some kind of improvized analog gain AGC I set up, but it can also be manually controlled by the setting "RF gain" in Menu2 !). "Volume" in Menu2 controls the digital gain of the codec before the final headphone amp. I do not remember exactly, but you should be able to control for more digital gain easily by applying a multiplication factor in the software.

Do not hesitate to ask questions on the menu entries, the software functions etc.

Also, I have included some explanations of the different software algorithms etc. in the github Wiki:


Even more explanations can be found in my second SDR team project UHSDR:


You will notice a certain similarity of many features between the two SDR projects: I have developed some of the implemented features of the UHSDR on the Teensy Convolution SDR and vice versa ;-).

Have fun!

However, if I did the math correctly, voltage gain of 50 is 17dB compared to 36dB? But I am not sure whether my gain figure is voltage gain or power gain . . . (I have to learn a little more)
voltage to dB: 20log(U) so it should be 34 dB,
power to dB: 10log(P).
Thanks Walter!

so, gains should be comparable, which makes it even more puzzling, why the output is so low.

BTW: Bob, are you using the Teensy audio board or another codec?

All the best,

Thanks Frank. I am using the stock Teensy Audio Adaptor, with Line Inputs.

The input level needs to be enough to cover the ADC noise. When I listen with no antenna connected to the SoftRock, I hear noise, but it is weak---not enough to listen to a station at that level. The S-meter shows -112 dBm. When I remove the inputs to the Codec, the S-meter shows -129 dBm and I cannot hear the noise in the headphones. When I tune in a AM broadcast station about 20 km away, using a reasonable antenna it shows -72 dBm and is fine for listening in the headphones with the Volume at 90.

So, I conclude that things are working as planned, but I need to add a gain variable just before converting from floating point to fixed. I will try that and report back.

Frank, I bet you have some voltage gain in the audio amplifier driving your speaker?

Thanks, Bob
I added a software gain factor to your existing scaling
     // scale after interpolation
      //      float32_t interpol_scale = 8.0;
      //      if(band[bands].mode == DEMOD_LSB || band[bands].mode == DEMOD_USB) interpol_scale = 16.0;
      //      if(band[bands].mode == DEMOD_USB) interpol_scale = 16.0;
      arm_scale_f32(float_buffer_L, PUA_AUDIO_GAIN*DF, float_buffer_L, BUFFER_SIZE * N_BLOCKS);
      arm_scale_f32(float_buffer_R, PUA_AUDIO_GAIN*DF, float_buffer_R, BUFFER_SIZE * N_BLOCKS);

with #define PUA_AUDIO_GAIN 4
showing reasonable results. That may not be the best value, but it can be played with. Once setup, it probably doesn't need to be changed, so the #define is simple and adequate. Onward... Bob
Hi Bob,

nice and simple workaround which does not affect processor load! (because the scaling is done anyway to account for the decimation/interpolation factor)

Concerning the audio amp:
- yes, I use a cheap PAM8403 module from ebay for the stereo speakers
- however, for the headphone output I use the original output jack of the Teensy audio board to plug in my headphones, so this does not introduce extra gain

Headphones could also be very different, I use standard headphones with 32ohms, but sometimes use studio headphones with 80ohms, that makes a large difference in perceived volume.

73 Frank
I have modified the HardRock to use the Si5351 (Adafruit board) and to have a broadband transformer input. Using x1, x3 and x5 LO multiples, I have received from 10's of kHz to 144 MHz with this. But, this happened because I had a SoftRock sitting here. Unless you just want to play with boards and solder, it is easier to just to go the Elektor route.

Frank, I looked at my headphones, and all they say on them is "Radio Shack." Nothing about models or impedance is on them. So just for fun and education, I measured their impedance:
They would seem to be what they call 40-Ohm headphones (the simple model is 35 Ohms resistive in series with 95 uH). I have no idea how efficient they are. Doesn't make any difference, anyway, as we have enough drive now.

The impedance was measured using my Audio Vector Network Analyzer which is T3.6 based. It is out for publication in QEX now, and will generally be made available as soon as they get it printed.

I am pursuing the RF filtering to make my Convolution SDR work better. I looked at various options that would (greatly) reduce the x3 RF mixing from signals above the pass band. The candidate that looked good was a 5-pole elliptic using 2 inductors and5 capacitors. Frank, is that the sort of thing you are using? I would also add something in the way of a high pass filter that would remove the AM broadcast band, for frequencies where this could be a problem. I was contemplating doing a OSH Park board that might have one or two of these filters, along with a bypass relay. Is there such a PCB around, already?

A related question. Frank, would going to a serial control of some sort for the filters have appeal? Elecraft amongst probably others uses some simple 2-wire serial bus, along with minimal PICs to control boards like the filters. Following the Elecraft lead, the board might have 2 filters with latching relays and a 12F series 8-pin PIC to latch the relays. When the relays are set, the PIC goes to sleep and the whole board draws microamps and produces no interference. But, it is a change from the parallel lines you are using. Each board could have a different address either using I2C or something in that spirit, and there would be no practical limit to the number of filters.

Or maybe there is a better way??

73, Bob W7PUA
Hi. Can someone explain in intuitive terms how a convolutional SDR works in comparison to a traditional sdr either using weaver method or sideband filter