Я пытаюсь заставить Java воспроизводить разные стереозвуки на двух выходах (передние и задние аудиоразъемы).
Моя звуковая карта настроена так, чтобы обрабатывать оба выхода независимо, и в микшере Windows я могу заставить их издавать тестовый звук отдельно, так что это не проблема карты.
Я попробовал подход Change Mixer для вывода звука в java используя разные выходы, получив два клипа с разными микшерами, с AudioSystem.getClip(AudioSystem.getMixerInfo()[i]);
. Однако эта строка кода работает только с Java Sound Audio Engine (AudioSystem.getMixerInfo()[0]
), который выводит звук по умолчанию в Windows. Что-нибудь еще бросает
java.lang.IllegalArgumentException: Line unsupported: interface Clip supporting format PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
В следующем примере кода создается 5-секундный белый шум, который воспроизводится в течение 1 секунды, а затем завершается. Он выводит информацию о микшере, как показано в разделе , как мне получить макет каналов микшера. в Java. В настоящее время он выводится на микшер «Java Sound Audio Engine», и попытка перейти на любой другой микшер вызывает указанное выше исключение.
import java.io.ByteArrayInputStream;
import java.security.SecureRandom;
import java.util.Random;
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.Line;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.SourceDataLine;
public class Main {
static int SAMPLE_RATE = 44100;
static AudioFormat format = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED, // Encoding
SAMPLE_RATE, // sample rate
8, // sample size in bits
2, // channels
4, // frame size
SAMPLE_RATE, // frame rate
true); // is big endian
static int DURATION = 5;
Thread soundThread;
// Noise audio
static AudioInputStream inputStream = new AudioInputStream(new ByteArrayInputStream(generateNoise(DURATION*2*SAMPLE_RATE)), format, DURATION*SAMPLE_RATE);
public static void main(String[] args) {
try {
// https://stackoverflow.com/questions/12863081/how-do-i-get-mixer-channels-layout-in-java
Mixer.Info[] mi = AudioSystem.getMixerInfo();
for (Mixer.Info info : mi) {
System.out.println("info: " + info);
Mixer m = AudioSystem.getMixer(info);
System.out.println("mixer " + m);
Line.Info[] sl = m.getSourceLineInfo();
for (Line.Info info2 : sl) {
System.out.println(" info: " + info2);
Line line = AudioSystem.getLine(info2);
if (line instanceof SourceDataLine) {
SourceDataLine source = (SourceDataLine) line;
DataLine.Info i = (DataLine.Info) source.getLineInfo();
for (AudioFormat format : i.getFormats()) {
System.out.println(" format: " + format);
}
}
}
System.out.println("");
}
// Code only works for AudioSystem.getMixerInfo()[0]
final Clip clip = AudioSystem.getClip(AudioSystem.getMixerInfo()[0]);
clip.open(inputStream);
Thread soundThread = new Thread(new Runnable() {
@Override
public void run() {
try {
clip.loop(Clip.LOOP_CONTINUOUSLY);
Thread.sleep(1000);
clip.close();
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
});
soundThread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
private static byte[] generateNoise(int size) {
byte[] out = new byte[size];
Random r = new SecureRandom();
r.nextBytes(out);
return out;
}
}
Вот информация о микшере. Этот код работал с обоими подключенными выходными разъемами, и Windows распознает два разных устройства вывода (динамики и наушники). Похоже, что только звуковой движок Java может воспроизводить звуки.
info: Java Sound Audio Engine, version 1.0
mixer com.sun.media.sound.HeadspaceMixer@22c84d9
info: interface SourceDataLine supporting 8 audio formats
format: PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
format: PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
format: PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
format: PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
format: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
format: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
format: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
format: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
info: interface Clip supporting 8 audio formats, and buffers of 0 to 4194304 bytes
info: Microsoft ?T?E???h, version Unknown Version
mixer com.sun.media.sound.SimpleInputDevice@7e0df503
info: Stereo Mixer (Realtek High Defi, version Unknown Version
mixer com.sun.media.sound.SimpleInputDevice@4650d89c
info: Port Realtek HD Audio 2nd output (Re, version 6.1
mixer com.sun.media.sound.PortMixer@65bd0dd4
info: Port Stereo Mixer (Realtek High Defi, version 6.1
mixer com.sun.media.sound.PortMixer@78b5f53a
info: ?}?X? source port
info: Port Speakers (Realtek High Definiti, version 6.1
mixer com.sun.media.sound.PortMixer@b37c60d
Я использую Java 6 из-за других ограничений. Кроме того, некоторые имена не работают, вероятно, потому, что я нахожусь в японской среде, и Eclipse не будет получать имена в правильной кодировке (я пытался изменить все на UTF-8 и Shift_JIS, но ничего не изменилось, но я думаю, что это не связано к этой проблеме).
Другими словами, похоже, что он не может выводить клипы из разных микшеров, потому что Java может выводить только на «Java Sound Audio Engine», который идет на аудиоустройство Windows по умолчанию. Есть ли способ заставить другие микшеры работать? Есть ли альтернатива использованию нескольких аудиовыходов?
Обновление: кажется, что эта проблема уже решена но я все еще не могу заставить его работать. Я отключил записывающее устройство «Stereo Mix» и запустил пример кода, указанный в этой ссылке, и получил следующий результат:
MIXER 0: Java Sound Audio Engine, version 1.0
OUTPUT LINE (SourceDataLine) 0: interface SourceDataLine supporting 8 audio formats
OUTPUT LINE (SourceDataLine) 1: interface Clip supporting 8 audio formats, and buffers of 0 to 4194304 bytes
MIXER 1: Port Realtek HD Audio 2nd output (Re, version 6.1
INPUT LINE (TargetDataLine) 0: HEADPHONE target port
MIXER 2: Port Speakers (Realtek High Definiti, version 6.1
INPUT LINE (TargetDataLine) 0: SPEAKER target port
Таким образом, похоже, что только Java Sound Audio Engine может выводить звук, поскольку микшеры для переднего и заднего аудиоразъемов обрабатываются как входные линии. Звук воспроизводится через выходы Clip или SourceDataLine на устройстве воспроизведения Windows по умолчанию.
Кроме того, похоже, что они решили проблему с помощью DirectAudio, но я так и не понял, как их использовать.