synthesis.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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-2007 *
  9. * by the Xiph.Org Foundation http://www.xiph.org/ *
  10. * *
  11. ********************************************************************
  12. function: single-block PCM synthesis
  13. last mod: $Id$
  14. ********************************************************************/
  15. #include <stdio.h>
  16. #include <ogg/ogg.h>
  17. #include "vorbis/codec.h"
  18. #include "codec_internal.h"
  19. #include "registry.h"
  20. #include "misc.h"
  21. #include "os.h"
  22. int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
  23. vorbis_dsp_state *vd=vb->vd;
  24. private_state *b=vd->backend_state;
  25. vorbis_info *vi=vd->vi;
  26. codec_setup_info *ci=vi->codec_setup;
  27. oggpack_buffer *opb=&vb->opb;
  28. int type,mode,i;
  29. /* first things first. Make sure decode is ready */
  30. _vorbis_block_ripcord(vb);
  31. oggpack_readinit(opb,op->packet,op->bytes);
  32. /* Check the packet type */
  33. if(oggpack_read(opb,1)!=0){
  34. /* Oops. This is not an audio data packet */
  35. return(OV_ENOTAUDIO);
  36. }
  37. /* read our mode and pre/post windowsize */
  38. mode=oggpack_read(opb,b->modebits);
  39. if(mode==-1)return(OV_EBADPACKET);
  40. vb->mode=mode;
  41. vb->W=ci->mode_param[mode]->blockflag;
  42. if(vb->W){
  43. /* this doesn;t get mapped through mode selection as it's used
  44. only for window selection */
  45. vb->lW=oggpack_read(opb,1);
  46. vb->nW=oggpack_read(opb,1);
  47. if(vb->nW==-1) return(OV_EBADPACKET);
  48. }else{
  49. vb->lW=0;
  50. vb->nW=0;
  51. }
  52. /* more setup */
  53. vb->granulepos=op->granulepos;
  54. vb->sequence=op->packetno;
  55. vb->eofflag=op->e_o_s;
  56. /* alloc pcm passback storage */
  57. vb->pcmend=ci->blocksizes[vb->W];
  58. vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
  59. for(i=0;i<vi->channels;i++)
  60. vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
  61. /* unpack_header enforces range checking */
  62. type=ci->map_type[ci->mode_param[mode]->mapping];
  63. return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]->
  64. mapping]));
  65. }
  66. /* used to track pcm position without actually performing decode.
  67. Useful for sequential 'fast forward' */
  68. int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){
  69. vorbis_dsp_state *vd=vb->vd;
  70. private_state *b=vd->backend_state;
  71. vorbis_info *vi=vd->vi;
  72. codec_setup_info *ci=vi->codec_setup;
  73. oggpack_buffer *opb=&vb->opb;
  74. int mode;
  75. /* first things first. Make sure decode is ready */
  76. _vorbis_block_ripcord(vb);
  77. oggpack_readinit(opb,op->packet,op->bytes);
  78. /* Check the packet type */
  79. if(oggpack_read(opb,1)!=0){
  80. /* Oops. This is not an audio data packet */
  81. return(OV_ENOTAUDIO);
  82. }
  83. /* read our mode and pre/post windowsize */
  84. mode=oggpack_read(opb,b->modebits);
  85. if(mode==-1)return(OV_EBADPACKET);
  86. vb->mode=mode;
  87. vb->W=ci->mode_param[mode]->blockflag;
  88. if(vb->W){
  89. vb->lW=oggpack_read(opb,1);
  90. vb->nW=oggpack_read(opb,1);
  91. if(vb->nW==-1) return(OV_EBADPACKET);
  92. }else{
  93. vb->lW=0;
  94. vb->nW=0;
  95. }
  96. /* more setup */
  97. vb->granulepos=op->granulepos;
  98. vb->sequence=op->packetno;
  99. vb->eofflag=op->e_o_s;
  100. /* no pcm */
  101. vb->pcmend=0;
  102. vb->pcm=NULL;
  103. return(0);
  104. }
  105. long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
  106. codec_setup_info *ci=vi->codec_setup;
  107. oggpack_buffer opb;
  108. int mode;
  109. oggpack_readinit(&opb,op->packet,op->bytes);
  110. /* Check the packet type */
  111. if(oggpack_read(&opb,1)!=0){
  112. /* Oops. This is not an audio data packet */
  113. return(OV_ENOTAUDIO);
  114. }
  115. {
  116. int modebits=0;
  117. int v=ci->modes;
  118. while(v>1){
  119. modebits++;
  120. v>>=1;
  121. }
  122. /* read our mode and pre/post windowsize */
  123. mode=oggpack_read(&opb,modebits);
  124. }
  125. if(mode==-1)return(OV_EBADPACKET);
  126. return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
  127. }
  128. int vorbis_synthesis_halfrate(vorbis_info *vi,int flag){
  129. /* set / clear half-sample-rate mode */
  130. codec_setup_info *ci=vi->codec_setup;
  131. /* right now, our MDCT can't handle < 64 sample windows. */
  132. if(ci->blocksizes[0]<=64 && flag)return -1;
  133. ci->halfrate_flag=(flag?1:0);
  134. return 0;
  135. }
  136. int vorbis_synthesis_halfrate_p(vorbis_info *vi){
  137. codec_setup_info *ci=vi->codec_setup;
  138. return ci->halfrate_flag;
  139. }