Console.Beep for 64-bit Windows

Lately, I’ve been experimenting with making music with computers. I do not have a music background so it’s been a difficult route. One of the things I regret is not taking a music or band class in high school. Fortunately, there are plenty of websites that explain how to read sheet music and plenty of videos to watch to learn how to play popular songs. It’s like learning a new programming language in which you’re learning new syntax and semantics, but takes a lot of practice and constant self-improvement via experimentation and feedback from others to perfect.

Now you’re probably thinking why I’m talking about music theory on a programming blog. Well, a cheap and easy way to make music is to write a console application using Visual C# Express. You can use Console.Beep() and specify a frequency and duration to make a note. This is the route I tried, but I was extremely disappointed to find out that Console.Beep() didn’t work with the 64-bit version of Windows starting with Vista and newer.

Well, there is a work-around! This MSDN forum post outlines how to send the beep to the computer speakers via a class. It appears to take the note information (amplitude, frequency, and duration), convert it into a sine wave, converts the sine wave to a byte array, saves the byte array as a WAV file in memory, and plays the WAV file to the computer speakers. Brilliant!

I am not the author of the code so any questions regarding it should be posted in the forum post, but I will repost the code here in case the forum post disappears.

// include these at the top of the file:
// using System;
// using System.IO;
// using System.Media;

// the following code goes inside your namespace
public class Beep
{
    // I added this function because amplitude should just always be 1000
    // < 1000 sounds muffled and > 1000 throws an exception
    public static void Play( double frequency, double duration )
    {
        BeepBeep( 1000, frequency, duration );
    }

    private static void BeepBeep( double Amplitude, double Frequency, double Duration )
    {
        double Amp = ( ( Amplitude * ( System.Math.Pow( 2, 15 ) ) ) / 1000 ) - 1;
        double DeltaFT = 2 * Math.PI * Frequency / 44100.0;

        int Samples = (int)(441.0 * Duration / 10.0);
        int Bytes = Samples * sizeof(int);
        int[] Hdr = { 0X46464952, 36 + Bytes, 0X45564157, 0X20746D66, 16, 0X20001, 44100, 176400, 0X100004, 0X61746164, Bytes };

        using ( MemoryStream MS = new MemoryStream( 44 + Bytes ) )
        {
            using ( BinaryWriter BW = new BinaryWriter( MS ) )
            {
                for ( int I = 0; I < Hdr.Length; I++ )
                {
                    BW.Write( Hdr[I] );
                }
                for ( int T = 0; T < Samples; T++ )
                {
                    short Sample = System.Convert.ToInt16( Amp * Math.Sin( DeltaFT * T ) );
                    BW.Write( Sample );
                    BW.Write( Sample );
                }

                BW.Flush();
                MS.Seek( 0, SeekOrigin.Begin );
                using ( SoundPlayer SP = new SoundPlayer( MS ) )
                {
                    SP.PlaySync();
                }
            }
        }
    }
}
Advertisements
  1. November 12th, 2012

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: