text: /************************************************************************ 
   IMPORTANT NOTE : this file contains two clearly delimited sections :
   the ARCHITECTURE section (in two parts) and the USER section. Each section
   is governed by its own copyright and license. Please check individually
   each section for license and copyright information.
   *************************************************************************/
  
  /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
  
  /************************************************************************
   FAUST Architecture File
   Copyright (C) 2003-2019 GRAME, Centre National de Creation Musicale
   ---------------------------------------------------------------------
   This Architecture section is free software; you can redistribute it
   and/or modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 3 of
   the License, or (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; If not, see <http://www.gnu.org/licenses/>.
   
   EXCEPTION : As a special exception, you may create a larger work
   that contains this FAUST architecture section and distribute
   that work under terms of your choice, so long as this FAUST
   architecture section is not modified.
   
   ************************************************************************
   ************************************************************************/
  
  #include <libgen.h>
  #include <stdlib.h>
  #include <iostream>
  #include <list>
  #include <cmath>
  
  #include "faust/dsp/timed-dsp.h"
  #include "faust/gui/FUI.h"
  #include "faust/misc.h"
  #include "faust/gui/GUI.h"
  #include "faust/gui/JSONUI.h"
  #include "faust/gui/console.h"
  #include "faust/audio/alsa-dsp.h"
  
  #ifdef OSCCTRL
  #include "faust/gui/OSCUI.h"
  #endif
  
  #ifdef HTTPCTRL
  #include "faust/gui/httpdUI.h"
  #endif
  
  // Always include this file, otherwise -nvoices only mode does not compile....
  #include "faust/gui/MidiUI.h"
  
  #ifdef MIDICTRL
  #include "faust/midi/rt-midi.h"
  #include "faust/midi/RtMidi.cpp"
  #endif
  
  /******************************************************************************
   *******************************************************************************
   
   VECTOR INTRINSICS
   
   *******************************************************************************
   *******************************************************************************/
  
  <<includeIntrinsic>>
  
  /********************END ARCHITECTURE SECTION (part 1/2)****************/
  
  /**************************BEGIN USER SECTION **************************/
  
  <<includeclass>>
  
  /***************************END USER SECTION ***************************/
  
  /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
  
  #include "faust/dsp/poly-dsp.h"
  
  #ifdef POLY2
  #include "faust/dsp/dsp-combiner.h"
  #include "effect.h"
  #endif
  
  /***************************END USER SECTION ***************************/
  
  /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
  
  dsp* DSP;
  
  std::list<GUI*> GUI::fGuiList;
  ztimedmap GUI::gTimedZoneMap;
  
  //-------------------------------------------------------------------------
  // 									MAIN
  //-------------------------------------------------------------------------
  
  static bool hasMIDISync()
  {
      JSONUI jsonui;
      mydsp* tmp_dsp = new mydsp();
      tmp_dsp->buildUserInterface(&jsonui);
      std::string json = jsonui.JSON();
      delete tmp_dsp;
  
      return ((json.find("midi") != std::string::npos) &&
              ((json.find("start") != std::string::npos) ||
              (json.find("stop") != std::string::npos) ||
              (json.find("clock") != std::string::npos)));
  }
  
  int main(int argc, char *argv[] )
  {
      char* appname = basename (argv [0]);
      char rcfilename[256];
      char* home = getenv("HOME");
      int nvoices = 0;
      mydsp_poly* dsp_poly = NULL;
      snprintf(rcfilename, 256, "%s/.%src", home, appname);
  
  #ifdef POLY2
      nvoices = lopt(argv, "--nvoices", nvoices);
      int group = lopt(argv, "--group", 1);
      std::cout << "Started with " << nvoices << " voices\n";
      dsp_poly = new mydsp_poly(new mydsp(), nvoices, true, group);
  
  #if MIDICTRL
      if (hasMIDISync()) {
          DSP = new timed_dsp(new dsp_sequencer(dsp_poly, new effect()));
      } else {
          DSP = new dsp_sequencer(dsp_poly, new effect());
      }
  #else
      DSP = new dsp_sequencer(dsp_poly, new effect());
  #endif
      
  #else
      nvoices = lopt(argv, "--nvoices", nvoices);
      int group = lopt(argv, "--group", 1);
      
      if (nvoices > 0) {
          std::cout << "Started with " << nvoices << " voices\n";
          dsp_poly = new mydsp_poly(new mydsp(), nvoices, true, group);
          
  #if MIDICTRL
          if (hasMIDISync()) {
              DSP = new timed_dsp(dsp_poly);
          } else {
              DSP = dsp_poly;
          }
  #else
          DSP = dsp_poly;
  #endif
      } else {
  #if MIDICTRL
          if (hasMIDISync()) {
              DSP = new timed_dsp(new mydsp());
          } else {
              DSP = new mydsp();
          }
  #else
          DSP = new mydsp();
  #endif
      }
  #endif
      
      if (!DSP) {
          std::cerr << "Unable to allocate Faust DSP object" << std::endl;
          exit(1);
      }
  
      CMDUI* interface = new CMDUI(argc, argv, true);
      FUI* finterface	= new FUI();
      DSP->buildUserInterface(interface);
      DSP->buildUserInterface(finterface);
  
  #ifdef MIDICTRL
      rt_midi midi_handler(appname);
      midi_handler.addMidiIn(dsp_poly);
      MidiUI midiinterface(&midi_handler);
      DSP->buildUserInterface(&midiinterface);
      std::cout << "MIDI is on" << std::endl;
  #endif
  
  #ifdef HTTPCTRL
      httpdUI* httpdinterface = new httpdUI(appname, DSP->getNumInputs(), DSP->getNumOutputs(), argc, argv);
      DSP->buildUserInterface(httpdinterface);
      std::cout << "HTTPD is on" << std::endl;
  #endif
  
  #ifdef OSCCTRL
      GUI* oscinterface = new OSCUI(appname, argc, argv);
      DSP->buildUserInterface(oscinterface);
  #endif
  
      alsaaudio audio (argc, argv, DSP);
      audio.init(appname, DSP);
      finterface->recallState(rcfilename);
      audio.start();
  
  #ifdef HTTPCTRL
      httpdinterface->run();
  #endif
  
  #ifdef OSCCTRL
      oscinterface->run();
  #endif
  #ifdef MIDICTRL
      if (!midiinterface.run()) {
          std::cerr << "MidiUI run error\n";
      }
  #endif
      interface->run();
  
  #ifdef MIDICTRL
      midiinterface.stop();
  #endif
  
      audio.stop();
      finterface->saveState(rcfilename);
  
      // desallocation
      delete interface;
      delete finterface;
  #ifdef HTTPCTRL
      delete httpdinterface;
  #endif
  #ifdef OSCCTRL
      delete oscinterface;
  #endif
  
      return 0;
  }
  
  /********************END ARCHITECTURE SECTION (part 2/2)****************/
  