annotate tremor/floor0.c @ 28147:ba2cf9827d09

Define HAVE_FAST_64BIT if appropriate
author reimar
date Tue, 23 Dec 2008 11:42:11 +0000
parents 8dfda4d651ec
children e83eef58b30a
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 * *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
6 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
7 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
8 * *
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: floor backend 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 <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"
24796
8dfda4d651ec _vorbis_block_alloc() is used w/o prototype, this will crash on ia64.
diego
parents: 14280
diff changeset
28 #include "block.h"
14280
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
29
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
30 #define LSP_FRACBITS 14
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
31
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
32 typedef struct {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
33 long n;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
34 int ln;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
35 int m;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
36 int *linearmap;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
37
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
38 vorbis_info_floor0 *vi;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
39 ogg_int32_t *lsp_look;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
40
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
41 } vorbis_look_floor0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
42
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
43 /*************** LSP decode ********************/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
44
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
45 #include "lsp_lookup.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
46
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
47 /* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
48 16.16 format
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
49 returns in m.8 format */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
50
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
51 static long ADJUST_SQRT2[2]={8192,5792};
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
52 static inline ogg_int32_t vorbis_invsqlook_i(long a,long e){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
53 long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
54 long d=a&INVSQ_LOOKUP_I_MASK; /* 0.10 */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
55 long val=INVSQ_LOOKUP_I[i]- /* 1.16 */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
56 ((INVSQ_LOOKUP_IDel[i]*d)>>INVSQ_LOOKUP_I_SHIFT); /* result 1.16 */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
57 val*=ADJUST_SQRT2[e&1];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
58 e=(e>>1)+21;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
59 return(val>>e);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
60 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
61
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
62 /* interpolated lookup based fromdB function, domain -140dB to 0dB only */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
63 /* a is in n.12 format */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
64 static inline ogg_int32_t vorbis_fromdBlook_i(long a){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
65 int i=(-a)>>(12-FROMdB2_SHIFT);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
66 if(i<0) return 0x7fffffff;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
67 if(i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))return 0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
68
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
69 return FROMdB_LOOKUP[i>>FROMdB_SHIFT] * FROMdB2_LOOKUP[i&FROMdB2_MASK];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
70 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
71
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
72 /* interpolated lookup based cos function, domain 0 to PI only */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
73 /* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
74 static inline ogg_int32_t vorbis_coslook_i(long a){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
75 int i=a>>COS_LOOKUP_I_SHIFT;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
76 int d=a&COS_LOOKUP_I_MASK;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
77 return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
78 COS_LOOKUP_I_SHIFT);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
79 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
80
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
81 /* interpolated lookup based cos function */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
82 /* a is in 0.16 format, where 0==0, 2^^16==PI, return .LSP_FRACBITS */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
83 static inline ogg_int32_t vorbis_coslook2_i(long a){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
84 a=a&0x1ffff;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
85
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
86 if(a>0x10000)a=0x20000-a;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
87 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
88 int i=a>>COS_LOOKUP_I_SHIFT;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
89 int d=a&COS_LOOKUP_I_MASK;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
90 a=((COS_LOOKUP_I[i]<<COS_LOOKUP_I_SHIFT)-
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
91 d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
92 (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
93 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
94
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
95 return(a);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
96 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
97
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
98 static const int barklook[28]={
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
99 0,100,200,301, 405,516,635,766,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
100 912,1077,1263,1476, 1720,2003,2333,2721,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
101 3184,3742,4428,5285, 6376,7791,9662,12181,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
102 15624,20397,27087,36554
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
103 };
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
104
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
105 /* used in init only; interpolate the long way */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
106 static inline ogg_int32_t toBARK(int n){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
107 int i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
108 for(i=0;i<27;i++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
109 if(n>=barklook[i] && n<barklook[i+1])break;
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(i==27){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
112 return 27<<15;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
113 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
114 int gap=barklook[i+1]-barklook[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
115 int del=n-barklook[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
116
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
117 return((i<<15)+((del<<15)/gap));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
118 }
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 static const unsigned char MLOOP_1[64]={
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
122 0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
123 14,14,14,14, 14,14,14,14, 14,14,14,14, 14,14,14,14,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
124 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
125 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
126 };
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
127
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
128 static const unsigned char MLOOP_2[64]={
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
129 0,4,5,5, 6,6,6,6, 7,7,7,7, 7,7,7,7,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
130 8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
131 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
132 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
133 };
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
134
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
135 static const unsigned char MLOOP_3[8]={0,1,2,2,3,3,3,3};
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
136
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
137 void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
138 ogg_int32_t *lsp,int m,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
139 ogg_int32_t amp,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
140 ogg_int32_t ampoffset,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
141 ogg_int32_t *icos){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
142
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
143 /* 0 <= m < 256 */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
144
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
145 /* set up for using all int later */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
146 int i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
147 int ampoffseti=ampoffset*4096;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
148 int ampi=amp;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
149 ogg_int32_t *ilsp=(ogg_int32_t *)alloca(m*sizeof(*ilsp));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
150 /* lsp is in 8.24, range 0 to PI; coslook wants it in .16 0 to 1*/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
151 for(i=0;i<m;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
152 #ifndef _LOW_ACCURACY_
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
153 ogg_int32_t val=MULT32(lsp[i],0x517cc2);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
154 #else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
155 ogg_int32_t val=((lsp[i]>>10)*0x517d)>>14;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
156 #endif
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
157
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
158 /* safeguard against a malicious stream */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
159 if(val<0 || (val>>COS_LOOKUP_I_SHIFT)>=COS_LOOKUP_I_SZ){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
160 memset(curve,0,sizeof(*curve)*n);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
161 return;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
162 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
163
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
164 ilsp[i]=vorbis_coslook_i(val);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
165 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
166
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
167 i=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
168 while(i<n){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
169 int j,k=map[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
170 ogg_uint32_t pi=46341; /* 2**-.5 in 0.16 */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
171 ogg_uint32_t qi=46341;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
172 ogg_int32_t qexp=0,shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
173 ogg_int32_t wi=icos[k];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
174
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
175 #ifdef _V_LSP_MATH_ASM
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
176 lsp_loop_asm(&qi,&pi,&qexp,ilsp,wi,m);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
177
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
178 pi=((pi*pi)>>16);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
179 qi=((qi*qi)>>16);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
180
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
181 if(m&1){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
182 qexp= qexp*2-28*((m+1)>>1)+m;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
183 pi*=(1<<14)-((wi*wi)>>14);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
184 qi+=pi>>14;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
185 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
186 qexp= qexp*2-13*m;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
187
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
188 pi*=(1<<14)-wi;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
189 qi*=(1<<14)+wi;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
190
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
191 qi=(qi+pi)>>14;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
192 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
193
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
194 if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
195 qi>>=1; qexp++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
196 }else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
197 lsp_norm_asm(&qi,&qexp);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
198
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
199 #else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
200
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
201 qi*=labs(ilsp[0]-wi);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
202 pi*=labs(ilsp[1]-wi);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
203
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
204 for(j=3;j<m;j+=2){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
205 if(!(shift=MLOOP_1[(pi|qi)>>25]))
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
206 if(!(shift=MLOOP_2[(pi|qi)>>19]))
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
207 shift=MLOOP_3[(pi|qi)>>16];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
208 qi=(qi>>shift)*labs(ilsp[j-1]-wi);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
209 pi=(pi>>shift)*labs(ilsp[j]-wi);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
210 qexp+=shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
211 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
212 if(!(shift=MLOOP_1[(pi|qi)>>25]))
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
213 if(!(shift=MLOOP_2[(pi|qi)>>19]))
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
214 shift=MLOOP_3[(pi|qi)>>16];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
215
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
216 /* pi,qi normalized collectively, both tracked using qexp */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
217
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
218 if(m&1){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
219 /* odd order filter; slightly assymetric */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
220 /* the last coefficient */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
221 qi=(qi>>shift)*labs(ilsp[j-1]-wi);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
222 pi=(pi>>shift)<<14;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
223 qexp+=shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
224
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
225 if(!(shift=MLOOP_1[(pi|qi)>>25]))
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
226 if(!(shift=MLOOP_2[(pi|qi)>>19]))
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
227 shift=MLOOP_3[(pi|qi)>>16];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
228
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
229 pi>>=shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
230 qi>>=shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
231 qexp+=shift-14*((m+1)>>1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
232
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
233 pi=((pi*pi)>>16);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
234 qi=((qi*qi)>>16);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
235 qexp=qexp*2+m;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
236
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
237 pi*=(1<<14)-((wi*wi)>>14);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
238 qi+=pi>>14;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
239
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
240 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
241 /* even order filter; still symmetric */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
242
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
243 /* p*=p(1-w), q*=q(1+w), let normalization drift because it isn't
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
244 worth tracking step by step */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
245
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
246 pi>>=shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
247 qi>>=shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
248 qexp+=shift-7*m;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
249
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
250 pi=((pi*pi)>>16);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
251 qi=((qi*qi)>>16);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
252 qexp=qexp*2+m;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
253
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
254 pi*=(1<<14)-wi;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
255 qi*=(1<<14)+wi;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
256 qi=(qi+pi)>>14;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
257
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
258 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
259
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
260
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
261 /* we've let the normalization drift because it wasn't important;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
262 however, for the lookup, things must be normalized again. We
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
263 need at most one right shift or a number of left shifts */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
264
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
265 if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
266 qi>>=1; qexp++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
267 }else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
268 while(qi && !(qi&0x8000)){ /* checks for 0.0xxxxxxxxxxxxxxx or less*/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
269 qi<<=1; qexp--;
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 #endif
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
273
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
274 amp=vorbis_fromdBlook_i(ampi* /* n.4 */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
275 vorbis_invsqlook_i(qi,qexp)-
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
276 /* m.8, m+n<=8 */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
277 ampoffseti); /* 8.12[0] */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
278
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
279 #ifdef _LOW_ACCURACY_
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
280 amp>>=9;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
281 #endif
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
282 curve[i]= MULT31_SHIFT15(curve[i],amp);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
283 while(map[++i]==k) curve[i]= MULT31_SHIFT15(curve[i],amp);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
284 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
285 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
286
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
287 /*************** vorbis decode glue ************/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
288
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
289 static void floor0_free_info(vorbis_info_floor *i){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
290 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
291 if(info){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
292 memset(info,0,sizeof(*info));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
293 _ogg_free(info);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
294 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
295 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
296
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
297 static void floor0_free_look(vorbis_look_floor *i){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
298 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
299 if(look){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
300
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
301 if(look->linearmap)_ogg_free(look->linearmap);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
302 if(look->lsp_look)_ogg_free(look->lsp_look);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
303 memset(look,0,sizeof(*look));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
304 _ogg_free(look);
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
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
308 static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
309 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
310 int j;
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_info_floor0 *info=(vorbis_info_floor0 *)_ogg_malloc(sizeof(*info));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
313 info->order=oggpack_read(opb,8);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
314 info->rate=oggpack_read(opb,16);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
315 info->barkmap=oggpack_read(opb,16);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
316 info->ampbits=oggpack_read(opb,6);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
317 info->ampdB=oggpack_read(opb,8);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
318 info->numbooks=oggpack_read(opb,4)+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
319
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
320 if(info->order<1)goto err_out;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
321 if(info->rate<1)goto err_out;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
322 if(info->barkmap<1)goto err_out;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
323 if(info->numbooks<1)goto err_out;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
324
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
325 for(j=0;j<info->numbooks;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
326 info->books[j]=oggpack_read(opb,8);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
327 if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
328 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
329 return(info);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
330
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
331 err_out:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
332 floor0_free_info(info);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
333 return(NULL);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
334 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
335
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
336 /* initialize Bark scale and normalization lookups. We could do this
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
337 with static tables, but Vorbis allows a number of possible
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
338 combinations, so it's best to do it computationally.
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
339
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
340 The below is authoritative in terms of defining scale mapping.
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
341 Note that the scale depends on the sampling rate as well as the
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
342 linear block and mapping sizes */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
343
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
344 static vorbis_look_floor *floor0_look (vorbis_dsp_state *vd,vorbis_info_mode *mi,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
345 vorbis_info_floor *i){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
346 int j;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
347 ogg_int32_t scale;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
348 vorbis_info *vi=vd->vi;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
349 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
350 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
351 vorbis_look_floor0 *look=(vorbis_look_floor0 *)_ogg_calloc(1,sizeof(*look));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
352 look->m=info->order;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
353 look->n=ci->blocksizes[mi->blockflag]/2;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
354 look->ln=info->barkmap;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
355 look->vi=info;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
356
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
357 /* the mapping from a linear scale to a smaller bark scale is
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
358 straightforward. We do *not* make sure that the linear mapping
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
359 does not skip bark-scale bins; the decoder simply skips them and
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
360 the encoder may do what it wishes in filling them. They're
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
361 necessary in some mapping combinations to keep the scale spacing
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
362 accurate */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
363 look->linearmap=(int *)_ogg_malloc((look->n+1)*sizeof(*look->linearmap));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
364 for(j=0;j<look->n;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
365
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
366 int val=(look->ln*
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
367 ((toBARK(info->rate/2*j/look->n)<<11)/toBARK(info->rate/2)))>>11;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
368
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
369 if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
370 look->linearmap[j]=val;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
371 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
372 look->linearmap[j]=-1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
373
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
374 look->lsp_look=(ogg_int32_t *)_ogg_malloc(look->ln*sizeof(*look->lsp_look));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
375 for(j=0;j<look->ln;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
376 look->lsp_look[j]=vorbis_coslook2_i(0x10000*j/look->ln);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
377
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
378 return look;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
379 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
380
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
381 static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
382 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
383 vorbis_info_floor0 *info=look->vi;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
384 int j,k;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
385
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
386 int ampraw=oggpack_read(&vb->opb,info->ampbits);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
387 if(ampraw>0){ /* also handles the -1 out of data case */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
388 long maxval=(1<<info->ampbits)-1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
389 int amp=((ampraw*info->ampdB)<<4)/maxval;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
390 int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
391
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
392 if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
393 codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
394 codebook *b=ci->fullbooks+info->books[booknum];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
395 ogg_int32_t last=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
396 ogg_int32_t *lsp=(ogg_int32_t *)_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+1));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
397
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
398 for(j=0;j<look->m;j+=b->dim)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
399 if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim,-24)==-1)goto eop;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
400 for(j=0;j<look->m;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
401 for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
402 last=lsp[j-1];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
403 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
404
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
405 lsp[look->m]=amp;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
406 return(lsp);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
407 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
408 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
409 eop:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
410 return(NULL);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
411 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
412
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
413 static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
414 void *memo,ogg_int32_t *out){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
415 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
416 vorbis_info_floor0 *info=look->vi;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
417
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
418 if(memo){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
419 ogg_int32_t *lsp=(ogg_int32_t *)memo;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
420 ogg_int32_t amp=lsp[look->m];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
421
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
422 /* take the coefficients back to a spectral envelope curve */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
423 vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
424 lsp,look->m,amp,info->ampdB,look->lsp_look);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
425 return(1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
426 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
427 memset(out,0,sizeof(*out)*look->n);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
428 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
429 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
430
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
431 /* export hooks */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
432 vorbis_func_floor floor0_exportbundle={
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
433 &floor0_unpack,&floor0_look,&floor0_free_info,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
434 &floor0_free_look,&floor0_inverse1,&floor0_inverse2
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
435 };
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
436
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
437