合計 昨日 今日

電子ドラムで叩いた音の楽譜の描画

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Name: zakky
[URL]
Date: 2018年1月10日(水) 15:38
No: 1
(OFFLINE)

 電子ドラムで叩いた音の楽譜の描画

五線譜を表示させ、模範演奏となるmidiファイルを読み込ませ、その楽譜を五線譜に表示させようと思っています。そこに、電子ドラムで叩いた音をリアルタイムに表示させて、模範演奏と自分の演奏のタイミングのずれを可視化させようと考えています。midiファイルを読み込んで、模範演奏を流すことはできますが、楽譜の描画がうまくいきません。電子ドラムも同様に、リアルタイムにドラムからメッセージ0x99 0x2B 0x00といった3バイトが送られてきます。(何も叩かないときは常に0xF8、たまに0xFEが送られてきます。)元々はピアノで実装されていたプログラムで、それを使ってドラム用に変更させようとしています。ピアノの場合はmidiファイルの演奏の楽譜の表示はうまくいっていました。

問題となっている部分のプログラムだけ抜粋して貼り付けています。

コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
void PutNote(cv::Mat& sheet, unsigned char status, unsigned char data1, unsigned char data2, long duration, cv::Scalar color, int note_x, int& index) { //音符の配置
 
    if ((status & 0xF0) == 0x90 && ((status & 0x0F) == 9 || data2 != 0x00))    {
 
        if (data1 == (0x18 + NOTE_OFFSET)) { // Do C
            index = 0;
        }
        else if (data1 == (0x1A + NOTE_OFFSET)) { // Re D
            index = 1;
        }
        else if (data1 == (0x1C + NOTE_OFFSET)) { // Mi E
            index = 2;
        }
        else if (data1 == (0x1D + NOTE_OFFSET)) { // Fa F
            index = 3;
        }
        else if (data1 == (0x26 + NOTE_OFFSET)) { // So G
            index = 4;
        }
        else if (data1 == (0x21 + NOTE_OFFSET)) { // Ra
            index = 5;
        }
        else if (data1 == (0x23 + NOTE_OFFSET)) { //Shi
            index = 6;
        }
        else if (data1 == (0x24 + NOTE_OFFSET)) { // Do
            index = 7;
        }
        else if (data1 == (0x1F + NOTE_OFFSET)) { // Re
            index = 8;
        }
        else if (data1 == (0x28 + NOTE_OFFSET)) {
            index = 9;
        }
        else if (data1 == (0x19 + NOTE_OFFSET)) {
            index = 10;
        }
        if (index != -1) {
            if (duration == 120) {
                cv::ellipse(sheet, cv::Point(note_x, note_y[index]), cv::Size(NOTE_W, NOTE_H / 2), NOTE_ANGLE, 0, 360, color, -1);
            }
            else if (duration == 240) {
                cv::ellipse(sheet, cv::Point(note_x, note_y[index]), cv::Size(NOTE_W, NOTE_H / 2), NOTE_ANGLE, 0, 360, color, 2);
            }
            else {
            }
        }
    }
    else if (status == 0x80 || data2 == 0x00) {
    }
}

Name: みけCAT
[URL]
伝説なるハッカー(690,092 ポイント)
Date: 2018年1月11日(木) 00:31
No: 2
(ONLINE)

 Re: 電子ドラムで叩いた音の楽譜の描画

zakky さんが書きました:模範演奏を流すことはできますが、楽譜の描画がうまくいきません。

解決したければ、具体的に「どうなってほしいのに」「どうなってしまう」のかを教えていただけるとありがたいです。

zakky さんが書きました:電子ドラムも同様に、リアルタイムにドラムからメッセージ0x99 0x2B 0x00といった3バイトが送られてきます。(何も叩かないときは常に0xF8、たまに0xFEが送られてきます。)

0x99 0x2B 0x00は、「9番目のチャンネルでノートオン、ノートナンバーは0x2B、ベロシティは0x00」という意味ですね。
0xF8は同期信号で4分音符1個あたり24回送られ、0xFEは機器が生きていることを示す信号らしいです。

SMF(Standard MIDI File)フォーマット解説 | 技術的読み物 | FISH&BREAD
Summary of MIDI Messages

zakky さんが書きました:問題となっている部分のプログラムだけ抜粋して貼り付けています。

引数の意味は何か(MIDIデータとどう対応するか)、NOTE_OFFSETとは何かなど疑問が多いですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Name: zakky
[URL]
Date: 2018年1月11日(木) 00:37
No: 3
(OFFLINE)

 Re: 電子ドラムで叩いた音の楽譜の描画

分かりやすくもう一度投稿し直します。


Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[19人]