private unsafe void basterdised_rice_decompress(int output_size, ref int pos, ref predictor_t predictor_info, ref int[] predicterror_buffer, int readsamplesize) { fixed (predictor_t* pr = &predictor_info) fixed (int* output_buffer = &predicterror_buffer[0]) fixed (byte* buff = &_framesBuffer[0]) { uint history = setinfo_rice_initialhistory; int rice_kmodifier = setinfo_rice_kmodifier; int rice_historymult = pr->ricemodifier * setinfo_rice_historymult / 4; int sign_modifier = 0; for (int output_count = 0; output_count < output_size; output_count++) { int x = sign_modifier + decode_scalar(buff, ref pos, 31 - count_leading_zeroes((history >> 9) + 3), rice_kmodifier, readsamplesize); output_buffer[output_count] = (x >> 1) ^ - (x & 1); sign_modifier = 0; /* now update the history */ history = (uint)(history + (x * rice_historymult) - ((history * rice_historymult) >> 9)); if (x > 0xffff) history = 0xffff; /* special case: there may be compressed blocks of 0 */ if ((history < 128) && (output_count + 1 < output_size)) { int k = 7 - (31 - count_leading_zeroes(history)) + (((int)history + 16) >> 6); int block_size = decode_scalar(buff, ref pos, k, rice_kmodifier, 16); if (block_size > 0) { if (output_count + 1 + block_size > output_size) throw new Exception("buffer overflow: " + output_size.ToString() + " vs " + (output_count + 1 + block_size).ToString()); //block_size = (int) output_size - output_count - 1; for (int p = 0; p < block_size; p++) output_buffer[output_count + 1 + p] = 0; output_count += block_size; } sign_modifier = block_size > 0xffff ? 0 : 1; history = 0; } } } }
private unsafe void predictor_decompress_fir_adapt(int output_size, ref predictor_t predictor_info, ref int[] error_buffer, ref int[] buffer_out, int readsamplesize) { int i; fixed (predictor_t* pr = &predictor_info) fixed (int* buf_out = &buffer_out[0], buf_err = &error_buffer[0]) { if (pr->predictor_coef_num == 0) { for (i = 0; i < output_size; i++) buf_out[i] = buf_err[i]; return; } int sample = 0; if (pr->predictor_coef_num == 0x1f) { /* 11111 - max value of predictor_coef_num */ /* second-best case scenario for fir decompression, * error describes a small difference from the previous sample only */ if (output_size <= 1) return; for (i = 0; i < output_size; i++) { sample = extend_sign32(sample + buf_err[i], readsamplesize); buf_out[i] = sample; } return; } if (output_size <= predictor_info.predictor_coef_num || pr->predictor_coef_num < 0) throw new Exception("invalid output size"); /* read warm-up samples */ for (i = 0; i <= predictor_info.predictor_coef_num; i++) { sample = extend_sign32(sample + buf_err[i], readsamplesize); buf_out[i] = sample; } /* general case */ int* buf_pos = buf_out; int predictor_coef_table_sum = pr->predictor_coef_table_sum; for (i = (int)pr->predictor_coef_num + 1; i < output_size; i++) { int j; int sum = 0; int outval; int error_val = buf_err[i]; int sample_val = *(buf_pos++); for (j = 0; j < pr->predictor_coef_num; j++) sum += buf_pos[j] * pr->predictor_coef_table[j]; sum -= predictor_coef_table_sum * sample_val; outval = (1 << (pr->prediction_quantitization - 1)) + sum; outval >>= pr->prediction_quantitization; outval += sample_val + error_val; buf_pos[pr->predictor_coef_num] = extend_sign32(outval, readsamplesize); if (error_val != 0) { short error_sign = sign_only(error_val); for (j = 0; j < pr->predictor_coef_num; j++) { int val = sample_val - buf_pos[j]; if (val == 0) continue; short sign = sign_only(error_sign * val); pr->predictor_coef_table[j] -= sign; predictor_coef_table_sum -= sign; val *= sign; /* absolute value with same sign as error */ error_val -= (val >> pr->prediction_quantitization) * (j + 1); if (error_val * error_sign <= 0) break; } } } pr->predictor_coef_table_sum = predictor_coef_table_sum; } }
private unsafe void readPredictor(ref int pos, ref predictor_t predictor_info) { fixed (predictor_t* pr = &predictor_info) { pr->prediction_type = (int)readbits(_framesBuffer, ref pos, 4); pr->prediction_quantitization = (int)readbits(_framesBuffer, ref pos, 4); pr->ricemodifier = (int)readbits(_framesBuffer, ref pos, 3); pr->predictor_coef_num = (int)readbits(_framesBuffer, ref pos, 5); /* read the predictor table */ pr->predictor_coef_table_sum = 0; for (int i = pr->predictor_coef_num - 1; i >= 0; i--) { pr->predictor_coef_table[i] = (short)readbits(_framesBuffer, ref pos, 16); pr->predictor_coef_table_sum += pr->predictor_coef_table[i]; } } }