#java #audio
#ява #Аудио
Вопрос:
Хорошо, я искал, но не нашел решения. Мне удалось получить byte[]
вывод с микрофона с AudioFormat(44100.0f, 32, 2, true, true);
форматом. Хорошо, но теперь я хочу воспроизвести его через наушники, чтобы протестировать.
Я много чего прочитал, погуглил и посмотрел здесь, в StackOverflow, но я не могу найти способ просто воспроизвести мои уже сохраненные данные в наушниках (или на реальном устройстве вывода звука).
Я читал, что обычный способ — воспроизвести его из клипа (а клип считывает поток файлов аудиофайла) или альтернативно использовать SourceDataLine. Но я хочу вернуть byte[]
в выходной поток или в буфер и воспроизвести его в реальном времени.
Мой код предназначен для вызова около 60 раз в секунду (поскольку он работает вложенным в 3D-приложение, возможно, я добавлю его позже) и выводит byte[]
для графического представления.
Мой фактический (нерабочий) подход заключается в следующем (публикуя полный код ниже для завершения):
/* DATA
AudioFormat format; //Audio format (already initialiced)
TargetDataLine line; //Microphone line (working)
DataLine.Info info;
byte soundArray[]; //The last retrieved data
*/
private void playOnRealtime() throws LineUnavailableException {
Clip clip = AudioSystem.getClip();
TargetDataLine d_line;
AudioInputStream inputStream;
DataLine.Info info = new DataLine.Info(SourceDataLine.class,
format); // format is an AudioFormat object
if (!AudioSystem.isLineSupported(info)) {
System.err.print("Dataline OUT not supported!");
}
try {
d_line = AudioSystem.getTargetDataLine(format);
d_line.open();
d_line.start();
inputStream = AudioSystem.getAudioInputStream(format, new AudioInputStream(d_line));
clip.open(inputStream);
clip.start();
d_line.stop();
clip.stop();
} catch (LineUnavailableException ex) {
// Handle the error.
// ...
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Полный код здесь (если кто-то сочтет это уместным):
package main;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
public class Monitor implements Runnable {
AudioFormat format;
TargetDataLine line;
DataLine.Info info;
byte soundArray[];
public Monitor() {
format = new AudioFormat(44100.0f, 32, 2, true, true);
// format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
// 44100.0F, 16, 2, 4, 44100.0F, false);
try {
line = AudioSystem.getTargetDataLine(format);
} catch (LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DataLine.Info info = new DataLine.Info(TargetDataLine.class,
format); // format is an AudioFormat object
if (!AudioSystem.isLineSupported(info)) {
// Handle the error ...
}
// Obtain and open the line.
try {
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
} catch (LineUnavailableException ex) {
// Handle the error ...
}
soundArray = new byte[8000];
}
boolean started;
@Override
public void run() {
try {
line.open();
line.start();
line.read(soundArray, 0, 8000);
System.out.println('A');
printFloatArray(fragment(16, soundArray));
line.stop();
} catch (LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
playOnRealtime();
} catch (LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static byte[] fragment(int n, byte[] array) {
int length = array.length;
byte[] result = new byte[n];
for (int k = 0; k < n; k ) {
result[k] = array[k * (length / n)];
}
return resu<
}
private static void printFloatArray(byte[] array) {
for (byte var : array) {
System.out.print(String.format("=", var) "t");
}
}
public byte[] getData(int n_div) {
return fragment(n_div, soundArray);
}
private void playOnRealtime() throws LineUnavailableException {
Clip clip = AudioSystem.getClip();
TargetDataLine d_line;
AudioInputStream inputStream;
DataLine.Info info = new DataLine.Info(SourceDataLine.class,
format); // format is an AudioFormat object
if (!AudioSystem.isLineSupported(info)) {
System.err.print("Dataline OUT not supported!");
}
try {
d_line = AudioSystem.getTargetDataLine(format);
d_line.open();
d_line.start();
inputStream = AudioSystem.getAudioInputStream(format, new AudioInputStream(d_line));
clip.open(inputStream);
clip.start();
d_line.stop();
clip.stop();
} catch (LineUnavailableException ex) {
// Handle the error.
// ...
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}