哦,你想找到音量?那麼,並不是所有的硬件都支持它,但這裏是你如何獲得數據。
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的包裝,並用它來正確地實現這些方法。希望這有助於。
考慮添加一個Audio或Javasound標記來提醒用戶這個特別的興趣! –