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 <midi++/port_request.h>
27 #include <mach/mach_time.h>
29 #include <pbd/pthread_utils.h>
34 MIDITimeStamp CoreMidi_MidiPort::MIDIGetCurrentHostTime()
36 return mach_absolute_time();
39 CoreMidi_MidiPort::CoreMidi_MidiPort (PortRequest &req) : Port (req)
43 if (0 == (err = Open(req))) {
45 req.status = PortRequest::OK;
47 req.status = PortRequest::Unknown;
50 CoreMidi_MidiPort::~CoreMidi_MidiPort () {Close();}
52 void CoreMidi_MidiPort::Close ()
54 if (midi_destination) MIDIEndpointDispose(midi_destination);
55 if (midi_source) MIDIEndpointDispose(midi_source);
56 if (midi_client) MIDIClientDispose(midi_client);
59 int CoreMidi_MidiPort::write (byte *msg, size_t msglen, timestamp_t timestamp)
62 MIDIPacketList* pktlist = (MIDIPacketList*)midi_buffer;
63 MIDIPacket* packet = MIDIPacketListInit(pktlist);
64 packet = MIDIPacketListAdd(pktlist,sizeof(midi_buffer),packet,MIDIGetCurrentHostTime(),msglen,msg);
68 err = MIDIReceived(midi_source,pktlist);
70 //error << "MIDIReceived error" << err << endmsg.
73 bytes_written += msglen;
80 int CoreMidi_MidiPort::Open (PortRequest &req)
83 CFStringRef coutputStr;
86 coutputStr = CFStringCreateWithCString(0, req.devname, CFStringGetSystemEncoding());
87 err = MIDIClientCreate(coutputStr, 0, 0, &midi_client);
88 CFRelease(coutputStr);
90 //error << "Cannot open CoreMidi client : " << err << endmsg.
94 str = req.tagname + string("_in");
95 coutputStr = CFStringCreateWithCString(0, str.c_str(), CFStringGetSystemEncoding());
96 err = MIDIDestinationCreate(midi_client, coutputStr, read_proc, this, &midi_destination);
97 CFRelease(coutputStr);
98 if (!midi_destination) {
99 //error << "Cannot create CoreMidi destination : " << err << endmsg.
103 str = req.tagname + string("_out");
104 coutputStr = CFStringCreateWithCString(0, str.c_str(), CFStringGetSystemEncoding());
105 err = MIDISourceCreate(midi_client, coutputStr, &midi_source);
106 CFRelease(coutputStr);
108 //error << "Cannot create CoreMidi source : " << err << endmsg.
119 void CoreMidi_MidiPort::read_proc (const MIDIPacketList *pktlist, void *refCon, void *connRefCon)
121 CoreMidi_MidiPort* driver = (CoreMidi_MidiPort*)refCon;
122 MIDIPacket *packet = (MIDIPacket *)pktlist->packet;
124 if (driver->firstrecv) {
125 driver->firstrecv = false;
126 PBD::ThreadCreated (pthread_self(), "COREMIDI");
129 for (unsigned int i = 0; i < pktlist->numPackets; ++i) {
131 driver->bytes_read += packet->length;
133 if (driver->input_parser) {
134 driver->input_parser->raw_preparse (*driver->input_parser, packet->data, packet->length);
135 for (int i = 0; i < packet->length; i++) {
136 driver->input_parser->scanner (packet->data[i]);
138 driver->input_parser->raw_postparse (*driver->input_parser, packet->data, packet->length);
141 packet = MIDIPacketNext(packet);