Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson).
[jack2.git] / common / JackPort.cpp
blobf8c62d6734be02a733253c557e62cacac862fef4
1 /*
2 Copyright (C) 2001-2003 Paul Davis
3 Copyright (C) 2004-2008 Grame
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.
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.
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.
21 #include "JackPort.h"
22 #include "JackError.h"
23 #include "JackPortType.h"
24 #include <stdio.h>
25 #include <assert.h>
27 namespace Jack
30 JackPort::JackPort()
32 Release();
35 bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags)
37 jack_port_type_id_t id = GetPortTypeId(port_type);
38 if (id == PORT_TYPES_MAX)
39 return false;
40 fTypeId = id;
41 fFlags = flags;
42 fRefNum = refnum;
43 strcpy(fName, port_name);
44 fInUse = true;
45 fLatency = 0;
46 fTotalLatency = 0;
47 fTied = NO_PORT;
48 // DB: At this point we do not know current buffer size in frames,
49 // but every time buffer will be returned to any user,
50 // it will be called with either ClearBuffer or MixBuffers
51 // with correct current buffer size.
52 // So it is safe to init with 0 here.
53 ClearBuffer(0);
54 return true;
57 void JackPort::Release()
59 fTypeId = 0;
60 fFlags = JackPortIsInput;
61 fRefNum = -1;
62 fInUse = false;
63 fLatency = 0;
64 fTotalLatency = 0;
65 fMonitorRequests = 0;
66 fTied = NO_PORT;
67 fAlias1[0] = '\0';
68 fAlias2[0] = '\0';
71 int JackPort::GetRefNum() const
73 return fRefNum;
76 jack_nframes_t JackPort::GetLatency() const
78 return fLatency;
81 jack_nframes_t JackPort::GetTotalLatency() const
83 return fTotalLatency;
86 void JackPort::SetLatency(jack_nframes_t nframes)
88 fLatency = nframes;
91 int JackPort::Tie(jack_port_id_t port_index)
93 fTied = port_index;
94 return 0;
97 int JackPort::UnTie()
99 fTied = NO_PORT;
100 return 0;
103 int JackPort::RequestMonitor(bool onoff)
106 jackd.h
107 * If @ref JackPortCanMonitor is set for this @a port, turn input
108 * monitoring on or off. Otherwise, do nothing.
110 if (!(fFlags & JackPortCanMonitor))
111 return -1;
114 if (onoff) {
115 fMonitorRequests++;
116 } else if (fMonitorRequests) {
117 fMonitorRequests--;
120 return 0;
123 int JackPort::EnsureMonitor(bool onoff)
126 jackd.h
127 * If @ref JackPortCanMonitor is set for this @a port, turn input
128 * monitoring on or off. Otherwise, do nothing.
130 if (!(fFlags & JackPortCanMonitor))
131 return -1;
134 if (onoff) {
135 if (fMonitorRequests == 0) {
136 fMonitorRequests++;
138 } else {
139 if (fMonitorRequests > 0) {
140 fMonitorRequests = 0;
144 return 0;
147 const char* JackPort::GetName() const
149 return fName;
152 const char* JackPort::GetShortName() const
154 /* we know there is always a colon, because we put
155 it there ...
157 return strchr(fName, ':') + 1;
160 int JackPort::GetFlags() const
162 return fFlags;
165 const char* JackPort::GetType() const
167 const JackPortType* type = GetPortType(fTypeId);
168 return type->name;
171 void JackPort::SetName(const char* new_name)
173 char* colon = strchr(fName, ':');
174 int len = sizeof(fName) - ((int) (colon - fName)) - 2;
175 snprintf(colon + 1, len, "%s", new_name);
178 bool JackPort::NameEquals(const char* target)
180 char buf[JACK_PORT_NAME_SIZE + 1];
182 /* this nasty, nasty kludge is here because between 0.109.0 and 0.109.1,
183 the ALSA audio backend had the name "ALSA", whereas as before and
184 after it, it was called "alsa_pcm". this stops breakage for
185 any setups that have saved "alsa_pcm" or "ALSA" in their connection
186 state.
189 if (strncmp(target, "ALSA:capture", 12) == 0 || strncmp(target, "ALSA:playback", 13) == 0) {
190 snprintf(buf, sizeof(buf), "alsa_pcm%s", target + 4);
191 target = buf;
194 return (strcmp(fName, target) == 0
195 || strcmp(fAlias1, target) == 0
196 || strcmp(fAlias2, target) == 0);
199 int JackPort::GetAliases(char* const aliases[2])
201 int cnt = 0;
203 if (fAlias1[0] != '\0') {
204 snprintf(aliases[0], JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE, "%s", fAlias1);
205 cnt++;
208 if (fAlias2[0] != '\0') {
209 snprintf(aliases[1], JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE, "%s", fAlias2);
210 cnt++;
213 return cnt;
216 int JackPort::SetAlias(const char* alias)
218 if (fAlias1[0] == '\0') {
219 snprintf(fAlias1, sizeof(fAlias1), "%s", alias);
220 } else if (fAlias2[0] == '\0') {
221 snprintf(fAlias2, sizeof(fAlias2), "%s", alias);
222 } else {
223 return -1;
226 return 0;
229 int JackPort::UnsetAlias(const char* alias)
231 if (strcmp(fAlias1, alias) == 0) {
232 fAlias1[0] = '\0';
233 } else if (strcmp(fAlias2, alias) == 0) {
234 fAlias2[0] = '\0';
235 } else {
236 return -1;
239 return 0;
242 void JackPort::ClearBuffer(jack_nframes_t frames)
244 const JackPortType* type = GetPortType(fTypeId);
245 (type->init)(GetBuffer(), frames * sizeof(float), frames);
248 void JackPort::MixBuffers(void** src_buffers, int src_count, jack_nframes_t buffer_size)
250 const JackPortType* type = GetPortType(fTypeId);
251 (type->mixdown)(GetBuffer(), src_buffers, src_count, buffer_size);
254 } // end of namespace