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.

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