Windows Media decoder


#1

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!


#2

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?

Chris


#3

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!


#4

[quote=“jules”]
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.

Chris


#5

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


#6

Now that you mention it, I remember. Thanks!

Chris


#7

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

[/code]


#8

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?


#9

[attachment=0]winme.png[/attachment]
(means: CoInitialize not called)

No. Open. Close. Reopen


#10

“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?


#11

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:


#12

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.


#13

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)…


#14

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.