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.

1159 lines
39KB

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