Windows Media decoder

I’ve just added a new WindowsMediaAudioFormat class, which should be able to play things like mp3s, asfs, etc on Windows… Would appreciate people’s feedback if anyone wants to try it out on a range of audio files. Thanks!

Hi Jules,

I’m still using Juce 1.53.87 and implemented the encoder there so I also use juce_DynamicLibrary.h and juce_win32_ComSmartPtr from the modules branch.
I had the problem that Wmvcore.dll couldn’t be loaded, though it works in the modules branch. With statically linking wmvcore.lib and using WMCreateSyncReader directly it seems to work.

The wmSyncReader->SetReadStreamSamples (0, false) in WMAudioReader’s constructor returns E_INVALIDARG. Should it?


No idea, must be something broken in the way you’ve brought in the DynamicLibrary class, I guess…

Hmm, looks like it needs to look up the stream number rather than assuming it’s 0… Will sort that out, thanks!

No idea, must be something broken in the way you’ve brought in the DynamicLibrary class, I guess…[/quote]
Probably, but since it works I’m quite satisfied with statically linking wmvcore.lib.

Also I immediatly tried to implement QuickTimeAudioFormat for mp3-reading on OS X, only to find out that Quicktime doesn’t like 64 bit.
Do you know any other way to use OS X for decoding mp3?

Quicktime X seems to support 64 bit, but I’m not sure whether it is available on 10.5 machines and also I’m not sure whether it can be used with Juce.


Well CoreAudio does read mp3 and I think Jules has done a reader for it FWIW

Now that you mention it, I remember. Thanks!


jules, after some first few checks i found a problem:

If you open the same file shortly 2 times one after another (directly after the first reading) the opening fails at this point.

With my code ( the acm-reader class i send to you a while ago, it works )

[code] if (wmCreateSyncReader != nullptr)
HRESULT hr = wmCreateSyncReader (nullptr, WMT_RIGHT_PLAYBACK, wmSyncReader.resetAndGetPointerAddress());
hr = wmSyncReader->OpenStream (new JuceIStream (*input));

        if (SUCCEEDED (hr))   //  <-------- false


Hmm. What was the actual HRESULT code? Anything informative?

And do you mean you’re opening the same file multiple times simultaneously, or opening/closing it multiple times?

(means: CoInitialize not called)

No. Open. Close. Reopen

“Coinitialise not called”??? In the juce demo I can click on the same song repeatedly with no problems. Are you sure you’re not just calling it on a thread where you haven’t called CoInitialise?

First time i open the file to get basics like size, samplerate, channels on the messagethread AND close it.

Then i open the file again on my background loader-thread, to to load the audio - content (which works well with the class i send you a while ago)

of cause not, i only use the audioformat class as it its (as a black box), is there a need to call CoInitialise somewhere? :roll:

Any thread that uses COM must call CoInitialise. I guess it might as well be added to that class…

[code] if (wmCreateSyncReader != nullptr)
CoInitialize (0);

        HRESULT hr = wmCreateSyncReader (nullptr, WMT_RIGHT_PLAYBACK, wmSyncReader.resetAndGetPointerAddress());[/code]

since there’s no way to guarantee it has happened otherwise.

thanks, ok now it works.

But it is not sample-accurate (even with pre-loading). My old class skips through the whole file to achieve this ( ok not very elegant/performant :slight_smile:
All other Audioformats ARE actually sample accurate (CoreAudio needs preloading,OGG doesn’t need it, didn’t try the new MP3 Audioformat yet)…

Well, that’s more of a question for MS than me, I think I’m using their objects correctly. You could always use this class to do a brute-force read from the start without seeking if you needed to.