📄 g723.cpp
字号:
// Copyright (C) 1999-2001 Open Source Telecom Corporation.//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// As a special exception to the GNU General Public License, permission is// granted for additional uses of the text contained in its release// of ccaudio.//// The exception is that, if you link the ccaudio library with other// files to produce an executable, this does not by itself cause the// resulting executable to be covered by the GNU General Public License.// Your use of that executable is in no way restricted on account of// linking the ccaudio library code into it.//// This exception does not however invalidate any other reasons why// the executable file might be covered by the GNU General Public License.//// This exception applies only to the code released under the// name ccaudio. If you copy code from other releases into a copy of// ccaudio, as the General Public License permits, the exception does// not apply to the code that you add in this way. To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for ccaudio, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.#include "codecs.h"namespace ccAudioCodec {using namespace ost;class g72x{protected: long yl; /* Locked or steady state step size multiplier. */ short yu; /* Unlocked or non-steady state step size multiplier. */ short dms; /* Short term energy estimate. */ short dml; /* Long term energy estimate. */ short ap; /* Linear weighting coefficient of 'yl' and 'yu'. */ short a[2]; /* Coefficients of pole portion of prediction filter. */ short b[6]; /* Coefficients of zero portion of prediction filter. */ short pk[2]; /* * Signs of previous two samples of a partially * reconstructed signal. */ short dq[6]; /* * Previous 6 samples of the quantized difference * signal represented in an internal floating point * format. */ short sr[2]; /* * Previous 2 samples of the quantized difference * signal represented in an internal floating point * format. */ char td; /* delayed tone detect, new in 1988 version */ g72x(); int predictor_zero(); int predictor_pole(); int step_size(); void update(int code_size, int y, int wi, int fi, int dq,int sr, int dqsex);}; class g723_16 : protected g72x, protected AudioCodec{protected: friend class g723; static short _dqlntab[4]; static short _witab[4]; static short _fitab[4]; static short _qtab[1]; g723_16(); Sample decoder(int code); unsigned char encoder(Sample sample); unsigned encode(Linear buffer, void *dest, unsigned lsamples, bool buffered); unsigned decode(Linear buffer, void *source, unsigned lsamples, bool buffered);};class g723_24 : protected g72x, protected AudioCodec{protected: friend class g723; g723_24(); unsigned encode(Linear buffer, void *source, unsigned lsamples, bool buffered ); unsigned decode(Linear buffer, void *dest, unsigned lsamples, bool buffered);};class g723_40 : protected g72x, protected AudioCodec{protected: friend class g723; g723_40(); unsigned encode(Linear buffer, void *source, unsigned lsamples, bool buffered); unsigned decode(Linear buffer, void *dest, unsigned lsamples, bool buffered);};static class g723 : public AudioCodec{ friend class g723_16; friend class g723_24; friend class g723_40;public: g723(Encoding encoding); unsigned encode(Linear buffer, void *source, unsigned lsamples, bool buffered) {return 0;}; unsigned decode(Linear buffer, void *dest, unsigned lsamples, bool buffered) {return 0;}; AudioCodec *getByFormat(const char *format); AudioCodec *getByInfo(Info &info);} g723_3(Audio::g723_3bit), g723_2(Audio::g723_2bit), g723_5(Audio::g723_5bit);g723::g723(Encoding encoding) : AudioCodec("g.723", encoding){ info.framesize = getFrame(encoding); info.framecount = getCount(encoding); info.rate = 8000; info.bitrate = info.framesize * 64000l / info.framecount; info.annotation = "g.723";}AudioCodec *g723::getByInfo(Info &info){ switch(info.encoding) { case g723_2bit: return new g723_16(); case g723_3bit: return new g723_24(); case g723_5bit: return new g723_40(); default: return NULL; }}AudioCodec *g723::getByFormat(const char *options){ return getByInfo(info);}static short power2[15] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000};static int quan(int val, short *table, int size){ int i; for (i = 0; i < size; i++) if (val < *table++) break; return (i);}static int fmult(int an, int srn){ short anmag, anexp, anmant; short wanexp, wanmant; short retval; anmag = (an > 0) ? an : ((-an) & 0x1FFF); anexp = quan(anmag, power2, 15) - 6; anmant = (anmag == 0) ? 32 : (anexp >= 0) ? anmag >> anexp : anmag << -anexp; wanexp = anexp + ((srn >> 6) & 0xF) - 13; wanmant = (anmant * (srn & 077) + 0x30) >> 4; retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) : (wanmant >> -wanexp); return (((an ^ srn) < 0) ? -retval : retval);}static int quantize(int d, int y, short *table, int size){ short dqm; /* Magnitude of 'd' */ short exp; /* Integer part of base 2 log of 'd' */ short mant; /* Fractional part of base 2 log */ short dl; /* Log of magnitude of 'd' */ short dln; /* Step size scale factor normalized log */ int i; /* * LOG * * Compute base 2 log of 'd', and store in 'dl'. */ dqm = abs(d); exp = quan(dqm >> 1, power2, 15); mant = ((dqm << 7) >> exp) & 0x7F; /* Fractional portion. */ dl = (exp << 7) + mant; /* * SUBTB * * "Divide" by step size multiplier. */ dln = dl - (y >> 2); /* * QUAN * * Obtain codword i for 'd'. */ i = quan(dln, table, size); if (d < 0) /* take 1's complement of i */ return ((size << 1) + 1 - i); else if (i == 0) /* take 1's complement of 0 */ return ((size << 1) + 1); /* new in 1988 */ else return (i);}static int reconstruct(int sign, int dqln, int y){ short dql; /* Log of 'dq' magnitude */ short dex; /* Integer part of log */ short dqt; short dq; /* Reconstructed difference signal sample */ dql = dqln + (y >> 2); /* ADDA */ if (dql < 0) return ((sign) ? -0x8000 : 0); /* ANTILOG */ dex = (dql >> 7) & 15; dqt = 128 + (dql & 127); dq = (dqt << 7) >> (14 - dex); return ((sign) ? (dq - 0x8000) : dq);}g72x::g72x(){ int i; yl = 34816L; yu = 544; dms = dml = 0; ap = 0; for(i = 0; i < 6; ++i) { if(i < 2) { a[i] = 0; pk[i] = 0; sr[i] = 0; } b[i] = 0; dq[i] = 0; } td = 0;}int g72x::predictor_zero(){ int i, sum = 0; for(i = 0; i < 6; ++i) sum += fmult(b[i] >> 2, dq[i]); return sum;}int g72x::predictor_pole(){ int i, sum = 0; for(i = 0; i < 2; ++i) sum += fmult(a[i] >> 2, sr[i]); return sum;}int g72x::step_size(){ int y, dif, al; if(ap >= 256) return yu; y = yl >> 6; dif = yu - y; al = ap >> 2; if(dif > 0) y += (dif * al) >> 6; else if(dif < 0) y += (dif * al + 0x3f) >> 6; return y;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -