トップ | puarts.com
ロゴ
「MIDI」に関連する記事一覧
0  

あまり需要ないかもしれませんが、MIDIノートの値から音階名を文字列で取得する関数を作ったので載せておきます。


void GetMidiNoteAsString(char *o_midi_note_as_string, int midi_note)
{
    const char* ScaleAsString[] = {
        "C",
        "C#",
        "D",
        "D#",
        "E",
        "F",
        "F#",
        "G",
        "G#",
        "A",
        "A#",
        "B",
    };

    int scale_index = midi_note % 12;
    int octave_offset = -1; // 国際式は-1、YAMAHA式は-2
    int octave = midi_note / 12 + octave_offset; 
    sprintf(o_midi_note_as_string, "%s %d", ScaleAsString[scale_index], octave);
}

周波数(Hz)からMIDIノートを取得するC++関数を載せておきます。
http://en.wikipedia.org/wiki/MIDI_Tuning_Standard の式をそのまま書いただけですが。


int GetMidiNoteFromFrequency(float frequency_as_hz)
{
    return static_cast<int>(69.0f + 12.0f * log2f(frequency_as_hz / 440.0f) + 0.5f);
}

WindowsでデバイスIDが0のMIDIインプットデバイスからノートオンイベントが送られてきた(キーボードなどのキーが押された)ときの音階と押された強さ(ベロシティ)を返すC++プラグラムのソースコードです。

無限ループしているので、終了はできなくなっています。



#include <stdio.h>

#include <windows.h> 
#include <mmsystem.h> 

#pragma comment(lib, "winmm.lib")

void CALLBACK MidiInProc(
    HMIDIIN midi_in_handle, 
    UINT wMsg, 
    DWORD dwInstance,
    DWORD dwParam1, 
    DWORD dwParam2
) 
{
    switch (wMsg) 
    {
    case MIM_OPEN:
        printf("MIDI device was opened\n");
        break;
    case MIM_CLOSE:
        printf("MIDI device was closed\n");
        break;
    case MIM_DATA:
        {
            unsigned char status_byte = (dwParam1 & 0x000000ff);
            bool is_noteon_event = status_byte == 0x90;
            if( !is_noteon_event )
            {
                break;
            }
            unsigned char velocity = (dwParam1 & 0x00ff0000) >> 16;
            bool is_pressed = velocity != 0;
            if( !is_pressed )
            {
                break;
            }
            unsigned char note = ( dwParam1 & 0x0000ff00 ) >> 8;
            printf("MIM_DATA: wMsg=%08X, p1=%08X, p2=%08X\n", wMsg, dwParam1, dwParam2);
            printf("note = %u, velocity = %u\n", note, velocity);
        }
        break;
    case MIM_LONGDATA:
    case MIM_ERROR:
    case MIM_LONGERROR:
    case MIM_MOREDATA:
    default:
        break;
    }
}

int main(int argc, char** argv) 
{
    HMIDIIN midi_in_handle;
    MMRESULT res;
    UINT device_id;
    WCHAR errmsg[MAXERRORLENGTH]; 
    char errmsg_buff[MAXERRORLENGTH];

    device_id = 0u;

    res = midiInOpen(&midi_in_handle, device_id, (DWORD_PTR)MidiInProc, 0, CALLBACK_FUNCTION);
    if (res != MMSYSERR_NOERROR) {
        printf("Cannot open MIDI input device %u", device_id);
        return 1;
    } 

    printf("Successfully opened a MIDI input device %u.\n", device_id);

    midiInStart(midi_in_handle);

    while (true) {}

    midiInStop(midi_in_handle);
    midiInReset(midi_in_handle);
 
    midiInClose(midi_in_handle);

    return 0;
}

WindowsでMIDIインプットデバイスをリストアップをするだけのC++プログラムのソースコードです。


#include <stdio.h> 

#include <windows.h> 
#include <mmsystem.h>

#pragma comment(lib, "winmm.lib")

int main(int argc, char** argv) 
{
    MMRESULT result;
    MIDIINCAPS midi_in_caps;
    const s32 BUFF_SIZE = 32;
    char device_name_buff[BUFF_SIZE];
    unsigned int num_devices =  midiInGetNumDevs();

    printf( "number of devices: %d\n", num_devices);

    for( unsigned int dev_id=0; dev_id<num_devices; ++dev_id )
    {
        UINT cbMidiInCaps;
        result = midiInGetDevCaps(
                        dev_id,
                        &midi_in_caps,
                        sizeof(midi_in_caps)
                    );
        if (result != MMSYSERR_NOERROR) { continue; }

        errno_t error = wcstombs_s( 
            NULL, device_name_buff, BUFF_SIZE, 
            midi_in_caps.szPname, sizeof(midi_in_caps.szPname));
        if( error!=0 ){ continue; }

        printf("ID=%d: %s\n", dev_id, device_name_buff);
    }
	return 0;
}

MIDIのnote onイベントを検出して、note onがあったフレームにだけ白い画像を吐き出すようなプログラムを作り、そのプログラムで作成した連番画像の白い画像のフレームを適当に作ったアニメーション素材で置き換えてみました。

最終的にシンセで適当に弾いた即興曲にそれっぽい映像を簡単につけたいだけなんですが、その第一段階としてMIDIからトリガーとなる瞬間のマーカー画像を吐き出すところまで作りました。波形データでなく、MIDIを使うことにしたのは波形データからトリガーとなる瞬間を検出するのが難しそうだったからです。MIDIだと不要な音をシーケンサーで取り除けるのでトリガーにしたい音を絞ることが容易です。いつものように放置しなければ、何かしら音楽とシンクロナイズする映像作品を簡単に作れる仕組みができそうです。

私はMIDIシーケンサーとして8年ほど『音楽ツクールDX』というソフトを愛用しています。MIDIを制作するだけであれば最低限必要な機能はついていますし、使いやすさに関しても不自由を感じることはほとんどありません。対応している音源は古いものばかりですが音楽ツクールDXにない音源の音色制御は対応している別ソフトで行えば可能ですし、MIDI Yokeを使えばSound Fontの再生も可能です。

ただひとつだけ不満な点があって、他のMIDIの一部分をコピーしたいというときに、同時に複数のMIDIを開けないという仕様だったもので異なるMIDI間で部分的なコピーできずにすごく不便さを感じていました。あるMIDIを開いているときに別のMIDIを開くと今開いていたMIDIは強制的に閉じられてしまうのです。
昔作ったMIDIのドラムトラックだけ使いまわそうというのはよくあるので、そういうときにMIDIの部分的なコピーができないというのは苦しいものです。

しかし、ちょっとした裏ワザで複数のMIDIを同時に開くことが可能なことに気がつきました。

それは音楽ツクールDXの実行ファイルであるOngApp.exeファイルをコピーして起動し、音楽ツクールDXを複数立ち上げることです。

several_ongapp.gif

この状態で複数の音楽ツクールDXごとに別々のMIDIを開き、コピー&ペーストすることで、異なるMIDI間での部分的なMIDIのコピーが可能になりました。

もし未だに音楽ツクールDXを使っていて、同じことに不満を感じていた方がいたら是非試してみて下さい。
最近、大学の研究室で低コストで誰でも作曲ができるような作曲支援ツールを作りたいという学部生がいた関係で私もいろいろとMIDI関係で調べていました。

私は普段はYAMAHAのMotif-ESというシンセサイザーの音源を使って曲を作っているので、正直フリーのソフトウェア音源なんてどうせたいしたことはできないだろうと思っていました。

しかし、実際に調べてみると今ってフリーでSound Fontというデータフォーマットの音色データがたくさんネット上に公開されていて、これを使えばなかなかの高音質の音でMIDIを再生できてしまうんですね。実際にダウンロードして使ってみると想像以上の音質の良さに驚きました。音楽をやっていたのに今までこんないいものを知らなかったなんて。

ということで比較できるよう、通常のWindows 7に内臓されている音源とフリーで公開されているSound Fontを使ってショパンの別れの曲のMIDIを再生したものをアップしておきます。

こちらはWindows 7 に内臓されているMicrosoft GS Wavetable Synthのバイオリンで録音したもの


こちらはネットで拾ってきたバイオリンのSound Fontの音色で録音したもの

ちなみにこのSound FontファイルをダウンロードしたページのURLはこちらhttp://freesf2.com/page3/page2/page2.html


かなり音質の差がありますよね。正直毎回シンセサイザーを起動して接続しないと高音質の音が再生できないという状況が面倒だと思っていたので、サウンドフォントを使って作曲もありだなと思えます。
このサウンドフォントは結局自分でサンプリングした波形データの組み合わせなので、音質が良いものを使えばそれだけ質が上がるのは当然です。

音色はしょぼいものから高品質なものまで多種多様ということです。

メモリリソースはかなり食うようですが、今のPCのスペックからすれば数100MB程度ならたいしたことはないように感じます。

ちなみに再生にはTiMidity++というオープンソースソフトウェアを使いました。

このソフトとMIDI Yokeというソフトを連携させるとWindowsの標準MIDIデバイスをこのTiMidity++に設定できるようになるので、通常のMIDIをサウンドフォントの音色で再生することができるようになります。

ネットで調べればいくらでも情報があるので、具体的な導入方法はそちらを参照して下さい。ただWindows 7 64bitの情報はそんなになかったのですが、特に特別なことをしなくても私の場合はWindows 7 64bitに導入できたので問題ないと思います。

これを導入してから今まで自分で作ってきたMIDIファイルを再生しまくってみました。ピアノの音をよく使っていたので、ピアノの大幅な音質アップにはかなりテンションが上がります。

普段、MIDIをよく再生するが、音質に満足できていないという方は試してみる価値ありです。
0  

0.0217 sec
にほんブログ村 ゲームブログ ファイアーエムブレムへ にほんブログ村 デザインブログ コンピュータグラフィックスへ

Copyright(C)2006-2018 wsp All Rights Reserved