00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef WIN32
00022 #pragma warning (disable : 4786)
00023 #endif
00024
00025 #include "JackAudioDriver.h"
00026 #include "JackTime.h"
00027 #include "JackError.h"
00028 #include "JackEngineControl.h"
00029 #include "JackClientControl.h"
00030 #include "JackPort.h"
00031 #include "JackGraphManager.h"
00032 #include "JackEngine.h"
00033 #include <assert.h>
00034
00035 namespace Jack
00036 {
00037
00038 JackAudioDriver::JackAudioDriver(const char* name, JackEngine* engine, JackSynchro** table)
00039 : JackDriver(name, engine, table),
00040 fCaptureChannels(0),
00041 fPlaybackChannels(0),
00042 fWithMonitorPorts(false)
00043 {}
00044
00045 JackAudioDriver::~JackAudioDriver()
00046 {}
00047
00048 int JackAudioDriver::SetBufferSize(jack_nframes_t buffer_size)
00049 {
00050 fEngineControl->fBufferSize = buffer_size;
00051 fGraphManager->SetBufferSize(buffer_size);
00052 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize);
00053 if (!fEngineControl->fTimeOut)
00054 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs);
00055 return 0;
00056 }
00057
00058 int JackAudioDriver::SetSampleRate(jack_nframes_t sample_rate)
00059 {
00060 fEngineControl->fSampleRate = sample_rate;
00061 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize);
00062 if (!fEngineControl->fTimeOut)
00063 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs);
00064 return 0;
00065 }
00066
00067 int JackAudioDriver::Open(jack_nframes_t nframes,
00068 jack_nframes_t samplerate,
00069 int capturing,
00070 int playing,
00071 int inchannels,
00072 int outchannels,
00073 bool monitor,
00074 const char* capture_driver_name,
00075 const char* playback_driver_name,
00076 jack_nframes_t capture_latency,
00077 jack_nframes_t playback_latency)
00078 {
00079 fCaptureChannels = inchannels;
00080 fPlaybackChannels = outchannels;
00081 fWithMonitorPorts = monitor;
00082 return JackDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency);
00083 }
00084
00085 int JackAudioDriver::Attach()
00086 {
00087 JackPort* port;
00088 jack_port_id_t port_index;
00089 char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE];
00090 char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE];
00091 unsigned long port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
00092 int i;
00093
00094 JackLog("JackAudioDriver::Attach fBufferSize = %ld fSampleRate = %ld\n", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
00095
00096 for (i = 0; i < fCaptureChannels; i++) {
00097 snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fClientControl->fName, fCaptureDriverName, i + 1);
00098 snprintf(name, sizeof(name) - 1, "system:capture_%d", i + 1);
00099 if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) {
00100 jack_error("driver: cannot register port for %s", name);
00101 return -1;
00102 }
00103 port = fGraphManager->GetPort(port_index);
00104 port->SetAlias(alias);
00105 port->SetLatency(fEngineControl->fBufferSize + fCaptureLatency);
00106 fCapturePortList[i] = port_index;
00107 JackLog("JackAudioDriver::Attach fCapturePortList[i] port_index = %ld\n", port_index);
00108 }
00109
00110 port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
00111
00112 for (i = 0; i < fPlaybackChannels; i++) {
00113 snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fClientControl->fName, fPlaybackDriverName, i + 1);
00114 snprintf(name, sizeof(name) - 1, "system:playback_%d", i + 1);
00115 if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) {
00116 jack_error("driver: cannot register port for %s", name);
00117 return -1;
00118 }
00119 port = fGraphManager->GetPort(port_index);
00120 port->SetAlias(alias);
00121 port->SetLatency(fEngineControl->fBufferSize + fPlaybackLatency);
00122 fPlaybackPortList[i] = port_index;
00123 JackLog("JackAudioDriver::Attach fPlaybackPortList[i] port_index = %ld\n", port_index);
00124
00125
00126 if (fWithMonitorPorts) {
00127 JackLog("Create monitor port \n");
00128 snprintf(name, sizeof(name) - 1, "%s:%s:monitor_%u", fClientControl->fName, fPlaybackDriverName, i + 1);
00129 if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) {
00130 jack_error("Cannot register monitor port for %s", name);
00131 return -1;
00132 } else {
00133 port = fGraphManager->GetPort(port_index);
00134 port->SetLatency(fEngineControl->fBufferSize);
00135 fMonitorPortList[i] = port_index;
00136 }
00137 }
00138 }
00139
00140 return 0;
00141 }
00142
00143 int JackAudioDriver::Detach()
00144 {
00145 int i;
00146 JackLog("JackAudioDriver::Detach\n");
00147
00148 for (i = 0; i < fCaptureChannels; i++) {
00149 fGraphManager->ReleasePort(fClientControl->fRefNum, fCapturePortList[i]);
00150 }
00151
00152 for (i = 0; i < fPlaybackChannels; i++) {
00153 fGraphManager->ReleasePort(fClientControl->fRefNum, fPlaybackPortList[i]);
00154 if (fWithMonitorPorts)
00155 fGraphManager->ReleasePort(fClientControl->fRefNum, fMonitorPortList[i]);
00156 }
00157
00158 return 0;
00159 }
00160
00161 int JackAudioDriver::Write()
00162 {
00163 for (int i = 0; i < fPlaybackChannels; i++) {
00164 if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) {
00165 float* buffer = GetOutputBuffer(i);
00166 int size = sizeof(float) * fEngineControl->fBufferSize;
00167
00168 if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0)
00169 memcpy(GetMonitorBuffer(i), buffer, size);
00170 }
00171 }
00172 return 0;
00173 }
00174
00175 int JackAudioDriver::Process()
00176 {
00177 return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync();
00178 }
00179
00180
00181
00182
00183
00184
00185 int JackAudioDriver::ProcessAsync()
00186 {
00187 if (Read() < 0) {
00188 jack_error("ProcessAsync: read error");
00189 return 0;
00190 }
00191
00192 if (Write() < 0) {
00193 jack_error("ProcessAsync: write error");
00194 return 0;
00195 }
00196
00197 if (fIsMaster) {
00198 if (!fEngine->Process(fLastWaitUst))
00199 jack_error("JackAudioDriver::ProcessAsync Process error");
00200 fGraphManager->ResumeRefNum(fClientControl, fSynchroTable);
00201 if (ProcessSlaves() < 0)
00202 jack_error("JackAudioDriver::ProcessAsync ProcessSlaves error");
00203 } else {
00204 fGraphManager->ResumeRefNum(fClientControl, fSynchroTable);
00205 }
00206 return 0;
00207 }
00208
00209
00210
00211
00212
00213
00214 int JackAudioDriver::ProcessSync()
00215 {
00216 if (Read() < 0) {
00217 jack_error("ProcessSync: read error");
00218 return 0;
00219 }
00220
00221 if (fIsMaster) {
00222
00223 if (fEngine->Process(fLastWaitUst)) {
00224 fGraphManager->ResumeRefNum(fClientControl, fSynchroTable);
00225 if (ProcessSlaves() < 0)
00226 jack_error("JackAudioDriver::ProcessSync ProcessSlaves error, engine may now behave abnormally!!");
00227 if (fGraphManager->SuspendRefNum(fClientControl, fSynchroTable, fEngineControl->fTimeOutUsecs) < 0)
00228 jack_error("JackAudioDriver::ProcessSync SuspendRefNum error, engine may now behave abnormally!!");
00229 } else {
00230 jack_error("ProcessSync: error");
00231 }
00232
00233 if (Write() < 0)
00234 jack_error("ProcessSync: write error");
00235
00236 } else {
00237 fGraphManager->ResumeRefNum(fClientControl, fSynchroTable);
00238 }
00239 return 0;
00240 }
00241
00242 void JackAudioDriver::NotifyXRun(jack_time_t callback_usecs)
00243 {
00244 fEngine->NotifyXRun(callback_usecs);
00245 }
00246
00247 jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index)
00248 {
00249 assert(fCapturePortList[port_index]);
00250 return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize);
00251 }
00252
00253 jack_default_audio_sample_t* JackAudioDriver::GetOutputBuffer(int port_index)
00254 {
00255 assert(fPlaybackPortList[port_index]);
00256 return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize);
00257 }
00258
00259 jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index)
00260 {
00261 assert(fPlaybackPortList[port_index]);
00262 return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize);
00263 }
00264
00265 }