Jack2
1.9.10
|
00001 /* 00002 Copyright (C) 2008 Grame 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00017 00018 */ 00019 00020 #include "JackAudioAdapter.h" 00021 #include "JackError.h" 00022 #include "JackCompilerDeps.h" 00023 #include "JackTools.h" 00024 #include "JackTime.h" 00025 #include "jslist.h" 00026 #include <stdio.h> 00027 #include <stdlib.h> 00028 #include <assert.h> 00029 00030 using namespace std; 00031 00032 namespace Jack 00033 { 00034 00035 int JackAudioAdapter::Process(jack_nframes_t frames, void* arg) 00036 { 00037 JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg); 00038 return adapter->ProcessAux(frames); 00039 } 00040 00041 int JackAudioAdapter::ProcessAux(jack_nframes_t frames) 00042 { 00043 // Always clear output 00044 for (int i = 0; i < fAudioAdapter->GetInputs(); i++) { 00045 fInputBufferList[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(fCapturePortList[i], frames); 00046 memset(fInputBufferList[i], 0, frames * sizeof(jack_default_audio_sample_t)); 00047 } 00048 00049 for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) { 00050 fOutputBufferList[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(fPlaybackPortList[i], frames); 00051 } 00052 00053 fAudioAdapter->PullAndPush(fInputBufferList, fOutputBufferList, frames); 00054 return 0; 00055 } 00056 00057 int JackAudioAdapter::BufferSize(jack_nframes_t buffer_size, void* arg) 00058 { 00059 JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg); 00060 adapter->Reset(); 00061 adapter->fAudioAdapter->SetHostBufferSize(buffer_size); 00062 return 0; 00063 } 00064 00065 int JackAudioAdapter::SampleRate(jack_nframes_t sample_rate, void* arg) 00066 { 00067 JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg); 00068 adapter->Reset(); 00069 adapter->fAudioAdapter->SetHostSampleRate(sample_rate); 00070 return 0; 00071 } 00072 00073 void JackAudioAdapter::Latency(jack_latency_callback_mode_t mode, void* arg) 00074 { 00075 JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg); 00076 00077 if (mode == JackCaptureLatency) { 00078 for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) { 00079 jack_latency_range_t range; 00080 range.min = range.max = adapter->fAudioAdapter->GetInputLatency(i); 00081 jack_port_set_latency_range(adapter->fCapturePortList[i], JackCaptureLatency, &range); 00082 } 00083 00084 } else { 00085 for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) { 00086 jack_latency_range_t range; 00087 range.min = range.max = adapter->fAudioAdapter->GetOutputLatency(i); 00088 jack_port_set_latency_range(adapter->fPlaybackPortList[i], JackPlaybackLatency, &range); 00089 } 00090 } 00091 } 00092 00093 JackAudioAdapter::JackAudioAdapter(jack_client_t* client, JackAudioAdapterInterface* audio_io, const JSList* params) 00094 :fClient(client), fAudioAdapter(audio_io) 00095 { 00096 const JSList* node; 00097 const jack_driver_param_t* param; 00098 fAutoConnect = false; 00099 00100 for (node = params; node; node = jack_slist_next(node)) { 00101 param = (const jack_driver_param_t*)node->data; 00102 switch (param->character) { 00103 case 'c': 00104 fAutoConnect = true; 00105 break; 00106 } 00107 } 00108 } 00109 00110 JackAudioAdapter::~JackAudioAdapter() 00111 { 00112 // When called, Close has already been used for the client, thus ports are already unregistered. 00113 delete fAudioAdapter; 00114 } 00115 00116 void JackAudioAdapter::FreePorts() 00117 { 00118 for (int i = 0; i < fAudioAdapter->GetInputs(); i++) { 00119 if (fCapturePortList[i]) { 00120 jack_port_unregister(fClient, fCapturePortList[i]); 00121 } 00122 } 00123 for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) { 00124 if (fPlaybackPortList[i]) { 00125 jack_port_unregister(fClient, fPlaybackPortList[i]); 00126 } 00127 } 00128 00129 delete[] fCapturePortList; 00130 delete[] fPlaybackPortList; 00131 00132 delete[] fInputBufferList; 00133 delete[] fOutputBufferList; 00134 } 00135 00136 void JackAudioAdapter::ConnectPorts() 00137 { 00138 const char** ports; 00139 00140 ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); 00141 if (ports != NULL) { 00142 for (int i = 0; i < fAudioAdapter->GetInputs() && ports[i]; i++) { 00143 jack_connect(fClient, jack_port_name(fCapturePortList[i]), ports[i]); 00144 } 00145 jack_free(ports); 00146 } 00147 00148 ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); 00149 if (ports != NULL) { 00150 for (int i = 0; i < fAudioAdapter->GetOutputs() && ports[i]; i++) { 00151 jack_connect(fClient, ports[i], jack_port_name(fPlaybackPortList[i])); 00152 } 00153 jack_free(ports); 00154 } 00155 } 00156 00157 void JackAudioAdapter::Reset() 00158 { 00159 fAudioAdapter->Reset(); 00160 } 00161 00162 int JackAudioAdapter::Open() 00163 { 00164 char name[32]; 00165 jack_log("JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fAudioAdapter->GetInputs(), fAudioAdapter->GetOutputs()); 00166 fAudioAdapter->Create(); 00167 00168 //jack ports 00169 fCapturePortList = new jack_port_t*[fAudioAdapter->GetInputs()]; 00170 fPlaybackPortList = new jack_port_t*[fAudioAdapter->GetOutputs()]; 00171 00172 fInputBufferList = new jack_default_audio_sample_t*[fAudioAdapter->GetInputs()]; 00173 fOutputBufferList = new jack_default_audio_sample_t*[fAudioAdapter->GetOutputs()]; 00174 00175 for (int i = 0; i < fAudioAdapter->GetInputs(); i++) { 00176 snprintf(name, sizeof(name), "capture_%d", i + 1); 00177 if ((fCapturePortList[i] = jack_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, 0)) == NULL) { 00178 goto fail; 00179 } 00180 } 00181 00182 for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) { 00183 snprintf(name, sizeof(name), "playback_%d", i + 1); 00184 if ((fPlaybackPortList[i] = jack_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, 0)) == NULL) { 00185 goto fail; 00186 } 00187 } 00188 00189 //callbacks and activation 00190 if (jack_set_process_callback(fClient, Process, this) < 0) { 00191 goto fail; 00192 } 00193 if (jack_set_buffer_size_callback(fClient, BufferSize, this) < 0) { 00194 goto fail; 00195 } 00196 if (jack_set_sample_rate_callback(fClient, SampleRate, this) < 0) { 00197 goto fail; 00198 } 00199 if (jack_set_latency_callback(fClient, Latency, this) < 0) { 00200 goto fail; 00201 } 00202 if (jack_activate(fClient) < 0) { 00203 goto fail; 00204 } 00205 00206 if (fAutoConnect) { 00207 ConnectPorts(); 00208 } 00209 00210 // Ring buffers are now allocated... 00211 return fAudioAdapter->Open(); 00212 return 0; 00213 00214 fail: 00215 FreePorts(); 00216 fAudioAdapter->Destroy(); 00217 return -1; 00218 } 00219 00220 int JackAudioAdapter::Close() 00221 { 00222 fAudioAdapter->Close(); 00223 fAudioAdapter->Destroy(); 00224 return 0; 00225 } 00226 00227 } //namespace