Jack2 1.9.6

JackPort.cpp

00001 /*
00002 Copyright (C) 2001-2003 Paul Davis
00003 Copyright (C) 2004-2008 Grame
00004 
00005 This program is free software; you can redistribute it and/or modify
00006 it under the terms of the GNU Lesser General Public License as published by
00007 the Free Software Foundation; either version 2.1 of the License, or
00008 (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU Lesser General Public License for more details.
00014 
00015 You should have received a copy of the GNU Lesser General Public License
00016 along with this program; if not, write to the Free Software 
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 
00019 */
00020 
00021 #include "JackPort.h"
00022 #include "JackError.h"
00023 #include "JackPortType.h"
00024 #include <stdio.h>
00025 #include <assert.h>
00026 
00027 namespace Jack
00028 {
00029 
00030 JackPort::JackPort()
00031 {
00032     Release();
00033 }
00034 
00035 bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags)
00036 {
00037     jack_port_type_id_t id = GetPortTypeId(port_type);
00038     if (id == PORT_TYPES_MAX)
00039         return false;
00040     fTypeId = id;
00041     fFlags = flags;
00042     fRefNum = refnum;
00043     strcpy(fName, port_name);
00044     fInUse = true;
00045     fLatency = 0;
00046     fTotalLatency = 0;
00047     fTied = NO_PORT;
00048     // DB: At this point we do not know current buffer size in frames,
00049     // but every time buffer will be returned to any user,
00050     // it will be called with either ClearBuffer or MixBuffers
00051     // with correct current buffer size.
00052     // So it is safe to init with 0 here.
00053     ClearBuffer(0);
00054     return true;
00055 }
00056 
00057 void JackPort::Release()
00058 {
00059     fTypeId = 0;
00060     fFlags = JackPortIsInput;
00061     fRefNum = -1;
00062     fInUse = false;
00063     fLatency = 0;
00064     fTotalLatency = 0;
00065     fMonitorRequests = 0;
00066     fTied = NO_PORT;
00067     fAlias1[0] = '\0';
00068     fAlias2[0] = '\0';
00069 }
00070 
00071 int JackPort::GetRefNum() const
00072 {
00073     return fRefNum;
00074 }
00075 
00076 jack_nframes_t JackPort::GetLatency() const
00077 {
00078     return fLatency;
00079 }
00080 
00081 jack_nframes_t JackPort::GetTotalLatency() const
00082 {
00083     return fTotalLatency;
00084 }
00085 
00086 void JackPort::SetLatency(jack_nframes_t nframes)
00087 {
00088     fLatency = nframes;
00089 }
00090 
00091 int JackPort::Tie(jack_port_id_t port_index)
00092 {
00093     fTied = port_index;
00094     return 0;
00095 }
00096 
00097 int JackPort::UnTie()
00098 {
00099     fTied = NO_PORT;
00100     return 0;
00101 }
00102 
00103 int JackPort::RequestMonitor(bool onoff)
00104 {
00114     if (onoff) {
00115         fMonitorRequests++;
00116     } else if (fMonitorRequests) {
00117         fMonitorRequests--;
00118     }
00119 
00120     return 0;
00121 }
00122 
00123 int JackPort::EnsureMonitor(bool onoff)
00124 {
00134     if (onoff) {
00135         if (fMonitorRequests == 0) {
00136             fMonitorRequests++;
00137         }
00138     } else {
00139         if (fMonitorRequests > 0) {
00140             fMonitorRequests = 0;
00141         }
00142     }
00143 
00144     return 0;
00145 }
00146 
00147 const char* JackPort::GetName() const
00148 {
00149     return fName;
00150 }
00151 
00152 const char* JackPort::GetShortName() const
00153 {
00154     /* we know there is always a colon, because we put
00155        it there ...
00156     */
00157     return strchr(fName, ':') + 1;
00158 }
00159 
00160 int JackPort::GetFlags() const
00161 {
00162     return fFlags;
00163 }
00164 
00165 const char* JackPort::GetType() const
00166 {
00167     const JackPortType* type = GetPortType(fTypeId);
00168     return type->name;
00169 }
00170 
00171 void JackPort::SetName(const char* new_name)
00172 {
00173     char* colon = strchr(fName, ':');
00174     int len = sizeof(fName) - ((int) (colon - fName)) - 2;
00175     snprintf(colon + 1, len, "%s", new_name);
00176 }
00177 
00178 bool JackPort::NameEquals(const char* target)
00179 {
00180     char buf[JACK_PORT_NAME_SIZE + 1];
00181 
00182     /* this nasty, nasty kludge is here because between 0.109.0 and 0.109.1,
00183        the ALSA audio backend had the name "ALSA", whereas as before and
00184        after it, it was called "alsa_pcm". this stops breakage for
00185        any setups that have saved "alsa_pcm" or "ALSA" in their connection
00186        state.
00187     */
00188 
00189     if (strncmp(target, "ALSA:capture", 12) == 0 || strncmp(target, "ALSA:playback", 13) == 0) {
00190         snprintf(buf, sizeof(buf), "alsa_pcm%s", target + 4);
00191         target = buf;
00192     }
00193 
00194     return (strcmp(fName, target) == 0
00195             || strcmp(fAlias1, target) == 0
00196             || strcmp(fAlias2, target) == 0);
00197 }
00198 
00199 int JackPort::GetAliases(char* const aliases[2])
00200 {
00201     int cnt = 0;
00202 
00203     if (fAlias1[0] != '\0') {
00204         snprintf(aliases[0], JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE, "%s", fAlias1);
00205         cnt++;
00206     }
00207 
00208     if (fAlias2[0] != '\0') {
00209         snprintf(aliases[1], JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE, "%s", fAlias2);
00210         cnt++;
00211     }
00212 
00213     return cnt;
00214 }
00215 
00216 int JackPort::SetAlias(const char* alias)
00217 {
00218     if (fAlias1[0] == '\0') {
00219         snprintf(fAlias1, sizeof(fAlias1), "%s", alias);
00220     } else if (fAlias2[0] == '\0') {
00221         snprintf(fAlias2, sizeof(fAlias2), "%s", alias);
00222     } else {
00223         return -1;
00224     }
00225 
00226     return 0;
00227 }
00228 
00229 int JackPort::UnsetAlias(const char* alias)
00230 {
00231     if (strcmp(fAlias1, alias) == 0) {
00232         fAlias1[0] = '\0';
00233     } else if (strcmp(fAlias2, alias) == 0) {
00234         fAlias2[0] = '\0';
00235     } else {
00236         return -1;
00237     }
00238 
00239     return 0;
00240 }
00241 
00242 void JackPort::ClearBuffer(jack_nframes_t frames)
00243 {
00244     const JackPortType* type = GetPortType(fTypeId);
00245     (type->init)(GetBuffer(), frames * sizeof(float), frames);
00246 }
00247 
00248 void JackPort::MixBuffers(void** src_buffers, int src_count, jack_nframes_t buffer_size)
00249 {
00250     const JackPortType* type = GetPortType(fTypeId);
00251     (type->mixdown)(GetBuffer(), src_buffers, src_count, buffer_size);
00252 }
00253 
00254 } // end of namespace