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 39KB

9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158
  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI 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. // This is an AudioTransportSource which will own it's assigned source
  72. struct AudioSourceOwningTransportSource : public AudioTransportSource
  73. {
  74. AudioSourceOwningTransportSource (PositionableAudioSource* s) : source (s)
  75. {
  76. AudioTransportSource::setSource (s);
  77. }
  78. ~AudioSourceOwningTransportSource()
  79. {
  80. setSource (nullptr);
  81. }
  82. private:
  83. ScopedPointer<PositionableAudioSource> source;
  84. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioSourceOwningTransportSource)
  85. };
  86. //==============================================================================
  87. // An AudioSourcePlayer which will remove itself from the AudioDeviceManager's
  88. // callback list once it finishes playing its source
  89. struct AutoRemovingSourcePlayer : public AudioSourcePlayer,
  90. private Timer
  91. {
  92. AutoRemovingSourcePlayer (AudioDeviceManager& dm, AudioTransportSource* ts, bool ownSource)
  93. : manager (dm), transportSource (ts, ownSource)
  94. {
  95. jassert (ts != nullptr);
  96. manager.addAudioCallback (this);
  97. AudioSourcePlayer::setSource (transportSource);
  98. startTimerHz (10);
  99. }
  100. ~AutoRemovingSourcePlayer()
  101. {
  102. setSource (nullptr);
  103. manager.removeAudioCallback (this);
  104. }
  105. void timerCallback() override
  106. {
  107. if (getCurrentSource() == nullptr || ! transportSource->isPlaying())
  108. delete this;
  109. }
  110. void audioDeviceStopped() override
  111. {
  112. AudioSourcePlayer::audioDeviceStopped();
  113. setSource (nullptr);
  114. }
  115. private:
  116. AudioDeviceManager& manager;
  117. OptionalScopedPointer<AudioTransportSource> transportSource;
  118. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AutoRemovingSourcePlayer)
  119. };
  120. //==============================================================================
  121. AudioDeviceManager::AudioDeviceManager()
  122. : numInputChansNeeded (0),
  123. numOutputChansNeeded (2),
  124. listNeedsScanning (true),
  125. inputLevel (0),
  126. cpuUsageMs (0),
  127. timeToCpuScale (0)
  128. {
  129. callbackHandler = new CallbackHandler (*this);
  130. }
  131. AudioDeviceManager::~AudioDeviceManager()
  132. {
  133. currentAudioDevice = nullptr;
  134. defaultMidiOutput = nullptr;
  135. for (int i = 0; i < callbacks.size(); ++i)
  136. if (AutoRemovingSourcePlayer* p = dynamic_cast<AutoRemovingSourcePlayer*> (callbacks.getUnchecked(i)))
  137. delete p;
  138. }
  139. //==============================================================================
  140. void AudioDeviceManager::createDeviceTypesIfNeeded()
  141. {
  142. if (availableDeviceTypes.size() == 0)
  143. {
  144. OwnedArray<AudioIODeviceType> types;
  145. createAudioDeviceTypes (types);
  146. for (int i = 0; i < types.size(); ++i)
  147. addAudioDeviceType (types.getUnchecked(i));
  148. types.clear (false);
  149. if (AudioIODeviceType* first = availableDeviceTypes.getFirst())
  150. currentDeviceType = first->getTypeName();
  151. }
  152. }
  153. const OwnedArray<AudioIODeviceType>& AudioDeviceManager::getAvailableDeviceTypes()
  154. {
  155. scanDevicesIfNeeded();
  156. return availableDeviceTypes;
  157. }
  158. void AudioDeviceManager::audioDeviceListChanged()
  159. {
  160. if (currentAudioDevice != nullptr)
  161. {
  162. currentSetup.sampleRate = currentAudioDevice->getCurrentSampleRate();
  163. currentSetup.bufferSize = currentAudioDevice->getCurrentBufferSizeSamples();
  164. currentSetup.inputChannels = currentAudioDevice->getActiveInputChannels();
  165. currentSetup.outputChannels = currentAudioDevice->getActiveOutputChannels();
  166. }
  167. sendChangeMessage();
  168. }
  169. //==============================================================================
  170. static void addIfNotNull (OwnedArray<AudioIODeviceType>& list, AudioIODeviceType* const device)
  171. {
  172. if (device != nullptr)
  173. list.add (device);
  174. }
  175. void AudioDeviceManager::createAudioDeviceTypes (OwnedArray<AudioIODeviceType>& list)
  176. {
  177. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI (false));
  178. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI (true));
  179. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_DirectSound());
  180. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ASIO());
  181. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_CoreAudio());
  182. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_iOSAudio());
  183. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_JACK());
  184. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ALSA());
  185. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_OpenSLES());
  186. addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Android());
  187. }
  188. void AudioDeviceManager::addAudioDeviceType (AudioIODeviceType* newDeviceType)
  189. {
  190. if (newDeviceType != nullptr)
  191. {
  192. jassert (lastDeviceTypeConfigs.size() == availableDeviceTypes.size());
  193. availableDeviceTypes.add (newDeviceType);
  194. lastDeviceTypeConfigs.add (new AudioDeviceSetup());
  195. newDeviceType->addListener (callbackHandler);
  196. }
  197. }
  198. static bool deviceListContains (AudioIODeviceType* type, bool isInput, const String& name)
  199. {
  200. StringArray devices (type->getDeviceNames (isInput));
  201. for (int i = devices.size(); --i >= 0;)
  202. if (devices[i].trim().equalsIgnoreCase (name.trim()))
  203. return true;
  204. return false;
  205. }
  206. //==============================================================================
  207. String AudioDeviceManager::initialise (const int numInputChannelsNeeded,
  208. const int numOutputChannelsNeeded,
  209. const XmlElement* const xml,
  210. const bool selectDefaultDeviceOnFailure,
  211. const String& preferredDefaultDeviceName,
  212. const AudioDeviceSetup* preferredSetupOptions)
  213. {
  214. scanDevicesIfNeeded();
  215. numInputChansNeeded = numInputChannelsNeeded;
  216. numOutputChansNeeded = numOutputChannelsNeeded;
  217. if (xml != nullptr && xml->hasTagName ("DEVICESETUP"))
  218. return initialiseFromXML (*xml, selectDefaultDeviceOnFailure,
  219. preferredDefaultDeviceName, preferredSetupOptions);
  220. return initialiseDefault (preferredDefaultDeviceName, preferredSetupOptions);
  221. }
  222. String AudioDeviceManager::initialiseDefault (const String& preferredDefaultDeviceName,
  223. const AudioDeviceSetup* preferredSetupOptions)
  224. {
  225. AudioDeviceSetup setup;
  226. if (preferredSetupOptions != nullptr)
  227. {
  228. setup = *preferredSetupOptions;
  229. }
  230. else if (preferredDefaultDeviceName.isNotEmpty())
  231. {
  232. for (int j = availableDeviceTypes.size(); --j >= 0;)
  233. {
  234. AudioIODeviceType* const type = availableDeviceTypes.getUnchecked(j);
  235. const StringArray outs (type->getDeviceNames (false));
  236. for (int i = 0; i < outs.size(); ++i)
  237. {
  238. if (outs[i].matchesWildcard (preferredDefaultDeviceName, true))
  239. {
  240. setup.outputDeviceName = outs[i];
  241. break;
  242. }
  243. }
  244. const StringArray ins (type->getDeviceNames (true));
  245. for (int i = 0; i < ins.size(); ++i)
  246. {
  247. if (ins[i].matchesWildcard (preferredDefaultDeviceName, true))
  248. {
  249. setup.inputDeviceName = ins[i];
  250. break;
  251. }
  252. }
  253. }
  254. }
  255. insertDefaultDeviceNames (setup);
  256. return setAudioDeviceSetup (setup, false);
  257. }
  258. String AudioDeviceManager::initialiseFromXML (const XmlElement& xml,
  259. const bool selectDefaultDeviceOnFailure,
  260. const String& preferredDefaultDeviceName,
  261. const AudioDeviceSetup* preferredSetupOptions)
  262. {
  263. lastExplicitSettings = new XmlElement (xml);
  264. String error;
  265. AudioDeviceSetup setup;
  266. if (preferredSetupOptions != nullptr)
  267. setup = *preferredSetupOptions;
  268. if (xml.getStringAttribute ("audioDeviceName").isNotEmpty())
  269. {
  270. setup.inputDeviceName = setup.outputDeviceName
  271. = xml.getStringAttribute ("audioDeviceName");
  272. }
  273. else
  274. {
  275. setup.inputDeviceName = xml.getStringAttribute ("audioInputDeviceName");
  276. setup.outputDeviceName = xml.getStringAttribute ("audioOutputDeviceName");
  277. }
  278. currentDeviceType = xml.getStringAttribute ("deviceType");
  279. if (findType (currentDeviceType) == nullptr)
  280. {
  281. if (AudioIODeviceType* const type = findType (setup.inputDeviceName, setup.outputDeviceName))
  282. currentDeviceType = type->getTypeName();
  283. else if (availableDeviceTypes.size() > 0)
  284. currentDeviceType = availableDeviceTypes.getUnchecked(0)->getTypeName();
  285. }
  286. setup.bufferSize = xml.getIntAttribute ("audioDeviceBufferSize");
  287. setup.sampleRate = xml.getDoubleAttribute ("audioDeviceRate");
  288. setup.inputChannels .parseString (xml.getStringAttribute ("audioDeviceInChans", "11"), 2);
  289. setup.outputChannels.parseString (xml.getStringAttribute ("audioDeviceOutChans", "11"), 2);
  290. setup.useDefaultInputChannels = ! xml.hasAttribute ("audioDeviceInChans");
  291. setup.useDefaultOutputChannels = ! xml.hasAttribute ("audioDeviceOutChans");
  292. error = setAudioDeviceSetup (setup, true);
  293. midiInsFromXml.clear();
  294. forEachXmlChildElementWithTagName (xml, c, "MIDIINPUT")
  295. midiInsFromXml.add (c->getStringAttribute ("name"));
  296. const StringArray allMidiIns (MidiInput::getDevices());
  297. for (int i = allMidiIns.size(); --i >= 0;)
  298. setMidiInputEnabled (allMidiIns[i], midiInsFromXml.contains (allMidiIns[i]));
  299. if (error.isNotEmpty() && selectDefaultDeviceOnFailure)
  300. error = initialise (numInputChansNeeded, numOutputChansNeeded,
  301. nullptr, false, preferredDefaultDeviceName);
  302. setDefaultMidiOutput (xml.getStringAttribute ("defaultMidiOutput"));
  303. return error;
  304. }
  305. String AudioDeviceManager::initialiseWithDefaultDevices (int numInputChannelsNeeded,
  306. int numOutputChannelsNeeded)
  307. {
  308. lastExplicitSettings = nullptr;
  309. return initialise (numInputChannelsNeeded, numOutputChannelsNeeded,
  310. nullptr, false, String(), nullptr);
  311. }
  312. void AudioDeviceManager::insertDefaultDeviceNames (AudioDeviceSetup& setup) const
  313. {
  314. if (AudioIODeviceType* type = getCurrentDeviceTypeObject())
  315. {
  316. if (setup.outputDeviceName.isEmpty())
  317. setup.outputDeviceName = type->getDeviceNames (false) [type->getDefaultDeviceIndex (false)];
  318. if (setup.inputDeviceName.isEmpty())
  319. setup.inputDeviceName = type->getDeviceNames (true) [type->getDefaultDeviceIndex (true)];
  320. }
  321. }
  322. XmlElement* AudioDeviceManager::createStateXml() const
  323. {
  324. return lastExplicitSettings.createCopy();
  325. }
  326. //==============================================================================
  327. void AudioDeviceManager::scanDevicesIfNeeded()
  328. {
  329. if (listNeedsScanning)
  330. {
  331. listNeedsScanning = false;
  332. createDeviceTypesIfNeeded();
  333. for (int i = availableDeviceTypes.size(); --i >= 0;)
  334. availableDeviceTypes.getUnchecked(i)->scanForDevices();
  335. }
  336. }
  337. AudioIODeviceType* AudioDeviceManager::findType (const String& typeName)
  338. {
  339. scanDevicesIfNeeded();
  340. for (int i = availableDeviceTypes.size(); --i >= 0;)
  341. if (availableDeviceTypes.getUnchecked(i)->getTypeName() == typeName)
  342. return availableDeviceTypes.getUnchecked(i);
  343. return nullptr;
  344. }
  345. AudioIODeviceType* AudioDeviceManager::findType (const String& inputName, const String& outputName)
  346. {
  347. scanDevicesIfNeeded();
  348. for (int i = availableDeviceTypes.size(); --i >= 0;)
  349. {
  350. AudioIODeviceType* const type = availableDeviceTypes.getUnchecked(i);
  351. if ((inputName.isNotEmpty() && deviceListContains (type, true, inputName))
  352. || (outputName.isNotEmpty() && deviceListContains (type, false, outputName)))
  353. {
  354. return type;
  355. }
  356. }
  357. return nullptr;
  358. }
  359. void AudioDeviceManager::getAudioDeviceSetup (AudioDeviceSetup& setup)
  360. {
  361. setup = currentSetup;
  362. }
  363. void AudioDeviceManager::deleteCurrentDevice()
  364. {
  365. currentAudioDevice = nullptr;
  366. currentSetup.inputDeviceName.clear();
  367. currentSetup.outputDeviceName.clear();
  368. }
  369. void AudioDeviceManager::setCurrentAudioDeviceType (const String& type,
  370. const bool treatAsChosenDevice)
  371. {
  372. for (int i = 0; i < availableDeviceTypes.size(); ++i)
  373. {
  374. if (availableDeviceTypes.getUnchecked(i)->getTypeName() == type
  375. && currentDeviceType != type)
  376. {
  377. if (currentAudioDevice != nullptr)
  378. {
  379. closeAudioDevice();
  380. Thread::sleep (1500); // allow a moment for OS devices to sort themselves out, to help
  381. // avoid things like DirectSound/ASIO clashes
  382. }
  383. currentDeviceType = type;
  384. AudioDeviceSetup s (*lastDeviceTypeConfigs.getUnchecked(i));
  385. insertDefaultDeviceNames (s);
  386. setAudioDeviceSetup (s, treatAsChosenDevice);
  387. sendChangeMessage();
  388. break;
  389. }
  390. }
  391. }
  392. AudioIODeviceType* AudioDeviceManager::getCurrentDeviceTypeObject() const
  393. {
  394. for (int i = 0; i < availableDeviceTypes.size(); ++i)
  395. if (availableDeviceTypes.getUnchecked(i)->getTypeName() == currentDeviceType)
  396. return availableDeviceTypes.getUnchecked(i);
  397. return availableDeviceTypes[0];
  398. }
  399. String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& newSetup,
  400. const bool treatAsChosenDevice)
  401. {
  402. jassert (&newSetup != &currentSetup); // this will have no effect
  403. if (newSetup == currentSetup && currentAudioDevice != nullptr)
  404. return String();
  405. if (! (newSetup == currentSetup))
  406. sendChangeMessage();
  407. stopDevice();
  408. const String newInputDeviceName (numInputChansNeeded == 0 ? String() : newSetup.inputDeviceName);
  409. const String newOutputDeviceName (numOutputChansNeeded == 0 ? String() : newSetup.outputDeviceName);
  410. String error;
  411. AudioIODeviceType* type = getCurrentDeviceTypeObject();
  412. if (type == nullptr || (newInputDeviceName.isEmpty() && newOutputDeviceName.isEmpty()))
  413. {
  414. deleteCurrentDevice();
  415. if (treatAsChosenDevice)
  416. updateXml();
  417. return String();
  418. }
  419. if (currentSetup.inputDeviceName != newInputDeviceName
  420. || currentSetup.outputDeviceName != newOutputDeviceName
  421. || currentAudioDevice == nullptr)
  422. {
  423. deleteCurrentDevice();
  424. scanDevicesIfNeeded();
  425. if (newOutputDeviceName.isNotEmpty() && ! deviceListContains (type, false, newOutputDeviceName))
  426. return "No such device: " + newOutputDeviceName;
  427. if (newInputDeviceName.isNotEmpty() && ! deviceListContains (type, true, newInputDeviceName))
  428. return "No such device: " + newInputDeviceName;
  429. currentAudioDevice = type->createDevice (newOutputDeviceName, newInputDeviceName);
  430. if (currentAudioDevice == nullptr)
  431. error = "Can't open the audio device!\n\n"
  432. "This may be because another application is currently using the same device - "
  433. "if so, you should close any other applications and try again!";
  434. else
  435. error = currentAudioDevice->getLastError();
  436. if (error.isNotEmpty())
  437. {
  438. deleteCurrentDevice();
  439. return error;
  440. }
  441. if (newSetup.useDefaultInputChannels)
  442. {
  443. inputChannels.clear();
  444. inputChannels.setRange (0, numInputChansNeeded, true);
  445. }
  446. if (newSetup.useDefaultOutputChannels)
  447. {
  448. outputChannels.clear();
  449. outputChannels.setRange (0, numOutputChansNeeded, true);
  450. }
  451. if (newInputDeviceName.isEmpty()) inputChannels.clear();
  452. if (newOutputDeviceName.isEmpty()) outputChannels.clear();
  453. }
  454. if (! newSetup.useDefaultInputChannels) inputChannels = newSetup.inputChannels;
  455. if (! newSetup.useDefaultOutputChannels) outputChannels = newSetup.outputChannels;
  456. currentSetup = newSetup;
  457. currentSetup.sampleRate = chooseBestSampleRate (newSetup.sampleRate);
  458. currentSetup.bufferSize = chooseBestBufferSize (newSetup.bufferSize);
  459. error = currentAudioDevice->open (inputChannels,
  460. outputChannels,
  461. currentSetup.sampleRate,
  462. currentSetup.bufferSize);
  463. if (error.isEmpty())
  464. {
  465. currentDeviceType = currentAudioDevice->getTypeName();
  466. currentAudioDevice->start (callbackHandler);
  467. currentSetup.sampleRate = currentAudioDevice->getCurrentSampleRate();
  468. currentSetup.bufferSize = currentAudioDevice->getCurrentBufferSizeSamples();
  469. currentSetup.inputChannels = currentAudioDevice->getActiveInputChannels();
  470. currentSetup.outputChannels = currentAudioDevice->getActiveOutputChannels();
  471. for (int i = 0; i < availableDeviceTypes.size(); ++i)
  472. if (availableDeviceTypes.getUnchecked (i)->getTypeName() == currentDeviceType)
  473. *(lastDeviceTypeConfigs.getUnchecked (i)) = currentSetup;
  474. if (treatAsChosenDevice)
  475. updateXml();
  476. }
  477. else
  478. {
  479. deleteCurrentDevice();
  480. }
  481. return error;
  482. }
  483. double AudioDeviceManager::chooseBestSampleRate (double rate) const
  484. {
  485. jassert (currentAudioDevice != nullptr);
  486. const Array<double> rates (currentAudioDevice->getAvailableSampleRates());
  487. if (rate > 0 && rates.contains (rate))
  488. return rate;
  489. rate = currentAudioDevice->getCurrentSampleRate();
  490. if (rate > 0 && rates.contains (rate))
  491. return rate;
  492. double lowestAbove44 = 0.0;
  493. for (int i = rates.size(); --i >= 0;)
  494. {
  495. const double sr = rates[i];
  496. if (sr >= 44100.0 && (lowestAbove44 < 1.0 || sr < lowestAbove44))
  497. lowestAbove44 = sr;
  498. }
  499. if (lowestAbove44 > 0.0)
  500. return lowestAbove44;
  501. return rates[0];
  502. }
  503. int AudioDeviceManager::chooseBestBufferSize (int bufferSize) const
  504. {
  505. jassert (currentAudioDevice != nullptr);
  506. if (bufferSize > 0 && currentAudioDevice->getAvailableBufferSizes().contains (bufferSize))
  507. return bufferSize;
  508. return currentAudioDevice->getDefaultBufferSize();
  509. }
  510. void AudioDeviceManager::stopDevice()
  511. {
  512. if (currentAudioDevice != nullptr)
  513. currentAudioDevice->stop();
  514. }
  515. void AudioDeviceManager::closeAudioDevice()
  516. {
  517. stopDevice();
  518. currentAudioDevice = nullptr;
  519. }
  520. void AudioDeviceManager::restartLastAudioDevice()
  521. {
  522. if (currentAudioDevice == nullptr)
  523. {
  524. if (currentSetup.inputDeviceName.isEmpty()
  525. && currentSetup.outputDeviceName.isEmpty())
  526. {
  527. // This method will only reload the last device that was running
  528. // before closeAudioDevice() was called - you need to actually open
  529. // one first, with setAudioDevice().
  530. jassertfalse;
  531. return;
  532. }
  533. AudioDeviceSetup s (currentSetup);
  534. setAudioDeviceSetup (s, false);
  535. }
  536. }
  537. void AudioDeviceManager::updateXml()
  538. {
  539. lastExplicitSettings = new XmlElement ("DEVICESETUP");
  540. lastExplicitSettings->setAttribute ("deviceType", currentDeviceType);
  541. lastExplicitSettings->setAttribute ("audioOutputDeviceName", currentSetup.outputDeviceName);
  542. lastExplicitSettings->setAttribute ("audioInputDeviceName", currentSetup.inputDeviceName);
  543. if (currentAudioDevice != nullptr)
  544. {
  545. lastExplicitSettings->setAttribute ("audioDeviceRate", currentAudioDevice->getCurrentSampleRate());
  546. if (currentAudioDevice->getDefaultBufferSize() != currentAudioDevice->getCurrentBufferSizeSamples())
  547. lastExplicitSettings->setAttribute ("audioDeviceBufferSize", currentAudioDevice->getCurrentBufferSizeSamples());
  548. if (! currentSetup.useDefaultInputChannels)
  549. lastExplicitSettings->setAttribute ("audioDeviceInChans", currentSetup.inputChannels.toString (2));
  550. if (! currentSetup.useDefaultOutputChannels)
  551. lastExplicitSettings->setAttribute ("audioDeviceOutChans", currentSetup.outputChannels.toString (2));
  552. }
  553. for (int i = 0; i < enabledMidiInputs.size(); ++i)
  554. lastExplicitSettings->createNewChildElement ("MIDIINPUT")
  555. ->setAttribute ("name", enabledMidiInputs[i]->getName());
  556. if (midiInsFromXml.size() > 0)
  557. {
  558. // Add any midi devices that have been enabled before, but which aren't currently
  559. // open because the device has been disconnected.
  560. const StringArray availableMidiDevices (MidiInput::getDevices());
  561. for (int i = 0; i < midiInsFromXml.size(); ++i)
  562. if (! availableMidiDevices.contains (midiInsFromXml[i], true))
  563. lastExplicitSettings->createNewChildElement ("MIDIINPUT")
  564. ->setAttribute ("name", midiInsFromXml[i]);
  565. }
  566. if (defaultMidiOutputName.isNotEmpty())
  567. lastExplicitSettings->setAttribute ("defaultMidiOutput", defaultMidiOutputName);
  568. }
  569. //==============================================================================
  570. void AudioDeviceManager::addAudioCallback (AudioIODeviceCallback* newCallback)
  571. {
  572. {
  573. const ScopedLock sl (audioCallbackLock);
  574. if (callbacks.contains (newCallback))
  575. return;
  576. }
  577. if (currentAudioDevice != nullptr && newCallback != nullptr)
  578. newCallback->audioDeviceAboutToStart (currentAudioDevice);
  579. const ScopedLock sl (audioCallbackLock);
  580. callbacks.add (newCallback);
  581. }
  582. void AudioDeviceManager::removeAudioCallback (AudioIODeviceCallback* callbackToRemove)
  583. {
  584. if (callbackToRemove != nullptr)
  585. {
  586. bool needsDeinitialising = currentAudioDevice != nullptr;
  587. {
  588. const ScopedLock sl (audioCallbackLock);
  589. needsDeinitialising = needsDeinitialising && callbacks.contains (callbackToRemove);
  590. callbacks.removeFirstMatchingValue (callbackToRemove);
  591. }
  592. if (needsDeinitialising)
  593. callbackToRemove->audioDeviceStopped();
  594. }
  595. }
  596. void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelData,
  597. int numInputChannels,
  598. float** outputChannelData,
  599. int numOutputChannels,
  600. int numSamples)
  601. {
  602. const ScopedLock sl (audioCallbackLock);
  603. if (inputLevelMeasurementEnabledCount.get() > 0 && numInputChannels > 0)
  604. {
  605. for (int j = 0; j < numSamples; ++j)
  606. {
  607. float s = 0;
  608. for (int i = 0; i < numInputChannels; ++i)
  609. s += std::abs (inputChannelData[i][j]);
  610. s /= numInputChannels;
  611. const double decayFactor = 0.99992;
  612. if (s > inputLevel)
  613. inputLevel = s;
  614. else if (inputLevel > 0.001f)
  615. inputLevel *= decayFactor;
  616. else
  617. inputLevel = 0;
  618. }
  619. }
  620. else
  621. {
  622. inputLevel = 0;
  623. }
  624. if (callbacks.size() > 0)
  625. {
  626. const double callbackStartTime = Time::getMillisecondCounterHiRes();
  627. tempBuffer.setSize (jmax (1, numOutputChannels), jmax (1, numSamples), false, false, true);
  628. callbacks.getUnchecked(0)->audioDeviceIOCallback (inputChannelData, numInputChannels,
  629. outputChannelData, numOutputChannels, numSamples);
  630. float** const tempChans = tempBuffer.getArrayOfWritePointers();
  631. for (int i = callbacks.size(); --i > 0;)
  632. {
  633. callbacks.getUnchecked(i)->audioDeviceIOCallback (inputChannelData, numInputChannels,
  634. tempChans, numOutputChannels, numSamples);
  635. for (int chan = 0; chan < numOutputChannels; ++chan)
  636. {
  637. if (const float* const src = tempChans [chan])
  638. if (float* const dst = outputChannelData [chan])
  639. for (int j = 0; j < numSamples; ++j)
  640. dst[j] += src[j];
  641. }
  642. }
  643. const double msTaken = Time::getMillisecondCounterHiRes() - callbackStartTime;
  644. const double filterAmount = 0.2;
  645. cpuUsageMs += filterAmount * (msTaken - cpuUsageMs);
  646. }
  647. else
  648. {
  649. for (int i = 0; i < numOutputChannels; ++i)
  650. zeromem (outputChannelData[i], sizeof (float) * (size_t) numSamples);
  651. }
  652. }
  653. void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice* const device)
  654. {
  655. cpuUsageMs = 0;
  656. const double sampleRate = device->getCurrentSampleRate();
  657. const int blockSize = device->getCurrentBufferSizeSamples();
  658. if (sampleRate > 0.0 && blockSize > 0)
  659. {
  660. const double msPerBlock = 1000.0 * blockSize / sampleRate;
  661. timeToCpuScale = (msPerBlock > 0.0) ? (1.0 / msPerBlock) : 0.0;
  662. }
  663. {
  664. const ScopedLock sl (audioCallbackLock);
  665. for (int i = callbacks.size(); --i >= 0;)
  666. callbacks.getUnchecked(i)->audioDeviceAboutToStart (device);
  667. }
  668. sendChangeMessage();
  669. }
  670. void AudioDeviceManager::audioDeviceStoppedInt()
  671. {
  672. cpuUsageMs = 0;
  673. timeToCpuScale = 0;
  674. sendChangeMessage();
  675. const ScopedLock sl (audioCallbackLock);
  676. for (int i = callbacks.size(); --i >= 0;)
  677. callbacks.getUnchecked(i)->audioDeviceStopped();
  678. }
  679. void AudioDeviceManager::audioDeviceErrorInt (const String& message)
  680. {
  681. const ScopedLock sl (audioCallbackLock);
  682. for (int i = callbacks.size(); --i >= 0;)
  683. callbacks.getUnchecked(i)->audioDeviceError (message);
  684. }
  685. double AudioDeviceManager::getCpuUsage() const
  686. {
  687. return jlimit (0.0, 1.0, timeToCpuScale * cpuUsageMs);
  688. }
  689. //==============================================================================
  690. void AudioDeviceManager::setMidiInputEnabled (const String& name, const bool enabled)
  691. {
  692. if (enabled != isMidiInputEnabled (name))
  693. {
  694. if (enabled)
  695. {
  696. const int index = MidiInput::getDevices().indexOf (name);
  697. if (index >= 0)
  698. {
  699. if (MidiInput* const midiIn = MidiInput::openDevice (index, callbackHandler))
  700. {
  701. enabledMidiInputs.add (midiIn);
  702. midiIn->start();
  703. }
  704. }
  705. }
  706. else
  707. {
  708. for (int i = enabledMidiInputs.size(); --i >= 0;)
  709. if (enabledMidiInputs[i]->getName() == name)
  710. enabledMidiInputs.remove (i);
  711. }
  712. updateXml();
  713. sendChangeMessage();
  714. }
  715. }
  716. bool AudioDeviceManager::isMidiInputEnabled (const String& name) const
  717. {
  718. for (int i = enabledMidiInputs.size(); --i >= 0;)
  719. if (enabledMidiInputs[i]->getName() == name)
  720. return true;
  721. return false;
  722. }
  723. void AudioDeviceManager::addMidiInputCallback (const String& name, MidiInputCallback* callbackToAdd)
  724. {
  725. removeMidiInputCallback (name, callbackToAdd);
  726. if (name.isEmpty() || isMidiInputEnabled (name))
  727. {
  728. const ScopedLock sl (midiCallbackLock);
  729. MidiCallbackInfo mc;
  730. mc.deviceName = name;
  731. mc.callback = callbackToAdd;
  732. midiCallbacks.add (mc);
  733. }
  734. }
  735. void AudioDeviceManager::removeMidiInputCallback (const String& name, MidiInputCallback* callbackToRemove)
  736. {
  737. for (int i = midiCallbacks.size(); --i >= 0;)
  738. {
  739. const MidiCallbackInfo& mc = midiCallbacks.getReference(i);
  740. if (mc.callback == callbackToRemove && mc.deviceName == name)
  741. {
  742. const ScopedLock sl (midiCallbackLock);
  743. midiCallbacks.remove (i);
  744. }
  745. }
  746. }
  747. void AudioDeviceManager::handleIncomingMidiMessageInt (MidiInput* source, const MidiMessage& message)
  748. {
  749. if (! message.isActiveSense())
  750. {
  751. const ScopedLock sl (midiCallbackLock);
  752. for (int i = 0; i < midiCallbacks.size(); ++i)
  753. {
  754. const MidiCallbackInfo& mc = midiCallbacks.getReference(i);
  755. if (mc.deviceName.isEmpty() || mc.deviceName == source->getName())
  756. mc.callback->handleIncomingMidiMessage (source, message);
  757. }
  758. }
  759. }
  760. //==============================================================================
  761. void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName)
  762. {
  763. if (defaultMidiOutputName != deviceName)
  764. {
  765. Array<AudioIODeviceCallback*> oldCallbacks;
  766. {
  767. const ScopedLock sl (audioCallbackLock);
  768. oldCallbacks.swapWith (callbacks);
  769. }
  770. if (currentAudioDevice != nullptr)
  771. for (int i = oldCallbacks.size(); --i >= 0;)
  772. oldCallbacks.getUnchecked(i)->audioDeviceStopped();
  773. defaultMidiOutput = nullptr;
  774. defaultMidiOutputName = deviceName;
  775. if (deviceName.isNotEmpty())
  776. defaultMidiOutput = MidiOutput::openDevice (MidiOutput::getDevices().indexOf (deviceName));
  777. if (currentAudioDevice != nullptr)
  778. for (int i = oldCallbacks.size(); --i >= 0;)
  779. oldCallbacks.getUnchecked(i)->audioDeviceAboutToStart (currentAudioDevice);
  780. {
  781. const ScopedLock sl (audioCallbackLock);
  782. oldCallbacks.swapWith (callbacks);
  783. }
  784. updateXml();
  785. sendChangeMessage();
  786. }
  787. }
  788. //==============================================================================
  789. // An AudioSource which simply outputs a buffer
  790. class AudioSampleBufferSource : public PositionableAudioSource
  791. {
  792. public:
  793. AudioSampleBufferSource (AudioSampleBuffer* audioBuffer, bool ownBuffer, bool playOnAllChannels)
  794. : buffer (audioBuffer, ownBuffer),
  795. position (0), looping (false), playAcrossAllChannels (playOnAllChannels)
  796. {}
  797. //==============================================================================
  798. void setNextReadPosition (int64 newPosition) override
  799. {
  800. jassert (newPosition >= 0);
  801. if (looping)
  802. newPosition = newPosition % static_cast<int64> (buffer->getNumSamples());
  803. position = jmin (buffer->getNumSamples(), static_cast<int> (newPosition));
  804. }
  805. int64 getNextReadPosition() const override { return static_cast<int64> (position); }
  806. int64 getTotalLength() const override { return static_cast<int64> (buffer->getNumSamples()); }
  807. bool isLooping() const override { return looping; }
  808. void setLooping (bool shouldLoop) override { looping = shouldLoop; }
  809. //==============================================================================
  810. void prepareToPlay (int, double) override {}
  811. void releaseResources() override {}
  812. void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override
  813. {
  814. bufferToFill.clearActiveBufferRegion();
  815. const int bufferSize = buffer->getNumSamples();
  816. const int samplesNeeded = bufferToFill.numSamples;
  817. const int samplesToCopy = jmin (bufferSize - position, samplesNeeded);
  818. if (samplesToCopy > 0)
  819. {
  820. int maxInChannels = buffer->getNumChannels();
  821. int maxOutChannels = bufferToFill.buffer->getNumChannels();
  822. if (! playAcrossAllChannels)
  823. maxOutChannels = jmin (maxOutChannels, maxInChannels);
  824. for (int i = 0; i < maxOutChannels; ++i)
  825. bufferToFill.buffer->copyFrom (i, bufferToFill.startSample, *buffer,
  826. i % maxInChannels, position, samplesToCopy);
  827. }
  828. position += samplesNeeded;
  829. if (looping)
  830. position %= bufferSize;
  831. }
  832. private:
  833. //==============================================================================
  834. OptionalScopedPointer<AudioSampleBuffer> buffer;
  835. int position;
  836. bool looping, playAcrossAllChannels;
  837. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioSampleBufferSource)
  838. };
  839. void AudioDeviceManager::playSound (const File& file)
  840. {
  841. if (file.existsAsFile())
  842. {
  843. AudioFormatManager formatManager;
  844. formatManager.registerBasicFormats();
  845. playSound (formatManager.createReaderFor (file), true);
  846. }
  847. }
  848. void AudioDeviceManager::playSound (const void* resourceData, size_t resourceSize)
  849. {
  850. if (resourceData != nullptr && resourceSize > 0)
  851. {
  852. AudioFormatManager formatManager;
  853. formatManager.registerBasicFormats();
  854. MemoryInputStream* mem = new MemoryInputStream (resourceData, resourceSize, false);
  855. playSound (formatManager.createReaderFor (mem), true);
  856. }
  857. }
  858. void AudioDeviceManager::playSound (AudioFormatReader* reader, bool deleteWhenFinished)
  859. {
  860. if (reader != nullptr)
  861. playSound (new AudioFormatReaderSource (reader, deleteWhenFinished), true);
  862. }
  863. void AudioDeviceManager::playSound (AudioSampleBuffer* buffer, bool deleteWhenFinished, bool playOnAllOutputChannels)
  864. {
  865. if (buffer != nullptr)
  866. playSound (new AudioSampleBufferSource (buffer, deleteWhenFinished, playOnAllOutputChannels), true);
  867. }
  868. void AudioDeviceManager::playSound (PositionableAudioSource* audioSource, bool deleteWhenFinished)
  869. {
  870. if (audioSource != nullptr && currentAudioDevice != nullptr)
  871. {
  872. AudioTransportSource* transport = dynamic_cast<AudioTransportSource*> (audioSource);
  873. if (transport == nullptr)
  874. {
  875. if (deleteWhenFinished)
  876. {
  877. transport = new AudioSourceOwningTransportSource (audioSource);
  878. }
  879. else
  880. {
  881. transport = new AudioTransportSource();
  882. transport->setSource (audioSource);
  883. deleteWhenFinished = true;
  884. }
  885. }
  886. transport->start();
  887. new AutoRemovingSourcePlayer (*this, transport, deleteWhenFinished);
  888. }
  889. else
  890. {
  891. if (deleteWhenFinished)
  892. delete audioSource;
  893. }
  894. }
  895. void AudioDeviceManager::playTestSound()
  896. {
  897. const double sampleRate = currentAudioDevice->getCurrentSampleRate();
  898. const int soundLength = (int) sampleRate;
  899. const double frequency = 440.0;
  900. const float amplitude = 0.5f;
  901. const double phasePerSample = double_Pi * 2.0 / (sampleRate / frequency);
  902. AudioSampleBuffer* newSound = new AudioSampleBuffer (1, soundLength);
  903. for (int i = 0; i < soundLength; ++i)
  904. newSound->setSample (0, i, amplitude * (float) std::sin (i * phasePerSample));
  905. newSound->applyGainRamp (0, 0, soundLength / 10, 0.0f, 1.0f);
  906. newSound->applyGainRamp (0, soundLength - soundLength / 4, soundLength / 4, 1.0f, 0.0f);
  907. playSound (newSound, true, true);
  908. }
  909. //==============================================================================
  910. void AudioDeviceManager::enableInputLevelMeasurement (const bool enableMeasurement)
  911. {
  912. if (enableMeasurement)
  913. ++inputLevelMeasurementEnabledCount;
  914. else
  915. --inputLevelMeasurementEnabledCount;
  916. inputLevel = 0;
  917. }
  918. double AudioDeviceManager::getCurrentInputLevel() const
  919. {
  920. jassert (inputLevelMeasurementEnabledCount.get() > 0); // you need to call enableInputLevelMeasurement() before using this!
  921. return inputLevel;
  922. }