How to send just one byte?


#1

I am working on a simple application to send out sysex packages on the midi out connection of my pc. It works great with complete sysex packages. Since the purpose of this application is for debuggin bootloader code in external hardware it would be very usefull if i could single step true the transmission of the sysex file. The problem is that when I transmit single bytes they are only transfered if they are midi status bytes like 0xF0 and 0xF7. The bytes in between are not showing up on the midi connection. I use the sendMessageNow(message) function with a single byte message. Any ideas on how to get this to work?

Thanks in advance,
John


#2

Sorry, it’s not designed to do anything as low-level as that! It might not even be possible, because I think that the actual OS functions like midiOutShortMsg actually parse the data, expecting a complete message, and won’t work with random bytes.


#3

Thanks for the fast response Jules.

That is a shame, it would have been such a nice feature to have. I just checked if it was possibly to send out single bytes from a program called MIDI-OX, and it is. So somehow it should be possibly, but I am not sure that my OS skills are good enough for me to figure out how to do that.
I will post a solution if I find one.

/ John


#4

Yes, there’s probably some way of doing it, but I bet you’re the only person who’ll ever ask for it!


#5
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <mmsystem.h>

unsigned char	Vol[] = {0xf1};


void PrintMidiOutErrorMsg(unsigned long err)
{
#define BUFFERSIZE 120
	char	buffer[BUFFERSIZE];
	
	if (!(err = midiOutGetErrorText(err, &buffer[0], BUFFERSIZE)))
	{
		printf("%s\r\n", &buffer[0]);
	}
	else if (err == MMSYSERR_BADERRNUM)
	{
		printf("Strange error number returned!\r\n");
	}
	else
	{
		printf("Specified pointer is invalid!\r\n");
	}
}

int main(int argc, char **argv)
{
	HMIDIOUT		handle;
	MIDIHDR			midiHdr;
	UINT			err;

	if (!(err = midiOutOpen(&handle, 0, 0, 0, CALLBACK_NULL)))
	{
		midiHdr.lpData = (LPBYTE)&Vol[0];
		midiHdr.dwBufferLength = sizeof(Vol);
		midiHdr.dwFlags = 0;
		err = midiOutPrepareHeader(handle,  &midiHdr, sizeof(MIDIHDR));

	    if (!err)
		{
	        /* Output the SysEx message. Note that this could return immediately if
			the device driver can output the message on its own in the background.
			Otherwise, the driver may make us wait in this call until the entire
			data is output
			*/
		    err = midiOutLongMsg(handle, &midiHdr, sizeof(MIDIHDR));
			if (err)
			{
				PrintMidiOutErrorMsg(err);
			}

			
			while (MIDIERR_STILLPLAYING == midiOutUnprepareHeader(handle, &midiHdr, sizeof(MIDIHDR)))
			{
				Sleep(1000);
			}
		}
		else
		{
			PrintMidiOutErrorMsg(err);
		}

		midiOutClose(handle);
	}
	else
	{
		printf("Error opening default MIDI Out device!\r\n");
		PrintMidiOutErrorMsg(err);
	}

	return(0);
}

this program sends one byte (F1 a MTC quarter frame), the info and code is taken from http://www.borg.com/~jglatt/tech/lowmidi.htm i was playing with WINMM api some time ago when i was doing a sysex controller that was pure MFC (don’t shoot). Anyway i think it will work but i’m also pretty sure you can’t push just any byte cause the driver will refuse some types of messages, but i guess that depends on the driver (i tested it with MIDI Yoke and i was able to push F1 and F9 bytes but not F7 alone). A good starting point anyway i think.