Jack2 1.9.12

JackPort.cpp
1 /*
2 Copyright (C) 2001-2003 Paul Davis
3 Copyright (C) 2004-2008 Grame
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21 #include "JackPort.h"
22 #include "JackError.h"
23 #include "JackPortType.h"
24 #include <stdio.h>
25 #include <assert.h>
26
27 namespace Jack
28 {
29
30 JackPort::JackPort()
31 {
32 Release();
33 }
34
35 bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags)
36 {
37 jack_port_type_id_t id = GetPortTypeId(port_type);
38 assert(id >= 0 && id <= PORT_TYPES_MAX);
39 if (id == PORT_TYPES_MAX) {
40 return false;
41 }
42 fTypeId = id;
43 fFlags = flags;
44 fRefNum = refnum;
45 strcpy(fName, port_name);
46 fInUse = true;
47 fLatency = 0;
48 fTotalLatency = 0;
49 fMonitorRequests = 0;
50 fPlaybackLatency.min = fPlaybackLatency.max = 0;
51 fCaptureLatency.min = fCaptureLatency.max = 0;
52 fTied = NO_PORT;
53 fAlias1[0] = '\0';
54 fAlias2[0] = '\0';
55 // DB: At this point we do not know current buffer size in frames,
56 // but every time buffer will be returned to any user,
57 // it will be called with either ClearBuffer or MixBuffers
58 // with correct current buffer size.
59 // So it is safe to init with 0 here.
60 ClearBuffer(0);
61 return true;
62 }
63
64 void JackPort::Release()
65 {
66 fTypeId = 0;
67 fFlags = JackPortIsInput;
68 fRefNum = -1;
69 fInUse = false;
70 fLatency = 0;
71 fTotalLatency = 0;
72 fMonitorRequests = 0;
73 fPlaybackLatency.min = fPlaybackLatency.max = 0;
74 fCaptureLatency.min = fCaptureLatency.max = 0;
75 fTied = NO_PORT;
76 fAlias1[0] = '\0';
77 fAlias2[0] = '\0';
78 }
79
80 int JackPort::GetRefNum() const
81 {
82 return fRefNum;
83 }
84
85 jack_nframes_t JackPort::GetLatency() const
86 {
87 return fLatency;
88 }
89
90 jack_nframes_t JackPort::GetTotalLatency() const
91 {
92 return fTotalLatency;
93 }
94
95 void JackPort::SetLatency(jack_nframes_t nframes)
96 {
97 fLatency = nframes;
98
99 /* setup the new latency values here,
100 * so we dont need to change the backend codes.
101 */
102 if (fFlags & JackPortIsOutput) {
103 fCaptureLatency.min = nframes;
104 fCaptureLatency.max = nframes;
105 }
106 if (fFlags & JackPortIsInput) {
107 fPlaybackLatency.min = nframes;
108 fPlaybackLatency.max = nframes;
109 }
110 }
111
112 void JackPort::SetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range)
113 {
114 if (mode == JackCaptureLatency) {
115 fCaptureLatency = *range;
116
117 /* hack to set latency up for
118 * backend ports
119 */
120 if ((fFlags & JackPortIsOutput) && (fFlags & JackPortIsPhysical)) {
121 fLatency = (range->min + range->max) / 2;
122 }
123 } else {
124 fPlaybackLatency = *range;
125
126 /* hack to set latency up for
127 * backend ports
128 */
129 if ((fFlags & JackPortIsInput) && (fFlags & JackPortIsPhysical)) {
130 fLatency = (range->min + range->max) / 2;
131 }
132 }
133 }
134
135 void JackPort::GetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range) const
136 {
137 if (mode == JackCaptureLatency) {
138 *range = fCaptureLatency;
139 } else {
140 *range = fPlaybackLatency;
141 }
142 }
143
144 int JackPort::Tie(jack_port_id_t port_index)
145 {
146 fTied = port_index;
147 return 0;
148 }
149
150 int JackPort::UnTie()
151 {
152 fTied = NO_PORT;
153 return 0;
154 }
155
156 int JackPort::RequestMonitor(bool onoff)
157 {
167 if (onoff) {
168 fMonitorRequests++;
169 } else if (fMonitorRequests) {
170 fMonitorRequests--;
171 }
172
173 return 0;
174 }
175
176 int JackPort::EnsureMonitor(bool onoff)
177 {
187 if (onoff) {
188 if (fMonitorRequests == 0) {
189 fMonitorRequests++;
190 }
191 } else {
192 if (fMonitorRequests > 0) {
193 fMonitorRequests = 0;
194 }
195 }
196
197 return 0;
198 }
199
200 const char* JackPort::GetName() const
201 {
202 return fName;
203 }
204
205 const char* JackPort::GetShortName() const
206 {
207 /* we know there is always a colon, because we put
208 it there ...
209 */
210 return strchr(fName, ':') + 1;
211 }
212
213 int JackPort::GetFlags() const
214 {
215 return fFlags;
216 }
217
218 const char* JackPort::GetType() const
219 {
220 const JackPortType* type = GetPortType(fTypeId);
221 return type->fName;
222 }
223
224 void JackPort::SetName(const char* new_name)
225 {
226 char* colon = strchr(fName, ':');
227 int len = sizeof(fName) - ((int) (colon - fName)) - 2;
228 snprintf(colon + 1, len, "%s", new_name);
229 }
230
231 bool JackPort::NameEquals(const char* target)
232 {
233 char buf[REAL_JACK_PORT_NAME_SIZE+1];
234
235 /* this nasty, nasty kludge is here because between 0.109.0 and 0.109.1,
236 the ALSA audio backend had the name "ALSA", whereas as before and
237 after it, it was called "alsa_pcm". this stops breakage for
238 any setups that have saved "alsa_pcm" or "ALSA" in their connection
239 state.
240 */
241
242 if (strncmp(target, "ALSA:capture", 12) == 0 || strncmp(target, "ALSA:playback", 13) == 0) {
243 snprintf(buf, sizeof(buf), "alsa_pcm%s", target + 4);
244 target = buf;
245 }
246
247 return (strcmp(fName, target) == 0
248 || strcmp(fAlias1, target) == 0
249 || strcmp(fAlias2, target) == 0);
250 }
251
252 int JackPort::GetAliases(char* const aliases[2])
253 {
254 int cnt = 0;
255
256 if (fAlias1[0] != '\0') {
257 snprintf(aliases[0], REAL_JACK_PORT_NAME_SIZE, "%s", fAlias1);
258 cnt++;
259 }
260
261 if (fAlias2[0] != '\0') {
262 snprintf(aliases[1], REAL_JACK_PORT_NAME_SIZE, "%s", fAlias2);
263 cnt++;
264 }
265
266 return cnt;
267 }
268
269 int JackPort::SetAlias(const char* alias)
270 {
271 if (fAlias1[0] == '\0') {
272 snprintf(fAlias1, sizeof(fAlias1), "%s", alias);
273 } else if (fAlias2[0] == '\0') {
274 snprintf(fAlias2, sizeof(fAlias2), "%s", alias);
275 } else {
276 return -1;
277 }
278
279 return 0;
280 }
281
282 int JackPort::UnsetAlias(const char* alias)
283 {
284 if (strcmp(fAlias1, alias) == 0) {
285 fAlias1[0] = '\0';
286 } else if (strcmp(fAlias2, alias) == 0) {
287 fAlias2[0] = '\0';
288 } else {
289 return -1;
290 }
291
292 return 0;
293 }
294
295 void JackPort::ClearBuffer(jack_nframes_t frames)
296 {
297 const JackPortType* type = GetPortType(fTypeId);
298 (type->init)(GetBuffer(), frames * sizeof(jack_default_audio_sample_t), frames);
299 }
300
301 void JackPort::MixBuffers(void** src_buffers, int src_count, jack_nframes_t buffer_size)
302 {
303 const JackPortType* type = GetPortType(fTypeId);
304 (type->mixdown)(GetBuffer(), src_buffers, src_count, buffer_size);
305 }
306
307 } // end of namespace
_jack_latency_range::min
jack_nframes_t min
Definition: types.h:270
_jack_latency_range
Definition: types.h:265
_jack_latency_range::max
jack_nframes_t max
Definition: types.h:274
Jack::JackPort::RequestMonitor
int RequestMonitor(bool onoff)
Definition: JackPort.cpp:156
Jack::JackPort::EnsureMonitor
int EnsureMonitor(bool onoff)
Definition: JackPort.cpp:176