Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Want more cowbell? Yes please!

Author: Clint Rutkas: twitter, blog
Download: Download
Software: Visual Studio 2008 Standard or better (Trial Download)
Windows Mobile 6.0 SDK
Windows Mobile 6.1 Emulator Images (Optional)
Hardware: Windows Mobile Pro (Optional)
Time Required: 2 hours
Cost: Free-ish

After playing way too much guitar hero, bought a guitar only to quickly realize I'm horrible.  Asking my friends, I decided to adopt the world's hardest instrument to play, that's right, the cow bell.  It takes years to master and I decide to turn my cell phone, an HTC Touch Diamond  into this magical instrument too.

This is a fairly straight forward application.  We'll touch on altering the volume of a cell phone along with interacting with a touch screen and how to do a deploy for Windows Mobile so you can have a cowbell band of your own.  The application will also properly resize an image to match the screen proportions, however you'll have to download the source code for that.

You'll see while getting your system up and working with the emulator may take a few additional steps, it will code mostly like a typical windows application for this instance.

The source code shown isn't everything you need to get the application running, please download the source code to get the rest.  The link is at the top of the article.

Getting up and running with baby steps

imageAfter you get Visual Studio 2008 up and running, if you don't have the Windows Mobile 6.0 SDK, please download it and install it.  The link is at the top of this article.  Visual Studio 2008 only comes with the Windows mobile 5.0 SDK.

On the right is a picture of the emulator in one of styling forms.  On top of just being able to test on an emulator, you can do a direct deploy to your cell phone.  Now a Windows Mobile Professional phone can do this directly, however a Windows Mobile Standard (non-touch screen) does require a few extra steps.  I blogged about these steps over on my blog.  After your phone is properly configured, all you need to do is change your target deployment.

image

I highlighted the device deploy instead of the emulator.

Smart Device Creation

To create a new solution we go to File –> New –> Project.  We'll select the language of our choice (c# for me) then go to “Smart Device”

image

Easy so far, right?  Next comes selecting the framework along with your target platform.  Select “Windows Mobile 6 Professional SDK” then click OK and you're good to start.

image

Altering Volume

To alter your volume currently in the compact framework, you have to do some pinvokes to call native API calls.  This is scary for some but don't fret.  There is a site called pinvoke.net that makes doing these calls simple as pie.  We'll create a new class called Audio to encapsulate all audio functions.  This includes playing a file and altering the volume.  First we'll do the simple ability to play an audio file.  Since we'll be grabbing our data from the resources, we'll use a MemoryStream object convert the bytes to a stream so we can read it in.  We'll need to include the System.Media namespace to be able to play audio.  To do the pinvokes, we'll include the System.Runtime.InteropServices.

C#

private readonly SoundPlayer sp;

    public Audio(byte[] AudioResource)
    {
        sp = new SoundPlayer(new MemoryStream(AudioResource));
        sp.Load();
    }

    public void Play()
    {
        sp.Play();
    }

    public void PlayLoop()
    {
        sp.PlayLooping();
    }

    public void Stop()
    {
        sp.Stop();
    }

VB

    Private ReadOnly sp As SoundPlayer

    Public Sub New(ByVal AudioResource As Byte())
        sp = New SoundPlayer(New MemoryStream(AudioResource))
        sp.Load()
    End Sub

    Public Sub Play()
        sp.Play()
    End Sub

    Public Sub PlayLoop()
        sp.PlayLooping()
    End Sub

    Public Sub [Stop]()
        sp.[Stop]()
    End Sub

And in the application, we'll call the audio file like the following:

c#

    private readonly Audio audio = new Audio(Properties.Resources.CowBellAudio);

VB

    Private ReadOnly audio As New Audio(My.Resources.CowBellAudio)

Next we'll add in the ability to alter the volume with the pinvokes.  Sadly, I'm not sure why the set volume numbers act as they do.  After searching the internet, these numbers kept appearing.  In a perfect world, I would have liked to see 0 to 100 or something like that but it isn't so.  We'll create get / sets in the wrapper to make a more seamless wrapper object to hide the pinvoke calls.

C#

    [DllImport("coredll.dll")]
    private static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume);

    [DllImport("coredll.dll")]
    private static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume);

    public static uint Volume
    {
        get
        {
            uint _volume;
            waveOutGetVolume(IntPtr.Zero, out _volume);
            return _volume;
        }

        set
        {
            waveOutSetVolume(IntPtr.Zero, value);
        }
    }

    public enum Volumes
    {
        OFF = 0,
        LOW = 858993459,
        NORMAL = 1717986918,
        MEDIUM = -1717986919,
        HIGH = -858993460,
        VERY_HIGH = -1
    }

VB

    Declare Function waveOutGetVolume Lib "coredll.dll" (ByVal uDeviceID As Integer, ByRef lpdwVolume As Integer) As Integer
    Declare Function waveOutSetVolume Lib "coredll.dll" (ByVal device As IntPtr, ByVal volume As Integer) As Integer

    Public Shared Property AudioVolume() As Integer
        Get
            Dim _volume As Integer
            waveOutGetVolume(IntPtr.Zero, _volume)
            Return _volume
        End Get

        Set(ByVal value As Integer)
            waveOutSetVolume(IntPtr.Zero, value)
        End Set
    End Property

    Public Enum Volumes
        OFF = 0
        LOW = 858993459
        NORMAL = 1717986918
        MEDIUM = -1717986919
        HIGH = -858993460
        VERY_HIGH = -1
    End Enum

Creating the Cowbell

Pretty Pictures and sounds

This is a cowbell application so we need an actual cowbell on it.  After a quick image search, I found the cowbell image on the internet and the X is from the Famfamfam Silk icon collection

We'll want to embed these images to make deployment easier and have everything self-contained so we'll use the resource in the project's property tab.  To reach this, you go to Project->Properties or right click on your project and at the bottom, there is the Properties menu option.

In here, we'll want to use the Images section along with the audio section.

image

When you select the section you want, click the Add Resource button and track down the file you need.  Referencing these resources is pretty straight forward now but each language has a slightly different way to do it.

C#

    Properties.Resources.cowBellImage;

VB

    My.Resources.cowBellImage

Easy no?

Items on the form

We'll want to turn off some elements on the form to maximize the cowbell.  We'll set the WindowState to Maximum, TopMost to True, MinimizeBox to False and FormBorder to None.

We'll drag on two picture boxes on the form naming them picCowbell and picClose.  We'll set the background to both elements to be transparent.  We'll also want to double click on each picture boxes to create a Click event.  For the picClose element, we'll add in the Close() method to shut down the application.

We'll also create a MouseDown event on the picCowbell.  Here we'll determine how loud to play then play the sound.  We'll create the Audio object during the form creation so it is already loaded into memory and will only be created once.

C#

private readonly Audio audio = new Audio(Properties.Resources.CowBellAudio);
private void picCowbell_MouseDown(object sender, MouseEventArgs e)
{
    Audio.Volumes value;
    switch ((int)Math.Round((e.Y / (Height * 1.0)) * 5))
    {
        //case 0: // implied with default;
        //case 1:
        default:
            value = Audio.Volumes.LOW;
            break;
        case 2:
            value = Audio.Volumes.NORMAL;
            break;
        case 3:
            value = Audio.Volumes.MEDIUM;
            break;
        case 4:
            value = Audio.Volumes.HIGH;
            break;
        case 5:
            value = Audio.Volumes.VERY_HIGH;
            break;
    }

    // no need to take the performance hit of changing the volume
    // if the values aren't different
    if( oldValue != value)
    {
        Audio.Volume = (uint) value;
        oldValue = value;
    }
    audio.Play();
}

VB

Private ReadOnly audio As New Audio(My.Resources.CowBellAudio)
Private Sub picCowbell_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
    Dim value As Audio.Volumes
    Select Case Convert.ToInt32(Math.Round((e.Y / (Height * 1)) * 5))
        Case 2
            value = audio.Volumes.NORMAL
            Exit Select
        Case 3
            value = audio.Volumes.MEDIUM
            Exit Select
        Case 4
            value = audio.Volumes.HIGH
            Exit Select
        Case 5
            value = audio.Volumes.VERY_HIGH
            Exit Select
        Case Else
            'case 0: // implied with default;
            'case 1:
            value = audio.Volumes.LOW
            Exit Select
    End Select

    ' no need to take the performance hit of changing the volume
    ' if the values aren't different
    If oldValue <> value Then
        audio.AudioVolume = Convert.ToInt32(value)
        oldValue = value
    End If
    audio.Play()
End Sub

Hailing a CAB for deployment

We'll right click on the solution in the solution explorer or we can go to File->New->Project.  If you do the file menu route, you'll have a screen that is slightly different than mine.  At the bottom you'll have a drop down menu where you'll want to change it from “Create a new solution” to “Add to Solution”.

image

Since I want a CAB install, I'll go to the “Other Project Types” then to “Setup and Deployment” and select a Smart Device CAB Project”.

 

From there, right click on “Application Folder” and go to “Add”.  Select “Primary Output” and hit OK.

image

So with the output added in now, we'll need to do some more magic.  In the “File System” window, we'll right-click on “File System on Target Machine” and go “Add Special Folder” then to “Start Menu Folder”.

Now that we have our start menu, we'll go back to the “Application Menu” and right click on the “Primary output from Cowbell”.  Select “Create Shortcut” and drag that shortcut to your start menu folder.  I suggest you rename it too.

Then you can build it, drag the CAB over and install on your device.

Rocking out

To download the application's full source code, please download it from http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9059259/cowbell.zip

image

About the Author

Clint Rutkas works for Microsoft and has created a few cool projects in the past like a Disco Dance Floor, an automated bartender system and a self-balancing skateboard.  His blog is http://BetterThanEveryone.com where he posts about what crazy application idea he is working on next.

Tags:

Follow the Discussion

  • Monkey See, Monkey Build Monkey See, Monkey Build

    MORE COWBELL, we need more windows mobile cowbell!

  • djhaymandjhayman

    "Sadly, I’m not sure why the set volume numbers act as they do.  After searching the internet, these numbers kept appearing.  In a perfect world, I would have liked to see 0 to 100 or something like that but it isn’t so."

    Convert the values to hex and you'll see why:

    OFF = 00000000

    LOW = 33333333

    NORMAL = 66666666

    MEDIUM = 99999999

    HIGH = CCCCCCCC

    VERY_HIGH = FFFFFFFF

    So it ranges from 0 to FFFFFFFF - these must just be "common" values that fall in that range.

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.