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

#ifndef __WAVE_H__
#define __WAVE_H__

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

class Xml;

//---------------------------------------------------------
//   SampleV
//    peak file value
//---------------------------------------------------------

struct SampleV {
      unsigned char peak;
      unsigned char rms;
      };

//---------------------------------------------------------
//   SndFileList
//---------------------------------------------------------

class SndFile;
class SndFileList : public std::list<SndFile*> {
   public:
      SndFile* search(const QString& name);
      };

typedef SndFileList::iterator iSndFile;
typedef SndFileList::const_iterator ciSndFile;

//---------------------------------------------------------
//   SndFile
//---------------------------------------------------------

class SndFile {
      static SndFileList _sndFiles;
      QFileInfo* finfo;
      SNDFILE* sf;
      SF_INFO sfinfo;
      int refs;
      SampleV** cache;
      int csize;                    // frames in cache

      void readCache(const QString& path, bool progress);
      void writeCache(const QString& path);

      bool openFlag;
      bool writeFlag;

   public:
      SndFile(const QString& name);
      ~SndFile();

      static SndFileList sndFiles;

      bool openRead();        // return true on error
      bool openWrite();       // return true on error
      void close();
      void remove();

      bool isOpen() const     { return openFlag; }
      bool isWritable() const { return writeFlag; }
      void update();

      void incRef();
      void decRef();
      int references()       { return refs; }

      QString basename() const;
      QString path() const;
      QString name() const;

      unsigned samples() const;
      unsigned channels() const;
      unsigned samplerate() const;
      unsigned format() const;
      int sampleBits() const;
      void setFormat(int fmt, int ch, int rate);

      size_t read(int channel, float**, size_t);
      size_t write(int channel, float**, size_t);

      off_t seek(off_t frames, int whence);
      void read(SampleV* s, int mag, unsigned pos);
      QString strerror() const;

      static SndFile* search(const QString& name);
      };

//---------------------------------------------------------
//   Clip
//---------------------------------------------------------

class Clip {
      QString _name;
      SndFile* f;
      int _spos;        // start sample position in WaveFile
      int len;          // len of clip
      int prefs;        // physical references (incl. undo/redo)
      int lrefs;        // logical references
      bool deleted;

   public:
      Clip();
      Clip(SndFile* f, int start, int len);
      ~Clip();
      const QString& name() const      { return _name;  }
      void setName(const QString& s)   { _name = s;     }
      void incRef();
      int decRef();
      int spos() const                 { return _spos;  }
      void setSpos(int s)              { _spos = s;     }
      SndFile* file1() const            { return f;      }

      void read(unsigned, float**, int, unsigned);
      void read(Xml&);
      void write(int, Xml&) const;
      int samples() const              { return len; }
      void setSamples(int s)           { len = s;    }
      int  references()                { return lrefs; }
      };

class ClipList : public std::list<Clip*> {
   public:
      int idx(Clip*) const;
      Clip* search(const QString&) const;
      void write(int, Xml&) const;
      void add(Clip* clip) { push_back(clip); }
      void remove(Clip*);
      };

typedef ClipList::iterator iClip;
typedef ClipList::const_iterator ciClip;

extern ClipList* waveClips;

extern SndFile* getWave(const QString& name, bool writeFlag);

#endif

