I have a device that a user interacts with alongside of a C# WPF program. This program must beep when the user presses a button on the device, for either a specified amount of time or for as long as the user presses the button, whichever is shorter. The only speaker available to produce the beep/tone is the computer BIOS speaker; we cannot assume that other speakers are around (and it's actually safe to assume that there won't be any other speakers).
How can I produce a continuous tone for the necessary duration?
What I have so far produces lots of beeps, but not a continuous tone.
First, a thread is started:
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();
}
}
The thread itself:
bool mMakeTone = false;
private void ProduceTone(){
while(this.Visibility == Visibility.Visible){
if(mMakeTone ){
Console.Beep();
}
else{
Thread.Sleep(10);
}
}
}
And then the mMakeTone boolean is flipped to true during the duration of the button press, up to a time specified by the device itself.
I suspect that it's just a quick change to the Console.Beep() line above, but I'm not sure what it would be.
There is an overload for Console.Beep that takes a frequency and duration, which is useful if you want to produce a sound for a specified duration. The ability to turn on a sound and then later turn it off using the BIOS speaker is not directly supported by the Console.Beep method, or any other API that I am aware of, without perhaps installing a fake sound card driver.
A little experimentation has discovered the following:
So... You should be able to accomplish your task by creating a new background thread to call Console.Beep() with the frequency of your choosing and a very long duration. To later terminate the sound, you may just call Console.Beep() on your main thread with any frequency and an extremely, non-zero duration (e.g. 1) to terminate the sound playing from the background thread. You should not make the sound playing on the background thread any longer that a reasonable duration because the thread will live until the sound would have ordinarily stopped playing and you don't want a lot of background threads piling up on you.
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);
}