Enabling NAudio for Windows 8 Store Apps–First Steps
One of my goals for NAudio 1.7 is to have a version available for Windows Store apps. Obviously there are a lot of classes in NAudio that simply won’t work with Windows Store apps, but I have been pleasantly surprised to discover that the bulk of the WASAPI and Media Foundation APIs are allowed. ACM, and all the rest of the old MME functions (waveIn.., waveOut…) are obviously not available. I’m not entirely sure what the status of DirectX Media Objects is (DMOs), but I suspect they are not available.
The first step was simply to create a Windows Store class library and see how much of the existing code I could move across. Here’s some notes on classes that I couldn’t move across
WaveFormatCustomMarshaller
- not supported because there is no support forSystem.Runtime.InteropServices.ICustomMarshaller
. This is a bit of a shame, but not a huge loss.ProgressLog
andFileAssociations
in the utils folder probably should have been kicked out of the NAudio DLL a long time ago. I’ll mark them as obsolete.- Some of the DMO interfaces were marked with
System.Security.SuppressUnmanagedCodeSecurity
. I can’t remember why I needed to do this. It may be irrelevant if Windows Store apps can’t use DMO. I’ve simply allowed the code to compile by hiding this attribute with#if !NETFX_CORE
- One really annoying thing is that the Guid constructor has subtly changed, meaning that you can’t pass in unsigned int and shorts. It means that I had to put
unchecked
casts to short or int on lots of them - One apparent oversight is that
COMException
no longer has an error code property. I guess it might be available in the exception data dictionary. It was only needed for DMO so again it may not matter - The
ApplicationException
class has gone away, so I’ve replaced all instances of it with more appropriate exception types (usuallyInvalidDataException
orArgumentException
) - The fact that there is no more
GetSafeHandle
on wait handles means that I will need to rework the WASAPI code to useCreateEventEx
. - I’ve not bothered to bring across the Cakewalk drum map or sfz support. Both can probably be obsoleted from NAudio.
- The
AcmMp3FrameDecompressor
is not supported, and I suspect that Media Foundation will become the main way to decode MP3s (with the other option being fully managed decoders for which I have a working prototype – watch this space) Encoding.ASCIIEncoding
is no longer present. Quite a bit of my code uses it, and I’ve switched to UTF8 for now even though it it is not strictly correct. I’ll probably have to make my own byte encoding utility for legacy file formats. AlsoEncoding.GetString
has lost the overload that takes one parameter.- I had some very old code still using
ArrayList
removing it had some knock-on effects throughout the SoundFont classes (which I suspect very few people actually use). WaveFileChunkReader
will have to wait untilRiffChunk
gets rewritten to not depend on mmioToFourCC- Everything in the
GUI
namespace is WindowsForms and won’t come across - The
Midi
namespace I have left out for now. The classes for the events should move across, and the file reader writer will need reworking for Windows 8 file APIs. I don’t think windows store apps have any support for actual MIDI devices unfortunately. - The old
Mixer
API is not supported at all in Win 8. The WASAPI APIs will give some control over stream volumes. - ASIO - I’m assuming ASIO is not supported at all in Windows Store apps
- The Compression folder has all the ACM stuff. None of this is supported in Windows Store apps.
- The MmeInterop folder also doesn’t contain anything that is supported in Windows Store apps.
- SampleProviders - all came across successfully. These are going to be a very important part of NAudio moving forwards
- MediaFoundation (a new namespace), has come across successfully, and should allow converting MP3, AAC, and WMA to WAV in Windows Store apps. It will also be very useful for regular Windows apps on Vista and above. Expect more features to be added in this area in the near future..
- WaveInputs - not much of this folder could be ported
WasapiCapture
- needs rework to not useThread
orWaitHandle
. Also I think the way you specify what device to use has changed in Windows Store appsWasapiLoopbackCapture
– I don’t know if Windows Store apps are going to support loopback capture, but I will try to see what is possible- I may revisit the
IWaveIn
interface, which I have never really been happy with, and come up with anIRecorder
interface in the future,to make it easier to get at the samples as they are recorded (rather than just getting a byte array)
- WaveOutputs:
WasapiOut
– should work in Windows Store, but because it usesThread
andEventWaitHandle
it needs some reworkingAsioOut, WaveOut, WaveOutEvent, DirectSoundOut
- not supported. For Windows Store apps, it will either be WasapiOut or possibly a new output device depending on what I find in the Windows RT API reference.AiffFileWriter, CueWaveFileWriter, WaveFileWriter
- all the classes that can write audio files need to be reworked as you can’t useFileStream
in Windows Store. I need to find a good approach to this that doesn’t require the Windows Store and regular .NET code to completely diverge. Suggestions welcome.
- WaveProviders – mostly came across with a few exceptions:
MixingWaveProvider32
- used unsafe code,MixingSampleProvider
should be preferred anywayWaveRecorder
- relies on WaveFileWriter which needs rework
- WaveStream -lots of classes in this folder will need reworking for
WaveFileReader AiffFileReader, AudioFileReader, CueWaveFileReader
all need to support Windows Store file APIsMp3FileReader
– may be less important now we haveMediaFoundationReader
, but it still can be useful to have a frame by frame decode, so I’ll see if I can make a newIMp3FrameDecompressor
that works in Windows Store apps.RiffChunk
- to be reworkedWaveInBuffer, WaveOutBuffer
- are no longer applicable (and should really be moved into the MmeInterop folder)Wave32To16Stream
- contains unsafe code, should be obsoleted anywayWaveMixerStream32
- contains unsafe code, also should be obsoleted
So as you can see, there is plenty of work still to be done. There are a few additional tasks once I’ve got everything I wanted moved across.
- I want to investigate all the new Media APIs (e.g transcoding) and see if NAudio can offer any value-add to using these APIs
- Make a Windows Store demo app to show off and test what can be done. Would also like to test on a Surface device if possible (not sure if I’ll run into endian issues on ARM devices – anyone know?).
- Update the nuget package to contain a Windows Store binary
Comments
I love NAudio and have used it for desktop apps before but want to do so for Windows Store apps - and this is great news.
Ananth BalasubramaniamMy current need is quite specific, how can I decode MP3s using NAudio on Windows 8? How much is missing to be able to that at this time?
Thanks!
The MediaFoundationReader class will be able to do this, it may be enough for you for now. I've not ported the WaveFileWriter yet though. Hopefully I'll get round to a demo app soon showing how to do this.
Mark HThis is fantastic Mark! Any place we can go to grab early bits if we want to test it out ourselves (I'm writing a synthesizer and want to see if I can avoid introducing a C++ component just for my WASAPI audio renderer).
Jason Olsonhi Jason, currently I'm not publishing any builds so you'd need to build from source over at CodePlex. Unfortunately I've not done WASAPI yet, although I don't think there will be too much to do given that I've already done the bulk of the interop. Annoyingly there seems to be a problem with my VS2012 install which means I can't make Windows Store apps at the moment, so there will be a bit of a delay until I work out how to fix that.
Mark HIf I remember correctly Encoding.GetEncoding("utf-7") is a way to get ASCII encoding in the Windows Runtime.
Christoph