C#:产生连续的音调,直到中断

C#:产生连续的音调,直到中断,c#,beep,C#,Beep,我有一个设备,用户可以在C#WPF程序旁边与之交互。当用户按下设备上的按钮时,该程序必须发出嘟嘟声,持续指定的时间或只要用户按下按钮,以较短者为准。唯一可以产生蜂鸣音/音调的扬声器是计算机BIOS扬声器;我们不能假设周围有其他演讲者(事实上,假设不会有其他演讲者是安全的) 如何在必要的持续时间内产生连续的音调 到目前为止,我听到的是很多嘟嘟声,但不是连续的音调 首先,启动一个线程: private void UserControl_IsVisibleChanged(object send

我有一个设备,用户可以在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);
            }
        }
    }
然后,在按下按钮的持续时间内,直到设备本身指定的时间,布尔值翻转为true


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

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

Console.Beep()方法有两个重载,您正在使用的一个重载没有任何参数,只会发出一声短嘟嘟声。第二个重载使用两个整数,第一个表示音调的频率,第二个表示发出音调的毫秒数

即使您绕过并转到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寻呼机都没有音量控制…

控制台有过载。寻呼机需要一定的频率和持续时间,如果您想在指定的持续时间内发出声音,这很有用。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);
}

如果您有连续声音的波形文件,可以使用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调用。您可能需要查看或。

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

using System;


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

在下面的示例中,嘟嘟声频率为1000赫兹,持续时间为60000毫秒,换言之为1分钟。

第一次检查时,这似乎是一个更好的解决方案。然而,在我的测试中,从.net发出更长的控制台蜂鸣声似乎会导致严重的问题。我有我的两个开发机器都在我的蓝屏上试验5秒和更长的蜂鸣声。我不记得我的任何机器在这之前最后一次出现蓝屏…在这种情况下,替代方案似乎是安装一个假的声卡驱动程序或在后台线程中循环嘟嘟声,使用的持续时间小于导致BSOD的持续时间,并有一种机制从循环中脱落。对于我来说,没有持续时间更长的蓝屏。不过,我确实注意到,如果我使用10秒的持续时间,但在此之前中断,再次启动嘟嘟声不会持续整整10秒——几乎就像它冲掉了最初通话的剩余部分。蓝色屏幕并不是每次都出现在我身上,但足以鼓励我停止玩它们:(我没有得到BSOD,超过4秒似乎超出了这个特定设备的实际预期。还要注意的是,如果没有其他音频设备,Windows将很高兴通过系统扬声器播放声音。也许我错过了一些东西,但对那些否决我的人来说:我想到的是,比如说,一个非常短的50毫秒的音调连续,也就是说,可以循环,而不检测到它已经改变。波形的结尾将匹配开始——想象一个单一波长的完美正弦波。只需循环它,直到你需要停止它。看起来这将完成同样的事情。