DTMF Decoder | Blue Box | |
---|---|---|
This project (left) was inspired by Blue Box DTMF Decoder, an iOS app developed by Sunshine Valley Systems (right) |
- Write a DTMF tone decoder
- Get back to my roots as a Windows C Usermode programmer
- See what's changed in the last 25 years of Windows Win32 programming (since I wrote paint from Charles Petzold's book Programming Windows)
- Write a model Win32 program that does everything correctly
- Write a Fourier Transform (or something like one)
- Write a good, general purpose logger that I can use with other projects
The project's home page (hosted by GitHub) is here
The source code documentation (hosted by UH) is here
The application can be downloaded from here
-
The Application Framework: After reviewing An Overview of App Development Options I'm going with Win32. Here's a summary of my options:
- WinUI 3: This is the current recommended platform. That said, it
has a number of deficiencies:
- It's cross-platform and I don't need cross-platform support. I'm not writing this for HoloLens, Xbox, Team, blah, blah.
- It rides on top of Win32 and I'd like to stay as close to the machine as possible.
- I don't trust that it's a solid foundation i.e. Silverlight and one WinUI 3 reviewer wrote:
WinUI 3 is trumpeted as the next big thing in Windows development. ... I personally don't see this as the modern native library C++ Windows developers have been wishing for the past 12-15 years. ... The API is cumbersome at best. The generated code is not optimal. I think that time has shown that WinRT and UWP were a mistake. WinUI, instead of starting from scratch, sweeps the dirt under the carpet. I think it's another mistake and time will tell whether I'm write or wrong.
- MFC: I like the Microsoft Foundation Class, but I think it works best when you have a 100% solid understanding of C and Win32 first. Also, I'd like to write this in C and not C++
- WPF, Forms and UWP: Same argument as the two above.
- WinUI 3: This is the current recommended platform. That said, it
has a number of deficiencies:
-
The Graphics Framework: I started down the GDI path, but good `old Stack Overflow pointed me towards Direct2D.
-
Logging: I've been programming for a long time and grown accustomed to being able to write debug messages to the console. I'm going to push myself a bit:
- No console logging this time.
- Instead, I'm going to rely more on the debugger than I ever have before.
- I will use DebugOutputString
-
Performance: (Unintended, but fun) Due to the realtime nature of the application, I had to hand-code a Goertzel Algorithm (a type of Discrete Fourier Transform) in x86-64 Assembly Language.
-
Assertions: I love assertions. There's two ways to implement assert in a program like this:
For this project, I'm going with _ASSERTE. There are more options and this is an exploratory project.
Note: I compared the Debug and Release configurations of both of these techniques with Ghidra. I was pleasantly surprised to see that both completely disappear in the Release versions. In a Debug configuration, they have different implementations.
-
Cleaning up Threads: Most of the subsystems have a
cleanupSomething
function. The threads also needstopSomething
functions that trigger the threads to end (and wait until they actually do end). One dilemma I faced is: Should thecleanup
function also stop the threads? I think the answer is: No. I will have separatecleanup
andstop
functions. The reason is that the threads use each others' resources. I'm going to want to stop all of the threads first, then cleanup their resources.
This project is the product of a tremendous amount of R&D and would not be possible without the following world-class tools:
Tool | Website | Logo |
---|---|---|
Visual Studio Community Edition | https://visualstudio.microsoft.com/vs/community/ | |
Doxygen | https://doxygen.nl | |
Git | https://git-scm.com | |
GitHub | https://github.com | |
DOT | https://graphviz.org | |
DIA | http://dia-installer.de | |
Sysinternals | https://sysinternals.com/ | |
Ghidra | https://ghidra-sre.org |
- DOT
- DIA for Windows
- DebugView from SysInternals
DTMF Decoder applies the Unix philosophy of doing one thing very well: Decoding DTMF strings. Therefore, it does not provide a lot of status/popups/messages to users. However, DTMF Decoder does send quite a bit of data and status information to OutputDebugString. Therefore, using DebugView is a good way to see what's going on inside.
Here's how the whole thing fits together. Checkout Architecture