1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
/********************************************************************
* *
* THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
* THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
* PLEASE READ THESE TERMS DISTRIBUTING. *
* *
* THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *
* by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *
* http://www.xiph.org/ *
* *
********************************************************************
function: spectrum envelope and residue code/decode
author: Monty <xiphmont@mit.edu>
modifications by: Monty
last modification date: Nov 16 1999
********************************************************************/
#include <stdio.h>
#include <math.h>
#include "os.h"
#include "codec.h"
#include "bitwise.h"
#include "spectrum.h"
/* this code is still seriously abbreviated. I'm filling in pieces as
we go... --Monty 19991004 */
/* unlike other LPC-based coders, we never apply the filter but only
inspect the frequency response, thus we don't need to guard against
instability. However, two coefficients quantising to the same
value will cause the response to explode. */
int _vs_spectrum_encode(vorbis_block *vb,double amp,double *lsp){
/* no real coding yet. Just write out full sized words for now
because people need bitstreams to work with */
int scale=vb->W;
int m=vb->vd->vi->floororder[scale];
int n=vb->pcmend*4;
int last=0;
double dlast=0.;
double min=M_PI/n/2.;
int bits=rint(log(n)/log(2));
int i;
#if 0
if(amp>0){
{
FILE *out=fopen("lspdiff.vqd","a");
for(i=0;i<m;i++)
fprintf(out,"%lf ",lsp[i]);
fprintf(out,"\n");
fclose(out);
}
}
#endif
_oggpack_write(&vb->opb,amp*327680,18);
for(i=0;i<m;i++){
int val=rint(lsp[i]/M_PI*n-last);
_oggpack_write(&vb->opb,val,bits);
lsp[i]=(last+=val)*M_PI/n;
/* Underpowered but sufficient for now. In the real spec (coming
soon), a distance of zero can't happen. */
if(lsp[i]<dlast+min)lsp[i]=dlast+min;
dlast=lsp[i];
}
return(0);
}
int _vs_spectrum_decode(vorbis_block *vb,double *amp,double *lsp){
int scale=vb->W;
int m=vb->vd->vi->floororder[scale];
int n=vb->pcmend*4;
int last=0;
double dlast=0.;
int bits=rint(log(n)/log(2));
int i;
double min=M_PI/n/2.;
*amp=_oggpack_read(&vb->opb,18)/327680.;
for(i=0;i<m;i++){
int val=_oggpack_read(&vb->opb,bits);
lsp[i]=(last+=val)*M_PI/n;
/* Underpowered but sufficient */
if(lsp[i]<dlast+min)lsp[i]=dlast+min;
dlast=lsp[i];
}
return(0);
}
void _vs_residue_quantize(double *data,double *curve,
vorbis_info *vi,int n){
/* The following is temporary, hardwired bullshit */
int i;
for(i=0;i<n;i++){
int val=0;
if(curve[i]!=0.)val=rint(data[i]/curve[i]);
if(val>16)val=16;
if(val<-16)val=-16;
/*if(val==0 || val==2 || val==-2){
if(data[i]<0){
val=-1;
}else{
val=1;
}
}*/
data[i]=val;
/*if(val<0){
}else{
data[i]=val+15;
}*/
}
}
int _vs_residue_encode(vorbis_block *vb,double *data){
/* no real coding yet. Just write out full sized words for now
because people need bitstreams to work with */
int n=vb->pcmend/2;
int i;
for(i=0;i<n;i++){
_oggpack_write(&vb->opb,(int)(data[i]+16),6);
}
return(0);
}
int _vs_residue_decode(vorbis_block *vb,double *data){
/* no real coding yet. Just write out full sized words for now
because people need bitstreams to work with */
int n=vb->pcmend/2;
int i;
for(i=0;i<n;i++){
data[i]=_oggpack_read(&vb->opb,6)-16;
/*if(data[i]>=0)data[i]+=1;*/
}
return(0);
}
|