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.

933 lines
31KB

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