Java实现Shazam声音识别算法的实例代码

Shazam算法采用傅里叶变换将时域信号转换为频域信号,并获得音频指纹,最后匹配指纹契合度来识别音频。

1、AudioSystem获取音频

奈奎斯特-香农采样定理告诉我们,为了能捕获人类能听到的声音频率,我们的采样速率必须是人类听觉范围的两倍。人类能听到的声音频率范围大约在20Hz到20000Hz之间,所以在录制音频的时候采样率大多是44100Hz。这是大多数标准MPEG-1 的采样率。44100这个值最初来源于索尼,因为它可以允许音频在修改过的视频设备上以25帧(PAL)或者30帧( NTSC)每秒进行录制,而且也覆盖了专业录音设备的20000Hz带宽。所以当你在选择录音的频率时,选择44100Hz就好了。

定义音频格式:

  public static float sampleRate = 44100;
  public static int sampleSizeInBits = 16;
  public static int channels = 2; // double
  public static boolean signed = true; // Indicates whether the data is signed or unsigned
  public static boolean bigEndian = true; // Indicates whether the audio data is stored in big-endian or little-endian order
  public AudioFormat getFormat() {
    return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,
        bigEndian);
  }

调用麦克风获取音频,保存到out中

 public static ByteArrayOutputStream out = new ByteArrayOutputStream();1
    try {
      AudioFormat format = smartAuto.getFormat(); // Fill AudioFormat with the settings
      DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
      startTime = new Date().getTime();
      System.out.println(startTime);
      SmartAuto.line = (TargetDataLine) AudioSystem.getLine(info);
      SmartAuto.line.open(format);
      SmartAuto.line.start();
      new FileAnalysis().getDataToOut("");
      while (smartAuto.running) {
        checkTime(startTime);
      }
      SmartAuto.line.stop();
      SmartAuto.line.close();
    } catch (Throwable e) {
      e.printStackTrace();
    }

获取到的out数据需要通过傅里叶变换,从时域信号转换为频域信号。

傅里叶变换

public Complex[] fft(Complex[] x) {
    int n = x.length;
    // 因为exp(-2i*n*PI)=1,n=1时递归原点
    if (n == 1){
      return x;
    }
    // 如果信号数为奇数,使用dft计算
    if (n % 2 != 0) {
      return dft(x);
    }
    // 提取下标为偶数的原始信号值进行递归fft计算
    Complex[] even = new Complex[n / 2];
    for (int k = 0; k < n / 2; k++) {
      even[k] = x[2 * k];
    }
    Complex[] evenValue = fft(even);
    // 提取下标为奇数的原始信号值进行fft计算
    // 节约内存
    Complex[] odd = even;
    for (int k = 0; k < n / 2; k++) {
      odd[k] = x[2 * k + 1];
    }
    Complex[] oddValue = fft(odd);
    // 偶数+奇数
    Complex[] result = new Complex[n];
    for (int k = 0; k < n / 2; k++) {
      // 使用欧拉公式e^(-i*2pi*k/N) = cos(-2pi*k/N) + i*sin(-2pi*k/N)
      double p = -2 * k * Math.PI / n;
      Complex m = new Complex(Math.cos(p), Math.sin(p));
      result[k] = evenValue[k].add(m.multiply(oddValue[k]));
      // exp(-2*(k+n/2)*PI/n) 相当于 -exp(-2*k*PI/n),其中exp(-n*PI)=-1(欧拉公式);
      result[k + n / 2] = evenValue[k].subtract(m.multiply(oddValue[k]));
    }
    return result;
  }

计算out的频域值

 private void setFFTResult(){
    byte audio[] = SmartAuto.out.toByteArray();
    final int totalSize = audio.length;
    System.out.println("totalSize = " + totalSize);
    int chenkSize = 4;
    int amountPossible = totalSize/chenkSize;
    //When turning into frequency domain we'll need complex numbers:
    SmartAuto.results = new Complex[amountPossible][];
    DftOperate dfaOperate = new DftOperate();
    //For all the chunks:
    for(int times = 0;times < amountPossible; times++) {
      Complex[] complex = new Complex[chenkSize];
      for(int i = 0;i < chenkSize;i++) {
        //Put the time domain data into a complex number with imaginary part as 0:
        complex[i] = new Complex(audio[(times*chenkSize)+i], 0);
      }
      //Perform FFT analysis on the chunk:
      SmartAuto.results[times] = dfaOperate.fft(complex);
    }
    System.out.println("results = " + SmartAuto.results.toString());
  }

总结

以上所述是小编给大家介绍的Java实现Shazam声音识别算法的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Java进阶教程之运行时类型识别RTTI机制

    运行时类型识别(RTTI, Run-Time Type Identification)是Java中非常有用的机制,在Java运行时,RTTI维护类的相关信息. 多态(polymorphism)是基于RTTI实现的.RTTI的功能主要是由Class类实现的. Class类 Class类是"类的类"(class of classes).如果说类是对象的抽象和集合的话,那么Class类就是对类的抽象和集合. 每一个Class类的对象代表一个其他的类.比如下面的程序中,Class类的对象c1代

  • java识别一篇文章中某单词出现个数的方法

    本文实例讲述了java识别一篇文章中某单词出现个数的方法.分享给大家供大家参考.具体如下: 1. java代码: import java.io.DataInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.StringTokenizer; import java.util.regex.Matche

  • Java基于直方图应用的相似图片识别实例

    本文实例讲述了Java实现基于直方图应用的相似图片识别,是非常实用的技巧.分享给大家供大家参考.具体分析如下: 一.算法概述: 首先对源图像与要筛选的图像进行直方图数据采集,对采集的各自图像直方图进行归一化再使用巴氏系数算法对直方图数据进行计算,最终得出图像相似度值,其值范围在[0, 1]之间 0表示极其不同,1表示极其相似(相同). 二.算法步骤详解: 大致可以分为两步,根据源图像与候选图像的像素数据,生成各自直方图数据.第二步:使用第一步输出的直方图结果,运用巴氏系数(Bhattachary

  • java网络编程之识别示例 获取主机网络接口列表

    获取主机地址信息 在Java中我们使用InetAddress类来代表目标网络地址,包括主机名和数字类型的地址信息,并且InetAddress的实例是不可变的,每个实例始终指向一个地址.InetAddress类包含两个子类,分别对应两个IP地址的版本: 复制代码 代码如下: Inet4AddressInet6Address 我们通过前面的笔记可以知道:IP地址实际上是分配给主机与网络之间的连接,而不是主机本身,NetworkInterface类提供了访问主机所有接口的信息的功能.下面我们通过一个简

  • java asp分析各种搜索引擎的关键字,自动识别url 中关键字的编码

    所以必须要通过编码后的关键字,例如"解析关键字编码"在google里面输入搜索,得到编码后的"%E8%A7%A3%E6%9E%90%E5%85%B3%E9%94%AE%E5%AD%97%E7%BC%96%E7%A0%81" 1.从以上地址中解析出关键字部分. 2.通过编码后的关键字获取编码时的编码名称(如:gbk,utf-8等等) 3.用URLdecode(keywords,encodeCode)来解码得到对应的关键字. 以下是java代码的实现: 复制代码 代码如

  • Java实现Shazam声音识别算法的实例代码

    Shazam算法采用傅里叶变换将时域信号转换为频域信号,并获得音频指纹,最后匹配指纹契合度来识别音频. 1.AudioSystem获取音频 奈奎斯特-香农采样定理告诉我们,为了能捕获人类能听到的声音频率,我们的采样速率必须是人类听觉范围的两倍.人类能听到的声音频率范围大约在20Hz到20000Hz之间,所以在录制音频的时候采样率大多是44100Hz.这是大多数标准MPEG-1 的采样率.44100这个值最初来源于索尼,因为它可以允许音频在修改过的视频设备上以25帧(PAL)或者30帧( NTSC

  • Java编程基于快速排序的三个算法题实例代码

    快速排序原理简介 快速排序是我们之前学习的冒泡排序的升级,他们都属于交换类排序,都是采用不断的比较和移动来实现排序的.快速排序是一种非常高效的排序算法,它的实现,增大了记录的比较和移动的距离,将关键字较大的记录从前面直接移动到后面,关键字较小的记录从后面直接移动到前面,从而减少了总的比较次数和移动次数.同时采用"分而治之"的思想,把大的拆分为小的,小的拆分为更小的,其原理如下:对于给定的一组记录,选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,

  • Java实现AES算法的实例代码

    使用AES算法可用于对数据进行加密码与解密,使用的时候需要注意两点:1)被加密的串越长,加密后的字符串越长,注意数据库字段的设计:2)Linux与Windows环境中可能会出现由于环境差异导致在Windows中测试成功,到Linux上后加密的串无法被正确解密.下列算法已在真实环境中进行实测,应用时也务必做好二次验证避免出现线上事故. private static final String ALGORITHM_NAME = "AES"; //加密因子,可根据您的需要自定义 private

  • Java编程实现打印螺旋矩阵实例代码

    直接上代码吧. 昨晚腾讯在线测试遇到的题. 螺旋矩阵是指一个呈螺旋状的矩阵,它的数字由第一行开始到右边不断变大,向下变大,向左变大,向上变大,如此循环. import java.util.Scanner; public class mysnakematrix { private int n; // private int a[][]; // 声明一个矩阵 private int value = 1; // 矩阵里数字的值 public mysnakematrix(int i) { this.n

  • Java使用正则表达式(regex)匹配中文实例代码

    只能输入中文 /** * 22.验证汉字 * 表达式 ^[\u4e00-\u9fa5]{0,}$ * 描述 只能汉字 * 匹配的例子 清清月儿 */ @Test public void a1() { Scanner sc = new Scanner(System.in); String input = sc.nextLine(); String regex = "^[\\u4e00-\\u9fa5]*$"; Matcher m = Pattern.compile(regex).matc

  • Java web的读取Excel简单实例代码

    目录结构: Data.xls数据: 后台页面: public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //System.out.println(this.getServletContext().getRealPath ("/")); try{ Workbook wb = Workbook.getWorkbook(

  • Java Web 简单的分页显示实例代码

    本文通过两个方法:(1)计算总的页数. (2)查询指定页数据,实现简单的分页效果. 思路:首先得在 DAO 对象中提供分页查询的方法,在控制层调用该方法查到指定页的数据,在表示层通过 EL 表达式和 JSTL 将该页数据显示出来. 先给大家展示下效果图: 题外话:该分页显示是用 "表示层-控制层-DAO层-数据库"的设计思想实现的,有什么需要改进的地方大家提出来,共同学习进步.废话不多说了,开始进入主题,详细步骤如下所示: 1.DAO层-数据库 JDBCUtils 类用于打开和关闭数据

  • java 日期各种格式之间的相互转换实例代码

    java 日期各种格式之间的相互转换实例代码 java日期各种格式之间的相互转换,直接调用静态方法 实例代码: java日期各种格式之间的相互转换,直接调用静态方法 package com.hxhk.cc.util; import java.text.SimpleDateFormat; import java.util.Date; import com.lowagie.text.pdf.codec.postscript.ParseException; public class DateUtil

  • java 文件大数据Excel下载实例代码

    java 文件大数据Excel下载实例代码 excel可以用xml表示.故可以以此来实现边写边下载文件 package com.tydic.qop.controller; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.I

  • Java 大小写最快转换方式实例代码

    Java 大小写最快转换方式实例代码          这里直接给出实现代码,在代码中注释都很清楚,不多做介绍. Java代码 package io.mycat; import java.util.stream.IntStream; /** * 小写字母的 'a'=97 大写字母 A=65 更好相差32利用这个差进行大小写转换 * @author : Hpgary * @date : 2017年5月3日 10:26:26 * @mail: hpgary@qq.com * */ public cl

随机推荐