# How to decode Morse code (CW)

I have two related questions on this topic. First, about how wide should the filter be around the carrier frequency? What is used to determine this?

Second, in Python, I must use 'numtaps' when implementing a filter. What exactly are numtaps? How can I determine what to set this value to? Setting it to about the carrier frequency seems to make decoding more successful.

From another stackexchange question (https://ham.stackexchange.com/a/2018) you should use a filter approximately 4 times as wide in Hz as the expected words per minute of the morse code. That answer also includes some links and more info.

The value "numtaps" says how long to make the filter. You are using an FIR filter. The sharpness and the stop band attenuation (how much the stuff you don't want to hear gets reduced) are both dependent (amongst other things) on the value of numtaps. Higher values gets you better filter performance, but it is more work for the computer.
If you find that you need high values, then you are not using an optimal filter. There is another factor that influences the quality of the filter, and that is the "window" that is used to shape the filter. If you don't use a window, then the stop band will not be reduced far enough.

The length of the filter (numtaps) is also relevant to the lowest frequency you can work with. If you try to make a band pass filter, for example, then numtaps needs to be at least as long as the lowest frequency (in samples.) Say you are sampling at 1000Hz and want to make a band pass from 1Hz to 3Hz. You will need for numtaps to be a least 1000. If you used instead only 333 for numtaps then you would end up with a lowpass that lets through everything below 3 Hz.

You seem to be using scipy - here is the description of the FIR-filter designer "firwin." http://docs.scipy.org/doc/scipy-0.13.0/reference/generated/scipy.signal.firwin.html

Also refer to the windows page: http://docs.scipy.org/doc/scipy-0.13.0/reference/generated/scipy.signal.get_window.html#scipy.signal.get_window

I think you should try a blackmanharris or some other window that doesn't require parameters - otherwise you will have to start guessing numbers that you don't understand.

Simply using a window at all (other than boxcar) should improve things considerably so that you don't need such long filters - numtaps equivalent to the beep frequency should not be needed - you should be able to get away with well under 100 for numtaps