annotate tremor/floor0.c @ 24787:02535b3216c5

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