Nov 3 2012

Research skills in programming

When I started high school, I wanted to make RPG games using a friendly tool called RPG Maker XP. That software came with some default graphics that you could use. The selection, of course, was limited and to be distinguishable from the rest of the crowd, it was worth digging the internet for graphics other people had made and shared. So I spent quite a bit of time exploring the depths of the internet to find such hidden jewels.

Every so and then, I'm reminded of how useful it is to have good research skills. This week, I wanted to do something that doesn't sound too complicated : generate the waveform of an audio file (i.e. draw the sound) in a C# Metro app. Anddddd to do that, here's the (likely incomplete) list of things I had to figure out :

1) The discretized form of a sound wave is called a PCM.
2) I need Win32/COM APIs since WinRT won't provide useful ones.
3) Need to use PInvoke to call C++ functions in a DLL which can use Win32 APIs.
4) Syntax! Need to add stuff like "CallingConvention = CallingConvention.Cdecl", "Extern 'C'", to get PInvoke to work.
5) Need to use Marshall to get arrays from C++ functions.
6) Need to use some Media Foundation libraries to decode music files.
7) Need to send the audio file to the DLL in the right format. Fortunately, one guy on the internet has the insight that IRandomAccessStream can be cast into a IUnknown which can be fed into the MF libraries.
8) Microsoft has a tutorial on decoding files with MF! How nice. Unfortunately, it takes me forever to figure out how to link libraries to the DLL. Turns out that I have to enable a compiler flag /ZW or something.
9) Enabling the compiler flag is not sufficient, the libraries of interest need to be explicitly linked to so that VS can find them.
10) Okay, most of the code in the tutorial works! It does take forever to understand what it's doing though, because pretty much every variable they use is of some type I don't know and has long names and uses even longer constants (MF_SOURCE_READERF_CURRENTMEDIATYPECHANGE much?).
11) The tutorial writes data directly into a WAV file but I want an array of values. Spend some time figuring out how to read the data from pointers down to individual bits.
12) Now, I look into how the data in tracks with multiple channels is arranged so I can split with channels.
13) Finally got my waveform!

Phew, that almost didn't have any jargon. All that just to draw a bunch of superimposed sine waves (speaking of superimposition, next step is figuring out how to do a discrete fourier transform...)

Maybe I'll write a tutorial on Codeproject on how to do this at one point.

Oh, and that procedure was actually quite short for something that involves C++.