annotate tremor/res012.c @ 22996:2a60af5e78a7

skip MMX code in rgb32to16 if the size of the input is smaller than the size of the units the MMX code processes
author ivo
date Wed, 18 Apr 2007 09:26:22 +0000
parents cd6b211be811
children 8dfda4d651ec
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
14280
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
1 /********************************************************************
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
2 * *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
4 * *
19251
cd6b211be811 Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents: 14280
diff changeset
5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
cd6b211be811 Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents: 14280
diff changeset
6 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
cd6b211be811 Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents: 14280
diff changeset
7 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
cd6b211be811 Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents: 14280
diff changeset
8 * *
14280
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
11 * *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
12 ********************************************************************
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
13
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
14 function: residue backend 0, 1 and 2 implementation
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
15
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
16 ********************************************************************/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
17
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
18 #include <stdlib.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
19 #include <string.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
20 #include <math.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
21 #include "ogg.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
22 #include "ivorbiscodec.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
23 #include "codec_internal.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
24 #include "registry.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
25 #include "codebook.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
26 #include "misc.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
27 #include "os.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
28
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
29 typedef struct {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
30 vorbis_info_residue0 *info;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
31 int map;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
32
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
33 int parts;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
34 int stages;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
35 codebook *fullbooks;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
36 codebook *phrasebook;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
37 codebook ***partbooks;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
38
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
39 int partvals;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
40 int **decodemap;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
41
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
42 } vorbis_look_residue0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
43
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
44 void res0_free_info(vorbis_info_residue *i){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
45 vorbis_info_residue0 *info=(vorbis_info_residue0 *)i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
46 if(info){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
47 memset(info,0,sizeof(*info));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
48 _ogg_free(info);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
49 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
50 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
51
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
52 void res0_free_look(vorbis_look_residue *i){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
53 int j;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
54 if(i){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
55
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
56 vorbis_look_residue0 *look=(vorbis_look_residue0 *)i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
57
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
58 for(j=0;j<look->parts;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
59 if(look->partbooks[j])_ogg_free(look->partbooks[j]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
60 _ogg_free(look->partbooks);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
61 for(j=0;j<look->partvals;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
62 _ogg_free(look->decodemap[j]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
63 _ogg_free(look->decodemap);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
64
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
65 memset(look,0,sizeof(*look));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
66 _ogg_free(look);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
67 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
68 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
69
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
70 static int ilog(unsigned int v){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
71 int ret=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
72 while(v){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
73 ret++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
74 v>>=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
75 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
76 return(ret);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
77 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
78
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
79 static int icount(unsigned int v){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
80 int ret=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
81 while(v){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
82 ret+=v&1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
83 v>>=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
84 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
85 return(ret);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
86 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
87
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
88 /* vorbis_info is for range checking */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
89 vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
90 int j,acc=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
91 vorbis_info_residue0 *info=(vorbis_info_residue0 *)_ogg_calloc(1,sizeof(*info));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
92 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
93
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
94 info->begin=oggpack_read(opb,24);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
95 info->end=oggpack_read(opb,24);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
96 info->grouping=oggpack_read(opb,24)+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
97 info->partitions=oggpack_read(opb,6)+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
98 info->groupbook=oggpack_read(opb,8);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
99
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
100 for(j=0;j<info->partitions;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
101 int cascade=oggpack_read(opb,3);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
102 if(oggpack_read(opb,1))
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
103 cascade|=(oggpack_read(opb,5)<<3);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
104 info->secondstages[j]=cascade;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
105
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
106 acc+=icount(cascade);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
107 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
108 for(j=0;j<acc;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
109 info->booklist[j]=oggpack_read(opb,8);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
110
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
111 if(info->groupbook>=ci->books)goto errout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
112 for(j=0;j<acc;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
113 if(info->booklist[j]>=ci->books)goto errout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
114
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
115 return(info);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
116 errout:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
117 res0_free_info(info);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
118 return(NULL);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
119 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
120
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
121 vorbis_look_residue *res0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
122 vorbis_info_residue *vr){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
123 vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
124 vorbis_look_residue0 *look=(vorbis_look_residue0 *)_ogg_calloc(1,sizeof(*look));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
125 codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
126
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
127 int j,k,acc=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
128 int dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
129 int maxstage=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
130 look->info=info;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
131 look->map=vm->mapping;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
132
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
133 look->parts=info->partitions;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
134 look->fullbooks=ci->fullbooks;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
135 look->phrasebook=ci->fullbooks+info->groupbook;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
136 dim=look->phrasebook->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
137
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
138 look->partbooks=(codebook ***)_ogg_calloc(look->parts,sizeof(*look->partbooks));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
139
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
140 for(j=0;j<look->parts;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
141 int stages=ilog(info->secondstages[j]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
142 if(stages){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
143 if(stages>maxstage)maxstage=stages;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
144 look->partbooks[j]=(codebook **)_ogg_calloc(stages,sizeof(*look->partbooks[j]));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
145 for(k=0;k<stages;k++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
146 if(info->secondstages[j]&(1<<k)){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
147 look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
148 #ifdef TRAIN_RES
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
149 look->training_data[k][j]=calloc(look->partbooks[j][k]->entries,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
150 sizeof(***look->training_data));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
151 #endif
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
152 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
153 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
154 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
155
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
156 look->partvals=look->parts;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
157 for(j=1;j<dim;j++)look->partvals*=look->parts;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
158 look->stages=maxstage;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
159 look->decodemap=(int **)_ogg_malloc(look->partvals*sizeof(*look->decodemap));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
160 for(j=0;j<look->partvals;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
161 long val=j;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
162 long mult=look->partvals/look->parts;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
163 look->decodemap[j]=(int *)_ogg_malloc(dim*sizeof(*look->decodemap[j]));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
164 for(k=0;k<dim;k++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
165 long deco=val/mult;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
166 val-=deco*mult;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
167 mult/=look->parts;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
168 look->decodemap[j][k]=deco;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
169 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
170 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
171
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
172 return(look);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
173 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
174
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
175
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
176 /* a truncated packet here just means 'stop working'; it's not an error */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
177 static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
178 ogg_int32_t **in,int ch,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
179 long (*decodepart)(codebook *, ogg_int32_t *,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
180 oggpack_buffer *,int,int)){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
181
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
182 long i,j,k,l,s;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
183 vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
184 vorbis_info_residue0 *info=look->info;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
185
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
186 /* move all this setup out later */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
187 int samples_per_partition=info->grouping;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
188 int partitions_per_word=look->phrasebook->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
189 int n=info->end-info->begin;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
190
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
191 int partvals=n/samples_per_partition;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
192 int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
193 int ***partword=(int ***)alloca(ch*sizeof(*partword));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
194
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
195 for(j=0;j<ch;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
196 partword[j]=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword[j]));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
197
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
198 for(s=0;s<look->stages;s++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
199
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
200 /* each loop decodes on partition codeword containing
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
201 partitions_pre_word partitions */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
202 for(i=0,l=0;i<partvals;l++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
203 if(s==0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
204 /* fetch the partition word for each channel */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
205 for(j=0;j<ch;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
206 int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
207 if(temp==-1)goto eopbreak;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
208 partword[j][l]=look->decodemap[temp];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
209 if(partword[j][l]==NULL)goto errout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
210 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
211 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
212
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
213 /* now we decode residual values for the partitions */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
214 for(k=0;k<partitions_per_word && i<partvals;k++,i++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
215 for(j=0;j<ch;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
216 long offset=info->begin+i*samples_per_partition;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
217 if(info->secondstages[partword[j][l][k]]&(1<<s)){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
218 codebook *stagebook=look->partbooks[partword[j][l][k]][s];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
219 if(stagebook){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
220 if(decodepart(stagebook,in[j]+offset,&vb->opb,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
221 samples_per_partition,-8)==-1)goto eopbreak;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
222 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
223 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
224 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
225 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
226 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
227
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
228 errout:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
229 eopbreak:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
230 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
231 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
232
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
233 int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
234 ogg_int32_t **in,int *nonzero,int ch){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
235 int i,used=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
236 for(i=0;i<ch;i++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
237 if(nonzero[i])
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
238 in[used++]=in[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
239 if(used)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
240 return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
241 else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
242 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
243 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
244
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
245 int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
246 ogg_int32_t **in,int *nonzero,int ch){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
247 int i,used=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
248 for(i=0;i<ch;i++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
249 if(nonzero[i])
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
250 in[used++]=in[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
251 if(used)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
252 return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
253 else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
254 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
255 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
256
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
257 /* duplicate code here as speed is somewhat more important */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
258 int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
259 ogg_int32_t **in,int *nonzero,int ch){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
260 long i,k,l,s;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
261 vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
262 vorbis_info_residue0 *info=look->info;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
263
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
264 /* move all this setup out later */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
265 int samples_per_partition=info->grouping;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
266 int partitions_per_word=look->phrasebook->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
267 int n=info->end-info->begin;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
268
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
269 int partvals=n/samples_per_partition;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
270 int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
271 int **partword=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
272 int beginoff=info->begin/ch;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
273
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
274 for(i=0;i<ch;i++)if(nonzero[i])break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
275 if(i==ch)return(0); /* no nonzero vectors */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
276
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
277 samples_per_partition/=ch;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
278
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
279 for(s=0;s<look->stages;s++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
280 for(i=0,l=0;i<partvals;l++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
281
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
282 if(s==0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
283 /* fetch the partition word */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
284 int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
285 if(temp==-1)goto eopbreak;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
286 partword[l]=look->decodemap[temp];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
287 if(partword[l]==NULL)goto errout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
288 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
289
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
290 /* now we decode residual values for the partitions */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
291 for(k=0;k<partitions_per_word && i<partvals;k++,i++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
292 if(info->secondstages[partword[l][k]]&(1<<s)){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
293 codebook *stagebook=look->partbooks[partword[l][k]][s];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
294
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
295 if(stagebook){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
296 if(vorbis_book_decodevv_add(stagebook,in,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
297 i*samples_per_partition+beginoff,ch,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
298 &vb->opb,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
299 samples_per_partition,-8)==-1)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
300 goto eopbreak;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
301 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
302 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
303 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
304 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
305
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
306 errout:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
307 eopbreak:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
308 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
309 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
310
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
311
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
312 vorbis_func_residue residue0_exportbundle={
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
313 &res0_unpack,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
314 &res0_look,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
315 &res0_free_info,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
316 &res0_free_look,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
317 &res0_inverse
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
318 };
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
319
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
320 vorbis_func_residue residue1_exportbundle={
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
321 &res0_unpack,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
322 &res0_look,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
323 &res0_free_info,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
324 &res0_free_look,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
325 &res1_inverse
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
326 };
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
327
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
328 vorbis_func_residue residue2_exportbundle={
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
329 &res0_unpack,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
330 &res0_look,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
331 &res0_free_info,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
332 &res0_free_look,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
333 &res2_inverse
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
334 };