home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 14 / MA_Cover_14.iso / source / c / pegase_src / coderc.hpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-15  |  16.1 KB  |  427 lines

  1. #ifndef  _CODER_CLASS_HPP
  2. #define  _CODER_CLASS_HPP
  3.  
  4. /*
  5. **
  6. ** CoderC.hpp
  7. **
  8. ** $VER: CoderC.hpp 1.0 (19.04.98)
  9. **
  10. ** $Revision: 1.4 $
  11. ** $State: Exp $
  12. ** $Date: 1998/08/16 19:03:38 $
  13. **
  14. ** $Log: CoderC.hpp $
  15. ** Revision 1.4  1998/08/16 19:03:38  kakace
  16. ** Version Beta3+
  17. **
  18. ** Revision 1.3  1998/08/02 15:17:05  kakace
  19. ** Fonctionnement OK (Layer 1/2 + Stereo/JStereo)
  20. **
  21. ** Revision 1.2  1998/07/27 02:16:38  kakace
  22. ** Séparation de la classe PsychoC
  23. **
  24. ** Revision 1.1  1998/07/24 14:26:53  kakace
  25. ** Automatic global CheckIn
  26. **
  27. */
  28.  
  29. #define USE_QUICK_PUTBITS
  30.  
  31.  
  32. //----------------------------------------------------------------------------------------------------
  33.  
  34. #ifndef  _PEGASECOND_HPP
  35. #include "PegaseCond.hpp"
  36. #endif
  37.  
  38. #ifndef  _INPUTSTREAM_CLASS_HPP
  39. #include "InputStreamC.hpp"
  40. #endif
  41.  
  42. #ifndef  _FILEINFOS_CLASS_HPP
  43. #include "FileInfosC.hpp"
  44. #endif
  45.  
  46.  
  47. //----------------------------------------------------------------------------------------------------
  48. //=========================================== Définitions ============================================
  49. //----------------------------------------------------------------------------------------------------
  50.  
  51. // Status de l'encodeur.
  52.  
  53. enum e_EncoderST {
  54.         ESTAT_READY,                    // Encodeur prêt à fonctionner.
  55.         ESTAT_WARNING,                  // Avertissement.
  56.         ESTAT_NOTREADY,                 // Encodeur non prêt.
  57.         ESTAT_NOMEMORY,                 // Plus assez de mémoire.
  58.         ESTAT_IOERROR,                  // Erreur I/O
  59.         ESTAT_NOTSUPPORTED              // Layer non supporté.
  60.     };
  61.  
  62. // Codes d'erreur secondaires.
  63.  
  64. enum e_EncErrCodes {
  65.         ERR_NONE,                       // Pas d'erreur.
  66.         ERR_NOT_INITIALIZED,            // Encodeur pas encore initialisé.
  67.         ERR_ISTREAM_FAILURE,            // Erreur pendant la création du flux d'entrée.
  68.         ERR_INTERNAL_BUFFERS,           // Des tampons n'ont pas pu être alloués.
  69.         ERR_OPEN_OSTREAM,               // Erreur pendant l'ouverture du fichier de sortie.
  70.         ERR_SEEK_OSTREAM,               // Erreur lors du positionnement en fin de fichier.
  71.         ERR_WRITE_OSTREAM,              // Erreur pendant l'écriture du tampon de sortie.
  72.         ERR_CLOSE_OSTREAM,              // Erreur pendant la fermeture du fichier de sortie.
  73.         ERR_BAD_FREQUENCY,              // Fréquence d'échantillonage non acceptée.
  74.     };
  75.  
  76. // Constantes diverses.
  77.  
  78. const ULONG SCALE_BLOCK =   12;
  79. const ULONG HAN_SIZE    =  512;
  80. const ULONG SCALE_RANGE =   64;
  81. const ULONG LOGBLKSIZE  =   10;
  82. const ULONG CBANDS      =   63;
  83. const ULONG SBLIMIT     =   32;
  84. const ULONG MAX_CH      =    2;
  85.  
  86. const REAL  CB_FRACTION =    0.33;
  87. const REAL  DBMIN       = -200.0;
  88. const REAL  POWERNORM   =   90.308998699194;    // 20 × Log10(32768)
  89. const REAL  LXMIN       =   32.0;
  90. const REAL  LN_TO_LOG10 =    0.2302585092994;   // log(10) / 10
  91. const REAL  LOG10_005   =   -1.301029995664;    // Log10(0.05)
  92. const REAL  LOG10_05    =   -0.301029995664;    // Log10(0.5)
  93. const REAL  LOG10_2     =    0.301029995664;    // Log10(2)
  94. const REAL  LOG10_TO_LN =    4.3429448190325;   // 10 / log(10)
  95. const REAL  SQRT_00005  =    0.022360679775;    // sqrt(0.0005)
  96.  
  97.  
  98. // Constantes personnelles (certaines sont basées sur de simples suppositions de ma part...)
  99.  
  100. const ULONG FRAME_SIZE    = SCALE_BLOCK * SBLIMIT;      // =  384
  101. const ULONG MAX_FRAMESETS = 3;
  102. const ULONG BIGGEST_FRAME = FRAME_SIZE * MAX_FRAMESETS; // = 1152
  103.  
  104. const ULONG OUTPUT_BUFFSIZE = 64 * 1024;                // 64 Ko (Attention au MaxTransfert)
  105.  
  106.  
  107. //----------------------------------------------------------------------------------------------------
  108. //========================================== Classe CoderC ===========================================
  109. //----------------------------------------------------------------------------------------------------
  110. //
  111. //  Classe de base, dérivée pour obtenir une classe spécialisée par Layer.
  112.  
  113. typedef float T_ANAWINDOW;
  114.  
  115.  
  116. class PsychoC;
  117.  
  118. class CoderC : public EncoderConfigC
  119. {
  120.     public:
  121.  
  122.         // Fonctions de traitement virtuelles.
  123.  
  124.         virtual int     Encode() = 0;
  125.         virtual ULONG   BitsForNoNoise() = 0;
  126.         virtual void    OneBitAllocation() = 0;
  127.         virtual int     GetAudio();
  128.  
  129.         // Fonctions d'accès aux membres privés.
  130.  
  131.         void SetErrorCodes(e_EncoderST iPrimaryError, e_EncErrCodes iSecondaryError)
  132.         {
  133.             enc_iEncoderStatus  = iPrimaryError;
  134.             enc_iSecondaryError = iSecondaryError;
  135.         }
  136.  
  137.         e_EncoderST   GetEncoderStatus()  const {return enc_iEncoderStatus;}
  138.         e_EncErrCodes GetSecondaryError() const {return enc_iSecondaryError;}
  139.  
  140.         ULONG       GetProgression()   const    {return enc_pInputHandle->GetProgression();}
  141.         ULONG       GetNumChannels()   const    {return enc_bStereo;}
  142.         WORD       *GetSamplePtr()     const    {return enc_pwSampleBuffer;}
  143.  
  144.     protected:
  145.  
  146.         // Constructeur et destructeur.
  147.  
  148.         CoderC(FileInfosC &roFileInfos, ULONG iReserved = 0);
  149.         virtual ~CoderC();                      // Destructeur virtuel.
  150.  
  151.         // Fonctions "privées"
  152.  
  153.         typedef REAL  T_SubBandSmplStereo[MAX_CH][SCALE_BLOCK][SBLIMIT];
  154.         typedef REAL  T_SubBandSmplMono[SCALE_BLOCK][SBLIMIT];
  155.         typedef LONG  T_2_SBLIMIT[MAX_CH][SBLIMIT];
  156.         typedef UBYTE T_ScaleStereo[MAX_CH][SBLIMIT];
  157.         typedef UBYTE T_ScaleMono[SBLIMIT];
  158.         typedef REAL  T_AnaFilter[128];
  159.  
  160.         typedef LONG T_F2_32[MAX_CH][SBLIMIT];
  161.  
  162.         void  SubBandCoding_Stereo(T_SubBandSmplStereo *pdSample);
  163.         void  SubBandCoding_Mono(T_SubBandSmplMono *pdSample);
  164.  
  165.         void  ScaleFactor(T_ScaleStereo *pScalar, T_SubBandSmplStereo *pSample);
  166.         void  ScaleFactorCalc(UBYTE *pbScalar, T_SubBandSmplMono *pdSample);
  167.  
  168.         void  MixChannels(T_SubBandSmplStereo *pSample, T_SubBandSmplMono *pJSample);
  169.         void  MainBitAllocation();
  170.  
  171.         void  InitSlotsPerFrame(UWORD wSamplesPerFrame, UWORD wNumBitsN);
  172.         void  SetJSBound(UBYTE mode_ext) {enc_bJSBound = (mode_ext + 1) * 4;}
  173.  
  174.         void  UpdateCRC(ULONG iData, ULONG iLength);
  175.         void  CRC_Calc();
  176.         void  FillFrame();
  177.  
  178.         // Fonction d'écriture dans le fichier destination.
  179.  
  180.     #ifdef USE_QUICK_PUTBITS
  181.         void    PutBits(ULONG iSource, ULONG iLength) {
  182.             UWORD *p = BitBuffPtr;
  183.             *p++ = iLength;
  184.             *p++ = iSource;
  185.             BitBuffPtr = p;
  186.         }
  187.         void    InitBitBuffer() {BitBuffPtr = bit_buffer;}
  188.  
  189.         UWORD   *BitBuffPtr;
  190.     #else
  191.         void    PutBits(ULONG iSource, ULONG iLength);
  192.     #endif
  193.  
  194.         // Membres données.
  195.  
  196.         FileInfosC      &enc_roFileInfos;           // Objet FileInfosC.
  197.         PsychoC         *enc_poPsychoC;             // Objet PsychoC.
  198.         InputStreamC    *enc_pInputHandle;          // Handle vers le flux d'entrée.
  199.         e_EncoderST      enc_iEncoderStatus;        // Statut de l'encodeur (codes d'erreur, etc)
  200.         e_EncErrCodes    enc_iSecondaryError;       // Code d'erreur secondaire.
  201.  
  202.         // Variables générales.
  203.  
  204.         UWORD            enc_wSamplesPerFrame;      // Nombre d'échantillons par page.
  205.         UBYTE            enc_bBitsPerSlot;          // Nombre de bits par Slot.
  206.         UBYTE            enc_bBitsPerSlotN;         // Décalage en rapport avec le nombre de bits par Slot.
  207.  
  208.         LONG             enc_iAvgDataBits;          // (adb)
  209.         UWORD            enc_wSlotsPerFrame;        // Nombre de Slots par page.
  210.         UWORD            enc_wSPF_Reminder;         //
  211.         UWORD            enc_wSlotFree;             // Place disponible dans le dernier slot utilisé.
  212.         WORD             enc_wFrameSize;            // Nombre d'échantillons lus à chaque passe.
  213.  
  214.         WORD            *enc_pSamples;              // Pointeur vers le buffer contenant les échantillons.
  215.         WORD            *enc_pwSampleBuffer;        // Pointeur vers les échantillons à encoder.
  216.         T_AnaFilter     *enc_pdAnaFilter;
  217.         WORD            *enc_pSB_ActualPtr;         // Pointeur de lecture dans le tampon d'entrée
  218.         T_F2_32          enc_LTMin;                 // ltmin[][]
  219.         T_ScaleStereo    enc_bBitAlloc;             // bit_alloc[][]
  220.         ULONG            enc_iFrameNumber;          // Numéro de la page courante.
  221.         UBYTE            enc_bStereo;               // 1 = Mono, 2 = Stéréo/Joint-stéréo/Dual-Channel
  222.         UBYTE            enc_bPad;
  223.         UBYTE            enc_bSBLimit;              // Valeur SBLIMIT suivant le type de Layer.
  224.         UBYTE            enc_bJSBound;              // Valeur "jsbound".
  225.         ULONG            enc_iMinNeededBits;        // Nombre de bits nécessaires pour l'entête et le CRC.
  226.         UWORD            enc_wCRC;                  // Somme de contrôle.
  227.         UWORD            enc_wPad;
  228.                                                     // (évolue au fur et à mesure de la progression).
  229.  
  230.         // Bloc d'entête pour chaque "frame"
  231.  
  232.         struct BSHeader {LONGBITS bsh_SyncWord:12;
  233.                          LONGBITS bsh_Version:1;
  234.                          LONGBITS bsh_Layer:2;
  235.                          LONGBITS bsh_CRC:1;
  236.                          LONGBITS bsh_Bitrate:4;
  237.                          LONGBITS bsh_SmplFreq:2;
  238.                          LONGBITS bsh_Padding:1;
  239.                          LONGBITS bsh_Extension:1;
  240.                          LONGBITS bsh_Mode:2;
  241.                          LONGBITS bsh_ModeExt:2;
  242.                          LONGBITS bsh_Copyright:1;
  243.                          LONGBITS bsh_Original:1;
  244.                          LONGBITS bsh_Emphasis:2;
  245.                         };
  246.  
  247.         union BitStreamHeader {ULONG    iBSHeader;
  248.                                BSHeader sBSHeader;
  249.                               } enc_BSHeader;
  250.  
  251.         double enc_adMultiples[64];
  252.  
  253.     private:
  254.  
  255.         void    InitAnaFilter();
  256.         int     GetIndex(double real);
  257.         int     GetIndex(float real);
  258.         void    WriteBuffer();
  259.         void    InitWrite();
  260.         void    CleanupWrite();
  261.  
  262.         // Gestion du fichier encodé.
  263.         // NE PAS TOUCHER A CETTE STRUCTURE SANS MODIFIER AUSSI LE SOURCE ASM !!!
  264.  
  265.         struct s_OutputStream {void   *pOutputBuffer;
  266.                                ULONG   iOB_BitIndex;
  267.                                ULONG   iOB_TotalBits;
  268.                                ULONG   iOB_BitsFree;
  269.                               };
  270.  
  271.         s_OutputStream   enc_sOutputStreamDatas;
  272.         BPTR             enc_bpOB_FileLock;
  273.  
  274.     #ifdef USE_QUICK_PUTBITS
  275.         UWORD   bit_buffer[6000];
  276.     #endif
  277.  
  278. #if _USE_ASM_FCT_ == 1 || _CPUMODEL_ == 68020
  279.         void PutBitsASM(s_OutputStream *pStreamDatas, ULONG iValue, ULONG iLength);
  280.         void PutBitsASM2(s_OutputStream *pStreamDatas, UWORD *buffer, UWORD *lastPos);
  281. #endif
  282. };
  283.  
  284.  
  285. //----------------------------------------------------------------------------------------------------
  286. //========================================= Classe CoderL1C ==========================================
  287. //----------------------------------------------------------------------------------------------------
  288. //
  289. //  Encodage Layer 1
  290.  
  291. class CoderL1C : public CoderC
  292. {
  293.     public:
  294.  
  295.         CoderL1C(FileInfosC &roFileInfos);
  296.         ~CoderL1C();
  297.  
  298.         void    CRC_Calc();
  299.         void    EncodeScale();          // encode_scale + encode_bit_alloc
  300.         void    EncodeSamples();
  301.         void    EncodeSubBand();
  302.  
  303.         // Fonctions virtuelles.
  304.  
  305.         int     GetAudio();
  306.         ULONG   BitsForNoNoise();
  307.         void    OneBitAllocation();
  308.         int     Encode();
  309.  
  310.     private:
  311.  
  312.         // Tableaux et autres tampons globaux
  313.  
  314.         T_SubBandSmplStereo *enc_pdSB_Samples;          // Tampon des échantillons pré-analysés.
  315.         T_SubBandSmplMono   *enc_pdJ_Samples;           // Tampon des échantillons pré-analysés (JOINTSTEREO)
  316.         T_ScaleStereo        enc_bScalar;               // Tableau des indices vers le tableau multiple[].
  317.         T_ScaleMono          enc_bJScale;               // Tableau des indices vers le tableau multiple[] (JOINTSTEREO)
  318.  
  319.         static LONG         snr[15];
  320.         static REAL         quant_a[14];
  321. };
  322.  
  323. LONG CoderL1C::snr[15] = {    0,  7000, 16000, 25280, 31590, 37750, 43840,
  324.                           49890, 55930, 61960, 67980, 74010, 80030, 86050,
  325.                           92010
  326.                          };
  327.  
  328. REAL CoderL1C::quant_a[14] = {0.750000000, 0.875000000, 0.968750000, 0.984375000,
  329.                               0.992187500, 0.996093750, 0.998046875, 0.999023438,
  330.                               0.999511719, 0.999755859, 0.999877930, 0.999938965,
  331.                               0.999969482, 0.999984741
  332.                              };
  333.  
  334.  
  335. //----------------------------------------------------------------------------------------------------
  336. //========================================= Classe CoderL2C ==========================================
  337. //----------------------------------------------------------------------------------------------------
  338. //
  339. //  Encodage Layer 2
  340.  
  341. #define MAX_ALLOC_TABLES     4
  342. #define MAX_ALLOC_LINES     30
  343. #define MAX_ALLOC_COLS      16
  344.  
  345.  
  346. class CoderL2C : public CoderC
  347. {
  348.     public:
  349.  
  350.         CoderL2C(FileInfosC &roFileInfos);
  351.         ~CoderL2C();
  352.  
  353.         void    CRC_Calc();
  354.         void    EncodeScale();          // encode_scale() + encode_bit_alloc()
  355.         void    EncodeSamples();
  356.         void    EncodeSubBand();
  357.  
  358.         // Fonctions virtuelles.
  359.  
  360.         int     GetAudio();
  361.         ULONG   BitsForNoNoise();
  362.         void    OneBitAllocation();
  363.         int     Encode();
  364.  
  365.     private:
  366.  
  367.         // Données nécessaires à la génération des tables d'encodage.
  368.  
  369.         struct s_InitTbl { UWORD wSteps;
  370.                            UBYTE bBits;
  371.                            UBYTE bGroup;
  372.                            UBYTE bQuant;
  373.                          };
  374.  
  375.         struct s_SBAlloc { UWORD  wSteps;                     // Valeurs = [0,65535]
  376.                            UBYTE  bBits;                      // Valeurs = [2;16]
  377.                            UBYTE  bGroup;                     // Valeurs = [0;3]
  378.                            UWORD  wQuant;                     // valeurs = [0;16]
  379.                            UWORD  wStepMask;
  380.                            ULONG  iTotalBits;                 // SCALE_BLOCK * iGroup * iBits
  381.                            ULONG  iBitMask;                   // 1 << iBits
  382.                          };
  383.  
  384.         typedef s_SBAlloc T_AllocTable[MAX_ALLOC_LINES][MAX_ALLOC_COLS];
  385.  
  386.         UBYTE InitAllocTables(T_AllocTable *paTable, UBYTE iTable);
  387.         void  TransmissionPattern();
  388.  
  389.         T_AllocTable        *enc_psAllocTable;      // Table courante.
  390.  
  391.         // Tableaux et autres tampons globaux
  392.  
  393.         typedef REAL  T_SB_Samples[MAX_FRAMESETS][MAX_CH][SCALE_BLOCK][SBLIMIT];
  394.         typedef REAL  T_J_Samples[MAX_FRAMESETS][SCALE_BLOCK][SBLIMIT];
  395.         typedef UBYTE T_Scalar[MAX_FRAMESETS][MAX_CH][SBLIMIT];
  396.         typedef UBYTE T_JScale[MAX_FRAMESETS][SBLIMIT];
  397.  
  398.         T_SB_Samples    *enc_pdSB_Samples;          // Tampon des échantillons pré-analysés.
  399.         T_J_Samples     *enc_pdJ_Samples;           // Tampon des échantillons pré-analysés (JOINTSTEREO)
  400.         T_Scalar         enc_bScalar;               // Tableau des indices vers le tableau multiple[].
  401.         T_JScale         enc_bJScale;               // Tableau des indices vers le tableau multiple[] (JOINTSTEREO)
  402.         T_ScaleStereo    enc_bScaleFactorInfo;      // scfsi[][]
  403.  
  404.         static LONG         snr[18];
  405.         static ULONG        sfsPerScfsi[4];
  406.         static REAL         quant_a[17];
  407. };
  408.  
  409. LONG CoderL2C::snr[18] = {    0,  7000, 11000, 16000, 20840, 25280,
  410.                           31590, 37750, 43840, 49890, 55930, 61960,
  411.                           67980, 74010, 80030, 86050, 92010, 98010
  412.                          };
  413.  
  414. ULONG CoderL2C::sfsPerScfsi[] = {20, 14, 8, 14};
  415.  
  416. REAL CoderL2C::quant_a[17] = {0.750000000, 0.625000000, 0.875000000, 0.562500000, 0.937500000,
  417.                               0.968750000, 0.984375000, 0.992187500, 0.996093750, 0.998046875,
  418.                               0.999023438, 0.999511719, 0.999755859, 0.999877930, 0.999938965,
  419.                               0.999969482, 0.999984741
  420.                              };
  421.  
  422.  
  423. //----------------------------------------------------------------------------------------------------
  424.  
  425. #endif  // _CODER_CLASS_HPP
  426.  
  427.