Click here to Skip to main content
13,260,383 members (43,942 online)
Click here to Skip to main content
Add your own
alternative version

Stats

4.5K views
362 downloads
6 bookmarked
Posted 16 Apr 2017

MIDI Piano

, 16 Apr 2017
Rate this:
Please Sign up or sign in to vote.
Midi keyboard with both mouse and computer keyboard control.

Introduction

This is the C++ 64-bit transcription of an original PowerBASIC project written by  Borje Hagsten.
https://forum.powerbasic.com/forum/user-to-user-discussions/source-code/749520-pbpiano-custom-control

The C++ version is build upon direct access to the core FLAT SDK API to produce a tiny standalone EXEcutable of only 36 Kb. This was done by eliminating as much as possible most of the CRT, using the same approach done by Matt Pietrek's LibCTiny.lib, and the different technics explained here
http://www.jose.it-berater.org/smfforum/index.php?board=345.0

This project has been also translated into WinDev p-code here
https://depot.pcsoft.fr/resource.awp?file_id=280;piano-midi-programmation-bas-niveau

About the use of the custom control



The GUI exposed a complete MIDI interface using either the mouse or the PC's keyboard to play the selected instrument.

You can press on F1 to display this information help

Using the code

This project has been done with the latest C++ Visual Studio 2017 community free version.

For the fun of it, you can enable extra skinning by editing the lines of code shown bellow (at the end of 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);
          }
//    }
//}

then with the WinLIFT magic, the whole GUI will change to this

Points of Interest

You can reduce drastically the size of your 64-bit code if you follow these few steps.

1 - Always use direct call to the core FLAT API whenever available.
2 - Prefer procedural code when there is no need to use a class to achieve the same thing.
3 - Use explicit linking rather than implicit.
4 - Get free of the runtime Library, using Multi-threaded (/MT) in the code generation.

And here is an example on how to use explicit linking to MSVCRT to achieve ultimate granularity

#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);
}

The end

Enjoy playing midi with this tiny piece of { unsafe } code ;)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

zapsolution
Software Developer zapsolution
France France
I am a low level SDK programmer, focusing mainly on graphic imaging and multimedia applications.
I am using several languages, including C, C++, PowerBASIC, WinDev.
I wrote also a few demos in C#, but i never used DotNET in real code production.

You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.171114.1 | Last Updated 16 Apr 2017
Article Copyright 2017 by zapsolution
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid