📄 converttog723data.cpp
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include ".\HeadH\Head.h"
#include ".\Filter\16to8.h"
extern FSDEF fs;
int InitOutFileHead( dataHEAD filehead, FILE *fp_SpeechOut, unsigned short TotalNumSentence);
int Codec_G723( char *tmpFileIn, char *Dir_Current );
//把给定输入语音文件中的16k采样语音转换为通过G.723编解码之后的8k采样语音,并写入输出文件
//入口参数:FILE *fp_SpeechIn 输入语音文件的指针
// FILE *fp_SpeechOut 输出语音文件的指针
// char *Dir_Current 本程序( SpeechViaG723 )所在的目录
int ConvertToG723Data( FILE *fp_SpeechIn, FILE *fp_SpeechOut, char *Dir_Current )
{
FILE *fp_in, *fp_out;
FILE *fp_tmpIn = NULL, *fp_tmpOut = NULL;
// char str_tmp[_MAX_PATH];
long ltemp;
// long i;
//------------------语音输入文件所需变量-------------------//
dataHEAD filehead;//记录文件头信息
unsigned short TotalNumSentence; //语音文件的总句子数
unsigned short nSentence;//循环计数用
long SentenceLength;//句子长度Bytes
unsigned long DataStart;//语音数据在binary输出文件中的起始地址
short *VoiceData_Short = NULL;//语音数据
//------------------语音输出文件所需变量-------------------//
short *VoiceData_Filtered = NULL;//滤波后的语音数据
// short *VoiceData_AfterG723 = NULL;//G.723 编解码后的语音数据
long SentenceLength_Filtered;//滤波后的句子长度Bytes
// long SentenceLength_AfterG723;//过 G.723 之后的句子长度Bytes
long DataOutStart;//语音数据在binary输出文件中的起始地址
fp_in = fp_SpeechIn;
fp_out = fp_SpeechOut;
//读入语音文件的头
fread( &filehead, sizeof(dataHEAD), 1,fp_in );
//-----------------------读出语音文件中一共有多少句话--------------------//
//在863数据中,第199,200字节并没有标识出该文件中总共有多少句话,
//但是其索引区后紧接数据区,所以从第一个索引的值就可以推算出总共有多少句话
fseek( fp_in, 200,SEEK_SET );
fread( <emp, sizeof(long), 1, fp_in );//第一个索引的值
TotalNumSentence = (short)( (ltemp-200)/(2*sizeof(long)) );//每个索引有8个字节:2个long
//若不是863数据,还有一种格式是每个文件有 >= 1000 句话的索引区
//这种情况在198字节应该有句子数
if( TotalNumSentence >= 1000 )
{
fseek( fp_in, 198, SEEK_SET );
fread( &TotalNumSentence, sizeof(short), 1, fp_in );
}
printf( "一共%d句话\n", TotalNumSentence );
//-------------------------------修改文件头-----------------------------//
strcpy( filehead.ParameterType,"16to8" );
filehead.SampleType = 2;//在文件头中定义数据类型(1=char;2=short;3=long;4=float;5=double)
//写文件头到binary输出文件,并初始化索引区
InitOutFileHead( filehead, fp_out, TotalNumSentence);
//一句语音数据滤波之后的位置,初值是数据区的起始位置
DataOutStart = 200 + TotalNumSentence*sizeof(long)*2;
//初始化滤波器
initialfilter();
//按句读入语音,并作处理
for( nSentence = 0; nSentence < TotalNumSentence; nSentence++){
printf( "第%d句\b\r", nSentence);
//从第(nSentence)句话的索引区读出该句话语音数据的首地址(DataStart)及总的字节数(SentenceLength)
fseek( fp_in, 200+2*sizeof(long)*nSentence, SEEK_SET );
fread( &DataStart, sizeof(long), 1, fp_in );
fread( &SentenceLength, sizeof(long), 1, fp_in );
//分配语音内存
VoiceData_Short = ( short * ) malloc ( SentenceLength );
SentenceLength_Filtered = SentenceLength/2;
VoiceData_Filtered = ( short * ) malloc ( SentenceLength_Filtered );
//将第(nSentence)句话的语音数据读入内存VoiceData_Short
fseek( fp_in, DataStart, SEEK_SET );
fread( VoiceData_Short, SentenceLength, 1, fp_in );
//----------------------16k->8k,滤波-----------------------//
//滤波前对本句所需变量做初始化初始化
initial_sentence();
//FIR滤波器函数
for (long i = 0; i < SentenceLength/2; i++ )
VoiceData_Short[i]=Filter(VoiceData_Short[i], fs.B,fs.x,numFilter);
//抽取函数
for ( i = 0; i < SentenceLength_Filtered/2; i++ )
downsample_16_to_8_one_sentence( VoiceData_Short, VoiceData_Filtered, &fs.j);
//将第(nSentence)句滤波后的语音写入输出文件
//写当前句(第nSentence句)的索引区
fseek( fp_out, 200+sizeof(long)*2*nSentence, SEEK_SET);
fwrite( &DataOutStart, sizeof(long), 1, fp_out );//本句开始的位置
fwrite( &SentenceLength_Filtered, sizeof(long), 1, fp_out );//本句的长度
//写当前句的语音数据
fseek( fp_out, 0, SEEK_END);
fwrite( VoiceData_Filtered, 1, SentenceLength_Filtered, fp_out );//这句话的转换后语音
DataOutStart += SentenceLength_Filtered;//下一句数据输出的起始位置
/*
//----------------------G.723编解码--------------------------//
//产生中间文件,把一句滤波后的语音写入中间文件
sprintf( str_tmp, "%s\\tmp\\tmpIn.dat", Dir_Current);
fp_tmpIn = fopen( str_tmp, "wb+" );
if( fp_tmpIn == NULL ){
perror("Temp In File open error!\n");
exit(1);
}
fwrite( VoiceData_Filtered, 1, SentenceLength_Filtered, fp_tmpIn );
fclose( fp_tmpIn );
Codec_G723( "tmpIn.dat", Dir_Current );
printf( "第%d句\b\r", nSentence);
//----------------------codec over--------------------------//
sprintf( str_tmp, "%s\\tmp\\tmpOut.dat", Dir_Current);
fp_tmpOut = fopen( str_tmp, "rb" );
if( fp_tmpOut == NULL ){
perror("Temp Out File open error!\n");
exit(1);
}
//Compute the file length
fseek( fp_tmpOut, 0L, SEEK_END ) ;
SentenceLength_AfterG723 = ftell( fp_tmpOut ) ;
//从 tmpOut.dat 中编解码后的语音读入,准备写入输出文件里
fseek( fp_tmpOut, 0L, SEEK_SET );
VoiceData_AfterG723 = ( short * ) malloc ( SentenceLength_AfterG723 );
fread( VoiceData_AfterG723, SentenceLength_AfterG723, 1, fp_tmpOut );
fclose( fp_tmpOut );
//将第(nSentence)句编解码后的语音写入输出文件
//写当前句(第nSentence句)的索引区
fseek( fp_out, 200+sizeof(long)*2*nSentence, SEEK_SET);
fwrite( &DataOutStart, sizeof(long), 1, fp_out );//本句开始的位置
fwrite( &SentenceLength_AfterG723, sizeof(long), 1, fp_out );//本句的长度
//写当前句的语音数据
fseek( fp_out, 0, SEEK_END);
fwrite( VoiceData_AfterG723, 1, SentenceLength_AfterG723, fp_out );//这句话的转换后语音
DataOutStart += SentenceLength_AfterG723;//下一句数据输出的起始位置
*/
//释放内存
if( VoiceData_Short != NULL ){
free( VoiceData_Short );
VoiceData_Short = NULL;
}
if( VoiceData_Filtered != NULL ){
free( VoiceData_Filtered );
VoiceData_Filtered = NULL;
}
/* if( VoiceData_AfterG723 != NULL ){
free( VoiceData_AfterG723 );
VoiceData_AfterG723 = NULL;
}
*/ }
return 0;
}
//写文件头到binary输出文件,并初始化索引区
int InitOutFileHead( dataHEAD filehead, FILE *fp_out, unsigned short TotalNumSentence)
{
long ltemp = 0, i;
long Length_index;//binary输出文件中索引区长度
if( !fp_out ){
perror("OutputFile not open!\n");
exit(1);
}
//-----------------------写文件头到binary输出文件,并初始化索引区------------------//
//前196个字节
fwrite( &filehead, sizeof(dataHEAD), 1, fp_out);
//第197,198字节放空
fwrite( <emp, sizeof(char), 2, fp_out);
//第199,200字节写入总共有多少句子
fwrite( &TotalNumSentence, sizeof(short), 1, fp_out);
//计算binary输出文件中索引区长度
Length_index = TotalNumSentence*sizeof(long)*2;//bytes
//计算每句索引的位置(bytes),这里获得初始值
//对输出文件的句子索引区进行初始化,随便写
for( i = 0; i < Length_index; i++ )
fwrite( <emp, sizeof(char), 1, fp_out);
return 0;
}
/*
//G.723编解码
int Codec_G723( char *tmpFileIn, char *Dir_Current )
{
char cInstruction[500];
//把编解码命令行写入 cInstruction
sprintf( cInstruction, "%s\\G723_fixedpoint -b -r53 -v %s\\tmp\\%s %s\\tmp\\tmpOut.dat > .\\tmp\\intermedia", Dir_Current, Dir_Current, tmpFileIn, Dir_Current );
system( cInstruction );
return 0;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -