21 #include "JackSystemDeps.h"    22 #include "JackDriver.h"    24 #include "JackError.h"    26 #include "JackGraphManager.h"    27 #include "JackGlobals.h"    28 #include "JackEngineControl.h"    29 #include "JackClientControl.h"    30 #include "JackLockedEngine.h"    40 JackDriver::JackDriver(
const char* name, 
const char* alias, JackLockedEngine* engine, JackSynchro* table)
    44     fWithMonitorPorts(false){
    45     assert(strlen(name) < JACK_CLIENT_NAME_SIZE);
    46     fSynchroTable = table;
    47     strcpy(fAliasName, alias);
    57 JackDriver::~JackDriver()
    62 int JackDriver::Open()
    66     if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, 
this, 
false) != 0) {
    67         jack_error(
"Cannot allocate internal client for driver");
    71     fClientControl.fRefNum = refnum;
    72     fClientControl.fActive = 
true;
    73     fEngineControl->fDriverNum++;
    74     fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); 
    79 int JackDriver::Open(jack_nframes_t buffer_size,
    80                      jack_nframes_t sample_rate,
    86                      const char* capture_driver_name,
    87                      const char* playback_driver_name,
    88                      jack_nframes_t capture_latency,
    89                      jack_nframes_t playback_latency)
    91     jack_log(
"JackDriver::Open capture_driver_name = %s", capture_driver_name);
    92     jack_log(
"JackDriver::Open playback_driver_name = %s", playback_driver_name);
    94     char name_res[JACK_CLIENT_NAME_SIZE + 1];
    98     if (fEngine->ClientCheck(fClientControl.fName, -1, name_res, JACK_PROTOCOL_VERSION, (
int)JackNullOption, (
int*)&status) < 0) {
    99         jack_error(
"Client name = %s conflits with another running client", fClientControl.fName);
   102     strcpy(fClientControl.fName, name_res);
   104     if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, 
this, 
false) != 0) {
   105         jack_error(
"Cannot allocate internal client for driver");
   109     fClientControl.fRefNum = refnum;
   110     fClientControl.fActive = 
true;
   111     fEngineControl->fDriverNum++;
   112     if (buffer_size > 0) {
   113         fEngineControl->fBufferSize = buffer_size;
   115     if (sample_rate > 0) {
   116         fEngineControl->fSampleRate = sample_rate;
   118     fCaptureLatency = capture_latency;
   119     fPlaybackLatency = playback_latency;
   121     assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE);
   122     assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE);
   124     strcpy(fCaptureDriverName, capture_driver_name);
   125     strcpy(fPlaybackDriverName, playback_driver_name);
   127     fEngineControl->UpdateTimeOut();
   129     fGraphManager->SetBufferSize(fEngineControl->fBufferSize);
   130     fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); 
   135 int JackDriver::Close()
   137     if (fClientControl.fRefNum >= 0) {
   139         fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); 
   140         fClientControl.fActive = 
false;
   141         fEngineControl->fDriverNum--;
   142         return fEngine->ClientInternalClose(fClientControl.fRefNum, 
false);
   155     if (!freewheel && !fEngineControl->fSyncMode) {
   156         jack_log(
"JackDriver::SetupDriverSync driver sem in flush mode");
   157         fSynchroTable[ref].SetFlush(
true);
   159         jack_log(
"JackDriver::SetupDriverSync driver sem in normal mode");
   160         fSynchroTable[ref].SetFlush(
false);
   164 int JackDriver::ClientNotify(
int refnum, 
const char* name, 
int notify, 
int sync, 
const char* message, 
int value1, 
int value2)
   166     jack_log(
"JackDriver::ClientNotify ref = %ld driver = %s name = %s notify = %ld", refnum, fClientControl.fName, name, notify);
   170         case kStartFreewheelCallback:
   171             jack_log(
"JackDriver::kStartFreewheel");
   175         case kStopFreewheelCallback:
   176             jack_log(
"JackDriver::kStopFreewheel");
   184 bool JackDriver::IsRealTime()
 const   186     return fEngineControl->fRealTime;
   189 void JackDriver::CycleIncTime()
   191     fEngineControl->CycleIncTime(fBeginDateUst);
   194 void JackDriver::CycleTakeBeginTime()
   196     fBeginDateUst = GetMicroSeconds();  
   197     fEngineControl->CycleIncTime(fBeginDateUst);
   200 void JackDriver::CycleTakeEndTime()
   202     fEndDateUst = GetMicroSeconds();    
   205 JackClientControl* JackDriver::GetClientControl()
 const   207     return (JackClientControl*)&fClientControl;
   210 void JackDriver::NotifyXRun(jack_time_t cur_cycle_begin, 
float delayed_usecs)
   212     fEngineControl->NotifyXRun(cur_cycle_begin, delayed_usecs);
   213     fEngine->NotifyDriverXRun();
   216 void JackDriver::NotifyBufferSize(jack_nframes_t buffer_size)
   218     fEngine->NotifyBufferSize(buffer_size);
   219     fEngineControl->InitFrameTime();
   222 void JackDriver::NotifySampleRate(jack_nframes_t sample_rate)
   224     fEngine->NotifySampleRate(sample_rate);
   225     fEngineControl->InitFrameTime();
   228 void JackDriver::NotifyFailure(
int code, 
const char* reason)
   230     fEngine->NotifyFailure(code, reason);
   233 void JackDriver::SetMaster(
bool onoff)
   238 bool JackDriver::GetMaster()
   243 void JackDriver::AddSlave(JackDriverInterface* slave)
   245     fSlaveList.push_back(slave);
   248 void JackDriver::RemoveSlave(JackDriverInterface* slave)
   250     fSlaveList.remove(slave);
   253 int JackDriver::ProcessReadSlaves()
   256     list<JackDriverInterface*>::const_iterator it;
   257     for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
   258         JackDriverInterface* slave = *it;
   259         if (slave->IsRunning()) {
   260             if (slave->ProcessRead() < 0) {
   268 int JackDriver::ProcessWriteSlaves()
   271     list<JackDriverInterface*>::const_iterator it;
   272     for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
   273         JackDriverInterface* slave = *it;
   274         if (slave->IsRunning()) {
   275             if (slave->ProcessWrite() < 0) {
   283 int JackDriver::ProcessRead()
   285     return (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync();
   288 int JackDriver::ProcessWrite()
   290     return (fEngineControl->fSyncMode) ? ProcessWriteSync() : ProcessWriteAsync();
   293 int JackDriver::ProcessReadSync()
   298 int JackDriver::ProcessWriteSync()
   303 int JackDriver::ProcessReadAsync()
   308 int JackDriver::ProcessWriteAsync()
   313 int JackDriver::Process()
   318 int JackDriver::Attach()
   323 int JackDriver::Detach()
   328 int JackDriver::Read()
   333 int JackDriver::Write()
   338 int JackDriver::Start()
   341         fEngineControl->InitFrameTime();
   344     return StartSlaves();
   347 int JackDriver::Stop()
   353 int JackDriver::StartSlaves()
   356     list<JackDriverInterface*>::const_iterator it;
   357     for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
   358         JackDriverInterface* slave = *it;
   359         if (slave->Start() < 0) {
   369 int JackDriver::StopSlaves()
   372     list<JackDriverInterface*>::const_iterator it;
   373     for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
   374         JackDriverInterface* slave = *it;
   375         if (slave->Stop() < 0) {
   382 bool JackDriver::IsFixedBufferSize()
   387 int JackDriver::SetBufferSize(jack_nframes_t buffer_size)
   390     list<JackDriverInterface*>::const_iterator it;
   391     for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
   392         JackDriverInterface* slave = *it;
   393         if (slave->SetBufferSize(buffer_size) < 0) {
   400 int JackDriver::SetSampleRate(jack_nframes_t sample_rate)
   403     list<JackDriverInterface*>::const_iterator it;
   404     for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
   405         JackDriverInterface* slave = *it;
   406         if (slave->SetSampleRate(sample_rate) < 0) {
   413 bool JackDriver::Initialize()
   418 static string RemoveLast(
const string& name)
   420     return name.substr(0, name.find_last_of(
':')); 
   423 void JackDriver::SaveConnections(
int alias)
   425     const char** connections;
   426     char alias1[REAL_JACK_PORT_NAME_SIZE+1];
   427     char alias2[REAL_JACK_PORT_NAME_SIZE+1];
   428     char system_alias1[REAL_JACK_PORT_NAME_SIZE+1];
   429     char system_alias2[REAL_JACK_PORT_NAME_SIZE+1];
   431     char* system_aliases[2];
   436     system_aliases[0] = system_alias1;
   437     system_aliases[1] = system_alias2;
   439     fConnections.clear();
   441     for (
int i = 0; i < fCaptureChannels; ++i) {
   442         if (fCapturePortList[i] && (connections = fGraphManager->GetConnections(fCapturePortList[i])) != 0) {
   444                 for (
int j = 0; connections[j]; j++) {
   445                     JackPort* port_id = fGraphManager->GetPort(fCapturePortList[i]);
   446                     fConnections.push_back(make_pair(port_id->GetType(), make_pair(port_id->GetName(), connections[j])));
   447                     jack_info(
"Save connection: %s %s", fGraphManager->GetPort(fCapturePortList[i])->GetName(), connections[j]);
   450                 int res1 = fGraphManager->GetPort(fCapturePortList[i])->GetAliases(aliases);
   451                 string sub_system_name;
   453                     sub_system_name = aliases[alias-1];
   455                     sub_system_name = fGraphManager->GetPort(fCapturePortList[i])->GetName();
   457                 for (
int j = 0; connections[j]; j++) {
   458                     JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j]));
   459                     int res2 = port_id->GetAliases(system_aliases);
   462                         sub_system = system_aliases[alias-1];
   464                         sub_system = connections[j];
   466                     fConnections.push_back(make_pair(port_id->GetType(), make_pair(sub_system_name, sub_system)));
   467                     jack_info(
"Save connection: %s %s", sub_system_name.c_str(), sub_system.c_str());
   474     for (
int i = 0; i < fPlaybackChannels; ++i) {
   475         if (fPlaybackPortList[i] && (connections = fGraphManager->GetConnections(fPlaybackPortList[i])) != 0) {
   477                 for (
int j = 0; connections[j]; j++) {
   478                     JackPort* port_id = fGraphManager->GetPort(fPlaybackPortList[i]);
   479                     fConnections.push_back(make_pair(port_id->GetType(), make_pair(connections[j], port_id->GetName())));
   480                     jack_info(
"Save connection: %s %s", connections[j], fGraphManager->GetPort(fPlaybackPortList[i])->GetName());
   483                 int res1 = fGraphManager->GetPort(fPlaybackPortList[i])->GetAliases(aliases);
   484                 string sub_system_name;
   486                     sub_system_name = aliases[alias-1];
   488                     sub_system_name = fGraphManager->GetPort(fPlaybackPortList[i])->GetName();
   490                 for (
int j = 0; connections[j]; j++) {
   491                     JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j]));
   492                     int res2 = port_id->GetAliases(system_aliases);
   495                         sub_name = system_aliases[alias-1];
   497                         sub_name = connections[j];
   499                     fConnections.push_back(make_pair(port_id->GetType(), make_pair(sub_name, sub_system_name)));
   500                     jack_info(
"Save connection: %s %s", sub_name.c_str(), sub_system_name.c_str());
   508 string JackDriver::MatchPortName(
const char* name, 
const char** ports, 
int alias, 
const std::string& type)
   510     char alias1[REAL_JACK_PORT_NAME_SIZE+1];
   511     char alias2[REAL_JACK_PORT_NAME_SIZE+1];
   517     for (
int i = 0; ports && ports[i]; ++i) {
   519         jack_port_id_t port_id2 = fGraphManager->GetPort(ports[i]);
   520         JackPort* port2 = (port_id2 != NO_PORT) ? fGraphManager->GetPort(port_id2) : NULL;
   523             int res = port2->GetAliases(aliases);
   526                 name_str = string(aliases[alias-1]);
   528                 name_str = string(ports[i]);
   530             string sub_name = RemoveLast(name);
   531             if ((name_str.find(sub_name) != string::npos) && (type == 
string(port2->GetType()))) {
   540 void JackDriver::LoadConnections(
int alias, 
bool full_name)
   542     list<pair<string, pair<string, string> > >::const_iterator it;
   545         for (it = fConnections.begin(); it != fConnections.end(); it++) {
   546             pair<string, string> connection = (*it).second;
   547             jack_info(
"Load connection: %s %s", connection.first.c_str(), connection.second.c_str());
   548             fEngine->PortConnect(fClientControl.fRefNum, connection.first.c_str(), connection.second.c_str());
   551         const char** inputs = fGraphManager->GetPorts(NULL, NULL, JackPortIsInput);
   552         const char** outputs = fGraphManager->GetPorts(NULL, NULL, JackPortIsOutput);
   554         for (it = fConnections.begin(); it != fConnections.end(); it++) {
   555             pair<string, string> connection = (*it).second;
   556             string real_input = MatchPortName(connection.first.c_str(), outputs, alias, (*it).first);
   557             string real_output = MatchPortName(connection.second.c_str(), inputs, alias, (*it).first);
   558             if ((real_input != 
"") && (real_output != 
"")) {
   559                 jack_info(
"Load connection: %s %s", real_input.c_str(), real_output.c_str());
   560                 fEngine->PortConnect(fClientControl.fRefNum, real_input.c_str(), real_output.c_str());
   565         if (fGraphManager->IsPendingChange()) {
   566             JackSleep(
int(fEngineControl->fPeriodUsecs * 1.1f));
   578 int JackDriver::ResumeRefNum()
   580     return fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable);
   583 int JackDriver::SuspendRefNum()
   585     return fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs);
 SERVER_EXPORT void jack_error(const char *fmt,...)
SERVER_EXPORT void jack_info(const char *fmt,...)
SERVER_EXPORT void jack_log(const char *fmt,...)
void SetupDriverSync(int ref, bool freewheel)