1 /*
2 Copyright (C) 2001 Paul Davis
3 Copyright (C) 2004-2008 Grame
4
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.
9
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.
14
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.
18
19 */
20
21 #include "JackSystemDeps.h"
22 #include "JackThreadedDriver.h"
23 #include "JackError.h"
24 #include "JackTools.h"
25 #include "JackGlobals.h"
26 #include "JackEngineControl.h"
27
28 namespace Jack
29 {
30
JackThreadedDriver(JackDriver * driver)31 JackThreadedDriver::JackThreadedDriver(JackDriver* driver):fThread(this),fDriver(driver)
32 {}
33
~JackThreadedDriver()34 JackThreadedDriver::~JackThreadedDriver()
35 {
36 delete fDriver;
37 }
38
Open()39 int JackThreadedDriver::Open()
40 {
41 return fDriver->Open();
42 }
43
Open(jack_nframes_t buffer_size,jack_nframes_t samplerate,bool capturing,bool playing,int inchannels,int outchannels,bool monitor,const char * capture_driver_name,const char * playback_driver_name,jack_nframes_t capture_latency,jack_nframes_t playback_latency)44 int JackThreadedDriver::Open(jack_nframes_t buffer_size,
45 jack_nframes_t samplerate,
46 bool capturing,
47 bool playing,
48 int inchannels,
49 int outchannels,
50 bool monitor,
51 const char* capture_driver_name,
52 const char* playback_driver_name,
53 jack_nframes_t capture_latency,
54 jack_nframes_t playback_latency)
55 {
56 return fDriver->Open(buffer_size,
57 samplerate, capturing,
58 playing, inchannels,
59 outchannels, monitor,
60 capture_driver_name, playback_driver_name,
61 capture_latency, playback_latency);
62 }
63
Close()64 int JackThreadedDriver::Close()
65 {
66 return fDriver->Close();
67 }
68
Process()69 int JackThreadedDriver::Process()
70 {
71 return fDriver->Process();
72 }
73
Attach()74 int JackThreadedDriver::Attach()
75 {
76 return fDriver->Attach();
77 }
78
Detach()79 int JackThreadedDriver::Detach()
80 {
81 return fDriver->Detach();
82 }
83
Read()84 int JackThreadedDriver::Read()
85 {
86 return fDriver->Read();
87 }
88
Write()89 int JackThreadedDriver::Write()
90 {
91 return fDriver->Write();
92 }
93
IsFixedBufferSize()94 bool JackThreadedDriver::IsFixedBufferSize()
95 {
96 return fDriver->IsFixedBufferSize();
97 }
98
SetBufferSize(jack_nframes_t buffer_size)99 int JackThreadedDriver::SetBufferSize(jack_nframes_t buffer_size)
100 {
101 return fDriver->SetBufferSize(buffer_size);
102 }
103
SetSampleRate(jack_nframes_t sample_rate)104 int JackThreadedDriver::SetSampleRate(jack_nframes_t sample_rate)
105 {
106 return fDriver->SetSampleRate(sample_rate);
107 }
108
SetMaster(bool onoff)109 void JackThreadedDriver::SetMaster(bool onoff)
110 {
111 fDriver->SetMaster(onoff);
112 }
113
GetMaster()114 bool JackThreadedDriver::GetMaster()
115 {
116 return fDriver->GetMaster();
117 }
118
AddSlave(JackDriverInterface * slave)119 void JackThreadedDriver::AddSlave(JackDriverInterface* slave)
120 {
121 fDriver->AddSlave(slave);
122 }
123
RemoveSlave(JackDriverInterface * slave)124 void JackThreadedDriver::RemoveSlave(JackDriverInterface* slave)
125 {
126 fDriver->RemoveSlave(slave);
127 }
128
ProcessReadSlaves()129 int JackThreadedDriver::ProcessReadSlaves()
130 {
131 return fDriver->ProcessReadSlaves();
132 }
133
ProcessWriteSlaves()134 int JackThreadedDriver::ProcessWriteSlaves()
135 {
136 return fDriver->ProcessWriteSlaves();
137 }
138
ProcessRead()139 int JackThreadedDriver::ProcessRead()
140 {
141 return fDriver->ProcessRead();
142 }
143
ProcessWrite()144 int JackThreadedDriver::ProcessWrite()
145 {
146 return fDriver->ProcessWrite();
147 }
148
ProcessReadSync()149 int JackThreadedDriver::ProcessReadSync()
150 {
151 return fDriver->ProcessReadSync();
152 }
153
ProcessWriteSync()154 int JackThreadedDriver::ProcessWriteSync()
155 {
156 return fDriver->ProcessWriteSync();
157 }
158
ProcessReadAsync()159 int JackThreadedDriver::ProcessReadAsync()
160 {
161 return fDriver->ProcessReadAsync();
162 }
163
ProcessWriteAsync()164 int JackThreadedDriver::ProcessWriteAsync()
165 {
166 return fDriver->ProcessWriteAsync();
167 }
168
GetSlaves()169 std::list<JackDriverInterface*> JackThreadedDriver::GetSlaves()
170 {
171 return fDriver->GetSlaves();
172 }
173
ClientNotify(int refnum,const char * name,int notify,int sync,const char * message,int value1,int value2)174 int JackThreadedDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
175 {
176 return fDriver->ClientNotify(refnum, name, notify, sync, message, value1, value2);
177 }
178
GetClientControl() const179 JackClientControl* JackThreadedDriver::GetClientControl() const
180 {
181 return fDriver->GetClientControl();
182 }
183
IsRealTime() const184 bool JackThreadedDriver::IsRealTime() const
185 {
186 return fDriver->IsRealTime();
187 }
188
IsRunning() const189 bool JackThreadedDriver::IsRunning() const
190 {
191 return fDriver->IsRunning();
192 }
193
Start()194 int JackThreadedDriver::Start()
195 {
196 jack_log("JackThreadedDriver::Start");
197
198 if (fDriver->Start() < 0) {
199 jack_error("Cannot start driver");
200 return -1;
201 }
202 if (fThread.StartSync() < 0) {
203 jack_error("Cannot start thread");
204 return -1;
205 }
206
207 return 0;
208 }
209
Stop()210 int JackThreadedDriver::Stop()
211 {
212 jack_log("JackThreadedDriver::Stop");
213
214 switch (fThread.GetStatus()) {
215
216 // Kill the thread in Init phase
217 case JackThread::kStarting:
218 case JackThread::kIniting:
219 if (fThread.Kill() < 0) {
220 jack_error("Cannot kill thread");
221 }
222 break;
223
224 // Stop when the thread cycle is finished
225 case JackThread::kRunning:
226 if (fThread.Stop() < 0) {
227 jack_error("Cannot stop thread");
228 }
229 break;
230
231 default:
232 break;
233 }
234
235 if (fDriver->Stop() < 0) {
236 jack_error("Cannot stop driver");
237 return -1;
238 }
239 return 0;
240 }
241
Execute()242 bool JackThreadedDriver::Execute()
243 {
244 return (Process() == 0);
245 }
246
Init()247 bool JackThreadedDriver::Init()
248 {
249 if (fDriver->Initialize()) {
250 SetRealTime();
251 return true;
252 } else {
253 return false;
254 }
255 }
256
SetRealTime()257 void JackThreadedDriver::SetRealTime()
258 {
259 if (fDriver->IsRealTime()) {
260 jack_log("JackThreadedDriver::Init real-time");
261 // Will do "something" on OSX only...
262 GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000;
263 GetEngineControl()->fComputation = JackTools::ComputationMicroSec(GetEngineControl()->fBufferSize) * 1000;
264 fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint);
265 if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) {
266 jack_error("AcquireSelfRealTime error");
267 } else {
268 set_threaded_log_function();
269 }
270 } else {
271 jack_log("JackThreadedDriver::Init non-realtime");
272 }
273 }
274
275
276 } // end of namespace
277