再度確かめてwavpack(-hh)を0.1%リードしているのを再確認。実装を修正、テストを固めた。アサートはデコードが不完全なことに起因していた。
お話作りにはいる(が、23日になってしまった…)
wavpackのsign algorithmの係数更新がかっこよすぎる...
#if 1 // PERFCOND
#define update_weight(weight, delta, source, result) \
if (source && result) { int32_t s = (int32_t) (source ^ result) >> 31; weight = (delta ^ s) + (weight - s); }
#elif 1
#define update_weight(weight, delta, source, result) \
if (source && result) weight += (((source ^ result) >> 30) | 1) * delta;
#else
#define update_weight(weight, delta, source, result) \
if (source && result) (source ^ result) < 0 ? (weight -= delta) : (weight += delta);
#endif
(source ^ result) >> 31 で予測と信号の符号が合っているかどうかがわかる。合ってたら0, 合ってなかったら~0=-1。係数更新も weight = (delta ^ s) + (weight - s) で確かに成立している( s=0,~0=-1 で考えよ)。難点は、source == resultのときに+=で更新してしまうところか。