SMFプレイヤーをつくろう!リベンジ「出力ポート、MIDIと周波数の関係」

ツール制作
スポンサーリンク

はじめに

いくつか機能とかコード修正したのでその紹介をします。

変更点について

Sequencerのインターフェースにメソッド名に似せる

入れ替えとか、いつかクラスを公開時に役立ちそう。

Sequencerにあった、ティック単位の位置調節の追加

内部では、ms単位で処理しているので、ティックから時間に変更するようなメソッドを追加しました。

メタイベント0x59の調情報取得

この調の情報。最初はノートオン時に反映させると思ってたのですが、必要ないことが判明。ただ単に、この調だよみたいなメモだったんですねこれ。

一応調が分かるように、昔愛用していたてきとーシーケンサを参考にしつつ次のようなテーブル作成して利用。フラット・シャープの数を表す1バイトは、1バイトの符号あり整数で、正負からフラットの数か、シャープの数か。また絶対値からその数が分かります。

keysignature_table = new String[2][];
//長調
keysignature_table[0] = new String[7*2+1];
keysignature_table[0][ 0] = "Cb";//フラット7つ
keysignature_table[0][ 1] = "Gb";//フラット6つ
keysignature_table[0][ 2] = "Db";//フラット5つ
keysignature_table[0][ 3] = "Ab";//フラット4つ
keysignature_table[0][ 4] = "Eb";//フラット3つ
keysignature_table[0][ 5] = "Bb";//フラット2つ
keysignature_table[0][ 6] = "F"; //フラット1つ
keysignature_table[0][ 7] = "C"; //
keysignature_table[0][ 8] = "G"; //シャープ1つ
keysignature_table[0][ 9] = "D"; //シャープ2つ
keysignature_table[0][10] = "A"; //シャープ3つ
keysignature_table[0][11] = "E"; //シャープ4つ
keysignature_table[0][12] = "B"; //シャープ5つ
keysignature_table[0][13] = "F#";//シャープ6つ
keysignature_table[0][14] = "C#";//シャープ7つ
//短調
keysignature_table[1] = new String[7*2+1];
keysignature_table[1][ 0] = "Abm";//フラット7つ
keysignature_table[1][ 1] = "Ebm";//フラット6つ
keysignature_table[1][ 2] = "Bbm";//フラット5つ
keysignature_table[1][ 3] = "Fm"; //フラット4つ
keysignature_table[1][ 4] = "Cm"; //フラット3つ
keysignature_table[1][ 5] = "Gm"; //フラット2つ
keysignature_table[1][ 6] = "Dm"; //フラット1つ
keysignature_table[1][ 7] = "Am"; //
keysignature_table[1][ 8] = "Em"; //シャープ1つ
keysignature_table[1][ 9] = "Bm"; //シャープ2つ
keysignature_table[1][10] = "F#m";//シャープ3つ
keysignature_table[1][11] = "C#m";//シャープ4つ
keysignature_table[1][12] = "G#m";//シャープ5つ
keysignature_table[1][13] = "D#m";//シャープ6つ
keysignature_table[1][14] = "A#m";//シャープ7つ

mはマイナー。

再生速度を調節するテンポ係数の追加

テンポを変更できるようになりました。これの実装は簡単。

メタイベント0x21のMIDIの出力ポート変更

めちゃくちゃ面倒だった。

例えば、ポートAとポートBが同じMIDIOUTを示していた場合、ポートBをポートAと同じMIDIOUT。つまり再利用しなくてはいけない。

他にも、OS内部では、「Microsoft GS Wavetable SW Synth」を指定した「Microsoft MIDI マッパー」をポートA。ポートBに「Microsoft GS Wavetable SW Synth」を設定した場合。実際内部では同じ音源なのですが、名前が違うので設定しようとするのですが、もちろんエラーが発生する。

エラーが発生したら、以前使用していた音源へ元に戻す機能がないといけないし。とにかく、簡単そうなのですが、厄介な問題があり大変でした。

まだない機能

何小節目/全体小節数、1小節の中のティック表示

TMIDI Playerにある機能。もともと、拍子の表示機能を追加してあるので、これらの機能簡単に実装できるのですが。

小節表示はいいかもしれませんが、それ以外の表示は不要かも。

ループポイント

SequencerでJava1.5から使えるようになった機能。

ただただ面倒。ゲームしか使い道ないし。Σ(・ω・`|||)!!えっ

今時、MIDIをBGMとかアプレットとかではいいかもしれないけど、アプリケーションとして配布なら.oggとか.mp3を使うほうが普通のような気がする。自分で使うようになったら、付けるかもしれない。

鍵盤表示

どれが鳴っているかノートオン情報を取得するメソッドは前々から用意してあります。(一時停止でノートオフするときのメモで用意してありました。といっても後から気がついたのですが、コントロールチェンジの123にAll Note OFFというのが未対応かも)

後は、GUI側の問題。これあると楽しそう。

MIDIと周波数の関係

MIDIのノートオンではどの範囲の周波数の音まで出せるのか調べてみました。もしかして、音源とか作るときに役立つかなと。

MIDIのノートオンの基本周波数の幅について

FFTで調べた結果、A4(0x45=69)が440Hz。

ということで、

12 * 5 + 0 = 60 = C4
12 * 5 + 1 = 61 = C#4
12 * 5 + 2 = 62 = D4
12 * 5 + 3 = 63 = D#4
12 * 5 + 4 = 64 = E4
12 * 5 + 5 = 65 = F4
12 * 5 + 6 = 66 = F#4
12 * 5 + 7 = 67 = G4
12 * 5 + 8 = 68 = G#4
12 * 5 + 9 = 69 = A4

で値としては、ノート番号(音の高さの値)が0x00から0x7F、0~127まで使えるので、

  • 一番下の音は、0x00 =  0 = 12 * 0 + 0 = C-1
  • 一番高い音は、0x7F = 127 = 12 *10 + 7 = G9

まで出せる。

ここで1オクターブは12個の音があり、音が1オクターブ上がると周波数が2倍になるので、

  • A4(0x45=69)が440Hz
  • A5(0x51=81)が880Hz。

ここで、ノート番号がxのときf(x)[Hz]の周波数の音が出るとしたら、


のような式で求めらるので、SMFではf(x=0x00) = 8.18[Hz] ~ f(x=0x7f) = 12543.85[Hz] の音の高さの設定があるということ。

周波数からSMFのノートオン番号へ戻す方法

逆に、周波数から、SMFのノート番号へ変換するときは、上の式の逆関数を利用するとよい。

これを使えば、自分の声の高さを調べて、その高さと同じ音をMIDIで流せるようになりますね。細かい基本周波数の部分は、ピッチベンドを使うとよいと思います。

おわりに

ここまでのソースコード

以前のブログへ SMFプレイヤーをつくろう!リベンジ「完成した」
続く… SMFプレイヤーをつくろう!リベンジ「言語の設定とキーボードの表示」

完成したJava製のSMFプレイヤーのダウンロード

コメント

  1. […] 周波数からMIDIノートナンバーへの変換は、 「SMFプレイヤーをつくろう!リベンジ「出力ポート、MIDIと周波数の関係」」で紹介しています。 […]

  2. […] といっても前回の段階でSMFの再生の最低限の機能は実装されているので、 […]

  3. […] 以前のブログへ SMFプレイヤーをつくろう!リベンジ「完成した」 次のブログへ  SMFプレイヤーをつくろう!リベンジ「出力ポートとMIDIと周波数の関係」 […]

タイトルとURLをコピーしました