65.9K
CodeProject 正在变化。 阅读更多。
Home

MIDI 钢琴

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (6投票s)

2017年4月16日

CPOL

1分钟阅读

viewsIcon

15242

downloadIcon

1167

使用鼠标和电脑键盘控制的 MIDI 键盘

引言

这是 C++ 64 位版本的原始 PowerBASIC 项目的移植,由 Borje Hagsten 编写。

C++ 版本是基于对核心 FLAT SDK API 的直接访问构建的,从而产生一个仅为 36 KB 的微型独立 EXE 可执行文件。这是通过消除尽可能多的 CRT,使用 Matt Pietrek 的 LibCTiny.lib 所采用的相同方法,以及 此处 解释的不同技术来实现的。

该项目也已被翻译成 WinDev p-code 此处

关于自定义控件的使用

GUI 使用鼠标或 PC 键盘暴露了一个完整的 MIDI 接口来播放所选乐器。

您可以按 F1 显示此信息帮助

Using the Code

该项目是使用最新的 C++ Visual Studio 2017 community 免费版本完成的。

为了好玩,您可以编辑以下代码行(在 Main.cpp 的末尾)来启用额外的 皮肤

//if (skInitEngine (L"Reader.sks", L"")) {               // these 2 lines enable or disable
//    if (skSkinWindow(gP.hMain, (WCHAR*) SYSTOOLTIP)) { // the use of the WinLIFT skin engine.
          // Show the main window
          ShowWindow(gP.hMain, nCmdShow);
          UpdateWindow(gP.hMain);
          while (GetMessage(&msg, NULL, 0, 0)) {
              TranslateMessage(&msg);
              DispatchMessage(&msg);
          }
//    }
//}

然后,通过 WinLIFT 的魔力,整个 GUI 将变为这样

关注点

如果您遵循以下几个步骤,可以大大减小 64 位代码的尺寸

  1. 尽可能使用对核心 FLAT API 的直接调用
  2. 如果不需要使用类来实现相同的功能,则优先使用过程式代码
  3. 使用显式链接而不是隐式链接
  4. 摆脱运行时库,在代码生成中使用 多线程 (/MT)

这里有一个关于如何使用显式链接到 MSVCRT 以实现最终粒度的示例

#define long_proc typedef long (__stdcall *zProc)
#define void_proc typedef void (__stdcall *zProc)
#define double_proc typedef double (__stdcall *zProc)

#define M_LOG2E 1.44269504088896340736 

HMODULE MSVCRT() {
    static HMODULE hModule;
    if (hModule == 0) { hModule = LoadLibrary(L"MSVCRT"); }
    return hModule;
}

double log2(IN double X) {
    double l2 = 0;
    HMODULE hModule = MSVCRT();
    if (hModule) {
        double_proc (double);
        zProc hProc = (zProc) GetProcAddress(hModule, "log");
        if (hProc) { l2 = hProc(X) * M_LOG2E; }
    }
    return l2;
}

void RandoMize(IN DWORD seed) {
    HMODULE hModule = MSVCRT();
    if (hModule) {
        void_proc (DWORD);
        zProc hProc = (zProc) GetProcAddress(hModule, "srand");
        if (hProc) { hProc(seed); }
    }
}

long Rand() {
    long nRand = 0;
    HMODULE hModule = MSVCRT();
    if (hModule) {
        long_proc ();
        zProc hProc = (zProc) GetProcAddress(hModule, "rand");
        if (hProc) { nRand = hProc(); }
    }
    return nRand;
}

size_t rnd(IN long nMin, IN long nMax) { // QWORD
    double dblRange = nMax - nMin;
    double dblMaxFactor = dblRange / RAND_MAX;
    double dblRandomNumber = (double) Rand();
    return (size_t) (nMin + dblMaxFactor * dblRandomNumber);
}

结束

尽情享受使用这段 { 不安全 } 代码来播放 MIDI 吧。;)

© . All rights reserved.