137fe158a8611dd11ec0253ab1552399b780988dcGloria Wang/************************************************************************ 22da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * Copyright (C) 2002-2009, Xiph.org Foundation 32da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd 437fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * All rights reserved. 537fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * 637fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * Redistribution and use in source and binary forms, with or without 72da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * modification, are permitted provided that the following conditions 82da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * are met: 937fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * 1037fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * * Redistributions of source code must retain the above copyright 1137fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * notice, this list of conditions and the following disclaimer. 1237fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * * Redistributions in binary form must reproduce the above 1337fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * copyright notice, this list of conditions and the following disclaimer 1437fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * in the documentation and/or other materials provided with the 1537fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * distribution. 162da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * * Neither the names of the Xiph.org Foundation nor Pinknoise 172da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * Productions Ltd nor the names of its contributors may be used to 182da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * endorse or promote products derived from this software without 192da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * specific prior written permission. 2037fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * 2137fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2237fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2337fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2437fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2537fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2637fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2737fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2837fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2937fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3037fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3137fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3237fe158a8611dd11ec0253ab1552399b780988dcGloria Wang ************************************************************************ 337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang function: PCM data vector blocking, windowing and dis/reassembly 357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3637fe158a8611dd11ec0253ab1552399b780988dcGloria Wang ************************************************************************/ 377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <stdlib.h> 397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "ogg.h" 407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "mdct.h" 417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "ivorbiscodec.h" 427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "codec_internal.h" 437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "misc.h" 447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "window_lookup.h" 457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint vorbis_dsp_restart(vorbis_dsp_state *v){ 477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(!v)return -1; 487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang { 497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vorbis_info *vi=v->vi; 507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang codec_setup_info *ci; 517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(!vi)return -1; 537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci=vi->codec_setup; 547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(!ci)return -1; 557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->out_end=-1; 577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->out_begin=-1; 587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->granulepos=-1; 607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->sequence=-1; 617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->sample_count=-1; 627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return 0; 647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint vorbis_dsp_init(vorbis_dsp_state *v,vorbis_info *vi){ 677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i; 687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; 707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->vi=vi; 727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->work=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->work)); 747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->mdctright=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->mdctright)); 757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<vi->channels;i++){ 767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->work[i]=(ogg_int32_t *)_ogg_calloc(1,(ci->blocksizes[1]>>1)* 777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang sizeof(*v->work[i])); 787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->mdctright[i]=(ogg_int32_t *)_ogg_calloc(1,(ci->blocksizes[1]>>2)* 797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang sizeof(*v->mdctright[i])); 807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->lW=0; /* previous window size */ 837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->W=0; /* current window size */ 847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vorbis_dsp_restart(v); 867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return 0; 877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangvorbis_dsp_state *vorbis_dsp_create(vorbis_info *vi){ 907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vorbis_dsp_state *v=_ogg_calloc(1,sizeof(*v)); 917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vorbis_dsp_init(v,vi); 927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return v; 937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangvoid vorbis_dsp_clear(vorbis_dsp_state *v){ 967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i; 977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(v){ 987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vorbis_info *vi=v->vi; 997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(v->work){ 1017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<vi->channels;i++) 1027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(v->work[i])_ogg_free(v->work[i]); 1037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _ogg_free(v->work); 1047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(v->mdctright){ 1067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<vi->channels;i++) 1077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(v->mdctright[i])_ogg_free(v->mdctright[i]); 1087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _ogg_free(v->mdctright); 1097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 1127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangvoid vorbis_dsp_destroy(vorbis_dsp_state *v){ 1147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vorbis_dsp_clear(v); 1157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _ogg_free(v); 1167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 1177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic LOOKUP_T *_vorbis_window(int left){ 1197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang switch(left){ 1207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 32: 1217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return vwin64; 1227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 64: 1237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return vwin128; 1247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 128: 1257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return vwin256; 1267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 256: 1277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return vwin512; 1287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 512: 1297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return vwin1024; 1307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 1024: 1317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return vwin2048; 1327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 2048: 1337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return vwin4096; 1347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifndef LIMIT_TO_64kHz 1357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 4096: 1367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return vwin8192; 1377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif 1387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang default: 1397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(0); 1407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 1427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* pcm==0 indicates we just want the pending samples, no more */ 1447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint vorbis_dsp_pcmout(vorbis_dsp_state *v,ogg_int16_t *pcm,int samples){ 1457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vorbis_info *vi=v->vi; 1467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; 1477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(v->out_begin>-1 && v->out_begin<v->out_end){ 1487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int n=v->out_end-v->out_begin; 1497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(pcm){ 1507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i; 1517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(n>samples)n=samples; 1527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<vi->channels;i++) 1537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang mdct_unroll_lap(ci->blocksizes[0],ci->blocksizes[1], 1547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->lW,v->W,v->work[i],v->mdctright[i], 1557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _vorbis_window(ci->blocksizes[0]>>1), 1567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _vorbis_window(ci->blocksizes[1]>>1), 1577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang pcm+i,vi->channels, 1587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->out_begin,v->out_begin+n); 1597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(n); 1617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(0); 1637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 1647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint vorbis_dsp_read(vorbis_dsp_state *v,int s){ 1667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(s && v->out_begin+s>v->out_end)return(OV_EINVAL); 1677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v->out_begin+=s; 1687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(0); 1697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 1707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){ 1727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; 1737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_buffer opb; 1747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int mode; 1757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int modebits=0; 1767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int v=ci->modes; 1777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_readinit(&opb,op->packet); 1797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* Check the packet type */ 1817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_read(&opb,1)!=0){ 1827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* Oops. This is not an audio data packet */ 1837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(OV_ENOTAUDIO); 1847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang while(v>1){ 1877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang modebits++; 1887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v>>=1; 1897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* read our mode and pre/post windowsize */ 1927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang mode=oggpack_read(&opb,modebits); 1937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(mode==-1)return(OV_EBADPACKET); 1947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(ci->blocksizes[ci->mode_param[mode].blockflag]); 1957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 1967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic int ilog(ogg_uint32_t v){ 1997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int ret=0; 2007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(v)--v; 2017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang while(v){ 2027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ret++; 2037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v>>=1; 2047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(ret); 2067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 2077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint vorbis_dsp_synthesis(vorbis_dsp_state *vd,ogg_packet *op,int decodep){ 2097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vorbis_info *vi=vd->vi; 2107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; 2117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int mode,i; 2127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_readinit(&vd->opb,op->packet); 2147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* Check the packet type */ 2167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_read(&vd->opb,1)!=0){ 2177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* Oops. This is not an audio data packet */ 2187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return OV_ENOTAUDIO ; 2197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* read our mode and pre/post windowsize */ 2227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang mode=oggpack_read(&vd->opb,ilog(ci->modes)); 2237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(mode==-1 || mode>=ci->modes) return OV_EBADPACKET; 2247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* shift information we still need from last window */ 2267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->lW=vd->W; 2277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->W=ci->mode_param[mode].blockflag; 2287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<vi->channels;i++) 2297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang mdct_shift_right(ci->blocksizes[vd->lW],vd->work[i],vd->mdctright[i]); 2307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vd->W){ 2327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int temp; 2337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_read(&vd->opb,1); 2347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang temp=oggpack_read(&vd->opb,1); 2357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(temp==-1) return OV_EBADPACKET; 2367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* packet decode and portions of synthesis that rely on only this block */ 2397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(decodep){ 2407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang mapping_inverse(vd,ci->map_param+ci->mode_param[mode].mapping); 2417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vd->out_begin==-1){ 2437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->out_begin=0; 2447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->out_end=0; 2457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 2467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->out_begin=0; 2477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->out_end=ci->blocksizes[vd->lW]/4+ci->blocksizes[vd->W]/4; 2487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* track the frame number... This is for convenience, but also 2527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang making sure our last packet doesn't end with added padding. 2537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang This is not foolproof! It will be confused if we begin 2557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang decoding at the last page after a seek or hole. In that case, 2567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang we don't have a starting point to judge where the last frame 2577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang is. For this reason, vorbisfile will always try to make sure 2587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang it reads the last two marked pages in proper sequence */ 2597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* if we're out of sequence, dump granpos tracking until we sync back up */ 2617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vd->sequence==-1 || vd->sequence+1 != op->packetno-3){ 2627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* out of sequence; lose count */ 2637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->granulepos=-1; 2647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->sample_count=-1; 2657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->sequence=op->packetno; 2687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->sequence=vd->sequence-3; 2697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vd->sample_count==-1){ 2717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->sample_count=0; 2727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 2737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->sample_count+= 2747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->blocksizes[vd->lW]/4+ci->blocksizes[vd->W]/4; 2757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vd->granulepos==-1){ 2787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(op->granulepos!=-1){ /* only set if we have a 2797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang position to set to */ 2807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->granulepos=op->granulepos; 2827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* is this a short page? */ 2847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vd->sample_count>vd->granulepos){ 2857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* corner case; if this is both the first and last audio page, 2867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang then spec says the end is cut, not beginning */ 2877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(op->e_o_s){ 2887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* trim the end */ 2897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* no preceeding granulepos; assume we started at zero (we'd 2907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang have to in a short single-page stream) */ 2917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* granulepos could be -1 due to a seek, but that would result 2927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang in a long coun t, not short count */ 2937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->out_end-=(int)(vd->sample_count-vd->granulepos); 2957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 2967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* trim the beginning */ 2977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->out_begin+=(int)(vd->sample_count-vd->granulepos); 2987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vd->out_begin>vd->out_end) 2997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->out_begin=vd->out_end; 3007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 3067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->granulepos+= 3077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->blocksizes[vd->lW]/4+ci->blocksizes[vd->W]/4; 3087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(op->granulepos!=-1 && vd->granulepos!=op->granulepos){ 3097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vd->granulepos>op->granulepos){ 3117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long extra=(long)(vd->granulepos-op->granulepos); 3127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(extra) 3147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(op->e_o_s){ 3157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* partial last frame. Strip the extra samples off */ 3167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->out_end-=extra; 3177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } /* else {Shouldn't happen *unless* the bitstream is out of 3187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang spec. Either way, believe the bitstream } */ 3197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } /* else {Shouldn't happen *unless* the bitstream is out of 3207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang spec. Either way, believe the bitstream } */ 3217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vd->granulepos=op->granulepos; 3227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(0); 3267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 327