Java が 2 つの出力 (前面と背面のオーディオ ジャック) で異なるステレオ オーディオを再生するようにしようとしています。
私のサウンド カードは、両方の出力を個別に処理するように構成されています。Windows ミキサーでは、テスト サウンドを個別に出力できるので、カードの問題ではありません。
ミキサーを変更して、異なるミキサーで2つのクリップを取得することにより、異なる出力を使用してJavaでサウンドを出力するアプローチを試しましたAudioSystem.getClip(AudioSystem.getMixerInfo()[i]);
。ただし、このコード行はAudioSystem.getMixerInfo()[0]
、Windows のデフォルトのオーディオ出力で出力する Java Sound Audio Engine ( ) でのみ機能します。それ以外は投げる
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 で Mixer チャネル レイアウトを取得する方法に見られるように、Mixer 情報を出力します。現在、「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 は 2 つの異なる出力デバイス (スピーカーとヘッドフォン) として認識します。サウンドを再生できるのは 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 は Windows のデフォルトのオーディオ デバイスに接続する「Java Sound Audio Engine」にしか出力できないため、別のミキサーからクリップを出力することはできないようです。他のミキサーを機能させる方法はありますか? 複数のオーディオ出力を使用する代替手段はありますか?
更新:この問題は既に修正されているようですが、まだ機能しません。「ステレオ ミックス」録音デバイスを無効にし、そのリンクにあるサンプル コードを実行したところ、次の出力が得られました。
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 だけのようです。Windows の既定の再生デバイスで、Clip または SourceDataLine 出力のいずれかを介してオーディオを再生しました。
また、DirectAudio を使用して問題を解決したようですが、使用方法がわかりませんでした。