NAudio x64 Testing Needed
After a bit of a blogging break, I think it is time to give a brief status update. I have been trying to keep up with the constant stream of support requests coming in through the NAudio forums and comments on posts here but the reality is that there has been more than I can handle so please accept my apologies if your query has gone unanswered.
I do continue to make slow progress on NAudio. Today I checked in a changeset that should hopefully give us proper x64 support. My only trouble is that I do not have an x64 machine to test on (next PC I buy will be x64 but that may not be for another year). If anyone has a 64 bit OS and is willing to help me out with a quick test then please do the following:
- Download the latest NAudio source code and load it up in Visual Studio 2008
- Go to the NAudio project settings, and on the Build tab set the Platform target to Any CPU (it is currently set to “x86”)
- Run the NAudioDemo application and attempt to play an MP3 file
- Comment here letting me know how you got on
It would be great to be able to properly support x64 as currently you are forced to set your calling application to x86 only as well.
Tried to play an mp3 in x64 mode, but I there was an exception. I wasn't sure how to figure out which parameter was invalid.Brian
NAudio.MmException: InvalidParameter calling acmStreamPrepareHeader
at NAudio.MmException.Try(MmResult result, String function) in C:\Users\Brian\Downloads\naudio-43087\NAudio\Wave\MmeInterop\MmException.cs:line 40
at NAudio.Wave.Compression.AcmStreamHeader.Prepare() in C:\Users\Brian\Downloads\naudio-43087\NAudio\Wave\Compression\AcmStreamHeader.cs:line 37
at NAudio.Wave.Compression.AcmStreamHeader.Convert(Int32 bytesToConvert, Int32& sourceBytesConverted) in C:\Users\Brian\Downloads\naudio-43087\NAudio\Wave\Compression\AcmStreamHeader.cs:line 57
at NAudio.Wave.Compression.AcmStream.Convert(Int32 bytesToConvert, Int32& sourceBytesConverted) in C:\Users\Brian\Downloads\naudio-43087\NAudio\Wave\Compression\AcmStream.cs:line 163
at NAudio.Wave.WaveFormatConversionStream.Read(Byte array, Int32 offset, Int32 count) in C:\Users\Brian\Downloads\naudio-43087\NAudio\Wave\WaveStreams\WaveFormatConversionStream.cs:line 158
at NAudio.Wave.BlockAlignReductionStream.Read(Byte buffer, Int32 offset, Int32 count) in C:\Users\Brian\Downloads\naudio-43087\NAudio\Wave\WaveStreams\BlockAlignReductionStream.cs:line 148
at NAudio.Wave.WaveChannel32.Read(Byte destBuffer, Int32 offset, Int32 numBytes) in C:\Users\Brian\Downloads\naudio-43087\NAudio\Wave\WaveStreams\WaveChannel32.cs:line 151
at NAudioDemo.MeteringStream.Read(Byte buffer, Int32 offset, Int32 count) in C:\Users\Brian\Downloads\naudio-43087\NAudioDemo\MeteringStream.cs:line 54
at NAudio.Wave.WaveOutBuffer.OnDone() in C:\Users\Brian\Downloads\naudio-43087\NAudio\Wave\WaveStreams\WaveOutBuffer.cs:line 105
at NAudio.Wave.WaveOut.Play() in C:\Users\Brian\Downloads\naudio-43087\NAudio\Wave\WaveOutputs\WaveOut.cs:line 142
at NAudioDemo.AudioPlaybackForm.buttonPlay_Click(Object sender, EventArgs e) in C:\Users\Brian\Downloads\naudio-43087\NAudioDemo\AudioPlaybackForm.cs:line 97
thanks Brian, your help is greatly appreciated. I'll revisit the acmStreamPrepareHeader function. It could possibly be due to some changes I made to ACMSTREAMHEADER as well.Mark H
I think I may have found the issue. In AcmStreamHeader.Prepare I was hard-coding the cbStruct member. It now uses Marshal.SizeOf. I've checked in a new version to CodePlex for anyone else who is willing to test for me.Mark H
Hey Mark, I got the same exception with the new version, but I was able to get it to work. Marshal.SizeOf returned 104 for your class, but that wasn't big enough. I got it to work with a class that is 128 bytes.Brian
The acmStreamPrepareHeader method fills the reserved array (at an offset of 88 bytes) with data and seems to ignore the 24 bytes before it.
Here is a solution that works for both x86 and x64 modes.
Explicitly set the size to 128:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Size = 128)]
and simply delete the following field, because user code isn't supposed to touch it and it isn't needed:
public int reserved;
Is there anything else that needs testing in x64 mode?
thanks Brian. With hindsight, I think that was the reason why I originally had this structure with ten int members rather than an array and hardcoded its size. I've checked in your suggested code.Mark H
Playing an MP3 gives a fairly good workout to WaveOut and some of the ACM stuff. It is probably also worth giving a quick run through the recording form, and also checking that all the playback modes work (WaveOut both modes, DirectSound and WASAPI). Using the ACM test form (even just to see the contents of the listbox) will also test out a few more function signatures.
There is also some basic mixer interop and MIDI interop in NAudio. If you have any MIDI hardware you can use the NAudioDemo project to give it a go. Also you can run unit tests to give the mixer interop a runthrough. Some of the tests intermittently fail on x86 simply due to failing to set control values to exactly what we want, but the main thing is that the mixer functions can be called in x64 without crashing.
thanks again Brian for doing this, it is extremely helpful.
I have a 64bit OS, Windows 7 Pro, and I am hoping to get down a dirty with it shortly.The Reverand
I am using Beta 2 of Visual C# Express 2010 and when I compiled the latest source I was "warned" that there was a depreciated method call.
The call is in DirectSoundOut.Stop(), you use a Monitor.TryEnter() overload that doesn't use a lockTaken bool parameter.
Here is the new code for Stop():
public void Stop()
// Try and tidy up nicely
bool lockTaken = false;
Monitor.TryEnter(m_LockObject, 50, ref lockTaken);
playbackState = PlaybackState.Stopped;
// No joy - abort the thread!
if (notifyThread != null)
notifyThread = null;
thanks The Reverand. I'm guessing that must be some kind of .NET 4 thing, because that overload of Monitor.TryEnter isn't available on my system.Mark H
Must be. I'd never seen it before.The Reverand
Working perfectly for me with my 64-bit app while I had the same "InvalidParameter calling acmStreamPrepareHeaderAlienImation
With 46831 I can play MP3 if both the demo and NAudio set to x86. When both set to ANyCPU (VS2008, XP64):Bob Denny
NAudio.MmException was unhandled
Message="NoDriver calling acmFormatSuggest"
at NAudio.MmException.Try(MmResult result, String function) in D:\dev\DotNet Audio\naudio-46381\NAudio\Wave\MmeInterop\MmException.cs:line 40
at NAudio.Wave.Compression.AcmStream.SuggestPcmFormat(WaveFormat compressedFormat) in D:\dev\DotNet Audio\naudio-46381\NAudio\Wave\Compression\AcmStream.cs:line 111
at NAudio.Wave.WaveFormatConversionStream.CreatePcmStream(WaveStream sourceStream) in D:\dev\DotNet Audio\naudio-46381\NAudio\Wave\WaveStreams\WaveFormatConversionStream.cs:line 29
at NAudioDemo.AudioPlaybackForm.CreateInputStream(String fileName) in D:\dev\DotNet Audio\naudio-46381\NAudioDemo\AudioPlaybackForm.cs:line 122
at NAudioDemo.AudioPlaybackForm.buttonPlay_Click(Object sender, EventArgs e) in D:\dev\DotNet Audio\naudio-46381\NAudioDemo\AudioPlaybackForm.cs:line 78
at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
thanks Bob,Mark H
that's annoying, will have to check that the MP3 wave format translates properly to 64 bit.
Bob, is the ACM Format Conversion option on the NAudio Demo project able to show the ACM codecs installed on your PC. If so, is there an MP3 one one there, and are you able to display selected format info?Mark H
I changed the target-compile to x86 and everything works like a charm.Shimmy