C++ 利用MIDI库演奏《好天》

打印 上一主题 下一主题

主题 837|帖子 837|积分 2511

那些在MIDI库里徘徊的十六分音符终究没能拼成告白的主歌 我把周杰伦的《好天》写成C++的类
在每个midiEvent里埋藏故事的小黄花 调试器的断点比初恋更漫长
而青春不过是一串未导出的cmake工程文件 在堆栈溢出的夜晚
终将明白
有些旋律永久停在#pragma once的解释里
有些人永久停在未定义的引用里 大概你我的心跳终归运行在不同的时钟频率
却愿始终记得如何编译出一场永不落幕的好天                  --题记 就像在题记里说的一样,这是一个从未导出成功的工程文件。
以是如果你也想听听,可以在PowerShell里运行以下指令:
  1. git clone https://github.com/TwilightLemon/SunnyDays
  2. cd SunnyDays
  3. mkdir build
  4. cd build
  5. cmake .. -G "MinGW Makefiles"
  6. mingw32-make
  7. ./SunnyDays.exe
复制代码
没环境?巧了,她也如是说。
幸运的话能得到以下效果:

下面来简单讲讲如何利用C++和MIDI库作曲吧。
一、开始工作

1. 引入MIDI库和相关控制类

在CMakeLists.txt中:
  1. target_link_libraries(SunnyDays winmm)
复制代码
在MIDIHelper.h中:
  1. #include <windows.h>
  2. #pragma comment(lib,"winmm.lib")
复制代码
定义Scale(音阶), Instrument(乐器, 仅包括部分)等罗列。我把Drum单独提了出来。
  1. enum Scale
  2. {
  3.     X1 = 36, X2 = 38, X3 = 40, X4 = 41, X5 = 43, X6 = 45, X7 = 47,
  4.     L1 = 48, L2 = 50, L3 = 52, L4 = 53, L5 = 55, L6 = 57, L7 = 59,
  5.     M1 = 60, M2 = 62, M3 = 64, M4 = 65, M5 = 67, M6 = 69, M7 = 71,
  6.     H1 = 72, H2 = 74, H3 = 76, H4 = 77, H5 = 79, H6 = 81, H7 = 83,
  7.     LOW_SPEED = 500, MIDDLE_SPEED = 400, HIGH_SPEED = 300,
  8.     _ = 0XFF
  9. };
  10. enum Drum{
  11.     BassDrum = 36, SnareDrum = 38, ClosedHiHat = 42, OpenHiHat = 46
  12. };
  13. enum Instrument{
  14.     AcousticGrandPiano = 0, BrightAcousticPiano = 1,
  15.     ElectricGrandPiano = 2, HonkyTonkPiano = 3,
  16.     ElectricPiano1 = 4, ElectricPiano2 = 5
  17. };
复制代码
一些基础方法,包括初始化/关闭装备、设置参数、播放单个音符和播放和弦等。
  1. void initDevice();
  2. void closeDevice();
  3. void setInstrument(int channel, int instrument);
  4. void setVolume(int channel, int volume);
  5. void PlayNote(HMIDIOUT handle, UINT channel, UINT note, UINT velocity);
  6. void playChord(HMIDIOUT handle, UINT channel, UINT note1, UINT note2, UINT note3, UINT note4, UINT velocity);
  7. void playChord(HMIDIOUT handle, UINT channel, UINT note1, UINT note2, UINT note3, UINT velocity);
复制代码
在MIDIHelper.cpp中:
[code]void initDevice(){    midiOutOpen(&hMidiOut, 0, 0, 0, CALLBACK_NULL);}void closeDevice(){    midiOutClose(hMidiOut);}void setInstrument(int channel,int instrument){    if (channel > 15 || instrument > 127) return;    DWORD message = 0xC0 | channel | (instrument  15 || volume > 127) return;    DWORD message = 0xB0 | channel | (7  127 || velocity > 127) return;    DWORD message = 0x90 | channel | (note  127 || note2 > 127 || note3 > 127 || note4 > 127 || velocity > 127) return;    DWORD message1 = 0x90 | channel | (note1
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

温锦文欧普厨电及净水器总代理

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表