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