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.

502 lines
13KB

  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the GPL.txt file
  16. */
  17. #ifndef HAVE_JUCE
  18. # error This file should not be compiled if Juce is disabled
  19. #endif
  20. #include "CarlaEngineInternal.hpp"
  21. #include "CarlaBackendUtils.hpp"
  22. // #include "RtLinkedList.hpp"
  23. #include "juce_audio_devices.h"
  24. using namespace juce;
  25. CARLA_BACKEND_START_NAMESPACE
  26. #if 0
  27. } // Fix editor indentation
  28. #endif
  29. // -------------------------------------------------------------------------------------------------------------------
  30. static const char** gRetNames = nullptr;
  31. static OwnedArray<AudioIODeviceType> gJuceDeviceTypes;
  32. static void initJuceDevices()
  33. {
  34. static AudioDeviceManager manager;
  35. if (gJuceDeviceTypes.size() == 0)
  36. manager.createAudioDeviceTypes(gJuceDeviceTypes);
  37. }
  38. // -------------------------------------------------------------------------------------------------------------------
  39. // Cleanup
  40. static struct JuceCleanup {
  41. JuceCleanup() {}
  42. ~JuceCleanup()
  43. {
  44. if (gRetNames != nullptr)
  45. {
  46. delete[] gRetNames;
  47. gRetNames = nullptr;
  48. }
  49. gJuceDeviceTypes.clear(true);
  50. }
  51. } sJuceCleanup;
  52. // -------------------------------------------------------------------------------------------------------------------
  53. // Juce Engine
  54. class CarlaEngineJuce : public CarlaEngine,
  55. public AudioIODeviceCallback
  56. {
  57. public:
  58. CarlaEngineJuce(AudioIODeviceType* const devType)
  59. : CarlaEngine(),
  60. AudioIODeviceCallback(),
  61. fDeviceType(devType)
  62. {
  63. carla_debug("CarlaEngineJuce::CarlaEngineJuce(%p)", devType);
  64. // just to make sure
  65. pData->options.transportMode = ENGINE_TRANSPORT_MODE_INTERNAL;
  66. }
  67. ~CarlaEngineJuce() override
  68. {
  69. carla_debug("CarlaEngineJuce::~CarlaEngineJuce()");
  70. }
  71. // -------------------------------------
  72. bool init(const char* const clientName) override
  73. {
  74. CARLA_SAFE_ASSERT_RETURN(clientName != nullptr && clientName[0] != '\0', false);
  75. carla_debug("CarlaEngineJuce::init(\"%s\")", clientName);
  76. if (pData->options.processMode != ENGINE_PROCESS_MODE_CONTINUOUS_RACK && pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY)
  77. {
  78. setLastError("Invalid process mode");
  79. return false;
  80. }
  81. String deviceName;
  82. if (pData->options.audioDevice != nullptr && pData->options.audioDevice[0] != '\0')
  83. {
  84. deviceName = pData->options.audioDevice;
  85. }
  86. else
  87. {
  88. const int defaultIndex(fDeviceType->getDefaultDeviceIndex(false));
  89. StringArray deviceNames(fDeviceType->getDeviceNames());
  90. if (defaultIndex >= 0 && defaultIndex < deviceNames.size())
  91. deviceName = deviceNames[defaultIndex];
  92. }
  93. if (deviceName.isEmpty())
  94. {
  95. setLastError("Audio device has not been selected yet and a default one is not available");
  96. return false;
  97. }
  98. fDevice = fDeviceType->createDevice(deviceName, deviceName);
  99. if (fDevice == nullptr)
  100. {
  101. setLastError("Failed to create device");
  102. return false;
  103. }
  104. StringArray inputNames(fDevice->getInputChannelNames());
  105. StringArray outputNames(fDevice->getOutputChannelNames());
  106. BigInteger inputChannels;
  107. inputChannels.setRange(0, inputNames.size(), true);
  108. BigInteger outputChannels;
  109. outputChannels.setRange(0, outputNames.size(), true);
  110. String error = fDevice->open(inputChannels, outputChannels, pData->options.audioSampleRate, static_cast<int>(pData->options.audioBufferSize));
  111. if (error.isNotEmpty())
  112. {
  113. fDevice = nullptr;
  114. setLastError(error.toUTF8());
  115. return false;
  116. }
  117. pData->bufferSize = static_cast<uint32_t>(fDevice->getCurrentBufferSizeSamples());
  118. pData->sampleRate = fDevice->getCurrentSampleRate();
  119. pData->audio.inCount = static_cast<uint32_t>(inputChannels.countNumberOfSetBits());
  120. pData->audio.outCount = static_cast<uint32_t>(outputChannels.countNumberOfSetBits());
  121. CARLA_SAFE_ASSERT(pData->audio.outCount > 0);
  122. pData->audio.create(pData->bufferSize);
  123. fDevice->start(this);
  124. CarlaEngine::init(clientName);
  125. patchbayRefresh();
  126. return true;
  127. }
  128. bool close() override
  129. {
  130. carla_debug("CarlaEngineJuce::close()");
  131. pData->audio.isReady = false;
  132. bool hasError = !CarlaEngine::close();
  133. if (fDevice != nullptr)
  134. {
  135. if (fDevice->isPlaying())
  136. fDevice->stop();
  137. if (fDevice->isOpen())
  138. fDevice->close();
  139. fDevice = nullptr;
  140. }
  141. return !hasError;
  142. }
  143. bool isRunning() const noexcept override
  144. {
  145. return fDevice != nullptr && fDevice->isPlaying();
  146. }
  147. bool isOffline() const noexcept override
  148. {
  149. return false;
  150. }
  151. EngineType getType() const noexcept override
  152. {
  153. return kEngineTypeJuce;
  154. }
  155. const char* getCurrentDriverName() const noexcept override
  156. {
  157. return fDeviceType->getTypeName().toRawUTF8();
  158. }
  159. // -------------------------------------------------------------------
  160. // Patchbay
  161. bool patchbayRefresh() override
  162. {
  163. // const String& deviceName(fDevice->getName());
  164. return true;
  165. }
  166. // -------------------------------------------------------------------
  167. protected:
  168. void audioDeviceIOCallback(const float** inputChannelData, int numInputChannels, float** outputChannelData, int numOutputChannels, int numSamples) override
  169. {
  170. // assert juce buffers
  171. CARLA_SAFE_ASSERT_RETURN(numInputChannels == static_cast<int>(pData->audio.inCount),);
  172. CARLA_SAFE_ASSERT_RETURN(numOutputChannels == static_cast<int>(pData->audio.outCount),);
  173. CARLA_SAFE_ASSERT_RETURN(outputChannelData != nullptr,);
  174. CARLA_SAFE_ASSERT_RETURN(numSamples == static_cast<int>(pData->bufferSize),);
  175. if (numOutputChannels == 0 || ! pData->audio.isReady)
  176. return runPendingRtEvents();
  177. // initialize input events
  178. carla_zeroStruct<EngineEvent>(pData->events.in, kMaxEngineEventInternalCount);
  179. // TODO - get events from juce
  180. if (pData->graph.isRack)
  181. {
  182. pData->processRackFull(const_cast<float**>(inputChannelData), static_cast<uint32_t>(numInputChannels),
  183. outputChannelData, static_cast<uint32_t>(numOutputChannels),
  184. static_cast<uint32_t>(numSamples), false);
  185. }
  186. else
  187. {
  188. }
  189. // output events
  190. {
  191. // TODO
  192. //fMidiOutEvents...
  193. }
  194. runPendingRtEvents();
  195. return;
  196. // unused
  197. (void)inputChannelData;
  198. (void)numInputChannels;
  199. }
  200. void audioDeviceAboutToStart(AudioIODevice* /*device*/) override
  201. {
  202. }
  203. void audioDeviceStopped() override
  204. {
  205. }
  206. void audioDeviceError(const String& errorMessage) override
  207. {
  208. callback(ENGINE_CALLBACK_ERROR, 0, 0, 0, 0.0f, errorMessage.toRawUTF8());
  209. }
  210. // -------------------------------------------------------------------
  211. bool connectRackMidiInPort(const int) override
  212. {
  213. return false;
  214. }
  215. bool connectRackMidiOutPort(const int) override
  216. {
  217. return false;
  218. }
  219. bool disconnectRackMidiInPort(const int) override
  220. {
  221. return false;
  222. }
  223. bool disconnectRackMidiOutPort(const int) override
  224. {
  225. return false;
  226. }
  227. // -------------------------------------
  228. private:
  229. ScopedPointer<AudioIODevice> fDevice;
  230. AudioIODeviceType* const fDeviceType;
  231. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJuce)
  232. };
  233. // -----------------------------------------
  234. CarlaEngine* CarlaEngine::newJuce(const AudioApi api)
  235. {
  236. initJuceDevices();
  237. String juceApi;
  238. switch (api)
  239. {
  240. case AUDIO_API_NULL:
  241. case AUDIO_API_OSS:
  242. case AUDIO_API_PULSE:
  243. break;
  244. case AUDIO_API_JACK:
  245. juceApi = "JACK";
  246. break;
  247. case AUDIO_API_ALSA:
  248. juceApi = "ALSA";
  249. break;
  250. case AUDIO_API_CORE:
  251. juceApi = "CoreAudio";
  252. break;
  253. case AUDIO_API_ASIO:
  254. juceApi = "ASIO";
  255. break;
  256. case AUDIO_API_DS:
  257. juceApi = "DirectSound";
  258. break;
  259. }
  260. if (juceApi.isEmpty())
  261. return nullptr;
  262. AudioIODeviceType* deviceType = nullptr;
  263. for (int i=0, count=gJuceDeviceTypes.size(); i < count; ++i)
  264. {
  265. deviceType = gJuceDeviceTypes[i];
  266. if (deviceType == nullptr || deviceType->getTypeName() == juceApi)
  267. break;
  268. }
  269. if (deviceType == nullptr)
  270. return nullptr;
  271. deviceType->scanForDevices();
  272. return new CarlaEngineJuce(deviceType);
  273. }
  274. unsigned int CarlaEngine::getJuceApiCount()
  275. {
  276. return 0; // TODO
  277. initJuceDevices();
  278. return static_cast<unsigned int>(gJuceDeviceTypes.size());
  279. }
  280. const char* CarlaEngine::getJuceApiName(const unsigned int index)
  281. {
  282. initJuceDevices();
  283. if (static_cast<int>(index) >= gJuceDeviceTypes.size())
  284. return nullptr;
  285. AudioIODeviceType* const deviceType(gJuceDeviceTypes[static_cast<int>(index)]);
  286. if (deviceType == nullptr)
  287. return nullptr;
  288. return deviceType->getTypeName().toRawUTF8();
  289. }
  290. const char* const* CarlaEngine::getJuceApiDeviceNames(const unsigned int index)
  291. {
  292. initJuceDevices();
  293. if (static_cast<int>(index) >= gJuceDeviceTypes.size())
  294. return nullptr;
  295. AudioIODeviceType* const deviceType(gJuceDeviceTypes[static_cast<int>(index)]);
  296. if (deviceType == nullptr)
  297. return nullptr;
  298. deviceType->scanForDevices();
  299. StringArray deviceNames(deviceType->getDeviceNames());
  300. const int deviceNameCount(deviceNames.size());
  301. if (deviceNameCount <= 0)
  302. return nullptr;
  303. if (gRetNames != nullptr)
  304. {
  305. for (int i=0; gRetNames[i] != nullptr; ++i)
  306. delete[] gRetNames[i];
  307. delete[] gRetNames;
  308. }
  309. gRetNames = new const char*[deviceNameCount+1];
  310. for (int i=0; i < deviceNameCount; ++i)
  311. gRetNames[i] = carla_strdup(deviceNames[i].toRawUTF8());
  312. gRetNames[deviceNameCount] = nullptr;
  313. return gRetNames;
  314. }
  315. const EngineDriverDeviceInfo* CarlaEngine::getJuceDeviceInfo(const unsigned int index, const char* const deviceName)
  316. {
  317. initJuceDevices();
  318. if (static_cast<int>(index) >= gJuceDeviceTypes.size())
  319. {
  320. carla_stderr("here 001");
  321. return nullptr;
  322. }
  323. AudioIODeviceType* const deviceType(gJuceDeviceTypes[static_cast<int>(index)]);
  324. if (deviceType == nullptr)
  325. return nullptr;
  326. deviceType->scanForDevices();
  327. ScopedPointer<AudioIODevice> device(deviceType->createDevice(deviceName, deviceName));
  328. if (device == nullptr)
  329. return nullptr;
  330. static EngineDriverDeviceInfo devInfo = { 0x0, nullptr, nullptr };
  331. static uint32_t dummyBufferSizes[11] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 0 };
  332. static double dummySampleRates[14] = { 22050.0, 32000.0, 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0, 0.0 };
  333. // reset
  334. devInfo.hints = ENGINE_DRIVER_DEVICE_VARIABLE_BUFFER_SIZE | ENGINE_DRIVER_DEVICE_VARIABLE_SAMPLE_RATE;
  335. // cleanup
  336. if (devInfo.bufferSizes != nullptr && devInfo.bufferSizes != dummyBufferSizes)
  337. {
  338. delete[] devInfo.bufferSizes;
  339. devInfo.bufferSizes = nullptr;
  340. }
  341. if (devInfo.sampleRates != nullptr && devInfo.sampleRates != dummySampleRates)
  342. {
  343. delete[] devInfo.sampleRates;
  344. devInfo.sampleRates = nullptr;
  345. }
  346. if (device->hasControlPanel())
  347. devInfo.hints |= ENGINE_DRIVER_DEVICE_HAS_CONTROL_PANEL;
  348. Array<int> juceBufferSizes = device->getAvailableBufferSizes();
  349. if (int bufferSizesCount = juceBufferSizes.size())
  350. {
  351. uint32_t* const bufferSizes(new uint32_t[bufferSizesCount+1]);
  352. for (int i=0; i < bufferSizesCount; ++i)
  353. bufferSizes[i] = static_cast<uint32_t>(juceBufferSizes[i]);
  354. bufferSizes[bufferSizesCount] = 0;
  355. devInfo.bufferSizes = bufferSizes;
  356. }
  357. else
  358. {
  359. devInfo.bufferSizes = dummyBufferSizes;
  360. }
  361. Array<double> juceSampleRates = device->getAvailableSampleRates();
  362. if (int sampleRatesCount = juceSampleRates.size())
  363. {
  364. double* const sampleRates(new double[sampleRatesCount+1]);
  365. for (int i=0; i < sampleRatesCount; ++i)
  366. sampleRates[i] = juceSampleRates[i];
  367. sampleRates[sampleRatesCount] = 0.0;
  368. devInfo.sampleRates = sampleRates;
  369. }
  370. else
  371. {
  372. devInfo.sampleRates = dummySampleRates;
  373. }
  374. return &devInfo;
  375. }
  376. // -----------------------------------------
  377. CARLA_BACKEND_END_NAMESPACE