デグレファクトリーデグレファクトリー

未来の技術で高度なバグを埋め込むソフトウェア製作所

改良版 SNESAPU.DLL は、原作・本家の Alpha-II Productions で公開されている SNESAPU.DLL に独自の改良を加えたものです。

具体的な改良点には、バグの修正、再現性の改善、機能の追加があります。

この資料では SNESAPU.DLL に搭載されている各 API 仕様と、TimerTrick, Script700 (SE) の互換機能を利用するための API 仕様、その他の独自拡張機能について説明しています。

SPC の演奏に必要な API の解説のみを記載していますので、その他の API については本家サイト (Alpha-II Productions) のサンプル コードをご覧ください。

改良版 SNESAPU.DLL は、保存しただけでは演奏できない SPC ファイルをなるべく演奏させるための拡張規格、TimerTrick, Script700, Script700 SE に互換対応しております。

TimerTrick 互換機能は、木下氏が立案され、黒羽氏、PEN@海猫氏が実装された TimerTrick 規格に互換性があります。

Script700 互換機能は、41568k 氏が立案・実装された Script700 規格の一部の命令と、木下氏が立案・実装された Script700 SE 規格の一部の命令に互換性があります。

Script700 の構文については、Script700 互換機能マニュアルをご覧ください。

  1. サウンド デバイスを初期化します。

    このとき、出力する波形データのチャンネル、ビット、サンプリング レートを決めておきます。

  2. SetAPUOpt 関数で、演奏に関わる基本オプションを設定します。

    基本的に、サウンド デバイスを初期化したときと同じ設定を使用します。

  3. 必要であれば、その他の演奏オプションを設定します。 使用する関数は以下の通りです。

  4. SPC ファイルを読み取り、メモリ上に格納します。

  5. LoadSPCFile 関数で、読み取った SPC ファイルのメモリ内容を SNESAPU に転送します。

  6. 必要であれば、Script700 互換機能、または TimerTrick 互換機能を設定します。 使用する関数は以下の通りです。

  7. EmuAPU 関数を呼び出して波形データを取得します。

  8. 取得した波形データをサウンド デバイスへ転送して演奏を行います。

  9. 手順 7~8 を繰り返します。

SPC700, DSP のエミュレーションを行い、波形データを生成します。

void* EmuAPU(void *pBuf, u32 len, u8 type);

引数

戻り値

pBuf で指定されたバッファに書き込まれた波形データの終端ポインタが返ります。

解説

len に指定された長さの分だけ SPC700 と DSP のエミュレーションを行い、生成された波形データを pBuf に指定されたバッファにコピーします。

この関数を呼び出す前に SetAPUOpt 関数と LoadSPCFile 関数を呼び出して、演奏の準備を行う必要があります。 その後はこの関数を続けて呼び出すことで、連続した波形データを取得できます。

通常、バッファ サイズの計算をしやすくするために type には 1 を指定します。 この場合、len に指定する値はバイト数ではなくサンプル数であることにご注意ください。 例えば 2ch, 16bit, 48kHz で 3 秒のバッファを出力する場合、バッファのサイズは 2 × 2 × 48000 × 3 = 576000 バイト必要ですが、len に指定する値は 48000 × 3 = 144000 です。

生成された波形データのサイズより実際のバッファ サイズが不足している場合は異常終了します。

参照

LoadSPCFile, SetAPUOpt

SPC700, DSP のレジスタを初期化します。

void FixAPU(u16 pc, u8 a, u8 y, u8 x, u8 psw, u8 sp);

引数

戻り値

ありません。

解説

ResetAPU 関数を呼び出して SPC700, DSP をリセットした後に、この関数を呼び出して SPC ファイルから演奏するためのレジスタを設定します。

レジスタ設定後は GetAPUData 関数によって取得した RAM や DSP レジスタのバッファへデータを転送することで、SPC の演奏準備が完了します。

通常は LoadSPCFile 関数から SPC ファイルのバッファを転送した方が簡単です。

参照

GetAPUData, GetSPCRegs, LoadSPCFile, ResetAPU

SNESAPU 内部の演奏に関するメモリを取得します。

void GetAPUData(u8 **ppRAM, u8 **ppXRAM, u8 **ppOutPort, u32 **ppT64Cnt, DSPReg **ppDSP, Voice **ppVoice, u32 **ppVMMaxL, u32 **ppVMMaxR);

引数

戻り値

ありません。

解説

SNESAPU 内部で管理している演奏に関する一部のメモリにアクセスするためのポインタを取得できます。 取得が不要なポインタがある場合は、該当する引数に NULL を指定できます。

LoadSPCFile 関数を使用せずに演奏の準備をする場合は、ResetAPU 関数を呼び出して SPC700, DSP をリセットした後に、SPC ファイルから演奏するための RAM を ppRAM のバッファにコピーします。 同様に DSP レジスタを ppDSP のバッファにコピーします。 FixAPU 関数もあわせて参照してください。

通常は LoadSPCFile 関数から SPC ファイルのバッファを転送した方が簡単です。

演奏中に RAM、DSP レジスタを書き換える場合は、直接バッファを操作せずに SetAPURAM 関数、SetDSPReg 関数を呼び出してください。 これらの関数を使用しない場合、予期しない波形データが生成されることがあります。

EmuAPU 関数を呼び出す前に ppVMMaxLppVMMaxR のバッファに 0 を代入しておくと、EmuAPU 関数の実行後に音量レベルが設定されます。 この値は出力された音量を示すため、サウンド インジケータなどで利用できます。

参照

EmuAPU, FixAPU, GetSPCRegs, LoadSPCFile, ResetAPU, SetAPURAM, SetDSPReg

SNESAPU 内部の Script700 に関するメモリを取得します。

void GetScript700Data(char *pDLLVer, u32 **ppSPCReg, u8 **ppScript700);

引数

戻り値

ありません。

解説

Script700 のワーク エリアを示すポインタの他、GetAPUData 関数、SNESAPUInfo 関数では取得できない追加情報も取得できます。 取得が不要なポインタがある場合は、該当する引数に NULL を指定できます。

この関数は Script700 のデバッグ用で用意されています。 通常は使用しません。

参照

GetAPUData, SetScript700, SNESAPUInfo

※ v2.17.4 以降で使用可能

SNESAPU で使用しているすべてのメモリ内容のスナップショットを取り、コンテキスト情報としてバッファにコピーします。

u32 GetSNESAPUContext(void *pCtxOut);

引数

戻り値

コンテキスト情報の取得に成功したかどうかの結果が返ります。

0 は成功、0 以外の値は失敗です。 失敗した場合は、失敗の原因を示すコード値が返ります。

解説

コンテキスト情報は、1 つの SNESAPU インスタンスで複数の SPC を同時に扱ったり、逆シーク時を高速化するためのキャッシュ機構に利用したりするなどの目的で使用できます。

この関数を呼び出す直前に GetSNESAPUContextSize 関数でバッファに必要なメモリのサイズを取得してください。 GetSNESAPUContextSize 関数とこの関数の間では、他の関数を呼び出さないようにしてください。

この関数で取得したバッファは、SetSNESAPUContext 関数で使用できます。 バッファの構造や内容は SNESAPU 内部で管理していますので、変更しないでください。

この関数と SetSNESAPUContext 関数を組み合わせることで、SNESAPU の状態を複数保持し、簡単に切り替えることができます。

バッファが不要になった場合は、任意のタイミングでバッファを解放できます。 SNESAPU 側に解放したことを通知する必要はありません。

参照

GetSNESAPUContextSize, SeekAPU, SetSNESAPUContext

※ v2.17.4 以降で使用可能

SNESAPU のコンテキスト情報を格納するために必要なバッファのサイズを取得します。

u32 GetSNESAPUContextSize();

引数

ありません。

戻り値

必要なバッファのサイズ (byte) が返ります。

解説

この関数を呼び出して、戻り値のサイズ以上のバッファを確保してから GetSNESAPUContext 関数でバッファを使用してください。 バッファ サイズが不足している場合は異常終了します。

参照

GetSNESAPUContext

現在の SPC700 レジスタ値を取得します。

void GetSPCRegs(u16 *pPC, u8 *pA, u8 *pY, u8 *pX, u8 *pPSW, u8 *pSP);

引数

戻り値

ありません。

解説

関数を呼び出した時点の SPC レジスタの値を、引数に指定された各バッファにコピーします。

すべての引数に有効なポインタを指定してください。 無効なポインタや NULL を指定した場合は異常終了します。

参照

FixAPU, GetAPUData

SPC700 の入力ポートに値を書き込みます。

void InPort(u8 port, u8 val);

引数

戻り値

ありません。

解説

演奏途中で入力ポートに値を書き込むことで、SPC のサウンド ドライバに各種命令を与えることができます。 例えば、効果音を鳴らすなどの動作を行います。

入力ポートと書き込む値の関係性は、SPC ファイル内に組み込まれたサウンド ドライバに依存します。

出力ポートに書き込まれている値を取得する場合は、GetAPUData 関数を呼び出して、出力ポートの内容を保持したメモリへの (ppOutPort で取得した) ポインタから取得してください。

参照

GetAPUData, SetAPURAM

SPC ファイルのバッファを読み取り DLL 内部のメモリにコピーして、新しい SPC を演奏する準備を行います。

void LoadSPCFile(void *pFile);

引数

戻り値

ありません。

解説

ResetAPU 関数を呼び出してメモリを初期化後、pFile に指定されたバッファを DLL 内部のメモリにコピーします。 また、SPC ファイル内に設定されているレジスタ情報をもとに、FixAPU 関数でレジスタを初期化します。

pFile には、ファイル パスではなくファイルの内容を渡すことにご注意ください。 この関数はディスクからファイルを読み込む動作は行いません。 ファイルの読み込みはこの関数を呼び出す側 (プレイヤー側) で行う必要があります。

必ず 66048 バイト以上のメモリを確保して SPC ファイルの内容をバッファにコピーした後、そのバッファへのポインタを指定してください。 バッファ サイズが不足している場合は異常終了します。

バッファの内容は DLL 内部で用意されたメモリ上に保存されますので、この関数を呼び出した後すぐにバッファを解放、または書き換えができます。 演奏中もバッファを確保しておく必要はありません。

この関数を呼び出しても、SetAPULength, SetDSPVol 以外の関数で行った設定は維持されたままです。 したがって、ファイルに応じて設定を変更する場合 (特に SetScript700, SetTimerTrick) は、別途設定関数を呼び出して再設定する必要があります。

参照

FixAPU, ResetAPU, SetAPULength, SetDSPVol, SetScript700, SetTimerTrick

SNESAPU の演奏に関するメモリを初期化して、各レジスタ、メモリをクリアします。

void ResetAPU(u32 amp);

引数

戻り値

ありません。

解説

各レジスタとメモリを初期化後 IPL ROM をコピーして、SPC の転送準備を行います。

この関数を呼び出した直後の状態は、SHVC-SOUND のリセットを行った直後と同じ状態です。

SPC ファイルを転送する場合は LoadSPCFile 関数を使用した方が簡単です。 この関数は、入力ポート経由でデータを転送する場合に使用できます。

参照

InPort, LoadSPCFile, SetDSPAmp

指定された時間だけシークして、演奏をスキップ (早送り) します。

void SeekAPU(u32 time, u8 fast);

引数

戻り値

ありません。

解説

time で指定した分のエミュレーションを行いますが、波形データは生成しないため、EmuAPU 関数を呼び出すよりも高速に演奏をスキップすることができます。

この関数は早送りできますが、巻戻し (逆シーク) を行うことはできません。 逆シークを行うためには、LoadSPCFile 関数を呼び出して最初の状態に戻してから、想定の位置にシークする必要があります。

例えば演奏開始から 10 秒後に 7 秒の位置へ戻したい場合、この関数で -192000 を指定するのではなく、LoadSPCFile 関数を呼び出して 0 秒の位置にした後、この関数を呼び出して 7 秒後に設定します。 ただし、この方法ではシーク位置が後になるほど処理に時間がかかります。

この問題を回避するためには、演奏中定期的に GetSNESAPUContext 関数を呼び出してコンテキスト情報を記録しておきます。 逆シークを行う際、最も近い場所のコンテキスト情報を元に SetSNESAPUContext 関数を呼び出して状態を戻し、差分の時間のみをシークするようなキャッシュ機構の実装がプレイヤー側に必要です。 SNESAPU にはキャッシュ機構は実装されていません。

初期位置に戻す目的で ResetAPU 関数を使用することはできません。 ResetAPU 関数は DLL のメモリ上にコピーした SPC ファイルの内容も初期化してしまうためです。

fast に 1 を指定すると DSP のエミュレーションを行わないため、より高速に動作します。 代わりにシーク後は DSP がリセットされた状態から再開するため、一部の音が鳴らない状態から開始することがあります。

参照

EmuAPU, GetSNESAPUContext, LoadSPCFile, ResetAPU, SetSNESAPUContext

演奏時間とフェードアウト時間を設定します。

void SetAPULength(u32 time, u32 fade);

引数

戻り値

ありません。

解説

time に指定した時間は通常の音量で演奏し、その後 fade に指定した時間をかけてフェードアウトし、最後は無音状態になります。

全体の演奏時間は、timefade の合計値です。 例えば演奏時間が 120 秒、フェードアウト時間が 10 秒の場合、演奏時間は 130 秒です。

LoadSPCFile 関数、ResetAPU 関数を呼び出した場合、この関数で設定した内容は解除され、フェードアウトが無効になります。

参照

LoadSPCFile, ResetAPU

SNESAPU で波形データを生成する際の基本オプションを設定します。

void SetAPUOpt(u32 mixType, u32 numChn, u32 bits, u32 rate, u32 inter, u32 opts);

引数

戻り値

ありません。

解説

numChn, bits, rate に指定する値は、サウンド デバイスを初期化した際に指定した値と同等にしてください。 値が異なると、出力音声の異常や異常終了の原因となります。

inter の 5 以上、opts の 0x20 以上の値は独自拡張値です。 本家や互換性のない SNESAPU.DLL では使用できません。

LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持されます。

参照

LoadSPCFile, ResetAPU

SPC700 の 64KB RAM に値を書き込みます。

void SetAPURAM(u32 addr, u8 val);

引数

戻り値

ありません。

解説

64KB RAM には 1byte ずつ書き込むことができます。 演奏前であれば、GetAPUData 関数で取得した RAM へのポインタを利用して、一度にデータを書き込むことができます。 演奏中に RAM の中身を書き換える場合は、この関数を使用してください。

現在の RAM に書き込まれている値を取得する場合は、GetAPUData 関数で取得した RAM のバッファから取得してください。

DSP レジスタへの書き込みを示すアドレス (0xF2~0xF3) に値を書き込む目的で使用する場合は、SetDSPReg 関数を呼び出してください。

I/O ポートへの書き込みを示すアドレス (0xF4~0xF7) に値を書き込む目的で使用する場合は、InPort 関数を呼び出してください。

参照

GetAPUData, InPort, SetDSPReg

演奏速度を設定します。

void SetAPUSmpClk(u32 speed);

引数

戻り値

ありません。

解説

speed に指定できる値の範囲は 4096~1048576 です。 これは 1/16~16 倍に相当します。

LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持されます。

参照

LoadSPCFile, ResetAPU

音量を設定します。

void SetDSPAmp(u32 amp);

引数

戻り値

ありません。

解説

音量を上げすぎると、イヤー セーフ機能が働き、自動的に演奏が停止します。 イヤー セーフ機能を無効にする場合は SetAPUOpt 関数で設定してください。

LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持されます。

参照

LoadSPCFile, ResetAPU, SetAPUOpt

エコー フィードバック反転度を設定します。

void SetDSPEFBCT(s32 leak);

引数

戻り値

ありません。

解説

エコー フィードバック反転度を強くすると (設定値を -32768 に近づけると)、エコーがかかった際に音の幅が広がります。

LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持されます。

参照

LoadSPCFile, ResetAPU

ピッチ (音程) を設定します。

void SetDSPPitch(u32 pitch);

引数

戻り値

ありません。

解説

キーに換算する場合は、32000 * 2^(key/12) で求められます。

LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持されます。

参照

LoadSPCFile, ResetAPU

DSP レジスタに値を書き込みます。

b8 SetDSPReg(u8 reg, u8 val);

引数

戻り値

DSP レジスタの書き込みによって DSP の状態に影響があった場合は 0 以外、影響がなかった場合は 0 が返ります。

解説

DSP レジスタには 1byte ずつ書き込むことができます。 演奏前であれば、GetAPUData 関数で取得した DSP レジスタへのポインタを利用して、一度にデータを書き込むことができます。 演奏中に DSP レジスタの中身を書き換える場合は、この関数を使用してください。

現在の DSP レジスタに書き込まれている値を取得する場合は、GetAPUData 関数で取得した DSP レジスタのバッファから取得してください。

参照

GetAPUData, SetAPURAM

左右拡散度 (パンの割り振りの度合い) を設定します。

void SetDSPStereo(u32 sep);

引数

戻り値

ありません。

解説

この関数は各チャンネルの左右音量のみを制御するため、sep に 0 を指定しても、マスタ音量・エコー音量の左右に差があると、完全にモノラルにはなりません。

LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持されます。

参照

LoadSPCFile, ResetAPU

マスタ音量を基準として、実際に出力される音量の割合を設定します。

void SetDSPVol(u32 vol);

引数

戻り値

ありません。

解説

この関数はフェードアウト用の処理として SNESAPU 内部で自動的に呼び出されます。 そのため、SetAPULength 関数でフェードアウトを設定した場合、SNESAPU によって設定が上書きされますのでご注意ください。

フェードアウト処理を独自に行う場合に、この関数を呼び出してください。

LoadSPCFile 関数、ResetAPU 関数を呼び出した場合、この関数で設定した内容はリセットされます。

参照

LoadSPCFile, ResetAPU, SetAPULength

Script700 互換機能を設定・解除します。

u32 SetScript700(void *pSource);

引数

戻り値

Script700 コマンドの解析結果が返ります。

1 以上の値が返ると Script700 は有効、0 以下の値は無効です。

1 以上

DLL 内部で用意されたメモリを消費したサイズです。

0

pSource に NULL が指定されました。

-1

Script700 コマンドが多すぎるため、メモリに格納できません。

解説

Script700 コマンドはすぐに中間コード (バイナリ) に変換され、DLL 内部で用意されたメモリ上に保存されますので、この関数を呼び出した後すぐにバッファを解放、または書き換えができます。 演奏中もバッファを確保しておく必要はありません。

LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持され、初期化を行いません。 無効の状態に戻すには、pSource に 0 (NULL) を指定してこの関数を呼び出してください。

Script700 互換機能の #i, #ib コマンドを有効にする場合は、SNESAPUCallback 関数の呼び出しと SNESAPUCallbackProc 関数の実装が必要です。 実装しない場合、#i, #ib コマンドが使用できません (それ以外のコマンドは使用可能です)。

SNESAPUCallbackProc 関数を実装しないで #i, #ib コマンドに簡単に対応する場合、この関数は使用せず try700 関数を使用できます。 try700 関数は SPC の完全なファイル パスを指定することで、一部制約はありますが Script700 ファイルの読み込みを自動化します。 詳しくは try700 関数の解説を参照してください。

独自の Script700 エンジンを使用しているため、同じ Script700 コマンドでも他のプレイヤーと仕様や動作が異なる場合があります。

この関数は、SNESAPUCallbackProc コールバック内でも使用することができ、この場合は include モードとして動作します。

参照

LoadSPCFile, ResetAPU, SetScript700Data, SetTimerTrick, SNESAPUCallback, SNESAPUCallbackProc, try700

Script700 互換機能のデータ領域に任意のバイナリ データをコピーします。

u32 SetScript700Data(u32 addr, void *pData, u32 size);

引数

戻り値

Script700 データ領域へのコピー結果が返ります。

1 以上の値が返ると Script700 は有効、-1 以下の値は無効です。 0 の場合は、状態は変わりません。

1 以上

データをコピーした後の末端のアドレスです。

0

pData に NULL が指定されました。

-1

バッファ サイズが多すぎるため、メモリに格納できません。

解説

Script700 のコマンドとは別に、Script700 のデータ領域に任意のデータをコピーします。

addr はデータ領域のオフセット位置を 0 とした相対位置を指定します。 そのため、誤ったアドレスを指定しても Script700 のデータ領域以外のメモリにコピーされることはありません。

この関数を呼ぶ前に、必ず SetScript700 関数を呼び出して Script700 の内部メモリを初期化してください。

この関数は、SNESAPUCallbackProc コールバック内でも使用することができ、この場合は include モードとして動作します。

参照

SetScript700, SNESAPUCallback, SNESAPUCallbackProc

※ v2.17.4 以降で使用可能

バッファにコピーされたコンテキスト情報から、SNESAPU で使用しているすべてのメモリの内容を戻します。

u32 SetSNESAPUContext(void *pCtxIn);

引数

戻り値

コンテキスト情報の設定に成功したかどうかの結果が返ります。

0 は成功、0 以外の値は失敗です。 失敗した場合は、失敗の原因を示すコード値が返ります。

解説

予め GetSNESAPUContext 関数で取得したコンテキスト情報を SNESAPU に転送し、スナップショットを戻します。

スナップショットを戻すと、現在の状態はすべて破棄されますので、後から現在の状態に戻したい場合は、この関数を呼び出す前に GetSNESAPUContext 関数を呼び出して別途コンテキスト情報を保持してください。

参照

GetSNESAPUContext, SeekAPU

TimerTrick 互換機能を設定・解除します。

void SetTimerTrick(u32 port, u32 wait);

引数

戻り値

ありません。

解説

TimerTrick 互換機能は Script700 互換機能を利用して実現していますので、この関数を呼び出した後に SetScript700 関数を呼び出すと、TimerTrick 互換機能は自動的に無効化されます。

LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持され、初期化を行いません。 無効の状態に戻すには、port に任意の値、wait に 0 (NULL) を指定してこの関数を呼び出してください。

この関数を SNESAPUCallbackProc コールバック内で呼び出した場合は、何も行いません。

参照

LoadSPCFile, ResetAPU, SetScript700, SNESAPUCallbackProc

※ v2.17.0 以降で使用可能

SNESAPU のコールバックを設定します。

CBFUNC SNESAPUCallback(CBFUNC pCbFunc, u32 cbMask);

引数

戻り値

この関数を呼び出す前に設定されていた SNESAPUCallbackProc 関数へのポインタが返ります。

コールバック関数が指定されていなかった場合は NULL が返ります。

解説

コールバックを実装することによって、Script700 互換機能の拡張や DSP の割り込みなどを受け取ることができるようになります。 コールバックを実装していない場合は、機能上いくつかの制約が生じます。 例えば、Script700 互換機能の #i, #ib コマンド (追加ファイルの取り込み) が機能しません。

Script700 互換機能の #i, #ib コマンドを有効にする場合は、SNESAPU.DLL を LoadLibrary 関数でロード後にこの関数を 1 度だけ呼び出します。 その際、pCbFunc には SNESAPUCallbackProc 関数へのポインタ、cbMask には 0x60000000 を指定します。 すると、Script700 ファイルが読み込まれた際に #i, #ib コマンドが存在する場合、指定したコールバック関数が呼び出され #i, #ib で指定されたパスが渡されます。 実際の読み取り処理については SNESAPUCallbackProc 関数の解説を参照してください。

SNESAPUCallbackProc 関数を実装しないで #i, #ib コマンドに簡単に対応する場合、SetScript700 関数の代わりに try700 関数を使用できます。 try700 関数は SPC の完全なファイル パスを指定することで、一部制約はありますが Script700 ファイルの読み込みを自動化します。 詳しくは try700 関数の解説を参照してください。

参照

SetScript700, SNESAPUCallbackProc, try700

※ v2.17.0 以降で使用可能

SNESAPU のコールバックを処理するための、アプリケーション側で定義する CBFUNC 型のコールバック関数です。

SNESAPUCallback 関数を呼び出してこの関数のポインタを指定することでコールバックを設定します。

SNESAPUCallbackProc 関数はアプリケーション定義のため、実際にこの名前で定義しなくてもかまいません。

u32 SNESAPUCallbackProc(u32 effect, u32 addr, u32 value, void *pData);

引数

戻り値

明確な意図がない限り、value と同じ値を返してください。

値の意味は effect によって変わります。 詳細は解説を参照してください。

解説

このコールバック関数を実装する場合の基本形は以下のようになります。

u32 SNESAPUCallbackProc(u32 effect, u32 addr, u32 value, void *pData) {
	switch (effect) {
	case 0x01:
		// 処理を記述します。
		break;

	case 0x02:
		// 処理を記述します。
		break;

	:

	}

	return value;  // 明確な意図がない限り value を返します。
}

Script700 互換機能の #i, #ib コマンドに対応する場合は、以下のような実装になります。

※下記コードはイメージです。 実際の言語仕様にあわせて実装してください。

u32 SNESAPUCallbackProc(u32 effect, u32 addr, u32 value, void *pData) {
	switch (effect) {
	case 0x20000000: // #ib コマンド
	case 0x40000000: // #i コマンド
		// SPC ファイルのパスを相対として pData のパスを取得
		// 仮に SPC ファイル パス (g_SPCPath) が C:\SPC\test.spc、pData が 700\base.700 の場合、
		// 最終的に lpFile は C:\SPC\700\base.700 となるようにします。
		// pData は ASCII ですので Unicode (UTF-16LE) との混在にご注意ください。
		void* lpFile = Concat(g_SPCPath, pData);
		
		// ファイルサイズを取得
		HANDLE hFile = CreateFile(lpFile, GENERIC_READ, FILE_SHARE_READ, null,
				OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
		if (hFile == INVALID_HANDLE_VALUE) break;
		u32 temp = 0;
		u32 dwSize = GetFileSize(hFile, &temp);
		
		// ファイルを読み込む
		void *lpBuffer = malloc(dwSize);
		ReadFile(hFile, lpBuffer, dwSize, &temp, null);
		
		// Script700 を適用
		if (effect == 0x40000000) {
			// effect が 0x40000000 の場合は SetScript700 API を呼び出す
			SetScript700(lpBuffer);
		} else {
			// effect が 0x20000000 の場合は SetScript700Data API を呼び出す
			SetScript700Data(addr, lpBuffer, dwSize);
		}
		
		// ファイルをクローズしてバッファを解放
		CloseHandle(hFile);
		free(lpBuffer);
		
		break;
	}

	return value;
}

コールバック関数内から他の SNESAPU の関数を呼び出す場合は、以下の関数に限定してください。 下記以外の関数を呼び出すと、デッドロックや異常終了の原因となります。

参照

EmuAPU, GetAPUData, GetSPCRegs, SetScript700, SetScript700Data, SNESAPUCallback, SNESAPUInfo

SNESAPU のバージョン情報を取得します。

void SNESAPUInfo(u32 *pVer, u32 *pMin, u32 *pOpt);

引数

戻り値

ありません。

解説

取得が不要な情報がある場合は、該当する引数に NULL を指定できます。

pVerpMin に格納されるバージョン番号は 32bit で構成されており、下位 8bit はリビジョン番号、次の 8bit はマイナー番号、上位 16bit はメジャー番号を示します。

メジャー番号とマイナー番号は、4bit 区切りで各桁の数字を示します。 ASCII コードに変換する場合、0x30 に 4bit ごとの数値を足します。

リビジョン番号はアルファベットを示す ASCII コードが入り、リビジョン番号が 0 の場合は 0x00 (NULL)、1 の場合は 0x61 (a)、2 の場合は 0x62 (b) と続きます。

例えば、バージョン番号が v2.17.4 の場合、pVer は 0x00021764 となります。

pMin に格納されるバージョン番号は 0x00011000 固定です。

参照

ありません。

※ 他プレイヤー用の SNESAPU.DLL で使用可能。 SNES SPC700 Player 付属の SNESAPU.DLL は不可

SHVC-SOUND (実機のサウンドボード) にパラレル ポート経由で SPC の内容を転送します。

u32 TransmitSPC(u32 addr);

引数

戻り値

SHVC-SOUND への通信結果が返ります。 0 が返ると通信成功、それ以外の値は通信失敗です。

0

SHVC-SOUND との通信が成功しました。

-1

GiveIO または InpOut32 がインストールされていません。

-2

パラレル ポートが双方向通信モードではありません。

-3

ブート ローダを格納できる空きがありません。

1~9

SHVC-SOUND のリセットに失敗しました。

10~19, -10~-19

メモリローダーの転送に失敗しました。

20~29, -20~-29

SPC ファイル イメージの転送に失敗しました。

解説

SHVC-SOUND への通信には、予め GiveIO または InpOut32 のインストール、25pin パラレル ポート (双方向通信)、データ通信回路が必要です。 データ通信回路図は http://www.raphnet.net/electronique/snes_apu/snes_apu_en.php を参照してください。

この関数を呼び出す前に LoadSPCFile 関数で SPC ファイルを DLL へ転送して、演奏の準備を行ってください。

Script700 を動作させる場合には、この関数を呼び出す前に SetScript700 関数を呼び出してください。 その後、EmuAPU 関数を非常に短い間隔で呼び出すことで、Script700 が動作し SHVC-SOUND のポートへ書き込みが行われます。

EmuAPU 関数を呼び出す間隔が小さいほど細かなポート制御ができます。 単純な転送であれば 5ms 程度で十分ですが、多量のデータをやりとりする必要がある場合は非常に細かい間隔で実行する必要があります。

Script700 を使用しない場合は EmuAPU 関数を呼び出す必要はありません。 TransmitSPC を呼び出した後、自動的に演奏が開始されます。

参照

EmuAPU, LoadSPCFile, SetScript700, TransmitSPCEx

※ v2.17.1 以降で使用可能

※ 他プレイヤー用の SNESAPU.DLL で使用可能。 SNES SPC700 Player 付属の SNESAPU.DLL は不可

SPC の内容を外部機器 (SHVC-SOUND, G.I.M.I.C) に転送します。

u32 TransmitSPCEx(TRANSMITSPCEX *table);

引数

戻り値

外部機器への通信結果が返ります。 0 が返ると通信成功、それ以外の値は通信失敗です。

解説

G.I.M.I.C への通信を行う「黒猫GMC」などのフロントエンド ソフトウェアのために用意されている関数です。

この関数を呼び出す前に LoadSPCFile 関数で SPC ファイルを DLL へ転送して、演奏の準備を行ってください。

tablebScript700 パラメータに true を指定すると、別スレッドで Script700 の実行が自動的に行われます。 TransmitSPC 関数とは異なり、EmuAPU 関数を別途呼び出す必要はありません。

参照

EmuAPU, LoadSPCFile, TransmitSPC

※ 他プレイヤー用の SNESAPU.DLL で使用可能。 SNES SPC700 Player 付属の SNESAPU.DLL は不可

Script700 ファイルを読み込む一連の処理を自動的に行います。

u32 try700(void *pFile);

引数

戻り値

デバッグ用のための処理結果を表すコード値が返ります。 無視してもかまいません。

解説

この関数は互換のために残されていますが、当面の間サポートされます。

この関数を呼び出すことで、SPC ファイルのパスをもとに Script700 ファイルを読み込み実行するための一連の処理を自動的に実行します。 この処理には、Script700 互換機能の #i, #ib コマンドの対応も含まれます。

Script700 ファイルが圧縮されていない状態でディスク上に保存されていることを前提として動作しますので、圧縮ファイルから展開する場合はプレイヤー側で対応する必要があります。 例えば、この関数を使わず SetScript700 関数を独自に呼び出し SNESAPUCallbackProc を実装する方法や、この関数を呼び出す前に圧縮ファイルを一時的にすべて展開する方法があります。

参照

SetScript700, SNESAPUCallback, SNESAPUCallbackProc

本家 SNESAPU.DLL v2.0 系で発生していたもののうち、修正された不具合の内容です。 () 内は修正されたバージョンです。