以下、本発明の実施の形態について、図面を参照しながら詳細に説明する。
図1は、本実施の形態による運指表示装置の構成を説明する図である。
その運指表示装置10は、図1に示すように、装置10全体の制御を行うCPU11と、そのCPU11がワークに用いるRAM12と、CPU11が実行するプログラムや各種制御用データ等を格納したROM103と、例えばキーボードやポインティングデバイス(マウス等)等の入力装置用のインターフェース、CD−ROMやDVD等の記録媒体にアクセスする媒体駆動装置、及びそのインターフェース等からなる入力部14と、及び表示装置に画像を表示させる表示部15と、を備えた構成となっている。
その運指表示装置10は、例えばパーソナルコンピューター(PC)に、運指表示装置10として動作させるためのアプリケーション・プログラム(以下「運指表示アプリケーション」)を搭載させることにより実現させている。そのアプリケーションは、例えば入力部14を構成する媒体駆動装置がアクセス可能な記録媒体に記録して提供されるものである。そのアプリケーションは、インターネット等のネットワークを介して配信するようにしても良い。アプリケーションを搭載(インストール)できるように、ROM13としては書き込み可能なメモリ(例えばフラッシュメモリ)が採用されている。運指表示装置10を実現させるPCは、ROM13の他に、或いはその代わりにハードディスク装置等の補助記憶装置を搭載したものであっても良い。表示部15が画像を表示させる表示装置は、外付けのもの、搭載されたものの何れであっても良い。ここでは便宜的に、表示装置は搭載されたもの、つまり表示部15を構成しているものと想定する。
本実施の形態では、楽曲の演奏で発音させるべき楽音毎に、その楽音を発音させるべきタイミング、及びその楽音の音高を示す演奏データを取得し、その演奏データから楽譜(図14〜図17)を表示部15に表示させるようにしている。その楽音を発音させるために用いるべき指を示す運指データは、必要に応じて演奏データから生成し、その演奏データに追加するようにしている。それにより、最終的に図2に示すような演奏データを取得して、運指データを表示可能とさせている。図14〜図17において、楽譜の近傍に表記した「1」〜「5」の数字は、運指データが示す指に割り当てた指番号(指情報)である。その指番号を対応する音符の近傍に配置して表示することにより、楽曲の進行により発音させるべき楽音と併せて運指をユーザーに教示するようにしている。図2に示す演奏データはRAM12に書き込まれた場合のものであり、その格納場所は、[]で示す括弧内の数値(インデクス値)で指定される。
その演奏データは、図2に示すように、データlTime、lGate、lTmsec、Pitch、iPosX、DrawPos、cfig、cDisp、iHand、icost、icostN、cIsHarm、iArpS、iArpE、pHTop、pHTail、cTendency、cTendSteps、cIsSO、pPFTop、pPHTail、pNHTop、pNHTail、iNP、prev、及びnextを有している。各データは以下のようなものである。
データlTimeは、発音開始時刻を示すものである。その発音開始時刻は例えば演奏開始からのものをMIDIで扱う単位時間(ステップ)数で表されている。データlGateは発音時間を示すものである。データlTmsecはデータlTimeが示す発音開始時刻を絶対時間(単位はmsec)で示すものである。データPitchは楽音のピッチを示すもの(ピッチ番号、或いはノート番号と呼ぶ)である。データiPosXはそのピッチが割り当てられた鍵の鍵盤上の座標(X座標)を示すものである。データDrawPosは、その鍵の押鍵に用いるべき指の指番号を表示部15に表示させる際の座標を示すデータである。データcfigは、その鍵の押鍵に割り当てられた指を示す指番号である。値の0は親指を示し、同様にして、1は人差し指、2は中指、3は薬指、4は小指をそれぞれ示している。データcDispは、指番号の表示・非表示を示すフラグである。値の0は非表示、1は表示を示している。データiHandは鍵を押鍵して発音される楽音が属するパートを示すものである。そのパートは押鍵に使う指がある手で区別されるものであり、その手が右手のパートでは1、左手では2がデータiHandとして格納される。データicostは、割り当てられた指で鍵を押鍵する難易度の評価値(難易度データ)である。データicostNは、難易度を正規化した評価値である。データ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を除く他のデータは、その最小運指データ生成用のものである。
図2に示すような構成の演奏データ、実演奏データ、或いは運指データは例えば、入力部14を構成する媒体駆動装置がアクセス可能な記録媒体により、或いは不図示の通信ネットワークを介して運指表示装置10に入力される。ここでは記録媒体により入力されるものと想定する。
本実施の形態では、上記演奏データが実演奏データ分のみで構成されている場合に対応するために、運指データを生成する機能を搭載させている。それにより、実演奏データ分のみで構成されている演奏データを入力したとしても、演奏データ毎に運指データを生成してそれを表示できるようにしている。
図14〜図17に示す楽譜は、演奏(実演奏)データ毎に、それが表す音符の種類、それを配置すべき位置を決定し、五線譜上に配置して表示させるものである。音符の種類はデータlGateから特定でき、Y座標はデータPitchから特定でき、X座標はデータlTimeから特定できる。休符は、音符(楽音)の発音終了時刻(データlTime、lGateによって示される)から次の音符の発音開始時刻(データlTime)の時間間隔(無音期間)の長さから特定することができる。
上述したように、図14〜図17に示す楽譜の近傍に表記した「1」〜「5」の数字は、運指データが示す指に割り当てた指番号(指情報)である。上記データcDispは、その指番号を表示させるか否か管理するために用意したデータであり、その値として1が格納された演奏データのみを対象に、それを構成するデータcfigを表示させるようにしている。図14〜図17にそれぞれ示した運指表示例は、楽譜上、休符の直後に位置する音符の発音に用いるべき指の指番号を表示させた場合、指越え・指くぐりなどの特殊な指使いをして音符を発音させるべき指の指番号を表示させた場合、音符を発音させる難易度によりその発音に用いるべき指の指番号を表示させた場合、及び正規化した難易度により音符の発音に用いるべき指の指番号を表示させた場合のものである。
このようにして本実施の形態では、休符の直後に位置する音符、特殊な指使いをして発音させるべき音符、或いは発音させる難易度が予め設定された範囲内の音符の少なくとも一方に相当する音符の発音に用いるべき指の指番号を選択的に表示させるようにしている。それにより、指番号の確認をより容易に行えるようにして、その確認のために要する負担を軽減させ、演奏により集中できるようにさせている。
表示させる指番号の選択に休符、特殊な指使い、及び難易度を考慮したのは以下の理由からである。
休符は、演奏操作の切れ目に相当する。その休符箇所では、手を移動させる、或いは各指を余裕のある状態に戻す、といった演奏を続けるうえで動作のポイントとなる場合が多い。休符の直後の押鍵に用いるべき指を知らせると、ユーザーはその指でその押鍵を行えるように手、或いは指を動かすようになる。そのような動作を行うことにより、手、或いは指は演奏を行ううえでより理想的な状態に近づく結果となる。このようなことから、休符後の押鍵に用いるべき指を教示することはユーザーにとって非常に有益と考えられる。このため、休符に着目している。
特殊な指使いは、難易度が高いだけでなく、それを行ううえでの制約もある。それにより、休符と同様に、演奏を続けるうえで動作のポイントとなる場合が多い。このことから、特殊な指使いによる押鍵に用いるべき指を教示することはユーザーにとって非常に有益と考えられる。このため、特殊な指使いに着目している。
一般的に、難易度(データicost)が高い押鍵ほど、その押鍵を適切に行うのは困難となる。このことから、困難と思われる押鍵、及びその押鍵に用いるべき指といったものをユーザーが確認できるようにさせている。ユーザーによって困難、或いは押鍵に用いるべき指を確認したいと感じる難易度は異なることから、指番号を表示させる難易度の範囲はユーザーが任意に指定できるようにさせている(図16)。
演奏する楽曲によって平均的な難易度が異なる。ユーザーにとって高いと思われる難易度であっても、楽曲全体では低いほうに位置していることもある。このことから本実施の形態では、正規化した難易度により指番号を表示できるようにしている。それにより、演奏する楽曲での相対的な評価による難易度(データicostN)で指番号を表示させることができるようにさせている。
上述したようにして選択・表示される指番号は、演奏を行ううえで非常に重要なポイントとなる押鍵、或いはユーザーにとって確認を望む押鍵を適切に行えるように支援する情報となる。このため、そのような指番号のみを選択して表示させたとしても、ユーザーは表示された指番号が示す指で押鍵すべき鍵を適切に押鍵することにより、楽曲全体の演奏も高い確率で適切な運指を行えるようになる。従って、表示させない指番号が存在することの影響は実質的にないか、或いは非常に小さくなる。
上記運指(最小運指)データは、運指がより容易となるように生成される。そのために、運指(押鍵すべき鍵の押鍵に使う指をその鍵に運ぶ動作)の難易度を計算している。本実施の形態では、そのこともあって、難易度を考慮した指番号の選択を可能とさせている。最終的に求められた難易度を示す値は上記データicostとして格納され、正規化された難易度を示す値は上記データicostNとして格納される。それらの値は以降、コスト値とも呼ぶことにする。
以降は図3〜図13に示す各種フローチャートを参照して、上述したように指番号を表示させる対象とする演奏データを選択して指番号を図14〜図17に示すように表示させる運指表示装置10の動作について詳細に説明する。その動作は、CPU13が、上記運指表示アプリケーションをROM13からRAM12に読み出して実行することで実現される。
図3は、全体処理のフローチャートである。これは、上記運指表示アプリケーションを起動させてから終了させるまでの間に実行される処理を抜粋してその流れを示したものである。始めに図3を参照して、その全体処理について詳細に説明する。
先ず、ステップ101では、各種変数に初期値を代入するといった初期化を行う。次のステップ102では、入力部14を構成する媒体駆動装置に、それに装着された記録媒体にアクセスさせ、その記録媒体に格納された演奏データ(図2)の読み込みを行う。特には詳細な説明は省略するが、その読み込みは、入力部14を構成する入力装置、或いはそれと接続された入力装置への操作によってユーザーが指定した演奏データを対象に行う。その読み込みによって演奏データをRAM12に格納した後はステップ103に移行する。
ステップ103では、図6に示すコスト値算出用の運指コストテーブルをRAM12に展開し、準備する。続くステップ104では、演奏データに格納された運指データを評価する運指評価処理を実行する。その評価処理の実行により、演奏データが実演奏データ分のみで構成されている場合には、運指データが生成される。それにより、実行後の演奏データは図2に示すような構成のものとなる。
ステップ104に続くステップ105では、演奏データを対象に、指番号の表示・非表示を設定する表示・非表示設定処理を実行する。次のステップ106では、その設定結果に従って、楽譜、及び指番号を表示させる描画処理を実行する。その描画処理の実行により、図14〜図17に示すように指番号を楽譜と共に表示部15に表示させた後、一連の処理を終了する。
以降は、上記全体処理内で実行されるサブルーチン処理について詳細に説明する。
図4は、上記ステップ104として実行される運指評価処理のフローチャートである。次に図4を参照して、その評価処理について詳細に説明する。
先ず、ステップ201では、運指評価に用いる各種変数の初期化等を行う。続くステップ202では、運指データを演奏データ中に有する楽曲データを取得するためのデータ取得処理を実行する。入力部14を介して入力した楽曲データを構成する演奏データに運指データが含まれていない場合、その運指データを演奏データ毎に生成する処理を行う。その生成は周知の技術を用いて行う。
ステップ202に続くステップ203では、変数meに、楽曲データ中で先頭に位置する演奏データを指定するインデクス値(ポインタ)を代入する。次のステップ204では、運指評価が終了したか否か判定する。その評価は、変数meの値で指定される演奏データを先頭のものから最後のものまで順次、変更しながら行われる。このため、変数meの値で指定される演奏データが存在しない場合、判定はYESとなり、ここで一連の処理を終了する。そうでない場合には、判定はNOとなってステップ205に移行する。
ステップ205では、変数meの値で指定される演奏データが示す楽音(指定音)とその次に発音すべき楽音間のコストを算出する2音間コスト算出処理を実行する。次に移行するステップ206では、現在、注目している運指(指定音を発音させるための運指)が禁止条件とする事項の何れかに該当しているか否か確認するための禁止事項検索処理を実行する。その後はステップ207に移行する。
ステップ207では、変数meの値で指定される演奏データ中のデータiNP(図中「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で実行されるサブルーチン処理について、図5〜図8を参照して詳細に説明する。
図5は、上記ステップ205として実行される2音間コスト算出処理のフローチャートである。始めに図5を参照して、そのコスト算出処理について詳細に説明する。
このコスト算出処理では、連続する2音にのみ着目する形でその2音を発音させるための運指のコストを算出するようになっている。そのコストの算出は、図6に示す運指コストテーブルを参照し、対応する値を抽出することで行っている。コスト算出処理について説明する前に、そのコストテーブルについて具体的に説明する。
図6中、「bw」は鍵盤種類(0は白鍵、1は黒鍵)、「pm」はピッチ変化方向(0は増加方向、1は減少方向)、「f1」は変数ev1の値で指定される音符の指番号(その値で指定される演奏データ中のデータcfigの値)、「f2」は変数ev2の値で指定される音符の指番号、「intv」はそれら2つの音符間のピッチ差、をそれぞれ表している。それにより、テーブルは、それらのデータの各値の組み合わせで示される状況別に、その状況下での運指のコスト(の値)を格納したものとなっている。このことから、2音間コスト算出処理では、それらのデータの各値を求め、各値の組み合わせで指定される欄に格納されたコスト(値)を抽出し、それを指定音の運指のコストとして更新するようになっている。運指コストテーブルは、5個の値によって示される状況別にコストの値を格納したものであることから、図5中では5次元の配列変数CTとして「CT[bw][pm][f1][f2][intv]」と表記している。
先ず、ステップ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に移行する。
ステップ306では、変数intvの値が定数MAXINTV以下か否か判定する。その定数MAXINTVは、運指により押鍵を行う難易度が極めて高いと考えられる鍵間(ピッチ差)を判定するために用意したものである。このことから、着目する2つの音符の間にそのようなピッチ差が存在していない場合、判定はYESとなり、ステップ307でev1.icostとして、変数bw、pm、f1、f2、及びintvの各値によって運指コストテーブル(図6)から抽出される値(図中「CT[bw][pm][f1][f2][intv]」と表記)を代入した後、一連の処理を終了する。そうでない場合には、判定はNOとなり、ステップ308でev1.icostとして定数MAXCOSTを代入した後、一連の処理を終了する。
上記定数MAXCOSTは、例えばコストとして想定する範囲内で最大値として定めたものである。図4中のステップ212では最大値としてこの定数MAXCOSTにme.icostを更新するようになっている。
上述したような構成の運指コストテーブルでは、2音間の発音開始時刻の時間間隔が考慮されていない。その時間間隔が短くなるほど、運指は困難となるのが普通である。このことから、上記ステップ307では、特には図示していないが、ev1.icostとして、変数bw、pm、f1、f2、及びintvの各値によって運指コストテーブルから値を抽出した後、抽出値に時間間隔に応じた係数を乗算し、その乗算結果をev1.icostとして格納している。
図7は、図4に示す運指評価処理内でステップ206として実行される禁止事項検索処理のフローチャートである。次に図7を参照して、その検索処理について詳細に説明する。
例えば親指や小指はその長さ、手における位置などの理由により、鍵盤上の黒鍵の押鍵はそれ以外の指よりも困難である。同じ指を使った連続する押鍵は、離鍵から押鍵までの時間間隔、押鍵する鍵間の距離(音高(ピッチ)差)などに応じて難易度(コスト)が変化する。時間間隔が短く、且つ鍵間の距離が大きいような場合、その押鍵は不可能か、或いは極めて困難となる。他にも不可能、或いは極めて困難な運指は存在する。このようなことから、検索処理では、指定音に割り当てられた運指が不可能、或いは極めて困難と考えられる条件(禁止事項)毎に、それを満たしているか否か検索により確認するようになっている。
先ず、ステップ401では、親指や小指といった比較的に短い指で演奏者から見て離れた場所にある黒鍵を押鍵するような運指を禁止条件に該当しているとして検出するための黒鍵の指使い検出処理を実行する。次のステップ402では、和音を発音させる場合に、或る指で押鍵する鍵より高音の鍵をその指より低音側に位置する指で押鍵する、或いはその逆に押鍵するといったことを禁止事項として検出するための和音での指の逆転検出処理を実行する。その後はステップ403に移行する。
ステップ403では、複数の鍵を押鍵する状況下で、同時に押鍵していることが不可能と考えられる指の割り当てを禁止条件として検出するための指の開き幅の限界検出処理を実行する。続くステップ404では、同時に押鍵していることが不可能な数の押鍵を禁止条件として検出するための多声条件検出処理を実行する。その実行後、一連の処理を終了する。
上記ステップ401〜4の各検出処理では、禁止条件を満たしていることが確認された場合、me.iNPとして0以外の値を格納(更新)する。それにより、図4に示す運指評価処理では、ステップ207の判定がYESとなって、その指定音のコストは最大値に更新されることとなる。
図8は、図4に示す運指評価処理内でステップ208として実行されるコスト補正処理のフローチャートである。その運指評価処理内で実行されるサブルーチン処理では、最後に図8を参照してその補正処理について詳細に説明する。
先ず、ステップ501では、運指に従って指定音を発音させる際の状況を示す各種値を対応する変数に代入するための処理を実行する。次のステップ502では、変数meの値で指定される演奏データが示す楽音(指定音)の発音開始時刻に発音中の他の楽音、或いはその発音終了時刻前に発音を開始する他の楽音に着目してコストを補正するための多声音の補正処理を実行する。続くステップ503では、指定音の押鍵に必要な、指越え、或いは指くぐりという比較的に高度な演奏方法に着目してコストを補正するための指越え/指くぐりでの補正処理を実行する。その次のステップ504では、分散和音とそれに続く分散和音間の相互関係に着目してコストを補正するための分散和音での補正処理を実行する。その後はステップ505に移行する。
ステップ505では、単音が続く音符群とそれに続く和音間の相互関係に着目してコストを補正するための短音→和音遷移での補正処理を実行する。続くステップ506では、和音とそれに続く単音の音符群間の相互関係に着目してコストを補正するための和音→短音遷移での補正処理を実行する。その次のステップ507では、和音とそれに続く和音間の相互関係に着目してコストを補正するための和音→和音遷移での補正処理を実行する。その次に移行するステップ508では、和音とその直前に位置する和音間の相互関係に着目してコストを補正するための前方和音補正処理を実行する。一連の処理はその後に終了する。
このようにして、コスト補正処理では、互いに異なる内容毎に、その内容に着目してコストを必要に応じて補正するための処理を実行するようになっている。それにより、コスト補正処理を実行する前の指定音のコスト(me.icost)の値は、該当する内容の有無、その数に応じて補正される(以上のようなコストの算出についての参考技術文献としては、本出願人が出願した特願2004−261020号が挙げられる)。
図4に示す全体処理内で実行されるサブルーチン処理の説明に戻る。
上述したように本実施の形態では、表示させる指番号の選択は、休符、特殊な指使い、及び難易度を条件にして行うようにしている。実際の選択に用いる条件の種類は、そのなかから一つをユーザーに指定させるようにしている。その指定は、図4に示す全体処理内でステップ105として表示・非表示設定処理の実行時に問い合わせ、ユーザーに行わせている。その指定結果により、設定処理では図9〜図12に示す各サブルーチン処理の少なくとも一つが実行される。このことから、図9〜図12を参照して、ユーザーが指定した条件の種類別に、設定処理内で実行されるサブルーチン処理について詳細に説明する。
図9は、休符箇所を考慮した表示・非表示設定処理のフローチャートである。その設定処理は、ユーザーが条件として休符を指定した場合に実行される。始めに図9を参照して、その設定処理について詳細に説明する。
先ず、ステップ601では、変数meに、先頭に位置する演奏データのインデクス値を代入する。その代入後に移行するステップ602では、変数meの値で指定される演奏データが最後に位置するものではないか否か判定する。その演奏データが最後に位置するものであった場合、判定はNOとなり、ここで一連の処理を終了する。そうでない場合には、判定はYESとなってステップ603に移行する。
ステップ603では、me.cDispの値として1を格納して、表示設定を行う。次のステップ604では、変数mepに、現在、対象としている演奏データの直前に位置する演奏データのインデクス値(me.prev)を代入する。その後に移行するステップ605では、変数mepの値で指定される演奏データが存在するか否か判定する。現在、対象としている演奏データが先頭に位置するものであった場合、その前の演奏データは存在しないことから、判定はNOとなってステップ611に移行する。そうでない場合には、判定はYESとなってステップ606に移行する。
ステップ606では、変数lRestTに、me.lTimeの値からmep.iTimeの値を減算し、その減算結果にmep.lGateの値を加算して得られる値(=me.lTime−mep.iTime+mep.lGate:直前の鍵を離鍵すべきタイミングとなってから次の鍵を押鍵すべきタイミングとなるまでの時間間隔を示す値)を代入する。また、変数lStepTに、me.lTimeの値からmep.iTimeの値を減算した値(=me.lTime−mep.iTime:直前の鍵を押鍵すべきタイミングとなってから次の鍵を押鍵すべきタイミングとなるまでの時間間隔を示す値)を代入する。それらの代入を行った後はステップ607に移行して、変数lRestTの値は定数iResの値の2倍以上か否か判定する。定数iResは、一定以上、無音期間が続く箇所を、指番号の表示の対象となる休符箇所として検出するために用意したものである。例えば4分音符相当の時間を示す値である。このことから、一定以上、無音期間が続く箇所であった場合、判定はYESとなってステップ611に移行する。そうでない場合には、判定はNOとなり、ステップ608でme.iDispとして0を格納し非表示設定を行う。その後はステップ609に移行する。
ステップ609では、変数lStepTの値は定数iResの値の2倍以上であり、且つ変数lRestTの値は定数iResの1/4以上か否か判定する。それら何れの大小関係が満たされている場合、判定はYESとなり、ステップ610でme.iDispに1を格納した後、ステップ611に移行する。そうでない場合には、つまりそれらの大小関係の少なくとも一つが満たされていない場合には、判定はNOとなってステップ611に移行する。
このようにして本実施の形態では、一定以上、長く押鍵すべき鍵は指番号を表示する対象としている。これは、そのような鍵を押鍵すべき指で押鍵することで、それ以降の演奏をより適切な運指で行えるようになるからである。つまりそのような鍵は、休符直後に押鍵すべき鍵と演奏上の性格に類似点が多いためである。
ステップ611では、変数meの値がme.pHTailと一致するか否か、つまり対象としている演奏データが和音の最も音高の高い構成音のものか否か判定する。その構成音のものであった場合、判定はYESとなってステップ612に移行する。そうでない場合には、判定はNOとなってステップ617に移行し、変数meにme.nextの値を代入した後、上記ステップ602に戻る。
ステップ612では、変数mehに、me.pHTopの値を代入する。続くステップ613では、変数mehの値が変数meの値と一致しないか否か判定する。それらの値が一致する場合、判定はNOとなって上記ステップ617に移行する。そうでない場合には、判定はYESとなってステップ614に移行する。
ステップ614では、meh.cDispの値は1か否か判定する。その値が1であった場合、判定はYESとなり、ステップ616で和音の構成音の演奏データ全てデータiDispの値を1にする。その後、ステップ617に移行する。そうでない場合には、判定はNOとなり、ステップ615で変数mehにmeh.nextの値を代入した後、上記ステップ613に戻る。
me.pHTopの値は和音の先頭に位置する構成音の演奏データのインデクス値であり、その演奏データが示す楽音の直前に条件を満たす休符箇所が存在していれば、そのデータiDispとして1が格納されている。このことから、ステップ611〜616の処理により、条件を満たす休符箇所の直後に位置する和音の構成音の演奏データは全て表示設定されることになる。
図10は、特殊な指使いを考慮した表示・非表示設定処理のフローチャートである。その設定処理は、ユーザーが条件として特殊な指使いを指定した場合に実行される。次に図10を参照して、その設定処理について詳細に説明する。ここでは特殊な指使いとして、指越え、指くぐりのみを想定する。また、図9に示す休符箇所を考慮した表示・非表示設定処理と同じ、或いは基本的に同じ内容のステップの処理には同一の符号を付している。同一の符号を付したステップの処理の説明は省略する。
図10に示す表示・非表示設定処理では、ステップ603の処理の実行後、ステップ701に移行して、変数menに、次の演奏データのインデクス値を代入する。その代入後に移行するステップ702では、変数menの値で指定される演奏データが存在するか否か判定する。その演奏データが存在する場合、判定はYESとなり、ステップ703で変数iPassFに0を代入した後、ステップ704に移行する。そうでない場合には、つまり対象とする演奏データが最後に位置するものであった場合には、判定はNOとなってステップ714に移行する。
ステップ704では、me.iHandの値が1であり、me.cfigの値が0であり、men.cfigの値が0より大きく、且つme.iPosXの値がmen.iPosXの値より大きいか否か判定する。それらの関係は、右手の演奏において、親指で押鍵すべき鍵の次に、より音高の低い鍵を親指以外の指で押鍵すべき状況の場合に全て満足する。このことから、そのような状況であった場合、判定はYESとなってステップ705に移行し、指越えを行うべき状況であることを示す値の1を変数iPassFに代入した後、ステップ706に移行する。そうでない場合には、判定はNOとなって次にそのステップ706の処理を実行する。
ステップ706では、me.iHandの値が1であり、me.cfigの値が0より大きく、men.cfigの値が0であり、且つme.iPosXの値がmen.iPosXの値より小さいか否か判定する。それらの関係は、右手の演奏において、親指以外の指で押鍵すべき鍵(指定音)の次に、より音高の高い鍵を親指で押鍵すべき状況の場合に全て満足する。このことから、そのような状況であった場合、判定はYESとなってステップ706に移行し、指くぐりを行うべき状況であることを示す値の2を変数iPassFに代入した後、ステップ708に移行する。そうでない場合には、判定はNOとなって次にそのステップ708の処理を実行する。
ステップ708〜711では、左手の演奏を対象に、指越え、指くぐりの何れかの指使いを行うべき状況か否かの判定を行い、その判定結果に応じた値を変数iPassFに代入するための処理が行われる。それにより、親指で押鍵すべき鍵の次に、より音高の高い鍵を親指以外の指で押鍵すべき状況、つまり指越えを行うべき状況であれば1、親指以外の指で押鍵すべき鍵の次に、より音高の低い鍵を親指で押鍵すべき状況、つまり指くぐりを行うべき状況であれば2、が変数iPassFに代入されることとなる。ステップ712には、ステップ710、或いは711の処理の実行後に移行する。
ステップ712では、変数iPassFの値が0でないか否か判定する。その値が0でない場合、判定はYESとなり、ステップ713で変数meにme.nextの値を代入した後、上記ステップ602に戻る。そうでない場合には、判定はNOとなり、ステップ714でme.cDispの値を0に更新した後、そのステップ713に移行する。
図11は、難易度を考慮した表示・非表示設定処理のフローチャートである。その設定処理は、ユーザーが条件として難易度を指定した場合に実行される。次に図11を参照して、その設定処理について詳細に説明する。図9に示す休符箇所を考慮した表示・非表示設定処理と同じ、或いは基本的に同じ内容のステップの処理には同一の符号を付し、同一の符号を付したステップの処理の説明は省略する。
その難易度を示す値はデータicostとして演奏データに格納されている。対象となる難易度の範囲は、図16に示すように、下限値、上限値によりユーザーに指定させるようにしている。ユーザーが指定した下限値、上限値に相当するコスト値(難易度)はそれぞれ変数minCost、maxCostに代入される。
先ず、ステップ801では、変数meに、先頭に位置する演奏データのインデクス値を代入する。その代入後に移行するステップ802では、変数meの値が0(NULL)でないか否か判定する。その演奏データが最後に位置するものであった場合、データnextの値として0(NULL)が格納されている。このことから、その場合、判定はNOとなり、ここで一連の処理を終了する。そうでない場合には、判定はYESとなってステップ803に移行する。
ステップ803では、me.cDispの値を0に更新する。続くステップ804では、me.icostの値が変数minCostの値以上、且つ変数maxCostの値以下か否か判定する。me.icostの値がユーザーの指定範囲内の難易度を示していた場合、判定はYESとなり、ステップ805でme.cDispの値を1に更新した後、ステップ611に移行する。そうでない場合には、判定はNOとなってそのステップ611に移行する。それにより、難易度がユーザーの指定範囲内の難易度となっている構成音を有する和音は、全ての構成音で指番号を表示させる。
図12は、難易度の正規化処理のフローチャートである。その正規化処理は、ユーザーが条件として正規化した難易度を指定した場合に実行される。次に図12を参照して、その正規化処理について詳細に説明する。
その難易度を示す値はデータicostNとして演奏データに格納されている。正規化した難易度は0〜100の数値で表すようにしている。対象となる難易度の範囲は、図17に示すように、下限値、上限値を数値によりユーザーに指定させるようにしている。ユーザーが指定した下限値、上限値に相当するコスト値(難易度)はそれぞれ変数minCost、maxCostに代入される。それにより、正規化した難易度を考慮した表示・非表示の設定を行うためのサブルーチン処理は、図11に示す表示・非表示設定処理において、ステップ804のみが異なっている。つまりme.icostの代わりにme.icostNを用いることのみが異なっている。このことから、正規化した難易度を考慮した表示・非表示の設定を行うためのサブルーチン処理についての詳細な説明は省略する。
先ず、ステップ901では、変数の初期化を行う。その初期化により、変数CostAve、Ncount、及びmaxCostにはそれぞれ0を代入し、変数minCostには100を代入する。続くステップ902では、変数meに、先頭に位置する演奏データのインデクス値を代入する。その代入後はステップ903に移行して、変数meの値で指定される演奏データが最後に位置するものではないか否か判定する。その演奏データが最後に位置するものであった場合、判定はNOとなってステップ910に移行する。そうでない場合には、判定はYESとなってステップ904に移行する。
ステップ904では、変数CostAveに、それまでの値に変数me.icostの値を加算した結果を代入し、変数Ncountの値をインクリメントする。次のステップ905では、me.icostの値が変数maxCostの値より大きいか否か判定する。前者が後者より大きい場合、判定はYESとなり、ステップ706で変数maxCostにme.icostの値を代入した後、ステップ907に移行する。そうでない場合には、判定はNOとなってそのステップ907に移行する。
ステップ907では、me.icostの値が変数minCostの値より小さいか否か判定する。前者が後者より小さい場合、判定はYESとなり、ステップ708で変数minCostにme.icostの値を代入し、次のステップ909で変数meにme.nextの値を代入した後、上記ステップ903に戻る。そうでない場合には、判定はNOとなってそのステップ909に移行する。
上記ステップ903〜909で形成される処理ループをステップ903の判定がNOとなるまで繰り返し実行することにより、コスト値(難易度)の累算値が変数CostAveにストアされ、演奏データの総数が変数Ncountにストアされ、コスト値の最大値が変数maxCostにストアされ、コスト値の最小値が変数minCostにストアされる。ステップ903の判定がNOとなって移行するステップ910以降では、そのようにして取得されたデータを用いて難易度を正規化するための処理が行われる。
先ず、ステップ910では、変数CostAveに、それまでの値を変数Ncountの値で割った減算結果、つまりコスト値の平均値を代入する。次のステップ911では、変数meに、先頭に位置する演奏データのインデクス値を代入する。その次に移行するステップ912では、変数meの値で指定される演奏データが最後に位置するものではないか否か判定する。その演奏データが最後に位置するものであった場合、判定はNOとなり、ここで一連の処理を終了する。そうでない場合には、判定はYESとなってステップ913に移行する。
ステップ913では、変数iDifに、me.icostの値から変数CostAveの値を引いた減算結果を代入する。続くステップ914では、変数iDifの値が0以上か否か判定する。me.icostの値がコスト値の平均値未満であった場合、変数iDifの値は0未満となるから、判定はNOとなり、ステップ915で変数iDenに変数CostAveの値から変数minCostの値を引いた減算結果を代入し、次のステップ916でme.icostNに、変数iDifの値を変数iDenの値で割った除算結果に50を乗算し、その乗算結果に50を加算して得られる値(=50+iDif/iDen・50)を代入し、その次のステップ917で変数meにme.nextの値を代入した後、上記ステップ912に戻る。そうでない場合には、判定はYESとなり、ステップ918で変数iDenに変数maxCostの値から変数CostAveの値を引いた減算結果を代入した後、上記ステップ916に移行する。
このようにして本実施の形態では、コスト値の最小値を0、その最大値を100として、その間を等分に分ける形でコスト値を正規化している。正規化を行う方法は、そのようなものに限定されるわけではなく、様々な方法を採用しても良い。
図13は、図3に示す全体処理内でステップ106として実行される描画処理のフローチャートである。次に図13を参照して、その描画処理について詳細に説明する。
先ず、ステップ1001では、変数meに、表示上、先頭となる演奏データのインデクス値(図中「meDSt」と表記)を代入する。続くステップ1002では、変数meの値で指定される演奏データに相当する音符の画像データを生成して表示部15に表示させる。上述したように、その音符の種類はデータlGateから特定し、表示位置は、データlTimeから特定する。
ステップ1002に続くステップ1003では、me.iDispの値が1か否か判定する。その値が1であった場合、判定はYESとなり、ステップ1004でme.cfigの値に1を加えた値を指番号としてme.DrawPosが示す座標に表示させた後、ステップ1005に移行する。そうでない場合には、判定はNOとなってそのステップ1005に移行する。
ステップ1005では、変数meの値が表示上の終端となる演奏データのインデクス値(図中「meDEd」と表記)と一致するか否か判定する。表示すべき音符を全て表示させた場合、それらの値が一致することから、判定はYESとなり、ここで一連の処理を終了する。そうでない場合には、判定はNOとなり、ステップ1006で変数meにme.nextの値を代入した後、上記ステップ1002に戻る。
この描画処理を実行することにより、ユーザーが指定(選択)した条件の種類に応じて、図14〜図17に示すような楽譜の何れかが表示部15に表示されることとなる。
なお、本実施の形態では、ユーザーが指定可能な条件は1種類のみとしているが、複種類の条件を一度に指定できるようにしても良い。また、運指を表す指番号は、楽譜と併せて予め表示させるようにしているが、その指番号が示す指で押鍵を行うべきタイミングとなった場合にのみ表示させるようにしても良い。その場合、指番号ではなく、押鍵すべき指を表す画像、別の文字情報、などによってユーザーに通知しても良い。