Jack2 1.9.12

JackAudioAdapter.cpp
1 /*
2 Copyright (C) 2008 Grame
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "JackAudioAdapter.h"
21 #include "JackError.h"
22 #include "JackCompilerDeps.h"
23 #include "JackTools.h"
24 #include "JackTime.h"
25 #include "jslist.h"
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <assert.h>
29
30 using namespace std;
31
32 namespace Jack
33 {
34
35 int JackAudioAdapter::Process(jack_nframes_t frames, void* arg)
36 {
37 JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg);
38 return adapter->ProcessAux(frames);
39 }
40
41 int JackAudioAdapter::ProcessAux(jack_nframes_t frames)
42 {
43 // Always clear output
44 for (int i = 0; i < fAudioAdapter->GetInputs(); i++) {
45 fInputBufferList[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(fCapturePortList[i], frames);
46 memset(fInputBufferList[i], 0, frames * sizeof(jack_default_audio_sample_t));
47 }
48
49 for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) {
50 fOutputBufferList[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(fPlaybackPortList[i], frames);
51 }
52
53 fAudioAdapter->PullAndPush(fInputBufferList, fOutputBufferList, frames);
54 return 0;
55 }
56
57 int JackAudioAdapter::BufferSize(jack_nframes_t buffer_size, void* arg)
58 {
59 JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg);
60 adapter->Reset();
61 adapter->fAudioAdapter->SetHostBufferSize(buffer_size);
62 return 0;
63 }
64
65 int JackAudioAdapter::SampleRate(jack_nframes_t sample_rate, void* arg)
66 {
67 JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg);
68 adapter->Reset();
69 adapter->fAudioAdapter->SetHostSampleRate(sample_rate);
70 return 0;
71 }
72
73 void JackAudioAdapter::Latency(jack_latency_callback_mode_t mode, void* arg)
74 {
75 JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg);
76
77 if (mode == JackCaptureLatency) {
78 for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) {
79 jack_latency_range_t range;
80 range.min = range.max = adapter->fAudioAdapter->GetInputLatency(i);
81 jack_port_set_latency_range(adapter->fCapturePortList[i], JackCaptureLatency, &range);
82 }
83
84 } else {
85 for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) {
86 jack_latency_range_t range;
87 range.min = range.max = adapter->fAudioAdapter->GetOutputLatency(i);
88 jack_port_set_latency_range(adapter->fPlaybackPortList[i], JackPlaybackLatency, &range);
89 }
90 }
91 }
92
93 JackAudioAdapter::JackAudioAdapter(jack_client_t* client, JackAudioAdapterInterface* audio_io, const JSList* params)
94 :fClient(client), fAudioAdapter(audio_io)
95 {
96 const JSList* node;
97 const jack_driver_param_t* param;
98 fAutoConnect = false;
99
100 for (node = params; node; node = jack_slist_next(node)) {
101 param = (const jack_driver_param_t*)node->data;
102 switch (param->character) {
103 case 'c':
104 fAutoConnect = true;
105 break;
106 }
107 }
108 }
109
110 JackAudioAdapter::~JackAudioAdapter()
111 {
112 // When called, Close has already been used for the client, thus ports are already unregistered.
113 delete fAudioAdapter;
114 }
115
116 void JackAudioAdapter::FreePorts()
117 {
118 for (int i = 0; i < fAudioAdapter->GetInputs(); i++) {
119 if (fCapturePortList[i]) {
120 jack_port_unregister(fClient, fCapturePortList[i]);
121 }
122 }
123 for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) {
124 if (fPlaybackPortList[i]) {
125 jack_port_unregister(fClient, fPlaybackPortList[i]);
126 }
127 }
128
129 delete[] fCapturePortList;
130 delete[] fPlaybackPortList;
131
132 delete[] fInputBufferList;
133 delete[] fOutputBufferList;
134 }
135
136 void JackAudioAdapter::ConnectPorts()
137 {
138 const char** ports;
139
140 ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
141 if (ports != NULL) {
142 for (int i = 0; i < fAudioAdapter->GetInputs() && ports[i]; i++) {
143 jack_connect(fClient, jack_port_name(fCapturePortList[i]), ports[i]);
144 }
145 jack_free(ports);
146 }
147
148 ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput);
149 if (ports != NULL) {
150 for (int i = 0; i < fAudioAdapter->GetOutputs() && ports[i]; i++) {
151 jack_connect(fClient, ports[i], jack_port_name(fPlaybackPortList[i]));
152 }
153 jack_free(ports);
154 }
155 }
156
157 void JackAudioAdapter::Reset()
158 {
159 fAudioAdapter->Reset();
160 }
161
162 int JackAudioAdapter::Open()
163 {
164 char name[32];
165 jack_log("JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fAudioAdapter->GetInputs(), fAudioAdapter->GetOutputs());
166 fAudioAdapter->Create();
167
168 //jack ports
169 fCapturePortList = new jack_port_t*[fAudioAdapter->GetInputs()];
170 fPlaybackPortList = new jack_port_t*[fAudioAdapter->GetOutputs()];
171
172 fInputBufferList = new jack_default_audio_sample_t*[fAudioAdapter->GetInputs()];
173 fOutputBufferList = new jack_default_audio_sample_t*[fAudioAdapter->GetOutputs()];
174
175 for (int i = 0; i < fAudioAdapter->GetInputs(); i++) {
176 snprintf(name, sizeof(name), "capture_%d", i + 1);
177 if ((fCapturePortList[i] = jack_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, 0)) == NULL) {
178 goto fail;
179 }
180 }
181
182 for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) {
183 snprintf(name, sizeof(name), "playback_%d", i + 1);
184 if ((fPlaybackPortList[i] = jack_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, 0)) == NULL) {
185 goto fail;
186 }
187 }
188
189 //callbacks and activation
190 if (jack_set_process_callback(fClient, Process, this) < 0) {
191 goto fail;
192 }
193 if (jack_set_buffer_size_callback(fClient, BufferSize, this) < 0) {
194 goto fail;
195 }
196 if (jack_set_sample_rate_callback(fClient, SampleRate, this) < 0) {
197 goto fail;
198 }
199 if (jack_set_latency_callback(fClient, Latency, this) < 0) {
200 goto fail;
201 }
202 if (jack_activate(fClient) < 0) {
203 goto fail;
204 }
205
206 if (fAutoConnect) {
207 ConnectPorts();
208 }
209
210 // Ring buffers are now allocated...
211 return fAudioAdapter->Open();
212 return 0;
213
214 fail:
215 FreePorts();
216 fAudioAdapter->Destroy();
217 return -1;
218 }
219
220 int JackAudioAdapter::Close()
221 {
222 fAudioAdapter->Close();
223 fAudioAdapter->Destroy();
224 return 0;
225 }
226
227 } //namespace
jack_port_unregister
LIB_EXPORT int jack_port_unregister(jack_client_t *, jack_port_t *)
Definition: JackAPI.cpp:1109
jack_set_process_callback
LIB_EXPORT int jack_set_process_callback(jack_client_t *client, JackProcessCallback process_callback, void *arg)
Definition: JackAPI.cpp:829
jack_activate
LIB_EXPORT int jack_activate(jack_client_t *client)
Definition: JackAPI.cpp:1067
jack_port_set_latency_range
LIB_EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range)
Definition: JackAPI.cpp:586
jack_connect
LIB_EXPORT int jack_connect(jack_client_t *, const char *source_port, const char *destination_port)
Definition: JackAPI.cpp:1211
_jack_latency_range::min
jack_nframes_t min
Definition: types.h:270
jack_port_register
LIB_EXPORT jack_port_t * jack_port_register(jack_client_t *client, const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size)
Definition: JackAPI.cpp:1093
_jack_latency_range
Definition: types.h:265
_jack_latency_range::max
jack_nframes_t max
Definition: types.h:274
jack_set_sample_rate_callback
LIB_EXPORT int jack_set_sample_rate_callback(jack_client_t *client, JackSampleRateCallback srate_callback, void *arg)
Definition: JackAPI.cpp:948
jack_port_get_buffer
LIB_EXPORT void * jack_port_get_buffer(jack_port_t *, jack_nframes_t)
Definition: JackAPI.cpp:363
jack_set_buffer_size_callback
LIB_EXPORT int jack_set_buffer_size_callback(jack_client_t *client, JackBufferSizeCallback bufsize_callback, void *arg)
Definition: JackAPI.cpp:935
jack_port_name
LIB_EXPORT const char * jack_port_name(const jack_port_t *port)
Definition: JackAPI.cpp:383
jack_driver_param_t
Definition: driver_interface.h:125
jack_get_ports
LIB_EXPORT const char ** jack_get_ports(jack_client_t *, const char *port_name_pattern, const char *type_name_pattern, unsigned long flags)
Definition: JackAPI.cpp:1289
_JSList
Definition: linux/alsa/jslist.h:35
jack_log
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:108