/********************************************************************
* *
- * 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. *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
- * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
- * http://www.xiph.org/ *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: single-block PCM synthesis
- last mod: $Id: synthesis.c,v 1.12 2000/01/12 11:34:41 xiphmont Exp $
********************************************************************/
#include <stdio.h>
+#include <ogg/ogg.h>
#include "vorbis/codec.h"
-
-#include "envelope.h"
-#include "mdct.h"
-#include "lpc.h"
-#include "lsp.h"
-#include "bitwise.h"
-#include "spectrum.h"
+#include "codec_internal.h"
+#include "registry.h"
+#include "misc.h"
+#include "os.h"
int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
- double *window;
- vorbis_dsp_state *vd=vb->vd;
- vorbis_info *vi=vd->vi;
- oggpack_buffer *opb=&vb->opb;
- lpc_lookup *vl;
- int spectral_order;
- int n,i;
+ vorbis_dsp_state *vd= vb ? vb->vd : 0;
+ private_state *b= vd ? vd->backend_state : 0;
+ vorbis_info *vi= vd ? vd->vi : 0;
+ codec_setup_info *ci= vi ? vi->codec_setup : 0;
+ oggpack_buffer *opb=vb ? &vb->opb : 0;
+ int type,mode,i;
+
+ if (!vd || !b || !vi || !ci || !opb) {
+ return OV_EBADPACKET;
+ }
/* first things first. Make sure decode is ready */
- _oggpack_readinit(opb,op->packet,op->bytes);
+ _vorbis_block_ripcord(vb);
+ oggpack_readinit(opb,op->packet,op->bytes);
/* Check the packet type */
- if(_oggpack_read(opb,1)!=0){
+ if(oggpack_read(opb,1)!=0){
/* Oops. This is not an audio data packet */
- return(-1);
+ return(OV_ENOTAUDIO);
+ }
+
+ /* read our mode and pre/post windowsize */
+ mode=oggpack_read(opb,b->modebits);
+ if(mode==-1){
+ return(OV_EBADPACKET);
+ }
+
+ vb->mode=mode;
+ if(!ci->mode_param[mode]){
+ return(OV_EBADPACKET);
}
- /* Decode the block size */
- vb->W=_oggpack_read(opb,1);
+ vb->W=ci->mode_param[mode]->blockflag;
if(vb->W){
- vb->lW=_oggpack_read(opb,1);
- vb->nW=_oggpack_read(opb,1);
+
+ /* this doesn;t get mapped through mode selection as it's used
+ only for window selection */
+ vb->lW=oggpack_read(opb,1);
+ vb->nW=oggpack_read(opb,1);
+ if(vb->nW==-1){
+ return(OV_EBADPACKET);
+ }
}else{
vb->lW=0;
vb->nW=0;
}
- window=vb->vd->window[vb->W][vb->lW][vb->nW];
+ /* more setup */
+ vb->granulepos=op->granulepos;
+ vb->sequence=op->packetno;
+ vb->eofflag=op->e_o_s;
- /* other random setup */
- vb->frameno=op->frameno;
- vb->sequence=op->packetno-3; /* first block is third packet */
+ /* alloc pcm passback storage */
+ vb->pcmend=ci->blocksizes[vb->W];
+ vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
+ for(i=0;i<vi->channels;i++)
+ vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
- vb->eofflag=op->e_o_s;
- vl=&vb->vd->vl[vb->W];
- spectral_order=vi->floororder[vb->W];
-
- /* The storage vectors are large enough; set the use markers */
- n=vb->pcmend=vi->blocksize[vb->W];
-
- /* No envelope encoding yet */
- _oggpack_read(opb,0,1);
-
- for(i=0;i<vi->channels;i++){
- double *lpc=vb->lpc[i];
- double *lsp=vb->lsp[i];
-
- /* recover the spectral envelope */
- if(_vs_spectrum_decode(vb,&vb->amp[i],lsp)<0)return(-1);
-
- /* recover the spectral residue */
- if(_vs_residue_decode(vb,vb->pcm[i])<0)return(-1);
-
-#ifdef ANALYSIS
- {
- int j;
- FILE *out;
- char buffer[80];
-
- sprintf(buffer,"Sres%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<n/2;j++)
- fprintf(out,"%g\n",vb->pcm[i][j]);
- fclose(out);
- }
-#endif
-
- /* LSP->LPC */
- vorbis_lsp_to_lpc(lsp,lpc,vl->m);
-
- /* apply envelope to residue */
-
-#ifdef ANALYSIS
- {
- int j;
- FILE *out;
- char buffer[80];
- double curve[n/2];
- vorbis_lpc_to_curve(curve,lpc,vb->amp[i],vl);
-
-
- sprintf(buffer,"Smask%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<n/2;j++)
- fprintf(out,"%g\n",curve[j]);
- fclose(out);
-
- sprintf(buffer,"Slsp%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<vl->m;j++)
- fprintf(out,"%g\n",lsp[j]);
- fclose(out);
-
- sprintf(buffer,"Slpc%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<vl->m;j++)
- fprintf(out,"%g\n",lpc[j]);
- fclose(out);
- }
-#endif
-
- vorbis_lpc_apply(vb->pcm[i],lpc,vb->amp[i],vl);
-
-#ifdef ANALYSIS
- {
- int j;
- FILE *out;
- char buffer[80];
-
- sprintf(buffer,"Sspectrum%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<n/2;j++)
- fprintf(out,"%g\n",vb->pcm[i][j]);
- fclose(out);
- }
-#endif
-
+ /* unpack_header enforces range checking */
+ type=ci->map_type[ci->mode_param[mode]->mapping];
+
+ return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]->
+ mapping]));
+}
+
+/* used to track pcm position without actually performing decode.
+ Useful for sequential 'fast forward' */
+int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){
+ vorbis_dsp_state *vd=vb->vd;
+ private_state *b=vd->backend_state;
+ vorbis_info *vi=vd->vi;
+ codec_setup_info *ci=vi->codec_setup;
+ oggpack_buffer *opb=&vb->opb;
+ int mode;
+
+ /* first things first. Make sure decode is ready */
+ _vorbis_block_ripcord(vb);
+ oggpack_readinit(opb,op->packet,op->bytes);
+
+ /* Check the packet type */
+ if(oggpack_read(opb,1)!=0){
+ /* Oops. This is not an audio data packet */
+ return(OV_ENOTAUDIO);
+ }
+
+ /* read our mode and pre/post windowsize */
+ mode=oggpack_read(opb,b->modebits);
+ if(mode==-1)return(OV_EBADPACKET);
- /* MDCT->time */
- mdct_backward(&vb->vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
-
+ vb->mode=mode;
+ if(!ci->mode_param[mode]){
+ return(OV_EBADPACKET);
}
+
+ vb->W=ci->mode_param[mode]->blockflag;
+ if(vb->W){
+ vb->lW=oggpack_read(opb,1);
+ vb->nW=oggpack_read(opb,1);
+ if(vb->nW==-1) return(OV_EBADPACKET);
+ }else{
+ vb->lW=0;
+ vb->nW=0;
+ }
+
+ /* more setup */
+ vb->granulepos=op->granulepos;
+ vb->sequence=op->packetno;
+ vb->eofflag=op->e_o_s;
+
+ /* no pcm */
+ vb->pcmend=0;
+ vb->pcm=NULL;
+
return(0);
}
+long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
+ codec_setup_info *ci=vi->codec_setup;
+ oggpack_buffer opb;
+ int mode;
+
+ if(ci==NULL || ci->modes<=0){
+ /* codec setup not properly intialized */
+ return(OV_EFAULT);
+ }
+ oggpack_readinit(&opb,op->packet,op->bytes);
+
+ /* Check the packet type */
+ if(oggpack_read(&opb,1)!=0){
+ /* Oops. This is not an audio data packet */
+ return(OV_ENOTAUDIO);
+ }
+
+ /* read our mode and pre/post windowsize */
+ mode=oggpack_read(&opb,ov_ilog(ci->modes-1));
+ if(mode==-1 || !ci->mode_param[mode])return(OV_EBADPACKET);
+ return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
+}
+
+int vorbis_synthesis_halfrate(vorbis_info *vi,int flag){
+ /* set / clear half-sample-rate mode */
+ codec_setup_info *ci=vi->codec_setup;
+
+ /* right now, our MDCT can't handle < 64 sample windows. */
+ if(ci->blocksizes[0]<=64 && flag)return -1;
+ ci->halfrate_flag=(flag?1:0);
+ return 0;
+}
+
+int vorbis_synthesis_halfrate_p(vorbis_info *vi){
+ codec_setup_info *ci=vi->codec_setup;
+ return ci->halfrate_flag;
+}