使用C#播放音效的4種方式

使用C#播放音效的4種方式

使用者需求,當應用程式發現問題或錯誤時,希望主機能直接播放提示或警告音效,讓人員能快速到達主機位置進行問題排除。

  • Win32 API Beep
  • SystemSounds 類別
  • SoundPlayer 類別
  • WMPLib.dll

使用 Win32 API Beep 來播放

[DllImport("kernel32.dll")]
private static extern int Beep(int dwFreq, int dwDuration);

public enum Music
{
 Do = 523,
 Re = 587,
 Mi = 659,
 Fa = 698,
 So = 784,
 La = 880,
 Ti = 988,
 Do2 = 1046
}

我們使用 Win32 API 的 Beep,它有兩個參數,一是音頻的高底,我們利用例舉去定義 Do Re Mi 相似音,二是播放長度。

接下來當然是經典名曲的演奏:

// 小蜜峰
Beep((int)Music.Do, 300);
Beep((int)Music.Do, 300);
Beep((int)Music.So, 300);
Beep((int)Music.So, 300);
Beep((int)Music.La, 300);
Beep((int)Music.La, 300);
Beep((int)Music.So, 600);

Beep((int)Music.Fa, 300);
Beep((int)Music.Fa, 300);
Beep((int)Music.Mi, 300);
Beep((int)Music.Mi, 300);
Beep((int)Music.Re, 300);
Beep((int)Music.Re, 300);
Beep((int)Music.Do, 600);

Beep((int)Music.So, 300);
Beep((int)Music.So, 300);
Beep((int)Music.Fa, 300);
Beep((int)Music.Fa, 300);
Beep((int)Music.Mi, 300);
Beep((int)Music.Mi, 300);
Beep((int)Music.Re, 600);

Beep((int)Music.So, 300);
Beep((int)Music.So, 300);
Beep((int)Music.Fa, 300);
Beep((int)Music.Fa, 300);
Beep((int)Music.Mi, 300);
Beep((int)Music.Mi, 300);
Beep((int)Music.Re, 600);

Beep((int)Music.Do, 300);
Beep((int)Music.Do, 300);
Beep((int)Music.So, 300);
Beep((int)Music.So, 300);
Beep((int)Music.La, 300);
Beep((int)Music.La, 300);
Beep((int)Music.So, 600);

Beep((int)Music.Fa, 300);
Beep((int)Music.Fa, 300);
Beep((int)Music.Mi, 300);
Beep((int)Music.Mi, 300);
Beep((int)Music.Re, 300);
Beep((int)Music.Re, 300);
Beep((int)Music.Do, 600);

如果你播放試聽會發現音效會斷斷續續,效果不是很好。等等在說明原因。

使用 SystemSounds 類別播放

//系統音效
SystemSounds.Asterisk.Play();
SystemSounds.Beep.Play();
SystemSounds.Exclamation.Play();
SystemSounds.Hand.Play();
SystemSounds.Question.Play();

我們可以 SystemSounds 類別直接播放系統內建的事件音效。不過跟我們想要有警告或提示效果來說,不太理想。

使用 SoundPlayer 類別播放 WAV 檔

var player = new SoundPlayer();
player.SoundLocation = "http://billor.chsh.chc.edu.tw/sound/ambul.wav";
player.LoadAsync();
player.PlaySync();

player.SoundLocation = "http://billor.chsh.chc.edu.tw/sound/bb.wav";
player.Load();
player.PlaySync();

player.SoundLocation = "http://billor.chsh.chc.edu.tw/sound/ambul[1].wav";
player.LoadAsync();
player.PlaySync();

player.SoundLocation = "http://billor.chsh.chc.edu.tw/sound/balarm.wav";
player.Load();
player.PlaySync();

player.SoundLocation = "http://billor.chsh.chc.edu.tw/sound/alarm1.wav";
player.LoadAsync();
player.PlaySync();

player.SoundLocation = "http://billor.chsh.chc.edu.tw/sound/dive.wav";
player.Load();
player.PlaySync();

測試此段程式,請注意音量。

類似前一個 SystemSounds 類別,SoundPlayer 類別可以播放 .wav 音效檔並且可以讀取網路上的檔案來播放。測試效果非常好。

使用 WMPLib.dll 播放 MP3 檔

看到 WAV 檔,我知道你一定會問,那 MP3 啦?當然可以,不過這需要一些些技巧,如果不借助第三方元件,我們能使用系統 WMPLib.dll來播放 MP3 檔。

WindowsMediaPlayer Player;
private void PlayFile(String url)
{
 Player = new WMPLib.WindowsMediaPlayer();
 Player.PlayStateChange +=
  new WMPLib._WMPOCXEvents_PlayStateChangeEventHandler(Player_PlayStateChange);
 Player.MediaError +=
  new WMPLib._WMPOCXEvents_MediaErrorEventHandler(Player_MediaError);
 Player.URL = url;
 Player.controls.play();
}
private void Player_PlayStateChange(int NewState)
{
 var state = (WMPLib.WMPPlayState)NewState;
 //state.Dump();

 if ((WMPPlayState)NewState == WMPPlayState.wmppsStopped)
 {
  Console.WriteLine("Stop");
  Player.close();
 }
}
private void Player_MediaError(object pMediaObject)
{
 Console.WriteLine("Error");
 Player.close();
}

我們先下載內政部警政署防空警急警報音效檔案,將路徑指定即可:

PlayFile(@"z:\2013-3-27-9-36-24-56-nf1.mp3");

測試此段程式,請注意音量。

效果百分百,讓我都有點想改成伍佰的空襲警報:

PlayFile(@"z:\伍佰-空襲警報.mp3");

效果應該能超過100分。

  • 注意:WMPLib.dll 的路徑在不同作業系統版本裡,似乎路徑不太一樣,例如,在我的 Windows 10 裡是放在開發工具的路徑下:C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\PrivateAssemblies
  • 注意:WMPLib.dll 的使用需要本機電腦有安裝 Windows Media Player。

小結

如果你在播放 WAV 或 MP3 時又去播放小蜜峰,你會發現小蜜峰的效果明明很好。一開始不好是音效不斷開開關關,音效的反應沒有程式來得快。而在播放 WAV 或 MP3 時因為音效沒有開閉問題,所以播放上就順暢很多。

單純就音效而言,在 C# 裡採用 SoundPlayer 的實作最簡單效果又好,也沒有 WMPLib.dll 那一點點限制,可說是完全沒副作用。

完整範例可由 GitHub 取得:https://github.com/kkbruce/CSharpForMusicPlay。Code for Fun!

6 則留言:

  1. 小蜜蜂的音樂應該是so me me - fa re re - do re me fa so so so....吧XD

    回覆刪除
  2. 小蜜蜂的音樂應該是so me me - fa re re - do re me fa so so so ...吧XD

    回覆刪除
    回覆
    1. 把程式 copy 回去放看看就知道了 :-D

      刪除

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。