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.

511 lines
14KB

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