--- license: apache-2.0 library_name: acoustic-book-hash tags: - acoustics - fingerprinting - impulse-response - physical-media - numpy - cpu pipeline_tag: other language: - en --- # acoustic-book-hash **A closed book rings at its own set of frequencies when tapped. Those frequencies are a physical fingerprint of the book's construction.** A stack of paper is a layered resonator. Tap the cover, and the stack rings with a set of modes at frequencies `n · c / (2L)`, where `c` is the effective wave speed through the pressed pages and `L` is the stack height. Two copies of the same edition share both `c` and `L`. Different editions differ in at least one. The list of peak frequencies is the fingerprint. ## The claim in one sentence Two copies of the same edition produce nearly identical acoustic fingerprints; different editions do not. No training required. ## What it produces A `Fingerprint` containing: - `peaks` — up to 8 (frequency, amplitude) pairs in the 200–6000 Hz band - `book_id` — an optional string tag And a database interface: - `BookDatabase` — a collection of reference fingerprints - `query(fp)` — returns the best match and the similarity score - `save(path)` / `load(path)` — JSON persistence ## Install ```bash pip install numpy ``` No other dependencies. No model weights. No downloads. ## Usage ### Build a reference database from WAV files ```bash python acoustic_book_hash.py record-db mylib.json \ --book EdA-hardcover-2003 a1.wav a2.wav a3.wav \ --book EdB-paperback-2010 b1.wav b2.wav ``` ### Query a new tap ```bash python acoustic_book_hash.py query mylib.json unknown_tap.wav ``` Output: ``` query peaks: [809.0, 1219.0, 1600.0, 2402.0, 3205.0] Hz EdA-hardcover-2003 0.933 EdC-folio-1897 0.250 EdE-pulp-1972 0.375 ... best match: EdA-hardcover-2003 (0.933) ``` ### Programmatic ```python from acoustic_book_hash import ( BookDatabase, make_fingerprint, load_wav, window_tap, ) db = BookDatabase.load("mylib.json") data, sr = load_wav("unknown_tap.wav") data = window_tap(data, sr) fp = make_fingerprint(data, sr) best, all_matches = db.query(fp, threshold=0.6) print(best) ``` ## Benchmarks Synthetic demo. Five editions simulated from a physical model. Each edition's paper speed, stack height, and damping time differ. ### Pairwise similarity matrix | | EdA | EdB | EdC | EdD | EdE | |---|---|---|---|---|---| | EdA | 1.000 | 0.133 | 0.625 | 0.250 | 0.375 | | EdB | 0.133 | 1.000 | 0.533 | 0.400 | 0.533 | | EdC | 0.625 | 0.533 | 1.000 | 0.250 | 0.250 | | EdD | 0.250 | 0.400 | 0.250 | 1.000 | 0.375 | | EdE | 0.375 | 0.533 | 0.250 | 0.375 | 1.000 | Diagonal is 1.0 by construction. Off-diagonal varies with how close two editions' fundamental frequencies are: EdA and EdC (800 vs 682 Hz) share more peaks than EdA and EdD (800 vs 1000 Hz), even though both pairs are 150–200 Hz apart. The fingerprint is sensitive to *harmonics*, not just the fundamental. ### Robustness | condition | similarity | |---|---| | same tap point, re-tap | 1.000 | | different tap point | 0.875–1.000 | | + 1% noise | 1.000 | | + 3% noise | 0.875 | | + 5% noise | 0.933 | | + 10% noise | 1.000 | Robustness to noise in the demo is better than expected because the smoothing and peak extraction step removes the noise before the fingerprint is computed. Real recordings will have room reflections on top of noise, which are not in the model. ### Database identification | query | result | similarity | |---|---|---| | fresh tap of EdA | EdA-hardcover-2003 | 1.000 | | fresh tap of EdC | EdC-folio-1897 | 1.000 | | fresh tap of EdE | EdE-pulp-1972 | 0.875 | | EdA + 5% noise | EdA-hardcover-2003 | 0.857 | | unknown book | *(no match)* | 0.000 | ## Self-test 12 checks, all passing on a clean run: - physical model produces finite output - fundamental frequency in the sensible range - spectral peaks extracted in band - same edition (different taps): similarity > 0.85 - different editions: similarity < 0.4 - same book + 3% noise: similarity > 0.7 - database correctly identifies a fresh tap - unknown book correctly rejected - deterministic simulation - fingerprint serializes to JSON ## Applications - **Forgery detection in print-on-demand markets.** A counterfeit uses different paper stock and binding; the fingerprints differ. Requires a reference fingerprint of the genuine edition. - **Edition matching for libraries and rare book dealers.** A dealer can identify which of several similar editions a physical copy is without opening it. - **Copy-level tracking.** Two copies of the same edition have similar fingerprints but not identical ones (paper stock varies slightly between printings). Individual copies can be distinguished. - **Physical provenance.** A book kept in a humid environment has a measurably different fingerprint from the same edition kept dry. The fingerprint encodes the book's history. ## Honest limitations - **Every number in the benchmarks is from synthetic data.** The fingerprints in the demo come from a physical model, not from real recordings. Real books will have more complicated spectra (uneven paper, folded pages, dust jackets) and the peak extraction may not be as clean. - **Requires a quiet recording environment.** In a reverberant room, the room's reflections arrive within a few milliseconds and overlap the book's own response. A short window on the early response (30 ms) mitigates this but does not eliminate it. - **Requires the same tap point.** Different tap points change the phase pattern, which shifts peak amplitudes but not peak frequencies. Frequency-based comparison is invariant to this, but if two editions share the same fundamental, the amplitude pattern becomes load-bearing and tap-point variance matters. - **Requires calibration.** The reference fingerprints must be measured once per edition. There is no training phase. - **Sensitive to humidity.** Paper speed varies with moisture content. A book measured at 30% RH and again at 70% RH will have shifted mode frequencies. Real deployments need calibration or humidity normalization. - **The `paper_speed` parameter in the demo is a fitting constant.** Real paper speed varies between 60 and 100 m/s depending on paper type. The five demo editions are one plausible family, not a measurement. ## Reference Part of a series of small tools built in one session: | tool | reads | answers | |---|---|---| | `ir-source-localizer` | impulse responses | where is the source? | | **`acoustic-book-hash`** | **a tap on a book** | **which edition is it?** | ## License Apache-2.0