Oh, Sie möchten die Lautstärke finden? Nun, nicht alle Hardware unterstützt es, aber hier ist, wie Sie die Dataline bekommen.
Rufen Sie dann einfach SourceDataLine.getLevel() auf, um das Volume abzurufen. Ich hoffe das hilft.
Hinweis: Wenn der Sound von außerhalb der JVM stammt oder nicht über die JavaSound-API, erkennt diese Methode den Sound nicht, da die JVM keinen Zugriff auf das OS-Äquivalent der SourceDataLine hat.
UPDATE: Nach weiteren Untersuchungen ist getLevel() auf den meisten Systemen nicht implementiert. So habe ich manuell implementiert das Verfahren in diesem Forum Diskussion basiert off: https://community.oracle.com/message/5391003
Hier sind die Klassen:
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));
}
}
Die Methode, die ich nur auf 8bitPCM arbeitet verwendet, so haben wir die Codierung konvertieren, dass diese beiden mit Klassen. Hier ist die allgemeine abstrakte Konverterklasse.
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();
}
}
Und hier ist das eine für 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];
}
}
Diese für TargetDataLine ist, die in ihrem Anwendungsfall kann nicht funktionieren, aber Sie könnten einen Wrapper um SourceDataLine zu bauen und diese richtig diese Methoden zu implementieren verwenden . Hofft, das hilft.
Sie können ein Audio- oder Javasound-Tag hinzufügen, um Benutzer mit diesem speziellen Interesse zu warnen! –