简体   繁体   中英

Play a tone while key is down C#

I'm building a piano console application that plays a beep/tone with a specific frequency for a specific amount of time. Help Eventually play the tone as long as the key is pressed. PS eventually play several tones at once

namespace something
{

 public class piano
 {

  [DllImport("kernel32.dll")]
  static extern bool Beep(uint dwFreq, uint dwDuration);

  public static void  Main (string [] args)
    {

     Console.WriteLine("This is a piano.");

  //The following code is wrong but you get the idea
     char x = KeyDown;
     switch(x)

     case "q":
     Beep(523,500);
     break;

     case "w":
     Beep(587,500);
     break;

     //etc

     default:
     break;
   }
  }
 }

In a console application you can detect when a key has been pressed, but not when it has been released. Therefore I would use a WinForms application.

In a WinForms Form you can use the KeyDown and KeyUp events at form level. In order to activate them, you must set the KeyPreview property of the form to true . You can do this in the properties window or in code.

Then you must remember which keys are pressed. I'm using a HashSet<Keys> for this.

// Stores the keys in pressed state.
private HashSet<Keys> _pressedKeys = new HashSet<Keys>();

// Used in DisplayKeys method.
private StringBuilder _sb = new StringBuilder();

// Form constructor
public frmKeyboard()
{
    InitializeComponent();
    KeyPreview = true; // Activate key preview at form level.
}

private void frmKeyboard_KeyDown(object sender, KeyEventArgs e)
{
    // Each time a key is pressed, add it to the set of pressed keys.
    _pressedKeys.Add(e.KeyCode);
    DisplayKeys();
}

private void frmKeyboard_KeyUp(object sender, KeyEventArgs e)
{
    // Each time a key is released, remove it from the set of pressed keys.
    _pressedKeys.Remove(e.KeyCode);
    DisplayKeys();
}

private void DisplayKeys()
{
    _sb.Clear();
    foreach (Keys key in _pressedKeys.OrderBy(k => k)) {
        _sb.AppendLine(key.ToString());
    }
    label1.Text = _sb.ToString();
}

Now, you can press one or more keys at a time and they will be displayed in a label.


The simple Beep method will not let you play sounds simultaneously. For a possible solution see this thread on MSDN: Playing Sounds Simultaneously . Another alternative might be MIDI.NET .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM