tl; dr Für zukünftige Leser ist die Aufnahme von Audio in Echtzeit nicht möglich (für jetzt) mit Java oder C#. Verwenden Sie C++, da es eine Fülle von Audio-APIs bietet.Java audio visualizer- So erfassen Sie Echtzeit-Soundausgabe zum Lautsprecher?
Mein Ziel ist der aktuelle Sound abgespielt auf einem Windows-Rechner zu bekommen, und analysiert den Klang wie ein Grafik-Audio-Visualizer ist (die Lautstärke Eigenschaft und Hz (Basis und Höhen bekommen)). Wenn ich aktuellen Sound sage, meine ich, wenn man einen Youtube-Video oder Spotify-Song spielt, und dieses Programm würde diesen Audio-Output lesen. Ich habe KEINE Absicht, Sound zu spielen, sondern ihn in Echtzeit zu erfassen und zu visualisieren.
In dem Versuch, dies zu tun, ich lese, wie zu build an audio waveform display und es berührt, wie eine Audiodatei in ein Array von Bytes (a Line) zu konvertieren. Das hilft nicht, weil es nicht den aktuellen Sound bekommt. Ich lese auch auf, wie zu capture audio als auch, und this java accessing sound tutorial, keiner von denen meine Frage beantworten, weil sie beide eine Song-Datei zum Laden benötigen.
Ich verstehe das überhaupt nicht. Ich bin total ahnungslos und jede Hilfe wäre willkommen.
Edit: Ich habe ein wenig mehr umgesehen, und die second answer from this source führen mich zu dem Schluss, dass: Ich konnte alle Audiogeräte finden, sehen, welche einen Ton produziert. Ich weiß nicht, was ich danach machen soll.
Edit 2 (noch einmal bearbeitet): Aus dem Experimentieren und herumschauen habe ich diesen Code unten geschrieben. Ich denke, das bringt mich in die Richtung, in die ich will, aber ich weiß nicht, wie ich es beenden soll.
Mixer.Info[] mixers = AudioSystem.getMixerInfo();
for (Mixer.Info mixerInfo : mixers) {
Mixer mixer = AudioSystem.getMixer(mixerInfo);
try {
mixer.open();
Line.Info[] lines = mixer.getTargetLineInfo();
for (Line.Info linfo : lines) {
Line line = AudioSystem.getLine(linfo);
//here I'm opening the line, but I don't know how to grab data
line.open();
}
} catch (LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
benutzte ich diese Quelle: Checking The Level of Audio-Playback in a mixers line, aber ich bin nicht auf der Suche für alle Linien zu überprüfen, die Lautstärke spielen, ich muss nur die Benutzer Standard-Mixer, dass die Linie erhalten, und in der Lage, die Daten zu analysieren .
Bearbeiten 3: Ich habe versucht:
//creating a format for getting sound
float sampleRate = 8000;
int sampleSizeInBits = 16;
int channels = 2;
boolean signed = true;
boolean bigEndian = true;
AudioFormat format = new AudioFormat(sampleRate, sampleSizeInBits, channels,
signed, bigEndian);
//creating a line based off of the format
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
//opening and starting that line
line.open(format);
line.start();
while (conditionIsTrue){
//here, I don't know what to put as the parameters.
//Had I known, I don't know how I would get to analyze the data
line.read();
}
Ich glaube, ich auf dem richtigen Weg bin über den Code verwenden, aber ich weiß nicht, wie man den Ton zu extrahieren und die bpm, Base zu finden, Treble usw.
Edit 4: Dies war eine interessante Lektüre: Real-time low latency audio processing in Java. Dies berührt nicht, welche Klassen und wie dies tatsächlich implementiert wird, aber es gibt einige Einblicke.
Edit 5: @AndrewThompson Mit diesem Stück Code von Ihrem Link ausgehend konnte ich über die verfügbaren Quell- und Ziellinien iterieren.
Mixer.Info[] mixers = AudioSystem.getMixerInfo();
for (Mixer.Info mixerInfo : mixers) {
Mixer mixer = AudioSystem.getMixer(mixerInfo);
try {
mixer.open();
Line.Info[] sourceLines = mixer.getSourceLineInfo();
Line.Info[] targetLine = mixer.getTargetLineInfo();
for (Line.Info sourceLinfo : sourceLines) {
System.out.println(sourceLinfo);
}
for (Line.Info targetLinefo : targetLine) {
System.out.println(targetLinefo);
}
} catch (LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Die Ausgabe sieht wie folgt aus:
interface SourceDataLine supporting 8 audio formats, and buffers of at least 32 bytes
interface Clip supporting 8 audio formats, and buffers of at least 32 bytes
interface SourceDataLine supporting 8 audio formats, and buffers of at least 32 bytes
interface Clip supporting 8 audio formats, and buffers of at least 32 bytes
interface SourceDataLine supporting 8 audio formats, and buffers of at least 32 bytes
interface Clip supporting 8 audio formats, and buffers of at least 32 bytes
HEADPHONE target port
SPEAKER target port
Ich habe dann ein Verfahren geschaffen, das die Klangpegel aller Linien, die wie folgt aussieht bekommt:
private static void getVolumeOfAllLines() {
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) {
DataLine line = (DataLine)AudioSystem.getLine(linfo);
if(line != null)
System.out.println(line.getLevel());
}
} catch (LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
-in attemps um die aktuelle Zeile zu finden, die den Ton spielt und eine höhere Lautstärke anzeigt. Dies gibt:
-1.0
-1.0
-1.0
-1.0
-1.0
-1.0
keine Fortschritte.
Neuer Code:
private static void debug(){
Mixer.Info[] mixers = AudioSystem.getMixerInfo();
for (Mixer.Info mixerInfo : mixers) {
Mixer mixer = AudioSystem.getMixer(mixerInfo);
try {
mixer.open();
Line.Info[] lines = mixer.getTargetLineInfo();
AudioFormat format = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
44100,
16, 2, 4,
44100, false);
AudioFormat[] tdl = AudioSystem.getTargetFormats(AudioFormat.Encoding.PCM_SIGNED, format);
for (Line.Info linfo : lines) {
//Line line = AudioSystem.getLine(linfo);
TargetDataLine line = null;
DataLine.Info info = new DataLine.Info(TargetDataLine.class,
format); // format is an AudioFormat object
if (!AudioSystem.isLineSupported(info))
{
System.out.println("line not supported:" + line);
}
try
{
line = (TargetDataLine) AudioSystem.getLine(info); //error
line.open(format);
System.out.println("line opened:" + line);
line.start();
byte[] buffer = new byte[1024];
int ii = 0;
int numBytesRead = 0;
while (ii++ < 100) {
// Read the next chunk of data from the TargetDataLine.
numBytesRead = line.read(buffer, 0, buffer.length);
System.out.println("\nnumBytesRead:" + numBytesRead);
if (numBytesRead == 0) continue;
// following is a quickie test to see if content is only 0 vals
// present in the data that was read.
for (int i = 0; i < 16; i++)
{
if (buffer[i] != 0)
System.out.print(".");
else
System.out.print("0");
}
}
} catch (LineUnavailableException ex) {
ex.printStackTrace();
//...
}
}
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
}
Ich bin mir nicht sicher, dass es immer möglich ist. * Einige * Computer haben einen "Stereo Mix" -Eingang, der wie ein Mikrofon wirkt, das den Ausgang aufzeichnet. – immibis
Wenn Sie einige Computer sagen, könnten Sie das näher erläutern? (Wie in nur Windows Maschinen, Mac, etc) – Eric
Ich habe es auf einigen Windows-Maschinen gesehen. – immibis