incremental update to make sure the massive modifications exist on
[platform/upstream/libvorbis.git] / lib / mapping0.c
1 /********************************************************************
2  *                                                                  *
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.                            *
7  *                                                                  *
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/                                             *
11  *                                                                  *
12  ********************************************************************
13
14  function: channel mapping 0 implementation
15  last mod: $Id: mapping0.c,v 1.1 2000/01/20 04:43:02 xiphmont Exp $
16
17  ********************************************************************/
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <math.h>
22 #include "vorbis/codec.h"
23 #include "bitwise.h"
24 #include "bookinternal.h"
25 #include "registry.h"
26 #include "mapping0.h"
27
28 extern _vi_info_map *_vorbis_map0_dup(vi_info *vi,_vi_info_mapping *source){
29   vorbis_info_mapping0 *d=malloc(sizeof(vorbis_info_mapping0));
30   vorbis_info_mapping0 *s=(vorbis_info_mapping0 *)source;
31   memcpy(d,s,sizeof(vorbis_info_mapping0));
32
33   d->floorsubmap=malloc(sizeof(int)*vi->channels);
34   d->residuesubmap=malloc(sizeof(int)*vi->channels);
35   d->psysubmap=malloc(sizeof(int)*vi->channels);
36   memcpy(d->floorsubmap,s->floorsubmap,sizeof(int)*vi->channels);
37   memcpy(d->residuesubmap,s->residuesubmap,sizeof(int)*vi->channels);
38   memcpy(d->psysubmap,s->psysubmap,sizeof(int)*vi->channels);
39
40   return(d);
41 }
42
43 extern void _vorbis_map0_free(_vi_info_mapping *i){
44   vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)i;
45
46   if(d){
47     if(d->floorsubmap)free(d->floorsubmap);
48     if(d->residuesubmap)free(d->residuesubmap);
49     if(d->psysubmap)free(d->psysubmap);
50     memset(d,0,sizeof(vorbis_info_mapping0));
51     free(d);
52   }
53 }
54
55 extern void _vorbis_map0_pack(vorbis_info *vi,oggpack_buffer *opb,
56                               _vi_info_map *i){
57   int i;
58   vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)i;
59
60   _oggpack_write(opb,d->timesubmap,8);
61
62   /* we abbreviate the channel submappings if they all map to the same
63      floor/res/psy */
64   for(i=1;i<vi->channels;i++)if(d->floorsubmap[i]!=d->floorsubmap[i-1])break;
65   if(i==vi->channels){
66     _oggpack_write(opb,0,1);
67     _oggpack_write(opb,d->floorsubmap[0],8);
68   }else{
69     _oggpack_write(opb,1,1);
70     for(i=0;i<vi->channels;i++)
71       _oggpack_write(opb,d->floorsubmap[i],8);
72   }
73
74   for(i=1;i<vi->channels;i++)
75     if(d->residuesubmap[i]!=d->residuesubmap[i-1])break;
76   if(i==vi->channels){
77     /* no channel submapping */
78     _oggpack_write(opb,0,1);
79     _oggpack_write(opb,d->residuesubmap[0],8);
80   }else{
81     /* channel submapping */
82     _oggpack_write(opb,1,1);
83     for(i=0;i<vi->channels;i++)
84       _oggpack_write(opb,d->residuesubmap[i],8);
85   }
86 }
87
88 /* also responsible for range checking */
89 extern _vi_info_map *_vorbis_map0_unpack(vorbis_info *vi,oggpack_buffer *opb){
90   int i;
91   vorbis_info_mapping0 d=calloc(1,sizeof(vorbis_info_mapping0));
92   memset(d,0,sizeof(vorbis_info_mapping0));
93
94   d->timesubmap=_oggpack_read(opb,8);
95   if(d->timesubmap>=vi->times)goto err_out;
96
97   d->floorsubmap=malloc(sizeof(int)*vi->channels);
98   if(_oggpack_read(opb,1)){
99     /* channel submap */
100     for(i=0;i<vi->channels;i++)
101       d->floorsubmap[i]=_oggpack_read(opb,8);
102   }else{
103     int temp=_oggpack_read(opb,8);
104     for(i=0;i<vi->channels;i++)
105       d->floorsubmap[i]=temp;
106   }
107
108   d->residuesubmap=malloc(sizeof(int)*vi->channels);
109   if(_oggpack_read(opb,1)){
110     /* channel submap */
111     for(i=0;i<vi->channels;i++)
112       d->residuesubmap[i]=_oggpack_read(opb,8);
113   }else{
114     int temp=_oggpack_read(opb,8);
115     for(i=0;i<vi->channels;i++)
116       d->residuesubmap[i]=temp;
117   }
118
119   for(i=0;i<vi->channels;i++){
120     if(d->floorsubmap[i]<0 || d->floorsubmap[i]>=vi->floors)goto err_out;
121     if(d->residuesubmap[i]<0 || d->residuesubmap[i]>=vi->residuess)
122       goto err_out;
123   }
124
125   return d;
126
127  err_out:
128   _vorbis_map0_free(d);
129   return(NULL);
130 }
131
132 #include <stdio.h>
133 #include "os.h"
134 #include "lpc.h"
135 #include "lsp.h"
136 #include "envelope.h"
137 #include "mdct.h"
138 #include "psy.h"
139 #include "bitwise.h"
140 #include "spectrum.h"
141
142 /* no time mapping implementation for now */
143 int *_vorbis_map0_analysis(vorbis_block *vb,vorbis_info_map *i,
144                            ogg_packet *opb){
145   int i;
146   vorbis_dsp_state     *vd=vb->vd;
147   double               *window=vd->window[vb->W][vb->lW][vb->nW];
148   oggpack_buffer       *opb=&vb->opb;
149   vorbis_info_mapping0 *vi=i;
150   int                   n=vb->pcmend;
151
152   /* time domain pre-window: NONE IMPLEMENTED */
153
154   /* window the PCM data: takes PCM vector, vb; modifies PCM vector */
155
156   /* time-domain post-window: NONE IMPLEMENTED */
157
158   /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
159
160   /* perform psychoacoustics; takes PCM vector; returns transform floor 
161      and resolution floor, modifies PCM vector */
162
163   /* perform floor encoding; takes transform floor, returns decoded floor*/
164
165   /* perform residue encoding with residue mapping */
166
167
168
169   psy_lookup       *vp=&vb->vd->vp[vb->W];
170   lpc_lookup       *vl=&vb->vd->vl[vb->W];
171
172
173   vb->gluebits=0;
174   vb->time_envelope_bits=0;
175   vb->spectral_envelope_bits=0;
176   vb->spectral_residue_bits=0;
177
178   /*lpc_lookup       *vbal=&vb->vd->vbal[vb->W];
179     double balance_v[vbal->m];
180     double balance_amp;*/
181
182   /* first things first.  Make sure encode is ready*/
183   _oggpack_reset(opb);
184   /* Encode the packet type */
185   _oggpack_write(opb,0,1);
186
187   /* Encode the block size */
188   _oggpack_write(opb,vb->W,1);
189   if(vb->W){
190     _oggpack_write(opb,vb->lW,1);
191     _oggpack_write(opb,vb->nW,1);
192   }
193
194   /* No envelope encoding yet */
195   _oggpack_write(opb,0,1);
196   
197   /* time domain PCM -> MDCT domain */
198   for(i=0;i<vi->channels;i++)
199     mdct_forward(&vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
200
201   /* no balance yet */
202     
203   /* extract the spectral envelope and residue */
204   /* just do by channel.  No coupling yet */
205   {
206     for(i=0;i<vi->channels;i++){
207       static int frameno=0;
208       int j;
209       double *floor=alloca(n/2*sizeof(double));
210       double *curve=alloca(n/2*sizeof(double));
211       double *lpc=vb->lpc[i];
212       double *lsp=vb->lsp[i];
213
214       memset(floor,0,sizeof(double)*n/2);
215       
216 #ifdef ANALYSIS
217       {
218         FILE *out;
219         char buffer[80];
220         
221         sprintf(buffer,"Aspectrum%d.m",vb->sequence);
222         out=fopen(buffer,"w+");
223         for(j=0;j<n/2;j++)
224           fprintf(out,"%g\n",vb->pcm[i][j]);
225         fclose(out);
226
227       }
228 #endif
229
230       _vp_mask_floor(vp,vb->pcm[i],floor);
231
232 #ifdef ANALYSIS
233       {
234         FILE *out;
235         char buffer[80];
236         
237         sprintf(buffer,"Apremask%d.m",vb->sequence);
238         out=fopen(buffer,"w+");
239         for(j=0;j<n/2;j++)
240           fprintf(out,"%g\n",floor[j]);
241         fclose(out);
242       }
243 #endif
244
245       /* Convert our floor to a set of lpc coefficients */
246       vb->amp[i]=sqrt(vorbis_curve_to_lpc(floor,lpc,vl));
247
248       /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
249       vorbis_lpc_to_lsp(lpc,lsp,vl->m);
250
251       /* code the spectral envelope; mutates the lsp coeffs to reflect
252          what was actually encoded */
253       _vs_spectrum_encode(vb,vb->amp[i],lsp);
254
255       /* Generate residue from the decoded envelope, which will be
256          slightly different to the pre-encoding floor due to
257          quantization.  Slow, yes, but perhaps more accurate */
258
259       vorbis_lsp_to_lpc(lsp,lpc,vl->m); 
260       vorbis_lpc_to_curve(curve,lpc,vb->amp[i],vl);
261
262       /* this may do various interesting massaging too...*/
263       if(vb->amp[i])_vs_residue_train(vb,vb->pcm[i],curve,n/2);
264       _vs_residue_quantize(vb->pcm[i],curve,vi,n/2);
265
266 #ifdef ANALYSIS
267       {
268         FILE *out;
269         char buffer[80];
270         
271         sprintf(buffer,"Alpc%d.m",vb->sequence);
272         out=fopen(buffer,"w+");
273         for(j=0;j<vl->m;j++)
274           fprintf(out,"%g\n",lpc[j]);
275         fclose(out);
276
277         sprintf(buffer,"Alsp%d.m",vb->sequence);
278         out=fopen(buffer,"w+");
279         for(j=0;j<vl->m;j++)
280           fprintf(out,"%g\n",lsp[j]);
281         fclose(out);
282
283         sprintf(buffer,"Amask%d.m",vb->sequence);
284         out=fopen(buffer,"w+");
285         for(j=0;j<n/2;j++)
286           fprintf(out,"%g\n",curve[j]);
287         fclose(out);
288
289         sprintf(buffer,"Ares%d.m",vb->sequence);
290         out=fopen(buffer,"w+");
291         for(j=0;j<n/2;j++)
292           fprintf(out,"%g\n",vb->pcm[i][j]);
293         fclose(out);
294       }
295 #endif
296
297       /* encode the residue */
298       _vs_residue_encode(vb,vb->pcm[i]);
299
300     }
301   }
302
303   /* set up the packet wrapper */
304
305   op->packet=opb->buffer;
306   op->bytes=_oggpack_bytes(opb);
307   op->b_o_s=0;
308   op->e_o_s=vb->eofflag;
309   op->frameno=vb->frameno;
310   op->packetno=vb->sequence; /* for sake of completeness */
311
312   return(0);
313 }
314
315
316
317
318 /* commented out, relocated balance stuff */
319   /*{
320     double *C=vb->pcm[0];
321     double *D=vb->pcm[1];
322     
323     balance_amp=_vp_balance_compute(D,C,balance_v,vbal);
324     
325     {
326       FILE *out;
327       char buffer[80];
328       
329       sprintf(buffer,"com%d.m",frameno);
330       out=fopen(buffer,"w+");
331       for(i=0;i<n/2;i++){
332         fprintf(out," 0. 0.\n");
333         fprintf(out,"%g %g\n",C[i],D[i]);
334         fprintf(out,"\n");
335       }
336       fclose(out);
337       
338       sprintf(buffer,"L%d.m",frameno);
339       out=fopen(buffer,"w+");
340       for(i=0;i<n/2;i++){
341         fprintf(out,"%g\n",C[i]);
342       }
343       fclose(out);
344       sprintf(buffer,"R%d.m",frameno);
345       out=fopen(buffer,"w+");
346       for(i=0;i<n/2;i++){
347         fprintf(out,"%g\n",D[i]);
348       }
349       fclose(out);
350       
351     }
352     
353     _vp_balance_apply(D,C,balance_v,balance_amp,vbal,1);
354       
355     {
356       FILE *out;
357       char buffer[80];
358       
359       sprintf(buffer,"bal%d.m",frameno);
360       out=fopen(buffer,"w+");
361       for(i=0;i<n/2;i++){
362         fprintf(out," 0. 0.\n");
363         fprintf(out,"%g %g\n",C[i],D[i]);
364         fprintf(out,"\n");
365       }
366       fclose(out);
367       sprintf(buffer,"C%d.m",frameno);
368       out=fopen(buffer,"w+");
369       for(i=0;i<n/2;i++){
370         fprintf(out,"%g\n",C[i]);
371       }
372       fclose(out);
373       sprintf(buffer,"D%d.m",frameno);
374       out=fopen(buffer,"w+");
375       for(i=0;i<n/2;i++){
376         fprintf(out,"%g\n",D[i]);
377       }
378       fclose(out);
379       
380     }
381   }*/
382
383
384 int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
385   double           *window;
386   vorbis_dsp_state *vd=vb->vd;
387   vorbis_info      *vi=vd->vi;
388   oggpack_buffer   *opb=&vb->opb;
389   lpc_lookup       *vl;
390   int              spectral_order;
391   int              n,i;
392
393   /* first things first.  Make sure decode is ready */
394   _oggpack_readinit(opb,op->packet,op->bytes);
395
396   /* Check the packet type */
397   if(_oggpack_read(opb,1)!=0){
398     /* Oops.  This is not an audio data packet */
399     return(-1);
400   }
401
402   /* Decode the block size */
403   vb->W=_oggpack_read(opb,1);
404   if(vb->W){
405     vb->lW=_oggpack_read(opb,1);
406     vb->nW=_oggpack_read(opb,1);
407   }else{
408     vb->lW=0;
409     vb->nW=0;
410   }
411
412   window=vb->vd->window[vb->W][vb->lW][vb->nW];
413
414   /* other random setup */
415   vb->frameno=op->frameno;
416   vb->sequence=op->packetno-3; /* first block is third packet */
417
418   vb->eofflag=op->e_o_s;
419   vl=&vb->vd->vl[vb->W];
420   spectral_order=vi->floororder[vb->W];
421
422   /* The storage vectors are large enough; set the use markers */
423   n=vb->pcmend=vi->blocksize[vb->W];
424   
425   /* No envelope encoding yet */
426   _oggpack_read(opb,0,1);
427
428   for(i=0;i<vi->channels;i++){
429     double *lpc=vb->lpc[i];
430     double *lsp=vb->lsp[i];
431     
432     /* recover the spectral envelope */
433     if(_vs_spectrum_decode(vb,&vb->amp[i],lsp)<0)return(-1);
434     
435     /* recover the spectral residue */  
436     if(_vs_residue_decode(vb,vb->pcm[i])<0)return(-1);
437
438 #ifdef ANALYSIS
439     {
440       int j;
441       FILE *out;
442       char buffer[80];
443       
444       sprintf(buffer,"Sres%d.m",vb->sequence);
445       out=fopen(buffer,"w+");
446       for(j=0;j<n/2;j++)
447         fprintf(out,"%g\n",vb->pcm[i][j]);
448       fclose(out);
449     }
450 #endif
451
452     /* LSP->LPC */
453     vorbis_lsp_to_lpc(lsp,lpc,vl->m); 
454
455     /* apply envelope to residue */
456     
457 #ifdef ANALYSIS
458     {
459       int j;
460       FILE *out;
461       char buffer[80];
462       double curve[n/2];
463       vorbis_lpc_to_curve(curve,lpc,vb->amp[i],vl);
464       
465       
466       sprintf(buffer,"Smask%d.m",vb->sequence);
467       out=fopen(buffer,"w+");
468       for(j=0;j<n/2;j++)
469         fprintf(out,"%g\n",curve[j]);
470       fclose(out);
471
472       sprintf(buffer,"Slsp%d.m",vb->sequence);
473       out=fopen(buffer,"w+");
474       for(j=0;j<vl->m;j++)
475         fprintf(out,"%g\n",lsp[j]);
476       fclose(out);
477
478       sprintf(buffer,"Slpc%d.m",vb->sequence);
479       out=fopen(buffer,"w+");
480       for(j=0;j<vl->m;j++)
481         fprintf(out,"%g\n",lpc[j]);
482       fclose(out);
483     }
484 #endif
485
486     vorbis_lpc_apply(vb->pcm[i],lpc,vb->amp[i],vl);
487
488 #ifdef ANALYSIS
489     {
490       int j;
491       FILE *out;
492       char buffer[80];
493       
494       sprintf(buffer,"Sspectrum%d.m",vb->sequence);
495       out=fopen(buffer,"w+");
496       for(j=0;j<n/2;j++)
497         fprintf(out,"%g\n",vb->pcm[i][j]);
498       fclose(out);
499     }
500 #endif
501       
502
503     /* MDCT->time */
504     mdct_backward(&vb->vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
505     
506   }
507   return(0);
508 }
509
510