音频节奏检测(Onset Detection)

2023-05-16

1. 前言

最近市场上出现一些多个视频拼接而成MV,其原理是根据音频的节拍变换切换视频。
我在这里讲述下如何进行音频节拍检测。


2. 音频检测一般流程

这里写图片描述

3.

3.1 原始音频频谱

以1024为窗口(即每次读取1024个采样点)进行量化

        WaveDecoder decoder = new WaveDecoder( new FileInputStream( "samples/sample.wav" ) );
        ArrayList<Float> allSamples = new ArrayList<Float>( );
        float[] samples = new float[1024];

        while( decoder.readSamples( samples ) > 0 )
        {
            for( int i = 0; i < samples.length; i++ )
                allSamples.add( samples[i] );
        }

        samples = new float[allSamples.size()];
        for( int i = 0; i < samples.length; i++ )
            samples[i] = allSamples.get(i);

        Plot plot = new Plot( "Wave Plot", 512, 512 );
        plot.plot( samples, 44100 / 1000, Color.red );

音频频谱如下:
这里写图片描述

3.2 数据预处理

(1)差值处理
差值处理是分析序列数据的基本本方法。
我们把当前窗口数据减去上一个窗口数据,得到差值数据,公式如下:
SF(k)=i=0n1s(k,i)s(k1,i)

(2)傅里叶变换
傅立叶变换将原来难以处理的时域信号转换成了易于分析的频域信号(信号的频谱),这个我就不多提了……
想了解的推荐一篇文章:
错过这篇文章,可能你这辈子不懂什么叫傅里叶变换了

   public static final String FILE = "samples/judith.mp3";  

   public static void main( String[] argv ) throws Exception
   {
      MP3Decoder decoder = new MP3Decoder( new FileInputStream( FILE  ) );                          
      FFT fft = new FFT( 1024, 44100 );
      float[] samples = new float[1024];
      float[] spectrum = new float[1024 / 2 + 1];
      float[] lastSpectrum = new float[1024 / 2 + 1];
      List<Float> spectralFlux = new ArrayList<Float>( );

      while( decoder.readSamples( samples ) > 0 )
      {         
         fft.forward( samples );
         System.arraycopy( spectrum, 0, lastSpectrum, 0, spectrum.length ); 
         System.arraycopy( fft.getSpectrum(), 0, spectrum, 0, spectrum.length );

         float flux = 0;
         for( int i = 0; i < spectrum.length; i++ )         
            flux += (spectrum[i] - lastSpectrum[i]);            
         spectralFlux.add( flux );                  
      }     

      Plot plot = new Plot( "Spectral Flux", 1024, 512 );
      plot.plot( spectralFlux, 1, Color.red );      
      new PlaybackVisualizer( plot, 1024, new MP3Decoder( new FileInputStream( FILE ) ) );
   }

处理完的频谱如下:
这里写图片描述

(3)再次差分

float flux = 0;
   for( int i = 0; i < spectrum.length; i++ )           
   {
      float value = (spectrum[i] - lastSpectrum[i]);            
      flux += value < 0? 0: value;
   }
   spectralFlux.add( flux );

这里写图片描述


4. 节拍检测(Peak Detection)

通过傅里叶变换和差分处理后的数据,基本可以看出音频节奏了,要进一步数据量化,可以采用移动均线等方法。
这部分属于时间序列数据分析的内容,具有很广泛的应用,比如金融上很多指标的基本原理也是如此。
说多了,有点跑题,我们继续……

一般音频的采样率(Sample Rate)都是44100或者48000,这里我们就以44100为例。
前文我设置窗口大小为1024:
1s包含的窗口数:44100 / 1024 = 43
一个窗口所代表的时间为:
1000 / (44100 / 1024) = 23.21ms

那么需要以0.5s为区间计算均值,需要的窗口数约为22个。这里取前10个窗口+后10个窗口计算均值。

   public static final String FILE = "samples/explosivo.mp3";   
   public static final int THRESHOLD_WINDOW_SIZE = 20;
   public static final float MULTIPLIER = 1.5f;

   public static void main( String[] argv ) throws Exception
   {
      MP3Decoder decoder = new MP3Decoder( new FileInputStream( FILE  ) );                          
      FFT fft = new FFT( 1024, 44100 );
      fft.window( FFT.HAMMING );
      float[] samples = new float[1024];
      float[] spectrum = new float[1024 / 2 + 1];
      float[] lastSpectrum = new float[1024 / 2 + 1];
      List<Float> spectralFlux = new ArrayList<Float>( );
      List<Float> threshold = new ArrayList<Float>( );

      while( decoder.readSamples( samples ) > 0 )
      {         
         fft.forward( samples );
         System.arraycopy( spectrum, 0, lastSpectrum, 0, spectrum.length ); 
         System.arraycopy( fft.getSpectrum(), 0, spectrum, 0, spectrum.length );

         float flux = 0;
         for( int i = 0; i < spectrum.length; i++ ) 
         {
            float value = (spectrum[i] - lastSpectrum[i]);
            flux += value < 0? 0: value;
         }
         spectralFlux.add( flux );                  
      }     

      for( int i = 0; i < spectralFlux.size(); i++ )
      {
         int start = Math.max( 0, i - THRESHOLD_WINDOW_SIZE );
         int end = Math.min( spectralFlux.size() - 1, i + THRESHOLD_WINDOW_SIZE );
         float mean = 0;
         for( int j = start; j <= end; j++ )
            mean += spectralFlux.get(j);
         mean /= (end - start);
         threshold.add( mean * MULTIPLIER );
      }

      Plot plot = new Plot( "Spectral Flux", 1024, 512 );
      plot.plot( spectralFlux, 1, Color.red );      
      plot.plot( threshold, 1, Color.green ) ;
      new PlaybackVisualizer( plot, 1024, new MP3Decoder( new FileInputStream( FILE ) ) );
   }

这里写图片描述

区间为10个窗口的结果如下:
这里写图片描述

Peak Dectection:

for( int i = 0; i < threshold.size(); i++ )
{
   if( threshold.get(i) <= spectralFlux.get(i) )
      prunnedSpectralFlux.add( spectralFlux.get(i) - threshold.get(i) );
   else
      prunnedSpectralFlux.add( (float)0 );
}

这里写图片描述


5. 参考文献

[1] http://www.badlogicgames.com/wordpress/?p=161
[2] 错过这篇文章,可能你这辈子不懂什么叫傅里叶变换了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

音频节奏检测(Onset Detection) 的相关文章

  • Camouflaged Object Detection

    摘要 我们对一项名为伪装物体检测 COD 的新任务进行了全面研究 xff0c 该任务旨在识别 无缝 嵌入到周围环境中的物体 目标对象与背景之间的高内在相似性使目标检测比传统的目标检测任务更具挑战性 为了解决这个问题 xff0c 我们精心收集
  • Peak Detection 算法

    文章目录 背景只有一个peak找多个Peak 主要参考 xff1a https www baeldung com cs signal peak detection 背景 最近在利用CIR估计结果进行解卷积从而抵消信道的卷积影响 xff0c
  • ALPR-License Plate Detection and Recognition in Unconstrained Scenarios阅读笔记

    xff08 1 xff09 简介 论文下载地址 xff1a License Plate Detection and Recognition in Unconstrained Scenarios pdf github 的项目地址 xff1a
  • 使用TensorFlow Object Detection API进行图像物体检测

    参考 https github com tensorflow models tree master object detection 使用TensorFlow Object Detection API进行图像物体检测 准备 安装Tensor
  • object detection资料汇总

    转自 xff1a https handong1587 github io deep learning 2015 10 09 object detection html Jump to LeaderboardPapers R CNNMulti
  • 【OpenCV】ChArUco标定板角点的检测Detection of ChArUco Corners

    opencv3 4 15源文档链接 link ChArUco标定板角点的检测 GoalSource codeCharuco板创建ChArUco板检测ChArUco姿势估计 ArUco标记和板的快速检测和多功能性是非常有用的 然而 xff0c
  • iOS 实时确定名片的角点

    我想实现像这个应用程序这样的名片检测功能 https scanbot io 相机应检测到名片并自动拍摄它的照片 仅名片 我的想法是使用BradLarson s GPUImage库 检测角点 使用 Harris 角点检测算法 计算获得的角点的
  • JavaScript 中的圆碰撞

    对于学校 我需要用 JavaScript 编写一个程序来判断圆圈是否发生碰撞 它不需要以图形方式显示 我尝试了一下 但我的代码似乎不起作用 我该如何修复它 这是我生成的代码 function collision p1x p1y r1 p2x
  • Vanilla JS Div 碰撞检测

    我的以下实现可以在jsfiddle net 我有四个div 我的目标是使它们可以在页面上拖动 但不允许它们彼此重叠 每个都可以使用 mousemove 侦听器在页面上拖动 container addEventListener mousemo
  • 为什么 pynput 不检测数字键盘按下?

    我在 Windows 7 上使用 python 3 7 有没有办法检测 pynput 模块中的数字 例如 1 按键 我尝试了很多其他模块 但除了 tkinter 之外我什么也没得到 它需要一个窗户 但我不想要那个 from pynput i
  • iOS 运动检测:运动检测灵敏度级别

    我有一个简单的问题 我正在尝试检测用户何时摇动 iPhone 我有标准代码来检测运动 这没有问题 然而 在我的实际手机上进行测试时 我意识到你必须用力摇动设备才能触发运动检测 我想知道是否有办法实施一定程度的敏感性检查 例如 一种检测用户是
  • 二维等距网格中的点击检测?

    我从事网络开发已经很多年了 我正在慢慢地参与游戏开发 对于我当前的项目 我有这个等轴测图 我需要使用算法来检测正在单击哪个字段 顺便说一句 这一切都是在浏览器中使用 Javascript 实现的 The map看起来像this https
  • Dialogflow,从音频中检测意图

    我正在尝试将音频文件发送到对话流 API 进行意图检测 我已经有一个工作得很好的代理 但只能处理文本 我正在尝试添加音频功能 但没有成功 我正在使用此页面中提供的示例 Java https cloud google com dialogfl
  • 检测复制或相似的文本块

    我有很多关于 Markdown 格式编程的文本 有一个构建过程能够将这些文本转换为 Word HTML 并执行简单的验证规则 例如拼写检查或检查文档是否具有所需的标题结构 我想扩展该构建代码以检查所有文本中的复制粘贴或类似块 是否有任何现有
  • 适用于 ASP.NET 的恶意爬虫拦截器

    我刚刚偶然发现不良行为 http www bad behavior ioerror us 一个 PHP 插件 承诺通过阻止垃圾邮件和恶意爬虫访问该网站来检测它们 ASP NET 和 ASP NET MVC 是否存在类似的东西 我感兴趣的是完
  • 如何在 Firefox for Android 中检测 Android 的版本号?

    对于网站 如果用户使用 Android 4 设备 我们希望在 Play 商店中显示链接 我们测试的所有浏览器都在其用户代理字符串中发送 Android 版本号 除了 Firefox for Android Firefox 只是发送这个 Mo
  • 播放前检测浏览器/设备是否可以内嵌播放 HTML5 视频

    我知道我可以检查一下navigator userAgent如果设备是 iPhone 但还有其他设备 其中一些我不知道哪些设备会在其自己的播放器中播放视频 可以列出所有不内联播放视频的浏览器 设备 但我想知道是否还有其他解决方案 JavaSc
  • 每个请求上的 51Degrees 重新加载会减慢 ASP.NET MVC 的速度

    添加 51Degrees 移动检测库后 我的 ASP NET MVC 3 项目速度慢得像爬行一样 51Degrees 日志文件定义为
  • 使用环境变量识别 Cygwin、Linux、Windows

    当 makefile 需要在不同的操作系统上运行并且应根据操作系统正确设置各种设置 转义 路径分隔符等 时 就会出现问题 第一种方法是使用 Windows COMSPEC ifneq COMSPEC ComSpec in windows e
  • 改进 cvFindChessboardCorners

    不幸的是 我无法找到我的问题的任何解决方案 我想做的是使用 OpenCV 方法改进结果cvFindChessboardCorners为了能够实现更好的相机校准 因为我认为这就是为什么我在不扭曲 校正图像时得到较差结果的原因 就像我之前的问题

随机推荐

  • Furmark如何进行正确的烤机?

    Furmark是一款非常不错的显卡性能以及稳定度测试软件 xff0c 通过这款软件可以快速测试出显卡的性能以及显卡是否稳定 xff0c 下面小编就来教教大家Furmark如何进行正确的烤机吧 1 打开Furmark xff0c 可以看到如图
  • WinRAR一直自动关闭怎么回事

    很多用户都习惯使用WinRAR来压缩解压文件 xff0c 但是有小伙伴跟小编反映自己的WinRAR老是一直闪退 xff0c 这是怎么回事 xff1f 下面就来看看WinRAR软件闪退的解决办法吧 Win10纯净版 Win10 64位纯净版
  • win11共享文件夹需要用户名和密码?

    在共享文件夹时提示需要用户名和密码 xff0c 这是怎么回事 xff1f 不少win11用户跟小编反映了这个问题 xff0c 我们要如何解决呢 xff1f 下面就来看看具体的win11共享文件夹需要用户名和密码的解决办法吧 win11共享文
  • win11桌面文件在哪个文件夹?

    很多win10系统用户应该都知道 xff0c 桌面文件默认存储在C xff1a Users Username Desktop文件夹中 xff0c 那升级win11之后 xff0c 桌面文件在哪个文件夹呢 xff1f 有没有改动呢 xff1f
  • win7时间总是不对怎么办?

    一般用户的主机中的主板会有一个电池 xff0c 这个电池可以给主板供电 xff0c 但是主板电池没电了的话就会将原本的时间设置清空 xff0c 因此这个时候时间就是不对的 xff0c 下面就是关于win7时间总是不对的解决方法 xff0c
  • Win10无法连接打印机怎么办?不能使用打印机的解决方法

    在我们平常的办公中 xff0c 经常会需要使用到打印机打印文件 想要使用打印机是需要先将电脑与打印机连接的 xff0c 但是有部分Win10用户遇到了无法连接打印机的情况 xff0c 对于这种情况应该如何解决呢 xff1f 下面来看看详细的
  • 【python】6DOF analyse tool

    1 result show 1 1 note 图1为3D位置 xff0c 图2 xff0c 3 xff0c 4分别表示yaw pitch xff0c roll角随着时间的变化的波动 2 code span class token comme
  • Spring入门预备知识(上)

    Spring入门主要使用了下面几个技术 xff1a 工厂模式 单例模式 动态代理模式 面向接口编程 xff0c 下面分几部分详细分析 一 xff09 工厂模式 1 定义 xff1a 定义一个用于创建对象的接口 xff0c 让子类决定实例化哪
  • 电脑丢失dll文件能一键修复吗,哪种修复方法靠谱?

    Dll文件的丢失其实是一件挺常见的事情的 xff0c 最近就有网友问小编 xff0c 关于dll文件丢失的相关问题 xff0c 他问电脑丢失dll文件能一键修复吗 xff1f 这里小编告诉你 xff0c 有方法一键修复 xff0c 但是需要
  • vcruntime140_1.dll无法继续执行代码,怎么解决这种问题?

    经常使用电脑的人 xff0c 可能对于这个弹出框应该不陌生 xff0c vcruntime140 1 dll无法继续执行代码 xff0c 其实会出现这种情况 xff0c 主要是因为缺少一个动态链接库 DLL 文件导致的 这个文件是 Visu
  • 这可能是最简单又有效的自监督学习方法了

    文 王珣 64 知乎 本文已获作者授权 xff0c 禁止二次转载 从Kaiming的MoCo和Hinton组Chen Ting的SimCLR开始 xff0c 自监督学习 xff08 SSL xff09 成了计算机视觉的热潮显学 凡是大佬大组
  • idea 2022.1 创建maven卡死解决

    1 关闭项目 2 新建maven项目 创建成功
  • FFmpeg 命令常见操作

    1 转码 ffmpeg i source mp4 ss 20 t 10 c copy my mp4 ffmpeg ss 10 t 15 accurate seek i test mp4 c a copy c v copy tt mp4 i
  • FFprobe查看&统计视频信息

    1 查看音视频信息 1 1 查看基本信息 ffprobe span class token number 1280 span x720 h264 8mbps 30fps span class token punctuation span m
  • Linux 查看文件夹大小,磁盘剩余空间(du/df)

    1 简介 du查看目录大小 xff0c df查看磁盘使用情况 2 du disk usage xff08 1 xff09 基本功能 递归查看文件夹下所有文件的大小 xff08 2 xff09 常用参数 xff1a h human reada
  • Python matplotlib高级绘图详解

    1 前言 前面我们介绍了使用matplotlib简单的绘图方法 xff08 见 xff1a Python应用matplotlib绘图简介 xff09 但是想要完全控制你的图形 xff0c 以及更高级的用法 xff0c 就需要使用 pyplo
  • ffmpeg视频精准剪切

    1 导言 ffmepg剪切视频 xff0c 很方便 xff0c 但是也有很大缺陷 xff1a xff08 1 xff09 剪切时间点不精确 xff08 2 xff09 有时剪切的视频开头有黑屏 造成这些问题的原因是ffmpeg无法seek到
  • 【python】6DOF analyse tool2

    result show 1 1 note 图1为3D X Y Z combination位置 xff0c 图4 xff0c 5 xff0c 6分别表示yaw pitch xff0c roll角随着时间的变化的波动 span class to
  • AudioChannelManipulation

    Manipulating audio channels with ffmpeg Contents stereo mono streamstereo 2 mono filesstereo 2 mono streamsmono stereo2
  • 音频节奏检测(Onset Detection)

    1 前言 最近市场上出现一些多个视频拼接而成MV xff0c 其原理是根据音频的节拍变换切换视频 我在这里讲述下如何进行音频节拍检测 2 音频检测一般流程 3 3 1 原始音频频谱 以1024为窗口 xff08 即每次读取1024个采样点