以下、図面を参照して本発明の実施の形態について説明する。
[第1実施形態]
A.構成
(1)全体構成
図1は、本発明の第1実施形態による練習手順生成装置の全体構成を示すブロック図である。練習手順生成装置は、CPU1、ROM2、RAM3、入力部4、表示部5およびMIDIインタフェース6を備える。CPU1は、後述する入力部4の指示に従い、例えばMIDIインタフェース6を介して外部の電子楽器7から取込んだSMF形式の曲データMidiEventから曲の各小節を表す小節データMeasureを派生させ、曲データMidiEventおよび小節データMeasureを参照して曲構造を分析し、その分析結果に基づいて当該曲の演奏練習に最適な練習手順を生成する。本発明の要旨に係わる、こうしたCPU1の処理動作については追って詳述する。
ROM2は、CPU1にロードされる各種プログラムやテーブル等を記憶する。ここで言う各種制御プログラムとは、後述するメインルーチン、構造分析処理および練習手順生成処理を含む。
RAM3は、CPU1の演算に用いられる各種レジスタ・フラグデータを一時記憶するワークエリアと、MIDIインタフェース6を介して外部の電子楽器7より取込むSMF形式の曲データMidiEventが格納される曲データエリアと、この曲データエリアに格納された曲データMidiEventから派生させた小節データMeasureを記憶する小節データエリアと、曲構造の分析結果を参照して生成される練習手順データPracProcを記憶する練習手順データエリアを備える。曲データMidiEvent、小節データMeasureおよび練習手順データPracProcの各構成については追って説明する。入力部4は、ユーザ操作に対応した操作イベントを発生してCPU1に供給する。表示部5は、CPU1の制御の下に、例えば曲データMidiEventを楽譜表示したり、表示された楽譜上に練習手順を表示する。
(2)データ構成
次に、図2〜図4を参照してRAM3に格納される曲データMidiEvent、小節データMeasureおよび練習手順データPracProcの各構成を説明する。図2は、RAM3の曲データエリアに格納される曲データMidiEventの構成を示す図である。曲データMidiEvent[0]〜[N]は楽曲を構成する各音(メロディ)を表し、その終端には曲の終わりを表すENDデータを備える。
1つのメロディ音を表す曲データMidiEventは、曲開始時点からの経過時間で表現される発音開始時間ITime、発音期間を表す音長lGate、音高Pitch、音量Vel、本音を押鍵する指を指定する運指情報cfig、本音の弾き難さ(難易度)を表す運指コストiCost、ポインタprevおよびポインタnextから構成される。なお、運指情報cfigは、「0」の場合に親指、「1」の場合に人差し指、「2」の場合に中指、「3」の場合に薬指、「4」の場合に小指を指定する。ポインタprevは、1つ前の演奏データMidiEventのアドレスを指定する。ポインタnextは、次の演奏データMidiEventのアドレスを指定する。
図3は、RAM3の小節データエリアに格納される小節データMeasureの構成を示す図である。小節データMeasure[0]〜[N]は、各小節毎の属性を表す。1つの小節データMeasureは、曲開始時点からの経過時間で表現される開始時刻lTime、小節長lGate、小節に付与されるラベル番号iLavel、ラベルオプションiLvOption、ラベル内状態iLvStatus、演奏コストiCost、ポインタprevおよびポインタnextから構成される。
なお、ラベル番号iLavel、ラベルオプションiLvOption、ラベル内状態iLvStatus、ラベル内状態iLvStatusおよび演奏コストiCostの内容については追って述べる。また、ポインタprevは、1つ前の小節データMeasureのアドレスを指定する。ポインタnextは、次の小節データMeasureのアドレスを指定する。
図4は、RAM3の練習手順データエリアに格納される練習手順データPracProcの構成を示す図である。練習手順データPracProc[0]〜[N]は、上述した曲データMidiEvent[0]〜[N]および小節データMeasure[0]〜[N]を参照した曲構造分析から得られるデータであって、曲の演奏練習に最適な練習手順を表す。1つの練習手順データPracProcは、曲開始時点からの経過時間で表現される開始時刻lTime、区間長lGate、区間先頭の小節を指定するポインタMeasTop、区間後端の小節を指定するポインタMeasTerm、区間番号iPhraseID、優先度iPriority、演奏コストiCost、ポインタprevおよびポインタnextから構成される。
なお、ポインタMeasTop、ポインタMeasTerm、区間番号iPhraseID、優先度iPriorityおよび演奏コストiCostがそれぞれ意図するところについては追って述べる。また、ポインタprevは、1つ前の練習手順データPracProcのアドレスを指定する。ポインタnextは、次の練習手順データPracProcのアドレスを指定する。
B.動作
次に、図5〜図18を参照して第1実施形態の動作について説明する。以下では、CPU1が実行するメインルーチン、構造分析処理および練習手順生成処理の各動作について述べる。なお、構造分析処理は、マトリクス処理およびグループラベリング処理から構成される。グループラベリング処理は、ラベリング処理、類似部分ラベリング補正1処理、類似部分ラベリング補正2処理、類似部分ラベリング補正3処理およびラベリング検証処理から構成される。練習手順処理は、練習手順書込処理および並べ替え処理から構成される。
(1)メインルーチンの動作
入力部4からCPU1にメイルーチンの実行を指示するイベントが供給されると、CPU1は図4に図示するメインルーチンを実行してステップSA1に進み、設定処理を実行する。設定処理では、表示部5に画面表示される設定画面SGにおいてユーザが練習手順を生成する条件として、「小節の長さ」および「優先順位」を入力設定する。
ここで、図6を参照して設定画面SGの一例について説明する。この図に示す設定画面SGは、「小節の長さ」を設定する入力フィールドIF1および「優先順位」を設定する入力フィールドIF2〜IF7を備える。これら入力フィールドIF1〜IF7に入力設定される数値が意図するところについては追って述べる。
設定画面SGの入力フィールドIF1〜IF7に入力設定すると、CPU1はステップSA2に処理を進め、曲データの読み込みを実行する。すなわち、MIDIインタフェース6を介して外部の電子楽器7からSMF形式の曲データMidiEvent[0]〜[N]を取込んでRAM3の曲データエリアに格納する。また、ステップSA1では、RAM3の曲データエリアに格納した曲データMidiEvent[0]〜[N]に基づき、小節データMeasure[0]〜[N]を派生させてRAM3の小節データエリアに格納する。
なお、ここで派生される小節データMeasure[0]〜[N]は、ラベルオプションiLvOptionおよびラベル状態iLvStatusを含まない。ラベルオプションiLvOptionおよびラベル状態iLvStatusは、後述するグループラベリング処理(図9参照)にて生成される。
また、本実施の形態では、RAM3の曲データエリアに格納した曲データMidiEvent[0]〜[N]から小節データMeasure[0]〜[N]を派生する態様としたが、これに限らず、電子楽器7側で生成された小節データMeasure[0]〜[N]を、MIDIインタフェース6を介して取込む態様としても構わない。
次いで、ステップSA3では、曲データMidiEventおよび小節情報Measureを参照して曲構造を分析する構造分析処理を実行する。そして、ステップSA4では、曲構造を分析した結果に基づき、上記ステップSA1の設定処理にて設定された前提条件を加味した形で当該曲の演奏練習に最適な練習手順を生成する。この後、ステップSA5に進み、生成された練習手順を表示部5に表示出力する。
(2)構造分析処理の動作
次に、図7を参照して構造分析処理の動作を説明する。上述したメインルーチンのステップSA3(図5参照)を介して本処理が実行されると、CPU1は図7に図示するステップSB1に進み、マトリクス処理(後述する)を実行した後、ステップSB2に進み、グループラベリング処理(後述する)を実行する。
(3)マトリクス処理の動作
次に、図8を参照してマトリクス処理の動作を説明する。上述した構造分析処理のステップSB1(図7参照)を介して本処理が実行されると、CPU1は図8に図示するステップSC1に進み、比較元となる小節を指定するポインタReに、曲先頭の小節を指定する値をセットする。次いで、ステップSC2では、ポインタReで指定される比較元小節が曲終端を超えたか否かを判断する。ポインタReで指定される比較元小節が曲終端を超えていなければ、判断結果は「NO」になり、ステップSC3に進み、比較先となる小節を指定するポインタLuに、曲先頭の小節を指定する値をセットする。
続いて、ステップSC4では、ポインタLuで指定される比較先小節が曲終端を超えたか否かを判断する。曲終端を超えていなければ、判断結果は「NO」になり、ステップSC5に進み、小節内時間tを初期化する。すなわち、ポインタLuで指定される比較先小節の小節データMeasure中の開始時刻lTimeを小節内時間tにセットする。次いで、ステップSC6では、小節内時間tが小節を超えたか否か、つまりポインタLuで指定される比較先小節の小節データMeasure中の小節長lGateを超えたかどうかを判断する。小節内時間tが小節を超えなければ、判断結果は「NO」となり、ステップSC7に進み、一致判定処理を実行する。
一致判定処理では、ポインタReで指定される比較元小節において小節内時間tで発音している比較元音の音高と、ポインタLuで指定される比較先小節において小節内時間tで発音している比較先音との有無を判断し、同一音高の比較元音と比較先音とが存在する場合や、比較元音と比較先音とが共に存在しない場合にフラグs1、s2、s3をそれぞれ「1」をセットする。
また、一致判定処理では、比較元音と比較先音とが転調関係にある相対一致の場合、すなわち小節内時間tで発音している比較元音と比較先音とが有り、かつ比較元音と基準音(比較元小節の先頭音の音高)との音高差と、比較先音と基準音(比較先小節の先頭音の音高)との音高差とが一致する場合にフラグs1を「0」、フラグs2を「1」、フラグs3を「1」にセットする。
さらに、一致判定処理では、比較元音と比較先音とが相対方向的に一致する場合、すなわち基準音(比較元小節の先頭音の音高)と比較元音との音高差の方向が、基準音(比較先小節の先頭音の音高)と比較先音との音高差との方向に一致する場合にフラグs1を「0」、フラグs2を「0」、フラグs3を「1」にセットする。
加えて、一致判定処理では、比較元音と比較先音とがリズム一致する場合、すなわち小節内時間tで発音している比較元音と比較先音とが有り、かつ両音間の発音開始時間および消音時間の差が許容範囲内である場合や、小節内時間tで発音する比較元音および比較先音が共に存在せず、かつ現在一致判定の対象とされている比較元音および比較先音のそれぞれについて前音の消音時間と次音の発音開始時間とが許容範囲内にある場合にフラグs4を「1」にセットする。
そして、ステップSC8では、上記ステップSC7の一致判定処理により設定されるフラグs1の値をレジスタsum1に、フラグs2の値をレジスタsum2に、フラグs3の値をレジスタsum3に、フラグs4の値をレジスタsum4にそれぞれ加算する。この後、ステップSC9に進み、小節内時間tを歩進させた後、上述のステップSC6に処理を戻す。
以後、歩進される小節内時間tが、ポインタLuで指定される比較先小節を超える迄、上述したステップSC6〜SC9を繰り返す。これにより、レジスタsum1にはフラグs1が「1」となる完全一致期間を累算した積算時間が格納され、レジスタsum2にはフラグs2が「1」となる相対一致期間を累算した積算時間が格納され、レジスタsum3にはフラグs3が「1」となる相対方向的一致期間を累算した積算時間が格納され、さらにレジスタsum4にはフラグs4が「1」となるリズム一致期間を累算した積算時間が格納される。
そして、歩進される小節内時間tが、ポインタLuで指定される比較先小節を超えると、上記ステップSC6の判断結果が「YES」となり、ステップSC10に進む。ステップSC10では、レジスタsum1に格納される積算時間を比較先小節分の時間tで除算して得られる一致率(sum1/t)を、マトリクス要素Mat1[Re][Lu]にストアする。また、ステップSC10では、レジスタsum2に格納される積算時間を比較先小節分の時間tで除算して得られる一致率(sum2/t)を、マトリクス要素Mat2[Re][Lu]にストアする。
さらに、ステップSC10では、レジスタsum3に格納される積算時間を比較先小節分の時間tで除算して得られる一致率(sum3/t)を、マトリクス要素Mat3[Re][Lu]にストアする。加えて、ステップSC10では、レジスタsum4に格納される積算時間を比較先小節分の時間tで除算して得られる一致率(sum4/t)を、マトリクス要素Mat4[Re][Lu]にストアして本処理を終える。
なお、ここで言うマトリクス要素Mat1[Re][Lu]、Mat2[Re][Lu]、Mat3[Re][Lu]およびMat4[Re][Lu]とは、それぞれポインタReとポインタLuとで配列要素を指定する2次元レジスタである。
次いで、ステップSC11では、ポインタLuを歩進させ、比較先小節を次の小節に設定した後、上述のステップSC4に処理を戻す。以後、曲終端を超えるまでポインタLuで指定される比較先小節を歩進させる毎に、上述したステップSC5〜SC11を繰り返し実行する。そして、ポインタLuで指定される比較先小節が曲終端を超えると、上記ステップSC4の判断結果が「YES」になり、ステップSC12に進み、ポインタReを歩進させ、比較元小節を次の小節に設定した後、上述のステップSC2に処理を戻す。以後、ポインタReが曲終端を超える迄、ステップSC2以降を繰り返す。そして、ポインタRe(比較元小節)が曲終端を超えると、ステップSC2の判断結果が「YES」となり、本処理を終える。
以上のように、マトリクス処理では、RAM3の小節データエリアに格納された小節データMeasure[0]〜[N]を参照して、RAM3の曲データエリアに格納した曲データMidiEvent[0]〜[N]を、ポインタReで指定される比較元小節とポインタLuで指定される比較元小節とに区別しておき、比較元小節Reの比較元音と比較先小節Luの比較先音との関係を小節内時間t毎に判定する。
すなわち、比較元小節Reにおいて小節内時間tで発音している比較元音の音高と、比較先小節Luにおいて小節内時間tで発音している比較先音の音高とが一致している場合もしくは小節内時間tで発音する比較元音および比較先音が共に存在しない場合に「完全一致」と判定する。また、小節内時間tで発音している比較元音と比較先音とが有り、かつ比較元音と基準音(例えば小節先頭の音の音高)との音高差と、比較先音と基準音との音高差とが一致する場合、つまり比較元音と比較先音とが転調関係にある場合に「相対一致」と判定する。
さらに、小節内時間tで発音している比較元音と比較先音とが有り、かつ基準音(比較元小節の先頭音の音高)と比較元音との音高差の方向が、基準音(比較先小節の先頭音の音高)と比較先音との音高差の方向に一致する場合に「相対方向的一致」と判定する。加えて、小節内時間tで発音している比較元音と比較先音とが有り、かつ両音間の発音開始時間および消音時間の差が許容範囲内である場合もしくは小節内時間tで発音する比較元音および比較先音が共に存在せず、かつ現在一致判定の対象とされている比較元音および比較先音のそれぞれについて前音の消音時間と次音の発音開始時間とが許容範囲内にある場合に「リズム一致」と判定する。
こうして一致判定し終えると、ポインタReで指定される比較元小節中の各比較元音と、ポインタLuで指定される比較先小節中の比較先音との完全一致期間を累算して得た積算時間を、比較先小節分の時間tで除算して一致率(sum1/t)を算出し、算出した一致率をポインタReとポインタLuとで指定されるマトリクス要素Mat1[Re][Lu]にストアする。
また、ポインタReで指定される比較元小節中の各比較元音と、ポインタLuで指定される比較先小節中の比較先音との相対一致期間を累算して得た積算時間を、比較先小節分の時間tで除算して一致率(sum2/t)を算出し、算出した一致率をポインタReとポインタLuとで指定されるマトリクス要素Mat2[Re][Lu]にストアする。
さらに、ポインタReで指定される比較元小節中の各比較元音と、ポインタLuで指定される比較先小節中の比較先音との相対方向的一致期間を累算して得た積算時間を、比較先小節分の時間tで除算して一致率(sum3/t)を算出し、算出した一致率をポインタReとポインタLuとで指定されるマトリクス要素Mat3[Re][Lu]にストアする。
加えて、ポインタReで指定される比較元小節中の各比較元音と、ポインタLuで指定される比較先小節中の比較先音とのリズム一致期間を累算して得た積算時間を、比較先小節分の時間tで除算して一致率(sum4/t)を算出し、算出した一致率をポインタReとポインタLuとで指定されるマトリクス要素Mat4[Re][Lu]にストアする。
(4)グループラベリング処理の動作
次に、図9を参照してグループラベリング処理の動作を説明する。前述した構造分析処理のステップSB2(図7参照)を介して本処理が実行されると、CPU1は図9に図示するステップSD1を介してラベリング処理を実行する。ラベリング処理では、後述するように、ポインタReおよびポインタLuで指定されるマトリクス要素Mat1[Re][Lu]の中から閾値以上の一致率が規定数以上連続する範囲(小節区間)を探し出し、その範囲に対応する小節データMeasure中のラベル番号iLavelに同じ番号を付与すると共に、完全一致を表す値「0」をラベルオプションiLvOptionとして登録する。
続いて、ステップSD2では、類似部分ラベリング補正1処理を実行する。類似部分ラベリング補正1処理では、後述するように、ポインタReで指定される比較元小節とポインタLuで指定される比較先小節とに同じラベル番号iLavelが付与されておらず、しかもマトリクス要素Mat2[Re][Lu]の中から閾値以上の相対一致率が規定数以上連続する範囲、つまり比較元小節と比較先小節とが転調関係にあると見られる小節区間を探し出し、それに該当する小節区間を「類似性のある範囲」と表すように、対応する小節データMeasureのラベル番号iLavelおよびラベルオプションiLvOptionを設定する。
次いで、ステップSD3では、類似部分ラベリング補正2処理を実行する。類似部分ラベリング補正2処理は、上記ステップSD2の類似部分ラベリング補正1処理とほぼ同一であるであるので、その詳細な動作フローの説明については省略する。類似部分ラベリング補正2処理では、ポインタReで指定される比較元小節とポインタLuで指定される比較先小節とに同じラベル番号iLavelが付与されておらず、しかもマトリクス要素Mat3[Re][Lu]の中から閾値以上の相対方向的な一致率が規定数以上連続する範囲(小節区間)を探し出し、それに該当する小節区間を「音高差が類似する範囲」と表すように、対応する小節データMeasureのラベル番号iLavelおよびラベルオプションiLvOptionを設定する。
次に、ステップSD4を介して類似部分ラベリング補正3処理を実行する。類似部分ラベリング補正3処理は、上記ステップSD2の類似部分ラベリング補正1処理とほぼ同一であるであるので、その詳細な動作フローの説明については省略する。類似部分ラベリング補正3処理では、ポインタReで指定される比較元小節とポインタLuで指定される比較先小節とに同じラベル番号iLavelが付与されておらず、しかもマトリクス要素Mat4[Re][Lu]の中から閾値以上のリズム一致率が規定数以上連続する範囲(小節区間)を探し出し、それに該当する小節区間を「リズムが一致する範囲」と表すように、対応する小節データMeasureのラベル番号iLavelおよびラベルオプションiLvOptionを設定する。
そして、ステップSD5を介してラベリング検証処理を実行する。このラベリング検証処理では、後述するように、上記ステップSD1のラベリング処理によりラベリングされた小節区間が長過ぎる場合、すなわちラベリング先頭小節(ポインタRe)と、そこから規定数以上連続した小節(ポインタRetmp)とで指定されるマトリクス要素Mat1[Re][Retmp]の一致率が閾値以上の場合、そのポインタRetmpで指定される小節の1つ前の小節を区間終端とするようにラベリングされた小節区間を分割するようになっている。
(5)ラベリング処理の動作
次に、図10を参照してラベリング処理の動作を説明する。上述したグループラベリング処理のステップSD1(図9参照)を介して本処理が実行されると、図10に図示するステップSE1に進み、先頭小節を指定する値をポインタReにセットする。続いて、ステップSE2では、ポインタReで指定される比較元小節が曲終端を超えたか否かを判断する。曲終端を超えていなければ、判断結果は「NO」となり、ステップSE3に進む。
ステップSE3では、ポインタReで指定される比較元小節にラベル付与されているか否かを判断する。ラベル付与とは、ポインタReおよびポインタLuで指定されるマトリクス要素Mat1[Re][Lu]の中で、閾値以上の一致率を有するマトリクス要素が連続する範囲(小節区間)を一致性の高いグループとし、そのグループにラベル番号(後述する)を付与することを意味する。そして、ポインタReで指定される比較元小節にラベル付与済みならば、上記ステップSE3の判断結果は「NO」になり、ステップSE13に進み、ポインタReを歩進させた後、上述のステップSE2に処理を戻す。
一方、ポインタReで指定される比較元小節にラベル付与がなされていなければ、上記ステップSE3の判断結果は「YES」になり、ステップSE4に進み、先頭小節を指定する値をポインタLuにセットする。次いで、ステップSE5では、ポインタLuで指定される比較先小節が曲終端を超えたか否かを判断する。曲終端を超えていなければ、判断結果は「NO」となり、ステップSE6に進む。
ステップSE6では、ポインタReおよびポインタLuで指定されるマトリクス要素Mat1[Re][Lu]の一致率が閾値以上であるかどうかを判断する。マトリクス要素Mat1[Re][Lu]の一致率が閾値未満ならば、判断結果は「NO」になり、ステップSE10に進み、ポインタLuを歩進させ、比較先小節を次の小節に設定した後、上述のステップSE5に処理を戻す。
一方、マトリクス要素Mat1[Re][Lu]の一致率が閾値以上ならば、上記ステップSE6の判断結果は「NO」になり、ステップSE7に進む。ステップSE7では、閾値以上の一致率を有するマトリクス要素Mat1[Re][Lu]の範囲i(小節数)、すなわちMat1[Re+i][Lu+i]を検出する。次いで、ステップSE8では、閾値以上の一致率が連続した小節数iを保存する。そして、ステップSE9では、現在のポインタLuに、閾値以上の一致率が連続した小節数iを加算してポインタLuを更新させた後、上述のステップSE5に処理を戻す。
以後、更新されたポインタLuが曲終端を超える迄、一致率が連続して閾値を超える小節数iを検出する。そして、更新されたポインタLuが曲終端を超えると、上記ステップSE5の判断結果が「YES」になり、ステップSE11に進む。ステップSE11では、規定数以上の小節が閾値以上であるか否かを判断する。検出した小節数iが規定数未満であると、判断結果は「NO」になり、ステップSE13に進み、ポインタReを歩進させた後、前述したステップSE2に処理を戻す。
これに対し、検出した小節数iが規定数以上ならば、上記ステップSE11の判断結果が「YES」になり、ステップSE12に進み、採番およびラベリングを行う。すなわち、ステップSE12では、RAM3の小節データエリアに格納される小節データMeasure[0]〜[N]の内、閾値以上の一致率が連続した小節データMeasure中のラベル番号iLavelに同じ番号を付与すると共に、ラベルオプションiLvOptionとして、完全一致を表す値「0」をセットする。
この後、ステップSE13に進み、ポインタReを歩進させた後、前述したステップSE2に処理を戻す。以後、歩進されたポインタReで指定される比較元小節が曲終端を超える迄、上述したステップSE3以降の動作を繰り返す。そして、歩進されたポインタReで指定される比較元小節が曲終端を超えると、ステップSE2の判断結果が「YES」となり、本処理を終える。
このように、ラベリング処理では、ポインタReおよびポインタLuで指定されるマトリクス要素Mat1[Re][Lu]の中から閾値以上の一致率が規定数以上連続する範囲(小節区間)を探し出し、その範囲に対応する小節データMeasure中のラベル番号iLavelに同じ番号を付与すると共に、完全一致を表す値「0」をラベルオプションiLvOptionとして登録する。
なお、マトリクス要素Mat1[Re][Lu]中で閾値以上の一致率が規定数以上連続する範囲(小節区間)を検索し、該当する区間の各小節データMeasureにラベル番号iLavelを付与すると共に、完全一致を表す値「0」をラベルオプションiLvOptionに登録する処理操作全体をラベリングと称す。
(6)類似部分ラベリング補正1処理の動作
次に、図11を参照して類似部分ラベリング補正1処理の動作を説明する。上述したグループラベリング処理のステップSD2(図9参照)を介して本処理が実行されると、CPU1は図11に図示するステップSF1に進み、小節の先頭を指定する値をポインタReにセットする。続いて、ステップSF2では、ポインタReで指定される比較元小節が曲終端を超えたか否かを判断する。曲終端を超えていなければ、判断結果は「NO」となり、次のステップSF3に進む。
ステップSF3では、小節の先頭を指定する値をポインタLuにセットする。次いで、ステップSF4では、ポインタLuで指定される比較先小節が曲終端を超えたか否かを判断する。曲終端を超えていなければ、判断結果は「NO」となり、ステップSF5に進む。ステップSF5では、ポインタReで指定される比較元小節とポインタLuで指定される比較先小節とに同じラベル番号iLavelが付与されていないかどうかを判断する。同じラベル番号iLavelが付与されていれば、判断結果は「NO」になり、ステップSF12に進み、ポインタLuを歩進させた後、上述のステップSF4に処理を戻す。
一方、ポインタReで指定される比較元小節とポインタLuで指定される比較先小節とに同じラベル番号iLavelが付与されていない場合には、上記ステップSF5の判断結果が「YES」になり、ステップSF6に進む。ステップSF6では、ポインタReおよびポインタLuで指定されるマトリクス要素Mat2[Re][Lu]の相対一致率が閾値以上であるかどうかを判断する。マトリクス要素Mat2[Re][Lu]の相対一致率が閾値未満ならば、判断結果は「NO」になり、ステップSF12に進み、ポインタLuを歩進させた後、上述のステップSF4に処理を戻す。
これに対し、マトリクス要素Mat2[Re][Lu]の相対一致率が閾値以上ならば、上記ステップSF6の判断結果が「YES」になり、ステップSF7に進む。ステップSF7では、閾値以上の相対一致率を有するマトリクス要素Mat2[Re][Lu]の範囲i(小節数)、すなわちMat2[Re+i][Lu+i]を検出する。次いで、ステップSF8では、閾値以上の相対一致率が連続した小節数iを保存する。そして、ステップSF9では、上記ステップSF7にて検出した小節数iが規定小節以上であるか否かを判断する。
検出した小節数iが規定小節未満ならば、判断結果は「NO」になり、ステップSF12に進み、ポインタLuを歩進させた後、上述のステップSF4に処理を戻す。一方、検出した小節数iが規定小節以上であると、上記ステップSF9の判断結果が「YES」になり、ステップSF10に進み、ラベル付け替え処理を実行する。
ラベル付け替え処理では、
(イ)比較元小節Reおよび比較先小節Luの双方にラベル番号iLavelが付与されている場合には、比較先小節Luのラベル番号iLavelを比較元小節Reのラベル番号iLavelに書き換え、比較先小節LuのラベルオプションiLvOptionに類似(相対一致)を表す値「1」を設定する。
(ロ)比較元小節Reだけにラベル番号iLavelが付与されている場合には、そのラベル番号iLavelを比較先小節Luのラベル番号iLavelに設定すると共に、比較先小節LuのラベルオプションiLvOptionに値「1」を設定する。
(ハ)比較先小節Luだけにラベル番号iLavelが付与されている場合には、そのラベル番号iLavelを比較元小節Reのラベル番号iLavelに設定すると共に、比較元小節ReのラベルオプションiLvOptionに値「1」を設定する。
(ニ)比較元小節Reおよび比較先小節Luの双方にラベル番号iLavelが付与されていない場合には、新たに採番したラベル番号を、比較元小節Reおよび比較先小節Luのラベル番号iLavelに設定すると共に、比較元小節ReのラベルオプションiLvOptionに値「0」を、比較先小節LuのラベルオプションiLvOptionに値「1」を設定する。
そして、こうしたラベル付け替え処理が行われると、ステップSF11に進み、現在のポインタLuに、閾値以上の相対一致率が連続した小節数iを加算してポインタLuを更新させた後、上述のステップSF4に処理を戻す。以後、更新されたポインタLuで指定される比較先小節が曲終端を超える迄、相対一致率が規定小節以上連続して閾値を超える小節数iを探し出し、該当する小節区間についてラベル付け替えする処理を繰り返す。
そして、更新されたポインタLuで指定される比較先小節が曲終端を超えると、上記ステップSF4の判断結果が「YES」になり、ステップSF13に進み、ポインタReを歩進させた後、上述のステップSF2に処理を戻す。以後、歩進されたポインタReで指定される比較元小節が曲終端を超える迄、上述したステップSF3以降の処理を繰り返す。そして、歩進されたポインタReで指定される比較元小節が曲終端を超えると、ステップSF2の判断結果が「YES」となり、本処理を終える。
以上のように、類似部分ラベリング補正1処理では、ポインタReで指定される比較元小節とポインタLuで指定される比較先小節とに同じラベル番号iLavelが付与されておらず、しかもマトリクス要素Mat2[Re][Lu]の中から閾値以上の相対一致率が規定数以上連続する範囲、すなわち比較元小節と比較先小節とが転調関係にあると見られる小節区間を探し出し、該当する小節区間を「類似性のある範囲」と表すように対応する小節データMeasureのラベル番号iLavelおよびラベルオプションiLvOptionを設定するようになっている。
(7)ラベリング検証処理の動作
次に、図12〜図14を参照してラベリング検証処理の動作を説明する。上述したグループラベリング処理のステップSD5(図9参照)を介して本処理が実行されると、CPU1は図11に図示するステップSG1に処理を進め、先頭小節を指定する値をポインタReにセットする。続いて、ステップSG2では、ポインタReで指定される小節が曲終端を超えたか否かを判断する。曲終端を超えていなければ、判断結果は「NO」になり、ステップSG3に進む。ステップSG3では、ポインタReで指定される小節が、ラベリングされた区間の先頭小節(以下、ラベリング先頭小節と称す)であるか否かを判断する。
ラベリング先頭小節でなければ、判断結果は「NO」になり、ステップSG4に進み、ポインタReを歩進させた後、上記ステップSG2に処理を戻す。以後、上記ステップSG2〜SG4を繰り返すことによって、曲終端に達するまで、ポインタReを歩進させながらラベリング先頭小節を検索する。そして、ラベリング先頭小節が見つかると、上記ステップSG3の判断結果が「YES」になり、ステップSG5に進み、現在のポインタReを、ラベリング先頭小節を指定するポインタRetmpにセットする。
次いで、ステップSG6では、ポインタRetmpがラベリングされた小節の後端(以下、ラベリング後端小節と称す)に達したか否かを判断し、続いて、図13に図示するステップSG7では、ポインタRetmpがラベリング先頭小節を指定するか否かを判断する。以下、ポインタRetmpがラベリング先頭小節を指定する場合と、ラベリング先頭後端を指定する場合とに分けて動作を説明する。
<ポインタRetmpがラベリング先頭小節を指定する場合>
上記ステップSG5(図11参照)を介して最初にステップSG6へ進むパスでは、ポインタRetmpがラベリング先頭小節を指定するので、上記ステップSG6の判断結果は「NO」になり、図13に図示するステップSG7に進み、ここでの判断結果が「YES」になり、ステップSG8に進む。
ステップSG8では、ポインタReからポインタRetmpまでの小節数が規定数以上であるかどうかを判断する。初めてステップSG8に進むパスでは、ポインタReとポインタRetmpとが同一なので、判断結果は「NO」になり、ステップSG9に進む。ステップSG9では、ポインタRetmpで指定されるラベリング先頭小節の小節データMeasureに含まれるラベル内状態iLvStatusを「0」にセットして先頭の状態を解除する。
なお、小節データMeasure中のラベル内状態iLvStatus(図3参照)は、ラベリングされた小節の先頭であることを表す場合に「1」、ラベリングされた小節の後端であることを表す場合に「2」、状態解除を表す場合に「0」となるフラグである。
さて、こうして先頭の状態を解除し終えると、ステップSG10に進み、ポインタRetmpを歩進させた後、再び図12に図示するステップSG6に処理を戻す。以後、ポインタRetmpがラベリング先頭小節を指定し、かつポインタReからポインタRetmpまでの小節数が規定数以上存在するようになるまで、上述したステップSG6〜SG10を繰り返す。そして、ポインタRetmpの歩進に応じて、上記条件を満たすと、ステップSG8の判断結果が「YES」になり、ステップSG11に進む。
ステップSG11では、ポインタReとポインタRetmpとで指定されるマトリクス要素Mat1[Re][Lu]の一致率が閾値以上であるか否かを判断する。閾値未満ならば、判断結果が「NO」になり、上述したステップSG9に進む。一方、マトリクス要素Mat1[Re][Retmp]の一致率が閾値以上であると、上記ステップSG11の判断結果が「YES」になり、ステップSG12に進む。ステップSG12では、ポインタRetmpで指定される小節の1つ前の小節データMeasureに含まれるラベル内状態iLvStatusを「2」にセットしてラベリング後端小節に設定する。これによりラベリングされた小節区間が切断される。
<ポインタRetmpがラベリングされた小節の後端に達した場合>
以上のようにして、ラベリングされた小節区間が切断された後に、ステップSG10を介してポインタRetmpを歩進させた後、再び図11に図示するステップSG6に処理を戻す。そして、歩進されたポインタRetmpがラベリング後端小節に達すると、このステップSG6の判断結果が「YES」になり、図13に図示するステップSG13に進む。
ステップSG13では、エラー状態の有無を判断する。エラー状態とは、ポインタRetmpで指定される小節のラベル番号iLavelと、次小節のラベル番号iLavelとが同じで、ポインタRetmpの次の小節の小節データMeasure中のラベル内状態iLvStatusが「1(先頭)」でない状態を指す。そして、エラー状態でなければ、判断結果は「NO」になり、ステップSG14に進み、ポインタRetmpをポインタReにセットした後、前述のステップSG4(図12参照)に処理を戻す。
以後、上述した過程を実行し、ラベリング先頭小節から規定数以上存在し、かつポインタReとポインタRetmpとで指定されるマトリクス要素Mat1[Re][Retmp]の一致率が閾値以上であれば、ポインタRetmpで指定される小節の1つ前の小節データMeasureに含まれるラベル内状態iLvStatusを「2」にセットしてラベリングされた小節区間を切断する。
一方、上記ステップSG13にてエラー状態が検出されると、当該ステップSG13の判断結果が「YES」になり、ステップSG15に進み、ポインタRetmpを歩進させる。次いで、ステップSG16では、ポインタReとポインタRetmpとで指定されるマトリクス要素Mat1[Re][Retmp]の一致率が閾値以上であるか否かを判断する。
マトリクス要素Mat1[Re][Retmp]の一致率が閾値以上ならば、判断結果は「YES」になり、ステップSG17に進み、ポインタRetmpで指定される小節の小節データMeasureに含まれるラベル内状態iLvStatusを「1」にセットしてラベリング先頭小節に設定した後、上述のステップSG10に処理を戻す。
これに対し、ポインタReとポインタRetmpとで指定されるマトリクス要素Mat1[Re][Retmp]の一致率が閾値未満であると、上記ステップSG16の判断結果が「NO」となり、ステップSG18に進み、ポインタRetmpで指定される小節の小節データMeasureに含まれるラベル番号iLavelおよびラベル内状態iLvStatusを初期化してラベル解除する。
そして、ステップSG19では、ポインタRetmpで指定される小節のラベル番号iLavelと、次小節のラベル番号iLavelとが同じになるか否か、つまりエラー状態が連続しているかどうかを判断する。エラー状態が連続していると、判断結果が「YES」になり、ステップSG20に進み、ポインタRetmpを歩進させた後、上記ステップSG18に処理を戻す。以後、エラー状態が連続すれば、ステップSG18〜SG20を繰り返す。そして、エラー状態でなくなると、上記ステップSG19の判断結果が「NO」になり、上述したステップSG14に処理を進める。
以上のように、ラベリング検証処理では、ラベリングされた小節区間が長過ぎる場合、つまりラベリング先頭小節から規定値以上の小節数が連続する場合には、ポインタReとポインタRetmpとで指定されるマトリクス要素Mat1[Re][Retmp]を参照し、その一致率が閾値以上であれば、ポインタRetmpで指定される小節の1つ前の小節データMeasureに含まれるラベル内状態iLvStatusを「2」にセットしてラベリングされた小節区間を切断する。
例えば、マトリクス要素Mat1[Re][Retmp]において、図14(a)に図示するように、ラベリングされた小節区間が長過ぎ、ラベリング先頭小節から規定数以上連続するような場合には、同図(b)に図示する通り、ポインタRetmpで指定される小節の1つ前の小節で分断するようになっている。
(8)練習手順生成処理の動作
次に、図15を参照して練習手順生成処理の動作を説明する。前述したメインルーチンのステップSA4(図5参照)を介して本処理が実行されると、CPU1は図15に図示するステップSH1に進み、練習手順書込処理(後述する)を実行した後、ステップSH2に進み、並べ替え処理(後述する)を実行する。
(9)練習手順書込処理の動作
図16は、練習手順書込処理の動作を示すフローチャートである。上述した練習手順生成処理のステップSH1(図15参照)を介して本処理が実行されると、CPU1は図16に図示するステップSJ1に進み、RAM3の曲データエリアに格納される曲データMidiEvent[0]〜[N]に運指情報cfigが付与されているか否かを判断する。運指情報cfigが付与されていなければ、判断結果は「NO」になり、ステップSJ2に進み、曲データMidiEvent[0]〜[N]に基づき運指情報cfigを生成して曲データMidiEvent[0]〜[N]に付与する運指情報生成処理を実行した後、ステップSJ3に進む。
一方、運指情報cfigが既に曲データMidiEvent[0]〜[N]に付与されている場合には、上記ステップSJ1の判断結果が「YES」になり、ステップSJ3に進む。ステップSJ3では、先頭小節を指定する値をポインタMsにセットする。続いて、ステップSJ4では、ポインタMsで指定される小節が曲終端を超えたか否かを判断する。曲終端を超えていなければ、判断結果は「NO」となり、次のステップSJ5に進む。
ステップSJ5では、ポインタMsで指定される小節の小節データMeasure中にラベル番号iLavelが付与され、かつポインタMsで指定される小節がラベリング先頭小節であるか否かを判断する。ラベル番号iLavelが付与され、かつラベリング先頭小節でなければ、判断結果は「NO」になり、ステップSJ13に進み、ポインタMsを歩進させて次の小節を指定した後、上述したステップSJ4に処理を戻す。
一方、ポインタMsで指定される小節の小節データMeasureにラベル番号iLavelが付与され、かつポインタMsで指定される小節がラベリング先頭小節ならば、上記ステップSJ5の判断結果は「YES」になり、ステップSJ6に進む。ステップSJ6では、ポインタMsで指定される小節の次の小節を指定するポインタをポインタMstにストアする。次いで、ステップSJ7〜SJ8では、ポインタMstを歩進させながら、ラベル番号iLavelが付与され、かつラベリング後端の小節を探し出す。そして、該当する小節(ラベル番号iLavelが付与され、かつラベリング後端の小節)が見つかると、ステップSJ7の判断結果が「YES」になり、ステップSJ9に進む。
ステップSJ9では、ポインタMsで指定される小節からポインタMstで指定される小節までの区間における演奏難易度を算出する区間難易度計算処理を実行する。区間難易度計算処理では、先ず対応する区間中の各音を表す曲データMidiEventに含まれる運指情報cfigを参照して隣の音(次音)を押鍵する際の弾き易さを数値化した演奏コストiCostを生成し、生成された区間中の各音の演奏コストiCostを加算平均して当該区間の演奏難易度を定義する。
次いで、ステップSJ10では、RAM3に設けられる練習手順データエリアにおいて、練習手順データPracProcがストアされていない手順データ空き位置をポインタpdにセットする。そして、ステップSJ11では、ポインタpdで指定される練習手順データPracProc[pd]のポインタMeasTopとして、ポインタMsの値(ラベリング先頭の小節を指定する値)をストアする。
また、ステップSJ11では、ポインタpdで指定される練習手順データPracProc[pd]のポインタMeasTermとして、ポインタMstの値(ラベリング後端の小節を指定する値)をストアする。さらに、ステップSJ11では、ポインタpdで指定される練習手順データPracProc[pd]の区間番号iPhraseIDとして、ポインタMsで指定されるラベリング先頭小節の小節データMeasure中のラベル番号iLavel(Ms.iLavel)をストアする。また、ステップSJ11では、ポインタpdで指定される練習手順データPracProc[pd]の演奏コストiCostとして、上記ステップSJ9で算出した演奏難易度をストアする。
こうして、1つのラベリングされた区間を練習手順データPracProc[pd]として登録し終えると、ステップSJ12に進み、ポインタMstの値をポインタMsにセットした後、ステップSJ13に進み、ポインタMsを歩進させた後、上述のステップSJ4に処理を戻す。以後、上述したステップSJ4以降の動作を繰り返して演練習手順データPracProc[pd]を順次登録する。そして、ステップSJ13にて歩進されたポインタMsが曲終端を超えると、ステップSJ4の判断結果が「YES」となり、本処理を終える。
このように、練習手順書込処理では、ラベル番号iLavelを備えたラベリング先頭小節およびラベリング後端小節からなる区間を探し出し、該当する区間が見つかる毎に、その区間中の各音を表す曲データMidiEventに含まれる運指情報cfigを参照して隣の音(次音)を押鍵する際の弾き易さを数値化した演奏コストiCostを生成し、生成された区間中の各音の演奏コストiCostを加算平均して当該区間の演奏難易度を算出する。そして、この算出した演奏難易度を演奏コストiCost、区間の先頭および後端を表すポインタMs、Mstおよび区間のラベル番号Ms.iLavelを、練習手順データPracProc[pd]として登録する。
(10)並べ替え処理の動作
図17は、並べ替え処理の動作を示すフローチャートである。前述した練習手順生成処理のステップSH2(図15参照)を介して本処理が実行されると、CPU1は図17に図示するステップSK1に進み、RAM3の練習手順データエリアに格納される練習手順データPracProc[0]〜[N]の内、最初の練習手順データPracProcを指定するポインタを、ポインタpdにストアする。次いで、ステップSK2では、ポインタpdが練習手順データPracProcの終端を超えたか否かを判断する。
終端を超えていなければ、上記ステップSK2の判断結果は「NO」になり、ステップSK3に進む。ステップSK3では、初期設定としてレジスタiLengthをゼロリセットする。なお、レジスタiLengthには、1つの練習手順データPracProcにより指定される区間が、設定画面SG(図6参照)の入力フィールドIF1に入力設定した「小節数」以上の場合に「0(長い)」が、それ未満の場合に「1(短い)」がストアされる。こうした値がストアされるレジスタiLengthは、後述する優先順位マトリクスPriMat[iLength][iLevel]の引数として扱われる。
次いで、ステップSK4では、ポインタpdで指定される練習手順データPracProc[pd]中の区間長lGate(pd.lGate)が、設定画面SGの入力フィールドIF1に入力設定された小節数MeasLongより短いか否かを判断する。区間長lGate(pd.lGate)が小節数MeasLongより短ければ、判断結果は「YES」になり、ステップSK5に進み、レジスタiLengthに「1」をストアした後、ステップSK6に進む。
一方、区間長lGate(pd.lGate)が小節数MeasLongより長ければ、上記ステップSK4の判断結果は「NO」となり、レジスタiLengthの値は「0(長い)」のままステップSK6に進む。ステップSK6では、初期設定としてレジスタiLevelに「1(標準)」をストアする。なお、レジスタiLevelは、後述する優先順位マトリクスPriMat[iLength][iLevel]の引数として扱われ、その値は難易度(「1(標準)」、「2(易しい)」、「0(難しい)」)を表す。
続いて、ステップSK7では、ポインタpdで指定される練習手順データPracProc[pd]中の演奏コストiCost(pd.iCost)が、レジスタCostRange[1][1]に格納される第1判定値以下であるか否かを判断する。演奏コストiCost(pd.iCost)が、レジスタCostRange[1][1]に格納される第1判定値以下ならば、判断結果は「YES」になり、ステップSK8に進み、レジスタiLevelに「2(易しい)」をストアした後、後述のステップSK11に進む。
一方、演奏コストiCost(pd.iCost)が、レジスタCostRange[1][1]に格納される第1判定値より大きいと、上記ステップSK7の判断結果が「NO」になり、ステップSK9に進む。ステップSK9では、ポインタpdで指定される練習手順データPracProc[pd]中の演奏コストiCost(pd.iCost)が、レジスタCostRange[0][3]に格納される第2判定値以下であるか否かを判断する。演奏コストiCost(pd.iCost)が、レジスタCostRange[0][3]に格納される第2判定値以下ならば、判断結果は「YES」になり、ステップSK10に進み、レジスタiLevelに「0(難しい)」をストアした後、後述のステップSK11に進む。
演奏コストiCost(pd.iCost)が、レジスタCostRange[0][3]に格納される第2判定値より大きいと、上記ステップSK9の判断結果は「NO」になり、ステップSK11に進む。ステップSK11では、レジスタiLengthの値とレジスタiLevelの値とに応じて、優先順位マトリクスPriMat[iLength][iLevel]から読み出される優先順位を、ポインタpdで指定される練習手順データPracProc[pd]中の優先度iPriority(pd.iPriority)にストアする。
なお、2次元配列レジスタから構成され、レジスタiLengthの値とレジスタiLevelの値とで指定される優先順位マトリクスPriMat[2][3]には、設定画面SG(図6参照)に設けられ、「優先順位」が入力設定される2行3列の入力フィールドIF2〜SF7の入力値がストアされる。
例えば、設定画面SGの入力フィールドIF2〜SF7において、図6に図示する各値がそれぞれ入力設定された場合に、iLength=1、iLevel=1であると、優先順位マトリクスPriMat[1][1]から優先順位「1」が読み出され、これがポインタpdで指定される練習手順データPracProc[pd]中の優先度iPriority(pd.iPriority)として登録される。
このようにして、練習手順データPracProc[pd]に優先度iPriority(pd.iPriority)が登録されると、ステップSK12に進み、ポインタpdを歩進させて次の練習手順データPracProcを指定させた後、上述のステップSK2に処理を戻す。
以後、歩進されたポインタpdが終端を超える迄、上述したステップSK2〜SK12の処理を繰り返す。そして、全ての練習手順データPracProc[0]〜[N]について優先度iPriority(pd.iPriority)を登録し終え、歩進されたポインタpdが終端を超えると、上述したステップSK2の判断結果が「YES」になり、ステップSK13に進む。
ステップSK13では、各練習手順データPracProc[0]〜[N]に含まれる優先度iPriorityに従って、これら練習手順データPracProc[0]〜[N]を優先度順に並べ替える。続いて、ステップSK14では、上記ステップSK13にて優先度順に並べ替えられた練習手順データPracProcにおいて、例えば完全一致するグループ(区間)に対応した練習手順データPracProcが連続する等、同じフレーズグループが連続するケースが存在する場合には、後続のグループに対応した練習手順データPracProcを練習手順から外して本処理を終える。
以上説明したように、第1実施形態では、小節データMeasure[0]〜[N]および曲データMidiEvent[0]〜[N]に基づき曲構造を分析することによって、曲中でメロディが重複したり類似する区間などの複数の区間に分割し、分割された各区間の演奏難易度と区間長とを求めた後、ユーザ設定された区間の長さおよび演奏難易度に関する優先順位に従い、分割された各区間の長さと各区間の演奏難易度とを勘案して各区間の練習手順を指定する練習手順データPracProcを生成する。そして、生成した練習手順データPracProcを、例えば図18に図示するような表示態様でユーザに提示する結果、楽曲の構造に即した練習手順を生成することができるようになる。なお、図18において、例えば区間Aは完全一致区間、区間Bは相対一致区間、区間Cは相対方向的一致区間、区間Dはリズム一致区間を表す。
また、本実施の形態では、構造分析処理(図7参照)によって、比較元小節Reに対する比較先小節Luの一致度を判定し、判定された一致度の中から閾値以上の「完全一致度」、「相対一致度」、「相対方向的一致度」および「リズム一致度」が連続する比較先小節Luの範囲を、「完全一致区間」、「相対一致区間」、「相対方向的一致区間」および「リズム一致区間」に分割するので、曲構造に応じて楽曲を複数の区間、つまりメロディが重複する区間、メロディが類似する区間、音高変化が類似する区間およびリズムが一致する区間に分割することができる。さらに、本実施の形態では、設定画面SG(図6参照)において設定された優先順位を参照して、分割された区間の長さと、その区間の演奏難易度とに応じた優先度を発生して該当区間に付与し、付与された各区間を優先度順に並び替えるので、演奏練習を行うのに最適な練習順序を生成することができる。
[第2実施形態]
次に、図19〜図21を参照して第2実施形態について説明する。第2実施形態の構成は、前述した第1実施形態と同一なので、その説明については省略する。上述した第1実施形態では、ユーザ指定の優先順位に従って、各区間(ラベリングされた小節区間)の演奏難易度および区間長を勘案してそれら各区間の練習手順を生成したのに対し、第2実施形態では、ユーザが指定する優先順位および自己の演奏レベルに従って、各区間の演奏難易度および区間長を勘案してそれら各区間の練習手順を生成する。以下では、こうした第2実施形態による「並べ替え処理」の各動作を説明する。
第2実施形態では、図19に図示する設定画面SGにおいて、自己の演奏レベルを設定するボタンB1〜B5を有する点で第1実施形態と相違する。なお、図19に図示する一例では、ボタンB2が選択され、自己の演奏レベルが「入門」レベルであることを示している。設定画面SGに配設されるボタンB1〜B5のいずれかを選択して設定される自己の演奏レベルは、後述するレジスタUseLvにストアされる。
次に、図20を参照して第2実施形態による並べ替え処理の動作を説明する。上述した第1実施形態と同様に、練習手順生成処理のステップSH2(図15参照)を介して本処理が実行されると、CPU1は図20に図示するステップSL1に進み、RAM3の練習手順データエリアに格納される練習手順データPracProc[0]〜[N]の内、最初の練習手順データPracProcを指定するポインタを、ポインタpdにストアする。次いで、ステップSL2では、ポインタpdが練習手順データPracProcの終端を超えたか否かを判断する。
終端を超えていなければ、上記ステップSL2の判断結果は「NO」になり、ステップSL3に進む。ステップSL3では、レジスタiLengthをゼロリセットする。なお、レジスタiLengthには、1つの練習手順データPracProcにより指定される区間が、設定画面SG(図19参照)の入力フィールドIF1に入力設定した「小節数」以上の場合に「0(長い)」が、それ未満の場合に「1(短い)」がストアされる。こうした値がストアされるレジスタiLengthは、後述する優先順位マトリクスPriMat[iLength][iLevel]の引数として扱われる。
次いで、ステップSL4では、ポインタpdで指定される練習手順データPracProc[pd]中の区間長lGate(pd.lGate)が、設定画面SGの入力フィールドIF1に入力設定された小節数MeasLongより短いか否かを判断する。区間長lGate(pd.lGate)が小節数MeasLongより短ければ、判断結果は「YES」になり、ステップSL5に進み、レジスタiLengthに「1」をストアした後、ステップSL6に進む。
一方、区間長lGate(pd.lGate)が小節数MeasLongより長ければ、上記ステップSL4の判断結果は「NO」となり、レジスタiLengthの値は「0(長い)」のままステップSL6に進む。ステップSL6では、レジスタiLevelに「1(標準)」をストアする。なお、レジスタiLevelは、後述する優先順位マトリクスPriMat[iLength][iLevel]の引数として扱われ、その値は難易度(「1(標準)」、「2(易しい)」、「0(難しい)」)を表す。
続いて、ステップSL7では、ポインタpdで指定される練習手順データPracProc[pd]中の演奏コストiCost(pd.iCost)が、レジスタUseLvに格納されたユーザ演奏レベルで指定される第1判定値CostRange[1][UseLv]以下であるか否かを判断する。演奏コストiCost(pd.iCost)が、第1判定値CostRange[1][UseLv]以下ならば、判断結果は「YES」になり、ステップSL8に進み、レジスタiLevelに「2(易しい)」をストアした後、後述のステップSL11に進む。
一方、演奏コストiCost(pd.iCost)が、第1判定値CostRange[1][UseLv]より大きいと、上記ステップSL7の判断結果が「NO」になり、ステップSL9に進む。ステップSL9では、ポインタpdで指定される練習手順データPracProc[pd]中の演奏コストiCost(pd.iCost)が、レジスタUseLvに格納されたユーザ演奏レベルで指定される第2判定値CostRange[0][UseLv]以下であるか否かを判断する。演奏コストiCost(pd.iCost)が、第2判定値CostRange[0][UseLv]以下ならば、判断結果は「YES」になり、ステップSL10に進み、レジスタiLevelに「0(難しい)」をストアした後、後述のステップSL11に進む。
演奏コストiCost(pd.iCost)が、第2判定値CostRange[0][UseLv]より大きいと、上記ステップSL9の判断結果は「NO」になり、ステップSL11に進む。ステップSL11では、レジスタiLengthの値とレジスタiLevelの値とに応じて、優先順位マトリクスPriMat[iLength][iLevel]から読み出される優先順位を、ポインタpdで指定される練習手順データPracProc[pd]中の優先度iPriority(pd.iPriority)にストアする。
なお、2次元配列レジスタから構成され、レジスタiLengthの値とレジスタiLevelの値とで指定される優先順位マトリクスPriMat[2][3]には、設定画面SG(図19参照)に設けられ、「優先順位」が入力設定される2行3列の入力フィールドIF2〜SF7の入力値がストアされる。例えば、設定画面SGの入力フィールドIF2〜SF7において、図19に図示する各値がそれぞれ入力設定された場合に、iLength=1、iLevel=1であると、優先順位マトリクスPriMat[1][1]から優先順位「1」が読み出され、これがポインタpdで指定される練習手順データPracProc[pd]中の優先度iPriority(pd.iPriority)として登録される。
このようにして、練習手順データPracProc[pd]に優先度iPriority(pd.iPriority)が登録されると、ステップSL12に進み、ポインタpdを歩進させて次の練習手順データPracProcを指定させた後、上述のステップSL2に処理を戻す。
以後、歩進されたポインタpdが終端を超える迄、上述したステップSL2〜SL12の処理を繰り返す。そして、全ての練習手順データPracProc[0]〜[N]について優先度iPriority(pd.iPriority)を登録し終え、歩進されたポインタpdが終端を超えると、上述したステップSL2の判断結果が「YES」になり、ステップSL13に進む。
ステップSL13では、各練習手順データPracProc[0]〜[N]に含まれる優先度iPriorityに従って、これら練習手順データPracProc[0]〜[N]を優先度順に並べ替える。続いて、ステップSL14では、上記ステップSL13にて優先度順に並べ替えられた練習手順データPracProcにおいて、例えば完全一致するグループ(区間)に対応した練習手順データPracProcが連続する等、同じフレーズグループが連続するケースが存在する場合には、後続のグループに対応した練習手順データPracProcを練習手順から外して本処理を終える。
以上のように、第2実施形態では、小節データMeasure[0]〜[N]および曲データMidiEvent[0]〜[N]に基づき曲構造を分析することによって、曲中でメロディが重複したり類似する区間などの複数の区間に分割し、分割された各区間の演奏難易度と区間長とを求めた後、ユーザが指定する優先順位および自己の演奏レベルに従い、各区間の演奏難易度および区間長を勘案して分割された各区間の練習手順を指定する練習手順データPracProcを生成する。そして、生成した練習手順データPracProcを、例えば図21に図示するような表示態様でユーザに提示する結果、自己の演奏レベルを加味しつつ、楽曲の構造に即した練習手順を生成することができる。なお、図21において、例えば区間Aは完全一致する区間、区間Bは相対一致する区間、区間Cは相対方向的に一致する区間および区間Dはリズム一致する区間を表す。