Jack2  1.9.8
JackThreadedDriver.cpp
00001 /*
00002  Copyright (C) 2001 Paul Davis
00003  Copyright (C) 2004-2008 Grame
00004 
00005  This program is free software; you can redistribute it and/or modify
00006  it under the terms of the GNU General Public License as published by
00007  the Free Software Foundation; either version 2 of the License, or
00008  (at your option) any later version.
00009 
00010  This program is distributed in the hope that it will be useful,
00011  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  GNU General Public License for more details.
00014 
00015  You should have received a copy of the GNU General Public License
00016  along with this program; if not, write to the Free Software
00017  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 
00019 */
00020 
00021 #include "JackSystemDeps.h"
00022 #include "JackThreadedDriver.h"
00023 #include "JackError.h"
00024 #include "JackTools.h"
00025 #include "JackGlobals.h"
00026 #include "JackEngineControl.h"
00027 
00028 namespace Jack
00029 {
00030 
00031 JackThreadedDriver::JackThreadedDriver(JackDriver* driver):fThread(this)
00032 {
00033     fDriver = driver;
00034 }
00035 
00036 JackThreadedDriver::~JackThreadedDriver()
00037 {
00038     delete fDriver;
00039 }
00040 
00041 int JackThreadedDriver::Open()
00042 {
00043     return fDriver->Open();
00044 }
00045 
00046 int JackThreadedDriver::Open(jack_nframes_t buffer_size,
00047                              jack_nframes_t samplerate,
00048                              bool capturing,
00049                              bool playing,
00050                              int inchannels,
00051                              int outchannels,
00052                              bool monitor,
00053                              const char* capture_driver_name,
00054                              const char* playback_driver_name,
00055                              jack_nframes_t capture_latency,
00056                              jack_nframes_t playback_latency)
00057 {
00058     return fDriver->Open(buffer_size,
00059                         samplerate, capturing,
00060                         playing, inchannels,
00061                         outchannels, monitor,
00062                         capture_driver_name, playback_driver_name,
00063                         capture_latency, playback_latency);
00064 }
00065 
00066 int JackThreadedDriver::Close()
00067 {
00068     return fDriver->Close();
00069 }
00070 
00071 int JackThreadedDriver::Process()
00072 {
00073     return fDriver->Process();
00074 }
00075 
00076 int JackThreadedDriver::Attach()
00077 {
00078     return fDriver->Attach();
00079 }
00080 
00081 int JackThreadedDriver::Detach()
00082 {
00083     return fDriver->Detach();
00084 }
00085 
00086 int JackThreadedDriver::Read()
00087 {
00088     return fDriver->Read();
00089 }
00090 
00091 int JackThreadedDriver::Write()
00092 {
00093     return fDriver->Write();
00094 }
00095 
00096 bool JackThreadedDriver::IsFixedBufferSize()
00097 {
00098     return fDriver->IsFixedBufferSize();
00099 }
00100 
00101 int JackThreadedDriver::SetBufferSize(jack_nframes_t buffer_size)
00102 {
00103     return fDriver->SetBufferSize(buffer_size);
00104 }
00105 
00106 int JackThreadedDriver::SetSampleRate(jack_nframes_t sample_rate)
00107 {
00108     return fDriver->SetSampleRate(sample_rate);
00109 }
00110 
00111 void JackThreadedDriver::SetMaster(bool onoff)
00112 {
00113     fDriver->SetMaster(onoff);
00114 }
00115 
00116 bool JackThreadedDriver::GetMaster()
00117 {
00118     return fDriver->GetMaster();
00119 }
00120 
00121 void JackThreadedDriver::AddSlave(JackDriverInterface* slave)
00122 {
00123     fDriver->AddSlave(slave);
00124 }
00125 
00126 void JackThreadedDriver::RemoveSlave(JackDriverInterface* slave)
00127 {
00128     fDriver->RemoveSlave(slave);
00129 }
00130 
00131 int JackThreadedDriver::ProcessReadSlaves()
00132 {
00133     return fDriver->ProcessReadSlaves();
00134 }
00135 
00136 int JackThreadedDriver::ProcessWriteSlaves()
00137 {
00138     return fDriver->ProcessWriteSlaves();
00139 }
00140 
00141 int JackThreadedDriver::ProcessRead()
00142 {
00143     return fDriver->ProcessRead();
00144 }
00145 
00146 int JackThreadedDriver::ProcessWrite()
00147 {
00148     return fDriver->ProcessWrite();
00149 }
00150 
00151 int JackThreadedDriver::ProcessReadSync()
00152 {
00153     return fDriver->ProcessReadSync();
00154 }
00155 
00156 int JackThreadedDriver::ProcessWriteSync()
00157 {
00158     return fDriver->ProcessWriteSync();
00159 }
00160 
00161 int JackThreadedDriver::ProcessReadAsync()
00162 {
00163     return fDriver->ProcessReadAsync();
00164 }
00165 
00166 int JackThreadedDriver::ProcessWriteAsync()
00167 {
00168     return fDriver->ProcessWriteAsync();
00169 }
00170 
00171 std::list<JackDriverInterface*> JackThreadedDriver::GetSlaves()
00172 {
00173     return fDriver->GetSlaves();
00174 }
00175 
00176 int JackThreadedDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
00177 {
00178     return fDriver->ClientNotify(refnum, name, notify, sync, message, value1, value2);
00179 }
00180 
00181 JackClientControl* JackThreadedDriver::GetClientControl() const
00182 {
00183     return fDriver->GetClientControl();
00184 }
00185 
00186 bool JackThreadedDriver::IsRealTime() const
00187 {
00188     return fDriver->IsRealTime();
00189 }
00190 
00191 bool JackThreadedDriver::IsRunning() const
00192 {
00193     return fDriver->IsRunning();
00194 }
00195 
00196 int JackThreadedDriver::Start()
00197 {
00198     jack_log("JackThreadedDriver::Start");
00199 
00200     if (fDriver->Start() < 0) {
00201         jack_error("Cannot start driver");
00202         return -1;
00203     }
00204     if (fThread.StartSync() < 0) {
00205         jack_error("Cannot start thread");
00206         return -1;
00207     }
00208 
00209     return 0;
00210 }
00211 
00212 int JackThreadedDriver::Stop()
00213 {
00214     jack_log("JackThreadedDriver::Stop");
00215 
00216     switch (fThread.GetStatus()) {
00217 
00218         // Kill the thread in Init phase
00219         case JackThread::kStarting:
00220         case JackThread::kIniting:
00221             if (fThread.Kill() < 0) {
00222                 jack_error("Cannot kill thread");
00223             }
00224             break;
00225 
00226         // Stop when the thread cycle is finished
00227         case JackThread::kRunning:
00228             if (fThread.Stop() < 0) {
00229                 jack_error("Cannot stop thread");
00230             }
00231             break;
00232 
00233         default:
00234             break;
00235     }
00236 
00237     if (fDriver->Stop() < 0) {
00238         jack_error("Cannot stop driver");
00239         return -1;
00240     }
00241     return 0;
00242 }
00243 
00244 bool JackThreadedDriver::Execute()
00245 {
00246     return (Process() == 0);
00247 }
00248 
00249 bool JackThreadedDriver::Init()
00250 {
00251     if (fDriver->Initialize())  {
00252         SetRealTime();
00253         return true;
00254     } else {
00255         return false;
00256     }
00257 }
00258 
00259 void JackThreadedDriver::SetRealTime()
00260 {
00261     if (fDriver->IsRealTime()) {
00262         jack_log("JackThreadedDriver::Init real-time");
00263         // Will do "something" on OSX only...
00264         GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000;
00265         GetEngineControl()->fComputation = JackTools::ComputationMicroSec(GetEngineControl()->fBufferSize) * 1000;
00266         fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint);
00267         if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) {
00268             jack_error("AcquireSelfRealTime error");
00269         } else {
00270             set_threaded_log_function();
00271         }
00272     } else {
00273         jack_log("JackThreadedDriver::Init non-realtime");
00274     }
00275 }
00276 
00277 
00278 } // end of namespace