• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: MIDI send problems.
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: MIDI send problems.


  • Subject: Re: MIDI send problems.
  • From: Doug Wyatt <email@hidden>
  • Date: Tue, 7 Aug 2001 07:29:46 -0700

Below is a small command-line tool that creates a virtual destination and then calls MIDISend to send to it. I can't reproduce any problems with it ... can you? If not, then it's something for the author of the driver to investigate.

Doug


#define DEBUG 1

#include <CoreMIDI/MIDIServices.h>
#include <CoreAudio/HostTime.h>


void ClientProc(const MIDINotification *message, void *refCon)
{
}

#define NSMS(x) (long)((x / 1000000ULL) & 0x7FFFFFF) // nanos to 32 bits of millis

void MIDIPacketListDump(const MIDIPacketList *pktlist)
{
const MIDIPacket *pkt = pktlist->packet;
UInt64 nowHW = AudioGetCurrentHostTime();
UInt64 nowNS = AudioConvertHostTimeToNanos(nowHW);
for (unsigned int i = 0; i < pktlist->numPackets; ++i) {
printf("ld ld: ", NSMS(nowNS), NSMS(AudioConvertHostTimeToNanos(pkt->timeStamp)));
for (unsigned int j = 0; j < pkt->length; ++j)
printf("X ", pkt->data[j]);
printf("\n");
pkt = MIDIPacketNext(pkt);
}
}

void VirtualReadProc(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon)
{
MIDIPacketListDump(pktlist);
}

int main(int argc, char *argv[])
{
MIDIClientRef clientRef;
MIDIPortRef outPort;
MIDIEndpointRef destination;

check_noerr(MIDIClientCreate(CFSTR("test"), ClientProc, NULL, &clientRef));
check_noerr(MIDIOutputPortCreate(clientRef, CFSTR("outport"), &outPort));

check_noerr(MIDIDestinationCreate(clientRef, CFSTR("virtual dest"), VirtualReadProc, NULL, &destination));

Byte buffer[512];
MIDIPacketList *packetList = (MIDIPacketList *)buffer;
Byte sysExEvent[] = { 0xF0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0xF7 };

MIDITimeStamp timeStamp = 0;

MIDIPacket *packet = MIDIPacketListInit(packetList);
check(packet != NULL);
packet = MIDIPacketListAdd(packetList, 512, packet, 0,
sizeof(sysExEvent), sysExEvent);
check_noerr(MIDISend(outPort, destination, packetList));
CFRunLoopRun();

return 0;
}



On Thursday, August 2, 2001, at 03:37 PM, Jason Bagley wrote:

Hi,

I've been having trouble sending anything but 3 byte messages through
MIDISend, and I can't seem to get anything to send through MIDISendSysex
at all. Both calls return noErr, and when using MIDISendSysex my
SysexComplete routine is called with bytesToSend == 0 and complete ==
TRUE.

Trying to send messages larger than 3 bytes through MIDISend often freezes
my system! Cursor is active, but I can't do anything else. Unplugging the
interface from the USB chain does not end the freeze.

I've isolated some of the MIDI code in a small test app. There I can send
larger messages via MIDISend, but I have to send a 3 byte message first.
Otherwise, on subsequent invocations of the test app, no large data will
be sent.

I'm using OS X 10.0.4, and MIDISPORT 2x2 with the driver available from
MIDIMAN. I know others have said they have no trouble with this driver.

Thanks in advance for any help.

Here is a snippet of the test app:

const Byte kMIEXGGetKeyboardMode[] = { 0xf0, 0x43, 0x76, 0x65, 0x30,
0x7f, 0x00, 0x00, 0x02, 0xf7 };
Byte noteOn[] = { 0x90, 60, 4 };
Byte noteOff[] = { 0x80, 0, 0 };

...

const Byte *sysExEvent = kMIEXGGetKeyboardMode;
int sysExLength = CalcSysExLength(sysExEvent);

...

#if 0

// Send via MIDISendSysex

sysExRequest = malloc(sizeof(MIDISysexSendRequest) + sysExLength);
memcpy((unsigned char*)sysExRequest + sizeof(MIDISysexSendRequest),
sysExEvent, sysExLength);

sysExRequest->destination = destination;
sysExRequest->data = (unsigned char*)sysExRequest +
sizeof(MIDISysexSendRequest);
sysExRequest->bytesToSend = sysExLength;
sysExRequest->complete = false;
sysExRequest->completionProc = SysExCompletionProc;
sysExRequest->completionRefCon = (void *)sysExRequest;
result = MIDISendSysex(sysExRequest);
fprintf(stderr, "SendSysEx returned %ld.\n", result);

#else

// Send via MIDISend

packet = MIDIPacketListInit(packetList);
assert(NULL != packet);

// Workaround. Send a 3 byte message to "prime" driver?
packet = MIDIPacketListAdd(packetList, 512, packet, timeStamp, 3,
noteOff);
result = MIDISend(outputPort, destination, packetList);
fprintf(stderr, "MIDISend returned %ld.\n", result);

packet = MIDIPacketListInit(packetList);
packet = MIDIPacketListAdd(packetList, 512, packet, timeStamp + 100000,
sysExLength, sysExEvent);
result = MIDISend(outputPort, destination, packetList);
fprintf(stderr, "MIDISend returned %ld.\n", result);

#endif

fprintf(stderr, "Entering run loop.\n");
CFRunLoopRun();


Jason Bagley
Software Engineer
www.artlogic.com
_______________________________________________
coreaudio-api mailing list
email@hidden
http://www.lists.apple.com/mailman/listinfo/coreaudio-api


--
Doug Wyatt
work: email@hidden (CoreAudio)
personal: email@hidden http://www.sonosphere.com

"He was the sort of person who stood on mountaintops during thunderstorms in
wet copper armour shouting 'All the Gods are bastards.'"
-- Terry Pratchett


  • Follow-Ups:
    • Re(2): MIDI send problems.
      • From: "Jason Bagley" <email@hidden>
References: 
 >MIDI send problems. (From: "Jason Bagley" <email@hidden>)

  • Prev by Date: Re: Where is CoreAudio (aka Getting started...)?
  • Next by Date: MIDIReadProc problem
  • Previous by thread: MIDI send problems.
  • Next by thread: Re(2): MIDI send problems.
  • Index(es):
    • Date
    • Thread