Philippe Graffouliere
/
Nucleo_adat
?
Revision 2:79b8132da1d6, committed 2019-01-06
- Comitter:
- graffou
- Date:
- Sun Jan 06 17:14:36 2019 +0000
- Parent:
- 1:6349099b6962
- Commit message:
- ADAT encoder + decoder, with much more cleaner code.; CPU usage for encoder+decoder is ~40% (~4s codec over 480000 frames)
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 6349099b6962 -r 79b8132da1d6 main.cpp --- a/main.cpp Sun Jan 06 14:55:09 2019 +0000 +++ b/main.cpp Sun Jan 06 17:14:36 2019 +0000 @@ -38,6 +38,8 @@ uint32_t data[8]; // 24-bit audio in uint32_t adat[8]; // raw ADAT frame uint32_t adat_nrz[8]; // NRZI encoded ADAT frame +uint32_t dec_nrz[8]; // NRZI decoded ADAT frame +uint32_t adec[8]; // audio decoded frame DigitalIn pb(USER_BUTTON); DigitalOut myled(LED1); @@ -70,6 +72,109 @@ *x = ((*x)>>1) | ((*x)<<(31)); } + +inline uint32_t adat2audio(uint32_t x) +{ + + uint32_t R = x&0xF; + R |= ( (x>>1) & 0xF0); + R |= ( (x>>2) & 0xF00); + R |= ( (x>>3) & 0xF000); + R |= ( (x>>4) & 0xF0000); + R |= ( (x>>5) & 0xF00000); + + return R; +} + +inline uint32_t audio2adat(uint32_t x) +{ + uint32_t R = 0x02108421; + R |= ( (x << 1) & 0x1E ); + R |= ( (x << 2) & 0x3c0 ); + R |= ( (x << 3) & 0x7800 ); + R |= ( (x << 4) & 0xf0000 ); + R |= ( (x << 5) & 0x1E00000 ); + R |= ( (x << 6) & 0x3c000000 ); + return R; +} + +inline void adat_enc(uint32_t* in, uint32_t* out) +{ + uint32_t R0, R1; + R0 = audio2adat(in[0]); + R1 = audio2adat(in[1]); + out[0] = R0 | (R1 << 30); + R0 = audio2adat(in[2]); + out[1] = (R0 << 28) | (R1 >> 2); + R1 = audio2adat(in[3]); + out[2] = (R0 >> 4) | (R1 << 26); + R0 = audio2adat(in[4]); + out[3] = (R0 << 24) | (R1 >> 6); + R1 = audio2adat(in[5]); + out[4] = (R0 >> 8) | (R1 << 22); + R0 = audio2adat(in[6]); + out[5] = (R0 << 20) | (R1 >> 10); + R1 = audio2adat(in[7]); + out[6] = (R0 >> 12) | (R1 << 18); + out[7] = 0x08010000 | (R1 >> 14); +} + +inline void adat_dec(uint32_t* in, uint32_t* out) +{ + uint32_t R0, R1; + R0 = in[0]; + R1 = in[1]; + out[0] = adat2audio(R0 >> 1); + out[1] = adat2audio( (R0 >> 31) | (R1 << 1) ); + R0 = in[2]; + out[2] = adat2audio( (R1 >> 29) | (R0 << 3) ); + R1 = in[3]; + out[3] = adat2audio( (R0 >> 27) | (R1 << 5) ); + R0 = in[4]; + out[4] = adat2audio( (R1 >> 25) | (R0 << 7) ); + R1 = in[5]; + out[5] = adat2audio( (R0 >> 23) | (R1 << 9) ); + R0 = in[6]; + out[6] = adat2audio( (R1 >> 21) | (R0 << 11) ); + R1 = in[7]; + out[7] = adat2audio( (R0 >> 19) | (R1 << 13) ); +} + + +inline void nrz_enc(uint32_t* in, uint32_t* out) +{ + static char last_bit = 0; + for (int i = 0; i < 8; i++) + { + register uint32_t R = 0; + uint32_t x = in[i]; + unsigned char c; + for (int j = 0; j < 4; j++) + { + c = lut[(unsigned char)(x >> (j*8))]; + + c = last_bit ? ~c : c; + last_bit = c >> 7; + R = rorn(R | c, 8); + } + out[i] = R; + } +} + +inline void nrz_dec(uint32_t* in, uint32_t* out) +{ + static char dec_last_bit = 0; + for (int i = 0; i < 8; i++) + { + uint32_t x = in[i]; + out[i] = x ^ ( (x << 1) | dec_last_bit ); + dec_last_bit = x >> 31; + } +} + + + + int main() { Serial pc(USBTX, USBRX); @@ -77,7 +182,7 @@ for (int i = 0; i < 8; i++) { - data[i] = 0x00842184; + data[i] = 0x00042184 + (i << 20); } uint32_t nframes = 480000; // 10s real time data @@ -85,229 +190,21 @@ t.start(); for (int j = 0; j < nframes; j++) { - - register uint32_t r0 = 0x08010842; // user data (0), sync and ADAT '1's - register uint32_t r1 = rorn(data[7], 8); - register uint32_t R4 = 0x0000000F; // To write 4 audio bits at a time - unsigned char last_bit = 0; - - //ADAT frame encoding, starting from last word (sync) - // Pn comments enlight 'end of encoded word' - r0 |= (r1 & (R4 << 12)); - - ror1(&r1); - r0 |= (r1 & (R4 << 7)); - - ror1(&r1); - r0 |= (r1 & (R4 << 2)); - - ror1(&r1); - r0 |= (r1 & (R4 >> 3 )); - -//P0 - adat[7] = r0; - r0 = 0x10842108; - r0 |= (r1 & (R4 << 29)); - - ror1(&r1); - r0 |= (r1 & (R4 << 24)); - - ror1(&r1); - r0 |= (r1 & (R4 << 19)); - - r1 = rorn(data[6], 6); - r0 |= (r1 & (R4 << 14)); - - ror1(&r1); - r0 |= (r1 & (R4 << 9)); - - ror1(&r1); - r0 |= (r1 & (R4 << 4)); - - ror1(&r1); - r0 |= (r1 & (R4 >> 1 )); - -//P1 - //ror1(&r1); - adat[6] = r0; - r0 = 0x42108421; - r0 |= (r1 & (R4 << 31)); - - ror1(&r1); - r0 |= (r1 & (R4 << 26)); - - ror1(&r1); - - r0 |= (r1 & (R4 << 21)); - - r1 = rorn(data[5], 4); - r0 |= (r1 & (R4 << 16)); - - ror1(&r1); - r0 |= (r1 & (R4 << 11)); - - ror1(&r1); - r0 |= (r1 & (R4 << 6)); - - ror1(&r1); - r0 |= (r1 & (R4 << 1)); - - ror1(&r1); -//P2 - adat[5] = r0; - r0 = 0x08421084; - r0 |= (r1 & (R4 << 28)); - - ror1(&r1); - r0 |= (r1 & (R4 << 23)); - - r1 = rorn(data[4], 2); - r0 |= (r1 & (R4 << 18)); - - ror1(&r1); - r0 |= (r1 & (R4 << 13)); - - ror1(&r1); - r0 |= (r1 & (R4 << 8)); - - ror1(&r1); - r0 |= (r1 & (R4 << 3)); - - ror1(&r1); - r0 |= (r1 & (R4 >> 2 )); - -//P3 - adat[4] = r0; - r0 = 0x21084210; - r0 |= (r1 & (R4 << 30)); - - ror1(&r1); - r0 |= (r1 & (R4 << 25)); - - - r1 = data[3]; - r0 |= (r1 & (R4 << 20)); - - ror1(&r1); - r0 |= (r1 & (R4 << 15)); - - ror1(&r1); - r0 |= (r1 & (R4 << 10)); - - ror1(&r1); - r0 |= (r1 & (R4 << 5)); + if (pb) // so that the compiler cannot preprocess anything + { + for (int i = 0; i < 8; i++) + { + data[i] = (data[i] - i) &0xffffff;//make it recursive (makes really sure the compiler won't attempt to preprocess anything) + } - ror1(&r1); - r0 |= (r1 & (R4)); - - ror1(&r1); -//P4 - adat[3] = r0; - - r0 = 0x84210842; - r0 |= (r1 & (R4 << 27)); - r1 = data[2] << 2; - - r0 |= (r1 & (R4 << 22)); - ror1(&r1); - - r0 |= (r1 & (R4 << 17)); - ror1(&r1); - - r0 |= (r1 & (R4 << 12)); - ror1(&r1); - - r0 |= (r1 & (R4 << 7)); - ror1(&r1); - - r0 |= (r1 & (R4 << 2)); - ror1(&r1); - - r0 |= (r1 & (R4 >> 3)); - -//P5 - adat[2] = r0; - - r0 = 0x10842108; - r0 |= (r1 & (R4 << 29)); - r1 = data[1] << 4; - - r0 |= (r1 & (R4 << 24)); - ror1(&r1); - - r0 |= (r1 & (R4 << 19)); - ror1(&r1); - - r0 |= (r1 & (R4 << 14)); - ror1(&r1); - - r0 |= (r1 & (R4 << 9)); - ror1(&r1); - - r0 |= (r1 & (R4 << 4)); - ror1(&r1); - - r0 |= (r1 & (R4 >> 1)); - ror1(&r1); - -//P6 - adat[1] = r0; - - r0 = 0x42108421; - r0 |= (r1 & (R4 << 31)); - r1 = data[0] << 6; - - r0 |= (r1 & (R4 << 26)); - ror1(&r1); - - r0 |= (r1 & (R4 << 21)); - ror1(&r1); - - r0 |= (r1 & (R4 << 16)); - ror1(&r1); - - r0 |= (r1 & (R4 << 11)); - ror1(&r1); - - r0 |= (r1 & (R4 << 6)); - ror1(&r1); - - r0 |= (r1 & (R4 << 1)); - ror1(&r1); - -//P7 -- final - adat[0] = r0; - -// NRZ encoding (8-bit LUT based) CPU intensive because recursive -// -- decoding should be much faster (xor(D, (D>>1)) over 32-bit values) - for (int i = 0; i < 8; i++) - { - register uint32_t R = 0; - uint32_t x = adat[i]; - unsigned char c; - for (int j = 0; j < 4; j++) - { - c = lut[(unsigned char)(x >> (j*8))]; - - c = last_bit ? ~c : c; - last_bit = c >> 7; - R = rorn(R | c, 8); } - adat_nrz[i] = R; - } - - - if (pb) // so that the compiler cannot preprocess anything - { - for (int i = 0; i < 8; i++) - { - data[i] = adat[i] &0xffffff;//make it recursive (makes really sure the compiler won't attempt to preprocess anything) - } - + myled = pb; + + adat_enc(data, adat); + nrz_enc(adat, adat_nrz); + nrz_dec(adat_nrz, dec_nrz); + adat_dec(dec_nrz, adec); } - myled = pb; - } - t.stop(); @@ -316,7 +213,7 @@ gprintf("The time taken was %f seconds\n", toto.str()); for (int i = 0; i < 8; i++) { - printf("aata[%d] = %s\n", i, byte_to_binary(data[i])); + printf("data[%d] = %s\n", i, byte_to_binary(data[i])); } for (int i = 0; i < 8; i++) { @@ -326,6 +223,19 @@ { printf("adat_nrz[%d] = %s\n", i, byte_to_binary(adat_nrz[i])); } + for (int i = 0; i < 8; i++) + { + printf("dec_nrz[%d] = %s\n", i, byte_to_binary(dec_nrz[i])); + } + for (int i = 0; i < 8; i++) + { + printf("adec[%d] = %s\n", i, byte_to_binary(adec[i])); + } + + + + + }