首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WPF 應用程式中的 MIDI 音樂播放:基於 NAudio 庫的完整實作

     編輯:關於.NET

每台 PC 內建一支「16 人樂隊」——符合 MIDI(樂器數位介面)標準的電子音樂合成器,雖然常被忽視,卻是 Windows 多媒體功能中極具潛力的組件。.NET Framework 本身不支援 MIDI,但在 WPF 或 WinForms 中可透過 P/Invoke 或外部庫(如 NAudio)來存取。

NAudio 庫簡介

CodePlex 上的 NAudio 聲音庫提供了完整的 MIDI 支援。本文使用 NAudio 1.3.8 版,可從 codeplex.com/naudio 下載庫及原始碼。專案需引用 NAudio.dll 並引入命名空間:

using NAudio.Midi;

基礎範例:播放單一音符

播放 1 秒長的中央 C(鋼琴音色):

MidiOut midiOut = new MidiOut(0);
midiOut.Send(MidiMessage.StartNote(60, 127, 0).RawData);
Thread.Sleep(1000);
midiOut.Send(MidiMessage.StopNote(60, 0, 0).RawData);
Thread.Sleep(1000);
midiOut.Close();
midiOut.Dispose();
  • MidiOut(0):選擇 ID 為 0 的預設 MIDI 合成器
  • StartNote(60, 127, 0):音符 60(中央 C),力度 127(最大),通道 0
  • Thread.Sleep:簡易計時(UI 執行緒中應避免使用)

複音與和弦處理

同時發送多個 StartNote 即可實現複音。C 大調和弦範例:

midiOut.Send(MidiMessage.StartNote(60, 127, 0).RawData);  // C4
midiOut.Send(MidiMessage.StartNote(64, 127, 0).RawData);  // E4
midiOut.Send(MidiMessage.StartNote(67, 127, 0).RawData);  // G4
midiOut.Send(MidiMessage.StartNote(72, 127, 0).RawData);  // C5
// ...對應的 StopNote

樂器切換與通道

  • 樂器切換:MidiMessage.ChangePatch(47, 0) 切換至定音鼓(General MIDI 標準中第 48 號樂器,從 0 起算)
  • 16 通道機制:每通道獨立關聯樂器,通道 9 為打擊樂專用通道
  • 打擊樂範例:MidiMessage.StartNote(56, 127, 9) 播放鈴鐺聲音

基於 XAML 的 MIDI 字串格式

為貼合 WPF/XAML 風格,作者設計了 MIDI 字串 格式,可直接在 XAML 嵌入樂曲片段:

  • 音符:C4、C#3、Eb4(大寫 A-G + 升降號 + 八度號)
  • 休止符:R
  • 持續時間:1/4(四分音符)、/8(八分音符,分子預設 1)
  • 音長:-3/16(以減號前綴區分)
  • 樂器:I40(小提琴)、V64(音量)、T120(節拍 120 BPM)
  • 和弦:(C4 E4 G4 C5)
  • 多通道:| 分隔,如 T100 I56 G4 ... | T200 I40 ...
  • 打擊通道:通道內含 P 標記,如 P56(鈴鐺)

經典「Charge!」號角曲範例:

"T100 I56 G4 /12 C5 E5 G5 3/16 -3/32 E5 /16 G5 /2"

MidiStringPlayer 元件

Petzold.Midi 庫提供 MidiStringPlayer 類別(繼承 FrameworkElement),可嵌入 XAML 視覺樹:

<midi:MidiStringPlayer Name="player"
    PlayOnLoad="True"
    MidiString="{Binding ElementName=chargeButton, Path=Tag}" />

屬性與事件:

  • MidiString:樂曲字串
  • PlayOnLoad:載入時自動播放
  • Play()/Stop():控制播放
  • IsPlaying:唯讀狀態
  • Ended:播放完成事件
  • Failed:語法錯誤事件(含位移與說明)

計時器限制與範例程式

目前使用 DispatcherTimer(UI 執行緒,約 60Hz 精度),簡單音樂足夠,複雜節奏可能不準。NAudio 尚未封裝 Win32 高解析度 MIDI 計時器。範例包含兩個 WPF 程式:

  • MusicComposer:互動式編輯 MIDI 字串
  • WpfMusicDemo:預載多首經典樂曲(貝多芬第五、巴哈 D 小調托卡塔等)

下載範例碼:https://code.msdn.microsoft.com/mag201003UIFrontiers

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved