code wiki / (root) / nx_fidelity.nx

nx_fidelity.nx source

↩ module page · 85 lines · 3050 B

1const FID_MAGIC_131072: i64 = 131072 2const FID_MAGIC_65536: i64 = 65536 3const FID_MAGIC_32768: i64 = 32768 4// nx_fidelity.nx -- AUDIO arc R6: a sovereign FIDELITY metric. Grades how 5// faithfully a reconstruction (a clone, a codec output, an LPC resynthesis) 6// matches a reference, so clone/codec quality is MEASURED, not asserted. 7// 8// Segmental SNR: per frame, 10*log10( sum(ref^2) / sum((ref-test)^2) ), averaged. 9// Higher dB = closer. Uses a sovereign integer log2 (normalize + 16-iteration 10// mantissa squaring, the classic fixed-point log) converted to dB via the 11// constant 10/log2(10). Returned in DECI-decibels (dB*10) for resolution; an 12// exact reconstruction (zero error) caps at 99.0 dB. 13// 14// Pure integer, NO floats, NO imports (caller owns the buffers). 15// nx_segsnr(ref, test, n, frame) -> deci-dB (dB*10) 16// 17// license_tier: ORIGINAL 18// module: nishi-core.audio.fidelity 19// capability: AUDIO_FIDELITY_METRIC 20 21const FID_LOG10_K: i64 = 197336 // 10/log2(10) = 3.0103 in Q16.16 22const FID_CAP_DDB: i64 = 990 // 99.0 dB cap (deci-dB) for near-zero error 23 24// log2(x) for a Q16.16 value x (65536 = 1.0); returns Q16.16. 25func _fid_log2_q16(x: i64) -> i64 { 26 if x <= 0 { return 0 } 27 var v: i64 = x 28 var ip: i64 = 0 29 while v >= FID_MAGIC_131072 { v = v >> 1; ip = ip + 1 } // bring into [1,2) 30 while v < FID_MAGIC_65536 { v = v << 1; ip = ip - 1 } 31 var result: i64 = ip << 16 32 var b: i64 = FID_MAGIC_32768 // mantissa bit weight (Q16 .5) 33 var i: i64 = 0 34 while i < 16 { 35 v = (v * v) >> 16 36 if v >= FID_MAGIC_131072 { v = v >> 1; result = result + b } 37 b = b >> 1 38 i = i + 1 39 } 40 return result 41} 42 43func _fid_i16(p: *u8, i: i64) -> i64 { 44 let lo: i64 = p[i * 2] 45 let hi: i64 = p[i * 2 + 1] 46 var v: i64 = lo | (hi << 8) 47 if v >= 0x8000 { v = v - 0x10000 } 48 return v 49} 50 51func nx_segsnr(ref: *u8, test: *u8, n: i64, frame: i64) -> i64 { 52 var nf: i64 = 0 53 var acc: i64 = 0 54 var f: i64 = 0 55 while (f + 1) * frame <= n { 56 let st: i64 = f * frame 57 var sig: i64 = 0 58 var err: i64 = 0 59 var j: i64 = 0 60 while j < frame { 61 let r: i64 = _fid_i16(ref, st + j) 62 let t: i64 = _fid_i16(test, st + j) 63 sig = sig + r * r 64 let d: i64 = r - t 65 err = err + d * d 66 j = j + 1 67 } 68 var ddb: i64 = FID_CAP_DDB // default = error ~0 -> cap 69 if sig == 0 { ddb = 0 } 70 if err > 0 { 71 if sig > 0 { 72 let ratio_q16: i64 = (sig << 16) / err 73 let l2: i64 = _fid_log2_q16(ratio_q16) 74 let db_q16: i64 = (l2 * FID_LOG10_K) >> 16 // 10*log10(ratio), Q16 75 ddb = (db_q16 * 10) >> 16 // deci-dB (can be <0) 76 if ddb > FID_CAP_DDB { ddb = FID_CAP_DDB } 77 } 78 } 79 acc = acc + ddb 80 nf = nf + 1 81 f = f + 1 82 } 83 if nf < 1 { return 0 } 84 return acc / nf 85}