The DAB version has been ported to Linux Debian 9, 64-Bit. The result is a working solution, its properties shortly described here. The goal was to find out whether it is possible to run the DAB version of QIRX on Linux/Mono with the same Windows codebase. This could reached only partly, mainly due to the incompatiblity of the C# files automatically produced by the Windows Forms Designer. Under Mono, these showed often unacceptable behaviour in their original form.
Binary compatibility. The .NET assemblies produced with the Windows compiler run on Mono. However, the sources also have been ported to Linux, because of the testing and debugging necessities.
Development IDE. Monodevelop V7.4 (build 1035) has been used as the C# IDE. After having been updated to its latest version it run very stable. The version installable from the Debian package manager crashed reliably and should not be used. It is possible to directly import Visual Studio Solutions and Projects into Monodevelop, this being a great feature. Debugging is fairly comfortable, although everything seems to go a little slower than on Windows. However, this might have been due to using a Remote Desktop Windows-Linux environment, working very well.
Mono Upgrade. The Mono offered in the Debian package manager was outdated as well. The upgrade to the version 5.10 has been far from being a smooth experience. It took quite a while to find out how to update and export the necessary public keys for the update procedure to work.
C/C++ Libraries. The libraries necessary for the Viterbi and Reed-Solomon error correction and the MP2 audio decoding could be compiled and linked without any problems. Consisting of only a few files, they were compiled and linked "by hand". On the other hand, the libfaad library responisble for the AAC audio decoding consists of many C-files. Although this library is contained in the Debian distribution, it was built from the identical files having been used on Windows. The selected CodeLite IDE has been doing the job very well.
Not using the built-in libfaad had the reason that QIRX reliably crashed when it came to AAC decoding. An incompatibility with the libfaad used on Windows has been suspected. However, this was not the case. The culprit was an incompatibility between the Windows and the Linux (gcc) compiler with respect to the "long" data type . The former treats it - also in 64-Bit systems - as 32-Bit number, the latter as 64-Bit number. After a P/Invoke structure used by the "NeAACDecode" function had got a platform-specific change, everything worked as expected.
No spectra. The MS-Chart available in .Net Windows does not work in Mono.
Although the namespaces are all available in Monodevelop,
the functionality is not, important functions throw a NotImplementedException.
No Linux audio. NAudio does not work under Linux, as is well-known. Although a C# binding exists for the popular
PortAudio ,
it was abandoned after learning from the examples
that the blocking mode would not work. The (normally used) alternative with callback functions was not tried because the solution with P/Invoke
callbacks seemed very complicated. No C# examples were available.
As a consequence, the Audio .wav recorder is not available.
As a replacement, the solution to stream the audio via UDP broadcast was selected. It is a well-functioning and very simple work-around.
General GUI. Another source of incompatibility is the general Windows Forms behaviour. Not everything works like in the original on Windows. Resizing, Anchoring, Transparent backgrounds of bitmaps are examples of incompatiblities. These are not nice, but tolerable for the more experimental purpose followed here. However, in a production environment one had to find different solutions.
Conditional Compilation. The only parts of conditional compilation are the selections of the P/Invoke C++ DLLs (Shared Objects in Linux) in the C# code. Although Mono describes a runtime solution for the problem, this path was not followed. Instead, all P/Invoke interfaces were concentrated in one single project, and the switch between the Windows ".dll" and the Linux ".so" files is made with a conditional compile. The library names must be present at compile-time.
P/Invoke. Amazingly, with one exception the interfacing between Mono and native C code worked very smoothly.
Linux specifics must of course be observed, in particular the search algorithm for .so shared libraries.
The .so is NOT found when present in the path where the "exe" resides, in contrast to Windows.
As described above, one source of grief has been the fact that the Windows C-compiler treats the "long" data
type as 32-Bit, whereas the gcc compiler treats it as 64-Bit. Forgetting about this fact can easily result in many hours
of troubleshooting.
Runtime Platform Distinction. During runtime, platform-specific distinctions must be made in a number of code locations, often due to GUI incompatibilities. As the platform detection is very easy, this has been no principal source of trouble, it just caused a lot of testing.
The performance is disappointing. On an i7-equipped notebook (about 5 years old), the DAB services with the highest bit rates of 144kbit/s cannot be decoded within the necessary 96ms time frame, whereas the very same machine running under Windows7 has no problem decoding those services. The following pictures may give a hint for the reason. In both cases, Linux and Windows, the rtl_tcp I/Q data server was running on another machine.
The future and usability in production environments etc. of Mono, .NET Core and the like is not clear. A more or less comprehensive overview of the situation might be found on Stackoverflow.