1. 程式人生 > >調用API讓聲卡發出聲音

調用API讓聲卡發出聲音

help sci ole 搖滾 reat all hang ras con

1.定義一個枚舉,樂器類型
#region 樂器定義
public enum MusicNo:uint
{ /// <summary>
/// //大鋼琴
/// </summary>
AcousticGrandPiano = 0,
/// <summary>
///明亮的鋼琴
/// </summary>
BrightAcousticPiano = 1,
/// <summary>
///電子琴
/// </summary>
ElectricGrandPiano = 2,

/// <summary>
///酒吧鋼琴
/// </summary>
HonkyTonkPiano = 3,
/// <summary>
///柔和鋼琴
/// </summary>
RhodesPiano = 4,
/// <summary>
///合唱效果鋼琴
/// </summary>
ChorusedPiano = 5,
/// <summary>
///羽管鍵琴
/// </summary>
Harpsichord = 6,
/// <summary>
///克拉維科特琴
/// </summary>
Clavichord = 7,
/// <summary>
///鋼片琴
/// </summary>
Celesta = 8,
/// <summary>
///鐘琴
/// </summary>
Glockenspiel = 9,
/// <summary>
///八音盒
/// </summary>
Musicbox = 10,
/// <summary>
///顫音琴
/// </summary>
Vibraphone = 11,
/// <summary>
///馬林巴
/// </summary>
Marimba = 12,
/// <summary>
///木琴
/// </summary>
Xylophone = 13,
/// <summary>
///管鐘
/// </summary>
TubularBells = 14,
/// <summary>
///大揚琴
/// </summary>
Dulcimer = 15,
/// <summary>
/// 擊桿風琴
/// </summary>
HammondOrgan = 16,
/// <summary>
/// 打擊式風琴
/// </summary>
PercussiveOrgan = 17,
/// <summary>
/// 搖滾風琴
/// </summary>
RockOrgan = 18,
/// <summary>
/// 教堂風琴
/// </summary>
ChurchOrgan = 19,
/// <summary>
/// 簧管風琴
/// </summary>
ReedOrgan = 20,
/// <summary>
/// 手風琴
/// </summary>
Accordian = 21,
/// <summary>
/// 口琴
/// </summary>
Harmonica = 22,
/// <summary>
///探戈手風琴
/// </summary>
TangoAccordian = 23,
/// <summary>
/// 尼龍弦吉他
/// </summary>
AcousTicGuitarNylon = 24,
/// <summary>
/// 鋼弦吉他
/// </summary>
AcousTicGuitarSteel = 25,
/// <summary>
/// 爵士電吉他
/// </summary>
ElectricGuitarJazz = 26,
/// <summary>
/// 清音電吉他
/// </summary>
ElectricGuitarClean = 27,
/// <summary>
/// 悶音電吉他
/// </summary>
ElectricGuitarMuted = 28,
/// <summary>
/// 加驅動效果的電吉他
/// </summary>
OverdrivenGuitar = 29,
/// <summary>
/// 加失真效果的電吉他
/// </summary>
DistortionGuitar = 30,
/// <summary>
/// 吉他和音
/// </summary>
GuitarHarmonics = 31,
/// <summary>
///大貝司(聲學貝司)
/// </summary>
AcousticBass = 32,
/// <summary>
/// 電貝司(指彈)
/// </summary>
ElectricBassfinger = 33,
/// <summary>
/// 電貝司(撥片)
/// </summary>
ElectricBassPick = 34,
/// <summary>
/// 無品貝司
/// </summary>
FretlessBass = 35,
/// <summary>
/// 掌擊Bass 1
/// </summary>
SlapBass1 = 36,
/// <summary>
/// 掌擊Bass 2
/// </summary>
SlapBass2 = 37,
/// <summary>
/// 電子合成Bass 1
/// </summary>
SynthBass1 = 38,
/// <summary>
/// 電子合成Bass 2
/// </summary>
SynthBass2 = 39,
/// <summary>
/// 小提琴
/// </summary>
Violin = 40,
/// <summary>
/// 中提琴
/// </summary>
Viola = 41,
/// <summary>
/// 大提琴
/// </summary>
Cello = 42,
/// <summary>
/// 低音大提琴
/// </summary>
Contrabass = 43,
/// <summary>
///弦樂群顫音音色
/// </summary>
TremoloStrings = 44,
/// <summary>
///弦樂群撥弦音色
/// </summary>
PizzicatoStrings = 45,
/// <summary>
///豎琴
/// </summary>
OrchestralHarp = 46,
/// <summary>
/// 定音鼓
/// </summary>
Timpani = 47,
/// <summary>
///弦樂合奏音色1
/// </summary>
StringEnsemble1 = 48,
/// <summary>
///弦樂合奏音色2
/// </summary>
StringEnsemble2 = 49,
/// <summary>
///合成弦樂合奏音色1
/// </summary>
SynthStrings1 = 50,
/// <summary>
///合成弦樂合奏音色2
/// </summary>
SynthStrings2 = 51,
/// <summary>
///人聲合唱“啊”
/// </summary>
ChoirAahs = 52,
/// <summary>
///人聲“嘟”
/// </summary>
VoiceOohs = 53,
/// <summary>
///合成人聲
/// </summary>
SynthVoice = 54,
/// <summary>
///管弦敲擊齊奏
/// </summary>
OrchestraHit = 55,
/// <summary>
///小號
/// </summary>
Trumpet = 56,
/// <summary>
///長號
/// </summary>
Trombone = 57,
/// <summary>
///大號
/// </summary>
Tuba = 58,
/// <summary>
///加弱音器小號
/// </summary>
MutedTrumpet = 59,
/// <summary>
///法國號(圓號)
/// </summary>
FrenchHorn = 60,
/// <summary>
///銅管組(銅管樂器合奏音色)
/// </summary>
BrassSection = 61,
/// <summary>
///合成銅管音色1
/// </summary>
SynthBrass1 = 62,
/// <summary>
///合成銅管音色2
/// </summary>
SynthBrass2 = 63,
/// <summary>
///高音薩克斯風
/// </summary>
SopranoSax = 64,
/// <summary>
///次中音薩克斯風
/// </summary>
AltoSax = 65,
/// <summary>
///中音薩克斯風
/// </summary>
TenorSax = 66,
/// <summary>
///低音薩克斯風
/// </summary>
BaritoneSax = 67,
/// <summary>
///雙簧管
/// </summary>
Oboe = 68,
/// <summary>
///英國管
/// </summary>
EnglishHorn = 69,
/// <summary>
///巴松(大管)
/// </summary>
Bassoon = 70,
/// <summary>
///單簧管(黑管)
/// </summary>
Clarinet = 71,
/// <summary>
///短笛
/// </summary>
Piccolo = 72,
/// <summary>
///長笛
/// </summary>
Flute = 73,
/// <summary>
///豎笛
/// </summary>
Recorder = 74,
/// <summary>
///排簫
/// </summary>
PanFlute = 75,
/// <summary>
///[中文名稱暫缺]
/// </summary>
BottleBlow = 76,
/// <summary>
///日本尺八
/// </summary>
Shakuhachi = 77,
/// <summary>
///口哨聲
/// </summary>
Whistle = 78,
/// <summary>
///奧卡雷那
/// </summary>
Ocarina = 79,
/// <summary>
///合成主音1(方波)
/// </summary>
Lead1Square = 80,
/// <summary>
///合成主音2(鋸齒波)
/// </summary>
Lead2Sawtooth = 81,
/// <summary>
///合成主音3
/// </summary>
Lead3CaliopeLead = 82,
/// <summary>
///合成主音4
/// </summary>
Lead4ChiffLead = 83,
/// <summary>
///合成主音5
/// </summary>
Lead5Charang = 84,
/// <summary>
///合成主音6(人聲)
/// </summary>
Lead6Voice = 85,
/// <summary>
///合成主音7(平行五度)
/// </summary>
Lead7Fifths = 86,
/// <summary>
///合成主音8(貝司加主音)
/// </summary>
Lead8BassLead = 87,
/// <summary>
///合成音色1(新世紀)
/// </summary>
Pad1NewAge = 88,
/// <summary>
///合成音色2 (溫暖)
/// </summary>
Pad2Warm = 89,
/// <summary>
///合成音色3
/// </summary>
Pad3Polysynth = 90,
/// <summary>
///合成音色4 (合唱)
/// </summary>
Pad4Choir = 91,
/// <summary>
///合成音色5
/// </summary>
Pad5Bowed = 92,
/// <summary>
///合成音色6 (金屬聲)
/// </summary>
Pad6Metallic = 93,
/// <summary>
///合成音色7 (光環)
/// </summary>
Pad7Halo = 94,
/// <summary>
///合成音色8
/// </summary>
Pad8Wweep = 5,
/// <summary>
///合成效果 1 雨聲
/// </summary>

FX1Rain = 96,
/// <summary>
///合成效果 2 音軌
/// </summary>
FX2Soundtrack = 97,
/// <summary>
///合成效果 3 水晶
/// </summary>
FX3Crystal = 98,
/// <summary>
///合成效果 4 大氣
/// </summary>
FX4Atmosphere = 99,
/// <summary>
///合成效果 5 明亮
/// </summary>
FX5Brightness = 100,
/// <summary>
///合成效果 6 鬼怪
/// </summary>
FX6Goblins = 101,
/// <summary>
///合成效果 7 回聲
/// </summary>
FX7Echoes = 102,
/// <summary>
///合成效果 8 科幻
/// </summary>
FX8Scifi = 103,
/// <summary>
///西塔爾(印度)
/// </summary>
Sitar = 104,
/// <summary>
///班卓琴(美洲)
/// </summary>
Banjo = 105,
/// <summary>
///三昧線(日本)
/// </summary>
Shamisen = 106,
/// <summary>
///十三弦箏(日本)
/// </summary>
Koto = 107,
/// <summary>
///卡林巴
/// </summary>
Kalimba = 108,
/// <summary>
///風笛
/// </summary>
Bagpipe = 109,
/// <summary>
///民族提琴
/// </summary>
Fiddle = 110,
/// <summary>
///山奈
/// </summary>
Shanai = 111,
/// <summary>
/// 叮當鈴
/// </summary>
TinkleBell = 112,
/// <summary>
///[中文名稱暫缺]
/// </summary>
Agogo = 113,
/// <summary>
///鋼鼓
/// </summary>
SteelDrums = 114,
/// <summary>
///木魚
/// </summary>
Woodblock = 115,
/// <summary>
///太鼓
/// </summary>
TaikoDrum = 116,
/// <summary>
///通通鼓
/// </summary>
MelodicTom = 117,
/// <summary>
///合成鼓
/// </summary>
SynthDrum = 118,
/// <summary>
///銅鈸
/// </summary>
ReverseCymbal = 119,
/// <summary>
///吉他換把雜音
/// </summary>
GuitarFretNoise = 120,
/// <summary>
///呼吸聲
/// </summary>
BreathNoise = 121,
/// <summary>
///海浪聲
/// </summary>
Seashore = 122,
/// <summary>
///鳥鳴
/// </summary>
BirdTweet = 123,
/// <summary>
///電話鈴
/// </summary>
TelephoneRing = 124,
/// <summary>
///直升機
/// </summary>
Helicopter = 125,
/// <summary>
///鼓掌
/// </summary>
Applause = 126,
/// <summary>
/// Gunshot
/// </summary>
Gunshot = 127,
}

2.callback
public enum OpenFlag:uint
{
CALLBACK_NULL = 0x00000000,//{當 dwCallback 是 nil 時指定}
CALLBACK_WINDOW = 0x00010000,//{當 dwCallback 是窗口句柄時指定}
CALLBACK_FUNCTION = 0x0003000,// {當 dwCallback 是函數指針時指定}
}

3.打開設備返回值
public enum OpenMsg:uint
{
MMSYSERR_BADDEVICEID = 2,//{設備ID超界}
MMSYSERR_ALLOCATED = 4, //{指定的資源已被分配}
MMSYSERR_NOMEM = 7, //{不能分配或鎖定內存}
MIDIERR_NOMAP = 66,//{當前沒有 MIDI 映射, 只有打開映射程序才可能發生}
MIDIERR_NODEVICE = 68,//{MIDI 映射中的端口不存在, 只有打開映射程序才可能發生}
}
#endregion

4.midi幫助類
public class MIDIHelper
{
#region API
[DllImport("winmm.dll")]
static extern uint midiOutOpen(out IntPtr lphMidiOut, uint uDeviceID, IntPtr dwCallback, IntPtr dwInstance, uint dwFlags);//打開數字樂器接口輸出
[DllImport("winmm.dll")]
static extern uint midiOutClose(IntPtr hMidiOut);//關閉數字樂器接口輸出
[DllImport("winmm.dll")]
static extern uint midiOutShortMsg(IntPtr hMidiOut, uint dwMsg);//發送數字樂器接口消息

#endregion

5.定義變量
#region 自定義變量
bool isOpen = false;
IntPtr DeviceHandle = IntPtr.Zero;
public bool Opend => isOpen;

#endregion
#region 方法

6.打開設備。
public void Open()
{
IntPtr device;//此處後續要用
uint hand = midiOutOpen(out device, 0, IntPtr.Zero, IntPtr.Zero, 0);
isOpen = hand == 0;
DeviceHandle = device;
}
/// <summary>
/// 播放聲音返回0表示成功!621表示設備未打開
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>

public uint Play(uint msg,int time)//播放,嘗試了很多寫法,發現msg * 256 + 0x00403B90;基本正常,百度百科的方法聲音沙啞(msg*256+144+volume*655536+channel)
{
if (isOpen && DeviceHandle != IntPtr.Zero)
{
uint data = msg * 256 + 0x00403B90;
Console.WriteLine(data);
uint ms = midiOutShortMsg(DeviceHandle,data);
System.Threading.Thread.Sleep(time);
return msg;
}
else
return 621;
}
public uint ChangeInstruments(MusicNo musicNo)//改變樂器
{
return midiOutShortMsg(DeviceHandle, Convert.ToUInt32(192 + (uint)musicNo * 256));
}
public void Close()//關閉設備
{
uint msg = midiOutClose(DeviceHandle);
}
#endregion
}

接下來看看調用例子:

其中play方法中的數據12,50,...............摘自網上

MIDIHelper helper = new Gaofajin.Shell.MIDIHelper();
helper.Open();
if (helper.Opend)
{
helper.ChangeInstruments(Gaofajin.Shell.MusicNo.Piccolo);

helper.Play(12, 250);

helper.Play(12, 250);

helper.Play(15, 250);

helper.Play(17, 250);

helper.Play(19, 1000);

helper.Play(24, 700);

helper.Play(19, 250);

helper.Play(22, 200);

helper.Play(00, 250);

helper.Play(22, 900);

helper.Play(19, 400);

helper.Play(17, 400);

helper.Play(19, 400);

helper.Play(22, 400);

helper.Play(24, 250);

helper.Play(22, 250);

helper.Play(19, 1500);

helper.Play(00, 300);

helper.Play(19, 1000);

helper.Play(24, 700);

helper.Play(19, 250);

helper.Play(22, 200);

helper.Play(00, 250);

helper.Play(22, 900);

helper.Play(19, 400);

helper.Play(17, 400);

helper.Play(19, 400);

helper.Play(22, 400);

helper.Play(24, 250);

helper.Play(22, 250);

helper.Play(19, 1000);

helper.Play(00, 300);

helper.Play(19, 400);

helper.Play(17, 250);

helper.Play(15, 600);

helper.Play(00, 100);

helper.Play(15, 250);

helper.Play(17, 400);

helper.Play(19, 400);

helper.Play(17, 100);

helper.Play(00, 250);

helper.Play(17, 500);

helper.Play(00, 100);

helper.Play(17, 400);

helper.Play(15, 250);

helper.Play(12, 250);

helper.Play(00, 100);

helper.Play(12, 250);

helper.Play(15, 250);

helper.Play(17, 400);

helper.Play(19, 400);

helper.Play(22, 600);

helper.Play(24, 250);

helper.Play(22, 400);

helper.Play(19, 250);

helper.Play(17, 250);

helper.Play(15, 600);

helper.Play(17, 600);

helper.Play(19, 400);

helper.Play(17, 150);

helper.Play(00, 250);

helper.Play(17, 600);

helper.Play(15, 600);

helper.Play(12, 300);

helper.Play(00, 100);

helper.Play(12, 250);

helper.Play(15, 250);

helper.Play(17, 250);

helper.Play(19, 400);

helper.Play(22, 250);

helper.Play(24, 700);

helper.Play(00, 100);

helper.Play(24, 500);

}
helper.Close();

調用API讓聲卡發出聲音