项目代码下载

https://download.csdn.net/download/weixin_43865690/39129840

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)差值处理

差值处理是分析序列数据的基本本方法。
我们把当前窗口数据减去上一个窗口数据,得到差值数据,公式如下:

(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) );elseprunnedSpectralFlux.add( (float)0 );
}

5. 参考文献

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

项目代码下载

https://download.csdn.net/download/weixin_43865690/39129840

音频节奏检测(Onset Detection)相关推荐

  1. 音符起始点检测(音频节奏检测)(6)

    原文链接:Onset Detection Part 6: Onsets & Spectral Flux 在之前的一篇文章中,我从科学的角度讨论了起点/节拍检测.有很多不同的方案可以不同程度的做 ...

  2. 音符起始点检测(音频节奏检测)(1)

    原文链接:Onset Detection Part 1: The Basics 在这篇文章中,我想开始一个小的循序渐进的系列,它将允许您为您的音乐游戏需求构建自己的起始点检测器(onset detec ...

  3. 音符起始点检测(音频节奏检测)(5)

    原文链接:Onset Detection Part 5: The (Discrete) Fourier Transform 警告:这是我理解离散傅里叶变换的方法,在一些地方可能是错误的.对于傅里叶变换 ...

  4. 音符起始点检测(音频节奏检测)(4.5)

    原文链接:Onset Detection Part 4.5: What to expect (这篇文章没大翻译明白,建议阅读原文.大概内容就是在展示自制检测器对各种类型音乐的检测效果,以及和 audi ...

  5. 音符起始点检测(音频节奏检测)(7)

    原文链接:Onset Detection Part 7: Thresholding & Peak picking 在上一篇文章中,我们看到了如何将一个随着时间的推移而演化为一个简单一维函数的复 ...

  6. 音符起始点检测(音频节奏检测)(2)

    原文链接:Onset Detection Part 2: A simple framework 好了,我刚刚为我们的起始点检测入门教程组合了一个简单的框架.它位于 http://code.google ...

  7. excel 棒球数据游戏_使用librosa的棒球应用的音频发作检测数据准备

    excel 棒球数据游戏 介绍 (Introduction) I wish to build a deep learning project for a baseball application, o ...

  8. 行人检测(Pedestrian Detection)资源

    行人检测(Pedestrian Detection)资源 原文链接 http://hi.baidu.com/susongzhi/item/085983081b006311eafe38e7 一.论文 C ...

  9. [caffe]深度学习之CNN检测object detection方法摘要介绍

    [caffe]深度学习之CNN检测object detection方法摘要介绍  2015-08-17 17:44 3276人阅读 评论(1) 收藏 举报 一两年cnn在检测这块的发展突飞猛进,下面详 ...

最新文章

  1. 【学习笔记】高斯整数、高斯素数、费马平方和(全部相关概念及例题详解)《初等数论及其应用》
  2. MethodBase.GetCurrentMethod 方法
  3. javaEE开发问题整理(1)
  4. python legb_Python变量作用域LEGB用法解析
  5. oracle 删除时间段的,oracle SQL如何从日期中删除时间
  6. c语言命名规则_C语言的基本数据类型及变量
  7. Linux 系统的运行级别(Run Level)
  8. 文档比较比对工具Beyond Compare
  9. DM***+GET***测试
  10. Atitit rdmng 研发管理重要的领域 目录 第一章 编程语言 1 第一节 Dsl 1 第二章 编程方法与理念 通用化vs 专用化 1 第一节 动态化 1 第三章 框架与工具 通用vs专用
  11. 01 GOF设计模式的定义和分类
  12. 15 款MacBook Pro扩容之旅
  13. Hbase 二级索引
  14. ORACLE drop user时遇到的ORA-00604和ORA-00942错误排查
  15. AP5126 DC/DC 平均电流型 降压恒流驱动芯片
  16. 网盘修复版新增qq支付仿城通网盘115网盘源码下载
  17. 浏览器的储存方式有哪些
  18. Mybatis错误 Result Maps collection already contains value for xxx
  19. 使用BurpSuite对IOS客户端app抓包方法
  20. 国产FPGA市场分析 该如何破局

热门文章

  1. Exponial欧拉降幂
  2. angular.js:13920 Error: [$injector:unpr] Unknown provider: $scopeProvider - $scope - testServe
  3. 进入计算机管理模板,计算机管理个人简历模板
  4. python 魔法方法诠释
  5. TTL expired in transit
  6. 服务器灾备解决方案--两地三中心(图文详解)
  7. 计算机图形学-走样与反走样
  8. 带南海九段线分位数地图可视化(R语言版)
  9. android计算器开源小项目代码(附安装包.apk)
  10. 微信公众平台开发最佳实践(第2版)