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

#ifndef __AUDIO_H__
#define __AUDIO_H__

#include <pthread.h>
#include "driver/jackaudio.h"

class AudioPort;
class SndFile;
class AudioNode;
class PluginI;
class SynthI;
class AudioDevice;
class AudioNode;
class AudioDevice;
class WavePart;
class WaveTrack;

enum {
      AUDIO_SET_MIXDOWN, AUDIO_RECORD,
      AUDIO_ROUTEADD, AUDIO_ROUTESET, AUDIO_ROUTEREMOVE,
      AUDIO_VOL, AUDIO_PAN,
      AUDIO_ADDPLUGIN,
      AUDIO_REMOVE_SYNTHI, AUDIO_ADD_SYNTHI,
      AUDIO_SET_SEG_SIZE,
      AUDIO_SET_PREFADER, AUDIO_SET_CHANNELS,
      AUDIO_SEEK, AUDIO_PLAY,
      AUDIO_ADD_PART, AUDIO_CHANGE_PART, AUDIO_REMOVE_PART,
      AUDIO_REMOVE_TRACK,
      AUDIO_UNDO, AUDIO_REDO,
      };

//---------------------------------------------------------
//   Msg
//---------------------------------------------------------

struct AudioMsg {   // this should be an union
      int serialNo;
      int id;
      SndFile* downmix;
      AudioNode* snode;
      AudioNode* dnode;
      AudioPort* port;
      AudioDevice* device;
      int ival;
      int iival;
      double dval;
      PluginI* plugin;
      SynthI* synth;
      WavePart* spart;
      WavePart* dpart;
      WaveTrack* track;
      };

//---------------------------------------------------------
//   Audio
//---------------------------------------------------------

class Audio {
      int curSamplePos;

      void processMsg(const volatile AudioMsg* msg);
      volatile bool playState;
      bool recordState;

      volatile AudioMsg* msg;

      int fromThreadFdr;
      int fromThreadFdw;

      bool _running;

      pthread_mutex_t msgMutex;

      pthread_mutex_t mutex;   // protect sampleTime
      double sampleTime;

      int samplePos;

   public:
      Audio();
      ~Audio();
      void process(unsigned long samples);
      int pos() { return curSamplePos; }

      int curPlayPos();

      void start();
      void stop(bool);

      void setRunning(bool val) { _running = val; }
      bool isPlaying() const    { return playState; }
      void sendMsg(AudioMsg*);
      void msgRemoveRoute(AudioNode*, AudioNode*);
      void msgAddRoute(AudioNode*, AudioNode*);
      void msgSetRoute(AudioNode*, AudioNode*);
      void msgAddPlugin(AudioNode*, int idx, PluginI* plugin);
      void msgSetMute(AudioNode*, bool val);
      void msgSetVolume(AudioNode*, double val);
      void msgSetPan(AudioNode*, double val);
      void msgAddSynthI(SynthI* synth);
      void msgRemoveSynthI(SynthI* synth);
      void msgSetSegSize(int, int);
      void msgSetPrefader(AudioNode*, int);
      void msgSetChannels(AudioNode*, int);

//      void msgSetRecFile(AudioNode*, SndFile* sf);
      void msgSetOff(AudioNode*, bool);
      void msgSetRecord(AudioNode*, bool);

      void msgPlay(bool flag);
      void msgSeek(int);
      void msgAddPart(WavePart*);
      void msgRemovePart(WavePart*);
      void msgChangePart(WavePart* s, WavePart* d);
      void msgRemoveTrack(WaveTrack*);
      void msgUndo();
      void msgRedo();

      void writeTick();

      // transport:
      void startPlay();
      void stopPlay();
      void startRecord();
      void stopRecord();
      void seek(int tickpos);
      };

extern int processAudio(jack_nframes_t, void*);
extern void processAudio1(void*, void*);

extern Audio* audio;
extern AudioDevice* audioDevice;   // current audio device in use
#endif

