Audio plugin host https://kx.studio/carla
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.

613 lines
23KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2016 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of the ISC license
  6. http://www.isc.org/downloads/software-support-policy/isc-license/
  7. Permission to use, copy, modify, and/or distribute this software for any
  8. purpose with or without fee is hereby granted, provided that the above
  9. copyright notice and this permission notice appear in all copies.
  10. THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
  11. TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  12. FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
  13. OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  14. USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  16. OF THIS SOFTWARE.
  17. -----------------------------------------------------------------------------
  18. To release a closed-source product which uses other parts of JUCE not
  19. licensed under the ISC terms, commercial licenses are available: visit
  20. www.juce.com for more information.
  21. ==============================================================================
  22. */
  23. //==============================================================================
  24. static void* juce_libjackHandle = nullptr;
  25. static void* juce_loadJackFunction (const char* const name)
  26. {
  27. if (juce_libjackHandle == nullptr)
  28. return nullptr;
  29. return dlsym (juce_libjackHandle, name);
  30. }
  31. #define JUCE_DECL_JACK_FUNCTION(return_type, fn_name, argument_types, arguments) \
  32. return_type fn_name argument_types \
  33. { \
  34. typedef return_type (*fn_type) argument_types; \
  35. static fn_type fn = (fn_type) juce_loadJackFunction (#fn_name); \
  36. return (fn != nullptr) ? ((*fn) arguments) : (return_type) 0; \
  37. }
  38. #define JUCE_DECL_VOID_JACK_FUNCTION(fn_name, argument_types, arguments) \
  39. void fn_name argument_types \
  40. { \
  41. typedef void (*fn_type) argument_types; \
  42. static fn_type fn = (fn_type) juce_loadJackFunction (#fn_name); \
  43. if (fn != nullptr) (*fn) arguments; \
  44. }
  45. //==============================================================================
  46. JUCE_DECL_JACK_FUNCTION (jack_client_t*, jack_client_open, (const char* client_name, jack_options_t options, jack_status_t* status, ...), (client_name, options, status));
  47. JUCE_DECL_JACK_FUNCTION (int, jack_client_close, (jack_client_t *client), (client));
  48. JUCE_DECL_JACK_FUNCTION (int, jack_activate, (jack_client_t* client), (client));
  49. JUCE_DECL_JACK_FUNCTION (int, jack_deactivate, (jack_client_t* client), (client));
  50. JUCE_DECL_JACK_FUNCTION (jack_nframes_t, jack_get_buffer_size, (jack_client_t* client), (client));
  51. JUCE_DECL_JACK_FUNCTION (jack_nframes_t, jack_get_sample_rate, (jack_client_t* client), (client));
  52. JUCE_DECL_VOID_JACK_FUNCTION (jack_on_shutdown, (jack_client_t* client, void (*function)(void* arg), void* arg), (client, function, arg));
  53. JUCE_DECL_JACK_FUNCTION (void* , jack_port_get_buffer, (jack_port_t* port, jack_nframes_t nframes), (port, nframes));
  54. JUCE_DECL_JACK_FUNCTION (jack_nframes_t, jack_port_get_total_latency, (jack_client_t* client, jack_port_t* port), (client, port));
  55. JUCE_DECL_JACK_FUNCTION (jack_port_t* , jack_port_register, (jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size), (client, port_name, port_type, flags, buffer_size));
  56. JUCE_DECL_VOID_JACK_FUNCTION (jack_set_error_function, (void (*func)(const char*)), (func));
  57. JUCE_DECL_JACK_FUNCTION (int, jack_set_process_callback, (jack_client_t* client, JackProcessCallback process_callback, void* arg), (client, process_callback, arg));
  58. JUCE_DECL_JACK_FUNCTION (const char**, jack_get_ports, (jack_client_t* client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags), (client, port_name_pattern, type_name_pattern, flags));
  59. JUCE_DECL_JACK_FUNCTION (int, jack_connect, (jack_client_t* client, const char* source_port, const char* destination_port), (client, source_port, destination_port));
  60. JUCE_DECL_JACK_FUNCTION (const char*, jack_port_name, (const jack_port_t* port), (port));
  61. JUCE_DECL_JACK_FUNCTION (void*, jack_set_port_connect_callback, (jack_client_t* client, JackPortConnectCallback connect_callback, void* arg), (client, connect_callback, arg));
  62. JUCE_DECL_JACK_FUNCTION (jack_port_t* , jack_port_by_id, (jack_client_t* client, jack_port_id_t port_id), (client, port_id));
  63. JUCE_DECL_JACK_FUNCTION (int, jack_port_connected, (const jack_port_t* port), (port));
  64. JUCE_DECL_JACK_FUNCTION (int, jack_port_connected_to, (const jack_port_t* port, const char* port_name), (port, port_name));
  65. #if JUCE_DEBUG
  66. #define JACK_LOGGING_ENABLED 1
  67. #endif
  68. #if JACK_LOGGING_ENABLED
  69. namespace
  70. {
  71. void jack_Log (const String& s)
  72. {
  73. std::cerr << s << std::endl;
  74. }
  75. const char* getJackErrorMessage (const jack_status_t status)
  76. {
  77. if (status & JackServerFailed
  78. || status & JackServerError) return "Unable to connect to JACK server";
  79. if (status & JackVersionError) return "Client's protocol version does not match";
  80. if (status & JackInvalidOption) return "The operation contained an invalid or unsupported option";
  81. if (status & JackNameNotUnique) return "The desired client name was not unique";
  82. if (status & JackNoSuchClient) return "Requested client does not exist";
  83. if (status & JackInitFailure) return "Unable to initialize client";
  84. return nullptr;
  85. }
  86. }
  87. #define JUCE_JACK_LOG_STATUS(x) { if (const char* m = getJackErrorMessage (x)) jack_Log (m); }
  88. #define JUCE_JACK_LOG(x) jack_Log(x)
  89. #else
  90. #define JUCE_JACK_LOG_STATUS(x) {}
  91. #define JUCE_JACK_LOG(x) {}
  92. #endif
  93. //==============================================================================
  94. #ifndef JUCE_JACK_CLIENT_NAME
  95. #define JUCE_JACK_CLIENT_NAME "JUCEJack"
  96. #endif
  97. struct JackPortIterator
  98. {
  99. JackPortIterator (jack_client_t* const client, const bool forInput)
  100. : ports (nullptr), index (-1)
  101. {
  102. if (client != nullptr)
  103. ports = juce::jack_get_ports (client, nullptr, nullptr,
  104. forInput ? JackPortIsOutput : JackPortIsInput);
  105. // (NB: This looks like it's the wrong way round, but it is correct!)
  106. }
  107. ~JackPortIterator()
  108. {
  109. ::free (ports);
  110. }
  111. bool next()
  112. {
  113. if (ports == nullptr || ports [index + 1] == nullptr)
  114. return false;
  115. name = CharPointer_UTF8 (ports[++index]);
  116. clientName = name.upToFirstOccurrenceOf (":", false, false);
  117. return true;
  118. }
  119. const char** ports;
  120. int index;
  121. String name;
  122. String clientName;
  123. };
  124. class JackAudioIODeviceType;
  125. static Array<JackAudioIODeviceType*> activeDeviceTypes;
  126. //==============================================================================
  127. class JackAudioIODevice : public AudioIODevice
  128. {
  129. public:
  130. JackAudioIODevice (const String& deviceName,
  131. const String& inId,
  132. const String& outId)
  133. : AudioIODevice (deviceName, "JACK"),
  134. inputId (inId),
  135. outputId (outId),
  136. deviceIsOpen (false),
  137. callback (nullptr),
  138. totalNumberOfInputChannels (0),
  139. totalNumberOfOutputChannels (0)
  140. {
  141. jassert (deviceName.isNotEmpty());
  142. jack_status_t status;
  143. client = juce::jack_client_open (JUCE_JACK_CLIENT_NAME, JackNoStartServer, &status);
  144. if (client == nullptr)
  145. {
  146. JUCE_JACK_LOG_STATUS (status);
  147. }
  148. else
  149. {
  150. juce::jack_set_error_function (errorCallback);
  151. // open input ports
  152. const StringArray inputChannels (getInputChannelNames());
  153. for (int i = 0; i < inputChannels.size(); ++i)
  154. {
  155. String inputName;
  156. inputName << "in_" << ++totalNumberOfInputChannels;
  157. inputPorts.add (juce::jack_port_register (client, inputName.toUTF8(),
  158. JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0));
  159. }
  160. // open output ports
  161. const StringArray outputChannels (getOutputChannelNames());
  162. for (int i = 0; i < outputChannels.size(); ++i)
  163. {
  164. String outputName;
  165. outputName << "out_" << ++totalNumberOfOutputChannels;
  166. outputPorts.add (juce::jack_port_register (client, outputName.toUTF8(),
  167. JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0));
  168. }
  169. inChans.calloc (totalNumberOfInputChannels + 2);
  170. outChans.calloc (totalNumberOfOutputChannels + 2);
  171. }
  172. }
  173. ~JackAudioIODevice()
  174. {
  175. close();
  176. if (client != nullptr)
  177. {
  178. juce::jack_client_close (client);
  179. client = nullptr;
  180. }
  181. }
  182. StringArray getChannelNames (bool forInput) const
  183. {
  184. StringArray names;
  185. for (JackPortIterator i (client, forInput); i.next();)
  186. if (i.clientName == getName())
  187. names.add (i.name.fromFirstOccurrenceOf (":", false, false));
  188. return names;
  189. }
  190. StringArray getOutputChannelNames() override { return getChannelNames (false); }
  191. StringArray getInputChannelNames() override { return getChannelNames (true); }
  192. Array<double> getAvailableSampleRates() override
  193. {
  194. Array<double> rates;
  195. if (client != nullptr)
  196. rates.add (juce::jack_get_sample_rate (client));
  197. return rates;
  198. }
  199. Array<int> getAvailableBufferSizes() override
  200. {
  201. Array<int> sizes;
  202. if (client != nullptr)
  203. sizes.add (juce::jack_get_buffer_size (client));
  204. return sizes;
  205. }
  206. int getDefaultBufferSize() override { return getCurrentBufferSizeSamples(); }
  207. int getCurrentBufferSizeSamples() override { return client != nullptr ? juce::jack_get_buffer_size (client) : 0; }
  208. double getCurrentSampleRate() override { return client != nullptr ? juce::jack_get_sample_rate (client) : 0; }
  209. String open (const BigInteger& inputChannels, const BigInteger& outputChannels,
  210. double /* sampleRate */, int /* bufferSizeSamples */) override
  211. {
  212. if (client == nullptr)
  213. {
  214. lastError = "No JACK client running";
  215. return lastError;
  216. }
  217. lastError.clear();
  218. close();
  219. juce::jack_set_process_callback (client, processCallback, this);
  220. juce::jack_set_port_connect_callback (client, portConnectCallback, this);
  221. juce::jack_on_shutdown (client, shutdownCallback, this);
  222. juce::jack_activate (client);
  223. deviceIsOpen = true;
  224. if (! inputChannels.isZero())
  225. {
  226. for (JackPortIterator i (client, true); i.next();)
  227. {
  228. if (inputChannels [i.index] && i.clientName == getName())
  229. {
  230. int error = juce::jack_connect (client, i.ports[i.index], juce::jack_port_name ((jack_port_t*) inputPorts[i.index]));
  231. if (error != 0)
  232. JUCE_JACK_LOG ("Cannot connect input port " + String (i.index) + " (" + i.name + "), error " + String (error));
  233. }
  234. }
  235. }
  236. if (! outputChannels.isZero())
  237. {
  238. for (JackPortIterator i (client, false); i.next();)
  239. {
  240. if (outputChannels [i.index] && i.clientName == getName())
  241. {
  242. int error = juce::jack_connect (client, juce::jack_port_name ((jack_port_t*) outputPorts[i.index]), i.ports[i.index]);
  243. if (error != 0)
  244. JUCE_JACK_LOG ("Cannot connect output port " + String (i.index) + " (" + i.name + "), error " + String (error));
  245. }
  246. }
  247. }
  248. updateActivePorts();
  249. return lastError;
  250. }
  251. void close() override
  252. {
  253. stop();
  254. if (client != nullptr)
  255. {
  256. juce::jack_deactivate (client);
  257. juce::jack_set_process_callback (client, processCallback, nullptr);
  258. juce::jack_set_port_connect_callback (client, portConnectCallback, nullptr);
  259. juce::jack_on_shutdown (client, shutdownCallback, nullptr);
  260. }
  261. deviceIsOpen = false;
  262. }
  263. void start (AudioIODeviceCallback* newCallback) override
  264. {
  265. if (deviceIsOpen && newCallback != callback)
  266. {
  267. if (newCallback != nullptr)
  268. newCallback->audioDeviceAboutToStart (this);
  269. AudioIODeviceCallback* const oldCallback = callback;
  270. {
  271. const ScopedLock sl (callbackLock);
  272. callback = newCallback;
  273. }
  274. if (oldCallback != nullptr)
  275. oldCallback->audioDeviceStopped();
  276. }
  277. }
  278. void stop() override
  279. {
  280. start (nullptr);
  281. }
  282. bool isOpen() override { return deviceIsOpen; }
  283. bool isPlaying() override { return callback != nullptr; }
  284. int getCurrentBitDepth() override { return 32; }
  285. String getLastError() override { return lastError; }
  286. BigInteger getActiveOutputChannels() const override { return activeOutputChannels; }
  287. BigInteger getActiveInputChannels() const override { return activeInputChannels; }
  288. int getOutputLatencyInSamples() override
  289. {
  290. int latency = 0;
  291. for (int i = 0; i < outputPorts.size(); i++)
  292. latency = jmax (latency, (int) juce::jack_port_get_total_latency (client, (jack_port_t*) outputPorts [i]));
  293. return latency;
  294. }
  295. int getInputLatencyInSamples() override
  296. {
  297. int latency = 0;
  298. for (int i = 0; i < inputPorts.size(); i++)
  299. latency = jmax (latency, (int) juce::jack_port_get_total_latency (client, (jack_port_t*) inputPorts [i]));
  300. return latency;
  301. }
  302. String inputId, outputId;
  303. private:
  304. void process (const int numSamples)
  305. {
  306. int numActiveInChans = 0, numActiveOutChans = 0;
  307. for (int i = 0; i < totalNumberOfInputChannels; ++i)
  308. {
  309. if (activeInputChannels[i])
  310. if (jack_default_audio_sample_t* in
  311. = (jack_default_audio_sample_t*) juce::jack_port_get_buffer ((jack_port_t*) inputPorts.getUnchecked(i), numSamples))
  312. inChans [numActiveInChans++] = (float*) in;
  313. }
  314. for (int i = 0; i < totalNumberOfOutputChannels; ++i)
  315. {
  316. if (activeOutputChannels[i])
  317. if (jack_default_audio_sample_t* out
  318. = (jack_default_audio_sample_t*) juce::jack_port_get_buffer ((jack_port_t*) outputPorts.getUnchecked(i), numSamples))
  319. outChans [numActiveOutChans++] = (float*) out;
  320. }
  321. const ScopedLock sl (callbackLock);
  322. if (callback != nullptr)
  323. {
  324. if ((numActiveInChans + numActiveOutChans) > 0)
  325. callback->audioDeviceIOCallback (const_cast<const float**> (inChans.getData()), numActiveInChans,
  326. outChans, numActiveOutChans, numSamples);
  327. }
  328. else
  329. {
  330. for (int i = 0; i < numActiveOutChans; ++i)
  331. zeromem (outChans[i], sizeof (float) * numSamples);
  332. }
  333. }
  334. static int processCallback (jack_nframes_t nframes, void* callbackArgument)
  335. {
  336. if (callbackArgument != nullptr)
  337. ((JackAudioIODevice*) callbackArgument)->process (nframes);
  338. return 0;
  339. }
  340. void updateActivePorts()
  341. {
  342. BigInteger newOutputChannels, newInputChannels;
  343. for (int i = 0; i < outputPorts.size(); ++i)
  344. if (juce::jack_port_connected ((jack_port_t*) outputPorts.getUnchecked(i)))
  345. newOutputChannels.setBit (i);
  346. for (int i = 0; i < inputPorts.size(); ++i)
  347. if (juce::jack_port_connected ((jack_port_t*) inputPorts.getUnchecked(i)))
  348. newInputChannels.setBit (i);
  349. if (newOutputChannels != activeOutputChannels
  350. || newInputChannels != activeInputChannels)
  351. {
  352. AudioIODeviceCallback* const oldCallback = callback;
  353. stop();
  354. activeOutputChannels = newOutputChannels;
  355. activeInputChannels = newInputChannels;
  356. if (oldCallback != nullptr)
  357. start (oldCallback);
  358. sendDeviceChangedCallback();
  359. }
  360. }
  361. static void portConnectCallback (jack_port_id_t, jack_port_id_t, int, void* arg)
  362. {
  363. if (JackAudioIODevice* device = static_cast<JackAudioIODevice*> (arg))
  364. device->updateActivePorts();
  365. }
  366. static void threadInitCallback (void* /* callbackArgument */)
  367. {
  368. JUCE_JACK_LOG ("JackAudioIODevice::initialise");
  369. }
  370. static void shutdownCallback (void* callbackArgument)
  371. {
  372. JUCE_JACK_LOG ("JackAudioIODevice::shutdown");
  373. if (JackAudioIODevice* device = (JackAudioIODevice*) callbackArgument)
  374. {
  375. device->client = nullptr;
  376. device->close();
  377. }
  378. }
  379. static void errorCallback (const char* msg)
  380. {
  381. JUCE_JACK_LOG ("JackAudioIODevice::errorCallback " + String (msg));
  382. }
  383. static void sendDeviceChangedCallback();
  384. bool deviceIsOpen;
  385. jack_client_t* client;
  386. String lastError;
  387. AudioIODeviceCallback* callback;
  388. CriticalSection callbackLock;
  389. HeapBlock<float*> inChans, outChans;
  390. int totalNumberOfInputChannels;
  391. int totalNumberOfOutputChannels;
  392. Array<void*> inputPorts, outputPorts;
  393. BigInteger activeInputChannels, activeOutputChannels;
  394. };
  395. //==============================================================================
  396. class JackAudioIODeviceType : public AudioIODeviceType
  397. {
  398. public:
  399. JackAudioIODeviceType()
  400. : AudioIODeviceType ("JACK"),
  401. hasScanned (false)
  402. {
  403. activeDeviceTypes.add (this);
  404. }
  405. ~JackAudioIODeviceType()
  406. {
  407. activeDeviceTypes.removeFirstMatchingValue (this);
  408. }
  409. void scanForDevices()
  410. {
  411. hasScanned = true;
  412. inputNames.clear();
  413. inputIds.clear();
  414. outputNames.clear();
  415. outputIds.clear();
  416. if (juce_libjackHandle == nullptr) juce_libjackHandle = dlopen ("libjack.so.0", RTLD_LAZY);
  417. if (juce_libjackHandle == nullptr) juce_libjackHandle = dlopen ("libjack.so", RTLD_LAZY);
  418. if (juce_libjackHandle == nullptr) return;
  419. jack_status_t status;
  420. // open a dummy client
  421. if (jack_client_t* const client = juce::jack_client_open ("JuceJackDummy", JackNoStartServer, &status))
  422. {
  423. // scan for output devices
  424. for (JackPortIterator i (client, false); i.next();)
  425. {
  426. if (i.clientName != (JUCE_JACK_CLIENT_NAME) && ! inputNames.contains (i.clientName))
  427. {
  428. inputNames.add (i.clientName);
  429. inputIds.add (i.ports [i.index]);
  430. }
  431. }
  432. // scan for input devices
  433. for (JackPortIterator i (client, true); i.next();)
  434. {
  435. if (i.clientName != (JUCE_JACK_CLIENT_NAME) && ! outputNames.contains (i.clientName))
  436. {
  437. outputNames.add (i.clientName);
  438. outputIds.add (i.ports [i.index]);
  439. }
  440. }
  441. juce::jack_client_close (client);
  442. }
  443. else
  444. {
  445. JUCE_JACK_LOG_STATUS (status);
  446. }
  447. }
  448. StringArray getDeviceNames (bool wantInputNames) const
  449. {
  450. jassert (hasScanned); // need to call scanForDevices() before doing this
  451. return wantInputNames ? inputNames : outputNames;
  452. }
  453. int getDefaultDeviceIndex (bool /* forInput */) const
  454. {
  455. jassert (hasScanned); // need to call scanForDevices() before doing this
  456. return 0;
  457. }
  458. bool hasSeparateInputsAndOutputs() const { return true; }
  459. int getIndexOfDevice (AudioIODevice* device, bool asInput) const
  460. {
  461. jassert (hasScanned); // need to call scanForDevices() before doing this
  462. if (JackAudioIODevice* d = dynamic_cast<JackAudioIODevice*> (device))
  463. return asInput ? inputIds.indexOf (d->inputId)
  464. : outputIds.indexOf (d->outputId);
  465. return -1;
  466. }
  467. AudioIODevice* createDevice (const String& outputDeviceName,
  468. const String& inputDeviceName)
  469. {
  470. jassert (hasScanned); // need to call scanForDevices() before doing this
  471. const int inputIndex = inputNames.indexOf (inputDeviceName);
  472. const int outputIndex = outputNames.indexOf (outputDeviceName);
  473. if (inputIndex >= 0 || outputIndex >= 0)
  474. return new JackAudioIODevice (outputIndex >= 0 ? outputDeviceName
  475. : inputDeviceName,
  476. inputIds [inputIndex],
  477. outputIds [outputIndex]);
  478. return nullptr;
  479. }
  480. void portConnectionChange() { callDeviceChangeListeners(); }
  481. private:
  482. StringArray inputNames, outputNames, inputIds, outputIds;
  483. bool hasScanned;
  484. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JackAudioIODeviceType)
  485. };
  486. void JackAudioIODevice::sendDeviceChangedCallback()
  487. {
  488. for (int i = activeDeviceTypes.size(); --i >= 0;)
  489. if (JackAudioIODeviceType* d = activeDeviceTypes[i])
  490. d->portConnectionChange();
  491. }
  492. //==============================================================================
  493. AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK()
  494. {
  495. return new JackAudioIODeviceType();
  496. }