1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 2470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Use of this source code is governed by a BSD-style license 5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * that can be found in the LICENSE file in the root of the source 6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * tree. An additional intellectual property rights grant can be found 7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * in the file PATENTS. All contributing project authors may 8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * be found in the AUTHORS file in the root of the source tree. 9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * arith_routinshist.c 13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 14470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This C file contains arithmetic encoding and decoding. 15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 17470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 18470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "arith_routins.h" 19470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 20470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 21470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/**************************************************************************** 22470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_EncHistMulti(...) 23470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 24470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Encode the histogram interval 25470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 26470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input: 27470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - streamData : in-/output struct containing bitstream 28470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - data : data vector 29470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - cdf : array of cdf arrays 30470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - lenData : data vector length 31470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 32470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value : 0 if ok 33470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * <0 if error detected 34470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 35470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_EncHistMulti(Bitstr_enc *streamData, 360946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const int16_t *data, 370946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t **cdf, 380946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const int16_t lenData) 39470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 400946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_lower; 410946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_upper; 420946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_upper_LSB; 430946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_upper_MSB; 440946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint16_t *streamPtr; 450946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint16_t negCarry; 460946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint16_t *maxStreamPtr; 470946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint16_t *streamPtrCarry; 480946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t cdfLo; 490946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t cdfHi; 50470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k; 51470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 52470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 53470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* point to beginning of stream buffer 54470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * and set maximum streamPtr value */ 55470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamPtr = streamData->stream + streamData->stream_index; 56470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com maxStreamPtr = streamData->stream + STREAM_MAXW16_60MS - 1; 57470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 58470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper = streamData->W_upper; 59470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 60470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = lenData; k > 0; k--) 61470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 62470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* fetch cdf_lower and cdf_upper from cdf tables */ 630946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org cdfLo = (uint32_t) *(*cdf + (uint32_t)*data); 640946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org cdfHi = (uint32_t) *(*cdf++ + (uint32_t)*data++ + 1); 65470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 66470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* update interval */ 67470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper_LSB = W_upper & 0x0000FFFF; 68a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org W_upper_MSB = W_upper >> 16; 69470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_lower = WEBRTC_SPL_UMUL(W_upper_MSB, cdfLo); 70a3b5673879284f16a2f9f56bc14429eec4f20a0cbjornv@webrtc.org W_lower += ((W_upper_LSB * cdfLo) >> 16); 71470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper = WEBRTC_SPL_UMUL(W_upper_MSB, cdfHi); 72a3b5673879284f16a2f9f56bc14429eec4f20a0cbjornv@webrtc.org W_upper += ((W_upper_LSB * cdfHi) >> 16); 73470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 74470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* shift interval such that it begins at zero */ 75470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper -= ++W_lower; 76470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 77470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* add integer to bitstream */ 78470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->streamval += W_lower; 79470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 80470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* handle carry */ 81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (streamData->streamval < W_lower) 82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 83470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* propagate carry */ 84470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamPtrCarry = streamPtr; 85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (streamData->full == 0) { 86470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com negCarry = *streamPtrCarry; 87470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com negCarry += 0x0100; 88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *streamPtrCarry = negCarry; 89470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while (!(negCarry)) 90470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 91470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com negCarry = *--streamPtrCarry; 92470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com negCarry++; 93470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *streamPtrCarry = negCarry; 94470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 95470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 96470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while ( !(++(*--streamPtrCarry)) ); 97470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 98470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* renormalize interval, store most significant byte of streamval and update streamval 101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * W_upper < 2^24 */ 102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while ( !(W_upper & 0xFF000000) ) 103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 104d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker W_upper <<= 8; 105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (streamData->full == 0) { 106a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org *streamPtr++ += (uint16_t)(streamData->streamval >> 24); 107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->full = 1; 108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 109a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org *streamPtr = (uint16_t)((streamData->streamval >> 24) << 8); 110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->full = 0; 111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( streamPtr > maxStreamPtr ) { 114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_DISALLOWED_BITSTREAM_LENGTH; 115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 116d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker streamData->streamval <<= 8; 117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* calculate new stream_index */ 121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->stream_index = streamPtr - streamData->stream; 122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->W_upper = W_upper; 123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/**************************************************************************** 129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_DecHistBisectMulti(...) 130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Function to decode more symbols from the arithmetic bytestream, using 132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * method of bisection cdf tables should be of size 2^k-1 (which corresponds 133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * to an alphabet size of 2^k-2) 134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input: 136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - streamData : in-/output struct containing bitstream 137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - cdf : array of cdf arrays 138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - cdfSize : array of cdf table sizes+1 (power of two: 2^k) 139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - lenData : data vector length 140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output: 142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - data : data vector 143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value : number of bytes in the stream 145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * <0 if error detected 146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 1470946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_DecHistBisectMulti(int16_t *data, 1480946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org Bitstr_dec *streamData, 1490946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t **cdf, 1500946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t *cdfSize, 1510946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const int16_t lenData) 152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1530946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_lower = 0; 1540946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_upper; 1550946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_tmp; 1560946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_upper_LSB; 1570946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_upper_MSB; 1580946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t streamval; 1590946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t *streamPtr; 1600946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t *cdfPtr; 1610946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t sizeTmp; 162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k; 163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamPtr = streamData->stream + streamData->stream_index; 166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper = streamData->W_upper; 167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Error check: should not be possible in normal operation */ 169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (W_upper == 0) { 170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* first time decoder is called for this stream */ 174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (streamData->stream_index == 0) 175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* read first word from bytestream */ 177d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker streamval = (uint32_t)*streamPtr++ << 16; 178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamval |= *streamPtr++; 179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamval = streamData->streamval; 181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = lenData; k > 0; k--) 184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */ 186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper_LSB = W_upper & 0x0000FFFF; 187a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org W_upper_MSB = W_upper >> 16; 188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* start halfway the cdf range */ 190f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org sizeTmp = *cdfSize++ / 2; 191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdfPtr = *cdf + (sizeTmp - 1); 192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* method of bisection */ 194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for ( ;; ) 195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr); 1971e3ef4b999ada52fc4e421d1d06b73068e855413bjornv@webrtc.org W_tmp += (W_upper_LSB * (*cdfPtr)) >> 16; 198f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org sizeTmp /= 2; 199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (sizeTmp == 0) { 200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (streamval > W_tmp) 204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_lower = W_tmp; 206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdfPtr += sizeTmp; 207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper = W_tmp; 209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdfPtr -= sizeTmp; 210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (streamval > W_tmp) 213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_lower = W_tmp; 215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *data++ = cdfPtr - *cdf++; 216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper = W_tmp; 218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *data++ = cdfPtr - *cdf++ - 1; 219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* shift interval to start at zero */ 222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper -= ++W_lower; 223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* add integer to bitstream */ 225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamval -= W_lower; 226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* renormalize interval and update streamval */ 228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* W_upper < 2^24 */ 229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while ( !(W_upper & 0xFF000000) ) 230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* read next byte from stream */ 232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (streamData->full == 0) { 233d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker streamval = (streamval << 8) | (*streamPtr++ & 0x00FF); 234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->full = 1; 235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 236f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org streamval = (streamval << 8) | (*streamPtr >> 8); 237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->full = 0; 238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 239d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker W_upper <<= 8; 240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Error check: should not be possible in normal operation */ 244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (W_upper == 0) { 245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->stream_index = streamPtr - streamData->stream; 251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->W_upper = W_upper; 252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->streamval = streamval; 253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ( W_upper > 0x01FFFFFF ) { 255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return (streamData->stream_index*2 - 3 + !streamData->full); 256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return (streamData->stream_index*2 - 2 + !streamData->full); 258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/**************************************************************************** 263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_DecHistOneStepMulti(...) 264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Function to decode more symbols from the arithmetic bytestream, taking 266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * single step up or down at a time. 267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * cdf tables can be of arbitrary size, but large tables may take a lot of 268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * iterations. 269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input: 271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - streamData : in-/output struct containing bitstream 272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - cdf : array of cdf arrays 273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - initIndex : vector of initial cdf table search entries 274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - lenData : data vector length 275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output: 277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * - data : data vector 278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value : number of bytes in original stream 280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * <0 if error detected 281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 2820946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_DecHistOneStepMulti(int16_t *data, 2830946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org Bitstr_dec *streamData, 2840946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t **cdf, 2850946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t *initIndex, 2860946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const int16_t lenData) 287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2880946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_lower; 2890946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_upper; 2900946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_tmp; 2910946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_upper_LSB; 2920946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t W_upper_MSB; 2930946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t streamval; 2940946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t *streamPtr; 2950946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t *cdfPtr; 296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k; 297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamPtr = streamData->stream + streamData->stream_index; 300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper = streamData->W_upper; 301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Error check: Should not be possible in normal operation */ 302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (W_upper == 0) { 303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Check if it is the first time decoder is called for this stream */ 307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (streamData->stream_index == 0) 308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* read first word from bytestream */ 3107c15510f389b00fea03e8512cf1a09d0a344b8e9bjornv@webrtc.org streamval = (uint32_t)(*streamPtr++) << 16; 311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamval |= *streamPtr++; 312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamval = streamData->streamval; 314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = lenData; k > 0; k--) 317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */ 319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper_LSB = W_upper & 0x0000FFFF; 320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper_MSB = WEBRTC_SPL_RSHIFT_U32(W_upper, 16); 321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* start at the specified table entry */ 323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdfPtr = *cdf + (*initIndex++); 324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr); 3251e3ef4b999ada52fc4e421d1d06b73068e855413bjornv@webrtc.org W_tmp += (W_upper_LSB * (*cdfPtr)) >> 16; 326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (streamval > W_tmp) 328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for ( ;; ) 330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_lower = W_tmp; 332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* range check */ 334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (cdfPtr[0] == 65535) { 335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -3; 336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *++cdfPtr); 3391e3ef4b999ada52fc4e421d1d06b73068e855413bjornv@webrtc.org W_tmp += (W_upper_LSB * (*cdfPtr)) >> 16; 340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (streamval <= W_tmp) { 342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper = W_tmp; 346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *data++ = cdfPtr - *cdf++ - 1; 347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for ( ;; ) 349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper = W_tmp; 351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com --cdfPtr; 352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* range check */ 354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (cdfPtr < *cdf) { 355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -3; 356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr); 3591e3ef4b999ada52fc4e421d1d06b73068e855413bjornv@webrtc.org W_tmp += (W_upper_LSB * (*cdfPtr)) >> 16; 360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (streamval > W_tmp) { 362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_lower = W_tmp; 366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *data++ = cdfPtr - *cdf++; 367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* shift interval to start at zero */ 370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com W_upper -= ++W_lower; 371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* add integer to bitstream */ 373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamval -= W_lower; 374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* renormalize interval and update streamval */ 376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* W_upper < 2^24 */ 377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while ( !(W_upper & 0xFF000000) ) 378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* read next byte from stream */ 380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (streamData->full == 0) { 381d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker streamval = (streamval << 8) | (*streamPtr++ & 0x00FF); 382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->full = 1; 383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 384d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker streamval = (streamval << 8) | (*streamPtr >> 8); 385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->full = 0; 386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 387d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker W_upper <<= 8; 388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->stream_index = streamPtr - streamData->stream; 392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->W_upper = W_upper; 393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamData->streamval = streamval; 394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find number of bytes in original stream (determined by current interval width) */ 396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ( W_upper > 0x01FFFFFF ) { 397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return (streamData->stream_index*2 - 3 + !streamData->full); 398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return (streamData->stream_index*2 - 2 + !streamData->full); 400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 402