diff options
Diffstat (limited to 'lib/yazedc.cpp')
-rw-r--r-- | lib/yazedc.cpp | 603 |
1 files changed, 8 insertions, 595 deletions
diff --git a/lib/yazedc.cpp b/lib/yazedc.cpp index f4bced0..4f6144c 100644 --- a/lib/yazedc.cpp +++ b/lib/yazedc.cpp @@ -26,199 +26,14 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include "yazedc.h" -#define RS_L12_BITS 8 - -/* audio sector definitions for CIRC */ -#define FRAMES_PER_SECTOR 98 -/* user data bytes per frame */ -#define L1_RAW 24 -/* parity bytes with 8 bit */ -#define L1_Q 4 -#define L1_P 4 - -/* audio sector Cross Interleaved Reed-Solomon Code (CIRC) encoder (layer 1) */ -/* adds P- and Q- parity information to audio (f2) frames. Also - optionally handles the various delays and permutations. The output with all - stages enabled can be fed into the Eight-Fourteen-Modulator. - On input: 2352 bytes of audio data is given. - On output: 3136 bytes of CIRC enriched audio data are returned. - */ -int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR], - unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], - int delay1, int delay2, int delay3, int scramble); - -/* data sector definitions for RSPC */ -/* user data bytes per frame */ -#define L2_RAW (1024*2) -/* parity bytes for 16 bit units */ -#define L2_Q (26*2*2) -#define L2_P (43*2*2) - -/* known sector types */ -#define MODE_0 0 -#define MODE_1 1 -#define MODE_2 2 -#define MODE_2_FORM_1 3 -#define MODE_2_FORM_2 4 - -#ifdef __cplusplus -extern "C" { -#endif - -/* set one of the MODE_* constants for subsequent data sector formatting */ -int set_sector_type(int st); -/* get the current sector type setting for data sector formatting */ -int get_sector_type(void); - -/* data sector layer 2 Reed-Solomon Product Code encoder */ -/* encode the given data portion depending on sector type (see - get/set_sector_type() functions). Use the given address for the header. - The returned data is __unscrambled__ and not in F2-frame format (for that - see function scramble_L2()). - Supported sector types: - MODE_0: a 12-byte sync field, a header and 2336 zeros are returned. - MODE_1: the user data portion (2048 bytes) has to be given - at offset 16 in the inout array. - Sync-, header-, edc-, spare-, p- and q- fields will be added. - MODE_2: the user data portion (2336 bytes) has to be given - at offset 16 in the inout array. - Sync- and header- fields will be added. - MODE_2_FORM_1: the user data portion (8 bytes subheader followed - by 2048 bytes data) has to be given at offset 16 - in the inout array. - Sync-, header-, edc-, p- and q- fields will be added. - MODE_2_FORM_2: the user data portion (8 bytes subheader followed - by 2324 bytes data) has to be given at offset 16 - in the inout array. - Sync-, header- and edc- fields will be added. -*/ -int do_encode_L2(unsigned char *inout, int sectortype, unsigned address); -int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q]); -int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]); -unsigned long int build_edc(unsigned char inout[], int from, int upto); - -/* generates f2 frames from otherwise fully formatted sectors (generated by - do_encode_L2()). */ -int scramble_L2(unsigned char *inout); - -#ifdef __cplusplus -} -#endif - -/* r-w sub channel definitions */ -#define RS_SUB_RW_BITS 6 - -#define PACKETS_PER_SUBCHANNELFRAME 4 -#define LSUB_RAW 18 -#define LSUB_QRAW 2 -/* 6 bit */ -#define LSUB_Q 2 -#define LSUB_P 4 - -#ifdef __cplusplus -extern "C" { -#endif - -/* R-W subchannel encoder */ -/* On input: 72 bytes packed user data, four frames with each 18 bytes. - On output: per frame: 2 bytes user data, 2 bytes Q parity, - 16 bytes user data, 4 bytes P parity. - Options: - delay1: use low level delay line - scramble: perform low level permutations - */ -int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], - unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], - int delay1, int scramble); -int do_decode_sub(unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], - unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], - int delay1, int scramble); - -int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q]); -int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]); - -#ifdef __cplusplus -} -#endif - -unsigned char minute, second, frame; - -/* these prototypes will become public when the function are implemented */ -#ifdef MAIN -static int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)], - unsigned char out[L2_RAW]); -static int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], - unsigned char out[L1_RAW*FRAMES_PER_SECTOR], - int delay1, int delay2, int delay3, int scramble); -#endif +yazedc::yazedc() : minute(0), second(2), frame(0), sectortype(0) {} /* ------------- tables generated by gen_encodes --------------*/ #include "crctables" -static int encode_L1_Q(unsigned char inout[L1_RAW + L1_Q]) -{ - unsigned char *Q; - int i; - - memmove(inout+L1_RAW/2+L1_Q, inout+L1_RAW/2, L1_RAW/2); - Q = inout + L1_RAW/2; - - memset(Q, 0, L1_Q); - for (i = 0; i < L1_RAW + L1_Q; i++) { - unsigned char data; - - if (i == L1_RAW/2) i += L1_Q; - data = inout[i]; - if (data != 0) { - unsigned char base = rs_l12_log[data]; - - Q[0] ^= rs_l12_alog[(base+AQ[0][i]) % ((1 << RS_L12_BITS)-1)]; - Q[1] ^= rs_l12_alog[(base+AQ[1][i]) % ((1 << RS_L12_BITS)-1)]; - Q[2] ^= rs_l12_alog[(base+AQ[2][i]) % ((1 << RS_L12_BITS)-1)]; - Q[3] ^= rs_l12_alog[(base+AQ[3][i]) % ((1 << RS_L12_BITS)-1)]; - } - } - - return 0; -} -static int encode_L1_P(unsigned char inout[L1_RAW + L1_Q + L1_P]) -{ - unsigned char *P; - int i; - - P = inout + L1_RAW + L1_Q; - - memset(P, 0, L1_P); - for (i = 0; i < L2_RAW + L2_Q + L2_P; i++) { - unsigned char data; - - data = inout[i]; - if (data != 0) { - unsigned char base = rs_l12_log[data]; - - P[0] ^= rs_l12_alog[(base+AP[0][i]) % ((1 << RS_L12_BITS)-1)]; - P[1] ^= rs_l12_alog[(base+AP[1][i]) % ((1 << RS_L12_BITS)-1)]; - P[2] ^= rs_l12_alog[(base+AP[2][i]) % ((1 << RS_L12_BITS)-1)]; - P[3] ^= rs_l12_alog[(base+AP[3][i]) % ((1 << RS_L12_BITS)-1)]; - } - } - return 0; -} - -#ifdef MAIN -static int decode_L1_Q(unsigned char inout[L1_RAW + L1_Q]) -{ - return 0; -} - -static int decode_L1_P(unsigned char in[L1_RAW + L1_Q + L1_P]) -{ - return 0; -} -#endif - static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q]) { unsigned char *Q; @@ -322,19 +137,10 @@ static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P]) return 0; } -int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q]) -{ - return 0; -} -int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]) -{ - return 0; -} - -int scramble_L2(unsigned char *inout) +int yazedc::scramble_L2(unsigned char *inout) { unsigned char *r = inout + 12; - unsigned char *s = yellowbook_scrambler; + const unsigned char *s = yellowbook_scrambler; unsigned int i; unsigned int *f = (unsigned int *)inout; @@ -350,290 +156,7 @@ int scramble_L2(unsigned char *inout) return 0; } -static int encode_LSUB_Q(unsigned char inout[LSUB_RAW + LSUB_Q]) -{ - unsigned char *Q; -/* unsigned char data; */ - int i; - - memmove(inout+LSUB_QRAW+LSUB_Q, inout+LSUB_QRAW, LSUB_RAW-LSUB_QRAW); - Q = inout + LSUB_QRAW; - - memset(Q, 0, LSUB_Q); - -#if 0 - data = inout[0] & 0x3f; - if (data != 0) { - unsigned char base = rs_sub_rw_log[data]; - - Q[0] ^= rs_sub_rw_alog[(base+26) % ((1 << RS_SUB_RW_BITS)-1)]; - Q[1] ^= rs_sub_rw_alog[(base+7) % ((1 << RS_SUB_RW_BITS)-1)]; - } - data = inout[1] & 0x3f; - if (data != 0) { - unsigned char base = rs_sub_rw_log[data]; - - Q[0] ^= rs_sub_rw_alog[(base+6) % ((1 << RS_SUB_RW_BITS)-1)]; - Q[1] ^= rs_sub_rw_alog[(base+1) % ((1 << RS_SUB_RW_BITS)-1)]; - } -#else - for (i = 0; i < LSUB_QRAW; i++) { - unsigned char data; - - data = inout[i] & 0x3f; - if (data != 0) { - unsigned char base = rs_sub_rw_log[data]; - - Q[0] ^= rs_sub_rw_alog[(base+SQ[0][i]) % ((1 << RS_SUB_RW_BITS)-1)]; - Q[1] ^= rs_sub_rw_alog[(base+SQ[1][i]) % ((1 << RS_SUB_RW_BITS)-1)]; - } - } -#endif - return 0; -} - - -static int encode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]) -{ - unsigned char *P; - int i; - - P = inout + LSUB_RAW + LSUB_Q; - - memset(P, 0, LSUB_P); - for (i = 0; i < LSUB_RAW + LSUB_Q; i++) { - unsigned char data; - - data = inout[i] & 0x3f; - if (data != 0) { - unsigned char base = rs_sub_rw_log[data]; - - P[0] ^= rs_sub_rw_alog[(base+SP[0][i]) % ((1 << RS_SUB_RW_BITS)-1)]; - P[1] ^= rs_sub_rw_alog[(base+SP[1][i]) % ((1 << RS_SUB_RW_BITS)-1)]; - P[2] ^= rs_sub_rw_alog[(base+SP[2][i]) % ((1 << RS_SUB_RW_BITS)-1)]; - P[3] ^= rs_sub_rw_alog[(base+SP[3][i]) % ((1 << RS_SUB_RW_BITS)-1)]; - } - } - return 0; -} - -int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q]) -{ - unsigned char Q[LSUB_Q]; - int i; - - memset(Q, 0, LSUB_Q); - for (i = LSUB_QRAW + LSUB_Q -1; i>=0; i--) { - unsigned char data; - - data = inout[LSUB_QRAW + LSUB_Q -1 -i] & 0x3f; - if (data != 0) { - unsigned char base = rs_sub_rw_log[data]; - - Q[0] ^= rs_sub_rw_alog[(base+0*i) % ((1 << RS_SUB_RW_BITS)-1)]; - Q[1] ^= rs_sub_rw_alog[(base+1*i) % ((1 << RS_SUB_RW_BITS)-1)]; - } - } - - return (Q[0] != 0 || Q[1] != 0); -} -int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]) -{ - unsigned char P[LSUB_P]; - int i; - - memset(P, 0, LSUB_P); - for (i = LSUB_RAW + LSUB_Q + LSUB_P-1; i>=0; i--) { - unsigned char data; - - data = inout[LSUB_RAW + LSUB_Q + LSUB_P -1 -i] & 0x3f; - if (data != 0) { - unsigned char base = rs_sub_rw_log[data]; - - P[0] ^= rs_sub_rw_alog[(base+0*i) % ((1 << RS_SUB_RW_BITS)-1)]; - P[1] ^= rs_sub_rw_alog[(base+1*i) % ((1 << RS_SUB_RW_BITS)-1)]; - P[2] ^= rs_sub_rw_alog[(base+2*i) % ((1 << RS_SUB_RW_BITS)-1)]; - P[3] ^= rs_sub_rw_alog[(base+3*i) % ((1 << RS_SUB_RW_BITS)-1)]; - } - } - - return (P[0] != 0 || P[1] != 0 || P[2] != 0 || P[3] != 0); -} - -/* Layer 1 CIRC en/decoder */ -#define MAX_L1_DEL1 2 -static unsigned char l1_delay_line1[MAX_L1_DEL1][L1_RAW]; -#define MAX_L1_DEL2 108 -static unsigned char l1_delay_line2[MAX_L1_DEL2][L1_RAW+L1_Q]; -#define MAX_L1_DEL3 1 -static unsigned char l1_delay_line3[MAX_L1_DEL3][L1_RAW+L1_Q+L1_P]; -static unsigned l1_del_index; - -int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR], - unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], - int delay1, int delay2, int delay3, int permute) -{ - int i; - - for (i = 0; i < FRAMES_PER_SECTOR; i++) { - int j; - unsigned char t; - - if (in != out) - memcpy(out, in, L1_RAW); - - if (delay1) { - /* shift through delay line 1 */ - for (j = 0; j < L1_RAW; j++) { - if (((j/4) % MAX_L1_DEL1) == 0) { - t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j]; - l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = out[j]; - out[j] = t; - } - } - } - - if (permute) { - /* permute */ - t = out[2]; out[2] = out[8]; out[8] = out[10]; out[10] = out[18]; - out[18] = out[6]; out [6] = t; - t = out[3]; out[3] = out[9]; out[9] = out[11]; out[11] = out[19]; - out[19] = out[7]; out [7] = t; - t = out[4]; out[4] = out[16]; out[16] = out[20]; out[20] = out[14]; - out[14] = out[12]; out [12] = t; - t = out[5]; out[5] = out[17]; out[17] = out[21]; out[21] = out[15]; - out[15] = out[13]; out [13] = t; - } - - /* build Q parity */ - encode_L1_Q(out); - - if (delay2) { - /* shift through delay line 2 */ - for (j = 0; j < L1_RAW+L1_Q; j++) { - if (j != 0) { - t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j]; - l1_delay_line2[(l1_del_index + j*4) % MAX_L1_DEL2][j] = out[j]; - out[j] = t; - } - } - } - - /* build P parity */ - encode_L1_P(out); - - if (delay3) { - /* shift through delay line 3 */ - for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) { - if (((j) & MAX_L1_DEL3) == 0) { - t = l1_delay_line3[0][j]; - l1_delay_line3[0][j] = out[j]; - out[j] = t; - } - } - } - - /* invert Q and P parity */ - for (j = 0; j < L1_Q; j++) - out[j+12] = ~out[j+12]; - for (j = 0; j < L1_P; j++) - out[j+28] = ~out[j+28]; - - l1_del_index++; - out += L1_RAW+L1_Q+L1_P; - in += L1_RAW; - } - return 0; -} - -#ifdef MAIN -int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], - unsigned char out[L1_RAW*FRAMES_PER_SECTOR], - int delay1, int delay2, int delay3, int permute) -{ - int i; - - for (i = 0; i < FRAMES_PER_SECTOR; i++) { - int j; - unsigned char t; - - if (delay3) { - /* shift through delay line 3 */ - for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) { - if (((j) & MAX_L1_DEL3) != 0) { - t = l1_delay_line3[0][j]; - l1_delay_line3[0][j] = in[j]; - in[j] = t; - } - } - } - - /* invert Q and P parity */ - for (j = 0; j < L1_Q; j++) - in[j+12] = ~in[j+12]; - for (j = 0; j < L1_P; j++) - in[j+28] = ~in[j+28]; - - /* build P parity */ - decode_L1_P(in); - - if (delay2) { - /* shift through delay line 2 */ - for (j = 0; j < L1_RAW+L1_Q; j++) { - if (j != L1_RAW+L1_Q-1) { - t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j]; - l1_delay_line2[(l1_del_index + (MAX_L1_DEL2 - j*4)) % MAX_L1_DEL2][j] = in[j]; - in[j] = t; - } - } - } - - /* build Q parity */ - decode_L1_Q(in); - - if (permute) { - /* permute */ - t = in[2]; in[2] = in[6]; in[6] = in[18]; in[18] = in[10]; - in[10] = in[8]; in [8] = t; - t = in[3]; in[3] = in[7]; in[7] = in[19]; in[19] = in[11]; - in[11] = in[9]; in [9] = t; - t = in[4]; in[4] = in[12]; in[12] = in[14]; in[14] = in[20]; - in[20] = in[16]; in [16] = t; - t = in[5]; in[5] = in[13]; in[13] = in[15]; in[15] = in[21]; - in[21] = in[17]; in [17] = t; - } - - if (delay1) { - /* shift through delay line 1 */ - for (j = 0; j < L1_RAW; j++) { - if (((j/4) % MAX_L1_DEL1) != 0) { - t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j]; - l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = in[j]; - in[j] = t; - } - } - } - - if (in != out) - memcpy(out, in, (L1_RAW)); - - l1_del_index++; - in += L1_RAW+L1_Q+L1_P; - out += L1_RAW; - } - return 0; -} - -#endif - -#if 0 -static unsigned char bin2bcd(unsigned p) -{ - return ((p/10)<<4)|(p%10); -} -#endif - -static int build_address(unsigned char inout[], int sectortype, unsigned address) +int yazedc::build_address(unsigned char inout[], int sectortype, unsigned address) { inout[12] = minute; inout[13] = second; @@ -654,7 +177,6 @@ static int build_address(unsigned char inout[], int sectortype, unsigned address } #include "crctable.out" - unsigned long int build_edc(unsigned char inout[], int from, int upto) { unsigned char *p = inout+from; @@ -667,7 +189,7 @@ unsigned long int build_edc(unsigned char inout[], int from, int upto) } /* Layer 2 Product code en/decoder */ -int do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], int sectortype, unsigned address) +int yazedc::do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], int sectortype, unsigned address) { unsigned long int result; @@ -728,119 +250,12 @@ int do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], int secto return 0; } -#ifdef MAIN -static int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)], - unsigned char out[L2_RAW]) -{ - return 0; -} -#endif - - -#define MAX_SUB_DEL 8 -static unsigned char sub_delay_line[MAX_SUB_DEL][LSUB_RAW+LSUB_Q+LSUB_P]; -static unsigned sub_del_index; - -/* R-W Subchannel en/decoder */ -int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], - unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], - int delay1, int permute) -{ - int i; - - if (in == out) return -1; - - for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) { - int j; - unsigned char t; - - memcpy(out, in, (LSUB_RAW)); - - /* build Q parity */ - encode_LSUB_Q(out); - - /* build P parity */ - encode_LSUB_P(out); - - if (permute) { - /* permute */ - t = out[1]; out[1] = out[18]; out[18] = t; - t = out[2]; out[2] = out[ 5]; out[ 5] = t; - t = out[3]; out[3] = out[23]; out[23] = t; - } - - if (delay1) { - /* shift through delay_line */ - for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) { - if ((j % MAX_SUB_DEL) != 0) { - t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j]; - sub_delay_line[(sub_del_index + j) % MAX_SUB_DEL][j] = out[j]; - out[j] = t; - } - } - } - sub_del_index++; - out += LSUB_RAW+LSUB_Q+LSUB_P; - in += LSUB_RAW; - } - return 0; -} - -int -do_decode_sub( - unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], - unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], - int delay1, int permute) -{ - int i; - - if (in == out) return -1; - - for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) { - int j; - unsigned char t; - - if (delay1) { - /* shift through delay_line */ - for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) { - if ((j % MAX_SUB_DEL) != MAX_SUB_DEL-1) { - t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j]; - sub_delay_line[(sub_del_index + (MAX_SUB_DEL - j)) % MAX_SUB_DEL][j] = in[j]; - in[j] = t; - } - } - } - - if (permute) { - /* permute */ - t = in[1]; in[1] = in[18]; in[18] = t; - t = in[2]; in[2] = in[ 5]; in[ 5] = t; - t = in[3]; in[3] = in[23]; in[23] = t; - } - - /* build P parity */ - decode_LSUB_P(in); - - /* build Q parity */ - decode_LSUB_Q(in); - - memcpy(out, in, LSUB_QRAW); - memcpy(out+LSUB_QRAW, in+LSUB_QRAW+LSUB_Q, LSUB_RAW-LSUB_QRAW); - - sub_del_index++; - in += LSUB_RAW+LSUB_Q+LSUB_P; - out += LSUB_RAW; - } - return 0; -} - -static int sectortype = MODE_0; -int get_sector_type(void) +int yazedc::get_sector_type(void) { return sectortype; } -int set_sector_type(int st) +int yazedc::set_sector_type(int st) { switch(st) { case MODE_0: @@ -854,5 +269,3 @@ int set_sector_type(int st) } return 0; } - -/* ------------- --------------*/ |