Uscite multiple del mixer in Java


Sto cercando di far riprodurre Java audio stereo diverso in due uscite (jack audio anteriore e posteriore).

La mia scheda audio è configurata per trattare entrambe le uscite in modo indipendente, e nel mixer di Windows posso farle emettere un suono di prova separatamente, quindi non è un problema di scheda.

Ho provato l'approccio su Cambia Mixer per emettere il suono in java usando uscite diverse ottenendo due clip con mixer diversi, con AudioSystem.getClip(AudioSystem.getMixerInfo()[i]);. Tuttavia, questa riga di codice funziona solo con Java Sound Audio Engine (AudioSystem.getMixerInfo()[0]), che emette in uscita audio predefinita di Windows. Qualsiasi altra cosa getta

java.lang.IllegalArgumentException: Line unsupported: interface Clip supporting format PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian

Il seguente codice di esempio genera un rumore bianco lungo 5 secondi e lo riproduce per 1 secondo e poi termina. Stampa le informazioni del mixer come visto su come ottengo il layout dei canali del mixer in java. Attualmente emette il mixer "Java Sound Audio Engine" e il tentativo di passare a qualsiasi altro mixer genera l'eccezione sopra.

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;
    }
}

Ecco il Mixer informazione. Questo codice è stato eseguito con entrambi i jack di uscita collegati e Windows riconosce come due diversi dispositivi di uscita (altoparlanti e cuffie). Sembra che solo il motore audio di Java possa riprodurre suoni.

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

Sto usando Java 6 a causa di altre limitazioni. Inoltre, alcuni nomi sono rotti probabilmente perché sono in un ambiente giapponese e Eclipse non recupererà i nomi nella codifica corretta (ho provato a cambiare tutto in UTF-8 e Shift_JIS ma non è cambiato nulla, ma immagino che non lo sia relativo a questo problema).

In altre parole, sembra che non possa essere emesso in Clip da diversi Mixer perché Java può essere emesso solo su "Java Sound Audio Engine" che va al dispositivo audio predefinito di Windows. C'è un modo per far funzionare gli altri mixer? Esiste un'alternativa per utilizzare più uscite audio?

Update: Sembra che questo problema sia già stato risolto ma non riesco ancora a farlo funzionare. Ho disabilitato il dispositivo di registrazione" Stereo Mix " e ho eseguito il codice di esempio fornito in quel collegamento e ottenuto questo output:

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

Quindi sembra che solo Java Sound Audio Engine possa emettere il suono poiché entrambi i mixer per i jack audio anteriori e posteriori sono trattati come linee di ingresso. Audio riprodotto tramite Clip o uscite SourceDataLine nel dispositivo di riproduzione predefinito di Windows.

Inoltre, sembra che abbiano risoltoil problema usando DirectAudio ma non ho ancora capito come usarli.

Author: Community, 2016-01-22

1 answers

Durante il test su computer diversi, ho risolto questo problema aggiornando a Java 1.6.0_17 (che andava ancora bene con le limitazioni del mio ambiente per chiamare Java da Matlab) in modo che i driver DirectAudio fossero elencati (anche se sembra che dovrebbe funzionare da Java 1.5). Ogni dispositivo audio DirectAudio dà un SourceDataLine e una clip per ogni dispositivo.

 0
Author: walljam7, 2016-01-28 01:34:19