以下、本発明を実施するための形態について図面を参照しながら詳細に説明する。以下に説明する実施形態では、複数音を同時発音する音源と、音源コマンドバッファから、音源の制御に関する複数の音源コマンドを読み出して実行する処理部とを備えた電子鍵盤楽器等において、音源コマンドが音源コマンドバッファに書き込まれてから、音源コマンドが音源コマンドバッファから読み出されるまでの差分時間に応じて、音源における同時発音数が制御される。CPUの負荷をほぼリアルタイムで計測した結果に基づいて同時発音数が制御されるため、CPUパワーの不足で大きな遅延が発生して演奏に支障を来したり、不要な制限でCPU能力を持て余したりすることなく、CPUの能力を常に100%に近い形で引き出すことが可能となる技術である。
図1は、本発明による電子鍵盤楽器100の一実施形態の外観例を示す図である。電子鍵盤楽器100は、演奏操作子としての複数の鍵からなる鍵盤101と、音色選択や音色以外の各種機能選択を行うスイッチ・パネル102と、ピッチベンダーホイール103と、ピッチモジュレーションホイール104、特には図示しないサスティーンペダル、各種設定情報を表示するLCD(Liquid Crystal Display:液晶ディスプレイ)105等を備える。また、電子鍵盤楽器100は、特には図示しないが、演奏により生成された楽音を放音するスピーカを裏面部、側面部、又は背面部等に備える。
図2は、図1の電子鍵盤楽器100の制御システム200の一実施形態のハードウェア構成例を示す図である。図2において、電子鍵盤楽器100は、CPU(中央演算処理装置)201、ROM(リードオンリーメモリ)202、RAM(ランダムアクセスメモリ)203、タイマ204、波形ROM206が接続される音源LSI(大規模集積回路)205、図1の鍵盤101と図1のスイッチ・パネル102とが接続されるキースキャナ207、図1のピッチベンダーホイール103とピッチモジュレーションホイール104がそれぞれ接続される個別のA/Dコンバータ208、及び図1のLCD105が接続されるLCDコントローラ209が、それぞれシステムバス212に接続される構成を備える。また、音源LSI205から出力されるデジタル楽音波形データは、D/Aコンバータ210によりアナログ楽音波形信号に変換され、アンプ211で増幅された後に、特には図示しないスピーカ又は出力端子から出力される。
CPU201は、RAM203をワークメモリとして使用しながらROM202に記憶された制御プログラムを実行することにより、図1の電子鍵盤楽器100の制御動作を実行する。また、ROM202は、上記制御プログラム及び各種固定データを記憶する。
CPU201には、本実施形態で使用するタイマが2系統接続タイマ1 204a及びタイマ2 204bとして実装されており、これによって、レスポンスタイムコマンドの発行、及びレスポンスタイムの計測をする。タイマ1 204a及びタイマ2 204bはいずれも16ビットのカウンタであり、1μ(マイクロ)秒ごとにインクリメントする。
タイマ1 204aは、レスポンスタイムの計測用でありそのカウンタ値がFFFFH(「H」は16進数を示す)の次は0000Hに戻るという動作を繰り返すフリーランニングタイマである。従って、約66ミリ秒までしか計測できないが、本実施形態ではそれ以上の長時間をレスポンスタイムとして想定していないので、問題はない。
タイマ2 204bは、定期的にレスポンス計測用コマンドを発行するための割込み処理を起動するために使われる。本実施形態では、例えば25ミリ秒に1回タイマ割込みを発生するように設定される。
音源LSI205は、波形ROM206から波形を読み出し、D/Aコンバータ210に出力する。音源LSI205は、同時に最大256ボイスを発振させる能力を有する。
キースキャナ207は、鍵盤101(図1)とスイッチ・パネル102の操作ボタン状態を定常的に走査し、CPU201に割り込みを掛けて状態変化を伝える。
3つのA/DコンバータからなるA/Dコンバータ208には、本体の演奏操作子であるピッチベンダーホイール103、モジュレーションホイール104、及び特には図示しないサスティーンペダルが接続され、変化をCPU201に知らせる。CPU201は、A/Dコンバータ208の現在値を読みに行くことで、その時点の操作子の状態を知る。
LCDコントローラ209は、LCD105を制御するIC(集積回路)である。
図1及び図2の構成例を有する本実施形態の動作について、以下に詳細に説明する。本実施形態では、音源LSI205を制御する信号源として鍵盤101の演奏、音色変更のためのスイッチ・パネル102の操作、ピッチベンダーホイール103、モジュレーションホイール104、サスティーンペダルといったコントローラの操作がある。これらの手段によって発生した演奏信号は音源LSI205に送られる。
発生した演奏情報を音源LSI205に伝える手段としては、共通の音源コマンドバッファで情報を仲介し、ここに積まれた情報を音源処理プログラムが解釈して発音、消音、ピッチ変更、モジュレーション変更、音色変更が実行される。この音源コマンドバッファは、いわゆるリングバッファの形態をとり、音源制御情報を発生する各プログラムが同じ音源コマンドバッファにデータを積んでいき、音源処理プログラムによってのみ読み出される。なお、前述した従来技術でいうリングバッファとは異なるものである。
例えば、鍵盤101の演奏操作がキースキャナ207によって検知されると、キースキャナーインタラプトルーチンの割込みによって、鍵盤101の演奏に基づいて発生するキースキャナイベントに対応するMIDIメッセージが、音源コマンドバッファに書き込まれる。
本実施形態では、上記の信号源に加え、レスポンス計測用のタイマインタラプトルーチンが、タイマ2 204bからの25ミリ秒間隔の割込みによって、定期的に起動している。これは、上述の音源コマンドバッファにレスポンス計測用コマンドを書き込むためのルーチンである。このレスポンス計測用コマンドには、それが音源コマンドバッファに書き込まれるときに、タイマ1 204aのタイマ値がタイマ時刻として記録される。そして、このレスポンス計測用コマンドが音源コマンド処理によって読み出されるときに、その時点のタイマ1 204aが示すタイマ時刻(タイマ値)と、レスポンス計測用コマンドに記録されているタイマ時刻との差分時間がレスポンスタイムとして算出される。
このレスポンスタイムは状況によって毎回変動するが、単発的な処理の増減で急激な最大発音数の変化を発生させないように現在の同時最大発音数を徐々に増減させる処理が行われる。この背景としては、音色に依存して1音の処理のCPU負荷が異なったり、その他の機能の処理内容によっても最大発音数としての適正値が異なるため判断基準が一定にならないためである。つまり音色の種類によっては同時発音数150としても、もっと制限しないと改善が見込めないケース200としても、まだ演奏に支障がないというケースもありうる。そこで、現在のレスポンスタイムと基準になるレスポンスタイムとを比較し、その差異に応じて同時発音数を増減させる実測方式が、より効率的、現実的であると考えられる。勿論、その可変範囲は0になることはなく、最大同時発音数を超えることもない。
本実施形態では、レスポンスタイムに対応する同時発音数増減値が、ROM203に記憶されている図4(a)で後述するレスポンスタイム−同時発音数増減値対応テーブルを参照して取得され、同時発音数が制御される。これらの具体的な時間や数に関しては、後述する。
酢このような処理によって同時発音数が変化した結果、現在の実際の発音数を下回った場合は、優先度の低いオシレータから消音処理が実行される。この消音処理は、聴感上目立たないように、比較的緩やかなレートで消音するスローダンプ処理として実行される。また、その後レスポンスタイムが改善し、同時発音数が増えたとしても、消音したものを復帰させることは行わない。
以上の同時発音数の制御方式に基づく、本実施形態の具体的な処理について、以下に説明する。図3は本実施形態で使用される代表的な定数及び変数の一覧表を示す図である。図3(a)は、ROM203に記憶される代表的な定数として、レスポンスタイム−同時発音数増減値対応テーブルのデータRES_TIME_TBLのデータフォーマットを示す図である。このテーブルでは、図4(a)に示されるように、11種類のレスポンスタイムレンジ最大値(μ秒)RES_TIME_TBL[0].RANGE_TOP〜RES_TIME_TBL[10].RANGE_TOP毎に、同時発音数増減値RES_TIME_TBL[0].DIFF〜RES_TIME_TBL[10].DIFFが定義されている。
図3(b)は、RAM202に一時的に記憶される各種変数のデータフォーマットが示されている。これらについては、フローチャートの説明において後述する。
図4(b)は、音源コマンドバッファに記憶される各種コマンドのデータフォーマットを示す。音源コマンドバッファには、1つのコマンドが常に4バイトで記憶される。コマンドの種類は、最下位バイト側の第1バイト(bit0−7:第0〜第7ビット)で判断される。
鍵盤101の演奏、スイッチ・パネル102の操作、各種コントローラ(ピッチベンダーホイール103、モジュレーションホイール104、サスティーンペダル等)の操作に対応するMIDIメッセージコマンドは、第1バイトに値01Hが格納され、第2バイト(bit8−15:第8〜第15ビット)、第3バイト(bit16−23:第16〜第23ビット)、第4バイト(bit24−31:第24〜第31ビット)にMIDIメッセージコマンドMIDI[0]、MIDI[1]、MIDI[2]が格納される。
レスポンス計測用コマンドでは、第1バイトに値02H、第2バイトに値00Hが格納され、第3バイトにタイマ時刻値下位バイトTimeLSB、第4バイトにタイマ時刻値上位バイトTimeMSBが格納される。
音源リセットコマンドでは、第1バイトに値03H、第2〜第4バイトに値00Hが格納される。また、無効データは、第1バイトの値が00H、若しくは04H〜FFHの値の場合である。
図4(c)は、演奏情報のデータフォーマットを示す図である。Note on(ノートオン:押鍵)、Note off(ノートオフ:離鍵)、Modulation(モジュレーションホイール104の操作)、Hold pedal(サスティーンペダルの操作)、Program change(プログラムチェンジ)、Pitch bender change(ピッチベンダーホイール103の操作)毎に、MIDIメッセージコマンド値MIDI[0]、MIDI[1]、MIDI[2]の値がそれぞれ定義される。
図5は、本実施形態における電子楽器の制御処理例を示すメインフローチャートである。この処理は、図2のCPU201が、ROM203に記憶された制御プログラムを実行する処理として実現される。ここでの処理は、大きく分けて以下の5つから構成される。
初期化処理(ステップS501):電源投入時のみ実行される。
ユーザインターフェース処理(ステップS502):操作監視、設定変更、表示の処理である。音色切替えの処理を含む。
コントローラA/D処理(ステップS503):ピッチベンダーホイール103、ピッチモジュレーションホイール104、サスティーンペダルの状態監視とMIDIメッセージコマンドの発行(音源コマンドバッファへの書込み)の処理である。
音源コマンド処理(ステップS504):音源のコマンドバッファに積まれた音源コマンドを解析して順番に処理する。
音源定常サービス処理(ステップS505):ボイスの発音状態の制御処理等である。本実施形態では、ダンプ処理を説明する。
まず、CPU201は、初期化処理を実行する(ステップS501)。ここでは、CPU201は、図2のタイマ1 204a、タイマ2 204bの初期化、図2の音源LSI205の初期化、図1及び図2のLCD105の初期化、図2のA/Dコンバータ208の初期化、図2のキースキャナ207の初期化、その他、図3(b)に示したRAM202上の変数の初期化を実行する。変数の初期化では、まず全変数領域が0で埋められ、0以外の初期値を持つ以下の変数が個別に初期化される。
MAX_POLY=256:初期段階では発音制限は行わない。
CTRL_BENDER=4040H:これはピッチベンダの値をMIDIフォーマットで保持しているためであり、4040Hは中央値であることを意味する。
ステップS501の初期化処理の後、CPU201は、ステップS502からS505の一連の処理を繰り返し実行する。これらの一連の処理において、まずCPU201は、ユーザインターフェース処理を実行する(ステップS502)。図6は、図5のステップS502のユーザインターフェース処理の詳細例を示すフローチャートである。この処理では、図1のスイッチ・パネル102のボタンの状態をキースキャナ207を介して読み込み(ステップS601)、その変化に応じて機器の状態を変化させたり、その他の操作処理を行ったり(ステップS604)、状態を表示するLCDを更新したりする(ステップS605)。スイッチ・パネル102の音色選択ボタンが操作された場合には(ステップS602の判定がYES)、CPU201は、音源コマンドバッファ書込みサブルーチンをコールして、音色変更のMIDIメッセージコマンドを音源コマンドバッファに書き込む(ステップS603)。この場合、配列レジスタd[0]、d[1]、d[2]、及びd[3]はそれぞれ、図4(b)の第1バイト、第2バイト、第3バイト、及び第4バイトを指定するCPU201内のレジスタである。これらはRAM202に記憶される変数であってもよい。CPU201は、ステップS603で音源コマンドバッファ書込みサブルーチンをコールするときには、d[0]に値01H(図4(b)参照)、d[1]にCnH(nは電子鍵盤楽器100に割り当てられているMIDIチャネルの番号)、d[2]に音色番号(Program number)、d[3]に00H(共に、図4(c)のProgram changeのデータフォーマットを参照)を、それぞれ設定する。
次に、CPU201は、コントローラA/D処理を実行する(ステップS503)。この処理では、演奏者が図1のピッチベンダーホイール103、ピッチモジュレーションホイール104、及び特には図示しないサスティーンペダルを操作したときの操作位置情報が、A/Dコンバータ208を介して取得され、それぞれ音源コマンドバッファへの書込みが行われる。
図7は、図5のステップS503のコントローラA/D処理の詳細例を示すフローチャートである。図7の処理において、CPU201はまず、図2のA/Dコンバータ208から出力されるピッチベンダーホイール103のA/D(アナログ/デジタル変換)値を読み込む(ステップS701)。次に、CPU201は、ステップS701で読み込んだA/D値を、MIDIフォーマットに変換し、一時的なレジスタaに格納する(ステップS702)。そして、CPU201は、レジスタaの内容が、RAM202に記憶されピッチベンダーホイール103の操作位置を示す変数CTRL_BEND_WHEEL(図3(b)参照)の値と同じであるか否かを判定する(ステップS703)。ピッチベンダーホイール103について新たな操作が行われステップS703の判定がNOとなった場合には、CPU201は、音源コマンドバッファ書込みサブルーチンをコールして、ピッチベンダーホイール103のコントロール値変更のMIDIメッセージコマンドを音源コマンドバッファに書き込む(ステップS704)。この場合、CPU201は、d[0]に値01H(図4(b)参照)、d[1]にEnH、d[2]にレジスタaのLSB(下位バイト)、d[3]にレジスタaのMSB(上位バイト)(共に、図4(c)のPitch bender changeのデータフォーマットを参照)を、それぞれ設定する。
次に、CPU201は、図2のA/Dコンバータ208から出力されるモジュレーションホイール104のA/D値を読み込む(ステップS705)。次に、CPU201は、ステップS705で読み込んだA/D値を、MIDIフォーマットに変換し、レジスタaに格納する(ステップS706)。そして、CPU201は、レジスタaの内容が、RAM202に記憶されモジュレーションホイール104の操作位置を示す変数CTRL_MOD(図3(b)参照)の値と同じであるか否かを判定する(ステップS707)。モジュレーションホイール104について新たな操作が行われステップS707の判定がNOとなった場合には、CPU201は、音源コマンドバッファ書込みサブルーチンをコールして、モジュレーションホイール104のコントロール値変更のMIDIメッセージコマンドを音源コマンドバッファに書き込む(ステップS708)。この場合、CPU201は、d[0]に値01H(図4(b)参照)、d[1]にBnH、d[2]に01H、d[3]にレジスタaの内容(共に、図4(c)のModulationのデータフォーマットを参照)を、それぞれ設定する。
更に、CPU201は、図2のA/Dコンバータ208から出力されるサスティーンペダルのA/D値を読み込む(ステップS709)。次に、CPU201は、ステップS709で読み込んだA/D値を、MIDIフォーマットに変換し、レジスタaに格納する(ステップS710)。そして、CPU201は、レジスタaの内容が、RAM202に記憶されサスティーンペダルの操作位置を示す変数CTRL_PEDAL(図3(b)参照)の値と同じであるか否かを判定する(ステップS711)。サスティーンペダルについて新たな操作が行われステップS711の判定がNOとなった場合には、CPU201は、音源コマンドバッファ書込みサブルーチンをコールして、サスティーンペダルのコントロール値変更のMIDIメッセージコマンドを音源コマンドバッファに書き込む(ステップS712)。この場合、CPU201は、d[0]に値01H(図4(b)参照)、d[1]にBnH、d[2]に40H、d[3]にレジスタaの内容(共に、図4(c)のHold pedalのデータフォーマットを参照)を、それぞれ設定する。
図8は、図5のステップS504の音源コマンド処理の詳細例を示すフローチャートである。ここでは、音源コマンドバッファ上で、リードポインタRPの値を1つずつ進めながら、押鍵、離鍵、モジュレーション、ベンダー、サスティンペダルの各コマンドの種類に応じたコマンド実行処理、又は後述するレスポンス計測用コマンドに対応した制御処理を実行する。
CPU201はまず、他の処理(後述する図10の各インタラプトルーチン)からの割込みを禁止する(ステップS801)。
次に、CPU201は、音源コマンドバッファの読込みポインタであるリードポインタRPのアドレス(共に図3(b)参照)が、RAM202に記憶されている音源コマンドバッファの書込みポインタであるライトポインタWPのアドレスに追いついたか否かを判定する(ステップS802)。
ステップS802の判定がNOならば、CPU201は、RAM202に記憶されている音源コマンドバッファのリードポインタRPが示すエントリTG_CMD[RP](図3(b)参照)から4バイトのコマンド値(図4(b)参照)を読み込み、4バイトのレジスタdに格納する(ステップS803)。
CPU201は、次回の処理のために、リードポインタRPのアドレス値を1進める。ここで、1進めた記憶アドレス(RP+1)が255を超えたときに先頭アドレス側に折り返せるようにするために、(RP+1)とFFHとの論理積を取った値を、新たなリードポインタRPのアドレス値としている。
その後、CPU201は、音源コマンドバッファを開放するために、ステップS801で設定した割込みの禁止状態を解除する(ステップS805)。
そして、CPU201は、音源コマンド実行サブルーチンをコールしてレジスタdに読み出したコマンドを実行する(ステップS806)。このとき、CPU201は、レジスタdと000000FFHとの論理積をとることにより、レジスタdの下位側からみた第1バイトを取り出して、配列レジスタd[0]に格納する。また、CPU201は、レジスタdと0000FF00Hとの論理積をとりその結果を100Hで除算することにより、レジスタdの下位側からみた第2バイトを取り出して、配列レジスタd[1]に格納する。また、CPU201は、レジスタdと00FF0000Hとの論理積をとりその結果を10000Hで除算することにより、レジスタdの下位側からみた第3バイトを取り出して、配列レジスタd[2]に格納する。更に、CPU201は、レジスタdとFF000000Hとの論理積をとりその結果を1000000Hで除算することにより、レジスタdの最上位バイト(第4バイト)を取り出して、配列レジスタd[3]に格納する。CPU201は、以上のようにして設定した配列レジスタd[0]、d[1]、d[2]、及びd[3]を、音源コマンド実行サブルーチンに引数として渡す。音源コマンド実行サブルーチンの詳細については、図12以降のフローチャートの説明で後述する。
その後、CPU201は、ステップS801の処理に戻り、ステップS804でインクリメントされた次のリードポインタRPが示す音源コマンドバッファからの音源コマンドの読込み処理に移行する。
以上の処理が繰り返し実行された結果、リードポインタRPのアドレスがライトポインタWPのアドレスに追いつくと、CPU201は、ステップS801で設定した割込み禁止を解除する(ステップS807)。その後、CPU201は、図8のフローチャートで示される図5のステップS504の音源コマンド処理を終了する。
図9は、図5のステップS505の音源定常サービス処理の詳細例を示すフローチャートである。ここでは、CPU201は、発音中のボイスに対してピッチや音量などの時間的な変化の監視と制御を行う。特に、本実施形態に関連するのは、リリースダンプ及びスローダンプ中のボイス制御である。
CPU201はまず、ピッチ制御や音量制御等の各種音源定常サービス処理を実行する(ステップS901)。
その後、CPU201は、ステップS902でボイス番号を示すレジスタvの値を0にリセットした後、ステップS908でレジスタvの値を+1ずつインクリメントしながら、ステップS909でレジスタvの値が256に達したと判定するまで、ステップS903からS907の一連の処理を、各ボイス番号vのボイスについて繰り返し実行する。
上記繰返しにおいて、CPU201はまず、ボイス番号vのボイスの発音状態VOICE[v].STATがリリースダンプ中を示す値3又はスローダンプ中を示す値4(図3(b)参照)になっているか否かを判定する(ステップS903)。
ステップS903の判定がNOならば、CPU201は、ステップS908の処理に移って、次のボイス番号vに対する処理に移行する。
ステップS903の判定がYESならば、CPU201は、ボイス番号vのボイスのレベルをレジスタaに格納した後(ステップS904)、レジスタaの値が目標値である0に達したかどうかを調べ(ステップS905)、0に達したものが発見された場合(ステップS905の判定がYESの場合)には、次の処理を実行する。
CPU201は、ボイス番号vのボイスに対応する発音状態VOICE[v].STATを停止中を示す値0(図3(b)参照)にセットする(ステップS906)。
そして、CPU201は、RAM202に記憶されている現在の発音数を示す変数値CUR_POLYの値を1減算してセットし直すことにより、現在の発音数を1減らす(ステップS907)。
以上のようにして、現在のボイス番号vに対するステップS903からS907の一連の処理が終了すると、CPU201は、ステップS908でレジスタvの値を+1インクリメントして、ステップS909の判定からステップS903の処理に戻り、次のボイス番号vに対する処理を繰り返し実行する。
全てのボイスvに対する処理が完了してステップS909の判定がYESになると、CPU201は、図9のフローチャートで示される図5のステップS505の音源定常サービス処理を終了する。
次に、インタラプトルーチンについて説明する。まず、図2のキースキャナ207は、図1の鍵盤101やスイッチ・パネル102の操作を検知すると、CPU201に割込みを発生させる。CPU201は、この割込みを検知すると、図5のメインルーチンの処理を中断して、図10(a)のキースキャナーインタラプトルーチンを実行する。
CPU201はまず、キースキャナ207がレジスタs、k、及びvにそれぞれセットしたステータス(値0ならノートオフ、値1ならノートオン)、キーナンバ、及びベロシティの各値を読み込む(ステップS1001)。
CPU201は、レジスタsの値が1(ノートオン)であるか否かを判定する(ステップS1002)。
ステップS1002の判定がYESならば、CPU201は、音源コマンドバッファ書込みサブルーチンをコールして、ノートオンのMIDIメッセージコマンドを音源コマンドバッファに書き込む(ステップS1003)。この場合、CPU201は、配列レジスタd[0]に値01H(図4(b)参照)、d[1]に9nH、d[2]にレジスタkのキーナンバ値、d[3]にレジスタvのベロシティ値(共に、図4(c)のNote onのデータフォーマットを参照)を、それぞれ設定する。
一方、キースキャナイベントがノートオフイベントでステップS1002の判定がNOならば、CPU201は、音源コマンドバッファ書込みサブルーチンをコールして、ノートオフのMIDIメッセージコマンドを音源コマンドバッファに書き込む(ステップS1004)。この場合、CPU201は、配列レジスタd[0]に値01H(図4(b)参照)、d[1]に8nH、d[2]にレジスタkのキーナンバ値、d[3]にレジスタvのベロシティ値(共に、図4(c)のNote offのデータフォーマットを参照)を、それぞれ設定する。
ステップS1003又はS1004の処理の後、CPU201は、図10のフローチャートで示されるキースキャナーインタラプトルーチンの処理を終了し、図5のメインルーチンの処理に戻る。
次に、タイマインタラプトルーチンについて説明する。図2のタイマ2 204bは、25ミリ秒をカウントすると、CPU201に割込みを発生させる。この結果、CPU201は、図5のメインルーチンの処理を中断して、図10(b)のタイマインタラプトルーチンを実行する。
CPU201はまず、タイマ1 204aの現在値であるタイマ時刻をレジスタtに格納する(ステップS1011)。
次に、CPU201は、音源コマンドバッファ書込みサブルーチンをコールして、レスポンス計測用コマンドを音源コマンドバッファに書き込む(ステップS1012)。この場合、CPU201は、配列レジスタd[0]に値02H、d[1]に00H、d[2]にレジスタtに格納されたタイマ時刻の下位バイト、d[3]にレジスタtに格納されたタイマ時刻の上位バイトを、それぞれ設定する(共に図4(b)参照)。
続いて、CPU201は、タイマ2 204bを再スタートさせる(ステップS1013)。その後、CPU201は、図11のフローチャートで示されるタイマインタラプトルーチンを終了し、図5のメインルーチンの処理に戻る。
図11は、図6のステップS603、図7のステップS704、S708、S712、図10のステップS1003、又はS1004からぞれぞれコールされる、音源コマンドバッファ書込みサブルーチンの詳細例を示すフローチャートである。このとき、引数として、配列レジスタd[0]、d[1]、d[2]、及びd[3]が引き渡される。d[0]、d[1]、d[2]、及びd[3]はそれぞれ、図4(b)の音源コマンドバッファのデータフォーマットの第1バイト(bit0−7:第0〜第7ビット)、第2バイト(bit8−15:第8〜第15ビット)、第3バイト(bit16−23:第16〜第23ビット)、及び第4バイト(bit24−31:第24〜第31ビット)に書き込まれるデータである。
CPU201はまず、他の処理(図10の各インタラプトルーチン)からの割込みを禁止する(ステップS1101)。
次に、CPU201は、次式で示される演算により、音源コマンドバッファの連続する4バイトの書込みデータを作成し、結果をレジスタmに格納する(ステップS1102)。
m=d[0]+100H×d[1]+10000H×d[2]
+1000000H×d[3]
次に、CPU201は、リードポインタRPとライトポインタWPを比較し、書き込むスペースがあるか否かを調査する。具体的には、ライトポインタWPをプラス2インクリメントした値とFFHとで論理積を演算した結果が、リードポインタRPの値に等しいか否かを判定する(ステップS1103)。FFHを論理演算する意味は、前述した通りである。
ステップS1103の判定がNOならば、書き込むスペースがあるため、ライトポインタWPが示す音源コマンドバッファTC_CMD[WP]に、ステップS1102でレジスタmに得られている4バイトの書込みデータを格納する(ステップS1104)。その後、CPU201は、ライトポインタWPの値を+1インクリメントし、その結果をFFHと論理演算し、その演算結果を新たにライトポインタWPの値とする(ステップS1105)。
一方、ステップS1103の判定がYESならば、音源コマンドバッファに空きスペースがなかったら、処理すべき仕事量がCPU能力の限界を超えているので、演奏に耐えうる状態にいち早く戻すべきと判断し、音源LSI205にリセットコマンド送る。この場合、音源コマンドの読出し処理側ですぐにリセット処理がされるように、CPU201は、リードポインタRPが示す音源コマンドバッファTG_CMD[RP]の位置に音源リセットデータ00000003H(図4(b)参照)を書き込み(ステップS1106)、ライトポインタWPも「WP=(RP+1)&FFH」として合わせておく(ステップS1107)。
ステップS1105又はS1107の処理の後、CPU201は、ステップS1101で設定した割込み禁止を解除して(ステップS1108)、図11のフローチャートで例示される音源コマンドバッファ書込みサブルーチンを終了して、呼出し元の処理に戻る。
図12は、図5のステップS504の音源コマンド処理内で実行される図8のステップS806の音源コマンド実行サブルーチンの詳細例を示すフローチャートである。ここでは、図8のフローチャートの処理で音源コマンドバッファから読み出され実行が指示された音源コマンドが解析され、実行される。
CPU201はまず、第1バイト配列レジスタd[0]の値が01Hであるか否かを判定する(ステップS1201)。図4(b)に示したように、d[0]=01Hであれば演奏コマンド(鍵盤演奏(ノートオン、ノートオフ)、スイッチ・パネル102の操作、又はコントローラの操作)であり、この判定がYESならば、CPU201は、演奏コマンド処理サブルーチンを実行する(ステップS1202)。このとき、レジスタm1、m2、m3にそれぞれ配列レジスタd[1]、d[2]、d[3]の値が引数として格納されて、演奏コマンド処理サブルーチンがコールされる。このサブルーチンの実行が終了すると、CPU201は、図12のフローチャートで例示される図8のステップS806の音源コマンド実行サブルーチンを終了する。演奏コマンド処理サブルーチンの詳細は、図12から図18のフローチャートの説明で後述する。
ステップS1201の判定がNOならば、CPU201は次に、第1バイト配列レジスタd[0]の値が02Hであるか否かを判定する(ステップS1203)。図4(b)に示したように、d[0]=02Hであればレスポンス計測用コマンドであり、この判定がYESならば、CPU201は、レスポンス計測用コマンド処理サブルーチンを実行する(ステップS1204)。このとき、レジスタm2、m3にそれぞれ配列レジスタd[2]、d[3]の値が引数として格納されて、レスポンス計測用コマンド処理サブルーチンがコールされる。このサブルーチンの実行が終了すると、CPU201は、図12のフローチャートで例示される図8のステップS806の音源コマンド実行サブルーチンを終了する。レスポンス計測用コマンド処理サブルーチンの詳細は、図19及び図20のフローチャートの説明で後述する。
ステップS1203の判定もNOならば、CPU201は、第1バイト配列レジスタd[0]の値が03Hであるか否かを判定する(ステップS1205)。図4(b)に示したように、d[0]=03Hであれば音源リセットコマンドであり、この判定がYESならば、CPU201は、音源リセットコマンド処理サブルーチンを実行する(ステップS1206)。音源リセットコマンド処理サブルーチンの詳細は省略するが、CPU201は、音源LSI205に対して、全発音の停止を指示し、ピッチベンダーホイール103、モジュレーションホイール104、及びサスティーンペダルの各コントローラの状態をリセットする。このサブルーチンの実行が終了すると、CPU201は、図12のフローチャートで例示される図8のステップS806の音源コマンド実行サブルーチンを終了する。
ステップS1205の判定もNOならば、現在のコマンドは無効であるため(図4(b)参照)、CPU201は、図12のフローチャートで例示される図8のステップS806の音源コマンド実行サブルーチンを終了する。
図13は、図12のステップS1202の演奏コマンド処理ルーチンの詳細例を示すフローチャートである。CPU201はまず、レジスタm1で引き渡されたMIDI[0]の値が9nH(nは電子鍵盤楽器100に割り当てられているMIDIチャネル)であるか否かを判定する(ステップS1301)。図4(c)に示したように、MIDI[0]=9nHであればノートオン(Note on)コマンドであり、この判定がYESならば、CPU201は、押鍵コマンド処理サブルーチンを実行する(ステップS1302)。このとき、レジスタm0、m1にそれぞれ元のレジスタm2(キーナンバ)とm3(ベロシティ)の値が引数として格納されて、押鍵コマンド処理サブルーチンがコールされる。このサブルーチンの実行が終了すると、CPU201は、図13のフローチャートで例示される図12のステップS1202の演奏コマンド処理サブルーチンを終了する。押鍵コマンド処理サブルーチンの詳細は、図14から図16のフローチャートの説明で後述する。
ステップS1301の判定がNOならば、CPU201は、レジスタm1で引き渡されたMIDI[0]の値が8nHであるか否かを判定する(ステップS1303)。図4(c)に示したように、MIDI[0]=8nHであればノートオフ(Note off)コマンドであり、この判定がYESならば、CPU201は、離鍵コマンド処理サブルーチンを実行する(ステップS1304)。このとき、レジスタm0、m1にそれぞれ元のレジスタm2(キーナンバ)とm3(ベロシティ)の値が引数として格納されて、離鍵コマンド処理サブルーチンがコールされる。このサブルーチンの実行が終了すると、CPU201は、図13のフローチャートで例示される図12のステップS1202の演奏コマンド処理サブルーチンを終了する。離鍵コマンド処理サブルーチンの詳細は、図17のフローチャートの説明で後述する。
ステップS1303の判定がNOならば、CPU201は、レジスタm1で引き渡されたMIDI[0]の値がBnHで、かつレジスタm2で引き渡されたMIDI[1]の値が01Hであるか否かを判定する(ステップS1305)。図4(c)に示したように、MIDI[0]=BnHかつMIDI[1]=01Hであればモジュレーションホイール104による変調(Modulation)コマンドであり、この判定がYESならば、CPU201は、次の処理を実行する。CPU201はまず、RAM202に記憶されているモジュレーションホイール最深値を格納する変数CTRL_MODに、レジスタm3で引き渡されたモジュレーションデプス値(Depth)を格納する(ステップS1306)。そして、CPU201は、レジスタm3の値に応じたモジュレーション処理を実行する(ステップS1307)。この処理の詳細については、省略する。この処理が終了すると、CPU201は、図13のフローチャートで例示される図12のステップS1202の演奏コマンド処理サブルーチンを終了する。
ステップS1305の判定がNOならば、CPU201は、レジスタm1で引き渡されたMIDI[0]の値がBnHで、かつレジスタm2で引き渡されたMIDI[1]の値が40Hであるか否かを判定する(ステップS1308)。図4(c)に示したように、MIDI[0]=BnHかつMIDI[1]=40Hであればサスティーンペダルによるサスティーン処理(Hold pedal)コマンドであり、この判定がYESならば、CPU201は、サスティーンペダル処理サブルーチンを実行する(ステップS1309)。このとき、レジスタm1に元のレジスタm3(ペダル値)の値が引数として格納されて、サスティーンペダル処理サブルーチンがコールされる。このサブルーチンの実行が終了すると、CPU201は、図13のフローチャートで例示される図12のステップS1202の演奏コマンド処理サブルーチンを終了する。サスティーンペダル処理サブルーチンの詳細は、図18のフローチャートの説明で後述する。
ステップS1308の判定もNOならば、CPU201は、図13のフローチャートで例示される図12のステップS1202の演奏コマンド処理サブルーチンを終了する。
図14は、図13のステップS1302の押鍵コマンド処理サブルーチンの詳細例を示すフローチャートである。CPU201は、引数s=0(停止中)としてボイス検索サブルーチンをコールすることにより、まずどのボイスに割り当てるかを検索する(ステップS1401)。
未使用ボイスがあれば(ステップS1402の判定がNO)、CPU201は、最初に発見されたボイスを割り当てる(後述するステップS1412)。
未使用ボイスがない場合(ステップS1402の判定がYES)、以下の順序で割り当てるボイスを決定する。まず、CPU201は、引数s=4(スローダンプ中)として最古ボイス検索サブルーチンをコールすることにより、ボイス数制限によりスローダンプをさせられているボイスの中で最も古いものを検索する(ステップS1403)。
該当するボイスがあれば(ステップS1404の判定がNO)、CPU201は、ステップS1410に移行して、該当するボイスに対して、ボイスファーストダンプサブルーチンを実行する。
該当するボイスがなければ(ステップS1404の判定がYES)、CPU201は、引数s=3(リリースダンプ中)として最古ボイス検索サブルーチンをコールすることにより、離鍵によりリリースされ、減衰中のボイスの中で最も古いものを検索する(ステップS1405)。
該当するボイスがあれば(ステップS1405の判定がNO)、CPU201は、ステップS1410に移行して、該当するボイスに対して、ボイスファーストダンプサブルーチンを実行する。
該当するボイスがなければ(ステップS1406の判定がYES)、CPU201は、引数s=2(ホールド中)として最古ボイス検索サブルーチンをコールすることにより、サスティーンペダルによりホールドしているボイスの中で最も古いものを検索する(ステップS1407)。
該当するボイスがあれば(ステップS1408の判定がNO)、CPU201は、ステップS1410に移行して、該当するボイスに対して、ボイスファーストダンプサブルーチンを実行する。
該当するボイスがなければ(ステップS1408の判定がYES)、CPU201は、引数s=1(ホールド中)として最古ボイス検索サブルーチンをコールすることにより、
押鍵中のボイスの中で最も古いものを検索する(ステップS1409)。この処理の後、CPU201は、ステップS1410に移行して、検索されたボイスに対して、ボイスファーストダンプサブルーチンを実行する。
上述のように、未使用ボイス以外のボイスに割り当てる場合は、一旦消音するために、CPU201は、ボイスファーストダンプサブルーチンを実行する(ステップS1410)。CPU201は、このサブルーチンの中でボイスを高速にダンプさせ、発音を停止させる。VOICE[v].STAT変数にファストダンプ中が存在しない理由は、このサブルーチンの中でしか起こらない状態であるからである。
ステップS1410のボイスファーストダンプサブルーチンの実行の後、CPU201は、RAM202に記憶されている現在の発音数を示す変数値CUR_POLYの値を1減算してセットし直すことにより、現在の発音数を1減らす(ステップS1411)。
ステップS1402の判定がNOとなることにより、又はステップS1411の処理の後、必要な未使用ボイスが割り当てられると、CPU201は、レジスタvに格納されている検索により見つかったボイスvに対応してRAM202に記憶されているVOICE[v]変数の各情報を設定する。即ち、CPU201は、VOICE[v].STAT=1(押鍵中)、VOICE[v].COUNT=NOTE_ON_COUNT、VOICE[v].KEY=m0(キーナンバ)、VOICE[v].VOLE=m1(ベロシティ)をそれぞれ設定する。その後、CPU201は、RAM202に記憶されている初期化以後の発音回数を示す変数NOTE_ON_COUNTの値を+1インクリメントする(以上、ステップS1412)。
続いて、CPU201は、RAM202に記憶されている現在の発音数を示す変数値CUR_POLYの値を+1インクリメントすることにより、現在の発音数を1増やす(ステップS1413)。
最後に、CPU201は、レジスタvにボイス番号、レジスタkにキーナンバ、レジスタvにベロシティをそれぞれセットし、これらを引数として、音源LSI205を発音制御するための音源発音開始サブルーチンをコールする。この処理の詳細は省略する。
図15は、図14のステップS1401のボイス検索サブルーチンの詳細例を示すフローチャートである。CPU201は、ボイス番号を示すレジスタvの値を0にリセットした後(ステップS1501)、ステップS1503でレジスタvの値を+1ずつインクリメントしながら、ステップS1504でレジスタvの値が256に達したと判定するまで、レジスタvの示すボイスvのRAM202に記憶されている状態VOICE[v].STAT(図3(b)参照)の値が、図14のステップS1401で引数sとして指定されている値、即ちこの場合は停止中を示す値0であるか否かを判定する(ステップS1502)。
レジスタvが示す何れかのボイスvについて、ステップS1502の判定がYESになれば、CPU201は、このサブルーチンの戻り値をレジスタvのボイス番号にセットして、図15のフローチャートで例示される図14のステップS1401のボイス検索サブルーチンを終了する。
どのレジスタvの値についてもステップS1502の判定がNOとなり、最終的にステップS1504の判定がYESになると、CPU201は、このサブルーチンの戻り値をこの時点におけるレジスタvのボイス番号=256にセットして、図15のフローチャートで例示される図14のステップS1401のボイス検索サブルーチンを終了する。
図16は、図14のステップS1403、S1405、S1407、又はS1409の最古ボイス検索サブルーチンの詳細例を示すフローチャートである。CPU201は、ボイス番号を示すレジスタvの値を0にリセットした後(ステップS1601)、このサブルーチンの戻り値を示すレジスタpの値を該当ボイスがない場合の値256に初期設定し(ステップS1602)、更に、押鍵の古さ(押鍵履歴)を示すレジスタcの初期値をFFFFFFFFHに初期設定した後、ステップS1608でレジスタvの値を+1ずつインクリメントしながら、ステップS1609でレジスタvの値が256に達したと判定するまで、ステップS1604からS1607までの一連の処理を、ボイス番号v毎に繰り返し実行する。
上記繰返し処理において、CPU201はまず、レジスタvの示すボイスvのRAM202に記憶されている状態VOICE[v].STAT(図3(b)参照)の値が、図14のステップS1403、S1405、S1407、又はS1409で引数sとして指定されている値に等しいか否か、即ち、引数sとして指定された状態に合致するボイスが見つかったか否かを判定する(ステップS1604)。
ステップS1604の判定がNOならば、CPU201は、ステップS1608に移って、次のボイスvに対する検索処理に移行する。
ステップS1604の判定がYESになると、CPU201は、見つかったボイスに対応してRAM202に記憶されている押鍵履歴カウントVOICE[v].COUNT(図3(b)参照)の値が、レジスタcにセットされている現在までに見つかっている押鍵履歴カウントの値よりも小さいな否か、即ち、今回見つかったボイスが最も古く押鍵されているか否かを判定する(ステップS1605)。
ステップS1605の判定がNOならば、CPU201は、ステップS1608に移って、次のボイスvに対する検索処理に移行する。
ステップS1605の判定がYESになると、CPU201はまず、現在までの押鍵履歴カウントを示すレジスタcに、見つかったボイスに対応する押鍵履歴カウントVOICE[v].COUNTの値を格納する(ステップS1606)。
更に、CPU201は、戻り値を示すレジスタpに、今回見つかったボイス番号に対応するレジスタvの値を格納する(ステップS1607)。
以上のステップS1604からS1607までの一連の処理が全てのボイス番号vについて繰り返された後、ステップS1609の判定がYESとなると、CPU201は、レジスタpの値を戻り値として、図16のフローチャートで例示される最古ボイス検索サブルーチンを終了する。
図17は、図13のステップS1304の離鍵コマンド処理サブルーチンの詳細例を示すフローチャートである。CPU201は、ボイス番号を示すレジスタvの値を0にリセットした後(ステップS1701)、ステップS1708でレジスタvの値を+1ずつインクリメントしながら、ステップS1709でレジスタvの値が256に達したと判定するまで、ステップS1702からS1707の一連の処理をボイス番号v毎に繰り返し実行する。
上記繰返し処理において、CPU201はまず、レジスタvに対応するボイス番号vのRAM202に記憶されている発音状態を示す変数VOICE[v].STATの値が、押鍵中を示す値1であるか否かを判定する(ステップS1702)。
ステップS1702の判定がNOならば、CPU201は、ステップS1708に移って、次のボイス番号vに対応する処理に移行する。
ステップS1702の判定がYESならば、CPU201は、レジスタvに対応するボイス番号vのRAM202に記憶されているキーナンバを示す変数VOICE[v].KEYの値が、レジスタm0を介して引き渡された離鍵を指定するキーナンバkに一致するか否かを判定する(ステップS1703)。
ステップS1703の判定がNOならば、CPU201は、ステップS1708に移って、次のボイス番号vに対応する処理に移行する。
ステップS1703の判定もYESならば、CPU201は、RAM202内の変数CTRL_PEDALに記憶されているサスティーンペダルの最新値(図3(b)参照)が、40H以上であるか否かを判定する(ステップS1704)。
ステップS1704の判定がYESであれば、CPU201は、レジスタvに対応するボイス番号vのRAM202に記憶されている発音状態を示す変数VOICE[v].STATに、サスティーンペダルでホールド中であることを示す値2(図3(b)参照)をセットし(ステップS1705)、離鍵のためのエンベロープに関しては操作しない。
ステップS1704の判定がNOであれば、CPU201は、上記変数VOICE[v].STATに、リリース中であることを示す値3(図3(b)参照)をセットする(ステップS1706)。
ステップS1706の処理の後、CPU201は、ボイス番号vのボイスについて、音源エンベロープリリース制御開始処理を実行する(ステップS1707)。これにより、音源LSI205は、ボイス番号vのボイスについて、離鍵のためのエンベロープ制御に移行する。この処理の詳細は省略する。
ステップS1706又はS1707の処理の後、CPU201は、ボイス番号vの値を+1インクリメントして次のボイス番号vに対応する処理に移行する(ステップS1708)。
以上のステップS1702からS1707の一連の処理が繰り返されて、やがてステップS1708の判定がYESになると、CPU201は、図17のフローチャートで例示される図13のステップS1304の離鍵コマンド処理サブルーチンを終了する。
図18は、図13のステップS1309のサスティーンペダル処理サブルーチンの詳細例を示すフローチャートである。本実施形態のサスティーンペダルの操作の値はMIDIフォーマットに準拠しているので、その位置情報を0から7FHの範囲の値で扱うが、動作としては40H以上で押下、40H未満で開放状態とみなす。
CPU201はまず、レジスタm1を介して引き渡されたペダル値が40Hよりも小さいか否かを判定する(ステップS1801)。
ステップS1801の判定がNOならば、CPU201は、そのまま図18のフローチャートで示される図13のステップS1309のサスティーンペダル処理サブルーチンを終了する。
サスティーンペダルが開放状態となってステップS1801の判定がYESになると、CPU201は、RAM202内の変数CTRL_PEDAL(図3(b)参照)に記憶されているサスティーンペダルの最深値(いままでの値)が40H以上であるか否かを判定する(ステップS1802)。
ステップS1802の判定がNOならば、CPU201は、そのまま図18のフローチャートで示される図13のステップS1309のサスティーンペダル処理サブルーチンを終了する。
ステップS1802の判定がYES、即ち、サスティーンペダルの値が今まで40H以上の押下状態で、今回開放状態に変化した場合には、CPU201は、以下の処理を実行する。CPU201は、ボイス番号を示すレジスタvの値を0にリセットした後(ステップS1803)、ステップS1807でレジスタvの値を+1ずつインクリメントしながら、ステップS1808でレジスタvの値が256に達したと判定するまで、ステップS1804からS1806の一連の処理をボイス番号v毎に繰り返し実行する。
上記繰返し処理において、CPU201はまず、レジスタvの値に対応するボイス番号vのRAM202に記憶されている発音状態を示す変数VOICE[v].STATの値がサスティーンペダルホールド中を示す値2(図3(b)参照)であるか否かを判定する(ステップS1804)。
ステップS1804の判定がNOならば、CPU201は、ステップS1807に移って次のボイス番号vに対応する処理に移行する。
ステップS1804の判定がYESならば、CPU201は、レジスタvの値に対応するボイス番号vのRAM202に記憶されている発音状態を示す変数VOICE[v].STATにリリース中を示す値3(図3(b)参照)をセットする(ステップS1805)。
その後、CPU201は、ボイス番号vについて、図17のステップS1707と同様の音源エンベロープリリース制御開始処理を実行する(ステップS1806)。これにより、音源LSI205は、ボイス番号vのボイスについて、離鍵のためのエンベロープ制御に移行する。
以上のステップS1804からS1806の一連の処理が繰り返されて、やがてステップS1808の判定がYESになると、CPU201は、図18のフローチャートで例示される図13のステップS1309のサスティーンペダル処理サブルーチンを終了する。
図19は、図12のステップS1204のレスポンス計測用コマンド処理サブルーチンの詳細例を示すフローチャートである。CPU201はまず、タイマ1 204aの現在値であるタイマ時刻を、レジスタtに格納する(ステップS1901)。
次に、CPU201は、レジスタm2及びm3によって引き渡された今回音源コマンドバッファから読み込まれたレスポンス計測用コマンドに記録されているタイマ時刻下位バイト値とタイマ時刻上位バイト値とを用いて、レジスタtに格納された現在のタイマ時刻と上記記録されているタイマ時刻との差分値であるレスポンスタイムを次式で示される符号無し演算により算出し、レジスタdに格納する(ステップS1902)。
d=t−(m2+100H×m3)
その後、CPU201は、レジスタiの値を初期値0にリセットした後(ステップS1903)、ステップS1905でレジスタiの値を+1ずつインクリメントしながら、レジスタiの値に対応するレスポンスタイム−同時発音数増減値対応テーブルのエントリのレスポンスタイムレンジ最大値RES_TIME_TBL[i].RANGE_TOPにアクセスし、レジスタdに得られたレスポンスタイムがどのレンジに存在するかを判定する(ステップS1904)。
ステップS1904の判定がYESとなった時点で、CPU201は、その時点の同時発音数増減値RES_TIME_TBL[i].DIFFを、RAM202に記憶されている現在の基準最大発音数を示す変数MAX_POLYに加算する(ステップS1906)。
CPU201は、ステップS1906の処理の結果、変数MAX_POLYの値が同時発音数の最大値256を超えたか否かを判定する(ステップS1907)。ステップS1907の判定がYESならば、CPU201は、変数MAX_POLYに最大値256をセットする(ステップS1911)。その後、CPU201は、図19のフローチャートで示される図12のステップS1204のレスポンス計測用コマンド処理サブルーチンを終了する。
ステップS1907の判定がNOならば、CPU201は、変数MAX_POLYの値が同時発音数の最小値1を下回ったか否かを判定する(ステップS1908)。ステップS1908の判定がYESならば、CPU201は、変数MAX_POLYに最小値1をセットする(ステップS1912)。ステップS1907の判定がNOならば、CPU201は、ステップS1912の処理はスキップする。
その後、CPU201は、RAM202の変数CUR_POLYに記憶されている現在の発音数が、MAX_POLYの値よりも大きくなっているか否かを判定する(ステップS1909)。
ステップS1909の判定がNOならば、CPU201は、図19のフローチャートで示される図12のステップS1204のレスポンス計測用コマンド処理サブルーチンを終了する。
ステップS1909の判定がYESならば、CPU201は、発音ボイス削減処理サブルーチンを実行する(ステップS1910)。このとき、CPU201は、変数CUR_POLYの現在の発音数からMAX_POLYの値を減算して得られる値をレジスタmにセットし、これを発音ボイス削減処理サブルーチンに引き渡す。このサブルーチンの処理が終了すると、CPU201は、図19のフローチャートで示される図12のステップS1204のレスポンス計測用コマンド処理サブルーチンを終了する。
図20は、図19のステップS1910の発音ボイス削除処理サブルーチンの詳細例を示すフローチャートである。ここでは、CPU201は、変数CUR_POLYの現在の発音数よりもMAX_POLYが下回った場合に、過剰となった分(レジスタmの値)のボイスをスローダンプ処理によって開放する処理を実行する。スローダンプとは、突然ボイスをミュートするのではなく、音楽的に影響が少ないように徐々にフェイドアウトをするエンベロープを与える処理である。
まずCPU201は、ボイス番号を示すレジスタvの値を0にリセットした後(ステップS2001)、ステップS2004でレジスタvの値を+1ずつインクリメントしながら、ステップS2005でレジスタvの値が256に達したと判定するまで、ステップS2002とS2003の処理をボイス番号v毎に繰り返し実行する。ここでは、CPU201は、現時点ですでにスローダンプ中のボイスと、リリースダンプ中のボイスの数を調べて、その数を過剰ボイス数から控除する処理を実行する。
まず、CPU201は、レジスタvの値に対応するボイス番号vのRAM202に記憶されている発音状態を示す変数VOICE[v].STATの値が、リリースダンプ中を示す値3であるか又はスローダンプ中を示す値4であるか否かを判定する(ステップS2002)。CPU201は、ステップS2002の判定がYESである場合には、過剰ボイス数を示すレジスタmの値を−1減算する(ステップS2003)。CPU201は、ステップS2002の判定がNOである場合には、ステップS2003の減算処理はスキップする。
以上の処理が繰り返されてやがてステップS2006の判定がYESになると、CPU201は、レジスタmの値が0以下になったか否かを判定する(ステップS2006)。ステップS2006の判定がYESになれば、発音ボイス削減処理は不要となったため、図20のフローチャートで示される図19のステップS1910の発音ボイス削除処理サブルーチンを終了する。
ステップS2006の判定がNOならば、CPU201は、ボイス番号を示すレジスタvの値を0にリセットした後(ステップS2007)、ステップS2013でレジスタvの値を+1ずつインクリメントしながら、ステップS2014でレジスタvの値が256に達したと判定するまで、ステップS2008からS2013の一連の処理をボイス番号v毎に繰り返し実行する。
上記繰返し処理において、CPU201はまず、レジスタvの値に対応するボイス番号vのRAM202に記憶されている発音状態を示す変数VOICE[v].STATの値がサスティーンペダルホールド中を示す値2(図3(b)参照)であるか否かを判定する(ステップS2008)。
ステップS2008の判定がNOならば、CPU201は、ステップS2013に移って次のボイス番号vに対応する処理に移行する。
ステップS2008の判定がYESならば、CPU201は、ボイス番号vについて、音源エンベロープスローダンプ制御開始処理を実行する(ステップS2009)。これにより、音源LSI205は、ボイス番号vのボイスについて、離鍵のためのエンベロープ制御に移行する。この処理の詳細は省略する。
その後、CPU201は、レジスタvの値に対応するボイス番号vのRAM202に記憶されている発音状態を示す変数VOICE[v].STATにスローダンプ中を示す値4(図3(b)参照)をセットする(ステップS2010)。
更に、CPU201は、過剰ボイス数を示すレジスタmの値を−1減算する(ステップS2011)。
CPU201は、レジスタmの値が0以下になったか否かを判定する(ステップS2012)。ステップS2012の判定がYESになれば、発音ボイス削減処理は不要となったため、図20のフローチャートで示される図19のステップS1910の発音ボイス削除処理サブルーチンを終了する。
以上のステップS2008からS2012の一連の処理がボイス番号v毎に繰り返し実行され、やがてステップS2014の判定がYESになると、CPU201は再度、ボイス番号を示すレジスタvの値を0にリセットした後(ステップS2015)、ステップS2021でレジスタvの値を+1ずつインクリメントしながら、ステップS2022でレジスタvの値が256に達したと判定するまで、ステップS2016からS2020の一連の処理をボイス番号v毎に繰り返し実行する。
上記繰返し処理において、CPU201はまず、レジスタvの値に対応するボイス番号vのRAM202に記憶されている発音状態を示す変数VOICE[v].STATの値が押鍵中を示す値1(図3(b)参照)であるか否かを判定する(ステップS2016)。
ステップS2016の判定がNOならば、CPU201は、ステップS2021に移って次のボイス番号vに対応する処理に移行する。
ステップS2016の判定がYESならば、CPU201は、ボイス番号vについて、ステップS2009と同様の音源エンベロープスローダンプ制御開始処理を実行する(ステップS2017)。これにより、音源LSI205は、ボイス番号vのボイスについて、離鍵のためのエンベロープ制御に移行する。
その後、CPU201は、レジスタvの値に対応するボイス番号vのRAM202に記憶されている発音状態を示す変数VOICE[v].STATにスローダンプ中を示す値4(図3(b)参照)をセットする(ステップS2018)。
更に、CPU201は、過剰ボイス数を示すレジスタmの値を−1減算する(ステップS2019)。
CPU201は、レジスタmの値が0以下になったか否かを判定する(ステップS2020)。ステップS2020の判定がYESになれば、発音ボイス削減処理は不要となったため、図20のフローチャートで示される図19のステップS1910の発音ボイス削除処理サブルーチンを終了する。
以上のステップS2016からS2020の一連の処理がボイス番号v毎に繰り返し実行され、やがてステップS2014の判定がYESになると、CPU201は、図20のフローチャートで示される図19のステップS1910の発音ボイス削除処理サブルーチンを終了する。
以上説明した実施形態では、レスポンス計測用コマンドを定期的に音源コマンドバッファに書き込んでレスポンスタイムを計測していた。このほか、音源コマンドバッファに書き込まれる演奏コマンド自体にタイマ時刻情報を格納してレスポンスタイムを計測するようにしてもよい。或いは、レスポンス計測用コマンドや特定の演奏コマンドが音源コマンドバッファに書き込まれるときのタイマ時刻がRAM202に記録されるようにし、そのコマンドが音源コマンドバッファから読み出されるときの現在時刻との差分時間を計測するようにしてもよい。その他、音源コマンドが音源コマンドバッファに書き込まれてから読み出されるまでの差分時間を計測できる手法であれば、どのような手法を用いてもよい。
以上説明した実施形態により、電子楽器において、音色の種類や、その他の機能の稼働状態に応じて変化するCPUの負荷を、レスポンス計測用コマンドを介して実測することで、その時点における最適な同時発音数を定常的に適用できるようになるので、CPUパワーの不足で大きな遅延が発生して演奏に支障を来したり、不要な制限でCPU能力を持て余したりすることなく、CPUの能力を常に100%に近い形で引き出すことが可能な電子楽器を実現できる。
以上の実施形態に関して、更に以下の付記を開示する。
(付記1)
複数音を同時発音する音源と、
音源コマンドバッファから、前記音源の制御に関する複数の音源コマンドを読み出して実行する処理部と、
を備え、
前記処理部は、
前記音源コマンドが前記音源コマンドバッファに書き込まれてから、前記音源コマンドが前記音源コマンドバッファから読み出されるまでの差分時間に応じて、前記音源における同時発音数を制御する、電子楽器。
(付記2)
前記処理部は、
前記音源コマンドバッファに、現在時刻を記録したレスポンス計測用コマンドを定期的に書き込み、
前記音源コマンドバッファから前記レスポンス計測用コマンドを読み出すときの現在時刻と前記読み出したレスポンス計測用コマンドに記録されている現在時刻との差分時間として前記差分時間を計測する、
付記1に記載の電子楽器。
(付記3)
前記処理部は、前記差分時間に応じて前記音源における最大同時発音数を変更した場合に、前記変更後の最大同時発音数が現在の同時発音数を下回った場合に、過剰に発音されている分の発音ボイスをスローダンプ処理により消音させる、付記1又は2に記載の電子楽器。
(付記4)
複数音を同時発音する音源と、音源コマンドバッファから、前記音源の制御に関する複数の音源コマンドを読み出して実行する処理部と、を備えた電子楽器における制御方法であって、前記処理部は、
前記音源コマンドが前記音源コマンドバッファに書き込まれてから、前記音源コマンドが前記音源コマンドバッファから読み出されるまでの差分時間に応じて、前記音源における同時発音数を制御する、電子楽器の制御方法。
(付記5)
複数音を同時発音する音源と、音源コマンドバッファから、前記音源の制御に関する複数の音源コマンドを読み出して実行するコンピュータと、を備えた電子楽器において、前記コンピュータに、
前記音源コマンドが前記音源コマンドバッファに書き込まれてから、前記音源コマンドが前記音源コマンドバッファから読み出されるまでの差分時間に応じて、前記音源における同時発音数を制御するステップを、実行させるためのプログラム。