4

マイクではなく、ライン入力ポートからサウンドをキャプチャする必要があります。

マイクからの録音はできましたが、ライン入力ポートや特定のポートからの音声のキャプチャはできません。どうすればこの問題を処理できますか?

4

4 に答える 4

2

私もこれを理解していませんが、実際には必要です

mixer.getSourceLineInfo()これは Mixer からのビューなので... 本当に紛らわしい!!!

targetDataLine は記録可能な入力ラインですが、これらのラインがどこから来ているかを確認するには、ミキサーにあるポート (MICROPHONE 、LINE_IN、SPDIF など) を調べる必要があるため、

mixer.getSourceLineInfo()

これはポートのみを提供します。これらは、たとえば、LINE_IN 入力の録音ボリュームを制御するために使用できますが、PORT オブジェクトから直接録音することはできません。

DataLine.Info targetDataLineInfo = new DataLine.Info(TargetDataLine.class, AudioFormat); を使用する必要があります。

ここで、AudioFormat は次のようなユーザー定義の形式です

audioFormat = new AudioFormat(
                Encoding.PCM_SIGNED,
                sampleRate,
                bitRate,
                monoOrStereo,
                monoOrStereo * 2, // 
                sampleRate,
                false); 

次に、優先ミキサーからラインを取得します。

Mixer.getLine(audioFormat);

おそらくすでに行っているように、これにより記録可能な行が得られます...

私が理解できないのは、あなたのように、LINE_IN などのポートを選択し、ポート オブジェクトが制御できる一致する TargetDataLine を作成する方法です。

()

そこに実用的な例がある人..

于 2012-01-20T06:21:32.587 に答える
2
import javax.sound.sampled.*;

/**
 *
 * @author d07114915
 * 
 * Class to get a mixer with a specified recordable audio format from a specified port
 * For instance get a 44.1kHz 16bit record line for a "line in"  input
 */
public class MixerMatcher {
private static final String THE_INPUT_TYPE_I_WANT = "MICROPHONE";
private static final String THE_NAME_OF_THE_MIXER_I_WANT_TO_GET_THE_INPUT_FROM = "Realtek HD Audio Input";
private static final AudioFormat af = new AudioFormat(
        AudioFormat.Encoding.PCM_SIGNED,
        44100.0F,
        16,
        2,
        2 * 2,
        44100.0F,
        false);
private static final DataLine.Info targetDataLineInfo = new DataLine.Info(TargetDataLine.class, af);
private static final Port.Info myInputType = new Port.Info((Port.class), THE_INPUT_TYPE_I_WANT, true);
private static TargetDataLine targetDataLine = null;

public static void main(String[] args) {
    Mixer portMixer = null;
    Mixer targetMixer = null;
    try {
        for (Mixer.Info mi : AudioSystem.getMixerInfo()) {
            //               System.out.println("-" +mi.getName() + "-");
            if (mi.getName().equals(THE_NAME_OF_THE_MIXER_I_WANT_TO_GET_THE_INPUT_FROM)) {
                System.out.println("Trying to get portMixer for :" + mi.getName());
                portMixer = getPortMixerInfoFor(mi);
                if (portMixer != null) {
                    System.out.println(portMixer.getMixerInfo().toString());
                    targetMixer = AudioSystem.getMixer(mi);
                    break;
                }
            }
        }
        if (targetMixer != null) {
            targetMixer.open();

            targetDataLine = (TargetDataLine) targetMixer.getLine(targetDataLineInfo);
            System.out.println("Got TargetDataLine from :" + targetMixer.getMixerInfo().getName());

            portMixer.open();

            Port port = (Port) portMixer.getLine(myInputType);
            port.open();

            Control[] controls = port.getControls();
            System.out.println((controls.length > 0 ? "Controls for the "+ THE_INPUT_TYPE_I_WANT + " port:" : "The port has no controls."));
            for (Control c : controls) {
                System.out.println(c.toString());
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

}

//return the portMixer that corresponds to TargetMixer 
private static Mixer getPortMixerInfoFor(Mixer.Info mixerInfo) {
    //Check this out for interest
    //http://www.java-forum.org/spiele-multimedia-programmierung/94699-java-sound-api-zuordnung-port-mixer-input-mixer.html
    try {
        // get the requested mixer
        Mixer targetMixer = AudioSystem.getMixer(mixerInfo);
        targetMixer.open();
        //Check if it supports the desired format
        if (targetMixer.isLineSupported(targetDataLineInfo)) {
            System.out.println(mixerInfo.getName() + " supports recording @ " + af);
            //now go back and start again trying to match a mixer to a port
            //the only way I figured how is by matching name, because 
            //the port mixer name is the same as the actual mixer with "Port " in front of it
            // there MUST be a better way
            for (Mixer.Info portMixerInfo : AudioSystem.getMixerInfo()) {
                String port_string = "Port ";
                if ((port_string + mixerInfo.getName()).equals(portMixerInfo.getName())) {
                    System.out.println("Matched Port to Mixer:" + mixerInfo.getName());
                    Mixer portMixer = AudioSystem.getMixer(portMixerInfo);
                    portMixer.open();
                    //now check the mixer has the right input type eg LINE_IN
                    boolean lineTypeSupported = portMixer.isLineSupported((Line.Info) myInputType);
                    System.out.println(portMixerInfo.getName() +" does " + (lineTypeSupported? "" : "NOT") + " support " + myInputType.getName());
                    if (lineTypeSupported) {
                        portMixer.close();
                        targetMixer.close();
                        return portMixer;
                    }
                    portMixer.close();
                }
            }
        }
        targetMixer.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
}

これを実行すると、次のようになります。
Trying to get portMixer for :Realtek HD Audio Input
Realtek HD Audio Input supports recording @ PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian
Matched Port to Mixer:Realtek HD Audio Input
Port Realtek HD Audio Input does support MICROPHONE
Port Realtek HD Audio Input, version 5.10
Got TargetDataLine from :Realtek HD Audio Input
Controls for the MICROPHONE port:
Mic Volume Control containing Select, Microphone Boost, Volume, and Balance Controls.

ミキサーと入力タイプの設定をそれぞれ「USB サウンド デバイス」と「LINE_IN」に変更すると、次のようになります: (ミキサー名の「デバイス」という単語の後に 8 つの空白があることに注意してください。ページ!)

Trying to get portMixer for :USB Sound Device
Trying to get portMixer for :USB Sound Device
USB Sound Device supports recording @ PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian
Matched Port to Mixer:USB Sound Device
Port USB Sound Device does support LINE_IN
Port USB Sound Device , version 0.16
Got TargetDataLine from :USB Sound Device
Controls for the LINE_IN port:
Line Control containing Select, Mute, Volume, and Balance Controls.

ここでは、USB サウンド カードに入力ポートと出力ポートが表示されているため、そのうちの 1 つは LINE_IN をサポートしていません。これはおそらく出力であるため、「ステレオ ミックス」またはその他の出力タイプを録音できる可能性があるためです。

これが機能し、誰かの助けになることを願っています.... Javaドキュメントはかなりあいまいなので... Windowsでテストされていますが、LinuxはLINE_INなどのポート名を認識しないと思うので、OSポートを確認する必要がありますおそらく、ミキサー名の部分文字列が必要など、他のいくつかのことが必要です...私のLinuxでは、マイクは「キャプチャ」と呼ばれています...

詳細については、 jsresources.org の FAQを確認してください 。

エラーなどの改善があれば教えてください。

d07114915

于 2012-01-21T00:56:56.110 に答える
0

これを試して。ラップトップで完全にテストすることはできないので、動作する場合はお知らせください。その後、独自の関数を作成して、指定した入力タイプおよび/または目的のミキサーでPortMixer、 、ActualMixer およびを取得できます。TargateDataLine

private void testGettingInput() {
    //Check this out for interest
    //http://www.java-forum.org/spiele-multimedia-programmierung/94699-java-sound-api-zuordnung-port-mixer-input-mixer.html
    final String newLine = System.getProperty("line.separator");
    final String inputTypeString = "LINE_IN"; // or COMPACT_DISC or MICROPHONE etc ...
    final Port.Info myInputType = new Port.Info((Port.class), inputTypeString, true);
    final AudioFormat af = new AudioFormat(
            Encoding.PCM_SIGNED,
            44100.0F,
            16,
            2,
            2 * 2,
            44100.0F,
            false);
    final DataLine.Info targetDataLineInfo = new DataLine.Info(TargetDataLine.class, af);
    TargetDataLine targetDataLine;

    //Go through the System audio mixers
    for (Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) {
        try {
            Mixer targetMixer = AudioSystem.getMixer(mixerInfo);
            targetMixer.open();
            //Check if it supports the desired format
            if (targetMixer.isLineSupported(targetDataLineInfo)) {
                System.out.println(mixerInfo.getName() + " supports recording @" + af);
                //now go back and start again trying to match a mixer to a port
                //the only way I figured how is by matching name, because 
                //the port mixer name is the same as the actual mixer with "Port " in front of it
                // there MUST be a better way
                for (Mixer.Info mifo : AudioSystem.getMixerInfo()) {
                    String port_string = "Port ";
                    if ((port_string + mixerInfo.getName()).equals(mifo.getName())) {
                        System.out.println("Matched Port to Mixer:" + mixerInfo.getName());
                        Mixer portMixer = AudioSystem.getMixer(mifo);
                        portMixer.open();
                        portMixer.isLineSupported((Line.Info) myInputType);
                        //now check the mixer has the right input type eg LINE_IN
                        if (portMixer.isLineSupported((Line.Info) myInputType)) {
                            //OK we have a supported Port Type for the Mixer
                            //This has all matched (hopefully)
                            //now just get the record line
                            //There should be at least 1 line, usually 32 and possible unlimited
                            // which would be "AudioSystem.Unspecified" if we ask the mixer 
                            //but I haven't checked any of this
                            targetDataLine = (TargetDataLine) targetMixer.getLine(targetDataLineInfo);
                            System.out.println("Got TargetDataLine from :" + targetMixer.getMixerInfo().getName());
                            return;
                        }
                    }
                }
                System.out.println(newLine);
            }
            targetMixer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
于 2012-01-20T09:39:35.237 に答える
0

TargetDataLineクラスに慣れてください。また、独自の Javadoc から:

ターゲット データ行は、適切な DataLine.Info オブジェクトを指定して Mixer の getLine メソッドを呼び出すことにより、ミキサーから取得できます。

具体的には、 も確認Mixer.getTargetLineInfo()し、返された出力を調べて、探しているライン入力ポートに一致するラインを選択します。

于 2011-12-27T20:07:05.400 に答える