デグレファクトリー

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

他プレイヤー用の SNESAPU.DLL のみに実装されている API です。

SNESAPU.DLL は、スーパーファミコンのサウンドボード (SHVC-SOUND ユニット) のエミュレータが内蔵されたライブラリです。 本家は Alpha-II Productions 様が開発しています。

IC チップや電子回路の解析が行われる前のブラックボックステストによって開発されたエンジンであるため、後期のエミュレータと比較してクロック単位での再現性は劣りますが、実機では実現できない高音質な出力のサポートと高速処理を実現しています。

このサイトで公開している改良版 SNESAPU.DLL は、本家の SNESAPU.DLL に独自の改良を加えたものです。 具体的な改良点には、不具合の修正・再現性の改善・機能の追加があります。

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

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

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

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

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

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

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

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

    各引数には、サウンドデバイスを初期化したときと同じ設定を使用します。

  3. 【任意】 下記の関数を使用して、その他の演奏オプションを設定します。

    これらの関数は、演奏中でも随時呼び出して設定を変更することができます。

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

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

  5. 【任意】 SetAPULength 関数で、演奏時間・フェードアウトを設定します。

    関数を呼び出さない場合は、エンドレス再生が行われます。

  6. 【任意】 下記の関数を使用して、Script700 互換機能、または TimerTrick 互換機能を設定します。

    下記関数は同一機能を使用しており排他です。 最後に呼び出された関数が機能しますので、いずれか 1 つを使用してください。

    他プレイヤー用の SNESAPU.DLL のみに実装されている関数です。

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

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

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

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

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

引数

戻り値

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

例えばバッファに 256byte 書き込まれた場合、pBuf のアドレスより 256 加算された値が返ります。

解説

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

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

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

代わりに type に 0 を指定した場合、書き込まれるサイズは一定になりません。 この場合、pBuf に指定するバッファは若干多めのサイズでメモリを確保し、戻り値と pBuf の差から実際に書き込まれたサイズを算出してください。

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

※ v2.20.0 以降: 以下の条件をすべて満たす場合、サンプリングレートコンバータの都合により、ノイズが発生する場合があります。 条件 1~3 を満たしたまま回避するためには、len に 1ms 単位でサイズを指定すると簡単です。 例えばサンプリングレートが 48000 Hz の場合、len には 48 の倍数 (48, 96, 144, ...) を指定します。 44100・88200 Hz の場合は 10ms 単位 (441・882 の倍数) での指定が理想ですが、1 秒以下に限り 1ms 単位 (44・88 の倍数) が使用できます。

  1. SetAPUOpt 関数の rate に 32001 以上のサンプリングレートを指定している。

  2. SetAPUOpt 関数の opts に 0x800 (DSP_ECHOFIR) フラグを指定している。

  3. この関数で type に 1 を指定している。

  4. この関数で len に指定した値を計算式 (len * 32000 / サンプリングレート) に当てはめたとき、小数が発生する。

参照

GetAPUData, LoadSPCFile, SeekAPU, SetAPUOpt, TransmitSPC, TransmitSPCEx

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

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

参照

EmuAPU, FixAPU, GetScript700Data, GetSPCRegs, InPort, ResetAPU, SetAPUOpt, SetAPURAM, SetDSPReg

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

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

引数

戻り値

ありません。

解説

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

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

参照

GetAPUData, SetScript700, SetScript700Data, SNESAPUInfo

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

u32 GetSNESAPUContext(void *pCtxOut);

引数

戻り値

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

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

解説

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

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

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

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

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

参照

GetSNESAPUContextSize, SeekAPU, SetSNESAPUContext

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, try700) は、別途設定関数を呼び出して再設定する必要があります。

参照

FixAPU, ResetAPU, SeekAPU, SetAPULength, SetDSPVol, SetScript700, SetTimerTrick, TransmitSPC, TransmitSPCEx, try700

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

void ResetAPU(u32 amp);

引数

戻り値

ありません。

解説

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

この関数を呼び出した直後の状態は、SHVC-SOUND のリセットを行った直後と同じ状態です。 ただし、SetAPULength, SetDSPVol 以外の関数で行った設定は維持されたままです。

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

amp に -1 以外を指定した場合は、SetDSPAmp 関数を呼び出して音量設定を上書きします。

参照

FixAPU, GetAPUData, LoadSPCFile, SeekAPU, SetAPULength, SetDSPAmp, SetDSPVol, SetScript700, SetTimerTrick, try700

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

void SeekAPU(u32 time, u8 fast);

引数

戻り値

ありません。

解説

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

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

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

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

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

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

参照

EmuAPU, GetSNESAPUContext, LoadSPCFile, ResetAPU, SetAPUSmpClk, SetSNESAPUContext

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

void SetAPULength(u32 time, u32 fade);

引数

戻り値

ありません。

解説

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

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

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

参照

LoadSPCFile, ResetAPU, SetDSPVol

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 関数を呼び出しても、この関数で設定した内容は維持されます。

0x800 (DSP_ECHOFIR) のあり/なしによる動作の違いは、下記のとおりです。

動作

フラグあり

フラグなし

エコー作業用メモリ

64KB RAM にエコー処理途中の結果を書き込みます

書き込みません

FIR フィルタ

※ v2.19.0 以降: 16bit エミュレーション

17bit エミュレーション (高音質)

オーバーフロー処理

※ v2.20.0 以降: オーバードライブ効果あり

歪み防止処理あり

サンプリングレート変換

※ v2.20.0 以降: 32kHz で生成後にアップサンプリング

波形復元時からアップサンプリング (高音質)

※ v2.19.5 以前: rate に 32000 以外の値を指定した場合、サンプリングレートコンバータや内部変換処理の都合により、曲によっては再現性が極端に落ちる場合があります。 可能であれば SNESAPU では 32000 で波形データを生成し、別途高精度なサンプリングレートコンバータによって、目的の周波数へ変換してください。

※ v2.20.0 以降: rate に 32001 以上の値を指定し、かつ、opts に 0x800 (DSP_ECHOFIR) を指定した場合、v2.19.5 以前よりも実機に近い音が生成されますが、特定の条件下においてノイズが発生する場合があります。 詳細な発生条件については EmuAPU の解説をご覧ください。

参照

EmuAPU, GetAPUData, 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);

引数

戻り値

ありません。

解説

演奏速度の変更は、SPC700 の動作クロック数を調整して実現しているため、ピッチ (音程) には影響しません。

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

参照

LoadSPCFile, ResetAPU, SeekAPU

音量を設定します。

void SetDSPAmp(u32 amp);

引数

戻り値

ありません。

解説

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

LoadSPCFile 関数を呼び出しても、この関数で設定した内容は維持されます。 ResetAPU 関数の引数で -1 以外を指定した場合は、この関数で設定した内容は上書きされます。

参照

LoadSPCFile, ResetAPU, SetAPUOpt, SetDSPVol

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

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, SetDSPAmp

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

s32 SetScript700(void *pSource);

引数

戻り値

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

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

1 以上

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

0

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

-1

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

解説

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

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

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

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

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

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

参照

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

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

s32 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 モードとして動作します。

参照

GetScript700Data, SetScript700, SNESAPUCallback, SNESAPUCallbackProc

バッファにコピーされたコンテキスト情報から、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 関数を呼び出しても、この関数で設定した内容は維持され、Script700 関連の初期化を行いません。 無効の状態に戻すには、port に任意の値、wait に 0 (NULL) を指定してこの関数を呼び出してください。

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

参照

LoadSPCFile, ResetAPU, SetScript700, SNESAPUCallbackProc

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

CBFUNC SNESAPUCallback(CBFUNC pCbFunc, u32 cbMask);

引数

戻り値

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

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

解説

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

Script700 互換機能の bp, #i, #ib コマンドを有効にする場合は、SNESAPU.DLL を LoadLibrary 関数でロード後にこの関数を 1 度だけ呼び出します。 その際、pCbFunc には SNESAPUCallbackProc 関数へのポインタ、cbMask にはコールバックを受け取るフラグ値 (0x70000000) を指定します。 コールバック処理については SNESAPUCallbackProc 関数の解説を参照してください。

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

参照

SetScript700, SetScript700Data, SNESAPUCallbackProc, try700

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 の関数を呼び出す場合は、以下の関数に限定してください。 下記以外の関数を呼び出すと、デッドロックや異常終了の原因となります。

参照

SetScript700, SetScript700Data, SNESAPUCallback, try700

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 固定です。

参照

GetScript700Data

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

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

s32 TransmitSPC(u32 addr);

引数

戻り値

SHVC-SOUND への通信結果が返ります。 0 は成功、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 を呼び出した後、自動的に演奏が開始されます。

Script700 の処理を自動化する場合は、TransmitSPCEx 関数を使用してください。

参照

EmuAPU, LoadSPCFile, SetScript700, TransmitSPCEx

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

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

s32 TransmitSPCEx(TRANSMITSPCEX *table);

引数

戻り値

外部機器への通信結果が返ります。 0 は成功、0 以外の値は失敗です。 失敗した場合は、失敗の原因を示すコード値が返ります。

パラレルポート経由で通信した場合は、TransmitSPC を参照してください。

解説

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

tablecbSize パラメータには、構造体のサイズを指定します。

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

tabletransmitType パラメータには、TRANSMIT_TYPE_LPT, TRANSMIT_TYPE_GIMIC, TRANSMIT_TYPE_CALLBACK のいずれかの定数を指定します。

1 (TRANSMIT_TYPE_LPT)

パラレルポート経由で SHVC-SOUND と通信するために最適化された手法で実行します。 TRANSMITSPCEXLPT 構造体を使用してください。

2 (TRANSMIT_TYPE_GIMIC)

G.I.M.I.C と通信するために最適化された手法で実行します。 TRANSMITSPCEXCALLBACK 構造体を使用してください。

3 (TRANSMIT_TYPE_CALLBACK)

I/O 処理を独自実装したい場合に指定します。 TRANSMITSPCEXCALLBACK 構造体を使用してください。

SNESAPU から I/O ポートの読み込み・書き込みが要求されたとき、pCallbackRead, pCallbackWrite に指定したコールバック関数が呼び出されます。

第1引数はポート番号 (0~3)、第2引数 (書き込み時のみ) は書き込む値 (8bit) が渡されます。

参照

EmuAPU, LoadSPCFile, TransmitSPC

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

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

u32 try700(void *pFile);

引数

戻り値

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

解説

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

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

LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持され、初期化を行いません。 無効の状態に戻すには、この関数を再度呼び出してください。 Script700 ファイルが検出されない場合、Script700 は解除されます。 Script700 ファイルの有無にかかわらず強制的に無効化する場合は、SetScript700 関数を呼び出し、pSource に NULL を指定してください。

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

参照

LoadSPCFile, ResetAPU, SetScript700, SNESAPUCallback, SNESAPUCallbackProc

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