運指情報生成装置および運指情報生成処理プログラム
【課題】 処理負荷を低減させて処理時間の短縮化を図る運指情報生成装置を実現する。
【解決手段】 処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割し、分割されたフレーズ毎に運指生成スレッドを起動させてフレーズを構成する演奏データMidiEventに基づき運指生成を行い、これにて得られたフレーズの運指データを、同じフレーズ番号phIDを有するフレーズを構成する演奏データMidiEvent中の運指データcfigとしてコピーする。こうした処理を各トラックについて並列的に実行する結果、処理負荷を低減させて処理時間の短縮化を図ることが可能になる。
【解決手段】 処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割し、分割されたフレーズ毎に運指生成スレッドを起動させてフレーズを構成する演奏データMidiEventに基づき運指生成を行い、これにて得られたフレーズの運指データを、同じフレーズ番号phIDを有するフレーズを構成する演奏データMidiEvent中の運指データcfigとしてコピーする。こうした処理を各トラックについて並列的に実行する結果、処理負荷を低減させて処理時間の短縮化を図ることが可能になる。
【発明の詳細な説明】
【技術分野】
【0001】
本発明は、鍵盤を備えた電子楽器に用いて好適な運指情報生成装置および運指情報生成処理プログラムに関する。
【背景技術】
【0002】
鍵操作する際の指使い(運指)を演奏者に案内する運指情報を発生する装置が知られている。例えば特許文献1には、隣り合う2つの音に対して鍵盤を操作したときの指使いの容易さを表す2音運指データをそれぞれの指の組合わせに対応付けて記憶しておき、その内から演奏データ(与えられたメロディの音列)に対応する2音運指データを読み出し、読み出した2音運指データの累算値を最適にする運指を決定して運指情報を発生させる装置が開示されている。
【0003】
【特許文献1】特許第2526954号明細書
【発明の開示】
【発明が解決しようとする課題】
【0004】
ところで、上記特許文献1に開示された運指生成手法の他に、所定数の演奏データについて考えられる全ての指使い(運指)を評価し、その中から最適な運指を決定する手法も知られているが、そうした手法では考えられる全ての指使いについて個々に評価することから処理負荷が大きく膨大な処理時間を要するという問題がある。
そこで本発明は、このような事情に鑑みてなされたもので、処理負荷を低減させて処理時間の短縮化を図ることができる運指情報生成装置および運指情報生成処理プログラムを提供することを目的としている。
【課題を解決するための手段】
【0005】
上記目的を達成するため、請求項1に記載の発明では、曲を構成する各音を表すと共に、各音の演奏パートを表す演奏データを記憶する記憶手段と、前記記憶手段に記憶された演奏データをフレーズ区間に分割する動作を各演奏パート毎に並列的に行わせるフレーズ分割手段と、前記フレーズ分割手段により分割されたフレーズ区間の運指を生成する動作を各フレーズ区間毎に並列的に行わせる運指生成手段とを具備することを特徴とする。
【0006】
上記請求項1に従属する請求項2に記載の発明では、前記フレーズ分割手段は、処理対象とする演奏パートの演奏データの先頭から所定音数分に区切った参照フレーズを設定する設定手段と、前記設定手段により設定された参照フレーズ以降から当該参照フレーズに一致する比較フレーズを検索する第1の検索手段と、前記第1の検索手段が参照フレーズに一致する比較フレーズを検索できない場合に、参照フレーズの位置をずらしながら当該参照フレーズに一致する比較フレーズを検索する第2の検索手段と、前記第1および第2の検索手段のいずれかが参照フレーズに一致する比較フレーズを検索した場合に、検索された比較フレーズをフレーズ区間に設定する区間設定手段とを具備することを特徴とする。
【0007】
上記請求項1に従属する請求項3に記載の発明では、前記運指生成手段は、フレーズ区間の運指を生成する毎に、その生成した運指を同種のフレーズ区間に割り当てることを特徴とする。
【0008】
請求項4に記載の発明では、曲を構成する各音を表すと共に、各音の演奏パートを表す演奏データを記憶する記憶手段と、前記記憶手段に記憶された演奏データをフレーズ区間に分割し、分割された各フレーズ区間に含まれる音数から区間当りの平均構成音数を算出する動作を各演奏パート毎に並列的に行わせるフレーズ分割手段と、前記フレーズ分割手段により分割されたフレーズ区間が平均構成音数を超える場合は平均構成音数ずつに分割した演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせ、平均構成音数を超えない場合は該当フレーズを構成する全ての演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせる運指生成手段とを具備することを特徴とする。
【0009】
請求項5に記載の発明では、曲を構成する各音を表すと共に、各音毎に対応する演奏パートを表す演奏データをフレーズ区間に分割し、分割された各フレーズ区間に含まれる音数から区間当りの平均構成音数を算出する動作を、各演奏パート毎に並列的に行わせるフレーズ分割処理と、前記フレーズ分割処理により分割されたフレーズ区間が平均構成音数を超える場合は平均構成音数ずつに分割した演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせ、平均構成音数を超えない場合は該当フレーズを構成する全ての演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせる運指生成処理とをコンピュータで実行させることを特徴とする。
【発明の効果】
【0010】
請求項1に記載の発明によれば、曲を構成する各音を表すと共に、各音の演奏パートを表す演奏データをフレーズ区間に分割する動作を各演奏パート毎に並列的に行わせながら、分割されたフレーズ区間の運指を生成する動作を各フレーズ区間毎に並列的に行わせる為、処理負荷を低減させて処理時間の短縮化を図ることができる。
【0011】
請求項4、5に記載の発明によれば、曲を構成する各音を表すと共に、各音の演奏パートを表す演奏データをフレーズ区間に分割し、分割された各フレーズ区間に含まれる音数から区間当りの平均構成音数を算出する動作を各演奏パート毎に並列的に行わせつつ、分割されたフレーズ区間が平均構成音数を超える場合は平均構成音数ずつに分割した演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせ、平均構成音数を超えない場合は該当フレーズを構成する全ての演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせる為、負荷分散により処理負荷を低減させて処理時間の短縮化を図ることができる。
【発明を実施するための最良の形態】
【0012】
以下、図面を参照して本発明の実施形態について説明する。
A.第1実施形態
(1)構成
図1は、本発明の第1実施形態による運指情報生成装置の全体構成を示すブロック図である。運指情報生成装置は、CPU1、ROM2、RAM3、入力部4、表示部5およびMIDIインタフェース6を備える。CPU1は、マルチスレッドに対応したOS上で複数のスレッド(ソフトウェア実行単位)を時分割に実行して見かけ上、リアルタイム並列処理を実現するものであり、具体的には後述するメインルーチン(プライマリスレッド)が各トラック(演奏パート)毎に運指生成スレッドを起動させて各トラック毎の運指生成を並列処理する。
【0013】
ROM2は、CPU1にロードされる各種制御プログラムやテーブル等を記憶する。ここで言う各種制御プログラムとは、メインルーチン(プライマリスレッド)、運指生成スレッドおよび運指系列選択処理を含む。RAM3は、CPU1において用いられる各種レジスタ・フラグデータを一時記憶するワークエリアと、MIDIインタフェース6を介して外部の電子楽器7より取り込んだSMF形式の曲データを、後述する演奏データMidiEventに変換して記憶する演奏データエリアと、この演奏データエリアに格納される演奏データMidiEventをパート別に管理するトラックデータTrackを記憶するトラックデータエリアとを備える。これらRAM3に格納される主要なデータ構成については追って説明する。入力部4は、ユーザ操作に対応した操作イベントを発生してCPU1に供給する。表示部5は、CPU1の制御の下に、例えば演奏データMidiEventを楽譜表示すると共に、表示された楽譜において、演奏データMidiEventを構成する各音毎に対応させた運指データを表示する。
【0014】
(2)データ構成
次に、図2〜図3を参照してRAM3に設けられるトラックデータエリアおよび演奏データエリアの構成について説明する。図2は、RAM3のトラックデータエリアに格納されるトラックデータTrack[0]〜[N]の構成を示す図である。1つのトラックデータTrackは、演奏データエリアに格納される演奏データMidiEventを演奏パート別に管理するデータであり、演奏パートを表すトラック番号iTrack、パート番号iPart、ポインタpNote、ポインタprevおよびポインタnextから構成される。なお、パート番号iPartは、「0」の場合に右手パートを、「1」の場合に左手パートを表す。ポインタpNoteは、トラック番号iTrackの先頭の演奏データMidiEventを指定する。ポインタprevは1つ前の演奏データMidiEventを指定する。ポインタnextは1つ後の演奏データMidiEventを指定する。
【0015】
図3は、RAM3の演奏データエリアに格納される演奏データMidiEventの構成を示す図である。演奏データMidiEvent[0]〜[N]は、曲を構成する各音を表し、その終端にはENDデータを備える。演奏データMidiEventは、発音開始時刻ITime、音長lGate、フレーズ番号iPhrase、フレーズ内番号iPorder、音高Pitch、運指データcfig、運指評価値iCost、和音判別値cIsHarm、和音先頭ポインタphTop、和音終端ポインタphTail、ポインタprevおよびポインタnextから構成される。なお、和音判別値cIsHarmは、「0」の場合に和音でない旨を表し、「構成音−1」の値(「1」以上)の場合に和音の旨を表す。和音先頭ポインタphTopは、和音構成音の内、最も低い音高の音を指定する。和音終端ポインタphTailは、和音構成音の内、最も高い音高の音を指定する。ポインタprevは、1つ前の演奏データMidiEventを指定する。ポインタnextは、次の演奏データMidiEventを指定する。
【0016】
B.動作
次に、図4〜図6を参照して第1実施形態の動作について説明する。以下では、メインルーチン(プライマリスレッド)、運指生成スレッドおよび運指系列選択処理の各動作について述べる。
【0017】
(1)メインルーチンの動作
入力部4からCPU1にメイルーチンの実行を指示するイベントが供給されると、CPU1は図4に図示するメインルーチンを実行してステップSA1に進み、データ読み込み・演奏データ生成を行う。すなわち、ステップSA1では、MIDIインタフェース6を介して外部の電子楽器7からSMF形式の曲データを取り込み、取り込んだ楽曲データから図3に図示したデータ形式の演奏データMidiEvent[0]〜[N]を生成してRAM3の演奏データエリアに格納すると共に、これら演奏データMidiEvent[0]〜[N]をそれぞれ個別に演奏パート別に管理するトラックデータTrack[0]〜[N](図2参照)を生成してRAM3のトラックデータエリアに格納する。
【0018】
続いて、ステップSA2では、トラックデータTrack[0]〜[N]に基づき全てのトラック(演奏パート)を参照し終えたかどうかを判断する。参照し終えていなければ、判断結果は「NO」になり、ステップSA3に進む。ステップSA3では、運指生成の対象となるトラック(演奏パート)の先頭の演奏データを指定するポインタpNoteをレジスタmeFromにストアすると共に、レジスタmeToに曲終端を表す値「0」をストアする。そして、ステップSA4では、レジスタmeFromおよびレジスタmeToの各値を引数として運指生成スレッドを起動させてから上記ステップSA2に処理を戻す。
【0019】
以後、トラックデータTrack[0]〜[N]に基づき全てのトラック(演奏パート)を参照し終えるまで各トラック毎の運指生成スレッドを起動させる。そして、全トラックについて運指生成スレッドを起動させると、上記ステップSA2の判断結果が「YES」になり、ステップSA5に進む。ステップSA5では、全トラックの運指生成スレッド完了まで待機し、全トラックの運指生成スレッド完了に応じて判断結果が「YES」になり、本処理を完了させる。このように、プライマリスレッドであるメインルーチンでは、トラックデータTrack[0]〜[N]に基づき全てのトラック(演奏パート)を参照し終えるまで各トラック毎の運指生成スレッドを起動させ、全トラックの運指生成スレッド完了により本処理を完了させる。
【0020】
(2)運指生成スレッドの動作
次に、図5を参照して運指生成スレッドの動作を説明する。前述したメインルーチン(図4参照)により運指生成スレッドが起動されると、CPU1は図5に図示するステップSB1に進み、メインルーチンからの引数であるレジスタmeFromの内容、すなわち運指生成の対象となるトラック(演奏パート)の先頭の演奏データMidiEvent[pNote]を指定するポインタpNoteをレジスタmeおよびレジスタmetにストアする。続いて、ステップSB2では、先読み回数FIGSTEPSをレジスタiにストアする。
【0021】
ステップSB3〜SB5では、レジスタiにストアされた先読み回数FIGSTEPSが「0」に達するまでデクリメントさせることによって、レジスタmetのポインタ(met.next)を先読み回数FIGSTEPS分だけ先に進める。レジスタmetのポインタ(met.next)を先読み回数FIGSTEPS分だけ先に進めると、ステップSB3の判断結果が「NO」になり、ステップSB6に進む。
【0022】
ステップSB6では、先読み回数FIGSTEPS分だけ先に進めたポインタ(met.next)で指定される演奏データMidiEvent中の和音判別値cIsHarm(met.cIsHarm)が「0」、つまり和音でないかどうかを判断する。和音でなければ、判断結果は「YES」になり、後述のステップSB8に進む。一方、和音であると、上記ステップSB6の判断結果が「NO」になり、ステップSB7に進む。ステップSB7では、先読み回数FIGSTEPS分だけ先に進めたポインタ(met.next)で指定される演奏データMidiEvent中の和音終端ポインタphTail(met.phTail)をレジスタmetにストアする。
【0023】
次いで、ステップSB8では、レジスタmetのポインタとレジスタmeToのポインタとが一致していないか否かを判断する。すなわち、運指生成の対象となる演奏データMidiEventを指定するポインタ(レジスタmet)が終端ポインタ(レジスタmeTo)に達していないかどうかを判断する。運指生成の対象となる演奏データMidiEventを指定するポインタ(レジスタmet)が終端ポインタ(レジスタmeTo)に達していなければ、判断結果は「YES」になり、ステップSB9を介して運指系列選択処理(後述する)を実行する。
【0024】
後述するように、運指系列選択処理では、レジスタmetのポインタで指定される演奏データMidiEventに基づき、考えられる全ての指使い(運指系列)毎に「弾き難さ」を表す評価値を生成し、その内から最も小さい評価値の運指、すなわち一番弾き易い指使いを選択する。そして、こうした運指系列選択処理が完了すると、ステップSB10に進み、レジスタmeに格納されるポインタにより現在指定されている演奏データMidiEvent中のポインタnext(me.next)をレジスタmeにストアしてポインタ更新すると共に、レジスタmetに格納されるポインタにより現在指定されている演奏データMidiEvent中のポインタnext(met.next)をレジスタmetにストアしてポインタ更新する。
【0025】
次いで、ステップSB11では、上記ステップSB10にて更新されたレジスタmetに格納されるポインタ(met.next)で指定される演奏データMidiEvent中の和音判別値cIsHarm(met.cIsHarm)が「0」、つまり和音でないかどうかを判断する。和音であれば、判断結果は「NO」になり、ステップSB12に進み、ポインタ(met.next)で指定される演奏データMidiEvent中の和音終端ポインタphTail(met.phTail)をレジスタmetにストアした後、ステップSB2に処理を戻す。一方、和音でなければ、上記ステップSB11の判断結果が「YES」になり、ステップSB2に処理を戻す。
【0026】
以後、レジスタmetのポインタがレジスタmeToに格納される終端ポインタに達する迄、前述したステップSB2以降の処理を繰り返す。そして、レジスタmetのポインタがレジスタmeToに格納される終端ポインタに達すると、ステップSB8の判断結果が「NO」になり、本処理を終える。このように、運指生成スレッドは、メインルーチンから与えられた引数であるレジスタmeFromの内容に基づき各トラック(演奏パート)の運指生成をそれぞれ並列的に行うようになっている。
【0027】
(3)運指系列選択処理の動作
次に、図6を参照して運指系列選択処理の動作を説明する。上述した運指生成スレッドのステップSB9(図5参照)を介して本処理が実行されると、CPU1は図6に図示するステップSC1に進む。ステップSC1では、全ての運指系列について評価が完了したか否かを判断する。全ての運指系列について評価し終えていないと、判断結果は「NO」になり、次のステップSC2に進む。
【0028】
ステップSC2では、運指系列の評価値を生成してレジスタiCostにストアする。運指系列の評価値とは、演奏データMidiEventに対応して運指割当てされる指の座標と弾くべき鍵の座標との関係から得られる「弾き難さ」を表す値である。また、ここで言う運指割当てとは、親指から小指の各指の内、指位置が弾くべき鍵の座標以下であって、しかも押鍵操作されていない指を、弾くべき指として割り当てる処理を指す。次いで、ステップSC3では、レジスタiCostにストアした運指系列の評価値が、レジスタiCost1に格納される最小評価値より小さいか否かを判断する。レジスタiCostの評価値がレジスタiCost1の最小評価値より大きければ、判断結果は「NO」になり、ステップSC5に進む。
【0029】
一方、レジスタiCostの評価値がレジスタiCost1の最小評価値より小さいと、上記ステップSC3の判断結果が「YES」になり、ステップSC4に進む。ステップSC4では、レジスタiCostの評価値を、対応する演奏データMidiEvent中の運指評価値iCostとして更新登録すると共に、運指割り当てされた指を表す運指データを、対応する演奏データMidiEvent中の運指データcfigとして登録する。この後、ステップSC5に進み、レジスタiCostの評価値をレジスタiCost1にストアして最小評価値を更新させてから次の運指系列に移行する。
【0030】
以後、全ての運指系列について評価し終えまで上述したステップSC1〜SC5を繰り返す。そして、全ての運指系列について評価し終えると、上記ステップSC1の判断結果が「YES」になり、本処理を完了させる。このように、運指系列選択処理では、運指生成スレッドにて指定された演奏データMidiEventに基づき、考えられる全ての指使い(運指系列)毎に「弾き難さ」を表す評価値を生成し、その内から最も小さい評価値の運指、すなわち一番弾き易い指使いを選択し、その指使いを表す運指データcfigおよび運指評価値iCostを、対応する演奏データMidiEventに登録する。
【0031】
以上説明したように、第1実施形態では、各トラック(演奏パート)毎に起動した運指生成スレッドにおいて、それぞれ対応するトラックの演奏データMidiEventに基づき考えられる全ての指使い(運指系列)毎に「弾き難さ」を表す評価値を生成し、その内から最も小さい評価値の運指、すなわち一番弾き易い指使いを選択し、その指使いを表す運指データcfigおよび運指評価値iCostを対応する演奏データMidiEventに登録する処理を並列的に行う結果、処理負荷を低減させて処理時間の短縮化を図ることが可能になる。
【0032】
C.第2実施形態
次に、図7〜図9を参照して第1実施形態と相違する第2実施形態によるメインルーチン(プライマリスレッド)、トラック処理スレッドおよびフレーズ分割処理の各動作について説明する。なお、第2実施形態の構成は、第1実施形態と共通するので、その説明については省略する。
【0033】
(1)メインルーチンの動作
入力部4からCPU1にメイルーチンの実行を指示するイベントが供給されると、CPU1は図4に図示するメインルーチンを実行してステップSD1に進み、データ読み込み・演奏データ生成を行う。すなわち、ステップSD1では、MIDIインタフェース6を介して外部の電子楽器7からSMF形式の曲データを取り込み、取り込んだ楽曲データから図3に図示したデータ形式の演奏データMidiEvent[0]〜[N]を生成してRAM3の演奏データエリアに格納すると共に、これら演奏データMidiEvent[0]〜[N]をそれぞれ個別に演奏パート別に管理するトラックデータTrack[0]〜[N](図2参照)を生成してRAM3のトラックデータエリアに格納する。
【0034】
続いて、ステップSD2では、トラックデータTrack[0]〜[N]に基づき全てのトラック(演奏パート)を参照し終えたかどうかを判断する。参照し終えていなければ、判断結果は「NO」になり、ステップSD3に進む。ステップSD3では、運指生成の対象となるトラック(演奏パート)について、後述するトラック処理スレッドを起動させてから上記ステップSD2に処理を戻す。以後、トラックデータTrack[0]〜[N]に基づき全てのトラック(演奏パート)を参照し終えるまで各トラック毎のトラック処理スレッドを起動させる。そして、全トラックについてトラック処理スレッドを起動させると、上記ステップSD2の判断結果が「YES」になり、ステップSD4に進む。
【0035】
ステップSD4では、全てのトラック処理スレッドが完了するまで待機し、全トラック処理スレッド完了に応じて判断結果が「YES」になり、本処理を完了させる。このように、プライマリスレッドであるメインルーチンでは、トラックデータTrack[0]〜[N]に基づき全てのトラック(演奏パート)を参照し終えるまで各トラック毎のトラック処理スレッドを起動させ、これらが全て完了した時点で処理終了するようになっている。
【0036】
(2)トラック処理スレッドの動作
次に、図8を参照してトラック処理スレッドの動作を説明する。前述のメインルーチン(図7参照)によりトラック処理スレッドが起動されると、CPU1は図8に図示するステップSE1に進み、処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割するフレーズ分割処理(後述する)を実行する。次いで、ステップSE2では、運指生成の対象となるトラック(演奏パート)の先頭の演奏データMidiEvent[pNote]を指定するポインタpNoteをレジスタmeにストアする。
【0037】
ステップSE3では、レジスタmeの値が「0」でないか否か、すなわち曲終端に達していないかどうかを判断する。曲終端に達していなければ、判断結果は「YES」になり、ステップSE4に進む。ステップSE4では、レジスタmeのポインタで指定される演奏データMidiEvent中のフレーズ番号iPhrase(me.iPhrase)をレジスタphIDにストアする。以後、レジスタphIDの内容をフレーズ番号phIDと称す。続いて、ステップSE5では、レジスタmeのポインタで指定される演奏データMidiEvent中のポインタnextをレジスタmetにストアする。
【0038】
そして、ステップSE6〜SE7では、レジスタmetのポインタを歩進させながら、その歩進されるポインタで指定される演奏データMidiEvent中のフレーズ番号iPhrase(met.iPhrase)が、現在のフレーズ番号phIDに一致するか否かを判断する。換言すれば、フレーズの終わりとなる演奏データMidiEventを探し出す。
【0039】
フレーズ番号iPhrase(met.iPhrase)が現在のフレーズ番号phIDに一致している間は、ステップSE6の判断結果が「YES」になり、ステップSE6〜SE7を繰り返す。そして、フレーズ番号iPhrase(met.iPhrase)が現在のフレーズ番号phIDに一致せず、フレーズの終わりとなる演奏データMidiEventが検出されると、ステップSE6の判断結果が「NO」になり、ステップSE8に進む。
【0040】
ステップSE8では、レジスタmeのポインタ(フレーズの先頭を指定するポインタ)をレジスタmeFromにストアすると共に、レジスタmetのポインタ(フレーズの終わりとなる演奏データMidiEventを指定するポインタ)をレジスタmeToにストアする。そして、ステップSE9では、このレジスタme、meToの各ポインタを引数としてスレッド起動を指示する。次いで、ステップSE10では、レジスタmetのポインタで指定される演奏データMidiEvent中のポインタnextをレジスタmeにストアした後、上述したステップSE3に処理を戻す。
【0041】
上記ステップSE9においてスレッド起動が指示されると、ステップSE11を介して運指生成スレッド(図5参照)を実行させ、レジスタme、meToの各ポインタで指定されるフレーズを構成する演奏データMidiEventに基づき運指生成を行う。そして、ステップSE12では、上記ステップSE11の運指生成スレッドにて得られたフレーズの運指データを、同じフレーズ番号phIDを有するフレーズを構成する演奏データMidiEvent中の運指データcfigとしてコピーする。
【0042】
一方、上述したステップSE3〜SE10の、フレーズ番号phIDのフレーズ先頭および後端を探し出す過程で、レジスタmeの値が「0」となり、曲終端に達すると、上記ステップSE3の判断結果が「NO」になり、ステップSE13に進み、フレーズ単位で起動された全ての運指生成スレッド(ステップSE11)が終了するまで待機し、全スレッド終了に応じて判断結果が「YES」になり、本処理を終える。
【0043】
以上のように、トラック処理スレッドでは、処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割し、分割されたフレーズ毎に運指生成スレッドを起動させてフレーズを構成する演奏データMidiEventに基づき運指生成を行い、これにて得られたフレーズの運指データを、同じフレーズ番号phIDを有するフレーズを構成する演奏データMidiEvent中の運指データcfigとしてコピーするようになっている。
【0044】
(3)フレーズ分割処理の動作
次に、図9を参照してフレーズ分割処理の動作を説明する。トラック処理スレッドのステップSE1(図8参照)を介して本処理が実行されると、CPU1は図9に図示するステップSF1に進み、フレーズ番号を一時記憶するレジスタphIDをゼロリセットする。続いて、ステップSF2では、処理対象とするトラック(演奏パート)の先頭の演奏データMidiEvent[pNote]を指定するポインタpNoteをレジスタmeRefにストアする。
【0045】
次いで、ステップSF3では、先頭の演奏データMidiEvent[pNote]から規定個数先の演奏データMidiEventを指定するポインタをレジスタmetRefにストアする。そして、ステップSF4に進み、レジスタmetRefの値が「0」でないか否か、すなわち曲終端に達していないかどうかを判断する。曲終端に達していなければ、判断結果は「YES」になり、ステップSF5に進み、一致フラグHITを「0」にセットする。次に、ステップSF6では、レジスタmetRefのポインタで指定される演奏データMidiEvent以降であって、フレーズ検出されていない演奏データMidiEventを指定するポインタをレジスタmeSrcにストアする。
【0046】
ステップSF7では、レジスタmeSrcのポインタで指定される演奏データMidiEventから規定個数先の演奏データMidiEventを指定するポインタをレジスタmetRefにストアする。そして、ステップSF8では、レジスタmetSrcの値が「0」でないか否か、すなわち曲終端に達していないかどうかを判断する。曲終端に達していなければ、判断結果は「YES」になり、ステップSF11に進む。
【0047】
ステップSF11〜SF12では、レジスタmeRefのポインタで指定される演奏データMidiEventからレジスタmetRefのポインタで指定される演奏データMidiEventまでの各音からなる参照フレーズと、レジスタmeSrcのポインタで指定される演奏データMidiEventからレジスタmetSrcのポインタで指定される演奏データMidiEventまでの各音からなる比較フレーズとが一致しているかどうかを判断する。なお、一致・不一致の判断は、参照フレーズおよび比較フレーズをそれぞれ構成する各音の「音高」、「発音タイミング」および「音長」が一致するか否かで判定する。
【0048】
参照フレーズと比較フレーズが一致しなければ、上記ステップSF12の判断結果は「NO」になり、ステップSF13〜SF14において比較フレーズを更新する。すなわち、ステップSF13では、レジスタmetSrcのポインタで指定される演奏データMidiEvent以降であって、フレーズ検出されていない演奏データMidiEventを指定するポインタをレジスタmeSrcにストアする。続いて、ステップSF14では、レジスタmeSrcのポインタで指定される演奏データMidiEventから規定個数先の演奏データMidiEventを指定するポインタをレジスタmetRefにストアする。この後、上述したステップSF8に処理を戻す。
【0049】
こうして、ステップSF8〜SF14では、参照フレーズに一致する比較フレーズが出現するまでレジスタmeSrcおよびレジスタmetSrcの各ポインタを更新させる。そして、曲終端に達する以前に、参照フレーズに一致する比較フレーズが見つかると、ステップSF12の判断結果が「YES」になり、ステップSF15に進む。ステップSF15では、一致フラグHITが「1」でないか否か、つまり既に参照フレーズに一致する比較フレーズが見つかっているかどうかを判断する。初めて参照フレーズに一致する比較フレーズが見つかった場合には、判断結果が「YES」になり、ステップSF16に進み、フレーズ番号phIDをインクリメントして歩進させた後、ステップSF17にて一致フラグHITを「1」にセットする。
【0050】
一方、既に参照フレーズに一致する比較フレーズが見つかっている場合であれば、上記ステップSF15の判断結果は「NO」となり、ステップSF17に進み、一致フラグHITを「1」にセットする。次いで、ステップSF18では、レジスタmeSrcのポインタで指定される演奏データMidiEvent中のフレーズ番号iPhrase(meSrc.iPhrase)にフレーズ番号phIDを登録した後、上述のステップSF13に処理を進める。したがって、参照フレーズに一致する比較フレーズが続くような場合には、それらが同一のグループとして同一のフレーズ番号phIDが、対応する演奏データMidiEvent中のフレーズ番号iPhrase(meSrc.iPhrase)に登録される。
【0051】
さて、参照フレーズに一致する比較フレーズが出現するまでレジスタmeSrcおよびレジスタmetSrcの各ポインタを更新させる過程で、レジスタmetSrcのポインタが曲終端に達すると、上述したステップSF8の判断結果が「NO」になり、ステップSF9に進む。ステップSF9〜SF10では、新たな参照フレーズの位置を設定する。すなわち、ステップSF9では、フレーズ検出されていない最初の演奏データMidiEventを指定するポインタを、新たな参照フレーズの先頭としてレジスタmeRefにストアし、続くステップSF10では、この新たな参照フレーズの先頭から規定個数先の演奏データMidiEventを指定するポインタをレジスタmetRefにストアする。
【0052】
この後、前述したステップSF4に進み、レジスタmetRefの値が「0」でないか否か、すなわち曲終端に達していないかどうかを判断する。そして、曲終端に達していなければ、判断結果は「YES」になり、前述したステップSF5以降を実行して、新たに設定した参照フレーズに一致する比較フレーズを探し出す。そして、新たな参照フレーズを設定する際に、参照フレーズの後端が曲終端に達した場合に、ステップSF4の判断結果が「NO」となり、本処理を終える。
【0053】
このように、フレーズ分割処理では、処理対象とするトラック(演奏パート)の演奏データMidiEventを所定音数分に区切った参照フレーズを設定し、この参照フレーズに一致する比較フレーズを探し出す。そして、一致する比較フレーズが無ければ、参照フレーズの位置をずらしながら一致する比較フレーズを探し出し、一致した比較フレーズがあれば、その比較フレーズの先頭の演奏データMidiEvent中のフレーズ番号iPhrase(meSrc.iPhrase)にフレーズ番号phIDを登録する。これにより、処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割できる。
【0054】
以上説明したように、第2実施形態では、処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割し、分割されたフレーズ毎に運指生成スレッドを起動させてフレーズを構成する演奏データMidiEventに基づき運指生成を行い、これにて得られたフレーズの運指データを、同じフレーズ番号phIDを有するフレーズを構成する演奏データMidiEvent中の運指データcfigとしてコピーする。こうした処理を各トラックについて並列的に実行する結果、処理負荷を低減させて処理時間の短縮化を図ることが可能になる。
【0055】
C.第3実施形態
次に、図10を参照して第3実施形態によるトラック処理スレッドの動作を説明する。前述した第2実施形態と同様に、メインルーチン(図7参照)によりトラック処理スレッドが起動されると、CPU1は図10に図示するステップSG1に進み、処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割するフレーズ分割処理を実行する。次いで、ステップSG2では、カウンタiP、iNをゼロリセットする。続いて、ステップSG3では、運指生成の対象となるトラック(演奏パート)の先頭の演奏データMidiEvent[pNote]を指定するポインタpNoteをレジスタmeにストアする。
【0056】
ステップSG4では、レジスタmeの値が「0」でないか否か、すなわち曲終端に達していないかどうかを判断する。曲終端に達していなければ、判断結果は「YES」になり、ステップSG5に進む。ステップSG5では、レジスタmeのポインタで指定される演奏データMidiEvent中のフレーズ番号iPhrase(me.iPhrase)をレジスタphIDにストアする。以後、レジスタphIDの内容をフレーズ番号phIDと称す。続いて、ステップSG6では、レジスタmeのポインタで指定される演奏データMidiEvent中のポインタnextをレジスタmetにストアする。
【0057】
そして、ステップSG7〜SG9は、レジスタmetのポインタを歩進させながら、その歩進されるデータ数をカウンタiNにて計数する一方、歩進されるポインタで指定される演奏データMidiEvent中のフレーズ番号iPhrase(met.iPhrase)が、現在のフレーズ番号phIDに一致するか否かを判断する。換言すれば、フレーズを構成する演奏データ数(フレーズ構成音数)をカウンタiNにて計数しつつ、フレーズの終わりの演奏データMidiEventを探し出す。
【0058】
フレーズ番号iPhrase(met.iPhrase)が現在のフレーズ番号phIDに一致している間は、ステップSE6の判断結果が「YES」になり、ステップSG7〜SG9を繰り返す。そして、フレーズ番号iPhrase(met.iPhrase)が現在のフレーズ番号phIDに一致せず、フレーズの終わりとなる演奏データMidiEventが検出されると、ステップSG7の判断結果が「NO」になり、ステップSG10に進む。
【0059】
ステップSG10では、フレーズ数を計数するカウンタiPの値で指定されるレジスタmeF[iP]に、レジスタmeのポインタ(フレーズの先頭を指定するポインタ)をストアすると共に、カウンタiPの値で指定されるレジスタmeT[iP]に、レジスタmetのポインタ(フレーズの終わりとなる演奏データMidiEventを指定するポインタ)をストアする。さらに、ステップSG10では、カウンタiPの値で指定されるレジスタiN[iP]に、カウンタiNにて計数したフレーズ構成音数をストアする。次いで、ステップSG11では、カウンタiPの値をインクリメントして歩進させると共に、カウンタiNをゼロリセットする。そして、ステップSG12に進み、レジスタmetのポインタで指定される演奏データMidiEvent中のポインタnextをレジスタmeにストアした後、上述したステップSG4に処理を戻す。
【0060】
以後、レジスタmeのポインタが曲終端に達するまで上述したステップSG4〜SG12を繰り返す。これにより、前述のステップSG1において分割された各フレーズの先頭を指定するポインタがレジスタmeF[0]〜[iP]に、各フレーズの後端を指定するポインタがレジスタmeT[0]〜[iP]に、各フレーズ毎のフレーズ構成音数がレジスタiN[0]〜[iP]にそれぞれストアされる。そして、レジスタmeのポインタが曲終端に達すると、上述したステップSG4の判断結果が「NO」になり、ステップSG13に進む。
【0061】
ステップSG13では、レジスタiN[0]〜[iP]にそれぞれストアされた各フレーズ毎のフレーズ構成音数に基づきフレーズ当りの平均構成音数を算出し、算出した平均構成音数をレジスタiNAveにストアする。次いで、ステップSG14では、ポインタiをゼロリセットし、続くステップSG15では、ポインタiがカウンタiPの値(以下、フレーズ数iPと称す)より小さいか否かを判断する。ポインタiがフレーズ数iPより小さければ、判断結果は「YES」になり、ステップSG16に進む。
【0062】
ステップSG16では、ポインタiで指定されるレジスタiN[i]、つまりポインタiで指定されるフレーズのフレーズ構成音数が、レジスタiNAveにストアされる平均構成音数より大きいか否かを判断する。ポインタiで指定されるフレーズのフレーズ構成音数iN[i]が平均構成音数iNAveより大きい場合には、判断結果が「YES」になり、ステップSG17に進む。ステップSG17では、平均構成音数iNAveずつに分割した演奏データMidiEventについて運指生成するスレッドを起動させる。そして、ステップSG18に進み、ポインタiをインクリメントして歩進させた後、上述のステップSG15に処理を戻す。
【0063】
一方、ポインタiで指定されるフレーズのフレーズ構成音数iN[i]が平均構成音数iNAveより小さい場合には、上記ステップSG16の判断結果が「NO」となり、ステップSG19に進み、ポインタiで指定されるフレーズを構成する全ての演奏データMidiEventについて運指生成するスレッドを起動させた後、ステップSG18にてポインタiを歩進させてから上述のステップSG15に処理を戻す。
【0064】
こうして、フレーズ構成音数iN[i]が平均構成音数iNAveを超えるか否かに応じて、平均構成音数iNAveずつに分割した演奏データMidiEventについて運指生成するスレッドあるいはフレーズを構成する全ての演奏データMidiEventについて運指生成するスレッドのいずれかを起動させ終え、ポインタiがフレーズ数iPより大きくなると、上記ステップSG15の判断結果が「NO」になり、ステップSG20に進む。そして、ステップSG20では、起動された全ての運指生成スレッドが終了するまで待機し、全スレッド終了に応じて判断結果が「YES」になり、本処理を終える。
【0065】
以上のように、第3実施形態では、処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割し、分割された全てのフレーズを参照してフレーズ当りの平均構成音数iNAveを算出する。そして、分割された各フレーズ毎に平均構成音数iNAveを超えているか否かを判断し、平均構成音数iNAveを超えるフレーズであれば、平均構成音数iNAveずつに分割した演奏データMidiEventについて運指生成するスレッドを起動し、一方、平均構成音数iNAveを超えないフレーズならば、フレーズを構成する全ての演奏データMidiEventについて運指生成するスレッドを起動させるようにしたので、負荷分散により処理負荷を低減させて処理時間の短縮化を図ることが可能になる。
【0066】
なお、本実施形態では、分割された全てのフレーズを参照してフレーズ当りの平均構成音数iNAveを算出し、算出した平均構成音数iNAveを超える場合に、平均構成音数iNAveずつに分割した演奏データMidiEventについて運指生成するスレッドを起動し、平均構成音数iNAveを超えない場合にフレーズを構成する全ての演奏データMidiEventについて運指生成するスレッドを起動させるようにしたが、これに限らず、所定音数(演奏データ数)を超えるフレーズの場合に所定音数ずつに分割した演奏データMidiEventについて運指生成するスレッドを起動し、所定音数を超えないフレーズについはフレーズを構成する全ての演奏データMidiEventについて運指生成するスレッドを起動させる態様としても構わない。このようにすれば、平均構成音数iNAveを算出する処理が不要となり、より処理負荷低減を図ることができる。
【図面の簡単な説明】
【0067】
【図1】本発明による第1実施形態の構成を示すブロック図である。
【図2】トラックデータTrackの構成を示す図である。
【図3】演奏データMidiEventの構成を示す図である。
【図4】第1実施形態によるメインルーチンの動作を示すフローチャートである。
【図5】第1実施形態による運指生成スレッドの動作を示すフローチャートである。
【図6】第1実施形態による運指系列選択処理の動作を示すフローチャートである。
【図7】第2実施形態によるメインルーチンの動作を示すフローチャートである。
【図8】第2実施形態によるトラック処理スレッドの動作を示すフローチャートである。
【図9】第2実施形態によるフレーズ分割処理の動作を示すフローチャートである。
【図10】第3実施形態によるトラック処理スレッドの動作を示すフローチャートである。
【符号の説明】
【0068】
1 CPU
2 ROM
3 RAM
4 入力部
5 表示部
6 MIDIインタフェース
7 電子楽器
【技術分野】
【0001】
本発明は、鍵盤を備えた電子楽器に用いて好適な運指情報生成装置および運指情報生成処理プログラムに関する。
【背景技術】
【0002】
鍵操作する際の指使い(運指)を演奏者に案内する運指情報を発生する装置が知られている。例えば特許文献1には、隣り合う2つの音に対して鍵盤を操作したときの指使いの容易さを表す2音運指データをそれぞれの指の組合わせに対応付けて記憶しておき、その内から演奏データ(与えられたメロディの音列)に対応する2音運指データを読み出し、読み出した2音運指データの累算値を最適にする運指を決定して運指情報を発生させる装置が開示されている。
【0003】
【特許文献1】特許第2526954号明細書
【発明の開示】
【発明が解決しようとする課題】
【0004】
ところで、上記特許文献1に開示された運指生成手法の他に、所定数の演奏データについて考えられる全ての指使い(運指)を評価し、その中から最適な運指を決定する手法も知られているが、そうした手法では考えられる全ての指使いについて個々に評価することから処理負荷が大きく膨大な処理時間を要するという問題がある。
そこで本発明は、このような事情に鑑みてなされたもので、処理負荷を低減させて処理時間の短縮化を図ることができる運指情報生成装置および運指情報生成処理プログラムを提供することを目的としている。
【課題を解決するための手段】
【0005】
上記目的を達成するため、請求項1に記載の発明では、曲を構成する各音を表すと共に、各音の演奏パートを表す演奏データを記憶する記憶手段と、前記記憶手段に記憶された演奏データをフレーズ区間に分割する動作を各演奏パート毎に並列的に行わせるフレーズ分割手段と、前記フレーズ分割手段により分割されたフレーズ区間の運指を生成する動作を各フレーズ区間毎に並列的に行わせる運指生成手段とを具備することを特徴とする。
【0006】
上記請求項1に従属する請求項2に記載の発明では、前記フレーズ分割手段は、処理対象とする演奏パートの演奏データの先頭から所定音数分に区切った参照フレーズを設定する設定手段と、前記設定手段により設定された参照フレーズ以降から当該参照フレーズに一致する比較フレーズを検索する第1の検索手段と、前記第1の検索手段が参照フレーズに一致する比較フレーズを検索できない場合に、参照フレーズの位置をずらしながら当該参照フレーズに一致する比較フレーズを検索する第2の検索手段と、前記第1および第2の検索手段のいずれかが参照フレーズに一致する比較フレーズを検索した場合に、検索された比較フレーズをフレーズ区間に設定する区間設定手段とを具備することを特徴とする。
【0007】
上記請求項1に従属する請求項3に記載の発明では、前記運指生成手段は、フレーズ区間の運指を生成する毎に、その生成した運指を同種のフレーズ区間に割り当てることを特徴とする。
【0008】
請求項4に記載の発明では、曲を構成する各音を表すと共に、各音の演奏パートを表す演奏データを記憶する記憶手段と、前記記憶手段に記憶された演奏データをフレーズ区間に分割し、分割された各フレーズ区間に含まれる音数から区間当りの平均構成音数を算出する動作を各演奏パート毎に並列的に行わせるフレーズ分割手段と、前記フレーズ分割手段により分割されたフレーズ区間が平均構成音数を超える場合は平均構成音数ずつに分割した演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせ、平均構成音数を超えない場合は該当フレーズを構成する全ての演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせる運指生成手段とを具備することを特徴とする。
【0009】
請求項5に記載の発明では、曲を構成する各音を表すと共に、各音毎に対応する演奏パートを表す演奏データをフレーズ区間に分割し、分割された各フレーズ区間に含まれる音数から区間当りの平均構成音数を算出する動作を、各演奏パート毎に並列的に行わせるフレーズ分割処理と、前記フレーズ分割処理により分割されたフレーズ区間が平均構成音数を超える場合は平均構成音数ずつに分割した演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせ、平均構成音数を超えない場合は該当フレーズを構成する全ての演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせる運指生成処理とをコンピュータで実行させることを特徴とする。
【発明の効果】
【0010】
請求項1に記載の発明によれば、曲を構成する各音を表すと共に、各音の演奏パートを表す演奏データをフレーズ区間に分割する動作を各演奏パート毎に並列的に行わせながら、分割されたフレーズ区間の運指を生成する動作を各フレーズ区間毎に並列的に行わせる為、処理負荷を低減させて処理時間の短縮化を図ることができる。
【0011】
請求項4、5に記載の発明によれば、曲を構成する各音を表すと共に、各音の演奏パートを表す演奏データをフレーズ区間に分割し、分割された各フレーズ区間に含まれる音数から区間当りの平均構成音数を算出する動作を各演奏パート毎に並列的に行わせつつ、分割されたフレーズ区間が平均構成音数を超える場合は平均構成音数ずつに分割した演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせ、平均構成音数を超えない場合は該当フレーズを構成する全ての演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせる為、負荷分散により処理負荷を低減させて処理時間の短縮化を図ることができる。
【発明を実施するための最良の形態】
【0012】
以下、図面を参照して本発明の実施形態について説明する。
A.第1実施形態
(1)構成
図1は、本発明の第1実施形態による運指情報生成装置の全体構成を示すブロック図である。運指情報生成装置は、CPU1、ROM2、RAM3、入力部4、表示部5およびMIDIインタフェース6を備える。CPU1は、マルチスレッドに対応したOS上で複数のスレッド(ソフトウェア実行単位)を時分割に実行して見かけ上、リアルタイム並列処理を実現するものであり、具体的には後述するメインルーチン(プライマリスレッド)が各トラック(演奏パート)毎に運指生成スレッドを起動させて各トラック毎の運指生成を並列処理する。
【0013】
ROM2は、CPU1にロードされる各種制御プログラムやテーブル等を記憶する。ここで言う各種制御プログラムとは、メインルーチン(プライマリスレッド)、運指生成スレッドおよび運指系列選択処理を含む。RAM3は、CPU1において用いられる各種レジスタ・フラグデータを一時記憶するワークエリアと、MIDIインタフェース6を介して外部の電子楽器7より取り込んだSMF形式の曲データを、後述する演奏データMidiEventに変換して記憶する演奏データエリアと、この演奏データエリアに格納される演奏データMidiEventをパート別に管理するトラックデータTrackを記憶するトラックデータエリアとを備える。これらRAM3に格納される主要なデータ構成については追って説明する。入力部4は、ユーザ操作に対応した操作イベントを発生してCPU1に供給する。表示部5は、CPU1の制御の下に、例えば演奏データMidiEventを楽譜表示すると共に、表示された楽譜において、演奏データMidiEventを構成する各音毎に対応させた運指データを表示する。
【0014】
(2)データ構成
次に、図2〜図3を参照してRAM3に設けられるトラックデータエリアおよび演奏データエリアの構成について説明する。図2は、RAM3のトラックデータエリアに格納されるトラックデータTrack[0]〜[N]の構成を示す図である。1つのトラックデータTrackは、演奏データエリアに格納される演奏データMidiEventを演奏パート別に管理するデータであり、演奏パートを表すトラック番号iTrack、パート番号iPart、ポインタpNote、ポインタprevおよびポインタnextから構成される。なお、パート番号iPartは、「0」の場合に右手パートを、「1」の場合に左手パートを表す。ポインタpNoteは、トラック番号iTrackの先頭の演奏データMidiEventを指定する。ポインタprevは1つ前の演奏データMidiEventを指定する。ポインタnextは1つ後の演奏データMidiEventを指定する。
【0015】
図3は、RAM3の演奏データエリアに格納される演奏データMidiEventの構成を示す図である。演奏データMidiEvent[0]〜[N]は、曲を構成する各音を表し、その終端にはENDデータを備える。演奏データMidiEventは、発音開始時刻ITime、音長lGate、フレーズ番号iPhrase、フレーズ内番号iPorder、音高Pitch、運指データcfig、運指評価値iCost、和音判別値cIsHarm、和音先頭ポインタphTop、和音終端ポインタphTail、ポインタprevおよびポインタnextから構成される。なお、和音判別値cIsHarmは、「0」の場合に和音でない旨を表し、「構成音−1」の値(「1」以上)の場合に和音の旨を表す。和音先頭ポインタphTopは、和音構成音の内、最も低い音高の音を指定する。和音終端ポインタphTailは、和音構成音の内、最も高い音高の音を指定する。ポインタprevは、1つ前の演奏データMidiEventを指定する。ポインタnextは、次の演奏データMidiEventを指定する。
【0016】
B.動作
次に、図4〜図6を参照して第1実施形態の動作について説明する。以下では、メインルーチン(プライマリスレッド)、運指生成スレッドおよび運指系列選択処理の各動作について述べる。
【0017】
(1)メインルーチンの動作
入力部4からCPU1にメイルーチンの実行を指示するイベントが供給されると、CPU1は図4に図示するメインルーチンを実行してステップSA1に進み、データ読み込み・演奏データ生成を行う。すなわち、ステップSA1では、MIDIインタフェース6を介して外部の電子楽器7からSMF形式の曲データを取り込み、取り込んだ楽曲データから図3に図示したデータ形式の演奏データMidiEvent[0]〜[N]を生成してRAM3の演奏データエリアに格納すると共に、これら演奏データMidiEvent[0]〜[N]をそれぞれ個別に演奏パート別に管理するトラックデータTrack[0]〜[N](図2参照)を生成してRAM3のトラックデータエリアに格納する。
【0018】
続いて、ステップSA2では、トラックデータTrack[0]〜[N]に基づき全てのトラック(演奏パート)を参照し終えたかどうかを判断する。参照し終えていなければ、判断結果は「NO」になり、ステップSA3に進む。ステップSA3では、運指生成の対象となるトラック(演奏パート)の先頭の演奏データを指定するポインタpNoteをレジスタmeFromにストアすると共に、レジスタmeToに曲終端を表す値「0」をストアする。そして、ステップSA4では、レジスタmeFromおよびレジスタmeToの各値を引数として運指生成スレッドを起動させてから上記ステップSA2に処理を戻す。
【0019】
以後、トラックデータTrack[0]〜[N]に基づき全てのトラック(演奏パート)を参照し終えるまで各トラック毎の運指生成スレッドを起動させる。そして、全トラックについて運指生成スレッドを起動させると、上記ステップSA2の判断結果が「YES」になり、ステップSA5に進む。ステップSA5では、全トラックの運指生成スレッド完了まで待機し、全トラックの運指生成スレッド完了に応じて判断結果が「YES」になり、本処理を完了させる。このように、プライマリスレッドであるメインルーチンでは、トラックデータTrack[0]〜[N]に基づき全てのトラック(演奏パート)を参照し終えるまで各トラック毎の運指生成スレッドを起動させ、全トラックの運指生成スレッド完了により本処理を完了させる。
【0020】
(2)運指生成スレッドの動作
次に、図5を参照して運指生成スレッドの動作を説明する。前述したメインルーチン(図4参照)により運指生成スレッドが起動されると、CPU1は図5に図示するステップSB1に進み、メインルーチンからの引数であるレジスタmeFromの内容、すなわち運指生成の対象となるトラック(演奏パート)の先頭の演奏データMidiEvent[pNote]を指定するポインタpNoteをレジスタmeおよびレジスタmetにストアする。続いて、ステップSB2では、先読み回数FIGSTEPSをレジスタiにストアする。
【0021】
ステップSB3〜SB5では、レジスタiにストアされた先読み回数FIGSTEPSが「0」に達するまでデクリメントさせることによって、レジスタmetのポインタ(met.next)を先読み回数FIGSTEPS分だけ先に進める。レジスタmetのポインタ(met.next)を先読み回数FIGSTEPS分だけ先に進めると、ステップSB3の判断結果が「NO」になり、ステップSB6に進む。
【0022】
ステップSB6では、先読み回数FIGSTEPS分だけ先に進めたポインタ(met.next)で指定される演奏データMidiEvent中の和音判別値cIsHarm(met.cIsHarm)が「0」、つまり和音でないかどうかを判断する。和音でなければ、判断結果は「YES」になり、後述のステップSB8に進む。一方、和音であると、上記ステップSB6の判断結果が「NO」になり、ステップSB7に進む。ステップSB7では、先読み回数FIGSTEPS分だけ先に進めたポインタ(met.next)で指定される演奏データMidiEvent中の和音終端ポインタphTail(met.phTail)をレジスタmetにストアする。
【0023】
次いで、ステップSB8では、レジスタmetのポインタとレジスタmeToのポインタとが一致していないか否かを判断する。すなわち、運指生成の対象となる演奏データMidiEventを指定するポインタ(レジスタmet)が終端ポインタ(レジスタmeTo)に達していないかどうかを判断する。運指生成の対象となる演奏データMidiEventを指定するポインタ(レジスタmet)が終端ポインタ(レジスタmeTo)に達していなければ、判断結果は「YES」になり、ステップSB9を介して運指系列選択処理(後述する)を実行する。
【0024】
後述するように、運指系列選択処理では、レジスタmetのポインタで指定される演奏データMidiEventに基づき、考えられる全ての指使い(運指系列)毎に「弾き難さ」を表す評価値を生成し、その内から最も小さい評価値の運指、すなわち一番弾き易い指使いを選択する。そして、こうした運指系列選択処理が完了すると、ステップSB10に進み、レジスタmeに格納されるポインタにより現在指定されている演奏データMidiEvent中のポインタnext(me.next)をレジスタmeにストアしてポインタ更新すると共に、レジスタmetに格納されるポインタにより現在指定されている演奏データMidiEvent中のポインタnext(met.next)をレジスタmetにストアしてポインタ更新する。
【0025】
次いで、ステップSB11では、上記ステップSB10にて更新されたレジスタmetに格納されるポインタ(met.next)で指定される演奏データMidiEvent中の和音判別値cIsHarm(met.cIsHarm)が「0」、つまり和音でないかどうかを判断する。和音であれば、判断結果は「NO」になり、ステップSB12に進み、ポインタ(met.next)で指定される演奏データMidiEvent中の和音終端ポインタphTail(met.phTail)をレジスタmetにストアした後、ステップSB2に処理を戻す。一方、和音でなければ、上記ステップSB11の判断結果が「YES」になり、ステップSB2に処理を戻す。
【0026】
以後、レジスタmetのポインタがレジスタmeToに格納される終端ポインタに達する迄、前述したステップSB2以降の処理を繰り返す。そして、レジスタmetのポインタがレジスタmeToに格納される終端ポインタに達すると、ステップSB8の判断結果が「NO」になり、本処理を終える。このように、運指生成スレッドは、メインルーチンから与えられた引数であるレジスタmeFromの内容に基づき各トラック(演奏パート)の運指生成をそれぞれ並列的に行うようになっている。
【0027】
(3)運指系列選択処理の動作
次に、図6を参照して運指系列選択処理の動作を説明する。上述した運指生成スレッドのステップSB9(図5参照)を介して本処理が実行されると、CPU1は図6に図示するステップSC1に進む。ステップSC1では、全ての運指系列について評価が完了したか否かを判断する。全ての運指系列について評価し終えていないと、判断結果は「NO」になり、次のステップSC2に進む。
【0028】
ステップSC2では、運指系列の評価値を生成してレジスタiCostにストアする。運指系列の評価値とは、演奏データMidiEventに対応して運指割当てされる指の座標と弾くべき鍵の座標との関係から得られる「弾き難さ」を表す値である。また、ここで言う運指割当てとは、親指から小指の各指の内、指位置が弾くべき鍵の座標以下であって、しかも押鍵操作されていない指を、弾くべき指として割り当てる処理を指す。次いで、ステップSC3では、レジスタiCostにストアした運指系列の評価値が、レジスタiCost1に格納される最小評価値より小さいか否かを判断する。レジスタiCostの評価値がレジスタiCost1の最小評価値より大きければ、判断結果は「NO」になり、ステップSC5に進む。
【0029】
一方、レジスタiCostの評価値がレジスタiCost1の最小評価値より小さいと、上記ステップSC3の判断結果が「YES」になり、ステップSC4に進む。ステップSC4では、レジスタiCostの評価値を、対応する演奏データMidiEvent中の運指評価値iCostとして更新登録すると共に、運指割り当てされた指を表す運指データを、対応する演奏データMidiEvent中の運指データcfigとして登録する。この後、ステップSC5に進み、レジスタiCostの評価値をレジスタiCost1にストアして最小評価値を更新させてから次の運指系列に移行する。
【0030】
以後、全ての運指系列について評価し終えまで上述したステップSC1〜SC5を繰り返す。そして、全ての運指系列について評価し終えると、上記ステップSC1の判断結果が「YES」になり、本処理を完了させる。このように、運指系列選択処理では、運指生成スレッドにて指定された演奏データMidiEventに基づき、考えられる全ての指使い(運指系列)毎に「弾き難さ」を表す評価値を生成し、その内から最も小さい評価値の運指、すなわち一番弾き易い指使いを選択し、その指使いを表す運指データcfigおよび運指評価値iCostを、対応する演奏データMidiEventに登録する。
【0031】
以上説明したように、第1実施形態では、各トラック(演奏パート)毎に起動した運指生成スレッドにおいて、それぞれ対応するトラックの演奏データMidiEventに基づき考えられる全ての指使い(運指系列)毎に「弾き難さ」を表す評価値を生成し、その内から最も小さい評価値の運指、すなわち一番弾き易い指使いを選択し、その指使いを表す運指データcfigおよび運指評価値iCostを対応する演奏データMidiEventに登録する処理を並列的に行う結果、処理負荷を低減させて処理時間の短縮化を図ることが可能になる。
【0032】
C.第2実施形態
次に、図7〜図9を参照して第1実施形態と相違する第2実施形態によるメインルーチン(プライマリスレッド)、トラック処理スレッドおよびフレーズ分割処理の各動作について説明する。なお、第2実施形態の構成は、第1実施形態と共通するので、その説明については省略する。
【0033】
(1)メインルーチンの動作
入力部4からCPU1にメイルーチンの実行を指示するイベントが供給されると、CPU1は図4に図示するメインルーチンを実行してステップSD1に進み、データ読み込み・演奏データ生成を行う。すなわち、ステップSD1では、MIDIインタフェース6を介して外部の電子楽器7からSMF形式の曲データを取り込み、取り込んだ楽曲データから図3に図示したデータ形式の演奏データMidiEvent[0]〜[N]を生成してRAM3の演奏データエリアに格納すると共に、これら演奏データMidiEvent[0]〜[N]をそれぞれ個別に演奏パート別に管理するトラックデータTrack[0]〜[N](図2参照)を生成してRAM3のトラックデータエリアに格納する。
【0034】
続いて、ステップSD2では、トラックデータTrack[0]〜[N]に基づき全てのトラック(演奏パート)を参照し終えたかどうかを判断する。参照し終えていなければ、判断結果は「NO」になり、ステップSD3に進む。ステップSD3では、運指生成の対象となるトラック(演奏パート)について、後述するトラック処理スレッドを起動させてから上記ステップSD2に処理を戻す。以後、トラックデータTrack[0]〜[N]に基づき全てのトラック(演奏パート)を参照し終えるまで各トラック毎のトラック処理スレッドを起動させる。そして、全トラックについてトラック処理スレッドを起動させると、上記ステップSD2の判断結果が「YES」になり、ステップSD4に進む。
【0035】
ステップSD4では、全てのトラック処理スレッドが完了するまで待機し、全トラック処理スレッド完了に応じて判断結果が「YES」になり、本処理を完了させる。このように、プライマリスレッドであるメインルーチンでは、トラックデータTrack[0]〜[N]に基づき全てのトラック(演奏パート)を参照し終えるまで各トラック毎のトラック処理スレッドを起動させ、これらが全て完了した時点で処理終了するようになっている。
【0036】
(2)トラック処理スレッドの動作
次に、図8を参照してトラック処理スレッドの動作を説明する。前述のメインルーチン(図7参照)によりトラック処理スレッドが起動されると、CPU1は図8に図示するステップSE1に進み、処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割するフレーズ分割処理(後述する)を実行する。次いで、ステップSE2では、運指生成の対象となるトラック(演奏パート)の先頭の演奏データMidiEvent[pNote]を指定するポインタpNoteをレジスタmeにストアする。
【0037】
ステップSE3では、レジスタmeの値が「0」でないか否か、すなわち曲終端に達していないかどうかを判断する。曲終端に達していなければ、判断結果は「YES」になり、ステップSE4に進む。ステップSE4では、レジスタmeのポインタで指定される演奏データMidiEvent中のフレーズ番号iPhrase(me.iPhrase)をレジスタphIDにストアする。以後、レジスタphIDの内容をフレーズ番号phIDと称す。続いて、ステップSE5では、レジスタmeのポインタで指定される演奏データMidiEvent中のポインタnextをレジスタmetにストアする。
【0038】
そして、ステップSE6〜SE7では、レジスタmetのポインタを歩進させながら、その歩進されるポインタで指定される演奏データMidiEvent中のフレーズ番号iPhrase(met.iPhrase)が、現在のフレーズ番号phIDに一致するか否かを判断する。換言すれば、フレーズの終わりとなる演奏データMidiEventを探し出す。
【0039】
フレーズ番号iPhrase(met.iPhrase)が現在のフレーズ番号phIDに一致している間は、ステップSE6の判断結果が「YES」になり、ステップSE6〜SE7を繰り返す。そして、フレーズ番号iPhrase(met.iPhrase)が現在のフレーズ番号phIDに一致せず、フレーズの終わりとなる演奏データMidiEventが検出されると、ステップSE6の判断結果が「NO」になり、ステップSE8に進む。
【0040】
ステップSE8では、レジスタmeのポインタ(フレーズの先頭を指定するポインタ)をレジスタmeFromにストアすると共に、レジスタmetのポインタ(フレーズの終わりとなる演奏データMidiEventを指定するポインタ)をレジスタmeToにストアする。そして、ステップSE9では、このレジスタme、meToの各ポインタを引数としてスレッド起動を指示する。次いで、ステップSE10では、レジスタmetのポインタで指定される演奏データMidiEvent中のポインタnextをレジスタmeにストアした後、上述したステップSE3に処理を戻す。
【0041】
上記ステップSE9においてスレッド起動が指示されると、ステップSE11を介して運指生成スレッド(図5参照)を実行させ、レジスタme、meToの各ポインタで指定されるフレーズを構成する演奏データMidiEventに基づき運指生成を行う。そして、ステップSE12では、上記ステップSE11の運指生成スレッドにて得られたフレーズの運指データを、同じフレーズ番号phIDを有するフレーズを構成する演奏データMidiEvent中の運指データcfigとしてコピーする。
【0042】
一方、上述したステップSE3〜SE10の、フレーズ番号phIDのフレーズ先頭および後端を探し出す過程で、レジスタmeの値が「0」となり、曲終端に達すると、上記ステップSE3の判断結果が「NO」になり、ステップSE13に進み、フレーズ単位で起動された全ての運指生成スレッド(ステップSE11)が終了するまで待機し、全スレッド終了に応じて判断結果が「YES」になり、本処理を終える。
【0043】
以上のように、トラック処理スレッドでは、処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割し、分割されたフレーズ毎に運指生成スレッドを起動させてフレーズを構成する演奏データMidiEventに基づき運指生成を行い、これにて得られたフレーズの運指データを、同じフレーズ番号phIDを有するフレーズを構成する演奏データMidiEvent中の運指データcfigとしてコピーするようになっている。
【0044】
(3)フレーズ分割処理の動作
次に、図9を参照してフレーズ分割処理の動作を説明する。トラック処理スレッドのステップSE1(図8参照)を介して本処理が実行されると、CPU1は図9に図示するステップSF1に進み、フレーズ番号を一時記憶するレジスタphIDをゼロリセットする。続いて、ステップSF2では、処理対象とするトラック(演奏パート)の先頭の演奏データMidiEvent[pNote]を指定するポインタpNoteをレジスタmeRefにストアする。
【0045】
次いで、ステップSF3では、先頭の演奏データMidiEvent[pNote]から規定個数先の演奏データMidiEventを指定するポインタをレジスタmetRefにストアする。そして、ステップSF4に進み、レジスタmetRefの値が「0」でないか否か、すなわち曲終端に達していないかどうかを判断する。曲終端に達していなければ、判断結果は「YES」になり、ステップSF5に進み、一致フラグHITを「0」にセットする。次に、ステップSF6では、レジスタmetRefのポインタで指定される演奏データMidiEvent以降であって、フレーズ検出されていない演奏データMidiEventを指定するポインタをレジスタmeSrcにストアする。
【0046】
ステップSF7では、レジスタmeSrcのポインタで指定される演奏データMidiEventから規定個数先の演奏データMidiEventを指定するポインタをレジスタmetRefにストアする。そして、ステップSF8では、レジスタmetSrcの値が「0」でないか否か、すなわち曲終端に達していないかどうかを判断する。曲終端に達していなければ、判断結果は「YES」になり、ステップSF11に進む。
【0047】
ステップSF11〜SF12では、レジスタmeRefのポインタで指定される演奏データMidiEventからレジスタmetRefのポインタで指定される演奏データMidiEventまでの各音からなる参照フレーズと、レジスタmeSrcのポインタで指定される演奏データMidiEventからレジスタmetSrcのポインタで指定される演奏データMidiEventまでの各音からなる比較フレーズとが一致しているかどうかを判断する。なお、一致・不一致の判断は、参照フレーズおよび比較フレーズをそれぞれ構成する各音の「音高」、「発音タイミング」および「音長」が一致するか否かで判定する。
【0048】
参照フレーズと比較フレーズが一致しなければ、上記ステップSF12の判断結果は「NO」になり、ステップSF13〜SF14において比較フレーズを更新する。すなわち、ステップSF13では、レジスタmetSrcのポインタで指定される演奏データMidiEvent以降であって、フレーズ検出されていない演奏データMidiEventを指定するポインタをレジスタmeSrcにストアする。続いて、ステップSF14では、レジスタmeSrcのポインタで指定される演奏データMidiEventから規定個数先の演奏データMidiEventを指定するポインタをレジスタmetRefにストアする。この後、上述したステップSF8に処理を戻す。
【0049】
こうして、ステップSF8〜SF14では、参照フレーズに一致する比較フレーズが出現するまでレジスタmeSrcおよびレジスタmetSrcの各ポインタを更新させる。そして、曲終端に達する以前に、参照フレーズに一致する比較フレーズが見つかると、ステップSF12の判断結果が「YES」になり、ステップSF15に進む。ステップSF15では、一致フラグHITが「1」でないか否か、つまり既に参照フレーズに一致する比較フレーズが見つかっているかどうかを判断する。初めて参照フレーズに一致する比較フレーズが見つかった場合には、判断結果が「YES」になり、ステップSF16に進み、フレーズ番号phIDをインクリメントして歩進させた後、ステップSF17にて一致フラグHITを「1」にセットする。
【0050】
一方、既に参照フレーズに一致する比較フレーズが見つかっている場合であれば、上記ステップSF15の判断結果は「NO」となり、ステップSF17に進み、一致フラグHITを「1」にセットする。次いで、ステップSF18では、レジスタmeSrcのポインタで指定される演奏データMidiEvent中のフレーズ番号iPhrase(meSrc.iPhrase)にフレーズ番号phIDを登録した後、上述のステップSF13に処理を進める。したがって、参照フレーズに一致する比較フレーズが続くような場合には、それらが同一のグループとして同一のフレーズ番号phIDが、対応する演奏データMidiEvent中のフレーズ番号iPhrase(meSrc.iPhrase)に登録される。
【0051】
さて、参照フレーズに一致する比較フレーズが出現するまでレジスタmeSrcおよびレジスタmetSrcの各ポインタを更新させる過程で、レジスタmetSrcのポインタが曲終端に達すると、上述したステップSF8の判断結果が「NO」になり、ステップSF9に進む。ステップSF9〜SF10では、新たな参照フレーズの位置を設定する。すなわち、ステップSF9では、フレーズ検出されていない最初の演奏データMidiEventを指定するポインタを、新たな参照フレーズの先頭としてレジスタmeRefにストアし、続くステップSF10では、この新たな参照フレーズの先頭から規定個数先の演奏データMidiEventを指定するポインタをレジスタmetRefにストアする。
【0052】
この後、前述したステップSF4に進み、レジスタmetRefの値が「0」でないか否か、すなわち曲終端に達していないかどうかを判断する。そして、曲終端に達していなければ、判断結果は「YES」になり、前述したステップSF5以降を実行して、新たに設定した参照フレーズに一致する比較フレーズを探し出す。そして、新たな参照フレーズを設定する際に、参照フレーズの後端が曲終端に達した場合に、ステップSF4の判断結果が「NO」となり、本処理を終える。
【0053】
このように、フレーズ分割処理では、処理対象とするトラック(演奏パート)の演奏データMidiEventを所定音数分に区切った参照フレーズを設定し、この参照フレーズに一致する比較フレーズを探し出す。そして、一致する比較フレーズが無ければ、参照フレーズの位置をずらしながら一致する比較フレーズを探し出し、一致した比較フレーズがあれば、その比較フレーズの先頭の演奏データMidiEvent中のフレーズ番号iPhrase(meSrc.iPhrase)にフレーズ番号phIDを登録する。これにより、処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割できる。
【0054】
以上説明したように、第2実施形態では、処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割し、分割されたフレーズ毎に運指生成スレッドを起動させてフレーズを構成する演奏データMidiEventに基づき運指生成を行い、これにて得られたフレーズの運指データを、同じフレーズ番号phIDを有するフレーズを構成する演奏データMidiEvent中の運指データcfigとしてコピーする。こうした処理を各トラックについて並列的に実行する結果、処理負荷を低減させて処理時間の短縮化を図ることが可能になる。
【0055】
C.第3実施形態
次に、図10を参照して第3実施形態によるトラック処理スレッドの動作を説明する。前述した第2実施形態と同様に、メインルーチン(図7参照)によりトラック処理スレッドが起動されると、CPU1は図10に図示するステップSG1に進み、処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割するフレーズ分割処理を実行する。次いで、ステップSG2では、カウンタiP、iNをゼロリセットする。続いて、ステップSG3では、運指生成の対象となるトラック(演奏パート)の先頭の演奏データMidiEvent[pNote]を指定するポインタpNoteをレジスタmeにストアする。
【0056】
ステップSG4では、レジスタmeの値が「0」でないか否か、すなわち曲終端に達していないかどうかを判断する。曲終端に達していなければ、判断結果は「YES」になり、ステップSG5に進む。ステップSG5では、レジスタmeのポインタで指定される演奏データMidiEvent中のフレーズ番号iPhrase(me.iPhrase)をレジスタphIDにストアする。以後、レジスタphIDの内容をフレーズ番号phIDと称す。続いて、ステップSG6では、レジスタmeのポインタで指定される演奏データMidiEvent中のポインタnextをレジスタmetにストアする。
【0057】
そして、ステップSG7〜SG9は、レジスタmetのポインタを歩進させながら、その歩進されるデータ数をカウンタiNにて計数する一方、歩進されるポインタで指定される演奏データMidiEvent中のフレーズ番号iPhrase(met.iPhrase)が、現在のフレーズ番号phIDに一致するか否かを判断する。換言すれば、フレーズを構成する演奏データ数(フレーズ構成音数)をカウンタiNにて計数しつつ、フレーズの終わりの演奏データMidiEventを探し出す。
【0058】
フレーズ番号iPhrase(met.iPhrase)が現在のフレーズ番号phIDに一致している間は、ステップSE6の判断結果が「YES」になり、ステップSG7〜SG9を繰り返す。そして、フレーズ番号iPhrase(met.iPhrase)が現在のフレーズ番号phIDに一致せず、フレーズの終わりとなる演奏データMidiEventが検出されると、ステップSG7の判断結果が「NO」になり、ステップSG10に進む。
【0059】
ステップSG10では、フレーズ数を計数するカウンタiPの値で指定されるレジスタmeF[iP]に、レジスタmeのポインタ(フレーズの先頭を指定するポインタ)をストアすると共に、カウンタiPの値で指定されるレジスタmeT[iP]に、レジスタmetのポインタ(フレーズの終わりとなる演奏データMidiEventを指定するポインタ)をストアする。さらに、ステップSG10では、カウンタiPの値で指定されるレジスタiN[iP]に、カウンタiNにて計数したフレーズ構成音数をストアする。次いで、ステップSG11では、カウンタiPの値をインクリメントして歩進させると共に、カウンタiNをゼロリセットする。そして、ステップSG12に進み、レジスタmetのポインタで指定される演奏データMidiEvent中のポインタnextをレジスタmeにストアした後、上述したステップSG4に処理を戻す。
【0060】
以後、レジスタmeのポインタが曲終端に達するまで上述したステップSG4〜SG12を繰り返す。これにより、前述のステップSG1において分割された各フレーズの先頭を指定するポインタがレジスタmeF[0]〜[iP]に、各フレーズの後端を指定するポインタがレジスタmeT[0]〜[iP]に、各フレーズ毎のフレーズ構成音数がレジスタiN[0]〜[iP]にそれぞれストアされる。そして、レジスタmeのポインタが曲終端に達すると、上述したステップSG4の判断結果が「NO」になり、ステップSG13に進む。
【0061】
ステップSG13では、レジスタiN[0]〜[iP]にそれぞれストアされた各フレーズ毎のフレーズ構成音数に基づきフレーズ当りの平均構成音数を算出し、算出した平均構成音数をレジスタiNAveにストアする。次いで、ステップSG14では、ポインタiをゼロリセットし、続くステップSG15では、ポインタiがカウンタiPの値(以下、フレーズ数iPと称す)より小さいか否かを判断する。ポインタiがフレーズ数iPより小さければ、判断結果は「YES」になり、ステップSG16に進む。
【0062】
ステップSG16では、ポインタiで指定されるレジスタiN[i]、つまりポインタiで指定されるフレーズのフレーズ構成音数が、レジスタiNAveにストアされる平均構成音数より大きいか否かを判断する。ポインタiで指定されるフレーズのフレーズ構成音数iN[i]が平均構成音数iNAveより大きい場合には、判断結果が「YES」になり、ステップSG17に進む。ステップSG17では、平均構成音数iNAveずつに分割した演奏データMidiEventについて運指生成するスレッドを起動させる。そして、ステップSG18に進み、ポインタiをインクリメントして歩進させた後、上述のステップSG15に処理を戻す。
【0063】
一方、ポインタiで指定されるフレーズのフレーズ構成音数iN[i]が平均構成音数iNAveより小さい場合には、上記ステップSG16の判断結果が「NO」となり、ステップSG19に進み、ポインタiで指定されるフレーズを構成する全ての演奏データMidiEventについて運指生成するスレッドを起動させた後、ステップSG18にてポインタiを歩進させてから上述のステップSG15に処理を戻す。
【0064】
こうして、フレーズ構成音数iN[i]が平均構成音数iNAveを超えるか否かに応じて、平均構成音数iNAveずつに分割した演奏データMidiEventについて運指生成するスレッドあるいはフレーズを構成する全ての演奏データMidiEventについて運指生成するスレッドのいずれかを起動させ終え、ポインタiがフレーズ数iPより大きくなると、上記ステップSG15の判断結果が「NO」になり、ステップSG20に進む。そして、ステップSG20では、起動された全ての運指生成スレッドが終了するまで待機し、全スレッド終了に応じて判断結果が「YES」になり、本処理を終える。
【0065】
以上のように、第3実施形態では、処理対象とするトラック(演奏パート)の演奏データMidiEventをフレーズ区間に分割し、分割された全てのフレーズを参照してフレーズ当りの平均構成音数iNAveを算出する。そして、分割された各フレーズ毎に平均構成音数iNAveを超えているか否かを判断し、平均構成音数iNAveを超えるフレーズであれば、平均構成音数iNAveずつに分割した演奏データMidiEventについて運指生成するスレッドを起動し、一方、平均構成音数iNAveを超えないフレーズならば、フレーズを構成する全ての演奏データMidiEventについて運指生成するスレッドを起動させるようにしたので、負荷分散により処理負荷を低減させて処理時間の短縮化を図ることが可能になる。
【0066】
なお、本実施形態では、分割された全てのフレーズを参照してフレーズ当りの平均構成音数iNAveを算出し、算出した平均構成音数iNAveを超える場合に、平均構成音数iNAveずつに分割した演奏データMidiEventについて運指生成するスレッドを起動し、平均構成音数iNAveを超えない場合にフレーズを構成する全ての演奏データMidiEventについて運指生成するスレッドを起動させるようにしたが、これに限らず、所定音数(演奏データ数)を超えるフレーズの場合に所定音数ずつに分割した演奏データMidiEventについて運指生成するスレッドを起動し、所定音数を超えないフレーズについはフレーズを構成する全ての演奏データMidiEventについて運指生成するスレッドを起動させる態様としても構わない。このようにすれば、平均構成音数iNAveを算出する処理が不要となり、より処理負荷低減を図ることができる。
【図面の簡単な説明】
【0067】
【図1】本発明による第1実施形態の構成を示すブロック図である。
【図2】トラックデータTrackの構成を示す図である。
【図3】演奏データMidiEventの構成を示す図である。
【図4】第1実施形態によるメインルーチンの動作を示すフローチャートである。
【図5】第1実施形態による運指生成スレッドの動作を示すフローチャートである。
【図6】第1実施形態による運指系列選択処理の動作を示すフローチャートである。
【図7】第2実施形態によるメインルーチンの動作を示すフローチャートである。
【図8】第2実施形態によるトラック処理スレッドの動作を示すフローチャートである。
【図9】第2実施形態によるフレーズ分割処理の動作を示すフローチャートである。
【図10】第3実施形態によるトラック処理スレッドの動作を示すフローチャートである。
【符号の説明】
【0068】
1 CPU
2 ROM
3 RAM
4 入力部
5 表示部
6 MIDIインタフェース
7 電子楽器
【特許請求の範囲】
【請求項1】
曲を構成する各音を表すと共に、各音の演奏パートを表す演奏データを記憶する記憶手段と、
前記記憶手段に記憶された演奏データをフレーズ区間に分割する動作を各演奏パート毎に並列的に行わせるフレーズ分割手段と、
前記フレーズ分割手段により分割されたフレーズ区間の運指を生成する動作を各フレーズ区間毎に並列的に行わせる運指生成手段と
を具備することを特徴とする運指情報生成装置。
【請求項2】
前記フレーズ分割手段は、処理対象とする演奏パートの演奏データの先頭から所定音数分に区切った参照フレーズを設定する設定手段と、
前記設定手段により設定された参照フレーズ以降から当該参照フレーズに一致する比較フレーズを検索する第1の検索手段と、
前記第1の検索手段が参照フレーズに一致する比較フレーズを検索できない場合に、参照フレーズの位置をずらしながら当該参照フレーズに一致する比較フレーズを検索する第2の検索手段と、
前記第1および第2の検索手段のいずれかが参照フレーズに一致する比較フレーズを検索した場合に、検索された比較フレーズをフレーズ区間に設定する区間設定手段と
を具備することを特徴とする請求項1記載の運指情報生成装置。
【請求項3】
前記運指生成手段は、フレーズ区間の運指を生成する毎に、その生成した運指を同種のフレーズ区間に割り当てることを特徴とする請求項1記載の運指情報生成装置。
【請求項4】
曲を構成する各音を表すと共に、各音の演奏パートを表す演奏データを記憶する記憶手段と、
前記記憶手段に記憶された演奏データをフレーズ区間に分割し、分割された各フレーズ区間に含まれる音数から区間当りの平均構成音数を算出する動作を各演奏パート毎に並列的に行わせるフレーズ分割手段と、
前記フレーズ分割手段により分割されたフレーズ区間が平均構成音数を超える場合は平均構成音数ずつに分割した演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせ、平均構成音数を超えない場合は該当フレーズを構成する全ての演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせる運指生成手段と
を具備することを特徴とする運指情報生成装置。
【請求項5】
曲を構成する各音を表すと共に、各音毎に対応する演奏パートを表す演奏データをフレーズ区間に分割し、分割された各フレーズ区間に含まれる音数から区間当りの平均構成音数を算出する動作を、各演奏パート毎に並列的に行わせるフレーズ分割処理と、
前記フレーズ分割処理により分割されたフレーズ区間が平均構成音数を超える場合は平均構成音数ずつに分割した演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせ、平均構成音数を超えない場合は該当フレーズを構成する全ての演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせる運指生成処理と
をコンピュータで実行させることを特徴とする運指情報生成処理プログラム。
【請求項1】
曲を構成する各音を表すと共に、各音の演奏パートを表す演奏データを記憶する記憶手段と、
前記記憶手段に記憶された演奏データをフレーズ区間に分割する動作を各演奏パート毎に並列的に行わせるフレーズ分割手段と、
前記フレーズ分割手段により分割されたフレーズ区間の運指を生成する動作を各フレーズ区間毎に並列的に行わせる運指生成手段と
を具備することを特徴とする運指情報生成装置。
【請求項2】
前記フレーズ分割手段は、処理対象とする演奏パートの演奏データの先頭から所定音数分に区切った参照フレーズを設定する設定手段と、
前記設定手段により設定された参照フレーズ以降から当該参照フレーズに一致する比較フレーズを検索する第1の検索手段と、
前記第1の検索手段が参照フレーズに一致する比較フレーズを検索できない場合に、参照フレーズの位置をずらしながら当該参照フレーズに一致する比較フレーズを検索する第2の検索手段と、
前記第1および第2の検索手段のいずれかが参照フレーズに一致する比較フレーズを検索した場合に、検索された比較フレーズをフレーズ区間に設定する区間設定手段と
を具備することを特徴とする請求項1記載の運指情報生成装置。
【請求項3】
前記運指生成手段は、フレーズ区間の運指を生成する毎に、その生成した運指を同種のフレーズ区間に割り当てることを特徴とする請求項1記載の運指情報生成装置。
【請求項4】
曲を構成する各音を表すと共に、各音の演奏パートを表す演奏データを記憶する記憶手段と、
前記記憶手段に記憶された演奏データをフレーズ区間に分割し、分割された各フレーズ区間に含まれる音数から区間当りの平均構成音数を算出する動作を各演奏パート毎に並列的に行わせるフレーズ分割手段と、
前記フレーズ分割手段により分割されたフレーズ区間が平均構成音数を超える場合は平均構成音数ずつに分割した演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせ、平均構成音数を超えない場合は該当フレーズを構成する全ての演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせる運指生成手段と
を具備することを特徴とする運指情報生成装置。
【請求項5】
曲を構成する各音を表すと共に、各音毎に対応する演奏パートを表す演奏データをフレーズ区間に分割し、分割された各フレーズ区間に含まれる音数から区間当りの平均構成音数を算出する動作を、各演奏パート毎に並列的に行わせるフレーズ分割処理と、
前記フレーズ分割処理により分割されたフレーズ区間が平均構成音数を超える場合は平均構成音数ずつに分割した演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせ、平均構成音数を超えない場合は該当フレーズを構成する全ての演奏データを用いて運指生成する動作を各フレーズ区間毎に並列的に行わせる運指生成処理と
をコンピュータで実行させることを特徴とする運指情報生成処理プログラム。
【図1】
【図2】
【図3】
【図4】
【図5】
【図6】
【図7】
【図8】
【図9】
【図10】
【図2】
【図3】
【図4】
【図5】
【図6】
【図7】
【図8】
【図9】
【図10】
【公開番号】特開2007−47535(P2007−47535A)
【公開日】平成19年2月22日(2007.2.22)
【国際特許分類】
【出願番号】特願2005−232915(P2005−232915)
【出願日】平成17年8月11日(2005.8.11)
【出願人】(000001443)カシオ計算機株式会社 (8,748)
【Fターム(参考)】
【公開日】平成19年2月22日(2007.2.22)
【国際特許分類】
【出願日】平成17年8月11日(2005.8.11)
【出願人】(000001443)カシオ計算機株式会社 (8,748)
【Fターム(参考)】
[ Back to top ]