かなり難しいんじゃないでしょうか。
まずVBMP3ではおそらく無理だと思います。
なぜかというと、VBMP3のFFTは256バンド(512点サンプル)なので、44100Hzの音源の場合、周波数分解能が44100/2/256=86.13Hzとなります。
http://www.palm.org/f_pal/f_pal_special/sp011_pyrol_scale.html を見ると分かるように、これでは音階を区別するのに(特に低音部で)全然足りないことになります。
最大4096バンド(8192点サンプル)までのFFTが可能な、bass.dllというFreeの音楽再生ライブラリがあります。
周波数分解能は44100/2/4096=5.38Hzまで向上します。
試しにこれを使って音階を表示するプログラムを作ってみましたが、それでもWaveGeneなどで人工的に作成した和音を判別するのが精一杯で、
いろいろな音が混ざっている実際の音楽のコード判別となるとちょっと無理な感じです。
この先は、さらに周波数分解能を上げる(低音部では5.38Hzでもきつい)か、
音楽理論に基づいてアルゴリズムを工夫する必要があると思います。
#module
#defcfunc todouble int p1
temp = 0.0
lpoke temp, 4, (p1 & 0x80000000) | (((p1 & 0x7fffffff) >> 3) + ((p1 & 0x7fffffff) ! 0) * 0x38000000)
lpoke temp, 0, p1 << 29
return temp
#global
// 参考 : http://sprocket.babyblue.jp/html/hsp_koneta3.htm#tofloat
#uselib "bass.dll"
#func BASS_Init "BASS_Init" sptr, sptr, sptr, sptr, sptr
#func BASS_Free "BASS_Free"
#func BASS_StreamCreateFile "BASS_StreamCreateFile" sptr, sptr, sptr, sptr, sptr
#func BASS_StreamFree "BASS_StreamFree" sptr
#func BASS_ChannelPlay "BASS_ChannelPlay" sptr, sptr
#func BASS_ChannelStop "BASS_ChannelStop" sptr
#func BASS_ChannelGetData "BASS_ChannelGetData" sptr, sptr, sptr
#define BASS_DATA_FFT8192 $80000005 // 8192 sample FFT
onexit *Exit
screen 0, 20 * 39, 480
dim buf, 4096//FFTデータ取得バッファ
dim onkai, 39//39の音階の周波数
onkai(0) = 110.0
repeat 39 - 1
onkai(cnt + 1) = onkai(cnt) * 1.05946309436
loop
dim index, 39//39の音階がそれぞれFFTバッファの何番目の要素に対応するか
i = 0
repeat 4096
if (onkai(i) >= (double(44100) / 2 / 4096 * (double(cnt) - 0.5))) & (onkai(i) < (double(44100) / 2 / 4096 * double(cnt + 1) - 0.5)) {
index(i) = cnt
i++
if i >= 39 { break }
}
loop
dim kokken, 39//黒鍵テーブル
kokken = 0,1,0, 0,1,0,1,0,0,1,0,1,0,1,0, 0,1,0,1,0,0,1,0,1,0,1,0, 0,1,0,1,0,0,1,0,1,0,1,0
dim onmei, 39//音名テーブル
onmei = "F#","G","G#", "A","B","H","C","C#","D","D#","E","F","F#","G","G#", "A","B","H","C","C#","D","D#","E","F","F#","G","G#", "A","B","H","C","C#","D","D#","E","F","F#","G","G#"
//鍵盤描画
color 0, 0, 0
font "MS UI Gothic", 8
line 20 * 39, ginfo_winy - 150, 0, ginfo_winy - 150
repeat 39
color 0, 0, 0
line 20 * cnt, ginfo_winy, 20 * cnt, ginfo_winy - 150
if kokken(cnt) = 1 { boxf 20 * (cnt + 1), ginfo_winy, 20 * cnt, ginfo_winy - 150}
color 128, 128, 128
pos 20 * cnt + 5, ginfo_winy - 30
mes onmei(cnt)
pos 20 * cnt + 1, ginfo_winy - 20
mes strf("%3.1f", onkai(cnt))
pos 20 * cnt + 5, ginfo_winy - 10
mes index(cnt)
loop
//ファイル選択
dialog "wav;*.mp3", 16, ""
if stat = 0 { end }
fileName = refstr
//初期化&再生
BASS_Init -1, 44100, 0, hwnd, 0
BASS_StreamCreateFile 0, varptr(fileName), 0, 0, 0
hStream = stat
BASS_ChannelPlay hStream, 1
*Main
//FFTデータ取得
BASS_ChannelGetData hStream, varptr(buf), BASS_DATA_FFT8192
redraw 0
color 255, 255, 255 : boxf 0, 0, ginfo_winx, ginfo_winy - 150 - 1
//各音階に対応するFFTバッファの要素の値の大きさをグラフで描画
repeat 39
color 255, 0, 0
val = int(todouble(buf(index(cnt))) /*+ todouble(buf(index(cnt) - 1)) * 0.5 + todouble(buf(index(cnt) + 1)) * 0.5*/ * 500) //多少の周波数のずれは認めたほうがいいかも?(/*〜*/内)
boxf 20 * cnt + 5, ginfo_winy - 160, 20 * cnt + 5 + 10, ginfo_winy - 160 - val
loop
redraw 1
await 1
goto *Main
*Exit
BASS_ChannelStop hStream
BASS_StreamFree hStream
BASS_Free
end