/* This program is distributed under the terms of the 'MIT license'. The text of this licence follows... Copyright (c) 2004 J.D.Medhurst (a.k.a. Tixy) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** @file @brief Implementation of ITU-T (formerly CCITT) Recomendation %G726 */ #ifndef __G726_H__ #define __G726_H__ /** @defgroup g726 Audio Codec - ITU-T Recomendation G726 @{ */ /** @brief A class which implements ITU-T (formerly CCITT) Recomendation G726 "40, 32, 24, 16 kbit/s Adaptive Differential Pulse Code Modulation (ADPCM)" G726 replaces recomendations G721 and G723. Note, this implemetation reproduces bugs found in the G191 reference implementation of %G726. These bugs can be controlled by the #IMPLEMENT_G191_BUGS macro. @see IMPLEMENT_G191_BUGS @version 2005-02-13 - Added constructor G726(), - Added Encode(void* dst, int dstOffset, const void* src, size_t srcSize) and - Added Decode(void* dst, const void* src, int srcOffset, unsigned srcSize); @version 2006-05-20 - Changed code to use standard typedefs, e.g. replaced uint8 with uint8_t, and made use of size_t. @version 2007-01-13 - Fixed GCC compilation warnings. */ class G726 { public: /** Enumeration used to specify the coding law used for encoder input and decoder output. */ enum Law{ uLaw=0, /**< u law */ ALaw=1, /**< A law */ PCM16=2 /**< 16 bit uniform PCM values. These are 'left justified' values corresponding to the 14 bit values in G726 Annex A. */ }; /** Enumeration used to specify the ADPCM bit-rate. */ enum Rate{ Rate16kBits=2, /**< 16k bits per second (2 bits per ADPCM sample) */ Rate24kBits=3, /**< 24k bits per second (3 bits per ADPCM sample) */ Rate32kBits=4, /**< 32k bits per second (4 bits per ADPCM sample) */ Rate40kBits=5 /**< 40k bits per second (5 bits per ADPCM sample) */ }; /** Contructor which initialises the object to the reset state. @see Reset() @since 2005-02-13 */ inline G726() { Reset(); } /** Clears the internal state variables to their 'reset' values. Call this function before starting to decode/encode a new audio stream. */ IMPORT void Reset(); /** Set the encoding law used for encoder input and decoder output. @param law The encoding law. */ IMPORT void SetLaw(Law law); /** Set the ADPCM bit-rate used for encoder output and decoder intput. @param rate The ADPCM bit-rate. */ IMPORT void SetRate(Rate rate); /** Encodes a single PCM value as an ADPCM value. @pre The coding law and ADPCM bit-rate should have been previous initialised with SetLaw() and SetRate(). @param pcm The PCM value to encode. The bits in this value which lie outside the range of values for the currently set encoding law, are ignored. @return The encoded ADPCM value. The number of significant bits in this value are dependant on the bit-rate set by SetRate(). Unused bits are set to zero. */ IMPORT unsigned Encode(unsigned pcm); /** Decodes a single ADPCM value into a PCM value. @pre The coding law and ADPCM bit-rate should have been previous initialised with SetLaw() and SetRate(). @param adpcm The ADPCM value to decode. The bits in this value which lie outside the range of values for the currently set bit-rate, are ignored. @return The decoded PCM value. This is in the format specified by SetLaw(). @see IMPLEMENT_G191_BUGS */ IMPORT unsigned Decode(unsigned adpcm); /** Encode a buffer of uniform PCM values into ADPCM values. Each ADPCM value only occupies the minimum number of bits required and successive values occupy adjacent bit positions. E.g. Four 3 bit ADPCM values (A,B,C,D) are stored in two successive bytes like this: 1st byte: ccbbbaaa 2nd byte: ----dddc. Note that any unused bits in the last byte are set to zero. @pre The coding law and ADPCM bit-rate should have been previous initialised with SetLaw() and SetRate(). @param dst Pointer to location to store ADPCM values. @param dstOffset Offset from \a dst, in number-of-bits, at which the decoded values will be stored. I.e. the least significant bit of the first ADPCM value will be stored in byte @code dst[dstOffset>>3] @endcode at bit position @code dstOffset&7 @endcode Where the bit 0 is the least significant bit in a byte and bit 7 is the most significant bit. @param src Pointer to the buffer of PCM values to be converted. @param srcSize The size in bytes of the buffer at \a src. Must be a multiple of the size of a single PCM sample. @return The number of bits were stored in the \a dst buffer. @since 2005-02-13 */ IMPORT unsigned Encode(void* dst, int dstOffset, const void* src, size_t srcSize); /** Decode a buffer of ADPCM values into uniform PCM values. Each ADPCM value only occupies the minimum number of bits required and successive values occupy adjacent bit positions. E.g. Four 3 bit ADPCM values (A,B,C,D) are stored in two successive bytes like this: 1st byte: ccbbbaaa 2nd byte: ----dddc. @pre The coding law and ADPCM bit-rate should have been previous initialised with SetLaw() and SetRate(). @param dst Pointer to location to store PCM values. @param src Pointer to the buffer of ADPCM values to be converted. @param srcOffset Offset from \a src, in number-of-bits, from which the ADPCM values will be read. I.e. the least significant bit of the first ADPCM value will be read from byte @code src[srcOffset>>3] @endcode at bit position @code srcOffset&7 @endcode Where the bit 0 is the least significant bit in a byte and bit 7 is the most significant bit. @param srcSize The number of bits to be read from the buffer at \a src. Must be a multiple of the size of a single ADPCM value. @return The number of bytes which were stored in the \a dst buffer. @see IMPLEMENT_G191_BUGS @since 2005-02-13 */ IMPORT unsigned Decode(void* dst, const void* src, int srcOffset, unsigned srcSize); private: void InputPCMFormatConversionAndDifferenceSignalComputation(unsigned S,int SE,int& D); void AdaptiveQuantizer(int D,unsigned Y,unsigned& I); void InverseAdaptiveQuantizer(unsigned I,unsigned Y,unsigned& DQ); void QuantizerScaleFactorAdaptation1(unsigned AL,unsigned& Y); void QuantizerScaleFactorAdaptation2(unsigned I,unsigned Y); void AdaptationSpeedControl1(unsigned& AL); void AdaptationSpeedControl2(unsigned I,unsigned y,unsigned TDP,unsigned TR); void AdaptativePredictorAndReconstructedSignalCalculator1(int& SE,int& SEZ); void AdaptativePredictorAndReconstructedSignalCalculator2(unsigned DQ,unsigned TR,int SE,int SEZ,int& SR,int& A2P); void ToneAndTransitionDetector1(unsigned DQ,unsigned& TR); void ToneAndTransitionDetector2(int A2P,unsigned TR,unsigned& TDP); void OutputPCMFormatConversionAndSynchronousCodingAdjustment(int SR,int SE,unsigned Y,unsigned I,unsigned& SD); void DifferenceSignalComputation(int SL,int SE,int& D); void OutputLimiting(int SR,int& S0); unsigned EncodeDecode(unsigned input,bool encode); private: Law LAW; Rate RATE; // Persistant state for DELAY elements... int A1; int A2; unsigned AP; int Bn[6]; unsigned DML; unsigned DMS; unsigned DQn[6]; int PK1; int PK2; unsigned SR1; unsigned SR2; unsigned TD; unsigned YL; unsigned YU; friend class G726Test; }; /** When the source code is compiled with this macro defined, the code will reproduce bugs found in the G191 reference implementation of %G726. These bugs are also required so that the test sequences supplied in %G726 Appendix II produce the 'correct' results. The bugs affect the G726::Decode functions when the coding is uLaw or ALaw. @since 2005-02-13 */ #define IMPLEMENT_G191_BUGS /** @} */ // End of group #endif