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.

164 lines
4.2KB

  1. #include "EngineMgr.h"
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <cassert>
  5. #include "Nio.h"
  6. #include "InMgr.h"
  7. #include "OutMgr.h"
  8. #include "AudioOut.h"
  9. #include "MidiIn.h"
  10. #include "NulEngine.h"
  11. #if OSS
  12. #include "OssEngine.h"
  13. #include "OssMultiEngine.h"
  14. #endif
  15. #if ALSA
  16. #include "AlsaEngine.h"
  17. #endif
  18. #if JACK
  19. #include "JackEngine.h"
  20. #include "JackMultiEngine.h"
  21. #endif
  22. #if PORTAUDIO
  23. #include "PaEngine.h"
  24. #endif
  25. using namespace std;
  26. EngineMgr &EngineMgr::getInstance(const SYNTH_T *synth,
  27. const oss_devs_t *oss_devs)
  28. {
  29. static EngineMgr instance(synth, *oss_devs);
  30. return instance;
  31. }
  32. EngineMgr::EngineMgr(const SYNTH_T *synth, const oss_devs_t& oss_devs)
  33. {
  34. assert(synth);
  35. Engine *defaultEng = new NulEngine(*synth);
  36. //conditional compiling mess (but contained)
  37. engines.push_back(defaultEng);
  38. #if OSS
  39. engines.push_back(new OssEngine(*synth, oss_devs));
  40. engines.push_back(new OssMultiEngine(*synth, oss_devs));
  41. #endif
  42. #if ALSA
  43. engines.push_back(new AlsaEngine(*synth));
  44. #endif
  45. #if JACK
  46. engines.push_back(new JackEngine(*synth));
  47. engines.push_back(new JackMultiEngine(*synth));
  48. #endif
  49. #if PORTAUDIO
  50. engines.push_back(new PaEngine(*synth));
  51. #endif
  52. defaultOut = dynamic_cast<AudioOut *>(defaultEng);
  53. defaultIn = dynamic_cast<MidiIn *>(defaultEng);
  54. //Accept command line/compile time options
  55. if(!Nio::defaultSink.empty())
  56. setOutDefault(Nio::defaultSink);
  57. if(!Nio::defaultSource.empty())
  58. setInDefault(Nio::defaultSource);
  59. }
  60. EngineMgr::~EngineMgr()
  61. {
  62. for(list<Engine *>::iterator itr = engines.begin();
  63. itr != engines.end(); ++itr)
  64. delete *itr;
  65. }
  66. Engine *EngineMgr::getEng(string name)
  67. {
  68. transform(name.begin(), name.end(), name.begin(), ::toupper);
  69. for(list<Engine *>::iterator itr = engines.begin();
  70. itr != engines.end(); ++itr)
  71. if((*itr)->name == name)
  72. return *itr;
  73. return NULL;
  74. }
  75. bool EngineMgr::start()
  76. {
  77. bool expected = true;
  78. if(!(defaultOut && defaultIn)) {
  79. cerr << "ERROR: It looks like someone broke the Nio Output\n"
  80. << " Attempting to recover by defaulting to the\n"
  81. << " Null Engine." << endl;
  82. defaultOut = dynamic_cast<AudioOut *>(getEng("NULL"));
  83. defaultIn = dynamic_cast<MidiIn *>(getEng("NULL"));
  84. }
  85. OutMgr::getInstance(). currentOut = defaultOut;
  86. InMgr::getInstance(). current = defaultIn;
  87. //open up the default output(s)
  88. cout << "Starting Audio: " << defaultOut->name << endl;
  89. defaultOut->setAudioEn(true);
  90. if(defaultOut->getAudioEn())
  91. cout << "Audio Started" << endl;
  92. else {
  93. expected = false;
  94. cerr << "ERROR: The default audio output failed to open!" << endl;
  95. OutMgr::getInstance(). currentOut =
  96. dynamic_cast<AudioOut *>(getEng("NULL"));
  97. OutMgr::getInstance(). currentOut->setAudioEn(true);
  98. }
  99. cout << "Starting MIDI: " << defaultIn->name << endl;
  100. defaultIn->setMidiEn(true);
  101. if(defaultIn->getMidiEn())
  102. cout << "MIDI Started" << endl;
  103. else { //recover
  104. expected = false;
  105. cerr << "ERROR: The default MIDI input failed to open!" << endl;
  106. InMgr::getInstance(). current = dynamic_cast<MidiIn *>(getEng("NULL"));
  107. InMgr::getInstance(). current->setMidiEn(true);
  108. }
  109. //Show if expected drivers were booted
  110. return expected;
  111. }
  112. void EngineMgr::stop()
  113. {
  114. for(list<Engine *>::iterator itr = engines.begin();
  115. itr != engines.end(); ++itr)
  116. (*itr)->Stop();
  117. }
  118. bool EngineMgr::setInDefault(string name)
  119. {
  120. MidiIn *chosen;
  121. if((chosen = dynamic_cast<MidiIn *>(getEng(name)))) { //got the input
  122. defaultIn = chosen;
  123. return true;
  124. }
  125. //Warn user
  126. cerr << "Error: " << name << " is not a recognized MIDI input source"
  127. << endl;
  128. cerr << " Defaulting to the NULL input source" << endl;
  129. return false;
  130. }
  131. bool EngineMgr::setOutDefault(string name)
  132. {
  133. AudioOut *chosen;
  134. if((chosen = dynamic_cast<AudioOut *>(getEng(name)))) { //got the output
  135. defaultOut = chosen;
  136. return true;
  137. }
  138. //Warn user
  139. cerr << "Error: " << name << " is not a recognized audio backend" << endl;
  140. cerr << " Defaulting to the NULL audio backend" << endl;
  141. return false;
  142. }