本次练习要求:分帧操作:
帧长160点,重叠率0.5=帧移80,意味着每一帧的数据中有80个点是新的,80个点是历史数据,这样就可以先声明一个160长度的数组,然后把数组的每一个元素初始化为0,然后每次读取文件的时候读80个点,放在数组的后80个位置,等到读取下一组数据的时候先将后面的80个点memcpy到前面80个存储位置当作历史数据,然后再新读取的80个点放在后80个点的位置作为新数据,这样就完成了每一帧数据的读取与更新。最后将每一帧读取到的数据打印到一个txt文件中验证一下。
此次程序是在PowerOfPcm.cpp基础上更改的,首先变更struct内的成员,添加了160长度的数组,在结构体内对数组初始化失败,在后续int proc_pcm_data()中引用时使用memset进行了初始化,初始化完成后使用打印语句进行了验证。初始化完成后使用memcpy和循环语句进行分帧操作,开启循环后,每一时刻数组中的数据均分为两部分,前面部分为历史数据,后面部分为新读入的数据,从而完成了重叠更新即分帧的任务。
此次代码编写过程中,首次在结构体中添加数组,后续函数中引用时类似指针。
新手学习C++,后续代码实现过程中应采用边编写边调试的方法,这样更容易知道哪里出错,哪个语句有问题。
本次代码实现如下:
// 练习分帧操作:帧长160,重叠率0.5即帧移80,将每一帧数据打印到txt文件中。
/*memcpy是内存拷贝函数,函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中,即从源source中拷贝n个
字节到目标destin中。void *memcpy(void *destin, void *source, unsigned n),destin指向用于存储复制内容的目标数组。
所需头文件:C语言:#include<string.h>,C++:#include<cstring>。source和destin所指的内存区域可能重叠,但是如果source和destin所指的内存区域
重叠,那么这个函数并不能确保source所在重叠区域在拷贝之前不被覆盖。而使用memmove可以用来处理重叠区域。如果目标数组destin本身已有数据,
执行memcpy后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到要追加数据的地址。
*/
//此次程序是在PowerOfPcm.cpp基础上更改的。
#include<stdio.h>
#include<stdlib.h>
#include<string.h> //使用memcp需添加的头文件
const int FRAMELEN = 160; //帧长160个数据
const int STEP = 80; //帧移80个数据
int i;
//定义和输入输出相关的结构体
typedef struct {
FILE *input_ptr;
FILE *output_ptr;
short array1[160]; //定义一个动态数组,用来存放每帧数据,初始化为全0,array[160]={0}在VS2008无法运行,因此在后面初始化为0
short output_data;
}pcm_data;
int open_pcm_data(pcm_data *pcm_data_ptr)
{
if(NULL == pcm_data_ptr) //地址是空的
{
return -1;
}
int err = 0;
err = fopen_s(&pcm_data_ptr->input_ptr,"origin_audio.pcm","rb");
if(0!=err)
{
return -2;
}
err = fopen_s(&pcm_data_ptr->output_ptr,"output.txt","w+");
if(0!=err)
{
return -2;
}
return 0;
}
int close_pcm_data(pcm_data *pcm_data_ptr)
{
if(NULL == pcm_data_ptr)
{
return -1;
}
fclose(pcm_data_ptr->input_ptr);
fclose(pcm_data_ptr->output_ptr);
return 0;
}
int proc_pcm_data(pcm_data *pcm_data_ptr)
{
if (NULL == pcm_data_ptr)
{
return -1;
}
memset(pcm_data_ptr->array1,0,sizeof(short)*FRAMELEN); //初始化结构体中的数组,将数组中的数所占的字节设置为0
for(i=0;i<160;i++)
{
printf("%d\n",pcm_data_ptr->array1[i]); //验证数组初始化是否正确
}
//
while (!feof(pcm_data_ptr->input_ptr))
{
/*memcpy:之前已初始化数组内元素全为0,在开启循环后某一时刻,数组中的数据包含历史数据(放在数组前80位)和更新数据
(放在数组后80位)。
*/
memcpy(pcm_data_ptr->array1,&pcm_data_ptr->array1[STEP],sizeof(short)*(FRAMELEN-STEP));
fread(&pcm_data_ptr->array1[STEP],sizeof(short),FRAMELEN-STEP,pcm_data_ptr->input_ptr);
for(i=0;i<FRAMELEN;i++)
{
fprintf(pcm_data_ptr->output_ptr,"%d,",pcm_data_ptr->array1[i]);
}
fprintf(pcm_data_ptr->output_ptr,"\n");
fflush(pcm_data_ptr->output_ptr);
}
}
int main()
{
pcm_data pcm_data;
open_pcm_data(&pcm_data);
proc_pcm_data(&pcm_data);
close_pcm_data(&pcm_data);
return 0;
}