当前位置: 首页 > 面试题库 >

Java录制时检测静音

丁绪
2023-03-14
问题内容

在Java中开始录制操作时,如何检测静音?什么是PCM数据?如何在Java中计算PCM数据?

我找到了解决方案:

package bemukan.voiceRecognition.speechToText;

import javax.sound.sampled.*;
import java.io.*;

public class RecordAudio {
    private File audioFile;
    protected boolean running;
    private ByteArrayOutputStream out;
    private AudioInputStream inputStream;
    final static float MAX_8_BITS_SIGNED = Byte.MAX_VALUE;
    final static float MAX_8_BITS_UNSIGNED = 0xff;
    final static float MAX_16_BITS_SIGNED = Short.MAX_VALUE;
    final static float MAX_16_BITS_UNSIGNED = 0xffff;
    private AudioFormat format;
    private float level;
    private int frameSize;

    public RecordAudio(){
         getFormat();
    }

    private AudioFormat getFormat() {
        File file = new File("src/Facebook/1.wav");
        AudioInputStream stream;
        try {
            stream = AudioSystem.getAudioInputStream(file);
            format=stream.getFormat();
            frameSize=stream.getFormat().getFrameSize();
            return stream.getFormat();
        } catch (UnsupportedAudioFileException e) {

        } catch (IOException e) {

        }
        return null;
    }

    public void stopAudio() {

        running = false;
    }

    public void recordAudio() {

        try {
            final AudioFormat format = getFormat();
            DataLine.Info info = new DataLine.Info(
                    TargetDataLine.class, format);
            final TargetDataLine line = (TargetDataLine)
                    AudioSystem.getLine(info);
            line.open(format);
            line.start();
            Runnable runner = new Runnable() {
                int bufferSize = (int) format.getSampleRate()
                        * format.getFrameSize();
                byte buffer[] = new byte[bufferSize];

                public void run() {
                     int readPoint = 0;

                    out = new ByteArrayOutputStream();
                    running = true;
                     int sum=0;
                    while (running) {
                        int count =
                              line.read(buffer, 0, buffer.length);
                              calculateLevel(buffer,0,0);
                         System.out.println(level);

                        if (count > 0) {
                            out.write(buffer, 0, count);
                        }
                    }
                    line.stop();
                }
            };
            Thread captureThread = new Thread(runner);
            captureThread.start();
        } catch (LineUnavailableException e) {
            System.err.println("Line unavailable: " + e);
            System.exit(-2);
        }
    }

    public File getAudioFile() {
        byte[] audio = out.toByteArray();
        InputStream input = new ByteArrayInputStream(audio);
        try {

            final AudioFormat format = getFormat();
            final AudioInputStream ais =
                    new AudioInputStream(input, format,
                            audio.length / format.getFrameSize());
            AudioSystem.write(ais, AudioFileFormat.Type.WAVE, new File("temp.wav"));
            input.close();
            System.out.println("New file created!");
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
        return new File("temp.wav");
    }
    private void calculateLevel (byte[] buffer,
                                 int readPoint,
                                 int leftOver) {
        int max = 0;
        boolean use16Bit = (format.getSampleSizeInBits() == 16);
        boolean signed = (format.getEncoding() ==
                          AudioFormat.Encoding.PCM_SIGNED);
        boolean bigEndian = (format.isBigEndian());
        if (use16Bit) {
            for (int i=readPoint; i<buffer.length-leftOver; i+=2) {
                int value = 0;
                // deal with endianness
                int hiByte = (bigEndian ? buffer[i] : buffer[i+1]);
                int loByte = (bigEndian ? buffer[i+1] : buffer [i]);
                if (signed) {
                    short shortVal = (short) hiByte;
                    shortVal = (short) ((shortVal << 8) | (byte) loByte);
                    value = shortVal;
                } else {
                    value = (hiByte << 8) | loByte;
                }
                max = Math.max(max, value);
            } // for
        } else {
            // 8 bit - no endianness issues, just sign
            for (int i=readPoint; i<buffer.length-leftOver; i++) {
                int value = 0;
                if (signed) {
                    value = buffer [i];
                } else {
                    short shortVal = 0;
                    shortVal = (short) (shortVal | buffer [i]);
                    value = shortVal;
                }
                max = Math.max (max, value);
            } // for
        } // 8 bit
        // express max as float of 0.0 to 1.0 of max value
        // of 8 or 16 bits (signed or unsigned)
        if (signed) {
            if (use16Bit) { level = (float) max / MAX_16_BITS_SIGNED; }
            else { level = (float) max / MAX_8_BITS_SIGNED; }
        } else {
            if (use16Bit) { level = (float) max / MAX_16_BITS_UNSIGNED; }
            else { level = (float) max / MAX_8_BITS_UNSIGNED; }
        }
    } // calculateLevel


}

问题答案:

在Java中开始录制操作时,如何检测静音?

计算一组声音帧的dB或RMS值,并确定将其视为“静音”的级别。

什么是PCM数据?

数据是在脉冲编码调制格式。

如何在Java中计算PCM数据?

我不明白这个问题。但是,猜测它与speech-recognition标记有关,我有一些坏消息。从理论上讲,这可以使用Java Speech API来完成。但是,显然没有可用于API的“语音到文本”实现(仅“文字到语音”)。

我必须为语音识别项目计算均方根值。但是我不知道如何用Java计算。

对于信号double范围在-1到1之间的单个通道,可以使用此方法

/** Computes the RMS volume of a group of signal sizes ranging from -1 to 1. */
public double volumeRMS(double[] raw) {
    double sum = 0d;
    if (raw.length==0) {
        return sum;
    } else {
        for (int ii=0; ii<raw.length; ii++) {
            sum += raw[ii];
        }
    }
    double average = sum/raw.length;

    double sumMeanSquare = 0d;
    for (int ii=0; ii<raw.length; ii++) {
        sumMeanSquare += Math.pow(raw[ii]-average,2d);
    }
    double averageMeanSquare = sumMeanSquare/raw.length;
    double rootMeanSquare = Math.sqrt(averageMeanSquare);

    return rootMeanSquare;
}

有一个字节缓冲区来保存行中的输入值,我应该使用该缓冲区做什么?

如果使用该volumeRMS(double[])方法,则将byte值转换double为-1到1范围内的值的数组。



 类似资料:
  • 我在Android中使用新的库CameraX和Firebase ML工具包,并检测设备可以检测的每一帧人脸。 我知道这个库仍然在阿尔法,但我想有一种方法可以做到这一点。 即使没有jet,用Firebase ML录制视频时,还有什么方法可以实现人脸检测呢?

  • 在遵循类似的教程之后,我正在使用MediaRecorder类用相机录制视频 http://androidcookbook.com/Recipe.seam;jsessionid=40151FCD26222877E151C3EEFB406EED?recipeId=1375 我希望在录音时能够使麦克风静音/取消静音。怎么可能呢? 我正在开始设置音频源 但是如果我想在某个时候录制没有声音的音乐呢?

  • 主要内容:录制登录测试,创建JMeter测试计划,添加监听器,验证输出本节试图解释使用任何公开可用的网站记录登录测试的确切步骤,该网站提供具有登录凭据的可靠登录页面。 出于测试目的,我们将使用OrangeHRM在URL- http://opensource.demo.orangehrmlive.com 下提供的公开网站来记录成功登录其网站。还将使用BlazeMeter提供的chrome扩展,通过该扩展可以在chrome中记录用户操作,然后导出测试脚本。 随后,可以在

  • 描述 (Description) 它无法检测到选择器的重复。 例子 (Example) 以下示例演示了在LESS文件中使用重复检测 - extend_syntax.htm <!doctype html> <head> <link rel = "stylesheet" href = "style.css" type = "text/css" /> </head> <bo

  • 问题内容: 我希望在Java中实现一项功能,该功能可以读取图像并能够检测红色,蓝色,绿色,黄色等阴影,作为卫星图像分析程序的一部分。因此,例如在标准卫星图像中,蓝色将是水,因此我希望程序读取多少像素是蓝色的,然后它可以说图像的x%是水。 我知道通过读取每个像素的RGB值可以使用整个逻辑语句负载,但是有没有更简单的方法呢?否则,将有数百个if语句,这些语句将花费很长时间来编写,但执行起来也会很长。理

  • 问题内容: 我有200多个MP3文件,我需要使用静音检测来拆分其中的每个文件。我尝试了Audacity和WavePad,但它们没有批处理过程,将它们一一制作很慢。 场景如下: 分割曲目,而静音2秒或更长时间 然后在这些音轨的开头和结尾添加0.5 s并将其另存为.mp3 BitRate 192立体声 标准化卷以确保所有文件的卷和质量相同 我尝试了FFmpeg,但没有成功。 问题答案: 我发现pydu