1 /********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
4 * *
5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
6 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
7 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * *
9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
11 * *
12 ********************************************************************
13
14 function: residue backend 0, 1 and 2 implementation
15
16 ********************************************************************/
17
18 #include <stdlib.h>
19 #include <string.h>
20 #include <math.h>
21 #include "ogg.h"
22 #include "ivorbiscodec.h"
23 #include "codec_internal.h"
24 #include "codebook.h"
25 #include "misc.h"
26 #include "os.h"
27
res_clear_info(vorbis_info_residue * info)28 void res_clear_info(vorbis_info_residue *info){
29 if(info){
30 if(info->stagemasks)_ogg_free(info->stagemasks);
31 if(info->stagebooks)_ogg_free(info->stagebooks);
32 memset(info,0,sizeof(*info));
33 }
34 }
35
36
37 /* vorbis_info is for range checking */
res_unpack(vorbis_info_residue * info,vorbis_info * vi,oggpack_buffer * opb)38 int res_unpack(vorbis_info_residue *info,
39 vorbis_info *vi,oggpack_buffer *opb){
40 int j,k;
41 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
42 memset(info,0,sizeof(*info));
43
44 info->type=oggpack_read(opb,16);
45 if(info->type>2 || info->type<0)goto errout;
46 info->begin=oggpack_read(opb,24);
47 info->end=oggpack_read(opb,24);
48 info->grouping=oggpack_read(opb,24)+1;
49 info->partitions=oggpack_read(opb,6)+1;
50 info->groupbook=oggpack_read(opb,8);
51 if(info->groupbook>=ci->books)goto errout;
52
53 info->stagemasks=_ogg_malloc(info->partitions*sizeof(*info->stagemasks));
54 info->stagebooks=_ogg_malloc(info->partitions*8*sizeof(*info->stagebooks));
55
56 for(j=0;j<info->partitions;j++){
57 int cascade=oggpack_read(opb,3);
58 if(oggpack_read(opb,1))
59 cascade|=(oggpack_read(opb,5)<<3);
60 info->stagemasks[j]=cascade;
61 }
62
63 for(j=0;j<info->partitions;j++){
64 for(k=0;k<8;k++){
65 if((info->stagemasks[j]>>k)&1){
66 unsigned char book=oggpack_read(opb,8);
67 if(book>=ci->books)goto errout;
68 info->stagebooks[j*8+k]=book;
69 if(k+1>info->stages)info->stages=k+1;
70 }else
71 info->stagebooks[j*8+k]=0xff;
72 }
73 }
74
75 if(oggpack_eop(opb))goto errout;
76
77 return 0;
78 errout:
79 res_clear_info(info);
80 return 1;
81 }
82
res_inverse(vorbis_dsp_state * vd,vorbis_info_residue * info,ogg_int32_t ** in,int * nonzero,int ch)83 int res_inverse(vorbis_dsp_state *vd,vorbis_info_residue *info,
84 ogg_int32_t **in,int *nonzero,int ch){
85
86 int i,j,k,s,used=0;
87 codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup;
88 codebook *phrasebook=ci->book_param+info->groupbook;
89 int samples_per_partition=info->grouping;
90 int partitions_per_word=phrasebook->dim;
91 int pcmend=ci->blocksizes[vd->W];
92
93 if(info->type<2){
94 int max=pcmend>>1;
95 int end=(info->end<max?info->end:max);
96 int n=end-info->begin;
97
98 if(n>0){
99 int partvals=n/samples_per_partition;
100 int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
101
102 for(i=0;i<ch;i++)
103 if(nonzero[i])
104 in[used++]=in[i];
105 ch=used;
106
107 if(used){
108
109 char **partword=(char **)alloca(ch*sizeof(*partword));
110 for(j=0;j<ch;j++)
111 partword[j]=(char *)alloca(partwords*partitions_per_word*
112 sizeof(*partword[j]));
113
114 for(s=0;s<info->stages;s++){
115
116 for(i=0;i<partvals;){
117 if(s==0){
118 /* fetch the partition word for each channel */
119
120 partword[0][i+partitions_per_word-1]=1;
121 for(k=partitions_per_word-2;k>=0;k--)
122 partword[0][i+k]=partword[0][i+k+1]*info->partitions;
123
124 for(j=1;j<ch;j++)
125 for(k=partitions_per_word-1;k>=0;k--)
126 partword[j][i+k]=partword[j-1][i+k];
127
128 for(j=0;j<ch;j++){
129 int temp=vorbis_book_decode(phrasebook,&vd->opb);
130 if(temp==-1)goto eopbreak;
131
132 /* this can be done quickly in assembly due to the quotient
133 always being at most six bits */
134 for(k=0;k<partitions_per_word;k++){
135 ogg_uint32_t div=partword[j][i+k];
136 partword[j][i+k]=temp/div;
137 temp-=partword[j][i+k]*div;
138 }
139
140 }
141 }
142
143 /* now we decode residual values for the partitions */
144 for(k=0;k<partitions_per_word && i<partvals;k++,i++)
145 for(j=0;j<ch;j++){
146 long offset=info->begin+i*samples_per_partition;
147 if(info->stagemasks[(int)partword[j][i]]&(1<<s)){
148 codebook *stagebook=ci->book_param+
149 info->stagebooks[(partword[j][i]<<3)+s];
150 if(info->type){
151 if(vorbis_book_decodev_add(stagebook,in[j]+offset,&vd->opb,
152 samples_per_partition,-8)==-1)
153 goto eopbreak;
154 }else{
155 if(vorbis_book_decodevs_add(stagebook,in[j]+offset,&vd->opb,
156 samples_per_partition,-8)==-1)
157 goto eopbreak;
158 }
159 }
160 }
161 }
162 }
163 }
164 }
165 }else{
166 int max=(pcmend*ch)>>1;
167 int end=(info->end<max?info->end:max);
168 int n=end-info->begin;
169
170 if(n>0){
171 int partvals=n/samples_per_partition;
172 int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
173
174 char *partword=
175 (char *)alloca(partwords*partitions_per_word*sizeof(*partword));
176 int beginoff=info->begin/ch;
177
178 for(i=0;i<ch;i++)if(nonzero[i])break;
179 if(i==ch)return(0); /* no nonzero vectors */
180
181 samples_per_partition/=ch;
182
183 for(s=0;s<info->stages;s++){
184 for(i=0;i<partvals;){
185
186 if(s==0){
187 int temp;
188 partword[i+partitions_per_word-1]=1;
189 for(k=partitions_per_word-2;k>=0;k--)
190 partword[i+k]=partword[i+k+1]*info->partitions;
191
192 /* fetch the partition word */
193 temp=vorbis_book_decode(phrasebook,&vd->opb);
194 if(temp==-1)goto eopbreak;
195
196 /* this can be done quickly in assembly due to the quotient
197 always being at most six bits */
198 for(k=0;k<partitions_per_word;k++){
199 ogg_uint32_t div=partword[i+k];
200 partword[i+k]=temp/div;
201 temp-=partword[i+k]*div;
202 }
203 }
204
205 /* now we decode residual values for the partitions */
206 for(k=0;k<partitions_per_word && i<partvals;k++,i++)
207 if(info->stagemasks[(int)partword[i]]&(1<<s)){
208 codebook *stagebook=ci->book_param+
209 info->stagebooks[(partword[i]<<3)+s];
210 if(vorbis_book_decodevv_add(stagebook,in,
211 i*samples_per_partition+beginoff,ch,
212 &vd->opb,
213 samples_per_partition,-8)==-1)
214 goto eopbreak;
215 }
216 }
217 }
218 }
219 }
220 errout:
221 eopbreak:
222
223 return 0;
224 }
225
226