Audio Framework for Mac and Windows - c#

I realize I asked a question similar to this before, but the planning on what I want to do has come some way, and the parameters have become a bit different.
Basically, I'm looking for the best option for decoding and outputting audio on both Mac and Windows. Ideally, there will be no differences in needed code between the two platforms. I just want to be able to pass it a file path or HTTP URL and have it play the audio with the ability to pause, seek, etc.
It must be able to decode MP3 and AAC out of the box with no dependencies on the OS (like Phonon for Qt which is entirely dependent on the OS). Any other codecs beyond that would be a very nice bonus.
I've looked at things like libavcodec, which supposedly can decode about anything, but haven't been able to figure out how to get it to work. So far it seems that libraries I've seen are also ready for Mac and Linux or Windows and Linux but not Mac and Windows.
It does not need to be open source, but if it is needs to be usable in commercial products. I'm OK with licensing something as long as it's not too expensive and easy to use.
Finally, while C/C++ would be preferred, if there's something that would work with C#/Mono, that's OK too.
Any suggestions on something that would work for this?

I've created a C++ audio library for Mac and Windows named "Crosstalk".
Crosstalk is a C++ audio engine that allows you to create and route audio systems in real-time. The engine takes care of all the audio routing and gives you a simple platform for creating system components (E.g. "Mp3 Decoder" component connected to a "Low-Pass Filter" connected to an "Audio Device" and "File Recorder").
It's very easy to use. Here's an example of how to play an mp3 file (These components are provided with the engine):
XtSystem system;
XtMp3Decoder mp3Decoder;
XtAudioDevice audioDevice;
long md = system.addComponent(&mp3Decoder);
long ad = system.addComponent(&audioDevice);
system.connOutToIn(md,0,ad,0);
system.connOutToIn(md,1,ad,1);
mp3Decoder.loadFile("../05 Tchaikovski-Swan Lake-Scene.mp3");
mp3Decoder.play();
Included with Crosstalk is example Xcode and Visual Studio projects.
You can download Crosstalk and check out the API documentation and licensing details here: http://www.adaptaudio.com/Crosstalk
EDIT (01-12-2012):
Crosstalk has been replaced by an open-source project called "DSPatch". DSPatch is essentially an upgraded version of the routing engine behind Crosstalk that is no longer limited to only audio processing. DSPatch allows you to create and route almost any type of process chain imaginable, and free for personal AND proprietary use :)

decode MP3 and AAC out of the box
I'm not aware of any audio library that does this so easilly. The problem is the license issue regarding MP3 decoding.
I discuss some options on this post, and they are good for Windows/Mac OS X, but I'm not sure if they have C# bindings.
If you are willing to write the bindings yourself, you might be interested at libaudiodecoder:
A C++ cross platform MP3/AAC/WMA/WAV decoder.
It comes with an example that shows how to play a song on Windows/Mac through PortAudio.

Related

Rerouting applications' audio to another audio device

I have Virtual Audio Cables installed, but for some applications it's hard to have them permamnently rerouted through a different audio device, seen as they're missing a specific option to change this (Spotify or your web browser).
I'm wondering if it's possible to reroute another application's output audio-data to a different audio device (From my SPDIF to Realtek Digital Output, for example.), much like CheVolume can do.
Does anyone know if this is at all possible in C# (WinForms?)? And where would I start?
Check this Library by Mark Heath, it is called naudio.
Here is the link : https://naudio.codeplex.com/
You can use this library in C# .net winform based applications.
Its Free.

What APIs do I need to look at to code my own windows drive letter

I was thinking of messing around with my own file system code, as a learning exercise. To start with this could be a RAM drive, or just mounted within a file on another drive. Questions:
What windows APIs would I need to program to implement my own drive letter (eg an M: with my system)
Where is the documentation for these APIs?
Can you implement them using C#?
NB:
I know there are other Ram drive implementations out there - I don't need a list of them.
I've tried googling, but found it very hard to find the right search terms.
I'm not fussy for now about which version of windows, any version is fine as I'm developing using Windows 7, but I hope that version for earlier Windows will still work
Take a look at the IFS (Installable Filesystem) Kit.
You're talking about writing a filesystem driver. The basic model is that your code gets loaded into the NT kernel and processes IRPs.
No, you can't do it in C#.
You need to look at the Windows DDK - now called "WDK" apparently. The WDK includes the Installable File Systems (IFS) kit. See here:
Installable File Systems (IFS) kit
Device drivers on Windows are written in C/C++. As far as I know there is no way to implement a file system driver in .NET. There is no CLR in kernel space.
EDIT: asveikau beat me to it...
From this answer to a similar question: how to map a software as a Drive?
Have a look at Dokan. It looks like a nice scriptable wrapper to low-level filesystem drivers. Like FUSE on Linux.
The docs page mention that you can use it to write filesystem code in C#, VB, C++ and even Ruby! Since it exposes itself as a .Net library I'm guessing you can do it in any language running on the CLR as well such as IronPython or F#.
Depending on what you need (implement a file system or just a virtual disk with existing file system) you can use one of our virtual storage products: Callback File System and CallbackDisk respectively.
The difference is that CallbackDisk emulates a disk device (so you can mount, for example, ISO image there), and Callback File System lets you build your own file system (eg. distributed, or just remotely stored)
.NET APIs are available in both products.

Which audio library to use?

I want to build a .Net application for processing audio, and distribute it using ClickOnce deployment. I need access to a raw audio pipeline. Which audio library should I be using? I've heard the managed libraries for DirectSound are a dead end. I need as little as possible to be installed on the client's machine. Anything outside of the ClickOnce process isn't going to work.
NAudio might be a possibility, but isn't there potentially a separate driver install? There's also SlimDX.
It's a shame -- the managed DirectX libraries seem to work nicely and from what I've read, DirectX can be included in the ClickOnce install.
BASS : http://www.un4seen.com/
with Bass.Net is quite simple to use.
Although not free, Alvas.Audio may be worth looking at.
OpenTK has an OpenAL implementation, but I'm not sure how it behaves with ClickOnce and it lacks reading/writing complex audio file formats(such as vorbis).

Is it possible to generate complex tones in C#?

I need to create a sound containing tones of many different frequencies. Is there any way to do this in C#?
The only tone generating methods I've seen so far involve console.beep, which works, but only for pure tones (single frequencies).
The Audiere library makes this extremely easy to do. Here's a nearly complete C# program to generate the DTMF tone for the "1" button:
AudioDevice device = new AudioDevice();
OutputStream tone1a = device.CreateTone(697); // part A of DTMF for "1" button
OutputStream tone1b = device.CreateTone(1209); // part B
tone1a.Volume = 0.25f;
tone1b.Volume = 0.25f;
tone1a.Play();
tone1b.Play();
Thread.Sleep(2000);
// when tone1a stops, you can easily tell that the tone was indeed DTMF
tone1a.Stop();
To use Audiere in C#, the easiest way to get up and running is to use Harald Fielker's C# binding (which he claims works on Mono and VS; I can confirm it works in the both full version of VS2005 and using the separate Express 2008 versions of C# and VC++). You'll need to download the Win32 Audiere DLL, lib, and header (which are all in the same zip) and you'll need to build the C# binding from source using both VC++ and C#.
One of the nice benefits of using Audiere is that the calls are non-blocking. You don't have to wait for tone1a to stop playing before you start tone1b, which is clearly a necessity for playing complex tones. I am not aware of any hard upper limits on how many simultaneous output streams you can use, so it's probably whatever your hardware/OS supports. By the way, Audiere can also play certain audio files (MP3, WAV, AIFF, MOD, S3M, XM, IT by itself; Ogg Vorbis, Flac, Speex with external libraries), not just pure generated tones.
One possible downside is that there is a slightly audible "click" as you start or stop an individual tone; it's not noticeable if you add one tone to an already playing tone. The easiest workaround I've found for that is to slowly ramp the tone's volume up or down when you're turning the tone on or off, respectively. You might have to play around with the ramp speed to get it to sound "just right".
Note that Audiere is LGPL-licensed, and the binding has no license attached to it. You'll have to consult your legal team or try to get a hold of Harald if you want to use his binding in a commercial product; or you could just make your own binding and avoid the hassle.
#Tom: Since there is no specific license attached to Harald's library, I'm not sure what implications would come of hosting it; however, I believe I can at least give you fine detail on exactly how my libaudieresharpglue project is set up.
Using Visual C++ Express 2008, open up bindings/csharp/libaudieresharpglue/vc8.0/libaudieresharpglue.sln. VC++ will automatically convert the solution to a VS9 solution.
In another folder, you should have the Audiere package from Sourceforge. Under your VC++ project properties, go to Configuration Properties > C/C++ > General, and make sure you have path/to/audiere-1.9.4-win32/include in your "Additional Include Directories." Then, in that same window, go to Linker > General and make sure you have /path/to/audiere-1.9.4-win32/lib in your "Additional Library Directories." Then, you should be able to build the project (preferably in Release mode) and this output libaudieresharpglue.dll in your vc8.0/Release folder.
Next, open up Visual C# Express 2008. Open up bindings\csharp\test\vc8.0\AudiereCSharpTest.sln and let it convert the solution. The project should build fine, but then you will get an error when you run it. That's fine; in your csharp/test/vc8.0/bin/Release folder, you need to add both libaudieresharpglue.dll from the VC++ solution and audiere.dll from the package from Sourceforge.
Now, you should be able to build and run AudiereCSharpTest. Note that by default, #define stream_test is not commented out at the top of AudiereTest.cs, and that will reference a file that is not on your hard drive. You can simply comment out that #define and uncomment noise_test or square_test.
That should cover it; if I missed any details, hopefully they are small enough to get by on your own :)
You can always try DirectSound...
I have been looking at NAudio with the view to create a program that emulates feedback whilst playing a backing track. There is a blog post about generating sine waves at specific frequencies, I suspect that this could be adapted to do what you are looking for.
Yes it is possible.
Here is a link to a tutorial on this. but of course this also uses Console.Beep
The MSDN documentation doesn't make it clear if Console.Beep is asynchronous or not. If it is, you can probably fire off as many calls as you need in quick succession and nobody will be the wiser. You'd want to use the version that takes a frequency and a duration, of course.
Essentially, you have to implement your own software synthesizer or find a 3rd party library. See: http://en.wikipedia.org/wiki/Demo_(computer_programming)#Music

How can I play compressed sound files in C# in a portable way?

Is there a portable, not patent-restricted way to play compressed sound files in C# / .Net? I want to play short "jingle" sounds on various events occuring in the program.
System.Media.SoundPlayer can handle only WAV, but those are typically to big to embed in a downloadable apllication. MP3 is protected with patents, so even if there was a fully managed decoder/player it wouldn't be free to redistribute. The best format available would seem to be OGG Vorbis, but I had no luck getting any C# Vorbis libraries to work (I managed to extract a raw PCM with csvorbis but I don't know how to play it afterwards).
I neither want to distribute any binaries with my application nor depend on P/Invoke, as the project should run at least on Windows and Linux. I'm fine with bundling .Net assemblies as long as they are license-compatible with GPL.
[this question is a follow up to a mailing list discussion on mono-dev mailing list a year ago]
I finally revisited this topic, and, using help from BrokenGlass on writing WAVE header, updated csvorbis. I've added an OggDecodeStream that can be passed to System.Media.SoundPlayer to simply play any (compatible) Ogg Vorbis stream. Example usage:
using (var file = new FileStream(oggFilename, FileMode.Open, FileAccess.Read))
{
var player = new SoundPlayer(new OggDecodeStream(file));
player.PlaySync();
}
'Compatible' in this case means 'it worked when I tried it out'. The decoder is fully managed, works fine on Microsoft .Net - at the moment, there seems to be a regression in Mono's SoundPlayer that causes distortion.
Outdated:
System.Diagnostics.Process.Start("fullPath.mp3");
I am surprised but the method Dinah mentioned actually works. However, I was thinking about playing short "jingle" sounds on various events occurring in the program, I don't want to launch user's media player each time I need to do a 'ping!' sound.
As for the code project link - this is unfortunately only a P/Invoke wrapper.
I neither want to distribute any
binaries with my application nor
depend on P/Invoke, as the project
should run at least on Windows and
Linux. I'm fine with bundling .Net
assemblies as long as they are
license-compatible with GPL.
Unfortunatly its going to be impossible to avoid distributing binaries, or avoid P/Invoke. The .net class libraries use P/Invoke underneath anyway, the managed code has to communicate with the unmanage operating system API at some point, in order to do anything.
Converting the OGG file to PCM should be possible in Managed code, but because there is no Native Support for Audio in .net, you really have 3 options:
Call an external program to play the sound (as suggested earlier)
P/Invoke a C module to play the sound
P/Invoke the OS APIs to play the sound.
(4.) If you're only running this code on windows you could probably just use DirectShow.
P/Invoke can be used in a cross platform way
http://www.mono-project.com/Interop_with_Native_Libraries#Library_Names
Once you have your PCM data (using a OGG C Lib or Managed Code, something like this http://www.robburke.net/mle/mp3sharp/ of course there are licencing issues with MP3), you will need a way to play it, unfortunatly .net does not provide any direct assess to your sound card or methods to play streaming audio. You could convert the ogg files to PCM at startup, and then use System.Media.SoundPlayer, to play the wav files generated. The current method Microsoft suggests uses P/Invoke to access Sound playing API in the OS http://msdn.microsoft.com/en-us/library/ms229685.aspx
A cross platform API to play PCM sound is OpenAL and you should be able to play (PCM) sound using the c# bindings for OpenAL at www.taoframework.com, you will unfortunatly need to copy a number of DLL and .so files with your application in order for it to work when distributed, but this is, as i've explained earlier unavoidable.
Calling something which is located in 'System.Diagnostics' to play a sound looks like a pretty bad idea to me. Here is what that function is meant for:
//
// Summary:
// Starts a process resource by specifying the name of a document or application
// file and associates the resource with a new System.Diagnostics.Process component.
//
// Parameters:
// fileName:
// The name of a document or application file to run in the process.
//
// Returns:
// A new System.Diagnostics.Process component that is associated with the process
// resource, or null, if no process resource is started (for example, if an
// existing process is reused).
//
// Exceptions:
// System.ComponentModel.Win32Exception:
// There was an error in opening the associated file.
//
// System.ObjectDisposedException:
// The process object has already been disposed.
//
// System.IO.FileNotFoundException:
// The PATH environment variable has a string containing quotes.
i think you should have a look a fmod, which is the mother of all audio api
please feel free to dream about http://www.fmod.org/index.php/download#FMODExProgrammersAPI
The XNA Audio APIs work well in .net/c# applications, and work beautifully for this application. Event-based triggering, along with concurent playback of multiple sounds. Exactly what you want. Oh, and compression as well.
Well, it depends on a patent-related laws in a given country, but there is no way to write a mp3 decoder without violating patents, as far as i know. I think the best cross-platform, open source solution for your problem is GStreamer. It has c# bindings, which evolve rapidly. Using and building GStreamer on Windows is not an easy task however. Here is a good starting point. Banshee project uses this approach, but it is not really usable on windows yet (however, there are some almost-working nightly builds). FMOD is also a good alternative. Unfortunately, it is not open source and i find that its API is somehow C-styled.
There is a pure C# vorbis decoder available that is open source:
http://anonsvn.mono-project.com/viewvc/trunk/csvorbis/
Not sure if this is still relevant. Simplest solution would be to use NAudio, which is a managed open source audio API written in C#. Another thing to try would be utilizing ffmpeg, and creating a process to ffplay.exe (the right binaries are under shared builds).
There is no way for you to do this without using something else for your play handling.
Using the System.Diagnostic will launch an external software and I doubt you want that, right? You just want X sound file to play in the background when Y happens in your program, right?
Voted up because it looks like an interesting question. :D

Categories