zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

EngineMgr.cpp (4871B)


      1 /*
      2   ZynAddSubFX - a software synthesizer
      3 
      4   EngineMgr.cpp - MIDI/Audio Factory
      5   Copyright (C) 2016 Mark McCurry
      6 
      7   This program is free software; you can redistribute it and/or
      8   modify it under the terms of the GNU General Public License
      9   as published by the Free Software Foundation; either version 2
     10   of the License, or (at your option) any later version.
     11 */
     12 #include "EngineMgr.h"
     13 #include <algorithm>
     14 #include <iostream>
     15 #include <cassert>
     16 #include "Nio.h"
     17 #include "InMgr.h"
     18 #include "OutMgr.h"
     19 #include "AudioOut.h"
     20 #include "MidiIn.h"
     21 #include "NulEngine.h"
     22 using namespace std;
     23 
     24 #if OSS
     25 #include "OssEngine.h"
     26 #include "OssMultiEngine.h"
     27 #endif
     28 #if ALSA
     29 #include "AlsaEngine.h"
     30 #endif
     31 #if JACK
     32 #include "JackEngine.h"
     33 #include "JackMultiEngine.h"
     34 #endif
     35 #if PORTAUDIO
     36 #include "PaEngine.h"
     37 #endif
     38 #if SNDIO
     39 #include "SndioEngine.h"
     40 #endif
     41 
     42 namespace zyn {
     43 
     44 EngineMgr &EngineMgr::getInstance(const SYNTH_T *synth,
     45     const oss_devs_t *oss_devs)
     46 {
     47     static EngineMgr instance(synth, *oss_devs);
     48     return instance;
     49 }
     50 
     51 EngineMgr::EngineMgr(const SYNTH_T *synth, const oss_devs_t& oss_devs)
     52 {
     53     assert(synth);
     54     Engine *defaultEng = new NulEngine(*synth);
     55 
     56     //conditional compiling mess (but contained)
     57     engines.push_back(defaultEng);
     58 #if OSS
     59     engines.push_back(new OssEngine(*synth, oss_devs));
     60     engines.push_back(new OssMultiEngine(*synth, oss_devs));
     61 #else
     62     (void)oss_devs;
     63 #endif
     64 #if ALSA
     65     engines.push_back(new AlsaEngine(*synth));
     66 #endif
     67 #if JACK
     68     engines.push_back(new JackEngine(*synth));
     69     engines.push_back(new JackMultiEngine(*synth));
     70 #endif
     71 #if PORTAUDIO
     72     engines.push_back(new PaEngine(*synth));
     73 #endif
     74 #if SNDIO
     75     engines.push_back(new SndioEngine(*synth));
     76 #endif
     77 
     78     defaultOut = dynamic_cast<AudioOut *>(defaultEng);
     79 
     80     defaultIn = dynamic_cast<MidiIn *>(defaultEng);
     81 
     82     //Accept command line/compile time options
     83     if(!Nio::defaultSink.empty())
     84         setOutDefault(Nio::defaultSink);
     85 
     86     if(!Nio::defaultSource.empty())
     87         setInDefault(Nio::defaultSource);
     88 }
     89 
     90 EngineMgr::~EngineMgr()
     91 {
     92     for(list<Engine *>::iterator itr = engines.begin();
     93         itr != engines.end(); ++itr)
     94         delete *itr;
     95 }
     96 
     97 Engine *EngineMgr::getEng(string name)
     98 {
     99     transform(name.begin(), name.end(), name.begin(), ::toupper);
    100     for(list<Engine *>::iterator itr = engines.begin();
    101         itr != engines.end(); ++itr)
    102         if((*itr)->name == name)
    103             return *itr;
    104     return NULL;
    105 }
    106 
    107 bool EngineMgr::start()
    108 {
    109     bool expected = true;
    110     if(!(defaultOut && defaultIn)) {
    111         cerr << "ERROR: It looks like someone broke the Nio Output\n"
    112              << "       Attempting to recover by defaulting to the\n"
    113              << "       Null Engine." << endl;
    114         defaultOut = dynamic_cast<AudioOut *>(getEng("NULL"));
    115         defaultIn  = dynamic_cast<MidiIn *>(getEng("NULL"));
    116     }
    117 
    118     OutMgr::getInstance(). currentOut = defaultOut;
    119     InMgr::getInstance().  current    = defaultIn;
    120 
    121     //open up the default output(s)
    122     cout << "Starting Audio: " << defaultOut->name << endl;
    123     defaultOut->setAudioEn(true);
    124     if(defaultOut->getAudioEn())
    125         cout << "Audio Started" << endl;
    126     else {
    127         expected = false;
    128         cerr << "ERROR: The default audio output failed to open!" << endl;
    129         OutMgr::getInstance(). currentOut =
    130             dynamic_cast<AudioOut *>(getEng("NULL"));
    131         OutMgr::getInstance(). currentOut->setAudioEn(true);
    132     }
    133 
    134     cout << "Starting MIDI: " << defaultIn->name << endl;
    135     defaultIn->setMidiEn(true);
    136     if(defaultIn->getMidiEn())
    137         cout << "MIDI Started" << endl;
    138     else { //recover
    139         expected = false;
    140         cerr << "ERROR: The default MIDI input failed to open!" << endl;
    141         InMgr::getInstance(). current = dynamic_cast<MidiIn *>(getEng("NULL"));
    142         InMgr::getInstance(). current->setMidiEn(true);
    143     }
    144 
    145     //Show if expected drivers were booted
    146     return expected;
    147 }
    148 
    149 void EngineMgr::stop()
    150 {
    151     for(list<Engine *>::iterator itr = engines.begin();
    152         itr != engines.end(); ++itr)
    153         (*itr)->Stop();
    154 }
    155 
    156 bool EngineMgr::setInDefault(string name)
    157 {
    158     MidiIn *chosen;
    159     if((chosen = dynamic_cast<MidiIn *>(getEng(name)))) {    //got the input
    160         defaultIn = chosen;
    161         return true;
    162     }
    163 
    164     //Warn user
    165     cerr << "Error: " << name << " is not a recognized MIDI input source"
    166          << endl;
    167     cerr << "       Defaulting to the NULL input source" << endl;
    168 
    169     return false;
    170 }
    171 
    172 bool EngineMgr::setOutDefault(string name)
    173 {
    174     AudioOut *chosen;
    175     if((chosen = dynamic_cast<AudioOut *>(getEng(name)))) {    //got the output
    176         defaultOut = chosen;
    177         return true;
    178     }
    179 
    180     //Warn user
    181     cerr << "Error: " << name << " is not a recognized audio backend" << endl;
    182     cerr << "       Defaulting to the NULL audio backend" << endl;
    183     return false;
    184 }
    185 
    186 }