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.

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