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();
                }
            }
        }
    }
}

Enumeration and arrays

Recently, I discovered the usefulness of the enum type in C++. I can’t believe how long I’ve gone without using an enum because I didn’t know why I should use it over a #define. The two main reasons to use enums over #define is 1) sequential self-numbering and 2) enums allow the value to be visible to the debugger. This post is about the first reason.

Let’s say we want a list of variables, and the variables need to be assigned a unique number for processing, but we don’t care what number is assigned to it. Enumeration to the rescue! Define an enum with a list of variables and it will assign each variable an integer value starting from zero. For example:

enum
{
    alpha,
    beta,
    delta,
    gamma
};

// The values stored in the enum variables are:
// alpha == 0
// beta == 1
// delta == 2
// gamma == 3

Now you can add another variable to the the list in any position (because remember we don’t care what number is assigned to it, it just has to be a unique number) and you won’t have to renumber the other values. It just does it automatically!

enum
{
    alpha,
    beta,
    omega, //<---------
    delta,
    gamma
};

// The values stored in the enum variables are:
// alpha == 0
// beta == 1
// omega == 2
// delta == 3
// gamma == 4

You’re probably thinking: “Great, it self-numbers. What’s the point?” Well the point is that you can use this as array indices and declarations. Assume you have some boolean option settings for your program with the following options: isFullScreen, isWidescreen, isMoving.

Let’s start out making a new file called “options.h” with the following code:

namespace options
{
    enum
    {
        isFullScreen,
        isWidescreen,
        isMoving,
        size
    };
}

I put the enum inside a namespace so that I can use the enum in multiple places without creating an instance of an object. The namespace also allows Visual Studio to list all the enum variables in the autocomplete dialog when using the scope operator ("::"). All I need to do is add #include "options.h" to the top of the header files where I want to use this enum. The last variable size is always going to be the size of the array. Now, remember an enum variable is a const integer value which is why we can use it as an array index value. To use this enum in a class I would use the following code snippet:

// include the namespace file
#include "options.h"

// declares the array, but does not initialize the elements
bool myOptions[options::size];

// then I can initialize the values like so:
myOptions[options::isFullScreen] = false;
myOptions[options::isWidescreen] = false;
myOptions[options::isMoving] = false;

...

// usage example
if(myOptions[options::isFullScreen])
{
    // do something
}

That’s fine and dandy, but if we add another option, we would have to add another line to set that option to false on initialization. We’re lazy and are willing to write more code now to prevent having to write more code in the future so let’s add a reset function to the options namespace.

namespace options
{
    enum
    {
        isFullScreen,
        isWidescreen,
        isMoving,
        size
    };

    static void Reset(bool myArray[options::size], bool value);
}

// the following lines of code are in the same file as the namespace
/**
@brief Resets all the options to a specific value
@param myArray  The array of options using the namespace's enum
@param value    The value to assign to all the options
*/
void options::Reset(bool myArray[options::size], bool value)
{
    for(int i=0; i<options::size; i++)
    {
        myArray[i] = value;
    }
}

I put a value as a parameter because I want the flexibility to set all the options to true or false. The static keyword allows us to use the function without declaring an object so we just reference the function like so in the class:

// declares the array, but does not initialize the elements
bool myOptions[options::size];

// resets all the options
options::Reset(myOptions, false);

...

// usage example
if(myOptions[options::isFullScreen])
{
    // do something
}

Now let’s add another option to the enum to detect if a file is loaded:

namespace options
{
    enum
    {
        isLoaded, //<-----------
        isFullScreen,
        isWidescreen,
        isMoving,
        size
    };

    static void Reset(bool myArray[options::size], bool value);
}

The beauty of this is I can add this function without having to renumber or edit the existing code! I just add the new option where I need to use it.

// still works correctly
if(myOptions[options::isFullScreen])
{
    // do something
}

// do this for the new option
if(myOptions[options::isLoaded])
{
    // do something
}

This is not the only example for using enums with arrays. There are so many possibilities such as having an array of strings and looping through it to read the values. Learning how to use enums for arrays changed my life. It has made me more productive and made maintenance so much easier. It’s such an elegant, cheap, and easy way to improve the code tenfold.

Access denied on shared computer/drive

Like any other geek, I have more than one computer for personal use. I have an old ThinkCentre desktop (running Vista Business) as a file and media server and it does its job well. I have another desktop that I built for regular use and gaming (running Windows 7 Professional) and a ThinkPad laptop (running Windows 7 Professional) for portability.

Now the problem I encounter was the laptop could not access the ThinkCentre. In fact, I couldn’t even access the laptop’s own shared folder either! I was accessing the shared folders via the “Network” tree in “My Computer”. I kept getting an error from Windows saying “\\THINKCENTRE is not accessible” and “The specified provider name is invalid.”

What narrowed down my scope to just the laptop was the other desktop was able to access the shared folders just fine so that ruled out the ThinkCentre being the issue. To the interwebz!!! Let me save you a few hours of searching: don’t try to modify the registry or admin tools off the bat. This is the solution I found that worked for me:

http://www.vistax64.com/vista-networking-sharing/205026-specified-network-provider-name-invalid.html#post1268663

Sure enough, “Client for Microsoft Networks” was not installed on my laptop. I have no idea why, but I installed it. Go to Network and Sharing Center” > “Change Adapter Settings” > Right-click on network adapter (Wi-Fi in my case) > “Install” > “Client” > “Client for Microsoft Networks”. Press “OK” for the dialogs and restart the computer. Presto! I could now access the shared drive on the ThinkCentre!

Remove the IT worker’s perks and watch the modern world collapse

http://arstechnica.com/business/news/2011/12/bill-would-end-overtime-pay-requirement-for-many-more-it-workers.ars

First of all, I’m surprised that there are IT professionals that work hourly. I sort of worked hourly in the IT field, but that was while I was still in college. This bill doesn’t quite affect me as I’m now salaried, but it’s amazing that they’re even considering removing hourly worker’s overtime. What are they thinking? A person who works with computers all day isn’t doing a hard enough job as someone else? It’s certainly more challenging and complex than submitting nonsensical bills such as declaring pizza as a vegetable and censoring the internet! I can imagine the disgruntled IT professional who isn’t being paid overtime who will just wait until Monday to fix the mail server and upsetting all the executives.

Don’t Call Yourself A Programmer, And Other Career Advice | Kalzumeus Software

http://www.kalzumeus.com/2011/10/28/dont-call-yourself-a-programmer/

The article discusses a different outlook on enhancing one’s professional outlook. It certainly changed my view of how I should market myself and be less socially awkward. It is a long article, but it is worth reading especially if you’re an engineer.

Pizza box chassis

Pizza box chassis

Pizza box chassis

The top is a screenshot of a document from work outlining different chassis sizes and their byte value to set for programming. I thought it was a joke because engineers have the weirdest joke. The bottom is a picture of an actual pizza box computer. And it’s running Linux. *shudders* I’m not surprised though. Needs moar bell peppers.

Formatting and Styling Strings (C#)

We’ve discussed different ways to format a string using printf for C++ and string.format for Java/Android and since I’ve been working with C# recently I would add that to the blog as well.

In C#, it’s just like Java/Android: use string.Format(). Instead of dollar signs, you would use curly brackets with the parameter number. What’s nice is that you don’t really need to worry about the type. For example:

int foo = 9000;
string bar = "sparta";

string fubar = string.Format("This is {0}! It is over {1}!", bar, foo);

Would result with:

This is sparta! It is over 9000!"

See how I didn’t need to tell it {0} was a string and {1} was an integer? You can also add the format inside the curly bracket if you wish such as:

{index,length:formatString}

Where index is the index of the value to use; length is the amount of spaces you want this variable to take up; and formatString is a standard or custom string that can be used to do more formatting (such as setting up a date in US or EU format).

As usual, if you’d like to know more about the details, visit MSDN for more reading.