1. 根据采样定理设置好采样周期,至少大于2倍要采样的信号周期。这里以吉他6根弦为例

名称

频率(hz)
E1 329.6276
2B 246.9417
3G 195.9977
4D 146.8324
5A 110
6E 82.4069

这里最高是329.6276Hz  最低是82.4069  ,故采样周期一定要大于329.6276*2=659.2552Hz,考虑到会有比较紧的弦,频率可能会更高,这里我设置了4kHz采样周期以及8kHz采样周期,采集压电陶瓷经过运放放大后的信号,两种方案。均大于659.2552。其它信号自己类比一下,类似的。设置好ADC采样周期,这里我使用定时器设置4kH或者8khz触发ADC+DMA的形式进行采样,采样4096个点,具体配置可以自己查看别的帖子。这里主要讲算法。

2.下面进入到yin算法部分

首先在一段信号中确定一个起始点,记为Xi(这个起始点如何确定一会再说),然后在这段信号中定一段信号范围,这里可以是从前面的4096个点里的1024个点作为算法的作用范围,因为采样到的4096个点很多是无用点,或者是信号周期性不明显的点,一会再说如何找出这个需要yin处理的1024个点的范围)。

     这是单个yin的计算公式,其中Len是由Fv(一会再说这个Fv,以及如何确定len)确定的

我们的最终目标计算得出yin的序列,即:,这里可以视为一个yin序列数组,根据这一个数组就可以得出信号周期。

第一步:找出1024个有用点,以及Xi起始点的第一个点:方法思路:从4096个ADC采样点钟逐次找xi~xi+1023的方差或者是标准差,符合大于某个方差(标准差)阈值的数据则视为有效数据,方差、标准差反应了数据样本的离散程度,越大则代表信号越强,幅值越大,这个阈值需要自己确定,可以打印出来对比,以及吉他为例,我在不拨动琴弦的情况下,计算出来的方差均为100以下的数值,一但拨动了琴弦则上升到300以上,那么方差大于300的则为有效的数据。,在这段数据的第一个数则Xi的起点了。

第二步:确定Fv,以及len,以吉他为例子,根据上表我们可以大致确定一个吉他空弦可能的范围,(弦可能松也可能紧),这里我们定为,这里我们的采样率为Fs(4k或者8k),则每两个采样点之间的时间间隔为,由于len是一个变化的值,则假设Xi~X(i+len)这个间隔刚好等于信号的一个周期T,这里的话Xi-X(i+len)则得到最低值,(yin的核心思想就是找最低值),那么有,而这个T周期肯定是满足Fv频率范围的,因为周期与频率是倒数关系所以有,即

,假设采样率Fs为8000,则len的最小值为8,最大值为400,那么Yin序列内的个数就应该是400-8=393个yin数据也就是yin序列数组的大小,

 //开始yin序列for(len=8;len<=400;len++)  //计算len范围内的序列 Ylen=I到N的累加|Xi-Xi+len|  (小写为下标){        //BUGfor(i=Start_x;i<=(max2-len);i++)//累加{Yin_Seq[n]+=abs(input[i]-input[i+len]);mean++;}Yin_Seq[n]/=mean;mean=0;//    printf("%ld\n",Yin_Seq[n]);n++;}

其中input为输入的1024个有效样本,最后得出的大小为393的Yin_Seq序列数组。

假设采样率设置为4000k,(因为8k的采集波形我没有做记录,只做了4k采样率的波形图记录,这里采样率4k\8k不影响最终的结果,影响的只是精度以及yin序列数组的大小)这里拨动一下吉他空弦的6弦(频率为82.4069Hz,周期为0.0121349061789729s),采样一组数据打印,放到excel作分析,如下图所示:

可以看到在X轴的第95、143的点取得最低(Xi-X(i+len)),那么这两个点的间隔就是该弦目前的频率,143-95=48,我们的采样率是4000Hz,即为0.00025s,0.0121349061789729/0.00025=48.53962471589151,刚好吻合,其他琴弦计算方法也是一样,这里就不一一列举了。

上图的这种波形用C语言找最小值不太好找,所以甚至有可能,有一个点也是比较低的,但是相邻的却不是你想要的点,这种情况下我们可以再做多一步处理,加多一次限幅,这个限幅阈值可以自己根据打印出来的波形自己分析确定,我的思路是先排序按照升序的方法,然后找出前n个最小值,这个n自己确定。然后取平均,超过这个n的幅值则统统设为一个较大的数字,这里我设为400,限幅处理后的波形如下图所示:

怎么样,这样一来是不是就很好处理了,简单写一段代码就可以找出两个极值点的间隔了。

最后总结一下:该过程涉及到了奈奎斯特采样定理、方差(标准差)、排序、yin、限幅滤波等一系列算法,由于算法代码是用到工作上的,出于保密,不方便透露,本着互联网开放共享的原则,这里和大家分享,这里的总体思路已经非常的明朗了,可以自己写代码实现。这里不单单是可以用在音频处理上,也可以用在很多信号的处理上,具体的可以自己去研究。

Yin算法应用(单片机\嵌入式)相关推荐

  1. 【毕业设计】基于STM32 的电子计步器的设计与实现 - 物联网 单片机 嵌入式

    文章目录 1 简介 2 项目介绍 3 具体实现 3.1 整体架构 3.2 MPU6050 3.2.1 什么是MPU6050 3.2.2 MPU6050的特点: 4 如何实现记步 4.1 峰值判断记步法 ...

  2. 物联网毕设 单片机 嵌入式 题目选题推荐

    文章目录 1前言 2 如何选题 2.1 不要给自己挖坑 2.2 难度把控 2.3 如何命名题目 3 单片机 嵌入式 选题大全 3.1 嵌入式方向 3.2 算法方向 3.3 移动通信方向 3.4 学长作 ...

  3. 简单新颖的单片机 嵌入式 毕设项目

    文章目录 1前言 2 如何选题 2.1 不要给自己挖坑 2.2 难度把控 2.3 如何命名题目 3 单片机 嵌入式 选题大全 3.1 嵌入式方向 3.2 算法方向 3.3 移动通信方向 3.4 学长作 ...

  4. 单片机嵌入式二维码解码识别

    1)单片机嵌入式二维码(QRcode)生成 2)单片机嵌入式二维码(QRcode)解码 在我另一篇博客关于 "嵌入式二维码生成" 的博客里,经常会有小伙伴咨询关于单片机上做二维码解 ...

  5. 【分享】基于单片机嵌入式的家用智能节水淋浴控制器的设计-基于单片机的电子贺卡控制系统设计-基于单片机的倒计时牌控制系统设计-基于单片机的彩灯控制器系统设计-多模式彩灯-单片机的八路路数字电压表控制设计

    1334基于单片机嵌入式的家用智能节水淋浴控制器的设计-全套毕设课设设计资料 三个ds18b20分别采集进水口热水  冷水 和温水的水温,然后分别显示出来,按下开始按键,系统初始化,自动设置出水温度为 ...

  6. 使用YIN算法提取音频的F0 Contours

    使用YIN算法提取音频的F0 Contours的代码实现 简介 ​ ​ F0 Contours, 全称为Fundamental Frequency Contours, 它与Pitch Contours ...

  7. RSA算法在单片机上的一种应用

    本博客主要介绍将RSA加密算法应用到单片机编码之中的一种方法.借助单片机矩阵键盘和显示屏模块进行输入和输出操作.因本方案已经应用到省创项目中,再次只重点介绍RSA算法的应用在驱动程序中的编码以及主函数 ...

  8. DDA插补算法C语言,DDA直线插补算法在单片机上的实现基于C.doc

    DDA直线插补算法在单片机上的实现基于C /*-------------------------------*/ /*时间2011年11月*/ /*功能:DDA 插补算法在单片机上实现*/ /*作者J ...

  9. 【毕业设计】基于树莓派的智能小车设计 - 物联网 单片机 嵌入式 stm32

    文章目录 1 简介 2 实现功能 主控开发板:树莓派 电机和控制器 避障功能 3 实现效果 5 部分实现代码 6 最后 1 简介 Hi,大家好,这里是丹成学长,今天向大家介绍一个单片机项目 ** 基于 ...

最新文章

  1. 高并发场景下数据库的常见问题及解决方案
  2. linux c 取消宏定义
  3. java 上传超时_上传视频超时
  4. python读数据-如何用 Python 读取数据?
  5. 学生档案管理系统(续)
  6. Intellectual Property Essentials for Start-Ups
  7. 【Spring Boot】【Thymeleaf】The SpringStandard Dialect
  8. 【终极方法】Syntax error on tokens, delete these tokens
  9. day 05 多行输出与多行注释、字符串的格式化输出、预设创建者和日期
  10. reentrantlock原理_你必须要知道的热门 ReentrantLock 及 AQS 的实现原理
  11. C++中数组定义及初始化
  12. TCP/IP——链路层简记
  13. R语言机器学习:caret包使用及其黑箱模型解释(连续变量预测)
  14. 4.RabbitMQ实战 --- 解决Rabbit相关问题:编码与模式,RPC
  15. mysql解决端口占用
  16. Linux内核入门(七)—— 必要的编译知识
  17. c swap方法在哪个库里面_IOT操作系统用C++库的经验总结
  18. python实现登录抓取_[Python]网络爬虫(五):利用POST方式登录账号抓取
  19. 苹果充电显示不支持此配件_水果手机充电时,显示不支持此配件时的应急处理小窍门...
  20. 我的爱好作文玩计算机800,我的爱好作文800字

热门文章

  1. android区域统计,安卓版WPS教程:内置函数跨表求和统计区域销量
  2. 教你正确进入DFU及恢复模式 无敌重刷模式
  3. 关于FT和TTa引脚作为数据IO时配置问题
  4. jQuery Masonry构建pinterest网站布局注意要点(转)
  5. bad lucky :幸运的袋子
  6. 一枚FLAG普通码农辞职,回国3年的感受...
  7. Jquery easyUI datagrid遇到空行做判断
  8. BUUCTF-Pwn-jarvisoj_level2
  9. 遗传进展系列 | 1. 回归系数 相关系数 遗传力的关系
  10. 【开源探索】各种高仿网站合集