質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.27%

  • C++

    2505questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

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

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 62

zakky79

score 3

五線譜を表示させ、模範演奏となる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) {
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

この関数の動作を支配する情報をデバッグプリントし、「何が期待動作であるか」に対して「実際にどのように動作しているか」を調べることをお勧めします。

動作を支配する情報のうちとりあえずopencvに関係しない部分

status
data1
data2
duration
index

の値の「関数が呼び出された際の値」「if文による判定後の値」がどうなっているかを確認しましょう。またopencvに関する以下の値については「期待通りの情報が渡ってきているかどうか」も大切です。極端な話colorが透明色なら論理が正しくてもNoteの音符は描画されませんし、note_xが画面外の座標を示していればこれまた期待通りの位置には描画されません。

楽譜の描画がうまくいきません

この表現では閲覧者には「うまくいかないのだろう」ということは分かりますが具体的に「何が期待通りでないか」が分かりません。音符がまったく描画されないのか、位置がおかしいのかタイミングがおかしいのか等々の手掛かりがありません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.27%

関連した質問

  • 解決済

    python,opencvで円弧型の部分にのみ処理をしたい

    Python,OpenCVともに使うのが初めてです。 現在、類似画像検索のようなものを作っています。 そこで、画像の一部(円弧型)にある処理(ただ白いpixelを数えるだけ)を

  • 解決済

    ビット演算を使った配列の初期化

    こんにちは 現在52枚のカードを使ったゲームを作成しています。 Sはスペード、Hはハート、Dはダイヤ、Cはクラブというようにアルファベット一文字を絵柄に見立てています。 下記

  • 解決済

    cakephp2系 サーバから最新の値を取得し表示する方法

    前提・実現したいこと 動画再生後、モーダルを出現させ、モーダル内にチェックボックスを表示させチェックを入れて送信ボタンをクリックすると親画面に戻り次の動画の表示とajaxで送られ

  • 解決済

    for in文 where修飾子

    swiftについて質問です。 配列に画像が何枚も入っているものとします。 private var images: [UIImage] = [] for (index,

  • 解決済

    特定の列に特定の文字列が入力されたら

    グーグルスプレッドシートで、指定の列に特定の文字列が入力されたら、行をグレイアウト、指定のセルに現在時間を入力しコピーして最終行の1行上に貼り付けしてコピー元の削除と言う動作をさせ

  • 受付中

    C:大きな数の計算方法,オーバーフロー回避

    C言語で3^80の計算をしたいのですが、数が大きすぎてオーバーフローしてしまいます。各桁ごとに配列を置けばいいのかとも思いましたが、いまいちよくわかりません。 解決方法が分かる方

  • 解決済

    PILで画像を円形に切り抜きたい。

    Mac OS Sierra Ver:10.12.1 Python Imaging Libraryを使用して画像を円形に切り取る を参考に画像を円形に切り抜きたい。 Work

  • 解決済

    swift3 2点間の座標から方向を求めるやり方

    はじめまして。今2点間の座標から現在地に対する目的地の方向を出したくあるコードを見つけたのですが、expected declarationのerrorが出てしまいます。 いったいど

同じタグがついた質問を見る

  • C++

    2505questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。