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.

504 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. pData->audio.clear();
  142. return !hasError;
  143. }
  144. bool isRunning() const noexcept override
  145. {
  146. return fDevice != nullptr && fDevice->isPlaying();
  147. }
  148. bool isOffline() const noexcept override
  149. {
  150. return false;
  151. }
  152. EngineType getType() const noexcept override
  153. {
  154. return kEngineTypeJuce;
  155. }
  156. const char* getCurrentDriverName() const noexcept override
  157. {
  158. return fDeviceType->getTypeName().toRawUTF8();
  159. }
  160. // -------------------------------------------------------------------
  161. // Patchbay
  162. bool patchbayRefresh() override
  163. {
  164. // const String& deviceName(fDevice->getName());
  165. return true;
  166. }
  167. // -------------------------------------------------------------------
  168. protected:
  169. void audioDeviceIOCallback(const float** inputChannelData, int numInputChannels, float** outputChannelData, int numOutputChannels, int numSamples) override
  170. {
  171. // assert juce buffers
  172. CARLA_SAFE_ASSERT_RETURN(numInputChannels == static_cast<int>(pData->audio.inCount),);
  173. CARLA_SAFE_ASSERT_RETURN(numOutputChannels == static_cast<int>(pData->audio.outCount),);
  174. CARLA_SAFE_ASSERT_RETURN(outputChannelData != nullptr,);
  175. CARLA_SAFE_ASSERT_RETURN(numSamples == static_cast<int>(pData->bufferSize),);
  176. if (numOutputChannels == 0 || ! pData->audio.isReady)
  177. return runPendingRtEvents();
  178. // initialize input events
  179. carla_zeroStruct<EngineEvent>(pData->events.in, kMaxEngineEventInternalCount);
  180. // TODO - get events from juce
  181. if (pData->graph.isRack)
  182. {
  183. pData->processRackFull(const_cast<float**>(inputChannelData), static_cast<uint32_t>(numInputChannels),
  184. outputChannelData, static_cast<uint32_t>(numOutputChannels),
  185. static_cast<uint32_t>(numSamples), false);
  186. }
  187. else
  188. {
  189. }
  190. // output events
  191. {
  192. // TODO
  193. //fMidiOutEvents...
  194. }
  195. runPendingRtEvents();
  196. return;
  197. // unused
  198. (void)inputChannelData;
  199. (void)numInputChannels;
  200. }
  201. void audioDeviceAboutToStart(AudioIODevice* /*device*/) override
  202. {
  203. }
  204. void audioDeviceStopped() override
  205. {
  206. }
  207. void audioDeviceError(const String& errorMessage) override
  208. {
  209. callback(ENGINE_CALLBACK_ERROR, 0, 0, 0, 0.0f, errorMessage.toRawUTF8());
  210. }
  211. // -------------------------------------------------------------------
  212. bool connectRackMidiInPort(const int) override
  213. {
  214. return false;
  215. }
  216. bool connectRackMidiOutPort(const int) override
  217. {
  218. return false;
  219. }
  220. bool disconnectRackMidiInPort(const int) override
  221. {
  222. return false;
  223. }
  224. bool disconnectRackMidiOutPort(const int) override
  225. {
  226. return false;
  227. }
  228. // -------------------------------------
  229. private:
  230. ScopedPointer<AudioIODevice> fDevice;
  231. AudioIODeviceType* const fDeviceType;
  232. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJuce)
  233. };
  234. // -----------------------------------------
  235. CarlaEngine* CarlaEngine::newJuce(const AudioApi api)
  236. {
  237. initJuceDevices();
  238. String juceApi;
  239. switch (api)
  240. {
  241. case AUDIO_API_NULL:
  242. case AUDIO_API_OSS:
  243. case AUDIO_API_PULSE:
  244. break;
  245. case AUDIO_API_JACK:
  246. juceApi = "JACK";
  247. break;
  248. case AUDIO_API_ALSA:
  249. juceApi = "ALSA";
  250. break;
  251. case AUDIO_API_CORE:
  252. juceApi = "CoreAudio";
  253. break;
  254. case AUDIO_API_ASIO:
  255. juceApi = "ASIO";
  256. break;
  257. case AUDIO_API_DS:
  258. juceApi = "DirectSound";
  259. break;
  260. }
  261. if (juceApi.isEmpty())
  262. return nullptr;
  263. AudioIODeviceType* deviceType = nullptr;
  264. for (int i=0, count=gJuceDeviceTypes.size(); i < count; ++i)
  265. {
  266. deviceType = gJuceDeviceTypes[i];
  267. if (deviceType == nullptr || deviceType->getTypeName() == juceApi)
  268. break;
  269. }
  270. if (deviceType == nullptr)
  271. return nullptr;
  272. deviceType->scanForDevices();
  273. return new CarlaEngineJuce(deviceType);
  274. }
  275. unsigned int CarlaEngine::getJuceApiCount()
  276. {
  277. return 0; // TODO
  278. initJuceDevices();
  279. return static_cast<unsigned int>(gJuceDeviceTypes.size());
  280. }
  281. const char* CarlaEngine::getJuceApiName(const unsigned int index)
  282. {
  283. initJuceDevices();
  284. if (static_cast<int>(index) >= gJuceDeviceTypes.size())
  285. return nullptr;
  286. AudioIODeviceType* const deviceType(gJuceDeviceTypes[static_cast<int>(index)]);
  287. if (deviceType == nullptr)
  288. return nullptr;
  289. return deviceType->getTypeName().toRawUTF8();
  290. }
  291. const char* const* CarlaEngine::getJuceApiDeviceNames(const unsigned int index)
  292. {
  293. initJuceDevices();
  294. if (static_cast<int>(index) >= gJuceDeviceTypes.size())
  295. return nullptr;
  296. AudioIODeviceType* const deviceType(gJuceDeviceTypes[static_cast<int>(index)]);
  297. if (deviceType == nullptr)
  298. return nullptr;
  299. deviceType->scanForDevices();
  300. StringArray deviceNames(deviceType->getDeviceNames());
  301. const int deviceNameCount(deviceNames.size());
  302. if (deviceNameCount <= 0)
  303. return nullptr;
  304. if (gRetNames != nullptr)
  305. {
  306. for (int i=0; gRetNames[i] != nullptr; ++i)
  307. delete[] gRetNames[i];
  308. delete[] gRetNames;
  309. }
  310. gRetNames = new const char*[deviceNameCount+1];
  311. for (int i=0; i < deviceNameCount; ++i)
  312. gRetNames[i] = carla_strdup(deviceNames[i].toRawUTF8());
  313. gRetNames[deviceNameCount] = nullptr;
  314. return gRetNames;
  315. }
  316. const EngineDriverDeviceInfo* CarlaEngine::getJuceDeviceInfo(const unsigned int index, const char* const deviceName)
  317. {
  318. initJuceDevices();
  319. if (static_cast<int>(index) >= gJuceDeviceTypes.size())
  320. {
  321. carla_stderr("here 001");
  322. return nullptr;
  323. }
  324. AudioIODeviceType* const deviceType(gJuceDeviceTypes[static_cast<int>(index)]);
  325. if (deviceType == nullptr)
  326. return nullptr;
  327. deviceType->scanForDevices();
  328. ScopedPointer<AudioIODevice> device(deviceType->createDevice(deviceName, deviceName));
  329. if (device == nullptr)
  330. return nullptr;
  331. static EngineDriverDeviceInfo devInfo = { 0x0, nullptr, nullptr };
  332. static uint32_t dummyBufferSizes[11] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 0 };
  333. static double dummySampleRates[14] = { 22050.0, 32000.0, 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0, 0.0 };
  334. // reset
  335. devInfo.hints = ENGINE_DRIVER_DEVICE_VARIABLE_BUFFER_SIZE | ENGINE_DRIVER_DEVICE_VARIABLE_SAMPLE_RATE;
  336. // cleanup
  337. if (devInfo.bufferSizes != nullptr && devInfo.bufferSizes != dummyBufferSizes)
  338. {
  339. delete[] devInfo.bufferSizes;
  340. devInfo.bufferSizes = nullptr;
  341. }
  342. if (devInfo.sampleRates != nullptr && devInfo.sampleRates != dummySampleRates)
  343. {
  344. delete[] devInfo.sampleRates;
  345. devInfo.sampleRates = nullptr;
  346. }
  347. if (device->hasControlPanel())
  348. devInfo.hints |= ENGINE_DRIVER_DEVICE_HAS_CONTROL_PANEL;
  349. Array<int> juceBufferSizes = device->getAvailableBufferSizes();
  350. if (int bufferSizesCount = juceBufferSizes.size())
  351. {
  352. uint32_t* const bufferSizes(new uint32_t[bufferSizesCount+1]);
  353. for (int i=0; i < bufferSizesCount; ++i)
  354. bufferSizes[i] = static_cast<uint32_t>(juceBufferSizes[i]);
  355. bufferSizes[bufferSizesCount] = 0;
  356. devInfo.bufferSizes = bufferSizes;
  357. }
  358. else
  359. {
  360. devInfo.bufferSizes = dummyBufferSizes;
  361. }
  362. Array<double> juceSampleRates = device->getAvailableSampleRates();
  363. if (int sampleRatesCount = juceSampleRates.size())
  364. {
  365. double* const sampleRates(new double[sampleRatesCount+1]);
  366. for (int i=0; i < sampleRatesCount; ++i)
  367. sampleRates[i] = juceSampleRates[i];
  368. sampleRates[sampleRatesCount] = 0.0;
  369. devInfo.sampleRates = sampleRates;
  370. }
  371. else
  372. {
  373. devInfo.sampleRates = dummySampleRates;
  374. }
  375. return &devInfo;
  376. }
  377. // -----------------------------------------
  378. CARLA_BACKEND_END_NAMESPACE