I want to transcode a lot of audio from its source format to PCM without resampling or messing with the sample size. I figure if Windows Media Player can play the file and it doesn't use a legacy ACM codecs it must be using DirectSound to do so (this is on Windows XP and Windows Server 2k3). So is it possible to access DirectSound from C# and do so? I've tried searching the web but all the examples have been about playback which I have no interest in doing.
DirectSound is an audio playback API, you mean DirectShow. Windows Media player does use DirectShow to play audio files. In theory, all you need to do is build the same playback graph that media player uses, but replace the audio driver on the end with a .WAV writer filter.
This is somewhat easier to do in C++ code, since the DirectShow graph object is really designed to be called from C++, but with a good set of interop definitions, you can do this in C#.
There's http://directshownet.sourceforge.net/ for serious hacking with DirectShow in .NET, but that's probably overkill for your problem.
I would suggest getting a copy of GraphEdit if you don't already have one. You can use it to "prototype" direct show graphs interactively. drop a file into graphedit. then delete the filter on the end and replace it with a file writer filter.
One problem you will have is that there is no .WAV file writer filter in the default set of o DirectShow filters, you will have to find or write one.
If you just want to get the files converted, and could care less about learning how to write code using DirectShow, I would suggest that you just get a copy of Sound Forge (possibly even a demo version). It has a scripting language (C#,vb) that can be used to easily batch process most audio file formats.
Conversion to WAV can be done from the Windows command line using SoX (Sound eXchange, http://sox.sourceforge.net/). You could write a batch file or a C# application that calls SoX with the proper attributes. I'm not sure how WinAMP's feature works specifically, but it has a file writer output option built in as well. You can stream the entire playlist to wave files.
Have a look at this article on CodeProject about audio conversion here and here.
Related
I am developing application that receives media content(.mp3/.mp4/.avi) in form of bytes.
However, as WPF doesn't support playing media from stream, So I started with WMP.dll.
I am creating class library that receives media in form of bytes and media format and play media accordingly.
Referring Creating the WMP Programmatically, however, I didn't find method to pass bytes stream.
So My question is how do I play media from bytes using wmp.dll?
Edit: I am using WMP.dll using COM located at C:\WINDOWS\system32\wmp.dll
I've been through this process a long time ago ...
Basically I would advise you NOT to go down the WMP route at all. It's heavy, cumbersome and not very nice to work with. I encountered lots of issues along the way basically. Least of all it being feature rich (which it isn't).
The best solution I found and the one I'm still using now is a library called BASS from Un4SeenDevelopments.
This library is tiny < 100k and basically it's awesome. Never had a problem with it and it has it's own .NET wrapper that is a free download from the site.
The support is amazing and the compatibility via a massive selection of plugins and additional libraries is staggering.
Highly recommended for what you want to do.
"BASS is an audio library for use in software on several platforms. Its purpose is to provide developers with powerful and efficient sample, stream (MP3, MP2, MP1, OGG, WAV, AIFF, custom generated, and more via OS codecs and add-ons), MOD music (XM, IT, S3M, MOD, MTM, UMX), MO3 music (MP3/OGG compressed MODs), and recording functions. All in a compact DLL that won't bloat your distribution."
The following code works with some wav files, but with others I get, "InvalidOperationException was unhandled. Message=Sound API only supports playing PCM wave files."
var webClient = new WebClient();
webClient.DownloadFile(url, fileName);
var fileSound = new SoundPlayer(fileName);
fileSound.PlaySync();
Is there a way to programmatically check if a wav file is "bad" (not a PCM wave file) and then convert it as necessary?
What is odd is that the code works in the legacy Delphi app - all of the wav files play just fine. Here's the Delphi code:
filename := GetEnvironmentVariable('TEMP')+'\archieAndDingbat.wav';
URLDownloadToFile(nil, PChar(url), PChar(filename), 0, nil);
PlaySound(filename);
I looked at the properties of the two files in Explorer, and I see that there is, indeed, a difference. For the file that does play, its audio format is PCM; the one that won't play is CCITT u-Law.
So...I either need a way to convert from CCITT u-Law to PCM on the fly after downloading these files (they are download from an url and then played locally) OR perhaps a different way of playing these files than PlaySync() ...
Look at audiolab library from mitov. It works great
So, do you want to PLAY the file or CONVERT it ? What is the primary goal ? Do you play it as a prove you can convert it, or do you convert it because you don't know how to play not-converted file ?
http://www.catb.org/esr/faqs/smart-questions.html#goal
Your question's title claims "convert" but the body claims "Play"
This answer is about playing files.
You also may try to use FFDShow codecs directly without DirectX intermediate.
http://en.wikipedia.org/wiki/Libavcodec and http://libav.org/ and http://ffmpeg.org/ (they recently had a schism)
Googling for "FFDShow dotnet", "libav dotnet", "ffmpeg dotnet" shows a bunch of libraries to use it, such as
https://github.com/ermau/libav.net
Controlling ffdshow from .Net
Solid FFmpeg wrapper for C#/.NET
There is also BASS library. It is targeted as sound playback during gaming, so it probably has less range of formats and not much for re-coding. Still many music players are built on top of it. Some says it is the most simple API to use. So it worth considering. http://www.un4seen.com/
http://MediaInfo.sf.net is a library (native win32/win64 DLL) allowing to check most multimedia formats content.
I don't know if using tis C or C++ APis is easy from C# side.
The way to do it is to use newkie's code at: http://www.codeproject.com/Articles/175030/PlaySound-A-Better-Way-to-Play-Wav-Files-in-C?msg=4366037#xx4366037xx
In my case, at least, I had to change all of the lowercase x's to uppercase x's, though, to get it to work.
I am developing a windows phone 7 application and it does video recording. I would like to get the sound portion of the video file (MP4) and do some enhancements on the sound. I believe sound is saved as AAC frames in MP4. (Right?) How can I extract sound of a videa MP4 file?
Since this is a video file, it can be huge file. So uploading to cloud and processing there is not a good option. Since this WP7 application I cannot use unmaged dlls :( Is there a way to do in pure C#? Any open source tools/samples?
Thanks!
MP4 is a container format and realistically the sound portion isn't always AAC. It could be MP3 or any other number of different audio formats. You may be thinking of M4A, which I believe requires either AAC or ALAC.
On the subject of audio extraction, it should be possible to extract the audio from an MP4 using just managed code. You'll have to read up on the MP4 format (here, for example - this question is also worth reading) and then search through the file for the location of the audio and then either copy it to its own buffer or do your manipulations in chunks. Even then, you'll have to be able to recognize when it isn't an audio format that your app won't support.
It's possible that there already exists a .net library that can do all of this but I don't know of any. It's probably not very popular because managed code is definitely not the best angle to approach this from, but considering this is Windows Phone, it is, as you noted, your only avenue of approach.
Good luck!
I need to play the audio files like mp3 and .wav using c#. I don't want to use the com dll's and I need some functionality like to set the current time and end time of the file to play. etc.
Need some sample exmaples for the same.
To play audio using C# at some point the managed code will need to call into unmanaged APIs. NAudio provides wrappers for four different Windows audio playback APIs. WaveOut would be the most appropriate choice for you, since it is not COM based.
To decode MP3, you have a choice of using the codecs that come with Windows or trying to find a fully managed MP3 decoder. NAudio provides interop wrappers for two different Windows MP3 decoders - the Fraunhofer ACM codec that comes with Windows XP and above and the DirectX Media Object decoder that comes with Windows Vista and above. If you want a fully managed MP3 decoder, you can try NLayer which is a port I made of JavaLayer to .NET, although its public API doesn't currently allow it to slot neatly into an NAudio app.
I'm looking to develop a Silverlight application which will take a stream of data (not an audio stream as such) from a web server.
The data stream would then be manipulated to give audio of a certain format (G.711 a-Law for example) which would then be converted into PCM so that additional effects can be applied (such as boosting the volume).
I'm OK up to this point. I've got my data, converted the G.711 into PCM but my problem is being able to output this PCM audio to the sound card.
I basing a solution on some C# code intended for a .Net application but in Silverlight there is a problem with trying to take a copy of a delegate (function pointer) which will be the topic of a separate question once I've produced a simple code sample.
So, the question is... How can I output the PCM audio that I have held in a data structure (currently an array) in my Silverlight to the user? (Please don't say write the byte values to a text box)
If it were a MP3 or WMA file I would play it using a MediaElement but I don't want to have to make it into a file as this would put a crimp on applying dynamic effects to the audio.
I've seen a few posts from people saying low level audio support is poor/non-existant in Silverlight so I'm open to any suggestions/ideas people may have.
The simple answer is that there is no support for PCM playback from Silverlight in version 2. So unless you want to write a fully managed PCM to MP3 converter you are stuck. Even then I'm not sure you could get the MediaElement to play from isolated storage.
Is there any chance you could use a web service to perform the conversion?
See also this question:
Where's the sound API in Silverlight? Or, how do I write a music app to run in the browser?
Update: Silverlight 3 supports your custom audio sources. However, it won't let you intercept samples to perform effects on WMA or MP3, presumably for DRM reasons, so you would still potentially need to write your own decoder.
Short answer is use a MediaElement + a MediaStreamSource
Check out these:
http://blogs.msdn.com/gillesk/archive/2009/03/23/playing-back-wave-files-in-silverlight.aspx
http://code.msdn.microsoft.com/wavmss/Release/ProjectReleases.aspx?ReleaseId=2417
Basically, write a decoder in managed code to convert G.711 a-Law to PCM, then do whatever modifications you want to the raw values, then pass those into a MediaStreamSource.
Looks like Silverlight 3 supports direct PCM output now, or will when released. I don't see anything in the docs about the raw AV pipeline yet.
Mark Heath's answer is correct - only certain formats are supported - mp3 and certain flavours of WMA (unfortunately not WMA lossless which would be 'closer' to PCM).
To play PCM data in Silverlight, you could do the following:
* Convert the PCM into mp3 data, and store it in memory.
* Play the mp3 data using the technique presented at ManagedMediaHelpers. The idea here involves a class called Mp3MediaStreamSource (derived from System.Windows.Media.MediaStreamSource) that provides mp3 chunks to a MediaElement to play. The chunks will need to be in a stream, but of course a memory stream will do.
I initially thought you might be able to provide PCM chunks via MediaStreamSource, but this does not work. It's a real shame as it would solve your problem (and the one I was facing - making a Speex audio file player) really easily!