Ask me!

Feel free to ask me anything:  zorakbane@yahoo.com


XNA Music Hitching and Sounds Not Stopping XAct

posted Mar 24, 2012, 5:46 PM by Derick Janssen   [ updated Mar 24, 2012, 5:52 PM ]

Q:
I moved away from MediaPlayer for background music due to the hitching it creates when starting/stopping songs even on high-end systems under Win7/Vista. This has been documented in many threads and I guess it is a Windows MediaPlayer issue that is unfixable:

http://forums.create.msdn.com/forums/t/80427.aspx
http://forums.create.msdn.com/forums/p/45977/275034.aspx
http://forums.create.msdn.com/forums/p/69556/424388.aspx
http://forums.create.msdn.com/forums/p/44169/419462.aspx

Anyway, I have converted my .mp3 files to .wav and compressed them in XACT according to this thread:

http://blogs.msdn.com/b/mitchw/archive/2007/04/27/audio-compression-using-xact.aspx

So the songs are bigger than mp3 but still reasonable. Now I'm having some issues stopping and starting music cues. I'm using the following code which is based on the audio samples and many threads I've read here:


static Cue musicCue;

     //---------------------------------------------------------------- 
    // PlayMusicTrack() - stop current track if any 
    //                  - play new track 
    //---------------------------------------------------------------- 
    public static void PlayMusicTrack(string cueName) 
    { 
        if (musicCue != null && musicCue.IsPlaying) 
        { 
            musicCue.Stop(AudioStopOptions.Immediate); 
            musicCue.Dispose(); 
            musicCue = null; 
        } 
        musicCue = SoundManager.soundBank.GetCue(cueName); 
        musicCue.Play();  
    } 

But unfortunately, this doesn't work at all. The idea is that only a single music track will ever be playing, so I will just fecth a new Cue every time a new song is played. The following issues occur though:

- Cue.Stop() does not stop anything
- after the first Cue.Play(), subsequent Play() calls inexplicably start multiple song cues which also cannot be stopped.
 
There's a ton of threads on here about Cue.Stop() wonkiness so there must be some trick to getting it to work correctly.



A:
You shouldn't dispose it unless you plan on not using it anymore or reloading it later (which will hitch).

Hope this helps,
Derick

        public static void stopMusic() 
        { 
            if (MediaPlayer.State == MediaState.Playing) 
            { 
                MediaPlayer.Stop(); 
            } 
            music = null; 
        } 
 
        public static void stopSound(string fileNameMinusExtension) 
        { 
            soundBank.GetCue(fileNameMinusExtension).Stop(AudioStopOptions.AsAuthored); 
            soundBank.GetCue(fileNameMinusExtension).Stop(AudioStopOptions.Immediate); 
        } 
        public static void stopAllSounds() 
        { 
            for (int i = 0; i < NUM_SOUNDS; ++i) 
            { 
                stopSound(fileNames[i]); 
            } 
            stopMusic(); 
        } 


Steamworks API Multiplayer Lobby and UDK

posted Mar 24, 2012, 4:42 PM by Derick Janssen

Q:
I came across your website and saw you had steamworks experience. I have been working on a small game and busy with the multiplayer. What I'm trying to do is to use Steam Lobby and UDK to host a game and to list all available lobbies to join a specific game.

UDK already has the whole steamworks API integrated but everyone is only using the achievements and not the lobby that supports NAT.

A: 
We used the Lidgren network for our multiplayer code in Galactic Arms Race so we never had to worry about lobbies or master server stuff through steamworks api.  When we did our steamworks integration, we had to write a c++ wrapper dll that could be loaded in c# for the pertinent functions from the main steamworks api for functions that we used.

Your best bet is to make a standalone C++ .dll project which interfaces with steamworks and exports another .dll.  Then use UDK's dll bind to load in your custom dll and make a class to interface it.  There is lots of documentation with this route.  UDN Documentation also shows this sad note

"The lobby system is disabled by default, enable it in OnlineSubsystemSteamworks\Globals.uci (requires UScript and C++ recompile to enable) see OnlineLobbyInterfaceSteamworks.uc\UOnlineLobbyInterfaceSteamworks.cpp

 Note: At the moment, this is a Steamworks-specific interface, not a generalized interface compatible with other online subsystems as a result, it's subject to considerable change and binary compatibility breakage, since it may need to be generalized in the future."

Additionally you will need to have you game approved by Steam and you get your appid code, which you probably don't have at the moment.  You will need this code before you can get the Steamworks API to write the wrapper class and create your achievements and stats on their browser interface.

If you want to take a different approach away from steamworks, our lobby system in Chroma (UDK) we used google app engine to query and maintain a database that is updated by the servers every minute with a heartbeat.  When the client does a query it will return the servers that have been updated within the last five minutes.  We started with this tutorial.

1-2 of 2