jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

274 lines
6.0KB

  1. /*
  2. Copyright (C) 2001-2003 Paul Davis
  3. Copyright (C) 2004-2008 Grame
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #if defined(HAVE_CONFIG_H)
  17. #include "config.h"
  18. #endif
  19. #include "JackPort.h"
  20. #include "JackError.h"
  21. #include "JackPortType.h"
  22. #include <stdio.h>
  23. #include <assert.h>
  24. namespace Jack
  25. {
  26. JackPort::JackPort()
  27. : fTypeId(0),
  28. fFlags(JackPortIsInput),
  29. fRefNum( -1),
  30. fLatency(0),
  31. fTotalLatency(0),
  32. fMonitorRequests(0),
  33. fInUse(false),
  34. fTied(NO_PORT)
  35. {}
  36. bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags)
  37. {
  38. jack_port_type_id_t id = GetPortTypeId(port_type);
  39. if (id == PORT_TYPES_MAX)
  40. return false;
  41. fTypeId = id;
  42. fFlags = flags;
  43. fRefNum = refnum;
  44. strcpy(fName, port_name);
  45. fInUse = true;
  46. fLatency = 0;
  47. fTotalLatency = 0;
  48. fTied = NO_PORT;
  49. // DB: At this point we do not know current buffer size in frames,
  50. // but every time buffer will be returned to any user,
  51. // it will be called with either ClearBuffer or MixBuffers
  52. // with correct current buffer size.
  53. // So it is safe to init with 0 here.
  54. ClearBuffer(0);
  55. return true;
  56. }
  57. void JackPort::Release()
  58. {
  59. fTypeId = 0;
  60. fFlags = JackPortIsInput;
  61. fRefNum = -1;
  62. fInUse = false;
  63. fLatency = 0;
  64. fTotalLatency = 0;
  65. fTied = NO_PORT;
  66. fAlias1[0] = '\0';
  67. fAlias2[0] = '\0';
  68. }
  69. float* JackPort::GetBuffer()
  70. {
  71. return fBuffer;
  72. }
  73. int JackPort::GetRefNum() const
  74. {
  75. return fRefNum;
  76. }
  77. jack_nframes_t JackPort::GetLatency() const
  78. {
  79. return fLatency;
  80. }
  81. jack_nframes_t JackPort::GetTotalLatency() const
  82. {
  83. return fTotalLatency;
  84. }
  85. void JackPort::SetLatency(jack_nframes_t nframes)
  86. {
  87. fLatency = nframes;
  88. }
  89. int JackPort::Tie(jack_port_id_t port_index)
  90. {
  91. fTied = port_index;
  92. return 0;
  93. }
  94. int JackPort::UnTie()
  95. {
  96. fTied = NO_PORT;
  97. return 0;
  98. }
  99. int JackPort::RequestMonitor(bool onoff)
  100. {
  101. /**
  102. jackd.h
  103. * If @ref JackPortCanMonitor is set for this @a port, turn input
  104. * monitoring on or off. Otherwise, do nothing.
  105. if (!(fFlags & JackPortCanMonitor))
  106. return -1;
  107. */
  108. if (onoff) {
  109. fMonitorRequests++;
  110. } else if (fMonitorRequests) {
  111. fMonitorRequests--;
  112. }
  113. return 0;
  114. }
  115. int JackPort::EnsureMonitor(bool onoff)
  116. {
  117. /**
  118. jackd.h
  119. * If @ref JackPortCanMonitor is set for this @a port, turn input
  120. * monitoring on or off. Otherwise, do nothing.
  121. if (!(fFlags & JackPortCanMonitor))
  122. return -1;
  123. */
  124. if (onoff) {
  125. if (fMonitorRequests == 0) {
  126. fMonitorRequests++;
  127. }
  128. } else {
  129. if (fMonitorRequests > 0) {
  130. fMonitorRequests = 0;
  131. }
  132. }
  133. return 0;
  134. }
  135. bool JackPort::MonitoringInput()
  136. {
  137. return (fMonitorRequests > 0);
  138. }
  139. const char* JackPort::GetName() const
  140. {
  141. return fName;
  142. }
  143. const char* JackPort::GetShortName() const
  144. {
  145. /* we know there is always a colon, because we put
  146. it there ...
  147. */
  148. return strchr(fName, ':') + 1;
  149. }
  150. int JackPort::GetFlags() const
  151. {
  152. return fFlags;
  153. }
  154. const char* JackPort::GetType() const
  155. {
  156. const JackPortType* type = GetPortType(fTypeId);
  157. return type->name;
  158. }
  159. void JackPort::SetName(const char* new_name)
  160. {
  161. char* colon = strchr(fName, ':');
  162. int len = sizeof(fName) - ((int) (colon - fName)) - 2;
  163. snprintf(colon + 1, len, "%s", new_name);
  164. }
  165. bool JackPort::NameEquals(const char* target)
  166. {
  167. char buf[JACK_PORT_NAME_SIZE + 1];
  168. /* this nasty, nasty kludge is here because between 0.109.0 and 0.109.1,
  169. the ALSA audio backend had the name "ALSA", whereas as before and
  170. after it, it was called "alsa_pcm". this stops breakage for
  171. any setups that have saved "alsa_pcm" or "ALSA" in their connection
  172. state.
  173. */
  174. if (strncmp(target, "ALSA:capture", 12) == 0 || strncmp(target, "ALSA:playback", 13) == 0) {
  175. snprintf(buf, sizeof(buf), "alsa_pcm%s", target + 4);
  176. target = buf;
  177. }
  178. return (strcmp(fName, target) == 0
  179. || strcmp(fAlias1, target) == 0
  180. || strcmp(fAlias2, target) == 0);
  181. }
  182. int JackPort::GetAliases(char* const aliases[2])
  183. {
  184. int cnt = 0;
  185. if (fAlias1[0] != '\0') {
  186. snprintf(aliases[0], JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE, "%s", fAlias1);
  187. cnt++;
  188. }
  189. if (fAlias2[0] != '\0') {
  190. snprintf(aliases[1], JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE, "%s", fAlias2);
  191. cnt++;
  192. }
  193. return cnt;
  194. }
  195. int JackPort::SetAlias(const char* alias)
  196. {
  197. if (fAlias1[0] == '\0') {
  198. snprintf(fAlias1, sizeof(fAlias1), "%s", alias);
  199. } else if (fAlias2[0] == '\0') {
  200. snprintf(fAlias2, sizeof(fAlias2), "%s", alias);
  201. } else {
  202. return -1;
  203. }
  204. return 0;
  205. }
  206. int JackPort::UnsetAlias(const char* alias)
  207. {
  208. if (strcmp(fAlias1, alias) == 0) {
  209. fAlias1[0] = '\0';
  210. } else if (strcmp(fAlias2, alias) == 0) {
  211. fAlias2[0] = '\0';
  212. } else {
  213. return -1;
  214. }
  215. return 0;
  216. }
  217. void JackPort::ClearBuffer(jack_nframes_t frames)
  218. {
  219. const JackPortType* type = GetPortType(fTypeId);
  220. (type->init)(fBuffer, frames * sizeof(float), frames);
  221. }
  222. void JackPort::MixBuffers(void** src_buffers, int src_count, jack_nframes_t buffer_size)
  223. {
  224. const JackPortType* type = GetPortType(fTypeId);
  225. (type->mixdown)(fBuffer, src_buffers, src_count, buffer_size);
  226. }
  227. } // end of namespace