今天只看一个函数xcorr_kernal_c,它的位置位于pitch.h里。这个函数是用于计算两个函数的相关性的,然后输出到长度为4的数组里。

定义如下

void xcorr_kernel_c(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[4], int len)

入参x和y是两个用于计算的函数x和函数y。

长度为4的sum数组是输出的xcorr值。长度定义为4应该是方便后面计算,这个后面再找对应的证据。

len是计算互相关性计算数值的长度。一般来说,x长度为N,y的长度应该为N+3,那么建议的len=N.   3实际上是lag值。

函数源码如下

static OPUS_INLINE void xcorr_kernel_c(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[4], int len)
{int j;opus_val16 y_0, y_1, y_2, y_3;celt_assert(len>=3);y_3=0; /* gcc doesn't realize that y_3 can't be used uninitialized */y_0=*y++;y_1=*y++;y_2=*y++;for (j=0;j<len-3;j+=4){opus_val16 tmp;tmp = *x++;y_3=*y++;sum[0] = MAC16_16(sum[0],tmp,y_0);sum[1] = MAC16_16(sum[1],tmp,y_1);sum[2] = MAC16_16(sum[2],tmp,y_2);sum[3] = MAC16_16(sum[3],tmp,y_3);tmp=*x++;y_0=*y++;sum[0] = MAC16_16(sum[0],tmp,y_1);sum[1] = MAC16_16(sum[1],tmp,y_2);sum[2] = MAC16_16(sum[2],tmp,y_3);sum[3] = MAC16_16(sum[3],tmp,y_0);tmp=*x++;y_1=*y++;sum[0] = MAC16_16(sum[0],tmp,y_2);sum[1] = MAC16_16(sum[1],tmp,y_3);sum[2] = MAC16_16(sum[2],tmp,y_0);sum[3] = MAC16_16(sum[3],tmp,y_1);tmp=*x++;y_2=*y++;sum[0] = MAC16_16(sum[0],tmp,y_3);sum[1] = MAC16_16(sum[1],tmp,y_0);sum[2] = MAC16_16(sum[2],tmp,y_1);sum[3] = MAC16_16(sum[3],tmp,y_2);}if (j++<len){opus_val16 tmp = *x++;y_3=*y++;sum[0] = MAC16_16(sum[0],tmp,y_0);sum[1] = MAC16_16(sum[1],tmp,y_1);sum[2] = MAC16_16(sum[2],tmp,y_2);sum[3] = MAC16_16(sum[3],tmp,y_3);}if (j++<len){opus_val16 tmp=*x++;y_0=*y++;sum[0] = MAC16_16(sum[0],tmp,y_1);sum[1] = MAC16_16(sum[1],tmp,y_2);sum[2] = MAC16_16(sum[2],tmp,y_3);sum[3] = MAC16_16(sum[3],tmp,y_0);}if (j<len){opus_val16 tmp=*x++;y_1=*y++;sum[0] = MAC16_16(sum[0],tmp,y_2);sum[1] = MAC16_16(sum[1],tmp,y_3);sum[2] = MAC16_16(sum[2],tmp,y_0);sum[3] = MAC16_16(sum[3],tmp,y_1);}
}

其中

#define MAC16_16(a,x,y) (a)+((x)*(y)) 

该函数源码部分不长,总体来看的思路是这样的。

假设两个函数的值对应如下

x = a b c d
y = 1 2 3 4 5 6 7

输入len=4,那么sum的值如下计算

sum[0]=1a + 2b + 3c + 4d

sum[1]=2a + 3b + 4c + 5d

sum[2]=3a + 4b + 5c + 6d

sum[3]=4a + 5b + 6c + 7d

整个计算流程可以用图来表示,

第一轮计算是用x[0]即a和y[0:3],用黑色线条表示

第一轮计算是用x[1]即b和y[1:4],用蓝色线条表示

第三轮计算是用x[2]即c和y[2:5],用绿色线条表示

第四轮计算是用x[3]即d和y[3:6],用黄色线条表示

怎么理解整个算法呢?

我们假设x的函数为下图

假设y的函数为下图

那么cross correlation就是将y函数图像从左向右滑向x函数,并求过程中的重合部分面积。(准确说应该不是面积,应该是重合部分的运算累加)

1. 首先两个函数保持距离,y开始向x靠近

2. y和x开始产生重合,右移的过程可以看作是一段y的值和某一个固定的x的值做运算,即体现出算法中的图示。

3. y和x的重合部分越多,表示越具有相关性。但是该算法的输出是长度为4的数组。可以理解这些重复的部分的值被压缩到这个数组中。

从另一方面来看,求correlation的过程跟求卷积是类似的。

【opus源码分析】【互相关函数源码分析】xcorr_kernal_c相关推荐

  1. 老李推荐:第5章5节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 获取系统服务引用 1...

    老李推荐:第5章5节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 获取系统服务引用 上一节我们描述了monkey的命令处理入口函数run是如何调用optionPro ...

  2. 手机自动化测试:Appium源码分析之跟踪代码分析四 1

    手机自动化测试:Appium源码分析之跟踪代码分析四 控制器模块 // Appium webserver controller methods // https://github.com/hugs/a ...

  3. 【原创】【专栏】《Linux设备驱动程序》--- LDD3源码目录结构和源码分析经典链接

    http://blog.csdn.net/geng823/article/details/37567557 [原创][专栏]<Linux设备驱动程序>--- LDD3源码目录结构和源码分析 ...

  4. 【Linux 内核】进程管理 ( 进程相关系统调用源码分析 | fork() 源码 | vfork() 源码 | clone() 源码 | _do_fork() 源码 | do_fork() 源码 )

    文章目录 一.fork 系统调用源码 二.vfork 系统调用源码 三.clone 系统调用源码 四._do_fork 函数源码 五.do_fork 函数源码 Linux 进程相关 " 系统 ...

  5. 【Android 热修复】热修复原理 ( 类加载分析 | 分析 PathClassLoader 源码 | 分析 BaseDexClassLoader 源码 | 分析 PathDexList 源码 )

    文章目录 一.分析 PathClassLoader 源码 二.分析 BaseDexClassLoader 源码 三.分析 PathDexList 源码 四. 源码资源 一.分析 PathClassLo ...

  6. 【Android 电量优化】JobScheduler 源码分析 ( JobServiceContext 源码分析 | 闭环操作总结 | 用户提交任务 | 广播接收者接受相关广播触发任务执行 )★

    文章目录 一.JobServiceContext 引入 二.JobServiceContext 源码分析 三.用户在应用层如何使用 JobScheduler 四.用户提交任务 五.广播接收者监听广播触 ...

  7. 老李推荐:第6章1节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览 1...

    老李推荐:第6章1节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览 在上一章中我们有简要的介绍了事件源是怎么一回事,但是并没有进行详细的描述.那么往下的这几个 ...

  8. kafka源码分析之一server启动分析

    0. 关键概念 关键概念 Concepts Function Topic 用于划分Message的逻辑概念,一个Topic可以分布在多个Broker上. Partition 是Kafka中横向扩展和一 ...

  9. Android源码分析--MediaServer源码分析(二)

    在上一篇博客中Android源码分析–MediaServer源码分析(一),我们知道了ProcessState和defaultServiceManager,在分析源码的过程中,我们被Android的B ...

  10. android6.0源码分析之Camera2 HAL分析

    1.Camera HAL的初始化 Camera HAL的初始加载是在Native的CameraService初始化流程中的,而CameraService初始化是在Main_mediaServer.cp ...

最新文章

  1. nginx log response_python+pandas分析nginx日志的实例
  2. 安装Zabbix过程中出现的问题集
  3. Linkis1.0下载地址
  4. boost::mp11::mp_set_push_front相关用法的测试程序
  5. Android平台发展史
  6. 160 - 45 Dope2112.2
  7. [css] 举例说明跟字体相关的属性有哪些
  8. 实现Linux系统的回收站
  9. linux视图版怎么输入命令,分享在Linux命令下操作MySQL视图实例代码
  10. Android ADB 用法
  11. 一个人开长途车旅游安全吗?
  12. Windows下用FFmpeg+nginx+rtmp搭建直播环境 实现推流、拉流
  13. 万年历插件软件测试,万年历的程序代码
  14. matlab伴随矩阵怎么表示,怎样用Matlab求矩阵的伴随矩阵
  15. 教学向|如何快速入门maya制作动画,萌新也能冲
  16. Android新浪微博登录
  17. 【车间调度】帝国企鹅算法求解柔性车间调度问题【含Matlab源码 1991期】
  18. wamp mysql_WampServer 下载以及安装问题 以及配置远程连接MYSQL
  19. 搭档之家:哭唧唧!暗地较劲得不偿失,美团暂停支付宝后被无情反超
  20. 【Linux】使用私人服务器搭建qq机器人

热门文章

  1. Nat. Commun. | 机器学习在化学发现中的应用
  2. J. Cheminform. | 基于SMILES的利用骨架的分子生成模型
  3. pymatgen读/写各种文件
  4. Linux下安装搜狗拼音
  5. http android下载工具,Android实现下载工具的简单代码
  6. matlab科学计算及分析,matlab科学计算
  7. php嵌入html还是html嵌入php,php嵌入html有哪几种方法
  8. 灯泡亮度控制单片机_南航电赛-灯光控制系统
  9. 在线作图|2分钟在线绘制三维CCA图
  10. JCP:曝气生物滤池处理焦化废水过程中N2O和NO的产生机理与群落功能研究