现在要播放一个 wave 文件 (*.wav),查了一下网上的代码。一般是用 winmm.dll 中的 PlaySound() 或 snPlaySound 函数。下面代码以 PlaySound() 为例,写了一个 WavePlayer 类。包含两个静态方法,可以播放和停止播放声音文件。

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace PlaySoundProj
{
    
/// <summary>
    
/// This class contains functions to play wave files and stop playing.
    
/// </summary>

    public class WavePlayer
    
{
        
/// <summary>
        
/// Win32 api. This is used to play sound file.
        
/// </summary>

        [DllImport("winmm.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
        
private static extern bool PlaySound(string sound, IntPtr hMod, SoundFlags sf);

        
/// <summary>
        
/// This is used to serve PlaySound().
        
/// </summary>

        [Flags]
        
private enum SoundFlags : int
        
{
            SND_SYNC 
= 0x0000,  /* play synchronously (default) */
            SND_ASYNC 
= 0x0001,  /* play asynchronously */
            SND_NODEFAULT 
= 0x0002,  /* silence (!default) if sound not found */
            SND_MEMORY 
= 0x0004,  /* pszSound points to a memory file */
            SND_LOOP 
= 0x0008,  /* loop the sound until next sndPlaySound */
            SND_NOSTOP 
= 0x0010,  /* don't stop any currently playing sound */
            SND_NOWAIT 
= 0x00002000/* don't wait if the driver is busy */
            SND_ALIAS 
= 0x00010000/* name is a registry alias */
            SND_ALIAS_ID 
= 0x00110000/* alias is a predefined ID */
            SND_FILENAME 
= 0x00020000/* name is file name */
            SND_RESOURCE 
= 0x00040004,  /* name is resource name or atom */
        }


        
/// <summary>
        
/// Play a wave file asynchronously.
        
/// </summary>
        
/// <remarks>
        
/// If the file specified couldn't be found, the function returns false.
        
/// If any error occured, the function returns false.
        
/// On succeeded, returns true.
        
/// </remarks>
        
/// <param name="filePath">The wave </param>
        
/// <returns>True if succeeded, otherwise false.</returns>

        public static bool PlayAsyn(string fileName)
        
{
            
// If the file couldn't be found, returns false.
            if (!System.IO.File.Exists(fileName))
                
return false;

            
// play the sound from the selected filename.
            try
            
{
                
if (!PlaySound(fileName, IntPtr.Zero,
                    SoundFlags.SND_FILENAME 
| SoundFlags.SND_ASYNC))
                    
return false;
            }

            
catch
            
{
                
return false;
            }


            
return true;
        }


        
/// <summary>
        
/// Stop all playing sound.
        
/// </summary>

        public static void Stop()
        
{
            
// Stop playing. Ignores errors.
            try
            
{
                PlaySound(
null, IntPtr.Zero, SoundFlags.SND_ASYNC);
            }

            
catch { }
        }

    }

}


但是如果要播放流呢?根据 Win32 api 上的说明,SND_MEMORY 可以做,但如何做,不知道……
后来又查了一下,原来 Framework 标准库里已经有这样功能的类了,System.Media.Player。它不但可以播放声音文件,还可以播放流。

这样网上有人问的播放资源文件里的声音文件的问题就可以解决了。下面是一段示例。这里 chimes 是嵌入的 wave 文件。

SoundPlayer player = new SoundPlayer(Properties.Resources.chimes);
            player.Play();