以下、本発明による演奏評価システムの実施形態について、鍵盤を備えた電子楽器、パソコン、およびカメラを組合わせた場合を例に採って説明する。
図1は、実施形態における演奏評価システムの外観図である。電子楽器1は、鍵盤2を備えているとともに、その背面側には、アングル3が取り付け部3aによって固定されている。アングル3の最上部には、鍵盤2の中心部と対応する位置にカメラ取り付け部4が設けられ、CCDやCMOSなどの撮像素子を有するカメラ5が取り付けられている。なお、図には示していないが、カメラ取り付け部4には、カメラ5の水平位置(図の左右方向および奥行き方向の位置)を調節する機構が設けられている。
電子楽器1の上面にはパソコン6が置かれている。ただし、パソコン6は図に示した位置に限定されない。比較的奥行きのある電子楽器の場合や、平面型の表示部と本体とが別体のパソコンの場合には、演奏者の正面の位置、例えば、アングル3の取り付け部3aの上に置くようにしてもよい。
図2は、電子楽器1、カメラ5、パソコン6の接続関係、および、パソコン6の内部構成を示すブロック図である。パソコン6のCPU11は、システムバスを介して、ROM12、RAM13、スイッチ部14、表示部15、MIDI・I/F(インターフェース)16、ビデオキャプチャ・I/F17、不揮発性メモリ18と接続され、各部との間でコマンドおよびデータの授受を行うことによって、このシステム全体を制御する。
ROM12は、CPU11によって実行される演奏評価処理のプログラムや初期データなどを記憶している。RAM13は、CPU11のワークエリアであり、CPU11によって処理されるデータを一時的に記憶する。スイッチ部14は、キーボードおよびマウスなどのポインティングデバイスで構成され、ユーザの操作に応じて、曲選択指令、再生指令、再生停止指令などのコマンドをCPU11に入力する。表示部15は、液晶ディスプレイやプラズマディスプレイなどで構成され、演奏評価処理のプログラムやその他のアプリケーションを起動させるメニュー画面、選択された曲データの楽譜などを表示する。MIDI・I/F16は、演奏ガイドのためにMIDI形式の曲データを電子楽器1に出力するとともに、電子楽器1からMIDI形式の演奏データを入力する。
ビデオキャプチャ17は、カメラ5に対してCPU11の制御コマンドを出力してカメラ5を制御し、カメラ5で撮像された画像データをCPU11に入力する。例えば、カメラ5の位置設定指令に応じて、撮像画像の位置調整、画角調整、フォーカス調整などを制御する。不揮発性メモリ18は、USBなどのコネクタを介して、着脱可能に装着された半導体メモリ、又はハードディスクなどで構成され、外部記憶媒体やネットワークを介してインストールされた演奏練習用の曲データを記録するメモリである。
次に、CPU11によって実行される演奏評価処理のプログラムのフローチャート、ROM12又は不揮発性メモリ18に記憶されている演奏練習用の曲データ、RAM13に記憶される演奏データなどに基づいて、図1に示した演奏評価システムの動作について説明する。この演奏評価システムにおいては、ユーザが演奏練習用の曲データを演奏したときに、発音および消音のイベントや運指だけでなく、演奏する手の位置、手の傾き、手の幅を判定して演奏を評価する。このため、曲データの中には、各イベントにおいて模範となる手の位置、手の傾き、手の幅を表わすための画像を生成するためのパラメータが含まれている。パラメータについては後述する。ユーザの選択によって任意の評価対象を選択できるようになっているが、この実施形態においては、(1)手の位置、(2)手の位置および手の傾き、(3)手の位置および手の幅が選択された場合について説明する。
図3は、カメラ5によって撮像された1画面を示す図であり、カメラ5の撮像素子の各画素に対応するx座標およびy座標の位置が決定する。左上の座標(0,0)、右上の座標(SX,0)、左下の座標(0,SY)、座標(SX,SY)によって指定される画角の中に、鍵盤の画像2i、右手の画像7i、および左手の画像8iが撮像できるように、カメラ5の水平位置が調節されている。音楽教育を行う教師や管理側において、模範の曲データを作成する際には、教師は、右手および左手の甲に、中央、中指の根元、手首、親指の根元、小指の根元に異なる色彩のシールを貼付し、各指の爪に異なる色のシールを貼付して、演奏を行うことによって、模範となる手の位置、手の傾き、手の幅を表わすための画像のパラメータが作成される。
図4は、実施形態における演奏評価処理のメインルーチンのフローチャートである。種々の変数の初期化(ステップSA1)の後、曲データの読込みを行い(ステップSA2)、スイッチ部14から再生指令が入力されたか否かを判別する(ステップSA3)。再生指令が入力されたときは、曲データを電子楽器1に出力する再生処理を実行する(ステップSA4)。再生処理中において、スイッチ部14から再生停止指令が入力されたか否かを判別する(ステップSA5)。再生停止指令が入力されない場合には、曲が終了したか否かを判別し(ステップSA6)、曲が終了していない場合には、ステップSA4における再生処理を続行する。再生停止指令が入力されたとき、又は、曲が終了したときは、スイッチ部14から曲選択指令が入力されたか否かを判別する(ステップSA7)。曲選択指令が入力されたときは、ステップSA2に移行して、新たに選択された曲データを読込み、ステップSA3以降の処理を繰り返す。
ステップSA7において曲選択指令が入力されない場合には、ステップSA3に移行して、再生が終了した同じ曲データに対して再生指令が入力されたか否かを判別する。再生指令が入力されない場合には、この演奏練習管理のアプリケーションプログラムの終了指令が入力されたか否かを判別し(ステップSA8)、終了指令が入力されない場合にはステップSA3に移行して再生指令が入力されたか否かを判別する。終了指令が入力されたときは、演奏練習管理のアプリケーションプログラムを終了して、パソコンの初期メニューに戻る。
図5は、不揮発性メモリ18に記憶されている実施形態の模範の曲データを示すフォーマットを示す図である。この図に示すように、曲データは、NOTE(0)、NOTE(1)、NOTE(3)…、および、曲の終了を示すNULLからなる複数のイベントのシーケンスデータで構成されている。各イベントは、発音開始時間を示すONTIME、発音継続時間(音長)を示すGATE、音高を示すPITCH、指番号を示すパラメータであるFIGO、手の位置を示すパラメータであるPXOおよびPYO、手の傾きを示すパラメータであるGDO、手の幅を示すパラメータであるWDO、正誤判定に用いるフラグを示すMK、前回のイベントを示すポインタであるpr、次のイベントを示すポインタであるpnで構成されている。FIGOの番号は、右手の親指、人差し指、中指、薬指、小指がそれぞれ0,1,2,3,4で指定され、左手の親指、人差し指、中指、薬指、小指がそれぞれ5,6,7,8,9で指定される。
図6は、RAM13のバッファエリアONBUF(0)、ONBUF(1)、ONBUF(3)…の構成を示し、各バッファエリアには、再生指令に応じてROM12から読込まれたイベントのONTIME、PITCHの値とともに、消音時間を示すOFFTIMEおよび対応する図5のイベントNOTEを示すポインタであるpsがストアされる。このうち、ONTIME、PITCHの値がMIDI・I/F16を介して電子楽器1に出力され、PITCHに対応する鍵の発光素子がONTIMEの発音開始時間に発光して演奏ガイドが行われる。
図7ないし図11は、ユーザの演奏に応じて、MIDI・IF16を介して電子楽器1からパソコン6に入力された演奏データ、および、カメラ5によって撮像されて、ビデオキャプチャ・IF17を介してパソコン6に入力された画像データをストアするRAM13のエリアを示す図である。
図7は、電子楽器1から入力される演奏データをストアするRAM13のエリアを示す図である。この図に示すように、PLAY(0)、PLAY(1)、PLAY(2)…からなる各演奏データは、押鍵開始時間を示すONTIME、押鍵継続時間を示すGATE、押鍵の音高を示すPITCH、その演奏データを示すポインタであるpp、演奏した指番号を示すFIGP、1つ前に演奏した指番号を示すFPREV、押鍵の評価結果を示すONJ、離鍵の評価結果を示すOFFJ、手の位置の評価結果を示すPJ、手の傾きの評価結果を示すGJ、手の幅の評価結果を示すWJ、1つ前の演奏データを示すポインタであるpr、次の演奏データを示すポインタであるpnで構成されている。FIGPおよびFPREVのデータは、右手の親指0、人差し指1、中指2、薬指3、小指4、左手の親指5、人差し指6、中指78、薬指、小指9が割り当てられている。したがって、PLAYのデータが右手の演奏によるものか又は左手の演奏によるものかを指の番号によって識別できる。
図8は、電子楽器1から入力される演奏データを一時的にストアするRAM13のエリアを示す図である。この図に示すように、PLBUF(0)、PLBUF(1)、PLBUF(3)…の各エリアには、押鍵開始時間を示すONTIME、図7のエリアを示すポインタであるpp、図8の当該エリアを示すポインタであるpq、押鍵の評価結果を示すONJ、離鍵の評価結果を示すOFFJ、手の位置の評価結果を示すPJ、手の傾きの評価結果を示すGJ、手の幅の評価結果を示すWJのデータがストアされる。
図9は、カメラ5の画面における各画素IMG(0,0)、IMG(0,2)、IMG(030)…IMG(SX,SY)における青、緑、赤の3原色の値であるBVALUE、GVALUE、RVALUEを示す1画面分の画像データをストアするRAM13のエリアを示す図である。この場合において、BVALUE、GVALUE、RVALUEは0から1までの値で表される。外光の分光特性や反射率などによって多少変化はするが、白鍵の領域における各画素のBVALUE、GVALUE、RVALUEは、ほぼ(1,1,1)となり、黒鍵のBVALUE、GVALUE、RVALUEは、ほぼ(0,0,0)となる。
図10は、ユーザの手の甲に貼付された10個のシールの異なる色のデータHANDC(0)〜HANDC(9)をストアするRAM13のエリアを示す図である。各色は青、緑、赤の3原色の値であるBVALUE、GVALUE、RVALUEの比率によって識別される。上記したように、実施形態においては、ユーザの選択によって、手の動きの評価対象を選択する。その選択を2つのフラグGF、WFを用いて表わす。すなわち、(1)手の位置はGF=0、WF=0、(2)手の位置および手の傾きはGF=1、WF=0、(3)手の位置および手の幅はGF=0、WF=1で表わす。いずれかの選択によって、各指の爪には合計10個の異なる色のシールが貼付され、両手の甲には2個又は6個のシールが貼付される。
図11は、演奏中の右手HAND(0)および左手HAND(1)の中央を示すx座標PX、y座標PY、手の傾きGD、手の幅WDのデータを一時的にストアするRAM13のエリアを示す図である。
図12は、図4におけるステップSA4の再生処理のフローチャートである。まず、変数を初期化する(ステップSB1)。次に、MIDI・I/F16を介して電子楽器1に出力して演奏をガイドするために、図5のエリアにストアされているNOTEを指定するポインタpsを変数nにセットする(ステップSB2)。そして、ステップSB4からステップSB11までのループ処理を実行する。
すなわち、図5に示したROM12の曲データにおいて、NOTE(n)がNULLすなわち曲の終了であるか否かを判別し(ステップSB4)、NOTE(n)がNULLでない場合には、NOWTIMEに経過時間を加算する(ステップSB5)。すなわち、曲再生開始からの時刻であるリアルタイムでNOWTIMEを更新する。実際には、曲再生開始からのクロック数によってリアルタイムを表わすが、説明を分かり易くするために時刻を用いることにする。この後、ノートオン処理(ステップSB6)、ノートオフ処理(ステップSB7)、表示処理(ステップSB8)を行う。次に、NOWTIMEの時刻をLASTTIMEにストアして(ステップSB9)、nの値を次のイベントのポインタpnに変更する(ステップSB10)。そして、ステップSB4に移行して上記ループ処理を繰り返す。
ステップSB4においてNOTE(n)がNULLである場合には、ONBUF(0)がNULLであるか否かを判別する(ステップSB11)。ONBUF(0)がNULLでない場合には、ステップSB5においてNOWTIMEに経過時間を加算する。一方、ONBUF(0)がNULLである場合には、電子楽器1に出力するイベントが残っていないので、メインルーチンに戻る。
図13は、図12におけるステップSB6のノートオン処理のフローチャートである。この処理においては、不揮発性メモリ18の曲データをRAM13のバッファエリアにストアする。まず、変数nのイベントNOTE(n)がNULLであるか否かを判別し(ステップSC1)、NOTE(n)がNULLである場合にはこのフローを終了するが、NULLでない場合には、NOWTIMEの時刻がONTIMEの発音開始時間に達したか否かを判別する(ステップSC2)。まだ発音開始時間に達していない場合はこのフローを終了するが、発音開始時間に達したときは、ONBUFの空きエリアを捜すために、エリアを指定する変数iを0にセットし(ステップSC3)、iの値をインクリメントしながら以下のループ処理を実行する。
ONBUF(i)がNULLであるか否かを判別し(ステップSC4)、ONBUF(i)がNULLでない場合には、iの値を1つインクリメントする(ステップSC5)。このとき、iの値が最大値iMAXを超えたか否かを判別し(ステップSC6)、iの値が最大値以内である場合には、ステップSC4においてONBUF(i)がNULLであるか否かを判別する。ONBUF(i)がNULLである場合には、NOTE(n)の発音開始時間ONTIME、音高PITCH、ポインタpsをONBUF(i)にストアする(ステップSC7)。そして、ONBUF(i)のONTIME、PITCHを電子楽器1に出力し(ステップSC8)、変数nに次のイベントを示すポインタpnをストアする(ステップSC9)。そして、図12のフローに戻り、ステップSB7のノートオフ処理に移行する。
図14は、ステップSB7のノートオフ処理のフローチャートである。まず、RAM13のONBUFのエリアを指定する変数iを0にセットし(ステップSD1)、iの値をインクリメントしながら以下のループ処理を実行する。ONBUF(i)がNULLであるか否かを判別する(ステップSD2)。ONBUF(i)がNULLでない場合には、NOWTIMEの時刻がOFFTIMEの消音時間に達したか否かを判別する(ステップSD3)。ONBUF(i)がNULLである場合、又は、NOWTIMEの時刻がOFFTIMEの消音時間に達していない場合には、iの値を1つインクリメントする(ステップSD4)。このとき、iの値が最大値iMAXを超えたか否かを判別し(ステップSD5)、iの値が最大値以内である場合には、ステップSD2においてONBUF(i)がNULLであるか否かを判別する。
NOWTIMEの時刻がOFFTIMEの消音時間に達したときは、ONBUF(i)のPITCHおよび消音指令のMIDIデータを電子楽器1に出力する(ステップSD6)。次に、ONBUF(i+1)のデータをONBUF(i)のエリアに上書きして更新する(ステップSD7)。そして、iの値をインクリメントして(ステップSD8)、ONBUF(i+1)がNULLであるか否かを判別する(ステップSD9)。ONBUF(i+1)がNULLでない場合には、ステップSD7〜ステップSD9のループ処理を繰り返し、ONBUF(i+1)のデータを順次ONBUF(i)のエリアに上書きする。ステップSD9において、ONBUF(i+1)がNULLである場合には、バッファのエリアの上書きがすべて終了したので、図10のフローに戻り、ステップSB8の表示処理に移行する。
図15は、電子楽器1から演奏データが入力されたときの割り込み処理であるMIDI・IN処理のフローチャートである。この割り込みがあると、入力された演奏データが押鍵であるか否かを判別し(ステップSE1)、押鍵である場合には押鍵処理を行う(ステップSE2)。演奏データが押鍵でない場合には、演奏データが離鍵であるか否かを判別し(ステップSE3)、離鍵である場合には離鍵処理を行う(ステップSE4)。演奏データが押鍵でも離鍵でもない場合、例えば、エフェクト操作などの場合には、その演奏データに対応する処理を行う(ステップSE5)。演奏データに対応する処理の後はメインルーチンに戻る。
図16および図17は、図15におけるステップSE2の押鍵処理のフローチャートである。図16のフローにおいて、まず、押鍵された鍵番号をKEYにストアする(ステップSF1)。次に、初期設定を行うために、フラグPLAYFが0であるか否かを判別する(ステップSF2)。PLAYFは図4におけるステップSA1の変数の初期化で0にリセットされている。PLAYFが0である場合には、PLAYFを1にセットし(ステップSF3)、次の演奏データを示すポインタpnを0にセットし(ステップSF4)、この押鍵処理で用いる変数mを−1にセットし(ステップSF5)、ポインタpqを0にセットする(ステップSF6)。
ステップSF3ないしステップSF6の初期設定の後、又は、ステップSF2においてPLAYFが1である場合には、ポインタpnによって図7のPLAY(pn)を指定する(ステップSF7)。したがって、初期設定した直後はPLAY(0)を指定する。次に、押鍵開始時間であるONTIMEにNOWTIMEの現時刻をストアする(ステップSF8)。また、押鍵された鍵番号であるKEYのデータをPITCHにストアする(ステップSF9)。この後、ppにpnの値をセットし(ステップSF10)、prにmの値をセットし(ステップSF11)、mにpp+1の値をセットする(ステップSF12)。したがって、初期設定した最初は、現在のPLAY(pp)を示すポインタppの値は0、変数mの値は1となる。
次に、図17のフローに移行して、PLAY(m)がNULLであるか否かを判別する(ステップSF13)。したがって、最初は、PLAY(0)の次のエリアであるPLAY(1)がNULLであるか否かを判別する。PLAY(m)がNULLでない場合には、mの値を1つインクリメントする(ステップSF14)。このとき、mの値が最大値を超えたか否かを判別し(ステップSF15)、最大値以内である場合には、ステップSF13において再びPLAY(m)がNULLであるか否かを判別する。すなわち、変数mの値をインクリメントしながら、次の演奏データをストアできる空きエリアを捜す。
PLAY(m)がNULLの空きエリアを見つけた場合には、次のエリアを示すポインタpnにmの値をセットし(ステップSF16)、mに現在のエリアを示すポインタppの値をセットする(ステップSF17)。すなわち、mの値をインクリメントしてPLAY(m)がNULLの空きエリアを見つけたので、mの値を元の値に戻す。次に、図8に示したバッファにおいてPLBUF(pq)のエリアを指定する(ステップSF18)。したがって、最初はPLBUF(0)のエリアを指定する。次に、押鍵開始時間であるONTIMEにNOWTIMEの現時刻をストアする(ステップSF19)。次に、PLBUF(pq)のエリアのポインタppに、PLAY(pp)のエリアにおけるppの値をセットする(ステップSF20)。すなわち、電子楽器1から入力された現在の演奏データをストアしたPLAY(pp)のエリアとPLBUF(pq)のエリアとをポインタppによって対応させる。そして、pqの値を1つインクリメントして(ステップSF21)、次に演奏データをストアするためのPLBUF(pq)のエリアを示すポインタを変更する。この後は、演奏中の指を検出するための画像処理(ステップSF22)、演奏中の手の座標を特定する手の座標処理(ステップSF23)、演奏内容を判定する判定処理(ステップSF24)を行って、メインルーチンに戻る。
図18は、電子楽器1の鍵盤2の各鍵で指が接触する領域AR(0)〜AR(127)を示すRAM13のエリアを示す図である。各領域は、その領域内の画素の座標POSI(x、y)および鍵番号KEY(0〜127)で表わされる。図19は、図2に示した鍵盤の画像2iの一部であり、各白鍵および各黒鍵において押鍵する指が接触する範囲を二点鎖線の矩形の領域AR(0)、AR(1)、AR(2)、AR(3)…で示している。これらの領域は、撮像素子の画素によって位置の座標が確定されるので、各領域における1つの座標、例えば、左下の座標を基準にすると、すべての領域AR(0)〜AR(127)における画素の座標を確定することができる。
図20は、変数j,kで指定される画素(j,k)に基づく矩形の範囲を示す図である。この図に示すように、x(水平)方向がαでy(垂直)方向がβの範囲が画像処理の対象となる領域であり、この領域の画素数は(α+1)×(β+1)である。
図21ないし図23は、図17の押鍵処理におけるステップSF22の画像処理のフローチャートである。この画像処理においては、右手の親指、人差し指、中指、薬指、小指の各画像であるFIG(0)、FIG(1)、FIG(2)、FIG(3)、FIG(4)、および、左手の親指、人差し指、中指、薬指、小指の各画像であるFIG(5)、FIG(6)、FIG(7)、FIG(8)、FIG(9)において、爪に貼付された各シールにおける青、緑、赤の3原色の値として、あらかじめ登録されたBFIG、GFIG、RFIGの画像データと、カメラ5によって撮像された画像の各画素のデータとを比較する。
図21において、まず、押鍵された鍵番号であるKEYの値に対応する領域の基準座標であるx(KEY)をjとし、y(KEY)をkとする(ステップSG1)。すなわち、AR(KEY)の領域を特定する。次に、押鍵した指番号をストアするFIGPに−1をストアし、この画像処理によって各指に対応する画素をカウントするカウンタCNT(0)〜CNT(4)を0にクリアする(ステップSG2)。次に、変数j,kで指定される画素(j,k)をIMGにストアして(ステップSG3)、IMGの青成分、緑成分、および赤成分と基準の青成分、緑成分、および赤成分とのそれぞれの差の絶対値を算出する。
すなわち、BVALUEとBREFとの差の絶対値をDBにストアし(ステップSG4)、GVALUEとGREFとの差の絶対値をDGにストアし(ステップSG5)、RVALUEとRREFとの差の絶対値をDRにストアする(ステップSG6)。次に、DB、DG、DRの値のいずれかが所定値以下であるか否かを判別する(ステップSG7)。IMGの青成分、緑成分、又は赤成分と、基準の青成分、緑成分、又は赤成分との差が所定値以下である場合には、IMGの画素は爪に貼付されたシールの画素の可能性がある。一方、DB、DG、DRの値のすべてが所定値を超えている場合には、IMGの画素はシールの画素ではない。
ステップSG7において、DB、DG、DRの値のすべてが所定値を超えている場合には、jの値を1つインクリメントする(ステップSG8)。このとき、jの値がαの値を超えているか否かを判別し(ステップSG9)、αの値を超えているときは、jの値を0にセットして、kの値を1つインクリメントする(ステップSG10)。このとき、kの値がβの値を超えているか否かを判別する(ステップSG11)。ステップSG9においてjの値がαの値を超えていない場合、又は、ステップSG11においてkの値がβの値を超えていない場合には、AR(KEY)の領域において未処理の画素が残っているので、ステップSG3に移行してj,kで指定される画素(j,k)をIMGにストアして、上記のループ処理を繰り返し、その画素の色を判定する。
ステップSG7において、DB、DG、DRの値のいずれかが所定値以下である場合には、図22のフローにおいて、変数iを0にセットして(ステップSG12)、あらかじめ登録されている各指に貼付されたシールの色データの中から、iで指定する指のシールの色データであるFIGC(i)の青成分BFIG、緑成分GFIG、赤成分RFIGを読出し(ステップSG13)、IMGの画素(j,k)の青成分BVALUE、緑成分GVALUE、赤成分RVALUEとの差の絶対値を算出する。
すなわち、BVALUEとBFIGとの差の絶対値をJBにストアし(ステップSG14)、GVALUEとGFIGとの差の絶対値をJGにストアし(ステップSG15)、RVALUEとRFIGとの差の絶対値をJRにストアする(ステップSG16)。
そして、JB、JG、JRのすべてが基準値であるか否かを判別する(ステップSG17)。JB、JG、JRのすべてが基準値である場合には、画素(j,k)は指番号iの色データFIGC(i)と一致する。この場合には、CNT(i)の値を1つインクリメントする(ステップSG18)。この後、又は、ステップSG17においてJB、JG、JRのすべてが基準値でなく、画素(j,k)が指番号iの色データFIGC(i)と一致しない場合には、iの値を1つインクリメントする(ステップSG19)。このとき、iの値が4を超えたか否かを判別し(ステップSG20)、iの値が4以下である場合には、ステップSG13に移行して、次の指番号iで指定するFIGC(i)のBFIG、GFIG、RFIGを読出し、上記の色判別処理を繰り返す。そして、ステップSG20においてiの値が4を超えたときは、図21のフローのステップSG8に移行して、次の画素を指定する。
図21のステップSG11において、kの値がβの値を超えた場合、すなわち、押鍵された鍵番号の領域AR(KEY)におけるすべての画素について色判別処理が終了したときは、図23のフローにおいて、指番号を指定する2つの変数i,dをともに0にセットし(ステップSG21)、押鍵の指を示すFIGPにdの値をストアする(ステップSG22)。したがって、最初はFIGPの値は0であり、親指が押鍵の指として仮に設定される。次に、iの値を1つインクリメントし(ステップSG23)、iの値が4以下であるか否かを判別する(ステップSG24)。
iの値が4以下である場合には、CNT(i)の値がCNT(d)の値よりも大きいか否かを判別する(ステップSG25)。すなわち、押鍵された鍵番号の領域AR(KEY)において、iで指定する指のシールの画素数がdで指定する指のシールの画素数よりも大きいか否かを判別する。CNT(i)の値がCNT(d)の値よりも大きい場合には、押鍵した指の可能性は、dで指定した指よりもiで指定した指の方が高い。この場合には、dにiの値をセットして(ステップSG26)、ステップSG22に移行して、FIGPにストアする指番号dの値を変更する。そして、ステップSG23に移行して、iの値を1つインクリメントする。一方、ステップSG25において、CNT(i)の値がCNT(d)の値よりも小さい場合には、押鍵した指の可能性は、iで指定した指よりもdで指定した指の方が高い。この場合には、FIGPにストアする指番号を変更することなく、ステップSG23に移行して、iの値を1つインクリメントする。そして、iの値が4を超えるまでCNT(i)の値とCNT(d)の値とを比較しながら、押鍵した可能性がより高い指を捜す。
iの値が4を超えたときは、押鍵の指が暫定的に判定されるが、指くぐりや指越えによって親指がカメラ5から見えない場合もある。例えば、演奏練習前のウォーミングアップや初心者の基礎練習で音階を演奏する際には、低音から高音への1オクターブの演奏では「ドレミファソラシド」のファの鍵を指くぐりの親指で押鍵し、高音から低音への1オクターブの演奏では「ドシラソファミレド」のミの鍵を指越えの中指で押鍵する。このため、指くぐり又は指越えの演奏であるかを判定しなければ、押鍵の指を確定的に判定することができない。
したがって、ステップSG24においてiの値が4を超えたときは、FIGPの暫定的な指番号が0でないか否かを判別する(ステップSG27)。暫定的な指番号が0である場合には、カメラ5によって親指のシールが撮像されているので、指くぐりおよび指越えの演奏ではないので、暫定的に判定した親指は実際の押鍵の指として確定する。一方、FIGPの暫定的な指番号が0でない場合には、押鍵された鍵番号を中心とする所定範囲、例えば、手の幅に相当する範囲に、親指が無いか否かを判別する(ステップSG28)。親指がある場合には、暫定的に判定した人差し指、中指、薬指、又は小指は実際の押鍵の指として確定する。
所定範囲に親指が無い場合には、親指くぐり又は親指越えの演奏の可能性があるので、前回の押鍵の指を示すFPREVの値が0でないか否かを判別する(ステップSG29)。親指で押鍵した後に親指くぐりので押鍵することはないので、FPREVの値が0でない場合には、押鍵した指は親指であるので、FIGPに0をストアする(ステップSG30)。FPREVの値が0で前回の押鍵が親指である場合には、今回の押鍵は親指以外の他の指である。すなわち、暫定的な指番号が押鍵の指番号として確定される。指番号を確定した後は、その確定したFIGPの指番号をFPREVにストアして(ステップSG31)、このフローチャートを終了する。
図24および図25は、図17の押鍵処理におけるステップSF23の手の座標処理のフローチャートである。まず、変数iに0をセットし(ステップSH1)、レジスタxmax、xmin、ymax、yminにそれぞれ撮像画像の左端の最小値座標0、右端の最大値座標SX、上端の最小値座標0、下端の最大値座標SYをセットする(ステップSH2)。次に、現在処理中の画素の座標x、yをともに0にセットする(ステップSH3)。すなわち、図7のエリアのIMG(0,0)の画素を指定する。そして、座標x、座標yの値をインクリメントしながら、IMG(0,0)の画素からIMG(SX,SY)の画素に至るまで以下のループ処理を行う。
IMG(x,y)の画素の色と変数iで指定したHANDC(i)の色とが一致するか否かを判別する(ステップSH4)。両者の色が一致する場合には、xの座標がxmaxの座標よりも大きいか否かを判別し(ステップSH5)、xの座標がxmaxの座標よりも大きい場合には、xの座標をxmaxの座標として更新する(ステップSH6)。次に、xの座標がxminの座標よりも小さいか否かを判別し(ステップSH7)、xの座標がxminの座標よりも小さい場合には、xの座標をxminの座標として更新する(ステップSH8)。次に、yの座標がymaxの座標よりも大きいか否かを判別し(ステップSH9)、yの座標がymaxの座標よりも大きい場合には、yの座標をymaxの座標として更新する(ステップSH10)。次に、yの座標がyminの座標よりも小さいか否かを判別し(ステップSH11)、yの座標がyminの座標よりも小さい場合には、yの座標をyminの座標として更新する(ステップSH12)。すなわち、HANDC(i)の画像において、最大のx座標、最小のx座標、最大のy座標、および最小のy座標を検索する。
ステップSH4において、IMG(x,y)の画素の色とHANDC(i)の色とが一致しない場合には、xの座標を1つインクリメントする(ステップSH13)。このとき、xの座標が最大値座標SXを超えたか否かを判別し(ステップSH14)、xの座標がSX以下である場合には、ステップSH4に移行して、IMG(x,y)の画素の色とHANDC(i)の色とが一致するか否かを判別する。xの座標がSXを超えたときは、xの座標を0にセットし、yの座標を1つインクリメントする(ステップSH15)。このとき、yの座標が最大値座標SYを超えたか否かを判別し(ステップSH16)、yの座標がSY以下である場合には、ステップSH4に移行して、IMG(x,y)の画素の色とHANDC(i)の色とが一致するか否かを判別する。
yの座標がSYを超えたとき、すなわち、撮像された画面のすべての画素の色について、HANDC(i)の色との一致又は不一致の判別が終了したときは、xmaxの値とxminの値との和の平均値をPX(i)にストアし、ymaxの値とyminの値との和の平均値をPY(i)にストアする(ステップSH17)。すなわち、HANDC(i)に対応するシールのx座標の中心をPX(i)にストアし、y座標の中心をPY(i)にストアする。したがって、HANDC(i)に対応するシールの中心位置を取得する。次に、iの値を1つインクリメントして(ステップSH18)、次のシールを指定する。
次に、フラグGFが0であるか否かを判別し(ステップSH19)、GFが0である場合には、フラグWFが0であるか否かを判別する(ステップSH20)。WFが0である場合には、手の位置の座標を特定する場合であり、図26の撮像画像に示すように、右手および左手の中央に1個のシールが貼付されている場合である。この場合には、iの値が1を超えたか否かを判別する(ステップSH21)。iの値が1である場合には、ステップSH2に移行して、ステップSH21までの処理を繰り返す。ステップSH21において、iの値が1を超えたとき、すなわち、右手および左手の中央に貼付されたのシールの中心位置を取得したときは、メインルーチンに戻る。
ステップSH19においてGFが1である場合には、図27に示すように、右手および左手の中央、中指の根元、手首に3個のシールが貼付されている場合である。ステップSH20においてWFが1である場合には、図28に示すように、右手および左手の中央、親指の根元、小指の根元に3個のシールが貼付されている場合である。すなわち、GF=1又はWF=1である場合には、両手の甲に合計6個のシールが貼付されている場合である。この場合には、図25のフローにおいて、iの値が5を超えたか否かを判別する(ステップSH22)。iの値が5以下である場合には、図24のステップSH2に移行して、図25のステップSH22までの処理を繰り返す。
iの値が5を超えたときは、変数iを再び0にセットして(ステップSH23)、下記の演算式を実行する(ステップSH24)。
PXD=PX(4*i+2)−PX(4*i+3)
PYD=PY(4*i+2)−PY(4*i+3)
iの値が0(右手)であるときは、PXD=PX(2)−PX(3)となり、PYD=PY(2)−PY(3)となる。図10に示した割り付けによって、PX(2)は右手の中指の根元のx座標を表わし、PX(3)は右手の手首のx座標を表わす。したがって、PXDの値は、右手の中指の根元と手首との横方向の差分の値である。同様に、PY(2)は右手の中指の根元のy座標を表わし、PY(3)は右手の手首のy座標を表わす。したがって、PYDの値は、右手の中指の根元と手首との縦方向の差分の値である。
次に、GFが1であるか否かを判別する(ステップSH25)。GFが1である場合には、下記の演算式を実行して、GD(i)を算出する(ステップSH26)。
GD(i)=AT(PXD/PYD)−KGD
この演算式において、AT(PXD/PYD)はtan−1(PXD/PYD)すなわち逆正接関数であり、PXDおよびPYDの値によって手の傾き角度を算出している。KGDは電子楽器1の鍵盤2の傾き角度である。
したがって、iの値が0である場合には、GD(0)は鍵盤2に対する右手の相対的な傾きを表わしている。
ステップSH26の後、iの値を1つインクリメントして(ステップSH27)、iの値が1を超えたか否かを判別する(ステップSH28)。iの値が1である場合には、ステップSH24に移行してステップSH28までの処理を繰り返す。
したがって、ステップSH25の演算式において、iの値が1(左手)であるときは、PXD=PX(6)−PX(7)となり、PYD=PY(6)−PY(7)となる。図10に示した割り付けによって、PX(6)は左手の中指の根元のx座標を表わし、PX(7)は左手の手首のx座標を表わす。したがって、PXDの値は、左手の中指の根元と手首との横方向の差分の値である。同様に、PY(6)は左手の中指の根元のy座標を表わし、PY(7)は左手の手首のy座標を表わす。したがって、PYDの値は、左手の中指の根元と手首との縦方向の差分の値である。
また、ステップSH26の演算式において、iの値が1である場合には、GD(1)は鍵盤2に対する左手の相対的な傾きを表わしている。
ステップSH25においてGFが0である場合、すなわち、WFが1である場合には、下記の演算式を実行して、鍵盤2と手の相対的な傾きθを算出する(ステップSH29)。
θ=AT(PXD/PYD)−KGD
次に、下記の演算式を実行して、WD(i)を算出する(ステップSH29)。
|PX(4*i+4)−PX(4*i+5)|/cos(θ)=WD(i)
iの値が0(右手)である場合には、
|PX(4)−PX(5)|/cos(θ)=WD(0)
となる。したがって、WD(0)の値は右手の親指の根元の位置と小指の根元の座標差をGD(0)の余弦で除算した値であり、鍵盤2に対する相対的な手の傾きを補正した右手の幅を表わす。
ステップSH29の後は、iの値を1つインクリメントして(ステップSH27)、iの値が1を超えたか否かを判別する(ステップSH28)。iの値が1である場合には、ステップSH24に移行してステップSH29、ステップSH27、およびステップSH28の処理を繰り返す。
ステップSH29の演算式において、iの値が1(左手)であるときは、
|PX(8)−PX(9)|/cos(θ)=WD(1)
となる。したがって、WD(1)の値は左手の親指の根元の位置と小指の根元の座標差をGD(0)の余弦で除算した値であり、手の傾きを補正した左手の幅を表わす。
ステップSH28においてiの値が1を超えたときは、このフローを終了して、図17の押鍵処理におけるステップSF24の判定処理に以降する。
図29ないし図31は、図17の押鍵処理におけるステップSF24の判定処理のフローチャートである。この判定処理においては、検索用の2つのポインタpb、pfを使用して、演奏データの正誤や演奏のタイミングずれを判定する。pbは、すでに押鍵をガイドしたイベントを検索するポインタであり、pfは、次に押鍵をガイドする予定のイベントを検索するポインタである。図29において、まず、pbに変数nの値をセットする(ステップSK1)。変数nの値は、図13のフローのステップSC7およびステップSC8に示したように、電子楽器1に出力してすでに押鍵をガイドした発音のイベントNOTE(n)を示すものである。次に、pfにNOTE(n)のpnの値をセットする(ステップSK2)。すなわち、次に押鍵をガイドする予定のイベントを示すポインタpnの値をpfにセットする。
次に、NOTE(pb)およびNOTE(pf)がともにNULLであるか否かを判別する(ステップSK3)。これらがともにNULLである場合には、すでに押鍵をガイドしたイベントに対する演奏データの判定が終了し、次にガイドするイベントの無い状態、すなわち、判定する対象がないのでメインルーチンに戻る。NOTE(pb)およびNOTE(pf)のうち少なくとも一方がNULLでない場合には、NOTE(pb)がNULLであるか否かを判別する(ステップSK4)。NOTE(pb)がNULLでない場合には、このイベントを電子楽器1に出力して、電子楽器1から入力された演奏データがRAM13のPLBUFのエリアにストアされている場合である。
この場合には、イベントNOTE(pb)の発音開始時間であるONTIME(pb)をt1にストアし(ステップSK5)、演奏データPLBUF(pp)の押鍵開始時間であるONTIME(pp)をt2にストアする(ステップSK6)。そして、t1とt2の時間差の絶対値がタイミングずれの許容値LAG以下であるか否かを判別する(ステップSK7)。t1とt2の時間差の絶対値がLAG以下である場合には、押鍵をガイドしたイベントの音高であるPITCH(pb)の値が押鍵の鍵番号KEYの値と一致するか否かを判別する(ステップSK8)。値が一致する場合には、イベントNOTE(pb)に対する演奏データの判定を示すフラグMK(pb)が0(未判定)であるか否かを判別し(ステップSK9)、MK(pb)が0である場合には、MK(pb)を1(判定)にセットする(ステップSK10)。
次に、ppにpbの値をセットする(ステップSK11)。すなわち、判定対象の演奏データPLBUF(pp)のポインタを押鍵ガイドのイベントNOTE(pb)のポインタと一致させる。次に、t1とt2の時間差の絶対値が良否の閾値OK以内であるか否かを判別する(ステップSK12)。OK以内である場合には、図8における演奏データPLBUF(pp)の評価エリアONJに1をストアする(ステップSK13)。すなわち、演奏のタイミングずれがない正確な演奏であると判定する。ステップSK8においてPITCH(pb)の値がKEYの値と一致しない場合、又は、ステップSK9においてMK(pb)が1で、NOTE(pb)に対する判定が終っている場合には、演奏データがNOTE(pb)よりさらに前のイベントに対するものであるか否かを検索するために、pbにNOTE(pb)において1つ前のイベントを指定するポインタprをセットする(ステップSK14)。
ステップSK12において、t1とt2の時間差の絶対値がOKから外れている場合には、図30のフローにおいて、t1の時間がt2の時間より大きいか否かを判別する(ステップSK15)。すなわち、演奏データPLBUF(pp)の押鍵開始時間がイベントNOTE(pb)の発音開始時間より早いか否かを判別する(ステップSK15)。t1の時間がt2の時間より大きい場合には、ONJに2をストアする(ステップSK16)。すなわち、押鍵ガイドの発音タイミングに対して演奏のタイミングが早すぎると判定する。これと反対に、t1の時間がt2の時間より小さい場合には、ONJに3をストアする(ステップSK17)。すなわち、押鍵ガイドの発音タイミングに対して演奏のタイミングが遅すぎると判定する。
図29のステップSK13においてONJに1をストアした後、又は、図30のステップSK16においてONJに2をストアした後、又は、ステップSK17においてONJに3をストアした後は、次に押鍵をガイドする予定のイベントを検索する必要がないので、pfにNULLをストアする(ステップSK18)。さらに、すでに押鍵をガイドしたイベントも検索する必要がないので、pbにNULLをストアする(ステップSK19)。図29のステップSK7において、t1とt2の時間差の絶対値が許容値LAGを超えている場合には、電子楽器1から入力された演奏データは、すでに押鍵をガイドしたNOTE(pb)に対するものではないので、図30のステップSK19においてpbにNULLをストアする。
図30のステップSK19の後、又は、図29のステップSK23のステップSK4において、NOTE(pb)がNULLである場合、若しくは、ステップSK14において、pbにNOTE(pb)のprをセットした後は、図30のフローにおいて、NOTE(pf)がNULLであるか否かを判別する(ステップSK20)。NOTE(pf)がNULLでない場合には、イベントNOTE(pf)の発音開始時間であるONTIME(pf)をt1にストアし(ステップSK21)、演奏データPLBUF(pp)の押鍵開始時間であるONTIME(pp)をt2にストアする(ステップSK22)。そして、t1とt2の時間差の絶対値がタイミングずれの許容値LAG以下であるか否かを判別する(ステップSK23)。t1とt2の時間差の絶対値がLAG以下である場合には、押鍵をガイドしたイベントの音高であるPITCH(pf)の値が押鍵の鍵番号KEYの値と一致するか否かを判別する(ステップSK24)。値が一致する場合には、イベントNOTE(pf)に対する演奏データの判定を示すフラグMK(pf)が0(未判定)であるか否かを判別し(ステップSK25)、MK(pf)が0である場合には、MK(pf)を1(判定)にセットする(ステップSK26)。
次に、ppにpfの値をセットする(ステップSK27)。すなわち、判定対象の演奏データPLBUF(pp)のポインタを押鍵ガイドのイベントNOTE(pf)のポインタと一致させる。ステップSK24においてPITCH(pf)の値がKEYの値と一致しない場合、又は、ステップSK25においてMK(pf)が1で、NOTE(pf)に対する判定が終っている場合には、演奏データがNOTE(pf)よりさらに後のイベントに対するものであるか否かを検索するために、pfにNOTE(pf)において1つ後のイベントを指定するポインタpnをセットする(ステップSK28)。次に、図31のフローにおいて、t1とt2の時間差の絶対値が良否の閾値OK以内であるか否かを判別する(ステップSK29)。OK以内である場合には、図8における演奏データPLBUF(pp)および図7におけるPLAY(pp)の評価エリアONJに1をストアする(ステップSK30)。すなわち、演奏のタイミングずれがない正確な演奏であると判定する。
ステップSK29において、t1とt2の時間差の絶対値がOKから外れている場合には、t1の時間がt2の時間より大きいか否かを判別する(ステップSK31)。すなわち、演奏データPLBUF(pp)の押鍵開始時間がイベントNOTE(pf)の発音開始時間より早いか否かを判別する。t1の時間がt2の時間より大きい場合には、ONJに2をストアする(ステップSK32)。すなわち、押鍵ガイドの発音タイミングに対して演奏のタイミングが早すぎると判定する。これと反対に、t1の時間がt2の時間より小さい場合には、ONJに3をストアする(ステップSK33)。すなわち、押鍵ガイドの発音タイミングに対して演奏のタイミングが遅すぎると判定する。
図31のステップSK30においてONJに1をストアした後、ステップSK32においてONJに2をストアした後、又は、ステップSK33においてONJに3をストアした後は、すでに押鍵をガイドしたイベントを検索する必要がないので、pbにNULLをストアする(ステップSK34)。さらに、次に押鍵をガイドする予定のイベントに対して演奏データが入力されて、その判定が終了しているので、そのイベントを検索する必要がない。したがって、pfにNULLをストアする(ステップSK35)。図30のステップSK23において、t1とt2の時間差の絶対値が許容値LAGを超えている場合には、電子楽器1から入力された演奏データは、次に押鍵をガイドする予定のNOTE(pf)に対するものではないので、図31のステップSK35においてpfにNULLをストアする。
図30のステップSK20においてpfがNULLである場合、又は、ステップSK28において、pfにNOTE(pf)のpnをセットした後、又は、図31のステップSK35においてpfにNULLをストアした後は、図5の曲データにおける手の動きのパラメータ、すなわち、模範の手の位置を示すPXOおよびPYO、模範の手の傾きを示すGDO、模範の手の幅を示すWDOと、カメラ5で撮像された演奏中の手の動きのパラメータ、すなわち、図11に示す手の位置を示すPXおよびPY、手の傾きを示すGD、手の幅を示すWDとを比較して、それぞれの判定結果を図8のPLBUF(pp)および図7のPLAY(pp)における評価エリアPJ、GJ、WJにストアする。
図31において、PXとPXOとの差の絶対値が基準値XT以下であるか否かを判別し(ステップSK36)、XT以下である場合には、PYとPYOとの差の絶対値が基準値YT以下であるか否かを判別し(ステップSK37)、YT以下である場合にはPJに1(正確な手の位置)をストアする(ステップSK38)。ステップSK36においてPXとPXOとの差の絶対値がXTを超えている場合、又は、ステップSK37においてPYとPYOとの差の絶対値がYTを超えている場合には、PJに0(手の位置ずれ)をストアする(ステップSK39)。
次に、GFが1であるか否かを判別する(ステップSK40)。GFが1である場合には、GDとGDOとの差の絶対値が基準値GT以下であるか否かを判別し(ステップSK41)、GT以下である場合にはGJに1(正確な手の傾き)をストアし(ステップSK42)、GTを超えている場合にはGJに0(手の傾きのずれ)をストアする(ステップSK43)。ステップSK40においてGFが0である場合には、WFが1であるか否かを判別する(ステップSK44)。WFが1である場合には、WDとWDOとの差の絶対値が基準値WT以下であるか否かを判別し(ステップSK45)、WT以下である場合にはWJに1(正確な手の幅)をストアし(ステップSK46)、WTを超えている場合にはWJに0(手の幅のずれ)をストアする(ステップSK47)。
PJ、GJ、およびWJに1又は0をストアした後は、図29のステップSK3に移行して、NOTE(pb)およびNOTE(pf)がともにNULLであるか否かを判別する。いずれか一方がNULLでない場合には、ステップSK5以降の処理を繰り返す。そして、押鍵をガイドしたすべてのイベントに対して、電子楽器1から入力された演奏データの判定がすべて終了したときは、ステップSK3においてNOTE(pb)およびNOTE(pf)がともにNULLとなるので、メインルーチンに戻る。
図32は、図15のMIDI・INのフローにおけるステップSE4の離鍵処理のフローチャートである。まず、押鍵の鍵番号をKEYにストアし(ステップSL1)、KEYで指定される演奏データの離鍵開始時間ONTIME(KEY)に現時刻をストアする(ステップSL2)。次に、図8のPLBUFのエリアを指定するポインタpqを0にセットして(ステップSL3)、pqの値をインクリメントしながら、離鍵された鍵番号に対応する押鍵の演奏データを捜す。pqで指定するPLBUF(pq)がNULLであるか否かを判別し(ステップSL4)、PLBUF(pq)がNULLでない場合には、PLBUF(pq)におけるppによってPLAY(pp)を指定する(ステップSL5)。そして、PLAY(pp)の鍵番号とKEYの鍵番号とが一致するか否かを判別する(ステップSL6)。これらの鍵番号が一致しない場合には、pqの値を1つインクリメントして(ステップSL7)、ステップSL4において、新たなpqで指定するPLBUF(pq)がNULLであるか否かを判別する。
ステップSL6においてPLAY(pp)の鍵番号とKEYの鍵番号とが一致した場合には、PLAY(pp)の押鍵開始時間ONTIME(pp)に離鍵開始時間ONTIME(KEY)を加算した時間をPLAY(pp)の発音継続時間(音長)としてストアする(ステップSL8)。この後は、離鍵の演奏データに対する判定処理を行う(ステップSL9)。なお、ステップSL4において、PLBUF(pq)がNULLである場合には、離鍵された鍵番号に対応する押鍵の演奏データがPLBUFのすべてのエリアに存在しない。この場合にも、ステップSL9における判定処理を行う。判定処理の後はメインルーチンに戻る。
図33は、図32のフローにおけるステップSL9の判定処理のフローチャートである。まず、ポインタpqで指定するPLBUF(pq)がNULLであるか否かを判別し(ステップSM1)、PLBUF(pq)がNULLでない場合には、変数mを0にセットして(ステップSM2)、図6に示したONBUFのエリアにおけるノートオンのイベントの中から、ONBUF(m)を指定する(ステップSM3)。そして、ONBUF(m)の音高PITCH(m)とKEYの鍵番号とが一致するか否かを判別する(ステップSM4)。PITCH(m)とKEYとが一致しない場合には、mの値を1つインクリメントする(ステップSM5)。このとき、ONBUF(m)がNULLであるか否かを判別し(ステップSM6)、ONBUF(m)がNULLでない場合には、ステップSM3に移行して、新たなmに対するONBUF(m)を指定する。そして、PITCH(m)とKEYとが一致するか否かを判別する。
PITCH(m)とKEYとが一致した場合には、図6に示したONBUFのエリアにおいて、ONBUF(m)の発音終了時間OFFTIME(m)の値をt1にストアし(ステップSM7)、離鍵開始時間ONTIME(KEY)をt2にストアする(ステップSM8)。そして、t1とt2の時間差の絶対値がタイミングずれの許容値LAG以下であるか否かを判別する(ステップSM9)。t1とt2の時間差の絶対値がLAG以下である場合には、t1とt2の時間差の絶対値が良否の閾値OK以内であるか否かを判別する(ステップSM10)。OK以内である場合には、図7および図8の対応するエリアのOFFJに1をストアする(ステップSM11)。すなわち、演奏のタイミングずれがない正確な演奏であると判定する。
ステップSM10において、t1とt2の時間差の絶対値がOKから外れている場合には、t1の時間がt2の時間より大きいか否かを判別する(ステップSM12)。すなわち、演奏データの離鍵開始時間が離鍵ガイドのイベントの発音終了時間より早いか否かを判別する。t1の時間がt2の時間より大きい場合には、OFFJに2をストアする(ステップSM13)。すなわち、押鍵ガイドの消音タイミングに対して離鍵のタイミングが早すぎると判定する。これと反対に、t1の時間がt2の時間より小さい場合には、OFFJに3をストアする(ステップSM14)。すなわち、離鍵ガイドの消音タイミングに対して離鍵のタイミングが遅すぎると判定する。
ステップSM1においてPLBUF(pq)がNULLの場合、すなわち、離鍵した鍵番号に対応する演奏データがPLBUFのエリアにない場合には、その離鍵した鍵の押鍵が押鍵ガイドのイベントの音高と異なっているので、押鍵が誤っていると判定する。この場合には、OFFJに0をストアする(ステップSM15)。また、ステップSM6においてONBUF(m)がNULLの場合も同様に、離鍵した鍵番号に対応する演奏データがONBUFのエリアにないので、押鍵誤りと判定してOFFJに0をストアする(ステップSM15)。さらに、ステップSM9においてt1とt2の時間差の絶対値がタイミングずれの許容値LAGを超えている場合も、押鍵誤りと判定してOFFJに0をストアする(ステップSM15)。すなわち、この実施形態においては、離鍵の後にその押鍵が誤っているか否かを判定している。
この判定結果は、履歴データとして不揮発性メモリ18に保存されるとともに、パソコン6の表示部15に表示された楽譜にもリアルタイムで表示される。例えば、ONJおよびOFFJの値に応じて、正確な演奏(ONJ=OFFJ=1)の場合は「○」、誤った演奏(OFFJ=0)の場合は「×」、早すぎる演奏タイミング(ONJ=OFFJ=2)の場合は「→」、遅すぎる演奏タイミング(ONJ=OFFJ=3)の場合は「←」のマークが音符の画像に対応して表示される。また、PJ、GJ、WJが0である場合には、模範の手の位置、手の傾き、手の幅を表わす画像が表示部15に表示される。
以上のように、上記実施形態によれば、CPU11は、電子楽器1で演奏された楽曲の演奏データをMIDI・IF16を介して入力する。カメラ5は、電子楽器1の鍵盤2の画像2iおよび鍵盤2を演奏中の手の画像7i、8iを撮像する。CPU11は、楽曲に対する模範の演奏データにおける発音イベント、消音イベント、発音および消音のタイミングと、MIDI・IF16から入力された押鍵データ、離鍵データ、押鍵および離鍵のタイミングとを比較し、模範の演奏データにおける演奏中の手の画像とカメラ5によって撮像された演奏中の手の画像とを比較して、比較結果を判定して電子楽器1の演奏を評価する。
したがって、曲データを演奏した後に、演奏した音高の正誤や演奏のタイミングだけでなく、演奏中の手の動きを模範の演奏と比較することにより、効率的な演奏練習を実現できる。
この場合において、CPU11は、鍵盤2の画像2iおよび手の画像に基づいて検出した手の位置、手の傾き、若しくは手の幅、又はこれらの組み合わせと、模範の演奏データにおける演奏中の手の画像における手の位置、手の傾き、若しくは手の幅、又はこれらの組み合わせとを比較する。
したがって、演奏中の手の動きに対してきめ細かな評価を行うことができるので、より効率的な演奏練習を実現できる。この場合に、CPU11は、手の甲の複数箇所に貼付された異なる色彩のシールに基づいて手の位置、手の傾き、および手の幅を正確に検出する。
また、CPU11は、各指先に貼付された異なる色彩のシールに基づいて検出した運指の画像と、模範の演奏データにおける運指の画像とを比較して、運指の良否を正確に評価する。
さらに、CPU11は、スイッチ部14によって選択された評価対象に従って、手の位置、手の傾き、若しくは手の幅、又はこれらの組み合わせを比較対象とするので、演奏者が不得意とする演奏の手の動きを集中的に練習して、その評価を得ることで、演奏者の技量に応じた効率的な演奏練習を実現できる。
なお、上記実施形態においては、パソコン6と接続する鍵盤装置として、電子楽器1を例に採って本発明の演奏データ作成システムを説明したが、本発明の演奏データ作成システムに使用する鍵盤装置は電子楽器1に限定するものではない。例えば、外部音源と接続して楽音を発音するキーボード装置をパソコン6と接続することも可能である。
上記実施形態においては、手の爪に異なる色彩のシールを貼付することによって、シールの画像とそれ以外の画像とを識別して、演奏する指を判定する構成にしたが、実施形態の変形例として、手の爪にシールを貼付しない構成について説明する。
図34は、カメラ5で撮像された右手の画像と、その画像に対して上下位置yを変えながら、x方向にスキャンした信号を示す図である。なお、左手の画像は、右手の画像と対称になることと、指番号が異なるだけであるので、説明および図面は省略する。
図34(A)に示すように、親指くぐりや親指越えがない場合には、手が存在する部分を「1」存在しない部分を「0」に2値化した信号は、y1の位置では指の画像がないMODE=0のパターンになる。y2の位置になると、親指(0)の画像のみが現れ、他の指の画像はまだ現れないMODE=1のパターンになる。y3の位置になると、親指の画像はなくなり、人差し指(1)、中指(2)、薬指(3)、小指(4)の画像が現れるMODE=3のパターンになる。ここで、1又は0に2値化した信号における親指(0)、人差し指(1)、中指(2)、薬指(3)、小指(4)の画像信号を、FIG(0)、FIG(1)、FIG(2)、FIG(3)、FIG(4)と定義する。
一方、図34(B)に示すように、親指くぐりや親指越えがある場合には、y1の位置では、図32(A)の場合と同じように、指の画像がないMODE=0のパターンになるが、y2の位置においては、図32(A)の場合と異なり、指の画像がないMODE=0のパターンになる。そして、y3の位置になると、再び図34(A)の場合と同じように、親指の画像はなくなり、人差し指(1)、中指(2)、薬指(3)、小指(4)の画像が現れるMODE=3のパターンになる。
この変形例では、上記の実施形態における図17の画像処理(ステップSF22)が異なり、他の処理については実施形態と同じである。図35ないし図37は、変形例における画像処理のフローチャートである。
図35において、まず、押鍵された鍵の座標であるx(KEY)を変数jにストアし、y(KEY)を変数kにストアする(ステップSN1)。次に、鍵盤の画像を消去する(ステップSN2)。実際には、RAM13に鍵盤の画像のエリア、手の画像のエリア、座標のエリアを設けて、図19に示したように、各白鍵および各黒鍵において押鍵する指が接触する範囲の領域AR(0)、AR(1)、AR(2)、AR(3)…を確定した後は、鍵盤の画像のエリアを消去するか、又は画像処理の対象から外す。
次に、上下方向の位置であるyの値をy1にセットして(ステップSN3)、その位置でスキャンした信号のパターンがMODE=0であるか否かを判別する(ステップSN4)。信号のパターンがMODE=0でない場合には、鍵盤上に手がない状態であるのでこのフローを終了するが、信号のパターンがMODE=0の場合には、yの値を所定値であるΔだけインクリメントする(ステップSN5)。Δの値は実像における数ミリ程度、例えば、5ミリとする。次に、その位置でスキャンした信号のパターンがMODE=0からMODE=1に変化したか否かを判別する(ステップSN6)。
信号のパターンがMODE=1に変化したときは、さらにyの値をΔだけインクリメントする(ステップSN7)。そして、その位置でスキャンした信号のパターンにおいて、FIG(0)が1から0に変化したか否かを判別する(ステップSN8)。すなわち、親指の画像が消えたか否かを判別する。FIG(0)が0に変化したときは、yの値をΔだけデクリメントして(ステップSN9)、親指の画像が存在する位置まで戻る。そして、FIG(0)の位置を取得する(ステップSN10)。具体的には、図34(C)に示すように、親指の画像の左端および右端のx座標であるx1およびx2を検出して、中点の座標x=(x1+x2)/2の演算式で求めて、FIG(0)の座標P0(x、y)を取得する。
次に、再びyの値をΔだけインクリメントして(ステップSN11)、その位置でスキャンした信号のパターンがMODE=3に変化したか否かを判別する(ステップL12)。MODE=3に変化しない場合には、ステップSN11においてさらにyの値をΔだけインクリメントする。すなわち、親指以外の4本の指の画像が現れる状態、すなわち、FIG(1)=FIG(2)=FIG(3)=FIG(4)=1の信号のパターンになるまでyの値をインクリメントする。
ステップSN5におけるyの値のインクリメントによって、ステップSN6でMODE=1に変化しない場合には、MODE=2に変化したか否かを判別する(ステップSN13)。MODE=2に変化しない場合、すなわち、MODE=0の状態が続いている場合には、ステップSN5におけるyの値のインクリメントを繰り返す。ステップSN13においてMODE=2に変化した場合、すなわち、ステップSN5におけるyの値のインクリメントによって、MODE=0からMODE=1を経ることなくMODE=2に変化した場合は、図34(B)に示した親指くぐり又は親指越えの場合である。
この場合には、親指くぐりでの親指による押鍵であるか、又は親指越えでの中指による押鍵であるかを判別する必要がある。したがって、上記の実施形態の場合と同様に、前回の押鍵の指番号であるFPREVが0(親指)でないか否かを判別して(ステップSN14a)、FPREVが0でない場合には、FIGPに0をストアする(ステップSN14b)。すなわち、前回の押鍵が親指でない場合には、図34(B)に示した画像は親指くぐりであるので、今回の押鍵の指番号を0(親指)とする。FIGPに0をストアした後は、このフローを終了して判定処理に移行する。
ステップSN12においてMODE=2に変化した場合、又は、ステップSN24aにおいてFPREVが0である場合には、図36のフローにおいて、人差し指、中指、薬指、小指の信号FIG(1)、FIG(2)、FIG(3)、FIG(4)が1であるか0であるかを判別するフラグf(1)、f(2)、f(3)、f(4)をすべて1にセットし、指の画像の数を示す変数Mを4にセットする(ステップSN15)。次に、指を指定する変数iを1にセットして(ステップSN16)、yの値をΔだけインクリメントする(ステップSN17)。次に、指(i)に対応するf(i)が1であるか否かを判別する(ステップSN18)。f(i)が1である場合には、信号FIG(i)=0であるか否かを判別する(ステップSN19)。図34(A)、(B)に示すように、信号のパターンがMODE=2になった最初は、人差し指、中指、薬指、小指のすべてについて、信号FIG(i)=1である。したがって、iの値を1つインクリメントして(ステップSN20)、iの値が4を超えたか否かを判別する(ステップSN21)。iの値が4以下である場合には、ステップSN18においてf(i)が0であるか否かを判別する。iの値が4を超えた場合には、ステップSN16に移行して再びiを1に戻して、ステップSN17以下の処理を繰り返す。
yの値をΔ単位でインクリメントしていった結果、ある指(i)の信号FIG(i)=0になったときは、f(i)を0にリセットして(ステップSN22)、yの値をΔだけデクリメントして(ステップSN23)、FIG(i)=1の位置に戻る。そして、図34(C)に示すように、その指の位置である座標Pi(x、y)を取得する(ステップSN24a)。次に、yの値をΔだけインクリメントして元の位置に戻る(ステップSN24b)。この後、Mの値を1つデクリメントする(ステップSN25)。このとき、Mの値が0になったか否かを判別し(ステップSN26)、Mの値が1以上である場合には、ステップSN20に移行してiの値を1つインクリメントする。
このように、yの値をΔだけインクリメントしながら、任意の指のFIG(i)が1から0に変化する位置、すなわち、その指の先端部を検出するたびに、その指の座標Pi(x、y)を取得する。そして、1つの指の座標Pi(x、y)を取得するごとにMの値をデクリメントする。ステップSN26においてMの値が0になった場合、すなわち、人差し指、中指、薬指、小指のすべてについて座標Pi(x、y)(i=1〜4)を取得したときは、図37のフローにおいて、iを0にセットして(ステップSN27)、iの値を変化させながら押鍵した指を検出する処理を行う。
すなわち、Pi(x、y)がAR(KEY)の位置であるか否かを判別し(ステップSN28)、Pi(x、y)がAR(KEY)とは異なる位置である場合には、iの値をインクリメントする(ステップSN29)。このとき、iの値が4を超えたか否かを判別する(ステップSN30)。iの値が4以下である場合には、ステップSN28においてPi(x、y)がAR(KEY)の位置であるか否かを判別する。Pi(x、y)がAR(KEY)の位置である場合には、FIGPにiの値をストアする(ステップSN31)。そして、PPREVにFIGPの値をストアして(ステップSN32)、このフローを終了してメインフローに戻る。ステップSN30においてiの値が4を超えたときは、正常な演奏ではないので、FIGPにNULLをストアして(ステップSN33)、このフローを終了してメインフローに戻る。
以上のように、この変形例においては、CPU11は、各指にシールが貼付されない場合でも、鍵盤の画像および手の画像に基づいて、図35ないし図37の画像処理を行って、各鍵の位置および演奏中の各指の位置を検出することによって、演奏中の運指の画像処理を行うことができる。
さらに、上記実施形態においては、図26、図27、図28に示したように、右手および左手の甲において、中央、中指の根元、手首、親指の根元、小指の根元に異なる色彩のシールを貼付して、手の位置、手の傾き、手の幅を検出する構成を説明したが、図35ないし図37のフローを応用して、シールを貼付しない場合でも、手の位置、手の傾き、手の幅を検出することができる。
例えば、図34(A)の場合において、yの値をΔだけインクリメントしたときに、MODE=0からMODE=1に変化した場合には、MODE=1の信号において、手の甲に対応する信号の左右両端のx座標であるx1およびx2を取得し、その中点である(x1+x2)/2のx座標とy座標によって手の中央の位置PXおよびPYを検出できる。
さらに、yの値をΔだけデクリメントして、MODE=0に戻した場合において、MODE=0の信号における左端のx座標を取得すれば、親指の根元の位置のx座標を検出できる。この後、yの値をインクリメントしていき、MODE=1の信号が変形したときは、そのときのyの位置が手の甲と親指以外の4本の指との境界と見なせるので、信号における右端のx座標を取得すれば、小指の根元の位置のx座標を検出できる。したがって、小指の根元の位置のx座標から親指の根元の位置のx座標を減算すれば、右手の幅WD(0)のデータが得られる。
さらに、yの値をインクリメントして、MODE=2の信号に変化したとき、中指の信号FIG(2)における中心位置のx座標を図34(C)によって算出すれば、中指の根元の座標を検出できる。最後に、中指の先端における中心位置のx座標を図34(C)によって算出すれば、中指の指先の位置のx座標を検出できる。上記実施形態においては、手首の位置と中指の根元の位置によって手の傾きを算出したが、中指の根元の位置と中指の先端の位置によっても手の傾きを算出することができる。その算出方法は、図25のステップSH25およびステップSH26の処理と同じである。すなわち、逆正接関数を用いた演算によって、右手の傾きGD(0)を検出できる。
上記実施形態においては、ROM12にあらかじめ記憶された演奏データ作成処理のプログラムをCPU11が実行する装置の発明について説明したが、フレキシブルディスク(FD)、CD、MDなどの記憶媒体に記録されている演奏データ作成処理のプログラムをパソコン6の不揮発性メモリ18にインストールしたり、インターネットなどのネットワークからダウンロードした演奏データ作成処理のプログラムを不揮発性メモリ18にインストールして、そのプログラムをパソコン6のCPU11が実行することも可能である。この場合には、プログラムの発明やそのプログラムを記録した記録媒体の発明を実現できる。
すなわち、本発明による演奏評価処理のプログラムは、鍵盤装置で演奏された楽曲の演奏データを入力する第1のステップと、前記鍵盤装置の鍵盤の画像および当該鍵盤を演奏中の手の画像を所定の撮像手段によって撮像する第2のステップと、前記楽曲に対する模範の演奏データにおける発音イベント、消音イベント、発音および消音のタイミングと前記データ入力手段から入力された押鍵データ、離鍵データ、押鍵および離鍵のタイミングとを比較し、模範の演奏データにおける演奏中の手の画像と前記撮像手段によって撮像された演奏中の手の画像とを比較する第3のステップと、前記第3のステップによって比較された結果を判定して前記鍵盤装置の演奏を評価する第4のステップと、を実行する。
前記第3のステップは、前記鍵盤の画像および手の画像に基づいて検出した手の位置、手の傾き、若しくは手の幅、又は、これらの組み合わせと、模範の演奏データにおける手の位置、手の傾き、若しくは手の幅、又は、これらの組み合わせとを比較する。
前記第3のステップは、手の甲の複数箇所に施された異なる色彩に基づいて、手の位置、手の傾き、および手の幅を検出する。
前記第3のステップは、各指先に施された異なる色彩に基づいて検出した運指の画像と、模範の演奏データにおける運指の画像とを比較する。
前記第3のステップは、所定の操作手段によって選択された評価対象に従って、手の位置、手の傾き、若しくは手の幅、又はこれらの組み合わせを比較対象とする。