Skip to content

Instantly share code, notes, and snippets.

@cceckman
Last active August 29, 2015 14:03
Show Gist options
  • Save cceckman/cd171aa8ec212ca47d43 to your computer and use it in GitHub Desktop.
Save cceckman/cd171aa8ec212ca47d43 to your computer and use it in GitHub Desktop.
Packet decoder to 10-bit samples
// 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