00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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 fPlaybackLatency.min = fPlaybackLatency.max = 0;
00048 fCaptureLatency.min = fCaptureLatency.max = 0;
00049 fTied = NO_PORT;
00050
00051
00052
00053
00054
00055 ClearBuffer(0);
00056 return true;
00057 }
00058
00059 void JackPort::Release()
00060 {
00061 fTypeId = 0;
00062 fFlags = JackPortIsInput;
00063 fRefNum = -1;
00064 fInUse = false;
00065 fLatency = 0;
00066 fTotalLatency = 0;
00067 fMonitorRequests = 0;
00068 fTied = NO_PORT;
00069 fAlias1[0] = '\0';
00070 fAlias2[0] = '\0';
00071 }
00072
00073 int JackPort::GetRefNum() const
00074 {
00075 return fRefNum;
00076 }
00077
00078 jack_nframes_t JackPort::GetLatency() const
00079 {
00080 return fLatency;
00081 }
00082
00083 jack_nframes_t JackPort::GetTotalLatency() const
00084 {
00085 return fTotalLatency;
00086 }
00087
00088 void JackPort::SetLatency(jack_nframes_t nframes)
00089 {
00090 fLatency = nframes;
00091
00092
00093
00094
00095 if (fFlags & JackPortIsOutput) {
00096 fCaptureLatency.min = nframes;
00097 fCaptureLatency.max = nframes;
00098 }
00099 if (fFlags & JackPortIsInput) {
00100 fPlaybackLatency.min = nframes;
00101 fPlaybackLatency.max = nframes;
00102 }
00103 }
00104
00105 void JackPort::SetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range)
00106 {
00107 if (mode == JackCaptureLatency) {
00108 fCaptureLatency = *range;
00109
00110
00111
00112
00113 if ((fFlags & JackPortIsOutput) && (fFlags & JackPortIsPhysical))
00114 fLatency = (range->min + range->max) / 2;
00115 } else {
00116 fPlaybackLatency = *range;
00117
00118
00119
00120
00121 if ((fFlags & JackPortIsInput) && (fFlags & JackPortIsPhysical))
00122 fLatency = (range->min + range->max) / 2;
00123 }
00124 }
00125
00126 void JackPort::GetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range) const
00127 {
00128 if (mode == JackCaptureLatency) {
00129 *range = fCaptureLatency;
00130 } else {
00131 *range = fPlaybackLatency;
00132 }
00133 }
00134
00135 int JackPort::Tie(jack_port_id_t port_index)
00136 {
00137 fTied = port_index;
00138 return 0;
00139 }
00140
00141 int JackPort::UnTie()
00142 {
00143 fTied = NO_PORT;
00144 return 0;
00145 }
00146
00147 int JackPort::RequestMonitor(bool onoff)
00148 {
00158 if (onoff) {
00159 fMonitorRequests++;
00160 } else if (fMonitorRequests) {
00161 fMonitorRequests--;
00162 }
00163
00164 return 0;
00165 }
00166
00167 int JackPort::EnsureMonitor(bool onoff)
00168 {
00178 if (onoff) {
00179 if (fMonitorRequests == 0) {
00180 fMonitorRequests++;
00181 }
00182 } else {
00183 if (fMonitorRequests > 0) {
00184 fMonitorRequests = 0;
00185 }
00186 }
00187
00188 return 0;
00189 }
00190
00191 const char* JackPort::GetName() const
00192 {
00193 return fName;
00194 }
00195
00196 const char* JackPort::GetShortName() const
00197 {
00198
00199
00200
00201 return strchr(fName, ':') + 1;
00202 }
00203
00204 int JackPort::GetFlags() const
00205 {
00206 return fFlags;
00207 }
00208
00209 const char* JackPort::GetType() const
00210 {
00211 const JackPortType* type = GetPortType(fTypeId);
00212 return type->fName;
00213 }
00214
00215 void JackPort::SetName(const char* new_name)
00216 {
00217 char* colon = strchr(fName, ':');
00218 int len = sizeof(fName) - ((int) (colon - fName)) - 2;
00219 snprintf(colon + 1, len, "%s", new_name);
00220 }
00221
00222 bool JackPort::NameEquals(const char* target)
00223 {
00224 char buf[JACK_PORT_NAME_SIZE + 1];
00225
00226
00227
00228
00229
00230
00231
00232
00233 if (strncmp(target, "ALSA:capture", 12) == 0 || strncmp(target, "ALSA:playback", 13) == 0) {
00234 snprintf(buf, sizeof(buf), "alsa_pcm%s", target + 4);
00235 target = buf;
00236 }
00237
00238 return (strcmp(fName, target) == 0
00239 || strcmp(fAlias1, target) == 0
00240 || strcmp(fAlias2, target) == 0);
00241 }
00242
00243 int JackPort::GetAliases(char* const aliases[2])
00244 {
00245 int cnt = 0;
00246
00247 if (fAlias1[0] != '\0') {
00248 snprintf(aliases[0], JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE, "%s", fAlias1);
00249 cnt++;
00250 }
00251
00252 if (fAlias2[0] != '\0') {
00253 snprintf(aliases[1], JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE, "%s", fAlias2);
00254 cnt++;
00255 }
00256
00257 return cnt;
00258 }
00259
00260 int JackPort::SetAlias(const char* alias)
00261 {
00262 if (fAlias1[0] == '\0') {
00263 snprintf(fAlias1, sizeof(fAlias1), "%s", alias);
00264 } else if (fAlias2[0] == '\0') {
00265 snprintf(fAlias2, sizeof(fAlias2), "%s", alias);
00266 } else {
00267 return -1;
00268 }
00269
00270 return 0;
00271 }
00272
00273 int JackPort::UnsetAlias(const char* alias)
00274 {
00275 if (strcmp(fAlias1, alias) == 0) {
00276 fAlias1[0] = '\0';
00277 } else if (strcmp(fAlias2, alias) == 0) {
00278 fAlias2[0] = '\0';
00279 } else {
00280 return -1;
00281 }
00282
00283 return 0;
00284 }
00285
00286 void JackPort::ClearBuffer(jack_nframes_t frames)
00287 {
00288 const JackPortType* type = GetPortType(fTypeId);
00289 (type->init)(GetBuffer(), frames * sizeof(jack_default_audio_sample_t), frames);
00290 }
00291
00292 void JackPort::MixBuffers(void** src_buffers, int src_count, jack_nframes_t buffer_size)
00293 {
00294 const JackPortType* type = GetPortType(fTypeId);
00295 (type->mixdown)(GetBuffer(), src_buffers, src_count, buffer_size);
00296 }
00297
00298 }