The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

969 lines
33KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. AudioDeviceManager::AudioDeviceSetup::AudioDeviceSetup()
  18. : sampleRate (0),
  19. bufferSize (0),
  20. useDefaultInputChannels (true),
  21. useDefaultOutputChannels (true)
  22. {
  23. }
  24. bool AudioDeviceManager::AudioDeviceSetup::operator== (const AudioDeviceManager::AudioDeviceSetup& other) const
  25. {
  26. return outputDeviceName == other.outputDeviceName
  27. && inputDeviceName == other.inputDeviceName
  28. && sampleRate == other.sampleRate
  29. && bufferSize == other.bufferSize
  30. && inputChannels == other.inputChannels
  31. && useDefaultInputChannels == other.useDefaultInputChannels
  32. && outputChannels == other.outputChannels
  33. && useDefaultOutputChannels == other.useDefaultOutputChannels;
  34. }
  35. //==============================================================================
  36. class AudioDeviceManager::CallbackHandler : public AudioIODeviceCallback,
  37. public MidiInputCallback,
  38. public AudioIODeviceType::Listener
  39. {
  40. public:
  41. CallbackHandler (AudioDeviceManager& adm) noexcept : owner (adm) {}
  42. private:
  43. void audioDeviceIOCallback (const float** ins, int numIns, float** outs, int numOuts, int numSamples)
  44. {
  45. owner.audioDeviceIOCallbackInt (ins, numIns, outs, numOuts, numSamples);
  46. }
  47. void audioDeviceAboutToStart (AudioIODevice* device)
  48. {
  49. owner.audioDeviceAboutToStartInt (device);
  50. }
  51. void audioDeviceStopped()
  52. {
  53. owner.audioDeviceStoppedInt();
  54. }
  55. void audioDeviceError (const String& message)
  56. {
  57. owner.audioDeviceErrorInt (message);
  58. }
  59. void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message)
  60. {
  61. owner.handleIncomingMidiMessageInt (source, message);
  62. }
  63. void audioDeviceListChanged()
  64. {
  65. owner.audioDeviceListChanged();
  66. }
  67. AudioDeviceManager& owner;
  68. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CallbackHandler)
  69. };
  70. //==============================================================================
  71. AudioDeviceManager::AudioDeviceManager()
  72. : numInputChansNeeded (0),
  73. numOutputChansNeeded (2),
  74. listNeedsScanning (true),
  75. useInputNames (false),
  76. inputLevel (0),
  77. tempBuffer (2, 2),
  78. cpuUsageMs (0),
  79. timeToCpuScale (0)
  80. {
  81. callbackHandler = new CallbackHandler (*this);
  82. }
  83. AudioDeviceManager::~AudioDeviceManager()
  84. {
  85. currentAudioDevice = nullptr;
  86. defaultMidiOutput = nullptr;
  87. }
  88. //==============================================================================
  89. void AudioDeviceManager::createDeviceTypesIfNeeded()
  90. {
  91. if (availableDeviceTypes.size() == 0)
  92. {
  93. OwnedArray <AudioIODeviceType> types;
  94. createAudioDeviceTypes (types);
  95. for (int i = 0; i < types.size(); ++i)
  96. addAudioDeviceType (types.getUnchecked(i));
  97. types.clear (false);
  98. if (AudioIODeviceType* first = availableDeviceTypes.getFirst())
  99. currentDeviceType = first->getTypeName();
  100. }
  101. }
  102. const OwnedArray <AudioIODeviceType>& AudioDeviceManager::getAvailableDeviceTypes()
  103. {
  104. scanDevicesIfNeeded();
  105. return availableDeviceTypes;
  106. }
  107. void AudioDeviceManager::audioDeviceListChanged()
  108. {
  109. if (currentAudioDevice != nullptr)
  110. {
  111. currentSetup.sampleRate = currentAudioDevice->getCurrentSampleRate();
  112. currentSetup.bufferSize = currentAudioDevice->getCurrentBufferSizeSamples();
  113. currentSetup.inputChannels = currentAudioDevice->getActiveInputChannels();
  114. currentSetup.outputChannels = currentAudioDevice->getActiveOutputChannels();
  115. }
  116. sendChangeMessage();
  117. }
  118. //==============================================================================
  119. static void addIfNotNull (OwnedArray <AudioIODeviceType>& list, AudioIODeviceType* const device)
  120. {
  121. if (device != nullptr)
  122. list.add (device);
  123. }
  124. void AudioDeviceManager::createAudioDeviceTypes (OwnedArray <AudioIODeviceType>& list)
  125. {
  126. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI());
  127. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_DirectSound());
  128. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ASIO());
  129. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_CoreAudio());
  130. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_iOSAudio());
  131. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ALSA());
  132. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_JACK());
  133. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_OpenSLES());
  134. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Android());
  135. }
  136. void AudioDeviceManager::addAudioDeviceType (AudioIODeviceType* newDeviceType)
  137. {
  138. if (newDeviceType != nullptr)
  139. {
  140. jassert (lastDeviceTypeConfigs.size() == availableDeviceTypes.size());
  141. availableDeviceTypes.add (newDeviceType);
  142. lastDeviceTypeConfigs.add (new AudioDeviceSetup());
  143. newDeviceType->addListener (callbackHandler);
  144. }
  145. }
  146. //==============================================================================
  147. String AudioDeviceManager::initialise (const int numInputChannelsNeeded,
  148. const int numOutputChannelsNeeded,
  149. const XmlElement* const e,
  150. const bool selectDefaultDeviceOnFailure,
  151. const String& preferredDefaultDeviceName,
  152. const AudioDeviceSetup* preferredSetupOptions)
  153. {
  154. scanDevicesIfNeeded();
  155. numInputChansNeeded = numInputChannelsNeeded;
  156. numOutputChansNeeded = numOutputChannelsNeeded;
  157. if (e != nullptr && e->hasTagName ("DEVICESETUP"))
  158. {
  159. lastExplicitSettings = new XmlElement (*e);
  160. String error;
  161. AudioDeviceSetup setup;
  162. if (preferredSetupOptions != nullptr)
  163. setup = *preferredSetupOptions;
  164. if (e->getStringAttribute ("audioDeviceName").isNotEmpty())
  165. {
  166. setup.inputDeviceName = setup.outputDeviceName
  167. = e->getStringAttribute ("audioDeviceName");
  168. }
  169. else
  170. {
  171. setup.inputDeviceName = e->getStringAttribute ("audioInputDeviceName");
  172. setup.outputDeviceName = e->getStringAttribute ("audioOutputDeviceName");
  173. }
  174. currentDeviceType = e->getStringAttribute ("deviceType");
  175. if (findType (currentDeviceType) == nullptr)
  176. {
  177. if (AudioIODeviceType* const type = findType (setup.inputDeviceName, setup.outputDeviceName))
  178. currentDeviceType = type->getTypeName();
  179. else if (availableDeviceTypes.size() > 0)
  180. currentDeviceType = availableDeviceTypes.getUnchecked(0)->getTypeName();
  181. }
  182. setup.bufferSize = e->getIntAttribute ("audioDeviceBufferSize");
  183. setup.sampleRate = e->getDoubleAttribute ("audioDeviceRate");
  184. setup.inputChannels .parseString (e->getStringAttribute ("audioDeviceInChans", "11"), 2);
  185. setup.outputChannels.parseString (e->getStringAttribute ("audioDeviceOutChans", "11"), 2);
  186. setup.useDefaultInputChannels = ! e->hasAttribute ("audioDeviceInChans");
  187. setup.useDefaultOutputChannels = ! e->hasAttribute ("audioDeviceOutChans");
  188. error = setAudioDeviceSetup (setup, true);
  189. midiInsFromXml.clear();
  190. forEachXmlChildElementWithTagName (*e, c, "MIDIINPUT")
  191. midiInsFromXml.add (c->getStringAttribute ("name"));
  192. const StringArray allMidiIns (MidiInput::getDevices());
  193. for (int i = allMidiIns.size(); --i >= 0;)
  194. setMidiInputEnabled (allMidiIns[i], midiInsFromXml.contains (allMidiIns[i]));
  195. if (error.isNotEmpty() && selectDefaultDeviceOnFailure)
  196. error = initialise (numInputChannelsNeeded, numOutputChannelsNeeded, 0,
  197. false, preferredDefaultDeviceName);
  198. setDefaultMidiOutput (e->getStringAttribute ("defaultMidiOutput"));
  199. return error;
  200. }
  201. else
  202. {
  203. AudioDeviceSetup setup;
  204. if (preferredSetupOptions != nullptr)
  205. {
  206. setup = *preferredSetupOptions;
  207. }
  208. else if (preferredDefaultDeviceName.isNotEmpty())
  209. {
  210. for (int j = availableDeviceTypes.size(); --j >= 0;)
  211. {
  212. AudioIODeviceType* const type = availableDeviceTypes.getUnchecked(j);
  213. const StringArray outs (type->getDeviceNames (false));
  214. for (int i = 0; i < outs.size(); ++i)
  215. {
  216. if (outs[i].matchesWildcard (preferredDefaultDeviceName, true))
  217. {
  218. setup.outputDeviceName = outs[i];
  219. break;
  220. }
  221. }
  222. const StringArray ins (type->getDeviceNames (true));
  223. for (int i = 0; i < ins.size(); ++i)
  224. {
  225. if (ins[i].matchesWildcard (preferredDefaultDeviceName, true))
  226. {
  227. setup.inputDeviceName = ins[i];
  228. break;
  229. }
  230. }
  231. }
  232. }
  233. insertDefaultDeviceNames (setup);
  234. return setAudioDeviceSetup (setup, false);
  235. }
  236. }
  237. void AudioDeviceManager::insertDefaultDeviceNames (AudioDeviceSetup& setup) const
  238. {
  239. if (AudioIODeviceType* type = getCurrentDeviceTypeObject())
  240. {
  241. if (setup.outputDeviceName.isEmpty())
  242. setup.outputDeviceName = type->getDeviceNames (false) [type->getDefaultDeviceIndex (false)];
  243. if (setup.inputDeviceName.isEmpty())
  244. setup.inputDeviceName = type->getDeviceNames (true) [type->getDefaultDeviceIndex (true)];
  245. }
  246. }
  247. XmlElement* AudioDeviceManager::createStateXml() const
  248. {
  249. return lastExplicitSettings.createCopy();
  250. }
  251. //==============================================================================
  252. void AudioDeviceManager::scanDevicesIfNeeded()
  253. {
  254. if (listNeedsScanning)
  255. {
  256. listNeedsScanning = false;
  257. createDeviceTypesIfNeeded();
  258. for (int i = availableDeviceTypes.size(); --i >= 0;)
  259. availableDeviceTypes.getUnchecked(i)->scanForDevices();
  260. }
  261. }
  262. AudioIODeviceType* AudioDeviceManager::findType (const String& typeName)
  263. {
  264. scanDevicesIfNeeded();
  265. for (int i = availableDeviceTypes.size(); --i >= 0;)
  266. if (availableDeviceTypes.getUnchecked(i)->getTypeName() == typeName)
  267. return availableDeviceTypes.getUnchecked(i);
  268. return nullptr;
  269. }
  270. AudioIODeviceType* AudioDeviceManager::findType (const String& inputName, const String& outputName)
  271. {
  272. scanDevicesIfNeeded();
  273. for (int i = availableDeviceTypes.size(); --i >= 0;)
  274. {
  275. AudioIODeviceType* const type = availableDeviceTypes.getUnchecked(i);
  276. if ((inputName.isNotEmpty() && type->getDeviceNames (true).contains (inputName, true))
  277. || (outputName.isNotEmpty() && type->getDeviceNames (false).contains (outputName, true)))
  278. {
  279. return type;
  280. }
  281. }
  282. return nullptr;
  283. }
  284. void AudioDeviceManager::getAudioDeviceSetup (AudioDeviceSetup& setup)
  285. {
  286. setup = currentSetup;
  287. }
  288. void AudioDeviceManager::deleteCurrentDevice()
  289. {
  290. currentAudioDevice = nullptr;
  291. currentSetup.inputDeviceName = String::empty;
  292. currentSetup.outputDeviceName = String::empty;
  293. }
  294. void AudioDeviceManager::setCurrentAudioDeviceType (const String& type,
  295. const bool treatAsChosenDevice)
  296. {
  297. for (int i = 0; i < availableDeviceTypes.size(); ++i)
  298. {
  299. if (availableDeviceTypes.getUnchecked(i)->getTypeName() == type
  300. && currentDeviceType != type)
  301. {
  302. if (currentAudioDevice != nullptr)
  303. {
  304. closeAudioDevice();
  305. Thread::sleep (1500); // allow a moment for OS devices to sort themselves out, to help
  306. // avoid things like DirectSound/ASIO clashes
  307. }
  308. currentDeviceType = type;
  309. AudioDeviceSetup s (*lastDeviceTypeConfigs.getUnchecked(i));
  310. insertDefaultDeviceNames (s);
  311. setAudioDeviceSetup (s, treatAsChosenDevice);
  312. sendChangeMessage();
  313. break;
  314. }
  315. }
  316. }
  317. AudioIODeviceType* AudioDeviceManager::getCurrentDeviceTypeObject() const
  318. {
  319. for (int i = 0; i < availableDeviceTypes.size(); ++i)
  320. if (availableDeviceTypes.getUnchecked(i)->getTypeName() == currentDeviceType)
  321. return availableDeviceTypes.getUnchecked(i);
  322. return availableDeviceTypes[0];
  323. }
  324. String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& newSetup,
  325. const bool treatAsChosenDevice)
  326. {
  327. jassert (&newSetup != &currentSetup); // this will have no effect
  328. if (newSetup == currentSetup && currentAudioDevice != nullptr)
  329. return String::empty;
  330. if (! (newSetup == currentSetup))
  331. sendChangeMessage();
  332. stopDevice();
  333. const String newInputDeviceName (numInputChansNeeded == 0 ? String::empty : newSetup.inputDeviceName);
  334. const String newOutputDeviceName (numOutputChansNeeded == 0 ? String::empty : newSetup.outputDeviceName);
  335. String error;
  336. AudioIODeviceType* type = getCurrentDeviceTypeObject();
  337. if (type == nullptr || (newInputDeviceName.isEmpty() && newOutputDeviceName.isEmpty()))
  338. {
  339. deleteCurrentDevice();
  340. if (treatAsChosenDevice)
  341. updateXml();
  342. return String::empty;
  343. }
  344. if (currentSetup.inputDeviceName != newInputDeviceName
  345. || currentSetup.outputDeviceName != newOutputDeviceName
  346. || currentAudioDevice == nullptr)
  347. {
  348. deleteCurrentDevice();
  349. scanDevicesIfNeeded();
  350. if (newOutputDeviceName.isNotEmpty()
  351. && ! type->getDeviceNames (false).contains (newOutputDeviceName))
  352. {
  353. return "No such device: " + newOutputDeviceName;
  354. }
  355. if (newInputDeviceName.isNotEmpty()
  356. && ! type->getDeviceNames (true).contains (newInputDeviceName))
  357. {
  358. return "No such device: " + newInputDeviceName;
  359. }
  360. currentAudioDevice = type->createDevice (newOutputDeviceName, newInputDeviceName);
  361. if (currentAudioDevice == nullptr)
  362. error = "Can't open the audio device!\n\n"
  363. "This may be because another application is currently using the same device - "
  364. "if so, you should close any other applications and try again!";
  365. else
  366. error = currentAudioDevice->getLastError();
  367. if (error.isNotEmpty())
  368. {
  369. deleteCurrentDevice();
  370. return error;
  371. }
  372. if (newSetup.useDefaultInputChannels)
  373. {
  374. inputChannels.clear();
  375. inputChannels.setRange (0, numInputChansNeeded, true);
  376. }
  377. if (newSetup.useDefaultOutputChannels)
  378. {
  379. outputChannels.clear();
  380. outputChannels.setRange (0, numOutputChansNeeded, true);
  381. }
  382. if (newInputDeviceName.isEmpty()) inputChannels.clear();
  383. if (newOutputDeviceName.isEmpty()) outputChannels.clear();
  384. }
  385. if (! newSetup.useDefaultInputChannels) inputChannels = newSetup.inputChannels;
  386. if (! newSetup.useDefaultOutputChannels) outputChannels = newSetup.outputChannels;
  387. currentSetup = newSetup;
  388. currentSetup.sampleRate = chooseBestSampleRate (newSetup.sampleRate);
  389. currentSetup.bufferSize = chooseBestBufferSize (newSetup.bufferSize);
  390. error = currentAudioDevice->open (inputChannels,
  391. outputChannels,
  392. currentSetup.sampleRate,
  393. currentSetup.bufferSize);
  394. if (error.isEmpty())
  395. {
  396. currentDeviceType = currentAudioDevice->getTypeName();
  397. currentAudioDevice->start (callbackHandler);
  398. currentSetup.sampleRate = currentAudioDevice->getCurrentSampleRate();
  399. currentSetup.bufferSize = currentAudioDevice->getCurrentBufferSizeSamples();
  400. currentSetup.inputChannels = currentAudioDevice->getActiveInputChannels();
  401. currentSetup.outputChannels = currentAudioDevice->getActiveOutputChannels();
  402. for (int i = 0; i < availableDeviceTypes.size(); ++i)
  403. if (availableDeviceTypes.getUnchecked (i)->getTypeName() == currentDeviceType)
  404. *(lastDeviceTypeConfigs.getUnchecked (i)) = currentSetup;
  405. if (treatAsChosenDevice)
  406. updateXml();
  407. }
  408. else
  409. {
  410. deleteCurrentDevice();
  411. }
  412. return error;
  413. }
  414. double AudioDeviceManager::chooseBestSampleRate (double rate) const
  415. {
  416. jassert (currentAudioDevice != nullptr);
  417. if (rate > 0)
  418. for (int i = currentAudioDevice->getNumSampleRates(); --i >= 0;)
  419. if (currentAudioDevice->getSampleRate (i) == rate)
  420. return rate;
  421. double lowestAbove44 = 0.0;
  422. for (int i = currentAudioDevice->getNumSampleRates(); --i >= 0;)
  423. {
  424. const double sr = currentAudioDevice->getSampleRate (i);
  425. if (sr >= 44100.0 && (lowestAbove44 < 1.0 || sr < lowestAbove44))
  426. lowestAbove44 = sr;
  427. }
  428. if (lowestAbove44 > 0.0)
  429. return lowestAbove44;
  430. return currentAudioDevice->getSampleRate (0);
  431. }
  432. int AudioDeviceManager::chooseBestBufferSize (int bufferSize) const
  433. {
  434. jassert (currentAudioDevice != nullptr);
  435. if (bufferSize > 0)
  436. for (int i = currentAudioDevice->getNumBufferSizesAvailable(); --i >= 0;)
  437. if (currentAudioDevice->getBufferSizeSamples(i) == bufferSize)
  438. return bufferSize;
  439. return currentAudioDevice->getDefaultBufferSize();
  440. }
  441. void AudioDeviceManager::stopDevice()
  442. {
  443. if (currentAudioDevice != nullptr)
  444. currentAudioDevice->stop();
  445. testSound = nullptr;
  446. }
  447. void AudioDeviceManager::closeAudioDevice()
  448. {
  449. stopDevice();
  450. currentAudioDevice = nullptr;
  451. }
  452. void AudioDeviceManager::restartLastAudioDevice()
  453. {
  454. if (currentAudioDevice == nullptr)
  455. {
  456. if (currentSetup.inputDeviceName.isEmpty()
  457. && currentSetup.outputDeviceName.isEmpty())
  458. {
  459. // This method will only reload the last device that was running
  460. // before closeAudioDevice() was called - you need to actually open
  461. // one first, with setAudioDevice().
  462. jassertfalse;
  463. return;
  464. }
  465. AudioDeviceSetup s (currentSetup);
  466. setAudioDeviceSetup (s, false);
  467. }
  468. }
  469. void AudioDeviceManager::updateXml()
  470. {
  471. lastExplicitSettings = new XmlElement ("DEVICESETUP");
  472. lastExplicitSettings->setAttribute ("deviceType", currentDeviceType);
  473. lastExplicitSettings->setAttribute ("audioOutputDeviceName", currentSetup.outputDeviceName);
  474. lastExplicitSettings->setAttribute ("audioInputDeviceName", currentSetup.inputDeviceName);
  475. if (currentAudioDevice != nullptr)
  476. {
  477. lastExplicitSettings->setAttribute ("audioDeviceRate", currentAudioDevice->getCurrentSampleRate());
  478. if (currentAudioDevice->getDefaultBufferSize() != currentAudioDevice->getCurrentBufferSizeSamples())
  479. lastExplicitSettings->setAttribute ("audioDeviceBufferSize", currentAudioDevice->getCurrentBufferSizeSamples());
  480. if (! currentSetup.useDefaultInputChannels)
  481. lastExplicitSettings->setAttribute ("audioDeviceInChans", currentSetup.inputChannels.toString (2));
  482. if (! currentSetup.useDefaultOutputChannels)
  483. lastExplicitSettings->setAttribute ("audioDeviceOutChans", currentSetup.outputChannels.toString (2));
  484. }
  485. for (int i = 0; i < enabledMidiInputs.size(); ++i)
  486. lastExplicitSettings->createNewChildElement ("MIDIINPUT")
  487. ->setAttribute ("name", enabledMidiInputs[i]->getName());
  488. if (midiInsFromXml.size() > 0)
  489. {
  490. // Add any midi devices that have been enabled before, but which aren't currently
  491. // open because the device has been disconnected.
  492. const StringArray availableMidiDevices (MidiInput::getDevices());
  493. for (int i = 0; i < midiInsFromXml.size(); ++i)
  494. if (! availableMidiDevices.contains (midiInsFromXml[i], true))
  495. lastExplicitSettings->createNewChildElement ("MIDIINPUT")
  496. ->setAttribute ("name", midiInsFromXml[i]);
  497. }
  498. if (defaultMidiOutputName.isNotEmpty())
  499. lastExplicitSettings->setAttribute ("defaultMidiOutput", defaultMidiOutputName);
  500. }
  501. //==============================================================================
  502. void AudioDeviceManager::addAudioCallback (AudioIODeviceCallback* newCallback)
  503. {
  504. {
  505. const ScopedLock sl (audioCallbackLock);
  506. if (callbacks.contains (newCallback))
  507. return;
  508. }
  509. if (currentAudioDevice != nullptr && newCallback != nullptr)
  510. newCallback->audioDeviceAboutToStart (currentAudioDevice);
  511. const ScopedLock sl (audioCallbackLock);
  512. callbacks.add (newCallback);
  513. }
  514. void AudioDeviceManager::removeAudioCallback (AudioIODeviceCallback* callbackToRemove)
  515. {
  516. if (callbackToRemove != nullptr)
  517. {
  518. bool needsDeinitialising = currentAudioDevice != nullptr;
  519. {
  520. const ScopedLock sl (audioCallbackLock);
  521. needsDeinitialising = needsDeinitialising && callbacks.contains (callbackToRemove);
  522. callbacks.removeFirstMatchingValue (callbackToRemove);
  523. }
  524. if (needsDeinitialising)
  525. callbackToRemove->audioDeviceStopped();
  526. }
  527. }
  528. void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelData,
  529. int numInputChannels,
  530. float** outputChannelData,
  531. int numOutputChannels,
  532. int numSamples)
  533. {
  534. const ScopedLock sl (audioCallbackLock);
  535. if (inputLevelMeasurementEnabledCount.get() > 0 && numInputChannels > 0)
  536. {
  537. for (int j = 0; j < numSamples; ++j)
  538. {
  539. float s = 0;
  540. for (int i = 0; i < numInputChannels; ++i)
  541. s += std::abs (inputChannelData[i][j]);
  542. s /= numInputChannels;
  543. const double decayFactor = 0.99992;
  544. if (s > inputLevel)
  545. inputLevel = s;
  546. else if (inputLevel > 0.001f)
  547. inputLevel *= decayFactor;
  548. else
  549. inputLevel = 0;
  550. }
  551. }
  552. else
  553. {
  554. inputLevel = 0;
  555. }
  556. if (callbacks.size() > 0)
  557. {
  558. const double callbackStartTime = Time::getMillisecondCounterHiRes();
  559. tempBuffer.setSize (jmax (1, numOutputChannels), jmax (1, numSamples), false, false, true);
  560. callbacks.getUnchecked(0)->audioDeviceIOCallback (inputChannelData, numInputChannels,
  561. outputChannelData, numOutputChannels, numSamples);
  562. float** const tempChans = tempBuffer.getArrayOfChannels();
  563. for (int i = callbacks.size(); --i > 0;)
  564. {
  565. callbacks.getUnchecked(i)->audioDeviceIOCallback (inputChannelData, numInputChannels,
  566. tempChans, numOutputChannels, numSamples);
  567. for (int chan = 0; chan < numOutputChannels; ++chan)
  568. {
  569. if (const float* const src = tempChans [chan])
  570. if (float* const dst = outputChannelData [chan])
  571. for (int j = 0; j < numSamples; ++j)
  572. dst[j] += src[j];
  573. }
  574. }
  575. const double msTaken = Time::getMillisecondCounterHiRes() - callbackStartTime;
  576. const double filterAmount = 0.2;
  577. cpuUsageMs += filterAmount * (msTaken - cpuUsageMs);
  578. }
  579. else
  580. {
  581. for (int i = 0; i < numOutputChannels; ++i)
  582. zeromem (outputChannelData[i], sizeof (float) * (size_t) numSamples);
  583. }
  584. if (testSound != nullptr)
  585. {
  586. const int numSamps = jmin (numSamples, testSound->getNumSamples() - testSoundPosition);
  587. const float* const src = testSound->getSampleData (0, testSoundPosition);
  588. for (int i = 0; i < numOutputChannels; ++i)
  589. for (int j = 0; j < numSamps; ++j)
  590. outputChannelData [i][j] += src[j];
  591. testSoundPosition += numSamps;
  592. if (testSoundPosition >= testSound->getNumSamples())
  593. testSound = nullptr;
  594. }
  595. }
  596. void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice* const device)
  597. {
  598. cpuUsageMs = 0;
  599. const double sampleRate = device->getCurrentSampleRate();
  600. const int blockSize = device->getCurrentBufferSizeSamples();
  601. if (sampleRate > 0.0 && blockSize > 0)
  602. {
  603. const double msPerBlock = 1000.0 * blockSize / sampleRate;
  604. timeToCpuScale = (msPerBlock > 0.0) ? (1.0 / msPerBlock) : 0.0;
  605. }
  606. {
  607. const ScopedLock sl (audioCallbackLock);
  608. for (int i = callbacks.size(); --i >= 0;)
  609. callbacks.getUnchecked(i)->audioDeviceAboutToStart (device);
  610. }
  611. sendChangeMessage();
  612. }
  613. void AudioDeviceManager::audioDeviceStoppedInt()
  614. {
  615. cpuUsageMs = 0;
  616. timeToCpuScale = 0;
  617. sendChangeMessage();
  618. const ScopedLock sl (audioCallbackLock);
  619. for (int i = callbacks.size(); --i >= 0;)
  620. callbacks.getUnchecked(i)->audioDeviceStopped();
  621. }
  622. void AudioDeviceManager::audioDeviceErrorInt (const String& message)
  623. {
  624. const ScopedLock sl (audioCallbackLock);
  625. for (int i = callbacks.size(); --i >= 0;)
  626. callbacks.getUnchecked(i)->audioDeviceError (message);
  627. }
  628. double AudioDeviceManager::getCpuUsage() const
  629. {
  630. return jlimit (0.0, 1.0, timeToCpuScale * cpuUsageMs);
  631. }
  632. //==============================================================================
  633. void AudioDeviceManager::setMidiInputEnabled (const String& name, const bool enabled)
  634. {
  635. if (enabled != isMidiInputEnabled (name))
  636. {
  637. if (enabled)
  638. {
  639. const int index = MidiInput::getDevices().indexOf (name);
  640. if (index >= 0)
  641. {
  642. if (MidiInput* const midiIn = MidiInput::openDevice (index, callbackHandler))
  643. {
  644. enabledMidiInputs.add (midiIn);
  645. midiIn->start();
  646. }
  647. }
  648. }
  649. else
  650. {
  651. for (int i = enabledMidiInputs.size(); --i >= 0;)
  652. if (enabledMidiInputs[i]->getName() == name)
  653. enabledMidiInputs.remove (i);
  654. }
  655. updateXml();
  656. sendChangeMessage();
  657. }
  658. }
  659. bool AudioDeviceManager::isMidiInputEnabled (const String& name) const
  660. {
  661. for (int i = enabledMidiInputs.size(); --i >= 0;)
  662. if (enabledMidiInputs[i]->getName() == name)
  663. return true;
  664. return false;
  665. }
  666. void AudioDeviceManager::addMidiInputCallback (const String& name, MidiInputCallback* callbackToAdd)
  667. {
  668. removeMidiInputCallback (name, callbackToAdd);
  669. if (name.isEmpty() || isMidiInputEnabled (name))
  670. {
  671. const ScopedLock sl (midiCallbackLock);
  672. midiCallbacks.add (callbackToAdd);
  673. midiCallbackDevices.add (name);
  674. }
  675. }
  676. void AudioDeviceManager::removeMidiInputCallback (const String& name, MidiInputCallback* callbackToRemove)
  677. {
  678. for (int i = midiCallbacks.size(); --i >= 0;)
  679. {
  680. if (midiCallbackDevices[i] == name && midiCallbacks.getUnchecked(i) == callbackToRemove)
  681. {
  682. const ScopedLock sl (midiCallbackLock);
  683. midiCallbacks.remove (i);
  684. midiCallbackDevices.remove (i);
  685. }
  686. }
  687. }
  688. void AudioDeviceManager::handleIncomingMidiMessageInt (MidiInput* source, const MidiMessage& message)
  689. {
  690. if (! message.isActiveSense())
  691. {
  692. const bool isDefaultSource = (source == nullptr || source == enabledMidiInputs.getFirst());
  693. const ScopedLock sl (midiCallbackLock);
  694. for (int i = midiCallbackDevices.size(); --i >= 0;)
  695. {
  696. const String name (midiCallbackDevices[i]);
  697. if ((isDefaultSource && name.isEmpty()) || (name.isNotEmpty() && name == source->getName()))
  698. midiCallbacks.getUnchecked(i)->handleIncomingMidiMessage (source, message);
  699. }
  700. }
  701. }
  702. //==============================================================================
  703. void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName)
  704. {
  705. if (defaultMidiOutputName != deviceName)
  706. {
  707. Array <AudioIODeviceCallback*> oldCallbacks;
  708. {
  709. const ScopedLock sl (audioCallbackLock);
  710. oldCallbacks = callbacks;
  711. callbacks.clear();
  712. }
  713. if (currentAudioDevice != nullptr)
  714. for (int i = oldCallbacks.size(); --i >= 0;)
  715. oldCallbacks.getUnchecked(i)->audioDeviceStopped();
  716. defaultMidiOutput = nullptr;
  717. defaultMidiOutputName = deviceName;
  718. if (deviceName.isNotEmpty())
  719. defaultMidiOutput = MidiOutput::openDevice (MidiOutput::getDevices().indexOf (deviceName));
  720. if (currentAudioDevice != nullptr)
  721. for (int i = oldCallbacks.size(); --i >= 0;)
  722. oldCallbacks.getUnchecked(i)->audioDeviceAboutToStart (currentAudioDevice);
  723. {
  724. const ScopedLock sl (audioCallbackLock);
  725. callbacks = oldCallbacks;
  726. }
  727. updateXml();
  728. sendChangeMessage();
  729. }
  730. }
  731. //==============================================================================
  732. void AudioDeviceManager::playTestSound()
  733. {
  734. { // cunningly nested to swap, unlock and delete in that order.
  735. ScopedPointer <AudioSampleBuffer> oldSound;
  736. {
  737. const ScopedLock sl (audioCallbackLock);
  738. oldSound = testSound;
  739. }
  740. }
  741. testSoundPosition = 0;
  742. if (currentAudioDevice != nullptr)
  743. {
  744. const double sampleRate = currentAudioDevice->getCurrentSampleRate();
  745. const int soundLength = (int) sampleRate;
  746. AudioSampleBuffer* const newSound = new AudioSampleBuffer (1, soundLength);
  747. float* samples = newSound->getSampleData (0);
  748. const double frequency = 440.0;
  749. const float amplitude = 0.5f;
  750. const double phasePerSample = double_Pi * 2.0 / (sampleRate / frequency);
  751. for (int i = 0; i < soundLength; ++i)
  752. samples[i] = amplitude * (float) std::sin (i * phasePerSample);
  753. newSound->applyGainRamp (0, 0, soundLength / 10, 0.0f, 1.0f);
  754. newSound->applyGainRamp (0, soundLength - soundLength / 4, soundLength / 4, 1.0f, 0.0f);
  755. const ScopedLock sl (audioCallbackLock);
  756. testSound = newSound;
  757. }
  758. }
  759. void AudioDeviceManager::enableInputLevelMeasurement (const bool enableMeasurement)
  760. {
  761. if (enableMeasurement)
  762. ++inputLevelMeasurementEnabledCount;
  763. else
  764. --inputLevelMeasurementEnabledCount;
  765. inputLevel = 0;
  766. }
  767. double AudioDeviceManager::getCurrentInputLevel() const
  768. {
  769. jassert (inputLevelMeasurementEnabledCount.get() > 0); // you need to call enableInputLevelMeasurement() before using this!
  770. return inputLevel;
  771. }