So basically, I've been trying to record the MIDI inputs from a piano keyboard of mine, which is connected to my soundcard's game port.
However, I have been having trouble actually getting any MIDI input of any kind (or so I think). I'm not very well versed in MIDI (or actually most of anything that's programming), so bare with me.
Hopefully it's just something silly that I didn't understand. Anyways, this is the code I have so far. I've been using this to get feedback on what kind of values everything gives out, but I just can't get MIM_DATA to be the value for uMsg (which is what I need in order to know that my computer is indeed reading my piano inputs).
Code:
//Link winmm library
#include <windows.h>
#include <stdio.h>
#include <mmsystem.h>
#include <cstdlib>
#include <iostream>
#include <conio.h> /* include for kbhit() and getch() functions */
using namespace std;
void CALLBACK midiCallback(HMIDIIN handle, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
switch ( uMsg )
{
case MIM_OPEN:
cout << "-----OPENED.-----" << endl;
break;
case MIM_CLOSE:
cout << "-----EVERYTHING IS CLOSING.-----" << endl;
break;
case MIM_DATA:
cout << "-----APPARENTLY THERE IS DATA.-----" << endl; //I'm hoping to see this line...
break;
case MIM_LONGDATA:
cout << "-----LONGDATA'D.-----" << endl;
break;
case MIM_ERROR:
cout << "-----ERROR.-----" << endl;
break;
case MIM_LONGERROR:
cout << "-----LONGERROR. EVEN WORSE.-----" << endl;
break;
}
cout << "dwInstance is " << dwInstance << endl;
cout << "Handle is " << handle << endl;
cout << "dwParam1 is " << dwParam1 << endl; //dwParam1 is the bytes of the MIDI Message packed into an unsigned long
cout << "dwParam2 is " << dwParam2 << endl; //dwParam2 is the timestamp of key press
cout << "uMsg is " << uMsg << endl;
cout << "-----" << endl;
}
void MidiThing(){
MIDIINCAPS mic;
unsigned long result;
HMIDIIN inHandle;
int ckey; // storage for the current keyboard key being pressed
unsigned long iNumDevs, i;
iNumDevs = midiInGetNumDevs(); /* Get the number of MIDI In devices in this computer */
/* Go through all of those devices, displaying their names */
for (i = 0; i < iNumDevs; i++)
{
/* Get info about the next device */
if (!midiInGetDevCaps(i, &mic, sizeof(MIDIINCAPS)))
{
/* Display its Device ID and name */
printf("Device ID #%u: %s\r\n", i, mic.szPname);
}
}
cout << "These are the only available devices...?" << endl;
cout << endl;
// Open the default MIDI In device.
result = midiInOpen(&inHandle, 0, (DWORD)midiCallback, 0, CALLBACK_FUNCTION);
if (result)
{
printf("There was an error opening the default MIDI In device!\r\n");
}
else
{
midiInStart(inHandle);
cout << endl;
cout << "midiInStart has been called." << endl;
}
cout << endl;
cout << "The unsigned long, result, value was " << result << endl;
cout << MIM_OPEN << " is MIM_OPEN's value" << endl;
cout << MIM_CLOSE << " is MIM_CLOSE's value" << endl;
cout << MIM_DATA << " is MIM_DATA's value" << endl;
cout << endl;
printf("Press \"q\" to quit.\n");
while (1) {
if (kbhit()) {
ckey = getch();
if (ckey == 'q')
{
cout << "Stopped." << endl;
cout << endl;
break;
}
}
}
midiInStop(inHandle);
midiInReset(inHandle);
midiInClose(inHandle);
cout << endl;
cout << "Lines are done twice because midiCallback " << endl;
cout << "is called when midiInClose is called...?" << endl;
cout << endl;
cout << inHandle << " was the MIDIIN handle." << endl;
cout << "Stuff's closed now." << endl;
cout << endl;
cout << endl;
cout << endl;
}
int main(int argc, char *argv[])
{
MidiThing();
system("PAUSE");
return EXIT_SUCCESS;
}
For the midiInStart function, I will admit I'm not exactly sure what to do with it.
The for loop in the middle of program where you press q to quit has no purpose for being there... but I uhh, left it in anyway.
EDIT: Okay wow. I just got it to work (kinda lame considering I've been stuck for about 3 hours until finally deciding to post here, and then finding the answer 5 minutes after). It turns out that the line
Code:
result = midiInOpen(&inHandle, 0, (DWORD)midiCallback, 0, CALLBACK_FUNCTION);
has to be written like
Code:
result = midiInOpen(&inHandle, 0, (DWORD)midiCallback, NULL, CALLBACK_FUNCTION);
Though I've solved my main issue, Dev-C++ gives me a warning for using NULL here though. Also, I'd still like to know what exactly midiInStart does and how to set up a buffer with it.
http://msdn.microsoft.com/en-us/libr...30(VS.85).aspx
The page I linked tells me that I should send at least one buffer to the driver before recording, but I'm not exactly sure how.