I've just noticed some more "bugs" in the program. There should be a constant delay between dots and dashes in the audio output, but looking at the sample this is not the case.
I think this is because the sample sent to libao does not pause execution inside the C program.
There are two solutions to this:
1) Calculate an additional time to wait and add it to the delay sent to usleep(); e.g. usleep(delay + (<dot or dash> * 1000));
2) Have a loop that polls libao for some finished state.
Personally I like solution 1) because, it's easier to implement, requires less reading about libao and relies less on the behaviour of software outside of the morse program (e.g. if libao never returns finish, what to do? complicated). Then again solution 1) is also complicated because the time it takes to play a dot or dash is based on other things like the sample rate.
There's also something not right about the sound recorded by Audacity. This shows that at the end of the sample the output is left high when it should be left low, which looks ugly and I think makes "ticking" more likely if/when the sample is interrupted. Since the human ear (and computer speaker) function by changes in movement from down to up and up to down, this makes no difference to the sound you hear. It just looks ugly.
There's also a slight issue if the C program is forcefully halted by something like a Ctrl-C. Even though I've put code to cleanly close and shutdown the ao device, this will not get executed if the program is halted externally. The OS might be clever and do this upon detecting the executable that opened the device has been forcefully halted. It may not. I'm not sure there is a C solution to this (i.e. a function that gets executed upon a forceful halt). Maybe I could fork off a TSR process in memory that monitors the existence of the morse executable process and cleanly shuts down the ao device if it stops running. That's complicated and may introduce further problems. I've tested forcing the program to halt without closing the ao device and this doesn't effect sound output from other programs or future executions of morse. So this might just be me worrying about nothing.
If I ever go back to improve this morse program I will fix all of these things (including the tweaking).
I think this is because the sample sent to libao does not pause execution inside the C program.
There are two solutions to this:
1) Calculate an additional time to wait and add it to the delay sent to usleep(); e.g. usleep(delay + (<dot or dash> * 1000));
2) Have a loop that polls libao for some finished state.
Personally I like solution 1) because, it's easier to implement, requires less reading about libao and relies less on the behaviour of software outside of the morse program (e.g. if libao never returns finish, what to do? complicated). Then again solution 1) is also complicated because the time it takes to play a dot or dash is based on other things like the sample rate.
There's also something not right about the sound recorded by Audacity. This shows that at the end of the sample the output is left high when it should be left low, which looks ugly and I think makes "ticking" more likely if/when the sample is interrupted. Since the human ear (and computer speaker) function by changes in movement from down to up and up to down, this makes no difference to the sound you hear. It just looks ugly.
There's also a slight issue if the C program is forcefully halted by something like a Ctrl-C. Even though I've put code to cleanly close and shutdown the ao device, this will not get executed if the program is halted externally. The OS might be clever and do this upon detecting the executable that opened the device has been forcefully halted. It may not. I'm not sure there is a C solution to this (i.e. a function that gets executed upon a forceful halt). Maybe I could fork off a TSR process in memory that monitors the existence of the morse executable process and cleanly shuts down the ao device if it stops running. That's complicated and may introduce further problems. I've tested forcing the program to halt without closing the ao device and this doesn't effect sound output from other programs or future executions of morse. So this might just be me worrying about nothing.
If I ever go back to improve this morse program I will fix all of these things (including the tweaking).