10#include <mach/mach_time.h>
19void MidiOutMessageBuffer::recvMessage(
20 const std::vector<uint8_t>& message, EmuTime::param )
23 MIDITimeStamp abstime = mach_absolute_time();
25 MIDIPacketList packetList;
26 MIDIPacket *curPacket = MIDIPacketListInit(&packetList);
27 curPacket = MIDIPacketListAdd(&packetList,
sizeof(packetList),
28 curPacket, abstime, message.size(), message.data());
30 fprintf(stderr,
"Failed to package MIDI data\n");
31 }
else if (OSStatus status = sendPacketList(&packetList)) {
32 fprintf(stderr,
"Failed to send MIDI data (%d)\n",
int(status));
41void MidiOutCoreMIDI::registerAll(PluggingController& controller)
43 for (
auto i :
xrange(MIDIGetNumberOfDestinations())) {
44 if (MIDIEndpointRef endpoint = MIDIGetDestination(i)) {
45 controller.registerPluggable(
46 std::make_unique<MidiOutCoreMIDI>(endpoint));
51MidiOutCoreMIDI::MidiOutCoreMIDI(MIDIEndpointRef endpoint_)
55 CFStringRef midiDeviceName;
56 OSStatus status = MIDIObjectGetStringProperty(
57 endpoint, kMIDIPropertyDisplayName, &midiDeviceName);
59 status = MIDIObjectGetStringProperty(
60 endpoint, kMIDIPropertyName, &midiDeviceName);
63 name =
"Nameless endpoint";
65 name =
strCat(StringOp::fromCFString(midiDeviceName),
" OUT");
66 CFRelease(midiDeviceName);
70void MidiOutCoreMIDI::plugHelper(Connector& ,
74 if (OSStatus status = MIDIClientCreate(CFSTR(
"openMSX"),
nullptr,
nullptr, &client)) {
75 throw PlugException(
"Failed to create MIDI client (", status,
')');
78 if (OSStatus status = MIDIOutputPortCreate(client, CFSTR(
"Output"), &port)) {
79 MIDIClientDispose(client);
81 throw PlugException(
"Failed to create MIDI port (", status,
')');
85void MidiOutCoreMIDI::unplugHelper(EmuTime::param )
90 if (OSStatus status = MIDIClientDispose(client)) {
91 fprintf(stderr,
"Failed to dispose of MIDI client (%d)\n",
int(status));
97std::string_view MidiOutCoreMIDI::getName()
const
102std::string_view MidiOutCoreMIDI::getDescription()
const
104 return "Sends MIDI events to an existing CoreMIDI destination.";
107OSStatus MidiOutCoreMIDI::sendPacketList(MIDIPacketList *myPacketList)
109 return MIDISend(port, endpoint, myPacketList);
112template<
typename Archive>
113void MidiOutCoreMIDI::serialize(Archive& ,
unsigned )
122MidiOutCoreMIDIVirtual:: MidiOutCoreMIDIVirtual()
128void MidiOutCoreMIDIVirtual::plugHelper(Connector& ,
132 if (OSStatus status = MIDIClientCreate(CFSTR(
"openMSX"),
nullptr,
nullptr, &client)) {
133 throw PlugException(
"Failed to create MIDI client (", status,
')');
136 if (OSStatus status = MIDISourceCreate(client, CFSTR(
"openMSX"), &endpoint)) {
137 MIDIClientDispose(client);
138 throw PlugException(
"Failed to create MIDI endpoint (", status,
')');
142void MidiOutCoreMIDIVirtual::unplugHelper(EmuTime::param )
146 if (OSStatus status = MIDIEndpointDispose(endpoint)) {
147 fprintf(stderr,
"Failed to dispose of MIDI port (%d)\n",
int(status));
150 if (OSStatus status = MIDIClientDispose(client)) {
151 fprintf(stderr,
"Failed to dispose of MIDI client (%d)\n",
int(status));
156std::string_view MidiOutCoreMIDIVirtual::getName()
const
158 return "Virtual OUT";
161std::string_view MidiOutCoreMIDIVirtual::getDescription()
const
163 return "Sends MIDI events from a newly created CoreMIDI virtual source.";
166OSStatus MidiOutCoreMIDIVirtual::sendPacketList(MIDIPacketList *myPacketList)
168 return MIDIReceived(endpoint, myPacketList);
171template<
typename Archive>
172void MidiOutCoreMIDIVirtual::serialize(Archive& ,
unsigned )
This file implemented 3 utility functions:
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
constexpr auto xrange(T e)