Prototype sound functionality problems.

Feb 2 at 5:20 PM
Hi,

I have coded two methods of audio into my game engine based on NAudio.
  1. Create a WaveOutEvent object every time a sound needs to be be played.
  2. Create arrays of WaveOutEvent objects already initialised to play certain sounds. The play method checks the array to detect the first player in the array which is not stopped, and plays it.
Ok, so neither of these work yet. I need some advice!

Details on 1:

The play sound method uses a string variable 'path', which contains the path of the wav file to be played.
                if(mode == "SINGLE")
                {
                    WaveOutEvent wavePlayer1;
                    AudioFileReader file1;
                    
                    wavePlayer1 = new WaveOutEvent();
                    file1 = new AudioFileReader(path);
                    wavePlayer1.Init(file1);
                    wavePlayer1.Play();                     
                }
The sound plays once, but when I attempt to play the second time I get the error "Error: Already allocated calling waveOutOpen". This confuses me since a new WaveOutEvent object local to the block of code is created and played, meaning subsequent objects are new objects - not the same. Is that right?

Details on 2:

The initialisation code called at the start of the game engine is pretty basic:
                    // Array of players ----------------------------------------
                    NAudio_EATEN_GHOST_Array = new WaveOutEvent[noOfPlayers];
                    NAudio_EATEN_PILL_Array = new WaveOutEvent[noOfPlayers];
                    NAudio_EATEN_POWERPILL_Array = new WaveOutEvent[noOfPlayers];
                    NAudio_KILLED_BY_GHOST_Array = new WaveOutEvent[noOfPlayers];   
                    
                    AudioFileReader file;
                    
                    for(int i=0;i<NAudio_EATEN_GHOST_Array.Length;i++)
                    {
                        NAudio_EATEN_GHOST_Array[i] = new WaveOutEvent();
                        file = new AudioFileReader("D:\\Programming\\SFX\\EATEN_GHOST\\Hit_55.wav");
                        NAudio_EATEN_GHOST_Array[i].Init(file);
                        
                        NAudio_EATEN_PILL_Array[i] = new WaveOutEvent();
                        file = new AudioFileReader("D:\\Programming\\SFX\\EATEN_PILL\\Hit_43_s.wav");
                        NAudio_EATEN_PILL_Array[i].Init(file);
        
                        NAudio_EATEN_POWERPILL_Array[i] = new WaveOutEvent();
                        file = new AudioFileReader("D:\\Programming\\SFX\\EATEN_POWERPILL\\Hit_49.wav");        
                        NAudio_EATEN_POWERPILL_Array[i].Init(file);
    
                        NAudio_KILLED_BY_GHOST_Array[i] = new WaveOutEvent();
                        file = new AudioFileReader("D:\\Programming\\SFX\\KILLED_BY_GHOST\\Hit_72.wav");
                        NAudio_KILLED_BY_GHOST_Array[i].Init(file);
                    }
                    // Array of players ----------------------------------------            
With the players all created, the method to play a sound includes the following code, which again is pretty basic and attempts to use the playback state event:
                if(mode == "PLAYER_ARRAY")
                {
                    switch(effectsIn)
                    {
                        case "KILLED_BY_GHOST":
                            // 1.   Choose a media player which is not playing.
                            i = 0;
                            do
                            {
                                if(NAudio_KILLED_BY_GHOST_Array[i].PlaybackState != PlaybackState.Stopped)
                                {
                                    // Keep looking
                                    i++;
                                }
                                else
                                {
                                    found = true;
                                }
                            } while( (i<NAudio_KILLED_BY_GHOST_Array.Length) && (!found));
                            // Now 'i' holds the index of the player which is not playing.
                            
                            // 2.   Play effect                 
                            if(found)
                            {
                                NAudio_KILLED_BY_GHOST_Array[i].Play();
                            }
                            break;
                            
                        case "EATEN_PILL":
                            // 1.   Choose a media player which is not playing.
                            i = 0;
                            do
                            {
                                MessageBox.Show(NAudio_EATEN_PILL_Array[i].PlaybackState.ToString());
                                if(NAudio_EATEN_PILL_Array[i].PlaybackState != PlaybackState.Stopped)
                                {
                                    // Keep looking
                                    i++;
                                }
                                else
                                {
                                    found = true;
                                }
                            } while( (i<NAudio_EATEN_PILL_Array.Length) && (!found));
                            // Now 'i' holds the index of the player which is not playing.
                            
                            // 2.   Play effect 
                            if(found)
                            {                   
                                NAudio_EATEN_PILL_Array[i].Play();
                            }
                            
                            break;
                        case "EATEN_GHOST":
                            // 1.   Choose a media player which is not playing.
                            i = 0;
                            do
                            {
                                if(NAudio_EATEN_GHOST_Array[i].PlaybackState != PlaybackState.Stopped)
                                {
                                    // Keep looking
                                    i++;
                                }
                                else
                                {
                                    found = true;
                                }
                            } while( (i<NAudio_EATEN_GHOST_Array.Length) && (!found));
                            // Now 'i' holds the index of the player which is not playing.
                            
                            // 2.   Play effect                 
                            if(found)
                            {
                                NAudio_EATEN_GHOST_Array[i].Play(); 
                            }
                            break;
                        case "EATEN_POWERPILL":
                            // 1.   Choose a media player which is not playing.
                            i = 0;
                            do
                            {
                                if(NAudio_EATEN_POWERPILL_Array[i].PlaybackState != PlaybackState.Stopped)
                                {
                                    // Keep looking
                                    i++;
                                }
                                else
                                {
                                    found = true;
                                }
                            } while( (i<NAudio_EATEN_POWERPILL_Array.Length) && (!found));
                            // Now 'i' holds the index of the player which is not playing.
                            
                            // 2.   Play effect                 
                            if(found)
                            {
                                NAudio_EATEN_POWERPILL_Array[i].Play();
                            }
                            break;
                    } // switch             
                }
In the case of the EATEN_PILL effect, there are 5 WaveOutEvent objects in the array. 5 sounds play successfully (noOfPlayers is 5...), but then no more. The rest of the calls give silence. The message box debug tells me that the sounds never go back to PlaybackState.Stopped. They are always 'PlaybackState.Playing'. But the sound is a second long, so how can this be?

In any case both attempts have not worked, and the code is pretty useless.

Am I coming from this from the wrong angle? Is there another way to use the cleverness of the API to achieve what I need to? Argh.
Coordinator
Feb 17 at 3:05 PM
Check my article on fire and forget audio playback here.