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.

289 lines
5.8KB

  1. /*
  2. Copyright (C) 2001-2003 Paul Davis
  3. Copyright (C) 2004-2006 Grame
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 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 General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #include "JackPort.h"
  17. #include "JackError.h"
  18. #include <stdio.h>
  19. #include <assert.h>
  20. namespace Jack
  21. {
  22. JackPort::JackPort()
  23. : fFlags(JackPortIsInput), fRefNum( -1), fLatency(0), fMonitorRequests(0), fInUse(false), fLocked(false), fTied(NO_PORT)
  24. {}
  25. JackPort::~JackPort()
  26. {}
  27. void JackPort::Allocate(int refnum, const char* port_name, JackPortFlags flags)
  28. {
  29. fFlags = flags;
  30. fRefNum = refnum;
  31. strcpy(fName, port_name);
  32. memset(fBuffer, 0, BUFFER_SIZE_MAX * sizeof(float));
  33. fInUse = true;
  34. fLocked = false;
  35. fLatency = 0;
  36. fTied = NO_PORT;
  37. }
  38. void JackPort::Release()
  39. {
  40. fFlags = JackPortIsInput;
  41. fRefNum = -1;
  42. fInUse = false;
  43. fLocked = false;
  44. fLatency = 0;
  45. fTied = NO_PORT;
  46. fAlias1[0] = '\0';
  47. fAlias2[0] = '\0';
  48. }
  49. bool JackPort::IsUsed() const
  50. {
  51. return fInUse;
  52. }
  53. float* JackPort::GetBuffer()
  54. {
  55. return fBuffer;
  56. }
  57. int JackPort::GetRefNum() const
  58. {
  59. return fRefNum;
  60. }
  61. int JackPort::Lock()
  62. {
  63. fLocked = true;
  64. return 0;
  65. }
  66. int JackPort::Unlock()
  67. {
  68. fLocked = false;
  69. return 0;
  70. }
  71. jack_nframes_t JackPort::GetLatency() const
  72. {
  73. return fLatency;
  74. }
  75. void JackPort::SetLatency(jack_nframes_t nframes)
  76. {
  77. fLatency = nframes;
  78. }
  79. int JackPort::Tie(jack_port_id_t port_index)
  80. {
  81. fTied = port_index;
  82. return 0;
  83. }
  84. int JackPort::UnTie()
  85. {
  86. fTied = NO_PORT;
  87. return 0;
  88. }
  89. int JackPort::RequestMonitor(bool onoff)
  90. {
  91. /**
  92. jackd.h
  93. * If @ref JackPortCanMonitor is set for this @a port, turn input
  94. * monitoring on or off. Otherwise, do nothing.
  95. if (!(fFlags & JackPortCanMonitor))
  96. return -1;
  97. */
  98. if (onoff) {
  99. fMonitorRequests++;
  100. } else if (fMonitorRequests) {
  101. fMonitorRequests--;
  102. }
  103. return 0;
  104. }
  105. int JackPort::EnsureMonitor(bool onoff)
  106. {
  107. /**
  108. jackd.h
  109. * If @ref JackPortCanMonitor is set for this @a port, turn input
  110. * monitoring on or off. Otherwise, do nothing.
  111. if (!(fFlags & JackPortCanMonitor))
  112. return -1;
  113. */
  114. if (onoff) {
  115. if (fMonitorRequests == 0) {
  116. fMonitorRequests++;
  117. }
  118. } else {
  119. if (fMonitorRequests > 0) {
  120. fMonitorRequests = 0;
  121. }
  122. }
  123. return 0;
  124. }
  125. bool JackPort::MonitoringInput()
  126. {
  127. return (fMonitorRequests > 0);
  128. }
  129. const char* JackPort::GetName() const
  130. {
  131. return fName;
  132. }
  133. const char* JackPort::GetShortName() const
  134. {
  135. /* we know there is always a colon, because we put
  136. it there ...
  137. */
  138. return strchr(fName, ':') + 1;
  139. }
  140. int JackPort::Flags() const
  141. {
  142. return fFlags;
  143. }
  144. const char* JackPort::Type() const
  145. {
  146. // TO IMPROVE
  147. return JACK_DEFAULT_AUDIO_TYPE;
  148. }
  149. int JackPort::SetName(const char* new_name)
  150. {
  151. char* colon = strchr(fName, ':');
  152. int len = sizeof(fName) - ((int) (colon - fName)) - 2;
  153. snprintf(colon + 1, len, "%s", new_name);
  154. return 0;
  155. }
  156. void JackPort::Rename(const char* name, int index)
  157. {
  158. SetAlias(GetName());
  159. snprintf(fName, sizeof(fName) - 1, name, index);
  160. }
  161. bool JackPort::NameEquals(const char* target)
  162. {
  163. return (strcmp(fName, target) == 0
  164. || strcmp(fAlias1, target) == 0
  165. || strcmp(fAlias2, target) == 0);
  166. }
  167. int JackPort::GetAliases(char* const aliases[2])
  168. {
  169. int cnt = 0;
  170. if (fAlias1[0] != '\0') {
  171. snprintf(aliases[0], JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE, "%s", fAlias1);
  172. cnt++;
  173. }
  174. if (fAlias2[0] != '\0') {
  175. snprintf(aliases[1], JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE, "%s", fAlias2);
  176. cnt++;
  177. }
  178. return cnt;
  179. }
  180. int JackPort::SetAlias(const char* alias)
  181. {
  182. if (fAlias1[0] == '\0') {
  183. snprintf(fAlias1, sizeof(fAlias1), "%s", alias);
  184. } else if (fAlias2[0] == '\0') {
  185. snprintf(fAlias2, sizeof(fAlias2), "%s", alias);
  186. } else {
  187. return -1;
  188. }
  189. return 0;
  190. }
  191. int JackPort::UnsetAlias(const char* alias)
  192. {
  193. if (strcmp(fAlias1, alias) == 0) {
  194. fAlias1[0] = '\0';
  195. } else if (strcmp(fAlias2, alias) == 0) {
  196. fAlias2[0] = '\0';
  197. } else {
  198. return -1;
  199. }
  200. return 0;
  201. }
  202. void JackPort::MixBuffer(float* mixbuffer, float* buffer, jack_nframes_t frames)
  203. {
  204. jack_nframes_t frames_group = frames / 4;
  205. frames = frames % 4;
  206. while (frames_group > 0) {
  207. register float mixFloat1 = *mixbuffer;
  208. register float sourceFloat1 = *buffer;
  209. register float mixFloat2 = *(mixbuffer + 1);
  210. register float sourceFloat2 = *(buffer + 1);
  211. register float mixFloat3 = *(mixbuffer + 2);
  212. register float sourceFloat3 = *(buffer + 2);
  213. register float mixFloat4 = *(mixbuffer + 3);
  214. register float sourceFloat4 = *(buffer + 3);
  215. buffer += 4;
  216. frames_group--;
  217. mixFloat1 += sourceFloat1;
  218. mixFloat2 += sourceFloat2;
  219. mixFloat3 += sourceFloat3;
  220. mixFloat4 += sourceFloat4;
  221. *mixbuffer = mixFloat1;
  222. *(mixbuffer + 1) = mixFloat2;
  223. *(mixbuffer + 2) = mixFloat3;
  224. *(mixbuffer + 3) = mixFloat4;
  225. mixbuffer += 4;
  226. }
  227. while (frames > 0) {
  228. register float mixFloat1 = *mixbuffer;
  229. register float sourceFloat1 = *buffer;
  230. buffer++;
  231. frames--;
  232. mixFloat1 += sourceFloat1;
  233. *mixbuffer = mixFloat1;
  234. mixbuffer++;
  235. }
  236. }
  237. } // end of namespace