#1
by zakky » 7年前
五線譜を表示させ、模範演奏となるmidiファイルを読み込ませ、その楽譜を五線譜に表示させようと思っています。そこに、電子ドラムで叩いた音をリアルタイムに表示させて、模範演奏と自分の演奏のタイミングのずれを可視化させようと考えています。midiファイルを読み込んで、模範演奏を流すことはできますが、楽譜の描画がうまくいきません。電子ドラムも同様に、リアルタイムにドラムからメッセージ0x99 0x2B 0x00といった3バイトが送られてきます。(何も叩かないときは常に0xF8、たまに0xFEが送られてきます。)元々はピアノで実装されていたプログラムで、それを使ってドラム用に変更させようとしています。ピアノの場合はmidiファイルの演奏の楽譜の表示はうまくいっていました。
問題となっている部分のプログラムだけ抜粋して貼り付けています。
コード:
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) {
}
}
五線譜を表示させ、模範演奏となるmidiファイルを読み込ませ、その楽譜を五線譜に表示させようと思っています。そこに、電子ドラムで叩いた音をリアルタイムに表示させて、模範演奏と自分の演奏のタイミングのずれを可視化させようと考えています。midiファイルを読み込んで、模範演奏を流すことはできますが、楽譜の描画がうまくいきません。電子ドラムも同様に、リアルタイムにドラムからメッセージ0x99 0x2B 0x00といった3バイトが送られてきます。(何も叩かないときは常に0xF8、たまに0xFEが送られてきます。)元々はピアノで実装されていたプログラムで、それを使ってドラム用に変更させようとしています。ピアノの場合はmidiファイルの演奏の楽譜の表示はうまくいっていました。
問題となっている部分のプログラムだけ抜粋して貼り付けています。
[code]
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) {
}
}
[/code]