Possible leads on PO-32 backup encoding

New to signal processing, but I figured I’d give a basic BPSK decoder a shot. A window of six peaks/valleys to one bit seems to fit the signal well enough.

Going with start-lull/start-peak thresholds of about 1000/1200, at least for my 16-bit TASCAM recordings over line out.

Here’s what I have so far for a possible analog decoding of the factory default configuration. Of course, the digital backup format inside of the analog signal is still unknown.

Snippet:

00000000 66 66 66 66 66 66 66 66
00000008 66 66 66 66 66 66 66 66
00000016 66 66 66 66 66 66 66 66
00000024 66 66 66 66 66 66 66 66
00000032 66 66 66 66 66 66 66 66
00000040 66 66 66 66 66 66 66 66
00000048 66 66 66 66 66 66 66 66
00000056 66 66 66 66 66 66 66 66
00000064 66 66 66 66 66 66 66 66
00000072 66 66 66 66 66 66 66 66
00000080 66 66 66 66 66 66 66 66
00000088 66 66 66 66 66 66 66 66
00000096 66 66 66 66 66 66 66 66
00000104 66 66 66 66 66 66 66 66
00000112 66 66 66 66 66 66 66 66
00000120 66 66 66 66 66 66 66 66
00000128 66 66 66 66 66 66 66 66
00000136 66 66 66 66 66 66 66 66
00000144 66 66 66 66 66 66 66 66
00000152 66 66 66 66 66 66 66 66
00000160 66 66 66 66 66 66 66 66
00000168 66 66 66 66 66 66 66 66
00000176 66 66 66 66 66 66 66 66
00000184 66 66 66 66 66 66 66 66
00000192 66 66 66 66 66 66 66 66
00000200 66 66 66 66 66 66 66 66
00000208 66 66 66 66 66 66 66 66
00000216 66 66 66 66 66 66 66 66
00000224 66 66 66 66 66 66 66 66
00000232 66 66 66 66 66 66 66 66
00000240 66 66 66 66 66 66 66 66
00000248 66 66 66 66 9a 45 84 08
00000256 57 7d 16 b3 a3 df 56 b7
00000264 7c 13 f9 f5 b1 f0 25 49
00000272 ab b6 73 d7 a6 dd 76 98
00000280 ef b8 0b 10 55 a6 3c f9
00000288 f9 81 3b 68 dd 03 69 a9
00000296 f7 fe c8 28 d8 35 33 c6
00000304 f4 66 86 6c 51 65 1b e2
00000312 b2 01 c9 3f 96 3a 91 3a
...
0000112 ea 64 4c 2b 57 29 19 e8
00000120 ff 1b f4 d6 fd 8b 32 3d
00000128 1a 76 b8 e7 2b a6 94 53
00000136 83 6e fc d9 6b 28 64 42
00000144 34 8b fd 5f 20 3d 79 fb
00000152 42 b4 de 64 19 88 21 a9
00000160 40 54 22 54 99 e4 83 4c
00000168 e5 ee fe 5d 7c f9 55 55
00000176 55

I changed the active pattern from the first to the second and reran. The byte difference between these two backups is quite small:

--- /tmp/pattern-0-hex.txt      2020-05-02 22:23:54.000000000 -0500
+++ /tmp/pattern-1-hex.txt      2020-05-02 22:23:57.000000000 -0500
@@ -658,6 +658,6 @@
 00000136 83 6e fc d9 6b 28 64 42
 00000144 34 8b fd 5f 20 3d 79 fb
 00000152 42 b4 de 64 19 88 21 a9
-00000160 40 54 22 54 99 e4 83 4c
-00000168 e5 ee fe 5d 7c f9 55 55
-00000176 55
+00000160 40 54 22 54 99 e4 7c cf
+00000168 42 62 73 bf 41 ac aa aa
+00000176 aa

That’s an eleven byte difference, not too shabby.

Am I correct in assuming that the active pattern is specified toward the end of the signal? Note that the final three bytes are repeated. Checksums? Seems promising!

All of this is under the assumption that Tonic uses a simple BPSK as opposed to a more gnarly QPSK, DPSK, etc. That would be even harder to crack. Maybe Thrift is encoding the configuration structs. Maybe protobuf. Maybe the bits are inverted. Who knows!

3 Likes

One phenomenal thing about this experiment is that I found a bug in my hex dumper. Gotta go back and do the analysis with UNIX hexdump The line markers were off, and some kind of artifact was initially causing inconsistent export byte decodings from the same PO configuration. :stuck_out_tongue:

I Write + Pattern + insert batteries for a factory restore and took fresh recordings. Did that several times. Just in case the clock interaction alters the exported data somehow, I went with a standard procedure of leaving the clock as-is and using the Write button to end the clock set prompt. It’s entirely possible that small changes are affecting internal values that end up in the transmissions.

A UUID on factory restore appears to be ruled out, and it wouldn’t make much sense for the clock to be preserved or play much of a role in the output. But you never know. For comparison, Amazon Kindle beams back your entire reading history, down to the GUI events, back to HQ.

Also skipped testing restore operation on the recordings, as each WAV has been able to successfully restore, given 1-3 tries.

Now the factory default decoding has stabilized to 0x66 … 0xaa.

Re-exports of the same active pattern configuration yield identical hex decodings, across factory restores. Pattern 1 (“p0.wav”) always produces the same digital output.

Active pattern configurations 3rd - 16th are similar, though the size of the diff varies from just two lines (p0 vs. p2) to seven lines (p0 vs. p5). If the PSK decoder is correct, then the bit packing of the currently selected pattern is more complicated that it would first appear.

TODO:

Find out what inputs are included in the 0x555555 vs. 0xaaaaaa checksum calculation. Seems to be some kind of even/odd parity signal terminator.

So many possibilities to test! How many leading 0x66’s must be heard for a successful reception? How many trailing 0x55’s/0xaa’s?

How does microtonic mark that a specific set of sound buttons should be changed, while at the same time preserving the rest of the configuration should remain as-is?

We could start writing a BPSK encoder and generating our own synthetic backup files, but I just got my Tonic and am not ready to risk bricking it.

Turn more knobs and check their hex diffs!

1 Like

Cuckoo was kind enough to include a factory backup track in his microtonic pack. With inner threshold 6000, outer threshold 9000, this produces an identical hex dump to mine! File size 5297 bytes (~ 5.3 KB).

Long term, would love to write a more flexible decoder that automatically fits arbitrary volumes. Tracking in https://github.com/mcandre/rouge/issues/1

For now, just adding some diagnostics to the error messages for a quick idea of whereabouts the peak seeker fails. Guess and check, baby.

have u read thru this thread yet?
lots of discussion on decoding the data format

Yes, thank you for the link! Curious if someone can upload WAVE PCM examples for PO-35 backups. Their format is probably different but still helpful for understanding PO-32.

Taking the discussion there with a grain of salt. The PO-32 waveform in Audacity looks closer to a simple BPSK than anything else, at least to my novice eyes. I’ve read that QPSK is visually close to BPSK but that a decent modem can tell the difference. How can we test for QPSK vs. BPSK?

With a fixed six peak/valley window, all of my PO-32 backup tracks are successfully parsing digits, albeit probably wrong digits, to the very end of the track. No sequence of consecutive peaks/valleys within these windows!

That gives me confidence that the signal is some PSK, I’m just not sure which particular PSK algorithm. I’m tempted to believe that this means that the signal cannot be a DPSK, as my understanding is DPSK has far more consecutive peaks and consecutive valleys. Right?

I could easily be on the wrong track. Anyone with better information is welcome to contribute code to rouge to decode these signals more accurately!

There was some previous discussion on this subject:

It seems there is a “DPSK” string inside the uTonic installer, so that is a good starting point. Note that PO-32 uses a low speed monophonic transfer. PO-33/35 uses a high speed stereo transfer.

I stopped looking into this after I realized the difficulty level here. Without help from TE I guess the chance of success is zero (maybe it is possible for the PO-32). I just wish TE would play nice and provide a data transfer library.