7

私はバイノーラルビートでいくつかの作業を行っており、わずかに異なる周波数で2つのサウンドを再生できるJavaアプリケーションを構築しようとしています...約25〜30Hzの違いです。

完璧な世界では、Java に 2 つの整数入力、たとえば 440 と 410 を与え、Java に 440Hz トーンと 410Hz トーンを再生させたいと考えています。

私がjavax.sound.*クラスで見たことを考えると、Java はピアノの音と同等のものしかサポートしていないようです... A4 @ 440Hz、次に A-sharp-4 @ 466.164Hz、そして反対方向では G-sharp-4 @ 415.305Hz。「隣接」は通常、バイノーラル ビートを生成する範囲内ですが、トーンの周波数をより細かく制御しようとしています。

単純なオーディオ合成は周波数、強度、および時間の長さにすぎないため、 Java に「A4」を再生するように指示すると、クラスの腸のどこかに、ある種のルックアップがあるように見えjavax.sound.*ます。 440Hz。問題は、そのテーブルをハックして、「A4.1」が 449Hz に相当すると言う方法があるかどうかです。

私は をいじっていますjavax.sound.midiが、まだ調査しjavax.sound.sampledていません。sampledクラスを使用するには、トーンをサンプリングする必要があるようです。私は合成するほうが好きです。私が間違っている場合は、私を正しく操縦してください。

私が見たサードパーティのインターフェイスのほとんどは、特に音楽の制作と操作を目的としており、微分音を扱う能力が限られています。ソリューションの経験や推奨事項はありますか?

4

2 に答える 2

5

javax.sound.sampled.*;のクラスを使用して、サンプルを生成し、それらをサウンドカードに送信できます。基本的にソフトウェア発振器を作成します。

ある程度の知識が必要ですが、それを機能させると本当に楽しいことがあります;)

これを作成したとき、私はこれらのクラスで遊んでいました:http: //bobusumisu.net/testing/bobusynth-alpha1/

これが私を始めたチュートリアルです:http ://www.drdobbs.com/jvm/230500178

于 2012-05-24T00:08:02.027 に答える
4

これは、すでに提供され、受け入れられている回答を補足するためのものです (+1 を付けました)。

オンザフライでトリガー関数を実行する代わりに、ウェーブテーブルを使用できます。つまり、半分サンプリング/半分合成のようなものです。また、FM シンセシス用に 6 つの独立したカーソルを指す正弦波テーブルを使用し、この方法でいくつかの Yamaha DX7 パッチを複製しました。しかし、これはすべて javax.sound.sampled を介して行われます。ソフト シンセが構築されたら、MIDI ライブラリ クラスを使用してそれを制御したい場合があります。

1K 配列に 1 つの正弦波の浮動小数点数を入力するとします。

ウェーブ テーブルをインクリメントしてループし、各配列メンバーを順番に抽出して (SourceDataLine を介してサウンド カードに書き込むことによって) ウェーブ テーブルを「再生」すると、サンプル レートに直接関係するピッチが得られます。1 秒あたり 44100 サンプルの場合、1024 メンバーの配列は 44100/1024 = 43.066... 回循環して、その「秒」をデータで埋めます (非常に低いピッチ -- 約 43 Hz)。2 つおきのテーブル メンバーをスキップすると、ピッチはその 2 倍になります。ピッチ 440 を取得するには、ウェーブ テーブル配列をステップ実行するために使用する正しい「増分」を見つける必要があります。の waveTable * 希望のピッチ) / サンプルレート

たとえば、(1024 * 440 ) / 44100 の増分は 10.21678... したがって、waveTable の最初の値が配列位置 0 にある場合、使用される 2 番目の値は位置 10 と 11 の間になります。 2 つの配列位置の間にある値の場合、線形補間を使用します。

このリンクの「テルミン」には、javax.sound.sampled ライブラリでこのメソッドを使用します。キーボードが表示されていますが、マウスをキー上で動かすと、微分音のコントロールを簡単に聞く/見ることができます。

http://www.hexara.com/VSL/JTheremin.htm

上記では、マウスの位置 (MouseMotionListener を介して呼び出される) を使用して、この関数を介して目的のピッチを計算します。

return Math.pow(2, ((mouseX + tuningLoc) / (octaveWidth)));

ここで、octaveWidth は 1 オクターブをカバーするピクセル数です。

于 2012-05-24T20:44:09.140 に答える