作者声明:
1.由于不清楚含有引用内容的文章是否能划为原创,所以就果断标记为原创啦。
2.如果您有强烈的欲望去转载本文,希望您能在文章醒目处注明原文地址,谢谢。
正文:
寒假期间,甚为无聊。深思熟虑之下,决定拓宽一下编程知识面。由于本人音乐细胞少的要死,所以便选中了music(哪里不会学哪里)。
在之前的学习过程中,我掌握了基于C语言的控制台编程。控制台有个大毛病,丑。为了不跑题,我就只吐槽它的声音表现能力了。其实,也不能说是控制台,应该是TC框架。在如此先进的现在,TC的许多库函数和能力已经被MS给禁用了。这也导致,我的时间消耗量增加了许多。
相信,大部分中国学生都是先在TC框架下编程,你用了好长时间学会了使用一些简单的I/O函数,然后自己加工数据,生成一个安静的黑乎乎的或许功能强大的exe。当你生产了一堆这样的程序后,总有一天你会意识到,我他喵的要声音!然后第一反应,找库函数。啊,有个sound(),结果不能用。啊,有个Beep(),结果是蜂鸣器。啊,playSound(),只能播放音频文件。啊,Dsp编程,太难。啊,DirectSound,还是难。最后,你在重重雾霾之中看到了一丝亮光,MIDI。
MIDI难吗,我觉得也挺难的。但是它符合我的要求,让你do(C)你就do。MIDI((Musical Instrument Digital Interface)的一些概念性知识,这里就不赘述了。MIDI功能强大,属于系统底层API。MIDI发声的方式是驱动声卡,它能演绎出很多的音色,如果你够强,自己写个交响曲我想也是可以的。下面列出我在网上找的播放MIDI音频的过程:
① 播放MIDI音频前应先查询系统是否具备播放MIDI音频的设备
② 读出RIFF格式的MIDI文件
③ 检查MIDI音频输出设备的性能
④ 打开MIDI输出设备
⑤ 打开音频输出设备,获得设备句柄后,生成MIDI音频信息头结构
⑥ 发送MIDI消息和发送记录为结构MIDIHDR的系统特有消息,即播放MIDI音频
⑦ 播放结束后清除已准备好的MIDI音频数据块结构MIDIHDR,释放分配的资源
⑧ 关闭MIDI音频输出设备
很明显,这套流程是假设有一个MIDI文件的,这怎么算是基础呢?去除2、3甚至是1。然后你发现,就是//开-放音乐-关//,简单多了。下面给出一段网友codexy写的代码:
#include
#include
int main(void)
{
unsigned long result;
HMIDIOUT handle;
result=midiOutOpen(&handle,0,0,0,CALLBACK_NULL);
if(result)
{
printf("There is an error opening the default MIDI out device!/n");
}
/* Output the C note (ie, sound the note) */
midiOutShortMsg(handle, 0x00403C90);
Sleep(2000);
/* Output the E note */
midiOutShortMsg(handle, 0x00404090);
Sleep(2000);
/* Output the G note */
midiOutShortMsg(handle, 0x00404390);
Sleep(2000);
/* Here you should insert a delay so that you can hear the notes sounding */
/* Now let's turn off those 3 notes */
// You should know this bad way to turn off MIDI, maybe it's wrong, but you don't hear the sound. yes?
midiOutShortMsg(handle, 0x00003C90);
midiOutShortMsg(handle, 0x00004090);
midiOutShortMsg(handle, 0x00004390);
/* Close the MIDI device */
midiOutClose(handle);
return 0;
}
或许,你会为其中的一些16进制数字感到迷惑,那么你应该去了解一下MIDI API函数和MIDI规范。最后给出一个网址,也是网友codexy的博文里引用到的:
http://www.giordanobenicchi.it/midi-tech/lowmidi.htm
谢谢阅读!