📄 ogglib.cpp
字号:
// OGGLib.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "OGGLib.h"
//#include "lib/vorbis_codec.h"
#include "lib/ogg.h"
#include "lib/ivorbiscodec.h"
#include "lib/misc.h"
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_comment vc; /* struct that stores all the bitstream user comments */
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 eos=0;
int i;
int decode_header=0;
int stream_init=0;
ogg_int32_t **pcm;
int samples;
int in_loop=0;
int currentpos;
ogg_int16_t* convbuffer; //[4096]; /* take 8k out of the data segment, not the stack */
int convsize=4096;
#define FIXP_FRACBITS 28
#if (_WIN32_WCE < 300)
#define _strnicmp strncmp
#endif
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
int Seeking=0;
#define NEED_MORE 32768
// This is an example of an exported function.
OGGLIB_API void SeekStart()
{
}
OGGLIB_API void SeekEnd()
{
}
OGGLIB_API void Init(int Equalizer,char* eq)
{
ogg_sync_init(&oy); /* Now we can read pages */
stream_init=0;
in_loop=0;
decode_header=0;
currentpos=0;
i=0;
}
// This is an example of an exported function.
OGGLIB_API void Exit(void)
{
ogg_stream_clear(&os);
/* ogg_page and ogg_packet structs always point to storage in
libvorbis. They're never freed or manipulated directly */
vorbis_block_clear(&vb);
vorbis_dsp_clear(&vd);
vorbis_comment_clear(&vc);
vorbis_info_clear(&vi); /* must be called last */
ogg_sync_clear(&oy);
}
//static char buffer[40000];
OGGLIB_API int GetHeaderInfo(unsigned char * inbuff, int bytes, int* Freq, int* ch, int* BitRate, LPTSTR Title, LPTSTR Artist, LPTSTR Album)
{
int page=0;
int comment;
if (inbuff)
{
buffer=ogg_sync_buffer(&oy,bytes);
memcpy(buffer,inbuff,bytes);
ogg_sync_wrote(&oy,bytes);
}
//convbuffer=(ogg_int16_t*) outmemory;
if (!decode_header)
{
if (!stream_init)
{
/* submit a 4k block to libvorbis' Ogg layer */
/* Get the first page. */
if(ogg_sync_pageout(&oy,&og)!=1)
{
return -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);
vorbis_comment_init(&vc);
if(ogg_stream_pagein(&os,&og)<0)
{
/* error; stream version mismatch perhaps */
return -1;
}
if(ogg_stream_packetout(&os,&op)!=1)
{
/* no page? must not be vorbis */
return -1;
}
if(vorbis_synthesis_headerin(&vi,&vc,&op)<0)
{
/* error case; not a vorbis header */
return -1;
}
stream_init=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. */
while(i<2)
{
while(i<2)
{
int result=ogg_sync_pageout(&oy,&og);
if(result==0)
return NEED_MORE; /* 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)
return NEED_MORE;
if(result<0)
{
/* Uh oh; data at some point was corrupted or missing!
We can't tolerate that in a header. Die. */
return -1;
}
vorbis_synthesis_headerin(&vi,&vc,&op);
i++;
}
}
}
/* no harm in not checking before adding more */
}
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 */
for (comment=0;comment<vc.comments;comment++)
{
if (!_strnicmp(vc.user_comments[comment],"TITLE=",6))
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,vc.user_comments[comment]+6,-1,Title,200);
else if (!_strnicmp(vc.user_comments[comment],"ARTIST=",7))
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,vc.user_comments[comment]+7,-1,Artist,200);
else if (!_strnicmp(vc.user_comments[comment],"ALBUM=",6))
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,vc.user_comments[comment]+6,-1,Album,200);
}
decode_header=1;
}
/* The rest is just a straight decode loop until end of stream */
eos=0;
*Freq=vi.rate;
*BitRate=vi.bitrate_nominal*-1;
*ch=vi.channels;
// Exit();
// Init(0,0);
return 0;
}
OGGLIB_API int DecompressAudio(unsigned char * inbuff, int bytes, char *outmemory, int outmemsize, int *done, int* inputpos)
{
*done=0;
int page=0;
if (inbuff)
{
buffer=ogg_sync_buffer(&oy,bytes);
memcpy(buffer,inbuff,bytes);
ogg_sync_wrote(&oy,bytes);
}
//convbuffer=(ogg_int16_t*) outmemory;
while(!eos)
{
while(!eos)
{
if (inbuff||(page))
{
int result=ogg_sync_pageout(&oy,&og);
page=0;
//if(result==0) return NEED_MORE; /* need more data */
if(result<=0) /* missing or corrupt data at this page position */
{
return NEED_MORE;
}
if (ogg_stream_pagein(&os,&og)<0)
{
return -2;
}
}
while(1)
{
int result=1;
result=ogg_stream_packetout(&os,&op);
if(result==0)
{
page=1;
break; //return NEED_MORE; /* need more data */
}
if(result<0)
{ /* missing or corrupt data at this page position */
/* no reason to complain; already complained above */
}
else
{
/* we have a packet. Decode it */
if(vorbis_synthesis(&vb,&op)==0) /* test for success! */
vorbis_synthesis_blockin(&vd,&vb);
/*
**pcm is a multichannel float 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 clipflag=0;
int bout=samples; //(samples<convsize?samples:convsize);
int i;
for(i=0;i<vi.channels;i++)
{
ogg_int32_t *src=pcm[i];
short *dest=((short *)outmemory)+i;
for(j=0;j<samples;j++)
{
*dest=CLIP_TO_15(src[j]>>9);
dest+=vi.channels;
}
}
*inputpos=currentpos+op.bytes;
currentpos+=op.bytes;
*done+=2*vi.channels*bout;
vorbis_synthesis_read(&vd,bout);
outmemory+=2*vi.channels*bout;
if (*done>=4096)
return 0;
}
}
}
if(ogg_page_eos(&og))eos=1;
}
}
if (eos)
{
// int x=oy.fill-oy.returned;
// if (x)
// return (x+3)*-1;
return -1;
}
/* clean up this logical bitstream; before exit we see if we're
followed by another [chained] */
return 0;
}
// This is the constructor of a class that has been exported.
// see OGGLib.h for the class definition
COGGLib::COGGLib()
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -