#ifndef _INPUTSTREAM_CLASS_HPP
#define _INPUTSTREAM_CLASS_HPP

/*
**
** InputStreamC.hpp
**
** $VER: InputStreamC.hpp 1.0 (12.04.98)
**
** $Revision: 1.3 $
** $State: Exp $
** $Date: 1998/08/16 19:03:38 $
**
** $Log: InputStreamC.hpp $
** Revision 1.3  1998/08/16 19:03:38  kakace
** Version Beta3+
**
** Revision 1.2  1998/08/02 15:17:04  kakace
** Fonctionnement OK (Layer 1/2 + Stereo/JStereo)
**
** Revision 1.1  1998/07/24 14:26:53  kakace
** Automatic global CheckIn
**
** Revision 1.19  1998/07/24 14:14:27  kakace
** Version intermédiaire (CheckIn global)
**
** Revision 1.17  1998/07/02 15:52:00  kakace
** Automatic global CheckIn
**
*/


//----------------------------------------------------------------------------------------------------

#ifndef  _INCLUDE_STRING_H
#include <string.h>
#endif

#ifndef  DOS_DOS_H
#include <dos/dos.h>
#endif

#ifndef  _FILEINFOS_CLASS_HPP
#include "FileInfosC.hpp"
#endif


//----------------------------------------------------------------------------------------------------
//======================================== class InputStream =========================================
//----------------------------------------------------------------------------------------------------
//
//   Cette Classe permet de gérer différents types de fichier en entrée (CDDA, PCM ou AIFF par
// exemple). Chaque objet de ce type contient un tampon d'entrée, ainsi que les fonctions nécessaires
// à la gestion de ce tampon.
// Le tampon d'entrée contient toujours des échantillons sur 16 bits, quelque soit le type de fichier.
//
//   Chaque objet de cette classe contient une référence vers l'objet FileInfos décrivant le fichier.
// Cela permet de centraliser les informations de ce fichier dans une seule structure.

const ULONG INPUT_BUFF_SIZE = 2304*96;          // Taille du tampon de lecture.


// Format des échantillons dans le tampon d'entrée.

enum e_AudioFMT {FORMAT_MOTOROLA_MONO = 0,      // bit 0 : 0 = Mono, 1 = Stéréo.
                 FORMAT_MOTOROLA_STEREO,        // bit 1 : 0 = Motorola, 1 = Intel.
                 FORMAT_INTEL_MONO,
                 FORMAT_INTEL_STEREO
                };


//----------------------------------------------------------------------------------------------------

class InputStreamC
{
    public:

        // Constructeur et destructeur.

        InputStreamC(FileInfosC &roFileInfos);      // Constructeur.
        ~InputStreamC() {
            if (istr_pBufferAddr) FreeStreamBuffer();
            if (istr_bpOldDirLock || istr_bpFileHandle) this->CloseStream();
        }

        // Fonctions d'accès aux membres privés (glues vers l'objet FileInfoC)

        ULONG GetSampleFreq()  const {return istr_roFileInfo.GetSampleFreq();}
        UBYTE GetNumChannels() const {return istr_roFileInfo.GetNumChannels();}
        ULONG GetNumFrames()   const {return istr_roFileInfo.GetNumFrames();}
        ULONG GetNumSamples()  const {return istr_roFileInfo.GetNumSamples();}
        LONG  GetIoError()     const {return istr_roFileInfo.GetIoError();}

        STRING GetFileName()    const {return istr_roFileInfo.NodeName();}
        STRING GetPathName()    const {return istr_roFileInfo.GetPathName();}

        // Fonctions de gestion.

        e_AudioFMT GetAudioFormat() const           {return istr_iAudioFormat;}
        void       SetAudioFormat(e_AudioFMT fmt)   {istr_iAudioFormat = fmt;
                                                     istr_roFileInfo.SetByteOrder( (fmt > FORMAT_MOTOROLA_STEREO) ? 1 : 0);}

        ULONG     GetProgression() const {return istr_iProgressValue;}
        u_Time    GetTime()        const {return istr_roFileInfo.GetTime();}

        e_IoErrors AllocStreamBuffer();         // Allouer le tampon de lecture.
        void       FreeStreamBuffer();          // Libérer le tampon de lecture.

        WORD *ReadSamples(UWORD iNumSamples);   // Fonction de lecture des échantillons.
        void  SetRollGap(ULONG iGapSpace)
            {istr_iRollGap = iGapSpace;}

        // Fonctions virtuelles.

        virtual e_IoErrors OpenStream();        // Ouvrir le fichier.
        virtual void       CloseStream();       // Fermer le fichier.

        virtual int  GetFileInfos() = 0;        // Obtenir les informations sur le fichier audio.
        virtual int  OverrideSettings(ULONG iSmplFreq, UBYTE bNumChnl);


    protected:

        // Fonctions virtuelles.

        virtual int     SeekToAudio();      // Se positionner au début du chunk audio.
        virtual LONG    FillBuffer();       // Remplir le tampon de lecture.

        // Fonctions de gestion privées.

        WORD *GetNextBlockAddr(UWORD iNumSamples);
        void  RollBuffer();

        // Fonctions de gestions (glues vers les fonctions de l'objet FileInfo)

        void SetIoError(e_IoErrors iIOErr, LONG iErr2 = 0) const
            {istr_roFileInfo.SetIoError(iIOErr, iErr2);}

        void SetFileType(e_AudioTypes iAT) const {istr_roFileInfo.SetFileType(iAT);}
        void SetNumFrames(ULONG iFrames);

        // Informations pour la gestion du tampon de lecture.

        WORD     *istr_pBufferAddr;         // Adresse du tampon d'entrée
        WORD     *istr_pCurrentPos;         // Dernier pointeur retourné par ReadSamples().
        WORD     *istr_pUpperLimit;         // Limite supérieure du tampon d'entrée.
        LONG      istr_iSamplesRead;        // Nombre total d'échantillons dans le tampon (sert de compteur)
        BOOL      istr_wEOF;                // TRUE si la fin du fichier a été rencontrée.
        BOOL      istr_wContinue;           // FALSE lorsqu'on doit remplir le tampon pour la première fois.

        ULONG     istr_iBufferSize;         // Taille du tampon (en octets).
        ULONG     istr_iRollGap;            // Espace laissé disponible en début de tampon (il est surchargé par une
                                            // copie des dernières données du tampons avant que celui-ci ne soit
                                            // rechargé avec de nouvelles données.

        // Variables utilisées pour calculer le taux de progression.

        ULONG     istr_iSmplProcessed;      // Nombre d'échantillons déjà traités (progression).
        ULONG     istr_iProgressValue;      // Pourcentage de progression
        ULONG     istr_iNextLimit;          // Prochaine valeur Processed qui causera le recalcul de la progression.
        ULONG     istr_iStepMin;            // Valeur minimale faisant changer le taux de progression.

        e_AudioFMT istr_iAudioFormat;       // Format des échantillons dans les tampons audio.

        // Informations concernant le fichier.

        FileInfosC &istr_roFileInfo;        // Référence sur l'objet décrivant le fichier.

        // Informations pour la gestion du fichier.

        BPTR      istr_bpOldDirLock;        // Lock sur le répertoire précédent.
        BPTR      istr_bpNewDirLock;        // Lock sur le répertoire courant.
        BPTR      istr_bpFileHandle;        //
};


//########## Fonctions INLINE ##########


// Constructeur.

inline InputStreamC::InputStreamC(FileInfosC &roFileInfo) : istr_roFileInfo(roFileInfo)
{
    // Initialiser les informations de gestion des tampons.

    istr_pBufferAddr = istr_pCurrentPos = NULL;
    istr_iSamplesRead = istr_iProgressValue = 0L;
    istr_iSmplProcessed = 0L;
}


// Destructeur

// inline InputStreamC::~InputStreamC()
// {
//     if (istr_pBufferAddr) FreeStreamBuffer();
//     if (istr_bpOldDirLock || istr_bpFileHandle) this->CloseStream();
// }


// Définir le nombre de pages, et le nombre d'échantillons.

inline void InputStreamC::SetNumFrames(ULONG iFrames)
{
    istr_iNextLimit = istr_iStepMin = iFrames / (100 >> GetNumChannels());
    istr_roFileInfo.SetNumFrames(iFrames);
}


// Modifier les paramètres du fichier (fréquence d'échantillonage et nombre de canaux).

inline int InputStreamC::OverrideSettings(ULONG iSampleFreq, UBYTE bNumChannels)
{
    return FALSE;                               // Interdiction de modifier les paramètres.
}

//----------------------------------------------------------------------------------------------------
//=========================================== Classe IFF =============================================
//----------------------------------------------------------------------------------------------------

#ifndef  IFF_IFFPARSE_H
#include <libraries/iffparse.h>
#endif

#ifndef  CLIB_IFFPARSE_PROTOS_H
#include <clib/iffparse_protos.h>
#endif


// Classe de base, dérivée pour être spécialisée pour chaque type de fichier IFF.

class IFF_AudioC : public InputStreamC
{
    public:

        // Fonctions de gestion (virtuelles)

        WORD  GetRightSample(UWORD iIndex);     // Lire l'échantillon indiqué (canal droit)
        WORD  GetLeftSample(UWORD iIndex);      // Lire l'échantillon indiqué (canal gauche)
        e_IoErrors OpenStream();                // Ouvrir le fichier.
        void       CloseStream();               // Fermer le fichier.

    protected:

        // Constructeur.

        IFF_AudioC(FileInfosC &roFileInfo) : InputStreamC(roFileInfo) {}

        // Fonctions virtuelles

        int             SeekToAudio();                  // Se positionner au début du chunk audio.
        LONG            FillBuffer();                   // Remplir le tampon de lecture.

        // Fonctions de gestion privées.

        StoredProperty *ReadChunks();                   // Lire le chunk indiqué.
        void            CheckAudioChunk(ULONG iOffset); // Contrôler la taille du chunk audio.

        // Membres données.

        IFFHandle  *istr_pIFF;

        LONG  istr_iAudioDataOffset;     // Nombre d'octets à sauter au début du chunk audio.
        ULONG istr_iTypeChunkID;
        ULONG istr_iHeaderChunkID;
        ULONG istr_iDataChunkID;
};


//----------------------------------------------------------------------------------------------------
//======================================== Classe AIFF_AudioC ========================================
//----------------------------------------------------------------------------------------------------

struct AIFF_SSND {ULONG Offset;
                  ULONG BlockSize;
                 };


class AIFF_AudioC : public IFF_AudioC
{
    public:

        // Constructeur.

        AIFF_AudioC(FileInfosC &roFileInfo) : IFF_AudioC(roFileInfo)
        {
            istr_iTypeChunkID   = 'AIFF';
            istr_iHeaderChunkID = 'COMM';
            istr_iDataChunkID   = 'SSND';
            istr_iAudioDataOffset = sizeof(struct AIFF_SSND);
        }

        // Fonctions virtuelles.

        int  GetFileInfos();                 // Obtenir les informations sur le fichier audio.
};


//----------------------------------------------------------------------------------------------------
//======================================== Classe MAUD_AudioC ========================================
//----------------------------------------------------------------------------------------------------

class MAUD_AudioC : public IFF_AudioC
{
    public:

        // Constructeur.

        MAUD_AudioC(FileInfosC &roFileInfo) : IFF_AudioC(roFileInfo)
        {
            istr_iTypeChunkID   = 'MAUD';
            istr_iHeaderChunkID = 'MHDR';
            istr_iDataChunkID   = 'MDAT';
            istr_iAudioDataOffset = 0;
        }

        // Fonctions virtuelles.

        int  GetFileInfos();                 // Obtenir les informations sur le fichier audio.
};


//----------------------------------------------------------------------------------------------------
//========================================== Classe RAW/PCM ==========================================
//----------------------------------------------------------------------------------------------------

class RAW_AudioC : public InputStreamC
{
    public:

        // Constructeur.

        RAW_AudioC(FileInfosC &roFileInfo) : InputStreamC(roFileInfo) {}

        // Fonctions de gestion (virtuelles)

        int   GetFileInfos();                   // Obtenir les informations sur le fichier audio.
        int   OverrideSettings(ULONG iSampleFreq, UBYTE bNumChannels);
};


//----------------------------------------------------------------------------------------------------
//========================================= Classe RIFF-WAV ==========================================
//----------------------------------------------------------------------------------------------------

class WAV_AudioC : public InputStreamC
{
    public:

        // Constructeur.

        WAV_AudioC(FileInfosC &roFileInfo) : InputStreamC(roFileInfo) {}

        // Fonctions de gestion (virtuelles)

        int   GetFileInfos();                   // Obtenir les informations sur le fichier audio.

    private:

        // Fonctions virtuelles.

        int   SeekToAudio();                    // Se positionner au début du chunk audio.

        // Fonctions de gestion.

        ULONG LocateChunk(ULONG iChunkID);      // Chercher un chunk précis.

        ULONG istr_iChannelSize;                // Nombre d'échantillons par canal.
};


//----------------------------------------------------------------------------------------------------
//=========================================== Classe CDDA ============================================
//----------------------------------------------------------------------------------------------------

class CDDA_AudioC : public InputStreamC
{
    public:

        // Constructeur.

        CDDA_AudioC(FileInfosC &roFileInfo) : InputStreamC(roFileInfo) {}

        // Fonctions de gestion (virtuelles)

        int  GetFileInfos();                   // Obtenir les informations sur le fichier audio.
//      int  OverrideSettings(ULONG iSampleFreq, UBYTE bNumChannels);
};


//----------------------------------------------------------------------------------------------------

#endif          // _INPUTSTREAM_CLASS_HPP

