?? g726.c
字號:
/* v2.0 24.Jan.2000============================================================================= U U GGG SSSS TTTTT U U G S T U U G GG SSSS T U U G G S T UUU GG SSS T ======================================== ITU-T - USER'S GROUP ON SOFTWARE TOOLS ======================================== ============================================================= COPYRIGHT NOTE: This source code, and all of its derivations, is subject to the "ITU-T General Public License". Please have it read in the distribution disk, or in the ITU-T Recommendation G.191 on "SOFTWARE TOOLS FOR SPEECH AND AUDIO CODING STANDARDS". =============================================================MODULE: G726.C ADPCM AT 40, 32, 24, AND 16 KBIT/S MODULEORIGINAL BY: Jose' Sindi Yamamoto (Fortran version of the G.721) <tdsindi@venus.cpqd.ansp.br> Simao Ferraz de Campos Neto (C translation, adaptation&testing of the G.721) <simao@venus.cpqd.ansp.br> Fernando Tofolli Queiroz (Extension of the G.721 to the other rates=>G.726) <tofolli@venus.cpqd.ansp.br> Simao Ferraz de Campos Neto (Adaptation and testing of the G.726) <simao@venus.cpqd.ansp.br>HISTORY:28.Feb.1994 v1.0c Version 1.0 in C, by translating Fortran to C (f2c)24.Jan.2000 v2.0 Corrected bug G726_compress() that caused incorrect processing of test vector ri40fa. Corrected code provided by Jayesh Patel <jayesh@dspse.com>. Verified by <simao.campos@labs.comsat.com>FUNCTIONS:Public: G726_encode ..... G726 encoder function; G726_decode ..... G726 decoder function;Private: G726_accum ...... addition of predictor outputs to form the partial signal estimate (from the sixth order predictor) and the signal estimate. G726_adda ....... addition of scale factor to logarithmic version of quantized difference signal. G726_addb ....... addition of quantized difference signal and signal estimate to form reconstructed signal. G726_addc....... obtain sign of addition of quantized difference signal and partial signal estimate. G726_antilog .... convert quantized difference signal from the logarithmic to the linear domain. G726_compress ... convert from uniform pcm to either a-law or u-law pcm. G726_delaya ..... memory block. G726_delayb ..... memory block. G726_delayc ..... memory block. G726_delayd ..... memory block. G726_expand ..... convert either a-law (law=1) or u-law (law=0) to uniform pcm. G726_filta ...... update of short term average of f(i). G726_filtb ...... update of long term average of f(i). G726_filtc ...... low pass filter of speed control parameter. G726_filtd ...... update of fast quantizer scale factor. G726_filte ...... update of slow quantizer scale factor. G726_floata ..... convert 15-bit signed magnitude to floating point. G726_floatb ..... convert 16-bit two's complement to floating point. G726_fmult ...... multiply predictor coefficients with corresponding quantized difference signal or reconstructed signal. Multiplication is done in floating point format. G726_functf ..... map quantizer output into the f(i) function. G726_functw ..... map quantizer output into logarithmic version of scale factor multiplier. G726_lima ....... limit speed control parameter. G726_limb ....... limit quantizer scale factor. G726_limc ....... limits on a2 coefficient of second order predictor. G726_limd ....... limits on a1 coefficient of second order predictor. G726_log ........ convert difference signal from linear to the logarithmic domain. G726_mix ........ form linear combination of fast and slow quantizer scale factors. G726_quan ....... quantize difference signal in logarithmic domain. G726_reconst .... reconstruction of quantized difference signal in the logarithmic domain. G726_subta ...... compute difference signal by subtracting signal estimate from input signal (or quantized reconstructed signal in decoder). G726_subtb ...... scale logarithmic version of difference signal by subtracting scale factor. G726_subtc ...... compute magnitude of the difference of short and long-term function of quantizer output sequence and then perform threshold comparison for quantizing speed control parameter. G726_sync ....... re-encode output pcm sample in decoder for synchronous tandem coding. G726_tone ....... partial band signal detection. G726_trans ...... transition detector. G726_triga ...... speed control trigger block. G726_trigb ...... predictor trigger block. G726_upa1 ....... update a1 coefficient of second order predictor. G726_upa2 ....... update a2 coefficient of second order predictor. G726_upb ........ update for coefficients of sixth order predictor. G726_xor ........ one bit "exclusive or" of sign of difference signal and sign of delayed difference signal.=============================================================================*//* * .................. INCLUDES .................. */#include "g726.h"/* * .................. FUNCTIONS .................. *//* ---------------------------------------------------------------------------- void G726_encode (short *inp_buf, short *out_buf, long smpno, ~~~~~~~~~~~~~~~~ char *law, short rate, short r, G726_state *state); Description: ~~~~~~~~~~~~ Simulation of the ITU-T G.726 ADPCM encoder. Takes the A or mu law input array of shorts `inp_buf' (16 bit, right- justified, without sign extension) of length `smpno', and saves the encoded samples in the array of shorts `out_buf', with the same number of samples and right-justified. The state variables are saved in the structure `state', and the reset can be stablished by making r equal to 1. The law is A if `law'=='1', and mu law if `law'=='0'. Return value: ~~~~~~~~~~~~~ None. Prototype: in file g726.h ~~~~~~~~~~ History: ~~~~~~~~ 31.Jan.91 v1.0f Version 1.0 in Fortran <tdsindi@venus.cpqd.ansp.br> 05.Feb.92 v1.0c Version 1.0 in C, by translating Fortran to C (f2c) <tdsimao@venus.cpqd.ansp.br> ----------------------------------------------------------------------------*/void G726_encode(inp_buf, out_buf, smpno, law, rate, r, state) short *inp_buf, *out_buf; long smpno; char *law; short r; short rate; G726_state *state;{ short s; short d, i; short y; short sigpk; short sr, tr; short yu; short al, fi, dl, ap, dq, ds, se, ax, td, sl, wi; short u1, u2, u3, u4, u5, u6; short a1, a2, b1, b2, b3, b4, b5, b6; short dqln; short a1p, a2p, a1t, a2t, b1p, b2p, b3p, b4p, b5p, b6p, dq6, pk2, sr2, wa1, wa2, wb1, wb2, wb3, wb4, wb5, wb6; short dml, dln, app, dql, dms; short dqs, tdp; short sez; short yut; long yl; long j; /* Invert even bits if A law */ if (*law == '1') { for (j = 0; j < smpno; j++) inp_buf[j] ^= 85; } /* Process all desired samples in inp_buf to out_buf; The comments about * general blocks are given as in G.726, and refer to: 4.1.1 Input PCM * format conversion and difference signal computation 4.1.2 Adaptive * quantizer 4.1.3 Inverse adaptive quantizer 4.1.4 Quantizer scale factor * adaptation 4.1.5 Adaptation speed control 4.1.6 Adaptive predictor and * reconstructed signal calculator 4.1.7 Tone and transition detector 4.1.8 * (Only in the decoder) */ for (j = 0; j < smpno; j++, r = 0) { s = inp_buf[j]; /* Process `known-state' part of 4.2.6 */ G726_delayd(&r, &state->sr1, &sr2); G726_delayd(&r, &state->sr0, &state->sr1); G726_delaya(&r, &state->a2r, &a2); G726_delaya(&r, &state->a1r, &a1); G726_fmult(&a2, &sr2, &wa2); G726_fmult(&a1, &state->sr1, &wa1); G726_delayd(&r, &state->dq5, &dq6); G726_delayd(&r, &state->dq4, &state->dq5); G726_delayd(&r, &state->dq3, &state->dq4); G726_delayd(&r, &state->dq2, &state->dq3); G726_delayd(&r, &state->dq1, &state->dq2); G726_delayd(&r, &state->dq0, &state->dq1); G726_delaya(&r, &state->b1r, &b1); G726_delaya(&r, &state->b2r, &b2); G726_delaya(&r, &state->b3r, &b3); G726_delaya(&r, &state->b4r, &b4); G726_delaya(&r, &state->b5r, &b5); G726_delaya(&r, &state->b6r, &b6); G726_fmult(&b1, &state->dq1, &wb1); G726_fmult(&b2, &state->dq2, &wb2); G726_fmult(&b3, &state->dq3, &wb3); G726_fmult(&b4, &state->dq4, &wb4); G726_fmult(&b5, &state->dq5, &wb5); G726_fmult(&b6, &dq6, &wb6); G726_accum(&wa1, &wa2, &wb1, &wb2, &wb3, &wb4, &wb5, &wb6, &se, &sez); /* Process 4.2.1 */ G726_expand(&s, law, &sl); G726_subta(&sl, &se, &d); /* Process delays and `know-state' part of 4.2.5 */ G726_delaya(&r, &state->dmsp, &dms); G726_delaya(&r, &state->dmlp, &dml); G726_delaya(&r, &state->apr, &ap); G726_lima(&ap, &al); /* Process `know-state' parts of 4.2.4 */ G726_delayb(&r, &state->yup, &yu); G726_delayc(&r, &state->ylp, &yl); G726_mix(&al, &yu, &yl, &y); /* Process 4.2.2 */ G726_log(&d, &dl, &ds); G726_subtb(&dl, &y, &dln); G726_quan(rate, &dln, &ds, &i); /* Save ADPCM quantized sample into output buffer */ out_buf[j] = i; /* Process 4.2.3 */ G726_reconst(rate, &i, &dqln, &dqs); G726_adda(&dqln, &y, &dql); G726_antilog(&dql, &dqs, &dq); /* Part of 4.2.5 */ G726_functf(rate, &i, &fi); G726_filta(&fi, &dms, &state->dmsp); G726_filtb(&fi, &dml, &state->dmlp); /* Remaining part of 4.2.4 */ G726_functw(rate, &i, &wi); G726_filtd(&wi, &y, &yut); G726_limb(&yut, &state->yup); G726_filte(&state->yup, &yl, &state->ylp); /* Process `known-state' part of 4.2.7 */ G726_delaya(&r, &state->tdr, &td); G726_trans(&td, &yl, &dq, &tr); /* More `known-state' parts of 4.2.6: update of `pk's */ G726_delaya(&r, &state->pk1, &pk2); G726_delaya(&r, &state->pk0, &state->pk1); G726_addc(&dq, &sez, &state->pk0, &sigpk); /* 4.2.6: find sr0 */ G726_addb(&dq, &se, &sr); G726_floatb(&sr, &state->sr0); /* 4.2.6: find dq0 */ G726_floata(&dq, &state->dq0); /* 4.2.6: prepar a2(r) */ G726_upa2(&state->pk0, &state->pk1, &pk2, &a2, &a1, &sigpk, &a2t); G726_limc(&a2t, &a2p); G726_trigb(&tr, &a2p, &state->a2r); /* 4.2.6: prepar a1(r) */ G726_upa1(&state->pk0, &state->pk1, &a1, &sigpk, &a1t); G726_limd(&a1t, &a2p, &a1p); G726_trigb(&tr, &a1p, &state->a1r); /* Remaining of 4.2.7 */ G726_tone(&a2p, &tdp); G726_trigb(&tr, &tdp, &state->tdr); /* Remaining of 4.2.5 */ G726_subtc(&state->dmsp, &state->dmlp, &tdp, &y, &ax); G726_filtc(&ax, &ap, &app); G726_triga(&tr, &app, &state->apr); /* Remaining of 4.2.6: update of all `b's */ G726_xor(&state->dq1, &dq, &u1); /* Here, b1 */ G726_upb(rate, &u1, &b1, &dq, &b1p); G726_trigb(&tr, &b1p, &state->b1r); G726_xor(&state->dq2, &dq, &u2); /* Here, b2 */ G726_upb(rate, &u2, &b2, &dq, &b2p); G726_trigb(&tr, &b2p, &state->b2r); G726_xor(&state->dq3, &dq, &u3); /* Here, b3 */ G726_upb(rate, &u3, &b3, &dq, &b3p); G726_trigb(&tr, &b3p, &state->b3r); G726_xor(&state->dq4, &dq, &u4); /* Here, b4 */ G726_upb(rate, &u4, &b4, &dq, &b4p); G726_trigb(&tr, &b4p, &state->b4r); G726_xor(&state->dq5, &dq, &u5); /* Here, b5 */ G726_upb(rate, &u5, &b5, &dq, &b5p); G726_trigb(&tr, &b5p, &state->b5r); G726_xor(&dq6, &dq, &u6); /* At last, b6 */ G726_upb(rate, &u6, &b6, &dq, &b6p); G726_trigb(&tr, &b6p, &state->b6r); }}/* ........................ end of G726_encode() ....................... *//* ---------------------------------------------------------------------------- void G726_decode (short *inp_buf, short *out_buf, long smpno, ~~~~~~~~~~~~~~~~ char *law, short rate, short r, G726_state *state); Description: ~~~~~~~~~~~~ Simulation of the ITU-T G.726 ADPCM decoder. Takes the ADPCM input array of shorts `inp_buf' (16 bit, right- justified, without sign extension) of length `smpno', and saves the decoded samples (A or mu law) in the array of shorts `out_buf', with the same number of samples and right-justified. The state variables are saved in the structure `state', and the reset can be stablished by making r equal to 1. The law is A if `law'=='1', and mu law if `law'=='0'. Return value: ~~~~~~~~~~~~~ None. Prototype: in file g726.h ~~~~~~~~~~ History: ~~~~~~~~ 31.Jan.91 v1.0f Version 1.0 in Fortran <tdsindi@venus.cpqd.ansp.br> 05.Feb.92 v1.0c Version 1.0 in C, by translating Fortran to C (f2c) <tdsimao@venus.cpqd.ansp.br> ----------------------------------------------------------------------------*/void G726_decode(inp_buf, out_buf, smpno, law, rate, r, state) short *inp_buf, *out_buf; long smpno; char *law; short r; short rate; G726_state *state;{ short i; short y; short sigpk; short sr, tr; short sp, dlnx, dsx, sd, slx, dlx, dx; /* these are unique to * the decoder */ long yl; short yu; short al, fi, ap, dq, se, ax, td, wi; short u1, u2, u3, u4, u5, u6; short a1, a2, b1, b2, b3, b4, b5, b6; short dqln; short a1p, a2p, a1t, a2t, b1p, b2p, b3p, b4p, b5p, b6p, dq6, pk2, sr2, wa1, wa2, wb1, wb2, wb3, wb4, wb5, wb6; short dml, app, dql, dms; short dqs, tdp; short sez; short yut; long j; /* Process all desired samples in inp_buf to out_buf; The comments about * general blocks are given as in G.726, and refer to: 4.1.1 Input PCM * format conversion and difference signal computation 4.1.2 Adaptive * quantizer 4.1.3 Inverse adaptive quantizer 4.1.4 Quantizer scale factor * adaptation 4.1.5 Adaptation speed control 4.1.6 Adaptive predictor and * reconstructed signal calculator 4.1.7 Tone and transition detector 4.1.8 * Output PCM format conversion and synchronous coding adjustment */ for (j = 0; j < smpno; j++, r = 0) { /* Process `known-state' part of 4.2.6 */ G726_delayd(&r, &state->sr1, &sr2); G726_delayd(&r, &state->sr0, &state->sr1); G726_delaya(&r, &state->a2r, &a2); G726_delaya(&r, &state->a1r, &a1); G726_fmult(&a2, &sr2, &wa2); G726_fmult(&a1, &state->sr1, &wa1); G726_delayd(&r, &state->dq5, &dq6); G726_delayd(&r, &state->dq4, &state->dq5); G726_delayd(&r, &state->dq3, &state->dq4); G726_delayd(&r, &state->dq2, &state->dq3); G726_delayd(&r, &state->dq1, &state->dq2); G726_delayd(&r, &state->dq0, &state->dq1); G726_delaya(&r, &state->b1r, &b1); G726_delaya(&r, &state->b2r, &b2); G726_delaya(&r, &state->b3r, &b3); G726_delaya(&r, &state->b4r, &b4); G726_delaya(&r, &state->b5r, &b5); G726_delaya(&r, &state->b6r, &b6); G726_fmult(&b1, &state->dq1, &wb1); G726_fmult(&b2, &state->dq2, &wb2); G726_fmult(&b3, &state->dq3, &wb3); G726_fmult(&b4, &state->dq4, &wb4); G726_fmult(&b5, &state->dq5, &wb5); G726_fmult(&b6, &dq6, &wb6); G726_accum(&wa1, &wa2, &wb1, &wb2, &wb3, &wb4, &wb5, &wb6, &se, &sez); /* Process delays and `know-state' part of 4.2.5 */ G726_delaya(&r, &state->dmsp, &dms); G726_delaya(&r, &state->dmlp, &dml); G726_delaya(&r, &state->apr, &ap); G726_lima(&ap, &al); /* Process `know-state' parts of 4.2.4 */ G726_delayb(&r, &state->yup, &yu); G726_delayc(&r, &state->ylp, &yl); G726_mix(&al, &yu, &yl, &y); /* Retrieve ADPCM sample from input buffer */ i = inp_buf[j]; /* Process 4.2.3 */ G726_reconst(rate, &i, &dqln, &dqs); G726_adda(&dqln, &y, &dql); G726_antilog(&dql, &dqs, &dq); /* Process `known-state' part of 4.2.7 */ G726_delaya(&r, &state->tdr, &td); G726_trans(&td, &yl, &dq, &tr); /* Part of 4.2.5 */ G726_functf(rate, &i, &fi); G726_filta(&fi, &dms, &state->dmsp); G726_filtb(&fi, &dml, &state->dmlp); /* Remaining part of 4.2.4 */ G726_functw(rate, &i, &wi); G726_filtd(&wi, &y, &yut); G726_limb(&yut, &state->yup); G726_filte(&state->yup, &yl, &state->ylp); /* More `known-state' parts of 4.2.6: update of `pk's */ G726_delaya(&r, &state->pk1, &pk2);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -