A Public, Cross-Platform DSP API?


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:

void DSP_vmul(
	const float x1[],
	DSP_Stride stride1,
	const float x2[],
	DSP_Stride stride2,
	float y[],
	DSP_Stride strideResult,
	DSP_Length n)
{
	while (n--)
	{
		*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.

#ifdef __APPLE__

// 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 >

#else

// 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...

#endif

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?

Advertisements

About Gerry Beauregard

I'm a Singapore-based Canadian software engineer, inventor, musician, and occasional triathlete. My current work and projects mainly involve audio technology for the web and iOS. I'm the author of AudioStretch, an audio time-stretching/pitch-shifting app for musicians. Past jobs have included writing speech recognition software for Apple, creating automatic video editing software for muvee, and designing ASICs for Nortel. I hold a Bachelor of Applied Science (Electrical Engineering) from Queen's University and a Master of Arts in Electroacoustic Music from Dartmouth College.
This entry was posted in Audio, DSP, FFT, iOS, Programming. Bookmark the permalink.

5 Responses to A Public, Cross-Platform DSP API?

  1. andrewescott says:

    I haven’t used this, but I recently stumbled across Superpowered.
    http://superpowered.com/about-superpowered/
    It appears to be free as long as your app is less than 50,000 installs.

    • Thanks for the link. Looks interesting, limited to mobile platforms though. I’m really thinking of an even lower-level API though, the sorts of lower-level building blocks (e.g. vector math functions, FFTs) that developers like me or the developer of Superpowered would use to create higher level functionality (e.g. an audio time stretcher).

  2. richi says:

    Hello Gerry,
    Nice article. Why not use IPP on all platforms (windows,mac os and linux) ? It looks like it is fully crossplatform now am I mistaken?
    Best regards,

    • IPP is only available for devices using processors that run the Intel instruction set. So it’s not of much use if you’re building for devices using ARM chips (e.g. iOS devices).

      • richi says:

        Yes you are right. Sorry, I didn’t think you were talking about mobile devices as well.
        But can you please confirm that for Windows, Mac OS and Linux , IPP is fine? Its a pitty you cant buy it separately anymore … You need to buy the Intel XE Composer edition minimum …

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s