在.Net / C#播放音频

我是一位多年经验丰富的MFC程序员,近年来他一直在使用Objective C for Mac和iOS开发商业应用程序 – 我正在努力加快.Net和C#的速度(我很快就会这样做)需要将我的一个商业应用程序从Mac转换为PC)。

我现在已经完成了几本书,并且为了更熟悉.Net(和C#),我决定将我的一个非商业应用程序转换为.Net作为学习练习一切顺利(界面正常,数据结构都很好)但我需要能够播放音频。

我的Mac应用程序从一系列数学公式生成音频 – 想象一个波浪发生器 – 不完全相同但相似。 在Mac上我将音频生成为16位带符号的原始音频,使用Core Audio设置音频输出路由,然后在音频路由需要新的音频缓冲区时进行回调(因此我可以动态生成音频) 。

我需要在PC上做同样的事情。 不幸的是,我发现MSDN文档是“无法看到树木”的案例,因为有大量的文档。 我可以找到能让我加载和播放mp3 / wav等文件的类,但我需要实时生成音频。 任何人都可以指出我正确的方向找到一些东西,可以让我在播放时动态填充缓冲区吗?

谢谢

我在几个项目中使用了这个样本 ,效果很好。 它基本上是使用P / Invoke的 Windows Waveform Audio API的.Net包装器。 其他选择:

  • n音讯
  • 来自.Net框架的Sound Player类

我已经创建了一个类,可以在Stream derivate作为输入的情况下播放音频。 因此,如果您能够将声音发生器打包到Stream兼容接口,它可能适合您。

我是如何做到的 – 我使用旧的Windows多媒体API中的非托管waveOut*方法,并从那里处理回放。

其他选项 – 我知道 – 直接使用waveOut ,来自: http : //windowsmedianet.sourceforge.net/或编写自己的DirectShow源filter,但这可能太复杂了,因为它必须用c ++编写。

如果您有兴趣尝试使用我的组件,我可以免费提供给您,因为我需要进行beta测试(我只在我的几个项目中使用它)。

编辑:

由于这个问题有6个赞成,我在这里免费提供我的组件(如果你觉得有用): http : //dl.dropbox.com/u/10020780/SimpleAudioPlayer.zip

也许你可以反思:)

我使用Audiere来完成这项工作并发现它非常有效。

它确实是一个C ++库,但是有一组可用于C# 的绑定 。

有关详细信息,请参阅我问的问题 。

你应该看看FMOD ,它允许这种操作等等。 它也是跨平台,如果你也在使用mac,它可能会感兴趣。

Alvas.Audio有3个音频播放器: 播放器

  player.FileName = "123.mp3"; player.Play(); 

PlayerEx

  public static void TestPlayerEx() { PlayerEx plex = new PlayerEx(); plex.Done += new PlayerEx.DoneEventHandler(plex_Done); Mp3Reader mr = new Mp3Reader(File.OpenRead("in.mp3")); IntPtr format = mr.ReadFormat(); byte[] data = mr.ReadData(); mr.Close(); plex.OpenPlayer(format); plex.AddData(data); plex.StartPlay(); } static void plex_Done(object sender, DoneEventArgs e) { if (e.IsEndPlaying) { ((PlayerEx)sender).ClosePlayer(); } } 

和RecordPlayer

  public static void TestRecordPlayer() { RecordPlayer rp = new RecordPlayer(); rp.PropertyChanged += new PropertyChangedEventHandler(rp_PropertyChanged); rp.Open(new Mp3Reader(File.OpenRead("in.mp3"))); rp.Play(); } static void rp_PropertyChanged(object sender, PropertyChangedEventArgs e) { switch (e.PropertyName) { case RecordPlayer.StateProperty: RecordPlayer rp = ((RecordPlayer)sender); if (rp.State == DeviceState.Stopped) { rp.Close(); } break; } }