Mercurial > libavcodec.hg
annotate vorbis.c @ 5775:38f220befc32 libavcodec
Replace "signed short" typecast with "int16_t" as suggested by
Mans Rullgard. Value at the right side is 16 bit length signed.
We can not know for sure that short is in fact 16 bits, even if
this virtually always is the case.
author | voroshil |
---|---|
date | Thu, 04 Oct 2007 15:13:42 +0000 |
parents | 2b72f9bc4f06 |
children | 575e0a847f0c |
rev | line source |
---|---|
4971 | 1 /** |
4972
c443ed30f430
rename vorbis.c to vorbis_dec.c and vorbis_common.c to vorbis.c
aurel
parents:
4971
diff
changeset
|
2 * @file vorbis.c |
4971 | 3 * Common code for Vorbis I encoder and decoder |
4 * @author Denes Balatoni ( dbalatoni programozo hu ) | |
5 | |
6 * This file is part of FFmpeg. | |
7 * | |
8 * FFmpeg is free software; you can redistribute it and/or | |
9 * modify it under the terms of the GNU Lesser General Public | |
10 * License as published by the Free Software Foundation; either | |
11 * version 2.1 of the License, or (at your option) any later version. | |
12 * | |
13 * FFmpeg is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Lesser General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Lesser General Public | |
19 * License along with FFmpeg; if not, write to the Free Software | |
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
21 */ | |
22 | |
23 #undef V_DEBUG | |
24 //#define V_DEBUG | |
25 | |
26 #define ALT_BITSTREAM_READER_LE | |
27 #include "avcodec.h" | |
28 #include "bitstream.h" | |
29 | |
30 #include "vorbis.h" | |
31 | |
32 | |
33 /* Helper functions */ | |
34 | |
35 unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n) { // x^(1/n) | |
36 unsigned int ret=0, i, j; | |
37 | |
38 do { | |
39 ++ret; | |
40 for(i=0,j=ret;i<n-1;i++) j*=ret; | |
41 } while (j<=x); | |
42 | |
43 return (ret-1); | |
44 } | |
45 | |
46 // Generate vlc codes from vorbis huffman code lengths | |
47 | |
48 int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, uint_fast32_t num) { | |
49 uint_fast32_t exit_at_level[33]={404,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
50 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | |
51 | |
52 uint_fast8_t i,j; | |
53 uint_fast32_t code,p; | |
54 | |
55 #ifdef V_DEBUG | |
56 GetBitContext gb; | |
57 #endif | |
58 | |
59 for(p=0;(bits[p]==0) && (p<num);++p); | |
60 if (p==num) { | |
61 // av_log(vc->avccontext, AV_LOG_INFO, "An empty codebook. Heh?! \n"); | |
62 return 0; | |
63 } | |
64 | |
65 codes[p]=0; | |
66 for(i=0;i<bits[p];++i) { | |
67 exit_at_level[i+1]=1<<i; | |
68 } | |
69 | |
70 #ifdef V_DEBUG | |
71 av_log(NULL, AV_LOG_INFO, " %d. of %d code len %d code %d - ", p, num, bits[p], codes[p]); | |
72 init_get_bits(&gb, (uint_fast8_t *)&codes[p], bits[p]); | |
73 for(i=0;i<bits[p];++i) { | |
74 av_log(NULL, AV_LOG_INFO, "%s", get_bits1(&gb) ? "1" : "0"); | |
75 } | |
76 av_log(NULL, AV_LOG_INFO, "\n"); | |
77 #endif | |
78 | |
79 ++p; | |
80 | |
81 for(;p<num;++p) { | |
82 if (bits[p]==0) continue; | |
83 // find corresponding exit(node which the tree can grow further from) | |
84 for(i=bits[p];i>0;--i) { | |
85 if (exit_at_level[i]) break; | |
86 } | |
87 if (!i) return 1; // overspecified tree | |
88 code=exit_at_level[i]; | |
89 exit_at_level[i]=0; | |
90 // construct code (append 0s to end) and introduce new exits | |
91 for(j=i+1;j<=bits[p];++j) { | |
92 exit_at_level[j]=code+(1<<(j-1)); | |
93 } | |
94 codes[p]=code; | |
95 | |
96 #ifdef V_DEBUG | |
97 av_log(NULL, AV_LOG_INFO, " %d. code len %d code %d - ", p, bits[p], codes[p]); | |
98 init_get_bits(&gb, (uint_fast8_t *)&codes[p], bits[p]); | |
99 for(i=0;i<bits[p];++i) { | |
100 av_log(NULL, AV_LOG_INFO, "%s", get_bits1(&gb) ? "1" : "0"); | |
101 } | |
102 av_log(NULL, AV_LOG_INFO, "\n"); | |
103 #endif | |
104 | |
105 } | |
106 | |
107 //no exits should be left (underspecified tree - ie. unused valid vlcs - not allowed by SPEC) | |
108 for (p=1; p<33; p++) | |
109 if (exit_at_level[p]) return 1; | |
110 | |
111 return 0; | |
112 } | |
113 | |
114 void ff_vorbis_ready_floor1_list(floor1_entry_t * list, int values) { | |
115 int i; | |
116 list[0].sort = 0; | |
117 list[1].sort = 1; | |
118 for (i = 2; i < values; i++) { | |
119 int j; | |
120 list[i].low = 0; | |
121 list[i].high = 1; | |
122 list[i].sort = i; | |
123 for (j = 2; j < i; j++) { | |
124 int tmp = list[j].x; | |
125 if (tmp < list[i].x) { | |
126 if (tmp > list[list[i].low].x) list[i].low = j; | |
127 } else { | |
128 if (tmp < list[list[i].high].x) list[i].high = j; | |
129 } | |
130 } | |
131 } | |
132 for (i = 0; i < values - 1; i++) { | |
133 int j; | |
134 for (j = i + 1; j < values; j++) { | |
135 if (list[list[i].sort].x > list[list[j].sort].x) { | |
136 int tmp = list[i].sort; | |
137 list[i].sort = list[j].sort; | |
138 list[j].sort = tmp; | |
139 } | |
140 } | |
141 } | |
142 } | |
143 | |
144 static void render_line(int x0, int y0, int x1, int y1, float * buf, int n) { | |
145 int dy = y1 - y0; | |
146 int adx = x1 - x0; | |
147 int ady = FFABS(dy); | |
148 int base = dy / adx; | |
149 int x = x0; | |
150 int y = y0; | |
151 int err = 0; | |
152 int sy; | |
153 if (dy < 0) sy = base - 1; | |
154 else sy = base + 1; | |
155 ady = ady - FFABS(base) * adx; | |
156 if (x >= n) return; | |
157 buf[x] = ff_vorbis_floor1_inverse_db_table[y]; | |
158 for (x = x0 + 1; x < x1; x++) { | |
159 if (x >= n) return; | |
160 err += ady; | |
161 if (err >= adx) { | |
162 err -= adx; | |
163 y += sy; | |
164 } else { | |
165 y += base; | |
166 } | |
167 buf[x] = ff_vorbis_floor1_inverse_db_table[y]; | |
168 } | |
169 } | |
170 | |
171 void ff_vorbis_floor1_render_list(floor1_entry_t * list, int values, uint_fast16_t * y_list, int * flag, int multiplier, float * out, int samples) { | |
172 int lx, ly, i; | |
173 lx = 0; | |
174 ly = y_list[0] * multiplier; | |
175 for (i = 1; i < values; i++) { | |
176 int pos = list[i].sort; | |
177 if (flag[pos]) { | |
178 render_line(lx, ly, list[pos].x, y_list[pos] * multiplier, out, samples); | |
179 lx = list[pos].x; | |
180 ly = y_list[pos] * multiplier; | |
181 } | |
182 if (lx >= samples) break; | |
183 } | |
184 if (lx < samples) render_line(lx, ly, samples, ly, out, samples); | |
185 } |