Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
244 chris 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-2002    *
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 "registry.h"
25
#include "codebook.h"
26
#include "misc.h"
27
#include "os.h"
28
 
29
extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes);
30
 
31
typedef struct {
32
  vorbis_info_residue0 *info;
33
  int         map;
34
 
35
  int         parts;
36
  int         stages;
37
  codebook   *fullbooks;
38
  codebook   *phrasebook;
39
  codebook ***partbooks;
40
 
41
  int         partvals;
42
  int       **decodemap;
43
 
44
} vorbis_look_residue0;
45
 
46
void res0_free_info(vorbis_info_residue *i){
47
  vorbis_info_residue0 *info=(vorbis_info_residue0 *)i;
48
  if(info){
49
    memset(info,0,sizeof(*info));
50
    _ogg_free(info);
51
  }
52
}
53
 
54
void res0_free_look(vorbis_look_residue *i){
55
  int j;
56
  if(i){
57
 
58
    vorbis_look_residue0 *look=(vorbis_look_residue0 *)i;
59
 
60
    for(j=0;j<look->parts;j++)
61
      if(look->partbooks[j])_ogg_free(look->partbooks[j]);
62
    _ogg_free(look->partbooks);
63
    for(j=0;j<look->partvals;j++)
64
      _ogg_free(look->decodemap[j]);
65
    _ogg_free(look->decodemap);
66
 
67
    memset(look,0,sizeof(*look));
68
    _ogg_free(look);
69
  }
70
}
71
 
72
static int ilog(unsigned int v){
73
  int ret=0;
74
  while(v){
75
    ret++;
76
    v>>=1;
77
  }
78
  return(ret);
79
}
80
 
81
static int icount(unsigned int v){
82
  int ret=0;
83
  while(v){
84
    ret+=v&1;
85
    v>>=1;
86
  }
87
  return(ret);
88
}
89
 
90
/* vorbis_info is for range checking */
91
vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
92
  int j,acc=0;
93
  vorbis_info_residue0 *info=(vorbis_info_residue0 *)_ogg_calloc(1,sizeof(*info));
94
  codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
95
 
96
  info->begin=oggpack_read(opb,24);
97
  info->end=oggpack_read(opb,24);
98
  info->grouping=oggpack_read(opb,24)+1;
99
  info->partitions=oggpack_read(opb,6)+1;
100
  info->groupbook=oggpack_read(opb,8);
101
 
102
  for(j=0;j<info->partitions;j++){
103
    int cascade=oggpack_read(opb,3);
104
    if(oggpack_read(opb,1))
105
      cascade|=(oggpack_read(opb,5)<<3);
106
    info->secondstages[j]=cascade;
107
 
108
    acc+=icount(cascade);
109
  }
110
  for(j=0;j<acc;j++)
111
    info->booklist[j]=oggpack_read(opb,8);
112
 
113
  if(info->groupbook>=ci->books)goto errout;
114
  for(j=0;j<acc;j++)
115
    if(info->booklist[j]>=ci->books)goto errout;
116
 
117
  return(info);
118
 errout:
119
  res0_free_info(info);
120
  return(NULL);
121
}
122
 
123
vorbis_look_residue *res0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm,
124
                          vorbis_info_residue *vr){
125
  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
126
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)_ogg_calloc(1,sizeof(*look));
127
  codec_setup_info     *ci=(codec_setup_info *)vd->vi->codec_setup;
128
 
129
  int j,k,acc=0;
130
  int dim;
131
  int maxstage=0;
132
  look->info=info;
133
  look->map=vm->mapping;
134
 
135
  look->parts=info->partitions;
136
  look->fullbooks=ci->fullbooks;
137
  look->phrasebook=ci->fullbooks+info->groupbook;
138
  dim=look->phrasebook->dim;
139
 
140
  look->partbooks=(codebook ***)_ogg_calloc(look->parts,sizeof(*look->partbooks));
141
 
142
  for(j=0;j<look->parts;j++){
143
    int stages=ilog(info->secondstages[j]);
144
    if(stages){
145
      if(stages>maxstage)maxstage=stages;
146
      look->partbooks[j]=(codebook **)_ogg_calloc(stages,sizeof(*look->partbooks[j]));
147
      for(k=0;k<stages;k++)
148
        if(info->secondstages[j]&(1<<k)){
149
          look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++];
150
#ifdef TRAIN_RES
151
          look->training_data[k][j]=calloc(look->partbooks[j][k]->entries,
152
                                           sizeof(***look->training_data));
153
#endif
154
        }
155
    }
156
  }
157
 
158
  look->partvals=look->parts;
159
  for(j=1;j<dim;j++)look->partvals*=look->parts;
160
  look->stages=maxstage;
161
  look->decodemap=(int **)_ogg_malloc(look->partvals*sizeof(*look->decodemap));
162
  for(j=0;j<look->partvals;j++){
163
    long val=j;
164
    long mult=look->partvals/look->parts;
165
    look->decodemap[j]=(int *)_ogg_malloc(dim*sizeof(*look->decodemap[j]));
166
    for(k=0;k<dim;k++){
167
      long deco=val/mult;
168
      val-=deco*mult;
169
      mult/=look->parts;
170
      look->decodemap[j][k]=deco;
171
    }
172
  }
173
 
174
  return(look);
175
}
176
 
177
 
178
/* a truncated packet here just means 'stop working'; it's not an error */
179
static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
180
                      ogg_int32_t **in,int ch,
181
                      long (*decodepart)(codebook *, ogg_int32_t *,
182
                                         oggpack_buffer *,int,int)){
183
 
184
  long i,j,k,l,s;
185
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
186
  vorbis_info_residue0 *info=look->info;
187
 
188
  /* move all this setup out later */
189
  int samples_per_partition=info->grouping;
190
  int partitions_per_word=look->phrasebook->dim;
191
  int n=info->end-info->begin;
192
 
193
  int partvals=n/samples_per_partition;
194
  int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
195
  int ***partword=(int ***)alloca(ch*sizeof(*partword));
196
 
197
  for(j=0;j<ch;j++)
198
    partword[j]=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword[j]));
199
 
200
  for(s=0;s<look->stages;s++){
201
 
202
    /* each loop decodes on partition codeword containing
203
       partitions_pre_word partitions */
204
    for(i=0,l=0;i<partvals;l++){
205
      if(s==0){
206
        /* fetch the partition word for each channel */
207
        for(j=0;j<ch;j++){
208
          int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
209
          if(temp==-1)goto eopbreak;
210
          partword[j][l]=look->decodemap[temp];
211
          if(partword[j][l]==NULL)goto errout;
212
        }
213
      }
214
 
215
      /* now we decode residual values for the partitions */
216
      for(k=0;k<partitions_per_word && i<partvals;k++,i++)
217
        for(j=0;j<ch;j++){
218
          long offset=info->begin+i*samples_per_partition;
219
          if(info->secondstages[partword[j][l][k]]&(1<<s)){
220
            codebook *stagebook=look->partbooks[partword[j][l][k]][s];
221
            if(stagebook){
222
              if(decodepart(stagebook,in[j]+offset,&vb->opb,
223
                            samples_per_partition,-8)==-1)goto eopbreak;
224
            }
225
          }
226
        }
227
    }
228
  }
229
 
230
 errout:
231
 eopbreak:
232
  return(0);
233
}
234
 
235
int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
236
                 ogg_int32_t **in,int *nonzero,int ch){
237
  int i,used=0;
238
  for(i=0;i<ch;i++)
239
    if(nonzero[i])
240
      in[used++]=in[i];
241
  if(used)
242
    return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add));
243
  else
244
    return(0);
245
}
246
 
247
int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
248
                 ogg_int32_t **in,int *nonzero,int ch){
249
  int i,used=0;
250
  for(i=0;i<ch;i++)
251
    if(nonzero[i])
252
      in[used++]=in[i];
253
  if(used)
254
    return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add));
255
  else
256
    return(0);
257
}
258
 
259
/* duplicate code here as speed is somewhat more important */
260
int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
261
                 ogg_int32_t **in,int *nonzero,int ch){
262
  long i,k,l,s;
263
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
264
  vorbis_info_residue0 *info=look->info;
265
 
266
  /* move all this setup out later */
267
  int samples_per_partition=info->grouping;
268
  int partitions_per_word=look->phrasebook->dim;
269
  int n=info->end-info->begin;
270
 
271
  int partvals=n/samples_per_partition;
272
  int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
273
  int **partword=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword));
274
  int beginoff=info->begin/ch;
275
 
276
  for(i=0;i<ch;i++)if(nonzero[i])break;
277
  if(i==ch)return(0); /* no nonzero vectors */
278
 
279
  samples_per_partition/=ch;
280
 
281
  for(s=0;s<look->stages;s++){
282
    for(i=0,l=0;i<partvals;l++){
283
 
284
      if(s==0){
285
        /* fetch the partition word */
286
        int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
287
        if(temp==-1)goto eopbreak;
288
        partword[l]=look->decodemap[temp];
289
        if(partword[l]==NULL)goto errout;
290
      }
291
 
292
      /* now we decode residual values for the partitions */
293
      for(k=0;k<partitions_per_word && i<partvals;k++,i++)
294
        if(info->secondstages[partword[l][k]]&(1<<s)){
295
          codebook *stagebook=look->partbooks[partword[l][k]][s];
296
 
297
          if(stagebook){
298
            if(vorbis_book_decodevv_add(stagebook,in,
299
                                        i*samples_per_partition+beginoff,ch,
300
                                        &vb->opb,
301
                                        samples_per_partition,-8)==-1)
302
              goto eopbreak;
303
          }
304
        }
305
    }
306
  }
307
 
308
 errout:
309
 eopbreak:
310
  return(0);
311
}
312
 
313
 
314
vorbis_func_residue residue0_exportbundle={
315
  &res0_unpack,
316
  &res0_look,
317
  &res0_free_info,
318
  &res0_free_look,
319
  &res0_inverse
320
};
321
 
322
vorbis_func_residue residue1_exportbundle={
323
  &res0_unpack,
324
  &res0_look,
325
  &res0_free_info,
326
  &res0_free_look,
327
  &res1_inverse
328
};
329
 
330
vorbis_func_residue residue2_exportbundle={
331
  &res0_unpack,
332
  &res0_look,
333
  &res0_free_info,
334
  &res0_free_look,
335
  &res2_inverse
336
};