楽譜情報処理

音の高さの表示ソフト drawwaveの紹介2

投稿日: 更新日:


音の高さの表示ソフト drawwaveの紹介」の続きです。

前回はバージョン0.035の紹介でしたが、
あれからバージョンアップしたので新しい機能とかを紹介していきます。p(´∇`)q

まずは、いつも通りのメイン画面です(^o^)

ボタンの配置と色が前と変わっています。
「Wave」というボタンが追加されたみたい……。

これを押すと……。

音声波形が表示されました(。>ω<)
以前、drawwaveとwaveが名前にあるのに、音声は波形が見られない><
とか言ったやさきに、機能追加です。

他に、音高のキーボード表現もついてました。
メニューバーの 表示(V) → キーボード(K) です

以前消化した↓のように線表示もいいけど、やっぱりキーボードの方が直感的で分かりやすいです(。>ω<)
押したところも赤くなるから、分かりやすいですし。

キーボードの設定は、こんな感じでした。

なんと、MIDI出力がついています。
これでマイクから喋った声をMIDI信号に変換できますね。

音声波形の表示設定は、無難にこんな感じ。

キーボードの表示設定はこんな感じ。

1オクターブのみ表示にチェックを入れると、低いドも高いドも同じ鍵盤に表示されるモードになります。
鍵盤の大きさは0.5倍~10倍まで設定できます。

10倍に設定するとこんな感じ。Σ(・ω・`|||)でかっ!

ところで、drawwaveのOUTとシーケンサのINを、MIDI Yokeなど仮装デバイスでつなげると、
喋った声で、*.midを作成できます。あんまり、うまくいかないけどね。(。・ε・。)ムー

ところで、音の高さを正確に出すおすすめ設定をここで紹介しておきます。
↓以前のスクリーンショットを使って説明。

シフト長を0.001ぐらいにして、メディアンフィルタの大きさを12ぐらいに設定する。
これで結構、音の高さを正確に拾えると思います。

これでdrawwaveの紹介2を終わります!
ちなみにこのdrawwave、まだまだ調整中です。

drawwaveのダウンロードページへ

広告

音の高さの表示ソフト drawwaveの紹介

投稿日: 更新日:


音の高さを調べるソフトといえば、「おんかいくん」などが上げられますが、
今日はJavaで製作された「drawwave」というソフトを紹介します。(*^U^*)

何をするソフトかというと、リアルタイム(実時間)で音声を目で見るソフトです。
音声の波形を描く ということで draw wave というわけです。

まずは、メイン画面です。(o^∇^o)ノ

赤いボタンは、おなじみの録音ボタンです。これを押すと解析が始まります。
(現在、解析中なので赤く光ってます!!)
緑のボタンは、音圧レベルを解析するときのキャリブレーションを行うためのボタンです。
(アイコンが分かりづらい上、このボタンは消える可能性も。)
青いのは、設定ボタンです。色々いれます。
SPLは、「Sound Pressure Level」の略で音圧レベルの表示ウィンドウを表示します。
Pitchは、音高基本周波数)の表示ウィンドウを表示します。

つまり、「音圧レベル」と「音高」を調べることができます。
(将来機能増えることもあると思いますが)
ということは、drawwave と言う名前なのに、音声波形の表示はサポートしていないのです。εミ(っ>_<)っ

言語機能で、日本語を選べます。
←解析していない場合は、赤いボタンが点灯していません!
辞書ファイルはxmlで、
決められた書式にのっとって作成した辞書ファイルを
同ディレクトリに置けば対応言語を増やすことが出来ます。

では早速、解析中のウィンドウを紹介していきます。

これが音圧レベルです。

音の大きさをデシベルで表示します。目盛りがついていて分かりやすいですね。
時間軸もあるので、どんな感じで音圧レベルが変わっていくか分かります。
また、騒音計のように動特性があります。

次は、音の高さの表示ウィンドウです。

音の高さは、1音のみに対応しています。
表示形式は色々と設定できて、上のやつはMIDIノートナンバーで高さを表現しています。
ピアノでC4(60)を鳴らしているのですが、60.2と大体あっていますね。
周波数からMIDIノートナンバーへの変換は、
SMFプレイヤーをつくろう!リベンジ「出力ポート、MIDIと周波数の関係」」で紹介しています。
ちなみに音の高さなのですが、1オクターブの間違いが結構あったりする。

次は設定の紹介です。

デバイス→波形入力です

デバイスは、使用する音声入力用デバイスを変えることが出来ます。
チャンネルでは、そのデバイスの両チャンネル(モノラル)、Lチャンネル、Rチャンネルと選ぶことが出来ます。
FireFace 800とか大きなオーディオインターフェイスだと「Analog (9+10) (RME Fireface 800)」など、
LとRとで別々の入力があるので、こういう設定は助かります。

音圧レベルの設定ウィンドウです。

動特性は、騒音計と同じように、FAST(=125[ms])とSLOW(=1000[ms])とで変更が可能です。
同じく騒音計と同じように、A特性高域強調IIRフィルタを通した後に表示しています。
といっても、マイクの周波数特性は考慮していないので、騒音計代わりに使う場合は、考慮する必要があります。
さらに、周波数別感度が±0[dB]である1[KHz]のサイン波で、キャリブレーションする必要があります。

音の高さの設定です。

アルゴリズムは、基本ケプストラムを利用しているのですが、
FFTからケプストラムを求める方法と、LPCから求める方法の2種類選択できます。
メディアンフィルタの大きさを変えることで、誤表示を減らすことも出来ます。

最後に、表示の設定

結構いろいろと設定できます。
音の高さの表現では、MIDIノートナンバー以外に、
基本周波数表示や、オクターブセントメルスケールでの表示が可能です。

続く「音の高さの表示ソフト drawwaveの紹介2

drawwaveのダウンロードページへ

SMFプレイヤーをつくろう!リベンジ「言語の設定とキーボードの表示」

投稿日: 更新日:


久しぶりにSMFプレイヤーの更新。
といっても前回の段階でSMFの再生の最低限の機能は実装されているので、
今回は表示関連を中心に。

まずは、言語の設定。

生まれて初めて、言語の設定を行えるような機能追加をしました。(=o・ω・o)
ほら、これからは日本以外にも視野を広げる時代ですから。はい。
実装としましては、言語の設定は、辞書式にしました。
辞書ファイルはカレントディレクトリにある*.langファイルを自動で検索。
また、リソースファイルの*.langを指定して選択できるように。
辞書ファイルの中身は、xmlです。といっても、JavaのPropertiesクラスを利用して実装しただけですが。
xmlにすると何が嬉しいかというと、辞書ファイルのエンコードを指定できるという点です。
Javaは通常Unicodeなので、設定ファイルもUnicodeで書かないといけないですが、
XMLでShift_JISと設定すれば、Unicode対応していないテキストエディタでも書き換えたりできますし。
ソフトの再起動しなくても、言語が変更されるところがこだわりポイント(*^U^*)
ほら、よく言語の設定をすると、ソフトの再起動が要求されるのとかあるじゃないですか。Timidity++とか。

次は、以前予告?していたキーボード。

キーボード。といってもチャンネル番号やら、使用している楽器などは表示していません。
上からチャンネル1~16と。ポートAしか表示してません。
キーボードの1つ1つが、キーボードクラスになっています。o(≧ω≦;)o
しかも、その1つ1つがスレッドを持って描写しているという設計。
ほら、キーボード1つのみ利用したいとかそういう場合に再利用できるし。
鍵盤の大きさも、横の鍵盤数も自由に設計できるようになってます。
出来る限り柔軟に柔軟に。ヾ(。・ω・。)
そういえば、描写の際に白鍵盤を先に描写してから、黒鍵盤を描写しないといけなくて、ちょっと面倒だった。
描写用のクラスは、以前作成したゲーム描写用の下地のクラスを利用しているので結構高速動作。
鍵盤の画像コピーも自前処理してます。
もっと高速にするには、やっぱり白鍵盤3種類作って、押した時と離した時のみ描写しないといけないかな。
ちなみに、このキーボードは全体を1回1回、目標fps10で描写しなおしてます^^;
鍵盤は以外にfpsゆっくりでも気にならないものですね。

後いい加減に、ホームページからダウンロードできるように設定。

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

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

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のノートオンではどの範囲の周波数の音まで出せるのか調べてみました。
ほら、もしかして、音源とか作るときに役立つかなと。

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のノート番号へ変換するときは、
上の式の逆関数を求めて、こんな感じに。

これを使えば、自分の声の高さを調べて、その高さと同じ音をMIDIで流せますね。
微妙なところはピッチベンドとか使うとして。

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

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

SMFプレイヤーをつくろう!リベンジ「ボリューム調節をつけよう」

投稿日: 更新日:


ボリューム調節をつけました。

MIDIでボリュームをいじる時はどうすればいいでしょうか。
1、デバイスのMIDIボリュームをいじる。
2、チャンネル全部にVolume(コントロールチェンジの0x07番)を送信。
3、チャンネル全部にExpression(コントロールチェンジの0x0B番)を送信。
4、SysExメッセージでマスターボリュームを制御。
5、ノートオンのベロシティを制御

方法は、いろいろあります。
問題は、Javaでどれを実装するかです。

「1」はおなじみの「Windows Media Player」がやらかす方法です。
なんかやらかすというと変な言い方なのですが、この方法を使うと次にMIDIデバイスを利用するソフト全部に及ぶというか。
まあ、「Windows Media Player」を終了させる時に、MIDIデバイスの音量を0にするという素晴らしいことをするので、
こんなのは些細なことなのですが。
いろいろ、意見がありましたが、Javaでは、デバイスの音量たぶん調節できないのでまず無理ということです。
(できるらしいです。海外のサイト調べてたらあった。)

「2」「3」これがまあ妥当な方法です。が実は罠があります。
なぜか受け付けないSMFが存在するという。
中みたら、SysExメッセージで色々書いてあって何やらしているようです。
うまくいくのもあるのですが、全部うまくいくとは限らないのでこれもパス。
ところで、「Volume」はチャンネルの音量。「Expression」は楽器の音量の違いらしいですよ。

「4」これは一番楽な方法。(^✹^)

でも…ごめん。「5」を採用してしまった。
なんというか、うん。特に意味ないです。

制御の方法なのですが、普通音量-30とかなら、現在の音量-30とか計算しそうですが、
こういう方法は自分としてはまずいと思います。
だって、人間の耳って指数とか感じる音量の変化があって線形じゃないんですよ。
あ、でももしかしたらMIDIの音量の設定ってそれもふまえて作ってあるのかな。
指数を利用して、現在の音量×e^-(0~2)みたいな式で音量調節することにしました。

それが上のです。うまく音量調節できてるかな。

ところでJavaのレイアウトはSpringLayoutが最強ですね。
めっちゃ使いやすい。あれっなんか前もこんなこと書いたような…。デジャブ?
あと、「Java Sound Synthesizer」の音にほれた。

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

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

SMFプレイヤーをつくろう!リベンジ「完成した」

投稿日: 更新日:


実は、昨日のうちにあっけなく完成。ワ――ヾ(o・ω・)ノ――イ
SMFプレイヤーをつくろう!リベンジ「セットテンポと分解能」の問題もいつのまにか全部解決してました。

というわけで、デバイスの設定とかできるようにして、とりあえずうん。

こんな感じ。
白い欄には、曲名・著作権情報・再生時間/長さ・拍:拍子・BPM・歌詞が表示されます。
シンセサイザーの一番の上のは、「Microsoft MIDI マッパー」マッパーがどうしても文字化けします。
「Java Sound Synthesizer」はJDK1.6使うと音聞こえるのに、JRE1.6の方使うと音でない。謎。
好みというか「Java Sound Synthesizer」は
「Microsoft GS Wavetable SW Synth」と違ってちゃんとリバーブ反映されてるようで音楽が綺麗。
対応していないの→調の設定・2ポート以上使用するSMF

下の●を動かせば、途中から再生とかも出来ます。

もう少しいろいろやってみたら、不評なJavaアプレットとかにしてみよう。[´・ω・`]

ところでJavaのレイアウトはSpringLayoutが最強ですね。
めっちゃ使いやすい。あれっなんか前もこんなこと書いたような…。デジャブ?

あと、Javaには、Receiverというのがあって、これを使えばMIDI音源とか作れるみたい。
いつか作ってみたいなあ。でも面倒そうだなあ。

以前のブログへ SMFプレイヤーをつくろう!リベンジ「拍子とタイムベース」
続く… SMFプレイヤーをつくろう!リベンジ「ボリューム調節をつけよう」

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

SMFプレイヤーをつくろう!リベンジ「拍子とタイムベース」

投稿日: 更新日:


今回は、現在再生中のSMFが、何分の何拍子のときに、何泊目を演奏しているか。
そういう情報を表示させる時の計算方法のメモです。

これらを計算するためには次のような情報を知る必要があります。
d 分の n 拍子の1拍は、デルタタイムでいうといくつになるか。
d 分の n 拍子の1小節は、デルタタイムでいうといくつになるか。

基礎知識として、
7/4(4分の7拍子)の場合は、1小節に分子の7拍もつということです。
また、1拍は、分母の4分音符が基本になっています。(分母は必ず2のn乗(0≦n)となる)
つまり、1小節は、4分音符が7つ分の長さあるということです。

タイムベースは、以前のメモより、4分音符の長さが基本となっています。
よって、タイムベースを x とおくと。
2分音符の長さは 2x
4分音符の長さは x
8分音符の長さは x/2
のようになっていくわけです。

というわけで、拍子の分母で、一番時間が長い2分音符の長さを y = 2x とおけば。
2分音符の長さは y/1
4分音符の長さは y/2
8分音符の長さは y/4

これらより、
d 分音符の長さは y /(d /2)=2y /d =4x /d なので、
d 分の n 拍子の1拍は、デルタタイムでいうと     4*timebase /d
d 分の n 拍子の1小節は、デルタタイムでいうと  4*timebase*n /d

あとは、1デルタタイムごとに、これらをふまえて計算していけば、
1小節の何拍目を演奏しているか分かります。

以前のブログへ SMFプレイヤーをつくろう!リベンジ「セットテンポと分解能」
続く… SMFプレイヤーをつくろう!リベンジ「完成した」

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