一种音频频谱动画柔和展现算法的制作方法

文档序号:11198884阅读:387来源:国知局
一种音频频谱动画柔和展现算法的制造方法与工艺

本发明涉及进度条显示技术领域,具体说是一种音频频谱动画柔和展现算法。



背景技术:

在android中,自定义控件,主要包括两类:

第一类,组合自定义控件,是指使用系统提供的各种界面控件,通过自定义封装成包括多个系统控件的自定义控件,代码在内部处理各子控件的交互,简化使用。

第二类,自绘制控件,是指通过继承系统提供的各种界面控件,在控件的测量、布局、绘制三个方法中,使用代码进行测量、绘制、处理交互事件的自定义控件。自绘制控件能提供比系统控件更新颖的界面、更丰富的交互方式。

频谱动画多在录音或播放音频时展示,通常是通过安卓自带的visualizer类,获得频谱信息,得到一个byte数组。然后把这个byte数组转换成point数组,最后再根据这个point数组绘制点,就行了。但这种现有频谱动画显示效果缺乏美感,功能单一,人机交互过程有待进一步完善。

在播放音频时还会在交互界面给出进度条,并且可以通过拖动进度条实现播放进度的相应控制。进度条通常是在独立的区域进行显示,同样也是功能单一,人机交互过程有待进一步完善。



技术实现要素:

针对现有技术中存在的缺陷,本发明的目的在于提供一种音频频谱动画柔和展现算法,把频谱数据更新频率间隔与绘制的间隔进行插值匹配,在100毫秒的数据更新间隔中,实现三次绘制,绘制时分段变化频谱数据,实现动画的柔和展现。

为达到以上目的,本发明采取的技术方案是:

一种音频频谱动画柔和展现算法,其特征在于,包括如下步骤:

外部播放器回调接口,通过updatevisualizer方法把频谱数据传入,以进行频谱数据更新;

使用cacheffts数组,分别从传入的频谱数据中,获取左右声道中频率变化最丰富一端的指定数量的频谱数据,

在cacheffts数组中,把右声道频谱数据追加到左声道频谱数据后面,形成一组频谱数据;

判断速度数组mspeeds是否已存在,

如不存在,则创建速度数组mspeeds,

如已存在,则复用速度数组mspeeds;

使用cacheffts数组中的频谱数据,与在二次更新频谱数据前插值的次数相除,所述相除计算使用3次,其满足:设计在100ms的更新间隔中,每33毫秒插入频谱动画一次,得到以下参数:

频谱数据中新的对应频谱数据,

要想从上一次频谱数据,变化到新的频谱数据,所需要的速度,存入速度数组mspeeds;

当计算好cacheffts数组和速度数组mspeeds后,启动异步绘制循环调用。

在上述技术方案的基础上,所述频谱数据参数格式为float数组,左右声道的频谱数据,通过fft_left和fft_right二个数组传入。

在上述技术方案的基础上,频谱数据传入后,updatevisualizer方法进行以下判断:

首先判断当前是否在停止绘制状态下,是在停止绘制状态下,则忽略本次频谱数据更新,

然后判断当前是否在暂停动画状态下,是在暂停动画状态下,则忽略本次频谱数据更新,

再后判断当前是否在插入柔和绘制频谱变化循环状态下,是在插入柔和绘制频谱变化循环状态下,则忽略本次频谱数据更新。

在上述技术方案的基础上,所述指定数量至少为32个。

在上述技术方案的基础上,所述异步绘制循环调用使用runnable进行,通过updatevisualizer方法进行第一次启动调用后,此runnable会使用速度数组mspeeds中的各位置速度,去与cacheffts数组中的各位置频谱数据,进行相加处理,数据更新后,调用绘制命令,同时判断自已循环次数是否到达,不到达再次异步启动自己定时调用。

本发明所述的音频频谱动画柔和展现算法,把频谱数据更新频率间隔与绘制的间隔进行插值匹配,在100毫秒的数据更新间隔中,实现三次绘制,绘制时分段变化频谱数据,实现动画的柔和展现。整个方案具有以下优点:

1、实现了频谱展现与进度条功能结合统一,具有占用空间小,进度条变化与频谱动画和谐统一的优点。

2、频谱动画使用贝赛尔曲线,间隔采样频谱数据,绘制两条贝赛尔曲线,两条曲线通过填充渐变色,使用颜色混合绘制模式,两条线条叠加创建了丰富的频谱展现效果。

3、使用自创算法,把频谱的傅里叶变换数组数据,转换为绘制所需要的屏幕坐标数据,再把屏幕坐标数据使用贝赛尔曲线显示出来。

4、使用自创算法,把频谱数据更新频率间隔与绘制的间隔进行插值匹配,在100毫秒的数据更新间隔中,实现三次绘制,绘制时分段变化频谱数据,实现动画的柔和展现。

5、经过优化数据的计算及图形生成算法,可高效转换频谱数据为曲线图形并定时随数据变化,从而形成随频谱变动的动画效果。

附图说明

本发明有如下附图:

图1本发明的流程图。

具体实施方式

以下结合附图对本发明作进一步详细说明。

如图1所示,本发明所述的音频频谱动画柔和展现算法,包括如下步骤:

步骤1,基于view控件,自定义新的控件类mprogress,在构造函数处增加初始化方法;

其中自定义新的控件类mprogress包括:

创建频谱绘制使用的path对象wavepath,并设置相应参数,所述参数至少包括频谱数组容量等参数,

创建频谱变换使用缓存数组对象cacheffts,

创建两条贝赛尔曲线绘制使用的paint对象mforepaint1,mforepaint2,

创建进度条绘制变量max、min、value,三个变量分别表示进度条最大值、最小值、当前值,所述自定义新的控件类mprogress使用这三个变量的换算值表示播放进度,

其中初始化方法包括:

初始化按键操作步进单位值,表示按键一次,变化多少;

初始化进度条背景绘制用paint对象lingbgpaint,

初始化进度条进度绘制用paint对象progresspaint,

初始化进度条缓冲绘制用paint对象secondpaint。

步骤2,进行频谱数据的接收、变换,准备好频谱绘制用图形对象,启动异步绘制循环调用;

具体步骤如下:

步骤2.1,外部播放器回调接口,通过updatevisualizer方法把频谱数据传入,以进行频谱数据更新,

所述频谱数据参数格式为float数组,左右声道的频谱数据,通过fft_left和fft_right二个数组(频谱数组)传入;

步骤2.2,updatevisualizer方法进行以下判断:

首先判断当前是否在停止绘制状态下,是在停止绘制状态下,则忽略本次频谱数据更新,

然后判断当前是否在暂停动画状态下,是在暂停动画状态下,则忽略本次频谱数据更新,

再后判断当前是否在插入柔和绘制频谱变化循环状态下,是在插入柔和绘制频谱变化循环状态下,则忽略本次频谱数据更新,

上述三个忽略条件,都是为了提高控件自绘制效率;

步骤2.3,上述三个忽略条件都不满足,则:使用cacheffts数组,分别从传入的频谱数据(fft_left和fft_right二个数组)中,获取左右声道中频率变化最丰富一端的指定数量的频谱数据,所述指定数量至少为32个,

所述fft_left和fft_right二个数组,是外部播放器已经经过转换的512容量数组,但其中只有一半是有效数据(频谱数据),另一半是镜像数据(镜像频谱数据),所以这里根据绘制效果,只取其一端指定数量(32个)频谱数据,

例如:

左声道数组的取其最后面的32个频谱数据,

右声道数组的取其最前面的32个频谱数据;

步骤2.4,在cacheffts数组中,把右声道频谱数据追加到左声道频谱数据后面,形成一组频谱数据;

如步骤2.3所举示例,指定数量为32个时,在cacheffts数组中就保存了64个频谱数据;

步骤2.5,判断速度数组mspeeds是否已存在,

如不存在,则创建速度数组mspeeds,

如已存在,则复用速度数组mspeeds;

步骤2.6,使用cacheffts数组中的频谱数据,与在二次更新频谱数据前插值的次数相除,所述相除计算使用3次,其满足:设计在100ms的更新间隔中,每33毫秒插入频谱动画一次,得到以下参数:

频谱数据中新的对应频谱数据,

要想从上一次频谱数据,变化到新的频谱数据,所需要的速度,存入速度数组mspeeds;

例如:上一次频谱数组[0]是30,现在更新的对应频谱数组[0]的值是60,则计算速度既为10,表示从30向上变化到60,变化3次,则每次变化速度为10;

更进一步,为防止一些频谱数据的突变,对速度做了最低速度与最高速度限制,当计算所得速度不符合限制时,强制降低或提高速度;

步骤2.7,当计算好cacheffts数组(步骤2.4,频谱数据数组)和速度数组mspeeds(步骤2.6)后,启动异步绘制循环调用;

所述异步绘制循环调用使用runnable进行,通过updatevisualizer方法进行第一次启动调用后,此runnable会使用速度数组mspeeds中的各位置速度,去与cacheffts数组中的各位置频谱数据,进行相加处理(速度有正有负),数据更新后,调用绘制命令,同时判断自已循环次数是否到达,不到达再次异步启动自己定时调用;

步骤3,进度条控件变化,通过外部播放器的回调,通过对setprogress(设置第一进度)、setsecondprogress(设置第二进度)的设定(设置)进行进度更新,

或者:通过ontouchevent函数,通过用户在控件上点击或触摸,改变progress(进度,例如当前播放进度)的位置;

具体说:

在ontouchevent方法中,首先判断当前触摸操作类型,

如果是action_down(按下)操作,则:记录当前按钮位置的x坐标,同时判断用户所按下的位置,是否在进度条当前进度的滑块范围内,如果是滑块范围内,标记为拖动模式,如果不是在滑块范围内,则标记为点击跳转模式;

在接收到action_move(移动)操作时,则:action_down操作中如果已经是拖动模式,则进行拖动更新progress操作,如果不是拖动模式,则判断用户当前滑动距离,是否达到拖动判断距离,如果达到,则启动拖动模式,并进行拖动更新progress操作(拖动更新progress值);

在接收到action_up(松开)操作时,则:action_down操作中如果不是拖动模式,则处理为点击跳转,把progress值设置为当前点击并抬起的x坐标处,实现progress值的变换;

同时复位触摸相关模式、变量值;

在onkeydown方法中,首先获取当前progress值,根据用户按钮的向左或向右的按钮,更新progress值为初始化时计算的步进单位值,如果达到最大或最小则不变;

步骤4,通过复写ondraw方法,实现频谱数据与进度条数据的绘制;具体步骤为:

步骤4.1,调用view的ondraw父绘制方法,把设置的背景绘制显示;

步骤4.2,判断当前是否是暂停状态,暂停状态下,直接返回只绘制背景;非暂停状态下,开始分层绘制频谱动画和进度条;

步骤4.3,通过cacheffts数组,进行频谱贝塞尔曲线绘制:

首先计算绘制基线basex和频谱可绘制最大高度值height,复位wavepath的内部数据,首先通过循环,获取cacheffts数组中的偶数位置的频谱数据,经过坐标x、y的计算,使用wavepath的quadto函数,增加到wavepath中保存为贝塞尔曲线绘制点;

其中:

x坐标是根据所绘制频谱数组数量与控件宽度可绘制区域平均等分得到,

y坐标则通过控件的高度减去cacheffts中频谱数据的值得到;

循环结束后,把最后的贝塞尔坐标与最开始的点通过调用close方法,进行直线封闭;

调用canvas对象(canvas类),首先保存当前状态,然后调用drawpath方法,把wavepath通过mforepaint1画笔绘制到界面;

步骤4.4,wavepath进行复位,再从头循环频谱数组cacheffts,获取其奇数位置的频谱数据,通过quadto转换为path数据保存到wavepath中,最后通过canvas的drawpath方法,使用mforepaint2画笔绘制到界面上;

步骤4.5,通过调用canvas的restore方法恢复canvas状态;

步骤4.6,通过进度条相关变量值,绘制缓冲进度与播放进度;

缓冲进度是一条细小线条,位于频谱数据动画和整个控件的底部,使用canvas的drawline方法绘制;

播放进度是一个二端有小横线的竖线,通过计算mthumbrect的值,调用canvas的drawline函数进行绘制;

所述mthumbrect指滑块区域,在绘制上,进度条是一个竖线,但用户触摸拖动,如果响应区域是竖线的话,99%的情况是点不到的,所以在这时,会在竖线为中心,设置一个触摸区域,点到这个矩形里,都认为是点到竖线的这个滑块上;

步骤5,停止频谱动画,通过设置一个统一的速度为2,然后以频谱数组中,是否还有哪些索引下频谱数据大于0为条件,循环进行频谱数组中的频谱数据去减速度2,然后调用ondraw进行绘制,直到cacheffts数组中所有位置的频谱数据都为0,则循环停止;

此时频谱动画中,频谱贝塞尔曲线表现就是缓慢下落结束。

本说明书中未作详细描述的内容属于本领域专业技术人员公知的现有技术。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1