├── melp_dll_pepper.zip ├── Build ├── VS2008 │ ├── Melp_lib │ │ ├── test_in.raw │ │ ├── test_out.raw │ │ ├── Melp_lib.sln │ │ └── Melp_lib.vcproj │ └── Test_vec │ │ ├── test_in.raw │ │ ├── test_out.raw │ │ ├── test_out-etalon.raw │ │ └── Test_vec.vcproj ├── ARM Keil │ ├── RTE │ │ ├── Device │ │ │ └── STM32F401RE │ │ │ │ └── RTE_Device.h │ │ └── RTE_Components.h │ └── MELP.uvoptx └── Periph.ini ├── fs.h ├── ARM ├── Serial.h ├── Serial.c └── Retarget.c ├── pit.h ├── spbstd.h ├── lpc.h ├── melp_sub.h ├── vq.h ├── dsp_sub.h ├── mat_lib.c ├── mat.h ├── fs_lib.c ├── melp_chn.c ├── melp.h ├── melp_ana.c ├── main.c ├── pit_lib.c ├── coeff.c ├── vq_lib.c ├── lpc_lib.c ├── melp_syn.c ├── dsp_sub.c ├── melp_sub.c └── fec_code.c /melp_dll_pepper.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DigitalHERMES/MELP_float/master/melp_dll_pepper.zip -------------------------------------------------------------------------------- /Build/VS2008/Melp_lib/test_in.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DigitalHERMES/MELP_float/master/Build/VS2008/Melp_lib/test_in.raw -------------------------------------------------------------------------------- /Build/VS2008/Test_vec/test_in.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DigitalHERMES/MELP_float/master/Build/VS2008/Test_vec/test_in.raw -------------------------------------------------------------------------------- /Build/VS2008/Melp_lib/test_out.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DigitalHERMES/MELP_float/master/Build/VS2008/Melp_lib/test_out.raw -------------------------------------------------------------------------------- /Build/VS2008/Test_vec/test_out.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DigitalHERMES/MELP_float/master/Build/VS2008/Test_vec/test_out.raw -------------------------------------------------------------------------------- /Build/VS2008/Test_vec/test_out-etalon.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DigitalHERMES/MELP_float/master/Build/VS2008/Test_vec/test_out-etalon.raw -------------------------------------------------------------------------------- /Build/ARM Keil/RTE/Device/STM32F401RE/RTE_Device.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DigitalHERMES/MELP_float/master/Build/ARM Keil/RTE/Device/STM32F401RE/RTE_Device.h -------------------------------------------------------------------------------- /Build/Periph.ini: -------------------------------------------------------------------------------- 1 | MAP 0x40000000, 0x4002FFFF Read Write // map peripherals 2 | MAP 0x20000000, 0x2002FFFF Read Write // map memory 3 | MAP 0x60000000, 0x600FFFFF Read Write // map memory for fread 4 | MAP 0x70000000, 0x700FFFFF Read Write // map memory for fwrite 5 | ##load ..\Test_files\test11i.hex -------------------------------------------------------------------------------- /Build/ARM Keil/RTE/RTE_Components.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Auto generated Run-Time-Environment Component Configuration File 4 | * *** Do not modify ! *** 5 | * 6 | * Project: 'MELP' 7 | * Target: 'MELP' 8 | */ 9 | 10 | #ifndef RTE_COMPONENTS_H 11 | #define RTE_COMPONENTS_H 12 | 13 | #define RTE_DEVICE_STARTUP_STM32F4XX /* Device Startup for STM32F4 */ 14 | 15 | #endif /* RTE_COMPONENTS_H */ 16 | -------------------------------------------------------------------------------- /fs.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | 20 | fs.h: Fourier series functions include file 21 | 22 | */ 23 | 24 | void fft(float *datam1,int nn,int isign); 25 | void find_harm(float input[], float mag[],float pitch,int num_harm,int length); 26 | void idft_real(float real[], float signal[], int length); 27 | -------------------------------------------------------------------------------- /ARM/Serial.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------- 2 | * Name: Serial.h 3 | * Purpose: Low level serial definitions 4 | * Note(s): 5 | *---------------------------------------------------------------------------- 6 | * This file is part of the uVision/ARM development tools. 7 | * This software may only be used under the terms of a valid, current, 8 | * end user licence from KEIL for a compatible version of KEIL software 9 | * development tools. Nothing else gives you the right to use this software. 10 | * 11 | * This software is supplied "AS IS" without warranties of any kind. 12 | * 13 | * Copyright (c) 2010-2013 Keil - An ARM Company. All rights reserved. 14 | *----------------------------------------------------------------------------*/ 15 | 16 | #ifndef __SERIAL_H 17 | #define __SERIAL_H 18 | 19 | extern void SER_Init (void); 20 | extern int SER_GetChar (void); 21 | extern int SER_PutChar (int c); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /pit.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | */ 16 | 17 | /* 18 | 19 | pit.h: include file for pitch subroutines 20 | 21 | */ 22 | 23 | /* External function definitions */ 24 | float double_chk(float sig_in[], float *pcorr, float pitch, float pdouble, int pmin, int pmax, int lmin); 25 | void double_ver(float sig_in[], float *pcorr, float pitch, int pmin, int pmax, int lmin); 26 | float find_pitch(float sig_in[],float *pcorr,int lower,int upper,int length); 27 | float frac_pch(float sig_in[], float *pcorr, float pitch, int range, int pmin, int pmax, int lmin); 28 | float pitch_ana(float sig_in[], float resid[], float pitch_est, float pitch_avg, float *pcorr); 29 | 30 | void pitch_ana_init(void); 31 | 32 | float p_avg_update(float pitch, float pcorr, float pthresh); 33 | void p_avg_init(void); 34 | 35 | -------------------------------------------------------------------------------- /spbstd.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | spbstd.h SPB standard header file. 20 | 21 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 22 | */ 23 | 24 | #ifndef _spbstd_h 25 | #define _spbstd_h 26 | 27 | /* 28 | ** Needed include files. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | /* OSTYPE-dependent definitions/macros. */ 37 | 38 | /* 39 | ** Constant definitions. 40 | */ 41 | #ifndef TRUE 42 | #define TRUE 1 43 | #endif 44 | #ifndef FALSE 45 | #define FALSE 0 46 | #endif 47 | #ifndef M_PI 48 | #define M_PI 3.14159265358979323846f 49 | #endif 50 | 51 | /* 52 | ** Macros. 53 | */ 54 | #ifndef SQR 55 | #define SQR(x) ((x)*(x)) 56 | #endif 57 | 58 | #endif /* #ifndef _spbstd_h */ 59 | -------------------------------------------------------------------------------- /lpc.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | lpc.h LPC include file. 20 | */ 21 | 22 | 23 | /* bandwidth expansion function */ 24 | int lpc_bw_expand(float *a, float *aw, float gamma, int p); 25 | 26 | /* sort LSPs and ensure minimum separation */ 27 | int lpc_clamp(float *w, float delta, int p); 28 | 29 | /* lpc conversion routines */ 30 | /* convert predictor parameters to LSPs */ 31 | int lpc_pred2lsp(float *a,float *w,int p); 32 | /* convert predictor parameters to reflection coefficients */ 33 | int lpc_pred2refl(float *a,float *k,int p); 34 | /* convert LSPs to predictor parameters */ 35 | int lpc_lsp2pred(float *w,float *a,int p); 36 | /* convert reflection coefficients to predictor parameters */ 37 | int lpc_refl2pred(float *k,float *a,int p); 38 | 39 | /* schur recursion */ 40 | float lpc_schur(float *r, float *a, int p); 41 | 42 | /* evaluation of |A(e^jw)|^2 at a single point (using Horner's method) */ 43 | float lpc_aejw(float *a,float w,int p); 44 | 45 | 46 | -------------------------------------------------------------------------------- /melp_sub.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | 20 | melp_sub.h: include file for MELP subroutines 21 | 22 | */ 23 | 24 | void dc_rmv(float sigin[], float sigout[], float dcdel[], int frame); 25 | void bpvc_ana(float speech[], float fpitch[], float bpvc[], float sub_pitch[]); 26 | void bpvc_ana_init(void); 27 | float gain_ana(float sigin[], float pitch, int minlength, int maxlength); 28 | void q_gain(float *gain,int *gain_index,float qlow,float qup,int qlev); 29 | void q_gain_dec(float *gain,int *gain_index,float qlow,float qup,int qlev); 30 | int q_bpvc(float *bpvc,int *bpvc_index,float bpthresh,int num_bands); 31 | void q_bpvc_dec(float *bpvc,int *bpvc_index,int uv_flag,int num_bands); 32 | void scale_adj(float *speech, float gain, float *prev_scale, int length, int sc_over); 33 | float lin_int_bnd(float x,float xmin,float xmax,float ymin,float ymax); 34 | void noise_est(float gain,float *noise_gain,float up,float down,float min,float max); 35 | void noise_sup(float *gain,float noise_gain,float max_noise,float max_atten,float nfact); 36 | 37 | -------------------------------------------------------------------------------- /vq.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | vq.h VQ include file. 20 | (Search/decode/distortion/weighting functions for VQ) 21 | 22 | Copyright (c) 1995 by Texas Instruments Incorporated. All rights reserved. 23 | */ 24 | 25 | #ifndef _vq_h_ 26 | #define _vq_h_ 27 | 28 | /* External function definitions */ 29 | void vq_init(void); 30 | 31 | float vq_ms4(float *cb, float *u, float *u_est, int *levels, int ma, int stages, int p, float *w, float *u_hat, int *indices, int max_inner); 32 | float *vq_msd2(float *cb, float *u, float *u_est, float *a, int *indices, int *levels, int stages, int p, int conversion); 33 | float *vq_lspw(float *w,float *lsp,float *a,int p); 34 | float vq_enc(float *cb, float *u, int levels, int p, float *u_hat, int *indices); 35 | void vq_fsw(float *w_fs, int num_harm, float pitch); 36 | 37 | 38 | #define msvq_enc(u,w,u_hat,par)\ 39 | vq_ms4(par.cb,u,(float*)NULL,par.levels,\ 40 | par.num_best,par.num_stages,par.num_dimensions,w,u_hat,\ 41 | par.indices,MSVQ_MAXCNT) 42 | 43 | #define fsvq_enc(u,u_hat,par)\ 44 | vq_enc(par.cb,u,par.levels[0],\ 45 | par.num_dimensions,u_hat,\ 46 | par.indices) 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /dsp_sub.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | */ 16 | 17 | /* 18 | 19 | dsp_sub.h: include file 20 | 21 | */ 22 | 23 | 24 | 25 | /* External function definitions */ 26 | void autocorr(float input[], float r[], int order, int npts); 27 | void envelope(float input[], float prev_in, float output[], int npts); 28 | void interp_array(float prev[],float curr[],float out[],float ifact,int size); 29 | float median(float input[], int npts); 30 | float peakiness(float input[], int npts); 31 | void quant_u(float *p_data, int *p_index, float qmin, float qmax, int nlev); 32 | void quant_u_dec(int index, float *p_data,float qmin, float qmax, int nlev); 33 | void rand_num(float output[],float amplitude, int npts); 34 | 35 | void polflt(float input[], const float coeff[], float output[], int order,int npts); 36 | void iirflt(float input[], const float coeff[], float output[], float delay[], int order,int npts); 37 | 38 | void zerflt(float input[], const float coeff[], float output[], int order,int npts); 39 | void firflt(float input[], const float coeff[], float output[], float delay[], int order,int npts); 40 | 41 | void firflt_f32(float input[], const float coeff[], float output[], int order,int npts); 42 | void iirflt_f32(float input[], const float coeff[], float output[], int order,int npts); 43 | 44 | void pack_code(int code,unsigned int **p_ch_beg,int *p_ch_bit,int numbits,int size); 45 | int unpack_code(unsigned int **p_ch_beg,int *p_ch_bit,int *p_code,int numbits,int wsize,unsigned int erase_mask); 46 | 47 | -------------------------------------------------------------------------------- /Build/VS2008/Melp_lib/Melp_lib.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Melp_lib", "Melp_lib.vcproj", "{7AC02F9B-DFE5-473D-8C16-89206F8191CE}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test_vec", "..\Test_vec\Test_vec.vcproj", "{A809BEB1-E032-4A42-A9E2-651B11CA91C4}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DSP_library", "..\..\..\..\DSP_library\Build\Win32\DSP_library\DSP_library.vcproj", "{0D3C61E1-A36D-42C1-B2A0-A4A0E685ED3A}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Win32 = Debug|Win32 13 | Release|Win32 = Release|Win32 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {7AC02F9B-DFE5-473D-8C16-89206F8191CE}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {7AC02F9B-DFE5-473D-8C16-89206F8191CE}.Debug|Win32.Build.0 = Debug|Win32 18 | {7AC02F9B-DFE5-473D-8C16-89206F8191CE}.Release|Win32.ActiveCfg = Release|Win32 19 | {7AC02F9B-DFE5-473D-8C16-89206F8191CE}.Release|Win32.Build.0 = Release|Win32 20 | {A809BEB1-E032-4A42-A9E2-651B11CA91C4}.Debug|Win32.ActiveCfg = Debug|Win32 21 | {A809BEB1-E032-4A42-A9E2-651B11CA91C4}.Debug|Win32.Build.0 = Debug|Win32 22 | {A809BEB1-E032-4A42-A9E2-651B11CA91C4}.Release|Win32.ActiveCfg = Release|Win32 23 | {A809BEB1-E032-4A42-A9E2-651B11CA91C4}.Release|Win32.Build.0 = Release|Win32 24 | {0D3C61E1-A36D-42C1-B2A0-A4A0E685ED3A}.Debug|Win32.ActiveCfg = Debug|Win32 25 | {0D3C61E1-A36D-42C1-B2A0-A4A0E685ED3A}.Debug|Win32.Build.0 = Debug|Win32 26 | {0D3C61E1-A36D-42C1-B2A0-A4A0E685ED3A}.Release|Win32.ActiveCfg = Release|Win32 27 | {0D3C61E1-A36D-42C1-B2A0-A4A0E685ED3A}.Release|Win32.Build.0 = Release|Win32 28 | EndGlobalSection 29 | GlobalSection(SolutionProperties) = preSolution 30 | HideSolutionNode = FALSE 31 | EndGlobalSection 32 | EndGlobal 33 | -------------------------------------------------------------------------------- /mat_lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | 20 | mat_lib.c: Matrix and vector manipulation library 21 | 22 | */ 23 | 24 | #include "spbstd.h" 25 | #include "mat.h" 26 | 27 | 28 | ///* V_ADD- vector addition */ 29 | //float *v_add(float *v1,float *v2,int n) 30 | //{ 31 | // arm_add_f32(v1, v2, v1, n); 32 | // return v1; 33 | //} 34 | // 35 | ///* V_EQU- vector equate */ 36 | //float *v_equ(float *v1,float *v2,int n) 37 | //{ 38 | // arm_copy_f32(v2, v1, n); 39 | // return v1; 40 | //} 41 | //int *v_equ_int(int *v1,int *v2,int n) 42 | //{ 43 | // arm_copy_q31(v2, v1, n); 44 | // return v1; 45 | //} 46 | // 47 | ///* V_INNER- inner product */ 48 | //float v_inner(float *v1,float *v2,int n) 49 | //{ 50 | // float innerprod; 51 | // arm_dot_prod_f32(v1, v2, n, &innerprod); 52 | // return innerprod; 53 | //} 54 | // 55 | ///* v_magsq - sum of squares */ 56 | //float v_magsq(float *v,int n) 57 | //{ 58 | // float magsq; 59 | // 60 | // arm_power_f32(v, n, &magsq); 61 | // return magsq; 62 | //} /* V_MAGSQ */ 63 | // 64 | ///* V_SCALE- vector scale */ 65 | //float *v_scale(float *v,float scale,int n) 66 | //{ 67 | // arm_scale_f32(v, scale, v, n); 68 | // return (v); 69 | //} 70 | // 71 | ///* V_SUB- vector difference */ 72 | //float *v_sub(float *v1,float *v2,int n) 73 | //{ 74 | // arm_sub_f32(v1, v2, v1, n); 75 | // return v1; 76 | //} 77 | // 78 | ///* v_zap - clear vector */ 79 | // 80 | //float *v_zap(float *v,int n) 81 | //{ 82 | // arm_fill_f32(0.0f, v, n); 83 | // return v; 84 | //} /* V_ZAP */ 85 | // 86 | //int *v_zap_int(int *v,int n) 87 | //{ 88 | // arm_fill_q31(0, v, n); 89 | // return v; 90 | //} /* V_ZAP */ 91 | -------------------------------------------------------------------------------- /mat.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | mat.h Matrix include file. 20 | (Low level matrix and vector functions.) 21 | 22 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 23 | */ 24 | #ifndef __MAT_H__ 25 | #define __MAT_H__ 26 | 27 | #ifndef _MSC_VER 28 | #ifndef ARM_MATH_CM4 29 | #define ARM_MATH_CM4 30 | #endif 31 | #define __TARGET_FPU_VFP 1 32 | #define __FPU_PRESENT 1 33 | #include 34 | #endif 35 | 36 | #include "arm_math.h" 37 | #include "arm_const_structs.h" 38 | 39 | static __INLINE float v_inner(float *v1,float *v2,int n) 40 | { 41 | float innerprod; 42 | arm_dot_prod_f32(v1, v2, n, &innerprod); 43 | return innerprod; 44 | } 45 | 46 | static __INLINE float v_magsq(float *v,int n) 47 | { 48 | float magsq; 49 | arm_power_f32(v, n, &magsq); 50 | return magsq; 51 | } 52 | 53 | static __INLINE int findmax(float input[], int npts) 54 | { 55 | uint32_t maxloc; 56 | float maxval; 57 | arm_max_f32(input, npts, &maxval, &maxloc); 58 | return (maxloc); 59 | } 60 | 61 | static __INLINE float arm_sqrt(float x) 62 | { 63 | float32_t res; 64 | arm_sqrt_f32(x, &res); 65 | return res; 66 | } 67 | 68 | static __INLINE float arm_sin(float x) 69 | { 70 | float32_t res; 71 | res = arm_sin_f32(x); 72 | return res; 73 | } 74 | 75 | static __INLINE float arm_cos(float x) 76 | { 77 | float32_t res; 78 | res = arm_cos_f32(x); 79 | return res; 80 | } 81 | 82 | //#define arm_sqrt sqrtf 83 | //#define arm_sin sinf 84 | //#define arm_cos cosf 85 | 86 | #define window(inp,cof,outp,n) arm_mult_f32((float32_t *)inp, (float32_t *)cof, (float32_t *)outp, n) 87 | #define v_zap(v,n) arm_fill_f32(0.0f, (float32_t *)v, n) 88 | #define v_fill(v,val,n) arm_fill_f32(val, (float32_t *)v, n) 89 | #define v_equ(v1,v2,n) arm_copy_f32((float32_t *)v2, (float32_t *)v1, n) 90 | #define v_sub(v1,v2,n) arm_sub_f32((float32_t *)v1, (float32_t *)v2, (float32_t *)v1, n) 91 | #define v_add(v1,v2,n) arm_add_f32((float32_t *)v1, (float32_t *)v2, (float32_t *)v1, n) 92 | #define v_scale(v,scale,n) arm_scale_f32((float32_t *)v, scale, v, n) 93 | 94 | #define v_zap_int(v,n) arm_fill_q31(0, (q31_t *)v, n) 95 | #define v_equ_int(v1,v2,n) arm_copy_q31((q31_t *)v2, (q31_t *)v1, n) 96 | 97 | #endif // __MAT_H__ 98 | -------------------------------------------------------------------------------- /ARM/Serial.c: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------- 2 | * Name: Serial.c 3 | * Purpose: Low level serial routines 4 | * Note(s): 5 | *---------------------------------------------------------------------------- 6 | * This file is part of the uVision/ARM development tools. 7 | * This software may only be used under the terms of a valid, current, 8 | * end user licence from KEIL for a compatible version of KEIL software 9 | * development tools. Nothing else gives you the right to use this software. 10 | * 11 | * This software is supplied "AS IS" without warranties of any kind. 12 | * 13 | * Copyright (c) 2004-2013 Keil - An ARM Company. All rights reserved. 14 | *----------------------------------------------------------------------------*/ 15 | 16 | #include /* STM32F4xx Definitions */ 17 | #include "Serial.h" 18 | 19 | #ifdef __DBG_ITM 20 | volatile int32_t ITM_RxBuffer; 21 | #endif 22 | 23 | /*----------------------------------------------------------------------------- 24 | * SER_Init: Initialize Serial Interface 25 | *----------------------------------------------------------------------------*/ 26 | void SER_Init (void) { 27 | #ifdef __DBG_ITM 28 | ITM_RxBuffer = ITM_RXBUFFER_EMPTY; 29 | 30 | #else 31 | RCC->APB1ENR |= (1UL << 19); /* Enable USART4 clock */ 32 | RCC->APB2ENR |= (1UL << 0); /* Enable AFIO clock */ 33 | RCC->AHB1ENR |= (1UL << 2); /* Enable GPIOC clock */ 34 | 35 | GPIOC->MODER &= 0xFF0FFFFF; 36 | GPIOC->MODER |= 0x00A00000; 37 | GPIOC->AFR[1] |= 0x00008800; /* PC10 UART4_Tx, PC11 UART4_Rx (AF8) */ 38 | 39 | /* Configure UART4: 115200 baud @ 42MHz, 8 bits, 1 stop bit, no parity */ 40 | UART4->BRR = (22 << 4) | 12; 41 | UART4->CR3 = 0x0000; 42 | UART4->CR2 = 0x0000; 43 | UART4->CR1 = 0x200C; 44 | #endif 45 | } 46 | 47 | 48 | /*----------------------------------------------------------------------------- 49 | * SER_PutChar: Write a character to Serial Port 50 | *----------------------------------------------------------------------------*/ 51 | int32_t SER_PutChar (int32_t ch) { 52 | #ifdef __DBG_ITM 53 | //int i; 54 | ITM_SendChar (ch & 0xFF); 55 | //for (i = 10000; i; i--); 56 | #else 57 | while (!(UART4->SR & 0x0080)); 58 | UART4->DR = (ch & 0xFF); 59 | #endif 60 | 61 | return (ch); 62 | } 63 | 64 | 65 | /*----------------------------------------------------------------------------- 66 | * SER_GetChar: Read a character from Serial Port 67 | *----------------------------------------------------------------------------*/ 68 | int32_t SER_GetChar (void) { 69 | #ifdef __DBG_ITM 70 | if (ITM_CheckChar()) 71 | return ITM_ReceiveChar(); 72 | #else 73 | if (UART4->SR & 0x0020) 74 | return (UART4->DR); 75 | #endif 76 | return (-1); 77 | } 78 | 79 | /*----------------------------------------------------------------------------- 80 | * end of file 81 | *----------------------------------------------------------------------------*/ 82 | -------------------------------------------------------------------------------- /fs_lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | 20 | fs_lib.c: Fourier series subroutines 21 | 22 | */ 23 | 24 | /* compiler include files */ 25 | #include 26 | #include 27 | #include 28 | #include "spbstd.h" 29 | #include "melp.h" 30 | #include "mat.h" 31 | #include "fs.h" 32 | 33 | 34 | /* */ 35 | /* Subroutine FIND_HARM: find Fourier coefficients using */ 36 | /* FFT of input signal divided into pitch dependent bins. */ 37 | /* */ 38 | #define FFTLENGTH 512 39 | #define DFTMAX 160 40 | 41 | /* Memory definition */ 42 | static float find_hbuf[2*FFTLENGTH] CCMRAM; 43 | static float mag[FFTLENGTH] CCMRAM; 44 | static float idftc[DFTMAX] CCMRAM; 45 | 46 | 47 | void find_harm(float input[], float fsmag[], float pitch, int num_harm, 48 | int length) 49 | { 50 | int i, j, k, iwidth, i2; 51 | float temp, avg, fwidth; 52 | 53 | v_fill(fsmag, 1.0f, num_harm); 54 | avg = 0.0; 55 | 56 | /* Perform peak-picking on FFT of input signal */ 57 | 58 | /* Calculate FFT of complex signal in scratch buffer */ 59 | v_zap(find_hbuf,2*FFTLENGTH); 60 | for (i = 0; i < 2*length; i+=2) 61 | find_hbuf[i] = input[i/2]; 62 | fft(find_hbuf,FFTLENGTH,-1); 63 | 64 | /* Calculate magnitude squared of coefficients */ 65 | arm_cmplx_mag_squared_f32(find_hbuf, mag, FFTLENGTH); 66 | 67 | /* Implement pitch dependent staircase function */ 68 | fwidth = FFTLENGTH / pitch; /* Harmonic bin width */ 69 | iwidth = (int) fwidth; 70 | if (iwidth < 2) iwidth = 2; 71 | i2 = iwidth/2; 72 | avg = 0.0; 73 | if (num_harm > 0.25f*pitch) num_harm = (int)(0.25f*pitch); 74 | for (k = 0; k < num_harm; k++) { 75 | i = (int)(((k+1)*fwidth) - i2 + 0.5f); /* Start at peak-i2 */ 76 | j = i + findmax(&mag[i],iwidth); 77 | fsmag[k] = mag[j]; 78 | avg += mag[j]; 79 | } 80 | 81 | /* Normalize Fourier series values to average magnitude */ 82 | temp = num_harm/(avg + .0001f); 83 | for (i = 0; i < num_harm; i++) { 84 | fsmag[i] = arm_sqrt(temp*fsmag[i]); 85 | } 86 | } 87 | 88 | /* Subroutine FFT: Fast Fourier Transform */ 89 | /************************************************************** 90 | * Replaces data by its DFT, if isign is 1, or replaces data * 91 | * by inverse DFT times nn if isign is -1. data is a complex * 92 | * array of length nn, input as a real array of length 2*nn. * 93 | * nn MUST be an integer power of two. This is not checked * 94 | * The real part of the number should be in the zeroeth * 95 | * of data , and the imaginary part should be in the next * 96 | * element. Hence all the real parts should have even indices * 97 | * and the imaginary parts, odd indices. * 98 | 99 | * Data is passed in an array starting in position 0, but the * 100 | * code is copied from Fortran so uses an internal pointer * 101 | * which accesses position 0 as position 1, etc. * 102 | 103 | * This code uses e+jwt sign convention, so isign should be * 104 | * reversed for e-jwt. * 105 | ***************************************************************/ 106 | void fft(float *datam1,int nn,int isign) 107 | { 108 | arm_cfft_f32(&arm_cfft_sR_f32_len512, datam1, 0, 1); 109 | } 110 | 111 | /* */ 112 | /* Subroutine IDFT_REAL: take inverse discrete Fourier */ 113 | /* transform of real input coefficients. */ 114 | /* Assume real time signal, so reduce computation */ 115 | /* using symmetry between lower and upper DFT */ 116 | /* coefficients. */ 117 | /* */ 118 | void idft_real(float real[], float signal[], int length) 119 | 120 | { 121 | int i, j, k, k_inc, length2; 122 | float w, accum; 123 | 124 | length2 = (length/2)+1; 125 | w = 2 * M_PI / length; 126 | for (i = 0; i < length; i++ ) { 127 | idftc[i] = arm_cos(w*i); 128 | } 129 | real[0] *= (1.0f/length); 130 | for (i = 1; i < length2-1; i++ ) { 131 | real[i] *= (2.0f/length); 132 | } 133 | if ((i*2) == length) 134 | real[i] *= (1.0f/length); 135 | else 136 | real[i] *= (2.0f/length); 137 | 138 | for (i = 0; i < length; i++ ) { 139 | accum = real[0]; 140 | k_inc = i; 141 | k = k_inc; 142 | for (j = 1; j < length2; j++ ) { 143 | accum += real[j] * idftc[k]; 144 | k += k_inc; 145 | if (k >= length) 146 | k -= length; 147 | } 148 | signal[i] = accum; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /melp_chn.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | Name: melp_chn_write, melp_chn_read 20 | Description: Write/read MELP channel bitstream 21 | Inputs: 22 | MELP parameter structure 23 | Outputs: 24 | updated MELP parameter structure (channel pointers) 25 | Returns: void 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include "melp.h" 32 | #include "vq.h" 33 | #include "melp_sub.h" 34 | #include "dsp_sub.h" 35 | 36 | /* Define number of channel bits per frame */ 37 | #define NUM_CH_BITS 54 38 | #define ORIGINAL_BIT_ORDER 0 /* flag to use bit order of original version */ 39 | 40 | /* Define bit buffer */ 41 | static unsigned int bit_buffer[NUM_CH_BITS] CCMRAM; 42 | static struct melp_param param_buffer; 43 | 44 | #if (ORIGINAL_BIT_ORDER) 45 | /* Original linear order */ 46 | static int bit_order[NUM_CH_BITS] RODATA = { 47 | 0, 1, 2, 3, 4, 5, 48 | 6, 7, 8, 9, 10, 11, 49 | 12, 13, 14, 15, 16, 17, 50 | 18, 19, 20, 21, 22, 23, 51 | 24, 25, 26, 27, 28, 29, 52 | 30, 31, 32, 33, 34, 35, 53 | 36, 37, 38, 39, 40, 41, 54 | 42, 43, 44, 45, 46, 47, 55 | 48, 49, 50, 51, 52, 53}; 56 | #else 57 | /* Order based on priority of bits */ 58 | static int bit_order[NUM_CH_BITS] RODATA = { 59 | 0, 17, 9, 28, 34, 3, 60 | 4, 39, 1, 2, 13, 38, 61 | 14, 10, 11, 40, 15, 21, 62 | 27, 45, 12, 26, 25, 33, 63 | 20, 24, 23, 32, 44, 46, 64 | 22, 31, 53, 52, 51, 7, 65 | 6, 19, 18, 29, 37, 30, 66 | 36, 35, 43, 42, 16, 41, 67 | 50, 49, 48, 47, 8, 5 68 | }; 69 | #endif 70 | 71 | static int sync_bit = 0; /* sync bit */ 72 | 73 | 74 | void melp_chn_write(struct melp_param *par) 75 | { 76 | int i, bit_cntr; 77 | unsigned int *bit_ptr; 78 | 79 | param_buffer.gain_index[1] = par->gain_index[1]; 80 | param_buffer.gain_index[0] = par->gain_index[0]; 81 | param_buffer.pitch_index = par->pitch_index; 82 | param_buffer.jit_index = par->jit_index; 83 | param_buffer.bpvc_index = par->bpvc_index; 84 | 85 | memcpy(param_buffer.msvq_par.indices, par->msvq_par.indices, sizeof(param_buffer.msvq_par.indices)); 86 | memcpy(param_buffer.fsvq_par.indices, par->fsvq_par.indices, sizeof(param_buffer.fsvq_par.indices)); 87 | return; 88 | 89 | /* FEC: code additional information in redundant indices */ 90 | // fec_code(par); 91 | 92 | /* Fill bit buffer */ 93 | bit_ptr = bit_buffer; 94 | bit_cntr = 0; 95 | 96 | pack_code(par->gain_index[1],&bit_ptr,&bit_cntr,5,1); 97 | 98 | /* Toggle and write sync bit */ 99 | sync_bit ^= 1; 100 | pack_code(sync_bit,&bit_ptr,&bit_cntr,1,1); 101 | pack_code(par->gain_index[0],&bit_ptr,&bit_cntr,3,1); 102 | pack_code(par->pitch_index,&bit_ptr,&bit_cntr,PIT_BITS,1); 103 | pack_code(par->jit_index,&bit_ptr,&bit_cntr,1,1); 104 | pack_code(par->bpvc_index,&bit_ptr,&bit_cntr,NUM_BANDS-1,1); 105 | 106 | for (i = 0; i < par->msvq_par.num_stages; i++) { 107 | pack_code(par->msvq_par.indices[i],&bit_ptr,&bit_cntr,par->msvq_par.bits[i],1); 108 | } 109 | pack_code(par->fsvq_par.indices[0],&bit_ptr,&bit_cntr, FS_BITS,1); 110 | } 111 | 112 | int melp_chn_read(struct melp_param *par) 113 | { 114 | int erase = 0; 115 | int i, bit_cntr; 116 | unsigned int *bit_ptr; 117 | 118 | /* Read information from bit buffer */ 119 | bit_ptr = bit_buffer; 120 | bit_cntr = 0; 121 | 122 | par->gain_index[1] = param_buffer.gain_index[1]; 123 | par->gain_index[0] = param_buffer.gain_index[0]; 124 | par->pitch_index = param_buffer.pitch_index; 125 | par->jit_index = param_buffer.jit_index; 126 | par->bpvc_index = param_buffer.bpvc_index; 127 | memcpy(par->msvq_par.indices, param_buffer.msvq_par.indices, sizeof(param_buffer.msvq_par)); 128 | memcpy(par->fsvq_par.indices, param_buffer.fsvq_par.indices, sizeof(param_buffer.fsvq_par)); 129 | 130 | /* Clear unvoiced flag */ 131 | par->uv_flag = 0; 132 | return 0; 133 | 134 | unpack_code(&bit_ptr,&bit_cntr,&par->gain_index[1],5,1,0); 135 | 136 | /* Read sync bit */ 137 | unpack_code(&bit_ptr,&bit_cntr,&i,1,1,0); 138 | unpack_code(&bit_ptr,&bit_cntr,&par->gain_index[0],3,1,0); 139 | unpack_code(&bit_ptr,&bit_cntr,&par->pitch_index,PIT_BITS,1,0); 140 | 141 | unpack_code(&bit_ptr,&bit_cntr,&par->jit_index,1,1,0); 142 | unpack_code(&bit_ptr,&bit_cntr,&par->bpvc_index, NUM_BANDS-1,1,0); 143 | 144 | for (i = 0; i < par->msvq_par.num_stages; i++) { 145 | unpack_code(&bit_ptr,&bit_cntr,&par->msvq_par.indices[i],par->msvq_par.bits[i],1,0); 146 | } 147 | unpack_code(&bit_ptr,&bit_cntr,&par->fsvq_par.indices[0], FS_BITS,1,0); 148 | 149 | /* Clear unvoiced flag */ 150 | par->uv_flag = 0; 151 | // erase = fec_decode(par,erase); 152 | /* Return erase flag */ 153 | return(erase); 154 | } 155 | -------------------------------------------------------------------------------- /Build/VS2008/Test_vec/Test_vec.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 26 | 29 | 32 | 35 | 38 | 41 | 54 | 57 | 60 | 63 | 70 | 73 | 76 | 79 | 82 | 85 | 88 | 91 | 92 | 100 | 103 | 106 | 109 | 112 | 115 | 127 | 130 | 133 | 136 | 145 | 148 | 151 | 154 | 157 | 160 | 163 | 166 | 167 | 168 | 169 | 173 | 177 | 178 | 179 | 184 | 187 | 188 | 189 | 194 | 197 | 198 | 199 | 204 | 205 | 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /ARM/Retarget.c: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------- 2 | * Name: Retarget.c 3 | * Purpose: 'Retarget' layer for target-dependent low level functions 4 | * Note(s): 5 | *---------------------------------------------------------------------------- 6 | * This file is part of the uVision/ARM development tools. 7 | * This software may only be used under the terms of a valid, current, 8 | * end user licence from KEIL for a compatible version of KEIL software 9 | * development tools. Nothing else gives you the right to use this software. 10 | * 11 | * This software is supplied "AS IS" without warranties of any kind. 12 | * 13 | * Copyright (c) 2011-2013 Keil - An ARM Company. All rights reserved. 14 | *----------------------------------------------------------------------------*/ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "Serial.h" 21 | 22 | #pragma import(__use_no_semihosting) 23 | 24 | 25 | // ARM Semihosting Commands 26 | #define SYS_OPEN (0x1) 27 | #define SYS_CLOSE (0x2) 28 | #define SYS_WRITE (0x5) 29 | #define SYS_READ (0x6) 30 | #define SYS_ISTTY (0x9) 31 | #define SYS_SEEK (0xa) 32 | #define SYS_ENSURE (0xb) 33 | #define SYS_FLEN (0xc) 34 | #define SYS_REMOVE (0xe) 35 | #define SYS_RENAME (0xf) 36 | #define SYS_EXIT (0x18) 37 | 38 | typedef unsigned int uint32_t; 39 | typedef short int int16_t; 40 | 41 | #define MIN(a,b) (a >= b ? b : a); 42 | 43 | struct __FILE { char *pData; int size;}; 44 | 45 | struct __FILE indata; 46 | struct __FILE outdata; 47 | 48 | 49 | 50 | _ARMABI FILE *fopen(const char * filename, 51 | const char * mode) 52 | { 53 | FILE *pFile; 54 | 55 | if (strcmp(mode, "rb") == 0) 56 | { 57 | pFile = &indata; 58 | pFile->pData = (char *)0x60000000; 59 | pFile->size = 360960; 60 | }else if (strcmp(mode, "wb") == 0) 61 | { 62 | pFile = &outdata; 63 | pFile->pData = (char *)0x70000000; 64 | pFile->size = 360960; 65 | }else 66 | { 67 | pFile = NULL; 68 | } 69 | 70 | return pFile; 71 | } 72 | _ARMABI size_t fread(void *buff, size_t elem_size, size_t num_elems, FILE *pFile) 73 | { 74 | size_t n_elems, n_bytes; 75 | n_elems = MIN(pFile->size/elem_size, num_elems); 76 | n_bytes = n_elems * elem_size; 77 | memcpy(buff, pFile->pData, n_bytes ); 78 | pFile->pData += n_bytes; 79 | pFile->size -= n_bytes; 80 | return n_elems; 81 | } 82 | 83 | _ARMABI size_t fwrite(const void *buff, size_t elem_size, size_t num_elems, FILE *pFile) 84 | { 85 | size_t n_elems, n_bytes; 86 | n_elems = MIN(pFile->size/elem_size, num_elems); 87 | n_bytes = n_elems * elem_size; 88 | memcpy(pFile->pData, buff, n_bytes ); 89 | pFile->pData += n_bytes; 90 | pFile->size -= n_bytes; 91 | return n_elems; 92 | } 93 | 94 | FILEHANDLE _sys_open(const char* name, int openmode) { 95 | uint32_t args[3]; 96 | args[0] = (uint32_t)name; 97 | args[1] = (uint32_t)openmode; 98 | args[2] = (uint32_t)strlen(name); 99 | return __semihost(SYS_OPEN, args); 100 | } 101 | 102 | int _sys_close(FILEHANDLE fh) { 103 | return __semihost(SYS_CLOSE, &fh); 104 | } 105 | 106 | int _sys_write(FILEHANDLE fh, const unsigned char* buffer, unsigned int length, int mode) { 107 | uint32_t args[3]; 108 | 109 | if (length == 0) return 0; 110 | args[0] = (uint32_t)fh; 111 | args[1] = (uint32_t)buffer; 112 | args[2] = (uint32_t)length; 113 | return __semihost(SYS_WRITE, args); 114 | } 115 | 116 | int _sys_read(FILEHANDLE fh, unsigned char* buffer, unsigned int length, int mode) { 117 | uint32_t args[3]; 118 | args[0] = (uint32_t)fh; 119 | args[1] = (uint32_t)buffer; 120 | args[2] = (uint32_t)length; 121 | return __semihost(SYS_READ, args); 122 | } 123 | 124 | int semihost_istty(FILEHANDLE fh) { 125 | return __semihost(SYS_ISTTY, &fh); 126 | } 127 | 128 | int semihost_seek(FILEHANDLE fh, long position) { 129 | uint32_t args[2]; 130 | args[0] = (uint32_t)fh; 131 | args[1] = (uint32_t)position; 132 | return __semihost(SYS_SEEK, args); 133 | } 134 | 135 | int semihost_ensure(FILEHANDLE fh) { 136 | return __semihost(SYS_ENSURE, &fh); 137 | } 138 | 139 | long semihost_flen(FILEHANDLE fh) { 140 | return __semihost(SYS_FLEN, &fh); 141 | } 142 | 143 | int semihost_remove(const char *name) { 144 | uint32_t args[2]; 145 | args[0] = (uint32_t)name; 146 | args[1] = (uint32_t)strlen(name); 147 | return __semihost(SYS_REMOVE, args); 148 | } 149 | 150 | int semihost_rename(const char *old_name, const char *new_name) { 151 | uint32_t args[4]; 152 | args[0] = (uint32_t)old_name; 153 | args[1] = (uint32_t)strlen(old_name); 154 | args[0] = (uint32_t)new_name; 155 | args[1] = (uint32_t)strlen(new_name); 156 | return __semihost(SYS_RENAME, args); 157 | } 158 | 159 | 160 | int fputc(int c, FILE *f) { 161 | return (SER_PutChar(c)); 162 | } 163 | 164 | 165 | int fgetc(FILE *f) { 166 | return (SER_GetChar()); 167 | } 168 | 169 | 170 | int ferror(FILE *f) { 171 | /* Your implementation of ferror */ 172 | return EOF; 173 | } 174 | 175 | 176 | void _ttywrch(int c) { 177 | SER_PutChar(c); 178 | } 179 | 180 | void _sys_exit(int return_code) { 181 | label: goto label; /* endless loop */ 182 | } 183 | 184 | void exit(int return_code) 185 | { 186 | label: goto label; /* endless loop */ 187 | } 188 | 189 | void __aeabi_assert(const char *expr, const char *file, int line) 190 | { 191 | // printf("Assert at file %s, expr %s, line %d", file, expr, line); 192 | exit(1); 193 | } 194 | -------------------------------------------------------------------------------- /Build/VS2008/Melp_lib/Melp_lib.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 28 | 31 | 34 | 37 | 40 | 55 | 58 | 61 | 64 | 67 | 70 | 73 | 76 | 79 | 82 | 83 | 91 | 94 | 97 | 100 | 103 | 106 | 116 | 119 | 122 | 125 | 128 | 131 | 134 | 137 | 140 | 143 | 144 | 145 | 146 | 147 | 148 | 153 | 156 | 157 | 160 | 161 | 164 | 165 | 168 | 169 | 172 | 173 | 176 | 177 | 180 | 181 | 184 | 185 | 188 | 189 | 192 | 193 | 196 | 197 | 200 | 201 | 204 | 205 | 208 | 209 | 210 | 215 | 218 | 219 | 222 | 223 | 226 | 227 | 230 | 231 | 234 | 235 | 238 | 239 | 242 | 243 | 246 | 247 | 250 | 251 | 252 | 257 | 258 | 259 | 260 | 261 | 262 | -------------------------------------------------------------------------------- /melp.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* */ 19 | /* melp.h: include file for MELP coder */ 20 | /* */ 21 | 22 | /* compiler flags */ 23 | #define ANA_SYN 0 24 | #define ANALYSIS 1 25 | #define SYNTHESIS 2 26 | 27 | #define RATE2400 2400 28 | #define RATE1200 1200 29 | 30 | 31 | /* compiler constants */ 32 | #define FRAME 180 /* speech frame size */ 33 | #define LPC_ORD 10 /* LPC order */ 34 | #define NUM_HARM 10 /* number of Fourier magnitudes */ 35 | #define NUM_GAINFR 2 /* number of gains per frame */ 36 | #define LPC_FRAME 200 /* LPC window size */ 37 | #define PITCHMIN 20 /* minimum pitch lag */ 38 | #define PITCHMAX 160 /* maximum pitch lag */ 39 | #define NUM_BANDS 5 /* number of frequency bands */ 40 | #define LPF_ORD 6 /* lowpass filter order */ 41 | #define DC_ORD 4 /* DC removal filter order */ 42 | #define BPF_ORD 6 /* bandpass analysis filter order */ 43 | #define ENV_ORD 2 /* bandpass envelope filter order */ 44 | #define MIX_ORD 32 /* mixed excitation filtering order */ 45 | #define DISP_ORD 64 /* pulse dispersion filter order */ 46 | #define DEFAULT_PITCH_ 50.0f /* default pitch value */ 47 | #define UV_PITCH 50 /* unvoiced pitch value */ 48 | #define VMIN 0.8F /* minimum strongly voiced correlation */ 49 | #define VJIT 0.5F /* jitter threshold for correlations */ 50 | #define BPTHRESH 0.6F /* bandpass voicing threshold */ 51 | #define MAX_JITTER 0.25F /* maximum jitter percentage (as a fraction) */ 52 | #define ASE_NUM_BW 0.5F /* adaptive spectral enhancement - numerator */ 53 | #define ASE_DEN_BW 0.8F /* adaptive spectral enhancement - denominator */ 54 | #define GAINFR (FRAME/NUM_GAINFR) /* size of gain frame */ 55 | #define MIN_GAINFR 120 /* minimum gain analysis window */ 56 | #define MINLENGTH 160 /* minimum correlation length */ 57 | #define FSAMP 8000.0F /* sampling frequency */ 58 | #define MSVQ_M 8 /* M-best for MSVQ search */ 59 | #define MSVQ_MAXCNT 256 /* maximum inner loop counter for MSVQ search */ 60 | #define BWMIN (50.0F*2/FSAMP) /* minimum LSF separation */ 61 | 62 | /* Noise suppression/estimation parameters */ 63 | /* Up by 3 dB/sec (0.5*22.5 ms frame), down by 12 dB/sec */ 64 | #define UPCONST 0.0337435f /* noise estimation up time constant */ 65 | #define DOWNCONST -0.135418f /* noise estimation down time constant */ 66 | #define NFACT 3.0f /* noise floor boost in dB */ 67 | #define MAX_NS_ATT 6.0f /* maximum noise suppression */ 68 | #define MAX_NS_SUP 20.0f /* maximum noise level to use in suppression */ 69 | #define MIN_NOISE 10.0f /* minimum value allowed in noise estimation */ 70 | #define MAX_NOISE 80.0f /* maximum value allowed in noise estimation */ 71 | 72 | /* Channel I/O constants */ 73 | #define CHWORDSIZE 6 /* number of bits per channel word */ 74 | #define ERASE_MASK 0x4000 /* erasure flag mask for channel word */ 75 | 76 | #define GN_QLO 10.0f /* minimum gain in dB */ 77 | #define GN_QUP 77.0f /* maximum gain in dB */ 78 | #define GN_QLEV 32 /* number of second gain quantization levels */ 79 | #define PIT_BITS 7 /* number of bits for pitch coding */ 80 | #define PIT_QLEV 99 /* number of pitch levels */ 81 | #define PIT_QLO 1.30103f /* minimum log pitch for quantization */ 82 | #define PIT_QUP 2.20412f /* maximum log pitch for quantization */ 83 | #define FS_BITS 8 /* number of bits for Fourier magnitudes */ 84 | #define FS_LEVELS (1< DISP_ORD) 120 | #define BEGIN MIX_ORD 121 | #else 122 | #define BEGIN DISP_ORD 123 | #endif 124 | 125 | #define TILT_ORD 1 126 | #define SYN_GAIN 1000.0f 127 | #define SCALEOVER 10 128 | #define PDEL SCALEOVER 129 | 130 | /* Compiler constants */ 131 | #define UVMAX 0.55f 132 | #define PDOUBLE1 0.75f 133 | #define PDOUBLE2 0.5f 134 | #define PDOUBLE3 0.9f 135 | #define PDOUBLE4 0.7f 136 | #define LONG_PITCH 100.0f 137 | 138 | 139 | /* Structure definition */ 140 | typedef struct msvq_param { /* Multistage VQ parameters */ 141 | int num_stages; 142 | int num_dimensions; 143 | int num_best; 144 | int bits[4]; 145 | int levels[4]; 146 | int indices[4]; 147 | float *cb; 148 | }msvq_param_t; 149 | 150 | typedef struct melp_param { /* MELP parameters */ 151 | float pitch; 152 | float lsf[LPC_ORD+1]; 153 | float gain[NUM_GAINFR]; 154 | float jitter; 155 | float bpvc[NUM_BANDS]; 156 | int pitch_index; 157 | int lsf_index[LPC_ORD]; 158 | int jit_index; 159 | int bpvc_index; 160 | int gain_index[NUM_GAINFR]; 161 | int uv_flag; 162 | float fs_mag[NUM_HARM]; 163 | msvq_param_t msvq_par; /* MS VQ parameters */ 164 | msvq_param_t fsvq_par; /* Fourier series VQ parameters */ 165 | }melp_param_t; 166 | 167 | #ifdef _MSC_VER 168 | #define CCMRAM 169 | #define RODATA 170 | #else 171 | #define CCMRAM __attribute__((section (".ccmram"))) 172 | #define RODATA __attribute__((section (".rodata"))) 173 | #endif 174 | 175 | /* External function definitions */ 176 | #ifdef _MSC_VER 177 | __declspec(dllexport) void __cdecl melp_ana(float sp_in[],struct melp_param *par); 178 | __declspec(dllexport) void __cdecl melp_syn(struct melp_param *par, float sp_out[]); 179 | __declspec(dllexport) void __cdecl melp_ana_init(struct melp_param *par); 180 | __declspec(dllexport) void __cdecl melp_syn_init(struct melp_param *par); 181 | __declspec(dllexport) int __cdecl melp_chn_read(struct melp_param *par); 182 | __declspec(dllexport) void __cdecl melp_chn_write(struct melp_param *par); 183 | 184 | __declspec(dllexport) void __cdecl fec_code(struct melp_param *par); 185 | __declspec(dllexport) int __cdecl fec_decode(struct melp_param *par, int erase); 186 | #else 187 | void melp_ana(float sp_in[],struct melp_param *par); 188 | void melp_syn(struct melp_param *par, float sp_out[]); 189 | void melp_ana_init(struct melp_param *par); 190 | void melp_syn_init(struct melp_param *par); 191 | int melp_chn_read(struct melp_param *par); 192 | void melp_chn_write(struct melp_param *par); 193 | 194 | void fec_code(struct melp_param *par); 195 | int fec_decode(struct melp_param *par, int erase); 196 | #endif 197 | -------------------------------------------------------------------------------- /melp_ana.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | Name: melp_ana.c 20 | Description: MELP analysis 21 | Inputs: 22 | speech[] - input speech signal 23 | Outputs: 24 | *par - MELP parameter structure 25 | Returns: void 26 | */ 27 | 28 | /* compiler include files */ 29 | 30 | #include 31 | #include 32 | #include "melp.h" 33 | #include "spbstd.h" 34 | #include "lpc.h" 35 | #include "mat.h" 36 | #include "vq.h" 37 | #include "fs.h" 38 | #include "pit.h" 39 | #include "melp_sub.h" 40 | #include "dsp_sub.h" 41 | 42 | /* memory definitions */ 43 | static float sigbuf[LPF_ORD+PITCH_FR] CCMRAM; 44 | static float speech[IN_BEG+FRAME] CCMRAM; 45 | static float dcdel[DC_ORD] CCMRAM; 46 | static float lpfsp_del[LPF_ORD] CCMRAM; 47 | static float pitch_avg; 48 | static float fpitch[2] CCMRAM; 49 | 50 | static float w_fs[NUM_HARM] CCMRAM; 51 | static float r[LPC_ORD+1] CCMRAM, 52 | lpc[LPC_ORD+1] CCMRAM; 53 | static float weights[LPC_ORD] CCMRAM; 54 | 55 | void melp_ana(float sp_in[],struct melp_param *par) 56 | { 57 | int i; 58 | float sub_pitch; 59 | float temp,pcorr,bpthresh; 60 | 61 | 62 | /* Remove DC from input speech */ 63 | dc_rmv(sp_in,&speech[IN_BEG],dcdel,FRAME); 64 | 65 | /* Copy input speech to pitch window and lowpass filter */ 66 | v_equ(&sigbuf[LPF_ORD],&speech[FRAME/2],PITCH_FR); 67 | v_equ(sigbuf,lpfsp_del,LPF_ORD); 68 | polflt(&sigbuf[LPF_ORD],lpf_den,&sigbuf[LPF_ORD],LPF_ORD,PITCH_FR); 69 | v_equ(lpfsp_del,&sigbuf[FRAME],LPF_ORD); 70 | zerflt(&sigbuf[LPF_ORD],lpf_num,&sigbuf[LPF_ORD],LPF_ORD,PITCH_FR); 71 | 72 | /* Perform global pitch search at frame end on lowpass speech signal */ 73 | /* Note: avoid short pitches due to formant tracking */ 74 | fpitch[1] = find_pitch(&sigbuf[LPF_ORD+(PITCH_FR/2)],&temp,(2*PITCHMIN),PITCHMAX,PITCHMAX); 75 | 76 | /* Perform bandpass voicing analysis for end of frame */ 77 | bpvc_ana(&speech[FRAME_END], fpitch, &par->bpvc[0], &sub_pitch); 78 | 79 | /* Force jitter if lowest band voicing strength is weak */ 80 | if (par->bpvc[0] < VJIT) 81 | par->jitter = MAX_JITTER; 82 | else 83 | par->jitter = 0.0; 84 | 85 | /* Calculate LPC for end of frame */ 86 | window(&speech[(FRAME_END-(LPC_FRAME/2))],win_cof,sigbuf,LPC_FRAME); 87 | autocorr(sigbuf,r,LPC_ORD,LPC_FRAME); 88 | lpc[0] = 1.0; 89 | lpc_schur(r,lpc,LPC_ORD); 90 | lpc_bw_expand(lpc,lpc,BWFACT,LPC_ORD); 91 | 92 | /* Calculate LPC residual */ 93 | zerflt(&speech[FRAME/2],lpc,&sigbuf[LPF_ORD],LPC_ORD,PITCH_FR); 94 | 95 | /* Check peakiness of residual signal */ 96 | temp = peakiness(&sigbuf[(LPF_ORD+(PITCHMAX/2))],PITCHMAX); 97 | 98 | /* Peakiness: force lowest band to be voiced */ 99 | if (temp > PEAK_THRESH) { 100 | par->bpvc[0] = 1.0; 101 | } 102 | 103 | /* Extreme peakiness: force second and third bands to be voiced */ 104 | if (temp > PEAK_THR2) { 105 | par->bpvc[1] = 1.0; 106 | par->bpvc[2] = 1.0; 107 | } 108 | 109 | /* Calculate overall frame pitch using lowpass filtered residual */ 110 | par->pitch = pitch_ana(&speech[FRAME_END], &sigbuf[LPF_ORD+PITCHMAX], sub_pitch,pitch_avg,&pcorr); 111 | bpthresh = BPTHRESH; 112 | 113 | /* Calculate gain of input speech for each gain subframe */ 114 | for (i = 0; i < NUM_GAINFR; i++) { 115 | if (par->bpvc[0] > bpthresh) { 116 | /* voiced mode: pitch synchronous window length */ 117 | temp = sub_pitch; 118 | par->gain[i] = gain_ana(&speech[FRAME_BEG+(i+1)*GAINFR], temp,MIN_GAINFR,2*PITCHMAX); 119 | }else { 120 | temp = 1.33f*GAINFR - 0.5f; 121 | par->gain[i] = gain_ana(&speech[FRAME_BEG+(i+1)*GAINFR], temp,0,2*PITCHMAX); 122 | } 123 | } 124 | 125 | /* Update average pitch value */ 126 | if (par->gain[NUM_GAINFR-1] > SILENCE_DB) 127 | temp = pcorr; 128 | else 129 | temp = 0.0; 130 | pitch_avg = p_avg_update(par->pitch, temp, VMIN); 131 | 132 | /* Calculate Line Spectral Frequencies */ 133 | lpc_pred2lsp(lpc,par->lsf,LPC_ORD); 134 | 135 | /* Force minimum LSF bandwidth (separation) */ 136 | lpc_clamp(par->lsf,BWMIN,LPC_ORD); 137 | 138 | /* Quantize MELP parameters to 2400 bps and generate bitstream */ 139 | 140 | /* Quantize LSF's with MSVQ */ 141 | vq_lspw(weights, &par->lsf[1], lpc, LPC_ORD); 142 | msvq_enc(&par->lsf[1], weights, &par->lsf[1], par->msvq_par); 143 | 144 | /* Force minimum LSF bandwidth (separation) */ 145 | lpc_clamp(par->lsf,BWMIN,LPC_ORD); 146 | 147 | /* Quantize logarithmic pitch period */ 148 | /* Reserve all zero code for completely unvoiced */ 149 | par->pitch = log10f(par->pitch); 150 | quant_u(&par->pitch,&par->pitch_index,PIT_QLO,PIT_QUP,PIT_QLEV); 151 | par->pitch = powf(10.0f,par->pitch); 152 | 153 | /* Quantize gain terms with uniform log quantizer */ 154 | q_gain(par->gain, par->gain_index,GN_QLO,GN_QUP,GN_QLEV); 155 | 156 | /* Quantize jitter and bandpass voicing */ 157 | quant_u(&par->jitter,&par->jit_index,0.0,MAX_JITTER,2); 158 | par->uv_flag = q_bpvc(&par->bpvc[0],&par->bpvc_index,bpthresh, 159 | NUM_BANDS); 160 | 161 | /* Calculate Fourier coefficients of residual signal from quantized LPC */ 162 | v_fill(par->fs_mag,1.0,NUM_HARM); 163 | if (par->bpvc[0] > bpthresh) { 164 | lpc_lsp2pred(par->lsf,lpc,LPC_ORD); 165 | zerflt(&speech[(FRAME_END-(LPC_FRAME/2))],lpc,sigbuf,LPC_ORD,LPC_FRAME); 166 | window(sigbuf,win_cof,sigbuf,LPC_FRAME); 167 | find_harm(sigbuf, par->fs_mag, par->pitch, NUM_HARM, LPC_FRAME); 168 | } 169 | 170 | /* quantize Fourier coefficients */ 171 | /* pre-weight vector, then use Euclidean distance */ 172 | window(&par->fs_mag[0],w_fs,&par->fs_mag[0],NUM_HARM); 173 | fsvq_enc(&par->fs_mag[0], &par->fs_mag[0], par->fsvq_par); 174 | 175 | 176 | /* Write channel bitstream */ 177 | melp_chn_write(par); 178 | 179 | /* Update delay buffers for next frame */ 180 | v_equ(&speech[0],&speech[FRAME],IN_BEG); 181 | fpitch[0] = fpitch[1]; 182 | } 183 | 184 | 185 | 186 | /* 187 | * melp_ana_init: perform initialization 188 | */ 189 | void melp_ana_init(melp_param_t *par) 190 | { 191 | int i; 192 | 193 | bpvc_ana_init(); 194 | pitch_ana_init(); 195 | p_avg_init(); 196 | 197 | v_zap(speech,IN_BEG+FRAME); 198 | pitch_avg=DEFAULT_PITCH_; 199 | v_fill(fpitch,DEFAULT_PITCH_,2); 200 | v_zap(lpfsp_del,LPF_ORD); 201 | 202 | /* Initialize multi-stage vector quantization (read codebook) */ 203 | 204 | par->msvq_par.num_best = MSVQ_M; 205 | par->msvq_par.num_stages = 4; 206 | par->msvq_par.num_dimensions = 10; 207 | 208 | par->msvq_par.levels[0] = 128; 209 | par->msvq_par.levels[1] = 64; 210 | par->msvq_par.levels[2] = 64; 211 | par->msvq_par.levels[3] = 64; 212 | 213 | par->msvq_par.bits[0] = 7; 214 | par->msvq_par.bits[1] = 6; 215 | par->msvq_par.bits[2] = 6; 216 | par->msvq_par.bits[3] = 6; 217 | 218 | par->msvq_par.cb = msvq_cb; 219 | 220 | /* Initialize Fourier magnitude vector quantization (read codebook) */ 221 | 222 | par->fsvq_par.num_best = 1; 223 | par->fsvq_par.num_stages = 1; 224 | par->fsvq_par.num_dimensions = NUM_HARM; 225 | 226 | par->fsvq_par.levels[0] = FS_LEVELS; 227 | par->fsvq_par.bits[0] = FS_BITS; 228 | par->fsvq_par.cb = fsvq_cb; 229 | 230 | /* Initialize fixed MSE weighting */ 231 | vq_fsw(w_fs, NUM_HARM, 60.0f); 232 | 233 | /* Pre-weight codebook (assume single stage only) */ 234 | if (fsvq_weighted == 0) 235 | { 236 | fsvq_weighted = 1; 237 | /* Scale codebook to 0 to 1 */ 238 | v_scale(msvq_cb,(2.0f/FSAMP),3200); 239 | for (i = 0; i < FS_LEVELS; i++) 240 | window(&fsvq_cb[i*NUM_HARM],w_fs,&fsvq_cb[i*NUM_HARM], NUM_HARM); 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* */ 19 | /* melp.c: Mixed Excitation LPC speech coder */ 20 | /* */ 21 | 22 | /* compiler include files */ 23 | #include 24 | #include "melp.h" 25 | #include "spbstd.h" 26 | #include "mat.h" 27 | #include "dsp_sub.h" 28 | #include "melp_sub.h" 29 | 30 | /* note: CHSIZE is shortest integer number of words in channel packet */ 31 | #define CHSIZE 9 32 | #define NUM_CH_BITS 54 33 | 34 | 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | 41 | //#include "sc1200.h" 42 | //#include "mat_lib.h" 43 | //#include "global.h" 44 | //#include "macro.h" 45 | //#include "mathhalf.h" 46 | //#include "dsp_sub.h" 47 | //#include "melp_sub.h" 48 | //#include "constant.h" 49 | //#include "math_lib.h" 50 | //#include "math.h" 51 | //#include "transcode.h" 52 | 53 | /* ====== External memory ====== */ 54 | 55 | #define FRAME 180 /* speech frame size */ 56 | #define NF 3 /* number of frames in one block */ 57 | #define BLOCK (NF*FRAME) 58 | 59 | typedef unsigned short uint16_t; 60 | typedef signed short int16_t; 61 | 62 | int mode; 63 | int rate; 64 | 65 | /* ========== Static Variables ========== */ 66 | 67 | char in_name[256], out_name[256]; 68 | struct melp_param melp_ana_par; /* melp analysis parameters */ 69 | struct melp_param melp_syn_par; /* melp synthesis parameters */ 70 | 71 | /* ========== Local Private Prototypes ========== */ 72 | 73 | static void parseCommandLine(int argc, char *argv[]); 74 | static void printHelpMessage(char *argv[]); 75 | 76 | static char *cmd_line[] = {"melp", "-i", "test_in.raw", "-o", "test_out.raw", 0}; 77 | 78 | extern int main_cmd(int argc, char *argv[]); 79 | 80 | #define MAXSIZE 1024 81 | #define SIGMAX 32767 82 | typedef int16_t SPEECH; 83 | 84 | SPEECH int_sp[MAXSIZE]; /* integer input array */ 85 | 86 | /* */ 87 | /* Subroutine READBL: read block of input data */ 88 | /* */ 89 | int readbl(float input[], FILE *fp_in, int size) 90 | { 91 | int i, length; 92 | 93 | length = fread(int_sp,sizeof(SPEECH),size,fp_in); 94 | for (i = 0; i < length; i++ ) 95 | input[i] = (float) int_sp[i]; 96 | for (i = length; i < size; i++ ) 97 | input[i] = 0.0f; 98 | 99 | return length; 100 | } 101 | 102 | /* */ 103 | /* Subroutine WRITEBL: write block of output data */ 104 | /* */ 105 | void writebl(float output[], FILE *fp_out, int size) 106 | 107 | { 108 | int i; 109 | float temp; 110 | 111 | for (i = 0; i < size; i++ ) { 112 | temp = output[i]; 113 | /* clamp to +- SIGMAX */ 114 | if (temp > SIGMAX) temp = SIGMAX; 115 | if (temp < -SIGMAX) temp = -SIGMAX; 116 | int_sp[i] = (SPEECH)temp; 117 | } 118 | fwrite(int_sp,sizeof(SPEECH),size,fp_out); 119 | } 120 | 121 | 122 | int main() 123 | { 124 | main_cmd(5, cmd_line); 125 | } 126 | 127 | /**************************************************************************** 128 | ** 129 | ** Function: main 130 | ** 131 | ** Description: The main function of the speech coder 132 | ** 133 | ** Arguments: 134 | ** 135 | ** int argc ---- number of command line parameters 136 | ** char *argv[] ---- command line parameters 137 | ** 138 | ** Return value: None 139 | ** 140 | *****************************************************************************/ 141 | int main_cmd(int argc, char *argv[]) 142 | { 143 | int length; 144 | int frame_count; 145 | 146 | float speech_in[BLOCK], speech_out[BLOCK]; 147 | int eof_reached = FALSE; 148 | FILE *fp_in, *fp_out; 149 | 150 | /* ====== Get input parameters from command line ====== */ 151 | parseCommandLine(argc, argv); 152 | 153 | /* ====== Open input, output, and parameter files ====== */ 154 | if ((fp_in = fopen(in_name,"rb")) == NULL){ 155 | fprintf(stderr, " ERROR: cannot read file %s.\n", in_name); 156 | exit(1); 157 | } 158 | if ((fp_out = fopen(out_name,"wb")) == NULL){ 159 | fprintf(stderr, " ERROR: cannot write file %s.\n", out_name); 160 | fclose(fp_in); 161 | exit(1); 162 | } 163 | 164 | /* ====== Initialize MELP analysis and synthesis ====== */ 165 | melp_ana_init(&melp_ana_par); 166 | melp_syn_init(&melp_syn_par); 167 | 168 | /* ====== Run MELP coder on input signal ====== */ 169 | frame_count = 0; 170 | eof_reached = FALSE; 171 | while (!eof_reached) 172 | { 173 | fprintf(stderr, "Frame = %ld\r", frame_count); 174 | 175 | /* Perform MELP analysis */ 176 | length = readbl(speech_in, fp_in, FRAME); 177 | if (length < FRAME){ 178 | eof_reached = TRUE; 179 | } 180 | melp_ana(speech_in, &melp_ana_par); 181 | 182 | /* Perform MELP synthesis */ 183 | melp_syn(&melp_syn_par, speech_out); 184 | writebl(speech_out, fp_out, FRAME); 185 | frame_count++; 186 | } 187 | 188 | fclose(fp_in); 189 | fclose(fp_out); 190 | fprintf(stderr, "\n\n"); 191 | 192 | return(0); 193 | } 194 | 195 | 196 | /**************************************************************************** 197 | ** 198 | ** Function: parseCommandLine 199 | ** 200 | ** Description: Translate command line parameters 201 | ** 202 | ** Arguments: 203 | ** 204 | ** int argc ---- number of command line parameters 205 | ** char *argv[] ---- command line parameters 206 | ** 207 | ** Return value: None 208 | ** 209 | *****************************************************************************/ 210 | static void parseCommandLine(int argc, char *argv[]) 211 | { 212 | int16_t i; 213 | int error_flag = FALSE; 214 | 215 | if (argc < 2) 216 | error_flag = TRUE; 217 | 218 | /* Setting default values. */ 219 | mode = ANA_SYN; 220 | rate = RATE2400; 221 | in_name[0] = '\0'; 222 | out_name[0] = '\0'; 223 | 224 | for (i = 1; i < argc; i++){ 225 | if ((strncmp(argv[i], "-h", 2 ) == 0) || 226 | (strncmp(argv[i], "-help", 5) == 0)){ 227 | printHelpMessage(argv); 228 | exit(0); 229 | } else if ((strncmp(argv[i], "-a", 2)) == 0) 230 | mode = ANALYSIS; 231 | else if ((strncmp(argv[i], "-s", 2)) == 0) 232 | mode = SYNTHESIS; 233 | else if ((strncmp(argv[i], "-i", 2)) == 0){ 234 | i++; 235 | if (i < argc) 236 | strcpy(in_name, argv[i]); 237 | else 238 | error_flag = TRUE; 239 | } else if ((strncmp(argv[i], "-o", 2)) == 0){ 240 | i++; 241 | if (i < argc) 242 | strcpy(out_name, argv[i]); 243 | else 244 | error_flag = TRUE; 245 | } else 246 | error_flag = TRUE; 247 | } 248 | 249 | if ((in_name[0] == '\0') || (out_name[0] == '\0')) 250 | error_flag = TRUE; 251 | 252 | if (error_flag){ 253 | printHelpMessage(argv); 254 | exit(1); 255 | } 256 | switch (mode){ 257 | case ANA_SYN: 258 | case ANALYSIS: 259 | case SYNTHESIS: 260 | if (rate == RATE2400) 261 | fprintf(stderr, " ---- 2.4kbps mode.\n"); 262 | else 263 | fprintf(stderr, " ---- 1.2kbps mode.\n"); 264 | break; 265 | } 266 | switch (mode){ 267 | case ANA_SYN: 268 | fprintf(stderr, " ---- Analysis and Synthesis.\n"); break; 269 | case ANALYSIS: 270 | fprintf(stderr, " ---- Analysis only.\n"); break; 271 | case SYNTHESIS: 272 | fprintf(stderr, " ---- Synthesis only.\n"); break; 273 | } 274 | 275 | fprintf(stderr, " ---- input from %s.\n", in_name); 276 | fprintf(stderr, " ---- output to %s.\n", out_name); 277 | } 278 | 279 | 280 | /**************************************************************************** 281 | ** 282 | ** Function: printHelpMessage 283 | ** 284 | ** Description: Print Command Line Usage 285 | ** 286 | ** Arguments: 287 | ** 288 | ** Return value: None 289 | ** 290 | *****************************************************************************/ 291 | static void printHelpMessage(char *argv[]) 292 | { 293 | fprintf(stdout, "Usage:\n"); 294 | fprintf(stdout, "\t%s [-as] -i infile -o outfile\n", argv[0]); 295 | fprintf(stdout, "\t\tdefault: Analysis/Synthesis at 2.4kbps\n"); 296 | fprintf(stdout, "\t\t-a --analysis\tAnalysis only\n"); 297 | fprintf(stdout, "\t\t-s --synthesis\tSynthesis only\n\n"); 298 | } 299 | -------------------------------------------------------------------------------- /pit_lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | 20 | pit_lib.c: pitch analysis subroutines 21 | 22 | */ 23 | 24 | #include 25 | #include 26 | #include "melp.h" 27 | #include "spbstd.h" 28 | #include "mat.h" 29 | #include "melp_sub.h" 30 | #include "dsp_sub.h" 31 | #include "pit.h" 32 | 33 | /* Static data */ 34 | static float lpres_del[LPF_ORD] CCMRAM; 35 | static float sigbuf[LPF_ORD+PITCH_FR] CCMRAM; 36 | static float good_pitch[NUM_GOOD] CCMRAM; 37 | 38 | /* */ 39 | /* double_chk.c: check for pitch doubling */ 40 | /* and also verify pitch multiple for short pitches. */ 41 | /* */ 42 | float double_chk(float sig_in[], float *pcorr, float pitch, float pdouble, int pmin, int pmax, int lmin) 43 | { 44 | int mult; 45 | float corr,thresh; 46 | float temp_pit; 47 | 48 | pitch = frac_pch(sig_in,pcorr,pitch,0,pmin,pmax,lmin); 49 | thresh = pdouble * (*pcorr); 50 | 51 | /* Check pitch submultiples from shortest to longest */ 52 | for (mult = NUM_MULT; mult >= 2; mult--) { 53 | temp_pit = pitch / mult; 54 | if (temp_pit >= pmin) { 55 | temp_pit = frac_pch(sig_in,&corr,temp_pit,0,pmin,pmax,lmin); 56 | double_ver(sig_in,&corr,temp_pit,pmin,pmax,lmin); 57 | 58 | /* stop if submultiple greater than threshold */ 59 | if (corr > thresh) { 60 | /* refine estimate one more time since previous window */ 61 | /* may be off center slightly and temp_pit has moved */ 62 | pitch = frac_pch(sig_in,pcorr,temp_pit,0,pmin,pmax,lmin); 63 | break; 64 | } 65 | } 66 | } 67 | 68 | /* Verify pitch multiples for short pitches */ 69 | double_ver(sig_in,pcorr,pitch,pmin,pmax,lmin); 70 | 71 | /* Return full floating point pitch value and correlation*/ 72 | return(pitch); 73 | } 74 | 75 | 76 | /* */ 77 | /* double_ver.c: verify pitch multiple for short pitches. */ 78 | /* */ 79 | void double_ver(float sig_in[], float *pcorr, float pitch, int pmin, int pmax, int lmin) 80 | { 81 | 82 | int mult; 83 | float corr,temp_pit; 84 | 85 | /* Verify pitch multiples for short pitches */ 86 | mult = 1; 87 | while (pitch*mult < SHORT_PITCH) 88 | mult++; 89 | 90 | if (mult > 1) { 91 | temp_pit = pitch * mult; 92 | temp_pit = frac_pch(sig_in,&corr,temp_pit,0,pmin,pmax,lmin); 93 | 94 | /* use smaller of two correlation values */ 95 | if (corr < *pcorr) 96 | *pcorr = corr; 97 | } 98 | } 99 | 100 | /* */ 101 | /* find_pitch.c: Determine pitch value. */ 102 | /* */ 103 | 104 | float find_pitch(float sig_in[], float *pcorr, int lower, int upper, 105 | int length) 106 | { 107 | 108 | int i,cbegin,ipitch,even_flag; 109 | float corr,maxcorr; 110 | float c0_0,cT_T; 111 | 112 | /* Find beginning of correlation window centered on signal */ 113 | ipitch = lower; 114 | maxcorr = 0.0f; 115 | even_flag = 1; 116 | cbegin = - ((length+upper)/2); 117 | c0_0 = v_magsq(&sig_in[cbegin],length); 118 | cT_T = v_magsq(&sig_in[cbegin+upper],length); 119 | 120 | for (i = upper; i >= lower; i--) { 121 | /* calculate normalized cross correlation */ 122 | corr = v_inner(&sig_in[cbegin],&sig_in[cbegin+i],length); 123 | if (corr > 0.01f) 124 | corr = (corr*corr) / (c0_0*cT_T); 125 | 126 | /* check if current maximum value */ 127 | if (corr > maxcorr) { 128 | maxcorr = corr; 129 | ipitch = i; 130 | } 131 | 132 | /* update for next iteration */ 133 | if (even_flag) { 134 | even_flag = 0; 135 | c0_0 += (sig_in[cbegin+length]*sig_in[cbegin+length]); 136 | c0_0 -= (sig_in[cbegin]*sig_in[cbegin]); 137 | cbegin++; 138 | }else { 139 | even_flag = 1; 140 | cT_T += (sig_in[cbegin+i-1]*sig_in[cbegin+i-1]); 141 | cT_T -= (sig_in[cbegin+i-1+length]*sig_in[cbegin+i-1+length]); 142 | } 143 | } 144 | 145 | /* Return full floating point pitch value and correlation*/ 146 | *pcorr = arm_sqrt(maxcorr); 147 | return((float) ipitch); 148 | } 149 | 150 | /* 151 | Name: frac_pch.c 152 | Description: Determine fractional pitch. 153 | Inputs: 154 | sig_in - input signal 155 | fpitch - initial floating point pitch estimate 156 | range - range for local integer pitch search (0=none) 157 | pmin - minimum allowed pitch value 158 | pmax - maximum allowed pitch value 159 | lmin - minimum correlation length 160 | Outputs: 161 | pcorr - correlation at fractional pitch value 162 | Returns: fpitch - fractional pitch value 163 | 164 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 165 | */ 166 | 167 | 168 | float frac_pch(float sig_in[], float *pcorr, float fpitch, int range, int pmin, int pmax, int lmin) 169 | { 170 | int length,cbegin,lower,upper,ipitch; 171 | float c0_0,c0_T,c0_T1,cT_T,cT_T1,cT1_T1,c0_Tm1; 172 | float frac,frac1; 173 | float corr,denom; 174 | 175 | /* Perform local integer pitch search for better fpitch estimate */ 176 | if (range > 0) { 177 | ipitch = (int) (fpitch + 0.5f); 178 | lower = ipitch - range; 179 | upper = ipitch + range; 180 | if (upper > pmax) 181 | upper = pmax; 182 | if (lower < pmin) 183 | lower = pmin; 184 | if (lower < 0.75f*ipitch) 185 | lower = (int) (0.75f*ipitch); 186 | length = ipitch; 187 | if (length < lmin) 188 | length = lmin; 189 | fpitch = find_pitch(sig_in,&corr,lower,upper,length); 190 | } 191 | 192 | /* Estimate needed crosscorrelations */ 193 | ipitch = (int) (fpitch + 0.5f); 194 | if (ipitch >= pmax) ipitch = pmax - 1; 195 | length = ipitch; 196 | if (length < lmin) length = lmin; 197 | cbegin = - ((length+ipitch)/2); 198 | c0_T = v_inner(&sig_in[cbegin],&sig_in[cbegin+ipitch],length); 199 | c0_T1 = v_inner(&sig_in[cbegin],&sig_in[cbegin+ipitch+1],length); 200 | c0_Tm1 = v_inner(&sig_in[cbegin],&sig_in[cbegin+ipitch-1],length); 201 | if (c0_Tm1 > c0_T1) { 202 | /* fractional component should be less than 1, so decrement pitch */ 203 | c0_T1 = c0_T; 204 | c0_T = c0_Tm1; 205 | ipitch-- ; 206 | } 207 | cT_T1 = v_inner(&sig_in[cbegin+ipitch],&sig_in[cbegin+ipitch+1],length); 208 | c0_0 = v_inner(&sig_in[cbegin],&sig_in[cbegin],length); 209 | cT_T = v_inner(&sig_in[cbegin+ipitch],&sig_in[cbegin+ipitch],length); 210 | cT1_T1 = v_inner(&sig_in[cbegin+ipitch+1],&sig_in[cbegin+ipitch+1],length); 211 | 212 | /* Find fractional component of pitch within integer range */ 213 | denom = c0_T1*(cT_T - cT_T1) + c0_T*(cT1_T1 - cT_T1); 214 | if (fabs(denom) > 0.01f) 215 | frac = (c0_T1*cT_T - c0_T*cT_T1) / denom; 216 | else 217 | frac = 0.5f; 218 | if (frac > MAXFRAC) frac = MAXFRAC; 219 | if (frac < MINFRAC) frac = MINFRAC; 220 | 221 | /* Make sure pitch is still within range */ 222 | fpitch = ipitch + frac; 223 | if (fpitch > pmax) fpitch = (float) pmax; 224 | if (fpitch < pmin) fpitch = (float) pmin; 225 | frac = fpitch - ipitch; 226 | 227 | /* Calculate interpolated correlation strength */ 228 | frac1 = 1.0f - frac; 229 | denom = c0_0*(frac1*frac1*cT_T + 2*frac*frac1*cT_T1 + frac*frac*cT1_T1); 230 | denom = arm_sqrt(denom); 231 | if (fabs(denom) > 0.01f) 232 | *pcorr = (frac1*c0_T + frac*c0_T1) / denom; 233 | else 234 | *pcorr = 0.0f; 235 | 236 | /* Return full floating point pitch value */ 237 | return(fpitch); 238 | } 239 | 240 | /* 241 | Name: p_avg_update.c 242 | Description: Update pitch average value. 243 | Inputs: 244 | pitch - current pitch value 245 | pcorr - correlation strength at current pitch value 246 | pthresh - pitch correlation threshold 247 | Returns: pitch_avg - updated average pitch value 248 | 249 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 250 | */ 251 | float p_avg_update(float pitch, float pcorr, float pthresh) 252 | { 253 | int i; 254 | float pitch_avg; 255 | 256 | /* Strong correlation: update good pitch array */ 257 | if (pcorr > pthresh) { 258 | for (i = NUM_GOOD-1; i >= 1; i--) 259 | good_pitch[i] = good_pitch[i-1]; 260 | good_pitch[0] = pitch; 261 | }else { 262 | /* Otherwise decay good pitch array to default value */ 263 | for (i = 0; i < NUM_GOOD; i++) 264 | good_pitch[i] = (PDECAY * good_pitch[i]) +((1.0f - PDECAY)*DEFAULT_PITCH_); 265 | } 266 | 267 | /* Pitch_avg = median of pitch values */ 268 | pitch_avg = median(good_pitch,NUM_GOOD); 269 | 270 | return(pitch_avg); 271 | } 272 | 273 | void p_avg_init() 274 | { 275 | /* Allocate and initialize good pitch array */ 276 | v_fill(good_pitch,DEFAULT_PITCH_,NUM_GOOD); 277 | } 278 | 279 | /* 280 | Name: pitch_ana.c 281 | Description: Pitch analysis 282 | Inputs: 283 | speech[] - input speech signal 284 | resid[] - LPC residual signal 285 | pitch_est - initial (floating point) pitch estimate 286 | pitch_avg - average pitch value 287 | Outputs: 288 | pcorr2 - pitch correlation strength 289 | Returns: pitch - pitch estimate 290 | 291 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 292 | */ 293 | 294 | float pitch_ana(float speech[], float resid[], float pitch_est, float pitch_avg, float *pcorr2) 295 | { 296 | 297 | float temp, temp2, pcorr, pitch; 298 | 299 | /* Lowpass filter residual signal */ 300 | v_equ(&sigbuf[LPF_ORD],&resid[-PITCHMAX],PITCH_FR); 301 | v_equ(sigbuf,lpres_del,LPF_ORD); 302 | polflt(&sigbuf[LPF_ORD],lpf_den,&sigbuf[LPF_ORD],LPF_ORD,PITCH_FR); 303 | v_equ(lpres_del,&sigbuf[FRAME],LPF_ORD); 304 | zerflt(&sigbuf[LPF_ORD],lpf_num,&sigbuf[LPF_ORD],LPF_ORD,PITCH_FR); 305 | 306 | /* Perform local search around pitch estimate */ 307 | temp = frac_pch(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr, 308 | pitch_est,5,PITCHMIN,PITCHMAX,MINLENGTH); 309 | 310 | if (pcorr < 0.6f) { 311 | /* If correlation is too low, try speech signal instead */ 312 | v_equ(&sigbuf[LPF_ORD],&speech[-PITCHMAX],PITCH_FR); 313 | temp = frac_pch(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr, 314 | pitch_est,0,PITCHMIN,PITCHMAX,MINLENGTH); 315 | 316 | if (pcorr < UVMAX) 317 | /* If correlation still too low, use average pitch */ 318 | pitch = pitch_avg; 319 | else { 320 | /* Else check for pitch doubling (speech thresholds) */ 321 | temp2 = PDOUBLE3; 322 | if (temp > LONG_PITCH) 323 | /* longer pitches are more likely to be doubles */ 324 | temp2 = PDOUBLE4; 325 | pitch = double_chk(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr, 326 | temp,temp2,PITCHMIN,PITCHMAX,MINLENGTH); 327 | } 328 | }else { 329 | /* Else check for pitch doubling (residual thresholds) */ 330 | temp2 = PDOUBLE1; 331 | /* longer pitches are more likely to be doubles */ 332 | if (temp > LONG_PITCH) 333 | temp2 = PDOUBLE2; 334 | pitch = double_chk(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr, 335 | temp,temp2,PITCHMIN,PITCHMAX,MINLENGTH); 336 | } 337 | 338 | if (pcorr < UVMAX) { 339 | /* If correlation still too low, use average pitch */ 340 | pitch = pitch_avg; 341 | } 342 | 343 | /* Return pitch and set correlation strength */ 344 | *pcorr2 = pcorr; 345 | return(pitch); 346 | } 347 | 348 | void pitch_ana_init() 349 | { 350 | /* Allocate and initialize delay memory */ 351 | v_zap(lpres_del,LPF_ORD); 352 | } 353 | -------------------------------------------------------------------------------- /coeff.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* Coeff.c: filter coefficient file */ 19 | /* */ 20 | /* */ 21 | /* (C) 1993,1994 Texas Instruments */ 22 | /* */ 23 | #include 24 | #include "melp.h" 25 | 26 | /* Butterworth lowpass filter */ 27 | /* numerator */ 28 | const float lpf_num[LPF_ORD+1] RODATA = { 29 | 0.00105165f, 30 | 0.00630988f, 31 | 0.01577470f, 32 | 0.02103294f, 33 | 0.01577470f, 34 | 0.00630988f, 35 | 0.00105165f}; 36 | /* denominator */ 37 | const float lpf_den[LPF_ORD+1] RODATA = { 38 | 1.00000000f, 39 | -2.97852993f, 40 | 4.13608100f, 41 | -3.25976428f, 42 | 1.51727884f, 43 | -0.39111723f, 44 | 0.04335699f}; 45 | 46 | /* Butterworth bandpass filters */ 47 | const float bpf_num[NUM_BANDS*(BPF_ORD+1)] RODATA = { 48 | 0.00002883f, 49 | 0.00017296f, 50 | 0.00043239f, 51 | 0.00057652f, 52 | 0.00043239f, 53 | 0.00017296f, 54 | 0.00002883f, 55 | 0.00530041f, 56 | 0.00000000f, 57 | -0.01590123f, 58 | 0.00000000f, 59 | 0.01590123f, 60 | 0.00000000f, 61 | -0.00530041f, 62 | 0.03168934f, 63 | 0.00000000f, 64 | -0.09506803f, 65 | -0.00000000f, 66 | 0.09506803f, 67 | -0.00000000f, 68 | -0.03168934f, 69 | 0.03168934f, 70 | 0.00000000f, 71 | -0.09506803f, 72 | 0.00000000f, 73 | 0.09506803f, 74 | 0.00000000f, 75 | -0.03168934f, 76 | 0.00105165f, 77 | -0.00630988f, 78 | 0.01577470f, 79 | -0.02103294f, 80 | 0.01577470f, 81 | -0.00630988f, 82 | 0.00105165f}; 83 | 84 | const float bpf_den[NUM_BANDS*(BPF_ORD+1)] RODATA = { 85 | 1.00000000, 86 | -4.48456301f, 87 | 8.52900508f, 88 | -8.77910797f, 89 | 5.14764268f, 90 | -1.62771478f, 91 | 0.21658286f, 92 | 1.00000000f, 93 | -4.42459751f, 94 | 8.79771496f, 95 | -9.95335557f, 96 | 6.75320305f, 97 | -2.60749972f, 98 | 0.45354593f, 99 | 1.00000000f, 100 | -1.84699031f, 101 | 2.63060194f, 102 | -2.21638838f, 103 | 1.57491237f, 104 | -0.62291281f, 105 | 0.19782519f, 106 | 1.00000000f, 107 | 1.84699031f, 108 | 2.63060194f, 109 | 2.21638838f, 110 | 1.57491237f, 111 | 0.62291281f, 112 | 0.19782519f, 113 | 1.00000000f, 114 | 2.97852993f, 115 | 4.13608100f, 116 | 3.25976428f, 117 | 1.51727884f, 118 | 0.39111723f, 119 | 0.04335699f}; 120 | 121 | /* Hamming window coefficients */ 122 | const float win_cof[LPC_FRAME] RODATA = { 123 | 0.08000000f, 124 | 0.08022927f, 125 | 0.08091685f, 126 | 0.08206205f, 127 | 0.08366374f, 128 | 0.08572031f, 129 | 0.08822971f, 130 | 0.09118945f, 131 | 0.09459658f, 132 | 0.09844769f, 133 | 0.10273895f, 134 | 0.10746609f, 135 | 0.11262438f, 136 | 0.11820869f, 137 | 0.12421345f, 138 | 0.13063268f, 139 | 0.13745997f, 140 | 0.14468852f, 141 | 0.15231113f, 142 | 0.16032019f, 143 | 0.16870773f, 144 | 0.17746538f, 145 | 0.18658441f, 146 | 0.19605574f, 147 | 0.20586991f, 148 | 0.21601716f, 149 | 0.22648736f, 150 | 0.23727007f, 151 | 0.24835455f, 152 | 0.25972975f, 153 | 0.27138433f, 154 | 0.28330667f, 155 | 0.29548489f, 156 | 0.30790684f, 157 | 0.32056016f, 158 | 0.33343221f, 159 | 0.34651017f, 160 | 0.35978102f, 161 | 0.37323150f, 162 | 0.38684823f, 163 | 0.40061762f, 164 | 0.41452595f, 165 | 0.42855935f, 166 | 0.44270384f, 167 | 0.45694532f, 168 | 0.47126959f, 169 | 0.48566237f, 170 | 0.50010932f, 171 | 0.51459603f, 172 | 0.52910806f, 173 | 0.54363095f, 174 | 0.55815022f, 175 | 0.57265140f, 176 | 0.58712003f, 177 | 0.60154169f, 178 | 0.61590200f, 179 | 0.63018666f, 180 | 0.64438141f, 181 | 0.65847211f, 182 | 0.67244472f, 183 | 0.68628531f, 184 | 0.69998007f, 185 | 0.71351536f, 186 | 0.72687769f, 187 | 0.74005374f, 188 | 0.75303036f, 189 | 0.76579464f, 190 | 0.77833383f, 191 | 0.79063545f, 192 | 0.80268724f, 193 | 0.81447716f, 194 | 0.82599349f, 195 | 0.83722473f, 196 | 0.84815969f, 197 | 0.85878747f, 198 | 0.86909747f, 199 | 0.87907943f, 200 | 0.88872338f, 201 | 0.89801971f, 202 | 0.90695917f, 203 | 0.91553283f, 204 | 0.92373215f, 205 | 0.93154896f, 206 | 0.93897547f, 207 | 0.94600427f, 208 | 0.95262835f, 209 | 0.95884112f, 210 | 0.96463638f, 211 | 0.97000835f, 212 | 0.97495168f, 213 | 0.97946144f, 214 | 0.98353313f, 215 | 0.98716270f, 216 | 0.99034653f, 217 | 0.99308145f, 218 | 0.99536472f, 219 | 0.99719408f, 220 | 0.99856769f, 221 | 0.99948420f, 222 | 0.99994268f, 223 | 0.99994268f, 224 | 0.99948420f, 225 | 0.99856769f, 226 | 0.99719408f, 227 | 0.99536472f, 228 | 0.99308145f, 229 | 0.99034653f, 230 | 0.98716270f, 231 | 0.98353313f, 232 | 0.97946144f, 233 | 0.97495168f, 234 | 0.97000835f, 235 | 0.96463638f, 236 | 0.95884112f, 237 | 0.95262835f, 238 | 0.94600427f, 239 | 0.93897547f, 240 | 0.93154896f, 241 | 0.92373215f, 242 | 0.91553283f, 243 | 0.90695917f, 244 | 0.89801971f, 245 | 0.88872338f, 246 | 0.87907943f, 247 | 0.86909747f, 248 | 0.85878747f, 249 | 0.84815969f, 250 | 0.83722473f, 251 | 0.82599349f, 252 | 0.81447716f, 253 | 0.80268724f, 254 | 0.79063545f, 255 | 0.77833383f, 256 | 0.76579464f, 257 | 0.75303036f, 258 | 0.74005374f, 259 | 0.72687769f, 260 | 0.71351536f, 261 | 0.69998007f, 262 | 0.68628531f, 263 | 0.67244472f, 264 | 0.65847211f, 265 | 0.64438141f, 266 | 0.63018666f, 267 | 0.61590200f, 268 | 0.60154169f, 269 | 0.58712003f, 270 | 0.57265140f, 271 | 0.55815022f, 272 | 0.54363095f, 273 | 0.52910806f, 274 | 0.51459603f, 275 | 0.50010932f, 276 | 0.48566237f, 277 | 0.47126959f, 278 | 0.45694532f, 279 | 0.44270384f, 280 | 0.42855935f, 281 | 0.41452595f, 282 | 0.40061762f, 283 | 0.38684823f, 284 | 0.37323150f, 285 | 0.35978102f, 286 | 0.34651017f, 287 | 0.33343221f, 288 | 0.32056016f, 289 | 0.30790684f, 290 | 0.29548489f, 291 | 0.28330667f, 292 | 0.27138433f, 293 | 0.25972975f, 294 | 0.24835455f, 295 | 0.23727007f, 296 | 0.22648736f, 297 | 0.21601716f, 298 | 0.20586991f, 299 | 0.19605574f, 300 | 0.18658441f, 301 | 0.17746538f, 302 | 0.16870773f, 303 | 0.16032019f, 304 | 0.15231113f, 305 | 0.14468852f, 306 | 0.13745997f, 307 | 0.13063268f, 308 | 0.12421345f, 309 | 0.11820869f, 310 | 0.11262438f, 311 | 0.10746609f, 312 | 0.10273895f, 313 | 0.09844769f, 314 | 0.09459658f, 315 | 0.09118945f, 316 | 0.08822971f, 317 | 0.08572031f, 318 | 0.08366374f, 319 | 0.08206205f, 320 | 0.08091685f, 321 | 0.08022927f, 322 | 0.08000000f}; 323 | 324 | /* Bandpass filter coefficients */ 325 | const float bp_cof[NUM_BANDS][MIX_ORD+1] RODATA = { 326 | { 327 | -0.00000000f, 328 | -0.00302890f, 329 | -0.00701117f, 330 | -0.01130619f, 331 | -0.01494082f, 332 | -0.01672586f, 333 | -0.01544189f, 334 | -0.01006619f, 335 | 0.00000000f, 336 | 0.01474923f, 337 | 0.03347158f, 338 | 0.05477206f, 339 | 0.07670890f, 340 | 0.09703726f, 341 | 0.11352143f, 342 | 0.12426379f, 343 | 0.12799355f, 344 | 0.12426379f, 345 | 0.11352143f, 346 | 0.09703726f, 347 | 0.07670890f, 348 | 0.05477206f, 349 | 0.03347158f, 350 | 0.01474923f, 351 | 0.00000000f, 352 | -0.01006619f, 353 | -0.01544189f, 354 | -0.01672586f, 355 | -0.01494082f, 356 | -0.01130619f, 357 | -0.00701117f, 358 | -0.00302890f, 359 | -0.00000000 360 | }, 361 | { 362 | -0.00000000f, 363 | -0.00249420f, 364 | -0.00282091f, 365 | 0.00257679f, 366 | 0.01451271f, 367 | 0.02868120f, 368 | 0.03621179f, 369 | 0.02784469f, 370 | -0.00000000f, 371 | -0.04079870f, 372 | -0.07849207f, 373 | -0.09392213f, 374 | -0.07451087f, 375 | -0.02211575f, 376 | 0.04567473f, 377 | 0.10232715f, 378 | 0.12432599f, 379 | 0.10232715f, 380 | 0.04567473f, 381 | -0.02211575f, 382 | -0.07451087f, 383 | -0.09392213f, 384 | -0.07849207f, 385 | -0.04079870f, 386 | -0.00000000f, 387 | 0.02784469f, 388 | 0.03621179f, 389 | 0.02868120f, 390 | 0.01451271f, 391 | 0.00257679f, 392 | -0.00282091f, 393 | -0.00249420f, 394 | -0.00000000 395 | }, 396 | { 397 | -0.00000000f, 398 | -0.00231491f, 399 | 0.00990113f, 400 | 0.02086129f, 401 | -0.00000000f, 402 | -0.03086123f, 403 | -0.02180695f, 404 | 0.00769333f, 405 | -0.00000000f, 406 | -0.01127245f, 407 | 0.04726837f, 408 | 0.10106105f, 409 | -0.00000000f, 410 | -0.17904543f, 411 | -0.16031428f, 412 | 0.09497157f, 413 | 0.25562154f, 414 | 0.09497157f, 415 | -0.16031428f, 416 | -0.17904543f, 417 | -0.00000000f, 418 | 0.10106105f, 419 | 0.04726837f, 420 | -0.01127245f, 421 | -0.00000000f, 422 | 0.00769333f, 423 | -0.02180695f, 424 | -0.03086123f, 425 | -0.00000000f, 426 | 0.02086129f, 427 | 0.00990113f, 428 | -0.00231491f, 429 | -0.00000000 430 | }, 431 | { 432 | -0.00000000f, 433 | 0.00231491f, 434 | 0.00990113f, 435 | -0.02086129f, 436 | 0.00000000f, 437 | 0.03086123f, 438 | -0.02180695f, 439 | -0.00769333f, 440 | -0.00000000f, 441 | 0.01127245f, 442 | 0.04726837f, 443 | -0.10106105f, 444 | 0.00000000f, 445 | 0.17904543f, 446 | -0.16031428f, 447 | -0.09497157f, 448 | 0.25562154f, 449 | -0.09497157f, 450 | -0.16031428f, 451 | 0.17904543f, 452 | 0.00000000f, 453 | -0.10106105f, 454 | 0.04726837f, 455 | 0.01127245f, 456 | -0.00000000f, 457 | -0.00769333f, 458 | -0.02180695f, 459 | 0.03086123f, 460 | 0.00000000f, 461 | -0.02086129f, 462 | 0.00990113f, 463 | 0.00231491f, 464 | -0.00000000 465 | }, 466 | { 467 | 0.00000000f, 468 | 0.00554149f, 469 | -0.00981750f, 470 | 0.00856805f, 471 | -0.00000000f, 472 | -0.01267517f, 473 | 0.02162277f, 474 | -0.01841647f, 475 | 0.00000000f, 476 | 0.02698425f, 477 | -0.04686914f, 478 | 0.04150730f, 479 | -0.00000000f, 480 | -0.07353666f, 481 | 0.15896026f, 482 | -0.22734513f, 483 | 0.25346255f, 484 | -0.22734513f, 485 | 0.15896026f, 486 | -0.07353666f, 487 | -0.00000000f, 488 | 0.04150730f, 489 | -0.04686914f, 490 | 0.02698425f, 491 | 0.00000000f, 492 | -0.01841647f, 493 | 0.02162277f, 494 | -0.01267517f, 495 | -0.00000000f, 496 | 0.00856805f, 497 | -0.00981750f, 498 | 0.00554149f, 499 | 0.00000000}}; 500 | /* Triangle pulse dispersion filter */ 501 | const float disp_cof[DISP_ORD+1] RODATA = { 502 | -0.17304259f, 503 | -0.01405709f, 504 | 0.01224406f, 505 | 0.11364226f, 506 | 0.00198199f, 507 | 0.00000658f, 508 | 0.04529633f, 509 | -0.00092027f, 510 | -0.00103078f, 511 | 0.02552787f, 512 | -0.06339257f, 513 | -0.00122031f, 514 | 0.01412525f, 515 | 0.24325127f, 516 | -0.01767043f, 517 | -0.00018612f, 518 | 0.05869485f, 519 | -0.00327456f, 520 | 0.00607395f, 521 | 0.02753924f, 522 | -0.03351673f, 523 | 0.00602189f, 524 | 0.01436539f, 525 | 0.82854582f, 526 | 0.00033165f, 527 | -0.00360180f, 528 | 0.07343483f, 529 | -0.00518645f, 530 | 0.01298488f, 531 | 0.02928440f, 532 | -0.01989405f, 533 | 0.01216758f, 534 | 0.01180979f, 535 | -0.38924775f, 536 | 0.00720325f, 537 | -0.01154561f, 538 | 0.08426287f, 539 | -0.00355720f, 540 | 0.02151233f, 541 | 0.02968464f, 542 | -0.01247640f, 543 | 0.01854666f, 544 | 0.00076184f, 545 | -0.07749640f, 546 | 0.01244697f, 547 | -0.02721777f, 548 | 0.07266098f, 549 | 0.00472008f, 550 | 0.03526439f, 551 | 0.02674603f, 552 | -0.00744038f, 553 | 0.02582623f, 554 | 0.00019707f, 555 | -0.02825247f, 556 | 0.01720989f, 557 | -0.06004292f, 558 | -0.07076744f, 559 | 0.00914347f, 560 | 0.06082730f, 561 | 0.01805528f, 562 | -0.00318634f, 563 | 0.03444110f, 564 | 0.00026302f, 565 | -0.01053809f, 566 | 0.02165922f}; 567 | -------------------------------------------------------------------------------- /vq_lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | 20 | vq_lib.c: vector quantization subroutines 21 | 22 | */ 23 | 24 | 25 | #include 26 | #include 27 | #include "spbstd.h" 28 | #include "vq.h" 29 | #include "mat.h" 30 | #include "lpc.h" 31 | #include "melp.h" 32 | 33 | #define BIGVAL 1E20f 34 | 35 | /* VQ_LSPW- compute LSP weighting vector- 36 | 37 | Atal's method: 38 | From Atal and Paliwal (ICASSP 1991) 39 | (Note: Paliwal and Atal used w(k)^2(u(k)-u_hat(k))^2, 40 | and we use w(k)(u(k)-u_hat(k))^2 so our weights are different 41 | but the method (i.e. the weighted MSE) is the same. 42 | 43 | */ 44 | 45 | float *vq_lspw(float *w,float *lsp,float *a,int p) 46 | { 47 | int j; 48 | 49 | for(j=0; j < p; j++) 50 | { 51 | w[j] = (float)powf(lpc_aejw(a,lsp[j]*M_PI,p),-0.3f); 52 | if (j == 8) 53 | w[j] *= 0.64f; 54 | else if (j == 9) 55 | w[j] *= 0.16f; 56 | } 57 | 58 | return(w); 59 | } /* VQ_LSPW */ 60 | 61 | /* 62 | VQ_MS4- 63 | Tree search multi-stage VQ encoder 64 | 65 | Synopsis: vq_ms4(cb,u,u_est,levels,ma,stages,p,w,u_hat,a_indices) 66 | Input: 67 | cb- one dimensional linear codebook array (codebook is structured 68 | as [stages][levels for each stage][p]) 69 | u- dimension p, the parameters to be encoded (u[0..p-1]) 70 | u_est- dimension p, the estimated parameters or mean (if NULL, assume 71 | estimate is the all zero vector) (u_est[0..p-1]) 72 | levels- the number of levels at each stage (levels[0..stages-1]) 73 | ma- the tree search size (keep ma candidates from one stage to the 74 | next) 75 | stages- the number of stages of msvq 76 | p- the predictor order 77 | w- the weighting vector (w[0..p-1]) 78 | max_inner- the maximum number of times the swapping procedure 79 | in the inner loop can be executed 80 | Output: 81 | u_hat- the reconstruction vector (if non null) 82 | a_indices- the codebook indices (for each stage) a_indices[0..stages-1] 83 | Parameters: 84 | 85 | */ 86 | 87 | #define P_SWAP(x,y,type) do{type u__p;u__p = x;x = y;y = u__p;}while(0) 88 | 89 | static int indices[2 * MSVQ_M * 4] CCMRAM; 90 | static int parents[2 * MSVQ_M] CCMRAM; 91 | static float errors[2 * MSVQ_M * 10] CCMRAM; 92 | static float uhatw[10] CCMRAM; 93 | static float d[2 * MSVQ_M] CCMRAM; 94 | static float u_tmp[10+1] CCMRAM; 95 | static float uhat[LPC_ORD] CCMRAM; 96 | 97 | float vq_ms4(float *cb, float *u, float *u_est, int *levels, int ma, int stages, int p, float *w, float *u_hat, int *a_indices,int max_inner) 98 | { 99 | float tmp, uhatw_sq; 100 | float d_cj,d_opt; 101 | float *p_d,*n_d,*p_distortion,*cb_currentstage,*cbp; 102 | float *p_errors,*n_errors,*p_e; 103 | int i,j,m,s,c,p_max,inner_counter; 104 | int *p_indices,*n_indices; 105 | int *p_parents,*n_parents; 106 | 107 | /* allocate memory for the current node and 108 | parent node (thus, the factors of two everywhere) 109 | The parents and current nodes are allocated contiguously */ 110 | 111 | /* initialize memory */ 112 | v_zap_int(indices,2*stages*ma); 113 | v_zap_int(parents,2*ma); 114 | 115 | /* initialize inner loop counter */ 116 | inner_counter = 0; 117 | 118 | /* set up memory */ 119 | p_indices = &indices[0]; 120 | n_indices = &indices[ma*stages]; 121 | p_errors = &errors[0]; 122 | n_errors = &errors[ma*p]; 123 | p_d = &d[0]; 124 | n_d = &d[ma]; 125 | p_parents = &parents[0]; 126 | n_parents = &parents[ma]; 127 | 128 | /* u_tmp is the input vector (i.e. if u_est is non-null, it is subtracted off) */ 129 | v_equ(u_tmp,u,p); 130 | if (u_est) 131 | { 132 | v_sub(u_tmp,u_est,p); 133 | } 134 | 135 | for(j=0,tmp=0.0; j < p; j++) 136 | { 137 | tmp += u_tmp[j]*u_tmp[j]*w[j]; 138 | } 139 | 140 | /* set up initial error vectors (i.e. error vectors = u_tmp) */ 141 | for(c=0; c < ma; c++) 142 | { 143 | v_equ(&n_errors[c*p],u_tmp,p); 144 | n_d[c] = tmp; 145 | } 146 | 147 | /* no longer need memory so free it here */ 148 | // MEM_FREE(FREE,u_tmp); 149 | 150 | /* codebook pointer is set to point to first stage */ 151 | cbp = cb; 152 | 153 | /* set m to 1 for the first stage 154 | and loop over all stages */ 155 | 156 | for(m=1,s=0; s < stages; s++) 157 | { 158 | /* Save the pointer to the beginning of the 159 | current stage. Note: cbp is only incremented in 160 | one spot, and it is incremented all the way through 161 | all the stages. */ 162 | cb_currentstage = cbp; 163 | 164 | /* set up pointers to the parent and current nodes */ 165 | P_SWAP(p_indices,n_indices,int*); 166 | P_SWAP(p_parents,n_parents,int*); 167 | P_SWAP(p_errors,n_errors,float*); 168 | P_SWAP(p_d,n_d,float*); 169 | 170 | /* p_max is the pointer to the maximum distortion 171 | node over all candidates. The so-called worst 172 | of the best. */ 173 | p_max = 0; 174 | 175 | /* set the distortions to a large value */ 176 | for(c=0; c < ma; c++) 177 | n_d[c] = BIGVAL; 178 | 179 | for(j=0; j < levels[s]; j++) 180 | { 181 | /* compute weighted codebook element, increment codebook pointer */ 182 | for(i=0,uhatw_sq=0.0; i < p; i++,cbp++) 183 | { 184 | uhatw_sq += *cbp * (tmp = *cbp * w[i]); 185 | uhatw[i] = -2.0f*tmp; 186 | } 187 | 188 | /* p_e points to the error vectors and p_distortion 189 | points to the node distortions. Note: the error 190 | vectors are contiguous in memory, as are the distortions. 191 | Thus, the error vector for the 2nd node comes immediately 192 | after the error for the first node. (This saves on 193 | repeated initializations) */ 194 | p_e = p_errors; 195 | p_distortion = p_d; 196 | 197 | /* iterate over all parent nodes */ 198 | for(c=0; c < m; c++) 199 | { 200 | d_cj = *p_distortion++ + uhatw_sq; 201 | for(i=0; i < p; i++) 202 | d_cj += *p_e++ * uhatw[i]; 203 | 204 | /* determine if d is less than the maximum candidate distortion 205 | i.e., is the distortion found better than the so-called 206 | worst of the best */ 207 | if (d_cj <= n_d[p_max]) 208 | { 209 | /* replace the worst with the values just found */ 210 | n_d[p_max] = d_cj; 211 | n_indices[p_max*stages+s] = j; 212 | n_parents[p_max] = c; 213 | 214 | /* want to limit the number of times the inner loop 215 | is entered (to reduce the *maximum* complexity) */ 216 | if (inner_counter < max_inner) 217 | { 218 | inner_counter++; 219 | if (inner_counter < max_inner) 220 | { 221 | p_max = 0; 222 | /* find the new maximum */ 223 | for(i=1; i < ma; i++) 224 | { 225 | if (n_d[i] > n_d[p_max]) 226 | p_max = i; 227 | } 228 | } 229 | else /* inner_counter == max_inner */ 230 | { 231 | /* The inner loop counter now exceeds the 232 | maximum, and the inner loop will now not 233 | be entered. Instead of quitting the search 234 | or doing something drastic, we simply keep 235 | track of the best candidate (rather than the 236 | M best) by setting p_max to equal the index 237 | of the minimum distortion 238 | i.e. only keep one candidate around 239 | the MINIMUM distortion */ 240 | for(i=1; i < ma; i++) 241 | { 242 | if (n_d[i] < n_d[p_max]) 243 | p_max = i; 244 | } 245 | } 246 | } 247 | } 248 | } /* for c */ 249 | } /* for j */ 250 | 251 | /* compute the error vectors for each node */ 252 | for(c=0; c < ma; c++) 253 | { 254 | /* get the error from the parent node and subtract off 255 | the codebook value */ 256 | v_equ(&n_errors[c*p],&p_errors[n_parents[c]*p],p); 257 | v_sub(&n_errors[c*p],&cb_currentstage[n_indices[c*stages+s]*p],p); 258 | 259 | /* get the indices that were used for the parent node */ 260 | v_equ_int(&n_indices[c*stages],&p_indices[n_parents[c]*stages],s); 261 | } 262 | 263 | m = (m*levels[s] > ma) ? ma : m*levels[s]; 264 | } /* for s */ 265 | 266 | /* find the optimum candidate c */ 267 | for(i=1,c=0; i < ma; i++) 268 | { 269 | if (n_d[i] < n_d[c]) 270 | c = i; 271 | } 272 | 273 | d_opt = n_d[c]; 274 | 275 | if (a_indices) 276 | { 277 | v_equ_int(a_indices,&n_indices[c*stages],stages); 278 | } 279 | if (u_hat) 280 | { 281 | if (u_est) 282 | v_equ(u_hat,u_est,p); 283 | else 284 | v_zap(u_hat,p); 285 | 286 | cb_currentstage = cb; 287 | for(s=0; s < stages; s++) 288 | { 289 | v_add(u_hat,&cb_currentstage[n_indices[c*stages+s]*p],p); 290 | cb_currentstage += levels[s]*p; 291 | } 292 | } 293 | return(d_opt); 294 | } 295 | 296 | /* 297 | VQ_MSD2- 298 | Tree search multi-stage VQ decoder 299 | 300 | Synopsis: vq_msd(cb,u,u_est,a,indices,levels,stages,p,conversion) 301 | Input: 302 | cb- one dimensional linear codebook array (codebook is structured 303 | as [stages][levels for each stage][p]) 304 | indices- the codebook indices (for each stage) indices[0..stages-1] 305 | levels- the number of levels (for each stage) levels[0..stages-1] 306 | u_est- dimension p, the estimated parameters or mean (if NULL, assume 307 | estimate is the all zero vector) (u_est[0..p-1]) 308 | stages- the number of stages of msvq 309 | p- the predictor order 310 | conversion- the conversion constant (see lpc.h, lpc_conv.c) 311 | Output: 312 | u- dimension p, the decoded parameters (if NULL, use alternate 313 | temporary storage) (u[0..p-1]) 314 | a- predictor parameters (a[0..p]), if NULL, don't compute 315 | Returns: 316 | pointer to reconstruction vector (u) 317 | Parameters: 318 | 319 | */ 320 | 321 | float *vq_msd2(float *cb, float *u, float *u_est, float *a, int *indices, int *levels, int stages, int p, int conversion) 322 | { 323 | float *u_hat,*cb_currentstage; 324 | int i; 325 | 326 | /* allocate memory (if required) */ 327 | if (u==(float*)NULL) 328 | { 329 | u_hat = uhat; // MEM_ALLOC(MALLOC,u_hat,p,float); 330 | } 331 | else 332 | u_hat = u; 333 | 334 | /* add estimate on (if non-null), or clear vector */ 335 | if (u_est) 336 | { 337 | v_equ(u_hat,u_est,p); 338 | } else 339 | { 340 | v_zap(u_hat,p); 341 | } 342 | 343 | /* add the contribution of each stage */ 344 | cb_currentstage = cb; 345 | for(i=0; i < stages; i++) 346 | { 347 | v_add(u_hat,&cb_currentstage[indices[i]*p],p); 348 | cb_currentstage += levels[i]*p; 349 | } 350 | 351 | return(u_hat); 352 | } 353 | 354 | /* VQ_ENC - 355 | encode vector with full VQ using unweighted Euclidean distance 356 | Synopsis: vq_enc(cb, u, levels, p, u_hat, indices) 357 | Input: 358 | cb- one dimensional linear codebook array 359 | u- dimension p, the parameters to be encoded (u[0..p-1]) 360 | levels- the number of levels 361 | p- the predictor order 362 | Output: 363 | u_hat- the reconstruction vector (if non null) 364 | a_indices- the codebook indices (for each stage) a_indices[0..stages-1] 365 | Parameters: 366 | */ 367 | 368 | float vq_enc(float *cb, float *u, int levels, int p, float *u_hat, int *indices) 369 | { 370 | int i,j,index; 371 | float d,dmin; 372 | float *p_cb; 373 | 374 | /* Search codebook for minimum distance */ 375 | index = 0; 376 | dmin = BIGVAL; 377 | p_cb = cb; 378 | for (i = 0; i < levels; i++) { 379 | d = 0.0; 380 | for (j = 0; j < p; j++) { 381 | d += SQR(u[j] - *p_cb); 382 | p_cb++; 383 | } 384 | if (d < dmin) { 385 | dmin = d; 386 | index = i; 387 | } 388 | } 389 | 390 | /* Update index and quantized value, and return minimum distance */ 391 | *indices = index; 392 | v_equ(u_hat,&cb[p*index],p); 393 | return(dmin); 394 | } 395 | 396 | /* VQ_FSW - 397 | compute the weights for Euclidean distance of Fourier harmonics */ 398 | 399 | void vq_fsw(float *w_fs, int num_harm, float pitch) 400 | { 401 | int j; 402 | float w0; 403 | 404 | /* Calculate fundamental frequency */ 405 | w0 = 2 * M_PI/pitch; 406 | for(j=0; j < num_harm; j++) { 407 | /* Bark-scale weighting */ 408 | w_fs[j] = 117.0f / (25.0f + 75.0f * 409 | powf(1.0f + 1.4f * SQR(w0 * (j+1) / (0.25f * M_PI)), 0.69f)); 410 | } 411 | } 412 | -------------------------------------------------------------------------------- /lpc_lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | */ 16 | 17 | /* 18 | 19 | lpc_lib.c: LPC function library 20 | 21 | */ 22 | 23 | #include 24 | #include 25 | #include "spbstd.h" 26 | #include "lpc.h" 27 | #include "melp.h" 28 | #include "mat.h" 29 | /* 30 | Name: lpc_aejw- Compute square of A(z) evaluated at exp(jw) 31 | Description: 32 | Compute the magnitude squared of the z-transform of 33 | 34 | A(z) = 1+a(1)z^-1 + ... +a(p)z^-p 35 | 36 | evaluated at z=exp(jw) 37 | Inputs: 38 | a- LPC filter (a[0] is undefined, a[1..p]) 39 | w- radian frequency 40 | p- predictor order 41 | Returns: 42 | |A(exp(jw))|^2 43 | See_Also: cos(3), sin(3) 44 | Includes: 45 | spbstd.h 46 | lpc.h 47 | Systems and Info. Science Lab 48 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 49 | 50 | */ 51 | 52 | float lpc_aejw(float *a,float w,int p) 53 | { 54 | int i; 55 | float c_re,c_im; 56 | float cs,sn,tmp; 57 | 58 | if (p==0) 59 | return(1.); 60 | 61 | /* use horners method 62 | A(exp(jw)) = 1+ e(-jw)[a(1)+e(-jw)[a(2)+e(-jw)[a(3)+.. 63 | ...[a(p-1)+e(-jw)a(p)]]]] 64 | */ 65 | 66 | cs = arm_cos(w); 67 | sn = -arm_sin(w); 68 | 69 | c_re = cs*a[p]; 70 | c_im = sn*a[p]; 71 | 72 | for(i=p-1; i > 0; i--) 73 | { 74 | /* add a[i] */ 75 | c_re += a[i]; 76 | 77 | /* multiply by exp(-jw) */ 78 | c_im = cs*(tmp=c_im) + sn*c_re; 79 | c_re = cs*c_re - sn*tmp; 80 | } 81 | 82 | /* add one */ 83 | c_re += 1.0f; 84 | 85 | return(SQR(c_re) + SQR(c_im)); 86 | } /* LPC_AEJW */ 87 | 88 | /* 89 | Name: lpc_bw_expand- Move the zeros of A(z) toward the origin. 90 | Aliases: lpc_bw_expand 91 | Description: 92 | Expand the zeros of the LPC filter by gamma, which 93 | moves each zero radially into the origin. 94 | 95 | for j = 1 to p 96 | aw[j] = a[j]*gamma^j 97 | 98 | (Can also be used to perform an exponential windowing procedure). 99 | Inputs: 100 | a- lpc vector (order p, a[1..p]) 101 | gamma- the bandwidth expansion factor 102 | p- order of lpc filter 103 | Outputs: 104 | aw- the bandwidth expanded LPC filter 105 | Returns: NULL 106 | See_Also: lpc_lagw(3l) 107 | Includes: 108 | spbstd.h 109 | lpc.h 110 | 111 | Systems and Info. Science Lab 112 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 113 | */ 114 | 115 | int lpc_bw_expand(float *a, float *aw, float gamma, int p) 116 | { 117 | int i; 118 | float gk; 119 | 120 | for(i=1,gk=gamma; i <= p; i++, gk *= gamma) 121 | aw[i] = a[i]*gk; 122 | return(0); 123 | } 124 | 125 | /* 126 | Name: lpc_clamp- Sort and ensure minimum separation in LSPs. 127 | Aliases: lpc_clamp 128 | Description: 129 | Ensure that all LSPs are ordered and separated 130 | by at least delta. The algorithm isn't guaranteed 131 | to work, so it prints an error message when it fails 132 | to sort the LSPs properly. 133 | Inputs: 134 | w- lsp vector (order p, w[1..p]) 135 | delta- the clamping factor 136 | p- order of lpc filter 137 | Outputs: 138 | w- the sorted and clamped lsps 139 | Returns: NULL 140 | See_Also: 141 | Includes: 142 | spbstd.h 143 | lpc.h 144 | Bugs: 145 | Currently only supports 10 loops, which is too 146 | complex and perhaps unneccesary. 147 | 148 | Systems and Info. Science Lab 149 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 150 | * 151 | */ 152 | 153 | #define MAX_LOOPS 10 154 | 155 | int lpc_clamp(float *w, float delta, int p) 156 | { 157 | int i,j,unsorted; 158 | float tmp,d,step1,step2; 159 | 160 | /* sort the LSPs- for 10 loops, complexity is approximately 150 p */ 161 | for (j=0,unsorted=TRUE; unsorted && (j < MAX_LOOPS); j++) 162 | { 163 | for(i=1,unsorted=FALSE; i < p; i++) 164 | if (w[i] > w[i+1]) 165 | { 166 | tmp = w[i+1]; 167 | w[i+1] = w[i]; 168 | w[i] = tmp; 169 | unsorted = TRUE; 170 | } 171 | } 172 | 173 | /* ensure minimum separation */ 174 | if (!unsorted) 175 | { 176 | for(j=0; j < MAX_LOOPS; j++) 177 | { 178 | for(i=1; i < p; i++) 179 | { 180 | if ((d = w[i+1]-w[i]) < delta) 181 | { 182 | step1 = step2 = (delta-d)/2.0f; 183 | if (i==1 && (w[i] < delta)) 184 | { 185 | step1 = w[i]/2.0f; 186 | }else if (i > 1) 187 | { 188 | if ((tmp = w[i] - w[i-1]) < delta) 189 | step1 = 0; 190 | else if (tmp < 2*delta) 191 | step1 = (tmp-delta)/2.0f; 192 | } 193 | if (i==(p-1) && (w[i+1] > (1.0f-delta))) 194 | { 195 | step2 = (1-w[i+1])/2.0f; 196 | }else if (i < (p-1)) 197 | { 198 | if ((tmp = w[i+2] - w[i+1]) < delta) 199 | step2 = 0; 200 | else if (tmp < 2*delta) 201 | step2 = (tmp-delta)/2.0f; 202 | } 203 | w[i] -= step1; 204 | w[i+1] += step2; 205 | } 206 | } 207 | } 208 | } 209 | return(0); 210 | } 211 | 212 | /* 213 | Name: lpc_schur- Schur recursion (autocorrelations to refl coef) 214 | Aliases: lpc_schur 215 | Description: 216 | Compute reflection coefficients from autocorrelations 217 | based on schur recursion. Will also compute predictor 218 | parameters by calling lpc_refl2pred(3l) if necessary. 219 | Inputs: 220 | r- autocorrelation vector (r[0..p]). 221 | p- order of lpc filter. 222 | Outputs: 223 | a- predictor parameters (can be NULL) 224 | k_tmp- reflection coefficients (can be NULL) 225 | Returns: 226 | alphap- the minimum residual energy 227 | Includes: 228 | spbstd.h 229 | lpc.h 230 | See_Also: 231 | lpc_refl2pred(3l) in lpc.h or lpc(3l) 232 | 233 | */ 234 | 235 | static float y[LPC_ORD + 2]; 236 | static float y2[LPC_ORD + 2]; 237 | static float k[LPC_ORD + 2]; 238 | static float b[LPC_ORD + 2]; 239 | static float b1[LPC_ORD + 2]; 240 | static float a1[LPC_ORD + 2]; 241 | 242 | static float c0[LPC_ORD/2 + 1]; 243 | static float c1[LPC_ORD/2 + 1]; 244 | static float *c[2]; 245 | 246 | static float f0[LPC_ORD/2 + 1]; 247 | static float f1[LPC_ORD/2 + 1]; 248 | static float *f[2]; 249 | 250 | float lpc_schur(float *r, float *a, int p) 251 | { 252 | int i,j; 253 | float temp,alphap; 254 | 255 | k[1] = -r[1]/r[0]; 256 | alphap = r[0]*(1-SQR(k[1])); 257 | 258 | y2[1] = r[1]; 259 | y2[2] = r[0]+k[1]*r[1]; 260 | 261 | for(i=2; i <= p; i++) 262 | { 263 | y[1] = temp = r[i]; 264 | 265 | for(j=1; j < i; j++) 266 | { 267 | y[j+1] = y2[j] + k[j]*temp; 268 | temp += k[j]*y2[j]; 269 | y2[j] = y[j]; 270 | } 271 | 272 | k[i] = -temp/y2[i]; 273 | y2[i+1] = y2[i]+k[i]*temp; 274 | y2[i] = y[i]; 275 | 276 | alphap *= 1-SQR(k[i]); 277 | } 278 | 279 | if (a != NULL) 280 | { 281 | (void)lpc_refl2pred(k,a,p); 282 | } 283 | 284 | return(alphap); 285 | } 286 | 287 | /* minimum LSP separation-- a global variable */ 288 | float lsp_delta = 0.0f; 289 | 290 | /* private functions */ 291 | static float lsp_g(float x,float *c,int p2); 292 | static int lsp_roots(float *w,float **c,int p2); 293 | 294 | #define DELTA 0.00781250f 295 | #define BISECTIONS 4 296 | 297 | 298 | /* LPC_PRED2LSP 299 | get LSP coeffs from the predictor coeffs 300 | Input: 301 | a- the predictor coefficients 302 | p- the predictor order 303 | Output: 304 | w- the lsp coefficients 305 | Reference: Kabal and Ramachandran 306 | 307 | */ 308 | 309 | int lpc_pred2lsp(float *a,float *w,int p) 310 | { 311 | int i,p2; 312 | 313 | p2 = p/2; 314 | c[0] = c0; 315 | c[1] = c1; 316 | c0[p2] = c1[p2] = 1.0; 317 | 318 | for(i=1; i <= p2; i++) 319 | { 320 | c0[p2-i] = (a[i] + a[p+1-i] - c0[p2+1-i]); 321 | c1[p2-i] = c1[p2+1-i] + a[i] - a[p+1-i]; 322 | } 323 | c0[0] /= 2.0f; 324 | c1[0] /= 2.0f; 325 | 326 | i = lsp_roots(w,c,p2); 327 | 328 | /* ensure minimum separation and sort */ 329 | (void)lpc_clamp(w,lsp_delta,p); 330 | 331 | return(i); 332 | } /* LPC_PRED2LSP */ 333 | 334 | /* LPC_PRED2REFL 335 | get refl coeffs from the predictor coeffs 336 | Input: 337 | a- the predictor coefficients 338 | p- the predictor order 339 | Output: 340 | k- the reflection coefficients 341 | Reference: Markel and Gray, Linear Prediction of Speech 342 | */ 343 | 344 | int lpc_pred2refl(float *a,float *k,int p) 345 | { 346 | float e; 347 | int i,j; 348 | 349 | /* equate temporary variables (b = a) */ 350 | for(i=1; i <= p; i++) 351 | b[i] = a[i]; 352 | 353 | /* compute reflection coefficients */ 354 | for(i=p; i > 0; i--) 355 | { 356 | k[i] = b[i]; 357 | e = 1 - SQR(k[i]); 358 | for(j=1; j < i; j++) 359 | b1[j] = b[j]; 360 | for(j=1; j < i; j++) 361 | b[j] = (b1[j] - k[i]*b1[i-j])/e; 362 | } 363 | return(0); 364 | } 365 | /* LPC_LSP2PRED 366 | get predictor coefficients from the LSPs 367 | Synopsis: lpc_lsp2pred(w,a,p) 368 | Input: 369 | w- the LSPs 370 | p- the predictor order 371 | Output: 372 | a- the predictor coefficients 373 | Reference: Kabal and Ramachandran 374 | */ 375 | 376 | int lpc_lsp2pred(float *w,float *a,int p) 377 | { 378 | int i,j,k,p2; 379 | float c[2]; 380 | 381 | 382 | /* ensure minimum separation and sort */ 383 | (void)lpc_clamp(w,lsp_delta,p); 384 | 385 | p2 = p/2; 386 | f[0] = f0; 387 | f[1] = f1; 388 | f[0][0] = f[1][0] = 1.0; 389 | f[0][1] = (float)-2.0f*arm_cos(w[1]*M_PI); 390 | f[1][1] = (float)-2.0f*arm_cos(w[2]*M_PI); 391 | 392 | k = 3; 393 | 394 | for(i=2; i <= p2; i++) 395 | { 396 | c[0] = (float)-2.0f*arm_cos(w[k++]*M_PI); 397 | c[1] = (float)-2.0f*arm_cos(w[k++]*M_PI); 398 | f[0][i] = f[0][i-2]; 399 | f[1][i] = f[1][i-2]; 400 | 401 | for(j = i; j >= 2; j--) 402 | { 403 | f[0][j] += c[0]*f[0][j-1]+f[0][j-2]; 404 | f[1][j] += c[1]*f[1][j-1]+f[1][j-2]; 405 | } 406 | f[0][1] += c[0]*f[0][0]; 407 | f[1][1] += c[1]*f[1][0]; 408 | } 409 | 410 | for(i = p2; i > 0; i--) 411 | { 412 | f[0][i] += f[0][i-1]; 413 | f[1][i] -= f[1][i-1]; 414 | 415 | a[i] = 0.5f * (f[0][i]+f[1][i]); 416 | a[p+1-i] = 0.5f * (f[0][i]-f[1][i]); 417 | } 418 | 419 | return(0); 420 | } 421 | 422 | /* LPC_REFL2PRED 423 | get predictor coefficients from the reflection coeffs 424 | 425 | Input: 426 | k- the reflection coeffs 427 | p- the predictor order 428 | Output: 429 | a- the predictor coefficients 430 | Reference: Markel and Gray, Linear Prediction of Speech 431 | */ 432 | 433 | int lpc_refl2pred(float *k,float *a,int p) 434 | { 435 | int i,j; 436 | 437 | for(i=1; i <= p; i++) 438 | { 439 | /* refl to a recursion */ 440 | a[i] = k[i]; 441 | for(j=1; j < i; j++) 442 | a1[j] = a[j]; 443 | for(j=1; j < i; j++) 444 | a[j] = a1[j] + k[i]*a1[i-j]; 445 | } 446 | return(0); 447 | } /* LPC_REFL2PRED */ 448 | 449 | /* G - compute the value of the Chebychev series 450 | sum c_k T_k(x) = x b_1(x) - b_2(x) + c_0 451 | b_k(x) = 2x b_{k+1}(x) - b_{k+2}(x) + c_k 452 | */ 453 | static float lsp_g(float x,float *c,int p2) 454 | { 455 | int i; 456 | float b[3]; 457 | 458 | b[1] = b[2] = 0.0; 459 | 460 | for(i=p2; i > 0; i--) 461 | { 462 | b[0] = 2.0f * x * b[1] - b[2] + c[i]; 463 | b[2] = b[1]; 464 | b[1] = b[0]; 465 | } 466 | b[0] = x*b[1]-b[2]+c[0]; 467 | return(b[0]); 468 | } /* G */ 469 | 470 | /* LSP_ROOTS 471 | - find the roots of the two polynomials G_1(x) and G_2(x) 472 | the first root corresponds to G_1(x) 473 | compute the inverse cos (and these are the LSFs) 474 | */ 475 | static int lsp_roots(float *w,float **c,int p2) 476 | { 477 | int i,k; 478 | float x,x0,x1,y,*ptr,g0,g1; 479 | 480 | w[0] = 0.0f; 481 | 482 | ptr = c[0]; 483 | x = 1.0f; 484 | g0 = lsp_g(x,ptr,p2); 485 | 486 | for(k=1,x = 1.0f-DELTA; x > -DELTA-1.0f; x -= DELTA) 487 | { 488 | /* Search for a zero crossing */ 489 | if (g0*(g1 = lsp_g(x,ptr,p2)) <= 0.0f) 490 | { 491 | /* Search Incrementally using bisection */ 492 | x0 = x+DELTA; 493 | x1 = x; 494 | 495 | for(i=0; i < BISECTIONS; i++) 496 | { 497 | x = (x0+x1)/2.0f; 498 | y = lsp_g(x,ptr,p2); 499 | 500 | if(y*g0 < 0.0f) 501 | { 502 | x1 = x; 503 | g1 = y; 504 | } 505 | else 506 | { 507 | x0 = x; 508 | g0 = y; 509 | } 510 | } 511 | /* Linear interpolate */ 512 | x = (g1*x0-g0*x1)/(g1-g0); 513 | 514 | /* Evaluate the LSF */ 515 | w[k] = (float)acosf(x)/M_PI; 516 | 517 | ptr = c[k % 2]; 518 | k++; 519 | if (k > 2*p2) 520 | return(0); 521 | g1 = lsp_g(x,ptr,p2); 522 | } 523 | g0 = g1; 524 | } 525 | return(1); 526 | } /* LSP_ROOTS */ 527 | 528 | -------------------------------------------------------------------------------- /melp_syn.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | Name: melp_syn.c 20 | Description: MELP synthesis 21 | This program takes the new parameters for a speech 22 | frame and synthesizes the output speech. It keeps 23 | an internal record of the previous frame parameters 24 | to use for interpolation. 25 | Inputs: 26 | *par - MELP parameter structure 27 | Outputs: 28 | speech[] - output speech signal 29 | Returns: void 30 | */ 31 | 32 | /* compiler include files */ 33 | 34 | #include 35 | #include 36 | #include "melp.h" 37 | #include "spbstd.h" 38 | #include "lpc.h" 39 | #include "mat.h" 40 | #include "vq.h" 41 | #include "fs.h" 42 | #include "dsp_sub.h" 43 | #include "melp_sub.h" 44 | 45 | 46 | /* temporary memory */ 47 | static float sigbuf[BEGIN+PITCHMAX] CCMRAM; 48 | static float sig2[BEGIN+PITCHMAX] CCMRAM; 49 | static float fs_real[PITCHMAX] CCMRAM; 50 | 51 | /* permanent memory */ 52 | static int firstcall = 1; /* Just used for noise gain init */ 53 | static float sigsave[2*PITCHMAX] CCMRAM; 54 | static struct melp_param prev_par; 55 | static int syn_begin; 56 | static float prev_scale; 57 | static float noise_gain = MIN_NOISE; 58 | static float pulse_del[MIX_ORD] CCMRAM, 59 | noise_del[MIX_ORD] CCMRAM; 60 | static float lpc_del[LPC_ORD] CCMRAM, 61 | ase_del[LPC_ORD] CCMRAM, 62 | tilt_del[TILT_ORD] CCMRAM; 63 | static float disp_del[DISP_ORD] CCMRAM; 64 | 65 | /* these can be saved or recomputed */ 66 | static float prev_pcof[MIX_ORD+1] CCMRAM, 67 | prev_ncof[MIX_ORD+1] CCMRAM; 68 | static float prev_tilt; 69 | 70 | // Temporary static vars 71 | static float tilt_cof[TILT_ORD+1] CCMRAM; 72 | static float lsf[LPC_ORD+1] CCMRAM; 73 | static float lpc[LPC_ORD+1] CCMRAM; 74 | static float ase_num[LPC_ORD+1] CCMRAM, 75 | ase_den[LPC_ORD+1] CCMRAM; 76 | static float curr_pcof[MIX_ORD+1] CCMRAM, 77 | curr_ncof[MIX_ORD+1] CCMRAM; 78 | static float pulse_cof[MIX_ORD+1] CCMRAM, 79 | noise_cof[MIX_ORD+1] CCMRAM; 80 | static float w_fs[NUM_HARM] CCMRAM; 81 | static float w_fs_inv[NUM_HARM] CCMRAM; 82 | 83 | void melp_syn(struct melp_param *par, float sp_out[]) 84 | { 85 | 86 | int i, gaincnt; 87 | int erase; 88 | int length; 89 | float intfact, ifact, ifact_gain; 90 | float gain,pulse_gain,pitch,jitter; 91 | float curr_tilt; 92 | float temp,sig_prob; 93 | 94 | /* Copy previous period of processed speech to output array */ 95 | if (syn_begin > 0) { 96 | if (syn_begin > FRAME) { 97 | v_equ(&sp_out[0],&sigsave[0],FRAME); 98 | /* past end: save remainder in sigsave[0] */ 99 | v_equ(&sigsave[0],&sigsave[FRAME],syn_begin-FRAME); 100 | } 101 | else 102 | v_equ(&sp_out[0],&sigsave[0],syn_begin); 103 | } 104 | 105 | /* Read and decode channel input buffer */ 106 | erase = melp_chn_read(par); 107 | 108 | /* Decode new frame if no erasures occurred */ 109 | if (erase) 110 | { /* Erasure: frame repeat */ 111 | *par = prev_par; 112 | /* Force all subframes to equal last one */ 113 | for (i = 0; i < NUM_GAINFR-1; i++) { 114 | par->gain[i] = par->gain[NUM_GAINFR-1]; 115 | } 116 | }else { 117 | /* Decode line spectrum frequencies */ 118 | vq_msd2(msvq_cb,&par->lsf[1],(float*)NULL,(float*)NULL,par->msvq_par.indices, 119 | par->msvq_par.levels,par->msvq_par.num_stages,LPC_ORD,0); 120 | i = FS_LEVELS; 121 | if (par->uv_flag) 122 | { 123 | v_fill(par->fs_mag,1.0F,NUM_HARM); 124 | }else 125 | { 126 | /* Decode Fourier magnitudes */ 127 | vq_msd2(fsvq_cb,par->fs_mag,(float*)NULL,(float*)NULL, 128 | par->fsvq_par.indices,&i,1,NUM_HARM,0); 129 | } 130 | 131 | /* Decode gain terms with uniform log quantizer */ 132 | q_gain_dec(par->gain, par->gain_index,GN_QLO,GN_QUP,GN_QLEV); 133 | 134 | /* Fractional pitch: */ 135 | /* Decode logarithmic pitch period */ 136 | if (par->uv_flag) 137 | { 138 | par->pitch = UV_PITCH; 139 | }else 140 | { 141 | quant_u_dec(par->pitch_index,&par->pitch,PIT_QLO,PIT_QUP, 142 | PIT_QLEV); 143 | par->pitch = powf(10.0f,par->pitch); 144 | } 145 | 146 | /* Decode jitter and bandpass voicing */ 147 | quant_u_dec(par->jit_index,&par->jitter,0.0,MAX_JITTER,2); 148 | q_bpvc_dec(&par->bpvc[0],&par->bpvc_index,par->uv_flag, 149 | NUM_BANDS); 150 | } 151 | 152 | if (par->uv_flag != 1 && !erase) { 153 | /* Un-weight Fourier magnitudes */ 154 | window(&par->fs_mag[0],w_fs_inv,&par->fs_mag[0],NUM_HARM); 155 | } 156 | 157 | /* Update adaptive noise level estimate based on last gain */ 158 | if (firstcall) { 159 | firstcall = 0; 160 | noise_gain = par->gain[NUM_GAINFR-1]; 161 | }else if (!erase) 162 | { 163 | for (i = 0; i < NUM_GAINFR; i++) { 164 | noise_est(par->gain[i],&noise_gain,UPCONST,DOWNCONST,MIN_NOISE,MAX_NOISE); 165 | /* Adjust gain based on noise level (noise suppression) */ 166 | noise_sup(&par->gain[i],noise_gain,MAX_NS_SUP,MAX_NS_ATT,NFACT); 167 | } 168 | } 169 | 170 | /* Clamp LSP bandwidths to avoid sharp LPC filters */ 171 | lpc_clamp(par->lsf,BWMIN,LPC_ORD); 172 | 173 | /* Calculate spectral tilt for current frame for spectral enhancement */ 174 | tilt_cof[0] = 1.0; 175 | lpc_lsp2pred(par->lsf,lpc,LPC_ORD); 176 | lpc_pred2refl(lpc,sig2,LPC_ORD); 177 | if (sig2[1] < 0.0f) 178 | curr_tilt = 0.5f*sig2[1]; 179 | else 180 | curr_tilt = 0.0f; 181 | 182 | /* Disable pitch interpolation for high-pitched onsets */ 183 | if (par->pitch < 0.5f * prev_par.pitch && 184 | par->gain[0] > 6.0f + prev_par.gain[NUM_GAINFR-1]) 185 | { /* copy current pitch into previous */ 186 | prev_par.pitch = par->pitch; 187 | } 188 | 189 | /* Set pulse and noise coefficients based on voicing strengths */ 190 | v_zap(curr_pcof, MIX_ORD + 1); 191 | v_zap(curr_ncof, MIX_ORD + 1); 192 | for (i = 0; i < NUM_BANDS; i++) 193 | { 194 | if (par->bpvc[i] > 0.5f) 195 | v_add(curr_pcof,&bp_cof[i][0],MIX_ORD+1); 196 | else 197 | v_add(curr_ncof,&bp_cof[i][0],MIX_ORD+1); 198 | } 199 | 200 | /* Process each pitch period */ 201 | while (syn_begin < FRAME) 202 | { 203 | /* interpolate previous and current parameters */ 204 | ifact = ((float) syn_begin ) / FRAME; 205 | 206 | if (syn_begin >= GAINFR) { 207 | gaincnt = 2; 208 | ifact_gain = ((float) syn_begin-GAINFR) / GAINFR; 209 | }else { 210 | gaincnt = 1; 211 | ifact_gain = ((float) syn_begin) / GAINFR; 212 | } 213 | 214 | /* interpolate gain */ 215 | if (gaincnt > 1) { 216 | gain = ifact_gain*par->gain[gaincnt-1] + 217 | (1.0f-ifact_gain)*par->gain[gaincnt-2]; 218 | }else { 219 | gain = ifact_gain*par->gain[gaincnt-1] + 220 | (1.0f-ifact_gain)*prev_par.gain[NUM_GAINFR-1]; 221 | } 222 | 223 | /* Set overall interpolation path based on gain change */ 224 | temp = par->gain[NUM_GAINFR-1] - prev_par.gain[NUM_GAINFR-1]; 225 | if (fabs(temp) > 6) { 226 | /* Power surge: use gain adjusted interpolation */ 227 | intfact = (gain - prev_par.gain[NUM_GAINFR-1]) / temp; 228 | if (intfact > 1.0f) intfact = 1.0f; 229 | if (intfact < 0.0f) intfact = 0.0f; 230 | }else { /* Otherwise, linear interpolation */ 231 | intfact = ((float) syn_begin) / FRAME; 232 | } 233 | 234 | /* interpolate LSF's and convert to LPC filter */ 235 | interp_array(prev_par.lsf,par->lsf,lsf,intfact,LPC_ORD+1); 236 | lpc_lsp2pred(lsf,lpc,LPC_ORD); 237 | 238 | /* Check signal probability for adaptive spectral enhancement filter */ 239 | sig_prob = lin_int_bnd(gain,noise_gain+12.0f,noise_gain+30.0f, 240 | 0.0f,1.0f); 241 | 242 | /* Calculate adaptive spectral enhancement filter coefficients */ 243 | ase_num[0] = 1.0f; 244 | lpc_bw_expand(lpc,ase_num,sig_prob*ASE_NUM_BW,LPC_ORD); 245 | lpc_bw_expand(lpc,ase_den,sig_prob*ASE_DEN_BW,LPC_ORD); 246 | tilt_cof[1] = sig_prob*(intfact*curr_tilt + 247 | (1.0f-intfact)*prev_tilt); 248 | 249 | /* interpolate pitch and pulse gain */ 250 | pitch = intfact*par->pitch + (1.0f-intfact)*prev_par.pitch; 251 | pulse_gain = SYN_GAIN * arm_sqrt(pitch); 252 | 253 | /* interpolate pulse and noise coefficients */ 254 | temp = arm_sqrt(ifact); 255 | interp_array(prev_pcof,curr_pcof,pulse_cof,temp,MIX_ORD+1); 256 | interp_array(prev_ncof,curr_ncof,noise_cof,temp,MIX_ORD+1); 257 | 258 | /* interpolate jitter */ 259 | jitter = ifact*par->jitter + (1.0f-ifact)*prev_par.jitter; 260 | 261 | /* convert gain to linear */ 262 | gain = powf(10.0f,0.05f*gain); 263 | 264 | /* Set period length based on pitch and jitter */ 265 | rand_num(&temp,1.0f,1); 266 | length = (int) (pitch * (1.0f-jitter*temp) + 0.5f); 267 | if (length < PITCHMIN) length = PITCHMIN; 268 | if (length > PITCHMAX) length = PITCHMAX; 269 | 270 | /* Use inverse DFT for pulse excitation */ 271 | v_fill(fs_real,1.0f,length); 272 | fs_real[0] = 0.0f; 273 | interp_array(prev_par.fs_mag,par->fs_mag,&fs_real[1],intfact, NUM_HARM); 274 | idft_real(fs_real,&sigbuf[BEGIN],length); 275 | 276 | /* Delay overall signal by PDEL samples (circular shift) */ 277 | /* use fs_real as a scratch buffer */ 278 | v_equ(fs_real,&sigbuf[BEGIN],length); 279 | v_equ(&sigbuf[BEGIN+PDEL],fs_real,length-PDEL); 280 | v_equ(&sigbuf[BEGIN],&fs_real[length-PDEL],PDEL); 281 | 282 | /* Scale by pulse gain */ 283 | v_scale(&sigbuf[BEGIN],pulse_gain,length); 284 | 285 | /* Filter and scale pulse excitation */ 286 | // v_equ(&sigbuf[BEGIN-MIX_ORD],pulse_del,MIX_ORD); 287 | // v_equ(pulse_del,&sigbuf[length+BEGIN-MIX_ORD],MIX_ORD); 288 | firflt(&sigbuf[BEGIN],pulse_cof,&sigbuf[BEGIN], pulse_del, MIX_ORD,length); 289 | 290 | /* Get scaled noise excitation */ 291 | rand_num(&sig2[BEGIN],(1.732f*SYN_GAIN),length); 292 | 293 | /* Filter noise excitation */ 294 | // v_equ(&sig2[BEGIN-MIX_ORD],noise_del,MIX_ORD); 295 | // v_equ(noise_del,&sig2[length+BEGIN-MIX_ORD],MIX_ORD); 296 | firflt(&sig2[BEGIN],noise_cof,&sig2[BEGIN], noise_del, MIX_ORD,length); 297 | 298 | /* Add two excitation signals (mixed excitation) */ 299 | v_add(&sigbuf[BEGIN],&sig2[BEGIN],length); 300 | 301 | /* Adaptive spectral enhancement */ 302 | // v_equ(&sigbuf[BEGIN-LPC_ORD],ase_del,LPC_ORD); 303 | iirflt(&sigbuf[BEGIN],ase_den,&sigbuf[BEGIN],ase_del, LPC_ORD, length); 304 | // v_equ(ase_del,&sigbuf[BEGIN+length-LPC_ORD],LPC_ORD); 305 | zerflt(&sigbuf[BEGIN],ase_num,&sigbuf[BEGIN],LPC_ORD,length); 306 | // v_equ(&sigbuf[BEGIN-TILT_ORD],tilt_del,TILT_ORD); 307 | // v_equ(tilt_del,&sigbuf[length+BEGIN-TILT_ORD],TILT_ORD); 308 | firflt(&sigbuf[BEGIN],tilt_cof,&sigbuf[BEGIN], tilt_del, TILT_ORD, length); 309 | 310 | /* Perform LPC synthesis filtering */ 311 | //v_equ(&sigbuf[BEGIN-LPC_ORD],lpc_del,LPC_ORD); 312 | iirflt(&sigbuf[BEGIN],lpc,&sigbuf[BEGIN],lpc_del, LPC_ORD,length); 313 | // v_equ(lpc_del,&sigbuf[length+BEGIN-LPC_ORD],LPC_ORD); 314 | 315 | /* Adjust scaling of synthetic speech */ 316 | scale_adj(&sigbuf[BEGIN],gain,&prev_scale,length,SCALEOVER); 317 | 318 | /* Implement pulse dispersion filter */ 319 | // v_equ(&sigbuf[BEGIN-DISP_ORD],disp_del,DISP_ORD); 320 | // v_equ(disp_del,&sigbuf[length+BEGIN-DISP_ORD],DISP_ORD); 321 | firflt(&sigbuf[BEGIN],disp_cof,&sigbuf[BEGIN], disp_del, DISP_ORD,length); 322 | 323 | /* Copy processed speech to output array (not past frame end) */ 324 | if (syn_begin+length > FRAME) { 325 | v_equ(&sp_out[syn_begin],&sigbuf[BEGIN],FRAME-syn_begin); 326 | 327 | /* past end: save remainder in sigsave[0] */ 328 | v_equ(&sigsave[0],&sigbuf[BEGIN+FRAME-syn_begin], length-(FRAME-syn_begin)); 329 | }else { 330 | v_equ(&sp_out[syn_begin],&sigbuf[BEGIN],length); 331 | } 332 | 333 | /* Update syn_begin for next period */ 334 | syn_begin += length; 335 | } 336 | 337 | /* Save previous pulse and noise filters for next frame */ 338 | v_equ(prev_pcof,curr_pcof,MIX_ORD+1); 339 | v_equ(prev_ncof,curr_ncof,MIX_ORD+1); 340 | 341 | /* Copy current parameters to previous parameters for next time */ 342 | prev_par = *par; 343 | prev_tilt = curr_tilt; 344 | 345 | /* Update syn_begin for next frame */ 346 | syn_begin -= FRAME; 347 | } 348 | 349 | 350 | /* 351 | * 352 | * Subroutine melp_syn_init(): perform initialization for melp 353 | * synthesis 354 | * 355 | */ 356 | 357 | void melp_syn_init(melp_param_t *par) 358 | { 359 | int i; 360 | 361 | v_zap(prev_par.gain,NUM_GAINFR); 362 | prev_par.pitch = UV_PITCH; 363 | prev_par.lsf[0] = 0.0f; 364 | for (i = 1; i < LPC_ORD+1; i++) 365 | prev_par.lsf[i] = prev_par.lsf[i-1] + (1.0f/(LPC_ORD+1)); 366 | prev_par.jitter = 0.0f; 367 | v_zap(&prev_par.bpvc[0],NUM_BANDS); 368 | prev_tilt=0.0f; 369 | prev_scale = 0.0f; 370 | syn_begin = 0; 371 | noise_gain = MIN_NOISE; 372 | firstcall = 1; 373 | v_zap(pulse_del,MIX_ORD); 374 | v_zap(noise_del,MIX_ORD); 375 | v_zap(lpc_del,LPC_ORD); 376 | v_zap(ase_del,LPC_ORD); 377 | v_zap(tilt_del,TILT_ORD); 378 | v_zap(disp_del,DISP_ORD); 379 | v_zap(sig2,BEGIN+PITCHMAX); 380 | v_zap(sigbuf,BEGIN+PITCHMAX); 381 | v_zap(sigsave,PITCHMAX); 382 | v_zap(prev_pcof,MIX_ORD+1); 383 | v_zap(prev_ncof,MIX_ORD+1); 384 | prev_ncof[MIX_ORD/2] = 1.0; 385 | 386 | v_fill(prev_par.fs_mag,1.0,NUM_HARM); 387 | 388 | /* Initialize multi-stage vector quantization (read codebook) */ 389 | par->msvq_par.num_best = MSVQ_M; 390 | par->msvq_par.num_stages = 4; 391 | par->msvq_par.num_dimensions = 10; 392 | 393 | par->msvq_par.levels[0] = 128; 394 | par->msvq_par.levels[1] = 64; 395 | par->msvq_par.levels[2] = 64; 396 | par->msvq_par.levels[3] = 64; 397 | 398 | par->msvq_par.bits[0] = 7; 399 | par->msvq_par.bits[1] = 6; 400 | par->msvq_par.bits[2] = 6; 401 | par->msvq_par.bits[3] = 6; 402 | 403 | par->msvq_par.cb = msvq_cb; 404 | 405 | /* Initialize Fourier magnitude vector quantization (read codebook) */ 406 | 407 | par->fsvq_par.num_best = 1; 408 | par->fsvq_par.num_stages = 1; 409 | par->fsvq_par.num_dimensions = NUM_HARM; 410 | 411 | par->fsvq_par.levels[0] = FS_LEVELS; 412 | par->fsvq_par.bits[0] = FS_BITS; 413 | par->fsvq_par.cb = fsvq_cb; 414 | 415 | /* Initialize fixed MSE weighting and inverse of weighting */ 416 | vq_fsw(w_fs, NUM_HARM, 60.0f); 417 | for (i = 0; i < NUM_HARM; i++) w_fs_inv[i] = 1.0f/w_fs[i]; 418 | 419 | /* Pre-weight codebook (assume single stage only) */ 420 | if (fsvq_weighted == 0) 421 | { 422 | fsvq_weighted = 1; 423 | /* Scale codebook to 0 to 1 */ 424 | v_scale(msvq_cb,(2.0f/FSAMP),3200); 425 | for (i = 0; i < FS_LEVELS; i++) 426 | window(&fsvq_cb[i*NUM_HARM],w_fs,&fsvq_cb[i*NUM_HARM], NUM_HARM); 427 | } 428 | } 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | -------------------------------------------------------------------------------- /dsp_sub.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | 20 | dsp_sub.c: general subroutines. 21 | 22 | */ 23 | 24 | /* compiler include files */ 25 | #include 26 | #include 27 | #include 28 | #include "dsp_sub.h" 29 | #include "spbstd.h" 30 | #include "mat.h" 31 | 32 | #define MAXSORT 5 33 | static float sorted[MAXSORT]; 34 | 35 | /* */ 36 | /* Subroutine autocorr: calculate autocorrelations */ 37 | /* */ 38 | void autocorr(float input[], float r[], int order, int npts) 39 | { 40 | int i; 41 | 42 | for (i = 0; i <= order; i++ ) 43 | { 44 | r[i] = v_inner(&input[0],&input[i],(npts-i)); 45 | } 46 | if (r[0] < 1.0F) r[0] = 1.0F; 47 | } 48 | 49 | /* */ 50 | /* Subroutine envelope: calculate time envelope of signal. */ 51 | /* Note: the delay history requires one previous sample */ 52 | /* of the input signal and two previous output samples. */ 53 | /* */ 54 | #define C2 (-0.9409F) 55 | #define C1 1.9266F 56 | 57 | void envelope(float input[], float prev_in, float output[], int npts) 58 | { 59 | int i; 60 | float curr_abs, prev_abs; 61 | prev_abs = fabsf(prev_in); 62 | for (i = 0; i < npts; i++) { 63 | curr_abs = fabsf(input[i]); 64 | output[i] = curr_abs - prev_abs + C2*output[i-2] + C1*output[i-1]; 65 | prev_abs = curr_abs; 66 | } 67 | } 68 | 69 | 70 | /* */ 71 | /* Subroutine interp_array: interpolate array */ 72 | /* */ 73 | void interp_array(float prev[],float curr[],float out[],float ifact,int npts) 74 | { 75 | int i; 76 | float ifact2; 77 | 78 | ifact2 = 1.0F - ifact; 79 | for (i = 0; i < npts; i++) 80 | out[i] = ifact*curr[i] + ifact2*prev[i]; 81 | } 82 | 83 | /* */ 84 | /* Subroutine median: calculate median value */ 85 | /* */ 86 | 87 | float median(float input[], int npts) 88 | { 89 | int i,j,loc; 90 | float insert_val; 91 | 92 | 93 | /* sort data in temporary array */ 94 | v_equ(sorted,input,npts); 95 | for (i = 1; i < npts; i++) { 96 | /* for each data point */ 97 | for (j = 0; j < i; j++) { 98 | /* find location in current sorted list */ 99 | if (sorted[i] < sorted[j]) 100 | break; 101 | } 102 | 103 | /* insert new value */ 104 | loc = j; 105 | insert_val = sorted[i]; 106 | for (j = i; j > loc; j--) 107 | sorted[j] = sorted[j-1]; 108 | sorted[loc] = insert_val; 109 | } 110 | return(sorted[npts/2]); 111 | } 112 | 113 | /* */ 114 | /* Subroutine PACK_CODE: Pack bit code into channel. */ 115 | /* */ 116 | void pack_code(int code,unsigned int **p_ch_beg,int *p_ch_bit, int numbits, int wsize) 117 | { 118 | int i,ch_bit; 119 | unsigned int *ch_word; 120 | 121 | ch_bit = *p_ch_bit; 122 | ch_word = *p_ch_beg; 123 | 124 | for (i = 0; i < numbits; i++) { 125 | /* Mask in bit from code to channel word */ 126 | if (ch_bit == 0) 127 | *ch_word = ((code & (1<> i); 128 | else 129 | *ch_word |= (((code & (1<> i) << ch_bit); 130 | 131 | /* Check for full channel word */ 132 | if (++ch_bit >= wsize) { 133 | ch_bit = 0; 134 | (*p_ch_beg)++ ; 135 | ch_word++ ; 136 | } 137 | } 138 | 139 | /* Save updated bit counter */ 140 | *p_ch_bit = ch_bit; 141 | } 142 | 143 | /* */ 144 | /* Subroutine peakiness: estimate peakiness of input */ 145 | /* signal using ratio of L2 to L1 norms. */ 146 | /* */ 147 | float peakiness(float input[], int npts) 148 | { 149 | int i; 150 | float sum_abs, peak_fact; 151 | 152 | sum_abs = 0.0; 153 | for (i = 0; i < npts; i++) 154 | sum_abs += fabsf(input[i]); 155 | 156 | if (sum_abs > 0.01F) 157 | peak_fact = arm_sqrt(npts*v_magsq(input,npts)) / sum_abs; 158 | else 159 | peak_fact = 0.0; 160 | 161 | return(peak_fact); 162 | } 163 | 164 | /* */ 165 | /* Subroutine QUANT_U: quantize positive input value with */ 166 | /* symmetrical uniform quantizer over given positive */ 167 | /* input range. */ 168 | /* */ 169 | void quant_u(float *p_data, int *p_index, float qmin, float qmax, int nlev) 170 | { 171 | register int i, j; 172 | register float step, qbnd, *p_in; 173 | 174 | p_in = p_data; 175 | 176 | /* Define symmetrical quantizer step-size */ 177 | step = (qmax - qmin) / (nlev - 1); 178 | 179 | /* Search quantizer boundaries */ 180 | qbnd = qmin + (0.5f * step); 181 | j = nlev - 1; 182 | for (i = 0; i < j; i ++ ) { 183 | if (*p_in < qbnd) 184 | break; 185 | else 186 | qbnd += step; 187 | } 188 | 189 | /* Quantize input to correct level */ 190 | *p_in = qmin + (i * step); 191 | *p_index = i; 192 | } 193 | 194 | /* */ 195 | /* Subroutine QUANT_U_DEC: decode uniformly quantized */ 196 | /* value. */ 197 | /* */ 198 | void quant_u_dec(int index, float *p_data,float qmin, float qmax, int nlev) 199 | { 200 | register float step; 201 | 202 | /* Define symmetrical quantizer stepsize */ 203 | step = (qmax - qmin) / (nlev - 1); 204 | 205 | /* Decode quantized level */ 206 | *p_data = qmin + (index * step); 207 | } 208 | 209 | /* */ 210 | /* Subroutine rand_num: generate random numbers to fill */ 211 | /* array using system random number generator. */ 212 | /* */ 213 | void rand_num(float output[], float amplitude, int npts) 214 | { 215 | int i; 216 | 217 | for (i = 0; i < npts; i++ ) { 218 | /* use system random number generator from -1 to +1 */ 219 | output[i] = (amplitude*2.0f) * ((float) rand()*(1.0f/RAND_MAX) - 0.5f); 220 | } 221 | } 222 | 223 | 224 | /* */ 225 | /* Subroutine UNPACK_CODE: Unpack bit code from channel. */ 226 | /* Return 1 if erasure, otherwise 0. */ 227 | /* */ 228 | int unpack_code(unsigned int **p_ch_beg, int *p_ch_bit, int *p_code, int numbits, int wsize, unsigned int ERASE_MASK) 229 | { 230 | int ret_code; 231 | int i,ch_bit; 232 | unsigned int *ch_word; 233 | 234 | ch_bit = *p_ch_bit; 235 | ch_word = *p_ch_beg; 236 | *p_code = 0; 237 | ret_code = *ch_word & ERASE_MASK; 238 | 239 | for (i = 0; i < numbits; i++) { 240 | /* Mask in bit from channel word to code */ 241 | *p_code |= (((*ch_word & (1<> ch_bit) << i); 242 | 243 | /* Check for end of channel word */ 244 | if (++ch_bit >= wsize) { 245 | ch_bit = 0; 246 | (*p_ch_beg)++ ; 247 | ch_word++ ; 248 | } 249 | } 250 | 251 | /* Save updated bit counter */ 252 | *p_ch_bit = ch_bit; 253 | 254 | /* Catch erasure in new word if read */ 255 | if (ch_bit != 0) 256 | ret_code |= *ch_word & ERASE_MASK; 257 | 258 | return(ret_code); 259 | } 260 | 261 | 262 | /* */ 263 | /* Subroutine polflt: all pole (IIR) filter. */ 264 | /* Note: The filter coefficients represent the */ 265 | /* denominator only, and the leading coefficient */ 266 | /* is assumed to be 1. */ 267 | /* The output array can overlay the input. */ 268 | /* */ 269 | void polflt(float input[], const float coeff[], float output[], int order,int npts) 270 | { 271 | int numTaps, numBlk; 272 | float accum0, accum1, accum2, accum3; 273 | float a1, a2, a3, a4, c0; 274 | float y1, y2, y3, y4; 275 | float *pc; 276 | float *py; 277 | a1 = coeff[1]; a2 = coeff[2]; a3 = coeff[3]; a4 = coeff[4]; 278 | y1 = output[-1]; y2 = output[-2]; y3 = output[-3]; y4 = output[-4]; 279 | numBlk = npts; 280 | while (numBlk >= 4) { 281 | accum0 = *input++ - (y1 * a1) - (y2 * a2) - (y3 * a3) - (y4 * a4); 282 | accum1 = *input++ - (y1 * a2) - (y2 * a3) - (y3 * a4); 283 | accum2 = *input++ - (y1 * a3) - (y2 * a4); 284 | accum3 = *input++ - (y1 * a4); 285 | 286 | pc = &coeff[5]; 287 | py = &output[-5]; 288 | numTaps = order - 4; 289 | while(numTaps > 0) 290 | { 291 | c0 = *pc++; 292 | y1 = y2; 293 | y2 = y3; 294 | y3 = y4; 295 | y4 = *py--; 296 | accum0 -= ( y4 * c0); 297 | accum1 -= ( y3 * c0); 298 | accum2 -= ( y2 * c0); 299 | accum3 -= ( y1 * c0); 300 | numTaps--; 301 | } 302 | accum1 -= (accum0 * a1); 303 | accum2 -= (accum1 * a1) + (accum0 * a2); 304 | accum3 -= (accum2 * a1) + (accum1 * a2) + (accum0 * a3); 305 | 306 | y4 = *output++ = accum0; 307 | y3 = *output++ = accum1; 308 | y2 = *output++ = accum2; 309 | y1 = *output++ = accum3; 310 | numBlk -= 4; 311 | } 312 | // For the rest (non-multiples of 4) of samples do it normally 313 | while(numBlk > 0) 314 | { 315 | accum0 = *input++; 316 | pc = &coeff[1]; 317 | py = &output[-1]; 318 | numTaps = order; 319 | while(numTaps > 0) 320 | { 321 | accum0 -= ( (*py--) * (*pc++) ); 322 | numTaps--; 323 | } 324 | *output++ = accum0; 325 | numBlk--; 326 | } 327 | } 328 | 329 | 330 | /* */ 331 | /* Subroutine iirflt: all pole (IIR) filter. */ 332 | /* Note: The filter coefficients represent the */ 333 | /* denominator only, and the leading coefficient */ 334 | /* is assumed to be 1. */ 335 | /* The output array can overlay the input. */ 336 | /* */ 337 | void iirflt(float input[], const float coeff[], float output[], float delay[], int order,int npts) 338 | { 339 | v_equ(&output[-order], delay, order); 340 | polflt(input, coeff, output, order, npts); 341 | v_equ(delay,&output[npts - order], order); 342 | } 343 | 344 | 345 | /* */ 346 | /* Subroutine firflt: all zero (FIR) filter. */ 347 | /* Note: the output array can overlay the input. */ 348 | /* */ 349 | void firflt(float input[], const float coeff[], float output[], float delay[], int order, int npts) 350 | { 351 | v_equ(&input[-order], delay, order); 352 | v_equ(delay, &input[npts - order], order); 353 | zerflt(input, coeff, output, order, npts); 354 | } 355 | 356 | void zerflt(float *pSrc, const float *pCoeffs, float *pDst, int order, int npts) 357 | { 358 | const float *px, *pb; /* Temporary pointers for state and coefficient buffers */ 359 | float acc0, acc1, acc2, acc3; /* Accumulators */ 360 | float x0, x1, x2, x3, c0; /* Temporary variables to hold state and coefficient values */ 361 | uint32_t numTaps, tapCnt, blkCnt; /* Loop counters */ 362 | float p0,p1,p2,p3; /* Temporary product values */ 363 | 364 | pSrc += (npts - 1); 365 | pDst += (npts - 1); 366 | numTaps = order + 1; 367 | 368 | 369 | /* Apply loop unrolling and compute 4 output values simultaneously. 370 | * The variables acc0 ... acc3 hold output values that are being computed 371 | */ 372 | blkCnt = npts; 373 | 374 | /* First part of the processing with loop unrolling. Compute 4 outputs at a time. 375 | ** a second loop below computes the remaining 1 to 3 samples. */ 376 | while(blkCnt >= 4) 377 | { 378 | /* Set all accumulators to zero */ 379 | acc0 = 0.0f; 380 | acc1 = 0.0f; 381 | acc2 = 0.0f; 382 | acc3 = 0.0f; 383 | 384 | /* Initialize state pointer */ 385 | px = pSrc; 386 | 387 | /* Initialize coeff pointer */ 388 | pb = pCoeffs; 389 | 390 | /* Read the first three samples from the state buffer */ 391 | x0 = *px--; 392 | x1 = *px--; 393 | x2 = *px--; 394 | 395 | /* Loop unrolling. Process 4 taps at a time. */ 396 | tapCnt = numTaps; 397 | 398 | /* Loop over the number of taps. Unroll by a factor of 4. 399 | ** Repeat until we've computed numTaps-4 coefficients. */ 400 | while(tapCnt >= 4) 401 | { 402 | /* Read the b[0] coefficient */ 403 | c0 = *(pb++); 404 | 405 | x3 = *(px--); 406 | 407 | p0 = x0 * c0; 408 | p1 = x1 * c0; 409 | p2 = x2 * c0; 410 | p3 = x3 * c0; 411 | 412 | /* Read the b[1] coefficient */ 413 | c0 = *(pb++); 414 | x0 = *(px--); 415 | 416 | acc0 += p0; 417 | acc1 += p1; 418 | acc2 += p2; 419 | acc3 += p3; 420 | 421 | /* Perform the multiply-accumulate */ 422 | p0 = x1 * c0; 423 | p1 = x2 * c0; 424 | p2 = x3 * c0; 425 | p3 = x0 * c0; 426 | 427 | /* Read the b[2] coefficient */ 428 | c0 = *(pb++); 429 | x1 = *(px--); 430 | 431 | acc0 += p0; 432 | acc1 += p1; 433 | acc2 += p2; 434 | acc3 += p3; 435 | 436 | /* Perform the multiply-accumulates */ 437 | p0 = x2 * c0; 438 | p1 = x3 * c0; 439 | p2 = x0 * c0; 440 | p3 = x1 * c0; 441 | 442 | /* Read the b[3] coefficient */ 443 | c0 = *(pb++); 444 | x2 = *(px--); 445 | 446 | acc0 += p0; 447 | acc1 += p1; 448 | acc2 += p2; 449 | acc3 += p3; 450 | 451 | /* Perform the multiply-accumulates */ 452 | p0 = x3 * c0; 453 | p1 = x0 * c0; 454 | p2 = x1 * c0; 455 | p3 = x2 * c0; 456 | 457 | acc0 += p0; 458 | acc1 += p1; 459 | acc2 += p2; 460 | acc3 += p3; 461 | 462 | tapCnt -= 4; 463 | } 464 | 465 | /* If the filter length is not a multiple of 4, compute the remaining filter taps */ 466 | while(tapCnt > 0) 467 | { 468 | /* Read coefficients */ 469 | c0 = *(pb++); 470 | 471 | /* Fetch 1 state variable */ 472 | x3 = *(px--); 473 | 474 | /* Perform the multiply-accumulates */ 475 | p0 = x0 * c0; 476 | p1 = x1 * c0; 477 | p2 = x2 * c0; 478 | p3 = x3 * c0; 479 | 480 | /* Reuse the present sample states for next sample */ 481 | x0 = x1; 482 | x1 = x2; 483 | x2 = x3; 484 | 485 | acc0 += p0; 486 | acc1 += p1; 487 | acc2 += p2; 488 | acc3 += p3; 489 | /* Decrement the loop counter */ 490 | tapCnt--; 491 | } 492 | 493 | 494 | /* The results in the 4 accumulators, store in the destination buffer. */ 495 | *pDst-- = acc0; 496 | *pDst-- = acc1; 497 | *pDst-- = acc2; 498 | *pDst-- = acc3; 499 | 500 | /* Advance the state pointer by 4 to process the next group of 4 samples */ 501 | pSrc -= 4; 502 | blkCnt -= 4; 503 | } 504 | 505 | /* If the blockSize is not a multiple of 4, compute any remaining output samples here. 506 | ** No loop unrolling is used. */ 507 | 508 | while(blkCnt > 0) 509 | { 510 | /* Set the accumulator to zero */ 511 | acc0 = 0.0f; 512 | /* Initialize state pointer */ 513 | px = pSrc; 514 | /* Initialize Coefficient pointer */ 515 | pb = pCoeffs; 516 | tapCnt = numTaps; 517 | 518 | /* Perform the multiply-accumulates */ 519 | do 520 | { 521 | acc0 += *px-- * *pb++; 522 | tapCnt--; 523 | } while(tapCnt > 0); 524 | 525 | /* The result is store in the destination buffer. */ 526 | *pDst-- = acc0; 527 | 528 | /* Advance state pointer by 1 for the next sample */ 529 | pSrc--; 530 | blkCnt--; 531 | } 532 | } 533 | 534 | //void zerflt(float input[], const float coeff[], float output[], int order, int npts) 535 | //{ 536 | // int i,j; 537 | // float accum; 538 | 539 | 540 | // firflt_f32(input, coeff, output, order, npts); 541 | // for (i = npts-1; i >= 0; i-- ) { 542 | // accum = 0.0; 543 | // for (j = 0; j <= order; j++ ) 544 | // accum += input[i-j] * coeff[j]; 545 | // output[i] = accum; 546 | // } 547 | //} 548 | -------------------------------------------------------------------------------- /melp_sub.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | 20 | melp_sub.c: MELP-specific subroutines 21 | 22 | */ 23 | 24 | #include 25 | #include 26 | #include "spbstd.h" 27 | #include "mat.h" 28 | #include "melp_sub.h" 29 | #include "dsp_sub.h" 30 | #include "pit.h" 31 | #include "melp.h" 32 | 33 | /* 34 | Name: bpvc_ana.c 35 | Description: Bandpass voicing analysis 36 | Inputs: 37 | speech[] - input speech signal 38 | fpitch[] - initial (floating point) pitch estimates 39 | Outputs: 40 | bpvc[] - bandpass voicing decisions 41 | pitch[] - frame pitch estimates 42 | Returns: void 43 | 44 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 45 | */ 46 | 47 | /* Static memory */ 48 | static float envdel2[NUM_BANDS] CCMRAM; 49 | static float sigbuf[BPF_ORD+PITCH_FR] CCMRAM; 50 | static float sigbuf1[FRAME+DC_ORD] CCMRAM; 51 | 52 | static float *bpfdel[NUM_BANDS] CCMRAM; 53 | static float bpfdel_data[NUM_BANDS*BPF_ORD] CCMRAM; 54 | 55 | static float *envdel[NUM_BANDS] CCMRAM; 56 | static float envdel_data[NUM_BANDS*ENV_ORD] CCMRAM; 57 | 58 | void bpvc_ana(float speech[], float fpitch[], float bpvc[], float pitch[]) 59 | { 60 | float pcorr, temp; 61 | int j; 62 | 63 | /* Filter lowest band and estimate pitch */ 64 | v_equ(&sigbuf[0],&bpfdel[0][0],BPF_ORD); 65 | polflt(&speech[-PITCHMAX],&bpf_den[0],&sigbuf[BPF_ORD], BPF_ORD, PITCH_FR); 66 | v_equ(&bpfdel[0][0],&sigbuf[FRAME],BPF_ORD); 67 | zerflt(&sigbuf[BPF_ORD],&bpf_num[0],&sigbuf[BPF_ORD], BPF_ORD, PITCH_FR); 68 | 69 | *pitch = frac_pch(&sigbuf[BPF_ORD+PITCHMAX], &bpvc[0],fpitch[0],5,PITCHMIN,PITCHMAX,MINLENGTH); 70 | 71 | for (j = 1; j < NUM_PITCHES; j++) { 72 | temp = frac_pch(&sigbuf[BPF_ORD+PITCHMAX], &pcorr,fpitch[j],5,PITCHMIN,PITCHMAX,MINLENGTH); 73 | /* choose largest correlation value */ 74 | if (pcorr > bpvc[0]) { 75 | *pitch = temp; 76 | bpvc[0] = pcorr; 77 | } 78 | } 79 | 80 | /* Calculate bandpass voicing for frames */ 81 | for (j = 1; j < NUM_BANDS; j++) { 82 | /* Bandpass filter input speech */ 83 | v_equ(&sigbuf[0],&bpfdel[j][0],BPF_ORD); 84 | polflt(&speech[-PITCHMAX],&bpf_den[j*(BPF_ORD+1)],&sigbuf[BPF_ORD], BPF_ORD, PITCH_FR); 85 | v_equ(&bpfdel[j][0],&sigbuf[FRAME],BPF_ORD); 86 | zerflt(&sigbuf[BPF_ORD],&bpf_num[j*(BPF_ORD+1)],&sigbuf[BPF_ORD],BPF_ORD, PITCH_FR); 87 | 88 | /* Check correlations for each frame */ 89 | temp = frac_pch(&sigbuf[BPF_ORD+PITCHMAX], &bpvc[j],*pitch,0,PITCHMIN,PITCHMAX,MINLENGTH); 90 | 91 | /* Calculate envelope of bandpass filtered input speech */ 92 | temp = envdel2[j]; 93 | envdel2[j] = sigbuf[BPF_ORD+FRAME-1]; 94 | v_equ(&sigbuf[BPF_ORD-ENV_ORD],&envdel[j][0],ENV_ORD); 95 | envelope(&sigbuf[BPF_ORD],temp,&sigbuf[BPF_ORD],PITCH_FR); 96 | v_equ(&envdel[j][0],&sigbuf[BPF_ORD+FRAME-ENV_ORD],ENV_ORD); 97 | 98 | /* Check correlations for each frame */ 99 | temp = frac_pch(&sigbuf[BPF_ORD+PITCHMAX],&pcorr, *pitch,0 ,PITCHMIN,PITCHMAX,MINLENGTH); 100 | 101 | /* reduce envelope correlation */ 102 | pcorr -= 0.1f; 103 | if (pcorr > bpvc[j]) 104 | bpvc[j] = pcorr; 105 | } 106 | } 107 | 108 | 109 | void bpvc_ana_init() 110 | { 111 | int i; 112 | 113 | for(i = 0; i < NUM_BANDS; i++) 114 | { 115 | bpfdel[i] = &bpfdel_data[BPF_ORD * i]; 116 | envdel[i] = &envdel_data[ENV_ORD * i]; 117 | } 118 | v_zap(&(bpfdel[0][0]),NUM_BANDS*BPF_ORD); 119 | v_zap(&(envdel[0][0]),NUM_BANDS*ENV_ORD); 120 | v_zap(envdel2,NUM_BANDS); 121 | } 122 | 123 | /* 124 | Name: dc_rmv.c 125 | Description: remove DC from input signal 126 | Inputs: 127 | sigin[] - input signal 128 | dcdel[] - filter delay history (size DC_ORD) 129 | frame - number of samples to filter 130 | Outputs: 131 | sigout[] - output signal 132 | dcdel[] - updated filter delay history 133 | Returns: void 134 | See_Also: 135 | 136 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 137 | */ 138 | 139 | /* Filter order */ 140 | #define DC_ORD 4 141 | 142 | /* DC removal filter */ 143 | /* 4th order Chebyshev Type II 60 Hz removal filter */ 144 | /* cutoff=60 Hz, stop=-30 dB */ 145 | static float dc_num[DC_ORD+1] RODATA = { 146 | 0.92692416f, 147 | -3.70563834f, 148 | 5.55742893f, 149 | -3.70563834f, 150 | 0.92692416f}; 151 | static float dc_den[DC_ORD+1] RODATA = { 152 | 1.00000000f, 153 | -3.84610723f, 154 | 5.55209760f, 155 | -3.56516069f, 156 | 0.85918839f}; 157 | 158 | void dc_rmv(float sigin[], float sigout[], float dcdel[], int frame) 159 | { 160 | /* Remove DC from input speech */ 161 | iirflt(sigin,dc_den,&sigbuf1[DC_ORD],dcdel, DC_ORD,frame); 162 | zerflt(&sigbuf1[DC_ORD],dc_num,sigout,DC_ORD,frame); 163 | } 164 | 165 | /* 166 | Name: gain_ana.c 167 | Description: analyze gain level for input signal 168 | Inputs: 169 | sigin[] - input signal 170 | pitch - pitch value (for pitch synchronous window) 171 | minlength - minimum window length 172 | maxlength - maximum window length 173 | Outputs: 174 | Returns: log gain in dB 175 | See_Also: 176 | 177 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 178 | */ 179 | 180 | #define MINGAIN 0.0f 181 | 182 | float gain_ana(float sigin[], float pitch, int minlength, int maxlength) 183 | { 184 | int length; 185 | float flength, gain; 186 | 187 | /* Find shortest pitch multiple window length (floating point) */ 188 | flength = pitch; 189 | while (flength < minlength) 190 | flength += pitch; 191 | 192 | /* Convert window length to integer and check against maximum */ 193 | length = (int)(flength + 0.5f); 194 | if (length > maxlength) 195 | length = (length/2); 196 | 197 | /* Calculate RMS gain in dB */ 198 | gain = 10.0f*log10f(0.01f + (v_magsq(&sigin[-(length/2)],length) / length)); 199 | if (gain < MINGAIN) gain = MINGAIN; 200 | 201 | return(gain); 202 | } 203 | 204 | /* 205 | Name: lin_int_bnd.c 206 | Description: Linear interpolation within bounds 207 | Inputs: 208 | x - input X value 209 | xmin - minimum X value 210 | xmax - maximum X value 211 | ymin - minimum Y value 212 | ymax - maximum Y value 213 | Returns: y - interpolated and bounded y value 214 | 215 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 216 | */ 217 | 218 | float lin_int_bnd(float x,float xmin,float xmax,float ymin,float ymax) 219 | { 220 | float y; 221 | 222 | if (x <= xmin) y = ymin; 223 | else if (x >= xmax) y = ymax; 224 | else y = ymin + (x-xmin)*(ymax-ymin)/(xmax-xmin); 225 | 226 | return(y); 227 | } 228 | 229 | /* 230 | Name: noise_est.c 231 | Description: Estimate long-term noise floor 232 | Inputs: 233 | gain - input gain (in dB) 234 | noise_gain - current noise gain estimate 235 | up - maximum up stepsize 236 | down - maximum down stepsize 237 | min - minimum allowed gain 238 | max - maximum allowed gain 239 | Outputs: 240 | noise_gain - updated noise gain estimate 241 | Returns: void 242 | 243 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 244 | */ 245 | 246 | void noise_est(float gain,float *noise_gain,float up,float down,float min,float max) 247 | { 248 | /* Update noise_gain */ 249 | if (gain > *noise_gain+up) *noise_gain = *noise_gain+up; 250 | else if (gain < *noise_gain+down) *noise_gain = *noise_gain+down; 251 | else *noise_gain = gain; 252 | 253 | /* Constrain total range of noise_gain */ 254 | if (*noise_gain < min) *noise_gain = min; 255 | if (*noise_gain > max) *noise_gain = max; 256 | } 257 | 258 | /* 259 | Name: noise_sup.c 260 | Description: Perform noise suppression on speech gain 261 | Inputs: (all in dB) 262 | gain - input gain (in dB) 263 | noise_gain - current noise gain estimate (in dB) 264 | max_noise - maximum allowed noise gain 265 | max_atten - maximum allowed attenuation 266 | nfact - noise floor boost 267 | Outputs: 268 | gain - updated gain 269 | Returns: void 270 | 271 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 272 | */ 273 | 274 | void noise_sup(float *gain,float noise_gain,float max_noise,float max_atten, float nfact) 275 | { 276 | float gain_lev,suppress; 277 | 278 | /* Reduce effect for louder background noise */ 279 | if (noise_gain > max_noise) noise_gain = max_noise; 280 | 281 | /* Calculate suppression factor */ 282 | gain_lev = *gain - (noise_gain + nfact); 283 | if (gain_lev > 0.001f) { 284 | suppress = -10.0f*log10f(1.0f - powf(10.0f,-0.1f*gain_lev)); 285 | if (suppress > max_atten) suppress = max_atten; 286 | } else 287 | suppress = max_atten; 288 | 289 | /* Apply suppression to input gain */ 290 | *gain -= suppress; 291 | } 292 | 293 | /* 294 | Name: q_bpvc.c, q_bpvc_dec.c 295 | Description: Quantize/decode bandpass voicing 296 | Inputs: 297 | bpvc, bpvc_index 298 | bpthresh - threshold 299 | NUM_BANDS - number of bands 300 | Outputs: 301 | bpvc, bpvc_index 302 | Returns: uv_flag - flag if unvoiced 303 | 304 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 305 | */ 306 | 307 | /* Compile constants */ 308 | #define INVALID_BPVC 0001 309 | 310 | int q_bpvc(float *bpvc,int *bpvc_index,float bpthresh,int num_bands) 311 | { 312 | int j, uv_flag; 313 | 314 | uv_flag = 1; 315 | 316 | if (bpvc[0] > bpthresh) { 317 | /* Voiced: pack bandpass voicing */ 318 | uv_flag = 0; 319 | *bpvc_index = 0; 320 | bpvc[0] = 1.0; 321 | 322 | for (j = 1; j < num_bands; j++) { 323 | *bpvc_index <<= 1; /* left shift */ 324 | if (bpvc[j] > bpthresh) { 325 | bpvc[j] = 1.0; 326 | *bpvc_index |= 1; 327 | }else { 328 | bpvc[j] = 0.0; 329 | *bpvc_index |= 0; 330 | } 331 | } 332 | 333 | /* Don't use invalid code (only top band voiced) */ 334 | if (*bpvc_index == INVALID_BPVC) { 335 | bpvc[(num_bands-1)] = 0.0; 336 | *bpvc_index = 0; 337 | } 338 | }else { 339 | /* Unvoiced: force all bands unvoiced */ 340 | *bpvc_index = 0; 341 | for (j = 0; j < num_bands; j++) 342 | bpvc[j] = 0.0; 343 | } 344 | 345 | return(uv_flag); 346 | } 347 | 348 | void q_bpvc_dec(float *bpvc,int *bpvc_index,int uv_flag,int num_bands) 349 | { 350 | int j; 351 | 352 | if (uv_flag) { 353 | /* Unvoiced: set all bpvc to 0 */ 354 | *bpvc_index = 0; 355 | bpvc[0] = 0.0; 356 | }else { 357 | /* Voiced: set bpvc[0] to 1.0 */ 358 | bpvc[0] = 1.0; 359 | } 360 | 361 | if (*bpvc_index == INVALID_BPVC) { 362 | /* Invalid code received: set higher band voicing to zero */ 363 | *bpvc_index = 0; 364 | } 365 | 366 | /* Decode remaining bands */ 367 | for (j = num_bands-1; j > 0; j--) { 368 | if ((*bpvc_index & 1) == 1) 369 | bpvc[j] = 1.0; 370 | else 371 | bpvc[j] = 0.0; 372 | *bpvc_index >>= 1; 373 | } 374 | } 375 | 376 | /* 377 | Name: q_gain.c, q_gain_dec.c 378 | Description: Quantize/decode two gain terms using quasi-differential coding 379 | Inputs: 380 | gain[2],gain_index[2] 381 | GN_QLO,GN_QUP,GN_QLEV for second gain term 382 | Outputs: 383 | gain[2],gain_index[2] 384 | Returns: void 385 | 386 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 387 | */ 388 | 389 | /* Compile constants */ 390 | #define GAIN_INT_DB 5.0f 391 | 392 | void q_gain(float *gain,int *gain_index,float gn_qlo,float gn_qup,int gn_qlev) 393 | { 394 | static float prev_gain = 0.0f; 395 | float temp,temp2; 396 | 397 | /* Quantize second gain term with uniform quantizer */ 398 | quant_u(&gain[1],&gain_index[1],gn_qlo,gn_qup,gn_qlev); 399 | 400 | /* Check for intermediate gain interpolation */ 401 | if (gain[0] < gn_qlo) 402 | gain[0] = gn_qlo; 403 | if (gain[0] > gn_qup) 404 | gain[0] = gn_qup; 405 | if (fabs(gain[1] - prev_gain) < GAIN_INT_DB && 406 | fabs(gain[0] - 0.5f*(gain[1]+prev_gain)) < 3.0f) { 407 | 408 | /* interpolate and set special code */ 409 | gain[0] = 0.5f*(gain[1]+prev_gain); 410 | gain_index[0] = 0; 411 | } 412 | else { 413 | 414 | /* Code intermediate gain with 7-levels */ 415 | if (prev_gain < gain[1]) { 416 | temp = prev_gain; 417 | temp2 = gain[1]; 418 | } 419 | else { 420 | temp = gain[1]; 421 | temp2 = prev_gain; 422 | } 423 | temp -= 6.0f; 424 | temp2 += 6.0f; 425 | if (temp < gn_qlo) 426 | temp = gn_qlo; 427 | if (temp2 > gn_qup) 428 | temp2 = gn_qup; 429 | quant_u(&gain[0],&gain_index[0],temp,temp2,7); 430 | 431 | /* Skip all-zero code */ 432 | gain_index[0]++; 433 | } 434 | 435 | /* Update previous gain for next time */ 436 | prev_gain = gain[1]; 437 | } 438 | 439 | void q_gain_dec(float *gain,int *gain_index,float gn_qlo,float gn_qup,int gn_qlev) 440 | { 441 | 442 | static float prev_gain = 0.0f; 443 | static int prev_gain_err = 0; 444 | float temp,temp2; 445 | 446 | /* Decode second gain term */ 447 | quant_u_dec(gain_index[1],&gain[1],gn_qlo,gn_qup,gn_qlev); 448 | 449 | if (gain_index[0] == 0) { 450 | /* interpolation bit code for intermediate gain */ 451 | if (fabs(gain[1] - prev_gain) > GAIN_INT_DB) { 452 | /* Invalid received data (bit error) */ 453 | if (prev_gain_err == 0) { 454 | /* First time: don't allow gain excursion */ 455 | gain[1] = prev_gain; 456 | } 457 | prev_gain_err = 1; 458 | } 459 | else 460 | prev_gain_err = 0; 461 | 462 | /* Use interpolated gain value */ 463 | gain[0] = 0.5f*(gain[1]+prev_gain); 464 | } else { 465 | /* Decode 7-bit quantizer for first gain term */ 466 | prev_gain_err = 0; 467 | gain_index[0]--; 468 | if (prev_gain < gain[1]) { 469 | temp = prev_gain; 470 | temp2 = gain[1]; 471 | }else { 472 | temp = gain[1]; 473 | temp2 = prev_gain; 474 | } 475 | temp -= 6.0f; 476 | temp2 += 6.0f; 477 | if (temp < gn_qlo) temp = gn_qlo; 478 | if (temp2 > gn_qup) temp2 = gn_qup; 479 | quant_u_dec(gain_index[0],&gain[0],temp,temp2,7); 480 | } 481 | 482 | /* Update previous gain for next time */ 483 | prev_gain = gain[1]; 484 | } 485 | 486 | /* 487 | Name: scale_adj.c 488 | Description: Adjust scaling of output speech signal. 489 | Inputs: 490 | speech - speech signal 491 | gain - desired RMS gain 492 | prev_scale - previous scale factor 493 | length - number of samples in signal 494 | SCALEOVER - number of points to interpolate scale factor 495 | Warning: SCALEOVER is assumed to be less than length. 496 | Outputs: 497 | speech - scaled speech signal 498 | prev_scale - updated previous scale factor 499 | Returns: void 500 | 501 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 502 | */ 503 | 504 | void scale_adj(float *speech, float gain, float *prev_scale, int length, int scale_over) 505 | { 506 | int i; 507 | float scale; 508 | 509 | /* Calculate desired scaling factor to match gain level */ 510 | scale = gain / (arm_sqrt(v_magsq(&speech[0],length) / length) + .01f); 511 | 512 | /* interpolate scale factors for first SCALEOVER points */ 513 | for (i = 1; i < scale_over; i++) { 514 | speech[i-1] *= ((scale*i + *prev_scale*(scale_over-i)) 515 | * (1.0f/scale_over) ); 516 | } 517 | 518 | /* Scale rest of signal */ 519 | v_scale(&speech[scale_over-1],scale,length-scale_over+1); 520 | 521 | /* Update previous scale factor for next call */ 522 | *prev_scale = scale; 523 | } 524 | -------------------------------------------------------------------------------- /fec_code.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 2.4 kbps MELP Proposed Federal Standard speech coder 4 | 5 | version 1.2 6 | 7 | Copyright (c) 1996, Texas Instruments, Inc. 8 | 9 | Texas Instruments has intellectual property rights on the MELP 10 | algorithm. The Texas Instruments contact for licensing issues for 11 | commercial and non-government use is William Gordon, Director, 12 | Government Contracts, Texas Instruments Incorporated, Semiconductor 13 | Group (phone 972 480 7442). 14 | 15 | 16 | */ 17 | 18 | /* 19 | Name: fec_code.c, fec_decode.c 20 | Description: Encode/decode FEC (Hamming codes) on selected MELP parameters 21 | Inputs: 22 | MELP parameter structure 23 | Outputs: 24 | updated MELP parameter structure 25 | Returns: void 26 | 27 | Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved. 28 | */ 29 | 30 | #include 31 | #include "melp.h" 32 | 33 | /* Prototypes */ 34 | int binprod_int(int *x, int *y, int n); 35 | int *vgetbits(int *y, int x, int p, int n); 36 | int vsetbits(int x, int p, int n, int *y); 37 | void sbc_enc(int x[], int n, int k, int *pmat); 38 | int sbc_dec(int x[], int n, int k, int *pmat, int syntab[]); 39 | int sbc_syn(int x[], int n, int k, int *pmat); 40 | 41 | 42 | /* Compiler constants */ 43 | #define UV_PIND 0 /* Unvoiced pitch index */ 44 | #define INVAL_PIND 1 /* Invalid pitch index */ 45 | #define BEP_CORR -1 /* "Correct" bit error position */ 46 | #define BEP_UNCORR -2 /* "Uncorrectable" bit error position */ 47 | 48 | extern int pitch_enc[PIT_QLEV+1]; /* Pitch index encoding table */ 49 | extern int pmat74[3][4]; /* (7,4) Hamming code parity matrix */ 50 | extern int syntab74[8]; /* (7,4) Hamming code syndrome->bep table */ 51 | extern int pmat84[4][4]; /* (8,4) Hamming code parity matrix */ 52 | extern int syntab84[16]; /* (8,4) Hamming code syndrome->bep table */ 53 | 54 | static int codewd74[7]; 55 | static int codewd84[8]; 56 | 57 | extern int pitch_dec[1<pitch_index++; 64 | 65 | /* 66 | ** Unvoiced case - use spare parameter bits for error protection. 67 | */ 68 | if (par->uv_flag) 69 | { 70 | /* Set pitch index to unvoiced value */ 71 | par->pitch_index = UV_PIND; 72 | 73 | /* 74 | ** Code 4 MSB of first vq stage index using (8,4) Hamming code; parity bits in 75 | ** bpvc index. 76 | */ 77 | vgetbits(codewd84,par->msvq_par.indices[0],6,4); 78 | sbc_enc(codewd84,8,4,&pmat84[0][0]); 79 | par->bpvc_index=vsetbits(par->bpvc_index,3,4,&codewd84[4]); 80 | /* 81 | ** Code 3 LSB of first vq stage index using (7,4) Hamming code; parity bits 82 | ** in 3 MSB of fsvq index. 83 | */ 84 | vgetbits(codewd74,par->msvq_par.indices[0],2,3); 85 | codewd74[3] = 0; 86 | sbc_enc(codewd74,7,4,&pmat74[0][0]); 87 | par->fsvq_par.indices[0]=vsetbits(par->fsvq_par.indices[0],7,3,&codewd74[4]); 88 | /* 89 | ** Code 4 MSB of second gain index using (7,4) Hamming code; parity bits in 90 | ** next 3 MSB of fsvq index. 91 | */ 92 | vgetbits(codewd74,par->gain_index[1],4,4); 93 | sbc_enc(codewd74,7,4,&pmat74[0][0]); 94 | par->fsvq_par.indices[0]=vsetbits(par->fsvq_par.indices[0],4,3,&codewd74[4]); 95 | /* 96 | ** Code LSB of second gain index, first gain index using (7,4) Hamming code; 97 | ** parity bits in 2 LSB of fsvq index, jitter index bit. 98 | */ 99 | vgetbits(codewd74,par->gain_index[1],0,1); 100 | vgetbits(&codewd74[1],par->gain_index[0],2,3); 101 | sbc_enc(codewd74,7,4,&pmat74[0][0]); 102 | par->fsvq_par.indices[0]=vsetbits(par->fsvq_par.indices[0],1,2,&codewd74[4]); 103 | par->jit_index=vsetbits(par->jit_index,0,1,&codewd74[6]); 104 | } 105 | 106 | /* Encode pitch index */ 107 | par->pitch_index = pitch_enc[par->pitch_index]; 108 | } 109 | 110 | int fec_decode(struct melp_param *par, int erase) 111 | { 112 | int berr_pos; 113 | 114 | /* Decode pitch index */ 115 | par->pitch_index = pitch_dec[par->pitch_index]; 116 | 117 | /* 118 | ** Set unvoiced flag for pitch index of UV_PIND; set erase flag for invalid 119 | ** pitch index INVAL_PIND. Otherwise, convert pitch index into quantization 120 | ** level. 121 | */ 122 | par->uv_flag = (par->pitch_index == UV_PIND); 123 | erase |= (par->pitch_index == INVAL_PIND); 124 | if (!par->uv_flag && !erase ) 125 | par->pitch_index-=2; /* Subtract to acct. for reserved pitch codes.*/ 126 | 127 | if (par->uv_flag && !erase) 128 | /* 129 | ** Unvoiced case - use spare parameter bits for error control coding. 130 | */ 131 | { 132 | /* 133 | ** Decode 4 MSB of first vq stage index using (8,4) Hamming code; parity bits 134 | ** in bpvc index. Set bpvc index to zero. 135 | */ 136 | vgetbits(codewd84,par->msvq_par.indices[0],6,4); 137 | vgetbits(&codewd84[4],par->bpvc_index,3,4); 138 | berr_pos=sbc_dec(codewd84,8,4,&pmat84[0][0],syntab84); 139 | erase |= berr_pos == BEP_UNCORR; 140 | par->msvq_par.indices[0]=vsetbits(par->msvq_par.indices[0],6,4,codewd84); 141 | par->bpvc_index = 0; 142 | 143 | /* Perform remaining decoding only if no frame repeat flagged. */ 144 | if (!erase) 145 | { 146 | /* 147 | ** Decode 3 LSB of first vq stage index using (7,4) Hamming code; parity bits 148 | ** in 3 MSB of fsvq index. 149 | */ 150 | vgetbits(codewd74,par->msvq_par.indices[0],2,3); 151 | codewd74[3] = 0; 152 | vgetbits(&codewd74[4],par->fsvq_par.indices[0],7,3); 153 | berr_pos=sbc_dec(codewd74,7,4,&pmat74[0][0],syntab74); 154 | par->msvq_par.indices[0]=vsetbits(par->msvq_par.indices[0],2,3,codewd74); 155 | /* 156 | ** Decode 4 MSB of second gain index using (7,4) Hamming code; parity bits in 157 | ** next 3 MSB of fsvq index. 158 | */ 159 | vgetbits(codewd74,par->gain_index[1],4,4); 160 | vgetbits(&codewd74[4],par->fsvq_par.indices[0],4,3); 161 | berr_pos=sbc_dec(codewd74,7,4,&pmat74[0][0],syntab74); 162 | par->gain_index[1]=vsetbits(par->gain_index[1],4,4,codewd74); 163 | /* 164 | ** Decode LSB of second gain index, first gain index using (7,4) Hamming code; 165 | ** parity bits in 2 LSB of fsvq index, jitter index bit. Set 166 | ** jitter index bits to one. 167 | */ 168 | vgetbits(codewd74,par->gain_index[1],0,1); 169 | vgetbits(&codewd74[1],par->gain_index[0],2,3); 170 | vgetbits(&codewd74[4],par->fsvq_par.indices[0],1,2); 171 | vgetbits(&codewd74[6],par->jit_index,0,1); 172 | berr_pos=sbc_dec(codewd74,7,4,&pmat74[0][0],syntab74); 173 | par->gain_index[1]=vsetbits(par->gain_index[1],0,1,codewd74); 174 | par->gain_index[0]=vsetbits(par->gain_index[0],2,3,&codewd74[1]); 175 | par->jit_index = 1; 176 | } 177 | } /* if (par->uv_flag && !erase) */ 178 | 179 | return(erase); 180 | 181 | } 182 | /* 183 | binprod returns a 184 | bitwise modulo-2 inner product between x and y. 185 | */ 186 | 187 | int binprod_int(int *x, int *y, int n) 188 | { 189 | int val=(int) 0; 190 | register int i; 191 | 192 | for (i=0; i>=p-n+1; y>=retval; y--,x>>=1) 215 | *y = x & lsb; 216 | 217 | return(retval); 218 | } 219 | 220 | int vsetbits(int x, int p, int n, int *y) 221 | { 222 | register int i,j; 223 | 224 | if (n < 0 || p < n-1) 225 | return(x); 226 | 227 | for (i=0,j=p; i -1) 268 | x[bep] ^= 0x1; 269 | return(bep); 270 | } 271 | 272 | int sbc_syn(int x[], int n, int k, int *pmat) 273 | { 274 | int retval=0; 275 | register int i,j; 276 | for (i=k,j=n-k-1; ierror position lookup table. */ 299 | int syntab84[16] RODATA = 300 | { 301 | BEP_CORR, /* 0x0 */ 302 | 7, /* 0x1 */ 303 | 6, /* 0x2 */ 304 | BEP_UNCORR, /* 0x3 */ 305 | 5, /* 0x4 */ 306 | BEP_UNCORR, /* 0x5 */ 307 | BEP_UNCORR, /* 0x6 */ 308 | 2, /* 0x7 */ 309 | 4, /* 0x8 */ 310 | BEP_UNCORR, /* 0x9 */ 311 | BEP_UNCORR, /* 0xA */ 312 | 1, /* 0xB */ 313 | BEP_UNCORR, /* 0xC */ 314 | 0, /* 0xD */ 315 | 3, /* 0xE */ 316 | BEP_UNCORR /* 0xF */ 317 | }; 318 | 319 | /* 320 | ** Pitch index encoding table. Reserve Hamming weight 0,1 words for 321 | ** unvoiced pitch value. Reserve Hamming weight 2 words for invalid (protect 322 | ** against single bit voiced pitch errors. Assign voiced pitch codes to 323 | ** values having Hamming weight > 2. 324 | */ 325 | 326 | int pitch_enc[PIT_QLEV+1] RODATA = 327 | { 328 | 0x0, /* UV_PIND */ 329 | 0x7, /* 1 (first pitch QL - note offset) */ 330 | 0xB, /* 2 */ 331 | 0xD, /* 3 */ 332 | 0xE, /* 4 */ 333 | 0xF, /* 5 */ 334 | 0x13, /* 6 */ 335 | 0x15, /* 7 */ 336 | 0x16, /* 8 */ 337 | 0x17, /* 9 */ 338 | 0x19, /* 10 */ 339 | 0x1A, /* 11 */ 340 | 0x1B, /* 12 */ 341 | 0x1C, /* 13 */ 342 | 0x1D, /* 14 */ 343 | 0x1E, /* 15 */ 344 | 0x1F, /* 16 */ 345 | 0x23, /* 17 */ 346 | 0x25, /* 18 */ 347 | 0x26, /* 19 */ 348 | 0x27, /* 20 */ 349 | 0x29, /* 21 */ 350 | 0x2A, /* 22 */ 351 | 0x2B, /* 23 */ 352 | 0x2C, /* 24 */ 353 | 0x2D, /* 25 */ 354 | 0x2E, /* 26 */ 355 | 0x2F, /* 27 */ 356 | 0x31, /* 28 */ 357 | 0x32, /* 29 */ 358 | 0x33, /* 30 */ 359 | 0x34, /* 31 */ 360 | 0x35, /* 32 */ 361 | 0x36, /* 33 */ 362 | 0x37, /* 34 */ 363 | 0x38, /* 35 */ 364 | 0x39, /* 36 */ 365 | 0x3A, /* 37 */ 366 | 0x3B, /* 38 */ 367 | 0x3C, /* 39 */ 368 | 0x3D, /* 40 */ 369 | 0x3E, /* 41 */ 370 | 0x3F, /* 42 */ 371 | 0x43, /* 43 */ 372 | 0x45, /* 44 */ 373 | 0x46, /* 45 */ 374 | 0x47, /* 46 */ 375 | 0x49, /* 47 */ 376 | 0x4A, /* 48 */ 377 | 0x4B, /* 49 */ 378 | 0x4C, /* 50 */ 379 | 0x4D, /* 51 */ 380 | 0x4E, /* 52 */ 381 | 0x4F, /* 53 */ 382 | 0x51, /* 54 */ 383 | 0x52, /* 55 */ 384 | 0x53, /* 56 */ 385 | 0x54, /* 57 */ 386 | 0x55, /* 58 */ 387 | 0x56, /* 59 */ 388 | 0x57, /* 60 */ 389 | 0x58, /* 61 */ 390 | 0x59, /* 62 */ 391 | 0x5A, /* 63 */ 392 | 0x5B, /* 64 */ 393 | 0x5C, /* 65 */ 394 | 0x5D, /* 66 */ 395 | 0x5E, /* 67 */ 396 | 0x5F, /* 68 */ 397 | 0x61, /* 69 */ 398 | 0x62, /* 70 */ 399 | 0x63, /* 71 */ 400 | 0x64, /* 72 */ 401 | 0x65, /* 73 */ 402 | 0x66, /* 74 */ 403 | 0x67, /* 75 */ 404 | 0x68, /* 76 */ 405 | 0x69, /* 77 */ 406 | 0x6A, /* 78 */ 407 | 0x6B, /* 79 */ 408 | 0x6C, /* 80 */ 409 | 0x6D, /* 81 */ 410 | 0x6E, /* 82 */ 411 | 0x6F, /* 83 */ 412 | 0x70, /* 84 */ 413 | 0x71, /* 85 */ 414 | 0x72, /* 86 */ 415 | 0x73, /* 87 */ 416 | 0x74, /* 88 */ 417 | 0x75, /* 89 */ 418 | 0x76, /* 90 */ 419 | 0x77, /* 91 */ 420 | 0x78, /* 92 */ 421 | 0x79, /* 93 */ 422 | 0x7A, /* 94 */ 423 | 0x7B, /* 95 */ 424 | 0x7C, /* 96 */ 425 | 0x7D, /* 97 */ 426 | 0x7E, /* 98 */ 427 | 0x7F /* 99 */ 428 | }; 429 | 430 | /* 431 | ** Pitch index decoding table. Hamming weight 1 codes map to UV_PIND, 432 | ** allowing for 1-bit error correction of unvoiced marker. Hamming weight 2 433 | ** codes map to INVAL_PIND, protecting against 1-bit errors in voiced pitches 434 | ** creating false unvoiced condition. 435 | */ 436 | 437 | int pitch_dec[1< 2 | 3 | 4 | 1.0 5 | 6 |
### uVision Project, (C) Keil Software
7 | 8 | 9 | *.c 10 | *.s*; *.src; *.a* 11 | *.obj 12 | *.lib 13 | *.txt; *.h; *.inc 14 | *.plm 15 | *.cpp 16 | 0 17 | 18 | 19 | 20 | 0 21 | 0 22 | 23 | 24 | 25 | MELP 26 | 0x4 27 | ARM-ADS 28 | 29 | 12000000 30 | 31 | 1 32 | 1 33 | 0 34 | 1 35 | 0 36 | 37 | 38 | 1 39 | 65535 40 | 0 41 | 0 42 | 0 43 | 44 | 45 | 79 46 | 66 47 | 8 48 | .\ 49 | 50 | 51 | 1 52 | 1 53 | 1 54 | 0 55 | 1 56 | 1 57 | 0 58 | 1 59 | 0 60 | 0 61 | 0 62 | 0 63 | 64 | 65 | 1 66 | 1 67 | 1 68 | 1 69 | 1 70 | 1 71 | 1 72 | 0 73 | 0 74 | 75 | 76 | 1 77 | 0 78 | 1 79 | 80 | 18 81 | 82 | 83 | 0 84 | User Manual (MCBSTM32F400) 85 | C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.4.0\MDK/Boards/Keil/MCBSTM32F400/Documentation/mcbstm32f200.chm 86 | 87 | 88 | 1 89 | Schematics (MCBSTM32F400) 90 | C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.4.0\MDK/Boards/Keil/MCBSTM32F400/Documentation/mcbstm32f400-schematics.pdf 91 | 92 | 93 | 2 94 | Getting Started (STM32F4-Discovery) 95 | C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.4.0\MDK/Boards/ST/STM32F4-Discovery/Documentation/DM00037368.pdf 96 | 97 | 98 | 3 99 | User Manual (STM32F4-Discovery) 100 | C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.4.0\MDK/Boards/ST/STM32F4-Discovery/Documentation/DM00039084.pdf 101 | 102 | 103 | 4 104 | Bill of Materials (STM32F4-Discovery) 105 | C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.4.0\MDK/Boards/ST/STM32F4-Discovery/Documentation/stm32f4discovery_bom.zip 106 | 107 | 108 | 5 109 | Gerber Files (STM32F4-Discovery) 110 | C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.4.0\MDK/Boards/ST/STM32F4-Discovery/Documentation/stm32f4discovery_gerber.zip 111 | 112 | 113 | 6 114 | Schematics (STM32F4-Discovery) 115 | C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.4.0\MDK/Boards/ST/STM32F4-Discovery/Documentation/stm32f4discovery_sch.zip 116 | 117 | 118 | 7 119 | MCBSTM32F400 Evaluation Board Web Page (MCBSTM32F400) 120 | http://www.keil.com/mcbstm32f400/ 121 | 122 | 123 | 8 124 | STM32F4-Discovery Web Page (STM32F4-Discovery) 125 | http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF252419 126 | 127 | 128 | 129 | 1 130 | 0 131 | 1 132 | 1 133 | 1 134 | 1 135 | 1 136 | 1 137 | 1 138 | 1 139 | 1 140 | 1 141 | 1 142 | 1 143 | 0 144 | 1 145 | 1 146 | 1 147 | 1 148 | 0 149 | 0 150 | 1 151 | 152 | 153 | 154 | 155 | ..\Periph.ini 156 | 157 | 158 | 159 | 160 | 161 | BIN\UL2CM3.DLL 162 | 163 | 164 | 165 | 0 166 | DLGDARM 167 | (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) 168 | 169 | 170 | 0 171 | ARMDBGFLAGS 172 | -T0 173 | 174 | 175 | 0 176 | UL2CM3 177 | UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32F4xx_512 -FL080000 -FS08000000 -FP0($$Device:STM32F407IETx$CMSIS\Flash\STM32F4xx_512.FLM) 178 | 179 | 180 | 181 | 182 | 0 183 | 0 184 | 138 185 | 1 186 |
134229010
187 | 0 188 | 0 189 | 0 190 | 0 191 | 0 192 | 1 193 | C:\Projects\Melp_float\melp.c 194 | 195 | 196 |
197 | 198 | 1 199 | 0 200 | 118 201 | 1 202 |
134228548
203 | 0 204 | 0 205 | 0 206 | 0 207 | 0 208 | 1 209 | C:\Projects\Melp_float\melp.c 210 | 211 | 212 |
213 |
214 | 215 | 216 | 1 217 | 0 218 | 0x60000000 219 | 0 220 | 221 | 222 | 223 | 0 224 | 225 | 226 | 0 227 | 1 228 | 0 229 | 0 230 | 0 231 | 0 232 | 0 233 | 1 234 | 0 235 | 0 236 | 0 237 | 0 238 | 0 239 | 0 240 | 0 241 | 0 242 | 0 243 | 0 244 | 0 245 | 1 246 | 0 247 | 0 248 | 0 249 | 0 250 | 251 | 252 | 253 |
254 |
255 | 256 | 257 | Source 258 | 0 259 | 0 260 | 0 261 | 0 262 | 263 | 1 264 | 1 265 | 1 266 | 0 267 | 0 268 | 0 269 | 0 270 | ..\..\coeff.c 271 | coeff.c 272 | 0 273 | 0 274 | 275 | 276 | 1 277 | 2 278 | 1 279 | 0 280 | 0 281 | 0 282 | 0 283 | ..\..\dsp_sub.c 284 | dsp_sub.c 285 | 0 286 | 0 287 | 288 | 289 | 1 290 | 3 291 | 1 292 | 0 293 | 0 294 | 0 295 | 0 296 | ..\..\fec_code.c 297 | fec_code.c 298 | 0 299 | 0 300 | 301 | 302 | 1 303 | 4 304 | 1 305 | 0 306 | 0 307 | 0 308 | 0 309 | ..\..\fs_lib.c 310 | fs_lib.c 311 | 0 312 | 0 313 | 314 | 315 | 1 316 | 5 317 | 1 318 | 0 319 | 0 320 | 0 321 | 0 322 | ..\..\fsvq_cb.c 323 | fsvq_cb.c 324 | 0 325 | 0 326 | 327 | 328 | 1 329 | 6 330 | 1 331 | 0 332 | 0 333 | 0 334 | 0 335 | ..\..\lpc_lib.c 336 | lpc_lib.c 337 | 0 338 | 0 339 | 340 | 341 | 1 342 | 7 343 | 1 344 | 0 345 | 0 346 | 0 347 | 0 348 | ..\..\mat_lib.c 349 | mat_lib.c 350 | 0 351 | 0 352 | 353 | 354 | 1 355 | 8 356 | 1 357 | 0 358 | 0 359 | 0 360 | 0 361 | ..\..\melp_ana.c 362 | melp_ana.c 363 | 0 364 | 0 365 | 366 | 367 | 1 368 | 9 369 | 1 370 | 0 371 | 0 372 | 0 373 | 0 374 | ..\..\melp_chn.c 375 | melp_chn.c 376 | 0 377 | 0 378 | 379 | 380 | 1 381 | 10 382 | 1 383 | 0 384 | 0 385 | 0 386 | 0 387 | ..\..\melp_sub.c 388 | melp_sub.c 389 | 0 390 | 0 391 | 392 | 393 | 1 394 | 11 395 | 1 396 | 0 397 | 0 398 | 0 399 | 0 400 | ..\..\melp_syn.c 401 | melp_syn.c 402 | 0 403 | 0 404 | 405 | 406 | 1 407 | 12 408 | 1 409 | 0 410 | 0 411 | 0 412 | 0 413 | ..\..\msvq_cb.c 414 | msvq_cb.c 415 | 0 416 | 0 417 | 418 | 419 | 1 420 | 13 421 | 1 422 | 0 423 | 0 424 | 0 425 | 0 426 | ..\..\pit_lib.c 427 | pit_lib.c 428 | 0 429 | 0 430 | 431 | 432 | 1 433 | 14 434 | 1 435 | 0 436 | 0 437 | 0 438 | 0 439 | ..\..\vq_lib.c 440 | vq_lib.c 441 | 0 442 | 0 443 | 444 | 445 | 446 | 447 | Retarget 448 | 1 449 | 0 450 | 0 451 | 0 452 | 453 | 2 454 | 15 455 | 1 456 | 0 457 | 0 458 | 0 459 | 0 460 | ..\..\ARM\Retarget.c 461 | Retarget.c 462 | 0 463 | 0 464 | 465 | 466 | 2 467 | 16 468 | 1 469 | 0 470 | 0 471 | 0 472 | 0 473 | ..\..\ARM\Serial.c 474 | Serial.c 475 | 0 476 | 0 477 | 478 | 479 | 480 | 481 | ::CMSIS 482 | 1 483 | 0 484 | 0 485 | 1 486 | 487 | 488 | 489 | ::Device 490 | 1 491 | 0 492 | 0 493 | 1 494 | 495 | 496 |
497 | --------------------------------------------------------------------------------