Skip to content

Repository files navigation

libppswing

This library reads and writes PinPoint swing files (.ppsw), the binary replacement for PinPoint Studio's swing.json.

A recorded swing's document holds its capture manifest, sensor streams, pose, club and ball tracks, phases and metrics. As JSON it was 30–65 MB per swing, and about 58% of that was indentation. As .ppsw it is about 2–4 MB. It is lossless: every number comes back bit-for-bit. It is also lazy: the session, review and metric scalars load without touching the pose tracks.

JSON (indented) .ppsw lossless .ppsw display-f32
2026-07-04 swing 1 (face-on) 35.1 MB 3.35 MB (10.5×) 1.93 MB (18.2×)

The format is specified in docs/specification/ppsw-format.md, and the design is described in docs/design.md. In short:

  • a 40-byte header, then zstd-compressed chunks, then a table of contents;
  • each chunk holds a subtree of the document, encoded as CBOR;
  • numeric arrays become typed, byte-shuffled ndarrays;
  • arrays of objects become column-wise tables.

What is here

  • include/ppswing/, src/: the C++17 library, ppswing::ppswing. Its only dependency is zstd 1.5.7, vendored in third_party/zstd.
  • tools/ppsw.cpp: the ppsw command line tool:
    ppsw convert swing.json [-o swing.ppsw] [--policy lossless|display-f32]
    ppsw dump    swing.ppsw [--indent]          # back to JSON
    ppsw info    swing.ppsw                     # chunk table
    ppsw verify  swing.json swing.ppsw          # lossless check (spec §1.1)
    
  • python/ppswing: a pure-Python reader, independent of the C++ code and with no required dependencies. It uses the stdlib zstd on Python 3.14+, or pip install zstandard on older versions. numpy is optional.
    import ppswing
    doc = ppswing.load_swing("…/swing_0001")        # a swing dir, swing.json or swing.ppsw
    r = ppswing.Reader("swing.ppsw"); r.root()       # the cheap read: no pose decoded
  • tools/corpus_check.py: converts a library of swings and proves the round trip with both decoders.
  • tools/make_fixture.py: trims and anonymises a real swing into a test fixture.

Building

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j8
ctest --test-dir build

Tests and tools build only when this is the top-level project. Embedded with add_subdirectory or FetchContent, only the library builds, and the consumer's build is unchanged.

The sanitizer build is:

cmake -S . -B build-asan -DPPSW_ENABLE_ASAN=ON -DPPSW_ENABLE_UBSAN=ON

Licence

MIT. The vendored zstd is BSD-3-Clause (third_party/zstd/LICENSE).

About

Reader/writer for PinPoint swing files (.ppsw): lossless, chunked, C++17 + Python

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages