mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-01-15 15:31:08 +00:00
424 lines
11 KiB
C
424 lines
11 KiB
C
|
/********************************************************************
|
||
|
* *
|
||
|
* THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
|
||
|
* *
|
||
|
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||
|
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||
|
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||
|
* *
|
||
|
* THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
|
||
|
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
|
||
|
* *
|
||
|
********************************************************************
|
||
|
|
||
|
function: simple example decoder using vorbisidec
|
||
|
|
||
|
********************************************************************/
|
||
|
|
||
|
/* Takes a vorbis bitstream from stdin and writes raw stereo PCM to
|
||
|
stdout using vorbisfile. Using vorbisfile is much simpler than
|
||
|
dealing with libvorbis. */
|
||
|
|
||
|
#include <stdarg.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include "ivorbiscodec.h"
|
||
|
#include "ivorbisfile.h"
|
||
|
#include "time.h"
|
||
|
#include "windows.h"
|
||
|
|
||
|
#define PROFILE
|
||
|
|
||
|
#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */
|
||
|
#include <io.h>
|
||
|
#include <fcntl.h>
|
||
|
#endif
|
||
|
|
||
|
char pcmout[4096]; /* take 4k out of the data segment, not the stack */
|
||
|
char ref[4096]; /* take 4k out of the data segment, not the stack */
|
||
|
char text[4096];
|
||
|
|
||
|
void Output(const char *fmt, ...)
|
||
|
{
|
||
|
#ifdef _WIN32_WCE
|
||
|
va_list ap;
|
||
|
char *t = text;
|
||
|
WCHAR uni[4096];
|
||
|
WCHAR *u = uni;
|
||
|
|
||
|
va_start(ap,fmt);
|
||
|
vsprintf(text, fmt, ap);
|
||
|
va_end(ap);
|
||
|
|
||
|
while (*t != 0)
|
||
|
{
|
||
|
*u++ = (WCHAR)(*t++);
|
||
|
}
|
||
|
*u++ = 0;
|
||
|
OutputDebugString(uni);
|
||
|
#else
|
||
|
vfprintf(stderr, fmt, ap);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
FILE *in;
|
||
|
FILE *out;
|
||
|
FILE *refin;
|
||
|
FILE *refout;
|
||
|
int max_samples;
|
||
|
} TestParams;
|
||
|
|
||
|
static DWORD run_test(void *tp)
|
||
|
{
|
||
|
TestParams *params = (TestParams *)tp;
|
||
|
FILE *in = params->in;
|
||
|
FILE *out = params->out;
|
||
|
FILE *refin = params->refin;
|
||
|
FILE *refout = params->refout;
|
||
|
int max_samples = params->max_samples;
|
||
|
OggVorbis_File vf;
|
||
|
int eof=0;
|
||
|
int current_section;
|
||
|
int maxdiff = 0;
|
||
|
int countdiffs = 0;
|
||
|
int samples = 0;
|
||
|
|
||
|
if(ov_open(in, &vf, NULL, 0) < 0) {
|
||
|
Output("Input does not appear to be an Ogg bitstream.\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
/* Throw the comments plus a few lines about the bitstream we're
|
||
|
decoding */
|
||
|
{
|
||
|
char **ptr=ov_comment(&vf,-1)->user_comments;
|
||
|
vorbis_info *vi=ov_info(&vf,-1);
|
||
|
if (out != NULL)
|
||
|
{
|
||
|
while(*ptr){
|
||
|
Output("%s\n",*ptr);
|
||
|
++ptr;
|
||
|
}
|
||
|
Output("\nBitstream is %d channel, %ldHz\n",vi->channels,vi->rate);
|
||
|
Output("\nDecoded length: %ld samples\n",
|
||
|
(long)ov_pcm_total(&vf,-1));
|
||
|
Output("Encoded by: %s\n\n",ov_comment(&vf,-1)->vendor);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
while((!eof) && (max_samples > 0)){
|
||
|
long ret=ov_read(&vf,pcmout,sizeof(pcmout),¤t_section);
|
||
|
if (ret == 0) {
|
||
|
/* EOF */
|
||
|
eof=1;
|
||
|
} else if (ret < 0) {
|
||
|
/* error in the stream. Not a problem, just reporting it in
|
||
|
case we (the app) cares. In this case, we don't. */
|
||
|
} else {
|
||
|
/* we don't bother dealing with sample rate changes, etc, but
|
||
|
you'll have to*/
|
||
|
if (out != NULL)
|
||
|
{
|
||
|
fwrite(pcmout,1,ret,out);
|
||
|
}
|
||
|
max_samples -= ret>>1;
|
||
|
if (refout != NULL)
|
||
|
{
|
||
|
fwrite(pcmout,1,ret,refout);
|
||
|
samples += ret>>1;
|
||
|
Output("%d", samples);
|
||
|
}
|
||
|
if (refin != NULL)
|
||
|
{
|
||
|
int i, diff;
|
||
|
|
||
|
fread(ref,1,ret,refin);
|
||
|
for (i=0; i<(ret>>1);i++)
|
||
|
{
|
||
|
diff = ((short *)pcmout)[i] - ((short *)ref)[i];
|
||
|
if (diff != 0)
|
||
|
{
|
||
|
if (diff < 0)
|
||
|
diff = -diff;
|
||
|
if (diff > maxdiff)
|
||
|
maxdiff = diff;
|
||
|
countdiffs++;
|
||
|
if (countdiffs < 50)
|
||
|
{
|
||
|
Output("samples differ: %x vs %x\n",
|
||
|
((unsigned short *)pcmout)[i],
|
||
|
((unsigned short *)ref)[i]);
|
||
|
}
|
||
|
else if ((countdiffs % 100) == 0)
|
||
|
{
|
||
|
Output("%d differences, maximum = %d\n",
|
||
|
countdiffs, maxdiff);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* cleanup */
|
||
|
ov_clear(&vf);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int filetimetoms(FILETIME *time)
|
||
|
{
|
||
|
unsigned long long l;
|
||
|
|
||
|
l = ((unsigned long long)time->dwLowDateTime) + (((unsigned long long)time->dwHighDateTime)<<32);
|
||
|
|
||
|
return (int)(l/10000);
|
||
|
}
|
||
|
|
||
|
char speedblock[32768];
|
||
|
void speedtest()
|
||
|
{
|
||
|
int readtime;
|
||
|
FILETIME userStartTime, userStopTime;
|
||
|
FILETIME kernelStartTime, kernelStopTime;
|
||
|
FILETIME exitStartTime, exitStopTime;
|
||
|
FILETIME creationStartTime, creationStopTime;
|
||
|
|
||
|
Output("Speed test: STMIA speed\n");
|
||
|
|
||
|
GetThreadTimes(GetCurrentThread(),
|
||
|
&creationStartTime,
|
||
|
&exitStartTime,
|
||
|
&kernelStartTime,
|
||
|
&userStartTime);
|
||
|
stmiaTest(speedblock, 32768, 65536);
|
||
|
GetThreadTimes(GetCurrentThread(),
|
||
|
&creationStopTime,
|
||
|
&exitStopTime,
|
||
|
&kernelStopTime,
|
||
|
&userStopTime);
|
||
|
readtime = filetimetoms(&userStopTime)-filetimetoms(&userStartTime);
|
||
|
Output("Speed test complete: Timing=%g\n",
|
||
|
((double)readtime)/1000);
|
||
|
|
||
|
Output("Speed test: STR speed\n");
|
||
|
|
||
|
GetThreadTimes(GetCurrentThread(),
|
||
|
&creationStartTime,
|
||
|
&exitStartTime,
|
||
|
&kernelStartTime,
|
||
|
&userStartTime);
|
||
|
strTest(speedblock, 32768, 65536);
|
||
|
GetThreadTimes(GetCurrentThread(),
|
||
|
&creationStopTime,
|
||
|
&exitStopTime,
|
||
|
&kernelStopTime,
|
||
|
&userStopTime);
|
||
|
readtime = filetimetoms(&userStopTime)-filetimetoms(&userStartTime);
|
||
|
Output("Speed test complete: Timing=%g\n",
|
||
|
((double)readtime)/1000);
|
||
|
|
||
|
Output("Speed test: SMULL speed\n");
|
||
|
|
||
|
GetThreadTimes(GetCurrentThread(),
|
||
|
&creationStartTime,
|
||
|
&exitStartTime,
|
||
|
&kernelStartTime,
|
||
|
&userStartTime);
|
||
|
smullTest(speedblock, 32768, 65536);
|
||
|
GetThreadTimes(GetCurrentThread(),
|
||
|
&creationStopTime,
|
||
|
&exitStopTime,
|
||
|
&kernelStopTime,
|
||
|
&userStopTime);
|
||
|
readtime = filetimetoms(&userStopTime)-filetimetoms(&userStartTime);
|
||
|
Output("Speed test complete: Timing=%g\n",
|
||
|
((double)readtime)/1000);
|
||
|
}
|
||
|
|
||
|
int main(int argc, char *argv[]){
|
||
|
FILE *in;
|
||
|
FILE *out = NULL;
|
||
|
FILE *refin = NULL;
|
||
|
FILE *refout = NULL;
|
||
|
int dectime, readtime;
|
||
|
FILETIME userStartTime, userStopTime;
|
||
|
FILETIME kernelStartTime, kernelStopTime;
|
||
|
FILETIME exitStartTime, exitStopTime;
|
||
|
FILETIME creationStartTime, creationStopTime;
|
||
|
TestParams params;
|
||
|
|
||
|
if (argc < 2)
|
||
|
{
|
||
|
Output("Syntax: testtremor <infile> [<outfile>]\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
#ifdef PROFILE
|
||
|
in = fopen(argv[1], "rb");
|
||
|
if (in == NULL)
|
||
|
{
|
||
|
Output("Failed to open '%s' for input\n", argv[1]);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
params.in = in;
|
||
|
params.out = NULL;
|
||
|
params.refin = NULL;
|
||
|
params.refout = NULL;
|
||
|
params.max_samples = 0x7FFFFFFF;
|
||
|
Profile_init(184000, 4);
|
||
|
run_test(¶ms);
|
||
|
Profile_dump();
|
||
|
#else
|
||
|
in = fopen(argv[1], "rb");
|
||
|
if (in == NULL)
|
||
|
{
|
||
|
Output("Failed to open '%s' for input\n", argv[1]);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
if (argc >= 3)
|
||
|
{
|
||
|
out = fopen(argv[2], "wb");
|
||
|
if (out == NULL)
|
||
|
{
|
||
|
Output("Failed to open '%s' for output\n", argv[2]);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (argc >= 4)
|
||
|
{
|
||
|
refin = fopen(argv[3], "rb");
|
||
|
if (refin == NULL)
|
||
|
{
|
||
|
Output("Can't find reference file. Creating instead.\n");
|
||
|
refout = fopen(argv[3], "wb");
|
||
|
if (refout == NULL)
|
||
|
{
|
||
|
Output("Failed to open '%s' as output reference file\n", argv[3]);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Output("First test: Decode correctness\n");
|
||
|
params.in = in;
|
||
|
params.out = out;
|
||
|
params.refin = refin;
|
||
|
params.refout = refout;
|
||
|
params.max_samples = 1*1024*1024;
|
||
|
run_test(¶ms);
|
||
|
Output("First test complete\n");
|
||
|
if (out != NULL)
|
||
|
fclose(out);
|
||
|
if (refin != NULL)
|
||
|
fclose(refin);
|
||
|
if (refout != NULL)
|
||
|
fclose(refout);
|
||
|
Output("Second test: Decode speed\n");
|
||
|
in = fopen(argv[1], "rb");
|
||
|
if (in == NULL)
|
||
|
{
|
||
|
Output("Failed to open '%s' for input\n", argv[1]);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
GetThreadTimes(GetCurrentThread(),
|
||
|
&creationStartTime,
|
||
|
&exitStartTime,
|
||
|
&kernelStartTime,
|
||
|
&userStartTime);
|
||
|
params.in = in;
|
||
|
params.out = NULL;
|
||
|
params.refin = NULL;
|
||
|
params.refout = NULL;
|
||
|
params.max_samples = 0x7FFFFFFF;
|
||
|
run_test(¶ms);
|
||
|
GetThreadTimes(GetCurrentThread(),
|
||
|
&creationStopTime,
|
||
|
&exitStopTime,
|
||
|
&kernelStopTime,
|
||
|
&userStopTime);
|
||
|
|
||
|
dectime = filetimetoms(&userStopTime)-filetimetoms(&userStartTime);
|
||
|
Output("Second test complete: Timing=%g\n",
|
||
|
((double)dectime)/1000);
|
||
|
Output("Third test: File read speed\n");
|
||
|
|
||
|
in = fopen(argv[1], "rb");
|
||
|
if (in == NULL)
|
||
|
{
|
||
|
Output("Failed to open '%s' for input\n", argv[1]);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
GetThreadTimes(GetCurrentThread(),
|
||
|
&creationStartTime,
|
||
|
&exitStartTime,
|
||
|
&kernelStartTime,
|
||
|
&userStartTime);
|
||
|
while (!feof(in))
|
||
|
{
|
||
|
fread(pcmout,1,4096,in);
|
||
|
}
|
||
|
GetThreadTimes(GetCurrentThread(),
|
||
|
&creationStopTime,
|
||
|
&exitStopTime,
|
||
|
&kernelStopTime,
|
||
|
&userStopTime);
|
||
|
readtime = filetimetoms(&userStopTime)-filetimetoms(&userStartTime);
|
||
|
Output("Third test complete: Timing=%g\n",
|
||
|
((double)readtime)/1000);
|
||
|
Output("Adjusted decode time: Timing=%g\n",
|
||
|
((double)(dectime-readtime))/1000);
|
||
|
#endif
|
||
|
Output("Done.\n");
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
#ifdef _WIN32_WCE
|
||
|
|
||
|
#define TESTFILE 0
|
||
|
|
||
|
int WinMain(HINSTANCE h,HINSTANCE i,LPWSTR l,int n)
|
||
|
{
|
||
|
#if TESTFILE == 9
|
||
|
char *argv[] = { "testtremor",
|
||
|
"\\Storage Card\\Tremolo\\infile9.ogg",
|
||
|
"\\Storage Card\\Tremolo\\output9.pcm",
|
||
|
#ifdef _LOW_ACCURACY_
|
||
|
"\\Storage Card\\Tremolo\\outputL9.ref",
|
||
|
#else
|
||
|
"\\Storage Card\\Tremolo\\output9.ref",
|
||
|
#endif /* _LOW_ACCURACY_ */
|
||
|
NULL };
|
||
|
#endif
|
||
|
#if TESTFILE == 2
|
||
|
char *argv[] = { "testtremor",
|
||
|
"\\Storage Card\\Tremolo\\infile2.ogg",
|
||
|
"\\Storage Card\\Tremolo\\output2.pcm",
|
||
|
#ifdef _LOW_ACCURACY_
|
||
|
"\\Storage Card\\Tremolo\\outputL2.ref",
|
||
|
#else
|
||
|
"\\Storage Card\\Tremolo\\output2.ref",
|
||
|
#endif /* _LOW_ACCURACY_ */
|
||
|
NULL };
|
||
|
#endif
|
||
|
#if TESTFILE == 0
|
||
|
char *argv[] = { "testtremor",
|
||
|
"\\Storage Card\\Tremolo\\infile.ogg",
|
||
|
"\\Storage Card\\Tremolo\\output.pcm",
|
||
|
#ifdef _LOW_ACCURACY_
|
||
|
"\\Storage Card\\Tremolo\\outputL.ref",
|
||
|
#else
|
||
|
"\\Storage Card\\Tremolo\\output.ref",
|
||
|
#endif /* _LOW_ACCURACY_ */
|
||
|
NULL };
|
||
|
#endif
|
||
|
return main(4, argv);
|
||
|
}
|
||
|
#endif
|
||
|
|