00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020 #include "CoreAudioMidiDriver.h"
00021
00022 #ifdef USE_CORE_AUDIO_MIDI
00023
00024 #include <pthread.h>
00025 #include <sched.h>
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 const MidiDriver::MidiDriverDesc CoreAudioMidiDriver::desc =
00037 MidiDriver::MidiDriverDesc ("CoreAudio", createInstance);
00038
00039 CoreAudioMidiDriver::CoreAudioMidiDriver() :
00040 au_MusicDevice(0), au_output(0),
00041 mClient(0), mOutPort(0), mDest(0)
00042 {
00043 OSStatus err;
00044 err = MIDIClientCreate(CFSTR("Pentagram MIDI Driver for OS X"), NULL, NULL, &mClient);
00045
00046 }
00047
00048 CoreAudioMidiDriver::~CoreAudioMidiDriver()
00049 {
00050 if (mClient)
00051 MIDIClientDispose(mClient);
00052 mClient = 0;
00053 }
00054
00055 int CoreAudioMidiDriver::open()
00056 {
00057 if (au_output || mDest)
00058 return 1;
00059
00060 OSStatus err = noErr;
00061
00062 mOutPort = 0;
00063 #ifdef ENABLE_HACKISH_NATIVE_MIDI_SUPPORT
00064 int dests = MIDIGetNumberOfDestinations();
00065 if (dests > 0 && mClient) {
00066 mDest = MIDIGetDestination(0);
00067 err = MIDIOutputPortCreate( mClient,
00068 CFSTR("scummvm_output_port"),
00069 &mOutPort);
00070 }
00071 #endif
00072
00073 if (err != noErr || !mOutPort) {
00074 AudioUnitConnection auconnect;
00075 ComponentDescription compdesc;
00076 Component compid;
00077
00078
00079 compdesc.componentType = kAudioUnitComponentType;
00080 compdesc.componentSubType = kAudioUnitSubType_MusicDevice;
00081 compdesc.componentManufacturer = kAudioUnitID_DLSSynth;
00082 compdesc.componentFlags = 0;
00083 compdesc.componentFlagsMask = 0;
00084 compid = FindNextComponent(NULL, &compdesc);
00085 au_MusicDevice = static_cast<AudioUnit>(OpenComponent(compid));
00086
00087
00088 au_output = static_cast<AudioUnit>(OpenDefaultComponent(kAudioUnitComponentType, kAudioUnitSubType_Output));
00089
00090
00091 auconnect.sourceAudioUnit = au_MusicDevice;
00092 auconnect.sourceOutputNumber = 0;
00093 auconnect.destInputNumber = 0;
00094 err =
00095 AudioUnitSetProperty(au_output, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, 0,
00096 static_cast<void*>(&auconnect), sizeof(AudioUnitConnection));
00097
00098
00099 AudioUnitInitialize(au_MusicDevice);
00100 AudioUnitInitialize(au_output);
00101
00102
00103 AudioOutputUnitStart(au_output);
00104 }
00105
00106 return 0;
00107 }
00108
00109 void CoreAudioMidiDriver::close()
00110 {
00111 if (mOutPort && mDest) {
00112 MIDIPortDispose(mOutPort);
00113 mOutPort = 0;
00114 mDest = 0;
00115 } else {
00116
00117 AudioOutputUnitStop(au_output);
00118
00119
00120 CloseComponent(au_output);
00121 au_output = 0;
00122 CloseComponent(au_MusicDevice);
00123 au_MusicDevice = 0;
00124 }
00125 }
00126
00127 void CoreAudioMidiDriver::send(uint32 message)
00128 {
00129 uint8 status_byte = (message & 0x000000FF);
00130 uint8 first_byte = (message & 0x0000FF00) >> 8;
00131 uint8 second_byte = (message & 0x00FF0000) >> 16;
00132
00133 if (mOutPort && mDest) {
00134 MIDIPacketList packetList;
00135 MIDIPacket *packet = &packetList.packet[0];
00136
00137 packetList.numPackets = 1;
00138
00139 packet->timeStamp = 0;
00140 packet->length = 3;
00141 packet->data[0] = status_byte;
00142 packet->data[1] = first_byte;
00143 packet->data[2] = second_byte;
00144
00145 MIDISend(mOutPort, mDest, &packetList);
00146 } else {
00147 assert(au_output != NULL);
00148 assert(au_MusicDevice != NULL);
00149 MusicDeviceMIDIEvent(au_MusicDevice, status_byte, first_byte, second_byte, 0);
00150 }
00151 }
00152
00153 void CoreAudioMidiDriver::send_sysex (uint8 status, const uint8 *msg, uint16 length)
00154 {
00155 uint8 buf[384];
00156
00157 if (mOutPort && mDest) {
00158 MIDIPacketList *packetList = (MIDIPacketList *)buf;
00159 MIDIPacket *packet = packetList->packet;
00160
00161 assert(sizeof(buf) >= sizeof(UInt32) + sizeof(MIDITimeStamp) + sizeof(UInt16) + length + 2);
00162
00163 packetList->numPackets = 1;
00164
00165 packet->timeStamp = 0;
00166
00167
00168 packet->length = length + 2;
00169 packet->data[0] = status;
00170 memcpy(packet->data + 1, msg, length);
00171 packet->data[length + 1] = 0xF7;
00172
00173 MIDISend(mOutPort, mDest, packetList);
00174 } else {
00175 assert(sizeof(buf) >= (size_t)length + 2);
00176 assert(au_output != NULL);
00177 assert(au_MusicDevice != NULL);
00178
00179
00180 buf[0] = status;
00181 memcpy(buf+1, msg, length);
00182 buf[length+1] = 0xF7;
00183
00184 MusicDeviceSysEx(au_MusicDevice, buf, length + 2);
00185 }
00186 }
00187
00188 void CoreAudioMidiDriver::increaseThreadPriority()
00189 {
00190 pthread_t self;
00191 int policy;
00192 struct sched_param param;
00193
00194 self = pthread_self();
00195 pthread_getschedparam(self, &policy, ¶m);
00196 param.sched_priority = sched_get_priority_max(policy);
00197 pthread_setschedparam(self, policy, ¶m);
00198 }
00199
00200 void CoreAudioMidiDriver::yield()
00201 {
00202 sched_yield();
00203 }
00204
00205 #endif //MACOSX