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.

CarlaEngineJuce.cpp 13KB

10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  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