365真正的官网-beat365体育登陆网址-365bet.com

— 怀旧经典 · 永恒记忆 —

java数字音频最强教程之如何检测一段音频中是否有声音

java数字音频最强教程之如何检测一段音频中是否有声音

声音检测

随着人工智能的发展,机器视觉,机器可视化也变的越来越完善,但是声音这块分析资料却比较少,有时候需要去检测一段视频或者音频中是否有声音。在某些场景中需要判断有声音则抓拍录制,当然这里只是先初步检测声音响度,如果还需要更高深的检测比如有人说话,也有其他嘈杂声音,我们如何去区分是人在说话,还是车开过,还是噪音,这个以后再讲。

可用于流媒体视频中实时检测,也可以用于离线文件检测,根据自己的需求,调节soundThreshold阈值,一般情况-65 db 为安静状态。

演示:

话不多说,直接上代码:

package com.zj.example;

import java.io.File;

import java.io.IOException;

import java.nio.ByteBuffer;

import java.nio.ByteOrder;

import javax.sound.sampled.AudioInputStream;

import javax.sound.sampled.AudioSystem;

import javax.sound.sampled.UnsupportedAudioFileException;

import com.zj.filter.DetectSoundFilter;

/**

* 识别音频中是否有声音

* @author ZJ

*

*/

public class TestDetectQuiet {

public static void main(String[] args) throws UnsupportedAudioFileException, IOException {

loadFile("./data/安静.wav");

// loadFile("./data/有声.wav");

}

/**

* 读取文件

*/

public static void loadFile(String path) throws UnsupportedAudioFileException, IOException {

File f = new File(path);

AudioInputStream audioStream = AudioSystem.getAudioInputStream(f);

readData(audioStream);

}

/**

* 读取数据

* @throws IOException

*/

public static void readData(AudioInputStream audioStream) throws IOException {

byte[] frame = new byte[2048];

DetectSoundFilter soundFilter = new DetectSoundFilter();

while (true) {

int read = audioStream.read(frame);

if (read < 0) {

break;

}

double[] byteToDouble = byteToDouble(frame);

boolean silence = soundFilter.isSilence(byteToDouble);

if(silence) {

System.out.println("这是安静的");

} else {

System.out.println("这是有声音的");

}

}

}

/**

* pcm转成浮点

* @param data

* @return

*/

public static double[] byteToDouble(byte[] data) {

ByteBuffer buf = ByteBuffer.wrap(data);

buf.order(ByteOrder.BIG_ENDIAN);

int i = 0;

double[] dData = new double[data.length / 2];

while (buf.remaining() > 1) {

short s = buf.getShort();

dData[i] = (double) s / 32767.0; // real

++i;

}

return dData;

}

}

检测声音核心部分:

package com.zj.filter;

/**

* 识别声音过滤器

* 用于判断有没有声音,甚至可以判断声音的响度

*

* @author ZJ

*

*/

public class DetectSoundFilter {

/**

* 声音响度阈值

*/

public double soundThreshold = -60; // db

/**

* 是否安静

* @param buffer

* @param soundThreshold

* @return

*/

public boolean isSilence(final double[] buffer) {

double currentSPL = soundPressureLevel(buffer);

System.out.println(currentSPL);

return currentSPL < soundThreshold;

}

/**

* 声压计算

* @param buffer

* @return

*/

private double soundPressureLevel(final double[] buffer) {

double value = Math.pow(localEnergy(buffer), 0.5);

value = value / buffer.length;

return linearToDecibel(value);

}

/**

* 线性转换为dB值

* @param value

* @return

*/

private double linearToDecibel(final double value) {

return 20.0 * Math.log10(value);

}

/**

* 音频帧去负数

* @param buffer

* @return

*/

private double localEnergy(final double[] buffer) {

double power = 0.0D;

for (double element : buffer) {

power += element * element;

}

return power;

}

}

demo里只是来检测某一帧,实际应用中可能需求不一样,可以自行修改,比如一段时间内都是安静的话,否则不认为是安静。

gitee地址

至此简单的声音响度识别功能实现了。

java数字音频最强教程

如果觉得可以,请随手点赞,Thanks♪(・ω・)ノ

相关推荐