Darrell Gibson

I have a problem when I want to play consecutive wav files. In order to do this I have to use the PlaySync() method that does not return until the wav file has been played. This works fine when the wav files are small (less than 5-8MB), but when the audio tracks are longer (and the files get larger > 8MB, 30MB for a typical music track) the PlaySync returns before the wav file has reached the end. This results is the audio track finishing playing prematurely. I have tried a number of alternative ways of doing this including using a local file, loading the file (asynchronously and synchronously), using file stream (again asynchronously and synchronously), using a background thread and using a foreground thread. The results are always the same. Interestingly each wav file always finishes playing at the same point, however different tracks finish at different points (sometimes after a few seconds others will play for over a minute). I have ever edited the wav files to see if it was something in the wav file that was causing an early return, but the stop point moved to a different point in the wav file.

If I play the files using the asynchronous Play() method they will play fine however I have no way of playing consecutive wav files with this method as there is no way to find out when the file has finished playing. I have even tried using the native PlaySound method, but I still get the same problem when I try and play the wav file synchronously.

I am using C++, but I have also tried this in C# and got exactly the same results. (I¡¯m using VS2005 by the way.) Here is the code I currently have:

void backgroundWorker1_DoWork( Object^ sender, DoWorkEventArgs^ e )

{

array<String^>^ song_files = gcnew array<String^>(2);

song_files[0] = "C:\\C++\\jukebox2\\jukebox2\\Music_library\\01 Naive.WAV";

song_files[1] = "C:\\C++\\jukebox2\\jukebox2\\Music_library\\15 Lost & Found.WAV";

for each (String^ s in song_files)

{

FileStream^ fst = gcnew FileStream(s, FileMode:Surprisepen, FileAccess::Read);

SoundPlayer^ sp = gcnew SoundPlayer(fst);

sp->PlaySync();

}

I have looked for similar post on this topic and found this (http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=433930&SiteID=1), but neither of the ticked solutions make any difference.

Is there any other reason why this method should return early Is something else forcing it to return How can I get at the guts of what is going on here

Any help would me much appreciated. Thanks,

Darrell.


Re: Windows Forms General Problem with SoundPlayer PlaySync () method

nobugz

This sounds like a problem with your audio driver. Start by installing the latest and greatest driver. The only workaround I can think of is to use a very small .wav file with no sound and P/Invoke the PlaySound() API function with the SND_NOWAIT option.





Re: Windows Forms General Problem with SoundPlayer PlaySync () method

Darrell Gibson

Fairly sure it is not a driver issue as I have tried it on a number of machines (work and home) now and the result is always the same.

Any other suggestions

Darrell.





Re: Windows Forms General Problem with SoundPlayer PlaySync () method

nobugz

I did give you another option. Check this thread for code, SND_NOWAIT = &H2000 (0x2000).





Re: Windows Forms General Problem with SoundPlayer PlaySync () method

Darrell Gibson

I have tried the PlaySound method and got the same results when I played the wav file synchronously. I fail to see how the SND_NOWAIT switch will change anything. Could you please explain your rational.

Ideally I'd still like to use the PlaySync method as it should do what what I want. Also my understanding is that the SoundPlayer uses the PlaySound API. If this is the case if it works in one it should work with the other.

Thanks your feedback.

Darrell.





Re: Windows Forms General Problem with SoundPlayer PlaySync () method

nobugz

The idea is to play the sound asynchronously, that worked, and detect that playing is completed by calling PlaySound again with the SND_NOWAIT option. It will return False if the sound is still playing, True (and play the short no-sound .wav) when it is done. Use a one second timer to repeat this.





Re: Windows Forms General Problem with SoundPlayer PlaySync () method

Darrell Gibson

Nice idea. I now see where you are coming from and it should work.

I also had a workaround in mind. My idea was from the size of the wav file calculate the execution time and then play the file asynchronously. The main thread could then be put to sleep for the file play time.

However as I said although these workarounds should work I'd ideally like to find out why the PlaySync does not operate as it should when large wav files are used.

Any further ideas

Darrell.





Re: Windows Forms General Problem with SoundPlayer PlaySync () method

Darrell Gibson

This morning I have built a console based project using the PlaySync method and got exactly the same results. I have also tried the PlaySound API again and it will still not play asynchronously without stopping before the end of file. I'm starting to suspect this could be a bug in the underlying code.

Anyone else experienced this kind of thing

Darrell.





Re: Windows Forms General Problem with SoundPlayer PlaySync () method

Darrell Gibson

Although I now have the workaround suggested by nobugz, I still have not got an answer to the problem with the PlaySync method. I have this weekend implemented playing a wav file using the old multi-media extensions (based on this tutorial http://www.codeproject.com/audio/wavefiles.asp) which works fine, but I still have not been able to get anymore details of why the PlaySync (and PlaySound API) problem persists. Any ideas would be greatly appreciated.

Thanks,

Darrell.





Re: Windows Forms General Problem with SoundPlayer PlaySync () method

Darrell Gibson

Still not found out the reason for the problem with the PlaySync() method, but thought I'd keep you posted on what I have found out. The MSDN (http://msdn2.microsoft.com/en-us/library/ms713264.aspx) does say that PlaySound can only be used to playback wav file < 100KB. It also says that for larger files use MCI. This can be easily done using mciSendString with the play command and wait flag. (An example can be found here: http://www.codeproject.com/audio/moemeka7.asp)

Is there a way to examine how much memory is available to a thread Is there a way to examine what has been loaded into memory

I'm off on holiday now, but I will have another go at getting the bottom of this when I get back.

Darrell