gpt4 book ai didi

java - 检查混音器线路中的音频播放电平?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:13:33 24 4
gpt4 key购买 nike

我试图弄清楚是否有任何类型的声音在 Windows 中播放(通过任何应用程序)。如果某处有什么东西在发出声音,我想知道它!

按照文档操作后,我找到了如何获取机器上的混音器列表以及这些混音器的行——如果我理解正确的话,这些是用于混音器输入/输出的内容.

但是,我遇到的问题是我不知道如何从线路中获取我需要的数据。

我看到的唯一具有音量级别概念的接口(interface)是 DataLine。问题是我无法弄清楚是什么返回了一个实现数据线接口(interface)的对象。

枚举所有混音器和线路:

public static void printMixers() {
Mixer.Info[] mixers = AudioSystem.getMixerInfo();
for (Mixer.Info mixerInfo : mixers) {
Mixer mixer = AudioSystem.getMixer(mixerInfo);
try {
mixer.open();
Line.Info[] lines = mixer.getSourceLineInfo();
for (Line.Info linfo : lines) {
System.out.println(linfo);
}
}
catch (LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

该代码枚举并显示了我机器上的所有音频设备。由此看来,那些 Lines 中的一个不应该包含某种播放级别数据吗?

最佳答案

哦,你想找到这本书吗?好吧,并非所有硬件都支持它,但这里是您获取数据线的方法。

    public static SourceDataLine getSourceDataLine(Line.Info lineInfo){
try{
return (SourceDataLine) AudioSystem.getLine(lineInfo);
}
catch(Exception ex){
ex.printStackTrace();
return null;
}
}

然后只需调用 SourceDataLine.getLevel() 即可获取音量。我希望这会有所帮助。

注意:如果声音源自 JVM 外部或不是通过 JavaSound API,则此方法不会检测到声音,因为 JVM 无法访问与 SourceDataLine 等效的操作系统。

更新:经过进一步研究,getLevel() 并未在大多数系统上实现。所以我已经根据这个论坛讨论手动实现了该方法:https://community.oracle.com/message/5391003

这里是类:

public class Main {

public static void main(String[] args){
MicrophoneAnalyzer mic = new MicrophoneAnalyzer(FLACFileWriter.FLAC);
System.out.println("HELLO");
mic.open();
while(true){
byte[] buffer = new byte[mic.getTargetDataLine().getFormat().getFrameSize()];
mic.getTargetDataLine().read(buffer, 0, buffer.length);
try{
System.out.println(getLevel(mic.getAudioFormat(), buffer));
}
catch(Exception e){
System.out.println("ERROR");
e.printStackTrace();
}
}
}

public static double getLevel(AudioFormat af, byte[] chunk) throws IOException{
PCMSigned8Bit converter = new PCMSigned8Bit(af);
if(chunk.length != converter.getRequiredChunkByteSize())
return -1;

AudioInputStream ais = converter.convert(chunk);
ais.read(chunk, 0, chunk.length);

long lSum = 0;
for(int i=0; i<chunk.length; i++)
lSum = lSum + chunk[i];

double dAvg = lSum / chunk.length;
double sumMeanSquare = 0d;

for(int j=0; j<chunk.length; j++)

sumMeanSquare = sumMeanSquare + Math.pow(chunk[j] - dAvg, 2d);

double averageMeanSquare = sumMeanSquare / chunk.length;

return (Math.pow(averageMeanSquare,0.5d));
}
}

我使用的方法仅适用于 8bitPCM,因此我们必须使用这两个类将编码转换为该编码。这里是通用的抽象转换器类。

import java.io.ByteArrayInputStream;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;

abstract class AbstractSignedLevelConverter
{
private AudioFormat srcf;

public AbstractSignedLevelConverter(AudioFormat sourceFormat)
{
srcf = sourceFormat;
}


protected AudioInputStream convert(byte[] chunk)
{
AudioInputStream ais = null;
if(AudioSystem.isConversionSupported( AudioFormat.Encoding.PCM_SIGNED,
srcf))
{
if(srcf.getEncoding() != AudioFormat.Encoding.PCM_SIGNED)
ais = AudioSystem.getAudioInputStream(
AudioFormat.Encoding.PCM_SIGNED,
new AudioInputStream(new ByteArrayInputStream(chunk),
srcf,
chunk.length * srcf.getFrameSize()));
else
ais = new AudioInputStream(new ByteArrayInputStream(chunk),
srcf,
chunk.length * srcf.getFrameSize());
}

return ais;
}

abstract public double convertToLevel(byte[] chunk) throws IOException;

public int getRequiredChunkByteSize()
{
return srcf.getFrameSize();
}
}

这是 8BitPCM 的

import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;

public class PCMSigned8Bit extends AbstractSignedLevelConverter
{
PCMSigned8Bit(AudioFormat sourceFormat)
{
super(sourceFormat);
}

public double convertToLevel(byte[] chunk) throws IOException
{
if(chunk.length != getRequiredChunkByteSize())
return -1;

AudioInputStream ais = convert(chunk);
ais.read(chunk, 0, chunk.length);

return (double)chunk[0];
}




}

这是针对 TargetDataLine 的,它可能不适用于您的用例,但您可以围绕 SourceDataLine 构建一个包装器并使用它来正确实现这些方法。希望这会有所帮助。

关于java - 检查混音器线路中的音频播放电平?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22120423/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com