0

JAVA で「ミキシング コンソール」を構築しようとしています。このミキサーでは、物理的なミキシング コンソールであるかのように、各「スライダー」がラインになります。しかし、Goo *** で検索してオラクルのドキュメントを読んだ後、実際に役立つものは何も見つかりませんでした。

最初に、使用可能なミキサーを一覧表示します (最後のコードを参照)。幸いなことに、すべてのサウンドカードが一覧表示され、ライン インとライン アウトが検出されます。しかし、その後、私は何をしなければなりませんか?

私の目的は、任意のライン イン (マイク) またはライン アウト (VLC で再生されるサウンドのキャプチャ) からのサウンドをキャッチする「仮想ライン」を作成し、「作業」してから別のラインに再注入できるようにすることです。 . もちろん、「in」と「out」をそれぞれの行に設定する必要があります。

  • (マイク)の3つの物理ラインがキャッチされ、「レベル調整」され、「コーラス」と呼ばれる仮想ラインに再注入され、この仮想ラインは「マスターレベル」と呼ばれるメインの物理ラインアウトに再注入されます。

  • VLC によって再生される曲 (曲のメロディーなど) は、通常はメインの "out" に直接送信され、"傍受" のようにキャッチされます。次に、マスターに再注入してミックスする前に、レベルを設定することにします。マイク付きなので、音楽のレベルに合わせて歌手のレベルを調整できます。

それで、誰が私が始めて進歩するのを助けることができますか? いつもお世話になっております。

私のミキサーをリストするコードは次のとおりです。

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Control;
import javax.sound.sampled.Line;
import javax.sound.sampled.Mixer;

public class Mixers {

Mixers() {      
    try {
        //List of the mixers from the system
        Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
        //Characteristics of each mixer
        for (Mixer.Info info : mixerInfo) {
            System.out.println("\n"+info+ " - Description : "+info.getDescription());
            Mixer mix=AudioSystem.getMixer(info);

            //Controles available for this mixer
            for (Control c:mix.getControls()) {
                System.out.println ("\t Control supported by this mixer : "+c);
            }
            //Sources available for this mixer
            for (Line.Info i : mix.getSourceLineInfo()) {
                System.out.println("\t Source line available : "+i);

                //Controls available for this Source
                for (Control c : AudioSystem.getLine(i).getControls()) {
                    System.out.println ("\t\t ==> Controls supported by this source : "+c);
                }
            }
            // TargeLines available for this mixer
            for (Line.Info i : mix.getTargetLineInfo()) {
                System.out.println("\t Target line available : "+i);

                //Controls available for this Target
                for (Control c : AudioSystem.getLine(i).getControls()) {
                    System.out.println ("\t\t Controls supported by this target : "+c);
                }
            }               
        }
    } catch (Exception e) {
        e.printStackTrace();
    }               
}

}

私の投稿を最後まで読んでくれて、解決策を教えてくれた人にもう一度感謝します。

ニコラス

4

2 に答える 2

1

これができれば、あなたが望んでいる次のステップは、さまざまなミキサーからデータを読み取り、「フレームごと」に操作を実行できるようになることだと思います。Java チュートリアルのオーディオのキャプチャでは、外部回線からのデータの読み取りについて言及しています。チュートリアルのUsing Files and Format Convertersには、個々のフレームに到達する方法を示すサンプル コードがあります。「Reading Sound Files」というヘッダーの下に、このためのサンプル コードがあります。最も重要な点は、次のコメントで示されています。

// Here, do something useful with the audio data that's 
// now in the audioBytes array...

あなたの場合、入力している行ごとに1つずつ、複数のauiodBytes配列があります。

ミックスするには、異なるラインからの PCM フレーム データを一緒に追加できます。ライン間のボリューム コントロールは、0 (無音) から 1 (フル ボリューム) までの係数などの乗数を使用して行うことができます。

1 つのフレームで乗数を変更しすぎないように注意する必要があります。そうしないと、データに導入された不連続性によってクリックが発生します。そのため、変更を複数のフレームに広げます。乗数の直線的な変化は、聞こえるオーディオ レベルと正確には一致しません。3次指数分布は、線形値と実際にそれらの値のように聞こえる同等の乗数との間の変換によく使用されると思います。PCM データが -1 と 1 の範囲外にならないように、最小関数と最大関数を入れたいと思うかもしれません。

バイトストリーム形式から PCM に変換する方法とその逆の方法を示すスタックオーバーフローに関する他の投稿があります。私の知る限り、このコードのソースである javax.sound.sampled は、ネイティブ コードに大きく依存しており、非常に低レベルです。私はこの方法でミキシングを行うことで多くのことを行うことができましたが、あなたが行おうとしているようにラインの外ではなく、私自身のデータ ソースに依存しています。これらの外部回線がどのように管理されているかはわかりません。特に、結果のミックスを再生しているときにコンピューターでそれらを再生しないようにしたい場合はそうです。

于 2015-12-20T21:48:18.447 に答える
0

JavaサウンドAPIでそれができるかどうかはわかりません。おそらく、サウンド ストリームをより細かく制御できる OpenAL (Java にはこれに対するバインディングがあります) など、はるかに下位の API を検討する必要があります。

于 2015-12-20T11:14:11.977 に答える