PDA

Click to See Complete Forum and Search --> : Playing MP3s with DirectX


Warmaster199
Aug 30th, 2000, 07:27 PM
Is it possible to play MP3s using Direct Sound or DirectX? I am making a game that will play MP3s using DirectX. But I have a problem: How to play MP3s using DirectX. Can anyone help me???

Arcom
Aug 31st, 2000, 11:07 AM
Try at MSND Online.
Go to http://msdn.microsoft.com/directx/ and click on DirecX SDK Documentation. I hope you'll find it there...

Warmaster199
Aug 31st, 2000, 01:46 PM
I found how to play MP3's using APIs. But will it play in the backround of my game which uses DirectSound? I better test it out.

parksie
Aug 31st, 2000, 02:02 PM
Which API are you using? The WMP API uses DirectSound.

Arcom
Aug 31st, 2000, 03:45 PM
You can also use Windows Media Player control for playing MP3s.

parksie
Aug 31st, 2000, 03:48 PM
That's exactly what I said...;)

Warmaster199
Aug 31st, 2000, 03:51 PM
I am using the MCI API. The functions that I can use to play the MP3 files are:


Public Declare Function mciGetErrorString Lib "winmm.dll" Alias "mciGetErrorStringA" (ByVal dwError As Long, ByVal lpstrBuffer As String, ByVal uLength As Long) As Long

Public Declare Function GetShortPathName Lib "kernel32" Alias "GetShortPathNameA" (ByVal lpszLongPath As String, ByVal lpszShortPath As String, ByVal cchBuffer As Long) As Long

Public Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long

Public Function mp3Play(FileName As String)
Dim cmdToDo As String * 255
Dim dwReturn As Long
Dim ret As String * 128

Dim tmp As String * 255
Dim lenShort As Long
Dim ShortPathAndFie As String

If Dir(FileName) = "" Then
mmOpen = "Error with input file"
Exit Function
End If
lenShort = GetShortPathName(FileName, tmp, 255)
ShortPathAndFie = Left$(tmp, lenShort)
glo_hWnd = hWnd
cmdToDo = "open " & ShortPathAndFie & " type MPEGVideo Alias MP3Play"
dwReturn = mciSendString(cmdToDo, 0&, 0&, 0&)

If dwReturn <> 0 Then 'not success
mciGetErrorString dwReturn, ret, 128
mmOpen = ret
MsgBox ret, vbCritical
Exit Function
End If

mmOpen = "Success"
mciSendString "play MP3Play", 0, 0, 0
End Function

Public Function mp3Stop() As String
mciSendString "stop MP3Play", 0, 0, 0
mciSendString "close MP3Play", 0, 0, 0
End Function

I got this code from a post on these forums.
I have just tested that code and it seems to work pretty good with DirectSound. Now all I need is a way to adjust the volume. I just don't know how it'll work in my game.

[Edited by Warmaster199 on 08-31-2000 at 05:01 PM]

parksie
Aug 31st, 2000, 03:53 PM
The problem in a game environment is that you'll need to be mixing in all the other sounds at the same time. The best bet is to work out how to play an MP3 yourself. It's not that hard and there will be less requirements for the end-user's system. Plus, using MCI in a game is not a good idea :(

Warmaster199
Aug 31st, 2000, 04:22 PM
Why would MCI be a bad idea? Is it slow? It can support so many media files that it's not even funny. I will only need to play the song (or songs) when I am in the actual game. I won't really need to do too much with the songs just listen to them while the explosions and screaming are playing use DirectSound. In the sample that I made with that code to play an MP3, it loaded pretty fast and it was streaming audio too.

parksie
Aug 31st, 2000, 04:24 PM
You lose so much control over what is being played that it's hard to keep track of the sound data.

noone
Aug 31st, 2000, 05:27 PM
MP3's are heavily compressed, wouldn't using them in a game lead to performance problems?

Warmaster199
Aug 31st, 2000, 07:02 PM
I know that MP3's are highly compressed, but they're a good format since they're considerably smaller than the same wav file. I could begin loading the MP3 as I begin loading the level and then play it in the game. Would that work? It seems that way would seem faster. If anyone has a faster way of loading MP3's than the API's I have posted here, Please post them or send them to me at Warmaster199@Hotmail.com

Warmaster199
Sep 1st, 2000, 01:13 PM
BTW, Did any of you know that several consol games(like Perfect Dark for N64) use MP3's for their music? I found this out the other day when I turned on PDark. It uses the Miles Sound system and MP3's. And does anyone own Age of Empires 2 - Age of Kings? If you look in it's main directory, you'll find that it uses MP3's. It has almost no waves, just MP3's. It doesn't require much of a PC either(200MHz or so).

Xero
Sep 5th, 2000, 03:20 PM
Well, I know most games use what is called "Redbook" audio. It's also a form of compression, and, they dont use it for soundfx of course, just for bg music.

kedaman
Sep 6th, 2000, 05:00 AM
I bet mixing a lot of channels streaming mp3's could be too slow for games, but if you have one mp3 playing background and then have the sounds as wavfiles.

parksie
Sep 6th, 2000, 12:31 PM
One slightly off-topic proposal:

If we have graphics cards that decode MPEG video, how about sound cards that can decode MP3s?

Warmaster199
Sep 6th, 2000, 02:53 PM
That's exactly it, kedaman, I will have an MP3 playing in the backround and the SFX will be .wav files.

kedaman
Sep 7th, 2000, 05:03 AM
Parksie, would be a great solution, hehe but there are tons of compression formats, could be kewl to have the slowest ones on a soundcard.

Warmaster199, i think i have the solution for you, it's the bass dll, (don't have the link right now) but i'm working on an activeX dll to create a object oriented interface to it, so you could just ask me later (when i have my connection at home) and i'll send it to you ;)

audioguy
Sep 9th, 2000, 12:25 PM
I am only a novice VB6 guy, but I am writing a multrack audio recording app and I have been through a lot of the research.

If you want to use multiple sounds you should use Directsound. Directsound does NOT support MP3, it only supports the wave (PCM) format. Directsound is quick because you can load small sounds direcly into a RAM buffer (good for gunshots, or other FX). You can also stream large files (like background music) from disk. It is pretty easy to use and the SDK has a lot of documentation for use with VB6.

I also have used a freeware control called Easysound. It works, but it is kind of buggy. And it seems to have a lot more latency than with directx.

Warmaster199
Sep 9th, 2000, 08:33 PM
I am using the MCI API that I posted here earlier in my game, and the game's performance so far is near stellar(dispite everyone saying it won't work). Maybe it works so good because my comp is a 350MHz PII. Now, how about ways to find the bit-rate, sound length, current position in sound, looping, pausing and things like that. Here is some more code:

Public Function IsItPlaying() As Boolean
Static yn As String * 30
mciSendString "status MP3Play mode", yn, Len(yn), 0
IsPlaying = (Mid$(yn, 1, 7) = "playing")
End Function

Public Function SeekTo(Second)
mciSendString "set MP3Play time format milliseconds", 0, 0, 0
If IsItPlaying = True Then mciSendString "play MP3Play from " & Second, 0, 0, 0
If IsItPlaying = False Then mciSendString "seek MP3Play to " & Second, 0, 0, 0
End Function

Public Function PositionInSec()
Static PIS As String * 30
mciSendString "set MP3Play time format milliseconds", 0, 0, 0
mciSendString "status MP3Play position", PIS, Len(PIS), 0
PositionInSec = Mid$(PIS, 1, Len(PIS)) / 1000
End Function

Public Function Position()
Static P As String * 30
mciSendString "set MP3Play time format milliseconds", 0, 0, 0
mciSendString "status MP3Play position", P, Len(P), 0
sec = Mid$(P, 1, Len(P)) / 1000
If sec < 60 Then Position = "0:" & Format(sec, "00")
If sec > 59 Then
mins = Int(sec / 60)
sec = sec - (mins * 60)
Position = Format(mins, "00") & ":" & Format(sec, "00")
End If
End Function

Public Function LengthInSec()
Static L As String * 30
mciSendString "set MP3Play time format milliseconds", 0, 0, 0
mciSendString "status MP3Play length", L, Len(s), 0
LengthInSec = Val(Mid$(L, 1, Len(L))) / 1000 'Round(CInt(Mid$(s, 1, Len(s))) / 1000)
End Function

Public Function Length()
Static L As String * 30
mciSendString "set MP3Play time format milliseconds", 0, 0, 0
mciSendString "status MP3Play length", L, Len(L), 0
sec = Val(Mid$(L, 1, Len(L))) / 1000 'Round(CInt(Mid$(l, 1, Len(l))) / 1000)
If sec < 60 Then Length = "0:" & Format(sec, "00")
If sec > 59 Then
mins = Int(sec / 60)
sec = sec - (mins * 60)
Length = Format(mins, "00") & ":" & Format(sec, "00")
End If
End Function

' For some stupid reason, It doesn't un-pause ---> help me!
Public Function mp3Pause()
mciSendString "pause MP3Play", 0, 0, 0
End Function

This all came from the same module... I just can't get this code to work... I don't know how to get it to work... Can anyone help?

DJDANNYK
Dec 13th, 2000, 05:10 PM
' For some stupid reason, It doesn't un-pause ---> help me!
Public Function mp3Pause()
mciSendString "pause MP3Play", 0, 0, 0
End Function


Try doing this instead


Public Function mp3Pause()
If IsItPlaying = True Then
mciSendString "pause MP3Play", 0&, 0&, 0&
Else
mciSendString "play MP3Play", 0&, 0&, 0&
End If
End Function

Hope it helps