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.

980 lines
32KB

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