【问题标题】:Is it possible to generate complex tones in C#?是否可以在 C# 中生成复杂的音调?
【发布时间】:2010-12-11 05:12:10
【问题描述】:

我需要创建一个包含许多不同频率的音调的声音。有没有办法在 C# 中做到这一点?

到目前为止,我看到的唯一音调生成方法涉及 console.beep,它有效,但仅适用于纯音调(单频)。

【问题讨论】:

  • 供您参考,使用电脑扬声器(发出哔哔声)通常不是一个好习惯。您应该使用默认的音频输出。
  • 我实际上更喜欢使用默认音频输出。最终它将需要通过耳机。
  • 这很重要。忘记哔哔声。您想使用 DirectSound 或 WaveOut。两者都是非托管 API,因此您必须使用 PInvoke 或切换到 C++/CLI 作为您的语言。

标签: c# audio beep


【解决方案1】:

是的,这是可能的。

Here is a link 到这方面的教程。但当然这也使用Console.Beep

【讨论】:

  • 据我所见,这一次也只能生成单个音调。
【解决方案2】:

您可以随时尝试 DirectSound...

【讨论】:

  • 您是否有专门用于使用 DirectSound 生成复杂音调的链接?
  • 简而言之,您会将大量 sin() 调用的结果写入波形缓冲区,然后让它播放该缓冲区。
【解决方案3】:

MSDN 文档没有明确说明 Console.Beep 是否是异步的。如果是这样,您可能可以根据需要快速连续拨打任意数量的电话,没有人会更聪明。当然,您会希望使用需要频率和持续时间的版本。

【讨论】:

  • 我是 C# 新手 - 可以使用线程对同步调用进行分层吗?
  • 您可以使用新线程调用 Console.Beep,但您仍然无法同时播放多个声音。
【解决方案4】:

我一直在关注NAudio,希望创建一个在播放背景音轨的同时模拟反馈的程序。有一篇关于生成sine waves at specific frequencies 的博客文章,我怀疑这可以适应你正在寻找的东西。

【讨论】:

  • 这是迄今为止最有希望的,但我无法同时运行多个频率。
  • 你试过使用多线程,文档提到支持windows混合设备。
【解决方案5】:

基本上,您必须实现自己的软件合成器或找到第 3 方库。见:http://en.wikipedia.org/wiki/Demo_(computer_programming)#Music

【讨论】:

    【解决方案6】:

    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_testsquare_test

    应该覆盖它;如果我错过了任何细节,希望它们足够小,您可以自己解决:)

    【讨论】:

    • 这是一个漂亮的库,如果 NAudio 不适合我,可能会仔细看看。
    • 我在编译要编译的包装器的“libaudieresharpglue.dll”部分时遇到了很大的问题。知道我可以在哪里获取二进制文件吗?
    • 我接受了这一点,因为这显然是我需要做的。然而,尽管你的白痴证明解释,我仍然无法编译“libaudieresharpglue.dll”(在 100 个错误处停止)。当我链接时,它告诉我它无法打开输入文件 '.\Release\audiere.obj' - 是不是我缺少一些基本的东西?
    • 一般来说,在担心链接器错误之前,您需要修复编译器错误。我不知道我是否遗漏了上面的一些重要内容,所以您可能想为编译库打开一个新问题——毕竟,C# 和 C++ 标记的问题通常会很快得到回答。
    • 刚刚重新审视了这个,它的工作就像一个魅力。谢谢马克!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多