I’ve had this idea that a neat little WPF project would be to build a toy music visualizer, like the kind in Windows Media Player or the iTunes player. I have a bit of a background in digital signal processing, and this seemed like a fun exercise for learning WPF.
It’s conceptually simple: Get a handle to the audio stream and draw some lines. If you want well-timed transitions or modulations, compute the Fourier transform to get the instantaneous energy at a particular frequency, then use that value to drive some change in the display when it crosses some threshold.
I was hand-waving and scribbling on the white board a few weeks ago to a team member, saying, “All you have to do is get the time-series and spectrum from Windows Media Player, then use WPF databinding.” My colleague smiled knowingly. “Oh, is that all?” she said.
The devil is in the details. Over the weekend, I started looking into what’s actually required. The WMPSDK does provide everything you need to build visualizations, including a callback when audio data and the corresponding spectrum are available. But there’s no managed wrapper. So it’s back to my first love, C++.
Well, that’s not entirely true. There is a wrapper for the WMP ActiveX control, and you can host this in Windows Forms, which is neat. But none of the many COM interfaces exposes the audio stream, so neither does the managed wrapper. I considered implementing a connection point on the plug-in class, but none of the various COM interfaces exposes the loaded plug-ins.
It was fun to create a WMP plug-in project from Whidbey, which built and ran effortlessly. Nice. The two default views paint a time-series and a spectrum, which is everything I could ask for. Unfortunately, I can’t think of a good way to expose these streams to clients of any sort, never mind managed clients. Yes, I could write to the file system, or maybe I could try using a pipe. But those options are a bit…messy.
At least I was able to answer a question that has long nagged at me: How are the visualizations rendered: GDI or DirectX? The answer is…GDI. Old school. I’m not sure if WMPSDK supports arbitrary view technologies, like the .NET designer architecture does (System.ComponentModel and related namespaces). That’s probably asking too much.
The WMPSDK is a COM-based architecture, and the project templates produce ATL, which is nice. I contemplated a number of possible ATL solutions, some more hacky than others. The basic issue is exposing the audio stream and the spectrum data to interested external clients. Ideally, I’d like to use these features without a visible instance of WMP running, but that’s probably not going to happen.
Ultimately, I ended up searching for third-party, open-source solutions. But if there are any savvy WMPSDK developers who can steer me in the right direction, I’d love to hear from you!