De beste codering die je kunt gebruiken, hangt sterk af van de distributie van je samples. U hebt ons verteld dat de delta's meestal vrij klein zijn, wat betekent dat uw eerste stap vrijwel zeker delta-codering zal zijn (elke waarde transformeren in een verschil met de vorige waarde.)
Een andere beperking is het systeem waarop je de codering uitvoert - je hebt gezegd dat het "ingebed" is, maar dat omvat een behoorlijk scala aan mogelijkheden. Je hebt ook gezegd dat SD-kaarten buiten bereik zijn, en dat je slechts 450 samples tegelijk in RAM buffert, wat inderdaad een heel klein systeem suggereert. In dat geval lijkt optimaliseren voor eenvoud en behoud van CPU / RAM in orde.
Als de meest voorkomende deltawaarde exact 0 is - dat wil zeggen, veel samples zijn hetzelfde als de vorige sample - is het waarschijnlijk een goed idee om die runs van 0 waarden eerst te "run-length coderen". (D.w.z. gewoon opslaan hoeveel er op een rij waren.)
De rest hangt verder af van hoe de verdeling van waarden eruitziet. Ik zal omwille van de oefening aannemen dat ze bijna allemaal in het bereik -64 < x < 63 liggen (d.w.z. een 7-bits geheel getal met teken). Ik neem ook aan dat het het gemakkelijkst is om met bytes te werken in plaats van met bits (wat waarschijnlijk waar is als je bijvoorbeeld C schrijft) - als dat niet waar is, kijk dan helemaal onderaan het antwoord voor een bit-wijs schema. Een heel eenvoudige byte-gewijze codering zou er ongeveer zo uit kunnen zien:
0b0xxxxxxx
- een letterlijke waarde (delta) weergegeven als 7-bits geheel getal met teken in het "xxxxxxx" -gedeelte. (Waarden van -64 tot 63.)
0b10xxxxxx
- een reeks nullen (delta's), waarvan de lengte wordt weergegeven door "xxxxxx" (6 bits ongetekend kunnen tot 63 uitdrukken, en als we meer nodig hebben, kunnen we gewoon nog een item toevoegen.)
0b110xxxxx 0byyyyyyyy
- een letterlijke waarde (delta) weergegeven als een 13-bits geheel getal met teken in het gedeelte "xxxxxyyyyyyyyy".
0b11111111 0bxxxxxxxx 0byyyyyyyy
- een letterlijke waarde (delta) weergegeven als een 16-bits geheel getal met teken. Dit is een erg inefficiënte codering (uiteraard) omdat het een 16-bits waarde omzet in een weergave van 3 bytes. Het verspilt onnodig ruimte om de output byte-uitgelijnd te houden. Deze regeling heeft alleen zin als zulke grote delta's zeer zeldzaam zijn. (Elk niet-triviaal compressieschema heeft een aantal inputs waarvan de resulterende output eigenlijk groter is; dit is een theorema van informatietheorie.)
(Het bovenstaande schema is enigszins geïnspireerd door de UTF-8-codering van Unicode.)
In tegenstelling tot Huffman-codes (vermeld in een ander antwoord), wordt de veronderstelde verdeling van waarden van tevoren vastgelegd. Dit is een deugd omdat het de zaken eenvoudig houdt, en het vermijdt dat overhead wordt toegevoegd aan het begin van elk blok samples; het is een ondeugd omdat een meer adaptief schema geen handmatige afstemming op de distributie vereist.
Als delta's veel kleiner dan -64 tot 63 vaak voorkomen, zal een betere byte-gewijs codering dan de bovenstaande meer dan één sample tegelijk moeten verwerken om beter te worden dan 2: 1 compressie (dat wil zeggen, meer dan één sample per outputbyte.)
Als bitsgewijze codering ok is, dan is een veel eenvoudiger te beschrijven schema als volgt: eerst nog delta-codering en daarna als volgt coderen. Een 0-bit wordt gevolgd door een positief geheel getal met variabele lengte dat het aantal te volgen nullen codeert; een 1 bit wordt gevolgd door een tekenbit en vervolgens een positief geheel getal met variabele lengte, die samen de volgende (delta) waarde coderen. De positieve gehele getallen met variabele lengte kunnen worden gecodeerd met een van de codes van https://en.wikipedia.org/wiki/Universal_code_(data_compression), zoals een van de Elias-codes. (Welke codering het beste is, hangt weer af van de distributie van de gegevens, maar waarschijnlijk zullen ze allemaal goed werken.)