Jack2 1.9.6
|
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 //static methods *********************************************************** 00036 int JackAudioAdapter::Process (jack_nframes_t frames, void* arg) 00037 { 00038 JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg); 00039 float* inputBuffer[adapter->fAudioAdapter->GetInputs()]; 00040 float* outputBuffer[adapter->fAudioAdapter->GetOutputs()]; 00041 00042 // Always clear output 00043 for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) { 00044 inputBuffer[i] = (float*)jack_port_get_buffer(adapter->fCapturePortList[i], frames); 00045 memset(inputBuffer[i], 0, frames * sizeof(float)); 00046 } 00047 00048 for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) { 00049 outputBuffer[i] = (float*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames); 00050 } 00051 00052 adapter->fAudioAdapter->PullAndPush(inputBuffer, outputBuffer, frames); 00053 return 0; 00054 } 00055 00056 int JackAudioAdapter::BufferSize ( jack_nframes_t buffer_size, void* arg ) 00057 { 00058 JackAudioAdapter* adapter = static_cast<JackAudioAdapter*> ( arg ); 00059 adapter->Reset(); 00060 adapter->fAudioAdapter->SetHostBufferSize ( buffer_size ); 00061 return 0; 00062 } 00063 00064 int JackAudioAdapter::SampleRate ( jack_nframes_t sample_rate, void* arg ) 00065 { 00066 JackAudioAdapter* adapter = static_cast<JackAudioAdapter*> ( arg ); 00067 adapter->Reset(); 00068 adapter->fAudioAdapter->SetHostSampleRate ( sample_rate ); 00069 return 0; 00070 } 00071 00072 //JackAudioAdapter ********************************************************* 00073 00074 JackAudioAdapter::JackAudioAdapter (jack_client_t* jack_client, JackAudioAdapterInterface* audio_io, const JSList* params, bool system) 00075 :fJackClient(jack_client), fAudioAdapter(audio_io) 00076 { 00077 const JSList* node; 00078 const jack_driver_param_t* param; 00079 fAutoConnect = false; 00080 00081 for (node = params; node; node = jack_slist_next(node)) { 00082 param = (const jack_driver_param_t*) node->data; 00083 switch (param->character) { 00084 case 'c': 00085 fAutoConnect = true; 00086 break; 00087 } 00088 } 00089 } 00090 00091 JackAudioAdapter::~JackAudioAdapter() 00092 { 00093 // When called, Close has already been used for the client, thus ports are already unregistered. 00094 delete fAudioAdapter; 00095 } 00096 00097 void JackAudioAdapter::FreePorts() 00098 { 00099 for (int i = 0; i < fAudioAdapter->GetInputs(); i++ ) 00100 if ( fCapturePortList[i] ) 00101 jack_port_unregister ( fJackClient, fCapturePortList[i] ); 00102 for (int i = 0; i < fAudioAdapter->GetOutputs(); i++ ) 00103 if ( fPlaybackPortList[i] ) 00104 jack_port_unregister ( fJackClient, fPlaybackPortList[i] ); 00105 00106 delete[] fCapturePortList; 00107 delete[] fPlaybackPortList; 00108 } 00109 00110 void JackAudioAdapter::ConnectPorts() 00111 { 00112 const char **ports; 00113 00114 ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); 00115 if (ports != NULL) { 00116 for (int i = 0; i < fAudioAdapter->GetInputs() && ports[i]; i++) { 00117 jack_connect(fJackClient,jack_port_name(fCapturePortList[i]), ports[i]); 00118 } 00119 free(ports); 00120 } 00121 00122 ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); 00123 if (ports != NULL) { 00124 for (int i = 0; i < fAudioAdapter->GetOutputs() && ports[i]; i++) { 00125 jack_connect(fJackClient, ports[i], jack_port_name(fPlaybackPortList[i])); 00126 } 00127 free(ports); 00128 } 00129 } 00130 00131 void JackAudioAdapter::Reset() 00132 { 00133 fAudioAdapter->Reset(); 00134 } 00135 00136 int JackAudioAdapter::Open() 00137 { 00138 char name[32]; 00139 jack_log("JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fAudioAdapter->GetInputs(), fAudioAdapter->GetOutputs()); 00140 fAudioAdapter->Create(); 00141 00142 //jack ports 00143 fCapturePortList = new jack_port_t*[fAudioAdapter->GetInputs()]; 00144 fPlaybackPortList = new jack_port_t*[fAudioAdapter->GetOutputs()]; 00145 00146 for (int i = 0; i < fAudioAdapter->GetInputs(); i++) 00147 { 00148 sprintf(name, "capture_%d", i + 1); 00149 if ((fCapturePortList[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL) 00150 goto fail; 00151 } 00152 00153 for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) 00154 { 00155 sprintf(name, "playback_%d", i + 1); 00156 if ((fPlaybackPortList[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 )) == NULL) 00157 goto fail; 00158 } 00159 00160 //callbacks and activation 00161 if ( jack_set_process_callback ( fJackClient, Process, this ) < 0 ) 00162 goto fail; 00163 if ( jack_set_buffer_size_callback ( fJackClient, BufferSize, this ) < 0 ) 00164 goto fail; 00165 if ( jack_set_sample_rate_callback ( fJackClient, SampleRate, this ) < 0 ) 00166 goto fail; 00167 if ( jack_activate ( fJackClient ) < 0 ) 00168 goto fail; 00169 00170 if (fAutoConnect) 00171 ConnectPorts(); 00172 00173 // Ring buffer are now allocated.. 00174 return fAudioAdapter->Open(); 00175 00176 fail: 00177 FreePorts(); 00178 fAudioAdapter->Destroy(); 00179 return -1; 00180 } 00181 00182 int JackAudioAdapter::Close() 00183 { 00184 fAudioAdapter->Close(); 00185 fAudioAdapter->Destroy(); 00186 return 0; 00187 } 00188 00189 } //namespace