Last active
August 29, 2015 14:03
-
-
Save cceckman/cd171aa8ec212ca47d43 to your computer and use it in GitHub Desktop.
Packet decoder to 10-bit samples
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// For chasecaleb of #xkcd. Untested- use at your own risk! | |
// I took this on just as a challange, so please review / check against your own work. | |
#define PACKET_DATA_SZ 22 | |
#define SAMPLE_BITS 10 | |
typedef struct { | |
uint32_t timestamp; | |
char data[PACKET_DATA_SZ]; | |
} sample_packet_t; | |
// ASSERT sizeof(sample_packet_t) == 32 | |
typedef struct{ | |
uint16_6 v : SAMPLE_BITS; // packed 10-bit sample | |
} sample_t; | |
sample_t samples[ (PACKET_DATA_SZ*8) / SAMPLE_BITS]; | |
void receive(device_t device, int rssi, char *data, int len){ | |
if(len != sizeof(sample_packet_t)) | |
{ | |
// Handlers for control signals here | |
}else{ | |
sample_packet_t *pkt = (sample_packet_t*)data; | |
char *packet = pkt.data; | |
// Handle sample packet | |
size_t bit_offset = 0; | |
size_t word_offset= 0; | |
size_t sample_offset = 0; | |
while( (word_offset*8 + bit_offset + 10) < 32*8){ // while there are packets to receive | |
samples[sample_offset++].v = | |
(packet[word_offset] >> bit_offset) | // Low byte component | |
( | |
((uint16_t)packet[word_offset + 1]) << 8 // cast to uint16_t so it can shift to high byte | |
& (0x00FF << (2 + bit_offset)) // mask with bits to keep from high byte; 2 is 10 bits/sample minus 8 samples per bit | |
) >> bit_offset; // shift high byte into position | |
bit_offset = (bit_offset + 10) % 8; move to next sample | |
word_offset += 1 + (bit_offset == 0); // increment word_offset; if next word aligns with byte boundary, double increment. | |
} | |
} | |
} | |
void decode(){ | |
size_t bit_offset = 0; | |
size_t word_offset= 0; | |
size_t sample_offset = 0; | |
while( (word_offset*8 + bit_offset + 10) < 32*8){ // while there are packets to receive | |
samples[sample_offset++].v = | |
(packet[word_offset] >> bit_offset) | // Low byte component | |
( | |
((uint16_t)packet[word_offset + 1]) << 8 // cast to uint16_t so it can shift to high byte | |
& (0x00FF << (2 + bit_offset)) // mask with bits to keep from high byte; 2 is 10 bits/sample minus 8 samples per bit | |
) >> bit_offset; // shift high byte into position | |
bit_offset = (bit_offset + 10) % 8; move to next sample | |
word_offset += 1 + (bit_offset == 0); // increment word_offset; if next word aligns with byte boundary, double increment. | |
} | |
} | |
void encode(){ | |
size_t bit_offset = 0; | |
size_t word_offset= 0; | |
size_t sample_offset = 0; | |
while( (word_offset*8 + bit_offset + 10) < 32*8){ // while there are packets to receive | |
packet[word_offset] |= (samples[sample_offset].v << bit_offset) & 0x00FF; | |
packet[word_offset+1] |= (((uint16_t)samples[sample_offset].v) << bit_offset) & 0xFF00; | |
bit_offset = (bit_offset + 10) % 8; move to next sample | |
word_offset += 1 + (bit_offset == 0); // increment word_offset; if next word aligns with byte boundary, double increment. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment