package com.android.dialer.helpdesk.util; /** * Standalone off-device test for {@link LegInterleaver}. * *

This is the code that decides whether dual-leg recording produces a real conversation or a * plausible-looking file in which the two speakers drift apart. Its failure mode is quiet: a wrong * alignment still yields playable stereo and a readable transcript, just with the operator's words * sliding away from when they were said. So the interesting cases here are the uneven ones - legs * delivering different amounts, a leg stalling, a leg arriving in odd-sized pieces. */ public class LegInterleaverTest { static int pass = 0, fail = 0; static void ok(String d) { pass++; System.out.println(" ok " + d); } static void bad(String d, String got) { fail++; System.out.println(" FAIL " + d + " (got: " + got + ")"); } static void eq(int got, int want, String d) { if (got == want) ok(d); else bad(d, got + ", want " + want); } static void eqBytes(byte[] got, int len, int[] want, String d) { if (len != want.length) { bad(d, "length " + len + ", want " + want.length); return; } for (int i = 0; i < len; i++) { if ((got[i] & 0xFF) != want[i]) { bad(d, "byte " + i + " = " + (got[i] & 0xFF) + ", want " + want[i]); return; } } ok(d); } static byte[] bytes(int... v) { byte[] b = new byte[v.length]; for (int i = 0; i < v.length; i++) b[i] = (byte) v[i]; return b; } public static void main(String[] args) { byte[] out = new byte[4096]; System.out.println("equal legs interleave left-sample-first"); LegInterleaver a = new LegInterleaver(64000); a.offerUp(bytes(1, 2, 3, 4), 4); // two mono samples: [1,2] [3,4] a.offerDown(bytes(9, 8, 7, 6), 4); // [9,8] [7,6] eq(a.available(), 8, "two frames ready"); int n = a.drainInto(out, 0, out.length); eqBytes(out, n, new int[] {1, 2, 9, 8, 3, 4, 7, 6}, "L,R,L,R with sample bytes kept in pairs"); eq(a.available(), 0, "nothing left over"); System.out.println("uneven legs: only frames present on BOTH sides are emitted"); LegInterleaver b = new LegInterleaver(64000); b.offerUp(bytes(1, 1, 2, 2, 3, 3), 6); // three samples b.offerDown(bytes(9, 9), 2); // one sample eq(b.available(), 4, "one common frame only"); n = b.drainInto(out, 0, out.length); eqBytes(out, n, new int[] {1, 1, 9, 9}, "the single common frame"); eq(b.available(), 0, "the uplink surplus is NOT emitted against silence"); b.offerDown(bytes(8, 8, 7, 7), 4); // downlink catches up eq(b.available(), 8, "the retained surplus pairs up when its counterpart arrives"); n = b.drainInto(out, 0, out.length); eqBytes(out, n, new int[] {2, 2, 8, 8, 3, 3, 7, 7}, "and interleaves in the original order"); System.out.println("a leg arriving in odd-sized pieces still aligns"); LegInterleaver c = new LegInterleaver(64000); c.offerUp(bytes(1, 1), 2); c.offerUp(bytes(2, 2), 2); c.offerDown(bytes(9, 9, 8, 8), 4); n = c.drainInto(out, 0, out.length); eqBytes(out, n, new int[] {1, 1, 9, 9, 2, 2, 8, 8}, "two offers on one leg equal one on the other"); System.out.println("capacity is respected and the remainder is kept"); LegInterleaver d = new LegInterleaver(64000); d.offerUp(bytes(1, 1, 2, 2), 4); d.offerDown(bytes(9, 9, 8, 8), 4); n = d.drainInto(out, 0, 4); // room for exactly one frame eqBytes(out, n, new int[] {1, 1, 9, 9}, "only what fits is written"); eq(d.available(), 4, "the rest waits rather than being dropped"); n = d.drainInto(out, 0, out.length); eqBytes(out, n, new int[] {2, 2, 8, 8}, "and comes out next time"); eq(d.drainInto(out, 0, 3), 0, "less than a whole frame of room writes nothing"); System.out.println("writing at an offset does not disturb what is already there"); LegInterleaver e = new LegInterleaver(64000); e.offerUp(bytes(1, 1), 2); e.offerDown(bytes(9, 9), 2); out[0] = 77; n = e.drainInto(out, 1, out.length - 1); eq(out[0] & 0xFF, 77, "the byte before the offset is untouched"); eq(n, 4, "one frame written at the offset"); System.out.println("a stalled leg drops the OLDEST audio, keeping the channels in the present"); LegInterleaver f = new LegInterleaver(8); // room for 4 mono samples f.offerUp(bytes(1, 1, 2, 2, 3, 3, 4, 4), 8); // fills it exactly eq(f.droppedBytes(), 0, "at the cap, nothing dropped yet"); f.offerUp(bytes(5, 5), 2); // one over eq(f.droppedBytes(), 2, "one sample discarded"); f.offerDown(bytes(9, 9), 2); n = f.drainInto(out, 0, out.length); // The oldest uplink sample [1,1] is gone, so the first frame pairs [2,2] with the live downlink. eqBytes(out, n, new int[] {2, 2, 9, 9}, "the surviving audio is the most RECENT, not the backlog"); System.out.println("dropping never splits a sample in half"); LegInterleaver g = new LegInterleaver(5); // deliberately not a multiple of 2 g.offerUp(bytes(1, 1, 2, 2, 3, 3), 6); eq(g.droppedBytes() % LegInterleaver.BYTES_PER_SAMPLE, 0, "only whole samples are discarded (a half would swap every following byte pair)"); System.out.println("degenerate input is harmless"); LegInterleaver h = new LegInterleaver(64000); eq(h.available(), 0, "nothing offered -> nothing available"); eq(h.drainInto(out, 0, out.length), 0, "draining an empty interleaver writes nothing"); h.offerUp(bytes(1, 1), 0); eq(h.available(), 0, "a zero-length offer adds nothing"); h.offerUp(bytes(1, 1), 2); eq(h.available(), 0, "one leg alone is never enough to emit a frame"); eq(h.drainInto(out, 0, -5), 0, "negative capacity writes nothing rather than throwing"); System.out.println(); System.out.println(pass + " passed, " + fail + " failed"); if (fail > 0) System.exit(1); } }