以下、本発明の実施の形態について、図面を参照しながら詳細に説明する。
<第1の実施の形態>
図1は、第1の実施の形態による演奏評価装置の構成を説明する図である。
その演奏評価装置10は、図1に示すように、装置10全体の制御を行うCPU11と、そのCPU11がワークに用いるRAM12と、CPU11が実行するプログラムや各種制御用データ、及び波形データ等を格納したROM103と、例えばキーボードやポインティングデバイス(マウス等)、CD−ROMやDVD等の記録媒体にアクセスする媒体駆動装置、及びそれらのインターフェース等からなる入力部14と、表示装置に画像を表示させる表示部15と、外部装置との間でMIDIデータを送受信するためのMIDIインターフェース(I/F)16と、発音させる楽音のデジタルデータ(波高値)を外部装置に出力するためのオーディオインターフェース(I/F)17と、を備えた構成となっている。
上記MIDI I/F16には、それとMIDIデータを送受信可能なMIDIインターフェース(I/F)21、及びキーボード22を備えた電子楽器20が接続され、上記オーディオI/F17には、波高値を入力して音声に変換できる音源システム30が接続されている。MIDI I/F21は、キーボード22に対する操作内容を示すMIDIデータを生成する機能を備えている。それにより、本実施の形態による演奏評価装置10は、電子楽器20のMIDI I/F21からMIDIデータをリアルタイムに入力して、キーボード22を操作して行ったユーザーの演奏を評価できるものとして実現されている。入力したMIDIデータにより発音が要求された楽音の発音は、その楽音の波高値を生成し、それを音源システム30に出力することにより行うようになっている。音源システム30は、例えばD/A変換器、アンプ、及びスピーカを少なくとも備えたものである。表示部15が画像を表示させる表示装置は、外付けのもの、搭載されたものの何れであっても良い。ここでは便宜的に、表示装置は搭載されたもの、つまり表示部15を構成しているものと想定する。
その演奏評価装置10は、例えばパーソナルコンピューター(PC)に、演奏評価装置10として動作させるためのアプリケーション・プログラム(以下「アプリケーション」)を搭載させることにより実現させている。そのアプリケーションは、例えば入力部14を構成する媒体駆動装置がアクセス可能な記録媒体に記録して提供するものである。そのアプリケーションは、インターネット等のネットワークを介して配信するようにしても良い。
アプリケーションを搭載(インストール)できるように、ROM13としては書き込み可能なメモリ(例えばフラッシュメモリ)が採用されている。そのアプリケーションが記録された記録媒体には、楽音の波高値を生成するための各種波形データが多数、記録されている。その波形データには、音色が異なる楽音発音用のものも含まれている。音色が同じ波形データはピッチ毎に用意されている。演奏評価装置10を実現させるPCは、ROM13の他に、或いはその代わりにハードディスク装置等の補助記憶装置を搭載したものであっても良い。そのアプリケーションについては以降「演奏評価アプリケーション」と呼ぶことにする。
各種波形データは、ROM13に保存させることができるようになっている。また、必要に応じて、記録媒体からコピーすることもできるようにしている。ここでは説明上、便宜的にROM13に保存されている場合のみを想定する。
ROM13に保存した波形データは、RAM12にコピーして使用している。これは、一般的にRAM12はROM13よりもアクセス速度が速いからである。それにより、より高速に、発音させるべき楽音の波高値を生成できるようにしている。
波形データをピッチ毎に用意することにより、それを構成するサンプリングデータ(波高値)は単に順次、読み出せば良いようにしている。それにより、データを読み出す速さ(歩進幅)に応じた補間を行わなくとも良いようにしている。
ユーザーは、電子楽器20のキーボード22を操作して演奏を行う。その演奏では、演奏の進行に合わせて、キーボード22を構成する鍵(演奏操作子)のなかで押鍵(操作)すべき鍵を順次、押鍵していくことが求められる。本実施の形態では、鍵単位でその鍵を押鍵する際の難易度を考慮した評価を行い、その評価を用いて演奏全体の採点を行うようにしている。
鍵単位で難易度を考慮した評価を行うことにより、押鍵すべき鍵への押鍵によって点数を与えられるようになる。特許文献1に記載された従来技術とは異なり、押鍵すべき鍵への押鍵が全く行われなくとも点数を与えるというようなことは確実に回避できる。
押鍵すべき鍵を押鍵したことの評価はその難易度に応じて異ならせることができる。押鍵するのが困難と考えられる鍵ほど、その押鍵には高い演奏技術が必要と言える。このため、難易度が高い鍵ほど、その押鍵を高く評価すれば、採点に演奏技術を適切な形で反映させることとなる。これらのことから、演奏する楽曲に係わらず、演奏技術をより適切に反映させた演奏の評価を行うことができる。
難易度に応じて評価方法を採用することができるが、多くの評価方法を採用するほど、制御が複雑となる。このことから本実施の形態では、高いか否かにより難易度を2段階、つまり難易度を示す値が定めた閾値以上か否かにより分け、難易度がその閾値以上の鍵を押鍵した場合、予め設定の点数を更に加えることで難易度を採点に反映させるようにしている。以降、その点数については「ボーナス点」と呼ぶことにする。
そのような採点を行うために、本実施の形態では図2、図3に示す各種データを管理している。ここで図2、図3を参照して、それらのデータについて具体的に説明する。
図2は、演奏データの構成を説明する図である。その演奏データは、発音させるべき楽音毎に用意されるデータである。楽曲全体の演奏内容を示す楽曲データは、発音させるべき楽音数の演奏データを有している。その演奏データは、例えば入力部14を構成する媒体駆動装置がアクセス可能な記録媒体、或いはROM13に格納されている。ここでは入力部14から入力、つまりそれを構成する媒体駆動装置がアクセス可能な記録媒体から読み出すものと想定する。そのROM13には、図4に示すような楽譜を表示するための楽譜データ等も格納されていると想定する。図2に示す演奏データはRAM12に書き込まれた場合のものであり、その格納場所は、[]で示す括弧内の数値(インデクス値)で指定される。これは図3に示す発音データも同様である。
この演奏データは、発音させるべき楽音を発音させるための指の運びである運指を示す運指データを含むものである。図2に示すように、データlTime、lGate、lTmsec、Pitch、iPosX、cfig、iHand、icost、cIsHarm、iArpS、iArpE、pHTop、pHTail、cTendency、cTendSteps、cIsSO、pPFTop、pPHTail、pNHTop、pNHTail、iNP、prev、及びnextを有している。各データは以下のようなものである。
データlTimeは、発音開始時刻を示すものである。その発音開始時刻は例えば演奏開始からのものをMIDIで扱う単位時間(ステップ)数で表されている。データlGateは発音時間を示すものである。データlTmsecはデータlTimeが示す発音開始時刻を絶対時間(単位はmsec)で示すものである。データPitchは楽音のピッチを示すもの(ピッチ番号、或いはノート番号と呼ぶ)である。データiPosXはそのピッチが割り当てられた鍵のキーボード22上の座標(X座標)を示すものである。データcfigは、その鍵の押鍵に割り当てられた指を示す値である。値の0は親指を示し、同様にして、1は人差し指、2は中指、3は薬指、4は小指をそれぞれ示している。データiHandは鍵を押鍵して発音される楽音が属するパートを示すものである。そのパートは押鍵に使う指がある手で区別されるものであり、その手が右手のパートでは1、左手では2がデータiHandとして格納される。データicostは、割り当てられた指で鍵を押鍵する難易度の評価値(難易度データ)である。データcIsHarmは楽音が和音の構成音か否かを示すものである。その値は構成音でなければ0、構成音であれば−1となる。
データiArpSは、アルペジオを構成する先頭の楽音か否かを示す先頭フラグである。データiArpEは、その末端(最後)の楽音か否かを示す末端フラグである。それらの値は、該当するか否かによって、予め定めた2種類の値のうちの何れかとなる。データpHTopは、和音の先頭音(一番下の音(最低音))の演奏データの格納場所を示すポインタ(インデクス値)である。データpHTailは、和音の終端音(一番上の音(最高音))の演奏データの格納場所を示すポインタ(インデクス値)である。それらのインデクス値は、楽音が和音の構成音であった場合に格納される。そうでなければ予め定めた固定値が格納される。
データcTendencyは、楽音近傍の楽音の並び(音列)の高低傾向を示す値(0は極値、正の値は上昇傾向、負の値は下降傾向、1は変化しない踊り場、2はそれ以外(の変化あり))である。データcTendStepsは極値となるまでの段階数である。データcIsSOは、ポリフォニーとなっているか否かを示すフラグである。その値の絶対値は音数を示している。正の値は前に同時発音中の楽音の存在を示し、負の値は後に同時発音中の楽音の存在を示している。データpPHTopは前の音列を構成する和音の先頭音の演奏データのポインタである。データpPHTailはその和音の終端音の演奏データのポインタである。データpNHTop、pNHTailはそれぞれ、次の音列を構成する和音の先頭音、終端音の演奏データのポインタである。データiNPは割り当てた指を押鍵に使うべきでない禁止条件に該当するか否かを示す値である(0は該当しないことを示す)。データprevは前の演奏データのポインタである。データnextは次の演奏データのポインタである。
上記データlTime、lGate、lTmsec、及びPitchは発音させるべき楽音、及びそれを発音させるべき期間(タイミング)を示すデータであり、本来の演奏データ(以下、混乱を避けるために「実演奏データ」と呼ぶ)を構成する。それら、並びにデータcfig、及びiHandは運指データを構成するものである。それらのなかで、データcfig、及びiHandは本来の運指データ(以下、混乱を避けるために「実運指データ」と呼ぶ)を構成する。データprev、及びnextを除く他のデータは、その実運指データ生成用のものである。
その実運指データは、運指がより容易となるように生成される。そのために、運指(押鍵すべき鍵の押鍵に使う指をその鍵に運ぶ動作)の難易度を計算している。本実施の形態では、そのことに着目し、その難易度を演奏評価に用いている。最終的に求められた難易度を示す値は、上記データicostとして格納される。その値は以降、コスト値と呼ぶことにする。
本実施の形態では、上記演奏データが実演奏データ分のみで構成されている場合に対応するために、運指データを生成する機能を搭載させている。それにより、実演奏データ分のみで構成されている演奏データによる評価を行う場合には、演奏データ毎に運指データを生成し、難易度を考慮した評価を行えるようにしている。
図3は、発音データの構成を説明する図である。その発音データは、発音させる楽音毎に用意されるデータである。図3に示すように、発音データは、演奏パートを示すトラック番号であるデータiCh、対応する音色データを示すデータiTone、楽音のピッチを示すデータiPitch、そのベロシティを示すデータiOnVel、そのピッチの楽音の状態を示すデータiStatus(−1の値は消音中、0の値は消音、1の値は演奏データが示す押鍵時間(押鍵開始から離鍵するまでの期間)であり、且つユーザーが押鍵中である状態、2の値は演奏データが示す押鍵時間であり、且つユーザーが押鍵していない状態(押鍵が遅れている状態)、3の値は演奏情報が示す押鍵時間でなく、且つユーザーが押鍵中である状態(押鍵が早く行われた状態)、をそれぞれ表す)、その楽音における演奏判断結果を示すデータiResult(0の値は未押鍵、1の値は適切な押鍵、2の値は遅れた押鍵、3の値は早い押鍵、4の値は誤った押鍵(ミスタッチ)、をそれぞれ表す)、対応する演奏データの格納場所を示すデータpME、対応する演奏データによる発音開始時刻を示すデータlOnStart、その消音開始時刻を示すデータlOffStart、ユーザーによる押鍵時刻(タイミング)を示すデータlNoteOn、その離鍵時刻(タイミング)を示すデータlNoteOff、前の発音データの格納場所を示すデータpPrev、及び次の発音データの格納場所を示すデータpNext、を備えている。この発音データは演奏中に順次、作成され、随時、更新される。
以降は図5〜図12に示す各種フローチャートを参照して、上述のデータを管理して楽音の発音、及び演奏評価を行う演奏評価装置10の動作について詳細に説明する。その動作は、CPU13が、上記演奏評価アプリケーションをROM13からRAM12に読み出して実行することで実現される。
図5は、全体処理のフローチャートである。これは、上記演奏評価アプリケーションを起動させてから終了させるまでの間に実行される処理を抜粋してその流れを示したものである。始めに図5を参照して、その全体処理について詳細に説明する。
先ず、ステップ101では、各種変数に初期値を代入するといった初期化を行う。次のステップ102では、ユーザーが指定の楽曲に対応する楽曲データをROM13から読み出してRAM12に格納する。その後に移行するステップ103では、楽曲データを構成する演奏データで示される運指を評価するための運指評価処理を実行する。その実行後はステップ104に移行する。
その演奏データが運指データを含むものであるとは限らない。このことから、その運指データが演奏データに含まれていない場合、運指評価処理では運指データの生成を併せて行う。運指の評価は、運指データに不適切な部分が存在すればそれをより適切なものに更新するために実行される。その実行により、各演奏データのデータicostは必要に応じて更新され、最終的には最も適切と考えられるものとなる。
ステップ104では、入力部14、或いはMIDI I/F16によるデータの入力を待つ。ここでは、入力部14を操作してのデータ入力については、演奏評価アプリケーションの終了指示、演奏評価の開始(楽曲データの再生開始)、その停止(終了)のみを想定する。
電子楽器20のキーボード22を構成するキー(鍵)をユーザーが押鍵、或いは離鍵すると、MIDI I/F21はその演奏操作の内容、及びその操作が行われたキーに応じたMIDIデータを生成して演奏評価装置10のMIDI I/F16に出力する。入力部14を構成するキーボード、或いはポインティングデバイスを操作すると、その操作内容が入力部14からCPU11に通知される。それにより、ステップ104からステップ105に移行し、入力が演奏評価アプリケーションの終了コマンドか否か判定する。そのアプリケーションを終了させるための操作をユーザーが入力部14に対して行った場合、判定はYESとなり、ここで一連の処理を終了する。そうでない場合には、判定はNOとなってステップ106に移行する。
ステップ106では、入力がMIDIデータか否か判定する。MIDI I/F16がMIDIデータを入力した場合、判定はYESとなり、ステップ107に移行して、その入力に対応するためのMIDI IN処理を実行した後、上記ステップ104に戻る。一方、そうでない場合には、判定はNOとなってステップ108に移行する。
ステップ108では、上記演奏評価の開始を指示するための再生開始コマンドを入力したか否か判定する。ユーザーがそのコマンド入力のための操作を入力部14に対して行った場合、判定はYESとなってステップ109に移行し、演奏評価のための再生処理を起動した後、上記ステップ104に戻る。そうでない場合には、判定はNOとなってステップ110に移行する。
ステップ110では、上記演奏評価の停止を指示するための再生停止コマンドをユーザーが入力したか否か判定する。ユーザーがそのコマンド入力のための操作を入力部14に対して行った場合、判定はYESとなってステップ111に移行し、再生処理の実行を管理するための変数である再生停止フラグをオン、つまりその実行停止を示す値を代入した後、上記ステップ104に戻る。そうでない場合には、判定はNOとなり、他のステップの処理を実行することなく、そのステップ104に戻る。
図6は、上記ステップ103として実行される運指評価処理のフローチャートである。次にその評価処理について、図6に示すそのフローチャートを参照して詳細に説明する。
先ず、ステップ201では、運指評価に用いる各種変数の初期化等を行う。続くステップ202では、運指データを演奏データ中に有する楽曲データを取得するためのデータ取得処理を実行する。入力部14を介して入力した楽曲データを構成する演奏データに運指データが含まれていない場合、その運指データを演奏データ毎に生成する処理を行う。その生成は周知の技術を用いて行う。
ステップ202に続くステップ203では、変数meに、楽曲データ中で先頭に位置する演奏データを指定するインデクス値(ポインタ)を代入する。次のステップ204では、運指評価が終了したか否か判定する。その評価は、変数meの値で指定される演奏データを先頭のものから最後のものまで順次、変更しながら行われる。このため、変数meの値で指定される演奏データが存在しない場合、判定はYESとなってステップ213に移行し、全演奏データのデータicostの値の平均値を算出して変数CostAveに代入(ストア)してから一連の処理を終了する。そうでない場合には、判定はNOとなってステップ205に移行する。
ステップ205では、変数meの値で指定される演奏データが示す楽音(指定音)とその次に発音すべき楽音間のコストを算出する2音間コスト算出処理を実行する。次に移行するステップ206では、現在、注目している運指(指定音を発音させるための運指)が禁止条件とする事項の何れかに該当しているか否か確認するための禁止事項検索処理を実行する。その後はステップ207に移行する。
ステップ207では、me.iNPの値が0でないか否か判定する。上記禁止事項検索処理では、該当する事項(禁止条件)に該当していることが判明した場合、その値として0以外の値を格納する。このことから、その場合、判定はYESとなり、ステップ212でme.icostとして、想定範囲内におけるコストの最大値を格納した後、ステップ209に移行する。そうでない場合には、判定はNOとなってステップ208に移行し、運指に従って指定音を発音させるためのコストをより適切なものに更新するためのコスト補正処理を実行する。ステップ209にはその後に移行する。
ステップ209では、me.icostの値、つまり指定音のコストの値が、閾値として定めた定数THRCOST(<コストの最大値)より大きいか否か判定する。その値が定数THRCOSTより大きい場合、判定はYESとなり、運指を修正するための運指修正処理を実行し(ステップ210)、その実行後に変数meにme.nextの値(次の演奏データを指定するインデクス値)を代入してから(ステップ211)、上記ステップ204に戻る。一方、そうでない場合には、判定はYESとなり、次にそのステップ211に移行する。
上記運指修正処理での運指の修正は、特に詳細な説明は省略するが、例えば指定音の前後の部分を考慮して処理対象とする区間を決定し、決定した区間内の演奏を行ううえで可能性のある全ての運指の組み合わせのなかからコストが最小となる組み合わせを抽出することで行っている。それにより、指定音に対して最適な運指を修正時には確実に設定させている。この結果、評価に用いる運指データは全て、それが示す運指が可能、且つそのコストが異常に大きくないものとなる。
ここで、上記ステップ205、206、及び208で実行されるサブルーチン処理について、図7〜図10を参照して詳細に説明する。
図7は、上記ステップ205として実行される2音間コスト算出処理のフローチャートである。始めに図7を参照して、そのコスト算出処理について詳細に説明する。
このコスト算出処理では、連続する2音にのみ着目する形でその2音を発音させるための運指のコストを算出するようになっている。そのコストの算出は、図8に示す運指コストテーブルを参照し、対応する値を抽出することで行っている。コスト算出処理について説明する前に、そのコストテーブルについて具体的に説明する。
図8中、「bw」は鍵盤種類(0は白鍵、1は黒鍵)、「pm」はピッチ変化方向(0は増加方向、1は減少方向)、「f1」は変数ev1の値で指定される音符の指番号(その値で指定される演奏データ中のデータcfigの値)、「f2」は変数ev2の値で指定される音符の指番号、「intv」はそれら2つの音符間のピッチ差、をそれぞれ表している。それにより、テーブルは、それらのデータの各値の組み合わせで示される状況別に、その状況下での運指のコスト(の値)を格納したものとなっている。このことから、2音間コスト算出処理では、それらのデータの各値を求め、各値の組み合わせで指定される欄に格納されたコスト(値)を抽出し、それを指定音の運指のコストとして更新するようになっている。運指コストテーブルは、5個の値によって示される状況別にコストの値を格納したものであることから、図7中では5次元の配列変数CTとして「CT[bw][pm][f1][f2][intv]」と表記している。以降、その図7に示すコスト算出処理について詳細に説明する。
先ず、ステップ301では、変数ev1、及びev2にそれぞれ、変数meの値、及びme.nextの値を代入する。続くステップ302では、変数f1にev1.cfigの値、変数p1にev1.iPosXの値、変数bwに変数p1の値を2で割った余り(図中「p1%2」と表記)、変数f2にev2.cfigの値、変数p2にev2.iPosXの値、をそれぞれ代入する。その代入後に移行するステップ303では、変数p1の値が変数p2の値以下か否か判定する。後者が前者より大きい場合、判定はYESとなり、ステップ304で0を変数pmに、変数p2の値から変数p1の値を引いた値を変数intvにそれぞれ代入してからステップ306に移行する。そうでない場合には、判定はNOとなり、ステップ305で1を変数pmに、変数p1の値から変数p2の値を引いた値を変数intvにそれぞれ代入してからステップ306に移行する。
ステップ3065では、変数intvの値が定数MAXINTV以下か否か判定する。その定数MAXINTVは、運指により押鍵を行う難易度が極めて高いと考えられる鍵間(ピッチ差)を判定するために用意したものである。このことから、着目する2つの音符の間にそのようなピッチ差が存在していない場合、判定はYESとなり、ステップ307でev1.icostとして、変数bw、pm、f1、f2、及びintvの各値によって運指コストテーブル(図8)から抽出される値(図中「CT[bw][pm][f1][f2][intv]」と表記)を代入した後、一連の処理を終了する。そうでない場合には、判定はNOとなり、ステップ308でev1.icostとして定数MAXCOSTを代入した後、一連の処理を終了する。
上記定数MAXCOSTは、例えばコストとして想定する範囲内で最大値として定めたものである。図6中のステップ212では最大値としてこの定数MAXCOSTにme.icostを更新するようになっている。
上述したような構成の運指コストテーブルでは、2音間の発音開始時刻の時間間隔が考慮されていない。その時間間隔が短くなるほど、運指は困難となるのが普通である。このことから、上記ステップ307では、特には図示していないが、ev1.icostとして、変数bw、pm、f1、f2、及びintvの各値によって運指コストテーブルから値を抽出した後、抽出値に時間間隔に応じた係数を乗算し、その乗算結果をev1.icostとして格納している。
図9は、図6に示す運指評価処理内でステップ206として実行される禁止事項検索処理のフローチャートである。次に図9を参照して、その検索処理について詳細に説明する。
例えば親指や小指はその長さ、手における位置などの理由により、鍵盤上の黒鍵の押鍵はそれ以外の指よりも困難である。同じ指を使った連続する押鍵は、離鍵から押鍵までの時間間隔、押鍵する鍵間の距離(音高(ピッチ)差)などに応じて難易度(コスト)が変化する。時間間隔が短く、且つ鍵間の距離が大きいような場合、その押鍵は不可能か、或いは極めて困難となる。他にも不可能、或いは極めて困難な運指は存在する。このようなことから、検索処理では、指定音に割り当てられた運指が不可能、或いは極めて困難と考えられる条件(禁止事項)毎に、それを満たしているか否か検索により確認するようになっている。
先ず、ステップ401では、親指や小指といった比較的に短い指で演奏者から見て離れた場所にある黒鍵を押鍵するような運指を禁止条件に該当しているとして検出するための黒鍵の指使い検出処理を実行する。次のステップ402では、和音を発音させる場合に、或る指で押鍵する鍵より高音の鍵をその指より低音側に位置する指で押鍵する、或いはその逆に押鍵するといったことを禁止事項として検出するための和音での指の逆転検出処理を実行する。その後はステップ403に移行する。
ステップ403では、複数の鍵を押鍵する状況下で、同時に押鍵していることが不可能と考えられる指の割り当てを禁止条件として検出するための指の開き幅の限界検出処理を実行する。続くステップ404では、同時に押鍵していることが不可能な数の押鍵を禁止条件として検出するための多声条件検出処理を実行する。その実行後、一連の処理を終了する。
上記ステップ401〜4の各検出処理では、禁止条件を満たしていることが確認された場合、me.iNPとして0以外の値を格納(更新)する。それにより、図6に示す運指評価処理では、ステップ207の判定がYESとなって、その指定音のコストは最大値に更新されることとなる。
図10は、図6に示す運指評価処理内でステップ208として実行されるコスト補正処理のフローチャートである。その運指評価処理内で実行されるサブルーチン処理では、最後に図10を参照してその補正処理について詳細に説明する。
先ず、ステップ501では、運指に従って指定音を発音させる際の状況を示す各種値を対応する変数に代入するための処理を実行する。次のステップ502では、変数meの値で指定される演奏データが示す楽音(指定音)の発音開始時刻に発音中の他の楽音、或いはその発音終了時刻前に発音を開始する他の楽音に着目してコストを補正するための多声音の補正処理を実行する。続くステップ503では、指定音の押鍵に必要な、指越え、或いは指くぐりという比較的に高度な演奏方法に着目してコストを補正するための指越え/指くぐりでの補正処理を実行する。その次のステップ504では、分散和音とそれに続く分散和音間の相互関係に着目してコストを補正するための分散和音での補正処理を実行する。その後はステップ505に移行する。
ステップ505では、単音が続く音符群とそれに続く和音間の相互関係に着目してコストを補正するための短音→和音遷移での補正処理を実行する。続くステップ506では、和音とそれに続く単音の音符群間の相互関係に着目してコストを補正するための和音→短音遷移での補正処理を実行する。その次のステップ507では、和音とそれに続く和音間の相互関係に着目してコストを補正するための和音→和音遷移での補正処理を実行する。その次に移行するステップ508では、和音とその直前に位置する和音間の相互関係に着目してコストを補正するための前方和音補正処理を実行する。一連の処理はその後に終了する。
このようにして、コスト補正処理では、互いに異なる内容毎に、その内容に着目してコストを必要に応じて補正するための処理を実行するようになっている。それにより、コスト補正処理を実行する前の指定音のコスト(me.icost)の値は、該当する内容の有無、その数に応じて補正される(以上のようなコストの算出についての参考技術文献としては、本出願人が出願した特願2004−261020号が挙げられる)。
図5に示す全体処理内で実行されるサブルーチン処理の説明に戻る。
図11は、図5に示す全体処理内でステップ107として実行されるMIDI IN処理のフローチャートである。次にそのIN処理について、図11に示すそのフローチャートを参照して詳細に説明する。
このIN処理は、MIDI I/F17を介して入力したMIDIデータに対応するための処理である。ここでは本発明に特に係わるデータ、つまりノートオンメッセージ、ノートオフメッセージの2種類のMIDIデータのみにのみ注目する。理解を容易とするために、図5に示す全体処理内のステップ109で再生処理が起動された場合に実行される処理を抜粋してその流れを示している。
上述したように、発音データ中のデータlOnStart(演奏データ中のデータlTime)は演奏開始からの時間を示している。そのような時間で押鍵すべきタイミングを表していることから、再生処理の起動時に時間を計時するためのカウントを0から開始させるようにしている。そのカウント、つまり時間の計時は、例えばCPU11に内蔵のハードタイマを用いて行っている。特に断らない限り、現在時刻はそのようにして計時した時間を指す意味で用いる。
先ず、ステップ601では、入力したMIDIデータが楽音の発音終了を指示するノートオフメッセージか否か判定する。そのMIDIデータがノートオフメッセージだった場合、判定はYESとなってステップ602に移行する。そうでない場合には、判定はNOとなってステップ612に移行する。
ステップ602では、入力したMIDIデータから、チャンネル番号、及びピッチ番号(ノートナンバー)を抽出し、それぞれ変数iCh、及びiPitに代入する。続くステップ603では、変数ndに、先頭に位置する発音データのインデクス値を代入する。その代入後に移行するステップ604では、変数ndの値で指定される発音データが存在しないか否か判定する。その発音データが存在しない場合、判定はYESとなってステップ625に移行し、表示部15の表示内容を必要に応じて更新した後、一連の処理を終了する。そうでない場合には、判定はNOとなってステップ605に移行する。
図4は、再生処理の実行中に表示される画面を説明する図である。本実施の形態では、演奏する楽曲の楽譜と併せて、現在までの採点結果を表示するようにしている。「LeftTrack」、「RightTrack」「SCORE」がそれぞれ配置されたエリアに表示された数値は、左手パートでの採点結果、右手パートでの採点結果、全体での採点結果(=左手パートでの採点結果+右手パートでの採点結果)を表している。楽譜、それらのうちの何れかの採点結果を更新する必要があった場合に、ステップ625では表示の更新を行う。
ステップ605では、nd.iPitchの値が変数iPitの値と一致するか否か判定する。それらが一致する場合、判定はYESとなってステップ607に移行し、そうでない場合には、判定はNOとなり、ステップ606で変数ndにnd.pNextを代入した後、上記ステップ604に戻る。
ステップ607では、nd.iStatusの値が1か否か判定する。その値が1であった場合、判定はYESとなり、ユーザーは離鍵すべきタイミングとなる前の鍵を離鍵したとして、ステップ608でnd.iStatusの値を2に更新し、更にステップ609でnd.lNoteOffを現在時刻に更新した後、上記ステップ625に移行する。そうでない場合には、判定はNOとなってステップ610に移行する。
ステップ610では、nd.iStatusの値が3か否か判定する。その値が3であった場合、判定はYESとなり、ステップ611でnd.iStatusの値を−1に更新した後、上記ステップ609に移行する。そうでない場合には、判定はNOとなって上記ステップ606に移行する。ここでのYESの判定は、主に離鍵すべきタイミングとなった鍵をユーザーが離鍵していないことを意味する。
上記ステップ601の判定がNOとなって移行するステップ612では、入力したMIDIデータが楽音の発音開始を指示するノートオンメッセージか否か判定する。そのMIDIデータがノートオンメッセージでなかった場合、判定はNOとなり、ここで一連の処理を終了する。そうでない場合には、判定はYESとなってステップ613に移行する。
ステップ613では、入力したMIDIデータから、チャンネル番号、ノートナンバー(ピッチ)、及びベロシティ値を抽出し、それぞれ変数ich、iPit、及びiVelに代入する。続くステップ614では、変数ndに、発音データのなかで先頭に位置する発音データの格納場所を示すインデクス値を代入する。その代入後に移行するステップ615〜624では、入力したMIDIデータに応じて、対応する発音データを作成、或いは更新するための処理を行う。
先ず、ステップ615では、変数ndの値が示す発音データが存在しないか否か判定する。今回、入力したMIDIデータに対応する発音データは、変数ndの値で指定される発音データ中のデータpNextをその変数ndに新たに代入していくことにより、順次、対象とする発音データを変更しながら探すようになっている。最後に位置する発音データにはそれに続く発音データが存在しないため、データpNextの値は初期値のままとなっている。このため、変数ndに新たに代入した値がその初期値であった場合、判定はYESとなってステップ626に移行する。そうでない場合には、判定はNOとなってステップ616に移行する。ここでのYESの判定は、ユーザーが押鍵すべきタイミングとなる前の鍵を押鍵したことを意味する。
ステップ616では、変数ndの値で指定される発音データ中のデータiStatus(図中「nd.iStatus」と表記)の値が2と一致し、且つnd.iPitchが示すピッチ番号が変数iPitのそれと一致するか否か判定する。それらのうちの少なくとも一つが一致しない場合、判定はNOとなってステップ617に移行し、変数ndにnd.pNextを代入した後、上記ステップ615に戻る。そうでない場合には、つまりそれらが共に一致する場合には、判定はYESとなってステップ618に移行する。
ステップ618では、現在時刻(再生処理起動から経過した時間)からnd.lOnStartが示す時間を引いて得られる時間を示す値を変数lDifに代入する。次のステップ619では、変数lDifの値が、許容できるとする最大時間を示す定数DELAY_ALLOWより小さいか否か判定する。ここではその変数lDifの値は押鍵が早かった時間を示している。このため、十分に短い時間だけ早く押鍵した場合、判定はYESとなり、nd.iStatusの値を1、nd.iResultの値を2にそれぞれ更新してから(ステップ620)、ステップ621に移行する。そうでない場合には、判定はNOとなって上記ステップ617に移行する。
ステップ621では、変数lDifの値が定数DELAY_OK未満か否か判定する。その値が定数DELAY_OK未満であった場合、判定はYESとなり、ステップ622でnd.iResultとして1を格納し、次にステップ623で採点のための採点処理を実行した後、ステップ624に移行する。そのステップ624では、nd.lNoteOnとして現在時刻(曲頭からの演奏時間)、nd.iOnVelとして変数iVelの値をそれぞれ格納し、その後は上記ステップ625に移行する。
このようにして、変数ndの値をインクリメントしながら、その値で指定される発音データが、入力したMIDIデータに対応するものか否か確認し、対応していると確認できた発音データの更新、及び採点を行うようにしている。
上記ステップ615の判定がYESとなって移行するステップ626では、変数ndに、新たに作成する発音データの格納場所を示すインデクス値を代入する。また、nd.pPrevとしてはそれまで最後に位置していた発音データのインデクス値を格納し、その発音データ中のデータpNextは変数ndの値に更新する。nd.pNextとしては、最後に位置する発音データであることを示す値を格納する。続くステップ627では、nd.iStatusとして3、nd.iPitchとして変数iPitの値、nd.iResultとして4をそれぞれ格納する。また、nd.fRelease、nd.pNext、nd.lOnStart、nd.lOffStart、nd.lNoteOffとして例えばそれぞれ所定の初期値を格納する。その後に上記ステップ624に移行する。
図12は、図5に示す全体処理内のステップ109で起動される再生処理のフローチャートである。次に図12を参照して、その再生処理について詳細に説明する。
先ず、ステップ701では、変数meに、演奏情報のなかで先頭に位置する演奏データの格納場所を示すインデクス値を代入する。続くステップ702では、上記再生停止フラグがオンとなっているか否か判定する。再生停止コマンドの入力によってそのフラグがオンされた場合、判定はYESとなり、ステップ703で発音データ全てのデータiStatusの値を0に更新した後、一連の処理を終了する。そうでない場合には、判定はNOとなってステップ704に移行する。
ステップ704では、発音中の楽音の存在を確認するための変数AllOffに、それが存在しないことを示す値の1を代入し、変数ndに、先頭に位置する発音データのインデクス値を代入する。次のステップ705では、変数ndの値で指定される発音データが存在しないか否か判定する。その発音データが存在しない場合、判定はYESとなってステップ714に移行する。そうでない場合には、判定はNOとなってステップ706に移行する。そのステップ706〜713では、演奏データを参照して、ユーザーによる離鍵時刻に着目した発音データの更新を行うための処理が行われる。
先ず、ステップ706では、nd.iStatusの値が0以外か否か、つまり変数ndの値で指定される発音データによって楽音を発音させていないか否か判定する。楽音を発音させていない場合、判定はNOとなり、ステップ707で変数ndにnd.pNextを代入した後、上記ステップ705に戻る。そうでない場合には、判定はYESとなってステップ708に移行する。
ステップ708では、楽音が発音中であることを示す値の0を変数AllOffに代入する。次のステップ709では、nd.lOffStartが示す消音開始時刻が現在時刻より前か否か判定する。現在、対象としている発音データが既に離鍵しているべき鍵に対応するものであった場合、その関係が成り立つことから、判定はYESとなってステップ710に移行する。そうでない場合には、判定はNOとなって上記ステップ707に移行する。
ステップ710では、nd.iStatusの値が2か否か判定する。その値が2であった場合、判定はYESとなり、離鍵すべきタイミングとなる前にユーザーが離鍵した鍵がそのタイミングになったとして、ステップ711でnd.iStatusの値を−1に更新した後、上記ステップ707に移行する。そうでない場合には、判定はNOとなってステップ712に移行する。
ステップ712では、nd.iStatusの値が1か否か判定する。その値が1であった場合、判定はYESとなり、離鍵すべきタイミングとなった鍵をユーザーが離鍵していないとして、ステップ713でnd.iStatusの値を3に更新した後、上記ステップ707に移行する。そうでない場合には、判定はNOとなって次にそのステップ707に移行する。
上記ステップ705の判定がYESとなって移行するステップ714では、変数AllOffの値が1と一致し、且つ変数meの値で指定される演奏データが存在しない(直前に対象としていた演奏データが最後のもの)か否か判定する。その値が1と一致し、且つその演奏データが存在しない場合、判定はYESとなり、発音ガイドを終了すべきタイミングが到来したとして、ステップ730でそれに対応するための表示の更新を行ってから一連の処理を終了する。そうでない場合には、判定はNOとなってステップ715に移行する。そのステップ715以降では、演奏データを参照しての発音データの作成、或いはユーザーによる押鍵時刻に着目した発音データの更新のための処理が行われる。
先ず、ステップ715では、me.lTimeが示す発音開始時刻が現在時刻(再生開始からの時間)より前か否か判定する。その発音開始時刻(押鍵すべきタイミング)が現在時刻より前であった場合、判定はYESとなってステップ716に移行する。そうでない場合には、判定はNOとなって上記ステップ702に戻る。
ステップ716では、変数ndに、先頭に位置する発音データのインデクス値を代入する。その代入後に移行するステップ717では、変数ndの値で指定される発音データが存在しないか否か判定する。その発音データが存在しない場合、判定はYESとなってステップ728に移行し、そうでない場合には、判定はNOとなってステップ718に移行する。
ステップ718では、nd.iStatusの値が3と一致し、且つnd.iPitchの値がme.Pitchの値と一致するか否か判定する。それらのうちの少なくとも一つが一致しない場合、判定はNOとなってステップ719に移行し、変数ndにnd.pNextを代入した後、上記ステップ717に戻る。そうでない場合には、つまりそれらが共に一致する場合には、判定はYESとなってステップ720に移行する。そのYESの判定は、対象としている発音データは、押鍵すべきタイミングとなる前の鍵をユーザーが押鍵することで作成されたことを意味する。
ステップ720では、現在時刻(再生処理起動から経過した時間)からnd.lNoteOnが示す時間を引いて得られる時間を示す値を変数lDifに代入する。次のステップ721では、変数lDifの値が定数DELAY_ALLOWより小さいか否か判定する。その値が示す時間が十分に短いような場合、判定はYESとなり、nd.iStatusの値を1、nd.iResultの値を3にそれぞれ更新してから(ステップ722)、ステップ723に移行する。そうでない場合には、判定はNOとなって上記ステップ719に移行する。
ステップ723では、変数lDifの値が定数DELAY_OK未満か否か判定する。その値が定数DELAY_OK未満であった場合、判定はYESとなり、ステップ724でnd.iResultとして1を格納し、次にステップ725で採点処理を実行した後、ステップ726に移行する。
ステップ726では、nd.lOnStartとしてme.lTime、nd.lOffStartとして現在時刻(曲頭からの演奏時間)にme.lGateの値を加算した値、nd.pMEとして変数meの値をそれぞれ格納する。次のステップ727では、変数meに、me.nextの値を代入する。その後は上記ステップ702に戻る。
上記ステップ717の判定がYESとなって移行するステップ728では、変数ndに、新たに作成する発音データの格納場所を示すインデクス値を代入する。nd.pPrevとしてそれまで最後に位置していた発音データのインデクス値を格納し、その発音データ中のデータpNextは変数ndの値に更新する。nd.pNextとしては、最後に位置する発音データであることを示す値を格納する。続くステップ729では、nd.iStatusとして2、nd.iPitchとしてme.Pitch、nd.iResultとして0、をそれぞれ格納する。また、nd.fRelease、nd.NoteOn、nd.lNoteOff、nd.pNextとして例えばそれぞれ所定の初期値を格納し、そのようなことを行った後に上記ステップ726に移行する。
このようにして、変数ndの値をインクリメントしながら、その値で指定される発音データが、入力したMIDIデータに対応するものか否か確認し、対応していると確認できた発音データの更新、及び採点を行うようにしている。
図13は、上記ステップ725、或いは図11に示すMIDI IN処理内のステップ623として実行される採点処理のフローチャートである。最後に図13を参照して、その採点処理について詳細に説明する。
先ず、ステップ801では、変数iScoreに基準点として設定の50を代入する。続くステップ802では、対象の演奏データを指定するインデクス値を変数meに代入する。その変数meはローカル変数であり、それに代入するインデクス値は、図11に示すMIDI IN処理、及び図12に示す再生処理それぞれのローカル変数である変数meの値である。
ステップ802に続くステップ803では、me.icostの値が変数CostAveに代入されている、全演奏データのデータicostの値の平均値より大きいか否か判定する。me.icostの値がその平均値以下であった場合、判定はNOとなり、ボーナス点を加える必要はないとしてステップ805に移行する。そうでない場合には、判定はYESとなり、ステップ804で変数iScoreの値を、ボーナス点として定めた50を加えた値に更新した後、そのステップ805に移行する。なお、me.icostの値と比較する値(コスト)は、様々な楽曲を考慮して決定した固定的な値としても良い。そのような値を採用した場合には、評価結果を正規化することができる。それにより、演奏する楽曲に係わらず、評価結果から自身の演奏技術を適切に把握できるようになる。
ステップ805では、図11に示すMIDI IN処理、或いは図12に示す再生処理から渡された変数lDifの値の絶対値が、定数DELAY_OK未満か否か判定する。ユーザーによる押鍵が高い精度で押鍵すべきタイミングと一致していた場合、判定はYESとなり、ステップ806で変数iScoreの値をそれまでの2倍に更新する形でボーナス点を加えた後、ステップ807に移行する。そうでない場合には、判定はNOとなってそのステップ807に移行する。
ステップ807では、pME.iHandの値が1、つまりユーザーが操作(ここでは押鍵)した鍵は右手パートの楽音を発音させるためのものか否か判定する。その楽音が右手パートに属するものであった場合、判定はYESとなり、ステップ808で変数rTotalにそれまでの値に変数iScoreの値を加算した値を新たに代入した後、一連の処理を終了する。そうでない場合には、判定はNOとなり、ステップ809で変数lTotalにそれまでの値に変数iScoreの値を加算した値を新たに代入した後、一連の処理を終了する。
上記変数iScore、lScoreはそれぞれ、右手パート、左手パート別に点数の累算値を保持させるために用意している。それらの値は、そのときの時点でのパート別の総得点を表している。このことから、それらのうちの一方を更新した場合、その更新後の値、及び全パートでの総得点を更新するようにしている(図4)。それにより、ユーザーに演奏評価の途中経過をリアルタイムで通知するようにしている。
なお、本実施の形態では、電子楽器20からMIDIデータを入力することにより、ユーザーが行った演奏操作をリアルタイムに検出し、その評価を行う形となっている。しかし、その評価は、通常の楽曲データが示す演奏操作を対象に行っても良い。つまり、ユーザーが行う演奏操作をリアルタイムで評価しなくとも良い。
また、本実施の形態では、ミスタッチ、つまり押鍵すべきでない鍵への押鍵は無視している。しかし、そのようなミスタッチをユーザーに知らせるようにしても良い。その実現は、例えば図11に示すMIDI IN処理を例えば図14に示すように変更することで行うようにしても良い。図11に示すステップの処理内容と同じ、或いは基本的に同じステップには同一の符号を付して説明を省略する。これは他の図でも同様とする。
その図14に示すMIDI IN処理では、ステップ609の処理を実行した後、ステップ901に移行し、nd.iResultの値がミスタッチを示す4か否か判定する。その値が4であった場合、判定はYESとなり、ステップ902で変数iPointに−50を代入し、その次に移行するステップ625でその変数iPointの値を表示部15に図4に示すように表示させた後、一連の処理を終了する。そうでない場合には、判定はNOとなってそのステップ625に移行する。このときには例えば表示させている楽譜のみを必要に応じて更新する。
本実施の形態では、押鍵されたタイミングに着目して評価を行っている。しかし、離鍵されたタイミングに着目した評価を行うようにしても良い。その実現は、例えば図14に示すMIDI IN処理を例えば図15に示すように変更することで行うようにしても良い。
その図15に示すMIDI IN処理では、ステップ901でNOと判定した場合、次にステップ1000に移行して、変数lDifに、現在時刻からnd.lOffStartの値、つまりユーザーが離鍵したタイミングが離鍵すべきタイミングから遅れた時間を示す値を代入する。続くステップ1001では、nd.iResultの値が1、2、或いは3と一致するか否か判定する。その値がそれらのうちの何れかと一致する場合、判定はYESとなり、ステップ1002で採点処理を実行した後、上記ステップ625に移行する。そうでない場合には、判定はNOとなり、そのステップ625に移行する。それにより、演奏データが示す鍵をその鍵を押鍵しているべき期間内にユーザーがその鍵を押鍵すれば、離鍵したタイミングに応じた加点を行うようになっている。
<第2の実施の形態>
上記第1の実施の形態では、ボーナス点の加算は押鍵タイミング、或いは離鍵タイミングに着目して行っている。これに対し、第2の実施の形態は、適切と見なせる押鍵が連続して行われた回数に着目してそのボーナス点を加算するようにしたものである。
第2の実施の形態における演奏評価装置の構成は、基本的に第1の実施の形態におけるそれと同じである。動作も大部分は同じか、或いは基本的に同じである。このことから、第1の実施の形態で付した符号をそのまま用いて、第1の実施の形態から異なる部分についてのみ説明する。
第2の実施の形態では、MIDI IN処理、及び採点処理に第1の実施の形態から異なる部分が存在する。このことから、それら2つの処理における相違に着目して説明を行う。
図16は、第2の実施の形態におけるMIDI IN処理のフローチャートである。ここでは、図15に示すIN処理から異なる部分についてのみ説明する。
図16に示すIN処理では、ステップ609の処理を実行した後、ステップ1101に移行する。そのステップ1101では、nd.iResultの値が0か否か判定する。ユーザーが押鍵すべき鍵を押鍵しなかった場合、その値は0となることから、判定はYESとなり、ステップ1102で変数iSuccessに0を代入した後、上記ステップ625に移行する。そうでない場合には、判定はNOとなってステップ901に移行する。その変数iSuccessは、適切と見なせる押鍵が連続して行われた回数をカウントするために用意したものである。
そのステップ901の判定がYESとなると、ステップ902に移行して、変数iPointに−50を代入する。続くステップ1103では、ミスタッチを行ったとして、変数iSuccessに0を代入する。その後は上記ステップ625に移行する。
図17は、第2の実施の形態における採点処理のフローチャートである。
図17に示す採点処理では、ステップ805の判定がNOとなるか、或いはステップ806の処理を実行することでステップ1201に移行し、変数iSuccessの値をインクリメントする。その次に移行するステップ1202では、変数iSuccessの値を定数bTimeで割ったときの余り(図中「iSuccess%bTime」と表記)が0と一致するか否か判定する。その余りは、変数iSuccessの値が定数bTimeの倍数となった場合に0となる。このことから、その値が定数bTimeの倍数であった場合、判定はYESとなってステップ1203に移行し、変数iScoreに、変数iSuccessの値を定数bTimeで割って得られる値の小数点以下を切り捨てて整数化した値に10を乗算し、その乗算結果をそれまでの値に加算して得られる値(図中「iScore+Int(iSuccess/bTime」と表記)を代入することでボーナス点を加算する。その後はステップ807に移行する。一方、そうでない場合には、判定はNOとなってそのステップ807に移行する。
なお、本実施の形態(第1、第2の実施の形態)は、PC等のデータ処理装置に本発明を適用したものである。その適用は、本実施の形態によるプログラムに相当する演奏評価アプリケーションをデータ処理装置に実行させることで実現させている。そのようなアプリケーションは電子楽器、音源装置等に搭載させる演奏評価装置用に開発しても良い。開発したアプリケーションは、CD−ROM、DVD、或いは着脱自在なフラッシュメモリ等の記録媒体に記録させて配布しても良い。公衆網等の通信ネットワークを介して、そのプログラムの一部、若しくは全部を配信するようにしても良い。そのようにした場合には、ユーザーはプログラムを取得してデータ処理装置、或いは演奏評価装置(それを搭載した装置)にロードすることにより、その装置に本発明を適用させることができる。このことから、記録媒体は、プログラムを配信する装置がアクセスできるものであっても良い。