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.

1168 lines
40KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI 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) override
  44. {
  45. owner.audioDeviceIOCallbackInt (ins, numIns, outs, numOuts, numSamples);
  46. }
  47. void audioDeviceAboutToStart (AudioIODevice* device) override
  48. {
  49. owner.audioDeviceAboutToStartInt (device);
  50. }
  51. void audioDeviceStopped() override
  52. {
  53. owner.audioDeviceStoppedInt();
  54. }
  55. void audioDeviceError (const String& message) override
  56. {
  57. owner.audioDeviceErrorInt (message);
  58. }
  59. void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message) override
  60. {
  61. owner.handleIncomingMidiMessageInt (source, message);
  62. }
  63. void audioDeviceListChanged() override
  64. {
  65. owner.audioDeviceListChanged();
  66. }
  67. AudioDeviceManager& owner;
  68. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CallbackHandler)
  69. };
  70. //==============================================================================
  71. // This is an AudioTransportSource which will own it's assigned source
  72. struct AudioSourceOwningTransportSource : public AudioTransportSource
  73. {
  74. AudioSourceOwningTransportSource (PositionableAudioSource* s) : source (s)
  75. {
  76. AudioTransportSource::setSource (s);
  77. }
  78. ~AudioSourceOwningTransportSource()
  79. {
  80. setSource (nullptr);
  81. }
  82. private:
  83. ScopedPointer<PositionableAudioSource> source;
  84. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioSourceOwningTransportSource)
  85. };
  86. //==============================================================================
  87. // An AudioSourcePlayer which will remove itself from the AudioDeviceManager's
  88. // callback list once it finishes playing its source
  89. struct AutoRemovingSourcePlayer : public AudioSourcePlayer,
  90. private Timer
  91. {
  92. AutoRemovingSourcePlayer (AudioDeviceManager& dm, AudioTransportSource* ts, bool ownSource)
  93. : manager (dm), transportSource (ts, ownSource)
  94. {
  95. jassert (ts != nullptr);
  96. manager.addAudioCallback (this);
  97. AudioSourcePlayer::setSource (transportSource);
  98. startTimerHz (10);
  99. }
  100. ~AutoRemovingSourcePlayer()
  101. {
  102. setSource (nullptr);
  103. manager.removeAudioCallback (this);
  104. }
  105. void timerCallback() override
  106. {
  107. if (getCurrentSource() == nullptr || ! transportSource->isPlaying())
  108. delete this;
  109. }
  110. void audioDeviceStopped() override
  111. {
  112. AudioSourcePlayer::audioDeviceStopped();
  113. setSource (nullptr);
  114. }
  115. private:
  116. AudioDeviceManager& manager;
  117. OptionalScopedPointer<AudioTransportSource> transportSource;
  118. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AutoRemovingSourcePlayer)
  119. };
  120. //==============================================================================
  121. AudioDeviceManager::AudioDeviceManager()
  122. : numInputChansNeeded (0),
  123. numOutputChansNeeded (2),
  124. listNeedsScanning (true),
  125. cpuUsageMs (0),
  126. timeToCpuScale (0)
  127. {
  128. callbackHandler = new CallbackHandler (*this);
  129. }
  130. AudioDeviceManager::~AudioDeviceManager()
  131. {
  132. currentAudioDevice = nullptr;
  133. defaultMidiOutput = nullptr;
  134. for (int i = 0; i < callbacks.size(); ++i)
  135. if (AutoRemovingSourcePlayer* p = dynamic_cast<AutoRemovingSourcePlayer*> (callbacks.getUnchecked(i)))
  136. delete p;
  137. }
  138. //==============================================================================
  139. void AudioDeviceManager::createDeviceTypesIfNeeded()
  140. {
  141. if (availableDeviceTypes.size() == 0)
  142. {
  143. OwnedArray<AudioIODeviceType> types;
  144. createAudioDeviceTypes (types);
  145. for (int i = 0; i < types.size(); ++i)
  146. addAudioDeviceType (types.getUnchecked(i));
  147. types.clear (false);
  148. if (AudioIODeviceType* first = availableDeviceTypes.getFirst())
  149. currentDeviceType = first->getTypeName();
  150. }
  151. }
  152. const OwnedArray<AudioIODeviceType>& AudioDeviceManager::getAvailableDeviceTypes()
  153. {
  154. scanDevicesIfNeeded();
  155. return availableDeviceTypes;
  156. }
  157. void AudioDeviceManager::audioDeviceListChanged()
  158. {
  159. if (currentAudioDevice != nullptr)
  160. {
  161. currentSetup.sampleRate = currentAudioDevice->getCurrentSampleRate();
  162. currentSetup.bufferSize = currentAudioDevice->getCurrentBufferSizeSamples();
  163. currentSetup.inputChannels = currentAudioDevice->getActiveInputChannels();
  164. currentSetup.outputChannels = currentAudioDevice->getActiveOutputChannels();
  165. }
  166. sendChangeMessage();
  167. }
  168. //==============================================================================
  169. static void addIfNotNull (OwnedArray<AudioIODeviceType>& list, AudioIODeviceType* const device)
  170. {
  171. if (device != nullptr)
  172. list.add (device);
  173. }
  174. void AudioDeviceManager::createAudioDeviceTypes (OwnedArray<AudioIODeviceType>& list)
  175. {
  176. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI (false));
  177. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI (true));
  178. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_DirectSound());
  179. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ASIO());
  180. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_CoreAudio());
  181. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_iOSAudio());
  182. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ALSA());
  183. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_JACK());
  184. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_OpenSLES());
  185. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Android());
  186. }
  187. void AudioDeviceManager::addAudioDeviceType (AudioIODeviceType* newDeviceType)
  188. {
  189. if (newDeviceType != nullptr)
  190. {
  191. jassert (lastDeviceTypeConfigs.size() == availableDeviceTypes.size());
  192. availableDeviceTypes.add (newDeviceType);
  193. lastDeviceTypeConfigs.add (new AudioDeviceSetup());
  194. newDeviceType->addListener (callbackHandler);
  195. }
  196. }
  197. static bool deviceListContains (AudioIODeviceType* type, bool isInput, const String& name)
  198. {
  199. StringArray devices (type->getDeviceNames (isInput));
  200. for (int i = devices.size(); --i >= 0;)
  201. if (devices[i].trim().equalsIgnoreCase (name.trim()))
  202. return true;
  203. return false;
  204. }
  205. //==============================================================================
  206. String AudioDeviceManager::initialise (const int numInputChannelsNeeded,
  207. const int numOutputChannelsNeeded,
  208. const XmlElement* const xml,
  209. const bool selectDefaultDeviceOnFailure,
  210. const String& preferredDefaultDeviceName,
  211. const AudioDeviceSetup* preferredSetupOptions)
  212. {
  213. scanDevicesIfNeeded();
  214. numInputChansNeeded = numInputChannelsNeeded;
  215. numOutputChansNeeded = numOutputChannelsNeeded;
  216. if (xml != nullptr && xml->hasTagName ("DEVICESETUP"))
  217. return initialiseFromXML (*xml, selectDefaultDeviceOnFailure,
  218. preferredDefaultDeviceName, preferredSetupOptions);
  219. return initialiseDefault (preferredDefaultDeviceName, preferredSetupOptions);
  220. }
  221. String AudioDeviceManager::initialiseDefault (const String& preferredDefaultDeviceName,
  222. const AudioDeviceSetup* preferredSetupOptions)
  223. {
  224. AudioDeviceSetup setup;
  225. if (preferredSetupOptions != nullptr)
  226. {
  227. setup = *preferredSetupOptions;
  228. }
  229. else if (preferredDefaultDeviceName.isNotEmpty())
  230. {
  231. for (int j = availableDeviceTypes.size(); --j >= 0;)
  232. {
  233. AudioIODeviceType* const type = availableDeviceTypes.getUnchecked(j);
  234. const StringArray outs (type->getDeviceNames (false));
  235. for (int i = 0; i < outs.size(); ++i)
  236. {
  237. if (outs[i].matchesWildcard (preferredDefaultDeviceName, true))
  238. {
  239. setup.outputDeviceName = outs[i];
  240. break;
  241. }
  242. }
  243. const StringArray ins (type->getDeviceNames (true));
  244. for (int i = 0; i < ins.size(); ++i)
  245. {
  246. if (ins[i].matchesWildcard (preferredDefaultDeviceName, true))
  247. {
  248. setup.inputDeviceName = ins[i];
  249. break;
  250. }
  251. }
  252. }
  253. }
  254. insertDefaultDeviceNames (setup);
  255. return setAudioDeviceSetup (setup, false);
  256. }
  257. String AudioDeviceManager::initialiseFromXML (const XmlElement& xml,
  258. const bool selectDefaultDeviceOnFailure,
  259. const String& preferredDefaultDeviceName,
  260. const AudioDeviceSetup* preferredSetupOptions)
  261. {
  262. lastExplicitSettings = new XmlElement (xml);
  263. String error;
  264. AudioDeviceSetup setup;
  265. if (preferredSetupOptions != nullptr)
  266. setup = *preferredSetupOptions;
  267. if (xml.getStringAttribute ("audioDeviceName").isNotEmpty())
  268. {
  269. setup.inputDeviceName = setup.outputDeviceName
  270. = xml.getStringAttribute ("audioDeviceName");
  271. }
  272. else
  273. {
  274. setup.inputDeviceName = xml.getStringAttribute ("audioInputDeviceName");
  275. setup.outputDeviceName = xml.getStringAttribute ("audioOutputDeviceName");
  276. }
  277. currentDeviceType = xml.getStringAttribute ("deviceType");
  278. if (findType (currentDeviceType) == nullptr)
  279. {
  280. if (AudioIODeviceType* const type = findType (setup.inputDeviceName, setup.outputDeviceName))
  281. currentDeviceType = type->getTypeName();
  282. else if (availableDeviceTypes.size() > 0)
  283. currentDeviceType = availableDeviceTypes.getUnchecked(0)->getTypeName();
  284. }
  285. setup.bufferSize = xml.getIntAttribute ("audioDeviceBufferSize", setup.bufferSize);
  286. setup.sampleRate = xml.getDoubleAttribute ("audioDeviceRate", setup.sampleRate);
  287. setup.inputChannels .parseString (xml.getStringAttribute ("audioDeviceInChans", "11"), 2);
  288. setup.outputChannels.parseString (xml.getStringAttribute ("audioDeviceOutChans", "11"), 2);
  289. setup.useDefaultInputChannels = ! xml.hasAttribute ("audioDeviceInChans");
  290. setup.useDefaultOutputChannels = ! xml.hasAttribute ("audioDeviceOutChans");
  291. error = setAudioDeviceSetup (setup, true);
  292. midiInsFromXml.clear();
  293. forEachXmlChildElementWithTagName (xml, c, "MIDIINPUT")
  294. midiInsFromXml.add (c->getStringAttribute ("name"));
  295. const StringArray allMidiIns (MidiInput::getDevices());
  296. for (int i = allMidiIns.size(); --i >= 0;)
  297. setMidiInputEnabled (allMidiIns[i], midiInsFromXml.contains (allMidiIns[i]));
  298. if (error.isNotEmpty() && selectDefaultDeviceOnFailure)
  299. error = initialise (numInputChansNeeded, numOutputChansNeeded,
  300. nullptr, false, preferredDefaultDeviceName);
  301. setDefaultMidiOutput (xml.getStringAttribute ("defaultMidiOutput"));
  302. return error;
  303. }
  304. String AudioDeviceManager::initialiseWithDefaultDevices (int numInputChannelsNeeded,
  305. int numOutputChannelsNeeded)
  306. {
  307. lastExplicitSettings = nullptr;
  308. return initialise (numInputChannelsNeeded, numOutputChannelsNeeded,
  309. nullptr, false, String(), nullptr);
  310. }
  311. void AudioDeviceManager::insertDefaultDeviceNames (AudioDeviceSetup& setup) const
  312. {
  313. if (AudioIODeviceType* type = getCurrentDeviceTypeObject())
  314. {
  315. if (setup.outputDeviceName.isEmpty())
  316. setup.outputDeviceName = type->getDeviceNames (false) [type->getDefaultDeviceIndex (false)];
  317. if (setup.inputDeviceName.isEmpty())
  318. setup.inputDeviceName = type->getDeviceNames (true) [type->getDefaultDeviceIndex (true)];
  319. }
  320. }
  321. XmlElement* AudioDeviceManager::createStateXml() const
  322. {
  323. return lastExplicitSettings.createCopy();
  324. }
  325. //==============================================================================
  326. void AudioDeviceManager::scanDevicesIfNeeded()
  327. {
  328. if (listNeedsScanning)
  329. {
  330. listNeedsScanning = false;
  331. createDeviceTypesIfNeeded();
  332. for (int i = availableDeviceTypes.size(); --i >= 0;)
  333. availableDeviceTypes.getUnchecked(i)->scanForDevices();
  334. }
  335. }
  336. AudioIODeviceType* AudioDeviceManager::findType (const String& typeName)
  337. {
  338. scanDevicesIfNeeded();
  339. for (int i = availableDeviceTypes.size(); --i >= 0;)
  340. if (availableDeviceTypes.getUnchecked(i)->getTypeName() == typeName)
  341. return availableDeviceTypes.getUnchecked(i);
  342. return nullptr;
  343. }
  344. AudioIODeviceType* AudioDeviceManager::findType (const String& inputName, const String& outputName)
  345. {
  346. scanDevicesIfNeeded();
  347. for (int i = availableDeviceTypes.size(); --i >= 0;)
  348. {
  349. AudioIODeviceType* const type = availableDeviceTypes.getUnchecked(i);
  350. if ((inputName.isNotEmpty() && deviceListContains (type, true, inputName))
  351. || (outputName.isNotEmpty() && deviceListContains (type, false, outputName)))
  352. {
  353. return type;
  354. }
  355. }
  356. return nullptr;
  357. }
  358. void AudioDeviceManager::getAudioDeviceSetup (AudioDeviceSetup& setup)
  359. {
  360. setup = currentSetup;
  361. }
  362. void AudioDeviceManager::deleteCurrentDevice()
  363. {
  364. currentAudioDevice = nullptr;
  365. currentSetup.inputDeviceName.clear();
  366. currentSetup.outputDeviceName.clear();
  367. }
  368. void AudioDeviceManager::setCurrentAudioDeviceType (const String& type,
  369. const bool treatAsChosenDevice)
  370. {
  371. for (int i = 0; i < availableDeviceTypes.size(); ++i)
  372. {
  373. if (availableDeviceTypes.getUnchecked(i)->getTypeName() == type
  374. && currentDeviceType != type)
  375. {
  376. if (currentAudioDevice != nullptr)
  377. {
  378. closeAudioDevice();
  379. Thread::sleep (1500); // allow a moment for OS devices to sort themselves out, to help
  380. // avoid things like DirectSound/ASIO clashes
  381. }
  382. currentDeviceType = type;
  383. AudioDeviceSetup s (*lastDeviceTypeConfigs.getUnchecked(i));
  384. insertDefaultDeviceNames (s);
  385. setAudioDeviceSetup (s, treatAsChosenDevice);
  386. sendChangeMessage();
  387. break;
  388. }
  389. }
  390. }
  391. AudioIODeviceType* AudioDeviceManager::getCurrentDeviceTypeObject() const
  392. {
  393. for (int i = 0; i < availableDeviceTypes.size(); ++i)
  394. if (availableDeviceTypes.getUnchecked(i)->getTypeName() == currentDeviceType)
  395. return availableDeviceTypes.getUnchecked(i);
  396. return availableDeviceTypes[0];
  397. }
  398. String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& newSetup,
  399. const bool treatAsChosenDevice)
  400. {
  401. jassert (&newSetup != &currentSetup); // this will have no effect
  402. if (newSetup == currentSetup && currentAudioDevice != nullptr)
  403. return String();
  404. if (! (newSetup == currentSetup))
  405. sendChangeMessage();
  406. stopDevice();
  407. const String newInputDeviceName (numInputChansNeeded == 0 ? String() : newSetup.inputDeviceName);
  408. const String newOutputDeviceName (numOutputChansNeeded == 0 ? String() : newSetup.outputDeviceName);
  409. String error;
  410. AudioIODeviceType* type = getCurrentDeviceTypeObject();
  411. if (type == nullptr || (newInputDeviceName.isEmpty() && newOutputDeviceName.isEmpty()))
  412. {
  413. deleteCurrentDevice();
  414. if (treatAsChosenDevice)
  415. updateXml();
  416. return String();
  417. }
  418. if (currentSetup.inputDeviceName != newInputDeviceName
  419. || currentSetup.outputDeviceName != newOutputDeviceName
  420. || currentAudioDevice == nullptr)
  421. {
  422. deleteCurrentDevice();
  423. scanDevicesIfNeeded();
  424. if (newOutputDeviceName.isNotEmpty() && ! deviceListContains (type, false, newOutputDeviceName))
  425. return "No such device: " + newOutputDeviceName;
  426. if (newInputDeviceName.isNotEmpty() && ! deviceListContains (type, true, newInputDeviceName))
  427. return "No such device: " + newInputDeviceName;
  428. currentAudioDevice = type->createDevice (newOutputDeviceName, newInputDeviceName);
  429. if (currentAudioDevice == nullptr)
  430. error = "Can't open the audio device!\n\n"
  431. "This may be because another application is currently using the same device - "
  432. "if so, you should close any other applications and try again!";
  433. else
  434. error = currentAudioDevice->getLastError();
  435. if (error.isNotEmpty())
  436. {
  437. deleteCurrentDevice();
  438. return error;
  439. }
  440. if (newSetup.useDefaultInputChannels)
  441. {
  442. inputChannels.clear();
  443. inputChannels.setRange (0, numInputChansNeeded, true);
  444. }
  445. if (newSetup.useDefaultOutputChannels)
  446. {
  447. outputChannels.clear();
  448. outputChannels.setRange (0, numOutputChansNeeded, true);
  449. }
  450. if (newInputDeviceName.isEmpty()) inputChannels.clear();
  451. if (newOutputDeviceName.isEmpty()) outputChannels.clear();
  452. }
  453. if (! newSetup.useDefaultInputChannels) inputChannels = newSetup.inputChannels;
  454. if (! newSetup.useDefaultOutputChannels) outputChannels = newSetup.outputChannels;
  455. currentSetup = newSetup;
  456. currentSetup.sampleRate = chooseBestSampleRate (newSetup.sampleRate);
  457. currentSetup.bufferSize = chooseBestBufferSize (newSetup.bufferSize);
  458. error = currentAudioDevice->open (inputChannels,
  459. outputChannels,
  460. currentSetup.sampleRate,
  461. currentSetup.bufferSize);
  462. if (error.isEmpty())
  463. {
  464. currentDeviceType = currentAudioDevice->getTypeName();
  465. currentAudioDevice->start (callbackHandler);
  466. currentSetup.sampleRate = currentAudioDevice->getCurrentSampleRate();
  467. currentSetup.bufferSize = currentAudioDevice->getCurrentBufferSizeSamples();
  468. currentSetup.inputChannels = currentAudioDevice->getActiveInputChannels();
  469. currentSetup.outputChannels = currentAudioDevice->getActiveOutputChannels();
  470. for (int i = 0; i < availableDeviceTypes.size(); ++i)
  471. if (availableDeviceTypes.getUnchecked (i)->getTypeName() == currentDeviceType)
  472. *(lastDeviceTypeConfigs.getUnchecked (i)) = currentSetup;
  473. if (treatAsChosenDevice)
  474. updateXml();
  475. }
  476. else
  477. {
  478. deleteCurrentDevice();
  479. }
  480. return error;
  481. }
  482. double AudioDeviceManager::chooseBestSampleRate (double rate) const
  483. {
  484. jassert (currentAudioDevice != nullptr);
  485. const Array<double> rates (currentAudioDevice->getAvailableSampleRates());
  486. if (rate > 0 && rates.contains (rate))
  487. return rate;
  488. rate = currentAudioDevice->getCurrentSampleRate();
  489. if (rate > 0 && rates.contains (rate))
  490. return rate;
  491. double lowestAbove44 = 0.0;
  492. for (int i = rates.size(); --i >= 0;)
  493. {
  494. const double sr = rates[i];
  495. if (sr >= 44100.0 && (lowestAbove44 < 1.0 || sr < lowestAbove44))
  496. lowestAbove44 = sr;
  497. }
  498. if (lowestAbove44 > 0.0)
  499. return lowestAbove44;
  500. return rates[0];
  501. }
  502. int AudioDeviceManager::chooseBestBufferSize (int bufferSize) const
  503. {
  504. jassert (currentAudioDevice != nullptr);
  505. if (bufferSize > 0 && currentAudioDevice->getAvailableBufferSizes().contains (bufferSize))
  506. return bufferSize;
  507. return currentAudioDevice->getDefaultBufferSize();
  508. }
  509. void AudioDeviceManager::stopDevice()
  510. {
  511. if (currentAudioDevice != nullptr)
  512. currentAudioDevice->stop();
  513. }
  514. void AudioDeviceManager::closeAudioDevice()
  515. {
  516. stopDevice();
  517. currentAudioDevice = nullptr;
  518. }
  519. void AudioDeviceManager::restartLastAudioDevice()
  520. {
  521. if (currentAudioDevice == nullptr)
  522. {
  523. if (currentSetup.inputDeviceName.isEmpty()
  524. && currentSetup.outputDeviceName.isEmpty())
  525. {
  526. // This method will only reload the last device that was running
  527. // before closeAudioDevice() was called - you need to actually open
  528. // one first, with setAudioDevice().
  529. jassertfalse;
  530. return;
  531. }
  532. AudioDeviceSetup s (currentSetup);
  533. setAudioDeviceSetup (s, false);
  534. }
  535. }
  536. void AudioDeviceManager::updateXml()
  537. {
  538. lastExplicitSettings = new XmlElement ("DEVICESETUP");
  539. lastExplicitSettings->setAttribute ("deviceType", currentDeviceType);
  540. lastExplicitSettings->setAttribute ("audioOutputDeviceName", currentSetup.outputDeviceName);
  541. lastExplicitSettings->setAttribute ("audioInputDeviceName", currentSetup.inputDeviceName);
  542. if (currentAudioDevice != nullptr)
  543. {
  544. lastExplicitSettings->setAttribute ("audioDeviceRate", currentAudioDevice->getCurrentSampleRate());
  545. if (currentAudioDevice->getDefaultBufferSize() != currentAudioDevice->getCurrentBufferSizeSamples())
  546. lastExplicitSettings->setAttribute ("audioDeviceBufferSize", currentAudioDevice->getCurrentBufferSizeSamples());
  547. if (! currentSetup.useDefaultInputChannels)
  548. lastExplicitSettings->setAttribute ("audioDeviceInChans", currentSetup.inputChannels.toString (2));
  549. if (! currentSetup.useDefaultOutputChannels)
  550. lastExplicitSettings->setAttribute ("audioDeviceOutChans", currentSetup.outputChannels.toString (2));
  551. }
  552. for (int i = 0; i < enabledMidiInputs.size(); ++i)
  553. lastExplicitSettings->createNewChildElement ("MIDIINPUT")
  554. ->setAttribute ("name", enabledMidiInputs[i]->getName());
  555. if (midiInsFromXml.size() > 0)
  556. {
  557. // Add any midi devices that have been enabled before, but which aren't currently
  558. // open because the device has been disconnected.
  559. const StringArray availableMidiDevices (MidiInput::getDevices());
  560. for (int i = 0; i < midiInsFromXml.size(); ++i)
  561. if (! availableMidiDevices.contains (midiInsFromXml[i], true))
  562. lastExplicitSettings->createNewChildElement ("MIDIINPUT")
  563. ->setAttribute ("name", midiInsFromXml[i]);
  564. }
  565. if (defaultMidiOutputName.isNotEmpty())
  566. lastExplicitSettings->setAttribute ("defaultMidiOutput", defaultMidiOutputName);
  567. }
  568. //==============================================================================
  569. void AudioDeviceManager::addAudioCallback (AudioIODeviceCallback* newCallback)
  570. {
  571. {
  572. const ScopedLock sl (audioCallbackLock);
  573. if (callbacks.contains (newCallback))
  574. return;
  575. }
  576. if (currentAudioDevice != nullptr && newCallback != nullptr)
  577. newCallback->audioDeviceAboutToStart (currentAudioDevice);
  578. const ScopedLock sl (audioCallbackLock);
  579. callbacks.add (newCallback);
  580. }
  581. void AudioDeviceManager::removeAudioCallback (AudioIODeviceCallback* callbackToRemove)
  582. {
  583. if (callbackToRemove != nullptr)
  584. {
  585. bool needsDeinitialising = currentAudioDevice != nullptr;
  586. {
  587. const ScopedLock sl (audioCallbackLock);
  588. needsDeinitialising = needsDeinitialising && callbacks.contains (callbackToRemove);
  589. callbacks.removeFirstMatchingValue (callbackToRemove);
  590. }
  591. if (needsDeinitialising)
  592. callbackToRemove->audioDeviceStopped();
  593. }
  594. }
  595. void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelData,
  596. int numInputChannels,
  597. float** outputChannelData,
  598. int numOutputChannels,
  599. int numSamples)
  600. {
  601. const ScopedLock sl (audioCallbackLock);
  602. inputLevelMeter.updateLevel (inputChannelData, numInputChannels, numSamples);
  603. outputLevelMeter.updateLevel (const_cast<const float**> (outputChannelData), numOutputChannels, numSamples);
  604. if (callbacks.size() > 0)
  605. {
  606. const double callbackStartTime = Time::getMillisecondCounterHiRes();
  607. tempBuffer.setSize (jmax (1, numOutputChannels), jmax (1, numSamples), false, false, true);
  608. callbacks.getUnchecked(0)->audioDeviceIOCallback (inputChannelData, numInputChannels,
  609. outputChannelData, numOutputChannels, numSamples);
  610. float** const tempChans = tempBuffer.getArrayOfWritePointers();
  611. for (int i = callbacks.size(); --i > 0;)
  612. {
  613. callbacks.getUnchecked(i)->audioDeviceIOCallback (inputChannelData, numInputChannels,
  614. tempChans, numOutputChannels, numSamples);
  615. for (int chan = 0; chan < numOutputChannels; ++chan)
  616. {
  617. if (const float* const src = tempChans [chan])
  618. if (float* const dst = outputChannelData [chan])
  619. for (int j = 0; j < numSamples; ++j)
  620. dst[j] += src[j];
  621. }
  622. }
  623. const double msTaken = Time::getMillisecondCounterHiRes() - callbackStartTime;
  624. const double filterAmount = 0.2;
  625. cpuUsageMs += filterAmount * (msTaken - cpuUsageMs);
  626. }
  627. else
  628. {
  629. for (int i = 0; i < numOutputChannels; ++i)
  630. zeromem (outputChannelData[i], sizeof (float) * (size_t) numSamples);
  631. }
  632. }
  633. void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice* const device)
  634. {
  635. cpuUsageMs = 0;
  636. const double sampleRate = device->getCurrentSampleRate();
  637. const int blockSize = device->getCurrentBufferSizeSamples();
  638. if (sampleRate > 0.0 && blockSize > 0)
  639. {
  640. const double msPerBlock = 1000.0 * blockSize / sampleRate;
  641. timeToCpuScale = (msPerBlock > 0.0) ? (1.0 / msPerBlock) : 0.0;
  642. }
  643. {
  644. const ScopedLock sl (audioCallbackLock);
  645. for (int i = callbacks.size(); --i >= 0;)
  646. callbacks.getUnchecked(i)->audioDeviceAboutToStart (device);
  647. }
  648. sendChangeMessage();
  649. }
  650. void AudioDeviceManager::audioDeviceStoppedInt()
  651. {
  652. cpuUsageMs = 0;
  653. timeToCpuScale = 0;
  654. sendChangeMessage();
  655. const ScopedLock sl (audioCallbackLock);
  656. for (int i = callbacks.size(); --i >= 0;)
  657. callbacks.getUnchecked(i)->audioDeviceStopped();
  658. }
  659. void AudioDeviceManager::audioDeviceErrorInt (const String& message)
  660. {
  661. const ScopedLock sl (audioCallbackLock);
  662. for (int i = callbacks.size(); --i >= 0;)
  663. callbacks.getUnchecked(i)->audioDeviceError (message);
  664. }
  665. double AudioDeviceManager::getCpuUsage() const
  666. {
  667. return jlimit (0.0, 1.0, timeToCpuScale * cpuUsageMs);
  668. }
  669. //==============================================================================
  670. void AudioDeviceManager::setMidiInputEnabled (const String& name, const bool enabled)
  671. {
  672. if (enabled != isMidiInputEnabled (name))
  673. {
  674. if (enabled)
  675. {
  676. const int index = MidiInput::getDevices().indexOf (name);
  677. if (index >= 0)
  678. {
  679. if (MidiInput* const midiIn = MidiInput::openDevice (index, callbackHandler))
  680. {
  681. enabledMidiInputs.add (midiIn);
  682. midiIn->start();
  683. }
  684. }
  685. }
  686. else
  687. {
  688. for (int i = enabledMidiInputs.size(); --i >= 0;)
  689. if (enabledMidiInputs[i]->getName() == name)
  690. enabledMidiInputs.remove (i);
  691. }
  692. updateXml();
  693. sendChangeMessage();
  694. }
  695. }
  696. bool AudioDeviceManager::isMidiInputEnabled (const String& name) const
  697. {
  698. for (int i = enabledMidiInputs.size(); --i >= 0;)
  699. if (enabledMidiInputs[i]->getName() == name)
  700. return true;
  701. return false;
  702. }
  703. void AudioDeviceManager::addMidiInputCallback (const String& name, MidiInputCallback* callbackToAdd)
  704. {
  705. removeMidiInputCallback (name, callbackToAdd);
  706. if (name.isEmpty() || isMidiInputEnabled (name))
  707. {
  708. const ScopedLock sl (midiCallbackLock);
  709. MidiCallbackInfo mc;
  710. mc.deviceName = name;
  711. mc.callback = callbackToAdd;
  712. midiCallbacks.add (mc);
  713. }
  714. }
  715. void AudioDeviceManager::removeMidiInputCallback (const String& name, MidiInputCallback* callbackToRemove)
  716. {
  717. for (int i = midiCallbacks.size(); --i >= 0;)
  718. {
  719. const MidiCallbackInfo& mc = midiCallbacks.getReference(i);
  720. if (mc.callback == callbackToRemove && mc.deviceName == name)
  721. {
  722. const ScopedLock sl (midiCallbackLock);
  723. midiCallbacks.remove (i);
  724. }
  725. }
  726. }
  727. void AudioDeviceManager::handleIncomingMidiMessageInt (MidiInput* source, const MidiMessage& message)
  728. {
  729. if (! message.isActiveSense())
  730. {
  731. const ScopedLock sl (midiCallbackLock);
  732. for (int i = 0; i < midiCallbacks.size(); ++i)
  733. {
  734. const MidiCallbackInfo& mc = midiCallbacks.getReference(i);
  735. if (mc.deviceName.isEmpty() || mc.deviceName == source->getName())
  736. mc.callback->handleIncomingMidiMessage (source, message);
  737. }
  738. }
  739. }
  740. //==============================================================================
  741. void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName)
  742. {
  743. if (defaultMidiOutputName != deviceName)
  744. {
  745. Array<AudioIODeviceCallback*> oldCallbacks;
  746. {
  747. const ScopedLock sl (audioCallbackLock);
  748. oldCallbacks.swapWith (callbacks);
  749. }
  750. if (currentAudioDevice != nullptr)
  751. for (int i = oldCallbacks.size(); --i >= 0;)
  752. oldCallbacks.getUnchecked(i)->audioDeviceStopped();
  753. defaultMidiOutput = nullptr;
  754. defaultMidiOutputName = deviceName;
  755. if (deviceName.isNotEmpty())
  756. defaultMidiOutput = MidiOutput::openDevice (MidiOutput::getDevices().indexOf (deviceName));
  757. if (currentAudioDevice != nullptr)
  758. for (int i = oldCallbacks.size(); --i >= 0;)
  759. oldCallbacks.getUnchecked(i)->audioDeviceAboutToStart (currentAudioDevice);
  760. {
  761. const ScopedLock sl (audioCallbackLock);
  762. oldCallbacks.swapWith (callbacks);
  763. }
  764. updateXml();
  765. sendChangeMessage();
  766. }
  767. }
  768. //==============================================================================
  769. // An AudioSource which simply outputs a buffer
  770. class AudioSampleBufferSource : public PositionableAudioSource
  771. {
  772. public:
  773. AudioSampleBufferSource (AudioSampleBuffer* audioBuffer, bool ownBuffer, bool playOnAllChannels)
  774. : buffer (audioBuffer, ownBuffer),
  775. position (0), looping (false), playAcrossAllChannels (playOnAllChannels)
  776. {}
  777. //==============================================================================
  778. void setNextReadPosition (int64 newPosition) override
  779. {
  780. jassert (newPosition >= 0);
  781. if (looping)
  782. newPosition = newPosition % static_cast<int64> (buffer->getNumSamples());
  783. position = jmin (buffer->getNumSamples(), static_cast<int> (newPosition));
  784. }
  785. int64 getNextReadPosition() const override { return static_cast<int64> (position); }
  786. int64 getTotalLength() const override { return static_cast<int64> (buffer->getNumSamples()); }
  787. bool isLooping() const override { return looping; }
  788. void setLooping (bool shouldLoop) override { looping = shouldLoop; }
  789. //==============================================================================
  790. void prepareToPlay (int, double) override {}
  791. void releaseResources() override {}
  792. void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override
  793. {
  794. bufferToFill.clearActiveBufferRegion();
  795. const int bufferSize = buffer->getNumSamples();
  796. const int samplesNeeded = bufferToFill.numSamples;
  797. const int samplesToCopy = jmin (bufferSize - position, samplesNeeded);
  798. if (samplesToCopy > 0)
  799. {
  800. int maxInChannels = buffer->getNumChannels();
  801. int maxOutChannels = bufferToFill.buffer->getNumChannels();
  802. if (! playAcrossAllChannels)
  803. maxOutChannels = jmin (maxOutChannels, maxInChannels);
  804. for (int i = 0; i < maxOutChannels; ++i)
  805. bufferToFill.buffer->copyFrom (i, bufferToFill.startSample, *buffer,
  806. i % maxInChannels, position, samplesToCopy);
  807. }
  808. position += samplesNeeded;
  809. if (looping)
  810. position %= bufferSize;
  811. }
  812. private:
  813. //==============================================================================
  814. OptionalScopedPointer<AudioSampleBuffer> buffer;
  815. int position;
  816. bool looping, playAcrossAllChannels;
  817. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioSampleBufferSource)
  818. };
  819. void AudioDeviceManager::playSound (const File& file)
  820. {
  821. if (file.existsAsFile())
  822. {
  823. AudioFormatManager formatManager;
  824. formatManager.registerBasicFormats();
  825. playSound (formatManager.createReaderFor (file), true);
  826. }
  827. }
  828. void AudioDeviceManager::playSound (const void* resourceData, size_t resourceSize)
  829. {
  830. if (resourceData != nullptr && resourceSize > 0)
  831. {
  832. AudioFormatManager formatManager;
  833. formatManager.registerBasicFormats();
  834. MemoryInputStream* mem = new MemoryInputStream (resourceData, resourceSize, false);
  835. playSound (formatManager.createReaderFor (mem), true);
  836. }
  837. }
  838. void AudioDeviceManager::playSound (AudioFormatReader* reader, bool deleteWhenFinished)
  839. {
  840. if (reader != nullptr)
  841. playSound (new AudioFormatReaderSource (reader, deleteWhenFinished), true);
  842. }
  843. void AudioDeviceManager::playSound (AudioSampleBuffer* buffer, bool deleteWhenFinished, bool playOnAllOutputChannels)
  844. {
  845. if (buffer != nullptr)
  846. playSound (new AudioSampleBufferSource (buffer, deleteWhenFinished, playOnAllOutputChannels), true);
  847. }
  848. void AudioDeviceManager::playSound (PositionableAudioSource* audioSource, bool deleteWhenFinished)
  849. {
  850. if (audioSource != nullptr && currentAudioDevice != nullptr)
  851. {
  852. AudioTransportSource* transport = dynamic_cast<AudioTransportSource*> (audioSource);
  853. if (transport == nullptr)
  854. {
  855. if (deleteWhenFinished)
  856. {
  857. transport = new AudioSourceOwningTransportSource (audioSource);
  858. }
  859. else
  860. {
  861. transport = new AudioTransportSource();
  862. transport->setSource (audioSource);
  863. deleteWhenFinished = true;
  864. }
  865. }
  866. transport->start();
  867. new AutoRemovingSourcePlayer (*this, transport, deleteWhenFinished);
  868. }
  869. else
  870. {
  871. if (deleteWhenFinished)
  872. delete audioSource;
  873. }
  874. }
  875. void AudioDeviceManager::playTestSound()
  876. {
  877. const double sampleRate = currentAudioDevice->getCurrentSampleRate();
  878. const int soundLength = (int) sampleRate;
  879. const double frequency = 440.0;
  880. const float amplitude = 0.5f;
  881. const double phasePerSample = double_Pi * 2.0 / (sampleRate / frequency);
  882. AudioSampleBuffer* newSound = new AudioSampleBuffer (1, soundLength);
  883. for (int i = 0; i < soundLength; ++i)
  884. newSound->setSample (0, i, amplitude * (float) std::sin (i * phasePerSample));
  885. newSound->applyGainRamp (0, 0, soundLength / 10, 0.0f, 1.0f);
  886. newSound->applyGainRamp (0, soundLength - soundLength / 4, soundLength / 4, 1.0f, 0.0f);
  887. playSound (newSound, true, true);
  888. }
  889. //==============================================================================
  890. AudioDeviceManager::LevelMeter::LevelMeter() noexcept : level() {}
  891. void AudioDeviceManager::LevelMeter::updateLevel (const float* const* channelData, int numChannels, int numSamples) noexcept
  892. {
  893. if (enabled.get() != 0 && numChannels > 0)
  894. {
  895. for (int j = 0; j < numSamples; ++j)
  896. {
  897. float s = 0;
  898. for (int i = 0; i < numChannels; ++i)
  899. s += std::abs (channelData[i][j]);
  900. s /= numChannels;
  901. const double decayFactor = 0.99992;
  902. if (s > level)
  903. level = s;
  904. else if (level > 0.001f)
  905. level *= decayFactor;
  906. else
  907. level = 0;
  908. }
  909. }
  910. else
  911. {
  912. level = 0;
  913. }
  914. }
  915. void AudioDeviceManager::LevelMeter::setEnabled (bool shouldBeEnabled) noexcept
  916. {
  917. enabled.set (shouldBeEnabled ? 1 : 0);
  918. level = 0;
  919. }
  920. double AudioDeviceManager::LevelMeter::getCurrentLevel() const noexcept
  921. {
  922. jassert (enabled.get() != 0); // you need to call setEnabled (true) before using this!
  923. return level;
  924. }
  925. double AudioDeviceManager::getCurrentInputLevel() const noexcept { return inputLevelMeter.getCurrentLevel(); }
  926. double AudioDeviceManager::getCurrentOutputLevel() const noexcept { return outputLevelMeter.getCurrentLevel(); }
  927. void AudioDeviceManager::enableInputLevelMeasurement (bool enable) noexcept { inputLevelMeter.setEnabled (enable); }
  928. void AudioDeviceManager::enableOutputLevelMeasurement (bool enable) noexcept { outputLevelMeter.setEnabled (enable); }