summaryrefslogtreecommitdiff
path: root/audio_codec/libcook/ra_couple.c (plain)
blob: 1f53c4542fa4624355c2ed8545d8f3a9d10ab6f5
1/* ***** BEGIN LICENSE BLOCK *****
2 * Source last modified: $Id: couple.c,v 1.6 2005/04/27 19:20:50 hubbe Exp $
3 *
4 * REALNETWORKS CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM
5 * Portions Copyright (c) 1995-2002 RealNetworks, Inc.
6 * All Rights Reserved.
7 *
8 * The contents of this file, and the files included with this file,
9 * are subject to the current version of the Real Format Source Code
10 * Porting and Optimization License, available at
11 * https://helixcommunity.org/2005/license/realformatsource (unless
12 * RealNetworks otherwise expressly agrees in writing that you are
13 * subject to a different license). You may also obtain the license
14 * terms directly from RealNetworks. You may not use this file except
15 * in compliance with the Real Format Source Code Porting and
16 * Optimization License. There are no redistribution rights for the
17 * source code of this file. Please see the Real Format Source Code
18 * Porting and Optimization License for the rights, obligations and
19 * limitations governing use of the contents of the file.
20 *
21 * RealNetworks is the developer of the Original Code and owns the
22 * copyrights in the portions it created.
23 *
24 * This file, and the files included with this file, is distributed and
25 * made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND,
26 * EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL
27 * SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT
29 * OR NON-INFRINGEMENT.
30 *
31 * Technology Compatibility Kit Test Suite(s) Location:
32 * https://rarvcode-tck.helixcommunity.org
33 *
34 * Contributor(s):
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38/**************************************************************************************
39 * Fixed-point RealAudio 8 decoder
40 * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com)
41 * October 2003
42 *
43 * couple.c - joint stereo processing
44 **************************************************************************************/
45
46#include "coder.h"
47#include "assembly.h"
48
49/* coupling band widths, based on Zwicker critical-bandwidth */
50const int cplband[MAXREGNS] = {
51 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
52 11, 11,
53 12, 12,
54 13, 13,
55 14, 14, 14,
56 15, 15, 15, 15,
57 16, 16, 16, 16, 16,
58 17, 17, 17, 17, 17, 17,
59 18, 18, 18, 18, 18, 18, 18,
60 19, 19, 19, 19, 19, 19, 19, 19, 19
61};
62
63/* Lookup tables for reconstructed scaling factors - format = Q31 */
64static const int cplScale[3 + 7 + 15 + 31 + 63] = {
65
66 /* cplScale2[3] */
67 0x79fc945f, 0x5a82799a, 0x26c59af8,
68
69 /* cplScale3[7] */
70 0x7d9a93a4, 0x77ef8978, 0x701e9f27, 0x5a82799a,
71 0x3dc04491, 0x2cb7094c, 0x18a6b4ed,
72
73 /* cplScale4[15] */
74 0x7ee90962, 0x7c936c4f, 0x79fc9465, 0x770e9d8f,
75 0x73a45b28, 0x6f749c4e, 0x69c04836, 0x5a82799a,
76 0x481dac45, 0x3ef11955, 0x36df3415, 0x2f011d16,
77 0x26c59ae8, 0x1d688afa, 0x10aaa6fd,
78
79 /* cplScale5[31] */
80 0x7f7a8410, 0x7e66f9cf, 0x7d46e886, 0x7c18c36e,
81 0x7adaa745, 0x798a3db9, 0x78249362, 0x76a5d7e1,
82 0x7508f83e, 0x7346f452, 0x7155abbc, 0x6f257fbd,
83 0x6c9c00f0, 0x6985577e, 0x655acbf3, 0x5a82799a,
84 0x4e2ca29a, 0x4873cee8, 0x43bc1a9b, 0x3f7c6426,
85 0x3b7ddcf1, 0x37a26159, 0x33d59802, 0x30072e43,
86 0x2c27c13f, 0x28266a5d, 0x23edbab6, 0x1f5e6927,
87 0x1a42fec7, 0x14294028, 0x0b8ab0db,
88
89 /* cplScale6[63] */
90 0x7fbea8be, 0x7f39f9ab, 0x7eb28121, 0x7e281805,
91 0x7d9a93a8, 0x7d09c543, 0x7c75796f, 0x7bdd7778,
92 0x7b418090, 0x7aa14ee1, 0x79fc9466, 0x7952f983,
93 0x78a41b51, 0x77ef897b, 0x7734c38d, 0x76733593,
94 0x75aa33b1, 0x74d8f46c, 0x73fe8908, 0x7319d333,
95 0x722976ad, 0x712bc4eb, 0x701e9f29, 0x6eff48fd,
96 0x6dca2025, 0x6c7a2377, 0x6b081945, 0x6968e250,
97 0x6789b6cc, 0x6545d976, 0x623e1923, 0x5a82799a,
98 0x520d1a91, 0x4e47c3aa, 0x4b4243b5, 0x489d2fc3,
99 0x46338b6a, 0x43f2498b, 0x41cdfe96, 0x3fbf1c82,
100 0x3dc0448d, 0x3bcd6c20, 0x39e361f6, 0x37ff83c3,
101 0x361f8e06, 0x34417ac7, 0x326368ee, 0x3083887b,
102 0x2ea0091f, 0x2cb70944, 0x2ac683d0, 0x28cc3a99,
103 0x26c59ae4, 0x24af97f2, 0x22867502, 0x20457311,
104 0x1de64c41, 0x1b604f6f, 0x18a6b4dc, 0x15a521e0,
105 0x1237205d, 0x0e0d0479, 0x08144f82
106};
107
108static const int cplScaleOffset[7] = { 0, 0, 0, 3, 10, 25, 56};
109
110
111/**************************************************************************************
112 * Function: DecodeCoupleInfo
113 *
114 * Description: decode indices for joint stereo scale factors
115 *
116 * Inputs: pointer to initialized Gecko2Info struct
117 * number of bits remaining in bitstream for this frame
118 *
119 * Outputs: filled-in cplindex[] buffer, with one index per coupling band
120 *
121 * Return: number of bits remaining in bitstream, -1 if out-of-bits
122 *
123 * Notes: couple index info can either be direct-coded or Huffman-coded
124 **************************************************************************************/
125int DecodeCoupleInfo(Gecko2Info *gi, int availbits)
126{
127 int bandstart = cplband[gi->cplStart];
128 int bandend = cplband[gi->nRegions - 1];
129 int hufmode, nbits, b, cache;
130 int *cplindex = gi->db.cplindex;
131 BitStreamInfo *bsi = &(gi->bsi);
132
133 if (availbits < 1) {
134 return -1;
135 }
136
137 /* one-bit flag indicating Huffman or direct coding */
138 hufmode = GetBits(bsi, 1, 1);
139 availbits--;
140
141 if (hufmode) {
142 /* HUFFMAN */
143 for (b = bandstart; b <= bandend; b++) {
144 cache = GetBits(bsi, MAX_HUFF_BITS, 0);
145 nbits = DecodeHuffmanScalar(huffTabCouple, &huffTabCoupleInfo[gi->cplQbits - HUFFTAB_COUPLE_OFFSET], cache, cplindex + b);
146 if (nbits > availbits) {
147 return -1;
148 }
149 availbits -= nbits;
150 AdvanceBitstream(bsi, nbits);
151 }
152 } else {
153 /* DIRECT */
154 if (availbits < gi->cplQbits * (bandend - bandstart + 1)) {
155 return -1;
156 }
157 for (b = bandstart; b <= bandend; b++) {
158 cplindex[b] = GetBits(bsi, gi->cplQbits, 1);
159 availbits -= gi->cplQbits;
160 }
161 }
162
163 return availbits;
164}
165
166/**************************************************************************************
167 * Function: JointDecodeMLT
168 *
169 * Description: decode the jointly-coded MLT
170 *
171 * Inputs: pointer to initialized Gecko2Info struct
172 * mltleft[0, ... , cplStart-1] has non-coupled coefficients for left
173 * mltrght[0, ... , cplStart-1] has non-coupled coefficients for right
174 * mltleft[cplStart, ... , cRegions] has coupled coefficients
175 *
176 * Outputs: mltleft[0, ... , nRegions-1] has reconstructed coefficients for left
177 * mltrght[0, ... , nRegions-1] has reconstructed coefficients for right
178 *
179 * Return: none
180 **************************************************************************************/
181void JointDecodeMLT(Gecko2Info *gi, int *mltleft, int *mltrght)
182{
183 int scaleleft, scalerght;
184 int i, r, q;
185 int cplquant, cploffset;
186 int *cplindex = gi->db.cplindex;
187
188 cplquant = (1 << gi->cplQbits) - 1; /* quant levels */
189 cploffset = cplScaleOffset[gi->cplQbits];
190
191 /* reconstruct the stereo channels */
192 for (r = gi->cplStart; r < gi->nRegions; r++) {
193
194 /*
195 * dequantize the expanded coupling ratio
196 * expand = (q - (cplquant>>1)) * (2.0f/cplquant);
197 *
198 * square-law compression
199 * ratio = sqrt(fabs(expand));
200 * if (expand < 0.0f) ratio = -ratio;
201 *
202 * reconstruct the scaling factors
203 * scaleleft = sqrt(0.5f - 0.5f * ratio);
204 * scalerght = sqrt(0.5f + 0.5f * ratio);
205 */
206 q = cplindex[cplband[r]];
207 scaleleft = cplScale[cploffset + q];
208 scalerght = cplScale[cploffset + cplquant - 1 - q];
209
210 /* drop extra sign bit (max gain = 0.998) */
211 for (i = 0; i < NBINS; i++) {
212 mltrght[NBINS * r + i] = MULSHIFT32(scalerght, mltleft[NBINS * r + i]) << 1;
213 mltleft[NBINS * r + i] = MULSHIFT32(scaleleft, mltleft[NBINS * r + i]) << 1;
214 }
215 }
216
217 /* set non-coded regions to zero */
218 for (i = gi->nRegions * NBINS; i < gi->nSamples; i++) {
219 mltleft[i] = 0;
220 mltrght[i] = 0;
221 }
222
223 return;
224}
225