Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/libvorbis/synthesis.c
9903 views
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
}
180
181