デグレファクトリー
未来の技術で高度なバグを埋め込むソフトウェア製作所
未来の技術で高度なバグを埋め込むソフトウェア製作所
※ 他プレイヤー用の 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 互換機能マニュアルをご覧ください。
この資料で解説している API バージョンは v2.x 系のものです。 v1.x 系や v3.x 系の API は仕様が異なります。
各関数の呼び出し規約は、すべて stdcall です。
各関数はスレッドセーフではありません。 同じ SNESAPU.DLL のインスタンスを複数スレッドから取り扱う場合は、クリティカルセクションなどを利用して、関数が同時に呼び出されないように実装してください。
この資料に記載されていない API については、動作保証はありません。 また、予告なく削除することがあります。
サウンドデバイスを初期化します。
このとき、出力する波形データのチャンネル、ビット、サンプリングレートを決めておきます。
SetAPUOpt 関数で、演奏に関わる基本オプションを設定します。
各引数には、サウンドデバイスを初期化したときと同じ設定を使用します。
【任意】 下記の関数を使用して、その他の演奏オプションを設定します。
これらの関数は、演奏中でも随時呼び出して設定を変更することができます。
SetAPUSmpClk - 演奏速度の設定
SetDSPAmp - 音量の設定
SetDSPEFBCT - エコーフィードバック反転度の設定
SetDSPPitch - 音程の設定
SetDSPStereo - 左右拡散度の設定
SPC ファイルを読み取り、メモリ上に格納します。
LoadSPCFile 関数で、読み取った SPC ファイルのメモリ内容を SNESAPU に転送します。
【任意】 SetAPULength 関数で、演奏時間・フェードアウトを設定します。
関数を呼び出さない場合は、エンドレス再生が行われます。
【任意】 下記の関数を使用して、Script700 互換機能、または TimerTrick 互換機能を設定します。
下記関数は同一機能を使用しており排他です。 最後に呼び出された関数が機能しますので、いずれか 1 つを使用してください。
SetScript700 - Script700 互換機能の設定
SetTimerTrick - TimerTrick 互換機能の設定
try700 - Script700 互換機能の設定 ※
※ 他プレイヤー用の SNESAPU.DLL のみに実装されている関数です。
EmuAPU 関数を呼び出して波形データを取得します。
取得した波形データをサウンドデバイスへ転送して演奏を行います。
手順 7~8 を繰り返します。
SPC700, DSP のエミュレーションを行い、波形データを生成します。
void* EmuAPU(void *pBuf, u32 len, u8 type);
引数
[out] pBuf
波形データを格納するためのバッファへのポインタを指定します。
[in] len
波形データを生成するサイズを指定します。
サイズの単位は type で指定します。
[in] type
len に指定する値の単位を指定します。
0 | 入力クロック数を基準としたサイズ。 24576000 で 1 秒分。 |
---|---|
1 | サンプル数。 サンプリングレートと同じ数で 1 秒分。 |
戻り値
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 の倍数) が使用できます。
SetAPUOpt 関数の rate に 32001 以上のサンプリングレートを指定している。
SetAPUOpt 関数の opts に 0x800 (DSP_ECHOFIR) フラグを指定している。
この関数で type に 1 を指定している。
この関数で 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);
引数
[in] pc
PC レジスタの値を指定します。
[in] a
A レジスタの値を指定します。
[in] y
Y レジスタの値を指定します。
[in] x
X レジスタの値を指定します。
[in] psw
PSW レジスタの値を指定します。
[in] sp
SP レジスタの値を指定します。
戻り値
ありません。
解説
ResetAPU 関数を呼び出して SPC700, DSP をリセットした後に、この関数を呼び出して SPC ファイルから演奏するためのレジスタを設定します。
レジスタ設定後は GetAPUData 関数によって取得した RAM や DSP レジスタのバッファへデータを転送することで、SPC の演奏準備が完了します。
通常は LoadSPCFile 関数から SPC ファイルのバッファを転送した方が簡単です。
参照
SNESAPU 内部の演奏に関するメモリを取得します。
void GetAPUData(u8 **ppRAM, u8 **ppXRAM, u8 **ppOutPort, u32 **ppT64Cnt, DSPReg **ppDSP, Voice **ppVoice, u32 **ppVMMaxL, u32 **ppVMMaxR);
引数
[out] ppRAM
64KB RAM の内容を保持したメモリへのポインタを格納するためのバッファへのポインタを指定します。
NULL を指定した場合は、バッファへコピーしません。
[out] ppXRAM
IPL ロード時に元のメモリ内容 (アドレス FFC0~FFFF) を退避しておくエミュレータ専用の拡張 RAM (128byte) の内容を保持したメモリへのポインタを格納するためのバッファへのポインタを指定します。
NULL を指定した場合は、バッファへコピーしません。
[out] ppOutPort
出力ポート (8bit * 4) の内容を保持したメモリへのポインタを格納するためのバッファへのポインタを指定します。
NULL を指定した場合は、バッファへコピーしません。
[out] ppT64Cnt
タイマーカウンタ (32bit, 64000 で 1 秒) を保持したメモリへのポインタを格納するためのバッファへのポインタを指定します。
NULL を指定した場合は、バッファへコピーしません。
[out] ppDSP
128byte DSP レジスタを保持したメモリへのポインタを格納するためのバッファへのポインタを指定します。
NULL を指定した場合は、バッファへコピーしません。
[out] ppVoice
DSP の発音状態 (8ch 分) を保持したメモリへのポインタを格納するためのバッファへのポインタを指定します。
NULL を指定した場合は、バッファへコピーしません。
[out] ppVMMaxL
出力音量レベル (32bit, 左) を保持したメモリへのポインタを格納するためのバッファへのポインタを指定します。
SetAPUOpt 関数で、値の型を int か float で選択できます。
NULL を指定した場合は、バッファへコピーしません。
[out] ppVMMaxR
出力音量レベル (32bit, 右) を保持したメモリへのポインタを格納するためのバッファへのポインタを指定します。
SetAPUOpt 関数で、値の型を int か float で選択できます。
NULL を指定した場合は、バッファへコピーしません。
戻り値
ありません。
解説
SNESAPU 内部で管理している演奏に関する一部のメモリにアクセスするためのポインタを取得できます。 取得が不要なポインタがある場合は、該当する引数に NULL を指定できます。
LoadSPCFile 関数を使用せずに演奏の準備をする場合は、ResetAPU 関数を呼び出して SPC700, DSP をリセットした後に、SPC ファイルから演奏するための RAM を ppRAM のバッファにコピーします。 同様に DSP レジスタを ppDSP のバッファにコピーします。 FixAPU 関数もあわせて参照してください。
通常は LoadSPCFile 関数から SPC ファイルのバッファを転送した方が簡単です。
演奏中に RAM, DSP レジスタを書き換える場合は、直接バッファを操作せずに InPort 関数、SetAPURAM 関数、SetDSPReg 関数を呼び出してください。 これらの関数を使用しない場合、予期しない波形データが生成されることがあります。
EmuAPU 関数を呼び出す前に ppVMMaxL と ppVMMaxR のバッファに 0 を代入しておくと、EmuAPU 関数の実行後に音量レベルが設定されます。 この値は出力された音量を示すため、サウンドインジケータなどで利用できます。
参照
EmuAPU, FixAPU, GetScript700Data, GetSPCRegs, InPort, ResetAPU, SetAPUOpt, SetAPURAM, SetDSPReg
SNESAPU 内部の Script700 に関するメモリを取得します。
void GetScript700Data(char *pDLLVer, u32 **ppSPCReg, u8 **ppScript700);
引数
[out] pDLLVer
DLL バージョンの文字列を格納するためのバッファ (最低 32byte) へのポインタを指定します。
NULL を指定した場合は、バッファへコピーしません。
[out] ppSPCReg
SPC レジスタの内容を保持したメモリへのポインタを格納するためのバッファへのポインタを指定します。
NULL を指定した場合は、バッファへコピーしません。
[out] ppScript700
Script700 のコンパイル結果を保持したメモリへのポインタを格納するためのバッファへのポインタを指定します。
NULL を指定した場合は、バッファへコピーしません。
戻り値
ありません。
解説
Script700 のワークエリアを示すポインタの他、GetAPUData 関数、SNESAPUInfo 関数では取得できない追加情報も取得できます。 取得が不要なポインタがある場合は、該当する引数に NULL を指定できます。
この関数は Script700 のデバッグ用で用意されています。 通常は使用しません。
参照
SNESAPU で使用しているすべてのメモリ内容のスナップショットを取り、コンテキスト情報としてバッファにコピーします。
u32 GetSNESAPUContext(void *pCtxOut);
引数
[out] pCtxOut
コンテキスト情報を格納するためのバッファへのポインタを指定します。
戻り値
コンテキスト情報の取得に成功したかどうかの結果が返ります。
0 は成功、0 以外の値は失敗です。 失敗した場合は、失敗の原因を示すコード値が返ります。
解説
コンテキスト情報は、1 つの SNESAPU インスタンスで複数の SPC を同時に扱ったり、逆シーク時を高速化するためのキャッシュ機構に利用したりするなどの目的で使用できます。
この関数を呼び出す直前に GetSNESAPUContextSize 関数でバッファに必要なメモリのサイズを取得してください。 GetSNESAPUContextSize 関数とこの関数の間では、他の関数を呼び出さないようにしてください。
この関数で取得したバッファは、SetSNESAPUContext 関数で使用できます。 バッファの構造や内容は SNESAPU 内部で管理していますので、変更しないでください。
この関数と SetSNESAPUContext 関数を組み合わせることで、SNESAPU の状態を複数保持し、簡単に切り替えることができます。
バッファが不要になった場合は、任意のタイミングでバッファを解放できます。 SNESAPU 側に解放したことを通知する必要はありません。
参照
SNESAPU のコンテキスト情報を格納するために必要なバッファのサイズを取得します。
u32 GetSNESAPUContextSize();
引数
ありません。
戻り値
必要なバッファのサイズ (byte) が返ります。
解説
この関数を呼び出して、戻り値のサイズ以上のバッファを確保してから GetSNESAPUContext 関数でバッファを使用してください。 バッファサイズが不足している場合は異常終了します。
参照
現在の SPC700 レジスタ値を取得します。
void GetSPCRegs(u16 *pPC, u8 *pA, u8 *pY, u8 *pX, u8 *pPSW, u8 *pSP);
引数
[out] pPC
PC レジスタの値を格納するためのバッファへのポインタを指定します。
[out] pA
A レジスタの値を格納するためのバッファへのポインタを指定します。
[out] pY
Y レジスタの値を格納するためのバッファへのポインタを指定します。
[out] pX
X レジスタの値を格納するためのバッファへのポインタを指定します。
[out] pPSW
PSW レジスタの値を格納するためのバッファへのポインタを指定します。
[out] pSP
SP レジスタの値を格納するためのバッファへのポインタを指定します。
戻り値
ありません。
解説
関数を呼び出した時点の SPC レジスタの値を、引数に指定された各バッファにコピーします。
すべての引数に有効なポインタを指定してください。 無効なポインタや NULL を指定した場合は異常終了します。
参照
SPC700 の入力ポートに値を書き込みます。
void InPort(u8 port, u8 val);
引数
[in] port
ポート番号 (0~3) を指定します。
[in] val
ポートに書き込む値を指定します。
戻り値
ありません。
解説
演奏途中で入力ポートに値を書き込むことで、SPC のサウンドドライバに各種命令を与えることができます。 例えば、効果音を鳴らすなどの動作を行います。
入力ポートと書き込む値の関係性は、SPC ファイル内に組み込まれたサウンドドライバに依存します。
出力ポートに書き込まれている値を取得する場合は、GetAPUData 関数を呼び出して、出力ポートの内容を保持したメモリへの (ppOutPort で取得した) ポインタから取得してください。
参照
SPC ファイルのバッファを読み取り DLL 内部のメモリにコピーして、新しい SPC を演奏する準備を行います。
void LoadSPCFile(void *pFile);
引数
[in] pFile
SPC ファイルの内容が格納されたバッファへのポインタを指定します。
バッファのサイズは最低でも 66048 バイト必要です。
戻り値
ありません。
解説
この関数を呼び出すと、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);
引数
[in] amp
音量を指定します。
65536 が 1 倍を基準とした値を指定します。 32768 を指定すると半分の音量で演奏します。
-1 を指定した場合は、前回の設定を維持します。
戻り値
ありません。
解説
各レジスタとメモリを初期化後 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);
引数
[in] time
シークする時間を指定します。 単位は 1/64000 秒です。
64000 を指定すると 1 秒間シークします。
[in] fast
シークする際の高速化処理方法を指定します。
0 | DSP エミュレーションを行います。 シーク動作が安定します。 |
---|---|
1 | DSP エミュレーションを行いません。 高速に動作します。 |
戻り値
ありません。
解説
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);
引数
[in] time
演奏時間を指定します。 単位は 1/64000 秒です。
64000 を指定すると 1 秒間演奏します。
[in] fade
フェードアウト時間を指定します。 単位は 1/64000 秒です。
64000 を指定すると 1 秒間フェードアウトします。
戻り値
ありません。
解説
time に指定した時間は通常の音量で演奏し、その後 fade に指定した時間をかけてフェードアウトし、最後は無音状態になります。 このフェードアウトは SetDSPVol 関数を使用しています。
全体の演奏時間は、time と fade の合計値です。 例えば演奏時間が 120 秒、フェードアウト時間が 10 秒の場合、演奏時間は 130 秒です。
LoadSPCFile 関数、ResetAPU 関数を呼び出した場合、この関数で設定した内容は解除され、フェードアウトが無効になります。
参照
SNESAPU で波形データを生成する際の基本オプションを設定します。
void SetAPUOpt(u32 mixType, u32 numChn, u32 bits, u32 rate, u32 inter, u32 opts);
引数
[in] mixType
ミキシング方法を指定します。
-1 を指定した場合は、前回の設定を維持します。 初期値は 1 です。
0 (MIX_NONE) | ミキシングを行いません。 出力結果は無音になります。 |
---|---|
1 (MIX_INT) |
|
2 (MIX_MMX) |
|
3 (MIX_FLOAT) | 内部的に 32bit-float (x87) でミキシングを行います。 最も高音質な出力が得られます。 |
[in] numChn
チャンネル数を指定します。 1, 2 が指定できます。
-1 を指定した場合は、前回の設定を維持します。 初期値は 2 です。
1 | モノラル |
---|---|
2 | ステレオ |
[in] bits
量子化ビット数を指定します。 8, 16, 24, 32, -32 が指定できます。
8~32 を指定すると整数 (int) で、-32 を指定すると浮動小数 (32bit-float) で出力します。
-1 を指定した場合は、前回の設定を維持します。 初期値は 16 です。
[in] rate
サンプリングレートを指定します。 8000~192000 の範囲で指定できます。
1 Hz 単位で指定できますが、改良版 SNESAPU.DLL では 8000, 10000, 11025, 12000, 16000, 20000, 22050, 24000, 32000, 40000, 44100, 48000, 64000, 80000, 88200, 96000, 192000 でテストされていますので、いずれかの指定が推奨です。
-1 を指定した場合は、前回の設定を維持します。 初期値は 32000 です。
[in] inter
補間処理の方法を指定します。
-1 を指定した場合は、前回の設定を維持します。 初期値は 3 です。
0 (INT_NONE) | 補間処理を使用しません。 |
---|---|
1 (INT_LINEAR) | 線形補間を使用します (2point-liner)。 |
2 (INT_CUBIC) | 三次スプライン補間を使用します (4point-cubic)。 |
3 (INT_GAUSS) | 実機と同じガウス分布補間を使用します (4point-gauss)。 |
4 (INT_SINC) | シンク関数補間を使用します (8point-sinc)。 |
5 | (将来のために予約されています。 現在は 7 と同じです) |
6 | (将来のために予約されています。 現在は 7 と同じです) |
7 (INT_GAUSS4) | 高精度ガウス分布補間を使用します (4point-gauss)。 |
[in] opts
DSP エミュレーションのオプションを指定します。 複数指定する場合はすべての値を合計した値を指定してください。
-1 を指定した場合は、前回の設定を維持します。 初期値は 0 です。
0x01 (DSP_ANALOG) | 実機と同じカットオフ周波数のローパスフィルタを使用します。 |
---|---|
0x02 (DSP_OLDSMP) | 古い BRR 復元プログラムを使用します。 現在は非推奨です。 |
0x04 (DSP_SURND) | 逆位相サラウンド効果を使用します。 |
0x08 (DSP_REVERSE) | 左右の出力を反転させます。 |
0x10 (DSP_NOECHO) | エコー機能を無効にします。 |
0x20 (DSP_NOPMOD) | ピッチモジュレーション機能を無効にします。 |
0x40 (DSP_NOPREAD) | ピッチベンド機能 (発音中の音程変更) を無効にします。 |
0x80 (DSP_NOFIR) | FIR フィルタ機能を無効にします。 |
0x100 (DSP_BASS) | BASS BOOST (低音強調) 機能を使用します。 |
0x200 (DSP_NOENV) | エンベロープ機能を無効にします。 すべての音が同一レベルで出力されます。 |
0x400 (DSP_NONOISE) | ノイズ発音機能を無効にします。 |
0x800 (DSP_ECHOFIR) | エコー/FIR などの DSP 処理を実機に近づけます (詳細は後述)。 |
0x1000 (DSP_NOSURND) | サラウンド機能を無効にします。 |
0x2000 (DSP_ENVSPD) | ※ v2.19.3 以降: エンベロープの増加・減衰速度を演奏速度と同期します。 |
0x4000 (DSP_NOPLMT) | ※ v2.20.0 以降: ピッチの最大値を 0x3FFF から 0xFFFF へ拡張します。 |
0x10000000 | (特殊操作用に予約されています) |
0x20000000 | (特殊操作用に予約されています) |
0x40000000 (DSP_FLOAT) | GetAPUData 関数で取得する出力音量レベル値を 32bit-float で出力します。 |
0x80000000 (DSP_NOSAFE) | イヤーセーフ機能を無効にします。 |
戻り値
ありません。
解説
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 の解説をご覧ください。
参照
SPC700 の 64KB RAM に値を書き込みます。
void SetAPURAM(u32 addr, u8 val);
引数
[in] addr
アドレス (0~65535) を指定します。
[in] val
アドレスに書き込む値を指定します。
戻り値
ありません。
解説
64KB RAM には 1byte ずつ書き込むことができます。 演奏前であれば、GetAPUData 関数で取得した RAM へのポインタを利用して、一度にデータを書き込むことができます。 演奏中に RAM の中身を書き換える場合は、この関数を使用してください。
現在の RAM に書き込まれている値を取得する場合は、GetAPUData 関数で取得した RAM のバッファから取得してください。
DSP レジスタへの書き込みを示すアドレス (0xF2~0xF3) に値を書き込む目的で使用する場合は、SetDSPReg 関数を呼び出してください。
I/O ポートへの書き込みを示すアドレス (0xF4~0xF7) に値を書き込む目的で使用する場合は、InPort 関数を呼び出してください。
参照
演奏速度を設定します。
void SetAPUSmpClk(u32 speed);
引数
[in] speed
演奏速度を指定します。 4096~1048576 の範囲で指定できます。 これは 1/16~16 倍に相当します。
65536 が 1 倍を基準とした値を指定します。 32768 を指定すると半分の速度で演奏します。
戻り値
ありません。
解説
演奏速度の変更は、SPC700 の動作クロック数を調整して実現しているため、ピッチ (音程) には影響しません。
LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持されます。
参照
音量を設定します。
void SetDSPAmp(u32 amp);
引数
[in] amp
音量を指定します。
65536 が 1 倍を基準とした値を指定します。 32768 を指定すると半分の音量で演奏します。
戻り値
ありません。
解説
音量を上げすぎると、イヤーセーフ機能が働き、自動的に演奏が停止します。 イヤーセーフ機能を無効にする場合は SetAPUOpt 関数で設定してください。
LoadSPCFile 関数を呼び出しても、この関数で設定した内容は維持されます。 ResetAPU 関数の引数で -1 以外を指定した場合は、この関数で設定した内容は上書きされます。
参照
エコーフィードバック反転度を設定します。
void SetDSPEFBCT(s32 leak);
引数
[in] leak
エコーフィードバック反転度を指定します。 -32768~32768 の範囲で指定できます。
32768 | 左右別々にエコーがかかります (通常)。 |
---|---|
0 | 左右両方に同じエコーがかかります。 |
-32768 | 左右にかかるエコーが反転します。 |
戻り値
ありません。
解説
エコーフィードバック反転度を強くすると (設定値を -32768 に近づけると)、エコーがかかった際に音の幅が広がります。
LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持されます。
参照
ピッチ (音程) を設定します。
void SetDSPPitch(u32 pitch);
引数
[in] pitch
ピッチを指定します。
32000 が 1 倍を基準とした値を指定します。 64000 を指定すると 1 オクターブ上がります。
戻り値
ありません。
解説
半音の上げ下げを表わすキーに換算する場合は、32000 * 2^(key/12) で求められます。
LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持されます。
参照
DSP レジスタに値を書き込みます。
b8 SetDSPReg(u8 reg, u8 val);
引数
[in] reg
アドレス (0~127) を指定します。
[in] val
アドレスに書き込む値を指定します。
戻り値
DSP レジスタの書き込みによって DSP の状態に影響があった場合は 0 以外、影響がなかった場合は 0 が返ります。
解説
DSP レジスタには 1byte ずつ書き込むことができます。 演奏前であれば、GetAPUData 関数で取得した DSP レジスタへのポインタを利用して、一度にデータを書き込むことができます。 演奏中に DSP レジスタの中身を書き換える場合は、この関数を使用してください。
現在の DSP レジスタに書き込まれている値を取得する場合は、GetAPUData 関数で取得した DSP レジスタのバッファから取得してください。
参照
左右拡散度 (パンの割り振りの度合い) を設定します。
void SetDSPStereo(u32 sep);
引数
[in] sep
左右拡散度を指定します。 0~65536 の範囲で指定できます。
65536 | パンの割り振りを強調します。 |
---|---|
32768 | パンの割り振りを標準レベルで行います (通常)。 |
0 | パンの割り振りを行いません (≒モノラル)。 |
戻り値
ありません。
解説
この関数は各チャンネルの左右音量のみを制御するため、sep に 0 を指定しても、マスタ音量・エコー音量の左右に差があると、完全にモノラルにはなりません。
LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持されます。
参照
マスタ音量を基準として、実際に出力される音量の割合を設定します。
void SetDSPVol(u32 vol);
引数
[in] vol
実際に出力される音量の割合を指定します。
65536 が 1 倍を基準とした値を指定します。 32768 を指定すると半分の音量で演奏します。
戻り値
ありません。
解説
この関数はフェードアウト用の処理として SNESAPU 内部で自動的に呼び出されます。 そのため、SetAPULength 関数でフェードアウトを設定した場合、SNESAPU によって設定が上書きされますのでご注意ください。
フェードアウト処理を独自に行う場合に、この関数を呼び出してください。
LoadSPCFile 関数、ResetAPU 関数を呼び出した場合、この関数で設定した内容はリセットされます。
参照
Script700 互換機能を設定・解除します。
s32 SetScript700(void *pSource);
引数
[in] pSource
NULL 文字で終わる Script700 コマンドの文字列が格納されたバッファへのポインタを指定します。
NULL を指定すると、Script700 互換機能を解除します。
戻り値
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);
引数
[in] addr
データをコピーする先のデータ領域のアドレスを指定します。
[in] pData
バイナリデータが格納されたバッファへのポインタを指定します。
NULL を指定すると、何もしません。
[in] 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);
引数
[in] pCtxIn
コンテキスト情報が格納されたバッファへのポインタを指定します。
戻り値
コンテキスト情報の設定に成功したかどうかの結果が返ります。
0 は成功、0 以外の値は失敗です。 失敗した場合は、失敗の原因を示すコード値が返ります。
解説
予め GetSNESAPUContext 関数で取得したコンテキスト情報を SNESAPU に転送し、スナップショットを戻します。
スナップショットを戻すと、現在の状態はすべて破棄されますので、後から現在の状態に戻したい場合は、この関数を呼び出す前に GetSNESAPUContext 関数を呼び出して別途コンテキスト情報を保持してください。
参照
TimerTrick 互換機能を設定・解除します。
void SetTimerTrick(u32 port, u32 wait);
引数
[in] port
ポート番号 (0~3、または 0xF4~0xF7) を指定します。
[in] wait
ウェイトタイム (1~0xFFFFFFFF) を指定します。
0 を指定すると、TimerTrick 互換機能を解除します。
戻り値
ありません。
解説
TimerTrick 互換機能は Script700 互換機能を利用して実現していますので、この関数を呼び出した後に SetScript700 関数を呼び出すと、TimerTrick 互換機能は自動的に無効化されます。
LoadSPCFile 関数、ResetAPU 関数を呼び出しても、この関数で設定した内容は維持され、Script700 関連の初期化を行いません。 無効の状態に戻すには、port に任意の値、wait に 0 (NULL) を指定してこの関数を呼び出してください。
この関数を SNESAPUCallbackProc コールバック内で呼び出した場合は、何も行いません。
参照
SNESAPU のコールバックを設定します。
CBFUNC SNESAPUCallback(CBFUNC pCbFunc, u32 cbMask);
引数
[in] pCbFunc
SNESAPUCallbackProc 関数へのポインタを指定します。
[in] cbMask
コールバック対象のエフェクトを指定します。 複数指定する場合はすべての値を合計した値を指定してください。
0x01 (CBE_DSPREG) | DSP レジスタの書き込みの割り込みを有効にします。 |
---|---|
0x02 (CBE_S700FCH) | SPC700 のフェッチの割り込みを有効にします。 |
0x10000000 (CBE_REQBP) | ※ v2.19.0 以降: Script700 経由でのブレイクポイント設定を有効にします。 |
0x20000000 (CBE_INCDATA) | 追加の Script700 バイナリファイル読み込みを有効にします。 |
0x40000000 (CBE_INCS700) | 追加の Script700 テキストファイル読み込みを有効にします。 |
0x80000000 | (デバッグ用として予約されています。) |
戻り値
この関数を呼び出す前に設定されていた 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 関数の解説を参照してください。
参照
SNESAPU のコールバックを処理するための、アプリケーション側で定義する CBFUNC 型のコールバック関数です。
SNESAPUCallback 関数を呼び出してこの関数のポインタを指定することでコールバックを設定します。
SNESAPUCallbackProc 関数はアプリケーション定義のため、実際にこの名前で定義しなくてもかまいません。
u32 SNESAPUCallbackProc(u32 effect, u32 addr, u32 value, void *pData);
引数
[in] effect
コールバックされた機能のエフェクトが指定されます。
0x01 (CBE_DSPREG) | DSP レジスタに値の書き込みが要求されました。 |
---|---|
0x02 (CBE_S700FCH) | SPC700 のフェッチが実行されました。 |
0x10000000 (CBE_REQBP) | ※ v2.19.0 以降: Script700 によってブレイクポイントが要求されました。 |
0x20000000 (CBE_INCDATA) | 追加の Script700 バイナリファイルが要求されました。 |
0x40000000 (CBE_INCS700) | 追加の Script700 テキストファイルが要求されました。 |
0x80000000 | (デバッグ用として予約されています。) |
[in] addr
アドレス情報が指定されます。
値の意味は effect によって変わります。 詳細は解説を参照してください。
[in] value
エフェクト値が指定されます。
値の意味は effect によって変わります。 詳細は解説を参照してください。
[in] pData
データが格納されたバッファへのポインタが指定されます。
値の意味は effect によって変わります。 詳細は解説を参照してください。
戻り値
明確な意図がない限り、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; }
effect = 0x01 (CBE_DSPREG) の場合
DSP レジスタに値が書き込まれようとしている場合にコールバックされます。
実際に書き込まれる値は戻り値になりますので、返す値を変えることで DSP レジスタの強制上書き処理を実装することができます。
addr | DSP レジスタのアドレス (0x00~0x7F) |
---|---|
value | DSP レジスタに書き込まれようとした値 (0x00~0xFF) |
pData | 使用しません |
戻り値 | 実際に DSP レジスタに書き込む値 (0x00~0xFF) |
effect = 0x02 (CBE_S700FCH) の場合
SPC700 でフェッチが行われ、命令が実行されようとしている場合にコールバックされます。
addr | 命令コード (下位 8bit、0x00~0xFF) を含む 4byte |
---|---|
value | 次の処理内容 |
pData | 命令が保存されているポインタ。 下位 16bit は SPC700 のプログラムカウンタ (PC) に相当します。 |
戻り値 | value と同じ値。 必要に応じてフラグをセットできます (下記参照)。 |
返す値は value と同じにしますが、下位 8bit を以下の値に変更することで、動作を変更できます。
0x01 | SPC700 の動作を中止し、次の EmuAPU 関数が呼び出されるまで何もせず、タイマーも進めません。 |
---|---|
0x02 | 命令を実行せず、NOP に置き換えます。 プログラムカウンタ (PC) は進めませんが、タイマーは進めます。 |
0x03 | SPC700 の動作を中止し、DSP のエンベロープ処理も停止します。 |
effect = 0x10000000 (CBE_REQBP) の場合
Script700 を実行中にブレイクポイントが要求された (bp コマンドが実行された) 場合にコールバックされます。
addr と value のペアを記録しておき、effect = 0x02 のコールバックを受け取った際に、addr とペアになる value 値を返却するように実装してください。
複数のブレイクポイントを実現するために、このイベントは複数回実行されることがあります。 addr と value のペアは 1 つだけではなく、複数記録できるようにしてください。
addr | 停止するアドレス (effect = 0x02 の addr とのマッチングで使用) |
---|---|
value | コールバック値 (effect = 0x02 で addr が一致したときに返却する値) |
pData | 使用しません |
戻り値 | value と同じ値 |
effect = 0x20000000 (CBE_INCDATA) の場合
Script700 の構文解析で追加のバイナリファイルが必要になった場合にコールバックされます。
pData に格納されたファイル名を、SPC ファイルの相対パスで処理してファイルを読み込み、SetScript700Data 関数を呼び出してデータを追加します。 このとき、SetScript700Data 関数の addr には、このコールバック関数の addr と同じ値を指定してください。 SetScript700Data 関数の戻り値は無視してかまいません。
pData に格納されるファイル名は ASCII です。 Unicode (UTF-16LE) の API を利用する場合は、別途 MultiByteToWideChar 関数などによって変換が必要ですのでご注意ください。
ファイルの読み込みに失敗した場合は、SetScript700Data 関数を呼び出さずにコールバックを終了してください。
addr | コピー先のデータ領域のアドレス |
---|---|
value | pData のバッファサイズ (バイト) |
pData | #ib コマンドに指定されたファイル名 (ASCII) |
戻り値 | value と同じ値 |
effect = 0x40000000 (CBE_INCS700) の場合
Script700 の構文解析で追加のテキストファイルが必要になった場合にコールバックされます。
pData に格納されたファイル名を、SPC ファイルの相対パスで処理してファイルを読み込み、SetScript700 関数を呼び出してデータを追加します。 SetScript700 関数の戻り値は無視してかまいません。
pData に格納されるファイル名は ASCII です。 Unicode (UTF-16LE) の API を利用する場合は、別途 MultiByteToWideChar 関数などによって変換が必要ですのでご注意ください。
ファイルの読み込みに失敗した場合は、SetScript700 関数を呼び出さずにコールバックを終了してください。
addr | 使用しません |
---|---|
value | pData のバッファサイズ (バイト) |
pData | #i コマンドに指定されたファイル名 (ASCII) |
戻り値 | value と同じ値 |
コールバック関数内から他の SNESAPU の関数を呼び出す場合は、以下の関数に限定してください。 下記以外の関数を呼び出すと、デッドロックや異常終了の原因となります。
参照
SNESAPU のバージョン情報を取得します。
void SNESAPUInfo(u32 *pVer, u32 *pMin, u32 *pOpt);
引数
[out] pVer
SNESAPU のバージョン番号を格納するためのバッファへのポインタを指定します。
NULL を指定した場合は、バッファへコピーしません。
[out] pMin
API の互換を維持する最低のバージョン番号を格納するためのバッファへのポインタを指定します。
NULL を指定した場合は、バッファへコピーしません。
[out] pOpt
SNESAPU で定義されているフラグを格納するためのバッファへのポインタを指定します。
NULL を指定した場合は、バッファへコピーしません。
戻り値
ありません。
解説
取得が不要な情報がある場合は、該当する引数に NULL を指定できます。
pVer、pMin に格納されるバージョン番号は 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 の内容を転送します。
s32 TransmitSPC(u32 addr);
引数
[in] addr
パラレルポートのデータアドレスを指定します。 マザーボードに実装済みの LPT1 を使用する場合、通常は 0x378 です。
外付けカードなどで増設した場合は、カードの仕様書を参照するか、デバイスマネージャからリソースの I/O の範囲をご覧ください。
戻り値
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 関数を使用してください。
参照
※ 他プレイヤー用の SNESAPU.DLL で使用可能。 SNES SPC700 Player 付属の SNESAPU.DLL は不可
SPC の内容を外部機器 (SHVC-SOUND, G.I.M.I.C) に転送します。
s32 TransmitSPCEx(TRANSMITSPCEX *table);
引数
[in] table
外部機器に転送するためのオプションが格納された構造体へのポインタを指定します。
TRANSMITSPCEXLPT 構造体、または、TRANSMITSPCEXCALLBACK 構造体を使用してください。 構造体の仕様は、SNESAPU.cpp を参照してください。
戻り値
外部機器への通信結果が返ります。 0 は成功、0 以外の値は失敗です。 失敗した場合は、失敗の原因を示すコード値が返ります。
パラレルポート経由で通信した場合は、TransmitSPC を参照してください。
解説
この関数を呼び出す前に LoadSPCFile 関数で SPC ファイルを DLL へ転送して、演奏の準備を行ってください。
table の cbSize パラメータには、構造体のサイズを指定します。
table の bScript700 パラメータに true を指定すると、別スレッドで Script700 の実行が自動的に行われます。 TransmitSPC 関数とは異なり、EmuAPU 関数を別途呼び出す必要はありません。
table の transmitType パラメータには、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) が渡されます。
参照
※ 他プレイヤー用の SNESAPU.DLL で使用可能。 SNES SPC700 Player 付属の SNESAPU.DLL は不可
Script700 ファイルを読み込む一連の処理を自動的に行います。
u32 try700(void *pFile);
引数
[in] pFile
NULL 文字で終わる SPC ファイルのパスが格納されたバッファへのポインタを指定します。
文字コードは ASCII と Unicode (UTF-16LE) の両方に対応しています。 正しい判別のために、必ず 4 バイト以上のバッファを指定してください。
戻り値
デバッグ用のための処理結果を表すコード値が返ります。 無視してもかまいません。
解説
この関数は互換のために残されていますが、当面の間サポートされます。
この関数を呼び出すことで、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 系で発生していたもののうち、修正された不具合の内容です。 () 内は修正されたバージョンです。
モノラル再生時に右側の音が入らない (v2.3.0)。
ステレオ再生時、ReverseStereo モードが効かない (v2.3.0)。
演奏中にエコーを無効にして再度エコーを有効にするとノイズが発生することがある (v2.4.3)。
エコーを使用する曲を演奏中、エコーが極端に弱くなったタイミングで CPU 使用率が異常に高くなる (v2.7.0)。
32bit-float で出力すると、内部計算ミスにより音量が異常に高く音割れする (v2.8.2)。
シーク時に DSP レジスタ更新を行っていないため、シーク直後から演奏がおかしくなる (v2.9.2)。
シーク時にミキシングフラグが正常に初期化されない (v2.10.1)。
KON のタイミングが速すぎるため、特定の曲で発音時に音量異常になることがある (v2.11.1)。
影響するゲーム : かまいたちの夜、ドラゴンクエスト3、Outer World
DSP レジスタの ENDX フラグが KON 時に初期化されない (v2.11.3)。
影響するゲーム : (未確認)
スタック処理が間違っているため RET 命令で暴走し、特定の曲の演奏が進まない (v2.11.8)。
影響するゲーム : 四柱推命学入門
Gain DIRECT 処理のタイミングに問題があり、特定の曲で音抜けが発生する (v2.12.3)。
影響するゲーム : 悪魔城ドラキュラXX
ADSR 処理のタイミングに問題があり、特定の曲でエンベロープが減衰しない (v2.13.3)。
影響するゲーム : デュアルオーブ2
オペコード処理の誤りにより、特定の曲で効果音が鳴らない (v2.14.4)。
影響するゲーム : 桃太郎電鉄
ADSR 処理の挙動に問題があり、特定の曲でエンベロープが減衰しない (v2.15.6)。
影響するゲーム : 蓬莱学園の冒険
ノイズジェネレータの実装が間違っているため、ノイズとピッチモジュレーションを併用した特定の曲で音が異なる (v2.17.6)。
影響するゲーム : ファイナルファンタジー6
EmuAPU で微小サイクル数を指定すると DSP エミュレーションが実行されない (v2.18.2)。
EmuAPU で命令実行サイクルちょうどを指定すると 2 度フェッチされる (v2.18.2)。
BRK 命令で意図せず BF, IF フラグがスタックされる (v2.18.2)。 ※ v3.0 系では修正済み
影響するゲーム : (未確認)
KON 直後の KOFF 参照タイミングが速すぎるため、一部の音が鳴らない (v2.18.4)。
影響するゲーム: Asterix
16bit 演算系命令において、RAM 領域をオーバーフロー参照する (v2.18.4)。
影響するゲーム : (未確認)
[dp+X], [dp]+Y パラメータで、ダイレクトページ領域をオーバーフロー参照する (v2.18.4)。
影響するゲーム : (未確認)
SETP 命令で意図せず PSW の I フラグが 0 になる (v2.18.4)。
影響するゲーム : (未確認)
FIR フィルタのオーバーフロー処理が実機と異なるため、大きいエコーで減衰しない (v2.19.0)。
影響するゲーム : スーパードンキーコング2
EmuAPU で約 87 秒以上の一括エミュレーションができない (v2.19.1)。
ADSR 処理の挙動に問題があり、特殊な条件でエンベロープが DECAY から SUSTAIN を飛ばし RELEASE へ移行し消音する (v2.19.1)。
影響するゲーム : (自作 SPC)
エコーのメモリ格納順序が実機と逆のため、演奏中に EDL を変更すると、エコーのかかり具合が実機と異なる (v2.19.4)。
影響するゲーム : (自作 SPC)
FIR フィルタの処理順序が実機と逆のため、ギターのオーバードライブ効果が出ない (v2.20.0)。
影響するゲーム : (自作 SPC)