filename | src/gdrom/edc_ecc.c |
changeset | 678:35eb00945316 |
prev | 669:ab344e42bca9 |
author | nkeynes |
date | Tue Jul 29 06:35:28 2008 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Workaround OS X's inability to handle CD reads of unknown size (ie where the read request failed to specify an expected sector type) - read raw sectors and parse it out by hand. |
file | annotate | diff | log | raw |
nkeynes@644 | 1 | /* |
nkeynes@644 | 2 | * Note: This file has been extracted from crkit 1.1.6 and modified to work within |
nkeynes@669 | 3 | * lxdream. |
nkeynes@644 | 4 | */ |
nkeynes@644 | 5 | /* |
nkeynes@644 | 6 | * This file has been modified for the cdrkit suite. |
nkeynes@644 | 7 | * |
nkeynes@644 | 8 | * The behaviour and appearence of the program code below can differ to a major |
nkeynes@644 | 9 | * extent from the version distributed by the original author(s). |
nkeynes@644 | 10 | * |
nkeynes@644 | 11 | * For details, see Changelog file distributed with the cdrkit package. If you |
nkeynes@644 | 12 | * received this file from another source then ask the distributing person for |
nkeynes@644 | 13 | * a log of modifications. |
nkeynes@644 | 14 | * |
nkeynes@644 | 15 | */ |
nkeynes@644 | 16 | |
nkeynes@644 | 17 | /* @(#)edc_ecc.c 1.21 03/04/04 Copyright 1998-2002 Heiko Eissfeldt, Joerg Schilling */ |
nkeynes@644 | 18 | |
nkeynes@644 | 19 | /* |
nkeynes@644 | 20 | * Copyright 1998-2002 by Heiko Eissfeldt |
nkeynes@644 | 21 | * Copyright 2002 by Joerg Schilling |
nkeynes@644 | 22 | * |
nkeynes@644 | 23 | * This file contains protected intellectual property. |
nkeynes@644 | 24 | * |
nkeynes@644 | 25 | * reed-solomon encoder / decoder for compact discs. |
nkeynes@644 | 26 | * |
nkeynes@644 | 27 | */ |
nkeynes@644 | 28 | /* |
nkeynes@644 | 29 | * This program is free software; you can redistribute it and/or modify |
nkeynes@644 | 30 | * it under the terms of the GNU General Public License version 2 |
nkeynes@644 | 31 | * as published by the Free Software Foundation. |
nkeynes@644 | 32 | * |
nkeynes@644 | 33 | * This program is distributed in the hope that it will be useful, |
nkeynes@644 | 34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
nkeynes@644 | 35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
nkeynes@644 | 36 | * GNU General Public License for more details. |
nkeynes@644 | 37 | * |
nkeynes@644 | 38 | * You should have received a copy of the GNU General Public License along with |
nkeynes@644 | 39 | * this program; see the file COPYING. If not, write to the Free Software |
nkeynes@644 | 40 | * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
nkeynes@644 | 41 | */ |
nkeynes@644 | 42 | |
nkeynes@644 | 43 | #include <stdint.h> |
nkeynes@644 | 44 | #include <stdio.h> |
nkeynes@644 | 45 | #include <string.h> |
nkeynes@678 | 46 | #include "gdrom/gddriver.h" |
nkeynes@644 | 47 | #include "ecc.h" |
nkeynes@644 | 48 | |
nkeynes@644 | 49 | #define xaligned(a, s) ((((uintptr_t)(a)) & (s)) == 0 ) |
nkeynes@644 | 50 | |
nkeynes@669 | 51 | int do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], |
nkeynes@669 | 52 | int sectortype, unsigned address); |
nkeynes@644 | 53 | |
nkeynes@669 | 54 | int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR], |
nkeynes@669 | 55 | unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], |
nkeynes@669 | 56 | int delay1, int delay2, int delay3, int permute); |
nkeynes@669 | 57 | |
nkeynes@669 | 58 | int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], |
nkeynes@669 | 59 | unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], |
nkeynes@669 | 60 | int delay1, int permute); |
nkeynes@669 | 61 | |
nkeynes@669 | 62 | int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)], |
nkeynes@669 | 63 | unsigned char out[L2_RAW]); |
nkeynes@669 | 64 | |
nkeynes@669 | 65 | int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], |
nkeynes@669 | 66 | unsigned char out[L1_RAW*FRAMES_PER_SECTOR], |
nkeynes@669 | 67 | int delay1, int delay2, int delay3, int permute); |
nkeynes@669 | 68 | |
nkeynes@669 | 69 | int do_decode_sub(unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], |
nkeynes@669 | 70 | unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], |
nkeynes@669 | 71 | int delay1, int permute); |
nkeynes@669 | 72 | |
nkeynes@644 | 73 | |
nkeynes@644 | 74 | |
nkeynes@644 | 75 | /* ------------- tables generated by gen_encodes --------------*/ |
nkeynes@644 | 76 | |
nkeynes@644 | 77 | #include "edc_scramble.h" |
nkeynes@644 | 78 | |
nkeynes@644 | 79 | #define DO4(a) a;a;a;a; |
nkeynes@644 | 80 | #define DO13(a) a;a;a;a;a;a;a;a;a;a;a;a;a; |
nkeynes@644 | 81 | |
nkeynes@644 | 82 | /* |
nkeynes@644 | 83 | * Scrambles 2352 - 12 = 2340 bytes |
nkeynes@644 | 84 | */ |
nkeynes@644 | 85 | int scramble_L2(unsigned char *inout); |
nkeynes@644 | 86 | |
nkeynes@644 | 87 | int scramble_L2(unsigned char *inout) |
nkeynes@644 | 88 | { |
nkeynes@644 | 89 | #ifndef EDC_SCRAMBLE_NOSWAP |
nkeynes@644 | 90 | unsigned int *f = (unsigned int *)inout; |
nkeynes@644 | 91 | #endif |
nkeynes@644 | 92 | |
nkeynes@644 | 93 | if (!xaligned(inout + 12, sizeof(uint32_t)-1)) { |
nkeynes@644 | 94 | |
nkeynes@644 | 95 | uint8_t *r = inout + 12; |
nkeynes@644 | 96 | const uint8_t *s = yellowbook_scrambler; |
nkeynes@644 | 97 | register int i; |
nkeynes@644 | 98 | |
nkeynes@644 | 99 | for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(unsigned char)/4; --i >= 0;) { |
nkeynes@644 | 100 | DO4(*r++ ^= *s++); |
nkeynes@644 | 101 | } |
nkeynes@644 | 102 | |
nkeynes@644 | 103 | } else { |
nkeynes@644 | 104 | uint32_t *r = (uint32_t *) (inout + 12); |
nkeynes@644 | 105 | const uint32_t *s = yellowbook_scrambler_uint32; |
nkeynes@644 | 106 | register int i; |
nkeynes@644 | 107 | |
nkeynes@644 | 108 | for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(uint32_t)/13; --i >= 0;) { |
nkeynes@644 | 109 | DO13(*r++ ^= *s++); |
nkeynes@644 | 110 | } |
nkeynes@644 | 111 | } |
nkeynes@644 | 112 | |
nkeynes@644 | 113 | #ifndef EDC_SCRAMBLE_NOSWAP |
nkeynes@644 | 114 | |
nkeynes@644 | 115 | /* generate F1 frames */ |
nkeynes@644 | 116 | for (i = 2352/sizeof(unsigned int); i; i--) { |
nkeynes@644 | 117 | *f++ = ((*f & 0xff00ff00UL) >> 8) | ((*f & 0x00ff00ffUL) << 8); |
nkeynes@644 | 118 | } |
nkeynes@644 | 119 | #endif |
nkeynes@644 | 120 | |
nkeynes@644 | 121 | return (0); |
nkeynes@644 | 122 | } |
nkeynes@644 | 123 | |
nkeynes@644 | 124 | #include "edc_l2sq.h" |
nkeynes@644 | 125 | |
nkeynes@644 | 126 | static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q]); |
nkeynes@644 | 127 | |
nkeynes@644 | 128 | static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q]) |
nkeynes@644 | 129 | { |
nkeynes@644 | 130 | unsigned char *dps; |
nkeynes@644 | 131 | unsigned char *dp; |
nkeynes@644 | 132 | unsigned char *Q; |
nkeynes@644 | 133 | register int i; |
nkeynes@644 | 134 | int j; |
nkeynes@644 | 135 | |
nkeynes@644 | 136 | Q = inout + 4 + L2_RAW + 4 + 8 + L2_P; |
nkeynes@644 | 137 | |
nkeynes@644 | 138 | dps = inout; |
nkeynes@644 | 139 | for (j = 0; j < 26; j++) { |
nkeynes@644 | 140 | register unsigned short a; |
nkeynes@644 | 141 | register unsigned short b; |
nkeynes@644 | 142 | a = b = 0; |
nkeynes@644 | 143 | |
nkeynes@644 | 144 | dp = dps; |
nkeynes@644 | 145 | for (i = 0; i < 43; i++) { |
nkeynes@644 | 146 | |
nkeynes@644 | 147 | /* LSB */ |
nkeynes@644 | 148 | a ^= L2sq[i][*dp++]; |
nkeynes@644 | 149 | |
nkeynes@644 | 150 | /* MSB */ |
nkeynes@644 | 151 | b ^= L2sq[i][*dp]; |
nkeynes@644 | 152 | |
nkeynes@644 | 153 | dp += 2*44-1; |
nkeynes@644 | 154 | if (dp >= &inout[(4 + L2_RAW + 4 + 8 + L2_P)]) { |
nkeynes@644 | 155 | dp -= (4 + L2_RAW + 4 + 8 + L2_P); |
nkeynes@644 | 156 | } |
nkeynes@644 | 157 | } |
nkeynes@644 | 158 | Q[0] = a >> 8; |
nkeynes@644 | 159 | Q[26*2] = a; |
nkeynes@644 | 160 | Q[1] = b >> 8; |
nkeynes@644 | 161 | Q[26*2+1] = b; |
nkeynes@644 | 162 | |
nkeynes@644 | 163 | Q += 2; |
nkeynes@644 | 164 | dps += 2*43; |
nkeynes@644 | 165 | } |
nkeynes@644 | 166 | return (0); |
nkeynes@644 | 167 | } |
nkeynes@644 | 168 | |
nkeynes@644 | 169 | static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P]); |
nkeynes@644 | 170 | |
nkeynes@644 | 171 | static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P]) |
nkeynes@644 | 172 | { |
nkeynes@644 | 173 | unsigned char *dp; |
nkeynes@644 | 174 | unsigned char *P; |
nkeynes@644 | 175 | register int i; |
nkeynes@644 | 176 | int j; |
nkeynes@644 | 177 | |
nkeynes@644 | 178 | P = inout + 4 + L2_RAW + 4 + 8; |
nkeynes@644 | 179 | |
nkeynes@644 | 180 | for (j = 0; j < 43; j++) { |
nkeynes@644 | 181 | register unsigned short a; |
nkeynes@644 | 182 | register unsigned short b; |
nkeynes@644 | 183 | |
nkeynes@644 | 184 | a = b = 0; |
nkeynes@644 | 185 | dp = inout; |
nkeynes@644 | 186 | for (i = 19; i < 43; i++) { |
nkeynes@644 | 187 | |
nkeynes@644 | 188 | /* LSB */ |
nkeynes@644 | 189 | a ^= L2sq[i][*dp++]; |
nkeynes@644 | 190 | |
nkeynes@644 | 191 | /* MSB */ |
nkeynes@644 | 192 | b ^= L2sq[i][*dp]; |
nkeynes@644 | 193 | |
nkeynes@644 | 194 | dp += 2*43 -1; |
nkeynes@644 | 195 | } |
nkeynes@644 | 196 | P[0] = a >> 8; |
nkeynes@644 | 197 | P[43*2] = a; |
nkeynes@644 | 198 | P[1] = b >> 8; |
nkeynes@644 | 199 | P[43*2+1] = b; |
nkeynes@644 | 200 | |
nkeynes@644 | 201 | P += 2; |
nkeynes@644 | 202 | inout += 2; |
nkeynes@644 | 203 | } |
nkeynes@644 | 204 | return (0); |
nkeynes@644 | 205 | } |
nkeynes@644 | 206 | |
nkeynes@644 | 207 | static unsigned char bin2bcd(unsigned p); |
nkeynes@644 | 208 | |
nkeynes@644 | 209 | static unsigned char bin2bcd(unsigned p) |
nkeynes@644 | 210 | { |
nkeynes@644 | 211 | return ((p/10)<<4)|(p%10); |
nkeynes@644 | 212 | } |
nkeynes@644 | 213 | |
nkeynes@644 | 214 | int cd_build_address(unsigned char inout[], int sectortype, unsigned address) |
nkeynes@644 | 215 | { |
nkeynes@644 | 216 | inout[12] = bin2bcd(address / (60*75)); |
nkeynes@644 | 217 | inout[13] = bin2bcd((address / 75) % 60); |
nkeynes@644 | 218 | inout[14] = bin2bcd(address % 75); |
nkeynes@644 | 219 | if (sectortype == MODE_0) |
nkeynes@644 | 220 | inout[15] = 0; |
nkeynes@644 | 221 | else if (sectortype == MODE_1) |
nkeynes@644 | 222 | inout[15] = 1; |
nkeynes@644 | 223 | else if (sectortype == MODE_2) |
nkeynes@644 | 224 | inout[15] = 2; |
nkeynes@644 | 225 | else if (sectortype == MODE_2_FORM_1) |
nkeynes@644 | 226 | inout[15] = 2; |
nkeynes@644 | 227 | else if (sectortype == MODE_2_FORM_2) |
nkeynes@644 | 228 | inout[15] = 2; |
nkeynes@644 | 229 | else |
nkeynes@644 | 230 | return (-1); |
nkeynes@644 | 231 | return (0); |
nkeynes@644 | 232 | } |
nkeynes@644 | 233 | |
nkeynes@644 | 234 | #include "edc_crctable.h" |
nkeynes@644 | 235 | |
nkeynes@644 | 236 | /* |
nkeynes@644 | 237 | * Called with 2064, 2056 or 2332 byte difference - all dividable by 4. |
nkeynes@644 | 238 | */ |
nkeynes@644 | 239 | unsigned int build_edc(unsigned char inout[], int from, int upto); |
nkeynes@644 | 240 | |
nkeynes@644 | 241 | unsigned int build_edc(unsigned char inout[], int from, int upto) |
nkeynes@644 | 242 | { |
nkeynes@644 | 243 | unsigned char *p = inout+from; |
nkeynes@644 | 244 | unsigned int result = 0; |
nkeynes@644 | 245 | |
nkeynes@644 | 246 | upto -= from-1; |
nkeynes@644 | 247 | upto /= 4; |
nkeynes@644 | 248 | while (--upto >= 0) { |
nkeynes@644 | 249 | result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8); |
nkeynes@644 | 250 | result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8); |
nkeynes@644 | 251 | result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8); |
nkeynes@644 | 252 | result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8); |
nkeynes@644 | 253 | } |
nkeynes@644 | 254 | return (result); |
nkeynes@644 | 255 | } |
nkeynes@644 | 256 | |
nkeynes@644 | 257 | /* Layer 2 Product code en/decoder */ |
nkeynes@669 | 258 | |
nkeynes@644 | 259 | int do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], |
nkeynes@669 | 260 | int sectortype, unsigned address) |
nkeynes@644 | 261 | { |
nkeynes@644 | 262 | unsigned int result; |
nkeynes@644 | 263 | |
nkeynes@644 | 264 | /* SYNCPATTERN "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" */ |
nkeynes@644 | 265 | #define SYNCPATTERN "\000\377\377\377\377\377\377\377\377\377\377" |
nkeynes@644 | 266 | |
nkeynes@644 | 267 | /* supply initial sync pattern */ |
nkeynes@644 | 268 | memcpy(inout, SYNCPATTERN, sizeof(SYNCPATTERN)); |
nkeynes@644 | 269 | |
nkeynes@644 | 270 | if (sectortype == MODE_0) { |
nkeynes@644 | 271 | memset(inout + sizeof(SYNCPATTERN), 0, 4 + L2_RAW + 12 + L2_P + L2_Q); |
nkeynes@644 | 272 | cd_build_address(inout, sectortype, address); |
nkeynes@644 | 273 | return (0); |
nkeynes@644 | 274 | } |
nkeynes@644 | 275 | |
nkeynes@644 | 276 | switch (sectortype) { |
nkeynes@644 | 277 | |
nkeynes@644 | 278 | case MODE_1: |
nkeynes@644 | 279 | cd_build_address(inout, sectortype, address); |
nkeynes@644 | 280 | result = build_edc(inout, 0, 16+2048-1); |
nkeynes@644 | 281 | inout[2064+0] = result >> 0L; |
nkeynes@644 | 282 | inout[2064+1] = result >> 8L; |
nkeynes@644 | 283 | inout[2064+2] = result >> 16L; |
nkeynes@644 | 284 | inout[2064+3] = result >> 24L; |
nkeynes@644 | 285 | memset(inout+2064+4, 0, 8); |
nkeynes@644 | 286 | encode_L2_P(inout+12); |
nkeynes@644 | 287 | encode_L2_Q(inout+12); |
nkeynes@644 | 288 | break; |
nkeynes@644 | 289 | case MODE_2: |
nkeynes@644 | 290 | cd_build_address(inout, sectortype, address); |
nkeynes@644 | 291 | break; |
nkeynes@644 | 292 | case MODE_2_FORM_1: |
nkeynes@644 | 293 | result = build_edc(inout, 16, 16+8+2048-1); |
nkeynes@644 | 294 | inout[2072+0] = result >> 0L; |
nkeynes@644 | 295 | inout[2072+1] = result >> 8L; |
nkeynes@644 | 296 | inout[2072+2] = result >> 16L; |
nkeynes@644 | 297 | inout[2072+3] = result >> 24L; |
nkeynes@644 | 298 | |
nkeynes@644 | 299 | /* clear header for P/Q parity calculation */ |
nkeynes@644 | 300 | inout[12] = 0; |
nkeynes@644 | 301 | inout[12+1] = 0; |
nkeynes@644 | 302 | inout[12+2] = 0; |
nkeynes@644 | 303 | inout[12+3] = 0; |
nkeynes@644 | 304 | encode_L2_P(inout+12); |
nkeynes@644 | 305 | encode_L2_Q(inout+12); |
nkeynes@644 | 306 | cd_build_address(inout, sectortype, address); |
nkeynes@644 | 307 | break; |
nkeynes@644 | 308 | case MODE_2_FORM_2: |
nkeynes@644 | 309 | cd_build_address(inout, sectortype, address); |
nkeynes@644 | 310 | result = build_edc(inout, 16, 16+8+2324-1); |
nkeynes@644 | 311 | inout[2348+0] = result >> 0L; |
nkeynes@644 | 312 | inout[2348+1] = result >> 8L; |
nkeynes@644 | 313 | inout[2348+2] = result >> 16L; |
nkeynes@644 | 314 | inout[2348+3] = result >> 24L; |
nkeynes@644 | 315 | break; |
nkeynes@644 | 316 | default: |
nkeynes@644 | 317 | return (-1); |
nkeynes@644 | 318 | } |
nkeynes@644 | 319 | |
nkeynes@644 | 320 | return (0); |
nkeynes@644 | 321 | } |
nkeynes@644 | 322 | |
nkeynes@644 | 323 | |
nkeynes@644 | 324 | /*--------------------------------------------------------------------------*/ |
nkeynes@644 | 325 | #include "edc_encoder.h" |
nkeynes@644 | 326 | |
nkeynes@644 | 327 | static int encode_L1_Q(unsigned char inout[L1_RAW + L1_Q]); |
nkeynes@644 | 328 | |
nkeynes@644 | 329 | static int encode_L1_Q(unsigned char inout[L1_RAW + L1_Q]) |
nkeynes@644 | 330 | { |
nkeynes@644 | 331 | unsigned char *Q; |
nkeynes@644 | 332 | int i; |
nkeynes@644 | 333 | |
nkeynes@644 | 334 | memmove(inout+L1_RAW/2+L1_Q, inout+L1_RAW/2, L1_RAW/2); |
nkeynes@644 | 335 | Q = inout + L1_RAW/2; |
nkeynes@644 | 336 | |
nkeynes@644 | 337 | memset(Q, 0, L1_Q); |
nkeynes@644 | 338 | for (i = 0; i < L1_RAW + L1_Q; i++) { |
nkeynes@644 | 339 | unsigned char data; |
nkeynes@644 | 340 | |
nkeynes@644 | 341 | if (i == L1_RAW/2) i += L1_Q; |
nkeynes@644 | 342 | data = inout[i]; |
nkeynes@644 | 343 | if (data != 0) { |
nkeynes@644 | 344 | unsigned char base = rs_l12_log[data]; |
nkeynes@644 | 345 | |
nkeynes@644 | 346 | Q[0] ^= rs_l12_alog[(base+AQ[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; |
nkeynes@644 | 347 | Q[1] ^= rs_l12_alog[(base+AQ[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; |
nkeynes@644 | 348 | Q[2] ^= rs_l12_alog[(base+AQ[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; |
nkeynes@644 | 349 | Q[3] ^= rs_l12_alog[(base+AQ[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; |
nkeynes@644 | 350 | } |
nkeynes@644 | 351 | } |
nkeynes@644 | 352 | return (0); |
nkeynes@644 | 353 | } |
nkeynes@644 | 354 | |
nkeynes@644 | 355 | static int encode_L1_P(unsigned char inout[L1_RAW + L1_Q + L1_P]); |
nkeynes@644 | 356 | |
nkeynes@644 | 357 | static int encode_L1_P(unsigned char inout[L1_RAW + L1_Q + L1_P]) |
nkeynes@644 | 358 | { |
nkeynes@644 | 359 | unsigned char *P; |
nkeynes@644 | 360 | int i; |
nkeynes@644 | 361 | |
nkeynes@644 | 362 | P = inout + L1_RAW + L1_Q; |
nkeynes@644 | 363 | |
nkeynes@644 | 364 | memset(P, 0, L1_P); |
nkeynes@644 | 365 | for (i = 0; i < L2_RAW + L2_Q + L2_P; i++) { |
nkeynes@644 | 366 | unsigned char data; |
nkeynes@644 | 367 | |
nkeynes@644 | 368 | data = inout[i]; |
nkeynes@644 | 369 | if (data != 0) { |
nkeynes@644 | 370 | unsigned char base = rs_l12_log[data]; |
nkeynes@644 | 371 | |
nkeynes@644 | 372 | P[0] ^= rs_l12_alog[(base+AP[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; |
nkeynes@644 | 373 | P[1] ^= rs_l12_alog[(base+AP[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; |
nkeynes@644 | 374 | P[2] ^= rs_l12_alog[(base+AP[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; |
nkeynes@644 | 375 | P[3] ^= rs_l12_alog[(base+AP[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; |
nkeynes@644 | 376 | } |
nkeynes@644 | 377 | } |
nkeynes@644 | 378 | return (0); |
nkeynes@644 | 379 | } |
nkeynes@644 | 380 | |
nkeynes@644 | 381 | static int decode_L1_Q(unsigned char inout[L1_RAW + L1_Q]); |
nkeynes@644 | 382 | |
nkeynes@644 | 383 | static int decode_L1_Q(unsigned char inout[L1_RAW + L1_Q]) |
nkeynes@644 | 384 | { |
nkeynes@644 | 385 | return (0); |
nkeynes@644 | 386 | } |
nkeynes@644 | 387 | |
nkeynes@644 | 388 | static int decode_L1_P(unsigned char in[L1_RAW + L1_Q + L1_P]); |
nkeynes@644 | 389 | |
nkeynes@644 | 390 | static int decode_L1_P(unsigned char in[L1_RAW + L1_Q + L1_P]) |
nkeynes@644 | 391 | { |
nkeynes@644 | 392 | return (0); |
nkeynes@644 | 393 | } |
nkeynes@644 | 394 | |
nkeynes@644 | 395 | int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q]); |
nkeynes@644 | 396 | |
nkeynes@644 | 397 | int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q]) |
nkeynes@644 | 398 | { |
nkeynes@644 | 399 | return (0); |
nkeynes@644 | 400 | } |
nkeynes@644 | 401 | |
nkeynes@644 | 402 | int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]); |
nkeynes@644 | 403 | |
nkeynes@644 | 404 | int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]) |
nkeynes@644 | 405 | { |
nkeynes@644 | 406 | return (0); |
nkeynes@644 | 407 | } |
nkeynes@644 | 408 | |
nkeynes@644 | 409 | static int encode_LSUB_Q(unsigned char inout[LSUB_RAW + LSUB_Q]); |
nkeynes@644 | 410 | |
nkeynes@644 | 411 | static int encode_LSUB_Q(unsigned char inout[LSUB_RAW + LSUB_Q]) |
nkeynes@644 | 412 | { |
nkeynes@644 | 413 | unsigned char *Q; |
nkeynes@644 | 414 | int i; |
nkeynes@644 | 415 | |
nkeynes@644 | 416 | memmove(inout+LSUB_QRAW+LSUB_Q, inout+LSUB_QRAW, LSUB_RAW-LSUB_QRAW); |
nkeynes@644 | 417 | Q = inout + LSUB_QRAW; |
nkeynes@644 | 418 | |
nkeynes@644 | 419 | memset(Q, 0, LSUB_Q); |
nkeynes@644 | 420 | |
nkeynes@644 | 421 | for (i = 0; i < LSUB_QRAW; i++) { |
nkeynes@644 | 422 | unsigned char data; |
nkeynes@644 | 423 | |
nkeynes@644 | 424 | data = inout[i] & 0x3f; |
nkeynes@644 | 425 | if (data != 0) { |
nkeynes@644 | 426 | unsigned char base = rs_sub_rw_log[data]; |
nkeynes@644 | 427 | |
nkeynes@644 | 428 | Q[0] ^= rs_sub_rw_alog[(base+SQ[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; |
nkeynes@644 | 429 | Q[1] ^= rs_sub_rw_alog[(base+SQ[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; |
nkeynes@644 | 430 | } |
nkeynes@644 | 431 | } |
nkeynes@644 | 432 | return (0); |
nkeynes@644 | 433 | } |
nkeynes@644 | 434 | |
nkeynes@644 | 435 | |
nkeynes@644 | 436 | static int encode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]); |
nkeynes@644 | 437 | |
nkeynes@644 | 438 | static int encode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]) |
nkeynes@644 | 439 | { |
nkeynes@644 | 440 | unsigned char *P; |
nkeynes@644 | 441 | int i; |
nkeynes@644 | 442 | |
nkeynes@644 | 443 | P = inout + LSUB_RAW + LSUB_Q; |
nkeynes@644 | 444 | |
nkeynes@644 | 445 | memset(P, 0, LSUB_P); |
nkeynes@644 | 446 | for (i = 0; i < LSUB_RAW + LSUB_Q; i++) { |
nkeynes@644 | 447 | unsigned char data; |
nkeynes@644 | 448 | |
nkeynes@644 | 449 | data = inout[i] & 0x3f; |
nkeynes@644 | 450 | if (data != 0) { |
nkeynes@644 | 451 | unsigned char base = rs_sub_rw_log[data]; |
nkeynes@644 | 452 | |
nkeynes@644 | 453 | P[0] ^= rs_sub_rw_alog[(base+SP[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; |
nkeynes@644 | 454 | P[1] ^= rs_sub_rw_alog[(base+SP[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; |
nkeynes@644 | 455 | P[2] ^= rs_sub_rw_alog[(base+SP[2][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; |
nkeynes@644 | 456 | P[3] ^= rs_sub_rw_alog[(base+SP[3][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; |
nkeynes@644 | 457 | } |
nkeynes@644 | 458 | } |
nkeynes@644 | 459 | return (0); |
nkeynes@644 | 460 | } |
nkeynes@644 | 461 | |
nkeynes@644 | 462 | int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q]); |
nkeynes@644 | 463 | |
nkeynes@644 | 464 | int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q]) |
nkeynes@644 | 465 | { |
nkeynes@644 | 466 | unsigned char Q[LSUB_Q]; |
nkeynes@644 | 467 | int i; |
nkeynes@644 | 468 | |
nkeynes@644 | 469 | memset(Q, 0, LSUB_Q); |
nkeynes@644 | 470 | for (i = LSUB_QRAW + LSUB_Q -1; i>=0; i--) { |
nkeynes@644 | 471 | unsigned char data; |
nkeynes@644 | 472 | |
nkeynes@644 | 473 | data = inout[LSUB_QRAW + LSUB_Q -1 -i] & 0x3f; |
nkeynes@644 | 474 | if (data != 0) { |
nkeynes@644 | 475 | unsigned char base = rs_sub_rw_log[data]; |
nkeynes@644 | 476 | |
nkeynes@644 | 477 | Q[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; |
nkeynes@644 | 478 | Q[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; |
nkeynes@644 | 479 | } |
nkeynes@644 | 480 | } |
nkeynes@644 | 481 | return (Q[0] != 0 || Q[1] != 0); |
nkeynes@644 | 482 | } |
nkeynes@644 | 483 | |
nkeynes@644 | 484 | int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]); |
nkeynes@644 | 485 | |
nkeynes@644 | 486 | int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]) |
nkeynes@644 | 487 | { |
nkeynes@644 | 488 | unsigned char P[LSUB_P]; |
nkeynes@644 | 489 | int i; |
nkeynes@644 | 490 | |
nkeynes@644 | 491 | memset(P, 0, LSUB_P); |
nkeynes@644 | 492 | for (i = LSUB_RAW + LSUB_Q + LSUB_P-1; i>=0; i--) { |
nkeynes@644 | 493 | unsigned char data; |
nkeynes@644 | 494 | |
nkeynes@644 | 495 | data = inout[LSUB_RAW + LSUB_Q + LSUB_P -1 -i] & 0x3f; |
nkeynes@644 | 496 | if (data != 0) { |
nkeynes@644 | 497 | unsigned char base = rs_sub_rw_log[data]; |
nkeynes@644 | 498 | |
nkeynes@644 | 499 | P[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; |
nkeynes@644 | 500 | P[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; |
nkeynes@644 | 501 | P[2] ^= rs_sub_rw_alog[(base+2*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; |
nkeynes@644 | 502 | P[3] ^= rs_sub_rw_alog[(base+3*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; |
nkeynes@644 | 503 | } |
nkeynes@644 | 504 | } |
nkeynes@644 | 505 | return (P[0] != 0 || P[1] != 0 || P[2] != 0 || P[3] != 0); |
nkeynes@644 | 506 | } |
nkeynes@644 | 507 | |
nkeynes@644 | 508 | /* Layer 1 CIRC en/decoder */ |
nkeynes@644 | 509 | #define MAX_L1_DEL1 2 |
nkeynes@644 | 510 | static unsigned char l1_delay_line1[MAX_L1_DEL1][L1_RAW]; |
nkeynes@644 | 511 | #define MAX_L1_DEL2 108 |
nkeynes@644 | 512 | static unsigned char l1_delay_line2[MAX_L1_DEL2][L1_RAW+L1_Q]; |
nkeynes@644 | 513 | #define MAX_L1_DEL3 1 |
nkeynes@644 | 514 | static unsigned char l1_delay_line3[MAX_L1_DEL3][L1_RAW+L1_Q+L1_P]; |
nkeynes@644 | 515 | static unsigned l1_del_index; |
nkeynes@644 | 516 | |
nkeynes@644 | 517 | int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR], |
nkeynes@644 | 518 | unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], |
nkeynes@644 | 519 | int delay1, int delay2, int delay3, int permute) |
nkeynes@644 | 520 | { |
nkeynes@644 | 521 | int i; |
nkeynes@644 | 522 | |
nkeynes@644 | 523 | for (i = 0; i < FRAMES_PER_SECTOR; i++) { |
nkeynes@644 | 524 | int j; |
nkeynes@644 | 525 | unsigned char t; |
nkeynes@644 | 526 | |
nkeynes@644 | 527 | if (in != out) |
nkeynes@644 | 528 | memcpy(out, in, L1_RAW); |
nkeynes@644 | 529 | |
nkeynes@644 | 530 | if (delay1) { |
nkeynes@644 | 531 | /* shift through delay line 1 */ |
nkeynes@644 | 532 | for (j = 0; j < L1_RAW; j++) { |
nkeynes@644 | 533 | if (((j/4) % MAX_L1_DEL1) == 0) { |
nkeynes@644 | 534 | t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j]; |
nkeynes@644 | 535 | l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = out[j]; |
nkeynes@644 | 536 | out[j] = t; |
nkeynes@644 | 537 | } |
nkeynes@644 | 538 | } |
nkeynes@644 | 539 | } |
nkeynes@644 | 540 | |
nkeynes@644 | 541 | if (permute) { |
nkeynes@644 | 542 | /* permute */ |
nkeynes@644 | 543 | t = out[2]; out[2] = out[8]; out[8] = out[10]; out[10] = out[18]; |
nkeynes@644 | 544 | out[18] = out[6]; out [6] = t; |
nkeynes@644 | 545 | t = out[3]; out[3] = out[9]; out[9] = out[11]; out[11] = out[19]; |
nkeynes@644 | 546 | out[19] = out[7]; out [7] = t; |
nkeynes@644 | 547 | t = out[4]; out[4] = out[16]; out[16] = out[20]; out[20] = out[14]; |
nkeynes@644 | 548 | out[14] = out[12]; out [12] = t; |
nkeynes@644 | 549 | t = out[5]; out[5] = out[17]; out[17] = out[21]; out[21] = out[15]; |
nkeynes@644 | 550 | out[15] = out[13]; out [13] = t; |
nkeynes@644 | 551 | } |
nkeynes@644 | 552 | |
nkeynes@644 | 553 | /* build Q parity */ |
nkeynes@644 | 554 | encode_L1_Q(out); |
nkeynes@644 | 555 | |
nkeynes@644 | 556 | if (delay2) { |
nkeynes@644 | 557 | /* shift through delay line 2 */ |
nkeynes@644 | 558 | for (j = 0; j < L1_RAW+L1_Q; j++) { |
nkeynes@644 | 559 | if (j != 0) { |
nkeynes@644 | 560 | t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j]; |
nkeynes@644 | 561 | l1_delay_line2[(l1_del_index + j*4) % MAX_L1_DEL2][j] = out[j]; |
nkeynes@644 | 562 | out[j] = t; |
nkeynes@644 | 563 | } |
nkeynes@644 | 564 | } |
nkeynes@644 | 565 | } |
nkeynes@644 | 566 | |
nkeynes@644 | 567 | /* build P parity */ |
nkeynes@644 | 568 | encode_L1_P(out); |
nkeynes@644 | 569 | |
nkeynes@644 | 570 | if (delay3) { |
nkeynes@644 | 571 | /* shift through delay line 3 */ |
nkeynes@644 | 572 | for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) { |
nkeynes@644 | 573 | if (((j) & MAX_L1_DEL3) == 0) { |
nkeynes@644 | 574 | t = l1_delay_line3[0][j]; |
nkeynes@644 | 575 | l1_delay_line3[0][j] = out[j]; |
nkeynes@644 | 576 | out[j] = t; |
nkeynes@644 | 577 | } |
nkeynes@644 | 578 | } |
nkeynes@644 | 579 | } |
nkeynes@644 | 580 | |
nkeynes@644 | 581 | /* invert Q and P parity */ |
nkeynes@644 | 582 | for (j = 0; j < L1_Q; j++) |
nkeynes@644 | 583 | out[j+12] = ~out[j+12]; |
nkeynes@644 | 584 | for (j = 0; j < L1_P; j++) |
nkeynes@644 | 585 | out[j+28] = ~out[j+28]; |
nkeynes@644 | 586 | |
nkeynes@644 | 587 | l1_del_index++; |
nkeynes@644 | 588 | out += L1_RAW+L1_Q+L1_P; |
nkeynes@644 | 589 | in += L1_RAW; |
nkeynes@644 | 590 | } |
nkeynes@644 | 591 | return (0); |
nkeynes@644 | 592 | } |
nkeynes@644 | 593 | |
nkeynes@644 | 594 | int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], |
nkeynes@669 | 595 | unsigned char out[L1_RAW*FRAMES_PER_SECTOR], |
nkeynes@669 | 596 | int delay1, int delay2, int delay3, int permute) |
nkeynes@644 | 597 | { |
nkeynes@644 | 598 | int i; |
nkeynes@644 | 599 | |
nkeynes@644 | 600 | for (i = 0; i < FRAMES_PER_SECTOR; i++) { |
nkeynes@644 | 601 | int j; |
nkeynes@644 | 602 | unsigned char t; |
nkeynes@644 | 603 | |
nkeynes@644 | 604 | if (delay3) { |
nkeynes@644 | 605 | /* shift through delay line 3 */ |
nkeynes@644 | 606 | for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) { |
nkeynes@644 | 607 | if (((j) & MAX_L1_DEL3) != 0) { |
nkeynes@644 | 608 | t = l1_delay_line3[0][j]; |
nkeynes@644 | 609 | l1_delay_line3[0][j] = in[j]; |
nkeynes@644 | 610 | in[j] = t; |
nkeynes@644 | 611 | } |
nkeynes@644 | 612 | } |
nkeynes@644 | 613 | } |
nkeynes@644 | 614 | |
nkeynes@644 | 615 | /* invert Q and P parity */ |
nkeynes@644 | 616 | for (j = 0; j < L1_Q; j++) |
nkeynes@644 | 617 | in[j+12] = ~in[j+12]; |
nkeynes@644 | 618 | for (j = 0; j < L1_P; j++) |
nkeynes@644 | 619 | in[j+28] = ~in[j+28]; |
nkeynes@644 | 620 | |
nkeynes@644 | 621 | /* build P parity */ |
nkeynes@644 | 622 | decode_L1_P(in); |
nkeynes@644 | 623 | |
nkeynes@644 | 624 | if (delay2) { |
nkeynes@644 | 625 | /* shift through delay line 2 */ |
nkeynes@644 | 626 | for (j = 0; j < L1_RAW+L1_Q; j++) { |
nkeynes@644 | 627 | if (j != L1_RAW+L1_Q-1) { |
nkeynes@644 | 628 | t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j]; |
nkeynes@644 | 629 | l1_delay_line2[(l1_del_index + (MAX_L1_DEL2 - j*4)) % MAX_L1_DEL2][j] = in[j]; |
nkeynes@644 | 630 | in[j] = t; |
nkeynes@644 | 631 | } |
nkeynes@644 | 632 | } |
nkeynes@644 | 633 | } |
nkeynes@644 | 634 | |
nkeynes@644 | 635 | /* build Q parity */ |
nkeynes@644 | 636 | decode_L1_Q(in); |
nkeynes@644 | 637 | |
nkeynes@644 | 638 | if (permute) { |
nkeynes@644 | 639 | /* permute */ |
nkeynes@644 | 640 | t = in[2]; in[2] = in[6]; in[6] = in[18]; in[18] = in[10]; |
nkeynes@644 | 641 | in[10] = in[8]; in [8] = t; |
nkeynes@644 | 642 | t = in[3]; in[3] = in[7]; in[7] = in[19]; in[19] = in[11]; |
nkeynes@644 | 643 | in[11] = in[9]; in [9] = t; |
nkeynes@644 | 644 | t = in[4]; in[4] = in[12]; in[12] = in[14]; in[14] = in[20]; |
nkeynes@644 | 645 | in[20] = in[16]; in [16] = t; |
nkeynes@644 | 646 | t = in[5]; in[5] = in[13]; in[13] = in[15]; in[15] = in[21]; |
nkeynes@644 | 647 | in[21] = in[17]; in [17] = t; |
nkeynes@644 | 648 | } |
nkeynes@644 | 649 | |
nkeynes@644 | 650 | if (delay1) { |
nkeynes@644 | 651 | /* shift through delay line 1 */ |
nkeynes@644 | 652 | for (j = 0; j < L1_RAW; j++) { |
nkeynes@644 | 653 | if (((j/4) % MAX_L1_DEL1) != 0) { |
nkeynes@644 | 654 | t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j]; |
nkeynes@644 | 655 | l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = in[j]; |
nkeynes@644 | 656 | in[j] = t; |
nkeynes@644 | 657 | } |
nkeynes@644 | 658 | } |
nkeynes@644 | 659 | } |
nkeynes@644 | 660 | |
nkeynes@644 | 661 | if (in != out) |
nkeynes@644 | 662 | memcpy(out, in, (L1_RAW)); |
nkeynes@644 | 663 | |
nkeynes@644 | 664 | l1_del_index++; |
nkeynes@644 | 665 | in += L1_RAW+L1_Q+L1_P; |
nkeynes@644 | 666 | out += L1_RAW; |
nkeynes@644 | 667 | } |
nkeynes@644 | 668 | return (0); |
nkeynes@644 | 669 | } |
nkeynes@644 | 670 | |
nkeynes@669 | 671 | int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)], |
nkeynes@644 | 672 | unsigned char out[L2_RAW]) |
nkeynes@644 | 673 | { |
nkeynes@644 | 674 | return (0); |
nkeynes@644 | 675 | } |
nkeynes@644 | 676 | |
nkeynes@644 | 677 | |
nkeynes@644 | 678 | |
nkeynes@644 | 679 | #define MAX_SUB_DEL 8 |
nkeynes@644 | 680 | static unsigned char sub_delay_line[MAX_SUB_DEL][LSUB_RAW+LSUB_Q+LSUB_P]; |
nkeynes@644 | 681 | static unsigned sub_del_index; |
nkeynes@644 | 682 | |
nkeynes@644 | 683 | /* R-W Subchannel en/decoder */ |
nkeynes@644 | 684 | |
nkeynes@644 | 685 | int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], |
nkeynes@644 | 686 | unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], |
nkeynes@644 | 687 | int delay1, int permute) |
nkeynes@644 | 688 | { |
nkeynes@644 | 689 | int i; |
nkeynes@644 | 690 | |
nkeynes@644 | 691 | if (in == out) return -1; |
nkeynes@644 | 692 | |
nkeynes@644 | 693 | for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) { |
nkeynes@644 | 694 | int j; |
nkeynes@644 | 695 | unsigned char t; |
nkeynes@644 | 696 | |
nkeynes@644 | 697 | memcpy(out, in, (LSUB_RAW)); |
nkeynes@644 | 698 | |
nkeynes@644 | 699 | /* build Q parity */ |
nkeynes@644 | 700 | encode_LSUB_Q(out); |
nkeynes@644 | 701 | |
nkeynes@644 | 702 | /* build P parity */ |
nkeynes@644 | 703 | encode_LSUB_P(out); |
nkeynes@644 | 704 | |
nkeynes@644 | 705 | if (permute) { |
nkeynes@644 | 706 | /* permute */ |
nkeynes@644 | 707 | t = out[1]; out[1] = out[18]; out[18] = t; |
nkeynes@644 | 708 | t = out[2]; out[2] = out[ 5]; out[ 5] = t; |
nkeynes@644 | 709 | t = out[3]; out[3] = out[23]; out[23] = t; |
nkeynes@644 | 710 | } |
nkeynes@644 | 711 | |
nkeynes@644 | 712 | if (delay1) { |
nkeynes@644 | 713 | /* shift through delay_line */ |
nkeynes@644 | 714 | for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) { |
nkeynes@644 | 715 | if ((j % MAX_SUB_DEL) != 0) { |
nkeynes@644 | 716 | t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j]; |
nkeynes@644 | 717 | sub_delay_line[(sub_del_index + j) % MAX_SUB_DEL][j] = out[j]; |
nkeynes@644 | 718 | out[j] = t; |
nkeynes@644 | 719 | } |
nkeynes@644 | 720 | } |
nkeynes@644 | 721 | } |
nkeynes@644 | 722 | sub_del_index++; |
nkeynes@644 | 723 | out += LSUB_RAW+LSUB_Q+LSUB_P; |
nkeynes@644 | 724 | in += LSUB_RAW; |
nkeynes@644 | 725 | } |
nkeynes@644 | 726 | return (0); |
nkeynes@644 | 727 | } |
nkeynes@644 | 728 | |
nkeynes@669 | 729 | int do_decode_sub(unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], |
nkeynes@669 | 730 | unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], |
nkeynes@669 | 731 | int delay1, int permute) |
nkeynes@644 | 732 | { |
nkeynes@644 | 733 | int i; |
nkeynes@644 | 734 | |
nkeynes@644 | 735 | if (in == out) return -1; |
nkeynes@644 | 736 | |
nkeynes@644 | 737 | for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) { |
nkeynes@644 | 738 | int j; |
nkeynes@644 | 739 | unsigned char t; |
nkeynes@644 | 740 | |
nkeynes@644 | 741 | if (delay1) { |
nkeynes@644 | 742 | /* shift through delay_line */ |
nkeynes@644 | 743 | for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) { |
nkeynes@644 | 744 | if ((j % MAX_SUB_DEL) != MAX_SUB_DEL-1) { |
nkeynes@644 | 745 | t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j]; |
nkeynes@644 | 746 | sub_delay_line[(sub_del_index + (MAX_SUB_DEL - j)) % MAX_SUB_DEL][j] = in[j]; |
nkeynes@644 | 747 | in[j] = t; |
nkeynes@644 | 748 | } |
nkeynes@644 | 749 | } |
nkeynes@644 | 750 | } |
nkeynes@644 | 751 | |
nkeynes@644 | 752 | if (permute) { |
nkeynes@644 | 753 | /* permute */ |
nkeynes@644 | 754 | t = in[1]; in[1] = in[18]; in[18] = t; |
nkeynes@644 | 755 | t = in[2]; in[2] = in[ 5]; in[ 5] = t; |
nkeynes@644 | 756 | t = in[3]; in[3] = in[23]; in[23] = t; |
nkeynes@644 | 757 | } |
nkeynes@644 | 758 | |
nkeynes@644 | 759 | /* build P parity */ |
nkeynes@644 | 760 | decode_LSUB_P(in); |
nkeynes@644 | 761 | |
nkeynes@644 | 762 | /* build Q parity */ |
nkeynes@644 | 763 | decode_LSUB_Q(in); |
nkeynes@644 | 764 | |
nkeynes@644 | 765 | memcpy(out, in, LSUB_QRAW); |
nkeynes@644 | 766 | memcpy(out+LSUB_QRAW, in+LSUB_QRAW+LSUB_Q, LSUB_RAW-LSUB_QRAW); |
nkeynes@644 | 767 | |
nkeynes@644 | 768 | sub_del_index++; |
nkeynes@644 | 769 | in += LSUB_RAW+LSUB_Q+LSUB_P; |
nkeynes@644 | 770 | out += LSUB_RAW; |
nkeynes@644 | 771 | } |
nkeynes@644 | 772 | return (0); |
nkeynes@644 | 773 | } |
nkeynes@644 | 774 | |
nkeynes@644 | 775 | static int sectortype = MODE_0; |
nkeynes@644 | 776 | |
nkeynes@644 | 777 | int get_sector_type(void); |
nkeynes@644 | 778 | |
nkeynes@644 | 779 | int get_sector_type() |
nkeynes@644 | 780 | { |
nkeynes@644 | 781 | return (sectortype); |
nkeynes@644 | 782 | } |
nkeynes@644 | 783 | |
nkeynes@644 | 784 | int set_sector_type(int st); |
nkeynes@644 | 785 | |
nkeynes@644 | 786 | int set_sector_type(int st) |
nkeynes@644 | 787 | { |
nkeynes@644 | 788 | switch(st) { |
nkeynes@644 | 789 | |
nkeynes@644 | 790 | case MODE_0: |
nkeynes@644 | 791 | case MODE_1: |
nkeynes@644 | 792 | case MODE_2: |
nkeynes@644 | 793 | case MODE_2_FORM_1: |
nkeynes@644 | 794 | case MODE_2_FORM_2: |
nkeynes@644 | 795 | sectortype = st; |
nkeynes@644 | 796 | return 0; |
nkeynes@644 | 797 | default: |
nkeynes@644 | 798 | return -1; |
nkeynes@644 | 799 | } |
nkeynes@644 | 800 | } |
nkeynes@644 | 801 |
.