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