5

I am looking for a cross-platform (.Net and Mono on Windows, MacOSX, and Linux) way to decode wav, mp3, or ogg files such that I can then play the decoded streams through DirectSound or OpenAL as desired.

A solution that can decode either mp3 or ogg would be sufficient -- decoding both is not necessary. If it (or another solution) can decode wav as well, that would be ideal, but isn't strictly necessary since I could potentially convert my wav files to mp3 or ogg.

A solution that can only decode wav files is only a partial solution, but I'll take what I can get. ;-)

Here's what I've already looked at:

  • DirectSound and Alut both support WAV decoding, but Alut has been deprecated.
  • ffmpeg will decode just about anything, but it doesn't seem to have a common stable release across platforms?
  • I have not tried csvorbis yet, but it's very old and I'm not sure what its current status is.

You are more than welcome to try to pursuade me that one of these above solutions is actually the best option.

Thanks.

Walt D
  • 4,491
  • 6
  • 33
  • 43

8 Answers8

4

You haven't mentioned the sort of licensing you're looking for. I've had excellent results with FMOD, which is available for free for non-commercial projects. It plays a diverse variety of formats, including ogg and mp3, and has an extensive API for controlling how to play them. It's cross-platform, like you require.

FMOD targets games to a large extent; I wouldn't be surprised if it already comes with excellent 3D features (though I don't know for sure).

As you can tell I'm quite a fan, which is mostly because it was surprisingly painless to get a blank C# project to play an OGG file for the first time.

Roman Starkov
  • 59,298
  • 38
  • 251
  • 324
1

You should be able to play back .wav files directly with System.Media.SoundPlayer. Not sure if that helps your use case.

jpobst
  • 9,982
  • 1
  • 29
  • 33
  • Unfortunately I don't think so. I need the raw waveform so that I can pass it to DirectSound/OpenAl to perform 3D sound effects. – Walt D Apr 10 '09 at 19:26
  • Another problem with it is that SoundPlayer doesn't play nice with GC and you need extra hacks (http://www.codeproject.com/KB/audio-video/soundplayerbug.aspx) – Roman Starkov Oct 18 '09 at 22:27
1

For simple support for WAV files you can look at mono's implementation in mcs/class/System/System.Media/AudioData.cs (http://anonsvn.mono-project.com/viewvc/trunk/mcs/class/System/System.Media/).

For decoding ogg audio files you can look at the csvorbis module in mono's sn server: http://anonsvn.mono-project.com/viewvc/trunk/csvorbis/

lupus
  • 3,963
  • 1
  • 18
  • 13
0

as always, fmod is your answer... please feel free to get solution to all your problems on http://www.fmod.org/index.php/download#FMODExProgrammersAPI

user217299
  • 110
  • 1
  • 4
0

wav file have structure 44 byte start audio signal. if read 44-to end file audio data(wav file)your have playing in .NET(opeanl) your music https://dpaste.com/8VNKMAUU5

public static void playwav()
    {
        Console.WriteLine("Hello World!");

        OpenTK.Audio.OpenAL.ALDevice device = OpenTK.Audio.OpenAL.ALDevice.Null;
        OpenTK.Audio.OpenAL.ALContext ctx = OpenTK.Audio.OpenAL.ALContext.Null;

        string defname = OpenTK.Audio.OpenAL.ALC.GetString(device, OpenTK.Audio.OpenAL.AlcGetString.DefaultDeviceSpecifier);
        Console.WriteLine(defname);
        device = OpenTK.Audio.OpenAL.ALC.OpenDevice(defname);

        if (!OpenTK.Audio.OpenAL.ALC.IsExtensionPresent(device, "ALC_EXT_EFX"))
            return;
        int[] atrributes = { 0, 0, 0, 0 };
        int[] iSends = { 0 };
        atrributes[0] = ((int)OpenTK.Audio.OpenAL.AlcContextAttributes.EfxMaxAuxiliarySends);
        atrributes[1] = 4;

        Console.WriteLine("EFX Extension found!\n");

        ctx = OpenTK.Audio.OpenAL.ALC.CreateContext(device, atrributes);

        OpenTK.Audio.OpenAL.ALC.MakeContextCurrent(ctx);
        OpenTK.Audio.OpenAL.ALC.ProcessContext(ctx);

        OpenTK.Audio.OpenAL.ALC.GetInteger(device, OpenTK.Audio.OpenAL.AlcGetInteger.EfxMaxAuxiliarySends, 1, iSends);


        //OpenTK.Audio.OpenAL.AL.GetProcAddress("LPALGENEFFECTS"); 

        int buffer;

        string str = @"C:\WorkC#\ConsoleApp3\ConsoleApp3\20211222-204048_.wav";
        //Microsoft.Win32.SafeHandles.SafeFileHandle safeFileHandle = new Microsoft.Win32.SafeHandles.SafeFileHandle("20211222-204048_.wav",true);
        FileStream fileStream = File.OpenRead(str);

        byte[] bufdata = new byte[fileStream.Length];
        //bufdata[0] = 0;
        byte[] RIFF = new byte[4];
        byte[] sizeRid = new byte[4];
        byte[] WAVE = new byte[4];
        byte[] FMT = new byte[4];
        fileStream.Read(RIFF, 0, 4);
        fileStream.Read(sizeRid, 0, 4);
        fileStream.Read(WAVE, 0, 4);
        fileStream.Read(FMT, 0, 4);

        fileStream.Read(bufdata, 44, (int)(fileStream.Length - 45));

        OpenTK.Audio.OpenAL.AL.GenBuffer(out buffer);

        UInt16 value = BitConverter.ToUInt16(RIFF, 0);

        Console.WriteLine(((char)value));
        Console.WriteLine(sizeRid.Length);
        Console.WriteLine(WAVE.Length);
        OpenTK.Audio.OpenAL.AL.BufferData(buffer, OpenTK.Audio.OpenAL.ALFormat.Stereo16, bufdata, 44100);

        Console.WriteLine((bufdata));

        int src;
        OpenTK.Audio.OpenAL.AL.GenSource(out src);
        OpenTK.Audio.OpenAL.AL.Source(src, OpenTK.Audio.OpenAL.ALSourcei.Buffer, buffer);
        OpenTK.Audio.OpenAL.AL.SourcePlay(src);
        int state = 4114;

        while (state == (int)OpenTK.Audio.OpenAL.ALSourceState.Playing)
        {
            OpenTK.Audio.OpenAL.AL.GetSource(src, OpenTK.Audio.OpenAL.ALGetSourcei.SourceState, out state);
            Console.Write(state + "\r");
            //int state = (int)OpenTK.Audio.OpenAL.ALSourceState.Playing;
            //OpenTK.Audio.OpenAL.AL.SourcePlay(src);
        }


        OpenTK.Audio.OpenAL.ALC.DestroyContext(ctx);
        OpenTK.Audio.OpenAL.ALC.CloseDevice(device);



        //OpenTK.Audio.OpenAL.ALC.GetContextsDevice();
    }
0

I worked with ffmpeg and so far I like it. Yea there are few issues across releases, but it is the most efficient of all.

Srikar Doddi
  • 15,499
  • 15
  • 65
  • 106
  • How easy is it to redistribute ffmpeg across multiple platforms? Specifically, are there easily-distributed Windows/Mac/Linux binaries that are compatible with Tao.Ffmpeg or some other .Net wrapper? – Walt D Apr 10 '09 at 19:22
  • should be fairly easy..Tversity uses it for all transcoding their media for xbox – Srikar Doddi Apr 10 '09 at 19:31
0

To partially answer my own question, it turns out that it's pretty easy to write your own WAV loader. I used this article that describes the wav file format:

http://www.sonicspot.com/guide/wavefiles.html

Walt D
  • 4,491
  • 6
  • 33
  • 43
-1

https://sites.google.com/site/cobnut3d/

SlimDX.DirectSound - is an example of code to C #.

Easy3D_47
  • 1
  • 1