简体   繁体   中英

Play a sound, wait for it to finish and then do something?

I'm writing a Windows Forms application which is supposed to play three sound files and at the end of each sound file, it's to change the source of an image.

I can get it to play the sounds using System.Media.SoundPlayer . However, it seems to play the sound in a different thread, continuing on.

The net effect of this is that only the last sound is played and all the images are changed.

I've tried Thread.Sleep , but it sleeps the whole GUI and after the sleep period everything happens at once and the last sound it played.

UPDATE

I thought PlaySynch was working, but it seems to freeze my GUI which is less than ideal. What else can I do?

Did you try SoundPlayer.PlaySync Method ? From the help:

The PlaySync method uses the current thread to play a .wav file, preventing the thread from handling other messages until the load is complete.

不使用Play方法,而是使用PlaySync方法。

Use this code:

[DllImport("WinMM.dll")]
public static extern bool  PlaySound(byte[]wfname, int fuSound);

//  flag values for SoundFlags argument on PlaySound
public static int SND_SYNC        = 0x0000;      // Play synchronously (default).
public static int SND_ASYNC       = 0x0001;      // Play asynchronously.
public static int SND_NODEFAULT   = 0x0002;      // Silence (!default) if sound not found.
public static int SND_MEMORY      = 0x0004;      // PszSound points to a memory file.
public static int SND_LOOP        = 0x0008;      // Loop the sound until next sndPlaySound.
public static int SND_NOSTOP      = 0x0010;      // Don't stop any currently playing sound.
public static int SND_NOWAIT      = 0x00002000;  // Don't wait if the driver is busy.
public static int SND_ALIAS       = 0x00010000;  // Name is a registry alias.
public static int SND_ALIAS_ID    = 0x00110000;  // Alias is a predefined ID.
public static int SND_FILENAME    = 0x00020000;  // Name is file name.
public static int SND_RESOURCE    = 0x00040004;  // Name is resource name or atom.
public static int SND_PURGE       = 0x0040;      // Purge non-static events for task.
public static int SND_APPLICATION = 0x0080;      // Look for application-specific association.
private Thread t; // used for pausing
private string bname;
private int soundFlags;

//-----------------------------------------------------------------
public void Play(string wfname, int SoundFlags)
{
    byte[] bname = new Byte[256];    //Max path length
    bname = System.Text.Encoding.ASCII.GetBytes(wfname);
            this.bname = bname;
            this.soundFlags = SoundFlags;
            t = new Thread(play);
            t.Start();
}
//-----------------------------------------------------------------

private void play()
{
    PlaySound(bname, soundFlags)
}

public void StopPlay()
{
    t.Stop();
}

public void Pause()
{
    t.Suspend(); // Yeah, I know it's obsolete, but it works.
}

public void Resume()
{
    t.Resume(); // Yeah, I know it's obsolete, but it works.
}

What you probably want to do is do an async sound, but then disable your UI in such a way that it doesn't respond to user response. Then once the sound is played, you re-enable your UI. This would allow you to still paint the UI as normal.

I figured out how to do it. I used PlaySynch, but I did the playing in a separate thread to the code the draws the UI. The same thread also updates the UI after each file is played.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM