2 Copyright (C) 2004 Paul Davis
3 Copyright (C) 2004 Grame
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <midi++/coremidi_midiport.h>
25 #include <midi++/types.h>
26 #include <mach/mach_time.h>
28 #include <pbd/pthread_utils.h>
33 MIDITimeStamp CoreMidi_MidiPort::MIDIGetCurrentHostTime()
35 return mach_absolute_time();
38 CoreMidi_MidiPort::CoreMidi_MidiPort (const XMLNode& node) : Port (node)
40 Descriptor desc (node);
44 if (0 == (err = Open(desc))) {
49 CoreMidi_MidiPort::~CoreMidi_MidiPort () {Close();}
51 void CoreMidi_MidiPort::Close ()
53 if (midi_destination) MIDIEndpointDispose(midi_destination);
54 if (midi_source) MIDIEndpointDispose(midi_source);
55 if (midi_client) MIDIClientDispose(midi_client);
58 int CoreMidi_MidiPort::write (byte *msg, size_t msglen, timestamp_t ignored)
61 MIDIPacketList* pktlist = (MIDIPacketList*)midi_buffer;
62 MIDIPacket* packet = MIDIPacketListInit(pktlist);
63 packet = MIDIPacketListAdd(pktlist,sizeof(midi_buffer),packet,MIDIGetCurrentHostTime(),msglen,msg);
67 err = MIDIReceived(midi_source,pktlist);
69 //error << "MIDIReceived error" << err << endmsg.
72 bytes_written += msglen;
79 int CoreMidi_MidiPort::Open (const Descriptor& desc)
82 CFStringRef coutputStr;
85 coutputStr = CFStringCreateWithCString(0, desc.device.c_str(), CFStringGetSystemEncoding());
86 err = MIDIClientCreate(coutputStr, 0, 0, &midi_client);
87 CFRelease(coutputStr);
89 //error << "Cannot open CoreMidi client : " << err << endmsg.
93 str = desc.tag + string("_in");
94 coutputStr = CFStringCreateWithCString(0, str.c_str(), CFStringGetSystemEncoding());
95 err = MIDIDestinationCreate(midi_client, coutputStr, read_proc, this, &midi_destination);
96 CFRelease(coutputStr);
97 if (!midi_destination) {
98 //error << "Cannot create CoreMidi destination : " << err << endmsg.
102 str = desc.tag + string("_out");
103 coutputStr = CFStringCreateWithCString(0, str.c_str(), CFStringGetSystemEncoding());
104 err = MIDISourceCreate(midi_client, coutputStr, &midi_source);
105 CFRelease(coutputStr);
107 //error << "Cannot create CoreMidi source : " << err << endmsg.
118 void CoreMidi_MidiPort::read_proc (const MIDIPacketList *pktlist, void *refCon, void *connRefCon)
120 CoreMidi_MidiPort* driver = (CoreMidi_MidiPort*)refCon;
121 MIDIPacket *packet = (MIDIPacket *)pktlist->packet;
123 if (driver->firstrecv) {
124 driver->firstrecv = false;
125 PBD::notify_gui_about_thread_creation (pthread_self(), "COREMIDI");
128 for (unsigned int i = 0; i < pktlist->numPackets; ++i) {
130 driver->bytes_read += packet->length;
132 if (driver->input_parser) {
133 driver->input_parser->raw_preparse (*driver->input_parser, packet->data, packet->length);
134 for (int i = 0; i < packet->length; i++) {
135 driver->input_parser->scanner (packet->data[i]);
137 driver->input_parser->raw_postparse (*driver->input_parser, packet->data, packet->length);
140 packet = MIDIPacketNext(packet);
145 CoreMidi_MidiPort::discover (vector<PortSet>& ports)
147 /* XXX do dynamic port discovery here */