1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
6 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
7 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
12 ********************************************************************
14 function: single-block PCM synthesis
17 ********************************************************************/
21 #include "ivorbiscodec.h"
22 #include "codec_internal.h"
28 static ogg_int32_t
*ipcm_vect
[CHANNELS
] IBSS_ATTR
;
30 static inline int _vorbis_synthesis1(vorbis_block
*vb
,ogg_packet
*op
,int decodep
){
31 vorbis_dsp_state
*vd
= vb
? vb
->vd
: 0;
32 private_state
*b
= vd
? (private_state
*)vd
->backend_state
: 0;
33 vorbis_info
*vi
= vd
? vd
->vi
: 0;
34 codec_setup_info
*ci
= vi
? (codec_setup_info
*)vi
->codec_setup
: 0;
35 oggpack_buffer
*opb
=vb
? &vb
->opb
: 0;
38 if (!vd
|| !b
|| !vi
|| !ci
|| !opb
) {
42 /* first things first. Make sure decode is ready */
43 _vorbis_block_ripcord(vb
);
44 oggpack_readinit(opb
,op
->packet
,op
->bytes
);
46 /* Check the packet type */
47 if(oggpack_read(opb
,1)!=0){
48 /* Oops. This is not an audio data packet */
52 /* read our mode and pre/post windowsize */
53 mode
=oggpack_read(opb
,b
->modebits
);
54 if(mode
==-1)return(OV_EBADPACKET
);
57 if(!ci
->mode_param
[mode
]){
58 return(OV_EBADPACKET
);
61 vb
->W
=ci
->mode_param
[mode
]->blockflag
;
63 vb
->lW
=oggpack_read(opb
,1);
64 vb
->nW
=oggpack_read(opb
,1);
65 if(vb
->nW
==-1) return(OV_EBADPACKET
);
72 vb
->granulepos
=op
->granulepos
;
73 vb
->sequence
=op
->packetno
-3; /* first block is third packet */
74 vb
->eofflag
=op
->e_o_s
;
76 if(decodep
&& vi
->channels
<=CHANNELS
)
80 /* set pcm end point */
81 vb
->pcmend
=ci
->blocksizes
[vb
->W
];
82 /* use statically allocated buffer */
83 if(vd
->reset_pcmb
|| vb
->pcm
[0]==NULL
)
85 /* one-time initialisation at codec start
86 NOT for every block synthesis start
87 allows us to flip between buffers once initialised
88 by simply flipping pointers */
89 for(i
=0; i
<vi
->channels
; i
++)
90 vb
->pcm
[i
] = &vd
->first_pcm
[i
*ci
->blocksizes
[1]];
93 vd
->reset_pcmb
= false;
95 /* unpack_header enforces range checking */
96 type
=ci
->map_type
[ci
->mode_param
[mode
]->mapping
];
97 return(_mapping_P
[type
]->inverse(vb
,b
->mode
[mode
]));
107 int vorbis_synthesis(vorbis_block
*vb
,ogg_packet
*op
)
108 ICODE_ATTR_TREMOR_NOT_MDCT
;
109 int vorbis_synthesis(vorbis_block
*vb
,ogg_packet
*op
){
110 return _vorbis_synthesis1(vb
,op
,1);
113 /* used to track pcm position without actually performing decode.
114 Useful for sequential 'fast forward' */
115 int vorbis_synthesis_trackonly(vorbis_block
*vb
,ogg_packet
*op
){
116 return _vorbis_synthesis1(vb
,op
,0);
119 long vorbis_packet_blocksize(vorbis_info
*vi
,ogg_packet
*op
){
120 codec_setup_info
*ci
=(codec_setup_info
*)vi
->codec_setup
;
124 oggpack_readinit(&opb
,op
->packet
,op
->bytes
);
126 /* Check the packet type */
127 if(oggpack_read(&opb
,1)!=0){
128 /* Oops. This is not an audio data packet */
129 return(OV_ENOTAUDIO
);
140 /* read our mode and pre/post windowsize */
141 mode
=oggpack_read(&opb
,modebits
);
143 if(mode
==-1)return(OV_EBADPACKET
);
144 return(ci
->blocksizes
[ci
->mode_param
[mode
]->blockflag
]);