The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

954 lines
32KB

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