Burning Desire

After actually building something for the first time in a while, I spent some time last night researching other stuff I want to write. One of the things I’m thinking about building is a WMA to Audio CD burning program. Of course, WMP9 (and many other programs) does this today. However, there’s one specific feature I need and it doesn’t appear to be one of the more standard ones.

Pretty soon, we’re going to make the Architecture Strategy Series content available for download. For each presentation, we’re going to provide the slides, the full Producer presentation, and a WMA file suitable for burring to CD. We’re even using the Windows Media Time Compression technology to get all the sessions under 80 minutes so they fit on CD. However, when you burn the file, it creates basically one long track, making it difficult to move back and forth within the presentation. I could break it into separate files per track, but that’s a pain. At least with one big file, there’s no chance of getting it out of order.

The Windows Media Format supports named markers. My burning program could build multiple tracks, based on those markers. Other audio players or CD burners would just ignore those markers. That way you get one file to download, but multiple tracks when you burn – the best of both worlds.

However, I have precious little time to dedicate to such a project, primarily as I have higher priority projects to build first. Additionally, I’d have to write it in C++ due to the lack of managed support for the various APIs and SDKs I would need. (Windows Media Format SDK to read audio file and the Image Mastering API to create the audio CD) So I gotta wonder if this capability already exists somewhere? Are there commonly-available tools that can use either named markers or a playlist file to create multiple tracks from on audio file? I’d hate to reinvent the wheel if I didn’t need to.

Pat Helland is Blogging

Pat Helland is the newest member of my team to start a blog. Back in the day, Pat was a co-founder of the Microsoft Transaction Server team. These days, he’s using the Metropolis analogy to help predict and explain the evolution of architecture. You can catch his Metropolis presentation as part of the Architecture Strategy Series). Subscribed plus I’ve added him to my teammate blog OPML file.

In addition to revealing his love of PEZ, Pat’s got a great dissertation on the multiple meanings of the term “service”. One of the issues with SOA is that not everyone agrees on what a “service” is. From what I can tell, the most common definition is “something you build with [insert your favorite vendor]‘s technology”. Having a vendor-independent description seems like a pretty good idea.

Build Slide Export

I blogged yesterday about the issues I’m having with manually repurposing content. One of the specific issues has to do with the Architecture Strategy Series. We provide that content via three channels – DVD, online seminars and (soon) download. We use Producer to create the DVD and download files. However, online seminar system doesn’t support Producer. The primary issue is that Producer uses the Save as HTML version of the PPT, but the online seminar system only supports static images. This means having to manually strip out the animations, which is a pain in the ass. Since I don’t ever want to have to do that again, I wrote a PowerPoint add-in to do it for me.

When you invoke the Build Slide Export add-in , it will step thru your presentation and screen capture each slide build to disk. It’s very similar to the built in Save as JPEG/GIF/PNG feature, except that it creates an image per build, not per slide. So those complex build slides turn out multiple image files. It’s sort that you can’t use the machine for anything else while it’s processing, but it was really easy to write the code. I tested it on a long complex PPT file with lots of builds (i.e. the one that took me hours to repurpose on Monday) and it took about 10 minutes.

I’m also providing the source to the add-in. It’s not much code: maybe 150 lines of relevant code at most. I grabbed the screen capture code from Perry Lee on C# Corner.

There were a couple of gotchas involved with this add-in. For example, the add-in project type uses version 7.0 of the office.dll that comes with VS.NET. However, Office 2003 comes with version 11.0 of that DLL and not 7.0, so the first time I went to deploy on my production machine, it didn’t work. I had to grab the right version of office.dll out of the GAC in order to reference it, so it’s included in the lib directory of the source archive (it looks like Simon did something similar with Niobe). Also, PowerPoint’s object model is a little funky. Specifically, SlideShowView.Next() has to be called differently depending on the types of builds in the slides. I handle four different scenarios in the code: no builds, only auto trigger builds, and manual trigger builds, optionally with a set of auto trigger builds before the first manual trigger build.

I’m sure there’s other enhancements that could be made – for example, the directory the images are saved isn’t selectable nor is the image format. If there’s any interest, I’ll spin up a GDN workspace.

Update: I just noticed a bug, albiet a cut-and-paste bug on my part. Turns out the screen capture code that I used is creating four image objects for each screen capture. To make matters worse, three of them are never assigned to a variable, so you can’t call Dispose() on them. So for any real-sized presenation, memory usage goes thru the roof. It’s relatively easy to fix. Take the code that looks like this:

Bitmap image = new Bitmap(
    Image.FromHbitmap(new IntPtr(hBitmap)),
    Image.FromHbitmap(new IntPtr(hBitmap)).Width,
    Image.FromHbitmap(new IntPtr(hBitmap)).Height);
image.Save(fileName,imageFormat);

And replace it with this:

Bitmap image = Image.FromHbitmap(new IntPtr(hBitmap));
image.Save(fileName,imageFormat);
image.Dispose();

With the improved code, only one bitmap per screen capture is made, and it’s explicitly disposed. That keeps memory usage under control.

Another Update: I’ve updated the binary and the code links above with the new v1.0.1 version that fixes the memory hogging problem.