]> git.tdb.fi Git - ext/vorbisfile.git/blob - lib/synthesis.c
Add headers to the library component so dependencies work correctly
[ext/vorbisfile.git] / lib / synthesis.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7  *                                                                  *
8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015             *
9  * by the Xiph.Org Foundation https://xiph.org/                     *
10  *                                                                  *
11  ********************************************************************
12
13  function: single-block PCM synthesis
14
15  ********************************************************************/
16
17 #include <stdio.h>
18 #include <ogg/ogg.h>
19 #include "vorbis/codec.h"
20 #include "codec_internal.h"
21 #include "registry.h"
22 #include "misc.h"
23 #include "os.h"
24
25 int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
26   vorbis_dsp_state     *vd= vb ? vb->vd : 0;
27   private_state        *b= vd ? vd->backend_state : 0;
28   vorbis_info          *vi= vd ? vd->vi : 0;
29   codec_setup_info     *ci= vi ? vi->codec_setup : 0;
30   oggpack_buffer       *opb=vb ? &vb->opb : 0;
31   int                   type,mode,i;
32
33   if (!vd || !b || !vi || !ci || !opb) {
34     return OV_EBADPACKET;
35   }
36
37   /* first things first.  Make sure decode is ready */
38   _vorbis_block_ripcord(vb);
39   oggpack_readinit(opb,op->packet,op->bytes);
40
41   /* Check the packet type */
42   if(oggpack_read(opb,1)!=0){
43     /* Oops.  This is not an audio data packet */
44     return(OV_ENOTAUDIO);
45   }
46
47   /* read our mode and pre/post windowsize */
48   mode=oggpack_read(opb,b->modebits);
49   if(mode==-1){
50     return(OV_EBADPACKET);
51   }
52
53   vb->mode=mode;
54   if(!ci->mode_param[mode]){
55     return(OV_EBADPACKET);
56   }
57
58   vb->W=ci->mode_param[mode]->blockflag;
59   if(vb->W){
60
61     /* this doesn;t get mapped through mode selection as it's used
62        only for window selection */
63     vb->lW=oggpack_read(opb,1);
64     vb->nW=oggpack_read(opb,1);
65     if(vb->nW==-1){
66       return(OV_EBADPACKET);
67     }
68   }else{
69     vb->lW=0;
70     vb->nW=0;
71   }
72
73   /* more setup */
74   vb->granulepos=op->granulepos;
75   vb->sequence=op->packetno;
76   vb->eofflag=op->e_o_s;
77
78   /* alloc pcm passback storage */
79   vb->pcmend=ci->blocksizes[vb->W];
80   vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
81   for(i=0;i<vi->channels;i++)
82     vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
83
84   /* unpack_header enforces range checking */
85   type=ci->map_type[ci->mode_param[mode]->mapping];
86
87   return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]->
88                                                    mapping]));
89 }
90
91 /* used to track pcm position without actually performing decode.
92    Useful for sequential 'fast forward' */
93 int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){
94   vorbis_dsp_state     *vd=vb->vd;
95   private_state        *b=vd->backend_state;
96   vorbis_info          *vi=vd->vi;
97   codec_setup_info     *ci=vi->codec_setup;
98   oggpack_buffer       *opb=&vb->opb;
99   int                   mode;
100
101   /* first things first.  Make sure decode is ready */
102   _vorbis_block_ripcord(vb);
103   oggpack_readinit(opb,op->packet,op->bytes);
104
105   /* Check the packet type */
106   if(oggpack_read(opb,1)!=0){
107     /* Oops.  This is not an audio data packet */
108     return(OV_ENOTAUDIO);
109   }
110
111   /* read our mode and pre/post windowsize */
112   mode=oggpack_read(opb,b->modebits);
113   if(mode==-1)return(OV_EBADPACKET);
114
115   vb->mode=mode;
116   if(!ci->mode_param[mode]){
117     return(OV_EBADPACKET);
118   }
119
120   vb->W=ci->mode_param[mode]->blockflag;
121   if(vb->W){
122     vb->lW=oggpack_read(opb,1);
123     vb->nW=oggpack_read(opb,1);
124     if(vb->nW==-1)   return(OV_EBADPACKET);
125   }else{
126     vb->lW=0;
127     vb->nW=0;
128   }
129
130   /* more setup */
131   vb->granulepos=op->granulepos;
132   vb->sequence=op->packetno;
133   vb->eofflag=op->e_o_s;
134
135   /* no pcm */
136   vb->pcmend=0;
137   vb->pcm=NULL;
138
139   return(0);
140 }
141
142 long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
143   codec_setup_info     *ci=vi->codec_setup;
144   oggpack_buffer       opb;
145   int                  mode;
146
147   if(ci==NULL || ci->modes<=0){
148     /* codec setup not properly intialized */
149     return(OV_EFAULT);
150   }
151
152   oggpack_readinit(&opb,op->packet,op->bytes);
153
154   /* Check the packet type */
155   if(oggpack_read(&opb,1)!=0){
156     /* Oops.  This is not an audio data packet */
157     return(OV_ENOTAUDIO);
158   }
159
160   /* read our mode and pre/post windowsize */
161   mode=oggpack_read(&opb,ov_ilog(ci->modes-1));
162   if(mode==-1 || !ci->mode_param[mode])return(OV_EBADPACKET);
163   return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
164 }
165
166 int vorbis_synthesis_halfrate(vorbis_info *vi,int flag){
167   /* set / clear half-sample-rate mode */
168   codec_setup_info     *ci=vi->codec_setup;
169
170   /* right now, our MDCT can't handle < 64 sample windows. */
171   if(ci->blocksizes[0]<=64 && flag)return -1;
172   ci->halfrate_flag=(flag?1:0);
173   return 0;
174 }
175
176 int vorbis_synthesis_halfrate_p(vorbis_info *vi){
177   codec_setup_info     *ci=vi->codec_setup;
178   return ci->halfrate_flag;
179 }