上一篇博客中,我们已经介绍了根据PCM解析出的数据绘制全部的波形图,但这样有一个缺点,就是很丑,而且和我们日常听音乐看到的波形图也不一样,我们在听音乐时的波形图时动态震荡的,跟随音乐抖动,很有feel的,接下来我们来介绍如何实现这一点。
之前我们在绘制波形图采用的是循环拿出PCM中的数据传入OpenGL进行绘制,而要实现动态显示,这一点必须改变,我们需要将PCM中解析出的数据保存起来,实现方法是解析出数据存入数组中:
//PCM文件数据解码保存到数组中
void fileOutput()
{
short pcm_In = 0;
int size = 0;
FILE *fp = fopen(OLD_FILE_PATH, "rb+"); //为读写打开一个二进制文件 即pcm文件
while(!feof(fp))
{
size = fread(&pcm_In, 2, 1, fp); //pcm中每个数据大小为2字节,每次读取1个数据
if(size>0)
{
//-------------------------------------------------------------------------------------------------------------------------
vertices.push_back((float)pcm_In/10000);
}
}
fclose(fp);
}
动态显示的思路:为数组设置两个迭代器指针,istart指向每次绘制图形时数据的起点,iend指向每次绘制图形时所取数据的终点,每次图形绘制结束之后,将两个指针向后移动若干位,刷新页面,再次绘制,直到iend指向数据【即数组】的最后一位时,停止绘制。代码如下:
void drawLint()
{
glClearColor (0.8, 0.8, 0.8, 0.8);
glClear (GL_COLOR_BUFFER_BIT);
glLineWidth(2);//设置线段宽度
glBegin(GL_LINES);
glColor3f(0.6,0.6,0.6);
float temp = 0.0;
float xstart=-1.0;
float xend=-1.0;
//testing-------------------------------------------------------------------------------------------------------------------
//绘制波形图
for(vector<float>::iterator it = istart; it != iend; it++ ) //用迭代器的方式输出容器对象的值
{
xstart=xstart+0.0033;
xend=xstart+0.0033;
glVertex2f(xstart,temp);
glVertex2f(xend,*it);
temp = *it;
}
//进行下一次绘制的起点和终点
istart+=6; //通过更改每次前进的数字可以实现波形振动频率的改变
iend+=6;
glEnd();
}
运行结果:
完成项目代码地址:https://github.com/xiaobooo/OpenGL/tree/master/CODE/Test