﻿■更新履歴
[2019-02-17 v0.14]
psf loaderにバグがあったのを修正。

[2018-08-10 v0.13]
All plugins: 初めてviopsfをinstallしたときにSPU plugin nameのコンボボックスのカーソルがセットされないのを修正。
foo_input_viopsf: foobar2000 SDKをv1.4用に更新。このバージョンからはfoobar2000v1.3以降が必要になります。
SPUプラグインも更新。
* foobar2000v1.4では本体側でdecoderのon/off切り替えが可能になったため、foo_psf_modは削除しました。


[2018-07-22 v0.12]
no$psxのContentsを参考にしてSPUレジスタに8bitの値を書き込むときの挙動を変更。
なお現在のpcsxrの仕様ではContentsに書かれている通りにはできないが、おそらく8bitの値をSPUに書き込むことはあまりないと思うので問題ないかと。
SPUプラグインも更新。
コンパイラをVC++2017に更新。


[2018-05-19 v0.11]
Crash Team Racingのpsfを鳴らせるようにパッチを当てることにした(*1)
その他細かい修正。
foo_input_viopsf: input_singletrack_factory_ex_tで
                  input_entry::flag_parallel_reads_slowを指定するようにした。

あと多分PAL ripだから問題が起きやすいのではないと思います。
driver作成者のコーディングミスでしょう。
psfのdebugの際にはpsflabでEmulation SettingsをHarsh compatibility modeにしたときにも
ちゃんと鳴らせるかを確認したほうが良いと思います。

*1
パッチは2箇所当てている。
1箇所目は、
8002571C: jal   0x800756A8
を
8002571C: jal   0x8002d394
にするパッチ。
sub_8002d394はjr $raするだけのnullsubである。
sub_800756a8内で、
800756B8: jalr  $v0
というコードがあるが、このとき$v0に0が入っているために
jalr 0x00000000
が実行されてしまう。
なお
8002571C: jal   0x800756A8
は、dma4でadpcmサンプルを転送中にv-blank割り込みが入ったときにしか実行されないらしい。
ゆえにfoo_psfやpsflabではEmulation SettingsがFriendly compatibility modeの場合は問題ないが、
Harsh compatibility modeの場合は再生できない。

もう一箇所のパッチは、
80029BA8: addiu $a1, $a0, 0x0008
80029BAC: sw    $a0, 0x0878($gp)
80029BB0: sw    $a1, 0x08B0($gp)
80029BB4: lbu   $v1, 0x0004($a0)
80029BB8: nop
を
80029BA8: nop
80029BAC: addiu $a1, $a0, 0x0008
80029BB0: sw    $a0, 0x0878($gp)
80029BB4: lbu   $v1, 0x0004($a0)
80029BB8: sw    $a1, 0x08B0($gp)
と変更する。

sub_80029BA8は
80010134: jal   0x80029BA8
80010138: lw    $a0, 0x8100($a0)
にて呼び出されるが、
viopsf(というよりpcsxr)では、このlw $a0, 0x8100($a0)の部分でロード遅延が発生すると考えて、
addiu $a1, $a0, 0x0008を計算するとき、lw $a0, 0x8100($a0)の命令実行前の$a0の値で計算しているらしい。
このパッチを当ててやるとlw $a0, 0x8100($a0)の命令実行後の$a0の値で計算されるようになる。

ただこれはpsf側の問題ではなくviopsf(というよりpcsxr)の
ロード遅延スロットのエミュレーションが間違っているせいかもしれない。
実機で確認しないとわからない。
パッチ1に関してはほぼ間違いなくpsf側のバグだと思うので、psf側を修正したほうが良いと思う。


[2018-02-25 v0.10]
Crash Bandicoot 2と3のpsfを鳴らせるようにパッチを当てた(*1)。
デバッグの際、aosdkのpsx_hw.cとeng_psf.cに書かれたコメントを参考にさせてもらいました。Thanks R. Belmont!

Brave Fencer MusashiのSword Fightはvhと組み合わせるvbが間違っている
もしくはそもそもseqに対して組み合わせるvh自体が間違っている
と思われます。

foobar2000でfoo_wave_seekbarなどの特定のcomponent使用時にフリーズするのはviopsfがマルチインスタンスに対応していないからだと思います。
これは現在のviopsfの仕様では対応できないので、foobar2000を使用している方はfoo_psfを使用したほうが良いでしょう。

*1
具体的には
800118B8: beq   $v1, $0, 0x800118B0
を
800118B8: beq   $v0, $0, 0x800118B0
に変えるパッチ。
このあたりではおそらくdma4でspu ramにadpcmサンプルを転送していて、
TestEventで転送終了したかどうかチェックし、転送終了したらループを抜けるようにしたいのだと思うが、
なぜかTestEventの戻り値が入っている$v0ではなく$v1の値を参照して分岐している。
なので$v0の値により分岐するようにパッチを当てた。
ちなみにfoo_psfやpsflabでもEmulation SettingsをHarsh compatibility modeにすると無音になる。
おそらく実機でも無音になるのでは?
psf側をきちんと修正したほうが良いと思う。


[2017-11-11 v0.09]
psxMemRead16らのmain ramにアクセスする関数内でpsxRegs.cycleに+1しているのを削除。
8byteや32byteの値を読み書きするcpu命令でもspuレジスタにアクセスできるようにした(*1)。
spuのサンプル出力のタイミングをより正確にした。
チョコボの不思議なダンジョン2のモンスター村のpsfが正しく鳴らないので、パッチを当てるようにした(*2)。
その他細かい変更。
SPUプラグインも更新。

*1
チョコボの不思議なダンジョン2のpsfドライバーはlbu命令でspuレジスタにアクセスすることがあるようだ。
モンスター村1のpsfで音量が小さくなることがあったのを修正できた。

*2
main ramの0x80106a6cに0x0feef103という値が書いてあるが、
これを0x00000000にする必要があるらしい。
どうやらこの値はspuの各channelをmuteするかどうかを表しているようだ。
bitが立っている場合そのchannelはmuteされてしまう。


[2017-09-17 v0.08]
zlibを v1.2.11に更新。
メタルギアソリッドのpsfを鳴らせるように修正。
HLE BIOSのコードを結構変更したので、他のpsfで問題が起きるかもしれません。
そのときは前バージョンのviopsf.binに差し替えてみてください。
KbMedia Player用プラグインのサポートを終了。Kobarin氏がもっとマトモなものを開発してくださっているようなので(Kobarin氏に感謝です)。
その他細かい修正。
SPUプラグインも更新。

[2016-06-25 v0.07]
foo_input_viopsf: ConverterやReplayGainScan使用時にもvolumeタグ、設定画面のvolumeの値を反映させるようにした。
                  volumeタグの値を反映させたくない場合はIgnore volume tagオプションを使用してください。
* SPUプラグインも更新
あまり開発意欲が沸かなくなったので、今後はあまり更新しないかもしれません。

[2015-11-29 v0.06]
SPUプラグインをコンボボックスで選択するようにした。
* SPUプラグインも更新

[2015-10-03 v0.05]
DMA Interrupt要求のタイミングを変更。FF9の107 Vamo' Alla Flamenco.psf が鳴るようになった。
* SPUプラグインも更新

[2015-09-12 v0.04]
Recompiler使用時に出力サンプルを取りこぼす可能性が(僅かだが)あったのを修正。
foo_input_viopsf: ReplayGainScanタグが存在する場合にもvolumeタグの値を反映させるようにした。
                  volumeタグの値を反映させたくない場合はIgnore volume tagオプションを使用してください。
Winamp 2.x/5.x用プラグインとKbMedia Player用プラグインを追加。
その他細かい修正。

[2015-08-15 v0.03]
一部のpsfで開始数秒が無音になるバグを修正。
_refreshタグ取得の優先順位が誤っていたのを修正。
その他細かい修正。

[2015-08-08 v0.02]
PSX-EXEのテキストセクションのアドレスを誤って取得することがあったのを修正。
PSX-EXEのテキストセクションのサイズはファイルサイズから算出するようにした。ヘッダには間違った数値を書いているpsfが多いようなので...。
HLE BIOSのstrcat、strncatらのコードを少し修正。
チョコボの不思議なダンジョン2はPSFのほうが誤っているらしいのでpsfローダーでパッチを当てるようにした(Thanks to the developer of AudioOverload)。
これによりRecompilerの一部のコードを元に戻せたので、やや速度アップ。
Interpreterのロード遅延スロットのエミュレーションを削除。これが正しいのかはわからないが、Interpreterでもドラクエ7、(パッチを当てた)チョコボの不思議なダンジョン2が再生できるようになった。
その他細かい修正。

foo_input_viopsf: ConverterやReplayGainScanのキャンセルボタンを押すとクラッシュするバグを修正。
                  Replaygainタグが存在する場合 or ConverterやReplayGainScan使用時 にはvolumeタグの値を無視するようにした。
                  しかしSPUコアを変えると音量が変わってしまうので、ReplayGainはあまり役に立たないかも。
                  Ignore volume tagオプションを追加。チェックするとvolumeタグの値を無視します。 
                  その他細かい修正。

[2015-08-01 v0.01]
最初のリリース


■必要な環境
Windows XP SP3以降のOS
ある程度パワーのあるCPU
foobar2000 v1.3以上 or Winamp 2.x/5.x


■再生できるフォーマット
PSF/MINIPSFのみです。PSF2/MINIPSF2には対応していません。


■本プラグインについて
PCSX-Reloaded r96687ベースです。
CPUはデフォルトではRecompilerを使用。設定画面でInterpreterに変更できます。
BIOSはPCSXR内蔵のHLE BIOSを使用しています。
SPUプラグインはEternal SPUを使うことを想定して作成しました。
インターフェース等のコードはvioxsfのものを流用しています(作者様に感謝)。
サウンドエミュとしてはかなり重いです。


■インストール方法
別途 SPUEternal.dll が必要です。
eternal spu で検索すると見つかると思います。v1.50 beta2、v1.41で動作を確認しています。

●foobar2000
foobar2000インストーラ版使用 & Program Files以下にインストールしている方は、user-componentsフォルダへのインストールを推奨します。

* user-componentsフォルダにインストールする場合
foo_input_viopsfというフォルダをつくり、その中にfoo_input_viopsf.dll、viopsf.bin、SPUEternal.dll を置いてください。

* componentsフォルダにインストールする場合
foo_input_viopsf.dll、viopsf.bin、SPUEternal.dll を置いてください。

●Winamp
* Winamp 2.x    -> in_viopsf.dll と viopsf.bin と SPUEternal.dll をPluginsフォルダにコピーしてください。
* Winamp 5.x    -> in_viopsfu.dll と viopsf.bin と SPUEternal.dll をPluginsフォルダにコピーしてください。

*追記1 SPUEternal.dllは複数バージョンダウンロードして、一方をSPUEternal141.dllなどとリネームしても良いです。
       ロードしたいSPUプラグインのファイル名は設定画面で指定できます(デフォルトではSPUEternal)。
*追記2 SPUEternal.dllの代わりにSPUplugin_for_viopsfフォルダ内のSPUプラグインも使用できます。
       viopsf.binと同じ場所に置き、設定画面でファイル名を指定してください。


■SPUプラグインについて
(1) PS Emu Proのプラグイン規格に準拠
(2) SPUrender関数がexportされている
(3) SPUinit -> SPUrender -> SPUshutdown の順にcallすれば動作する

これらの条件を満たすプラグインであれば、SPUEternal.dll 以外のSPUプラグインも使用できます。
ですがSPUrender関数を実装しているのは SPUEternal.dll のみ??
オープンソースのプラグインであれば改造して対応させられます。

本プラグインで使用している関数は
SPUinit
SPUrender
SPUshutdown
SPUconfigure
SPUwriteRegister
SPUreadRegister
SPUwriteDMA
SPUreadDMA
SPUwriteDMAMem
SPUreadDMAMem
SPUregisterCallback
です。

SPUopenとSPUcloseは呼びません。
KbMediaPlayer用のSPU再生プラグインである kbspu(SPUのコアにSPUEternal.dllを使用) のソースを見ると、SPUopenとSPUcloseは呼んでいなかったので同じ仕様にしました。


■設定画面
* SPU plugin name
使用したいSPUプラグインのファイル名を選択してください。
SPUプラグインはviopsf.binと同じ場所に置いてください。
アプリケーション起動時にSPUプラグインをロードしているため、再起動しないと変更が反映されません。

* Configure SPU plugin
SPUプラグインの設定画面を開きます。設定画面が用意されていないプラグインの場合は何も表示されません。
SPUEternal.dllの場合は設定はレジストリに保存しているようので、PSエミュ等でSPUEternal.dllを使用している場合、設定が共有されます。
なお本プラグインで使用時はReverbとFineTuneオプション以外は設定してもたぶん意味ないです。
psf再生中に設定を変えると不具合が生じるSPUプラグインがあるかもしれません。

* Enable Interpreter CPU
PCSXRにあるオプションと同じです。チェックするとCPUのコアにInterpreterを使用します。チェックなしの場合はRecompilerを使用します。
かなり重いので、Recompilerで正常に再生できなかった場合にのみチェックしてください。

* Ignore volume tag
チェックするとvolumeタグの値を無視します。
SPUEternalやspuPeopsSoundなどの元々音量が大きいSPUプラグイン使用時はチェック推奨です(多くの場合volumeタグは音量を大きくするように設定されているので)。

* volume
SPUプラグイン側で音量調節できる場合、そちらを使ったほうが良いです。


■注意
(1)foobar2000では、複数スレッドでPSFを同時に再生することができません。
   -> マルチコアCPU環境にてConverterを使った場合でも、シングルスレッド時と同程度の速度になります。
   -> PSF再生中に他のPSFに対してReplaygainScan/Converter 等を使う場合、再生中のPSFを停止しないと動作しません。
   -> foo_wave_seekbar使用時にフリーズするようです。

(2)Winamp用プラグインはマルチスレッドセーフではありません。
   psf再生中に他のpsfに対してReplayGainScan等を使うとクラッシュするので注意してください。 

(3)再現性に問題があるPSFがあります。
   特にSPUEternal.dll_v1.50beta2使用時は、ポップノイズがのりやすいようです。ベイグラントストーリー、サガフロンティア2、ヴァルキリープロファイルなど。 
   v1.41だと気になりませんでした。
   おそらく他にも問題のあるPSFがあると思います。
   
(4)シークはかなり重いです。

(5)Winamp用プラグインはデバッグ不足です。
   また、作者自身が普段使用しないのでバグがあっても気がつかないと思います。
   バグが見つかったら報告してもらえると助かります。

(6)エミュレーションについてはさっぱり理解できていないので、所々あやしいコーディングが...
   知識のある方は改良してやってください。

(7)このプラグインの開発はほぼ終了しています。
   今後バグ修正以外は更新しないと思います。

   
■Reference
* sexypsf
* AudioOverload SDK
* UPSE
* foo_psf
* kbspu
* vio2sf, viogsf, snsf9x
Thanks to the developers.


■License
[Zlib]
Please refer to https://www.zlib.net/zlib_license.html
(C) 1995-2017 Jean-loup Gailly and Mark Adler
http://www.zlib.org/

[vioxsf framework] -> ???

[PCSX-Reloaded] -> GPL v3
Please refer to src\viopsf\viopsf\pcsxr\COPYING.

PCSX Upstream Authors:	Linuzappz     <linuzappz@pcsx.net>
	Shadow        <shadow@pcsx.net>
	Pete Bernett  <psswitch@online.de>
	NoComp        <NoComp@mailcity.com>
	Nik3d
	Akumax        <akumax@pcsx.net>
	
PCSX Copyright:	(c) 1999-2003  Pcsx Team
	(c) 1998 Vision Thing
	
df Upstream Authors:	Ryan Schultz <schultz.ryan@gmail.com>
			Andrew Burton <adb@iinet.net.au>
			Stephen Chao <schao@myrealbox.com>
			Marcus Comstedt <marcus@mc.pp.se>
			Stefan Sikora <hoshy@schrauberstube.de>
			
df Copyright:	(c) 2005 Ryan Schultz
		(c) 2005 Andrew Burton
		(c) 2007 Stephen Chao
		(c) 2006 Marcus Comstedt
		
PCSX-Reloaded Authors/Contributors: avlex (Help on xcode project)
			    Benoît Gschwind (MDEC decoder improvements)
			    ckain (Various bugfixes)
			    Dario (Various bugfixes)
			    edgbla (Root counters, SIO1, various core/plugin fixes)
			    Firnis (GTE code from PCSX-Revolution Project)
			    Hopkat (Sound plugin improvements, core fixes)
			    Gabriele Gorla (MDEC decoder)
			    MaddTheSane (Various bugfixes)
			    maggix (Snow Leopard compile fix)
			    NeToU (Bugfix)
			    notaz (Various psxbios fixes)
			    Peter Collingbourne (Various core/psxbios fixes)
			    siveritas (Bugfix)
			    shalma (GTE Divider, many core improvements, sound plugin fixes)
			    Tristin Celestin (PulseAudio support)
			    UTunnels (Mode 1 ISO support)
			    VoidMage (Build system cleanups)
			    Wei Mingzhi (Input plugin, iso/cheat support, misc stuff)
			    (And others which I cannot keep track of)
			    
PCSX-Reloaded Translators: 99skull (Korean)
			   Delirious (Hungarian)
			   edgbla (Russian)
			   Giovanni Scafora (Italian)
			   Imanol08 (Spanish)
			   Jean-André Santoni (French)
			   Tibério Vítor (Brazilian Portuguese)
			   Wei Mingzhi (Simplified & Traditional Chinese)		   