【问题标题】:How to decode wav, mp3, and/or ogg in .Net/Mono?如何在 .Net/Mono 中解码 wav、mp3 和/或 ogg?
【发布时间】:2009-04-10 19:02:57
【问题描述】:

我正在寻找一种跨平台(Windows、MacOSX 和 Linux 上的 .Net 和 Mono)方法来解码 wav、mp3 或 ogg 文件,以便我可以根据需要通过 DirectSound 或 OpenAL 播放解码后的流。

可以解码 mp3 或 ogg 的解决方案就足够了 - 无需同时解码两者。如果它(或其他解决方案)也可以解码 wav,那将是理想的,但不是绝对必要的,因为我可能会将我的 wav 文件转换为 mp3 或 ogg。

只能解码wav文件的解决方案只是部分解决方案,但我会尽我所能。 ;-)

这是我已经看过的内容:

  • DirectSound 和 Alut 都支持 WAV 解码,但 Alut 已被弃用。
  • ffmpeg 几乎可以解码任何东西,但它似乎没有跨平台的通用稳定版本?
  • 我还没有尝试过 csvorbis,但它已经很老了,我不确定它目前的状态。

非常欢迎您尝试说服我上述解决方案之一实际上是最佳选择。

谢谢。

【问题讨论】:

    标签: .net mono mp3 wav oggvorbis


    【解决方案1】:

    您没有提到您正在寻找的许可类型。我使用FMOD 取得了出色的成绩,它可免费用于非商业项目。它播放多种格式,包括 ogg 和 mp3,并具有用于控制播放方式的广泛 API。它是跨平台的,如您所愿。

    FMOD 在很大程度上针对游戏;如果它已经具有出色的 3D 功能,我不会感到惊讶(尽管我不确定)。

    正如你所见,我是一个忠实的粉丝,这主要是因为第一次让一个空白的 C# 项目播放 OGG 文件非常轻松。

    【讨论】:

      【解决方案2】:

      对于 WAV 文件的简单支持,您可以在 mcs/class/System/System.Media/AudioData.cs (http://anonsvn.mono-project.com/viewvc/trunk/mcs/class/System/System.Media/) 中查看 mono 的实现。

      要解码 ogg 音频文件,您可以查看 mono 的 sn 服务器中的 csvorbis 模块: http://anonsvn.mono-project.com/viewvc/trunk/csvorbis/

      【讨论】:

        【解决方案3】:

        您应该可以使用 System.Media.SoundPlayer 直接播放 .wav 文件。不确定这是否有助于您的用例。

        【讨论】:

        • 不幸的是,我不这么认为。我需要原始波形,以便将其传递给 DirectSound/OpenAl 以执行 3D 音效。
        • 另一个问题是 SoundPlayer 不能很好地与 GC 配合使用,您需要额外的 hack (codeproject.com/KB/audio-video/soundplayerbug.aspx)
        【解决方案4】:

        我使用过 ffmpeg,到目前为止我很喜欢它。是的,跨版本几乎没有问题,但它是最有效的。

        【讨论】:

        • 跨多个平台重新分发 ffmpeg 有多容易?具体来说,是否有与 Tao.Ffmpeg 或其他一些 .Net 包装器兼容的易于分发的 Windows/Mac/Linux 二进制文件?
        • 应该相当容易..Tversity 使用它来为 xbox 转码他们的媒体
        【解决方案5】:

        为了部分回答我自己的问题,事实证明编写自己的 WAV 加载器非常容易。我使用了这篇描述wav文件格式的文章:

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

        【讨论】:

          【解决方案6】:

          一如既往,fmod 是您的答案... 请随时在http://www.fmod.org/index.php/download#FMODExProgrammersAPI上解决您的所有问题

          【讨论】:

            【解决方案7】:

            wav 文件有结构 44 字节的起始音频信号。如果读取 44-to end 文件音频数据(wav 文件)你已经在 .NET(opeanl)中播放你的音乐 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();
                }
            

            【讨论】:

              【解决方案8】:

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

              SlimDX.DirectSound - 是 C# 的代码示例。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2012-10-23
                • 1970-01-01
                • 2012-12-07
                • 2013-11-21
                • 2013-07-12
                • 2020-06-19
                • 1970-01-01
                相关资源
                最近更新 更多