Porting DSP code to take advantage of platform-specific ‘native’ DSP libraries is a pain. Surely there’s a better way.
Over the years, I’ve worked on DSP projects for many different platforms. As much as possible I try to find a library of essential DSP functions that are well-optimized for the target platform. For example, when I was doing a lot of development on Windows, I used Intel IPP (Integrated Performance Primitives). In recent years, I’ve been developing a lot for iOS, so I now use Apple’s Accelerate/vDSP Framework.
The advantage of using a ‘native’ DSP library is that it can be wicked fast. The FFTs in Intel IPP and in the Apple Accelerate framework are substantially faster than any of the C versions you’ll find on the web. They’re also very nicely documented. Unfortunately they’re also totally non-portable. If you write some nice code using Intel IPP, for example, porting it to some other platform where IPP is not supported will be a lot of work. Even within just the Windows world, you can’t even count on using Intel IPP alone, as it’s not supported on ARM.
A while ago, I needed to port a bunch of DSP code I’d written for iOS to make it run on a Linux server and on Android tablets. I ended up writing my own vDSP-like library – optimistically dubbed “OpenDSP” – all in standard C++, using signatures that are nearly identical to Apple’s own functions. For example, the Accelerate framework has function vDSP_vmul(), which “multiplies vector A by vector B and leaves the result in vector C”. My own implementation looks like this:
const float x1,
const float x2,
*y = *x1 * *x2;
x1 += stride1;
x2 += stride2;
y += strideResult;
I wrote my own implementations for the couple-of-dozen vDSP functions I needed, including several of the FFT ones. I put them all into a single file (OpenDSP.cpp), and in the accompanying OpenDSP.h header, I mapped the vDSP_abc function names to my DSP_abc, but only if the target was a non-Apple platform.
// If you're building for an Apple platform (Mac or iOS), then you really should use
// the Accelerate framework. It's really fast!
#include < Accelerate/Accelerate.h >
// If you're *not* building for an Apple platform, we use #defines to map vDSP function
// names to the corresponding OpenDSP function names. This allows you to write cross-platform
// signal processing code that's blazingly fast on Apple platforms, and uses Apple's vDSP
// functions, and run the same code on other platforms as well.
#define vDSP_vmul DSP_vmul
// Similarly for vDSP_vclr, vadd, vsmul, create_fftsetup, fft_zrip, etc...
This approach worked very well, in that I can now compile code using vDSP functions on any platform, not just Apple’s.
I’ve considered making my OpenDSP library public, but here’s the problem: the vDSP documentation, and therefore presumably the API itself, is covered by Apple’s copyright. So if I were to release the library publicly, Apple could plausibly come after me for copyright infringement. After all, Oracle sued Google over the Java API, and ultimately won the case.
Personally, I’d rather focus my brain power on developing interesting apps, not on learning platform-specific APIs. Ideally there would be a single public-domain API for basic DSP functions, with a generic C/C++ implementation that could be compiled for any platform. Platform owners would be free to create their own super-optimised implementations, or in the mean time developers could map them to existing platform-specific libraries (Intel IPP, Apple Accelerate/vDSP, ARM Ne10, etc.).
Does anyone know whether such an API already exists? If not, would anyone be interested in helping to define one?