[xiph-cvs] cvs commit: vorbis/lib block.c codec_internal.h mapping0.c synthesis.c vorbisfile.c window.c window.h
Monty
xiphmont at xiph.org
Sun Aug 17 22:34:02 PDT 2003
xiphmont 03/08/18 01:34:02
Modified: include/vorbis codec.h vorbisfile.h
lib block.c codec_internal.h mapping0.c synthesis.c
vorbisfile.c window.c window.h
Log:
Vorbisfile API addition for game and mod coders;
Do a 'free' sample rate conversion from source rate to half source
rate by calling ov_halfrate() after ov_open(); Although this is solid
for immediately desired usage, I want to clean it up a bit before
advertising it's existence, so no doc addition yet.
Does not break binary API.
Monty
Revision Changes Path
1.44 +4 -1 vorbis/include/vorbis/codec.h
Index: codec.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/include/vorbis/codec.h,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- codec.h 4 Mar 2003 21:23:37 -0000 1.43
+++ codec.h 18 Aug 2003 05:34:01 -0000 1.44
@@ -11,7 +11,7 @@
********************************************************************
function: libvorbis codec headers
- last mod: $Id: codec.h,v 1.43 2003/03/04 21:23:37 xiphmont Exp $
+ last mod: $Id: codec.h,v 1.44 2003/08/18 05:34:01 xiphmont Exp $
********************************************************************/
@@ -212,6 +212,9 @@
extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples);
extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op);
+extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag);
+extern int vorbis_synthesis_halfrate_p(vorbis_info *v);
+
/* Vorbis ERRORS and return codes ***********************************/
#define OV_FALSE -1
<p><p>1.20 +4 -1 vorbis/include/vorbis/vorbisfile.h
Index: vorbisfile.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/include/vorbis/vorbisfile.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- vorbisfile.h 6 Mar 2003 22:03:42 -0000 1.19
+++ vorbisfile.h 18 Aug 2003 05:34:01 -0000 1.20
@@ -11,7 +11,7 @@
********************************************************************
function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.h,v 1.19 2003/03/06 22:03:42 xiphmont Exp $
+ last mod: $Id: vorbisfile.h,v 1.20 2003/08/18 05:34:01 xiphmont Exp $
********************************************************************/
@@ -131,6 +131,9 @@
int bigendianp,int word,int sgned,int *bitstream);
extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2);
+extern int ov_halfrate(OggVorbis_File *vf,int flag);
+extern int ov_halfrate_p(OggVorbis_File *vf);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
<p><p>1.73 +32 -27 vorbis/lib/block.c
Index: block.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/block.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -r1.72 -r1.73
--- block.c 6 Mar 2003 22:05:26 -0000 1.72
+++ block.c 18 Aug 2003 05:34:01 -0000 1.73
@@ -5,13 +5,13 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
* *
********************************************************************
function: PCM data vector blocking, windowing and dis/reassembly
- last mod: $Id: block.c,v 1.72 2003/03/06 22:05:26 xiphmont Exp $
+ last mod: $Id: block.c,v 1.73 2003/08/18 05:34:01 xiphmont Exp $
Handle windowing, overlap-add, etc of the PCM vectors. This is made
more amusing by Vorbis' current two allowed block sizes.
@@ -168,6 +168,7 @@
int i;
codec_setup_info *ci=vi->codec_setup;
private_state *b=NULL;
+ int hs=ci->halfrate_flag;
memset(v,0,sizeof(*v));
b=v->backend_state=_ogg_calloc(1,sizeof(*b));
@@ -182,12 +183,12 @@
b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
- mdct_init(b->transform[0][0],ci->blocksizes[0]);
- mdct_init(b->transform[1][0],ci->blocksizes[1]);
+ mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
+ mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
/* Vorbis I uses only window type 0 */
- b->window[0]=_vorbis_window_get(0,ci->blocksizes[0]/2);
- b->window[1]=_vorbis_window_get(0,ci->blocksizes[1]/2);
+ b->window[0]=ilog2(ci->blocksizes[0])-6;
+ b->window[1]=ilog2(ci->blocksizes[1])-6;
if(encp){ /* encode/decode differ here */
@@ -636,14 +637,16 @@
int vorbis_synthesis_restart(vorbis_dsp_state *v){
vorbis_info *vi=v->vi;
codec_setup_info *ci;
+ int hs;
if(!v->backend_state)return -1;
if(!vi)return -1;
ci=vi->codec_setup;
if(!ci)return -1;
+ hs=ci->halfrate_flag;
- v->centerW=ci->blocksizes[1]/2;
- v->pcm_current=v->centerW;
+ v->centerW=ci->blocksizes[1]>>(hs+1);
+ v->pcm_current=v->centerW>>hs;
v->pcm_returned=-1;
v->granulepos=-1;
@@ -669,6 +672,7 @@
vorbis_info *vi=v->vi;
codec_setup_info *ci=vi->codec_setup;
private_state *b=v->backend_state;
+ int hs=ci->halfrate_flag;
int i,j;
if(!vb)return(OV_EINVAL);
@@ -688,10 +692,10 @@
if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
was called on block */
- int n=ci->blocksizes[v->W]/2;
- int n0=ci->blocksizes[0]/2;
- int n1=ci->blocksizes[1]/2;
-
+ int n=ci->blocksizes[v->W]>>(hs+1);
+ int n0=ci->blocksizes[0]>>(hs+1);
+ int n1=ci->blocksizes[1]>>(hs+1);
+
int thisCenter;
int prevCenter;
@@ -712,21 +716,19 @@
to have to constantly shift *or* adjust memory usage. Don't
accept a new block until the old is shifted out */
- /* overlap/add PCM */
-
for(j=0;j<vi->channels;j++){
/* the overlap/add section */
if(v->lW){
if(v->W){
/* large/large */
- float *w=b->window[1];
+ float *w=_vorbis_window_get(b->window[1]-hs);
float *pcm=v->pcm[j]+prevCenter;
float *p=vb->pcm[j];
for(i=0;i<n1;i++)
pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
}else{
/* large/small */
- float *w=b->window[0];
+ float *w=_vorbis_window_get(b->window[0]-hs);
float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
float *p=vb->pcm[j];
for(i=0;i<n0;i++)
@@ -735,7 +737,7 @@
}else{
if(v->W){
/* small/large */
- float *w=b->window[0];
+ float *w=_vorbis_window_get(b->window[0]-hs);
float *pcm=v->pcm[j]+prevCenter;
float *p=vb->pcm[j]+n1/2-n0/2;
for(i=0;i<n0;i++)
@@ -744,7 +746,7 @@
pcm[i]=p[i];
}else{
/* small/small */
- float *w=b->window[0];
+ float *w=_vorbis_window_get(b->window[0]-hs);
float *pcm=v->pcm[j]+prevCenter;
float *p=vb->pcm[j];
for(i=0;i<n0;i++)
@@ -776,8 +778,8 @@
}else{
v->pcm_returned=prevCenter;
v->pcm_current=prevCenter+
- ci->blocksizes[v->lW]/4+
- ci->blocksizes[v->W]/4;
+ ((ci->blocksizes[v->lW]/4+
+ ci->blocksizes[v->W]/4)>>hs);
}
}
@@ -815,10 +817,10 @@
/* granulepos could be -1 due to a seek, but that would result
in a long count, not short count */
- v->pcm_current-=(b->sample_count-v->granulepos);
+ v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
}else{
/* trim the beginning */
- v->pcm_returned+=(b->sample_count-v->granulepos);
+ v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
if(v->pcm_returned>v->pcm_current)
v->pcm_returned=v->pcm_current;
}
@@ -836,7 +838,7 @@
if(extra)
if(vb->eofflag){
/* partial last frame. Strip the extra samples off */
- v->pcm_current-=extra;
+ v->pcm_current-=extra>>hs;
} /* else {Shouldn't happen *unless* the bitstream is out of
spec. Either way, believe the bitstream } */
} /* else {Shouldn't happen *unless* the bitstream is out of
@@ -855,6 +857,7 @@
/* pcm==NULL indicates we just want the pending samples, no more */
int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
vorbis_info *vi=v->vi;
+
if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
if(pcm){
int i;
@@ -881,10 +884,11 @@
int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
vorbis_info *vi=v->vi;
codec_setup_info *ci=vi->codec_setup;
+ int hs=ci->halfrate_flag;
- int n=ci->blocksizes[v->W]/2;
- int n0=ci->blocksizes[0]/2;
- int n1=ci->blocksizes[1]/2;
+ int n=ci->blocksizes[v->W]>>(hs+1);
+ int n0=ci->blocksizes[0]>>(hs+1);
+ int n1=ci->blocksizes[1]>>(hs+1);
int i,j;
if(v->pcm_returned<0)return 0;
@@ -916,6 +920,7 @@
v->centerW=0;
}
+ /* solidify buffer into contiguous space */
if((v->lW^v->W)==1){
/* long/short or short/long */
for(j=0;j<vi->channels;j++){
@@ -953,6 +958,6 @@
float *vorbis_window(vorbis_dsp_state *v,int W){
private_state *b=v->backend_state;
- return b->window[W];
+ return _vorbis_window_get(b->window[W]);
}
<p><p>1.17 +3 -4 vorbis/lib/codec_internal.h
Index: codec_internal.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/codec_internal.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- codec_internal.h 11 Oct 2002 11:14:41 -0000 1.16
+++ codec_internal.h 18 Aug 2003 05:34:01 -0000 1.17
@@ -11,7 +11,7 @@
********************************************************************
function: libvorbis codec headers
- last mod: $Id: codec_internal.h,v 1.16 2002/10/11 11:14:41 xiphmont Exp $
+ last mod: $Id: codec_internal.h,v 1.17 2003/08/18 05:34:01 xiphmont Exp $
********************************************************************/
@@ -58,7 +58,7 @@
typedef struct private_state {
/* local lookup storage */
envelope_lookup *ve; /* envelope lookup */
- float *window[2];
+ int window[2];
vorbis_look_transform **transform[2]; /* block, type */
drft_lookup fft_look[2];
@@ -79,7 +79,6 @@
bitrate_manager_state bms;
ogg_int64_t sample_count;
-
} private_state;
/* codec_setup_info contains all the setup information specific to the
@@ -125,7 +124,7 @@
highlevel_encode_setup hi; /* used only by vorbisenc.c. It's a
highly redundant structure, but
improves clarity of program flow. */
-
+ int halfrate_flag; /* painless downsample for decode */
} codec_setup_info;
extern vorbis_look_psy_global *_vp_global_look(vorbis_info *vi);
<p><p>1.58 +2 -1 vorbis/lib/mapping0.c
Index: mapping0.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/mapping0.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -r1.57 -r1.58
--- mapping0.c 2 Mar 2003 11:45:17 -0000 1.57
+++ mapping0.c 18 Aug 2003 05:34:01 -0000 1.58
@@ -11,7 +11,7 @@
********************************************************************
function: channel mapping 0 implementation
- last mod: $Id: mapping0.c,v 1.57 2003/03/02 11:45:17 xiphmont Exp $
+ last mod: $Id: mapping0.c,v 1.58 2003/08/18 05:34:01 xiphmont Exp $
********************************************************************/
@@ -654,6 +654,7 @@
codec_setup_info *ci=vi->codec_setup;
private_state *b=vd->backend_state;
vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l;
+ int hs=ci->halfrate_flag;
int i,j;
long n=vb->pcmend=ci->blocksizes[vb->W];
<p><p>1.30 +16 -1 vorbis/lib/synthesis.c
Index: synthesis.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/synthesis.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- synthesis.c 11 Oct 2002 11:14:41 -0000 1.29
+++ synthesis.c 18 Aug 2003 05:34:01 -0000 1.30
@@ -11,7 +11,7 @@
********************************************************************
function: single-block PCM synthesis
- last mod: $Id: synthesis.c,v 1.29 2002/10/11 11:14:41 xiphmont Exp $
+ last mod: $Id: synthesis.c,v 1.30 2003/08/18 05:34:01 xiphmont Exp $
********************************************************************/
@@ -152,4 +152,19 @@
return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
}
+int vorbis_synthesis_halfrate(vorbis_info *vi,int flag){
+ /* set / clear half-sample-rate mode */
+ codec_setup_info *ci=vi->codec_setup;
+
+ /* right now, our MDCT can't handle < 64 sample windows. */
+ if(ci->blocksizes[0]<=64 && flag)return -1;
+ ci->halfrate_flag=(flag?1:0);
+ return 0;
+}
+
+int vorbis_synthesis_halfrate_p(vorbis_info *vi){
+ codec_setup_info *ci=vi->codec_setup;
+ return ci->halfrate_flag;
+}
+
<p><p>1.70 +29 -1 vorbis/lib/vorbisfile.c
Index: vorbisfile.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/vorbisfile.c,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -r1.69 -r1.70
--- vorbisfile.c 11 Mar 2003 23:52:02 -0000 1.69
+++ vorbisfile.c 18 Aug 2003 05:34:01 -0000 1.70
@@ -11,7 +11,7 @@
********************************************************************
function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.c,v 1.69 2003/03/11 23:52:02 xiphmont Exp $
+ last mod: $Id: vorbisfile.c,v 1.70 2003/08/18 05:34:01 xiphmont Exp $
********************************************************************/
@@ -735,7 +735,35 @@
return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
}
+
+/* cheap hack for game usage where downsampling is desirable; there's
+ no need for SRC as we can just do it cheaply in libvorbis. */
+
+int ov_halfrate(OggVorbis_File *vf,int flag){
+ int i;
+ if(vf->vi==NULL)return OV_EINVAL;
+ if(!vf->seekable)return OV_EINVAL;
+ if(vf->ready_state>=STREAMSET)
+ _decode_clear(vf); /* clear out stream state; later on libvorbis
+ will be able to swap this on the fly, but
+ for now dumping the decode machine is needed
+ to reinit the MDCT lookups. 1.1 libvorbis
+ is planned to be able to switch on the fly */
+ for(i=0;i<vf->links;i++){
+ if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
+ ov_halfrate(vf,0);
+ return OV_EINVAL;
+ }
+ }
+ return 0;
+}
+
+int ov_halfrate_p(OggVorbis_File *vf){
+ if(vf->vi==NULL)return OV_EINVAL;
+ return vorbis_synthesis_halfrate_p(vf->vi);
+}
+
/* Only partially open the vorbis file; test for Vorbisness, and load
the headers for the first chain. Do not seek (although test for
seekability). Use ov_test_open to finish opening the file, else
<p><p>1.22 +20 -29 vorbis/lib/window.c
Index: window.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/window.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- window.c 6 Mar 2003 22:05:26 -0000 1.21
+++ window.c 18 Aug 2003 05:34:01 -0000 1.22
@@ -11,7 +11,7 @@
********************************************************************
function: window functions
- last mod: $Id: window.c,v 1.21 2003/03/06 22:05:26 xiphmont Exp $
+ last mod: $Id: window.c,v 1.22 2003/08/18 05:34:01 xiphmont Exp $
********************************************************************/
@@ -2084,35 +2084,26 @@
1.0000000000F, 1.0000000000F, 1.0000000000F, 1.0000000000F,
};
-float *_vorbis_window_get(int type, int left){
- switch(type){
- case 0:
- /* The 'vorbis window' (window 0) is sin(sin(x)*sin(x)*pi*.5) */
- switch(left){
- case 32:
- return(vwin64);
- case 64:
- return(vwin128);
- case 128:
- return(vwin256);
- case 256:
- return(vwin512);
- case 512:
- return(vwin1024);
- case 1024:
- return(vwin2048);
- case 2048:
- return(vwin4096);
- case 4096:
- return(vwin8192);
- }
- default:
- return(NULL);
- }
+static float *vwin[8] = {
+ vwin64,
+ vwin128,
+ vwin256,
+ vwin512,
+ vwin1024,
+ vwin2048,
+ vwin4096,
+ vwin8192,
+};
+
+float *_vorbis_window_get(int n){
+ return vwin[n];
}
-void _vorbis_apply_window(float *d,float *window[2],long *blocksizes,
+void _vorbis_apply_window(float *d,int *winno,long *blocksizes,
int lW,int W,int nW){
+ float *windowLW=vwin[winno[lW]];
+ float *windowNW=vwin[winno[nW]];
+
lW=(W?lW:0);
nW=(W?nW:0);
@@ -2133,10 +2124,10 @@
d[i]=0.f;
for(p=0;i<leftend;i++,p++)
- d[i]*=window[lW][p];
+ d[i]*=windowLW[p];
for(i=rightbegin,p=rn/2-1;i<rightend;i++,p--)
- d[i]*=window[nW][p];
+ d[i]*=windowNW[p];
for(;i<n;i++)
d[i]=0.f;
<p><p>1.13 +2 -2 vorbis/lib/window.h
Index: window.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/window.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- window.h 6 Mar 2003 22:05:26 -0000 1.12
+++ window.h 18 Aug 2003 05:34:01 -0000 1.13
@@ -11,14 +11,14 @@
********************************************************************
function: window functions
- last mod: $Id: window.h,v 1.12 2003/03/06 22:05:26 xiphmont Exp $
+ last mod: $Id: window.h,v 1.13 2003/08/18 05:34:01 xiphmont Exp $
********************************************************************/
#ifndef _V_WINDOW_
#define _V_WINDOW_
-extern float *_vorbis_window_get(int type,int left);
+extern float *_vorbis_window_get(int n);
extern void _vorbis_apply_window(float *d,float *window[2],long *blocksizes,
int lW,int W,int nW);
<p><p>--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list