Sunday, January 09, 2005

Hobby programming : Play MP3 Files with VS.NET and DirectX 9

I am a computer programmer by trade. I often write code in ABAP that works inside of SAP, I write code in Visual Studio .NET for web pages, windows applications and SQL Server Agent Jobs and I write code in Visual Studio .NET that uses the SAP .NET Connector that connects to SAP.
I also do some coding as a hobby. I am sure the faint idea that I might write 'the' application and hit it rich is floating somewhere in my mind.
Who knows?

Anyway, I was searching the internet for a while - for a way to play MP3 files in Visual Studio .NET. I found people selling custom controls to do this and a lot of code out there for playing wave files inside of Visual Studio .NET.
Then I found an entry on a board regarding using DirectX 9 to play the MP3 files. I had purchased a book that was really good on the subject of DirectX 9 (under the guise of maybe I'll write a game program someday and make millions of dollars...) . The book, which unfortunately, I lost, was Managed DirectX 9 Kick Start : Graphics and Game Programmingby Tom Miller . Here is the link to it on Amazon.com - http://www.amazon.com/exec/obidos/tg/detail/-/0672325969/103-9289177-9582233?%5Fencoding=UTF8&v=glance - I was going to re-purchase this book at bn.com instead - but for some reason they were charging about $10 more for the book.

Anyway, I already have the DirectX 9 SDK installed on my PC ( as well as a DirectX 9 compatible video card, although that is not necessary for this bit of code).
Unable to get a hold of the book quickly, I searched the sample code that came with DirectX 9. And behold, they had some code for Audio/Video Playback - that could play MP3 files.

But unfortunately, there was a bunch of filler there - and I really need the MP3 file to play in a background process - so I wanted to see it work in a console application instead of a windows application.

So, I delved in to the code, and wrote a few applications of my own. The following code is the entire console program - for playing an MP3 file. You'll note it would have been shorter, but I had to keep the program alive long enough for the file to play. This program is in VB.NET, but anyone halfway competent should be able to convert it to C#.

And yes, there will be some notes at the end - so that you can actually use this code and have it compile.

Here is the code:

Imports Microsoft.DirectX
Imports Microsoft.DirectX.AudioVideoPlayback
Imports System.Threading

Module Module1

Dim lAudio As Audio
Sub Main()

Dim iEnd As Integer

Try
lAudio = New Audio("Your File Path To MP3 File")
lAudio.Play()
Console.WriteLine("Playing: " & "Welcome to My Nightmare")
Catch ex As Exception
Console.WriteLine(ex.Message)
Exit Sub
End Try

Dim th As Thread = Thread.CurrentThread
iEnd = CType(lAudio.Duration, Integer)

For iCnt As Integer = 0 To iEnd
If lAudio.Playing Then
th.Sleep(1000)
'Console.WriteLine(CType(iCnt, String))
End If
Next

lAudio.Stop()
lAudio.Dispose()
lAudio = Nothing

End Sub

End Module

OK, well that is it for the source code. Here are the notes:

  1. The imports/using statements at the top of the code for the DirectX 9 libraries will not work until you have referenced the dlls. Assuming you have the DirectX 9 SDK installed on your PC - this includes the managed DirectX 9 dlls. You can add the references the usual way - right click on references in the solution explorer and they are in the .NET tab - Microsoft.DirectX and Microsoft.DirectX.AudioVideoPlayback .
  2. You need to subsititute the file/path to your MP3 file on your computer in the line of code with the constant "Your File Path To MP3 File".
  3. In an experiment, you can comment out the code for the threading and the sleeping. :) You will see that the application ends immediately after opening the file and starting to play it. So, at least with a console application, you need to keep the main thread alive until the MP3 file is done playing.
  4. After the try catch, if we are still in the code - lAudio can never be nothing, so the remaining code should never cause a crash.
  5. The last three lines - involving stopping the lAudio object, disposing of it and setting it to nothing, are probably not necessary in this case; however, if you were to use this as part of larger more complex application, you would definitely need it (for your own sanity).
  6. The song I used was an MP3 I ripped of Alice Coopers "Welcom to My Nightmare" - an excellent song.
  7. 28 lines of code total - which could be reduced even further, because you do not have to use the imports statements, it just changes your declaration of variables a bit. Technically speaking, I did not have to create a variable for the current thread. That would change the statement in the for loop from th.Sleep(1000) to
    System.Threading.Thread.CurrentThread.Sleep(1000)

So, that's it. A super simple MP3 player (assuming you have VS.NET and DirectX 9). :)

My great idea for this code, would be to make a windows service program - that would be a simple alarm clock, using MP3 files. Hey I'll probably never write it, but if somebody does, I could use a freebie copy. :)

Since in number 7 I indicated that this program - could be even shorter - here it is. Only really 20 lines of code.

Module Module1
Dim lAudio As Microsoft.DirectX.AudioVideoPlayback.Audio
Sub Main()
Dim iEnd As Integer
Try
lAudio = New Microsoft.DirectX.AudioVideoPlayback.Audio("Your File Path To MP3 File")
lAudio.Play()
Console.WriteLine("Playing: " & "Welcome to My Nightmare")
Catch ex As Exception
Console.WriteLine(ex.Message)
Exit Sub
End Try
iEnd = CType(lAudio.Duration, Integer)
For iCnt As Integer = 0 To iEnd
If lAudio.Playing Then
System.Threading.Thread.CurrentThread.Sleep(1000)
'Console.WriteLine(CType(iCnt, String))
End If
Next
lAudio.Stop() : lAudio.Dispose() : lAudio = Nothing
End Sub
End Module

Abwägen

No comments: