ten-vad / src /pitch_est_st.h
Ziyi Lin
ONNX open source and license terms update
b50f2a2
//
// Copyright © 2025 Agora
// This file is part of TEN Framework, an open source project.
// Licensed under the Apache License, Version 2.0, with certain conditions.
// Refer to the "LICENSE" file in the root directory for more information.
//
#ifndef __PITCH_EST_ST_H__
#define __PITCH_EST_ST_H__
#include <stdio.h>
#include "pitch_est.h"
#define AUP_PE_ALIGN8(o) (((o) + 7) & (~7))
#define AUP_PE_MAX(x, y) (((x) > (y)) ? (x) : (y))
#define AUP_PE_MIN(x, y) (((x) > (y)) ? (y) : (x))
#define AUP_PE_NB_BANDS (18) // number of mel bands
#define AUP_PE_LPC_ORDER (16)
#define AUP_PE_XCORR_TRAINING_OFFSET (80) // = 80
#define AUP_PE_MIN_PERIOD_16KHZ (32) // stands for 1.333kHz, PITCH_MIN_PERIOD
#define AUP_PE_MAX_PERIOD_16KHZ (256) // stands for ~62Hz, PITCH_MAX_PERIOD
#define AUP_PE_LOWPSS_NSEC (5)
const float AUP_PE_B_2KHZ[AUP_PE_LOWPSS_NSEC][3] = {
{1.000000e+00f, -1.303155e-01f, 1.000000e+00f},
{1.000000e+00f, -1.563002e+00f, 1.000000e+00f},
{1.000000e+00f, -1.759739e+00f, 1.000000e+00f},
{1.000000e+00f, -1.811650e+00f, 1.000000e+00f},
{1.000000e+00f, -1.827332e+00f, 1.000000e+00f}};
const float AUP_PE_A_2KHZ[AUP_PE_LOWPSS_NSEC][3] = {
{1.000000e+00f, -1.726800e+00f, 7.526543e-01f},
{1.000000e+00f, -1.762977e+00f, 8.277960e-01f},
{1.000000e+00f, -1.802014e+00f, 9.079320e-01f},
{1.000000e+00f, -1.828423e+00f, 9.594240e-01f},
{1.000000e+00f, -1.846774e+00f, 9.888390e-01f}};
const float AUP_PE_G_2KHZ[AUP_PE_LOWPSS_NSEC] = {
2.156619e-01f, 2.156619e-01f, 2.156619e-01f, 2.156619e-01f, 2.156619e-01f};
const float AUP_PE_B_4KHZ[AUP_PE_LOWPSS_NSEC][3] = {
{1.000000e+00f, 1.198825e+00f, 1.000000e+00f},
{1.000000e+00f, -5.674614e-01f, 1.000000e+00f},
{1.000000e+00f, -1.099061e+00f, 1.000000e+00f},
{1.000000e+00f, -1.265846e+00f, 1.000000e+00f},
{1.000000e+00f, -1.318849e+00f, 1.000000e+00f}};
const float AUP_PE_A_4KHZ[AUP_PE_LOWPSS_NSEC][3] = {
{1.000000e+00f, -1.445267e+00f, 5.463974e-01f},
{1.000000e+00f, -1.426720e+00f, 6.820138e-01f},
{1.000000e+00f, -1.408255e+00f, 8.286664e-01f},
{1.000000e+00f, -1.400909e+00f, 9.240320e-01f},
{1.000000e+00f, -1.408242e+00f, 9.789776e-01f}};
const float AUP_PE_G_4KHZ[AUP_PE_LOWPSS_NSEC] = {
2.692541e-01f, 2.692541e-01f, 2.692541e-01f, 2.692541e-01f, 2.692541e-01f};
const float AUP_PE_B_8KHZ[AUP_PE_LOWPSS_NSEC][3] = {
{1.000000e+00f, 1.830863e+00f, 1.000000e+00f},
{1.000000e+00f, 1.039654e+00f, 1.000000e+00f},
{1.000000e+00f, 4.900788e-01f, 1.000000e+00f},
{1.000000e+00f, 2.419292e-01f, 1.000000e+00f},
{1.000000e+00f, 1.517919e-01f, 1.000000e+00f}};
const float AUP_PE_A_8KHZ[AUP_PE_LOWPSS_NSEC][3] = {
{1.000000e+00f, -8.445478e-01f, 2.453003e-01f},
{1.000000e+00f, -5.469711e-01f, 5.010509e-01f},
{1.000000e+00f, -2.646897e-01f, 7.464574e-01f},
{1.000000e+00f, -1.074159e-01f, 8.912371e-01f},
{1.000000e+00f, -4.448528e-02f, 9.702184e-01f}};
const float AUP_PE_G_8KHZ[AUP_PE_LOWPSS_NSEC] = {
4.165686e-01f, 4.165686e-01f, 4.165686e-01f, 4.165686e-01f, 4.165686e-01f};
#define AUP_PE_PI (3.1415926f)
#define AUP_PE_FEAT_TIME_WINDOW (40) // in ms
// how much time data to use for cross-correlation calculation
#define AUP_PE_FEAT_MAX_NFRM (12)
#define AUP_PE_TOTAL_NFEAT (55)
#define AUP_PE_ASSUMED_FFT_4_BAND_ENG (80)
const int AUP_PE_BAND_START_INDEX[AUP_PE_NB_BANDS] = {
// 0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40};
// compensation
const float AUP_PE_BAND_LPC_COMP[AUP_PE_NB_BANDS] = {
0.8f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 0.666667f,
0.5f, 0.5f, 0.5f, 0.333333f, 0.25f, 0.25f, 0.2f, 0.166667f, 0.173913f};
#define AUP_PE_PITCHMAXPATH_W (0.02f)
typedef struct PE_St_ {
void* dynamMemPtr; // memory pointer holding the dynamic memory
size_t dynamMemSize; // size of the buffer *dynamMemPtr
// void* ifftStHdl; // AgoraFft*
void* biquadIIRPtr;
// ---------------------------------------------------------------
// Static Configuration
PE_StaticCfg stCfg;
// ---------------------------------------------------------------
// Internal Static Config Registers, which are generated from stCfg
int nBins;
int procResampleRate; // AUP_PE_FS / stCfg.procFs
int minPeriod; // min. pitch period in procFs
int maxPeriod; // max. pitch period in procFs
int difPeriod; // maxPeriod - minPeriod
int inputResampleBufLen; // length of the resampling output buffer
int inputQLen; // MAX(TRAINING_OFFSET_XXXX, hopSz) + hopSz
int excBufLen; // PITCH_MAX_PERIOD + hopSz + 1
int nFeat; // number of feature frames to use/store
int estDelay; // pitch estimate delay in terms of frames
float dct_table[AUP_PE_NB_BANDS *
AUP_PE_NB_BANDS]; // coeff. table of DCT transformation
// ---------------------------------------------------------------
// Dynamic Configuration
PE_DynamCfg dynamCfg;
// ---------------------------------------------------------------
// Internal Dynamic Config Registers, which are generated from dynamCfg
// ---------------------------------------------------------------
// Variables
/////////////////////////////////////////////////////////////////////////
float* inputResampleBuf; // [inputResampleBufLen]
int inputResampleBufIdx;
float* inputQ; // [inputQLen]
float* alignedIn; // [hopSz]
float* lpcFilterOutBuf; // [hopSz]
float* excBuf; // [excBufLen]
// excBuf stores the smoothed LPC prediction result
float* excBufSq; // [excBufLen]
// = excBuf.^2
float lpc[AUP_PE_LPC_ORDER];
float pitch_mem[AUP_PE_LPC_ORDER];
float pitch_filt;
float tmpFeat[AUP_PE_TOTAL_NFEAT];
int xCorrOffsetIdx; // the oldest frame's index in xCorr Buffer
float* xCorrInst; // [maxPeriod]
float* xCorr[AUP_PE_FEAT_MAX_NFRM * 2]; // [stHdl->nFeat * 2][maxPeriod + 1]
// circ-buffer [<--->][...]
float*
xCorrTmp[AUP_PE_FEAT_MAX_NFRM * 2]; // [stHdl->nFeat * 2][maxPeriod + 1]
// temporarily modified version of xCorr
float frmWeight[AUP_PE_FEAT_MAX_NFRM * 2];
float frmWeightNorm[AUP_PE_FEAT_MAX_NFRM * 2];
// normalized version of frmWeight
// variables for best pitch estimation ....
/////////////////////////////////////////////////////////////////////////
float* pitchMaxPathReg[2]; // [2][maxPeriod]
int* pitchPrev[AUP_PE_FEAT_MAX_NFRM * 2]; // [stHdl->nFeat * 2][maxPeriod]
float pitchMaxPathAll;
int bestPeriodEst;
int voiced; // whether this frame has voice
float pitchEstResult; // the final result storing the estimated pitch freq.
} PE_St;
#endif // __PITCH_EST_ST_H__