00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
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
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
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 }