I uploaded a new version of the code.
The "stop" method was a kludge before, and had some race conditions with the "run" method. While these never happened, they could happen if the timing was just right. Now the method is fully synchronized. All audio control, including stopping audio, is now handled in the "run" thread and the "stop" method became much simpler.
Update: 11/10/2017 - I uploaded again. I did numerous numerical optimizations to make the code more efficient. Most significantly, the rise-fall envelope samples are now cached in a list so they don't have to be recomputed for every tone pulse. I did some polishing of names, methods, and comments. The code is now a bit shorter.
Update: 11/11/2017 - I uploaded again. Now the tone generator uses raised cosine pulse-shaping.
Update: 11/15/2017 - I updated the code yet again yesterday. I realized that the dot and dash tone pulses could be cached for a specific sending speed and a specific tone frequency, and then just used over and over again, as opposed to synthesizing the tone pulses repeatedly. I also synthesized some fixed-interval silences, which depend only on the sending speed. This greatly reduces the loading on the processor, at the expense of using some memory.