以下、本発明を実施するための形態について図面を参照しながら詳細に説明する。図1は、コード解析装置100の一実施形態を、ソフトウェア処理として実現できるコンピュータのハードウェア構成の一例を示す図である。
図1に示されるコンピュータは、CPU101、ROM(Read Only Memory:読出し専用メモリ)102、RAM(Random Access Memory:ランダムアクセスメモリ)103、入力手段104、表示手段105、サウンドシステム106、及び通信インタフェース107を有し、これらがバス108によって相互に接続された構成を有する。図1に示される構成はコード解析装置を実現できるコンピュータの一例であり、そのようなコンピュータはこの構成に限定されるものではない。
CPU101は、当該コンピュータ全体の制御を行う。ROM102は、後述する図4、図5、図8〜図10、図13、図14のフローチャートで示されるコード解析処理プログラムや、複数楽曲分のスタンダードMIDIファイル等を記憶する。RAM103は、コード解析処理プログラムの実行時に作業用メモリとして使用される。CPU101は、ROM102からコード解析処理プログラムをRAM103に読み出して実行する。コード解析処理プログラムは、例えば特には図示しない可搬記録媒体に記録して配布してもよく、或いは通信インタフェース107によりインターネットやローカルエリアネットワーク等のネットワークから取得できるようにしてもよい。
入力手段104は、ユーザによるキーボードやマウス等による入力操作を検出し、その検出結果をCPU101に通知する。入力操作は、例えば楽曲の選択操作、コード解析の指示操作、楽曲の再生装置等である。また、ユーザによる入力手段104の操作により、楽曲のスタンダードMIDIファイルがネットワークから通信インタフェース107を介してRAM103にダウンロードされるようにしてもよい。
表示手段105は、CPU101の制御によって出力されるコード判定データを液晶ディスプレイ装置等に表示する。
サウンドシステム106は、ユーザが入力手段104により、ROM102やネットワークから取得した楽曲のスタンダードMIDIファイルの再生を指示したときに、当該スタンダードMIDIファイルのシーケンスを順次読み込んで解釈することにより、ユーザが指定した楽器音で楽音信号を生成し、スピーカ等から発音する。
図2(a)は、ROM102からRAM103に読み込まれ、又はネットワークから通信インタフェース107を介してRAM103にダウンロードされるスタンダードMIDIファイルに格納されている、MIDIシーケンスデータの構成例を示す図である。楽曲は複数パート(=トラック)で構成され、各パートの先頭のノートイベントへのポインタ情報が、midiev[0]、midiev[1]、midiev[2]、・・・として保持される。CPU101は、ポインタ情報midiev[i](i=0,1,2,・・・)を参照することにより、iパートのRAM103に記憶されている最初のノートイベントにアクセスすることができる。
このノートイベントは、次の構造体データを保持する。lTimeは発音開始時刻を保持する。lGateはゲートタイム(発音時間長)を保持する。これらの時刻の単位としては、例えばティック(tick)が使われる。この場合、4分音符は例えば480ティックの時間長を有し、4分の4拍子の楽曲の場合、1拍=480ティックとなる。byData[0]はステータスを保持する。byData[1]は発音されるノートのピッチを保持する。byData[2]は発音されるノートのベロシティを保持する。byData[3]はその他ノートの発音を制御するために必要な情報を保持する。nextは次のノートイベントへのポインタ、prevは1つ前のノートイベントへのポインタである。CPU101は、nextやprevを参照することにより、RAM103に記憶されている次の又は1つ前のノートイベントにアクセスすることができる。
また、CPU101がサウンドシステム106を制御して楽曲を再生するために必要な、テンポや拍子などのメタ情報は、ポインタ情報metaev[0]、metaev[1]、metaev[2]、・・・から参照することができる。
図2(b)は、後述する調判定処理の結果得られる調データの構成例を示す図である。調情報は、ポインタ情報tonality[0]、tonality[1]、tonality[2]、・・・からアクセスされる。tonality[i](i=0、1、2、・・・)は、小節番号iに対応する調情報へのポインタである。これらのポインタから参照される調情報は、次の構造体データを保持する。lTickは楽曲のメロディに対する調の開始の時刻を保持する。lTickの時間単位は、前述したティックである。iMeasNoは調が開始される小節の番号を保持する。iKeyは調のキーを保持する。iScaleは調のタイプを保持するが、本実施形態では未使用である。doPowerValueは調判定時のパワー評価値を保持する。iLengthは調判定時の区間長を保持し、後述するように小節を単位とする区間長を示す1、2、又は4である。
図3は、後述するコード判定処理の結果得られるコード進行データの構成例を示す図である。コード進行データは、楽曲を構成する各小節の拍毎に、例えば第1候補、第2候補、第3候補、・・・の複数候補を持つことができる。いま、楽曲の先頭からの拍番号の通番を第1要素番号lCnt(lCnt=0、1、2、・・・)、各拍における候補番号を第2要素番号i(i=0、1、2、・・・)とすれば、各コード進行データは、ポインタ情報chordProg[lCnt][i]によってアクセスすることができる。このポインタ情報からアクセスされるコード情報は、次の構造体データを保持する。lTickはメロディに対するコードの開始の時刻を保持する。lTickの時間単位は、前述したティックである。iMeasNoは調の小節の番号を保持する。iTickInMeasは小節内でのコードの開始の時刻を保持する。iTickInMeasの時間単位も、前述したティックである。本実施形態では、コードは拍毎に判定されるため、iTickInMeasの時間単位も拍単位となり、1拍目、2拍目、3拍目、又は4拍目の何れかとなる。図2(a)の説明で前述したように、1拍は一般的に480ティックであるため、iTickInMeasは、0、480、960、1440の何れかの値となる。iRootはコード判定結果(ルート)を保持する。iTypeはコード判定結果(タイプ)を保持する。doPowerValuenはコード判定時のパワー評価値を保持する。
図4は、図1のCPU101が実行するコード解析装置の全体処理の例を示すメインフローチャートである。例えば、図1のコード解析装置100がスマートフォン等の汎用のコンピュータであった場合、ユーザがコード解析装置100のアプリをタップすることにより、CPU101が、図4のフローチャートで例示されるコード解析処理プログラムをスタートする。CPU101はまず、レジスタやRAM103に記憶される変数の初期化等の初期化処理を実行する(ステップS401)。その後、CPU101は、ステップS402からS408までの一連の処理を、繰り返し実行する。
CPU101はまず、ユーザがアプリ上の特定のボタンをタップすることによりアプリの終了が指示されたか否かを判定する(ステップS402)。ステップS402の判定がYESになると、CPU101は、図4のフローチャートで例示されるコード解析処理を終了する。
ステップS402の判定がNOならば、CPU101は、ユーザが入力手段104を介して楽曲の選曲を指示したか否かを判定する(ステップS403)。
ステップS403の判定がYESならば、CPU101は、ROM102又は通信インタフェース107を介してネットワークから、図2(a)のデータフォーマットを有する楽曲のスタンダードMIDIファイルのMIDIシーケンスデータを、RAM103に読み込む(ステップS404)。
その後、CPU101は、後述するコード判定処理を実行することにより、読込みが指示された楽曲のMIDIシーケンスデータの全体に渡って、コードを判定する処理を実行する(ステップS405)。その後、CPU101は、ステップS401の処理に戻る。
ステップS403の判定がNOならば、CPU101は、ユーザが入力手段104を介して楽曲の再生を指示しているか否かを判定する(ステップS406)。
ステップS406の判定がYESならば、CPU101は、RAM103に読み込まれているMIDIシーケンスデータを解釈しながら、サウンドシステム106に発音指示を出力することにより、楽曲の再生を行わせる(ステップS407)。その後、CPU101は、ステップS401の処理に戻る。
ステップS406の判定がNOならば、CPU101は、ステップS401の処理に戻る。
図5は、図4のステップS405のコード判定処理の詳細例を示すフローチャートである。
始めに、CPU101は、調判定処理を実行することにより、楽曲の小節毎に調を判定する(ステップS501)。この結果、RAM103に、図2(b)に例示されるデータ構成を有する調データが得られる。
次に、CPU101は、全ての小節毎に、以下のステップS503からS505までの一連の処理を繰り返し実行する(ステップS502)。
この全ての小節毎の繰返し処理において、CPU101は、更に小節内の全ての拍毎に、以下のステップS504とS505の処理を繰り返し実行する。この拍毎の繰返しにおいてCPU101はまず、ピッチクラスパワー作成処理を実行する(ステップS504)。ここでは、CPU101は、拍の構成音をピッチクラスパワーとして判定する。この処理の詳細については図10及び図11の説明で後述する。
次に、CPU101は、マッチング&結果保存処理を実行する(ステップS505)。ここでは、CPU101は、ステップS504で算出した現在の拍におけるピッチクラス毎のパワー情報累算値に基づいてその拍の構成音を判定し、その構成音に基づいてその拍のコードを判定する。この処理の詳細については図14の説明で後述する。その後、CPU101は、ステップS503の処理に戻る。
小節内の全ての拍について、ステップS504とS505の処理の実行が終了し、その小節内の全ての拍に対応するコード進行データが生成されると、CPU101はステップS502の処理に戻る。
楽曲の全ての小節について、ステップS502からS505の一連の処理の実行が終了し、楽曲の全ての小節内の全ての拍に対応するコード進行データが生成されると、CPU101はステップS506の処理に移行する。
ステップS506において、CPU101は、楽曲の全ての小節及び小節内の全ての拍に対して図3に例示されるデータフォーマットで得られる複数候補からなるコード進行データの全ての組合せの中から、楽曲全体でコストが最小となるコードの組合せを算出する。この処理の詳細については、図16から図18の説明において後述する。
この結果、CPU101は、楽曲全体に渡るコード進行の経路を確定し、これにより最適コードが確定する(ステップS507)。この処理の詳細については、図16及び図19の説明において後述する。この最適なコード進行は、特には図示しないが、ユーザによる入力手段104からの指示に基づいて、表示手段105に表示される。ユーザの指示に応じて、図4のステップS407の再生処理によるサウンドシステム106からの楽曲再生に同期して、表示手段105に表示される最適なコード進行が進んでゆく。その後、CPU101は、図5のフローチャートで示される図4のステップS405のコード判定処理を終了する。
次に、図5のステップS501の調判定処理の詳細について、以下に説明する。図6は、図5のステップS501の調判定処理の詳細例を示すフローチャートである。また、図7(a)は小節と拍の説明図、図7(b)は調判定の説明図である。
いま、読み込まれている楽曲が4拍子の楽曲の場合、図7の(a−2)に示されるような楽曲(Song)の進行に従って、図7の(a−3)に示されるように小節番号iMeasNoが、0、1、2、・・・というように進んでゆく。そして、図7(a−1)に示されるように、各小節内で、拍番号iBeatNが0、1、2、3というように繰り返される。
図6のフローチャートで例示される調判定処理において、CPU101は、図7(b−1)の楽曲(Song)及び(b−2)の小節番号(iMeasNo)の進行に合わせて、図7(b−3)(b−4)(b−5)に示されるように、1小節長、2小節長、4小節長という1小節の倍数の単位を有する複数の区間長から区間長を選択しながら、次の処理を実行する。以下の説明で、1小節の区間長をiFrameType=0、2小節の区間長をiFrameType=1、4小節の区間長をiFrameType=2と記載する。なお、区間長の選択は、1、2、4小節に限られたものではなく、例えば2、4、8小節であってもよい。CPU101は、iFrameType=0、1、2の各区間長で楽曲を区切った区間(図7(b−3)(b−4)(b−5)の各直線矢印が示す区間)毎に(ステップS601)、区間の開始小節を1小節ずつずらしながら(ステップS602)、以下の処理を実行する。
CPU101は、iFrameTypeにより規定される各区間毎に、その区間の構成音を判定し、その構成音に基づいて調を判定するキー判定処理を実行する(ステップS603)(調判定手段として動作)。この処理の詳細については、図9から図12の説明において後述する。
図8は、調判定の動作結果例を示す図である。この結果例において、図8(a)は小節番号(iMeasNo)を示している。また、図8(b)において、図8(a)の各小節番号に対応して記載されている音名群は、各小節番号に対応する小節毎にMIDIシーケンスデータからのノートイベントにより実際に発音が行われる楽音の各構成音の音名を示している。
図8の結果例において、例えばiFrameType=0(1小節区間長)に対しては、図8(c)に示されるように、図8(a)の各小節番号(iMeasNo)の1小節ずつを単位として、判定区間が1小節ずつずらされながら、B♭、B♭、G、B♭、A♭、E♭というように調が判定される。このとき、例えば「B♭:3」という記載は、B♭の調判定時にパワー評価値=3という評価値が得られていることを示している。この評価値については後述するが、この値が大きいほど調判定の信頼性が高いことを示している。
次に、例えばiFrameType=1(2小節区間長)に対しては、図8(d)の上下上下・・・の順で、図8(a)の各小節番号(iMeasNo)の連続する2小節ずつを単位として、判定区間が1小節ずつずらされながら、B♭、C、C、B♭、A♭、E♭というように調が判定される。
更に、例えばiFrameType=2(4小節区間長)に対しては、図8(e)の左上から右下に向かって、図8(a)の各小節番号(iMeasNo)の連続する4小節ずつを単位として、判定区間が1小節ずつずらされながら、B♭、C、C、A♭、A♭、A♭というように調が判定される。
図6のステップS603によるキー判定処理の動作の後、CPU101は、ステップS601によりiFrameType=0(1小節)、1(2小節)、2(4小節)というように順次指定される区間長で繰り返されるステップS603のキー判定処理の結果、現在までに計算されている区間長間で重なる区間毎に、その区間に対して各区間長で判定された調同士を比較することにより現時点での最適な調を決定する、結果保存処理を実行する(ステップS604)(調決定手段として動作)。この処理の詳細については、図13の説明において後述する。
図8の例においては、例えば図8(a)の小節番号(iMeasNo)=0において、iFrameType=1までのキー判定処理(ステップS603)が終了した時点で、図8(c)のiFrameType=0の調判定はキー音名がB♭でパワー評価値が3、図8(d)のiFrameType=1の調判定はキー音名がB♭でパワー評価値が4となっている。従って、このキー判定処理に続く結果保存処理(ステップS604)において、パワー評価値が大きいほうの調として、その時点での最適な調はキー音名がB♭でパワー評価値は4と決定される。更に、iFrameType=2までのキー判定処理が終了した時点で、その時点での最適な調は上述のようにキー音名がB♭でパワー評価値は4、図8(e)のiFrameType=2の調判定はキー音名がCでパワー評価値は7となっている。従って、このキー判定処理に続く結果保存処理において、最終時点での最適な調はキー音名=Cと決定される。この結果、CPU101は、RAM103に、図2(b)のデータフォーマットの調情報を生成する。この調情報において、lTickにはiMeasNo=0の小節の先頭の開始時刻が格納される。また、iMeasNoには小節番号として0が格納される。iKeyには最適な調として決定されたキー音名Cに対応するキー値=0が格納される。doPowerValueには最適な調が決定されたときのパワー評価値7が格納される。そして、iLengthには最適な調が決定されたときに採用されたiFrameTypeの値2が格納される。
図8の例において、例えば図8(a)の小節番号(iMeasNo)=1〜3までは、上述の場合と同様にして、各小節毎に最適な調がキー音名=Cと決定されパワー評価値7が得られ、図2(b)に例示されるデータフォーマットで調データが生成される。続いて、小節番号(iMeasNo)=4では、iFrameType=1(2小節長)から最も高いパワー評価値=6を有するとしてキー音名=Bbの調が選択される。以下、小節番号(iMeasNo)=5、6では、やはりiFrameType=1から最も高いパワー評価値=7を有するとしてキー音名=E♭の調が選択される。これは、小節番号(iMeasNo)が3から4に変わるときに、転調が発生したことを示している。
このように、本実施形態では、複数の区間長(iFrameType)での調判定結果が総合的に判断されることにより、例えば転調が発生した場合には、パワー評価値に基づいて1小節区間長や2小節区間長の短い区間長の判定結果が採用されることにより、転調を検知することが可能となる。また、1小節だけではコードを判定するのに十分な発音がないような場合であっても、パワー評価値に基づいて2小節区間長や4小節区間長のより長い区間長の判定結果が採用されることにより、適切な判定を行うことが可能となる。更に、本実施形態では、後述するようにパワー評価値を算出するときに、調の音階音以外の音についての配慮も行われるため、判定の精度を維持することが可能となる。
図6のステップS604の処理の後、CPU101は、ステップS602の処理に戻る。CPU101は、ひとつのiFrameTypeの値に対して区間の開始小節を1小節ずつずらしながら楽曲の全ての小節について、ステップS603のキー判定処理及びステップS604の結果保存処理を繰り返し実行する。全ての小節に対する上記繰返し処理が終了すると、ステップS601の処理に戻る。そして、CPU101は、iFrameType=0、1、2の全ての値(小節区間長)に対してステップS602からS604までの一連の処理を繰り返し実行する。3種類全てのiFrameTypeの値に対する上記繰返し処理が終了すると、図6のフローチャートで例示される図5のステップS501の調判定処理を終了する。
図9は、図6の調判定処理におけるステップS603のキー判定処理の詳細例を示すフローチャートである。CPU101はまず、ピッチクラスパワー作成処理を実行する(ステップS901)。ここでは、CPU101は、現在設定されている1小節、2小節、又は4小節の区間長を有する区間内でノートオンする楽曲のノートイベント毎に、そのノートイベントのベロシティとその区間内での発音時間長とに基づいて決定されるパワー情報値をそのノートのピッチに対応するピッチクラスに累算することにより、その区間におけるピッチクラス毎のパワー情報累算値を算出する。ここで、ピッチクラスとは、1オクターブを12半音で12分割したときの各半音に対して与えられている整数値をいい、例えば1オクターブ内の音名Cは整数値0、C#又はD♭は1、Dは2、D#又はE♭は3、Eは4、Fは5、F#又はG♭は6、Gは7、G#又はA♭は8、Aは9、A#又はB♭は10、Bは11に、それぞれ対応している。本実施形態では、調が、1小節、2小節、又は4小節の区間長を有する区間毎に判定される。ここで、調を表すキー音名及び音階音は、オクターブに依存しない音名の組合せとして決定される。従って、本実施形態では、CPU101が、区間内で発音されるノートを、RAM103に記憶されている図2(a)のデータフォーマットを有する各ノートイベントの発音時刻lTime及びゲートタイム(発音時間)lGateから検索し、検索されたノートのピッチ(図2(a)のbyData[1])を、その値を12で除算したときの0から11の何れかの剰余値として、ピッチクラスに変換する。そして、CPU101は、そのノートのベロシティとその区間内での発音時間長とに基づいて決定されるパワー情報値をそのノートのピッチに対応するピッチクラスに累算することにより、その拍におけるピッチクラス毎のパワー情報累算値を算出する。いま、ピッチクラスをiPc(0≦iPc≦11)として、ステップS901のピッチクラスパワー作成処理により作成された各ピッチクラスiPc(0≦iPc≦11)におけるパワー換算値を、ピッチクラスパワーlPichClassPower[iPc]とする。この処理の詳細については図10及び図11の説明で後述する。
次に、CPU101は、調のキー値を示す全てのikeyの値0から11について、以下のステップS903からS910の一連の処理を実行する(ステップS902)。まず、CPU101は、ステップS903からS908の一連の処理を実行する。
具体的には、CPU101は始めに、共にRAM103に記憶される変数である第1のパワー評価値lPowerと第2のパワー評価値lOtherPowerの各値を0にクリアする(ステップS903)。
次に、CPU101は、0から11までの値を有する全てのピッチクラスiPc毎に、以下のステップS905からS907の処理を実行する(ステップS904)。
まず、CPU101は、ステップ904で指定された現在のピッチクラスiPcが、ステップS902で指定された現在のキー値ikeyに基づいて定まる調の音階音に含まれるか否かを判定する(ステップS905)。この判定は、「scalenote[(12+iPc−ikey)%12]の値が1であるか否か」を判定する演算である。図10は、スケールノートの説明図である。図10において、(a)major、(b)hminor、及び(c)mminorの各行は、調のキー値がピッチクラス=0(音名=C)である場合における、メジャースケール、ハーモニックマイナースケール、及びメロディックマイナースケールの各スケールの音階を構成するピッチクラス及び音名を示している。各行で、値「1」が記載されているピッチクラス及び音名が、その行に対応するスケールの音階を構成する構成音である。値「0」が記載されているピッチクラス及び音名は、その行に対応するスケールの音階を構成しない音である。本実施形態では、処理の簡単化及び安定性確保のために、図10の(a)、(b)、及び(c)の各スケールの音階音が比較対象とされるのではなく、これらのスケールを統合した図10の(d)のスケール(以下これを「統合スケールscale」と記載する)の音階音が比較対象とされる。図10(d)の統合スケールscaleの音階音又は音階を構成しない音は、図10の(a)、(b)、及び(c)の各スケールの音階音又は音階を構成しない音に対してピッチクラス(音名)毎に論理和を演算して得られるものである。すなわち、ピッチクラス(音名)毎に、図10の(a)、(b)、及び(c)の各スケールの値が「1」であれば統合スケールscaleの値は「1」であり、図10の(a)、(b)、及び(c)の全てのスケールの値が「0」であれば統合スケールscaleの値は「0」である。図1のROM102は、キー値がピッチクラス=0(音名=C)であるときの図10(d)の統合スケールscaleに対応する配列定数scale[i]を記憶している。ここで、iは図10の0から11までのピッチクラスの値をとり、配列要素値scale[i]には、図10(d)の統合スケールscaleの行のピッチクラスiにおける値1又は0が格納されている。CPU101は、ステップS905において、まず、「(12+iPc−ikey)%12」の値を演算する。この演算では、ステップS904で指定されているピッチクラスiPcとステップS902で指定されているキー値ikeyとの差分値が、どのピッチクラスになるかが算出されている。括弧内で12が加算されているのは「iPc−ikey」の値がマイナス値にならないようにするためである。また、「%」は、剰余を求める剰余演算を示している。CPU101は、この演算結果を配列要素引数として、ROM102から読み出した配列要素値scalenote[(12+iPc−ikey)%12]の値が1であるか否かを判定する。これにより、CPU101は、ステップS904で指定されているピッチクラスiPcが、図10(d)に示されるキー値がピッチクラス=0(音名=C)のときの統合スケールscaleをキー値がステップS902で指定されているキー値ikeyであるときの統合スケールscaleに変換したときの音階音に含まれているか否かを判定することができる。
ステップ904で指定された現在のピッチクラスiPcが、ステップS902で指定された現在のキー値ikeyに対応する統合スケールscaleの音階音に含まれている場合(ステップS905の判定がYESの場合)には、CPU101は、そのピッチクラスiPcに対応してステップS901で算出されているピッチクラスパワーlPichClassPower[iPc]を、第1のパワー評価値lPowerに累算する(ステップS906)。図6のステップS906において、演算記号「+=」は、その左辺の値にその右辺の値を累算する演算を示している。後述するステップS907、図14のステップS1406、及びステップS1407の各「+=」記号も同様である。
一方、ステップ904で指定された現在のピッチクラスiPcが、ステップS902で指定された現在のキー値ikeyに対応する統合スケールscaleの音階音に含まれていない場合(ステップS905の判定がNOの場合)には、CPU101は、そのピッチクラスiPcに対応してステップS901で算出されているピッチクラスパワーlPichClassPower[iPc]を、第2のパワー評価値lOtherPowerに累算する(ステップS907)。
CPU101は、0から11までの値を有する全てのピッチクラスiPcについて、上述のステップS905からS907の処理の実行を終えると(ステップS904の判定が「終了」になると)、第1のパワー評価値lPowerを第2のパワー評価値lOtherPowerで除算して得られる値として、ステップS902で現在指定されているキー値ikeyに対応するパワー評価値doKeyPowerを算出する(ステップS908)。ステップS908の実行時点で、第1のパワー評価値lPowerはステップS902で現在指定されているキー値ikeyに対応する統合スケールscaleの音階音がどれくらいの強さで発音されるかを示している。また、第2のパワー評価値lOtherPowerは、キー値ikeyに対応する統合スケールscaleの音階音以外の音がどれくらいの強さで鳴っているかを示している。従って、「lPower÷lOtherPower」として算出されるパワー評価値doKeyPowerは、現在の区間で鳴っている楽音(ノート)がどのくらい、現在のキー値ikeyに対応する統合スケールscaleの音階音らしいかを示す指標となる。
続いて、CPU101は、ステップS908で算出した現在のキー値ikeyに対応するパワー評価値doKeyPowerを、現時点の直前までに指定されたキー値に対応するパワー評価値最高値doMaxと比較する(ステップS909)。そして、CPU101は、doKeyPowerがdoMaxer以上であれば、パワー評価値最高値doMaxとパワー評価値最高キー値imaxkeyを、現在のパワー評価値doKeyPowerとキー値iKeyにそれぞれ置き換える(ステップS910)。その後、CPU101は、ステップS902の処理に戻って、次のキー値ikeyに対する処理に移行する。
図11は、図9のステップS901のピッチクラスパワー作成処理の例を示すフローチャートであり、図11は、ピッチクラスパワー作成処理の説明図である。CPU101はまず、図4のステップS404でRAM103に読み込んだ図2(a)のデータフォーマット例を有するMIDIシーケンスデータにおいて、全てのトラック毎に、以下のステップS1102からS1111までの一連の処理を繰り返し実行する(ステップS1101)。以下、CPU101は、ステップS1101において、各トラックを、RAM103に記憶される変数であるトラック番号iTrackの値として順次指定する。ここでは、CPU101は、図2(a)の例のMIDIシーケンスデータにおいて、トラック番号iTrackに対応するポインタ情報midiev[iTrack]を参照することにより、トラック番号iTrackに対応するパートのRAM103に記憶されている最初のノートイベントにアクセスする。
そして、CPU101は、上記最初のノートイベントから順次、各ノートイベント内の図2(a)のnextポインタを参照しながら辿ることにより、トラック番号iTrackのパート内の全てのノートイベント毎に、以下のステップS1103からS1111までの一連の処理を繰り返し実行する(ステップS1102)。ここで、現在のノートイベントへのポインタを「me」と記載する。そして、現在のノートイベント内のデータ、例えば図2(a)の発音開始時刻lTimeへの参照は、「me−>lTime」などと記載する。
CPU101は、図6のステップS601により定まる1小節長、2小節長、又は4小節長の区間長を有してステップS602で指定される開始小節から始まる区間(以下これを「現在の該当範囲」と記載する)に、ステップS1102で指定されている現在のノートイベントが含まれるか否かを判定する(ステップS1103)。いま、CPU101は、楽曲先頭から計時した現在の該当範囲の先頭時刻を計算して、その時刻を、変数である該当範囲開始時刻lTickFromとしてRAM103に記憶する。前述したように、拍及び小節の時間単位としては、何れも前述したティックが使用され、1拍は一般的に480ティックで、4分の4拍子の楽曲の場合、1小節は4拍である。従って、例えば4分の4拍子の楽曲の場合では、楽曲の先頭を0小節目として図6のステップS602で指定される区間の開始小節番号をカウントした場合、区間の開始小節の開始時刻は(480ティック×4拍×区間の開始小節番号)となり、これが該当範囲開始時刻lTickFromとして算出される。同様に、CPU101は、楽曲先頭から計時した現在の該当範囲の終了時刻を計算して、その時刻を、変数である該当範囲終了時刻lTickToとしてRAM103に記憶する。該当範囲終了時刻lTickToは、該当範囲開始時刻lTickFrom+(480ティック×4拍×ステップS601で指定されている区間長)である。そして、CPU101は、現在のノートイベントのポインタmeから参照される現在のノートイベントの発音開始時刻lTimeと発音時間長lGate(共に図2(a)参照)とから定まる現在のノートイベントの発音区間が、上記該当範囲開始時刻lTickFrom及び該当範囲終了時刻lTickToに対して、図12の1201、1202、又は1203の何れかの関係にあるか否かを判定する。これらの何れかの関係が成立すれば、現在指定されているノートイベントによる発音は、現在の該当範囲に含まれる(かかっている)ことになる。これが成立する場合、CPU101は、ステップS1103の判定をYESとする。具体的には、図12の関係より、CPU101は、該当範囲終了時刻lTickToが現在のノートイベントの発音開始時刻me−>lTimeより後であって、かつ該当範囲開始時刻lTickFromが現在のノートイベントの発音終了時刻である(発音開始時刻me−>lTime+発音時間長me−>lGate)より前であれば、ステップ S1103の判定をYESとする。
ステップS1103の判定がNOであれば、CPU101は、現在のノートイベントは現在の該当範囲に含まれていないと判定して、ステップS1102の処理に戻り、次のノートイベントに対する処理に移行する。
ステップS1103の判定がYESであれば、CPU101は、該当範囲開始時刻lTickFromが、現在のノートイベントの発音開始時刻me−>lTimeよりも後であるか否かを判定する(ステップS1104)。
ステップS1104の判定がYESならば、図12の1201の状態が判定されたことになるので、CPU101は、RAM103に記憶される変数である現在のノートイベントの現在の該当範囲内での発音開始時刻lTickStartに、該当範囲開始時刻lTickFromをセットする(ステップS1105)。
一方、ステップS1104の判定がNOならば、図12の1202又は1203の状態が判定されたことになるので、CPU101は、現在のノートイベントの現在の該当範囲内での発音開始時刻lTickStartに、現在のノートイベントの発音開始時刻me−>lTimeをセットする(ステップS1106)。
ステップS1105又はS1106の処理の後、CPU101は、該当範囲終了時刻lTickToが、現在のノートイベントの発音終了時刻である(発音開始時刻me−>lTime+発音時間長me−>lGate)よりも後であるか否かを判定する(ステップS1107)。
ステップS1107の判定がYESならば、図12の1201又は1202の状態が判定されたことになるので、CPU101は、RAM103に記憶される変数である現在のノートイベントの現在の該当範囲内での発音終了時刻lTickEndに、現在のノートイベントの発音終了時刻である(発音開始時刻me−>lTime+発音時間長me−>lGate)をセットする(ステップS1108)。
一方、ステップS1107の判定がNOならば、図12の1203の状態が判定されたことになるので、CPU101は、現在のノートイベントの現在の該当範囲内での発音終了時刻lTickEndに、該当範囲終了時刻lTickToをセットする(ステップS1109)。
ステップS1108又はS1109の処理の後、CPU101は、RAM103に記憶される変数である現在のノートイベントのピッチiPitchに、現在のノートイベントのポインタmeから参照されるピッチbyData[1](図2(a)参照)の値を格納する(ステップS1110)。
そして、CPU101は、現在のノートイベントのピッチiPitchを12で除算したときの剰余(iPitch%12)として算出される現在のノートイベントに対応するピッチクラスにおけるRAM103に記憶される配列要素値であるピッチクラスパワーlPichClassPower[iPitch%12]に、以下の計算値を格納する。CPU101は、現在のノートイベントのベロシティとパート情報とから定まるベロシティ情報lPowerWeightに、現在のノートイベントの現在の該当範囲における発音時間長(lTickEnd−lTickStart)を乗算した値として、上記ピッチクラスパワーlPichClassPower[iPitch%12]を算出する。ここで、ベロシティ情報lPowerWeightは例えば、現在のノートイベントのポインタmeから参照されるベロシティme−>byData[2](図2(a)参照)に、現在のトラック番号iTrack(ステップS1101参照)に対応するパートに対して予め規定されROM102に記憶されている所定のパート係数を乗算した値として算出される。このようにして、現在のノートイベントに対応するピッチクラスパワーlPichClassPower[iPitch%12]の値は、現在の該当範囲内での現在のノートイベントの発音時間が長ければ長いほど、また発音の強さを示すベロシティが大きければ大きいほど、そして現在のノートイベントが属するパートに応じて、現在のノートイベントに対応するピッチクラス(iPitch%12)の音の現在の該当範囲での構成割合が大きいことになる。
ステップS1111の処理の後、CPU101は、ステップS1102の処理に戻り、次のノートイベントに対する処理に移行する。
上述のステップS1103からS1111までの一連の処理が繰り返し実行されることにより、現在のトラック番号iTrackに対応する全てのノートイベントmeに対応する処理が終了すると、CPU101は、ステップS1101の処理に戻り、次のトラック番号iTrackに対する処理に移行する。更に、上述のステップS1102からS1111の処理が繰り返し実行されることにより、全てのトラック番号iTrackに対応する処理が終了すると、CPU101は、図11のフローチャートで例示される図9のステップS901のピッチクラスパワー作成処理を終了する。
図13は、図5の調判定処理の詳細例である図6のフローチャートの処理におけるステップS604の結果保存処理の詳細例を示すフローチャートである。ここでは、CPU101は、図6のステップS603のキー判定処理により、現在の該当範囲(ステップS601で定まる区間長を有してステップS602で指定される開始小節から始まる区間)に対して算出されたパワー評価値doKeyPowerを、他の区間長に対して得られている重なる区間のパワー評価値と比較することにより、その区間に対して現時点での最適な調を決定する。
CPU101はまず、楽曲を構成する全ての小節毎に、ステップS1302からS1304までの一連の処理を繰り返し実行する(ステップS1301)。以下、CPU101は、ステップS1301において、楽曲の先頭の小節の小節番号を0としてそこから順次カウントされるRAM103に記憶される変数である小節番号iの値として、各小節を順次指定する。
この繰返し処理で、CPU101はまず、図6のステップS602で指定される区間の開始小節番号から、それを含んで図6のステップS601で指定されている区間長分の現在の該当範囲の小節番号のグループに、小節番号iが含まれるか否かを判定する(ステップS1301)。
ステップS1302の判定がNOならば、CPU101は、ステップS1301の処理に戻り、次の小節番号に対する処理に移行する。
ステップS1302の判定がYESならば、CPU101は、図6のステップS603のキー判定処理(図9のフローチャートの処理)により、現在の該当範囲に対して算出されたパワー評価値doKeyPowerが、RAM103に記憶されている図2(b)のデータフォーマット例を有する調データにおいて、小節番号iに対応するポインタ情報tonality[i]から参照される調情報として記憶されているパワー評価値tonality[i].doPower以上であるか否かを判定する(ステップS1303)。
ステップS1303の判定がNOならば、CPU101は、ステップS1301の処理に戻り、次の小節番号に対する処理に移行する。
ステップS1303の判定がYESならば、CPU101は、小節番号iに対応するポインタ情報tonality[i]から参照される調情報において、調のキーtonality[i].iKeyに、図9のステップS910で算出されているパワー評価値最高キー値imaxkeyをセットする。また、CPU101は、調判定時のパワー評価値tonality[i].doPowerValueに、図9のステップS910で算出されているパワー評価値最高値doMaxをセットする。更に、CPU101は、調判定時の区間長tonality[i].iLengthに、図6のステップS601で指定されている図6のステップS601で指定されている現在の区間長をセットする(以上、ステップS1304)。ステップS1304の処理の後、CPU101は、ステップS1301の処理に戻り、次の小節番号に対する処理に移行する。
なお、RAM103に生成される図2(b)の調データは、図4のステップS404の曲データの読込み時に、読み込まれたMIDIシーケンスデータのノートイベントの存在範囲の値から、必要小節数分のポインタ情報及びそれらから参照される調情報が初期生成される。例えば4分の4拍子の楽曲であれば、前述したように1拍=480ティックとして、必要小節数N=(末尾のノートイベントの図2(a)の(lTime+lGate)値÷480÷4拍)が算出される。この結果、tonality[0]からtonality[N−1]までのポインタ情報と、そこから参照される図2(b)の調情報の構造体データが生成される。そして、各ポインタ情報tonality[i](0≦i≦N−1)から参照される構造体データにおいて、tonality[i].iKeyには無効値が初期設定される。tonality[i].doPowerValueには、例えばマイナス値が初期設定される。tonality[i].lTickには、(480ティック×4拍×i小節)のティック時刻値がセットされる。また、tonality[i].iMeasNoには、小節番号iがセットされる。なお、本実施形態では、tonality[i].iScaleは未使用である。
前述した図8の例において、図6のステップS601で指定されている区間長=1小節長(iFrameType=0)、ステップS602で指定されている区間の開始小節番号(図8(a)のiMeasNo)=0のときに、ステップS603でのキー判定処理の結果として、図8(c)に示されるように、パワー評価値最高キー値imaxkeyとしてピッチクラス=10(音名=B♭)が得られ、パワー評価値最高値doMaxとして3が得られている。この結果、図6のステップS604の結果保存処理における図13のフローチャートにおいて、小節番号i=0のときに、ステップS1302の判定がYESとなる。そして、ステップS1303の判定処理が実行されるが、このとき、tonality[0].doPowerValueの値はマイナスの初期値となっているため、パワー評価値最高値doMax=3のほうが大きくなり、ステップS1303の判定はYESとなる。この結果、ステップS1304において、tonality[0].iKey=imaxkey=10(音名B♭)、tonality[0].doPowerValue=doMax=3、tonality[0].iLength=1(小節長)がセットされる。
次に、前述した図8の例において、図6のステップS601で指定されている区間長=2小節長(iFrameType=1)、ステップS602で指定されている区間の開始小節番号(図8(a)のiMeasNo)=0のときに、ステップS603でのキー判定処理の結果として、図8(d)に示されるように、パワー評価値最高キー値imaxkeyとしてピッチクラス=10(音名=B♭)が得られ、パワー評価値最高値doMaxとして4が得られている。この結果、図6のステップS604の結果保存処理における図13のフローチャートにおいて、小節番号i=0のときに、ステップS1302の判定がYESとなる。そして、ステップS1303の判定処理が実行されるが、このとき、tonality[0].doPowerValue=3となっているため、パワー評価値最高値doMax=4のほうが大きくなり、ステップS1303の判定はYESとなる。この結果、ステップS1304において、tonality[0].iKey=imaxkey=10(同じ音名B♭)、tonality[0].doPowerValue=doMax=4、tonality[0].iLength=2(小節長)がセットされる。
更に、前述した図8の例において、図6のステップS601で指定されている区間長=4小節長(iFrameType=2)、ステップS602で指定されている区間の開始小節番号(図8(a)のiMeasNo)=0のときに、ステップS603でのキー判定処理の結果として、図8(e)に示されるように、パワー評価値最高キー値imaxkeyとしてピッチクラス=0(音名=C)が得られ、パワー評価値最高値doMaxとして7が得られている。この結果、図6のステップS604の結果保存処理における図13のフローチャートにおいて、小節番号i=0のときに、ステップS1302の判定がYESとなる。そして、ステップS1303の判定処理が実行されるが、このとき、tonality[0].doPowerValue=4となっているため、パワー評価値最高値doMax=7のほうが大きくなり、ステップS1303の判定はYESとなる。この結果、ステップS1304において、tonality[0].iKey=imaxkey=0(音名C)、tonality[0].doPowerValue=doMax=7、tonality[0].iLength=4(小節長)がセットされる。
以上のステップS1302からS1304の一連の処理の実行が、楽曲を構成する全ての小節番号iについて完了すると、CPU101は、図13のフローチャートで示される図6のステップS604の結果保存処理を終了する。
以上の例からわかるように、本実施形態では、複数の区間長(iFrameType)での調判定結果が総合的に判断されることにより、例えば転調が発生した場合、又は1小節だけではコードを判定するのに十分な発音がないような場合であっても、適切な調判定を行うことが可能となる。更に、本実施形態では、後述するようにパワー評価値を算出するときに、コードの和音の構成音以外の音についての配慮も行われるため、調判定の精度を維持することが可能となる。更に、本実施形態では、図9のステップS906とS907で、調の音階音に関わるの第1のパワー評価値lPowerと音階音以外の音に関わる第2のパワー評価値lOtherPowerが算出され、それらに基づいて調のキー値ikeyに対応するパワー評価値doKeyPowerが算出される。従って、調のキー値ikeyに関して、その音階音と音階音以外の音の両方に配慮したパワー評価を行うことができ、判定の精度を維持することが可能となる。
次に、上記詳述した図5のステップS501の調判定処理により、図2(b)の調データとして各小節毎に調が適切に判定された後、全ての小節毎(ステップS502)及び各小説内の全ての拍毎(ステップS503)に繰り返し実行されるステップS504のピッチクラスパワー作成処理と、ステップS505のマッチング&結果保存処理の詳細について、以下に説明する。
まず、図5のステップS504のピッチクラスパワー作成処理の詳細について説明する。ここでは、CPU101は、現在設定されている拍内でノートオンする楽曲のノートイベント毎に、そのノートイベントのベロシティとその拍内での発音時間長とに基づいて決定されるパワー情報値をそのノートのピッチに対応するピッチクラスに累算することにより、現在の拍におけるピッチクラス毎のパワー情報累算値を算出する。
図5のステップS504の詳細は、前述した図11のフローチャートで示される。前述した図9のステップS901の詳細処理である図11の説明では、「現在の該当範囲」は現在指定されている調判定のための小節区間であった、これに対して図5のステップS504の詳細処理である以下の図11の説明では、「現在の該当範囲」は図5のステップS502で指定される小節内のステップS503で指定される拍に対応する範囲である。更に、図12の該当範囲開始時刻lTickFromは、現在の拍の開始時刻である。前述したように、拍及び小節の時間単位としては、何れも前述したティックが使用され、1拍は一般的に480ティックで、4分の4拍子の楽曲の場合、1小節は4拍である。従って、例えば4分の4拍子の楽曲の場合では、楽曲の先頭を0小節目として図5のステップS502で指定される小節の小節番号をカウントした場合、その小節の開始時刻は(480ティック×4拍×小節番号)となり、更に、小節の先頭の拍を0として図5のステップS503で指定される拍の拍番号をカウントした場合、その拍の小節内での開始時刻は(480ティック×拍番号)となる。従って、該当範囲開始時刻lTickFrom=(480ティック×4拍×小節番号)+(480ティック×拍番号)=480×(4拍×小節番号+拍番号)として算出される。また、図12の該当範囲終了時刻lTickToは、現在の拍の終了時刻である。1拍は480ティックであるから、該当範囲終了時刻lTickTo=該当範囲開始時刻lTickFrom+480=480×(4拍×小節番号+拍番号+1)として算出される。
CPU101は、以上の置換えの後に図11のフローチャートの処理を動作させることにより、ステップS1111で、現在のノートイベントのピッチiPitchを12で除算したときの剰余(iPitch%12)として算出される現在のノートイベントに対応するピッチクラスにおけるピッチクラスパワーlPichClassPower[iPitch%12]に、以下の計算値を格納する。CPU101は、現在のノートイベントのベロシティとパート情報とから定まるベロシティ情報lPowerWeightに、現在のノートイベントの現在の拍の範囲における発音時間長(lTickEnd−lTickStart)を乗算した値として、上記ピッチクラスパワーlPichClassPower[iPitch%12]を算出する。このようにして、現在のノートイベントに対応するピッチクラスパワーlPichClassPower[iPitch%12]の値は、現在の拍の範囲内での現在のノートイベントの発音時間が長ければ長いほど、また発音の強さを示すベロシティが大きければ大きいほど、そして現在のノートイベントが属するパートに応じて、現在のノートイベントに対応するピッチクラス(iPitch%12)の音の現在の拍の範囲での構成割合が大きいことになる。
図14は、図5のステップS505のマッチング&結果保存処理の詳細例を示すフローチャートである。
次に、CPU101は、コードのルート(根音)を示す全てのirootの値0から11について、以下のステップS1402からS1413の一連の処理を実行する(ステップS1401)。更に、CPU101は、コードの種別を示す全てのコードタイプitypeの値について、以下のステップS1403からS1413の一連の処理を実行する(ステップS1402)。
ステップS1403からS1413の繰返し処理において、CPU101は始めに、共にRAM103に記憶される変数である第1のパワー評価値lPowerと第2のパワー評価値lOtherPowerの各値を0にクリアする(ステップS1403)。
次に、CPU101は、0から11までの値を有する全てのピッチクラスiPc毎に、以下のステップS1405からS1407の処理を実行する(ステップS1404)。
まず、CPU101は、ステップ1404で指定された現在のピッチクラスiPcが、ステップS1401及びステップS1402で指定された現在のコードルートiroot及びコードタイプitypeに基づいて定まるコードの構成音(コードトーン)に含まれるか否かを判定する(ステップS1405)。この判定は、「chordtone[itype][(12+iPc−iroot)%12]の値が1であるか否か」を判定する演算である。図15は、コードトーンの説明図である。図15において、(a)major、(b)minor、(c)7th、及び(d)minor7thの各行は、コードルートがピッチクラス=0(音名=C)である場合における、メジャーコード、マイナーコード、セブンスコード、及びマイナーセブンスコードの各コードタイプにおける構成音のピッチクラス及び音名を示している。各行で、値「1」が記載されているピッチクラス及び音名が、その行に対応するコードの構成音である。値「0」が記載されているピッチクラス及び音名は、その行に対応するコードの構成音でない音が比較対象とされる。図1のROM102は、コードルートがピッチクラス=0(音名=C)であるときの例えば図15(a)、(b)、(c)、及び(d)の各コードタイプitypeに対応する配列定数chordtone[itype][i]を記憶している。なお、実際には、itypeの種類は、図15に示される4種類より多い。ここで、iは図15の0から11までのピッチクラスの値をとり、配列要素値chordtone[itype][i]には、第1配列要素引数itypeに対応する図15(a)、(b)、(c)、又は(d)として例示される行の第2配列要素引数iに対応するピッチクラスiにおける値1又は0が格納されている。CPU101は、ステップS1405において、まず、第2配列要素引数として「(12+iPc−iroot)%12」の値を演算する。この演算では、ステップS1404で指定されているピッチクラスiPcとステップS1401で指定されているコードルートirootとの差分値が、どのピッチクラスになるかが算出されている。括弧内で12が加算されているのは「iPc−iroot」の値がマイナス値にならないようにするためである。また、「%」は、剰余を求める剰余演算を示している。CPU101は、この演算結果を第2配列要素引数とし、更にステップS1402で指定されているitypeを第1配列要素引数として、ROM102から読み出した配列要素値chordtone[itype][(12+iPc−iroot)%12]の値が1であるか否かを判定する。これにより、CPU101は、ステップS1404で指定されているピッチクラスiPcが、図15に例示されるコードルートがピッチクラス=0(音名=C)のときのコード構成音をコードルートがステップS1401で指定されているirootであるときのコード構成音に変換したときのitypeに対応する行のコード構成音に含まれているか否かを判定することができる。
ステップ1404で指定された現在のピッチクラスiPcが、ステップS1401で指定された現在のコードルートiroot及びステップS1402で指定された現在のコードタイプitypeに対応するコードの構成音に含まれている場合(ステップS1405の判定がYESの場合)には、CPU101は、そのピッチクラスiPcに対応して図5のステップS504で算出されているピッチクラスパワーlPichClassPower[iPc]を、第1のパワー評価値lPowerに累算する(ステップS1406)。
一方、ステップ1404で指定された現在のピッチクラスiPcが、ステップS1401で指定された現在のコードルートiroot及びステップS1402で指定された現在のコードタイプitypeに対応するコードの構成音にに含まれていない場合(ステップS1405の判定がNOの場合)には、CPU101は、そのピッチクラスiPcに対応して図5のステップS504で算出されているピッチクラスパワーlPichClassPower[iPc]を、第2のパワー評価値lOtherPowerに累算する(ステップS1407)。
CPU101は、0から11までの値を有する全てのピッチクラスiPcについて、上述のステップS1405からS1407の処理の実行を終えると(ステップS1404の判定結果が「終了」を示すと)、次の処理を実行する。CPU101は、ステップS1401及びS1402で現在指定されているコードルート及びコードタイプで定まるコードの構成音中で、図5のステップS502で現在指定されている小節に対して図5のステップS501の調判定処理で決定された調の音階音に含まれる音数を、その調の音階音の数で除算した値を、補正係数TNRとして算出する。即ち、CPU101は、下記(1)式で示される演算を実行する(ステップS1408)。
TNR=(コード構成音中で調の音階音に含まれる音数)÷(調の音階音数)
・・・(1)
より具体的には、CPU101は、図5のステップS502で現在指定されている小節の小節番号を引数として、RAM103に記憶されている図2(b)のデータフォーマットのポインタ情報tonality[小節番号]から図2(b)の調情報を参照する。これにより、CPU101は、上記小節に対応する調のキー値を、tonality[小節番号].iKeyとして取得する。そして、CPU101は、ROM102に記憶されているキー値がピッチクラス=0(音名=C)であるときの図10(d)の統合スケールscaleに対応する配列定数scale[i]の各i毎の音階音を、上記取得したキー値tonality[小節番号].iKeyに従って変換する。これにより、CPU101は、上記取得したキー値tonality[小節番号].iKeyに対応した統合スケールscaleの音階音の情報を得る。この音階音を、ステップS1401とS1402で現在指定されているコードルート及びコードタイプで定まるコードの構成音と比較することにより、上記(1)式を計算する。
例えば、調判定結果がハ長調のときの各コードの補正値は、下記のようになる。
G7:1、Bdim:1、Bdim7:0.75、Bm7♭5=1.0、
Ddim7=0.75、Fdim7=0.75
続いて、CPU101は、ステップS1408で算出した補正係数TNRをステップS1406で算出された第1のパワー評価値lPowerに乗算し、また、第2のパワー評価値lOtherPowerに所定の負の定数OPRを乗算し、両者の乗算結果を加算した結果で、第1のパワー評価値lPowerを置き換えることにより、ステップS1401とS1402で現在指定されているコードルート及びコードタイプで定まるコードに対応する新たなパワー評価値lPowerを算出する(ステップS1409)。
上述の(1)の補正係数TNRを介して、本実施形態では、図5のステップS501での調判定処理による小節毎の調判定の結果を、その小節内の拍毎のコード判定に反映させることが可能となり、精度の高いコード判定が実現される。
CPU101は、図3のコード進行データとして得られている現在の拍番号lCntに対応する全てのコード候補の数i(i=0、1、2、・・・)について、以下のステップS1411からS1413の一連の処理を繰り返し実行する(ステップS1410)。
この繰返し処理において、CPU101はまず、現在の拍番号lCntに対応する第i+1候補(i=0なら第1候補、i=1なら第2候補、i=2なら第3候補、・・・)のポインタ情報chordProg[lCnt][i]が参照する、コード情報内のパワー評価値chordProg[lCnt][i].doPowerValueを取得する。ここで、現在の拍番号lCntは、楽曲の先頭からの拍の通し番号であり、4分の4拍子の楽曲の場合、「lCnt=(4拍×ステップS502の小節番号)+(ステップS503の拍番号)」として算出される。そして、CPU101は、ステップS1409で算出したパワー評価値lPowerが、上記chordProg[lCnt][i].doPowerValueの値よりも大きいか否かを判定する(以上、ステップS1411)。
ステップS1411の判定がNOの場合、CPU101は、ステップS1410の処理に戻って、iをインクリメントした次のコード候補に対する処理に移行する。
ステップS1411の判定がYESの場合、CPU101は、第i+1番目以降のポインタ情報chordProg[lCnt][i+1]、chordProg[lCnt][i+2]、chordProg[lCnt][i+3]、・・・が参照するコード情報を、順次いままでひとつずつ順位が高かったコード情報を参照するように、参照関係をシフトする。そして、CPU101は、第i番目のポインタ情報chordProg[lCnt][i]が新たに参照するコード情報の保存場所をRAM103上に確保し、その保存場所に新たに判定されたコードに関するコード情報を図3に例示されるデータフォーマットで格納する。
このコード情報において、lTickには現在の小節(ステップS502で決定)内の現在の拍(ステップS503で決定)に対応する開始の時刻が格納される。これは、図5のステップS504のピッチクラスパワー作成処理の説明で前述した該当範囲開始時刻lTickFrom=480×(4拍×現在の小節番号+小節内の現在の拍番号)である。iMeasNoには現在の小節の楽曲の先頭の小節を第0小節としてカウントした現在の小節番号が格納される。iTickInMeasには、小節内の現在の拍に対応する開始のティック時刻が格納される。図2(b)の説明で前述したように、iTickInMeasは、1拍目に対応するティック値0、2拍目に対応するティック値480、3拍目に対応するティック値960、又は4拍目に対応するティック値1440の何れかの値となる。iRootとiTypeにはそれぞれ、ステップS1401で指定されている現在のコードルートiroot値と、ステップS1402で指定されている現在のコードタイプitypeが格納される。doPowerValueにはステップS1409で算出されたパワー評価値が格納される。その後、CPU101は、ステップS1410の処理に戻り、次のコード候補に対する処理に移行する。
全てのコード候補の数iに対する処理が完了すると(ステップS1410の判定結果が「終了」を示すと)、CPU101は、ステップS1402の処理に戻り、次のコードタイプitypeについての繰返し処理に移行する。
全てのコードタイプitypeに対する繰返し処理が完了すると(ステップS1402の判定結果が「終了」を示すと)、CPU101は、ステップS1401の処理に戻り、次のコードルートirootについての繰返し処理に移行する。
全てのコードルートirootに対する繰返し処理が完了すると(ステップS1401の判定結果が「終了」を示すと)、CPU101は、図14のフローチャートで例示された図5のステップS505のマッチング&結果保存処理を終了する。
次に、図5のステップS506の最小コスト計算処理と、ステップS507の経路確定処理の詳細について、以下に説明する。楽曲データに対するコードの判定において、実際の楽曲で使われるコード以外の音の影響や逆にコードの構成音が常に鳴っていない状況があったりで、従来、適切なコード判定ができない場合があった。例えば、「シレファ」だけの発音の場合、この音を構成音として持つコードは、G7、Bdim、Bdim7、Bm7♭5、Ddim7、Fdim7がある。また、「ド、ド#、レ、ミb、ミ」の発音の場合、これらの一部を構成音として持つコードは、Cadd9、Cmadd9、C#mM7などがある。これら複数のコードの候補がある場合にそのコードが存在する拍タイミングのピッチクラスのみから判定するのには困難があり、音楽的知識を使ったり時間軸上の変化要素を考慮するなどの工夫が考えられる。
一般的には、“sus4”“mM7”などは、前後のコードの連結について音楽的に自然なルールがある。例えば、“sus4”のコードの次のコードは、同じコードルートを有する場合が多い。また、“mM7”のコードの前後のコードは、同じコードルートを有し、マイナーコードである場合が多い。
そこで、本実施形態では、音楽的な連結規則に基づく2つのコード間の連結コストが定義される。そして、CPU101は、図5のステップS506において、楽曲の全ての小節及び小節内の全ての拍に対して図3に例示されるデータフォーマットで得られる複数候補からなるコード進行データの全ての組合せの中から、上記連結コストに基づいて楽曲全体でコストが最小となるコードの組合せを算出する。最小コストの計算には、例えばダイクストラ法などを利用することができる。
図16は、最小コスト計算処理と経路確定処理の説明図である。図16(a)は、最小コスト計算処理における経路最適化処理の説明図である。図16(b)は、最小コスト計算処理及び経路確定処理による経路最適化結果の説明図である。ステップS506における最小コスト計算処理による経路最適化処理は、拍タイミング毎にコードの候補がm個(例えば3個)あるとすると、mのコード数の拍数乗の組合せの中から、最小コストとなる経路を求める処理である。以下、m=3の場合を例に説明する。
いま、図16に示されるように、図3のコード進行データとして、各拍タイミングn−2、n−1、n、n+1、・・・毎に、第1候補から第3候補までの3候補ずつのコード候補が得られている。いま、拍タイミングnを現在の拍タイミングとし、この現在の拍タイミングが、RAM103に記憶される変数lChordIdxによって指定されるとする。また、現在の直前の拍タイミングn−1が、RAM103に記憶される変数lPrevChordIdxによって指定されるとする。更に、lChordIdxで指定される現在の拍タイミングnにおける各候補番号(0、1、又は2)が、RAM103に記憶される変数iCurChordによって指定されるとする。また、lPrevChordIdxで指定される現在の直前の拍タイミングn−1における各候補番号(0、1、又は2)が、RAM103に記憶される変数iPrevChordによって指定されるとする。
本実施形態の最小コスト計算処理では、いま、楽曲の先頭の拍タイミングからコードの発音が始まって、各拍タイミング毎にコード候補が選択されながら、現在の拍タイミングlChordIdxにおける現在の候補番号iCurChordの現在のコード候補が選択されて発音されるまでにかかるトータルコストを、RAM103に記憶される配列変数である最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[lChordIdx][iCurChord]と定義する。このコスト値は、現在の直前の拍タイミングlPrevChordIdxにおける3つのコード候補の各々と現在のコード候補との間の各連結コストに、その3つのコード候補の各々において算出されている各最適コードトータル最小コストをそれぞれ加算した各値が最小となる値として算出される。また、その最小値をとる現在の直前の拍タイミングlPrevChordIdxにおけるコード候補を、RAM103に記憶される配列変数である現在のコード候補への直前最適コードルートiOptimizeChordRoutePrev[lChordIdx][iCurChord]と定義する。CPU101は、図5のステップS506の最小コスト計算処理において、楽曲の先頭の拍タイミングから楽曲の進行に沿った拍タイミング毎に順次、上述の最小コスト計算処理を実行してゆく。
図17は、図5のステップS506の最小コスト計算処理の詳細例を示すフローチャートである。CPU101は、lChordIdx=1以降の全ての拍タイミングについて、現在の拍タイミングlChordIdxを指定しながら、ステップS1702からS1708までの一連の処理を繰り返し実行する(ステップS1701)。lChordIdx=0の場合は、それより手前に拍タイミングが存在しないため、計算を行わない。
次に、CPU101は、現在の直前の拍タイミングlPrevChordIdxに、現在の拍タイミングlChordIdxの値から1減算した値を格納する(ステップS1702)。
続いて、CPU101は、ステップS1701で指定される現在の拍タイミングlChordIdx毎に、全てのコード候補について現在の拍タイミングの候補番号iCurChordを指定しながら、ステップS1704からS1709までの一連の処理を繰り返し実行する(ステップS1703)。
更に、CPU101は、ステップS1703で指定される現在の拍タイミングの候補番号iCurChord毎に、全ての直前の拍タイミングのコード候補について直前の拍タイミングの候補番号iPrevChordを指定しながら、ステップS1705からS1708までの一連の処理を繰り返し実行する(ステップS1704)。
ステップS1705からS1709までの繰返し処理において、CPU101はまず、ステップS1704で指定された直前の拍タイミングの候補番号iPrevChordのコード候補からステップS1703で指定された現在の拍タイミングの候補番号iCurChordのコード候補に遷移するときの連結コストを計算し、その計算結果をRAM103に記憶される変数であるコストdoCostに格納する(ステップS1705)。
次に、CPU101は、コストdoCostに、ステップS1703で指定された直前の拍タイミングの候補番号iPrevChordのコード候補に対して保持されている最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[lPrevChordIdx][iPrevChord]の値を加算する(ステップS1706)。なお、現在の拍タイミングlChordIdx=1で現在の直前の拍タイミングlPrevChordIdx=0の場合における最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[0][iPrevChord](iPrevChord=0、1、2)の値は0である。
次に、CPU101は、ステップS1706で更新されたコストdoCostの値が、ステップS1703で指定された現在の拍タイミングの候補番号iCurChordに対して現在までに得られているRAM103に記憶される変数であるコスト最小値doMin以下であるか否かを判定する(ステップS1707)。なお、コスト最小値doMinの値は、CPU101が、ステップS1703で新たな現在の拍タイミングの候補番号iCurChordを指定するときに、大きな初期値に設定される。
ステップS1707の判定がNOならば、CPU101は、ステップS1704の処理に戻って、iPrevChordをインクリメントして、直前の拍タイミングの次の候補番号iPrevChordに対する処理に移行する。
ステップS1707の判定がYESならば、CPU101は、現在までのコスト最小値doMinにコストdoCostの値を格納し、RAM103に記憶される変数であるコスト最小直前コードiMinPrevChordに、ステップS1704で指定されている直前の拍タイミングの候補番号iPrevChordを格納する。更に、CPU101は、現在の拍タイミングlChordIdx及び現在の拍タイミングの候補番号iCurChordのコード候補に対応する最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[lChordIdx][iCurChord]に、コストdoCostの値を格納する(以上、ステップS1708)。その後、CPU101は、ステップS1704の処理に戻り、iPrevChordをインクリメントして、直前の拍タイミングの次の候補番号iPrevChordに対する処理に移行する。
以上のステップS1705からS1708までの一連の処理がステップS1704で順次指定される直前の拍タイミングの候補番号iPrevChord毎に実行され、全ての直前の拍タイミングの候補番号iPrevChord(=0、1、2)に対する処理が完了すると、CPU101は、次の処理を実行する。CPU101は、現在の拍タイミングlChordIdx及び現在の拍タイミングの候補番号iCurChordに対応する直前最適コードルートiOptimizeChordRoutePrev[lChordIdx][iCurChord]に、コスト最小直前コードiMinPrevChordの値を格納する。その後、CPU101は、ステップS1703の処理に戻り、iCurChordをインクリメントして現在の拍タイミングの次の候補番号iCurChordに対する処理に移行する。
以上のステップS1704からS1709までの一連の処理がステップS1703で順次指定される現在の拍タイミングの候補番号iCurChord毎に実行され、全ての現在の拍タイミングの候補番号iCurChord(=0、1、2)に対する処理が完了すると、CPU101は、ステップS1701の処理に戻り、lChordIdxをインクリメントして、次の拍タイミングlChordIdxに対する処理に移行する。
以上のステップS1702からS1709までの一連の処理がステップS1701で順次指定される現在の拍タイミングlChordIdx毎に実行され、全ての現在の拍タイミングlChordIdxに対する処理が完了すると、CPU101は、図17のフローチャートで示される図5のステップS506の最小コスト計算処理を終了する。
図18は、図17のステップS1705のコスト計算処理の詳細例を示すフローチャートである。CPU101はまず、現在の拍タイミングlChordIdx及び現在の拍タイミングの候補番号iCurChordに対応してRAM103に記憶されているコード情報(図3参照)へのポインタ情報chordProg[lChordIdx][iCurChord]の値をRAM103に記憶される変数である現在ポインタcurに格納する(ステップS1801)。
CPU101は同様に、現在の直前の拍タイミングlPrevChordIdx及び直前の拍タイミングの候補番号iPrevChordに対応してRAM103に記憶されているコード情報へのポインタ情報chordProg[lPrevChordIdx][iPrevChord]の値をRAM103に記憶される変数である直前ポインタprevに格納する(ステップS1802)。
次に、CPU101は、連結コストdoCostの値を、0.5に初期設定する(ステップS1803)。
次に、CPU101は、現在の拍タイミングlChordIdxの候補番号iCurChordのコード情報のコードルートcur.iRoot(図3参照)に12を加算した後に、現在の直前の拍タイミングlPrevChordIdxの候補番号iPrevChordのコード情報のコードルートprev.iRootを減算し、その結果を12で除算したときの剰余値が5であるか否かを判定する(ステップS1804)。
ステップS1804の判定がYESの場合は、現在の直前の拍タイミングlPrevChordIdxの候補番号iPrevChordのコード候補から、現在の拍タイミングlChordIdxにおける候補番号iCurChordのコード候補への遷移は、音程差が5度のとても自然なコード遷移である。従って、この場合には、CPU101は、連結コストdoCostの値を最も良い値である最低値0.0に設定する(ステップS1805)。
ステップS1804の判定がNOの場合は、CPU101は、ステップS1805の処理はスキップし、連結コストdoCostの値は0.5のままとなる。
次に、CPU101は、現在の直前の拍タイミングlPrevChordIdxの候補番号iPrevChordのコード情報のコードタイプprev.iType(図3参照)が“sus4”であって、かつ、そのコード情報のコードルートprev.iRootと、現在の拍タイミングlChordIdxの候補番号iCurChordのコード情報のコードルートcur.iRootとが同じであるか否かを判定する(ステップS1806)。
ステップS1806の判定がYESの場合は、「“sus4”のコードの次のコードは同じコードルートを有する場合が多い」という音楽ルールに良く合っており、とても自然なコード遷移である。従って、この場合には、CPU101は、連結コストdoCostの値を最も良い値である最低値0.0に設定する(ステップS1807)。
ステップS1806の判定がNOの場合には、かなり不自然なコード遷移になるため、この場合には、CPU101は、連結コストdoCostの値を悪い値1.0に設定する(ステップS1808)。
次に、CPU101は、現在の直前の拍タイミングlPrevChordIdxの候補番号iPrevChordのコード情報のコードタイプprev.iTypeが“mM7”であって、かつ、現在の拍タイミングlChordIdxの候補番号iCurChordのコード情報のコードタイプcur.iTypeが“m7”であって、なおかつ、両方のコード情報のコードルートprev.iRootとcur.iRootとが同じであるか否かを判定する(ステップS1809)。
ステップS1809の判定がYESの場合も、音楽ルールに良く合っていてとても自然なコード遷移であるため、この場合も、CPU101は、連結コストdoCostの値を最も良い値である最低値0.0に設定する(ステップS1810)。
ステップS1809の判定がNOの場合には、かなり不自然なコード遷移になるため、この場合には、CPU101は、連結コストdoCostの値を悪い値1.0に設定する(ステップS1811)。
更に、CPU101は、現在の直前の拍タイミングlPrevChordIdxの候補番号iPrevChordのコード情報のコードタイプprev.iTypeが“maj”であって、かつ、現在の拍タイミングlChordIdxの候補番号iCurChordのコード情報のコードタイプcur.iTypeが“m”であって、なおかつ、両方のコード情報のコードルートprev.iRootとcur.iRootとが同じであるか否かを判定する(ステップS1812)。
ステップS1812の判定がYESの場合は、不自然なコード遷移になるため、CPU101は、連結コストdoCostに悪い値1.0を設定する(ステップS1813)。
ステップS1812の判定がNOの場合は、CPU101は、ステップS1813の処理はスキップする。
最後に、CPU101は、連結コストdoCostに、1から現在の拍タイミングlChordIdxの候補番号iCurChordのコード情報のパワー評価値cur.doPowerValueを減算した結果と、1から現在の直前の拍タイミングlPrevChordIdxの候補番号iPrevChordのコード情報のパワー評価値prev.doPowerValueを減算した結果とを乗算して、連結コストdoCostの値を調整する(ステップS1814)。その後、CPU101は、図18のフローチャートで示される図17のステップS1705のコスト計算処理を終了する。
図16(b)には、説明の簡単化のために、候補数を2、拍タイミングを0、1、2、3のみとした場合における、上述の図17の最小コスト計算処理による最小コスト計算結果の例を示してある。図16(b)において、大きな丸印は判定されたコード候補を示している。また、丸印間を連結する直線矢印付近に記載された数値は、その直線矢印の始点の丸印のコード候補から終点の丸印のコード候補への連結コストdoCostを示している。拍タイミング=0では、Cmajが第1コード候補、Cmが第2コード候補として判定されたとする。拍タイミング=1では、Amが第1コード候補、AmM7が第2コード候補として判定されたとする。拍タイミング=2では、Dmが第1コード候補、Dsus4が第2コード候補として判定されたとする。そして、拍タイミング=3では、G7が第1コード候補、Bdimが第2コード候補として判定されたとする。
図17の最小コスト計算処理において、まず、現在の拍タイミングlChordIdx=1で、候補番号iCurChord=0(第1候補)の場合、現在のコード候補として”Am”が得られている。この場合、現在の直前の拍タイミングlPrevChordIdx=0において、候補番号iPrevChord=0(第1候補)の直前のコード候補“Cmaj”から現在のコード候補”Am”への連結コストdoCostは、図18のフローチャートのアルゴリズムにより0.5と計算される。また、候補番号iPrevChord=1(第2候補)の直前のコード候補“Cm”から現在のコード候補”Am”への連結コストdoCostも、図18のフローチャートのアルゴリズムにより0.5と計算される。直前のコード候補“Cmaj”及び“Cm”の各最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[0][0/1]は、共に0である。図17のステップS1707では、連結コストdoCostとコスト最小値doMinが同値の場合にはあとのコード候補が優先される。従って、現在のコード候補“Am”の最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[1][0]は、“Am”の丸印の内部に示されるように0.5と計算される。また、現在のコード候補“Am”に対する直前最適コードルートiOptimizeChordRoutePrev[1][0]としては、“Am”の丸印に入力する太線矢印として示されるように直前のコード候補“Cm”が設定される。
現在の拍タイミングlChordIdx=1で、候補番号iCurChord=1(第2候補)の場合のコード候補”AmM7”についても同様の計算が実行される。現在のコード候補“AmM7”の最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[1][1]は、“AmM7”の丸印の内部に示されるように0.5と計算される。また、現在のコード候補“AmM7”に対する直前最適コードルートiOptimizeChordRoutePrev[1][1]としては、“AmM7”の丸印に入力する太線矢印として示されるように直前のコード候補“Cm”が設定される。
次に、現在の拍タイミングが1つ進んでlChordIdx=2となり、候補番号iCurChord=0(第1候補)の場合、現在のコード候補として“Dm”が得られている。この場合、現在の直前の拍タイミングlPrevChordIdx=1において、候補番号iPrevChord=0(第1候補)の直前のコード候補“Am”から現在のコード候補”Dm”への連結コストdoCostは、図18のフローチャートのアルゴリズムにより0.0と計算される。また、候補番号iPrevChord=1(第2候補)の直前のコード候補“AmM7”から現在のコード候補”Dm”への連結コストdoCostは、図18のフローチャートのアルゴリズムにより1.0と計算される。直前のコード候補“Am”及び“AmM7”の各最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[1][0/1]は、共に0.5である。従って、直前のコード候補“Am”から現在のコード候補”Dm”への図17のステップS1706で修正されたコストdoCostの値は0.5+0.0=0.5となる。同様に、直前のコード候補“AmM7”から現在のコード候補”Dm”への修正されたコストdoCostの値は0.5+1.0=1.5となる。従って、現在のコード候補“Dm”の最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[2][0]は、“Dm”の丸印の内部に示されるように0.5と計算される。また、現在のコード候補“Dm”に対する直前最適コードルートiOptimizeChordRoutePrev[2][0]としては、“Dm”の丸印に入力する太線矢印として示されるように直前のコード候補“Am”が設定される。
現在の拍タイミングlChordIdx=2で、候補番号iCurChord=1(第2候補)の場合のコード候補”Dsus4”についても同様の計算が実行される。現在のコード候補“Dsus4”の最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[2][1]は、“Dsus4”の丸印の内部に示されるように0.5と計算される。また、現在のコード候補“Dsus4”に対する直前最適コードルートiOptimizeChordRoutePrev[2][1]としては、“Dsus4”の丸印に入力する太線矢印として示されるように直前のコード候補“Am”が設定される。
次に、現在の拍タイミングが更に1つ進んでlChordIdx=3となり、候補番号iCurChord=0(第1候補)の場合、現在のコード候補として“G7”が得られている。この場合、現在の直前の拍タイミングlPrevChordIdx=2において、候補番号iPrevChord=0(第1候補)の直前のコード候補“Dm”から現在のコード候補”G7”への連結コストdoCostは、図18のフローチャートのアルゴリズムにより0.0と計算される。また、候補番号iPrevChord=1(第2候補)の直前のコード候補“Dsus4”から現在のコード候補”G7”への連結コストdoCostは、図18のフローチャートのアルゴリズムにより1.0と計算される。直前のコード候補“Dm”及び“Dsus4”の各最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[2][0/1]は、共に0.5である。従って、直前のコード候補“Dm”から現在のコード候補“G7”への修正されたコストdoCostの値は0.5+0.0=0.5となる。同様に、直前のコード候補“Dsus4”から現在のコード候補“G7”への修正されたコストdoCostの値は0.5+1.0=1.5となる。従って、現在のコード候補“G7”の最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[3][0]は、“G7”の丸印の内部に示されるように0.5と計算される。また、現在のコード候補“G7”に対する直前最適コードルートiOptimizeChordRoutePrev[3][0]としては、“G7”の丸印に入力する太線矢印として示されるように直前のコード候補“Dm”が設定される。
現在の拍タイミングlChordIdx=3で、候補番号iCurChord=1(第2候補)の場合のコード候補”Bdim”についても同様の計算が実行される。現在のコード候補“Bdim”の最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[3][1]は、“Bdim”の丸印の内部に示されるように1.0と計算される。また、現在のコード候補“Bdim”に対する直前最適コードルートiOptimizeChordRoutePrev[3][1]としては、“Bdim”の丸印に入力する太線矢印として示されるように直前のコード候補“Dm”が設定される。
次に、図5のステップS507の経路確定処理について説明する。経路確定処理において、CPU101は、末尾の拍タイミングから先頭の拍タイミングに逆方向に向かって、拍タイミングlChordIdx毎及び候補番号iCurChord毎のコード候補について算出された最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[lChordIdx][iCurChord]の小さい値を探しながら、また、直前最適コードルートiOptimizeChordRoutePrev[lChordIdx][iCurChord]を辿りながら、拍タイミング毎にコード候補を選択してゆき、選択されたコード候補を第1候補に置き換えていく。
図16(b)の例では、まず、末尾の拍タイミングlChordIdx=3において、最適コードトータル最小コストの値が最小値0.5である候補番号iCurChord=0のコード候補“G7”が選択され、lChordIdx=3における第1候補とされる。次に、lChordIdx=3で第1候補となったコード候補“G7”に設定されている直前最適コードルートiOptimizeChordRoutePrev[3][0]が参照されることにより、1つ手前の拍タイミングlChordIdx=2において、候補番号iCurChord=0のコード候補 “Dm”が選択され、lChordIdx=2における第1候補とされる。続いて、lChordIdx=2で第1候補となったコード候補“Dm”に設定されている直前最適コードルートiOptimizeChordRoutePrev[2][0]が参照されることにより、1つ手前の拍タイミングlChordIdx=1において、候補番号iCurChord=0のコード候補 “Am”が選択され、lChordIdx=1における第1候補とされる。最後に、lChordIdx=1で第1候補となったコード候補“Am”に設定されている直前最適コードルートiOptimizeChordRoutePrev[1][0]が参照されることにより、1つ手前の先頭の拍タイミングlChordIdx=0において、候補番号iCurChord=1のコード候補 “Cm”が選択され、lChordIdx=0における第1候補とされる。以上の経路確定処理の結果、楽曲の先頭の拍タイミングから順次、各拍タイミングの第1候補のコード候補“Cm”、“Am”、 “Dm”、及び “G7”が最適なコード進行として選択され、表示手段105等に表示される。
図19は、図5のステップS507の経路確定処理の詳細例を示すフローチャートであり、上述した動作を実現する。CPU101はまず、全ての拍タイミングについて、末尾の拍タイミングから先頭の拍タイミングに向かって、現在の拍タイミングlChordIdxをディクリメントしながら指定してゆき、lChordIdx毎に、ステップS1902からS1906までの一連の処理を繰り返し実行する(ステップS1901)。
ステップS1902からS1906までの一連の繰返し処理において、CPU101はまず、終端コードがあるか否か、即ち末尾の拍タイミングを指定しているか否かを判定する(ステップS1902)。
次に、CPU101は、ステップS1901で指定される末尾の拍タイミングlChordIdxについて、全てのコード候補について末尾の拍タイミングの候補番号iCurChordを指定しながら、ステップS1904からS1906までの一連の処理を繰り返し実行する(ステップS1903)。この処理は、図16(b)で説明したように、末尾の拍タイミングlChordIdxにおいて、最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[lChordIdx][iCurChord]の値が最小となる候補番号iCurChordを探索する処理である。
ステップS1904からS1906までの一連の繰返し処理において、CPU101は、ステップS1901で指定されているlChordIdxとステップS1903で指定されているiCurChordに対応する最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[lChordIdx][iCurChord]の値が、RAM103に記憶されている変数であるコスト最小値doMin以下である否かを判定する(ステップS1904)。コスト最小値doMinの値は、図19のフローチャートの処理の開始時に大きな値に初期設定されている。
ステップS1904の判定がNOならば、CPU101は、ステップS1903の処理に戻り、iCurChordをインクリメントして、次の候補番号iCurChordに対する処理に移行する。
ステップS1904の判定がYESになると、CPU101は、コスト最小値doMinに、ステップS1901で指定されているlChordIdxとステップS1903で指定されているiCurChordに対応する最適コードトータル最小コストdoOptimizeChordTotalMinimalCost[lChordIdx][iCurChord]の値を格納する(ステップS1905)。
そして、CPU101は、RAM103に記憶される変数である最適コード候補番号iChordBestに、ステップS1903で現在指定されているiCurChordの値を格納する(ステップS1906)。その後、CPU101は、ステップS1903の処理に戻り、iCurChordをインクリメントして、次の候補番号iCurChordに対する処理に移行する。
以上のようにして、ステップS1904からS1906の一連の処理の実行がiCurChordとして指定される全ての候補番号について完了すると、CPU101は、ステップS1908の処理に移行する。この状態において、最適コード候補番号iChordBestに、末尾の拍タイミングにおいて、最適コードトータル最小コストが最小となるコード候補の候補番号が得られている。ステップS1908において、CPU101は、現在の末尾の拍タイミングlChordIdxと最適コード候補番号iChordBestに対応するコード情報のコードルートchordProg[lChordIdx][iChordBest].iRootの値を、現在の末尾の拍タイミングlChordIdxの第1候補のコード情報のコードルートchordProg[lChordIdx][0].iRootに格納する(ステップS1908)。
次に、CPU101は、現在の末尾の拍タイミングlChordIdxと最適コード候補番号iChordBestに対応するコード情報のコードタイプchordProg[lChordIdx][iChordBest].iTypeの値を、現在の末尾の拍タイミングlChordIdxの第1候補のコード情報のコードタイプchordProg[lChordIdx][0].iTypeに格納する(ステップS1909)。
その後、CPU101は、現在の末尾の拍タイミングlChordIdxと最適コード候補番号iChordBestに対応するコード候補の直前最適コードルートiOptimizeChordRoutePrev[lChordIdx][iChordBest]の値を、直前の拍タイミングの候補番号iPrevChordに格納する(ステップS1910)。そして、CPU101は、ステップS1901の処理に戻り、lChordIdxをデクリメントして、1つ手前の拍タイミングlChordIdxに対応する処理に移行する。
末尾から手前の拍タイミングになると、ステップS1902の判定がNOとなる。この結果、CPU101は、ステップS1910で直前の拍タイミングの候補番号iPrevChordに格納されている直前最適コードルートを、最適コード候補番号iChordBestに格納する(ステップS1907)。
続いて、CPU101は、前述したステップS1908、S1909を実行することにより、現在の拍タイミングlChordIdxと最適コード候補番号iChordBestに対応するコード情報のコードルートchordProg[lChordIdx][iChordBest].iRootとコードタイプchordProg[lChordIdx][iChordBest].iTypeの各値を、現在の拍タイミングlChordIdxの第1候補のコード情報のコードルートchordProg[lChordIdx][0].iRootとコードタイプchordProg[lChordIdx][0].iTypeに格納する。
その後、CPU101は、現在の末尾の拍タイミングlChordIdxと最適コード候補番号iChordBestに対応するコード候補の直前最適コードルートiOptimizeChordRoutePrev[lChordIdx][iChordBest]の値を、直前の拍タイミングの候補番号iPrevChordに格納する(ステップS1910)。そして、CPU101は、再びステップS1901の処理に戻り、lChordIdxをデクリメントして、1つ手前の拍タイミングlChordIdxに対応する処理に移行する。
以上の処理が、拍タイミングlChordIdx毎に繰り返し実行されることにより、各拍タイミングlChordIdxの第1候補のコード情報のコードルートchordProg[lChordIdx][0].iRootとコードタイプchordProg[lChordIdx][0].iTypeとして、最適なコード進行を出力することができる。
以上説明した図5のステップS506の最小コスト計算処理では、コードの連結規則を使うので、複数候補が出てきたときに、より自然なコード判定結果を得ることが可能となる。
以上説明した実施形態により、転調も適切に判定できる調判定の結果からより適切なコード判定を行うことが可能となる。
以上説明した実施形態では、楽曲データ例として、MIDIシーケンスデータからのコード判定について説明したが、音楽音響信号からのコード判定を行ってもよい。その場合は、高速フーリエ変換などの音響分析を行うことにより、ピッチクラスパワーを求めることになる。
以上の実施形態に関して、更に以下の付記を開示する。
(付記1)
処理部を有するコード解析装置であって、前記処理部は、
楽曲の部分毎に、複数のコード候補を判定するコード判定手段と、
連続する部分間の前記コード候補同士の連結コストを計算する連結コスト計算手段と、
前記楽曲において、前記コード候補間の前記連結コストの総和が最小となる経路を決定し、前記決定した経路に従って前記部分毎の最適なコード候補を出力する最適コード候補選択手段と、
を有するコード解析装置。
(付記2)
前記連結コスト計算手段は、前記連続するコード候補間のコードルートとコードタイプの音楽的な遷移規則に基づいて、前記連結コストを計算する、付記1に記載のコード解析装置。
(付記3)
前記最適コード候補選択手段は、前記楽曲の先頭から順次進む前記部分毎に、現在の部分のコード候補毎に、前記現在の部分のコード候補に、前記現在の部分の直前の部分の各コード候補から遷移する遷移コストを、前記直前の部分の各コード候補と前記現在の部分のコード候補とに対して前記連結コスト計算手段により算出される各連結コストと、前記直前の部分の各コード候補に対してそれぞれ算出されているトータル最小コストとの和として算出し、前記現在の部分の直前の部分の各コード候補のうち前記遷移コストが最小のコード候補を前記現在の部分のコード候補への直前最適コード経路として算出し、前記最小の遷移コストを前記現在の部分のコード候補に対応する前記トータル最小コストとして算出する、付記1又は2に記載のコード解析装置。
(付記4)
前記最適コード候補選択手段は、前記楽曲の末尾の部分の各コード候補のうち、当該コード候補に対して算出されている前記トータル最小コストが最小となるコード候補を、前記末尾の部分の最適コード候補として選択し、当該最適コード候補を起点として、前記楽曲の末尾の部分から先頭の部分に向かって前記直前最適コード経路を順次辿ることによって、前記楽曲の各部分に対応する最適コード候補を順次選択する、付記3に記載のコード解析装置。
(付記5)
楽曲を入力して解析する処理部を有するコード解析装置において、前記処理部が、
前記楽曲の部分毎に、複数のコード候補を判定し、
規則に基づいて連続する前記コード候補間の連結コストを計算し、
前記部分毎に前記複数のコード候補からコード候補を選択する選択経路の組合せの中から、選択される前記コード候補間の前記連結コストの総和が最小となる選択経路を決定し、前記決定した選択経路に従って前記部分毎の最適なコード候補を出力する、
処理を実行するコード解析方法。
(付記6)
楽曲を入力して解析するコンピュータに、
前記楽曲の部分毎に、複数のコード候補を判定するステップと、
規則に基づいて連続する前記コード候補間の連結コストを計算するステップと、
前記部分毎に前記複数のコード候補からコード候補を選択する選択経路の組合せの中から、選択される前記コード候補間の前記連結コストの総和が最小となる選択経路を決定し、前記決定した選択経路に従って前記部分毎の最適なコード候補を出力するステップと、
を実行させるためのプログラム。