Audiere 库使这变得非常容易。这是一个几乎完整的 C# 程序,用于为“1”按钮生成 DTMF 音:
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();
要在 C# 中使用 Audiere,启动和运行的最简单方法是使用 Harald Fielker's C# binding(他声称它适用于 Mono 和 VS;我可以确认它适用于两个完整版本VS2005 并使用单独的 Express 2008 版本的 C# 和 VC++)。您需要下载 Win32 Audiere DLL, lib, and header(都在同一个 zip 中),并且需要使用 VC++ 和 C# 从源代码构建 C# 绑定。
使用 Audiere 的一大好处是调用是非阻塞的。您不必等到tone1a 停止演奏后才开始tone1b,这显然是演奏复杂音色的必要条件。我不知道您可以使用多少个同时输出流的硬上限,所以它可能是您的硬件/操作系统支持的任何内容。顺便说一句,Audiere 还可以播放某些音频文件(MP3、WAV、AIFF、MOD、S3M、XM、IT;Ogg Vorbis、Flac、Speex 以及外部库),而不仅仅是纯生成的音调。
一个可能的缺点是当您开始或停止单个音调时会发出轻微的“咔哒”声;如果您将一种音调添加到已经播放的音调中,则不会引起注意。我找到的最简单的解决方法是分别在打开或关闭音调时缓慢地提高或降低音调的音量。您可能需要调整斜坡速度才能让它听起来“恰到好处”。
请注意,Audiere 已获得 LGPL 许可,并且绑定没有附加任何许可。如果您想在商业产品中使用 Harald 的约束力,您必须咨询您的法律团队或尝试联系 Harald;或者您可以自己绑定并避免麻烦。
@Tom:由于 Harald 的图书馆没有附加特定的许可证,我不确定托管它会产生什么影响;但是,我相信我至少可以详细说明我的 libaudieresharpglue 项目是如何设置的。
使用 Visual C++ Express 2008,打开bindings/csharp/libaudieresharpglue/vc8.0/libaudieresharpglue.sln. VC++ 会自动将解决方案转换为 VS9 解决方案。
在另一个文件夹中,您应该有来自 Sourceforge 的 Audiere 包。在您的 VC++ 项目属性下,转到配置属性 > C/C++ > 常规,并确保在“其他包含目录”中有 path/to/audiere-1.9.4-win32/include。然后,在同一个窗口中,转到 Linker > General 并确保在“其他库目录”中有 /path/to/audiere-1.9.4-win32/lib。然后,您应该能够在您的vc8.0/Release 文件夹中构建项目(最好在发布模式下)和此输出libaudieresharpglue.dll。
接下来,打开 Visual C# Express 2008。打开 bindings\csharp\test\vc8.0\AudiereCSharpTest.sln 并让它转换解决方案。该项目应该可以正常构建,但是当您运行它时会出现错误。没关系;在您的csharp/test/vc8.0/bin/Release 文件夹中,您需要添加来自 VC++ 解决方案的 libaudieresharpglue.dll 和来自 Sourceforge 的包中的 audiere.dll。
现在,您应该能够构建和运行 AudiereCSharpTest。请注意,默认情况下,#define stream_test 在 AudiereTest.cs 的顶部没有被注释掉,这将引用不在您硬盘上的文件。您可以简单地注释掉 #define 并取消注释 noise_test 或 square_test。
应该覆盖它;如果我错过了任何细节,希望它们足够小,您可以自己解决:)