Question

I am trying to generate a musical note that will play through the iPhone speakers using Objective-C and MIDI. I have the code below but it is not doing anything. What am I doing wrong?

MIDIPacketList packetList;

packetList.numPackets = 1;

MIDIPacket* firstPacket = &packetList.packet[0];

firstPacket->timeStamp = 0; // send immediately

firstPacket->length = 3;

firstPacket->data[0] = 0x90;

firstPacket->data[1] = 80;

firstPacket->data[2] = 120;

MIDIPacketList pklt=packetList;

MIDISend(MIDIGetSource(0), MIDIGetDestination(0), &pklt);
Was it helpful?

Solution

You've got three problems:

  1. Declaring a MIDIPacketList doesn't allocate memory or initialize the structure
  2. You're passing the results of MIDIGetSource (which returns a MIDIEndpointRef) as the first parameter to MIDISend where it is expecting a MIDIPortRef instead. (You probably ignored a compiler warning about this. Never ignore compiler warnings.)
  3. Sending a MIDI note in iOS doesn't make any sound. If you don't have an external MIDI device connected to your iOS device, you need to set up something with CoreAudio that will generate sounds. That's beyond the scope of this answer.

So this code will run, but it won't make any sounds unless you've got external hardware:

//Look to see if there's anything that will actually play MIDI notes
NSLog(@"There are %lu destinations", MIDIGetNumberOfDestinations());

// Prepare MIDI Interface Client/Port for writing MIDI data:
MIDIClientRef midiclient = 0;
MIDIPortRef midiout = 0;
OSStatus status;
status = MIDIClientCreate(CFSTR("Test client"), NULL, NULL, &midiclient);
if (status) {
    NSLog(@"Error trying to create MIDI Client structure: %d", (int)status);
}
status = MIDIOutputPortCreate(midiclient, CFSTR("Test port"), &midiout);
if (status) {
    NSLog(@"Error trying to create MIDI output port: %d", (int)status);
}

Byte buffer[128];
MIDIPacketList *packetlist = (MIDIPacketList *)buffer;
MIDIPacket *currentpacket = MIDIPacketListInit(packetlist);
NSInteger messageSize = 3; //Note On is a three-byte message
Byte msg[3] = {0x90, 80, 120};
MIDITimeStamp timestamp = 0;
currentpacket = MIDIPacketListAdd(packetlist, sizeof(buffer), currentpacket, timestamp, messageSize, msg);
MIDISend(midiout, MIDIGetDestination(0), packetlist);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top