Dmitry Baikov patch for JackGraphManager.cpp.
[jack2.git] / common / JackDriver.cpp
blob152e26bbdf74a2eb1626bcdbbd9a765b650e811b
1 /*
2 Copyright (C) 2001 Paul Davis
3 Copyright (C) 2004-2006 Grame
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #ifdef WIN32
22 #pragma warning (disable : 4786)
23 #endif
25 #include "JackDriver.h"
26 #include "JackTime.h"
27 #include "JackError.h"
28 #include "JackPort.h"
29 #include "JackGraphManager.h"
30 #include "JackGlobals.h"
31 #include "JackEngineControl.h"
32 #include "JackClientControl.h"
33 #include "JackEngine.h"
34 #include <math.h>
35 #include <assert.h>
37 using namespace std;
39 namespace Jack
42 JackDriver::JackDriver(const char* name, JackEngine* engine, JackSynchro** table)
44 assert(strlen(name) < JACK_CLIENT_NAME_SIZE);
45 fSynchroTable = table;
46 fClientControl = new JackClientControl(name);
47 fEngine = engine;
48 fGraphManager = NULL;
49 fLastWaitUst = 0;
50 fIsMaster = true;
53 JackDriver::JackDriver()
55 fSynchroTable = NULL;
56 fClientControl = NULL;
57 fEngine = NULL;
58 fGraphManager = NULL;
59 fLastWaitUst = 0;
60 fIsMaster = true;
63 JackDriver::~JackDriver()
65 JackLog("~JackDriver\n");
66 delete fClientControl;
69 int JackDriver::Open()
71 int refnum = -1;
73 if (fEngine->ClientInternalOpen(fClientControl->fName, &refnum, &fEngineControl, &fGraphManager, this) != 0) {
74 jack_error("Cannot allocate internal client for audio driver");
75 return -1;
78 fClientControl->fRefNum = refnum;
79 fClientControl->fActive = true;
80 fGraphManager->DirectConnect(fClientControl->fRefNum, fClientControl->fRefNum); // Connect driver to itself for sync
83 In ASYNC mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations.
84 The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations.
86 if (!fEngineControl->fSyncMode) {
87 fSynchroTable[AUDIO_DRIVER_REFNUM]->SetFlush(true);
88 fSynchroTable[FREEWHEEL_DRIVER_REFNUM]->SetFlush(true);
89 fSynchroTable[LOOPBACK_DRIVER_REFNUM]->SetFlush(true);
91 return 0;
94 int JackDriver::Open(jack_nframes_t nframes,
95 jack_nframes_t samplerate,
96 int capturing,
97 int playing,
98 int inchannels,
99 int outchannels,
100 bool monitor,
101 const char* capture_driver_name,
102 const char* playback_driver_name,
103 jack_nframes_t capture_latency,
104 jack_nframes_t playback_latency)
106 JackLog("JackDriver::Open capture_driver_name = %s\n", capture_driver_name);
107 JackLog("JackDriver::Open playback_driver_name = %s\n", playback_driver_name);
108 int refnum = -1;
110 if (fEngine->ClientInternalOpen(fClientControl->fName, &refnum, &fEngineControl, &fGraphManager, this) != 0) {
111 jack_error("Cannot allocate internal client for audio driver");
112 return -1;
115 fClientControl->fRefNum = refnum;
116 fClientControl->fActive = true;
117 fEngineControl->fBufferSize = nframes;
118 fEngineControl->fSampleRate = samplerate;
119 fCaptureLatency = capture_latency;
120 fPlaybackLatency = playback_latency;
122 assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE);
123 assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE);
125 strcpy(fCaptureDriverName, capture_driver_name);
126 strcpy(fPlaybackDriverName, playback_driver_name);
128 fEngineControl->fPeriodUsecs = (jack_time_t)floor((((float)nframes) / (float)samplerate) * 1000000.0f);
129 if (fEngineControl->fTimeOutUsecs == 0) /* usecs; if zero, use 2 period size. */
130 fEngineControl->fTimeOutUsecs = (jack_time_t)(2.f * fEngineControl->fPeriodUsecs);
132 fGraphManager->DirectConnect(fClientControl->fRefNum, fClientControl->fRefNum); // Connect driver to itself for sync
135 In ASYNC mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations.
136 The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations.
138 if (!fEngineControl->fSyncMode) {
139 fSynchroTable[AUDIO_DRIVER_REFNUM]->SetFlush(true);
140 fSynchroTable[FREEWHEEL_DRIVER_REFNUM]->SetFlush(true);
141 fSynchroTable[LOOPBACK_DRIVER_REFNUM]->SetFlush(true);
143 return 0;
146 int JackDriver::Close()
148 JackLog("JackDriver::Close\n");
149 fGraphManager->DirectDisconnect(fClientControl->fRefNum, fClientControl->fRefNum); // Disconnect driver from itself for sync
150 fClientControl->fActive = false;
151 return fEngine->ClientInternalCloseIm(fClientControl->fRefNum);
154 bool JackDriver::IsRealTime()
156 return fEngineControl->fRealTime;
159 JackClientControl* JackDriver::GetClientControl() const
161 return fClientControl;
164 void JackDriver::NotifyXRun(jack_time_t callback_usecs)
166 fEngine->NotifyXRun(callback_usecs);
169 void JackDriverClient::SetMaster(bool onoff)
171 fIsMaster = onoff;
174 bool JackDriverClient::GetMaster()
176 return fIsMaster;
179 void JackDriverClient::AddSlave(JackDriverInterface* slave)
181 fSlaveList.push_back(slave);
184 void JackDriverClient::RemoveSlave(JackDriverInterface* slave)
186 fSlaveList.remove(slave);
189 int JackDriverClient::ProcessSlaves()
191 int res = 0;
192 list<JackDriverInterface*>::const_iterator it;
193 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
194 JackDriverInterface* slave = *it;
195 if (slave->Process() < 0)
196 res = -1;
198 return res;
201 } // end of namespace