00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackCompilerDeps.h"
00022 #include "JackCoreMidiDriver.h"
00023 #include "JackCoreMidiUtil.h"
00024 #include "JackEngineControl.h"
00025 #include "driver_interface.h"
00026
00027 #include <stdexcept>
00028 #include <mach/mach_time.h>
00029
00030 using Jack::JackCoreMidiDriver;
00031
00032 static char capture_driver_name[256];
00033 static char playback_driver_name[256];
00034
00035 static int in_channels, out_channels;
00036 static bool capturing, playing, monitor;
00037
00038 static jack_nframes_t capture_latency, playback_latency;
00039
00041
00043
00044 void
00045 JackCoreMidiDriver::HandleInputEvent(const MIDIPacketList *packet_list,
00046 void *driver, void *port)
00047 {
00048 ((JackCoreMidiPhysicalInputPort *) port)->ProcessCoreMidi(packet_list);
00049 }
00050
00051 void
00052 JackCoreMidiDriver::HandleNotificationEvent(const MIDINotification *message,
00053 void *driver)
00054 {
00055 ((JackCoreMidiDriver *) driver)->HandleNotification(message);
00056 }
00057
00059
00061
00062 JackCoreMidiDriver::JackCoreMidiDriver(const char *name, const char *alias,
00063 JackLockedEngine *engine,
00064 JackSynchro *table):
00065 JackMidiDriver(name, alias, engine, table),fThread(this)
00066 {
00067 mach_timebase_info_data_t info;
00068 kern_return_t result = mach_timebase_info(&info);
00069 if (result != KERN_SUCCESS) {
00070 throw std::runtime_error(mach_error_string(result));
00071 }
00072 client = 0;
00073 fCaptureChannels = 0;
00074 fPlaybackChannels = 0;
00075 num_physical_inputs = 0;
00076 num_physical_outputs = 0;
00077 num_virtual_inputs = 0;
00078 num_virtual_outputs = 0;
00079 physical_input_ports = 0;
00080 physical_output_ports = 0;
00081 time_ratio = (((double) info.numer) / info.denom) / 1000.0;
00082 virtual_input_ports = 0;
00083 virtual_output_ports = 0;
00084 internal_input = 0;
00085 internal_output = 0;
00086 }
00087
00088 JackCoreMidiDriver::~JackCoreMidiDriver()
00089 {}
00090
00091 bool JackCoreMidiDriver::Init()
00092 {
00093 return OpenAux();
00094 }
00095
00096 bool JackCoreMidiDriver::OpenAux()
00097 {
00098 int pi_count = 0;
00099 int po_count = 0;
00100 int vi_count = 0;
00101 int vo_count = 0;
00102 ItemCount potential_po_count;
00103 ItemCount potential_pi_count;
00104
00105 CFStringRef name = CFStringCreateWithCString(0, "JackMidi",
00106 CFStringGetSystemEncoding());
00107 if (! name) {
00108 jack_error("JackCoreMidiDriver::Open - failed to allocate memory for "
00109 "client name string");
00110 return false;
00111 }
00112
00113 OSStatus status = MIDIClientCreate(name, HandleNotificationEvent, this,
00114 &client);
00115 CFRelease(name);
00116
00117 if (status != noErr) {
00118 WriteMacOSError("JackCoreMidiDriver::Open", "MIDIClientCreate",
00119 status);
00120 return false;
00121 }
00122
00123 char *client_name = fClientControl.fName;
00124
00125
00126 potential_pi_count = MIDIGetNumberOfSources();
00127 if (potential_pi_count) {
00128 status = MIDIInputPortCreate(client, CFSTR("Physical Input Port"),
00129 HandleInputEvent, this, &internal_input);
00130 if (status != noErr) {
00131 WriteMacOSError("JackCoreMidiDriver::Open", "MIDIInputPortCreate",
00132 status);
00133 goto destroy;
00134 }
00135
00136 try {
00137 physical_input_ports =
00138 new JackCoreMidiPhysicalInputPort*[potential_pi_count];
00139 } catch (std::exception& e) {
00140 jack_error("JackCoreMidiDriver::Open - while creating physical "
00141 "input port array: %s", e.what());
00142 goto destroy;
00143 }
00144
00145 for (ItemCount i = 0; i < potential_pi_count; i++) {
00146 try {
00147 physical_input_ports[pi_count] =
00148 new JackCoreMidiPhysicalInputPort(fAliasName, client_name,
00149 capture_driver_name, i,
00150 client, internal_input,
00151 time_ratio);
00152 } catch (std::exception& e) {
00153 jack_error("JackCoreMidiDriver::Open - while creating "
00154 "physical input port: %s", e.what());
00155 goto destroy;
00156 }
00157 pi_count++;
00158 }
00159 }
00160
00161
00162 potential_po_count = MIDIGetNumberOfDestinations();
00163 if (potential_po_count) {
00164 status = MIDIOutputPortCreate(client, CFSTR("Physical Output Port"),
00165 &internal_output);
00166 if (status != noErr) {
00167 WriteMacOSError("JackCoreMidiDriver::Open", "MIDIOutputPortCreate",
00168 status);
00169 goto destroy;
00170 }
00171
00172 try {
00173 physical_output_ports =
00174 new JackCoreMidiPhysicalOutputPort*[potential_po_count];
00175 } catch (std::exception& e) {
00176 jack_error("JackCoreMidiDriver::Open - while creating physical "
00177 "output port array: %s", e.what());
00178 goto destroy;
00179 }
00180
00181 for (ItemCount i = 0; i < potential_po_count; i++) {
00182 try {
00183 physical_output_ports[po_count] =
00184 new JackCoreMidiPhysicalOutputPort(fAliasName, client_name,
00185 playback_driver_name, i,
00186 client, internal_output,
00187 time_ratio);
00188 } catch (std::exception& e) {
00189 jack_error("JackCoreMidiDriver::Open - while creating "
00190 "physical output port: %s", e.what());
00191 goto destroy;
00192 }
00193 po_count++;
00194 }
00195 }
00196
00197
00198 if (in_channels) {
00199 try {
00200 virtual_input_ports =
00201 new JackCoreMidiVirtualInputPort*[in_channels];
00202 } catch (std::exception& e) {
00203 jack_error("JackCoreMidiDriver::Open - while creating virtual "
00204 "input port array: %s", e.what());
00205 goto destroy;
00206
00207 }
00208 for (vi_count = 0; vi_count < in_channels; vi_count++) {
00209 try {
00210 virtual_input_ports[vi_count] =
00211 new JackCoreMidiVirtualInputPort(fAliasName, client_name,
00212 capture_driver_name,
00213 vi_count, vi_count + pi_count, client,
00214 time_ratio);
00215 } catch (std::exception& e) {
00216 jack_error("JackCoreMidiDriver::Open - while creating virtual "
00217 "input port: %s", e.what());
00218 goto destroy;
00219 }
00220 }
00221 }
00222
00223
00224 if (out_channels) {
00225 try {
00226 virtual_output_ports =
00227 new JackCoreMidiVirtualOutputPort*[out_channels];
00228 } catch (std::exception& e) {
00229 jack_error("JackCoreMidiDriver::Open - while creating virtual "
00230 "output port array: %s", e.what());
00231 goto destroy;
00232 }
00233 for (vo_count = 0; vo_count < out_channels; vo_count++) {
00234 try {
00235 virtual_output_ports[vo_count] =
00236 new JackCoreMidiVirtualOutputPort(fAliasName, client_name,
00237 playback_driver_name,
00238 vo_count, vo_count + po_count, client,
00239 time_ratio);
00240 } catch (std::exception& e) {
00241 jack_error("JackCoreMidiDriver::Open - while creating virtual "
00242 "output port: %s", e.what());
00243 goto destroy;
00244 }
00245 }
00246 }
00247
00248 if (! (pi_count || po_count || in_channels || out_channels)) {
00249 jack_error("JackCoreMidiDriver::Open - no CoreMIDI inputs or outputs "
00250 "found, and no virtual ports allocated.");
00251 }
00252
00253 if (! JackMidiDriver::Open(capturing, playing,
00254 in_channels + pi_count,
00255 out_channels + po_count, monitor,
00256 capture_driver_name,
00257 playback_driver_name, capture_latency,
00258 playback_latency)) {
00259 num_physical_inputs = pi_count;
00260 num_physical_outputs = po_count;
00261 num_virtual_inputs = in_channels;
00262 num_virtual_outputs = out_channels;
00263 return true;
00264 }
00265
00266 destroy:
00267
00268 if (physical_input_ports) {
00269 for (int i = 0; i < pi_count; i++) {
00270 delete physical_input_ports[i];
00271 }
00272 delete[] physical_input_ports;
00273 physical_input_ports = 0;
00274 }
00275
00276 if (physical_output_ports) {
00277 for (int i = 0; i < po_count; i++) {
00278 delete physical_output_ports[i];
00279 }
00280 delete[] physical_output_ports;
00281 physical_output_ports = 0;
00282 }
00283
00284 if (virtual_input_ports) {
00285 for (int i = 0; i < vi_count; i++) {
00286 delete virtual_input_ports[i];
00287 }
00288 delete[] virtual_input_ports;
00289 virtual_input_ports = 0;
00290 }
00291
00292 if (virtual_output_ports) {
00293 for (int i = 0; i < vo_count; i++) {
00294 delete virtual_output_ports[i];
00295 }
00296 delete[] virtual_output_ports;
00297 virtual_output_ports = 0;
00298 }
00299
00300 if (internal_output) {
00301 status = MIDIPortDispose(internal_output);
00302 if (status != noErr) {
00303 WriteMacOSError("JackCoreMidiDriver::Open", "MIDIPortDispose", status);
00304 }
00305 }
00306
00307 if (internal_input) {
00308 status = MIDIPortDispose(internal_input);
00309 if (status != noErr) {
00310 WriteMacOSError("JackCoreMidiDriver::Open", "MIDIPortDispose", status);
00311 }
00312 }
00313
00314 if (client) {
00315 status = MIDIClientDispose(client);
00316 if (status != noErr) {
00317 WriteMacOSError("JackCoreMidiDriver::Open", "MIDIClientDispose",
00318 status);
00319 }
00320 }
00321
00322
00323 if (! JackMidiDriver::Open(capturing, playing,
00324 in_channels + pi_count,
00325 out_channels + po_count, monitor,
00326 capture_driver_name,
00327 playback_driver_name, capture_latency,
00328 playback_latency)) {
00329 client = 0;
00330 num_physical_inputs = 0;
00331 num_physical_outputs = 0;
00332 num_virtual_inputs = 0;
00333 num_virtual_outputs = 0;
00334 return true;
00335 } else {
00336 return false;
00337 }
00338 }
00339
00340 bool JackCoreMidiDriver::Execute()
00341 {
00342 CFRunLoopRun();
00343 return false;
00344 }
00345
00346 int
00347 JackCoreMidiDriver::Attach()
00348 {
00349 jack_nframes_t buffer_size = fEngineControl->fBufferSize;
00350 jack_port_id_t index;
00351 jack_nframes_t latency = buffer_size;
00352 jack_latency_range_t latency_range;
00353 const char *name;
00354 JackPort *port;
00355 JackCoreMidiPort *port_obj;
00356 latency_range.max = latency;
00357 latency_range.min = latency;
00358
00359
00360 for (int i = 0; i < num_physical_inputs; i++) {
00361 port_obj = physical_input_ports[i];
00362 name = port_obj->GetName();
00363 if (fEngine->PortRegister(fClientControl.fRefNum, name,
00364 JACK_DEFAULT_MIDI_TYPE,
00365 CaptureDriverFlags, buffer_size, &index) < 0) {
00366 jack_error("JackCoreMidiDriver::Attach - cannot register physical "
00367 "input port with name '%s'.", name);
00368
00369 return -1;
00370 }
00371 port = fGraphManager->GetPort(index);
00372 port->SetAlias(port_obj->GetAlias());
00373 port->SetLatencyRange(JackCaptureLatency, &latency_range);
00374 fCapturePortList[i] = index;
00375 }
00376
00377
00378 for (int i = 0; i < num_virtual_inputs; i++) {
00379 port_obj = virtual_input_ports[i];
00380 name = port_obj->GetName();
00381 if (fEngine->PortRegister(fClientControl.fRefNum, name,
00382 JACK_DEFAULT_MIDI_TYPE,
00383 CaptureDriverFlags, buffer_size, &index) < 0) {
00384 jack_error("JackCoreMidiDriver::Attach - cannot register virtual "
00385 "input port with name '%s'.", name);
00386
00387 return -1;
00388 }
00389 port = fGraphManager->GetPort(index);
00390 port->SetAlias(port_obj->GetAlias());
00391 port->SetLatencyRange(JackCaptureLatency, &latency_range);
00392 fCapturePortList[num_physical_inputs + i] = index;
00393 }
00394
00395 if (! fEngineControl->fSyncMode) {
00396 latency += buffer_size;
00397 latency_range.max = latency;
00398 latency_range.min = latency;
00399 }
00400
00401
00402 for (int i = 0; i < num_physical_outputs; i++) {
00403 port_obj = physical_output_ports[i];
00404 name = port_obj->GetName();
00405 fEngine->PortRegister(fClientControl.fRefNum, name,
00406 JACK_DEFAULT_MIDI_TYPE,
00407 PlaybackDriverFlags, buffer_size, &index);
00408 if (index == NO_PORT) {
00409 jack_error("JackCoreMidiDriver::Attach - cannot register physical "
00410 "output port with name '%s'.", name);
00411
00412 return -1;
00413 }
00414 port = fGraphManager->GetPort(index);
00415 port->SetAlias(port_obj->GetAlias());
00416 port->SetLatencyRange(JackPlaybackLatency, &latency_range);
00417 fPlaybackPortList[i] = index;
00418 }
00419
00420
00421 for (int i = 0; i < num_virtual_outputs; i++) {
00422 port_obj = virtual_output_ports[i];
00423 name = port_obj->GetName();
00424 fEngine->PortRegister(fClientControl.fRefNum, name,
00425 JACK_DEFAULT_MIDI_TYPE,
00426 PlaybackDriverFlags, buffer_size, &index);
00427 if (index == NO_PORT) {
00428 jack_error("JackCoreMidiDriver::Attach - cannot register virtual "
00429 "output port with name '%s'.", name);
00430
00431 return -1;
00432 }
00433 port = fGraphManager->GetPort(index);
00434 port->SetAlias(port_obj->GetAlias());
00435 port->SetLatencyRange(JackPlaybackLatency, &latency_range);
00436 fPlaybackPortList[num_physical_outputs + i] = index;
00437 }
00438
00439 return 0;
00440 }
00441
00442 int
00443 JackCoreMidiDriver::Close()
00444 {
00445 fThread.Kill();
00446 return CloseAux();
00447 }
00448
00449 int
00450 JackCoreMidiDriver::CloseAux()
00451 {
00452
00453 int result = JackMidiDriver::Close();
00454
00455 OSStatus status;
00456 if (physical_input_ports) {
00457 for (int i = 0; i < num_physical_inputs; i++) {
00458 delete physical_input_ports[i];
00459 }
00460 delete[] physical_input_ports;
00461 num_physical_inputs = 0;
00462 physical_input_ports = 0;
00463 if (internal_input) {
00464 status = MIDIPortDispose(internal_input);
00465 if (status != noErr) {
00466 WriteMacOSError("JackCoreMidiDriver::Close", "MIDIPortDispose",
00467 status);
00468 result = -1;
00469 }
00470 internal_input = 0;
00471 }
00472 }
00473 if (physical_output_ports) {
00474 for (int i = 0; i < num_physical_outputs; i++) {
00475 delete physical_output_ports[i];
00476 }
00477 delete[] physical_output_ports;
00478 num_physical_outputs = 0;
00479 physical_output_ports = 0;
00480 if (internal_output) {
00481 status = MIDIPortDispose(internal_output);
00482 if (status != noErr) {
00483 WriteMacOSError("JackCoreMidiDriver::Close", "MIDIPortDispose",
00484 status);
00485 result = -1;
00486 }
00487 internal_output = 0;
00488 }
00489 }
00490 if (virtual_input_ports) {
00491 for (int i = 0; i < num_virtual_inputs; i++) {
00492 delete virtual_input_ports[i];
00493 }
00494 delete[] virtual_input_ports;
00495 num_virtual_inputs = 0;
00496 virtual_input_ports = 0;
00497 }
00498 if (virtual_output_ports) {
00499 for (int i = 0; i < num_virtual_outputs; i++) {
00500 delete virtual_output_ports[i];
00501 }
00502 delete[] virtual_output_ports;
00503 num_virtual_outputs = 0;
00504 virtual_output_ports = 0;
00505 }
00506
00507 if (client) {
00508 status = MIDIClientDispose(client);
00509 if (status != noErr) {
00510 WriteMacOSError("JackCoreMidiDriver::Close", "MIDIClientDispose",
00511 status);
00512 result = -1;
00513 }
00514 client = 0;
00515 }
00516 return result;
00517 }
00518
00519 void
00520 JackCoreMidiDriver::Restart()
00521 {
00522
00523 JackLock lock(this);
00524
00525
00526 if (fEngine->Lock()) {
00527
00528 SaveConnections(1);
00529 Stop();
00530 Detach();
00531 CloseAux();
00532 OpenAux();
00533 Attach();
00534 Start();
00535
00536 LoadConnections(1, false);
00537 fEngine->Unlock();
00538 } else {
00539 jack_error("Cannot acquire engine lock...");
00540 }
00541 }
00542
00543 void
00544 JackCoreMidiDriver::HandleNotification(const MIDINotification *message)
00545 {
00546 switch (message->messageID) {
00547
00548 case kMIDIMsgObjectAdded: {
00549
00550
00551
00552 const MIDIObjectAddRemoveNotification* add_message = reinterpret_cast<const MIDIObjectAddRemoveNotification*>(message);
00553 if (!JackCoreMidiPort::IsInternalPort(add_message->child)) {
00554 Restart();
00555 }
00556 break;
00557 }
00558
00559 case kMIDIMsgObjectRemoved: {
00560
00561
00562
00563 const MIDIObjectAddRemoveNotification* remove_message = reinterpret_cast<const MIDIObjectAddRemoveNotification*>(message);
00564 if (!JackCoreMidiPort::IsInternalPort(remove_message->child)) {
00565 Restart();
00566 }
00567 break;
00568 }
00569 }
00570 }
00571
00572 int
00573 JackCoreMidiDriver::Open(bool capturing_aux, bool playing_aux, int in_channels_aux,
00574 int out_channels_aux, bool monitor_aux,
00575 const char* capture_driver_name_aux,
00576 const char* playback_driver_name_aux,
00577 jack_nframes_t capture_latency_aux,
00578 jack_nframes_t playback_latency_aux)
00579 {
00580
00581 strcpy(capture_driver_name, capture_driver_name_aux);
00582 strcpy(playback_driver_name, playback_driver_name_aux);
00583
00584 capturing = capturing_aux;
00585 playing = playing_aux;
00586 in_channels = in_channels_aux;
00587 out_channels = out_channels_aux;
00588 monitor = monitor_aux;
00589 capture_latency = capture_latency_aux;
00590 playback_latency = playback_latency_aux;
00591
00592 fThread.StartSync();
00593
00594 int count = 0;
00595 while (fThread.GetStatus() != JackThread::kRunning && ++count < WAIT_COUNTER) {
00596 JackSleep(100000);
00597 jack_log("JackCoreMidiDriver::Open wait count = %d", count);
00598
00599 }
00600 if (count == WAIT_COUNTER) {
00601 jack_info("Cannot open CoreMIDI driver");
00602 fThread.Kill();
00603 return -1;
00604 } else {
00605 JackSleep(10000);
00606 jack_info("CoreMIDI driver is opened...");
00607 }
00608
00609 return 0;
00610 }
00611
00612 int
00613 JackCoreMidiDriver::Start()
00614 {
00615 jack_info("JackCoreMidiDriver::Start - Starting driver.");
00616
00617 JackMidiDriver::Start();
00618
00619 int pi_count = 0;
00620 int po_count = 0;
00621 int vi_count = 0;
00622 int vo_count = 0;
00623
00624 jack_info("JackCoreMidiDriver::Start - Enabling physical input ports.");
00625
00626 for (; pi_count < num_physical_inputs; pi_count++) {
00627 if (physical_input_ports[pi_count]->Start() < 0) {
00628 jack_error("JackCoreMidiDriver::Start - Failed to enable physical "
00629 "input port.");
00630 goto stop_physical_input_ports;
00631 }
00632 }
00633
00634 jack_info("JackCoreMidiDriver::Start - Enabling physical output ports.");
00635
00636 for (; po_count < num_physical_outputs; po_count++) {
00637 if (physical_output_ports[po_count]->Start() < 0) {
00638 jack_error("JackCoreMidiDriver::Start - Failed to enable physical "
00639 "output port.");
00640 goto stop_physical_output_ports;
00641 }
00642 }
00643
00644 jack_info("JackCoreMidiDriver::Start - Enabling virtual input ports.");
00645
00646 for (; vi_count < num_virtual_inputs; vi_count++) {
00647 if (virtual_input_ports[vi_count]->Start() < 0) {
00648 jack_error("JackCoreMidiDriver::Start - Failed to enable virtual "
00649 "input port.");
00650 goto stop_virtual_input_ports;
00651 }
00652 }
00653
00654 jack_info("JackCoreMidiDriver::Start - Enabling virtual output ports.");
00655
00656 for (; vo_count < num_virtual_outputs; vo_count++) {
00657 if (virtual_output_ports[vo_count]->Start() < 0) {
00658 jack_error("JackCoreMidiDriver::Start - Failed to enable virtual "
00659 "output port.");
00660 goto stop_virtual_output_ports;
00661 }
00662 }
00663
00664 jack_info("JackCoreMidiDriver::Start - Driver started.");
00665
00666 return 0;
00667
00668 stop_virtual_output_ports:
00669 for (int i = 0; i < vo_count; i++) {
00670 if (virtual_output_ports[i]->Stop() < 0) {
00671 jack_error("JackCoreMidiDriver::Start - Failed to disable virtual "
00672 "output port.");
00673 }
00674 }
00675 stop_virtual_input_ports:
00676 for (int i = 0; i < vi_count; i++) {
00677 if (virtual_input_ports[i]->Stop() < 0) {
00678 jack_error("JackCoreMidiDriver::Start - Failed to disable virtual "
00679 "input port.");
00680 }
00681 }
00682 stop_physical_output_ports:
00683 for (int i = 0; i < po_count; i++) {
00684 if (physical_output_ports[i]->Stop() < 0) {
00685 jack_error("JackCoreMidiDriver::Start - Failed to disable "
00686 "physical output port.");
00687 }
00688 }
00689 stop_physical_input_ports:
00690 for (int i = 0; i < pi_count; i++) {
00691 if (physical_input_ports[i]->Stop() < 0) {
00692 jack_error("JackCoreMidiDriver::Start - Failed to disable "
00693 "physical input port.");
00694 }
00695 }
00696
00697 return -1;
00698 }
00699
00700 int
00701 JackCoreMidiDriver::Stop()
00702 {
00703 int result = 0;
00704
00705 JackMidiDriver::Stop();
00706
00707 jack_info("JackCoreMidiDriver::Stop - disabling physical input ports.");
00708
00709 for (int i = 0; i < num_physical_inputs; i++) {
00710 if (physical_input_ports[i]->Stop() < 0) {
00711 jack_error("JackCoreMidiDriver::Stop - Failed to disable physical "
00712 "input port.");
00713 result = -1;
00714 }
00715 }
00716
00717 jack_info("JackCoreMidiDriver::Stop - disabling physical output ports.");
00718
00719 for (int i = 0; i < num_physical_outputs; i++) {
00720 if (physical_output_ports[i]->Stop() < 0) {
00721 jack_error("JackCoreMidiDriver::Stop - Failed to disable physical "
00722 "output port.");
00723 result = -1;
00724 }
00725 }
00726
00727 jack_info("JackCoreMidiDriver::Stop - disabling virtual input ports.");
00728
00729 for (int i = 0; i < num_virtual_inputs; i++) {
00730 if (virtual_input_ports[i]->Stop() < 0) {
00731 jack_error("JackCoreMidiDriver::Stop - Failed to disable virtual "
00732 "input port.");
00733 result = -1;
00734 }
00735 }
00736
00737 jack_info("JackCoreMidiDriver::Stop - disabling virtual output ports.");
00738
00739 for (int i = 0; i < num_virtual_outputs; i++) {
00740 if (virtual_output_ports[i]->Stop() < 0) {
00741 jack_error("JackCoreMidiDriver::Stop - Failed to disable virtual "
00742 "output port.");
00743 result = -1;
00744 }
00745 }
00746
00747 return result;
00748 }
00749
00750 int
00751 JackCoreMidiDriver::ProcessRead()
00752 {
00753 int res;
00754 if (Trylock()) {
00755 res = (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync();
00756 Unlock();
00757 } else {
00758 res = -1;
00759 }
00760 return res;
00761 }
00762
00763 int
00764 JackCoreMidiDriver::ProcessWrite()
00765 {
00766 int res;
00767 if (Trylock()) {
00768 res = (fEngineControl->fSyncMode) ? ProcessWriteSync() : ProcessWriteAsync();
00769 Unlock();
00770 } else {
00771 res = -1;
00772 }
00773 return res;
00774 }
00775
00776 int
00777 JackCoreMidiDriver::Read()
00778 {
00779 jack_nframes_t buffer_size = fEngineControl->fBufferSize;
00780 for (int i = 0; i < num_physical_inputs; i++) {
00781 physical_input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size);
00782 }
00783 for (int i = 0; i < num_virtual_inputs; i++) {
00784 virtual_input_ports[i]->
00785 ProcessJack(GetInputBuffer(num_physical_inputs + i), buffer_size);
00786 }
00787 return 0;
00788 }
00789
00790 int
00791 JackCoreMidiDriver::Write()
00792 {
00793 jack_nframes_t buffer_size = fEngineControl->fBufferSize;
00794 for (int i = 0; i < num_physical_outputs; i++) {
00795 physical_output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size);
00796 }
00797 for (int i = 0; i < num_virtual_outputs; i++) {
00798 virtual_output_ports[i]->
00799 ProcessJack(GetOutputBuffer(num_physical_outputs + i), buffer_size);
00800 }
00801 return 0;
00802 }
00803
00804 #ifdef __cplusplus
00805 extern "C" {
00806 #endif
00807
00808
00809 static Jack::JackCoreMidiDriver* driver = NULL;
00810
00811 SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor()
00812 {
00813 jack_driver_desc_t * desc;
00814 jack_driver_desc_filler_t filler;
00815 jack_driver_param_value_t value;
00816
00817 desc = jack_driver_descriptor_construct("coremidi", JackDriverSlave, "Apple CoreMIDI API based MIDI backend", &filler);
00818
00819 value.ui = 0;
00820 jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamUInt, &value, NULL, "CoreMIDI virtual bus", NULL);
00821 jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamUInt, &value, NULL, "CoreMIDI virtual bus", NULL);
00822
00823 return desc;
00824 }
00825
00826 SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params)
00827 {
00828 const JSList * node;
00829 const jack_driver_param_t * param;
00830 int virtual_in = 2;
00831 int virtual_out = 2;
00832
00833 for (node = params; node; node = jack_slist_next (node)) {
00834 param = (const jack_driver_param_t *) node->data;
00835
00836 switch (param->character) {
00837
00838 case 'i':
00839 virtual_in = param->value.ui;
00840 break;
00841
00842 case 'o':
00843 virtual_out = param->value.ui;
00844 break;
00845 }
00846 }
00847
00848
00849 if (!driver) {
00850 driver = new Jack::JackCoreMidiDriver("system_midi", "coremidi", engine, table);
00851 if (driver->Open(1, 1, virtual_in, virtual_out, false, "in", "out", 0, 0) == 0) {
00852 return driver;
00853 } else {
00854 delete driver;
00855 return NULL;
00856 }
00857 } else {
00858 jack_info("JackCoreMidiDriver already allocated, cannot be loaded twice");
00859 return NULL;
00860 }
00861 }
00862
00863 #ifdef __cplusplus
00864 }
00865 #endif