//=========================================================
//  MusE
//  Linux Music Editor
//    $Id: synth.h,v 1.1.1.1 2003/10/29 10:05:10 wschweer Exp $
//  (C) Copyright 2000-2001 Werner Schweer (ws@seh.de)
//=========================================================

#ifndef __SYNTH_H__
#define __SYNTH_H__

#include <qfileinfo.h>
#include <list>

#include "globals.h"
#include "ladspa.h"
#include "node.h"
#include "minstrument.h"
#include "driver/midirawin.h"
#include "midiport.h"

class MidiEvent;

//---------------------------------------------------------
//   Synth
//    software synthesizer; consists of
//          - LADSPA interface
//          - experimental extensions in addition to LADSPA:
//---------------------------------------------------------

class Synth {
      LADSPA_Descriptor_Function ladspa;
      const LADSPA_Descriptor* descr;
      QFileInfo info;
      int _instances;

   public:
      Synth(const QFileInfo* fi,
         LADSPA_Descriptor_Function _ladspa,
         const LADSPA_Descriptor* _descr)
         : info(*fi)
            {
            ladspa = _ladspa;
            descr  = _descr;
            _instances = 0;
            }
      LADSPA_Handle* handle;         // per instance
      void connect(LADSPA_Handle* h, int port, void* val) {
            descr->connect_port(h, port, (LADSPA_Data*)val);
            }
      void run(LADSPA_Handle* h, int n) { descr->run(h, n); }

      int instances() const       { return _instances; }
      void incInstances(int val)  { _instances += val; }
      const char* label() const   { return descr->Label; }
      QString baseName() const    { return info.baseName(); }
      QString path() const        { return info.dirPath(true); }
      int channels() const        { return descr->PortCount; }
      LADSPA_Handle instantiate() {
            ++_instances;
            return descr->instantiate(descr, sampleRate);
            }
      void activate(LADSPA_Handle h) { descr->activate(h); }
      void cleanup(LADSPA_Handle h)  { descr->cleanup(h); }
      };

extern int nsynthis;
extern Synth** synthis;

class Mess;

//---------------------------------------------------------
//   SynthI
//    software synthesizer instance
//---------------------------------------------------------

class SynthI : public AudioNode, public MidiInstrument, public MidiRawIn {
      Synth* synthesizer;
      Mess* _mess;
      bool _gui;
      pid_t _guiPid;
      int _readFd;
      int _writeFd;
      MidiDevice* _mdev;

      virtual bool getData(int, unsigned long, float**);

      virtual void realtimeSystemInput(int) {}
      virtual void mtcInputQuarter(int)     {}
      virtual void setSongPosition(int)     {}
      virtual void sysexReceived(const unsigned char* p, int n);
      virtual void eventReceived(int a, int b, int c);

   public:
      SynthI(Synth* s);
      ~SynthI();
      void setDevice(MidiDevice* d) { _mdev = d; }
      MidiDevice* mdev() const      { return _mdev; }
      Mess* mess() const            { return _mess; }
      Synth* synth() const          { return synthesizer; }

      virtual const char* getPatchName(int,int,int,int,MType);
      virtual void populatePatchPopup(QPopupMenu*, int ch, MType);
      void setParameter(const char* name, const char* value) const;

      virtual bool guiVisible() const { return _gui; }
      void guiExited();
      virtual void showGui(bool);
      virtual bool hasGui() const;

      int readFd() const  { return _readFd; }
      int writeFd() const { return _writeFd; }
      pid_t guiPid()      { return _guiPid; }

      virtual void writeToGui(const MidiPlayEvent*);
      void processInput();
      };

typedef std::list<SynthI*> SynthIList;
typedef SynthIList::iterator iSynthI;

extern SynthIList synthiInstances;
class QString;

extern void terminateSynthGuis();
#endif

