JAVAでMIDIサウンドを再生する

要点を説明する前に、コンピューターサウンドについて少し説明します。



コンピュータサウンドを再生するには、主に2つの形式があります。

デジタル(WAV形式)および合成( MIDI )。



デジタルサウンドは、今日のコンピューターサウンドの主要な標準です。 mp3形式の曲を再生したり、CDを聴いたり、映画を見たり、コンピューターゲームをプレイしたりするときに聞こえるデジタル化されたサウンドです。



デジタル化された音は、音の各瞬間における音波の振幅レベルの値を順番に記述するビットのセットです。 それを再生するとき、サウンドカードは「デジタル」サウンドを使い慣れた「アナログ」形式に変換するだけです。



しかし、別の種類のコンピューターサウンドがあります-合成(MIDI)



サウンドカードは、最大128種類の楽器の音を再生できる音楽シンセサイザーとして機能します。 楽器のシミュレーションの品質と原理は、サウンドカードによって異なります。 彼女は、単純な周波数のFM(周波数)ジェネレーターをいくつか組み合わせて、楽器の音をシミュレートしようとする場合があります。各ジェネレーターには、振幅、周波数、位相、その他のパラメーターが与えられます。 しかしより頻繁に、彼女はそこに保存されている楽器のサウンドサンプルの「データバンク」に目を向けます。



現在、 SoundFontで使用できるサウンドカードは多数あります。 これらは、サウンドカードにロードできるwavサンプルであり、これらの楽器の音はMIDIシーケンサーで制御できます。 通常、SoundFontの拡張子は.sf2で、パッチ(パッチ)またはプログラム(プログラム)と呼ばれることもあります。 いくつかのSoundFontはサウンドバンク(SoundFontバンク)に結合され、最大128のインストゥルメントと1組のドラムを含めることができます。

ネット上では、SF2形式のツールバンクの専門的なライブラリを簡単に見つけることができます。



シンセサイザーが目的のサウンドを再生するには、特別なコマンドを与える必要があります。 このようなコマンドのセットは、MIDI規格で記述されています。

MIDIは、Musical Instruments Digital Interfaceの頭字語で、文字通り楽器のデジタルインターフェイスを意味します。



これらのコマンドを使用して、サウンドカードシンセサイザーをどの楽器で演奏するかを「伝える」ことができます。 たとえば、ピアノや128種類の楽器のFシャープ。



何らかの目的で、Javaからノートを演奏する方法を学ぶ必要があるとしましょう。 そして、あなたはあなたのサウンドカードのシンセサイザーにそれをさせる方法を学ぶことに決めました。 検索エンジンによってインターネットの情報の海に飛び込んだ後、あなたは突然この問題に関する賢明な情報を見つけるのは容易ではないことに気付くでしょう。



midiで動作するのに十分なライブラリがあると言います。 そして彼らは皆、彼らの助けを借りて音楽のプログラミングのプロセスが簡単になることを約束します。 jfugueとjMusicの2つに出会いました。 YouTubeでの使用方法に関する視覚的なガイドラインがあります。 これらの各ライブラリでは、独自のメソッドとルールが考案されました。 ライブラリがエキゾチックであるほど、情報と例は少なくなります。 また、彼らの仕事の正確さと正確さを信頼する必要があります。

多くの理由から、学習を開始し、最初に標準ライブラリの使用方法を学習する方が良いと考えています: javax / sound / midi



このトピックに最初に出会った人のために、私の記事は最初の一歩を踏み出すのに役立つように設計されています。 最も基本的なMIDIサウンドスキルをお教えします。 そして、自分でアプリケーションを拡張し、必要に応じて、ライブラリ記述からの情報をインターネットからの例で簡単に補足できます。



だから、あなたが始める必要があるのは、ノートを演奏する方法を学ぶことです。

あなたの欲望にはいくつかの追加情報が含まれます-ノートの名前(番号)と音の長さです。 また、演奏したい楽器。

「特定の音を鳴らし、特定の時間と選択した楽器を鳴らしたい」という願望は非常に単純かつ明確に定式化されています。しかし、これを行う方法に関する正しい情報を見つけることは困難です。 この記事は、時間を無駄にせずに必要なものをすぐに入手できるように書かれた理由です。 そして、彼らは適用し始めました。



この表から判別できる番号に注意してください:





そして、ツール番号はここにあります



再生を直接プログラミングする前に、いくつかの準備が必要です。 つまり、Synthesizerオブジェクトを取得して開く必要があります。 次に、彼のチャンネルにアクセスします。

これは完全に明確ではないかもしれませんが、実際には、すべてが簡単です:

Synthesizer synth = MidiSystem.getSynthesizer(); synth.open(); MidiChannel[] channels = synth.getChannels();
      
      





このチャンネルは、128の楽器のいずれかを演奏できる普遍的なミュージシャンとして想像できます。 このようなチャネルは16個あります。

それが基本的に準備全体です。 次に、ミュージシャンにコマンドを与える方法を学ぶ必要があります。

最初のオクターブのFaノートを鳴らしたいとします。 これを行うには、音符の数を含む表を見ると、その数が65であることがわかります。16人のミュージシャンのいずれかを選択します。 0( チャネル[0] )の番号を付けてみましょう。 noteOnコマンドで再生が行われます。

2つのパラメーターが必要です。MIDIノート番号(0〜127)と音量(最大127)

次のようになります。

  channels[0].noteOn(65, 80);
      
      





このコマンドによれば、「ゼロ」の番号を持つミュージシャンは、最初のオクターブのFaノートを演奏し始めます。 80はボリュームです。 ミュージシャンがシンセサイザーのキーを押して、音が流れていることが想像できます。

音を止めるには、コマンドも必要だと思いました。 つまり このミュージシャン押されたキーを明確に離すように、 noteOffコマンドを実行します。

このように:

  channels[0].noteOff(65);
      
      





これらのコマンドの間で、一時停止する必要があります。一時停止は、サウンドの持続時間に依存します。

実際、それがすべてです。 また、サードパーティのライブラリは必要ありません。 これで、必要なものをすべて自分で簡単に作成できます。 「ミュージシャン」に別の音楽を取り入れさせる魔法の言葉を教えることは、最後の秘密をあなたに伝えることです。 ツール。

ここでツールを選択できることを思い出させてください。 128のインストゥルメントの1つを16のチャンネルのいずれかに割り当てることができます。 デフォルトでは、ほぼすべてのチャンネルでピアノが使用されます。

したがって、「バイオリン」ツールは「ゼロ」チャネルに割り当てられます。

  channels[0].programChange(41);
      
      





次の標準パッケージをインポートする必要があります。

  import javax.sound.midi.MidiChannel; import javax.sound.midi.MidiSystem; import javax.sound.midi.Synthesizer;
      
      







したがって、サウンドを再生するコードは次のようになります。

  try { Synthesizer synth = MidiSystem.getSynthesizer(); synth.open(); MidiChannel[] channels = synth.getChannels(); channels[0].programChange(41); channels[0].noteOn(65, 80); Thread.sleep(1000); // in milliseconds channels[0].noteOff(65); synth.close(); } catch (Exception e) { e.printStackTrace(); }
      
      







さらに、すでに述べたように、音声抽出のプログラミングの可能性は想像力によってのみ制限されます。



原始的なデモンストレーションでは、サウンドを再生する独自のメソッドを作成します。このメソッドは、単一のコマンドで押したり、一時停止したり、放したりします。 この目的のために、構造と機能を説明する必要のない別のクラスを用意しましょう。

 package music.player; import java.util.logging.Level; import java.util.logging.Logger; import javax.sound.midi.MidiChannel; import javax.sound.midi.MidiSystem; import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.Synthesizer; public class Player { private MidiChannel[] channels = null; private Synthesizer synth = null; public Player() { try { synth = MidiSystem.getSynthesizer(); synth.open(); channels = synth.getChannels(); channels[0].programChange(41); } catch (MidiUnavailableException ex) { Logger.getLogger(Player.class.getName()).log(Level.SEVERE, null, ex); } } public void close() { synth.close(); } public void playSound(int channel, int duration, int volume, int... notes) { for (int note : notes) { channels[channel].noteOn(note, volume); } try { Thread.sleep(duration); } catch (InterruptedException ex) { Logger.getLogger(Player.class.getName()).log(Level.SEVERE, null, ex); } for (int note : notes) { channels[channel].noteOff(note); } } }
      
      







シンセサイザーが作成され、クラスコンストラクターで開かれます。 チャンネルの配列を取得し、バイオリンツールを最初の(ゼロ)に割り当てます。

playSoundメソッドは、入力時に同時に鳴るチャネル番号、デュレーション、ボリューム、およびノー​​トのシーケンスを受け取ります。 実装は非常にシンプルです。すべての着信ノートが再生され、デュレーション間隔が保持され、その後すべてがオフになります。

このクラスの使用例は次のとおりです。4つのコードが演奏されます。

  Player player = new Player(); player.playSound(0, 1000, 80, 69, 72, 76); player.playSound(0, 1000, 80, 69, 74, 77); player.playSound(0, 1000, 80, 67, 71, 74); player.playSound(0, 1000, 80, 67, 72, 76); player.close();
      
      







さて、結論として、実験用に有名な美しいメロディーをプログラムしましょう。

コードをコピーして実行するだけで、「Jasper Forks-River Flows In You」を聞くことができます。

  int notes[][] = {{470, 81}, {230, 80}, {470, 81}, {250, -1}, {230, 80}, {470, 81}, {230, 69}, {230, 76}, {470, 81}, {230, 69}, {470, 74}, {470, 73}, {470, 74}, {470, 76}, {470, 73}, {470, 71}, {970, -1}, {230, 69}, {230, 68}, {470, 69}, {730, -1}, {230, 64}, {230, 69}, {230, 71}, {470, 73}, {970, -1}, {230, 73}, {230, 74}, {470, 76}, {730, -1}, {230, 69}, {230, 74}, {230, 73}, {470, 71}, {1450, -1}, {470, 81}, {230, 80}, {470, 81}, {250, -1}, {230, 80}, {470, 81}, {230, 69}, {230, 76}, {470, 81}, {230, 69}, {470, 74}, {470, 73}, {470, 74}, {470, 76}, {470, 73}, {470, 71}, {970, -1}, {230, 69}, {230, 68}, {470, 69}, {730, -1}, {230, 64}, {230, 69}, {230, 71}, {470, 73}, {970, -1}, {230, 73}, {230, 74}, {470, 76}, {730, -1}, {230, 69}, {230, 74}, {230, 73}, {470, 71}, {250, -1}}; Player player = new Player(); for (int[] note : notes) { if (note[1] != -1) { player.playSound(0, note[0], 80, note[1]); } else { try { Thread.sleep(note[0]); } catch (InterruptedException ex) { Logger.getLogger(Music.class.getName()).log(Level.SEVERE, null, ex); } } } player.close();
      
      





配列では、数値のペアに音の持続時間の値と音符の数が含まれています。 一時停止、違いのために、「マイナス1」と書きます。 チャンネルとボリュームはすべてのノートで同じになります-それぞれ0と80です。



さて、提示された資料を理解するのに苦労はなかったと思います。 この記事で、JAVAでMIDIサウンドを再生するためのプログラミングを簡単に開始できるようにして、時間と労力を節約できたら嬉しいです。



All Articles