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.

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