1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
9 * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: floor backend 0 implementation
15 last mod: $Id: floor0.c,v 1.6 2000/02/06 13:39:40 xiphmont Exp $
17 ********************************************************************/
22 #include "vorbis/codec.h"
27 #include "bookinternal.h"
32 vorbis_info_floor0 *vi;
36 static void free_info(vorbis_info_floor *i){
38 memset(i,0,sizeof(vorbis_info_floor0));
43 static void free_look(vorbis_look_floor *i){
44 vorbis_look_floor0 *f=(vorbis_look_floor0 *)i;
46 lpc_clear(&f->lpclook);
47 memset(f,0,sizeof(vorbis_look_floor0));
52 static void pack (vorbis_info_floor *i,oggpack_buffer *opb){
53 vorbis_info_floor0 *d=(vorbis_info_floor0 *)i;
55 _oggpack_write(opb,d->order,8);
56 _oggpack_write(opb,d->rate,16);
57 _oggpack_write(opb,d->barkmap,16);
58 _oggpack_write(opb,d->stages-1,4);
59 for(j=0;j<d->stages;j++)
60 _oggpack_write(opb,d->books[j],8);
63 static vorbis_info_floor *unpack (vorbis_info *vi,oggpack_buffer *opb){
65 vorbis_info_floor0 *d=malloc(sizeof(vorbis_info_floor0));
66 d->order=_oggpack_read(opb,8);
67 d->rate=_oggpack_read(opb,16);
68 d->barkmap=_oggpack_read(opb,16);
69 d->stages=_oggpack_read(opb,4)+1;
71 if(d->order<1)goto err_out;
72 if(d->rate<1)goto err_out;
73 if(d->barkmap<1)goto err_out;
74 if(d->stages<1)goto err_out;
76 for(j=0;j<d->stages;j++){
77 d->books[j]=_oggpack_read(opb,8);
78 if(d->books[j]<0 || d->books[j]>=vi->books)goto err_out;
86 static vorbis_look_floor *look (vorbis_info *vi,vorbis_info_mode *mi,
87 vorbis_info_floor *i){
88 vorbis_info_floor0 *d=(vorbis_info_floor0 *)i;
89 vorbis_look_floor0 *ret=malloc(sizeof(vorbis_look_floor0));
91 ret->n=vi->blocksizes[mi->blockflag]/2;
93 lpc_init(&ret->lpclook,ret->n,d->barkmap,d->rate,ret->m);
99 static int forward(vorbis_block *vb,vorbis_look_floor *i,
100 double *in,double *out){
102 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
103 vorbis_info_floor0 *info=look->vi;
105 /* use 'out' as temp storage */
106 /* Convert our floor to a set of lpc coefficients */
107 double amp=sqrt(vorbis_curve_to_lpc(in,out,&look->lpclook));
108 double *work=alloca(sizeof(double)*look->m);
110 /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
111 vorbis_lpc_to_lsp(out,out,look->m);
112 memcpy(work,out,sizeof(double)*look->m);
115 fprintf(stderr,"%0.3g, ",out[j]);
116 fprintf(stderr,"\n");
118 /* code the spectral envelope, and keep track of the actual quantized
120 _oggpack_write(&vb->opb,amp*32768,18);
122 codebook *b=vb->vd->fullbooks+info->books[0];
125 double next=out[j+b->dim-1];
126 for(k=0;k<b->dim;k++,j++)out[j]-=last;
131 for(k=0;k<info->stages;k++){
132 codebook *b=vb->vd->fullbooks+info->books[k];
133 for(j=0;j<look->m;j+=b->dim)
134 vorbis_book_encodev(b,out+j,&vb->opb);
137 for(j=0;j<look->m;j++)
138 out[j]=work[j]-out[j];
142 /* take the coefficients back to a spectral envelope curve */
143 vorbis_lsp_to_lpc(out,out,look->m);
144 vorbis_lpc_to_curve(out,out,amp,&look->lpclook);
149 static int inverse(vorbis_block *vb,vorbis_look_floor *i,double *out){
150 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
151 vorbis_info_floor0 *info=look->vi;
154 double amp=_oggpack_read(&vb->opb,18)/32768.;
155 memset(out,0,sizeof(double)*look->m);
156 for(k=0;k<info->stages;k++){
157 codebook *b=vb->vd->fullbooks+info->books[k];
158 for(j=0;j<look->m;j+=b->dim)
159 vorbis_book_decodev(b,out+j,&vb->opb);
163 codebook *b=vb->vd->fullbooks+info->books[0];
166 for(k=0;k<b->dim;k++,j++)out[j]+=last;
172 fprintf(stderr,"%0.3g, ",out[j]);
173 fprintf(stderr,"\n");
176 /* take the coefficients back to a spectral envelope curve */
177 vorbis_lsp_to_lpc(out,out,look->m);
178 vorbis_lpc_to_curve(out,out,amp,&look->lpclook);
184 vorbis_func_floor floor0_exportbundle={
185 &pack,&unpack,&look,&free_info,&free_look,&forward,&inverse