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 General Public License as published by
00007   the Free Software Foundation; either version 2 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 General Public License for more details.
00014 
00015   You should have received a copy of the GNU General Public License
00016   along with this program; if not, write to the Free Software
00017   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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 
00028 namespace Jack
00029 {
00030 
00031 JackPort::JackPort()
00032         : fFlags(JackPortIsInput), fRefNum( -1), fLatency(0), fTotalLatency(0), fMonitorRequests(0), fInUse(false), fTied(NO_PORT)
00033 {}
00034 
00035 JackPort::~JackPort()
00036 {}
00037 
00038 bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags)
00039 {
00040     int id = GetPortTypeId(port_type);
00041     if (id < 0)
00042         return false;
00043     fTypeId = id;
00044     fFlags = flags;
00045     fRefNum = refnum;
00046     strcpy(fName, port_name);
00047     fInUse = true;
00048     fLatency = 0;
00049         fTotalLatency = 0;
00050     fTied = NO_PORT;
00051     // DB: At this point we do not know current buffer size in frames,
00052     // but every time buffer will be returned to any user,
00053     // it will be called with either ClearBuffer or MixBuffers
00054     // with correct current buffer size.
00055     // So it is safe to init with 0 here.
00056     ClearBuffer(0);
00057     return true;
00058 }
00059 
00060 void JackPort::Release()
00061 {
00062     fTypeId = 0;
00063     fFlags = JackPortIsInput;
00064     fRefNum = -1;
00065     fInUse = false;
00066     fLatency = 0;
00067         fTotalLatency = 0;
00068     fTied = NO_PORT;
00069         fAlias1[0] = '\0';
00070         fAlias2[0] = '\0';
00071 }
00072 
00073 bool JackPort::IsUsed() const
00074 {
00075     return fInUse;
00076 }
00077 
00078 float* JackPort::GetBuffer()
00079 {
00080     return fBuffer;
00081 }
00082 
00083 int JackPort::GetRefNum() const
00084 {
00085     return fRefNum;
00086 }
00087 
00088 jack_nframes_t JackPort::GetLatency() const
00089 {
00090     return fLatency;
00091 }
00092 
00093 jack_nframes_t JackPort::GetTotalLatency() const
00094 {
00095     return fTotalLatency;
00096 }
00097 
00098 void JackPort::SetLatency(jack_nframes_t nframes)
00099 {
00100     fLatency = nframes;
00101 }
00102 
00103 int JackPort::Tie(jack_port_id_t port_index)
00104 {
00105     fTied = port_index;
00106     return 0;
00107 }
00108 
00109 int JackPort::UnTie()
00110 {
00111     fTied = NO_PORT;
00112     return 0;
00113 }
00114 
00115 int JackPort::RequestMonitor(bool onoff)
00116 {
00126     if (onoff) {
00127         fMonitorRequests++;
00128     } else if (fMonitorRequests) {
00129         fMonitorRequests--;
00130     }
00131 
00132     return 0;
00133 }
00134 
00135 int JackPort::EnsureMonitor(bool onoff)
00136 {
00146     if (onoff) {
00147         if (fMonitorRequests == 0) {
00148             fMonitorRequests++;
00149         }
00150     } else {
00151         if (fMonitorRequests > 0) {
00152             fMonitorRequests = 0;
00153         }
00154     }
00155 
00156     return 0;
00157 }
00158 
00159 bool JackPort::MonitoringInput()
00160 {
00161     return (fMonitorRequests > 0);
00162 }
00163 
00164 const char* JackPort::GetName() const
00165 {
00166     return fName;
00167 }
00168 
00169 const char* JackPort::GetShortName() const
00170 {
00171     /* we know there is always a colon, because we put
00172        it there ...
00173     */ 
00174     return strchr(fName, ':') + 1;
00175 }
00176 
00177 int JackPort::GetFlags() const
00178 {
00179     return fFlags;
00180 }
00181 
00182 const char* JackPort::GetType() const
00183 {
00184     const JackPortType* type = GetPortType(fTypeId);
00185     return type->name;
00186 }
00187 
00188 int JackPort::SetName(const char* new_name)
00189 {
00190     char* colon = strchr(fName, ':');
00191     int len = sizeof(fName) - ((int) (colon - fName)) - 2;
00192     snprintf(colon + 1, len, "%s", new_name);
00193     return 0;
00194 }
00195 
00196 bool JackPort::NameEquals(const char* target)
00197 {
00198         char buf[JACK_PORT_NAME_SIZE + 1];
00199 
00200         /* this nasty, nasty kludge is here because between 0.109.0 and 0.109.1,
00201            the ALSA audio backend had the name "ALSA", whereas as before and
00202            after it, it was called "alsa_pcm". this stops breakage for
00203            any setups that have saved "alsa_pcm" or "ALSA" in their connection
00204            state.
00205         */
00206 
00207         if (strncmp(target, "ALSA:capture", 12) == 0 || strncmp(target, "ALSA:playback", 13) == 0) {
00208                 snprintf(buf, sizeof(buf), "alsa_pcm%s", target + 4);
00209                 target = buf;
00210         }
00211         
00212         return (strcmp(fName, target) == 0 
00213                 || strcmp(fAlias1, target) == 0 
00214                 || strcmp(fAlias2, target) == 0);
00215 }
00216 
00217 int JackPort::GetAliases(char* const aliases[2])
00218 {
00219         int cnt = 0;
00220         
00221         if (fAlias1[0] != '\0') {
00222                 snprintf(aliases[0], JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE, "%s", fAlias1);
00223                 cnt++;
00224         }
00225 
00226         if (fAlias2[0] != '\0') {
00227                 snprintf(aliases[1], JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE, "%s", fAlias2);
00228                 cnt++;
00229         }
00230 
00231         return cnt;
00232 }
00233 
00234 int JackPort::SetAlias(const char* alias)
00235 {
00236         if (fAlias1[0] == '\0') {
00237                 snprintf(fAlias1, sizeof(fAlias1), "%s", alias);
00238         } else if (fAlias2[0] == '\0') {
00239                 snprintf(fAlias2, sizeof(fAlias2), "%s", alias);
00240         } else {
00241                 return -1;
00242         }
00243 
00244         return 0;
00245 }
00246 
00247 int JackPort::UnsetAlias(const char* alias)
00248 {
00249         if (strcmp(fAlias1, alias) == 0) {
00250                 fAlias1[0] = '\0';
00251         } else if (strcmp(fAlias2, alias) == 0) {
00252                 fAlias2[0] = '\0';
00253         } else {
00254                 return -1;
00255         }
00256 
00257         return 0;
00258 }
00259 
00260 void JackPort::ClearBuffer(jack_nframes_t frames)
00261 {
00262     const JackPortType* type = GetPortType(fTypeId);
00263     (type->init)(fBuffer, BUFFER_SIZE_MAX * sizeof(float), frames);
00264 }
00265 
00266 void JackPort::MixBuffers(void** src_buffers, int src_count, jack_nframes_t buffer_size)
00267 {
00268     const JackPortType* type = GetPortType(fTypeId);
00269     (type->mixdown)(fBuffer, src_buffers, src_count, buffer_size);
00270 }
00271 
00272 } // end of namespace

Generated on Thu Feb 14 11:16:02 2008 for Jackdmp by  doxygen 1.5.1