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.

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