annotate tremor/mapping0.c @ 25661:293aeec83153

Replace the persistent CODECS_FLAG_SELECTED by a local "stringset" with an almost-trivial implementation. This allows making the builtin codec structs const, and it also makes clearer that this "selected" status is not used outside the init functions.
author reimar
date Sat, 12 Jan 2008 14:05:46 +0000
parents cd6b211be811
children 54c35115639c
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: channel mapping 0 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 <stdio.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
20 #include <string.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
21 #include <math.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
22 #include "ogg.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
23 #include "ivorbiscodec.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
24 #include "mdct.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
25 #include "codec_internal.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
26 #include "codebook.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
27 #include "window.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
28 #include "registry.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
29 #include "misc.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
30
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
31 /* simplistic, wasteful way of doing this (unique lookup for each
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
32 mode/submapping); there should be a central repository for
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
33 identical lookups. That will require minor work, so I'm putting it
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
34 off as low priority.
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
35
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
36 Why a lookup for each backend in a given mode? Because the
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
37 blocksize is set by the mode, and low backend lookups may require
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
38 parameters from other areas of the mode/mapping */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
39
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
40 typedef struct {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
41 vorbis_info_mode *mode;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
42 vorbis_info_mapping0 *map;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
43
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
44 vorbis_look_floor **floor_look;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
45
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
46 vorbis_look_residue **residue_look;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
47
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
48 vorbis_func_floor **floor_func;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
49 vorbis_func_residue **residue_func;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
50
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
51 int ch;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
52 long lastframe; /* if a different mode is called, we need to
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
53 invalidate decay */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
54 } vorbis_look_mapping0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
55
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
56 static void mapping0_free_info(vorbis_info_mapping *i){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
57 vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
58 if(info){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
59 memset(info,0,sizeof(*info));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
60 _ogg_free(info);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
61 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
62 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
63
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
64 static void mapping0_free_look(vorbis_look_mapping *look){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
65 int i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
66 vorbis_look_mapping0 *l=(vorbis_look_mapping0 *)look;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
67 if(l){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
68
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
69 for(i=0;i<l->map->submaps;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
70 l->floor_func[i]->free_look(l->floor_look[i]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
71 l->residue_func[i]->free_look(l->residue_look[i]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
72 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
73
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
74 _ogg_free(l->floor_func);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
75 _ogg_free(l->residue_func);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
76 _ogg_free(l->floor_look);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
77 _ogg_free(l->residue_look);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
78 memset(l,0,sizeof(*l));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
79 _ogg_free(l);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
80 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
81 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
82
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
83 static vorbis_look_mapping *mapping0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
84 vorbis_info_mapping *m){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
85 int i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
86 vorbis_info *vi=vd->vi;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
87 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
88 vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)_ogg_calloc(1,sizeof(*look));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
89 vorbis_info_mapping0 *info=look->map=(vorbis_info_mapping0 *)m;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
90 look->mode=vm;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
91
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
92 look->floor_look=(vorbis_look_floor **)_ogg_calloc(info->submaps,sizeof(*look->floor_look));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
93
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
94 look->residue_look=(vorbis_look_residue **)_ogg_calloc(info->submaps,sizeof(*look->residue_look));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
95
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
96 look->floor_func=(vorbis_func_floor **)_ogg_calloc(info->submaps,sizeof(*look->floor_func));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
97 look->residue_func=(vorbis_func_residue **)_ogg_calloc(info->submaps,sizeof(*look->residue_func));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
98
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
99 for(i=0;i<info->submaps;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
100 int floornum=info->floorsubmap[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
101 int resnum=info->residuesubmap[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
102
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
103 look->floor_func[i]=_floor_P[ci->floor_type[floornum]];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
104 look->floor_look[i]=look->floor_func[i]->
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
105 look(vd,vm,ci->floor_param[floornum]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
106 look->residue_func[i]=_residue_P[ci->residue_type[resnum]];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
107 look->residue_look[i]=look->residue_func[i]->
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
108 look(vd,vm,ci->residue_param[resnum]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
109
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
110 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
111
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
112 look->ch=vi->channels;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
113
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
114 return(look);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
115 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
116
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
117 static int ilog(unsigned int v){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
118 int ret=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
119 if(v)--v;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
120 while(v){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
121 ret++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
122 v>>=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
123 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
124 return(ret);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
125 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
126
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
127 /* also responsible for range checking */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
128 static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
129 int i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
130 vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)_ogg_calloc(1,sizeof(*info));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
131 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
132 memset(info,0,sizeof(*info));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
133
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
134 if(oggpack_read(opb,1))
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
135 info->submaps=oggpack_read(opb,4)+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
136 else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
137 info->submaps=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
138
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
139 if(oggpack_read(opb,1)){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
140 info->coupling_steps=oggpack_read(opb,8)+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
141
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
142 for(i=0;i<info->coupling_steps;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
143 int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
144 int testA=info->coupling_ang[i]=oggpack_read(opb,ilog(vi->channels));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
145
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
146 if(testM<0 ||
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
147 testA<0 ||
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
148 testM==testA ||
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
149 testM>=vi->channels ||
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
150 testA>=vi->channels) goto err_out;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
151 }
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 if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
156
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
157 if(info->submaps>1){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
158 for(i=0;i<vi->channels;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
159 info->chmuxlist[i]=oggpack_read(opb,4);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
160 if(info->chmuxlist[i]>=info->submaps)goto err_out;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
161 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
162 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
163 for(i=0;i<info->submaps;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
164 int temp=oggpack_read(opb,8);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
165 if(temp>=ci->times)goto err_out;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
166 info->floorsubmap[i]=oggpack_read(opb,8);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
167 if(info->floorsubmap[i]>=ci->floors)goto err_out;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
168 info->residuesubmap[i]=oggpack_read(opb,8);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
169 if(info->residuesubmap[i]>=ci->residues)goto err_out;
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 info;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
173
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
174 err_out:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
175 mapping0_free_info(info);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
176 return(NULL);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
177 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
178
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
179 static int seq=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
180 static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
181 vorbis_dsp_state *vd=vb->vd;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
182 vorbis_info *vi=vd->vi;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
183 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
184 backend_lookup_state *b=(backend_lookup_state *)vd->backend_state;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
185 vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
186 vorbis_info_mapping0 *info=look->map;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
187
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
188 int i,j;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
189 long n=vb->pcmend=ci->blocksizes[vb->W];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
190
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
191 ogg_int32_t **pcmbundle=(ogg_int32_t **)alloca(sizeof(*pcmbundle)*vi->channels);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
192 int *zerobundle=(int *)alloca(sizeof(*zerobundle)*vi->channels);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
193
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
194 int *nonzero =(int *)alloca(sizeof(*nonzero)*vi->channels);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
195 void **floormemo=(void **)alloca(sizeof(*floormemo)*vi->channels);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
196
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
197 /* time domain information decode (note that applying the
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
198 information would have to happen later; we'll probably add a
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
199 function entry to the harness for that later */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
200 /* NOT IMPLEMENTED */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
201
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
202 /* recover the spectral envelope; store it in the PCM vector for now */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
203 for(i=0;i<vi->channels;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
204 int submap=info->chmuxlist[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
205 floormemo[i]=look->floor_func[submap]->
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
206 inverse1(vb,look->floor_look[submap]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
207 if(floormemo[i])
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
208 nonzero[i]=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
209 else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
210 nonzero[i]=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
211 memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
212 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
213
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
214 /* channel coupling can 'dirty' the nonzero listing */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
215 for(i=0;i<info->coupling_steps;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
216 if(nonzero[info->coupling_mag[i]] ||
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
217 nonzero[info->coupling_ang[i]]){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
218 nonzero[info->coupling_mag[i]]=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
219 nonzero[info->coupling_ang[i]]=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
220 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
221 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
222
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
223 /* recover the residue into our working vectors */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
224 for(i=0;i<info->submaps;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
225 int ch_in_bundle=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
226 for(j=0;j<vi->channels;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
227 if(info->chmuxlist[j]==i){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
228 if(nonzero[j])
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
229 zerobundle[ch_in_bundle]=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
230 else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
231 zerobundle[ch_in_bundle]=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
232 pcmbundle[ch_in_bundle++]=vb->pcm[j];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
233 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
234 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
235
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
236 look->residue_func[i]->inverse(vb,look->residue_look[i],
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
237 pcmbundle,zerobundle,ch_in_bundle);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
238 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
239
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
240 //for(j=0;j<vi->channels;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
241 //_analysis_output("coupled",seq+j,vb->pcm[j],-8,n/2,0,0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
242
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
243
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
244 /* channel coupling */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
245 for(i=info->coupling_steps-1;i>=0;i--){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
246 ogg_int32_t *pcmM=vb->pcm[info->coupling_mag[i]];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
247 ogg_int32_t *pcmA=vb->pcm[info->coupling_ang[i]];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
248
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
249 for(j=0;j<n/2;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
250 ogg_int32_t mag=pcmM[j];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
251 ogg_int32_t ang=pcmA[j];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
252
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
253 if(mag>0)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
254 if(ang>0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
255 pcmM[j]=mag;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
256 pcmA[j]=mag-ang;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
257 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
258 pcmA[j]=mag;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
259 pcmM[j]=mag+ang;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
260 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
261 else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
262 if(ang>0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
263 pcmM[j]=mag;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
264 pcmA[j]=mag+ang;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
265 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
266 pcmA[j]=mag;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
267 pcmM[j]=mag-ang;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
268 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
269 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
270 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
271
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
272 //for(j=0;j<vi->channels;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
273 //_analysis_output("residue",seq+j,vb->pcm[j],-8,n/2,0,0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
274
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
275 /* compute and apply spectral envelope */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
276 for(i=0;i<vi->channels;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
277 ogg_int32_t *pcm=vb->pcm[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
278 int submap=info->chmuxlist[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
279 look->floor_func[submap]->
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
280 inverse2(vb,look->floor_look[submap],floormemo[i],pcm);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
281 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
282
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
283 //for(j=0;j<vi->channels;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
284 //_analysis_output("mdct",seq+j,vb->pcm[j],-24,n/2,0,1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
285
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
286 /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
287 /* only MDCT right now.... */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
288 for(i=0;i<vi->channels;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
289 ogg_int32_t *pcm=vb->pcm[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
290 mdct_backward(n,pcm,pcm);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
291 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
292
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
293 //for(j=0;j<vi->channels;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
294 //_analysis_output("imdct",seq+j,vb->pcm[j],-24,n,0,0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
295
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
296 /* window the data */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
297 for(i=0;i<vi->channels;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
298 ogg_int32_t *pcm=vb->pcm[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
299 if(nonzero[i])
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
300 _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
301 else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
302 for(j=0;j<n;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
303 pcm[j]=0;
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
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
307 //for(j=0;j<vi->channels;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
308 //_analysis_output("window",seq+j,vb->pcm[j],-24,n,0,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 seq+=vi->channels;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
311 /* all done! */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
312 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
313 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
314
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
315 /* export hooks */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
316 vorbis_func_mapping mapping0_exportbundle={
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
317 &mapping0_unpack,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
318 &mapping0_look,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
319 &mapping0_free_info,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
320 &mapping0_free_look,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
321 &mapping0_inverse
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
322 };