3

我有一个用户与 C# WPF 程序一起交互的设备。当用户按下设备上的按钮时,该程序必须发出哔声,持续指定的时间或只要用户按下按钮,以较短者为准。唯一可产生哔声/音调的扬声器是计算机 BIOS 扬声器;我们不能假设周围有其他发言者(实际上可以假设没有任何其他发言者)。

如何在必要的持续时间内产生连续的音调?

到目前为止,我会发出很多哔哔声,但不是连续的音调。

首先,启动一个线程:

    private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) {
        if(this.Visibility == Visibility.Visible){
            mBeepThread = new Thread(new ThreadStart(ProduceTone));
            mBeepThread.Name = "Beep Thread";
            mBeepThread.Start();
        }
    }

线程本身:

    bool mMakeTone = false;
    private void ProduceTone(){
        while(this.Visibility == Visibility.Visible){
            if(mMakeTone ){
                Console.Beep();
            }
            else{
                Thread.Sleep(10);
            }
        }
    }

然后在按钮按下期间,mMakeTone 布尔值被翻转为 true,直到设备本身指定的时间。

我怀疑这只是对上面的 Console.Beep() 行的快速更改,但我不确定它会是什么。

4

4 回答 4

10

Console.Beep 有一个重载,它需要一个频率和持续时间,如果您想在指定的持续时间内产生声音,这很有用。Console.Beep 方法或我知道的任何其他 API 不直接支持打开声音然后使用 BIOS 扬声器将其关闭的能力,而无需安装假声卡驱动程序。

一个小小的实验发现了以下几点:

  • Console.Beep() 是同步的,直到声音结束才返回。
  • 从单独的线程调用 Console.Beep() 会中断当前正在进行的任何操作。

所以......您应该能够通过创建一个新的后台线程来以您选择的频率和很长的持续时间调用 Console.Beep() 来完成您的任务。要稍后终止声音,您可以在主线程上以任意频率和非常非零的持续时间(例如 1)调用 Console.Beep() 来终止从后台线程播放的声音。您不应该让后台线程上的声音播放时间超过合理的持续时间,因为线程将一直存在,直到声音通常停止播放并且您不希望大量后台线程堆积在您身上。

private void button1_Click(object sender, EventArgs e)
{
    // Starts beep on background thread
    Thread beepThread = new Thread(new ThreadStart(PlayBeep));
    beepThread.IsBackground = true;
    beepThread.Start();
}

private void button2_Click(object sender, EventArgs e)
{
    // Terminates beep from main thread
    Console.Beep(1000, 1);
}

private void PlayBeep()
{
    // Play 1000 Hz for 5 seconds
    Console.Beep(1000, 5000);
}
于 2009-07-28T18:56:17.857 回答
4

如果你有一个连续声音的波形文件,你可以使用 SoundPlayer:

SoundPlayer player = new SoundPlayer();
player.SoundLocation = @"C:\Program Files\MyApp\sound.wav";
player.PlayLooping();
...
// Later, when you know it's time to stop the sound:
player.Stop();

我不知道你是否能听到开始和停止的声音。

如果这对您不起作用,您可能需要降低到 Win32 调用的级别。您可能想查看Multimedia AudioDirectSound

于 2009-07-28T19:24:11.653 回答
0

不幸的是,如果没有一些低级别的硬件访问,我认为您想要的东西是不可能的。

Console.Beep() 方法有两个重载,您使用的没有任何参数的重载只是发出一声短促的哔声。第二个重载需要两个整数,第一个是音调的频率,第二个是发出音调的毫秒数。

即使您绕过.NET并转到 Windows API 调用,您仍然具有基本相同的 Beep 功能(具有频率和长度参数)。

因此,在没有低得多的编码的情况下,最好的办法就是发出 500 毫秒的音调,并以一系列间断的半秒哔声串在一起结束。

bool mMakeTone = false;
private void ProduceTone(){
    while(this.Visibility == Visibility.Visible){
        if(mMakeTone ){
            Console.Beep(800, 500); // 800 Hz tone for half a second
        }
        else{
            Thread.Sleep(10);
        }
    }
}

由于当今大多数 PC 蜂鸣器缺乏音量控制,请准备好在测试期间让自己发疯......

于 2009-07-28T18:51:12.420 回答
0

您可以使用Console.Beep(frequency,duration); 此方法允许您选择哔声的频率和持续时间。频率范围为 37-32767 赫兹,持续时间以毫秒为单位,没有限制。例如:

using System;


namespace beeptesthd
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Beep(1000,60000);
        }
    }
}

在以下示例中,哔声频率为 1000 赫兹,持续时间为 60000 毫秒,即 1 分钟。

于 2014-07-09T19:15:18.767 回答