views:

410

answers:

2

I have two sound files:

  • Sound A is an 18 second intro designed to be played once
  • Sound B is a 1 minute looping track

I'd like to play Sound A once, then once Sound A is done, immediately play Sound B and keep looping Sound B until I tell it to stop. This is supposed to be looping town music in an RPG.

I've tried doing this in code using just SoundEffect, but there's a tiny yet noticeable gap between the end of Sound A and the beginning of Sound B. Even if I put monitoring code watching Sound A's SoundEffectInstance.State in the Update() function, I haven't been able to start Sound B exactly when Sound A finishes so that it's seamless.

I'd prefer to use SoundEffect because I can load WMA files rather than being stuck with WAVs in XACT.

+2  A: 

Unfortunately, simplicity in the SoundEffect API is paid for by a reducing the flexibility. This type of audio programming is what XACT excels in ... if you require a complex composition then you probably want to investigate moving to XACT.

Joel Martinez
I considered making this a multi-part question, but that might get me in trouble.Specifically: how would this work in XACT? That program is an absolute nightmare to use. I would really love precise, click-this-then-this instructions on how to do this kind of looping audio in XACT, because I can't figure it out from inference alone.
Jordan Roher
heh, a fair enough statement :-) I personally haven't done this, but I imagine that it would be done with the transition feature: http://msdn.microsoft.com/en-us/library/ee415994%28v=VS.85%29.aspx
Joel Martinez
Haven't seen that document before. Looks promising. Thanks, Joel.
Jordan Roher
+1  A: 

A potentially second option. I'd imagine that the gap you're hearing is probably because the second sound needs to be either loaded into memory, or initialized, or the stream opened (not sure of the internal implementation). But if this is the case, I wonder if you could do something like this:

  1. Load the two sound effects (a and b)
  2. Begin playing sound effect A
  3. immediately begin playing sound effect B
  4. pause sound effect B after one frame
  5. when sound effect A finishes, restart sound effect A

My assumption is that since sound effect B is already initialized, it may start up quicker, thus lessening the perceived gap. Would love to hear if you get a chance to try this, and whether it worked :-)

Joel Martinez
Tried it, but to no avail. It sounds exactly the same. For the record, I'm loading and creating both SoundEffectInstances at the same time, in LoadContent(). Don't think the issue's related to resource loading. I did get an additional popping noise in the beginning, but I was able to stop that by setting the SoundEffectInstance's volume to 0 just before I hit Play().Plus, it turns out that my WMA's are getting turned into WAVs by XNA's SoundEffect content importer. Argh.I'm at a loss to resolve this. I'm trying to build an RPG, but I can't have 1GB of music because it's all in WAV format.
Jordan Roher
Oh, well that particular problem is actually no problem at all :-) see "Audio compression in Xact" http://blogs.msdn.com/mitchw/archive/2007/04/27/audio-compression-using-xact.aspx
Joel Martinez
The best solution I could find: create one Sound Bank. Drag both WAVs from the Wave Bank into that one Sound Bank. Each one should be a separate track. The looping track should be Track 2. Select it at the Play Wave level, check Infinite looping, and (crucially) set its time stamp to be the exact length of the intro part. You can specify down to 3 decimal places. I used a program called Audacity to get the intro song's exact length. Oh, and follow Joel's compression link. It'll reduce your WAV file size by 3/4.
Jordan Roher