Audio plugin host https://kx.studio/carla
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.

juce_AudioDeviceManager.cpp 33KB

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