[C#] 簡單產生播放MIDI音樂的方法 (midiOutShortMsg)

  • 2864
  • 0
  • 2014-01-12

摘要:[C#] 簡單產生播放MIDI音樂的方法 (midiOutShortMsg)

前言

 


早期電腦傳輸速率、儲存空間不發達的時候,MIDI是很流通方便的格式,

它的特色就是只儲存音樂的音長、音高等數據,然後交由該發聲裝置的音效設備發出聲響,

所以不同的設備所發出來的MIDI聲音都會略有不同,甚至可以匯入特殊音源,做出極擬真的音效,

無論如何,最基礎的幾個音響效果,例如鋼琴等等,普通人的木耳(例如我)聽不出明顯差別,

如果要製作簡單的音效已經足夠了

 

 

建立MIDI類別

 


要呼叫電腦讓送出MIDI訊息需要匯進一些必要參照,

做成一個類別,然後調用方法,程式碼如下

 


using System.Runtime.InteropServices;
class Midi
{
    [DllImport("winmm.dll")]
    private extern static int midiOutOpen(out int lphMidiOut, int uDeviceID, int dwCallback, int dwInstance, int dwFlags);
    [DllImport("winmm.dll")]
    private extern static int midiOutClose(int lphMidiOut);
    [DllImport("winmm.dll")]
    public extern static int midiOutShortMsg(int lphMidiOut, int dwMsg);
    public int midiOut;
    public Midi()
    {
        if (midiOutOpen(out midiOut, -1, 0, 0, 0) != 0)
        {
            throw new Exception("無法打開MIDI設備");
        }
    }
    ~Midi()
    {
        if (midiOut != 0)
        {
            midiOutClose(midiOut);
        }
    }
    public void Instrument(int instrument)
    {
        midiOutShortMsg(midiOut, instrument << 8 | 0xC0);
    }
    public void Play(int note)
    {
        midiOutShortMsg(midiOut, volumn << 16 | note << 8 | 0x90);
    }
    public void Stop(int note)
    {
        midiOutShortMsg(midiOut, note << 8 | 0x90);
    }
}

 

這是極度精簡化,只求能播放的樣子,

首先三個必要的方法分別是開啟MIDI設備、關閉MIDI設備、發送短訊息,

開啟MIDI設備會向電腦系統要求設備的授權,正常情況下都是可以取的到,

但只能取一個,第二個要再取就會失敗了

 

 

淺談midiOutShortMsg

 


再來就是看起來有點神祕的midiOutShortMsg,正常沒研究過的光是看到那個參數應該就昏頭了,

因為這篇主要就是播放懶人包,所以先講怎麼用,關於MIDI的訊息可以再發幾篇詳細的

 

void Instrument(int) 就是樂器,數值必須要在0~127之間,

各樂器的音色請參考 維基百科 http://zh.wikipedia.org/wiki/General_MIDI

 

void Play(int) 就是播放,數值必須要在0~127之間,

通常過低和過高的音人耳聽不太到,給個比較實際的數據,常見的鋼琴是88鍵,

而鋼琴的第一個音落在MIDI的第十個音上,換言之,

MIDI音效前端9個音不在鋼琴內,末端31個音不在鋼琴內,這樣應該就比較有概念了

彈奏下去的音響因樂器而異,如果播放後沒有停止就再度播放會把前一個先關掉再播放

 

void Stop(int) 自然就是停止了,數值也是在0~127之間,

有播當然就要有關,如果是鋼琴之類的觸擊音響人耳聽起來沒什麼差別,

但是其他樂器,例如小提琴,不關掉的話可是會無止盡的播下去的

所以建議在播放時,都要存下該音高

 

 

本篇的MIDI播放介紹先到此為止,希望能幫上有需要的朋友

 

對了提醒一下,雖然基本上C#裡都可以使用這個方法播出聲音,

包括Windows Store App,但是不能上架喔!官方不允許叫用這個API