Mittwoch, 15. Juli 2015

Töne mit Beep erzeugen

Nachdem ich in einem vorigen Post die Funktion Beep nur kurz angesprochen habe, möchte ich heute genauer auf die Auswahl der Frequenzen eingehen um tatsächliche musikalische Töne ausgeben zu können und das Spielen von Melodien vorzubereiten.
Mittels Beep() können die charakteristischen Piep Töne eines Computers ausgegeben werden (jedoch über den Lautsprecher, falls angeschlossen), doch Frequenz und Tondauer lassen sich komplett frei wählen. Deshalb kann, obwohl der Klang nicht der schönste ist, jede beliebige Melodie damit gespielt werden. In diesem Post werde ich eine Formel zur Berechnung von Tonfrequenzen zeigen, im nächsten dann ein kleines Keyboard basteln und dann die MIDI Schnittstelle verwenden um den Klang zu verschönern und Gitarrennoten spielen lassen.

Auf Wikipedia findet sich eine schöne Übersicht über die vom Klavier erzeugten Töne und deren Frequenz. Der Zusammenhang zwischen angeschlagener Tastennummer n (und damit Ton) und Frequenz f lässt sich wie folgt ausdrücken:

f(n) = x(n-49)/12*440 Hz

Im folgenden Programm gibt die Funktion PlayNote() mittels Beep() den zur übergebenen Taste gehörigen Ton in der übergebenen Länge ab, insgesamt spielt das Programm so die Melodie unserer schönen Nationalhymne ab (ich habe 24, also 2 Oktaven, zu den Tasten hinzuaddiert, sonst sind die Töne zu tief):


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Beep
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            PlayNote(31, 700);
            PlayNote(33, 300);

            PlayNote(35, 500);
            PlayNote(33, 500);
            PlayNote(36, 500);
            PlayNote(35, 500);

            PlayNote(33, 250);
            PlayNote(30, 250);
            PlayNote(31, 500);
            PlayNote(40, 500);
            PlayNote(38, 500);

            PlayNote(36, 500);
            PlayNote(35, 500);
            PlayNote(33, 500);
            PlayNote(35, 250);
            PlayNote(31, 250);

            PlayNote(38, 800);
        }

        public void PlayNote(int key, int duration)
        {
            key += 24;
            Console.Beep((int)(Math.Pow(Math.Pow(2, 1 / (double)12), key - 49) * 440), duration);
        }
    }
}

Keine Kommentare:

Kommentar veröffentlichen