⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zp_decim.cpp

📁 音频信号降采样程序 支持48k->8k 24k->8k 8k->1k 的降采样.实现方法,先做低通滤波,再做采样点抽取.低通滤波起使用67点FIR,系数由matlab使用窗函数法生成
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ZP_Decim.cpp: implementation of the CZP_Decim class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ZP_Dsp.h"
#include "ZP_Decim.h"
#include "FIR_H.H"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//FIR_Window_fun_mathods.m wp=0.28*pi;ws=0.38*pi;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CZP_Decim::CZP_Decim()
{}

BOOL CZP_Decim::Load( char* pszFilename )
{
	fpin = fopen (pszFilename, "rb");
	if( !fpin)return( FALSE );

	fread (input_headOfWave.Riff, 1,4, fpin);
	fread (&input_headOfWave.sizeOfFile, 1, 4, fpin);

	TRACE("input_headOfWave.sizeOfFile = %d\n",input_headOfWave.sizeOfFile);
	fread (input_headOfWave.WAVEfmt, 1,8, fpin);
	fread (&input_headOfWave.sizeOfFmt, 1,4, fpin);
	fread (&input_headOfWave.wFormatTag, 1,2, fpin);
	fread (&input_headOfWave.nChannels, 1,2, fpin);
	fread (&input_headOfWave.nSamplesPerSec, 1,4, fpin);
	fread (&input_headOfWave.navgBytesPerSec, 1,4, fpin);
	fread (&input_headOfWave.nBlockAlign, 1,2, fpin);
	fread (&input_headOfWave.nBitPerSample, 1,2, fpin);
	fread (input_headOfWave.Cdata, 1,4, fpin);
	fread (&input_headOfWave.sizeOfData, 1, 4, fpin);

	return 0;
}



BOOL CZP_Decim::Write( char* pszFilename, int Decimation_RATE )
{
	fpout = fopen( pszFilename, "wb" );
	if( !fpout )
		return( FALSE );

	fwrite( input_headOfWave.Riff, 1, 4, fpout );
	input_headOfWave.sizeOfFile = input_headOfWave.sizeOfData + 36;
	fwrite( &input_headOfWave.sizeOfFile, 1, 4, fpout );
	fwrite( input_headOfWave.WAVEfmt, 1, 8, fpout );
	fwrite( &input_headOfWave.sizeOfFmt, 1, 4, fpout );
	fwrite( &input_headOfWave.wFormatTag, 1, 2, fpout );
	fwrite( &input_headOfWave.nChannels, 1, 2, fpout );
	input_headOfWave.nSamplesPerSec = input_headOfWave.nSamplesPerSec / Decimation_RATE;
	TRACE("input_headOfWave.nSamplesPerSec = %d\n",input_headOfWave.nSamplesPerSec);
	fwrite( &input_headOfWave.nSamplesPerSec, 1, 4, fpout );
	input_headOfWave.navgBytesPerSec = input_headOfWave.nSamplesPerSec * 2;
	fwrite( &input_headOfWave.navgBytesPerSec, 1, 4, fpout );
	fwrite( &input_headOfWave.nBlockAlign, 1, 2, fpout );
	fwrite( &input_headOfWave.nBitPerSample, 1, 2, fpout );
	fwrite( input_headOfWave.Cdata, 1, 4, fpout );
	input_headOfWave.sizeOfData = ny * sizeof( short );
	fwrite( &input_headOfWave.sizeOfData, 1, 4, fpout );
		
	return 0;
}


//六倍抽取函数
//输入"文件名"    48k
//输出"8k_文件名"  8k
void CZP_Decim::CZP_Decim_6_File( char* aInFlNm )
{	
	short aIncx[FRM_LEN] = { 0 },
			aOutcx[FRM_LEN] = { 0 };
	double aIndb[FRM_LEN] = { 0 },
			aOutdb[FRM_LEN] = { 0 };
	double x[FRM_LEN+BUF_LEN] = { 0 },
			y[FRM_LEN+BUF_LEN] = { 0 },
			y_half[FRM_LEN + BUF_LEN] = { 0 },
			y_half_third[FRM_LEN + BUF_LEN] = { 0 };
	int ixbgn = 0,
		iybgn = 0,
		x_num = 0, y_num = 0, 
		ixDcRn = 0,
		iyDcRn = 0,
		i = 0,
		deci_num;
	char aOutFlNm[40] = "48kTo8k\\";
	int data_remain;
	
	strcat( aOutFlNm, aInFlNm );


	///////////打开输入文件,读文件头
	Load( aInFlNm );
	nx = input_headOfWave.sizeOfData / sizeof( short );//16位,单通道
	ny = nx / 6;//Decimation_RATE;

	int Decimation_RATE = 6;
	Write( aOutFlNm, Decimation_RATE );

	//分Frame降采样
	data_remain = nx;		

	ixbgn = 0;//从的0帧的第0个数据开始抽样
	iybgn = 0;//从的0帧的第0个数据开始抽样
	while( data_remain > FRM_LEN )//
	{	fread( aIncx, sizeof( short ), FRM_LEN, fpin );
		for( x_num = 0; x_num < FRM_LEN; x_num++ )
		{	x[x_num + BUF_LEN] = ( double ) aIncx[x_num];//初始化x后FRM_LEN个数据点
		}
		deci_num = 2;
		ixDcRn = decimation_buffer_and_frame
			( x, BUF_LEN + FRM_LEN, h_1, H1_Length, BUF_LEN, y_half, deci_num, &ixbgn);
		for( y_num = 0; y_num < ixDcRn; y_num++ )//中间
		{	y[y_num+BUF_LEN] = ( double )y_half[y_num];//初始化y后ixDcRn个数据点
		}
		deci_num = 3;
		iyDcRn = decimation_buffer_and_frame
			(y, BUF_LEN+ixDcRn, h_2, H2_Length, BUF_LEN, y_half_third, deci_num, &iybgn);

		for(x_num=0;x_num<BUF_LEN;x_num++)
		{	x[x_num]=(double)aIncx[FRM_LEN-BUF_LEN+x_num];//初始化x前BUF_LEN个数据点
		}
		for(x_num=0;x_num<BUF_LEN;x_num++)
		{	y[x_num]=(double)y_half[ixDcRn-BUF_LEN+x_num];//初始化y前BUF_LEN个数据点
		}

		data_remain=data_remain-FRM_LEN;

		/////////写输出wav文件数据
		for(y_num=0;y_num<iyDcRn;y_num++)
		{	aOutcx[y_num]=(short) y_half_third[y_num];
		}
		fwrite (aOutcx, sizeof(short), iyDcRn, fpout);////写输出wav文件数据
	}
	{//处理不够一zhen的数据 data_remain < FRM_LEN
		fread (aIncx, sizeof(short), data_remain, fpin);
		for(x_num=0;x_num<data_remain;x_num++)
		{	x[x_num+BUF_LEN]=(double)aIncx[x_num];//初始化x后FRM_LEN个数据点
		}
		deci_num = 2;
		ixDcRn=decimation_buffer_and_frame
			(x,BUF_LEN+data_remain,h_1,H1_Length,BUF_LEN,y_half,deci_num,&ixbgn);
		for(y_num=0;y_num<ixDcRn;y_num++)//中间
		{	y[y_num+BUF_LEN]=(double)y_half[y_num];//初始化y后ixDcRn个数据点
		}
		deci_num = 3;
		iyDcRn=decimation_buffer_and_frame
			(y,BUF_LEN+ixDcRn,h_2,H2_Length,BUF_LEN,y_half_third,deci_num,&iybgn);

		for(x_num=0;x_num<BUF_LEN;x_num++)
		{	x[x_num]=(double)aIncx[FRM_LEN-BUF_LEN+x_num];//初始化x前BUF_LEN个数据点
		}
		for(x_num=0;x_num<BUF_LEN;x_num++)
		{	y[x_num]=(double)y_half[ixDcRn-BUF_LEN+x_num];//初始化y前BUF_LEN个数据点
		}

		data_remain=data_remain-data_remain;


		/////////写输出wav文件数据
		for(y_num=0;y_num<iyDcRn;y_num++)
		{	aOutcx[y_num]=(short) y_half_third[y_num];
		}
		fwrite (aOutcx, sizeof(short), iyDcRn, fpout);////写输出wav文件数据
	}
	fclose(fpin);
	fclose(fpout);
}


//卷积 多项滤波器
int CZP_Decim::decimation_buffer_and_frame
	(double x[],int BUFFER_and_FRM_LEN,double Trans[],int h_Length,int bufferlength,double y[],int deci_num,int *begin_dec_n)
{
	int chouqu_jieguo_num=0,i=0;
	for(chouqu_jieguo_num=0;*begin_dec_n+bufferlength+chouqu_jieguo_num*deci_num<BUFFER_and_FRM_LEN;chouqu_jieguo_num++)
	{//计算
		y[chouqu_jieguo_num] = 0;
		for(i =0;i<h_Length;i++)//卷积
		{	y[chouqu_jieguo_num] =
				y[chouqu_jieguo_num]+Trans[i]*x[*begin_dec_n+bufferlength+chouqu_jieguo_num*deci_num-i];
		}
	}
	*begin_dec_n =(*begin_dec_n+bufferlength+chouqu_jieguo_num*deci_num)-BUFFER_and_FRM_LEN;
	return chouqu_jieguo_num;

}






int CZP_Decim::FIR(double x[],int BUFFER_and_FRM_LEN,double Trans[],int h_Length,int bufferlength,double y[],int deci_num,int *begin_dec_n)
{int chouqu_jieguo_num=0,i=0;
	for(chouqu_jieguo_num=0;*begin_dec_n+bufferlength+chouqu_jieguo_num*deci_num<BUFFER_and_FRM_LEN;chouqu_jieguo_num++)
	{//计算
		y[chouqu_jieguo_num] = 0;
		for(i =0;i<h_Length;i++)//卷积
		{	y[chouqu_jieguo_num] =
				y[chouqu_jieguo_num]+Trans[i]*x[*begin_dec_n+bufferlength+chouqu_jieguo_num*deci_num-i];
		}
	}
	return 0;
}



CZP_Decim::~CZP_Decim()
{
}




void CZP_Decim::CZP_Decim_8_File(char *aInFlNm)
{

	short aIncx[FRM_LEN]={0},aOutcx[FRM_LEN]={0};
	double aIndb[FRM_LEN]={0},aOutdb[FRM_LEN]={0};
	double x[FRM_LEN+BUF_LEN]={0},z[FRM_LEN+BUF_LEN]={0},
			y[FRM_LEN+BUF_LEN]={0},
			y_half[FRM_LEN+BUF_LEN]={0},
			y_half_third[FRM_LEN+BUF_LEN]={0},
			z_half_third[FRM_LEN+BUF_LEN]={0};
	int ixbgn=0,//x_begin_dec_n
		iybgn=0,//y_begin_dec_n
		izbgn=0,//y_begin_dec_n
		x_num=0, y_num=0, z_num=0,
		ixDcRn=0, //x_chouqu_jieguo_num
		iyDcRn=0, //iyDcRn
		izDcRn=0, //izDcRn
		i =0,deci_num;
	char aOutFlNm[40]="8kTo1k\\";
	strcat(aOutFlNm,aInFlNm);

	int data_remain;//剩下的还未处理的数据长度

	///////////打开输入文件,读文件头
	Load(aInFlNm);
	nx = input_headOfWave.sizeOfData/sizeof(short);//16位,单通道
	ny = nx/8;//Decimation_RATE;

	int Decimation_RATE = 8;
	Write(aOutFlNm,Decimation_RATE);


	//分Frame降采样

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -