missing pieces of analysis/synthesis.
Monty
svn path=/trunk/vorbis/; revision=139
# vorbis makefile configured for use with gcc on any platform
-# $Id: Makefile.in,v 1.9 1999/10/02 21:21:18 xiphmont Exp $
+# $Id: Makefile.in,v 1.10 1999/10/05 15:34:56 xiphmont Exp $
###############################################################################
# #
RANLIB=@RANLIB@
LIBS=@LIBS@ -lm
-OFILES = framing.o mdct.o smallft.o block.o envelope.o window.o\
+HFILES = mdct.h codec.h bitwise.h envelope.h lpc.h lsp.h modes.h\
+ psy.h smallft.h window.h xlogmap.h
+
+LFILES = framing.o mdct.o smallft.o block.o envelope.o window.o\
lsp.o lpc.o analysis.o synthesis.o psy.o info.o bitwise.o
-TARGETFILES = libvorbis.a
+
+EFILES = encoder_example.o decoder_example.o
all:
- $(MAKE) target CFLAGS="$(OPT)"
+ $(MAKE) target CFLAGS="$(OPT)"
-debug:
+debug:
$(MAKE) target CFLAGS="$(DEBUG)"
profile:
$(MAKE) target CFLAGS="$(PROFILE)"
+target: libvorbis.a encoder_example decoder_example
+
selftest:
$(MAKE) clean
$(CC) $(DEBUG) $(LDFLAGS) -D_V_SELFTEST framing.c -o test_framing
@./test_framing
@./test_bitwise
-dsptest: debug
- $(CC) $(DEBUG) $(LDFLAGS) dsptest.c libvorbis.a -o dsptest -lm
+encoder_example: $(EFILES) libvorbis.a
+ $(CC) $(CFLAGS) $(LDFLAGS) encoder_example.o libvorbis.a -o \
+ encoder_example -lm
-target: $(TARGETFILES)
+decoder_example: $(EFILES) libvorbis.a
+ $(CC) $(CFLAGS) $(LDFLAGS) decoder_example.o libvorbis.a -o \
+ decoder_example -lm
-libvorbis.a: $(OFILES)
- $(AR) -r libvorbis.a $(OFILES)
+libvorbis.a: $(LFILES)
+ $(AR) -r libvorbis.a $(LFILES)
$(RANLIB) libvorbis.a
-$(OFILES): mdct.h
+$(LFILES): $(HFILES)
.c.o:
$(CC) $(CFLAGS) -c $<
function: single-block PCM analysis
author: Monty <xiphmont@mit.edu>
modifications by: Monty
- last modification date: Oct 2 1999
+ last modification date: Oct 4 1999
********************************************************************/
#include "mdct.h"
#include "psy.h"
-extern void compute_balance(double *A, double *B, double *phi,int n);
+/* this code is still seriously abbreviated. I'm filling in pieces as
+ we go... --Monty 19991004 */
int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
int i;
- double *window=vb->vd->window[vb->W][vb->lW][vb->nW];
- lpc_lookup *vl=&vb->vd->vl[vb->W];
- lpc_lookup *vbal=&vb->vd->vbal[vb->W];
- int n=vb->pcmend;
- static int frameno=0;
+ double *window=vb->vd->window[vb->W][vb->lW][vb->nW];
+ lpc_lookup *vl=&vb->vd->vl[vb->W];
+ vorbis_dsp_state *vd=vi->vd;
+ vorbis_info *vi=vd->vi;
+ int n=vb->pcmend;
- double balance_v[vbal->m];
- double balance_amp;
+ /*lpc_lookup *vbal=&vb->vd->vbal[vb->W];
+ double balance_v[vbal->m];
+ double balance_amp;*/
+ /* we have the preecho metrics; decie what to do with them */
_ve_envelope_sparsify(vb);
_ve_envelope_apply(vb,0);
- for(i=0;i<vb->pcm_channels;i++)
- mdct_forward(&vb->vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
+ for(i=0;i<vi->channels;i++)
+ mdct_forward(&vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
- /* hardwired to stereo for now */
- {
+ /* no balance or channel coupling yet */
+ /*{
double *C=vb->pcm[0];
double *D=vb->pcm[1];
- /* Balance */
-
balance_amp=_vp_balance_compute(D,C,balance_v,vbal);
- /*{
+ {
FILE *out;
char buffer[80];
sprintf(buffer,"com%d.m",frameno);
out=fopen(buffer,"w+");
for(i=0;i<n/2;i++){
- fprintf(out," 0. 0.\n");
+ fprintf(out," 0. 0.\n");
fprintf(out,"%g %g\n",C[i],D[i]);
fprintf(out,"\n");
}
}
fclose(out);
- }*/
-
- /* apply balance vectors, mix down to the vectors we actually encode */
+ }
_vp_balance_apply(D,C,balance_v,balance_amp,vbal,1);
-
- /*{
+
+ {
FILE *out;
char buffer[80];
}
fclose(out);
- }*/
-
- /* extract the spectral envelope and residue */
+ }
+ }*/
- {
- double floor1[n/2];
+ /* extract the spectral envelope and residue */
+ /* just do by channel. No coupling yet */
+ {
+ for(i=0;i<vi->channels;vi++){
+ double floor[n/2];
double curve[n/2];
- double work[n/2];
- double lpc1[80];
- double lsp1[80];
- double lsp2[80];
- double amp1;
-
- memset(floor1,0,sizeof(floor1));
- memset(work,0,sizeof(work));
-
- _vp_noise_floor(C,floor1,n/2);
- _vp_noise_floor(D,floor1,n/2);
- _vp_mask_floor(C,floor1,n/2);
- _vp_mask_floor(D,floor1,n/2);
-
- memcpy(curve,floor1,sizeof(double)*n/2);
- amp1=sqrt(vorbis_curve_to_lpc(curve,lpc1,vl));
-
- /*vorbis_lpc_to_lsp(lpc1,lsp1,30);
-
- {
- int scale=1020;
- int last=0;
- for(i=0;i<30;i++){
- double q=lsp1[i]/M_PI*scale;
- int val=rint(q-last);
-
- last+=val;
- lsp1[i]=val;
-
- }
- }
+ double *lpc=vb->lpc[i];
+ double *lsp=vb->lsp[i];
+
+ memset(floor,0,sizeof(double)*n/2);
+ _vp_noise_floor(vb->pcm[i],floor,n/2);
+ _vp_mask_floor(vb->pcm[i],floor,n/2);
+ vb->amp[i]=sqrt(vorbis_curve_to_lpc(floor,lpc,vl));
+
+ vorbis_lpc_to_lsp(lpc,lsp,vl->m);
{
- int scale=1020;
- double last=0;
- for(i=0;i<30;i++){
- last+=lsp1[i];
- lsp2[i]=last*M_PI/scale;
+ /* make this scale configurable */
+ int scale=1020;
+ int last=0;
+ for(i=0;i<vl->m;i++){
+ double q=lsp[i]/M_PI*scale;
+ int val=rint(q-last);
+
+ last+=val;
+ lsp[i]=val;
+
}
}
+
+ /* make residue. Get the floor curve back from LPC (do we want
+ to recover all the way from LSP in the future? Yes, once the
+ residue massaging is smarter) */
-
-
- vorbis_lsp_to_lpc(lsp2,lpc1,30);*/
-
- vorbis_lpc_to_curve(work,lpc1,amp1,vl);
+ vorbis_lpc_to_curve(work,lpc1,amp1,vl);
_vp_psy_quantize(C,work,n/2);
_vp_psy_quantize(D,work,n/2);
#include "window.h"
#include "envelope.h"
#include "mdct.h"
+#include "lpc.h"
/* pcm accumulator examples (not exhaustive):
return(0);
}
-void vorbis_analysis_clear(vorbis_dsp_state *v){
+void vorbis_dsp_clear(vorbis_dsp_state *v){
int i,j,k;
if(v){
for(i=0;i<v->pcm_channels;i++)
if(v->pcm[i])free(v->pcm[i]);
free(v->pcm);
- free(v->pcmret);
+ if(v->pcmret)free(v->pcmret);
}
if(v->multipliers){
for(i=0;i<v->envelope_channels;i++)
_ve_envelope_clear(&v->ve);
mdct_clear(&v->vm[0]);
mdct_clear(&v->vm[1]);
+ lpc_clear(&v->vl[0]);
+ lpc_clear(&v->vl[1]);
+ lpc_clear(&v->vbal[0]);
+ lpc_clear(&v->vbal[1]);
memset(v,0,sizeof(vorbis_dsp_state));
}
}
function: codec headers
author: Monty <xiphmont@mit.edu>
modifications by: Monty
- last modification date: Oct 2 1999
+ last modification date: Oct 4 1999
********************************************************************/
#ifndef _vorbis_codec_h_
#define _vorbis_codec_h_
+#include <sys/types.h> /* get BSD style 16/32/64 bit types */
+
+/* If we have defines from the configure script, use those */
+#ifdef size64
+# define int64_t size64
+#endif
+#ifdef size32
+# define int32_t size32
+#endif
+#ifdef size16
+# define int16_t size16
+#endif
+
/* lookup structures for various simple transforms *****************/
typedef struct {
int *lacing_vals; /* The values that will go to the segment table */
- size64 *pcm_vals; /* pcm_pos values for headers. Not compact
+ int64_t *pcm_vals; /* pcm_pos values for headers. Not compact
this way, but it is simple coupled to the
lacing fifo */
long lacing_storage;
of a logical bitstream */
long serialno;
long pageno;
- size64 pcmpos;
+ int64_t pcmpos;
} ogg_stream_state;
long b_o_s;
long e_o_s;
- size64 frameno;
+ int64_t frameno;
} ogg_packet;
extern int ogg_stream_destroy(ogg_stream_state *os);
extern int ogg_stream_eof(ogg_stream_state *os);
-extern int ogg_page_version(ogg_page *og);
-extern int ogg_page_continued(ogg_page *og);
-extern int ogg_page_bos(ogg_page *og);
-extern int ogg_page_eos(ogg_page *og);
-extern size64 ogg_page_frameno(ogg_page *og);
-extern int ogg_page_serialno(ogg_page *og);
-extern int ogg_page_pageno(ogg_page *og);
+extern int ogg_page_version(ogg_page *og);
+extern int ogg_page_continued(ogg_page *og);
+extern int ogg_page_bos(ogg_page *og);
+extern int ogg_page_eos(ogg_page *og);
+extern int64_t ogg_page_frameno(ogg_page *og);
+extern int ogg_page_serialno(ogg_page *og);
+extern int ogg_page_pageno(ogg_page *og);
/* Vorbis PRIMITIVES: general ***************************************/
+extern void vorbis_dsp_clear(vorbis_dsp_state *v);
+
extern void vorbis_info_init(vorbis_info *vi);
-extern int vorbis_info_clear(vorbis_info *vi);
+extern void vorbis_info_clear(vorbis_info *vi);
extern int vorbis_info_modeset(vorbis_info *vi, int mode);
extern int vorbis_info_addcomment(vorbis_info *vi, char *comment);
extern int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op);
/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/
extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi);
-extern void vorbis_analysis_clear(vorbis_dsp_state *v);
extern double **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals);
extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals);
extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op);
/* Vorbis PRIMITIVES: synthesis layer *******************************/
-extern int vorbis_synthesis_clear(vorbis_dsp_state *v);
extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi);
extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op);
--- /dev/null
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *
+ * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: simple example decoder
+ author: Monty <xiphmont@mit.edu>
+ modifications by: Monty
+ last modification date: Oct 04 1999
+
+ ********************************************************************/
+
+/* Takes a vorbis bitstream from stdin and writes raw stereo PCM to
+ stdout */
+
+#include <stdio.h>
+#include <math.h>
+#include "codec.h"
+
+int16_t convbuffer[4096]; /* take 8k out of the data segment, not the stack */
+int convsize=4096;
+
+int main(){
+ ogg_sync_state oy; /* sync and verify incoming physical bitstream */
+ ogg_stream_state os; /* take physical pages, weld into a logical
+ stream of packets */
+ ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
+ ogg_packet op; /* one raw packet of data for decode */
+
+ vorbis_info vi; /* struct that stores all the static vorbis bitstream
+ settings */
+ vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
+ vorbis_block vb; /* local working space for packet->PCM decode */
+
+ char *buffer;
+ int bytes;
+ int i;
+ int eos=0;
+
+ /********** Decode setup ************/
+
+ ogg_sync_init(&oy); /* Now we can read pages */
+
+ /* grab some data at the head of the stream. We want the first page
+ (which is guaranteed to be small and only contain the Vorbis
+ stream initial header) We need the first page to get the stream
+ serialno. */
+
+ /* submit a 4k block to libvorbis */
+ buffer=ogg_sync_buffer(&oy,4096);
+ bytes=fread(buffer,1,4096,stdin);
+ ogg_sync_wrote(&oy,bytes);
+
+ /* Get the first page. */
+ if(ogg_sync_pageout(&oy,&og)!=1){
+ /* error case. Must not be Vorbis data */
+ fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n");
+ exit(1);
+ }
+
+ /* Get the serial number and set up the rest of decode. */
+ /* serialno first; use it to set up a logical stream */
+ ogg_stream_init(&os,ogg_page_serialno(&og));
+
+ /* extract the initial header from the first page and verify that the
+ Ogg bitstream is in fact Vorbis data */
+
+ /* I handle the initial header first instead of just having the code
+ read all three Vorbis headers at once because reading the initial
+ header is an easy way to identify a Vorbis bitstream and it's
+ useful to see that functionality seperated out. */
+
+ vorbis_info_init(&vi);
+ if(ogg_stream_pagein(&os,&og)<0){
+ /* error; stream version mismatch perhaps */
+ fprintf(stderr,"Error reading first page of Ogg bitstream data.\n");
+ exit(1);
+ }
+
+ if(ogg_stream_packetout(&os,&op)!=1){
+ /* no page? must not be vorbis */
+ fprintf(stderr,"Error reading initial header packet.\n");
+ exit(1);
+ }
+
+ if(vorbis_info_headerin(&vi,&op)<0){
+ /* error case; not a vorbis header */
+ fprintf(stderr,"This Ogg bitstream does not contain Vorbis audio data.\n");
+ exit(1);
+ }
+
+ /* At this point, we're sure we're Vorbis. We've set up the logical
+ (Ogg) bitstream decoder. Get the comment and codebook headers and
+ set up the Vorbis decoder */
+
+ /* The next two packets in order are the comment and codebook headers.
+ They're likely large and may span multiple pages. Thus we reead
+ and submit data until we get our two pacakets, watching that no
+ pages are missing. If a page is missing, error out; losing a
+ header page is the only place where missing data is fatal. */
+
+ i=0;
+ while(i<2){
+ while(i<2){
+ int result=ogg_sync_pageout(&oy,&og);
+ if(result==0)break; /* Need more data */
+ /* Don't complain about missing or corrupt data yet. We'll
+ catch it at the packet output phase */
+ if(result==1){
+ ogg_stream_pagein(&os,&og); /* we can ignore any errors here
+ as they'll also become apparent
+ at packetout */
+ while(i<2){
+ result=ogg_stream_packetout(&os,&op);
+ if(result==0)break;
+ if(result==-1){
+ /* Uh oh; data at some point was corrupted or missing!
+ We can't tolerate that in a header. Die. */
+ fprintf(stderr,"Corrupt secondary header. Exiting.\n");
+ exit(1);
+ }
+ vorbis_info_headerin(&vi,&op);
+ i++;
+ }
+ }
+ }
+ /* no harm in not checking before adding more */
+ buffer=ogg_sync_buffer(&oy,4096);
+ bytes=fread(buffer,1,4096,stdin);
+ if(bytes==0){
+ fprintf(stderr,"End of file before finding all Vorbis headers!\n");
+ exit(1);
+ }
+ ogg_sync_wrote(&oy,bytes);
+ }
+
+ /* Throw the comments plus a few lines about the bitstream we're
+ decoding */
+ {
+ char **ptr=vi->user_comments;
+ while(*ptr){
+ fprintf(stderr,"%s\n",*ptr);
+ ++ptr;
+ }
+ fprintf(stderr,"\nBitstream is %d channel, %dHz\n",vi->channels,vi->rate);
+ fprintf(stderr,"Encoded by: %s\n\n",vi->vendor);
+ }
+
+ convsize=4096/vi.channels;
+
+ /* OK, got and parsed all three headers. Initialize the Vorbis
+ packet->PCM decoder. */
+ vorbis_synthesis_init(&vd,&vi); /* central decode state */
+ vorbis_block_init(&vd,&vb); /* local state for most of the decode
+ so multiple block decodes can
+ proceed in parallel. We could init
+ multiple vorbis_block structures
+ for vd here */
+
+ /* The rest is just a straight decode loop until end of stream */
+ while(!eos){
+ while(!eos){
+ int result=ogg_sync_pageout(&oy,&og);
+ if(result==0)break; /* need more data */
+ if(result==-1){ /* missing or corrupt data at this page position */
+ fprintf(stderr,"Corrupt or missing data in bitstream; "
+ "continuing...\n");
+ }else{
+ ogg_stream_pagein(&os,&og); /* can safely ignore errors at
+ this point */
+ while(1){
+ result=ogg_stream_packetout(&os,&op);
+ if(result==0)break; /* need more data */
+ if(result==-1){ /* missing or corrupt data at this page position */
+ /* no reason to complain; already complained above */
+ }else{
+ /* we have a packet. Decode it */
+ double **pcm;
+ int samples;
+
+ vorbis_synthesis(&vb,&op);
+ vorbis_synthesis_blockin(&vd,&vb);
+ /*
+
+ **pcm is a multichannel double vector. In stereo, for
+ example, pcm[0] is left, and pcm[1] is right. samples is
+ the size of each channel. Convert the float values
+ (-1.<=range<=1.) to whatever PCM format and write it out */
+
+ while((samples=vorbis_synthesis_pcmout(&vd,&pcm))>0){
+ int j;
+ int out=(samples<convsize?samples:convsize);
+
+ /* convert doubles to 16 bit signed ints (host order) and
+ interleave */
+ for(i=0;i<vi.channels;i++){
+ int16_t *ptr=convbuffer+i;
+ double *mono=pcm[i];
+ for(j=0;j<out;j++){
+ int val=rint(mono[j]*32767.);
+ /* might as well guard clipping */
+ if(val>32767)val=32767;
+ if(val<-32768)val=-32768;
+ *ptr=val;
+ ptr+=2;
+ }
+ }
+
+ vorbis_synthesis_read(&vd,out); /* tell libvorbis how
+ many samples we
+ actually consumed */
+ }
+ }
+ }
+ if(ogg_page_eos(&og))eos=1;
+ }
+ }
+ if(!eos){
+ buffer=ogg_sync_buffer(&oy,4096);
+ bytes=fread(buffer,1,4096,stdin);
+ if(bytes==0)eos=1;
+ }else
+ ogg_sync_wrote(&oy,bytes);
+ }
+
+ /* clean up and exit (this example doesn't deal with the possibility
+ of chaining logical streams */
+
+ ogg_sync_clear(&oy);
+ ogg_stream_clear(&os);
+
+ /* ogg_page and ogg_packet structs always point to storage in
+ libvorbis. They're never freed or manipulated directly */
+
+ vorbis_info_clear(&vi);
+ vorbis_dsp_clear(&vd);
+ vorbis_block_clear(&vb);
+
+ fprintf(stderr,"Done.\n");
+ return(0);
+}
+
--- /dev/null
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *
+ * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: simple example encoder
+ author: Monty <xiphmont@mit.edu>
+ modifications by: Monty
+ last modification date: Oct 04 1999
+
+ ********************************************************************/
+
+/* takes a stereo 16bit 44.1kHz WAV file from stdin and encodes it into
+ a Vorbis bitstream */
+
+#include <stdio.h>
+#include <math.h>
+#include "codec.h"
+
+#define READ 1024
+signed char readbuffer[READ*4+44]; /* out of the data segment, not the stack */
+
+int main(){
+ ogg_stream_state os; /* take physical pages, weld into a logical
+ stream of packets */
+ ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
+ ogg_packet op; /* one raw packet of data for decode */
+
+ vorbis_info vi; /* struct that stores all the static vorbis bitstream
+ settings */
+ vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
+ vorbis_block vb; /* local working space for packet->PCM decode */
+
+ int eos=0;
+
+ /* we cheat on the WAV header; we just bypass 44 bytes and never
+ verify that it matches 16bit/stereo/44.1kHz. This is just an
+ example, after all. */
+
+ fread(readbuffer,1,44,stdin);
+
+ /********** Encode setup ************/
+
+ /* choose an encoding mode */
+ /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
+ vorbis_info_modeset(&vi,0);
+
+ /* add a comment */
+ vorbis_info_addcomment(&vi,"Track encoded by encoder_example.c");
+
+ /* set up the analysis state and auxiliary encoding storage */
+ vorbis_analysis_init(&vd,&vi);
+ vorbis_block_init(&vd,&vb);
+
+ /* set up our packet->stream encoder */
+ ogg_stream_init(&os,0); /* serial number 0 is fine */
+
+ /* Vorbis streams begin with three headers; the initial header (with
+ most of the codec setup parameters) which is mandated by the Ogg
+ bitstream spec. The second header holds any comment fields. The
+ third header holds the bitstream codebook. We merely need to
+ make the headers, then pass them to libvorbis one at a time;
+ libvorbis handles the additional Ogg bitstream constraints */
+
+ {
+ ogg_packet header;
+ ogg_packet header_comm;
+ ogg_packet header_code;
+
+ vorbis_info_headerout(&vi,&header,&header_comm,&header_code);
+ ogg_stream_packetin(&os,&header); /* automatically placed in its own
+ page */
+ ogg_stream_packetin(&os,&header_comm);
+ ogg_stream_packetin(&os,&header_code);
+
+ /* no need to write out here. We'll get to that in the main loop */
+ }
+
+ while(!eos){
+ long i;
+ long bytes=fread(readbuffer,1,READ*4,stdin); /* stereo hardwired here */
+
+ if(bytes==0){
+ /* end of file. this can be done implicitly in the mainline,
+ but it's easier to see here in non-clever fashion.
+ Tell the library we're at end of stream so that it can handle
+ the last frame and mark end of stream in the output properly */
+ vorbis_analysis_wrote(&vd,0);
+
+ }else{
+ /* data to encode */
+
+ /* expose the buffer to submit data */
+ double **buffer=vorbis_analysis_buffer(&vd,READ);
+
+ /* uninterleave samples */
+ for(i=0;i<bytes/4;i++){
+ buffer[0][i]=((readbuffer[i*4+1]<<8)|
+ (0x00ff&(int)readbuffer[i*4]))/32768.;
+ buffer[1][i]=((readbuffer[i*4+3]<<8)|
+ (0x00ff&(int)readbuffer[i*4+2]))/32768.;
+ }
+
+ /* tell the library how much we actually submitted */
+ vorbis_analysis_wrote(&vd,i);
+ }
+
+ /* vorbis does some data preanalysis, then divvies up blocks for
+ more involved (potentially parallel) processing. Get a single
+ block for encoding now */
+ while(vorbis_analysis_blockout(&vd,&vb)==1){
+
+ /* analysis */
+ vorbis_analysis(&vb,&op);
+
+ /* weld the packet into the bitstream */
+ ogg_stream_packetin(&os,&op);
+
+ /* write out pages (if any) */
+ while(!eos){
+ int result=ogg_stream_pageout(&os,&og);
+ if(result==0)break;
+ fwrite(og.header,1,og.header_len,stdout);
+ fwrite(og.body,1,og.body_len,stdout);
+
+ /* this could be set above, but for illustrative purposes, I do
+ it here (to show that vorbis does know where the stream ends) */
+
+ if(ogg_page_eos(&og))eos=1;
+
+ }
+ }
+ }
+
+ /* clean up and exit */
+
+ ogg_stream_clear(&os);
+ vorbis_info_clear(&vi);
+ vorbis_dsp_clear(&vd);
+ vorbis_block_clear(&vb);
+
+ /* ogg_page and ogg_packet structs always point to storage in
+ libvorbis. They're never freed or manipulated directly */
+
+ fprintf(stderr,"Done.\n");
+ return(0);
+}
+
}
/* convenience function */
-int vorbis_info_add_comment(vorbis_info *vi,char *comment){
+int vorbis_info_addcomment(vorbis_info *vi,char *comment){
vi->user_comments=realloc(vi->user_comments,
(vi->comments+1)*sizeof(char *));
vi->user_comments[vi->comments]=strdup(comment);
/* Also verify header-ness, vorbis */
{
char buffer[6];
- int type;
memset(buffer,0,6);
_v_readstring(&opb,buffer,6);
if(memcmp(buffer,"vorbis",6)){
/* build the packet */
if(vi->header)free(vi->header);
+ vi->header=malloc(_oggpack_bytes(&opb));
memcpy(vi->header,opb.buffer,_oggpack_bytes(&opb));
op->packet=vi->header;
op->bytes=_oggpack_bytes(&opb);
}
if(vi->header1)free(vi->header1);
+ vi->header1=malloc(_oggpack_bytes(&opb));
memcpy(vi->header1,opb.buffer,_oggpack_bytes(&opb));
op_comm->packet=vi->header1;
op_comm->bytes=_oggpack_bytes(&opb);
_oggpack_write(&opb,0x02,8);
if(vi->header2)free(vi->header2);
+ vi->header2=malloc(_oggpack_bytes(&opb));
memcpy(vi->header2,opb.buffer,_oggpack_bytes(&opb));
op_code->packet=vi->header2;
op_code->bytes=_oggpack_bytes(&opb);
return(0);
}
-int vorbis_info_clear(vorbis_info *vi){
+void vorbis_info_clear(vorbis_info *vi){
/* clear the non-flat storage before zeroing */
/* comments */
}
- memcpy(curve,work,sizeof(work));
-
return vorbis_gen_lpc(work,lpc,l);
}
/* get the LSP params back to LPC params. This will be for each
spectral floor curve */
+
+ /* {
+ int scale=1020;
+ double last=0;
+ for(i=0;i<30;i++){
+ last+=lsp1[i];
+ lsp2[i]=last*M_PI/scale;
+ }
+ }
+
+
+
+ vorbis_lsp_to_lpc(lsp2,lpc1,30);*/
+
+
/*for(i=0;i<vi->floorch;i++)
vorbis_lsp_to_lpc(vb->lsp[i],vb->lpc[i],vi->floororder);*/