日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java实现Shazam声音识别算法

發布時間:2023/12/8 java 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java实现Shazam声音识别算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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; // doublepublic static boolean signed = true; // Indicates whether the data is signed or unsignedpublic static boolean bigEndian = true; // Indicates whether the audio data is stored in big-endian or little-endian orderpublic AudioFormat getFormat() {return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,bigEndian);}

調用麥克風獲取音頻,保存到out中

public static ByteArrayOutputStream out = new ByteArrayOutputStream(); try {AudioFormat format = smartAuto.getFormat(); // Fill AudioFormat with the settingsDataLine.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声音识别算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。