Musical Console: Part 1 [Katy King]
I decided to have a little fun with one of the new Console features. I wrote a quick program that will load a text file containing a series of {freqeuency, duration} pairs and play it using Console.Beep(). The program loads the integer data into a Song class. A Song consists of an array of Note types, which are {frequency, duration} pairs. Frequency is in Hertz; duration is in milliseconds; a zero frequency represents a rest. Playing a Song calls Note.Play on each Note, which either calls Thread.Sleep() for a rest or Console.Beep() for a note.
I included two data files: “twinkle.dat” is “Twinkle, Twinkle, Little Star” (also the A-B-C song) and “teapot.dat” is “I'm a Little Teapot.” You can download the code and data files from https://msdn.microsoft.com/netframework/downloads/samples/bclsamples/. Of course, you can also easily make your own dat files.
Caveats:
- This was quick-and-dirty, not polished code. There is no error checking, so an invalid filename or file format is going to give you an exception. Beep() requires that the frequency must be between 37 and 32767, inclusive, and that the duration must be positive. I'm using a zero-frequency Note to represent a rest, but past that, an invalid frequency or duration will cause an exception.
- Frequencies must be integer, and so will be very slightly (<1Hz – not enough to be noticeable) off the true notes. (See https://www.techlib.com/reference/musical_note_frequencies.htm for a table and explanation of musical note frequencies.).
- I did the songs from memory, so if the notes or timing isn't quite the way you know them, I'll take the blame. :-)
So, the title says Part 1, indicating some room to consider improvements. Here are some of the ideas I’ve had for making this better in Part 2:
- Error checking. :-)
- Allow data files to specify note names (A, C, F#) instead of frequencies (440, 262, 370). This just requires a table lookup, and a means to specify which octave you want the note to be in. We would probably use generic collections for this.
- Allow data files to specify the length of notes in musical terms such as “whole note” or “quarter note” instead of milliseconds. The song or the player can set the tempo for the song.
- Allow the tempo to be easily adjusted with an extra command line argument (for example, passing in 2 would double the tempo).
- Read data from a MIDI file or other type of music or sound file instead of a text file. This would also require some conversion, as the capabilities for a sound file are beyond those of a Beep().
- Have some cool console color logic with the playing of the song
- Turn a computer keyboard into a (primitive) musical keyboard, reading key presses as notes. An interesting limitation, considering these are new features, is that Console does not include the KeyDown and KeyUp events, so you can’t tell how long the key was held down.
Comments
Anonymous
April 06, 2005
Wow. This takes me back. I remember writing text-based games in BASIC when I was a kid that would use the same concept to play music based on where you were in the game world.
Very geeky sample you have here. Very cool :)Anonymous
April 06, 2005
Thanks, Tobin.Anonymous
April 06, 2005
Try this. And repeat this joke with your friend's PC :-)
using System;
using System.Threading;
class Program
{
static void Main(string[] args)
{
for( int iRing=0; iRing<10; iRing++ )
{
for( int i=0; i<10; i++ )
{
Console.Beep(4000, 50);
Console.Beep(1000, 25);
Thread.Sleep(30);
}
Thread.Sleep(2800);
}
}
}Anonymous
April 07, 2005
Note to self: must incorporate this into my automated build. On success play U2's 'Beautiful Day'. On failure, Pearl Jam's 'Leash' . . .Anonymous
May 23, 2008
I decided to have a little fun with one of the new Console features. I wrote a quick program that will load a text file containing a series of {freqeuency, duration} pairs and play it using Console.Beep(). The program loads the integer data into a SonAnonymous
June 02, 2009
PingBack from http://patiochairsite.info/story.php?id=27309Anonymous
June 17, 2009
PingBack from http://patiosetsite.info/story.php?id=171Anonymous
June 19, 2009
PingBack from http://mydebtconsolidator.info/story.php?id=11892