近期工程需要对音频数据进行保存处理,本来想采用环来节省空间,后来发现写指针移动覆盖之前的数据时,读指针的位置太难判断,干脆采用队列的模式,将前面不需要得数据移除,给后边的写指针腾出空间,如此便可保留一定长度数据,且不需管理太多空间操作。想要实现数据的前移操作自然用到了memmove()函数,本来以为数据量如果达到百万级可能会影响效率问题,后来测试了一下,发现处理时间在毫秒级内,所以不用担心了。以下附代码,以及测试图。
memmove()函数
函数原型:void *memmove(void *dest, const void *source, size_t count)
返回值说明:返回指向dest的void *指针
参数说明:dest,source分别为目标串和源串的首地址。count为要移动的字符的个数
函数说明:memmove用于从source拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。
附代码
头文件:
#ifndef _CYCQUEDATA_H_
#define _CYCQUEDATA_H_
#include <string>
class CycQueData
{
public:
CycQueData(int m_size);
~CycQueData(void);
void Add(char*data,int len); //添加数据
void Save();
void Print();
private:
int m_totsize;//总长度
int m_Windex;//数据头
char* m_Audio;
};
#endif
,cpp
#include "CycQueData.h"
#include <time.h>
#include <Windows.h>
CycQueData::CycQueData(int m_size)
{
m_Audio = new char[m_size];
memset(m_Audio,0,m_size);
m_Windex = 0; //写指针
m_totsize = m_size;
}
CycQueData::~CycQueData(void)
{
delete[] m_Audio;
return;
}
void CycQueData::Add(char*data,int len)
{
if((m_Windex+len)<=m_totsize) //数据不移动直接拷贝
{
memcpy(m_Audio+m_Windex,data,len);
m_Windex+=len;
}
else
{
DWORD start = GetTickCount();
int overlen = (m_Windex+len)-m_totsize;//超出部分长度
int curindex = m_totsize-len; //当前指针应当指向位置
//数据移动
memmove(m_Audio, m_Audio + overlen, m_totsize-overlen);//前移腾出空间给超出部分数据
memcpy(m_Audio+curindex,data,len);
DWORD end = GetTickCount();
printf("time: %d\n", end-start) ;
}
return;
}
void CycQueData::Print()//打印显示
{
int m = 0;
printf("当前数据:\n");
while(m<m_totsize)
{
printf("%c ",m_Audio[m]);
m++;
}
printf("\n");
return;
}
测试文件:
#define MAX_D 88200*20
int main()
{
//char buf[] = {'A','B','C','D','E'};
char* buf = new char [MAX_D];
for(int i = 0;i<MAX_D;i++)
{
buf[i] = 'A';
}
CycQueData audio(MAX_D);
audio.Add(buf,MAX_D);
//audio.Print();
audio.Add(buf,MAX_D/2);//移动一半数据
//audio.Print();
getchar();
return 0;
}
运行截图:
总结:
执行效率在毫秒级内,可以满足一般使用需求,所以可以不用太在乎效率问题。