はじめに
いくつか機能とかコード修正したのでその紹介をします。
変更点について
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プレイヤーをつくろう!リベンジ「言語の設定とキーボードの表示」
コメント
[…] 周波数からMIDIノートナンバーへの変換は、 「SMFプレイヤーをつくろう!リベンジ「出力ポート、MIDIと周波数の関係」」で紹介しています。 […]
[…] といっても前回の段階でSMFの再生の最低限の機能は実装されているので、 […]
[…] 以前のブログへ SMFプレイヤーをつくろう!リベンジ「完成した」 次のブログへ SMFプレイヤーをつくろう!リベンジ「出力ポートとMIDIと周波数の関係」 […]