From 86db9e1fc4dd5eacefff7bd2bdc764d170f27e29 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Sat, 2 Dec 2006 08:47:11 +0000 Subject: [PATCH] updated ac97snd git-svn-id: svn://kolibrios.org@228 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/media/ac97snd/trunk/ac97.sln | 6 + programs/media/ac97snd/trunk/ac97wav.c | 302 +-- programs/media/ac97snd/trunk/crt.c | 10 +- programs/media/ac97snd/trunk/k_lib.asm | 194 +- programs/media/ac97snd/trunk/kolibri.h | 7 +- programs/media/ac97snd/trunk/mpg/common.c | 136 ++ programs/media/ac97snd/trunk/mpg/dct64_i386.c | 337 +++ programs/media/ac97snd/trunk/mpg/dct64_i486.c | 342 +++ .../media/ac97snd/trunk/mpg/decode_i386.c | 259 +++ .../media/ac97snd/trunk/mpg/decode_i486.c | 255 +++ programs/media/ac97snd/trunk/mpg/e_pow.c | 358 +++ programs/media/ac97snd/trunk/mpg/getbits.c | 134 ++ programs/media/ac97snd/trunk/mpg/getbits.h | 45 + programs/media/ac97snd/trunk/mpg/huffman.h | 340 +++ programs/media/ac97snd/trunk/mpg/l2tables.h | 164 ++ programs/media/ac97snd/trunk/mpg/layer1.c | 151 ++ programs/media/ac97snd/trunk/mpg/layer2.c | 306 +++ programs/media/ac97snd/trunk/mpg/layer3.c | 1953 +++++++++++++++++ programs/media/ac97snd/trunk/mpg/layer3.h | 17 + .../media/ac97snd/trunk/mpg/math_private.h | 209 ++ programs/media/ac97snd/trunk/mpg/mpg.vcproj | 365 +++ programs/media/ac97snd/trunk/mpg/mpg123.h | 358 +++ programs/media/ac97snd/trunk/mpg/readers.c | 880 ++++++++ programs/media/ac97snd/trunk/mpg/tabinit.c | 159 ++ 24 files changed, 7058 insertions(+), 229 deletions(-) create mode 100644 programs/media/ac97snd/trunk/mpg/common.c create mode 100644 programs/media/ac97snd/trunk/mpg/dct64_i386.c create mode 100644 programs/media/ac97snd/trunk/mpg/dct64_i486.c create mode 100644 programs/media/ac97snd/trunk/mpg/decode_i386.c create mode 100644 programs/media/ac97snd/trunk/mpg/decode_i486.c create mode 100644 programs/media/ac97snd/trunk/mpg/e_pow.c create mode 100644 programs/media/ac97snd/trunk/mpg/getbits.c create mode 100644 programs/media/ac97snd/trunk/mpg/getbits.h create mode 100644 programs/media/ac97snd/trunk/mpg/huffman.h create mode 100644 programs/media/ac97snd/trunk/mpg/l2tables.h create mode 100644 programs/media/ac97snd/trunk/mpg/layer1.c create mode 100644 programs/media/ac97snd/trunk/mpg/layer2.c create mode 100644 programs/media/ac97snd/trunk/mpg/layer3.c create mode 100644 programs/media/ac97snd/trunk/mpg/layer3.h create mode 100644 programs/media/ac97snd/trunk/mpg/math_private.h create mode 100644 programs/media/ac97snd/trunk/mpg/mpg.vcproj create mode 100644 programs/media/ac97snd/trunk/mpg/mpg123.h create mode 100644 programs/media/ac97snd/trunk/mpg/readers.c create mode 100644 programs/media/ac97snd/trunk/mpg/tabinit.c diff --git a/programs/media/ac97snd/trunk/ac97.sln b/programs/media/ac97snd/trunk/ac97.sln index f0751f6193..5d014c2e95 100644 --- a/programs/media/ac97snd/trunk/ac97.sln +++ b/programs/media/ac97snd/trunk/ac97.sln @@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pow_test", "pow_test\pow_te EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ac97", "ac97\ac97.vcproj", "{1C94A897-DA4F-45B2-B8A6-B97AD837828E}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpg", "mpg\mpg.vcproj", "{CF807B93-2860-41DF-A4D2-5B92B52DFD96}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -31,6 +33,10 @@ Global {1C94A897-DA4F-45B2-B8A6-B97AD837828E}.Debug|Win32.Build.0 = Debug|Win32 {1C94A897-DA4F-45B2-B8A6-B97AD837828E}.Release|Win32.ActiveCfg = Release|Win32 {1C94A897-DA4F-45B2-B8A6-B97AD837828E}.Release|Win32.Build.0 = Release|Win32 + {CF807B93-2860-41DF-A4D2-5B92B52DFD96}.Debug|Win32.ActiveCfg = Debug|Win32 + {CF807B93-2860-41DF-A4D2-5B92B52DFD96}.Debug|Win32.Build.0 = Debug|Win32 + {CF807B93-2860-41DF-A4D2-5B92B52DFD96}.Release|Win32.ActiveCfg = Release|Win32 + {CF807B93-2860-41DF-A4D2-5B92B52DFD96}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/programs/media/ac97snd/trunk/ac97wav.c b/programs/media/ac97snd/trunk/ac97wav.c index 1056641779..d3415ceaa4 100644 --- a/programs/media/ac97snd/trunk/ac97wav.c +++ b/programs/media/ac97snd/trunk/ac97wav.c @@ -14,15 +14,20 @@ // GNU General Public License for more details. #include "kolibri.h" -#include "stdio.h" +//#include "stdio.h" #include "string.h" #include "ac97wav.h" -#include "mp3dec/mp3dec.h" +#include "mpg/mpg123.h" + +#define MP3_ERROR_OUT_OF_BUFFER 5 +int m_last_error; void thread_proc(); void touch(char *buf, int size); +int mp3FindSync(byte* buf, int size, int* sync); +int stream_read_raw(struct reader *rd,unsigned char *buf, int size); -extern char *__argv; +char *fname; //extern char __path; @@ -40,6 +45,10 @@ char formats[37][12] = "PCM_2_8_11","PCM_1_8_11","PCM_2_8_8","PCM_1_8_8" }; *******/ +//int freqs[9] = {44100,48000,32000,22050,24000,16000 ,11025 ,12000 ,8000}; + +struct reader rd; +struct frame fr; DWORD hDrv; DWORD hSound; @@ -55,20 +64,22 @@ DWORD status; DWORD offset; DWORD first_sync; -char *testbuff; -char *outbuf; -char *inpbuf; +unsigned char *testbuff; +unsigned char *outbuf; +unsigned char *inpbuf; +unsigned char *outPtr; + int inpsize; int outsize; +int outremain; +int totalout; +int done; char srv_name[] = "INFINITY"; char srv_intel[] = "SOUND"; char header[] = "AC97 MP3 player"; char buttons_text[]=" Play Stop << >> Vol- Vol+"; -MPEG_DECODE_INFO mpginfo; -MPEG_DECODE_PARAM param; - void (*snd_play)(); void draw_window() @@ -88,8 +99,8 @@ void draw_window() draw_bar(7,41,286,11,0x404040); draw_bar(7,55,286,11,0x404040); - write_text(12,58,0x004000|FONT0, __argv, strlen(__argv)); - write_text(11,57,0x00FF20|FONT0, __argv, strlen(__argv)); + write_text(12,58,0x004000|FONT0, fname, strlen(fname)); + write_text(11,57,0x00FF20|FONT0, fname, strlen(fname)); write_text(8,8,0xFFFFFF|FONT0, header, strlen(header)); write_text(12,28,0x404040|FONT0,buttons_text,strlen(buttons_text)); @@ -100,7 +111,7 @@ void draw_window() void draw_progress_bar() { DWORD x; - x = 286.0f * (float)offset/(float)fileinfo.size; + x = 286.0f * (float)(rd.filepos-rd.strremain)/(float)fileinfo.size; if(x==0) return; draw_bar(7,41,x,11,0xA0A0A0); draw_bar(x+7,41,286-x,11,0x404040); @@ -115,18 +126,21 @@ void debug_out_str(char* str) } } -int main() //int argc, char *argv[]) +int main(int argc, char *argv[]) //int argc, char *argv[]) { DWORD fmt; char *thread_stack; DWORD r_bytes; int retval; + fname = argv[1]; + //debug_out_str(fname); + InitHeap(1024*1024); - if(get_fileinfo(__argv, &fileinfo)==FILE_NOT_FOUND) + if(get_fileinfo(fname, &fileinfo)==FILE_NOT_FOUND) return 0; if((hDrv=GetService(srv_intel))==0) - return 0; + return 0; if ((hSound=GetService(srv_name))==0) return 0; @@ -139,35 +153,38 @@ int main() //int argc, char *argv[]) SetMasterVol(hDrv,m_vol); }; - _asm {fninit}; - mp3DecodeInit(); - testbuff = UserAlloc(4096); - get_fileinfo(__argv, &fileinfo); + get_fileinfo(fname, &fileinfo); offset = 0; - retval=read_file (__argv,testbuff,0,2048,&r_bytes); + retval=read_file (fname,testbuff,0,2048,&r_bytes); if (retval) return 0; + + inpbuf = UserAlloc(0x10000); + touch(inpbuf, 0x10000); + create_reader(&rd, inpbuf, 0x10000); + init_reader(&rd,fname); + fmt = test_wav((WAVEHEADER*)testbuff); if (fmt != 0) { snd_play = &play_wave; + set_reader(&rd, 44); outbuf = UserAlloc(32*1024); touch(outbuf, 32768); - offset = 44; } else - { fmt = test_mp3(testbuff); - if(fmt ==0) return 0; - snd_play = &play_mp3; + { fmt = test_mp3(testbuff); + if(fmt ==0) return 0; + snd_play = &play_mp3; - inpsize = mpginfo.maxInputSize*30; - inpbuf = UserAlloc(inpsize); - touch(inpbuf, inpsize); - outsize = mpginfo.outputSize*30+0x10000; - outbuf = UserAlloc(outsize); - touch(outbuf, outsize); - first_sync = offset; + outremain = 0x40000 ; + outbuf = UserAlloc(outremain); + touch(outbuf, outremain); + make_decode_tables(32767); + init_layer2(); + init_layer3(SBLIMIT); + fr.single = -1; }; status = ST_PLAY; @@ -202,134 +219,129 @@ int main() //int argc, char *argv[]) void touch(char *buf, int size) { int i; + char a; for ( i = 0;i < size; i+=4096) - buf[i] = 0; + a = buf[i]; }; DWORD test_mp3(char *buf) -{ int retval; - int sync; +{ unsigned long hdr; WAVEHEADER whdr; - DWORD r_bytes=2048; - for (;;) - { - if (!mp3FindSync(buf, 2048, &sync)) - offset+= 2048; - else break; - - if (offset >= fileinfo.size || offset >= 102400) - return 0; - - retval = read_file (__argv,buf,offset,2048,&r_bytes); - if(retval != 0) return 0; - }; - offset+=sync; - retval = read_file (__argv,buf,offset,2048,&r_bytes); - if(retval != 0) return 0; - - mp3GetDecodeInfo(buf, r_bytes, &mpginfo, 1); + while (1) + { if(rd.filepos > 102400) + return 0; + if(!rd.head_read(&rd,&hdr)) + return 0; + if(!decode_header(&fr,hdr)) + { rd.strpos-=3; + rd.stream-=3; + rd.strremain+=3; + continue; + }; + break; + }; + + first_sync = rd.filepos-rd.strremain-4; + whdr.riff_id = 0x46464952; whdr.riff_format = 0x45564157; whdr.wFormatTag = 0x01; - whdr.nSamplesPerSec = mpginfo.frequency; - whdr.nChannels = mpginfo.channels; - whdr.wBitsPerSample = mpginfo.bitsPerSample; + whdr.nSamplesPerSec = freqs[fr.sampling_frequency]; + whdr.nChannels = 2; //mpginfo.channels; + whdr.wBitsPerSample = 16; return test_wav(&whdr); }; + void wave_out(char* buff) -{ DWORD ev[2]; +{ DWORD ev[6]; GetNotify(&ev[0]); SetBuffer(hSound,hBuff,buff,ev[1],0x8000); } void play_mp3() -{ int retval; - DWORD r_bytes; - char *inpPtr; - char *outPtr; - int inpBytes; +{ char *outPtr; int totalout; - - offset = first_sync; - - retval = read_file (__argv,inpbuf,offset,inpsize,&r_bytes); - if(retval != 0) - { status = ST_STOP; - return ; - }; - offset+=inpsize; + int outcount; + + set_reader(&rd, first_sync); - mp3DecodeStart(inpbuf, inpsize); - - inpPtr = inpbuf+mpginfo.skipSize; - inpBytes = inpsize-mpginfo.skipSize; outPtr = outbuf; totalout=0; - + done = 0; + memset(outbuf,0,0x10000); SetBuffer(hSound,hBuff,outbuf,0,0x10000); PlayBuffer(hSound, hBuff); - _asm { fninit } - while(1) { if(status!=ST_PLAY) break; - for(;;) - { param.inputBuf = inpPtr; - param.inputSize = inpBytes; - param.outputBuf = outPtr; - - if(!mp3DecodeFrame(¶m)) - if( mp3GetLastError()== MP3_ERROR_OUT_OF_BUFFER) - break; - - inpPtr += param.inputSize; - inpBytes -= param.inputSize; - outPtr+=param.outputSize; - totalout+=param.outputSize; - }; - memmove(inpbuf, inpPtr, inpBytes); - retval = read_file(__argv, &inpbuf[inpBytes],offset, inpsize-inpBytes, &r_bytes); - offset+=r_bytes; - - if (r_bytes== 0) break; - - inpPtr = inpbuf; - inpBytes += r_bytes; - if(totalout < 32768) continue; - - outPtr = outbuf; - while (totalout > 32768) - { wave_out(outPtr); - totalout-=0x8000; - outPtr+=0x8000; - }; - memmove(outbuf,outPtr, totalout); - outPtr = outbuf+totalout; + for(;;) + { outcount = 0; + if( !read_frame(&rd, &fr)) + { done = 1; + break; + }; + fr.do_layer(&fr, outPtr,&outcount); + outPtr+= outcount; + totalout+=outcount; + outremain-=outcount; + if(outremain < outcount*2) + break; }; + + if(done) + { if(totalout < 32768) + { memset(outPtr,0,32768-totalout); + totalout = 32768; + }; + }; + if(totalout < 32768) + continue; +/* + _asm + { push edx + push eax + mov eax, 0xFF + mov edx, 0x400 + out dx, al + pop eax + pop edx + }; +*/ + outPtr = outbuf; + while (totalout > 32768) + { wave_out(outPtr); + totalout-=0x8000; + outPtr+=0x8000; + outremain+=0x8000; + }; + if(done) break; + memmove(outbuf,outPtr, totalout); + outPtr = outbuf+totalout; + } + if(status != ST_EXIT) status = ST_STOP; }; void play_wave() -{ +{ DWORD ev[6]; int retval; int remain; int i; - offset = 44; +// offset = 44; - read_file (__argv,outbuf,offset,32*1024,0); - offset+=32*1024; +// read_file (fname,outbuf,offset,32*1024,0); +// offset+=32*1024; + stream_read_raw(&rd,outbuf,32768); SetBuffer(hSound,hBuff,outbuf,0,0x8000); - - read_file (__argv,outbuf,offset,32*1024,0); - offset+=32*1024; + stream_read_raw(&rd,outbuf,32768); SetBuffer(hSound,hBuff,outbuf,0x8000,0x8000); PlayBuffer(hSound, hBuff); @@ -337,28 +349,14 @@ void play_wave() retval = 0; while(1) { - if(status!=ST_PLAY) - break; + if(status!=ST_PLAY) + break; - GetNotify(&event[0]); - if(retval == FILE_EOF) - break; - remain = fileinfo.size-offset; - if(remain >=32768) - { retval = read_file (__argv,outbuf,offset,32*1024,0); - offset+=32*1024; - SetBuffer(hSound,hBuff,outbuf,event[1],0x8000); - continue; - }; - if(remain == 0) - { retval = FILE_EOF; - continue; - }; - read_file (__argv,outbuf,offset,remain,0); - for(i=remain;i<32768;i++) - outbuf[i] = 0; - SetBuffer(hSound,hBuff,outbuf,event[1],0x8000); - retval= FILE_EOF; + if( !stream_read_raw(&rd,outbuf,32768)) + { done = 1; + break; + }; + wave_out(outbuf); }; if(status != ST_EXIT) @@ -371,7 +369,7 @@ void snd_stop() }; void thread_proc() -{ int evnt; +{ int evnt; int pos; int key; @@ -449,10 +447,11 @@ void thread_proc() case 0x30: if(status==ST_DONE) break; - if(snd_play == play_mp3) - continue; +// if(snd_play == play_mp3) +// continue; pos = (GetMousePos(REL_WINDOW)>>16)-7; offset = ((fileinfo.size-44)/286*pos+44)&0xFFFFFFFC; + set_reader(&rd, offset); draw_progress_bar(); break; }; @@ -632,7 +631,8 @@ int wait_for_event(int time) }; int wait_for_event_infinite() -{ int retval; +{ void *a; + int retval; _asm { mov eax,10 int 0x40 @@ -657,8 +657,10 @@ void EndDraw() }; }; -void * __cdecl memmove ( void * dst, const void * src, size_t count) -{ void * ret = dst; +///********* +void *memmove ( void * dst, void * src, int count) +{ void *ret; + ret = dst; if (dst <= src || (char *)dst >= ((char *)src + count)) { @@ -678,11 +680,19 @@ void * __cdecl memmove ( void * dst, const void * src, size_t count) src = (char *)src - 1; } } - return(ret); + return ret; }; +//**********/ - - +void * __cdecl mem_cpy(void * dst,const void * src,size_t count) +{ void * ret = dst; + while (count--) + { *(char *)dst = *(char *)src; + dst = (char *)dst + 1; + src = (char *)src + 1; + }; + return(ret); +} // debug_out_str(formats[fmt]); // debug_out_str("\x0D\x0A\x00"); diff --git a/programs/media/ac97snd/trunk/crt.c b/programs/media/ac97snd/trunk/crt.c index 800763bbed..24000393e3 100644 --- a/programs/media/ac97snd/trunk/crt.c +++ b/programs/media/ac97snd/trunk/crt.c @@ -4,10 +4,12 @@ char pureCallMessage[] = "PURE function call!"; -char *__argv = 0; +char *__argv[2]; +int __argc; void (__cdecl *atExitList[atexitBufferSize])(); int atExitFnNum = 0; +int main(int argc, char *argv[]); void exit() { int i; @@ -62,8 +64,10 @@ void crtStartUp() if ( *pbegin != 0 ) (**pbegin)(); } - __argv = *((char **)0x1C); - main(); + __argc = 2; + __argv[0] = *((char **)0x20); + __argv[1] = *((char **)0x1C); + main(__argc, __argv); exit(); } diff --git a/programs/media/ac97snd/trunk/k_lib.asm b/programs/media/ac97snd/trunk/k_lib.asm index 257d9947ef..1decdc6e55 100644 --- a/programs/media/ac97snd/trunk/k_lib.asm +++ b/programs/media/ac97snd/trunk/k_lib.asm @@ -1,19 +1,3 @@ -; -; This file is part of the AC97 mp3 player. -; (C) copyright Serge 2006 -; email: infinity_sound@mail.ru -; -; This program is free software; you can redistribute it and/or modify -; it under the terms of the GNU General Public License as published by -; the Free Software Foundation; either version 2 of the License, or -; (at your option) any later version. -; -; This program is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. - - format MS COFF include "proc32.inc" @@ -63,27 +47,27 @@ struc CTRL_INFO .irq dd ? .glob_cntrl dd ? .glob_sta dd ? - .codec_io_base dd ? - .ctrl_io_base dd ? - .codec_mem_base dd ? - .ctrl_mem_base dd ? + .codec_io_base dd ? + .ctrl_io_base dd ? + .codec_mem_base dd ? + .ctrl_mem_base dd ? .codec_id dd ? } CTRL_INFO_SIZE equ 9*4 -SND_CREATE_DEV equ 1 -SND_CREATE_BUFF equ 2 -SND_PLAY equ 3 -SND_STOP equ 4 -SND_SETBUFF equ 5 +SND_CREATE_DEV equ 1 +SND_CREATE_BUFF equ 2 +SND_PLAY equ 3 +SND_STOP equ 4 +SND_SETBUFF equ 5 SND_DESTROY_BUFF equ 6 -DEV_SET_BUFF equ 4 -DEV_NOTIFY equ 5 -DEV_SET_MASTERVOL equ 6 -DEV_GET_MASTERVOL equ 7 -DEV_GET_INFO equ 8 +DEV_SET_BUFF equ 4 +DEV_NOTIFY equ 5 +DEV_SET_MASTERVOL equ 6 +DEV_GET_MASTERVOL equ 7 +DEV_GET_INFO equ 8 align 4 @@ -170,35 +154,46 @@ endp align 4 proc _InitHeap@4 stdcall, heap_size:dword - push ebx - mov eax, 68 - mov ebx, 11 + push ebx + mov eax, 68 + mov ebx, 11 mov ecx, [heap_size] - int 0x40 - pop ebx - ret + int 0x40 + pop ebx + ret endp align 4 proc _UserAlloc@4 stdcall, alloc_size:dword - push ebx - mov eax, 68 - mov ebx, 12 + push ebx + mov eax, 68 + mov ebx, 12 mov ecx, [alloc_size] - int 0x40 - pop ebx - ret + int 0x40 + pop ebx + ret endp +;align 4 +;proc _GetNotify@4 stdcall, p_ev:dword +; push ebx +; mov eax, 68 +; mov ebx, 14 +; mov ecx, [p_ev] +; int 0x40 +; pop ebx +; ret +;endp + align 4 proc _GetNotify@4 stdcall, p_ev:dword - push ebx - mov eax, 68 - mov ebx, 14 - mov ecx, [p_ev] - int 0x40 - pop ebx - ret + push ebx + mov eax, 68 + mov ebx, 14 + mov ecx, [p_ev] + int 0x40 + pop ebx + ret endp align 4 @@ -208,9 +203,9 @@ proc _CreateThread@8 stdcall, fn:dword, p_stack:dword mov ebx, 1 mov ecx, [fn] mov edx,[p_stack] - int 0x40 - pop ebx - ret + int 0x40 + pop ebx + ret endp align 4 @@ -218,31 +213,31 @@ proc _GetMousePos@4 stdcall,rel_type:dword push ebx mov eax, 37 mov ebx, [rel_type] - int 0x40 - pop ebx - ret + int 0x40 + pop ebx + ret endp align 4 proc CallServiceEx stdcall, ioctl:dword - push ebx - mov eax, 68 - mov ebx, 17 + push ebx + mov eax, 68 + mov ebx, 17 mov ecx, [ioctl] - int 0x40 - pop ebx - ret + int 0x40 + pop ebx + ret endp align 4 proc _GetService@4 stdcall, name:dword push ebx mov eax, 68 - mov ebx, 16 + mov ebx, 16 mov ecx, [name] - int 0x40 - pop ebx - ret + int 0x40 + pop ebx + ret endp align 4 @@ -271,7 +266,7 @@ proc _GetDevInfo@8 stdcall, hSrv:dword, p_info:dword lea eax, [handle] stdcall CallServiceEx, eax pop ebx - ret + ret endp align 4 @@ -299,7 +294,7 @@ proc _GetMasterVol@8 stdcall, hSrv:dword,pvol:dword lea eax, [handle] stdcall CallServiceEx, eax pop ebx - ret + ret endp align 4 @@ -328,7 +323,7 @@ proc _SetMasterVol@8 stdcall,hSrv:dword,vol:dword lea eax, [handle] stdcall CallServiceEx, eax pop ebx - ret + ret endp align 4 @@ -357,7 +352,7 @@ proc _CreateBuffer@8 stdcall, hSound:dword,format:dword lea eax, [handle] stdcall CallServiceEx, eax pop ebx - ret + ret endp align 4 @@ -386,7 +381,7 @@ proc _DestroyBuffer@8 stdcall, hSound:dword, str:dword lea eax, [handle] stdcall CallServiceEx, eax pop ebx - ret + ret endp align 4 @@ -415,7 +410,7 @@ proc _SetBuffer@20 stdcall,hSound:dword, str:dword, src:dword, offs:dword, size: lea eax, [handle] stdcall CallServiceEx, eax pop ebx - ret + ret endp align 4 @@ -444,7 +439,7 @@ proc _PlayBuffer@8 stdcall, hSound:dword, str:dword lea eax, [handle] stdcall CallServiceEx, eax pop ebx - ret + ret endp align 4 @@ -564,10 +559,10 @@ _write_text@20: align 4 proc _debug_out@4 stdcall, val:dword push ebx - mov ecx,[val] - mov ebx,1 - mov eax,63 - int 0x40 + mov ecx,[val] + mov ebx,1 + mov eax,63 + int 0x40 pop ebx ret endp @@ -633,7 +628,7 @@ dwords: shr ecx,2 jz tail - cld + cld rep stosd main_loop_tail: test edx,edx @@ -658,6 +653,51 @@ toend: ret +public _allmul + +_allmul: + mov eax, [esp+8] + mov ecx, [esp+16] + or ecx,eax + mov ecx, [esp+12] + jnz .hard + mov eax, [esp+4] + mul ecx + ret 16 +.hard: + push ebx + mul ecx + mov ebx,eax + mov eax, [esp+8] + mul dword [esp+20] + add ebx,eax + mov eax,[esp+8] + mul ecx + add edx,ebx + pop ebx + ret 16 + +align 4 +_allshr: + cmp cl,64 + jae .sign + + cmp cl, 32 + jae .MORE32 + shrd eax,edx,cl + sar edx,cl + ret +.MORE32: + mov eax,edx + sar edx,31 + and cl,31 + sar eax,cl + ret +.sign: + sar edx,31 + mov eax,edx + ret + public __ftol2_sse align 4 diff --git a/programs/media/ac97snd/trunk/kolibri.h b/programs/media/ac97snd/trunk/kolibri.h index f2711e74ca..6f28bbe2a6 100644 --- a/programs/media/ac97snd/trunk/kolibri.h +++ b/programs/media/ac97snd/trunk/kolibri.h @@ -67,6 +67,7 @@ typedef struct DWORD mod_time; DWORD mod_date; DWORD size; + DWORD size_high; } FILEINFO; void _stdcall InitHeap(int heap_size); @@ -93,15 +94,15 @@ int _stdcall get_fileinfo(char *name,FILEINFO* pinfo); int _stdcall read_file (char *name,char*buff,int offset,int count,int *reads); void exit(); -int get_key(void); -int get_button_id(); +int _cdecl get_key(void); +int _cdecl get_button_id(); void delay(int val); int wait_for_event(int time); int wait_for_event_infinite(); void BeginDraw(void); void EndDraw(void); void _stdcall DrawWindow(int x,int y, int sx, int sy,int workcolor,int style, - int captioncolor,int windowtype,int bordercolor); + int captioncolor,int windowtype,int bordercolor); void _stdcall debug_out(int ch); void _stdcall make_button(int x, int y, int xsize, int ysize, int id, int color); void _stdcall draw_bar(int x, int y, int xsize, int ysize, int color); diff --git a/programs/media/ac97snd/trunk/mpg/common.c b/programs/media/ac97snd/trunk/mpg/common.c new file mode 100644 index 0000000000..45ed69ae44 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/common.c @@ -0,0 +1,136 @@ +#include +#include "mpg123.h" + +int tabsel_123[2][3][16] = { + { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,}, + {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,}, + {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} }, + + { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} } +}; + +long freqs[9] = { 44100, 48000, 32000, + 22050, 24000, 16000 , + 11025 , 12000 , 8000 }; + +#define HDRCMPMASK 0xfffffd00 + +struct bitstream_info bsi; + +int ssize; + +unsigned long read_header(BYTE *mpeg) +{ unsigned long hdr; + + hdr = *mpeg++; + hdr <<= 8; + hdr |= *mpeg++; + hdr <<= 8; + hdr |= *mpeg++; + hdr <<= 8; + hdr |= *mpeg++; + return hdr; +}; + +int head_check(unsigned long head) +{ + if( (head & 0xffe00000) != 0xffe00000) + return FALSE; + if(!((head>>17)&3)) + return FALSE; + if( ((head>>12)&0xf) == 0xf) + return FALSE; + if( ((head>>10)&0x3) == 0x3 ) + return FALSE; + return TRUE; +} + +int decode_header(struct frame *fr,unsigned long newhead) +{ + if( newhead & (1<<20) ) { + fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1; + fr->mpeg25 = 0; + } + else { + fr->lsf = 1; + fr->mpeg25 = 1; + } + + fr->lay = 4-((newhead>>17)&3); + if( ((newhead>>10)&0x3) == 0x3) { + fprintf(stderr,"Stream error, reserved sampling rate\n"); + return 0; + } + if(fr->mpeg25) { + fr->sampling_frequency = 6 + ((newhead>>10)&0x3); + } + else + fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3); + fr->error_protection = ((newhead>>16)&0x1)^0x1; + + if(fr->mpeg25) /* allow Bitrate change for 2.5 ... */ + fr->bitrate_index = ((newhead>>12)&0xf); + + fr->bitrate_index = ((newhead>>12)&0xf); + fr->padding = ((newhead>>9)&0x1); + fr->extension = ((newhead>>8)&0x1); + fr->mode = ((newhead>>6)&0x3); + fr->mode_ext = ((newhead>>4)&0x3); + fr->copyright = ((newhead>>3)&0x1); + fr->original = ((newhead>>2)&0x1); + fr->emphasis = newhead & 0x3; + + fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2; + + if(!fr->bitrate_index) + { + fprintf(stderr, "Stream error, free format bitrate index not supported\n"); + return 0; + } + + switch(fr->lay) + { + case 1: + fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? + (fr->mode_ext<<2)+4 : 32; + fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000; + fr->framesize /= freqs[fr->sampling_frequency]; + fr->framesize = ((fr->framesize+fr->padding)<<2)-4; + break; + case 2: + fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? + (fr->mode_ext<<2)+4 : fr->II_sblimit; + fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000; + fr->framesize /= freqs[fr->sampling_frequency]; + fr->framesize += fr->padding - 4; + break; + + case 3: + fr->do_layer = do_layer3; + if(fr->lsf) + ssize = (fr->stereo == 1) ? 9 : 17; + else + ssize = (fr->stereo == 1) ? 17 : 32; + + if(fr->error_protection) + ssize += 2; + fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000; + fr->framesize /= freqs[fr->sampling_frequency]<<(fr->lsf); + fr->framesize = fr->framesize + fr->padding - 4; + break; + default: + return (0); + } + return 1; +} + +//void set_pointer(long backstep) +//{ +// bsi.wordpointer = bsbuf + ssize - backstep; +// if (backstep) +// memcpy(bsi.wordpointer,bsbufold+fsizeold-backstep,backstep); +// bsi.bitindex = 0; +//} + diff --git a/programs/media/ac97snd/trunk/mpg/dct64_i386.c b/programs/media/ac97snd/trunk/mpg/dct64_i386.c new file mode 100644 index 0000000000..dd852084a1 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/dct64_i386.c @@ -0,0 +1,337 @@ +/* + dct64_i386.c: DCT64, a C variant for i386 + + copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Michael Hipp +*/ + +/* + * Discrete Cosine Tansform (DCT) for subband synthesis + * optimized for machines with no auto-increment. + * The performance is highly compiler dependend. Maybe + * the dct64.c version for 'normal' processor may be faster + * even for Intel processors. + */ + +//#include "config.h" +#include "mpg123.h" + +static void dct64_1(real *out0,real *out1,real *b1,real *b2,real *samples) +{ + { + register real *costab = pnts[0]; + + b1[0x00] = samples[0x00] + samples[0x1F]; + b1[0x01] = samples[0x01] + samples[0x1E]; + b1[0x1F] = (samples[0x00] - samples[0x1F]) * costab[0x0]; + b1[0x1E] = (samples[0x01] - samples[0x1E]) * costab[0x1]; + + b1[0x02] = samples[0x02] + samples[0x1D]; + b1[0x03] = samples[0x03] + samples[0x1C]; + b1[0x1D] = (samples[0x02] - samples[0x1D]) * costab[0x2]; + b1[0x1C] = (samples[0x03] - samples[0x1C]) * costab[0x3]; + + b1[0x04] = samples[0x04] + samples[0x1B]; + b1[0x05] = samples[0x05] + samples[0x1A]; + b1[0x1B] = (samples[0x04] - samples[0x1B]) * costab[0x4]; + b1[0x1A] = (samples[0x05] - samples[0x1A]) * costab[0x5]; + + b1[0x06] = samples[0x06] + samples[0x19]; + b1[0x07] = samples[0x07] + samples[0x18]; + b1[0x19] = (samples[0x06] - samples[0x19]) * costab[0x6]; + b1[0x18] = (samples[0x07] - samples[0x18]) * costab[0x7]; + + b1[0x08] = samples[0x08] + samples[0x17]; + b1[0x09] = samples[0x09] + samples[0x16]; + b1[0x17] = (samples[0x08] - samples[0x17]) * costab[0x8]; + b1[0x16] = (samples[0x09] - samples[0x16]) * costab[0x9]; + + b1[0x0A] = samples[0x0A] + samples[0x15]; + b1[0x0B] = samples[0x0B] + samples[0x14]; + b1[0x15] = (samples[0x0A] - samples[0x15]) * costab[0xA]; + b1[0x14] = (samples[0x0B] - samples[0x14]) * costab[0xB]; + + b1[0x0C] = samples[0x0C] + samples[0x13]; + b1[0x0D] = samples[0x0D] + samples[0x12]; + b1[0x13] = (samples[0x0C] - samples[0x13]) * costab[0xC]; + b1[0x12] = (samples[0x0D] - samples[0x12]) * costab[0xD]; + + b1[0x0E] = samples[0x0E] + samples[0x11]; + b1[0x0F] = samples[0x0F] + samples[0x10]; + b1[0x11] = (samples[0x0E] - samples[0x11]) * costab[0xE]; + b1[0x10] = (samples[0x0F] - samples[0x10]) * costab[0xF]; + + } + + + { + register real *costab = pnts[1]; + + b2[0x00] = b1[0x00] + b1[0x0F]; + b2[0x01] = b1[0x01] + b1[0x0E]; + b2[0x0F] = (b1[0x00] - b1[0x0F]) * costab[0]; + b2[0x0E] = (b1[0x01] - b1[0x0E]) * costab[1]; + + b2[0x02] = b1[0x02] + b1[0x0D]; + b2[0x03] = b1[0x03] + b1[0x0C]; + b2[0x0D] = (b1[0x02] - b1[0x0D]) * costab[2]; + b2[0x0C] = (b1[0x03] - b1[0x0C]) * costab[3]; + + b2[0x04] = b1[0x04] + b1[0x0B]; + b2[0x05] = b1[0x05] + b1[0x0A]; + b2[0x0B] = (b1[0x04] - b1[0x0B]) * costab[4]; + b2[0x0A] = (b1[0x05] - b1[0x0A]) * costab[5]; + + b2[0x06] = b1[0x06] + b1[0x09]; + b2[0x07] = b1[0x07] + b1[0x08]; + b2[0x09] = (b1[0x06] - b1[0x09]) * costab[6]; + b2[0x08] = (b1[0x07] - b1[0x08]) * costab[7]; + + /* */ + + b2[0x10] = b1[0x10] + b1[0x1F]; + b2[0x11] = b1[0x11] + b1[0x1E]; + b2[0x1F] = (b1[0x1F] - b1[0x10]) * costab[0]; + b2[0x1E] = (b1[0x1E] - b1[0x11]) * costab[1]; + + b2[0x12] = b1[0x12] + b1[0x1D]; + b2[0x13] = b1[0x13] + b1[0x1C]; + b2[0x1D] = (b1[0x1D] - b1[0x12]) * costab[2]; + b2[0x1C] = (b1[0x1C] - b1[0x13]) * costab[3]; + + b2[0x14] = b1[0x14] + b1[0x1B]; + b2[0x15] = b1[0x15] + b1[0x1A]; + b2[0x1B] = (b1[0x1B] - b1[0x14]) * costab[4]; + b2[0x1A] = (b1[0x1A] - b1[0x15]) * costab[5]; + + b2[0x16] = b1[0x16] + b1[0x19]; + b2[0x17] = b1[0x17] + b1[0x18]; + b2[0x19] = (b1[0x19] - b1[0x16]) * costab[6]; + b2[0x18] = (b1[0x18] - b1[0x17]) * costab[7]; + } + + { + register real *costab = pnts[2]; + + b1[0x00] = b2[0x00] + b2[0x07]; + b1[0x07] = (b2[0x00] - b2[0x07]) * costab[0]; + b1[0x01] = b2[0x01] + b2[0x06]; + b1[0x06] = (b2[0x01] - b2[0x06]) * costab[1]; + b1[0x02] = b2[0x02] + b2[0x05]; + b1[0x05] = (b2[0x02] - b2[0x05]) * costab[2]; + b1[0x03] = b2[0x03] + b2[0x04]; + b1[0x04] = (b2[0x03] - b2[0x04]) * costab[3]; + + b1[0x08] = b2[0x08] + b2[0x0F]; + b1[0x0F] = (b2[0x0F] - b2[0x08]) * costab[0]; + b1[0x09] = b2[0x09] + b2[0x0E]; + b1[0x0E] = (b2[0x0E] - b2[0x09]) * costab[1]; + b1[0x0A] = b2[0x0A] + b2[0x0D]; + b1[0x0D] = (b2[0x0D] - b2[0x0A]) * costab[2]; + b1[0x0B] = b2[0x0B] + b2[0x0C]; + b1[0x0C] = (b2[0x0C] - b2[0x0B]) * costab[3]; + + b1[0x10] = b2[0x10] + b2[0x17]; + b1[0x17] = (b2[0x10] - b2[0x17]) * costab[0]; + b1[0x11] = b2[0x11] + b2[0x16]; + b1[0x16] = (b2[0x11] - b2[0x16]) * costab[1]; + b1[0x12] = b2[0x12] + b2[0x15]; + b1[0x15] = (b2[0x12] - b2[0x15]) * costab[2]; + b1[0x13] = b2[0x13] + b2[0x14]; + b1[0x14] = (b2[0x13] - b2[0x14]) * costab[3]; + + b1[0x18] = b2[0x18] + b2[0x1F]; + b1[0x1F] = (b2[0x1F] - b2[0x18]) * costab[0]; + b1[0x19] = b2[0x19] + b2[0x1E]; + b1[0x1E] = (b2[0x1E] - b2[0x19]) * costab[1]; + b1[0x1A] = b2[0x1A] + b2[0x1D]; + b1[0x1D] = (b2[0x1D] - b2[0x1A]) * costab[2]; + b1[0x1B] = b2[0x1B] + b2[0x1C]; + b1[0x1C] = (b2[0x1C] - b2[0x1B]) * costab[3]; + } + + { + register real const cos0 = pnts[3][0]; + register real const cos1 = pnts[3][1]; + + b2[0x00] = b1[0x00] + b1[0x03]; + b2[0x03] = (b1[0x00] - b1[0x03]) * cos0; + b2[0x01] = b1[0x01] + b1[0x02]; + b2[0x02] = (b1[0x01] - b1[0x02]) * cos1; + + b2[0x04] = b1[0x04] + b1[0x07]; + b2[0x07] = (b1[0x07] - b1[0x04]) * cos0; + b2[0x05] = b1[0x05] + b1[0x06]; + b2[0x06] = (b1[0x06] - b1[0x05]) * cos1; + + b2[0x08] = b1[0x08] + b1[0x0B]; + b2[0x0B] = (b1[0x08] - b1[0x0B]) * cos0; + b2[0x09] = b1[0x09] + b1[0x0A]; + b2[0x0A] = (b1[0x09] - b1[0x0A]) * cos1; + + b2[0x0C] = b1[0x0C] + b1[0x0F]; + b2[0x0F] = (b1[0x0F] - b1[0x0C]) * cos0; + b2[0x0D] = b1[0x0D] + b1[0x0E]; + b2[0x0E] = (b1[0x0E] - b1[0x0D]) * cos1; + + b2[0x10] = b1[0x10] + b1[0x13]; + b2[0x13] = (b1[0x10] - b1[0x13]) * cos0; + b2[0x11] = b1[0x11] + b1[0x12]; + b2[0x12] = (b1[0x11] - b1[0x12]) * cos1; + + b2[0x14] = b1[0x14] + b1[0x17]; + b2[0x17] = (b1[0x17] - b1[0x14]) * cos0; + b2[0x15] = b1[0x15] + b1[0x16]; + b2[0x16] = (b1[0x16] - b1[0x15]) * cos1; + + b2[0x18] = b1[0x18] + b1[0x1B]; + b2[0x1B] = (b1[0x18] - b1[0x1B]) * cos0; + b2[0x19] = b1[0x19] + b1[0x1A]; + b2[0x1A] = (b1[0x19] - b1[0x1A]) * cos1; + + b2[0x1C] = b1[0x1C] + b1[0x1F]; + b2[0x1F] = (b1[0x1F] - b1[0x1C]) * cos0; + b2[0x1D] = b1[0x1D] + b1[0x1E]; + b2[0x1E] = (b1[0x1E] - b1[0x1D]) * cos1; + } + + { + register real const cos0 = pnts[4][0]; + + b1[0x00] = b2[0x00] + b2[0x01]; + b1[0x01] = (b2[0x00] - b2[0x01]) * cos0; + b1[0x02] = b2[0x02] + b2[0x03]; + b1[0x03] = (b2[0x03] - b2[0x02]) * cos0; + b1[0x02] += b1[0x03]; + + b1[0x04] = b2[0x04] + b2[0x05]; + b1[0x05] = (b2[0x04] - b2[0x05]) * cos0; + b1[0x06] = b2[0x06] + b2[0x07]; + b1[0x07] = (b2[0x07] - b2[0x06]) * cos0; + b1[0x06] += b1[0x07]; + b1[0x04] += b1[0x06]; + b1[0x06] += b1[0x05]; + b1[0x05] += b1[0x07]; + + b1[0x08] = b2[0x08] + b2[0x09]; + b1[0x09] = (b2[0x08] - b2[0x09]) * cos0; + b1[0x0A] = b2[0x0A] + b2[0x0B]; + b1[0x0B] = (b2[0x0B] - b2[0x0A]) * cos0; + b1[0x0A] += b1[0x0B]; + + b1[0x0C] = b2[0x0C] + b2[0x0D]; + b1[0x0D] = (b2[0x0C] - b2[0x0D]) * cos0; + b1[0x0E] = b2[0x0E] + b2[0x0F]; + b1[0x0F] = (b2[0x0F] - b2[0x0E]) * cos0; + b1[0x0E] += b1[0x0F]; + b1[0x0C] += b1[0x0E]; + b1[0x0E] += b1[0x0D]; + b1[0x0D] += b1[0x0F]; + + b1[0x10] = b2[0x10] + b2[0x11]; + b1[0x11] = (b2[0x10] - b2[0x11]) * cos0; + b1[0x12] = b2[0x12] + b2[0x13]; + b1[0x13] = (b2[0x13] - b2[0x12]) * cos0; + b1[0x12] += b1[0x13]; + + b1[0x14] = b2[0x14] + b2[0x15]; + b1[0x15] = (b2[0x14] - b2[0x15]) * cos0; + b1[0x16] = b2[0x16] + b2[0x17]; + b1[0x17] = (b2[0x17] - b2[0x16]) * cos0; + b1[0x16] += b1[0x17]; + b1[0x14] += b1[0x16]; + b1[0x16] += b1[0x15]; + b1[0x15] += b1[0x17]; + + b1[0x18] = b2[0x18] + b2[0x19]; + b1[0x19] = (b2[0x18] - b2[0x19]) * cos0; + b1[0x1A] = b2[0x1A] + b2[0x1B]; + b1[0x1B] = (b2[0x1B] - b2[0x1A]) * cos0; + b1[0x1A] += b1[0x1B]; + + b1[0x1C] = b2[0x1C] + b2[0x1D]; + b1[0x1D] = (b2[0x1C] - b2[0x1D]) * cos0; + b1[0x1E] = b2[0x1E] + b2[0x1F]; + b1[0x1F] = (b2[0x1F] - b2[0x1E]) * cos0; + b1[0x1E] += b1[0x1F]; + b1[0x1C] += b1[0x1E]; + b1[0x1E] += b1[0x1D]; + b1[0x1D] += b1[0x1F]; + } + + out0[0x10*16] = b1[0x00]; + out0[0x10*12] = b1[0x04]; + out0[0x10* 8] = b1[0x02]; + out0[0x10* 4] = b1[0x06]; + out0[0x10* 0] = b1[0x01]; + out1[0x10* 0] = b1[0x01]; + out1[0x10* 4] = b1[0x05]; + out1[0x10* 8] = b1[0x03]; + out1[0x10*12] = b1[0x07]; + +#if 1 + out0[0x10*14] = b1[0x08] + b1[0x0C]; + out0[0x10*10] = b1[0x0C] + b1[0x0a]; + out0[0x10* 6] = b1[0x0A] + b1[0x0E]; + out0[0x10* 2] = b1[0x0E] + b1[0x09]; + out1[0x10* 2] = b1[0x09] + b1[0x0D]; + out1[0x10* 6] = b1[0x0D] + b1[0x0B]; + out1[0x10*10] = b1[0x0B] + b1[0x0F]; + out1[0x10*14] = b1[0x0F]; +#else + b1[0x08] += b1[0x0C]; + out0[0x10*14] = b1[0x08]; + b1[0x0C] += b1[0x0a]; + out0[0x10*10] = b1[0x0C]; + b1[0x0A] += b1[0x0E]; + out0[0x10* 6] = b1[0x0A]; + b1[0x0E] += b1[0x09]; + out0[0x10* 2] = b1[0x0E]; + b1[0x09] += b1[0x0D]; + out1[0x10* 2] = b1[0x09]; + b1[0x0D] += b1[0x0B]; + out1[0x10* 6] = b1[0x0D]; + b1[0x0B] += b1[0x0F]; + out1[0x10*10] = b1[0x0B]; + out1[0x10*14] = b1[0x0F]; +#endif + + { + real tmp; + tmp = b1[0x18] + b1[0x1C]; + out0[0x10*15] = tmp + b1[0x10]; + out0[0x10*13] = tmp + b1[0x14]; + tmp = b1[0x1C] + b1[0x1A]; + out0[0x10*11] = tmp + b1[0x14]; + out0[0x10* 9] = tmp + b1[0x12]; + tmp = b1[0x1A] + b1[0x1E]; + out0[0x10* 7] = tmp + b1[0x12]; + out0[0x10* 5] = tmp + b1[0x16]; + tmp = b1[0x1E] + b1[0x19]; + out0[0x10* 3] = tmp + b1[0x16]; + out0[0x10* 1] = tmp + b1[0x11]; + tmp = b1[0x19] + b1[0x1D]; + out1[0x10* 1] = tmp + b1[0x11]; + out1[0x10* 3] = tmp + b1[0x15]; + tmp = b1[0x1D] + b1[0x1B]; + out1[0x10* 5] = tmp + b1[0x15]; + out1[0x10* 7] = tmp + b1[0x13]; + tmp = b1[0x1B] + b1[0x1F]; + out1[0x10* 9] = tmp + b1[0x13]; + out1[0x10*11] = tmp + b1[0x17]; + out1[0x10*13] = b1[0x17] + b1[0x1F]; + out1[0x10*15] = b1[0x1F]; + } +} + +/* + * the call via dct64 is a trick to force GCC to use + * (new) registers for the b1,b2 pointer to the bufs[xx] field + */ +void dct64(real *a,real *b,real *c) +{ + real bufs[0x40]; + dct64_1(a,b,bufs,bufs+0x20,c); +} + diff --git a/programs/media/ac97snd/trunk/mpg/dct64_i486.c b/programs/media/ac97snd/trunk/mpg/dct64_i486.c new file mode 100644 index 0000000000..c70ffe84ef --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/dct64_i486.c @@ -0,0 +1,342 @@ +/* + dct64_i486.c: DCT64, a plain C variant for i486 + + copyright 1998-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Fabrice Bellard +*/ + +/* Discrete Cosine Tansform (DCT) for subband synthesis. + * + * This code is optimized for 80486. It should be compiled with gcc + * 2.7.2 or higher. + * + * Note: This code does not give the necessary accuracy. Moreover, no + * overflow test are done. + * + * (c) 1998 Fabrice Bellard. + */ + +#include "mpg123.h" + +#define COS_0_0 16403 +#define COS_0_1 16563 +#define COS_0_2 16890 +#define COS_0_3 17401 +#define COS_0_4 18124 +#define COS_0_5 19101 +#define COS_0_6 20398 +#define COS_0_7 22112 +#define COS_0_8 24396 +#define COS_0_9 27503 +#define COS_0_10 31869 +#define COS_0_11 38320 +#define COS_0_12 48633 +#define COS_0_13 67429 +#define COS_0_14 111660 +#define COS_0_15 333906 +#define COS_1_0 16463 +#define COS_1_1 17121 +#define COS_1_2 18577 +#define COS_1_3 21195 +#define COS_1_4 25826 +#define COS_1_5 34756 +#define COS_1_6 56441 +#define COS_1_7 167154 +#define COS_2_0 16704 +#define COS_2_1 19704 +#define COS_2_2 29490 +#define COS_2_3 83981 +#define COS_3_0 17733 +#define COS_3_1 42813 +#define COS_4_0 23170 + +#define SETOUT(out,n,expr) out[FIR_BUFFER_SIZE*(n)]=(expr) +#define MULL(a,b) (((long)(a)*(long)(b)) >> 15) +#define MUL(a,b) \ +(\ + ((!(b & 0x3F)) ? (((a)*(b >> 6)) >> 9) :\ + ((!(b & 0x1F)) ? (((a)*(b >> 5)) >> 10) :\ + ((!(b & 0x0F)) ? (((a)*(b >> 4)) >> 11) :\ + ((!(b & 0x07)) ? (((a)*(b >> 3)) >> 12) :\ + ((!(b & 0x03)) ? (((a)*(b >> 2)) >> 13) :\ + ((!(b & 0x01)) ? (((a)*(b >> 1)) >> 14) :\ + (((a)*(b )) >> 15)))))))) + + +void dct64_1_486(int *out0,int *out1,int *b1,int *b2) +{ + b1[0x00] = b2[0x00] + b2[0x1F]; + b1[0x1F] = MUL((b2[0x00] - b2[0x1F]),COS_0_0); + + b1[0x01] = b2[0x01] + b2[0x1E]; + b1[0x1E] = MUL((b2[0x01] - b2[0x1E]),COS_0_1); + + b1[0x02] = b2[0x02] + b2[0x1D]; + b1[0x1D] = MUL((b2[0x02] - b2[0x1D]),COS_0_2); + + b1[0x03] = b2[0x03] + b2[0x1C]; + b1[0x1C] = MUL((b2[0x03] - b2[0x1C]),COS_0_3); + + b1[0x04] = b2[0x04] + b2[0x1B]; + b1[0x1B] = MUL((b2[0x04] - b2[0x1B]),COS_0_4); + + b1[0x05] = b2[0x05] + b2[0x1A]; + b1[0x1A] = MUL((b2[0x05] - b2[0x1A]),COS_0_5); + + b1[0x06] = b2[0x06] + b2[0x19]; + b1[0x19] = MUL((b2[0x06] - b2[0x19]),COS_0_6); + + b1[0x07] = b2[0x07] + b2[0x18]; + b1[0x18] = MUL((b2[0x07] - b2[0x18]),COS_0_7); + + b1[0x08] = b2[0x08] + b2[0x17]; + b1[0x17] = MUL((b2[0x08] - b2[0x17]),COS_0_8); + + b1[0x09] = b2[0x09] + b2[0x16]; + b1[0x16] = MUL((b2[0x09] - b2[0x16]),COS_0_9); + + b1[0x0A] = b2[0x0A] + b2[0x15]; + b1[0x15] = MUL((b2[0x0A] - b2[0x15]),COS_0_10); + + b1[0x0B] = b2[0x0B] + b2[0x14]; + b1[0x14] = MUL((b2[0x0B] - b2[0x14]),COS_0_11); + + b1[0x0C] = b2[0x0C] + b2[0x13]; + b1[0x13] = MUL((b2[0x0C] - b2[0x13]),COS_0_12); + + b1[0x0D] = b2[0x0D] + b2[0x12]; + b1[0x12] = MULL((b2[0x0D] - b2[0x12]),COS_0_13); + + b1[0x0E] = b2[0x0E] + b2[0x11]; + b1[0x11] = MULL((b2[0x0E] - b2[0x11]),COS_0_14); + + b1[0x0F] = b2[0x0F] + b2[0x10]; + b1[0x10] = MULL((b2[0x0F] - b2[0x10]),COS_0_15); + + + b2[0x00] = b1[0x00] + b1[0x0F]; + b2[0x0F] = MUL((b1[0x00] - b1[0x0F]),COS_1_0); + b2[0x01] = b1[0x01] + b1[0x0E]; + b2[0x0E] = MUL((b1[0x01] - b1[0x0E]),COS_1_1); + b2[0x02] = b1[0x02] + b1[0x0D]; + b2[0x0D] = MUL((b1[0x02] - b1[0x0D]),COS_1_2); + b2[0x03] = b1[0x03] + b1[0x0C]; + b2[0x0C] = MUL((b1[0x03] - b1[0x0C]),COS_1_3); + b2[0x04] = b1[0x04] + b1[0x0B]; + b2[0x0B] = MUL((b1[0x04] - b1[0x0B]),COS_1_4); + b2[0x05] = b1[0x05] + b1[0x0A]; + b2[0x0A] = MUL((b1[0x05] - b1[0x0A]),COS_1_5); + b2[0x06] = b1[0x06] + b1[0x09]; + b2[0x09] = MUL((b1[0x06] - b1[0x09]),COS_1_6); + b2[0x07] = b1[0x07] + b1[0x08]; + b2[0x08] = MULL((b1[0x07] - b1[0x08]),COS_1_7); + + b2[0x10] = b1[0x10] + b1[0x1F]; + b2[0x1F] = MUL((b1[0x1F] - b1[0x10]),COS_1_0); + b2[0x11] = b1[0x11] + b1[0x1E]; + b2[0x1E] = MUL((b1[0x1E] - b1[0x11]),COS_1_1); + b2[0x12] = b1[0x12] + b1[0x1D]; + b2[0x1D] = MUL((b1[0x1D] - b1[0x12]),COS_1_2); + b2[0x13] = b1[0x13] + b1[0x1C]; + b2[0x1C] = MUL((b1[0x1C] - b1[0x13]),COS_1_3); + b2[0x14] = b1[0x14] + b1[0x1B]; + b2[0x1B] = MUL((b1[0x1B] - b1[0x14]),COS_1_4); + b2[0x15] = b1[0x15] + b1[0x1A]; + b2[0x1A] = MUL((b1[0x1A] - b1[0x15]),COS_1_5); + b2[0x16] = b1[0x16] + b1[0x19]; + b2[0x19] = MUL((b1[0x19] - b1[0x16]),COS_1_6); + b2[0x17] = b1[0x17] + b1[0x18]; + b2[0x18] = MULL((b1[0x18] - b1[0x17]),COS_1_7); + + + b1[0x00] = b2[0x00] + b2[0x07]; + b1[0x07] = MUL((b2[0x00] - b2[0x07]),COS_2_0); + b1[0x01] = b2[0x01] + b2[0x06]; + b1[0x06] = MUL((b2[0x01] - b2[0x06]),COS_2_1); + b1[0x02] = b2[0x02] + b2[0x05]; + b1[0x05] = MUL((b2[0x02] - b2[0x05]),COS_2_2); + b1[0x03] = b2[0x03] + b2[0x04]; + b1[0x04] = MULL((b2[0x03] - b2[0x04]),COS_2_3); + + b1[0x08] = b2[0x08] + b2[0x0F]; + b1[0x0F] = MUL((b2[0x0F] - b2[0x08]),COS_2_0); + b1[0x09] = b2[0x09] + b2[0x0E]; + b1[0x0E] = MUL((b2[0x0E] - b2[0x09]),COS_2_1); + b1[0x0A] = b2[0x0A] + b2[0x0D]; + b1[0x0D] = MUL((b2[0x0D] - b2[0x0A]),COS_2_2); + b1[0x0B] = b2[0x0B] + b2[0x0C]; + b1[0x0C] = MULL((b2[0x0C] - b2[0x0B]),COS_2_3); + + b1[0x10] = b2[0x10] + b2[0x17]; + b1[0x17] = MUL((b2[0x10] - b2[0x17]),COS_2_0); + b1[0x11] = b2[0x11] + b2[0x16]; + b1[0x16] = MUL((b2[0x11] - b2[0x16]),COS_2_1); + b1[0x12] = b2[0x12] + b2[0x15]; + b1[0x15] = MUL((b2[0x12] - b2[0x15]),COS_2_2); + b1[0x13] = b2[0x13] + b2[0x14]; + b1[0x14] = MULL((b2[0x13] - b2[0x14]),COS_2_3); + + b1[0x18] = b2[0x18] + b2[0x1F]; + b1[0x1F] = MUL((b2[0x1F] - b2[0x18]),COS_2_0); + b1[0x19] = b2[0x19] + b2[0x1E]; + b1[0x1E] = MUL((b2[0x1E] - b2[0x19]),COS_2_1); + b1[0x1A] = b2[0x1A] + b2[0x1D]; + b1[0x1D] = MUL((b2[0x1D] - b2[0x1A]),COS_2_2); + b1[0x1B] = b2[0x1B] + b2[0x1C]; + b1[0x1C] = MULL((b2[0x1C] - b2[0x1B]),COS_2_3); + + + b2[0x00] = b1[0x00] + b1[0x03]; + b2[0x03] = MUL((b1[0x00] - b1[0x03]),COS_3_0); + b2[0x01] = b1[0x01] + b1[0x02]; + b2[0x02] = MUL((b1[0x01] - b1[0x02]),COS_3_1); + + b2[0x04] = b1[0x04] + b1[0x07]; + b2[0x07] = MUL((b1[0x07] - b1[0x04]),COS_3_0); + b2[0x05] = b1[0x05] + b1[0x06]; + b2[0x06] = MUL((b1[0x06] - b1[0x05]),COS_3_1); + + b2[0x08] = b1[0x08] + b1[0x0B]; + b2[0x0B] = MUL((b1[0x08] - b1[0x0B]),COS_3_0); + b2[0x09] = b1[0x09] + b1[0x0A]; + b2[0x0A] = MUL((b1[0x09] - b1[0x0A]),COS_3_1); + + b2[0x0C] = b1[0x0C] + b1[0x0F]; + b2[0x0F] = MUL((b1[0x0F] - b1[0x0C]),COS_3_0); + b2[0x0D] = b1[0x0D] + b1[0x0E]; + b2[0x0E] = MUL((b1[0x0E] - b1[0x0D]),COS_3_1); + + b2[0x10] = b1[0x10] + b1[0x13]; + b2[0x13] = MUL((b1[0x10] - b1[0x13]),COS_3_0); + b2[0x11] = b1[0x11] + b1[0x12]; + b2[0x12] = MUL((b1[0x11] - b1[0x12]),COS_3_1); + + b2[0x14] = b1[0x14] + b1[0x17]; + b2[0x17] = MUL((b1[0x17] - b1[0x14]),COS_3_0); + b2[0x15] = b1[0x15] + b1[0x16]; + b2[0x16] = MUL((b1[0x16] - b1[0x15]),COS_3_1); + + b2[0x18] = b1[0x18] + b1[0x1B]; + b2[0x1B] = MUL((b1[0x18] - b1[0x1B]),COS_3_0); + b2[0x19] = b1[0x19] + b1[0x1A]; + b2[0x1A] = MUL((b1[0x19] - b1[0x1A]),COS_3_1); + + b2[0x1C] = b1[0x1C] + b1[0x1F]; + b2[0x1F] = MUL((b1[0x1F] - b1[0x1C]),COS_3_0); + b2[0x1D] = b1[0x1D] + b1[0x1E]; + b2[0x1E] = MUL((b1[0x1E] - b1[0x1D]),COS_3_1); + + { + int i; + for(i=0;i<32;i+=4) { + b1[i+0x00] = b2[i+0x00] + b2[i+0x01]; + b1[i+0x01] = MUL((b2[i+0x00] - b2[i+0x01]),COS_4_0); + b1[i+0x02] = b2[i+0x02] + b2[i+0x03]; + b1[i+0x03] = MUL((b2[i+0x03] - b2[i+0x02]),COS_4_0); + } + } + + b1[0x02] += b1[0x03]; + b1[0x06] += b1[0x07]; + b1[0x04] += b1[0x06]; + b1[0x06] += b1[0x05]; + b1[0x05] += b1[0x07]; + + b1[0x0A] += b1[0x0B]; + b1[0x0E] += b1[0x0F]; + b1[0x0C] += b1[0x0E]; + b1[0x0E] += b1[0x0D]; + b1[0x0D] += b1[0x0F]; + + b1[0x12] += b1[0x13]; + b1[0x16] += b1[0x17]; + b1[0x14] += b1[0x16]; + b1[0x16] += b1[0x15]; + b1[0x15] += b1[0x17]; + + b1[0x1A] += b1[0x1B]; + b1[0x1E] += b1[0x1F]; + b1[0x1C] += b1[0x1E]; + b1[0x1E] += b1[0x1D]; + b1[0x1D] += b1[0x1F]; + + SETOUT(out0,16,b1[0x00]); + SETOUT(out0,12,b1[0x04]); + SETOUT(out0, 8,b1[0x02]); + SETOUT(out0, 4,b1[0x06]); + SETOUT(out0, 0,b1[0x01]); + SETOUT(out1, 0,b1[0x01]); + SETOUT(out1, 4,b1[0x05]); + SETOUT(out1, 8,b1[0x03]); + SETOUT(out1,12,b1[0x07]); + + b1[0x08] += b1[0x0C]; + SETOUT(out0,14,b1[0x08]); + b1[0x0C] += b1[0x0a]; + SETOUT(out0,10,b1[0x0C]); + b1[0x0A] += b1[0x0E]; + SETOUT(out0, 6,b1[0x0A]); + b1[0x0E] += b1[0x09]; + SETOUT(out0, 2,b1[0x0E]); + b1[0x09] += b1[0x0D]; + SETOUT(out1, 2,b1[0x09]); + b1[0x0D] += b1[0x0B]; + SETOUT(out1, 6,b1[0x0D]); + b1[0x0B] += b1[0x0F]; + SETOUT(out1,10,b1[0x0B]); + SETOUT(out1,14,b1[0x0F]); + + b1[0x18] += b1[0x1C]; + SETOUT(out0,15,b1[0x10] + b1[0x18]); + SETOUT(out0,13,b1[0x18] + b1[0x14]); + b1[0x1C] += b1[0x1a]; + SETOUT(out0,11,b1[0x14] + b1[0x1C]); + SETOUT(out0, 9,b1[0x1C] + b1[0x12]); + b1[0x1A] += b1[0x1E]; + SETOUT(out0, 7,b1[0x12] + b1[0x1A]); + SETOUT(out0, 5,b1[0x1A] + b1[0x16]); + b1[0x1E] += b1[0x19]; + SETOUT(out0, 3,b1[0x16] + b1[0x1E]); + SETOUT(out0, 1,b1[0x1E] + b1[0x11]); + b1[0x19] += b1[0x1D]; + SETOUT(out1, 1,b1[0x11] + b1[0x19]); + SETOUT(out1, 3,b1[0x19] + b1[0x15]); + b1[0x1D] += b1[0x1B]; + SETOUT(out1, 5,b1[0x15] + b1[0x1D]); + SETOUT(out1, 7,b1[0x1D] + b1[0x13]); + b1[0x1B] += b1[0x1F]; + SETOUT(out1, 9,b1[0x13] + b1[0x1B]); + SETOUT(out1,11,b1[0x1B] + b1[0x17]); + SETOUT(out1,13,b1[0x17] + b1[0x1F]); + SETOUT(out1,15,b1[0x1F]); +} + + +/* + * the call via dct64 is a trick to force GCC to use + * (new) registers for the b1,b2 pointer to the bufs[xx] field + */ +void dct64_486(int *a,int *b,real *samples) +{ + int bufs[64]; + int i; + +#ifdef REAL_IS_FIXED +#define TOINT(a) ((a) * 32768 / (int)REAL_FACTOR) + + for(i=0;i<32;i++) { + bufs[i]=TOINT(samples[i]); + } +#else + int *p = bufs; + register double const scale = ((65536.0 * 32) + 1) * 65536.0; + + for(i=0;i<32;i++) { + *((double *) (p++)) = scale + *samples++; /* beware on bufs overrun: 8B store from x87 */ + } +#endif + + dct64_1_486(a,b,bufs+32,bufs); +} + diff --git a/programs/media/ac97snd/trunk/mpg/decode_i386.c b/programs/media/ac97snd/trunk/mpg/decode_i386.c new file mode 100644 index 0000000000..2c066c53cb --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/decode_i386.c @@ -0,0 +1,259 @@ +/* + decode_i386.c: decode for i386 (really faster?) + + copyright 1995-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Michael Hipp + + slighlty optimized for machines without autoincrement/decrement. + The performance is highly compiler dependend. Maybe + the decode.c version for 'normal' processor may be faster + even for Intel processors. +*/ + +//#include +#include +//#include + +//#include "config.h" +#include "mpg123.h" + +#if 0 + /* old WRITE_SAMPLE */ +#define WRITE_SAMPLE(samples,sum,clip) \ + if( (sum) > 32767.0) { *(samples) = 0x7fff; (clip)++; } \ + else if( (sum) < -32768.0) { *(samples) = -0x8000; (clip)++; } \ + else { *(samples) = sum; } +#else + /* new WRITE_SAMPLE */ + /* keep in mind that we are on known little-endian i386 here and special tricks are allowed... */ +#define WRITE_SAMPLE(samples,sum,clip) { \ + double dtemp; int v; /* sizeof(int) == 4 */ \ + dtemp = ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0)) + (sum); \ + v = ((*(int *)&dtemp) - 0x80000000); \ + if( v > 32767) { *(samples) = 0x7fff; (clip)++; } \ + else if( v < -32768) { *(samples) = -0x8000; (clip)++; } \ + else { *(samples) = v; } \ +} +#endif + +#if 0 +int synth_1to1_8bit(real *bandPtr,int channel,unsigned char *samples,int *pnt) +{ + short samples_tmp[64]; + short *tmp1 = samples_tmp + channel; + int i,ret; + int pnt1 = 0; + + ret = synth_1to1(bandPtr,channel,(unsigned char *)samples_tmp,&pnt1); + samples += channel + *pnt; + + for(i=0;i<32;i++) { + *samples = conv16to8[*tmp1>>AUSHIFT]; + samples += 2; + tmp1 += 2; + } + *pnt += 64; + + return ret; +} + +int synth_1to1_8bit_mono(real *bandPtr,unsigned char *samples,int *pnt) +{ + short samples_tmp[64]; + short *tmp1 = samples_tmp; + int i,ret; + int pnt1 = 0; + + ret = synth_1to1(bandPtr,0,(unsigned char *)samples_tmp,&pnt1); + samples += *pnt; + + for(i=0;i<32;i++) { + *samples++ = conv16to8[*tmp1>>AUSHIFT]; + tmp1+=2; + } + *pnt += 32; + + return ret; +} + +int synth_1to1_8bit_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt) +{ + short samples_tmp[64]; + short *tmp1 = samples_tmp; + int i,ret; + int pnt1 = 0; + + ret = synth_1to1(bandPtr,0,(unsigned char *)samples_tmp,&pnt1); + samples += *pnt; + + for(i=0;i<32;i++) { + *samples++ = conv16to8[*tmp1>>AUSHIFT]; + *samples++ = conv16to8[*tmp1>>AUSHIFT]; + tmp1 += 2; + } + *pnt += 64; + + return ret; +} + +int synth_1to1_mono(real *bandPtr,unsigned char *samples,int *pnt) +{ + short samples_tmp[64]; + short *tmp1 = samples_tmp; + int i,ret; + int pnt1 = 0; + + ret = synth_1to1(bandPtr,0,(unsigned char *) samples_tmp,&pnt1); + samples += *pnt; + + for(i=0;i<32;i++) { + *( (short *) samples) = *tmp1; + samples += 2; + tmp1 += 2; + } + *pnt += 64; + + return ret; +} +#endif + +int synth_1to1_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt) +{ + int i,ret; + + ret = synth_1to1(bandPtr,0,samples,pnt); + samples = samples + *pnt - 128; + + for(i=0;i<32;i++) { + ((short *)samples)[1] = ((short *)samples)[0]; + samples+=4; + } + + return ret; +} + +int synth_1to1(real *bandPtr,int channel,unsigned char *out,int *pnt) +{ +#ifndef PENTIUM_OPT + static real buffs[2][2][0x110]; + static const int step = 2; + static int bo = 1; + short *samples = (short *) (out + *pnt); + + real *b0,(*buf)[0x110]; + int clip = 0; + int bo1; +#endif + +// if(have_eq_settings) +// do_equalizer(bandPtr,channel); + +#ifndef PENTIUM_OPT + if(!channel) { + bo--; + bo &= 0xf; + buf = buffs[0]; + } + else { + samples++; + buf = buffs[1]; + } + + if(bo & 0x1) { + b0 = buf[0]; + bo1 = bo; + dct64(buf[1]+((bo+1)&0xf),buf[0]+bo,bandPtr); + } + else { + b0 = buf[1]; + bo1 = bo+1; + dct64(buf[0]+bo,buf[1]+bo+1,bandPtr); + } + + { + register int j; + real *window = decwin + 16 - bo1; + + for (j=16;j;j--,b0+=0x10,window+=0x20,samples+=step) + { + real sum; + sum = window[0x0] * b0[0x0]; + sum -= window[0x1] * b0[0x1]; + sum += window[0x2] * b0[0x2]; + sum -= window[0x3] * b0[0x3]; + sum += window[0x4] * b0[0x4]; + sum -= window[0x5] * b0[0x5]; + sum += window[0x6] * b0[0x6]; + sum -= window[0x7] * b0[0x7]; + sum += window[0x8] * b0[0x8]; + sum -= window[0x9] * b0[0x9]; + sum += window[0xA] * b0[0xA]; + sum -= window[0xB] * b0[0xB]; + sum += window[0xC] * b0[0xC]; + sum -= window[0xD] * b0[0xD]; + sum += window[0xE] * b0[0xE]; + sum -= window[0xF] * b0[0xF]; + + WRITE_SAMPLE(samples,sum,clip); + } + + { + real sum; + sum = window[0x0] * b0[0x0]; + sum += window[0x2] * b0[0x2]; + sum += window[0x4] * b0[0x4]; + sum += window[0x6] * b0[0x6]; + sum += window[0x8] * b0[0x8]; + sum += window[0xA] * b0[0xA]; + sum += window[0xC] * b0[0xC]; + sum += window[0xE] * b0[0xE]; + WRITE_SAMPLE(samples,sum,clip); + b0-=0x10,window-=0x20,samples+=step; + } + window += bo1<<1; + + for (j=15;j;j--,b0-=0x10,window-=0x20,samples+=step) + { + real sum; + sum = -window[-0x1] * b0[0x0]; + sum -= window[-0x2] * b0[0x1]; + sum -= window[-0x3] * b0[0x2]; + sum -= window[-0x4] * b0[0x3]; + sum -= window[-0x5] * b0[0x4]; + sum -= window[-0x6] * b0[0x5]; + sum -= window[-0x7] * b0[0x6]; + sum -= window[-0x8] * b0[0x7]; + sum -= window[-0x9] * b0[0x8]; + sum -= window[-0xA] * b0[0x9]; + sum -= window[-0xB] * b0[0xA]; + sum -= window[-0xC] * b0[0xB]; + sum -= window[-0xD] * b0[0xC]; + sum -= window[-0xE] * b0[0xD]; + sum -= window[-0xF] * b0[0xE]; + sum -= window[-0x0] * b0[0xF]; + + WRITE_SAMPLE(samples,sum,clip); + } + } + *pnt += 128; + + return clip; +#elif defined(USE_MMX) + { + static short buffs[2][2][0x110]; + static int bo = 1; + short *samples = (short *) (out + *pnt); + synth_1to1_MMX(bandPtr, channel, samples, (short *) buffs, &bo); + *pnt += 128; + return 0; + } +#else + { + int ret; + ret = synth_1to1_pent(bandPtr,channel,out+*pnt); + *pnt += 128; + return ret; + } +#endif +} diff --git a/programs/media/ac97snd/trunk/mpg/decode_i486.c b/programs/media/ac97snd/trunk/mpg/decode_i486.c new file mode 100644 index 0000000000..acce7a2dfc --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/decode_i486.c @@ -0,0 +1,255 @@ +/* + decode_i486.c: i486 decode + + copyright 1998-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Fabrice Bellard +*/ + +/* + * Subband Synthesis for MPEG Audio. + * + * Version optimized for 80486 by using integer arithmetic, + * multiplications by shift and add, and by increasing locality in + * order to fit the 8KB L1 cache. This code should be compiled with gcc + * 2.7.2 or higher. + * + * Note: this version does not guaranty a good accuracy. The filter + * coefficients are quantified on 14 bits. + * + * (c) 1998 Fabrice Bellard + */ + +//#include +#include "mpg123.h" + +#define FIR_SIZE 16 + +#define FIR16_1(pos,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15) \ +{\ + int sum;\ + sum=(c0)*b0[0]+(c1)*b0[1]+(c2)*b0[2]+(c3)*b0[3]+\ + (c4)*b0[4]+(c5)*b0[5]+(c6)*b0[6]+(c7)*b0[7]+\ + (c8)*b0[8]+(c9)*b0[9]+(c10)*b0[10]+(c11)*b0[11]+\ + (c12)*b0[12]+(c13)*b0[13]+(c14)*b0[14]+(c15)*b0[15];\ + sum=(sum+(1 << 13))>>14;\ + if (sum<-32768) sum=-32768;\ + else if (sum>32767) sum=32767;\ + samples[2*(pos)]=sum;\ + b0+=FIR_BUFFER_SIZE;\ +} + +#define FIR16_2(pos1,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,\ + pos2,d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15) \ +{\ + int sum1,sum2,v;\ +\ + v=b0[0];\ + sum1=(c0)*v;\ + sum2=(d0)*v;\ + v=b0[1];\ + sum1+=(c1)*v;\ + sum2+=(d1)*v;\ + v=b0[2];\ + sum1+=(c2)*v;\ + sum2+=(d2)*v;\ + v=b0[3];\ + sum1+=(c3)*v;\ + sum2+=(d3)*v;\ + v=b0[4];\ + sum1+=(c4)*v;\ + sum2+=(d4)*v;\ + v=b0[5];\ + sum1+=(c5)*v;\ + sum2+=(d5)*v;\ + v=b0[6];\ + sum1+=(c6)*v;\ + sum2+=(d6)*v;\ + v=b0[7];\ + sum1+=(c7)*v;\ + sum2+=(d7)*v;\ + v=b0[8];\ + sum1+=(c8)*v;\ + sum2+=(d8)*v;\ + v=b0[9];\ + sum1+=(c9)*v;\ + sum2+=(d9)*v;\ + v=b0[10];\ + sum1+=(c10)*v;\ + sum2+=(d10)*v;\ + v=b0[11];\ + sum1+=(c11)*v;\ + sum2+=(d11)*v;\ + v=b0[12];\ + sum1+=(c12)*v;\ + sum2+=(d12)*v;\ + v=b0[13];\ + sum1+=(c13)*v;\ + sum2+=(d13)*v;\ + v=b0[14];\ + sum1+=(c14)*v;\ + sum2+=(d14)*v;\ + v=b0[15];\ + sum1+=(c15)*v;\ + sum2+=(d15)*v;\ +\ + sum1=(sum1+(1<<13))>>14;\ + sum2=(sum2+(1<<13))>>14;\ +\ + if (sum1<-32768) sum1=-32768;\ + else if (sum1>32767) sum1=32767;\ + samples[(pos1)*2]=sum1;\ +\ + if (sum2<-32768) sum2=-32768;\ + else if (sum2>32767) sum2=32767;\ + samples[(pos2)*2]=sum2;\ + b0+=FIR_BUFFER_SIZE;\ +} + +int synth_1to1_486(real *bandPtr,int channel,unsigned char *out,int nb_blocks) +{ + static int buffs[2][2][17*FIR_BUFFER_SIZE]; + static int bo[2] = { FIR_SIZE-1, FIR_SIZE-1 }; + short *samples = (short *) out; + int *b0,(*buf)[17*FIR_BUFFER_SIZE]; + int clip = 0; + int block,b,bo_start; + + /* samples address */ + samples+=channel; + + bo_start=bo[channel]; + buf = buffs[channel]; + + b=bo_start; + for(block=0;block= FIR_BUFFER_SIZE) { + int *p,*q; + int c,i,j; + + /* we shift the buffers */ + for(c=0;c<2;c++) { + p=&buf[c][0]+1; + q=p+(FIR_BUFFER_SIZE-FIR_SIZE); + for(i=0;i<17;i++) { + for(j=0;j= FIR_BUFFER_SIZE) b=FIR_SIZE; + if(b & 1) { + b0 = buf[0] + b - (FIR_SIZE-1); + } else { + b0 = buf[1] + b - (FIR_SIZE-1); + } + + FIR16_1(0,-7,53,-114,509,-1288,1643,-9372,18759,9372,1643,1288,509,114,53,7,0); + FIR16_2(1,-6,52,-100,515,-1197,1783,-8910,18748,9834,1489,1379,500,129,54,7,0, + 31,0,-7,54,-129,500,-1379,1489,-9834,18748,8910,1783,1197,515,100,52,6); + FIR16_2(2,-6,50,-86,520,-1106,1910,-8447,18714,10294,1322,1469,488,145,55,8,0, + 30,0,-8,55,-145,488,-1469,1322,-10294,18714,8447,1910,1106,520,86,50,6); + FIR16_2(3,-5,49,-73,521,-1015,2023,-7986,18657,10751,1140,1559,473,161,56,9,0, + 29,0,-9,56,-161,473,-1559,1140,-10751,18657,7986,2023,1015,521,73,49,5); + samples+=64; + } + samples-=64*nb_blocks; + + /* filter bank: part 2 */ + + b=bo_start; + for(block=0;block= FIR_BUFFER_SIZE) b=FIR_SIZE; + if(b & 1) { + b0 = buf[0] + b - (FIR_SIZE-1) + 4*FIR_BUFFER_SIZE; + } else { + b0 = buf[1] + b - (FIR_SIZE-1) + 4*FIR_BUFFER_SIZE; + } + + FIR16_2(4,-4,47,-61,521,-926,2123,-7528,18578,11205,944,1647,455,177,56,10,0, + 28,0,-10,56,-177,455,-1647,944,-11205,18578,7528,2123,926,521,61,47,4); + FIR16_2(5,-4,45,-49,518,-837,2210,-7072,18477,11654,733,1733,434,194,57,11,0, + 27,0,-11,57,-194,434,-1733,733,-11654,18477,7072,2210,837,518,49,45,4); + FIR16_2(6,-4,44,-38,514,-751,2284,-6620,18353,12097,509,1817,411,212,57,12,0, + 26,0,-12,57,-212,411,-1817,509,-12097,18353,6620,2284,751,514,38,44,4); + FIR16_2(7,-3,42,-27,508,-665,2347,-6173,18208,12534,270,1899,383,229,56,13,0, + 25,0,-13,56,-229,383,-1899,270,-12534,18208,6173,2347,665,508,27,42,3); + + samples+=64; + } + samples-=64*nb_blocks; + + /* filter bank: part 3 */ + + b=bo_start; + for(block=0;block= FIR_BUFFER_SIZE) b=FIR_SIZE; + if(b & 1) { + b0 = buf[0] + b - (FIR_SIZE-1) + 8*FIR_BUFFER_SIZE; + } else { + b0 = buf[1] + b - (FIR_SIZE-1) + 8*FIR_BUFFER_SIZE; + } + + FIR16_2(8,-3,40,-18,500,-582,2398,-5732,18042,12963,17,1977,353,247,56,14,0, + 24,0,-14,56,-247,353,-1977,17,-12963,18042,5732,2398,582,500,18,40,3); + FIR16_2(9,-2,38,-9,490,-501,2437,-5297,17855,13383,-249,2052,320,266,55,15,0, + 23,0,-15,55,-266,320,-2052,-249,-13383,17855,5297,2437,501,490,9,38,2); + FIR16_2(10,-2,36,0,479,-423,2465,-4869,17647,13794,-530,2122,282,284,53,17,0, + 22,0,-17,53,-284,282,-2122,-530,-13794,17647,4869,2465,423,479,0,36,2); + FIR16_2(11,-2,34,7,467,-347,2483,-4449,17419,14194,-825,2188,242,302,52,18,0, + 21,0,-18,52,-302,242,-2188,-825,-14194,17419,4449,2483,347,467,-7,34,2); + + samples+=64; + } + samples-=64*nb_blocks; + + /* filter bank: part 4 */ + + b=bo_start; + for(block=0;block= FIR_BUFFER_SIZE) b=FIR_SIZE; + if(b & 1) { + b0 = buf[0] + b - (FIR_SIZE-1) + 12*FIR_BUFFER_SIZE; + } else { + b0 = buf[1] + b - (FIR_SIZE-1) + 12*FIR_BUFFER_SIZE; + } + + FIR16_2(12,-2,33,14,454,-273,2491,-4038,17173,14583,-1133,2249,198,320,50,19,0, + 20,0,-19,50,-320,198,-2249,-1133,-14583,17173,4038,2491,273,454,-14,33,2); + FIR16_2(13,-1,31,20,439,-203,2489,-3637,16907,14959,-1454,2304,151,339,47,21,-1, + 19,-1,-21,47,-339,151,-2304,-1454,-14959,16907,3637,2489,203,439,-20,31,1); + FIR16_2(14,-1,29,26,424,-136,2479,-3245,16623,15322,-1788,2354,100,357,44,22,-1, + 18,-1,-22,44,-357,100,-2354,-1788,-15322,16623,3245,2479,136,424,-26,29,1); + FIR16_2(15,-1,27,31,408,-72,2459,-2863,16322,15671,-2135,2396,46,374,40,24,-1, + 17,-1,-24,40,-374,46,-2396,-2135,-15671,16322,2863,2459,72,408,-31,27,1); + FIR16_1(16,-1,0,36,0,-11,0,-2493,0,16004,0,2431,0,391,0,26,0); + + samples+=64; + } + + return clip; +} + diff --git a/programs/media/ac97snd/trunk/mpg/e_pow.c b/programs/media/ac97snd/trunk/mpg/e_pow.c new file mode 100644 index 0000000000..9938963de7 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/e_pow.c @@ -0,0 +1,358 @@ +/* @(#)e_pow.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25, + for performance improvement on pipelined processors. +*/ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_pow.c,v 1.9 1995/05/12 04:57:32 jtc Exp $"; +#endif + +/* __ieee754_pow(x,y) return x**y + * + * n + * Method: Let x = 2 * (1+f) + * 1. Compute and return log2(x) in two pieces: + * log2(x) = w1 + w2, + * where w1 has 53-24 = 29 bit trailing zeros. + * 2. Perform y*log2(x) = n+y' by simulating muti-precision + * arithmetic, where |y'|<=0.5. + * 3. Return x**y = 2**n*exp(y'*log2) + * + * Special cases: + * 1. (anything) ** 0 is 1 + * 2. (anything) ** 1 is itself + * 3. (anything) ** NAN is NAN + * 4. NAN ** (anything except 0) is NAN + * 5. +-(|x| > 1) ** +INF is +INF + * 6. +-(|x| > 1) ** -INF is +0 + * 7. +-(|x| < 1) ** +INF is +0 + * 8. +-(|x| < 1) ** -INF is +INF + * 9. +-1 ** +-INF is NAN + * 10. +0 ** (+anything except 0, NAN) is +0 + * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 + * 12. +0 ** (-anything except 0, NAN) is +INF + * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF + * 14. -0 ** (odd integer) = -( +0 ** (odd integer) ) + * 15. +INF ** (+anything except 0,NAN) is +INF + * 16. +INF ** (-anything except 0,NAN) is +0 + * 17. -INF ** (anything) = -0 ** (-anything) + * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) + * 19. (-anything except 0 and inf) ** (non-integer) is NAN + * + * Accuracy: + * pow(x,y) returns x**y nearly rounded. In particular + * pow(integer,integer) + * always returns the correct integer provided it is + * representable. + * + * Constants : + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "math.h" +#include "math_private.h" +#define zero C[0] +#define one C[1] +#define two C[2] +#define two53 C[3] +#define huge C[4] +#define tiny C[5] +#define L1 C[6] +#define L2 C[7] +#define L3 C[8] +#define L4 C[9] +#define L5 C[10] +#define L6 C[11] +#define P1 C[12] +#define P2 C[13] +#define P3 C[14] +#define P4 C[15] +#define P5 C[16] +#define lg2 C[17] +#define lg2_h C[18] +#define lg2_l C[19] +#define ovt C[20] +#define cp C[21] +#define cp_h C[22] +#define cp_l C[23] +#define ivln2 C[24] +#define ivln2_h C[25] +#define ivln2_l C[26] + +double _cdecl scalbn(double,int); + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +#ifdef __STDC__ +static const double +#else +static double +#endif +bp[] = {1.0, 1.5,}, +dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ +dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ +C[] = { +0.0, +1.0, +2.0, +9007199254740992.0 , +1.0e300, +1.0e-300, +5.99999999999994648725e-01 , +4.28571428578550184252e-01 , +3.33333329818377432918e-01 , +2.72728123808534006489e-01 , +2.30660745775561754067e-01 , +2.06975017800338417784e-01 , +1.66666666666666019037e-01 , +-2.77777777770155933842e-03 , +6.61375632143793436117e-05 , +-1.65339022054652515390e-06 , +4.13813679705723846039e-08 , +6.93147180559945286227e-01 , +6.93147182464599609375e-01 , +-1.90465429995776804525e-09 , +8.0085662595372944372e-0017 , +9.61796693925975554329e-01 , +9.61796700954437255859e-01 , +-7.02846165095275826516e-09 , +1.44269504088896338700e+00 , +1.44269502162933349609e+00 , +1.92596299112661746887e-08 }; + + double pow_test(x,y) + double x, y; +{ + double z,ax,z_h,z_l,p_h,p_l; + double y1,t1,t2,r,s,t,u,v,w, t12,t14,r_1,r_2,r_3; + int32_t i,j,k,yisint,n; + int32_t hx,hy,ix,iy; + u_int32_t lx,ly; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hy,ly,y); + ix = hx&0x7fffffff; iy = hy&0x7fffffff; + + /* y==zero: x**0 = 1 */ + if((iy|ly)==0) return C[1]; + + /* +-NaN return x+y */ + if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) || + iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) + return x+y; + + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if(hx<0) { + if(iy>=0x43400000) yisint = 2; /* even integer y */ + else if(iy>=0x3ff00000) { + k = (iy>>20)-0x3ff; /* exponent */ + if(k>20) { + j = ly>>(52-k); + if((u_int32_t)(j<<(52-k))==ly) yisint = 2-(j&1); + } else if(ly==0) { + j = iy>>(20-k); + if((int32_t)(j<<(20-k))==iy) yisint = 2-(j&1); + } + } + } + + /* special value of y */ + if(ly==0) { + if (iy==0x7ff00000) { /* y is +-inf */ + if(((ix-0x3ff00000)|lx)==0) + return y - y; /* inf**+-1 is NaN */ + else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */ + return (hy>=0)? y: C[0]; + else /* (|x|<1)**-,+inf = inf,0 */ + return (hy<0)?-y: C[0]; + } + if(iy==0x3ff00000) { /* y is +-1 */ + if(hy<0) return C[1]/x; else return x; + } + if(hy==0x40000000) return x*x; /* y is 2 */ + if(hy==0x3fe00000) { /* y is 0.5 */ + if(hx>=0) /* x >= +0 */ + return sqrt(x); + } + } + + ax = fabs(x); + /* special value of x */ + if(lx==0) { + if(ix==0x7ff00000||ix==0||ix==0x3ff00000){ + z = ax; /*x is +-0,+-inf,+-1*/ + if(hy<0) z = C[1]/z; /* z = (1/|x|) */ + if(hx<0) { + if(((ix-0x3ff00000)|yisint)==0) { + z = (z-z)/(z-z); /* (-1)**non-int is NaN */ + } else if(yisint==1) + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + return z; + } + } + + /* (x<0)**(non-int) is NaN */ + if(((((u_int32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x); + + /* |y| is huge */ + if(iy>0x41e00000) { /* if |y| > 2**31 */ + if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */ + if(ix<=0x3fefffff) return (hy<0)? C[4]*C[4]:C[5]*C[5]; + if(ix>=0x3ff00000) return (hy>0)? C[4]*C[4]:C[5]*C[5]; + } + /* over/underflow if x is not close to one */ + if(ix<0x3fefffff) return (hy<0)? C[4]*C[4]:C[5]*C[5]; + if(ix>0x3ff00000) return (hy>0)? C[4]*C[4]:C[5]*C[5]; + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = x-1; /* t has 20 trailing zeros */ + w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25)); + u = C[25]*t; /* ivln2_h has 21 sig. bits */ + v = t*C[26]-w*C[24]; + t1 = u+v; + SET_LOW_WORD(t1,0); + t2 = v-(t1-u); + } else { + double s2,s_h,s_l,t_h,t_l,s22,s24,s26,r1,r2,r3; + n = 0; + /* take care subnormal number */ + if(ix<0x00100000) + {ax *= C[3]; n -= 53; GET_HIGH_WORD(ix,ax); } + n += ((ix)>>20)-0x3ff; + j = ix&0x000fffff; + /* determine interval */ + ix = j|0x3ff00000; /* normalize ix */ + if(j<=0x3988E) k=0; /* |x|>1)|0x20000000)+0x00080000+(k<<18)); + t_l = ax - (t_h-bp[k]); + s_l = v*((u-s_h*t_h)-s_h*t_l); + /* compute log(ax) */ + s2 = s*s; +#ifdef DO_NOT_USE_THIS + r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); +#else + r1 = C[10]+s2*C[11]; s22=s2*s2; + r2 = C[8]+s2*C[9]; s24=s22*s22; + r3 = C[6]+s2*C[7]; s26=s24*s22; + r = r3*s22 + r2*s24 + r1*s26; +#endif + r += s_l*(s_h+s); + s2 = s_h*s_h; + t_h = 3.0+s2+r; + SET_LOW_WORD(t_h,0); + t_l = r-((t_h-3.0)-s2); + /* u+v = s*(1+...) */ + u = s_h*t_h; + v = s_l*t_h+t_l*s; + /* 2/(3log2)*(s+...) */ + p_h = u+v; + SET_LOW_WORD(p_h,0); + p_l = v-(p_h-u); + z_h = C[22]*p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = C[23]*p_h+p_l*C[21]+dp_l[k]; + /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (double)n; + t1 = (((z_h+z_l)+dp_h[k])+t); + SET_LOW_WORD(t1,0); + t2 = z_l-(((t1-t)-dp_h[k])-z_h); + } + + s = C[1]; /* s (sign of result -ve**odd) = -1 else = 1 */ + if(((((u_int32_t)hx>>31)-1)|(yisint-1))==0) + s = -C[1];/* (-ve)**(odd int) */ + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + y1 = y; + SET_LOW_WORD(y1,0); + p_l = (y-y1)*t1+y*t2; + p_h = y1*t1; + z = p_l+p_h; + EXTRACT_WORDS(j,i,z); + if (j>=0x40900000) { /* z >= 1024 */ + if(((j-0x40900000)|i)!=0) /* if z > 1024 */ + return s*C[4]*C[4]; /* overflow */ + else { + if(p_l+C[20]>z-p_h) return s*C[4]*C[4]; /* overflow */ + } + } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */ + if(((j-0xc090cc00)|i)!=0) /* z < -1075 */ + return s*C[5]*C[5]; /* underflow */ + else { + if(p_l<=z-p_h) return s*C[5]*C[5]; /* underflow */ + } + } + /* + * compute 2**(p_h+p_l) + */ + i = j&0x7fffffff; + k = (i>>20)-0x3ff; + n = 0; + if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ + n = j+(0x00100000>>(k+1)); + k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */ + t = C[0]; + SET_HIGH_WORD(t,n&~(0x000fffff>>k)); + n = ((n&0x000fffff)|0x00100000)>>(20-k); + if(j<0) n = -n; + p_h -= t; + } + t = p_l+p_h; + SET_LOW_WORD(t,0); + u = t*C[18]; + v = (p_l-(t-p_h))*C[17]+t*C[19]; + z = u+v; + w = v-(z-u); + t = z*z; +#ifdef DO_NOT_USE_THIS + t1 = z - t*(C[12]+t*(C[13]+t*(C[14]+t*(C[15]+t*C[16])))); +#else + r_1 = C[15]+t*C[16]; t12 = t*t; + r_2 = C[13]+t*C[14]; t14 = t12*t12; + r_3 = t*C[12]; + t1 = z - r_3 - t12*r_2 - t14*r_1; +#endif + r = (z*t1)/(t1-C[2])-(w+z*w); + z = C[1]-(r-z); + GET_HIGH_WORD(j,z); + j += (n<<20); + if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */ + else SET_HIGH_WORD(z,j); + return s*z; +} diff --git a/programs/media/ac97snd/trunk/mpg/getbits.c b/programs/media/ac97snd/trunk/mpg/getbits.c new file mode 100644 index 0000000000..8f3b7cc97b --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/getbits.c @@ -0,0 +1,134 @@ +/* + getbits + + copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Michael Hipp +*/ + +#include "mpg123.h" + +#if 0 +static void check_buffer_range(int size) +{ + int pos = (bsi.wordpointer-bsbuf) + (size>>3); + + if( pos >= fsizeold) { + fprintf(stderr,"Pointer out of range (%d,%d)!\n",pos,fsizeold); + } +} +#endif + +void backbits(int number_of_bits) +{ + bsi.bitindex -= number_of_bits; + bsi.wordpointer += (bsi.bitindex>>3); + bsi.bitindex &= 0x7; +} + +int getbitoffset(void) +{ + return (-bsi.bitindex)&0x7; +} + +int getbyte(void) +{ +#ifdef DEBUG_GETBITS + if(bsi.bitindex) + fprintf(stderr,"getbyte called unsynched!\n"); +#endif + return *bsi.wordpointer++; +} + +unsigned int getbits(int number_of_bits) +{ + unsigned long rval; + +#ifdef DEBUG_GETBITS +fprintf(stderr,"g%d",number_of_bits); +#endif + + if(!number_of_bits) + return 0; + +#if 0 + check_buffer_range(number_of_bits+bsi.bitindex); +#endif + + { + rval = bsi.wordpointer[0]; + rval <<= 8; + rval |= bsi.wordpointer[1]; + rval <<= 8; + rval |= bsi.wordpointer[2]; + + rval <<= bsi.bitindex; + rval &= 0xffffff; + + bsi.bitindex += number_of_bits; + + rval >>= (24-number_of_bits); + + bsi.wordpointer += (bsi.bitindex>>3); + bsi.bitindex &= 7; + } + +#ifdef DEBUG_GETBITS +fprintf(stderr,":%x ",rval); +#endif + + return rval; +} + +unsigned int getbits_fast(int number_of_bits) +{ + unsigned int rval; +#ifdef DEBUG_GETBITS +fprintf(stderr,"g%d",number_of_bits); +#endif + +#if 0 + check_buffer_range(number_of_bits+bsi.bitindex); +#endif + + rval = (unsigned char) (bsi.wordpointer[0] << bsi.bitindex); + rval |= ((unsigned int) bsi.wordpointer[1]<>8; + rval <<= number_of_bits; + rval >>= 8; + + bsi.bitindex += number_of_bits; + + bsi.wordpointer += (bsi.bitindex>>3); + bsi.bitindex &= 7; + +#ifdef DEBUG_GETBITS +fprintf(stderr,":%x ",rval); +#endif + return rval; +} + +unsigned int get1bit(void) +{ + unsigned char rval; + +#ifdef DEBUG_GETBITS +fprintf(stderr,"g%d",1); +#endif + +#if 0 + check_buffer_range(1+bsi.bitindex); +#endif + + rval = *bsi.wordpointer << bsi.bitindex; + + bsi.bitindex++; + bsi.wordpointer += (bsi.bitindex>>3); + bsi.bitindex &= 7; + +#ifdef DEBUG_GETBITS +fprintf(stderr,":%d ",rval>>7); +#endif + + return rval>>7; +} + diff --git a/programs/media/ac97snd/trunk/mpg/getbits.h b/programs/media/ac97snd/trunk/mpg/getbits.h new file mode 100644 index 0000000000..7b7ad715e1 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/getbits.h @@ -0,0 +1,45 @@ +/* + getbits + + copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Michael Hipp +*/ + +#ifndef _MPG123_GETBITS_H_ +#define _MPG123_GETBITS_H_ + +/* that's the same file as getits.c but with defines to + force inlining */ + +static unsigned long rval; +static unsigned char rval_uc; + +#define backbits(nob) ((void)( \ + bsi.bitindex -= nob, \ + bsi.wordpointer += (bsi.bitindex>>3), \ + bsi.bitindex &= 0x7 )) + +#define getbitoffset() ((-bsi.bitindex)&0x7) +#define getbyte() (*bsi.wordpointer++) + +#define getbits(nob) ( \ + rval = bsi.wordpointer[0], rval <<= 8, rval |= bsi.wordpointer[1], \ + rval <<= 8, rval |= bsi.wordpointer[2], rval <<= bsi.bitindex, \ + rval &= 0xffffff, bsi.bitindex += nob, \ + rval >>= (24-nob), bsi.wordpointer += (bsi.bitindex>>3), \ + bsi.bitindex &= 7,rval) + +#define getbits_fast(nob) ( \ + rval = (unsigned char) (bsi.wordpointer[0] << bsi.bitindex), \ + rval |= ((unsigned long) bsi.wordpointer[1]<>8, \ + rval <<= nob, rval >>= 8, \ + bsi.bitindex += nob, bsi.wordpointer += (bsi.bitindex>>3), \ + bsi.bitindex &= 7, rval ) + +#define get1bit() ( \ + rval_uc = *bsi.wordpointer << bsi.bitindex, bsi.bitindex++, \ + bsi.wordpointer += (bsi.bitindex>>3), bsi.bitindex &= 7, rval_uc>>7 ) + + +#endif diff --git a/programs/media/ac97snd/trunk/mpg/huffman.h b/programs/media/ac97snd/trunk/mpg/huffman.h new file mode 100644 index 0000000000..4939e80047 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/huffman.h @@ -0,0 +1,340 @@ +/* + huffman.h: huffman tables ... recalcualted to work with optimzed decoder scheme (MH) + + copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Michael Hipp + + probably we could save a few bytes of memory, because the + smaller tables are often the part of a bigger table +*/ + + +#ifndef _MPG123_HUFFMAN_H_ +#define _MPG123_HUFFMAN_H_ + +struct newhuff +{ + unsigned int linbits; + short *table; +}; + +static short tab0[] = +{ + 0 +}; + +static short tab1[] = +{ + -5, -3, -1, 17, 1, 16, 0 +}; + +static short tab2[] = +{ + -15, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 17, -1, 1, + 16, 0 +}; + +static short tab3[] = +{ + -13, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 16, 17, -1, + 1, 0 +}; + +static short tab5[] = +{ + -29, -25, -23, -15, -7, -5, -3, -1, 51, 35, 50, 49, -3, -1, 19, + 3, -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, 17, -1, 1, 16, + 0 +}; + +static short tab6[] = +{ + -25, -19, -13, -9, -5, -3, -1, 51, 3, 35, -1, 50, 48, -1, 19, + 49, -3, -1, 34, 2, 18, -3, -1, 33, 32, 1, -1, 17, -1, 16, + 0 +}; + +static short tab7[] = +{ + -69, -65, -57, -39, -29, -17, -11, -7, -3, -1, 85, 69, -1, 84, 83, + -1, 53, 68, -3, -1, 37, 82, 21, -5, -1, 81, -1, 5, 52, -1, + 80, -1, 67, 51, -5, -3, -1, 36, 66, 20, -1, 65, 64, -11, -7, + -3, -1, 4, 35, -1, 50, 3, -1, 19, 49, -3, -1, 48, 34, 18, + -5, -1, 33, -1, 2, 32, 17, -1, 1, 16, 0 +}; + +static short tab8[] = +{ + -65, -63, -59, -45, -31, -19, -13, -7, -5, -3, -1, 85, 84, 69, 83, + -3, -1, 53, 68, 37, -3, -1, 82, 5, 21, -5, -1, 81, -1, 52, + 67, -3, -1, 80, 51, 36, -5, -3, -1, 66, 20, 65, -3, -1, 4, + 64, -1, 35, 50, -9, -7, -3, -1, 19, 49, -1, 3, 48, 34, -1, + 2, 32, -1, 18, 33, 17, -3, -1, 1, 16, 0 +}; + +static short tab9[] = +{ + -63, -53, -41, -29, -19, -11, -5, -3, -1, 85, 69, 53, -1, 83, -1, + 84, 5, -3, -1, 68, 37, -1, 82, 21, -3, -1, 81, 52, -1, 67, + -1, 80, 4, -7, -3, -1, 36, 66, -1, 51, 64, -1, 20, 65, -5, + -3, -1, 35, 50, 19, -1, 49, -1, 3, 48, -5, -3, -1, 34, 2, + 18, -1, 33, 32, -3, -1, 17, 1, -1, 16, 0 +}; + +static short tab10[] = +{ +-125,-121,-111, -83, -55, -35, -21, -13, -7, -3, -1, 119, 103, -1, 118, + 87, -3, -1, 117, 102, 71, -3, -1, 116, 86, -1, 101, 55, -9, -3, + -1, 115, 70, -3, -1, 85, 84, 99, -1, 39, 114, -11, -5, -3, -1, + 100, 7, 112, -1, 98, -1, 69, 53, -5, -1, 6, -1, 83, 68, 23, + -17, -5, -1, 113, -1, 54, 38, -5, -3, -1, 37, 82, 21, -1, 81, + -1, 52, 67, -3, -1, 22, 97, -1, 96, -1, 5, 80, -19, -11, -7, + -3, -1, 36, 66, -1, 51, 4, -1, 20, 65, -3, -1, 64, 35, -1, + 50, 3, -3, -1, 19, 49, -1, 48, 34, -7, -3, -1, 18, 33, -1, + 2, 32, 17, -1, 1, 16, 0 +}; + +static short tab11[] = +{ +-121,-113, -89, -59, -43, -27, -17, -7, -3, -1, 119, 103, -1, 118, 117, + -3, -1, 102, 71, -1, 116, -1, 87, 85, -5, -3, -1, 86, 101, 55, + -1, 115, 70, -9, -7, -3, -1, 69, 84, -1, 53, 83, 39, -1, 114, + -1, 100, 7, -5, -1, 113, -1, 23, 112, -3, -1, 54, 99, -1, 96, + -1, 68, 37, -13, -7, -5, -3, -1, 82, 5, 21, 98, -3, -1, 38, + 6, 22, -5, -1, 97, -1, 81, 52, -5, -1, 80, -1, 67, 51, -1, + 36, 66, -15, -11, -7, -3, -1, 20, 65, -1, 4, 64, -1, 35, 50, + -1, 19, 49, -5, -3, -1, 3, 48, 34, 33, -5, -1, 18, -1, 2, + 32, 17, -3, -1, 1, 16, 0 +}; + +static short tab12[] = +{ +-115, -99, -73, -45, -27, -17, -9, -5, -3, -1, 119, 103, 118, -1, 87, + 117, -3, -1, 102, 71, -1, 116, 101, -3, -1, 86, 55, -3, -1, 115, + 85, 39, -7, -3, -1, 114, 70, -1, 100, 23, -5, -1, 113, -1, 7, + 112, -1, 54, 99, -13, -9, -3, -1, 69, 84, -1, 68, -1, 6, 5, + -1, 38, 98, -5, -1, 97, -1, 22, 96, -3, -1, 53, 83, -1, 37, + 82, -17, -7, -3, -1, 21, 81, -1, 52, 67, -5, -3, -1, 80, 4, + 36, -1, 66, 20, -3, -1, 51, 65, -1, 35, 50, -11, -7, -5, -3, + -1, 64, 3, 48, 19, -1, 49, 34, -1, 18, 33, -7, -5, -3, -1, + 2, 32, 0, 17, -1, 1, 16 +}; + +static short tab13[] = +{ +-509,-503,-475,-405,-333,-265,-205,-153,-115, -83, -53, -35, -21, -13, -9, + -7, -5, -3, -1, 254, 252, 253, 237, 255, -1, 239, 223, -3, -1, 238, + 207, -1, 222, 191, -9, -3, -1, 251, 206, -1, 220, -1, 175, 233, -1, + 236, 221, -9, -5, -3, -1, 250, 205, 190, -1, 235, 159, -3, -1, 249, + 234, -1, 189, 219, -17, -9, -3, -1, 143, 248, -1, 204, -1, 174, 158, + -5, -1, 142, -1, 127, 126, 247, -5, -1, 218, -1, 173, 188, -3, -1, + 203, 246, 111, -15, -7, -3, -1, 232, 95, -1, 157, 217, -3, -1, 245, + 231, -1, 172, 187, -9, -3, -1, 79, 244, -3, -1, 202, 230, 243, -1, + 63, -1, 141, 216, -21, -9, -3, -1, 47, 242, -3, -1, 110, 156, 15, + -5, -3, -1, 201, 94, 171, -3, -1, 125, 215, 78, -11, -5, -3, -1, + 200, 214, 62, -1, 185, -1, 155, 170, -1, 31, 241, -23, -13, -5, -1, + 240, -1, 186, 229, -3, -1, 228, 140, -1, 109, 227, -5, -1, 226, -1, + 46, 14, -1, 30, 225, -15, -7, -3, -1, 224, 93, -1, 213, 124, -3, + -1, 199, 77, -1, 139, 184, -7, -3, -1, 212, 154, -1, 169, 108, -1, + 198, 61, -37, -21, -9, -5, -3, -1, 211, 123, 45, -1, 210, 29, -5, + -1, 183, -1, 92, 197, -3, -1, 153, 122, 195, -7, -5, -3, -1, 167, + 151, 75, 209, -3, -1, 13, 208, -1, 138, 168, -11, -7, -3, -1, 76, + 196, -1, 107, 182, -1, 60, 44, -3, -1, 194, 91, -3, -1, 181, 137, + 28, -43, -23, -11, -5, -1, 193, -1, 152, 12, -1, 192, -1, 180, 106, + -5, -3, -1, 166, 121, 59, -1, 179, -1, 136, 90, -11, -5, -1, 43, + -1, 165, 105, -1, 164, -1, 120, 135, -5, -1, 148, -1, 119, 118, 178, + -11, -3, -1, 27, 177, -3, -1, 11, 176, -1, 150, 74, -7, -3, -1, + 58, 163, -1, 89, 149, -1, 42, 162, -47, -23, -9, -3, -1, 26, 161, + -3, -1, 10, 104, 160, -5, -3, -1, 134, 73, 147, -3, -1, 57, 88, + -1, 133, 103, -9, -3, -1, 41, 146, -3, -1, 87, 117, 56, -5, -1, + 131, -1, 102, 71, -3, -1, 116, 86, -1, 101, 115, -11, -3, -1, 25, + 145, -3, -1, 9, 144, -1, 72, 132, -7, -5, -1, 114, -1, 70, 100, + 40, -1, 130, 24, -41, -27, -11, -5, -3, -1, 55, 39, 23, -1, 113, + -1, 85, 7, -7, -3, -1, 112, 54, -1, 99, 69, -3, -1, 84, 38, + -1, 98, 53, -5, -1, 129, -1, 8, 128, -3, -1, 22, 97, -1, 6, + 96, -13, -9, -5, -3, -1, 83, 68, 37, -1, 82, 5, -1, 21, 81, + -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, -19, -11, + -5, -1, 65, -1, 4, 64, -3, -1, 35, 50, 19, -3, -1, 49, 3, + -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16, + 0 +}; + +static short tab15[] = +{ +-495,-445,-355,-263,-183,-115, -77, -43, -27, -13, -7, -3, -1, 255, 239, + -1, 254, 223, -1, 238, -1, 253, 207, -7, -3, -1, 252, 222, -1, 237, + 191, -1, 251, -1, 206, 236, -7, -3, -1, 221, 175, -1, 250, 190, -3, + -1, 235, 205, -1, 220, 159, -15, -7, -3, -1, 249, 234, -1, 189, 219, + -3, -1, 143, 248, -1, 204, 158, -7, -3, -1, 233, 127, -1, 247, 173, + -3, -1, 218, 188, -1, 111, -1, 174, 15, -19, -11, -3, -1, 203, 246, + -3, -1, 142, 232, -1, 95, 157, -3, -1, 245, 126, -1, 231, 172, -9, + -3, -1, 202, 187, -3, -1, 217, 141, 79, -3, -1, 244, 63, -1, 243, + 216, -33, -17, -9, -3, -1, 230, 47, -1, 242, -1, 110, 240, -3, -1, + 31, 241, -1, 156, 201, -7, -3, -1, 94, 171, -1, 186, 229, -3, -1, + 125, 215, -1, 78, 228, -15, -7, -3, -1, 140, 200, -1, 62, 109, -3, + -1, 214, 227, -1, 155, 185, -7, -3, -1, 46, 170, -1, 226, 30, -5, + -1, 225, -1, 14, 224, -1, 93, 213, -45, -25, -13, -7, -3, -1, 124, + 199, -1, 77, 139, -1, 212, -1, 184, 154, -7, -3, -1, 169, 108, -1, + 198, 61, -1, 211, 210, -9, -5, -3, -1, 45, 13, 29, -1, 123, 183, + -5, -1, 209, -1, 92, 208, -1, 197, 138, -17, -7, -3, -1, 168, 76, + -1, 196, 107, -5, -1, 182, -1, 153, 12, -1, 60, 195, -9, -3, -1, + 122, 167, -1, 166, -1, 192, 11, -1, 194, -1, 44, 91, -55, -29, -15, + -7, -3, -1, 181, 28, -1, 137, 152, -3, -1, 193, 75, -1, 180, 106, + -5, -3, -1, 59, 121, 179, -3, -1, 151, 136, -1, 43, 90, -11, -5, + -1, 178, -1, 165, 27, -1, 177, -1, 176, 105, -7, -3, -1, 150, 74, + -1, 164, 120, -3, -1, 135, 58, 163, -17, -7, -3, -1, 89, 149, -1, + 42, 162, -3, -1, 26, 161, -3, -1, 10, 160, 104, -7, -3, -1, 134, + 73, -1, 148, 57, -5, -1, 147, -1, 119, 9, -1, 88, 133, -53, -29, + -13, -7, -3, -1, 41, 103, -1, 118, 146, -1, 145, -1, 25, 144, -7, + -3, -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 71, -7, + -3, -1, 40, 130, -1, 24, 129, -7, -3, -1, 116, 8, -1, 128, 86, + -3, -1, 101, 55, -1, 115, 70, -17, -7, -3, -1, 39, 114, -1, 100, + 23, -3, -1, 85, 113, -3, -1, 7, 112, 54, -7, -3, -1, 99, 69, + -1, 84, 38, -3, -1, 98, 22, -3, -1, 6, 96, 53, -33, -19, -9, + -5, -1, 97, -1, 83, 68, -1, 37, 82, -3, -1, 21, 81, -3, -1, + 5, 80, 52, -7, -3, -1, 67, 36, -1, 66, 51, -1, 65, -1, 20, + 4, -9, -3, -1, 35, 50, -3, -1, 64, 3, 19, -3, -1, 49, 48, + 34, -9, -7, -3, -1, 18, 33, -1, 2, 32, 17, -3, -1, 1, 16, + 0 +}; + +static short tab16[] = +{ +-509,-503,-461,-323,-103, -37, -27, -15, -7, -3, -1, 239, 254, -1, 223, + 253, -3, -1, 207, 252, -1, 191, 251, -5, -1, 175, -1, 250, 159, -3, + -1, 249, 248, 143, -7, -3, -1, 127, 247, -1, 111, 246, 255, -9, -5, + -3, -1, 95, 245, 79, -1, 244, 243, -53, -1, 240, -1, 63, -29, -19, + -13, -7, -5, -1, 206, -1, 236, 221, 222, -1, 233, -1, 234, 217, -1, + 238, -1, 237, 235, -3, -1, 190, 205, -3, -1, 220, 219, 174, -11, -5, + -1, 204, -1, 173, 218, -3, -1, 126, 172, 202, -5, -3, -1, 201, 125, + 94, 189, 242, -93, -5, -3, -1, 47, 15, 31, -1, 241, -49, -25, -13, + -5, -1, 158, -1, 188, 203, -3, -1, 142, 232, -1, 157, 231, -7, -3, + -1, 187, 141, -1, 216, 110, -1, 230, 156, -13, -7, -3, -1, 171, 186, + -1, 229, 215, -1, 78, -1, 228, 140, -3, -1, 200, 62, -1, 109, -1, + 214, 155, -19, -11, -5, -3, -1, 185, 170, 225, -1, 212, -1, 184, 169, + -5, -1, 123, -1, 183, 208, 227, -7, -3, -1, 14, 224, -1, 93, 213, + -3, -1, 124, 199, -1, 77, 139, -75, -45, -27, -13, -7, -3, -1, 154, + 108, -1, 198, 61, -3, -1, 92, 197, 13, -7, -3, -1, 138, 168, -1, + 153, 76, -3, -1, 182, 122, 60, -11, -5, -3, -1, 91, 137, 28, -1, + 192, -1, 152, 121, -1, 226, -1, 46, 30, -15, -7, -3, -1, 211, 45, + -1, 210, 209, -5, -1, 59, -1, 151, 136, 29, -7, -3, -1, 196, 107, + -1, 195, 167, -1, 44, -1, 194, 181, -23, -13, -7, -3, -1, 193, 12, + -1, 75, 180, -3, -1, 106, 166, 179, -5, -3, -1, 90, 165, 43, -1, + 178, 27, -13, -5, -1, 177, -1, 11, 176, -3, -1, 105, 150, -1, 74, + 164, -5, -3, -1, 120, 135, 163, -3, -1, 58, 89, 42, -97, -57, -33, + -19, -11, -5, -3, -1, 149, 104, 161, -3, -1, 134, 119, 148, -5, -3, + -1, 73, 87, 103, 162, -5, -1, 26, -1, 10, 160, -3, -1, 57, 147, + -1, 88, 133, -9, -3, -1, 41, 146, -3, -1, 118, 9, 25, -5, -1, + 145, -1, 144, 72, -3, -1, 132, 117, -1, 56, 131, -21, -11, -5, -3, + -1, 102, 40, 130, -3, -1, 71, 116, 24, -3, -1, 129, 128, -3, -1, + 8, 86, 55, -9, -5, -1, 115, -1, 101, 70, -1, 39, 114, -5, -3, + -1, 100, 85, 7, 23, -23, -13, -5, -1, 113, -1, 112, 54, -3, -1, + 99, 69, -1, 84, 38, -3, -1, 98, 22, -1, 97, -1, 6, 96, -9, + -5, -1, 83, -1, 53, 68, -1, 37, 82, -1, 81, -1, 21, 5, -33, + -23, -13, -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, + -5, -1, 65, -1, 4, 64, -1, 35, 50, -3, -1, 19, 49, -3, -1, + 3, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16, + 0 +}; + +static short tab24[] = +{ +-451,-117, -43, -25, -15, -7, -3, -1, 239, 254, -1, 223, 253, -3, -1, + 207, 252, -1, 191, 251, -5, -1, 250, -1, 175, 159, -1, 249, 248, -9, + -5, -3, -1, 143, 127, 247, -1, 111, 246, -3, -1, 95, 245, -1, 79, + 244, -71, -7, -3, -1, 63, 243, -1, 47, 242, -5, -1, 241, -1, 31, + 240, -25, -9, -1, 15, -3, -1, 238, 222, -1, 237, 206, -7, -3, -1, + 236, 221, -1, 190, 235, -3, -1, 205, 220, -1, 174, 234, -15, -7, -3, + -1, 189, 219, -1, 204, 158, -3, -1, 233, 173, -1, 218, 188, -7, -3, + -1, 203, 142, -1, 232, 157, -3, -1, 217, 126, -1, 231, 172, 255,-235, +-143, -77, -45, -25, -15, -7, -3, -1, 202, 187, -1, 141, 216, -5, -3, + -1, 14, 224, 13, 230, -5, -3, -1, 110, 156, 201, -1, 94, 186, -9, + -5, -1, 229, -1, 171, 125, -1, 215, 228, -3, -1, 140, 200, -3, -1, + 78, 46, 62, -15, -7, -3, -1, 109, 214, -1, 227, 155, -3, -1, 185, + 170, -1, 226, 30, -7, -3, -1, 225, 93, -1, 213, 124, -3, -1, 199, + 77, -1, 139, 184, -31, -15, -7, -3, -1, 212, 154, -1, 169, 108, -3, + -1, 198, 61, -1, 211, 45, -7, -3, -1, 210, 29, -1, 123, 183, -3, + -1, 209, 92, -1, 197, 138, -17, -7, -3, -1, 168, 153, -1, 76, 196, + -3, -1, 107, 182, -3, -1, 208, 12, 60, -7, -3, -1, 195, 122, -1, + 167, 44, -3, -1, 194, 91, -1, 181, 28, -57, -35, -19, -7, -3, -1, + 137, 152, -1, 193, 75, -5, -3, -1, 192, 11, 59, -3, -1, 176, 10, + 26, -5, -1, 180, -1, 106, 166, -3, -1, 121, 151, -3, -1, 160, 9, + 144, -9, -3, -1, 179, 136, -3, -1, 43, 90, 178, -7, -3, -1, 165, + 27, -1, 177, 105, -1, 150, 164, -17, -9, -5, -3, -1, 74, 120, 135, + -1, 58, 163, -3, -1, 89, 149, -1, 42, 162, -7, -3, -1, 161, 104, + -1, 134, 119, -3, -1, 73, 148, -1, 57, 147, -63, -31, -15, -7, -3, + -1, 88, 133, -1, 41, 103, -3, -1, 118, 146, -1, 25, 145, -7, -3, + -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 40, -17, -7, + -3, -1, 130, 24, -1, 71, 116, -5, -1, 129, -1, 8, 128, -1, 86, + 101, -7, -5, -1, 23, -1, 7, 112, 115, -3, -1, 55, 39, 114, -15, + -7, -3, -1, 70, 100, -1, 85, 113, -3, -1, 54, 99, -1, 69, 84, + -7, -3, -1, 38, 98, -1, 22, 97, -5, -3, -1, 6, 96, 53, -1, + 83, 68, -51, -37, -23, -15, -9, -3, -1, 37, 82, -1, 21, -1, 5, + 80, -1, 81, -1, 52, 67, -3, -1, 36, 66, -1, 51, 20, -9, -5, + -1, 65, -1, 4, 64, -1, 35, 50, -1, 19, 49, -7, -5, -3, -1, + 3, 48, 34, 18, -1, 33, -1, 2, 32, -3, -1, 17, 1, -1, 16, + 0 +}; + +static short tab_c0[] = +{ + -29, -21, -13, -7, -3, -1, 11, 15, -1, 13, 14, -3, -1, 7, 5, + 9, -3, -1, 6, 3, -1, 10, 12, -3, -1, 2, 1, -1, 4, 8, + 0 +}; + +static short tab_c1[] = +{ + -15, -7, -3, -1, 15, 14, -1, 13, 12, -3, -1, 11, 10, -1, 9, + 8, -7, -3, -1, 7, 6, -1, 5, 4, -3, -1, 3, 2, -1, 1, + 0 +}; + + + +static struct newhuff ht[] = +{ + { /* 0 */ 0 , tab0 } , + { /* 2 */ 0 , tab1 } , + { /* 3 */ 0 , tab2 } , + { /* 3 */ 0 , tab3 } , + { /* 0 */ 0 , tab0 } , + { /* 4 */ 0 , tab5 } , + { /* 4 */ 0 , tab6 } , + { /* 6 */ 0 , tab7 } , + { /* 6 */ 0 , tab8 } , + { /* 6 */ 0 , tab9 } , + { /* 8 */ 0 , tab10 } , + { /* 8 */ 0 , tab11 } , + { /* 8 */ 0 , tab12 } , + { /* 16 */ 0 , tab13 } , + { /* 0 */ 0 , tab0 } , + { /* 16 */ 0 , tab15 } , + + { /* 16 */ 1 , tab16 } , + { /* 16 */ 2 , tab16 } , + { /* 16 */ 3 , tab16 } , + { /* 16 */ 4 , tab16 } , + { /* 16 */ 6 , tab16 } , + { /* 16 */ 8 , tab16 } , + { /* 16 */ 10, tab16 } , + { /* 16 */ 13, tab16 } , + { /* 16 */ 4 , tab24 } , + { /* 16 */ 5 , tab24 } , + { /* 16 */ 6 , tab24 } , + { /* 16 */ 7 , tab24 } , + { /* 16 */ 8 , tab24 } , + { /* 16 */ 9 , tab24 } , + { /* 16 */ 11, tab24 } , + { /* 16 */ 13, tab24 } +}; + +static struct newhuff htc[] = +{ + { /* 1 , 1 , */ 0 , tab_c0 } , + { /* 1 , 1 , */ 0 , tab_c1 } +}; + + +#endif diff --git a/programs/media/ac97snd/trunk/mpg/l2tables.h b/programs/media/ac97snd/trunk/mpg/l2tables.h new file mode 100644 index 0000000000..59fed889f3 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/l2tables.h @@ -0,0 +1,164 @@ +/* + l2tables.h: Layer 2 Alloc tables + + copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Michael Hipp + + most other tables are calculated on program start (which is (of course) not ISO-conform) + Layer-3 huffman table is in huffman.h +*/ + + +#ifndef _MPG123_L2TABLES_H_ +#define _MPG123_L2TABLES_H_ + +struct al_table alloc_0[] = { + {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511}, + {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767}, + {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511}, + {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767}, + {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511}, + {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767} }; + +struct al_table alloc_1[] = { + {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511}, + {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767}, + {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511}, + {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767}, + {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511}, + {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767} }; + +struct al_table alloc_2[] = { + {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255}, + {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383}, + {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255}, + {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} }; + +struct al_table alloc_3[] = { + {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255}, + {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383}, + {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255}, + {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} }; + +struct al_table alloc_4[] = { + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9} }; + +#endif + diff --git a/programs/media/ac97snd/trunk/mpg/layer1.c b/programs/media/ac97snd/trunk/mpg/layer1.c new file mode 100644 index 0000000000..bda5a0e383 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/layer1.c @@ -0,0 +1,151 @@ +/* + layer1.c: the layer 1 decoder + + copyright 1995-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Michael Hipp + + may have a few bugs after last optimization ... +*/ + +#include "mpg123.h" + +void I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT],struct frame *fr) +{ + unsigned int *ba=balloc; + unsigned int *sca = (unsigned int *) scale_index; + + if(fr->stereo == 2) { + int i; + int jsbound = fr->jsbound; + for (i=0;istereo == 2) { + int jsbound = fr->jsbound; + register real *f0 = fraction[0]; + register real *f1 = fraction[1]; + ba = balloc; + for (sample=smpb,i=0;idown_sample_sblimit;i<32;i++) + fraction[0][i] = fraction[1][i] = 0.0; + } + else { + register real *f0 = fraction[0]; + ba = balloc; + for (sample=smpb,i=0;idown_sample_sblimit;i<32;i++) + fraction[0][i] = 0.0; + } +} + +int do_layer1(struct frame *fr,byte *pcm_sample, int *pcm_point) +{ + int clip=0; + int i,stereo = fr->stereo; + unsigned int balloc[2*SBLIMIT]; + unsigned int scale_index[2][SBLIMIT]; + real fraction[2][SBLIMIT]; + int single = fr->single; + + fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext<<2)+4 : 32; + + if(stereo == 1 || single == 3) + single = 0; + + I_step_one(balloc,scale_index,fr); + + for (i=0;i= 0) + { + clip += (fr->synth_mono)( (real *) fraction[single],pcm_sample,pcm_point); + } + else { + int p1=*pcm_point; + clip += (fr->synth)( (real *) fraction[0],0,pcm_sample,&p1); + clip += (fr->synth)( (real *) fraction[1],1,pcm_sample,pcm_point); + } + } + return clip; +} + + diff --git a/programs/media/ac97snd/trunk/mpg/layer2.c b/programs/media/ac97snd/trunk/mpg/layer2.c new file mode 100644 index 0000000000..9565f90fee --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/layer2.c @@ -0,0 +1,306 @@ +/* + layer2.c: the layer 2 decoder, root of mpg123 + + copyright 1994-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Michael Hipp + + mpg123 started as mp2 decoder a long time ago... +*/ + +#include "mpg123.h" +#include "l2tables.h" + +static int grp_3tab[32 * 3] = { 0, }; /* used: 27 */ +static int grp_5tab[128 * 3] = { 0, }; /* used: 125 */ +static int grp_9tab[1024 * 3] = { 0, }; /* used: 729 */ + +real muls[27][64]; /* also used by layer 1 */ + +void init_layer2(void) +{ + static double mulmul[27] = { + 0.0 , -2.0/3.0 , 2.0/3.0 , + 2.0/7.0 , 2.0/15.0 , 2.0/31.0, 2.0/63.0 , 2.0/127.0 , 2.0/255.0 , + 2.0/511.0 , 2.0/1023.0 , 2.0/2047.0 , 2.0/4095.0 , 2.0/8191.0 , + 2.0/16383.0 , 2.0/32767.0 , 2.0/65535.0 , + -4.0/5.0 , -2.0/5.0 , 2.0/5.0, 4.0/5.0 , + -8.0/9.0 , -4.0/9.0 , -2.0/9.0 , 2.0/9.0 , 4.0/9.0 , 8.0/9.0 }; + static int base[3][9] = { + { 1 , 0, 2 , } , + { 17, 18, 0 , 19, 20 , } , + { 21, 1, 22, 23, 0, 24, 25, 2, 26 } }; + int i,j,k,l,len; + real *table; + static int tablen[3] = { 3 , 5 , 9 }; + static int *itable,*tables[3] = { grp_3tab , grp_5tab , grp_9tab }; + + for(i=0;i<3;i++) + { + itable = tables[i]; + len = tablen[i]; + for(j=0;jstereo-1; + int sblimit = fr->II_sblimit; + int jsbound = fr->jsbound; + int sblimit2 = fr->II_sblimit<alloc; + int i; + static unsigned int scfsi_buf[64]; + unsigned int *scfsi,*bita; + int sc,step; + + bita = bit_alloc; + if(stereo) + { + for (i=jsbound;i;i--,alloc1+=(1<bits); + *bita++ = (char) getbits(step); + } + for (i=sblimit-jsbound;i;i--,alloc1+=(1<bits); + bita[1] = bita[0]; + bita+=2; + } + bita = bit_alloc; + scfsi=scfsi_buf; + for (i=sblimit2;i;i--) + if (*bita++) + *scfsi++ = (char) getbits_fast(2); + } + else /* mono */ + { + for (i=sblimit;i;i--,alloc1+=(1<bits); + bita = bit_alloc; + scfsi=scfsi_buf; + for (i=sblimit;i;i--) + if (*bita++) + *scfsi++ = (char) getbits_fast(2); + } + + bita = bit_alloc; + scfsi=scfsi_buf; + for (i=sblimit2;i;i--) + if (*bita++) + switch (*scfsi++) + { + case 0: + *scale++ = getbits_fast(6); + *scale++ = getbits_fast(6); + *scale++ = getbits_fast(6); + break; + case 1 : + *scale++ = sc = getbits_fast(6); + *scale++ = sc; + *scale++ = getbits_fast(6); + break; + case 2: + *scale++ = sc = getbits_fast(6); + *scale++ = sc; + *scale++ = sc; + break; + default: /* case 3 */ + *scale++ = getbits_fast(6); + *scale++ = sc = getbits_fast(6); + *scale++ = sc; + break; + } + +} + +void II_step_two(unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int *scale,struct frame *fr,int x1) +{ + int i,j,k,ba; + int stereo = fr->stereo; + int sblimit = fr->II_sblimit; + int jsbound = fr->jsbound; + struct al_table *alloc2,*alloc1 = fr->alloc; + unsigned int *bita=bit_alloc; + int d1,step; + + for (i=0;ibits; + for (j=0;jbits; + if( (d1=alloc2->d) < 0) + { + real cm=muls[k][scale[x1]]; + fraction[j][0][i] = ((real) ((int)getbits(k) + d1)) * cm; + fraction[j][1][i] = ((real) ((int)getbits(k) + d1)) * cm; + fraction[j][2][i] = ((real) ((int)getbits(k) + d1)) * cm; + } + else + { + static int *table[] = { 0,0,0,grp_3tab,0,grp_5tab,0,0,0,grp_9tab }; + unsigned int idx,*tab,m=scale[x1]; + idx = (unsigned int) getbits(k); + tab = (unsigned int *) (table[d1] + idx + idx + idx); + fraction[j][0][i] = muls[*tab++][m]; + fraction[j][1][i] = muls[*tab++][m]; + fraction[j][2][i] = muls[*tab][m]; + } + scale+=3; + } + else + fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0; + } + } + + for (i=jsbound;ibits; + bita++; /* channel 1 and channel 2 bitalloc are the same */ + if ( (ba=*bita++) ) + { + k=(alloc2 = alloc1+ba)->bits; + if( (d1=alloc2->d) < 0) + { + real cm; + cm=muls[k][scale[x1+3]]; + fraction[1][0][i] = (fraction[0][0][i] = (real) ((int)getbits(k) + d1) ) * cm; + fraction[1][1][i] = (fraction[0][1][i] = (real) ((int)getbits(k) + d1) ) * cm; + fraction[1][2][i] = (fraction[0][2][i] = (real) ((int)getbits(k) + d1) ) * cm; + cm=muls[k][scale[x1]]; + fraction[0][0][i] *= cm; fraction[0][1][i] *= cm; fraction[0][2][i] *= cm; + } + else + { + static int *table[] = { 0,0,0,grp_3tab,0,grp_5tab,0,0,0,grp_9tab }; + unsigned int idx,*tab,m1,m2; + m1 = scale[x1]; m2 = scale[x1+3]; + idx = (unsigned int) getbits(k); + tab = (unsigned int *) (table[d1] + idx + idx + idx); + fraction[0][0][i] = muls[*tab][m1]; fraction[1][0][i] = muls[*tab++][m2]; + fraction[0][1][i] = muls[*tab][m1]; fraction[1][1][i] = muls[*tab++][m2]; + fraction[0][2][i] = muls[*tab][m1]; fraction[1][2][i] = muls[*tab][m2]; + } + scale+=6; + } + else { + fraction[0][0][i] = fraction[0][1][i] = fraction[0][2][i] = + fraction[1][0][i] = fraction[1][1][i] = fraction[1][2][i] = 0.0; + } +/* + should we use individual scalefac for channel 2 or + is the current way the right one , where we just copy channel 1 to + channel 2 ?? + The current 'strange' thing is, that we throw away the scalefac + values for the second channel ...!! +-> changed .. now we use the scalefac values of channel one !! +*/ + } + + if(sblimit > (fr->down_sample_sblimit) ) + sblimit = fr->down_sample_sblimit; + + for(i=sblimit;isampling_frequency >= 3) /* Or equivalent: (fr->lsf == 1) */ + table = 4; + else + table = translate[fr->sampling_frequency][2-fr->stereo][fr->bitrate_index]; + sblim = sblims[table]; + + fr->alloc = tables[table]; + fr->II_sblimit = sblim; +} + + +int do_layer2(struct frame *fr,byte *pcm_sample,int *pcm_point) +{ + int clip=0; + int i,j; + int stereo = fr->stereo; + real fraction[2][4][SBLIMIT]; /* pick_table clears unused subbands */ + unsigned int bit_alloc[64]; + int scale[192]; + int single = fr->single; + + II_select_table(fr); + fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? + (fr->mode_ext<<2)+4 : fr->II_sblimit; + + if (fr->jsbound > fr->II_sblimit) { + fr->jsbound=fr->II_sblimit; + } + + if(stereo == 1 || single == 3) + single = 0; + + II_step_one(bit_alloc, scale, fr); + + for (i=0;i>2); + for (j=0;j<3;j++) + { + if(single >= 0) + { + clip += (fr->synth_mono) (fraction[single][j],pcm_sample,pcm_point); + } + else { + int p1=*pcm_point; + clip += (fr->synth) (fraction[0][j],0,pcm_sample, &p1); + clip += (fr->synth) (fraction[1][j],1,pcm_sample,pcm_point); + } + } + } + + return clip; +} + + diff --git a/programs/media/ac97snd/trunk/mpg/layer3.c b/programs/media/ac97snd/trunk/mpg/layer3.c new file mode 100644 index 0000000000..25f74d3757 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/layer3.c @@ -0,0 +1,1953 @@ +/* + leyer3.c: the layer 3 decoder + + copyright 1995-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Michael Hipp + + Optimize-TODO: put short bands into the band-field without the stride of 3 reals + Length-optimze: unify long and short band code where it is possible + + The int-vs-pointer situation has to be cleaned up. +*/ + +//#include +//#include "config.h" +#include "mpg123.h" +#include "huffman.h" + +//#include "common.h" +//#include "debug.h" + +#include "getbits.h" + +static real ispow[8207]; +static real aa_ca[8],aa_cs[8]; +static real COS1[12][6]; +static real win[4][36]; +static real win1[4][36]; +static real gainpow2[256+118+4]; +#ifdef USE_3DNOW +real COS9[9]; +static real COS6_1,COS6_2; +real tfcos36[9]; +#else +static real COS9[9]; +static real COS6_1,COS6_2; +static real tfcos36[9]; +#endif +static real tfcos12[3]; +#define NEW_DCT9 +#ifdef NEW_DCT9 +static real cos9[3],cos18[3]; +#endif + +struct bandInfoStruct { + int longIdx[23]; + int longDiff[22]; + int shortIdx[14]; + int shortDiff[13]; +}; + +int longLimit[9][23]; +int shortLimit[9][14]; + +struct bandInfoStruct bandInfo[9] = { + +/* MPEG 1.0 */ + { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576}, + {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158}, + {0,4*3,8*3,12*3,16*3,22*3,30*3,40*3,52*3,66*3, 84*3,106*3,136*3,192*3}, + {4,4,4,4,6,8,10,12,14,18,22,30,56} } , + + { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576}, + {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192}, + {0,4*3,8*3,12*3,16*3,22*3,28*3,38*3,50*3,64*3, 80*3,100*3,126*3,192*3}, + {4,4,4,4,6,6,10,12,14,16,20,26,66} } , + + { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} , + {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} , + {0,4*3,8*3,12*3,16*3,22*3,30*3,42*3,58*3,78*3,104*3,138*3,180*3,192*3} , + {4,4,4,4,6,8,12,16,20,26,34,42,12} } , + +/* MPEG 2.0 */ + { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, + {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } , + {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} , + {4,4,4,6,6,8,10,14,18,26,32,42,18 } } , + +/* mhipp trunk has 330 -> 332 without further explanation ... */ + { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576}, + {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,70,76,36 } , + {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,136*3,180*3,192*3} , + {4,4,4,6,8,10,12,14,18,24,32,44,12 } } , + + { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, + {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 }, + {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,134*3,174*3,192*3}, + {4,4,4,6,8,10,12,14,18,24,30,40,18 } } , +/* MPEG 2.5 */ + { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} , + {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54}, + {0,12,24,36,54,78,108,144,186,240,312,402,522,576}, + {4,4,4,6,8,10,12,14,18,24,30,40,18} }, + { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} , + {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54}, + {0,12,24,36,54,78,108,144,186,240,312,402,522,576}, + {4,4,4,6,8,10,12,14,18,24,30,40,18} }, + { {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576}, + {12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2}, + {0, 24, 48, 72,108,156,216,288,372,480,486,492,498,576}, + {8,8,8,12,16,20,24,28,36,2,2,2,26} } , +}; + +static int mapbuf0[9][152]; +static int mapbuf1[9][156]; +static int mapbuf2[9][44]; +static int *map[9][3]; +static int *mapend[9][3]; + +static unsigned int n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */ +static unsigned int i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */ + +static real tan1_1[16],tan2_1[16],tan1_2[16],tan2_2[16]; +static real pow1_1[2][16],pow2_1[2][16],pow1_2[2][16],pow2_2[2][16]; + +#ifdef GAPLESS +/* still a dirty hack, places in bytes (zero-based)... */ +static unsigned long position; /* position in raw decoder bytestream */ +static unsigned long begin; /* first byte to play == number to skip */ +static unsigned long end; /* last byte to play */ +static unsigned long ignore; /* forcedly ignore stuff in between */ +static int bytified; + +/* input in bytes already */ +void layer3_gapless_init(unsigned long b, unsigned long e) +{ + bytified = 0; + position = 0; + ignore = 0; + begin = b; + end = e; + debug2("layer3_gapless_init: from %lu to %lu samples", begin, end); +} + +void layer3_gapless_set_position(unsigned long frames, struct frame* fr, struct audio_info_struct *ai) +{ + position = samples_to_bytes(frames*spf(fr), fr, ai); + debug1("set; position now %lu", position); +} + +void layer3_gapless_bytify(struct frame *fr, struct audio_info_struct *ai) +{ + if(!bytified) + { + begin = samples_to_bytes(begin, fr, ai); + end = samples_to_bytes(end, fr, ai); + bytified = 1; + debug2("bytified: begin=%lu; end=%5lu", begin, end); + } +} + +/* I need initialized fr here! */ +void layer3_gapless_set_ignore(unsigned long frames, struct frame *fr, struct audio_info_struct *ai) +{ + ignore = samples_to_bytes(frames*spf(fr), fr, ai); +} + +/* + take the (partially or fully) filled and remove stuff for gapless mode if needed + pcm_point may then be smaller than before... +*/ +void layer3_gapless_buffercheck() +{ + /* pcm_point bytes added since last position... */ + unsigned long new_pos = position + pcm_point; + if(begin && (position < begin)) + { + debug4("new_pos %lu (old: %lu), begin %lu, pcm_point %i", new_pos, position, begin, pcm_point); + if(new_pos < begin) + { + if(ignore > pcm_point) ignore -= pcm_point; + else ignore = 0; + pcm_point = 0; /* full of padding/delay */ + } + else + { + unsigned long ignored = begin-position; + /* we need to shift the memory to the left... */ + debug3("old pcm_point: %i, begin %lu; good bytes: %i", pcm_point, begin, (int)(new_pos-begin)); + if(ignore > ignored) ignore -= ignored; + else ignore = 0; + pcm_point -= ignored; + debug3("shifting %i bytes from %p to %p", pcm_point, pcm_sample+(int)(begin-position), pcm_sample); + memmove(pcm_sample, pcm_sample+(int)(begin-position), pcm_point); + } + } + /* I don't cover the case with both end and begin in chunk! */ + else if(end && (new_pos > end)) + { + ignore = 0; + /* either end in current chunk or chunk totally out */ + debug2("ending at position %lu / point %i", new_pos, pcm_point); + if(position < end) pcm_point -= new_pos-end; + else pcm_point = 0; + debug1("set pcm_point to %i", pcm_point); + } + else if(ignore) + { + if(pcm_point < ignore) + { + ignore -= pcm_point; + debug2("ignored %i bytes; pcm_point = 0; %lu bytes left", pcm_point, ignore); + pcm_point = 0; + } + else + { + /* we need to shift the memory to the left... */ + debug3("old pcm_point: %i, to ignore: %lu; good bytes: %i", pcm_point, ignore, pcm_point-(int)ignore); + pcm_point -= ignore; + debug3("shifting %i bytes from %p to %p", pcm_point, pcm_sample+ignore, pcm_sample); + memmove(pcm_sample, pcm_sample+ignore, pcm_point); + ignore = 0; + } + } + position = new_pos; +} +#endif + +/* + * init tables for layer-3 + */ + +#pragma warning(disable:4244) +void init_layer3(int down_sample_sblimit) +{ + int i,j,k,l; + + for(i=-256;i<118+4;i++) +#ifdef USE_MMX + if(!param.down_sample) + gainpow2[i+256] = 16384.0 * pow((double)2.0,-0.25 * (double) (i+210) ); + else +#endif + gainpow2[i+256] = DOUBLE_TO_REAL(pow_test((double)2.0,-0.25 * (double) (i+210))); + + for(i=0;i<8207;i++) + ispow[i] = DOUBLE_TO_REAL(pow_test((double)i,(double)4.0/3.0)); + + for (i=0;i<8;i++) { + static double Ci[8]={-0.6,-0.535,-0.33,-0.185,-0.095,-0.041,-0.0142,-0.0037}; + double sq=sqrt(1.0+Ci[i]*Ci[i]); + aa_cs[i] = DOUBLE_TO_REAL(1.0/sq); + aa_ca[i] = DOUBLE_TO_REAL(Ci[i]/sq); + } + + for(i=0;i<18;i++) { + win[0][i] = win[1][i] = DOUBLE_TO_REAL(0.5 * sin( M_PI / 72.0 * (double) (2*(i+0) +1) ) / cos ( M_PI * (double) (2*(i+0) +19) / 72.0 )); + win[0][i+18] = win[3][i+18] = DOUBLE_TO_REAL(0.5 * sin( M_PI / 72.0 * (double) (2*(i+18)+1) ) / cos ( M_PI * (double) (2*(i+18)+19) / 72.0 )); + } + for(i=0;i<6;i++) { + win[1][i+18] = DOUBLE_TO_REAL(0.5 / cos ( M_PI * (double) (2*(i+18)+19) / 72.0 )); + win[3][i+12] = DOUBLE_TO_REAL(0.5 / cos ( M_PI * (double) (2*(i+12)+19) / 72.0 )); + win[1][i+24] = DOUBLE_TO_REAL(0.5 * sin( M_PI / 24.0 * (double) (2*i+13) ) / cos ( M_PI * (double) (2*(i+24)+19) / 72.0 )); + win[1][i+30] = win[3][i] = DOUBLE_TO_REAL(0.0); + win[3][i+6 ] = DOUBLE_TO_REAL(0.5 * sin( M_PI / 24.0 * (double) (2*i+1) ) / cos ( M_PI * (double) (2*(i+6 )+19) / 72.0 )); + } + + for(i=0;i<9;i++) + COS9[i] = DOUBLE_TO_REAL(cos( M_PI / 18.0 * (double) i)); + + for(i=0;i<9;i++) + tfcos36[i] = DOUBLE_TO_REAL(0.5 / cos ( M_PI * (double) (i*2+1) / 36.0 )); + for(i=0;i<3;i++) + tfcos12[i] = DOUBLE_TO_REAL(0.5 / cos ( M_PI * (double) (i*2+1) / 12.0 )); + + COS6_1 = DOUBLE_TO_REAL(cos( M_PI / 6.0 * (double) 1)); + COS6_2 = DOUBLE_TO_REAL(cos( M_PI / 6.0 * (double) 2)); + +#ifdef NEW_DCT9 + cos9[0] = DOUBLE_TO_REAL(cos(1.0*M_PI/9.0)); + cos9[1] = DOUBLE_TO_REAL(cos(5.0*M_PI/9.0)); + cos9[2] = DOUBLE_TO_REAL(cos(7.0*M_PI/9.0)); + cos18[0] = DOUBLE_TO_REAL(cos(1.0*M_PI/18.0)); + cos18[1] = DOUBLE_TO_REAL(cos(11.0*M_PI/18.0)); + cos18[2] = DOUBLE_TO_REAL(cos(13.0*M_PI/18.0)); +#endif + + for(i=0;i<12;i++) { + win[2][i] = DOUBLE_TO_REAL(0.5 * sin( M_PI / 24.0 * (double) (2*i+1) ) / cos ( M_PI * (double) (2*i+7) / 24.0 )); + for(j=0;j<6;j++) + COS1[i][j] = DOUBLE_TO_REAL(cos( M_PI / 24.0 * (double) ((2*i+7)*(2*j+1)) )); + } + + for(j=0;j<4;j++) { + static int len[4] = { 36,36,12,36 }; + for(i=0;i 0) { + if( i & 1 ) + p1 = pow_test(base,(i+1.0)*0.5); + else + p2 = pow_test(base,i*0.5); + } + pow1_1[j][i] = DOUBLE_TO_REAL(p1); + pow2_1[j][i] = DOUBLE_TO_REAL(p2); + pow1_2[j][i] = DOUBLE_TO_REAL(M_SQRT2 * p1); + pow2_2[j][i] = DOUBLE_TO_REAL(M_SQRT2 * p2); + } + } + + for(j=0;j<9;j++) { + struct bandInfoStruct *bi = &bandInfo[j]; + int *mp; + int cb,lwin; + int *bdf; + + mp = map[j][0] = mapbuf0[j]; + bdf = bi->longDiff; + for(i=0,cb = 0; cb < 8 ; cb++,i+=*bdf++) { + *mp++ = (*bdf) >> 1; + *mp++ = i; + *mp++ = 3; + *mp++ = cb; + } + bdf = bi->shortDiff+3; + for(cb=3;cb<13;cb++) { + int l = (*bdf++) >> 1; + for(lwin=0;lwin<3;lwin++) { + *mp++ = l; + *mp++ = i + lwin; + *mp++ = lwin; + *mp++ = cb; + } + i += 6*l; + } + mapend[j][0] = mp; + + mp = map[j][1] = mapbuf1[j]; + bdf = bi->shortDiff+0; + for(i=0,cb=0;cb<13;cb++) { + int l = (*bdf++) >> 1; + for(lwin=0;lwin<3;lwin++) { + *mp++ = l; + *mp++ = i + lwin; + *mp++ = lwin; + *mp++ = cb; + } + i += 6*l; + } + mapend[j][1] = mp; + + mp = map[j][2] = mapbuf2[j]; + bdf = bi->longDiff; + for(cb = 0; cb < 22 ; cb++) { + *mp++ = (*bdf++) >> 1; + *mp++ = cb; + } + mapend[j][2] = mp; + + } + + for(j=0;j<9;j++) { + for(i=0;i<23;i++) { + longLimit[j][i] = (bandInfo[j].longIdx[i] - 1 + 8) / 18 + 1; + if(longLimit[j][i] > (down_sample_sblimit) ) + longLimit[j][i] = down_sample_sblimit; + } + for(i=0;i<14;i++) { + shortLimit[j][i] = (bandInfo[j].shortIdx[i] - 1) / 18 + 1; + if(shortLimit[j][i] > (down_sample_sblimit) ) + shortLimit[j][i] = down_sample_sblimit; + } + } + + for(i=0;i<5;i++) { + for(j=0;j<6;j++) { + for(k=0;k<6;k++) { + int n = k + j * 6 + i * 36; + i_slen2[n] = i|(j<<3)|(k<<6)|(3<<12); + } + } + } + for(i=0;i<4;i++) { + for(j=0;j<4;j++) { + for(k=0;k<4;k++) { + int n = k + j * 4 + i * 16; + i_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12); + } + } + } + for(i=0;i<4;i++) { + for(j=0;j<3;j++) { + int n = j + i * 3; + i_slen2[n+244] = i|(j<<3) | (5<<12); + n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15); + } + } + + for(i=0;i<5;i++) { + for(j=0;j<5;j++) { + for(k=0;k<4;k++) { + for(l=0;l<4;l++) { + int n = l + k * 4 + j * 16 + i * 80; + n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12); + } + } + } + } + for(i=0;i<5;i++) { + for(j=0;j<5;j++) { + for(k=0;k<4;k++) { + int n = k + j * 4 + i * 20; + n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12); + } + } + } +} + +/* + * read additional side information (for MPEG 1 and MPEG 2) + */ +static int III_get_side_info(struct III_sideinfo *si,int stereo, + int ms_stereo,long sfreq,int single,int lsf) +{ + int ch, gr; + int powdiff = (single == 3) ? 4 : 0; + + static const int tabs[2][5] = { { 2,9,5,3,4 } , { 1,8,1,2,9 } }; + const int *tab = tabs[lsf]; + + si->main_data_begin = getbits(tab[1]); + if (stereo == 1) + si->private_bits = getbits_fast(tab[2]); + else + si->private_bits = getbits_fast(tab[3]); + + if(!lsf) { + for (ch=0; chch[ch].gr[0].scfsi = -1; + si->ch[ch].gr[1].scfsi = getbits_fast(4); + } + } + + for (gr=0; grch[ch].gr[gr]); + + gr_info->part2_3_length = getbits(12); + gr_info->big_values = getbits(9); + if(gr_info->big_values > 288) { + gr_info->big_values = 288; + } + gr_info->pow2gain = gainpow2+256 - getbits_fast(8) + powdiff; + if(ms_stereo) + gr_info->pow2gain += 2; + gr_info->scalefac_compress = getbits(tab[4]); + + if(get1bit()) { /* window switch flag */ + int i; + gr_info->block_type = getbits_fast(2); + gr_info->mixed_block_flag = get1bit(); + gr_info->table_select[0] = getbits_fast(5); + gr_info->table_select[1] = getbits_fast(5); + /* + * table_select[2] not needed, because there is no region2, + * but to satisfy some verifications tools we set it either. + */ + gr_info->table_select[2] = 0; + for(i=0;i<3;i++) + gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast(3)<<3); + + if(gr_info->block_type == 0) { + /* exit(1); */ + return 1; + } + + /* region_count/start parameters are implicit in this case. */ + if(!lsf || gr_info->block_type == 2) + gr_info->region1start = 36>>1; + else { +/* check this again for 2.5 and sfreq=8 */ + if(sfreq == 8) + gr_info->region1start = 108>>1; + else + gr_info->region1start = 54>>1; + } + gr_info->region2start = 576>>1; + } + else { + int i,r0c,r1c; + for (i=0; i<3; i++) + gr_info->table_select[i] = getbits_fast(5); + r0c = getbits_fast(4); + r1c = getbits_fast(3); + gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ; + gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1; + gr_info->block_type = 0; + gr_info->mixed_block_flag = 0; + } + if(!lsf) + gr_info->preflag = get1bit(); + gr_info->scalefac_scale = get1bit(); + gr_info->count1table_select = get1bit(); + } + } + return 0; +} + +/* + * read scalefactors + */ +static int III_get_scale_factors_1(int *scf,struct gr_info_s *gr_info,int ch,int gr) +{ + static const unsigned char slen[2][16] = { + {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4}, + {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3} + }; + int numbits; + int num0 = slen[0][gr_info->scalefac_compress]; + int num1 = slen[1][gr_info->scalefac_compress]; + + if (gr_info->block_type == 2) { + int i=18; + numbits = (num0 + num1) * 18; + + if (gr_info->mixed_block_flag) { + for (i=8;i;i--) + *scf++ = getbits_fast(num0); + i = 9; + numbits -= num0; /* num0 * 17 + num1 * 18 */ + } + + for (;i;i--) + *scf++ = getbits_fast(num0); + for (i = 18; i; i--) + *scf++ = getbits_fast(num1); + *scf++ = 0; *scf++ = 0; *scf++ = 0; /* short[13][0..2] = 0 */ + } + else { + int i; + int scfsi = gr_info->scfsi; + + if(scfsi < 0) { /* scfsi < 0 => granule == 0 */ + for(i=11;i;i--) + *scf++ = getbits_fast(num0); + for(i=10;i;i--) + *scf++ = getbits_fast(num1); + numbits = (num0 + num1) * 10 + num0; + *scf++ = 0; + } + else { + numbits = 0; + if(!(scfsi & 0x8)) { + for (i=0;i<6;i++) + *scf++ = getbits_fast(num0); + numbits += num0 * 6; + } + else { + scf += 6; + } + + if(!(scfsi & 0x4)) { + for (i=0;i<5;i++) + *scf++ = getbits_fast(num0); + numbits += num0 * 5; + } + else { + scf += 5; + } + + if(!(scfsi & 0x2)) { + for(i=0;i<5;i++) + *scf++ = getbits_fast(num1); + numbits += num1 * 5; + } + else { + scf += 5; + } + + if(!(scfsi & 0x1)) { + for (i=0;i<5;i++) + *scf++ = getbits_fast(num1); + numbits += num1 * 5; + } + else { + scf += 5; + } + *scf++ = 0; /* no l[21] in original sources */ + } + } + return numbits; +} + +static int III_get_scale_factors_2(int *scf,struct gr_info_s *gr_info,int i_stereo) +{ + unsigned char *pnt; + int i,j,n=0,numbits=0; + unsigned int slen; + + static unsigned char stab[3][6][4] = { + { { 6, 5, 5,5 } , { 6, 5, 7,3 } , { 11,10,0,0} , + { 7, 7, 7,0 } , { 6, 6, 6,3 } , { 8, 8,5,0} } , + { { 9, 9, 9,9 } , { 9, 9,12,6 } , { 18,18,0,0} , + {12,12,12,0 } , {12, 9, 9,6 } , { 15,12,9,0} } , + { { 6, 9, 9,9 } , { 6, 9,12,6 } , { 15,18,0,0} , + { 6,15,12,0 } , { 6,12, 9,6 } , { 6,18,9,0} } }; + + if(i_stereo) /* i_stereo AND second channel -> do_layer3() checks this */ + slen = i_slen2[gr_info->scalefac_compress>>1]; + else + slen = n_slen2[gr_info->scalefac_compress]; + + gr_info->preflag = (slen>>15) & 0x1; + + n = 0; + if( gr_info->block_type == 2 ) { + n++; + if(gr_info->mixed_block_flag) + n++; + } + + pnt = stab[n][(slen>>12)&0x7]; + + for(i=0;i<4;i++) { + int num = slen & 0x7; + slen >>= 3; + if(num) { + for(j=0;j<(int)(pnt[i]);j++) + *scf++ = getbits_fast(num); + numbits += pnt[i] * num; + } + else { + for(j=0;j<(int)(pnt[i]);j++) + *scf++ = 0; + } + } + + n = (n << 1) + 1; + for(i=0;iscalefac_scale; + real *xrpnt = (real *) xr; + int l[3],l3; + int part2remain = gr_info->part2_3_length - part2bits; + int *me; + + /* mhipp tree has this split up a bit... */ + int num=getbitoffset(); + long mask = (long) getbits(num)<<(BITSHIFT+8-num); + part2remain -= num; + + { + int bv = gr_info->big_values; + int region1 = gr_info->region1start; + int region2 = gr_info->region2start; +if(region1 > region2) +{ + return 1; +} + l3 = ((576>>1)-bv)>>1; +/* + * we may lose the 'odd' bit here !! + * check this later again + */ + if(bv <= region1) { + l[0] = bv; l[1] = 0; l[2] = 0; + } + else { + l[0] = region1; + if(bv <= region2) { + l[1] = bv - l[0]; l[2] = 0; + } + else { + l[1] = region2 - l[0]; l[2] = bv - region2; + } + } + } + + if(gr_info->block_type == 2) { + /* + * decoding with short or mixed mode BandIndex table + */ + int i,max[4]; + int step=0,lwin=3,cb=0; + register real v = 0.0; + register int *m,mc; + + if(gr_info->mixed_block_flag) { + max[3] = -1; + max[0] = max[1] = max[2] = 2; + m = map[sfreq][0]; + me = mapend[sfreq][0]; + } + else { + max[0] = max[1] = max[2] = max[3] = -1; + /* max[3] not really needed in this case */ + m = map[sfreq][1]; + me = mapend[sfreq][1]; + } + + mc = 0; + for(i=0;i<2;i++) { + int lp = l[i]; + struct newhuff *h = ht+gr_info->table_select[i]; + for(;lp;lp--,mc--) { + register int x,y; + if( (!mc) ) { + mc = *m++; + xrpnt = ((real *) xr) + (*m++); + lwin = *m++; + cb = *m++; + if(lwin == 3) { + v = gr_info->pow2gain[(*scf++) << shift]; + step = 1; + } + else { + v = gr_info->full_gain[lwin][(*scf++) << shift]; + step = 3; + } + } + { + register short *val = h->table; + REFRESH_MASK; + while((y=*val++)<0) { + if (mask < 0) + val -= y; + num--; + mask <<= 1; + } + x = y >> 4; + y &= 0xf; + } + if(x == 15 && h->linbits) { + max[lwin] = cb; + REFRESH_MASK; + x += ((unsigned long) mask) >> (BITSHIFT+8-h->linbits); + num -= h->linbits+1; + mask <<= h->linbits; + if(mask < 0) + *xrpnt = REAL_MUL(-ispow[x], v); + else + *xrpnt = REAL_MUL(ispow[x], v); + mask <<= 1; + } + else if(x) { + max[lwin] = cb; + if(mask < 0) + *xrpnt = REAL_MUL(-ispow[x], v); + else + *xrpnt = REAL_MUL(ispow[x], v); + num--; + mask <<= 1; + } + else + *xrpnt = DOUBLE_TO_REAL(0.0); + xrpnt += step; + if(y == 15 && h->linbits) { + max[lwin] = cb; + REFRESH_MASK; + y += ((unsigned long) mask) >> (BITSHIFT+8-h->linbits); + num -= h->linbits+1; + mask <<= h->linbits; + if(mask < 0) + *xrpnt = REAL_MUL(-ispow[y], v); + else + *xrpnt = REAL_MUL(ispow[y], v); + mask <<= 1; + } + else if(y) { + max[lwin] = cb; + if(mask < 0) + *xrpnt = REAL_MUL(-ispow[y], v); + else + *xrpnt = REAL_MUL(ispow[y], v); + num--; + mask <<= 1; + } + else + *xrpnt = DOUBLE_TO_REAL(0.0); + xrpnt += step; + } + } + + for(;l3 && (part2remain+num > 0);l3--) { + /* not mixing code and declarations to keep C89 happy */ + struct newhuff* h; + register short* val; + register short a; + /* This is only a humble hack to prevent a special segfault. */ + /* More insight into the real workings is still needed. */ + /* especially why there are (valid?) files that make xrpnt exceed the array with 4 bytes without segfaulting, more seems to be really bad, though. */ + #ifdef DEBUG + if(!(xrpnt < &xr[SBLIMIT][0])) + { + if(param.verbose) debug2("attempted soft xrpnt overflow (%p !< %p) ?", (void*) xrpnt, (void*) &xr[SBLIMIT][0]); + } + #endif + if(!(xrpnt < &xr[SBLIMIT][0]+5)) + { + return 2; + } + h = htc+gr_info->count1table_select; + val = h->table; + + REFRESH_MASK; + while((a=*val++)<0) { + if (mask < 0) + val -= a; + num--; + mask <<= 1; + } + if(part2remain+num <= 0) { + num -= part2remain+num; + break; + } + + for(i=0;i<4;i++) { + if(!(i & 1)) { + if(!mc) { + mc = *m++; + xrpnt = ((real *) xr) + (*m++); + lwin = *m++; + cb = *m++; + if(lwin == 3) { + v = gr_info->pow2gain[(*scf++) << shift]; + step = 1; + } + else { + v = gr_info->full_gain[lwin][(*scf++) << shift]; + step = 3; + } + } + mc--; + } + if( (a & (0x8>>i)) ) { + max[lwin] = cb; + if(part2remain+num <= 0) { + break; + } + if(mask < 0) + *xrpnt = -v; + else + *xrpnt = v; + num--; + mask <<= 1; + } + else + *xrpnt = DOUBLE_TO_REAL(0.0); + xrpnt += step; + } + } + + if(lwin < 3) { /* short band? */ + while(1) { + for(;mc > 0;mc--) { + *xrpnt = DOUBLE_TO_REAL(0.0); xrpnt += 3; /* short band -> step=3 */ + *xrpnt = DOUBLE_TO_REAL(0.0); xrpnt += 3; + } + if(m >= me) + break; + mc = *m++; + xrpnt = ((real *) xr) + *m++; + if(*m++ == 0) + break; /* optimize: field will be set to zero at the end of the function */ + m++; /* cb */ + } + } + + gr_info->maxband[0] = max[0]+1; + gr_info->maxband[1] = max[1]+1; + gr_info->maxband[2] = max[2]+1; + gr_info->maxbandl = max[3]+1; + + { + int rmax = max[0] > max[1] ? max[0] : max[1]; + rmax = (rmax > max[2] ? rmax : max[2]) + 1; + gr_info->maxb = rmax ? shortLimit[sfreq][rmax] : longLimit[sfreq][max[3]+1]; + } + + } + else { + /* + * decoding with 'long' BandIndex table (block_type != 2) + */ + int *pretab = gr_info->preflag ? pretab1 : pretab2; + int i,max = -1; + int cb = 0; + int *m = map[sfreq][2]; + register real v = 0.0; + int mc = 0; + + /* + * long hash table values + */ + for(i=0;i<3;i++) { + int lp = l[i]; + struct newhuff *h = ht+gr_info->table_select[i]; + + for(;lp;lp--,mc--) { + int x,y; + if(!mc) { + mc = *m++; + cb = *m++; + if(cb == 21) + v = 0.0; + else + v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift]; + + } + { + register short *val = h->table; + REFRESH_MASK; + while((y=*val++)<0) { + if (mask < 0) + val -= y; + num--; + mask <<= 1; + } + x = y >> 4; + y &= 0xf; + } + + if (x == 15 && h->linbits) { + max = cb; + REFRESH_MASK; + x += ((unsigned long) mask) >> (BITSHIFT+8-h->linbits); + num -= h->linbits+1; + mask <<= h->linbits; + if(mask < 0) + *xrpnt++ = REAL_MUL(-ispow[x], v); + else + *xrpnt++ = REAL_MUL(ispow[x], v); + mask <<= 1; + } + else if(x) { + max = cb; + if(mask < 0) + *xrpnt++ = REAL_MUL(-ispow[x], v); + else + *xrpnt++ = REAL_MUL(ispow[x], v); + num--; + mask <<= 1; + } + else + *xrpnt++ = DOUBLE_TO_REAL(0.0); + + if (y == 15 && h->linbits) { + max = cb; + REFRESH_MASK; + y += ((unsigned long) mask) >> (BITSHIFT+8-h->linbits); + num -= h->linbits+1; + mask <<= h->linbits; + if(mask < 0) + *xrpnt++ = REAL_MUL(-ispow[y], v); + else + *xrpnt++ = REAL_MUL(ispow[y], v); + mask <<= 1; + } + else if(y) { + max = cb; + if(mask < 0) + *xrpnt++ = REAL_MUL(-ispow[y], v); + else + *xrpnt++ = REAL_MUL(ispow[y], v); + num--; + mask <<= 1; + } + else + *xrpnt++ = DOUBLE_TO_REAL(0.0); + } + } + + /* + * short (count1table) values + */ + for(;l3 && (part2remain+num > 0);l3--) { + struct newhuff *h = htc+gr_info->count1table_select; + register short *val = h->table,a; + + REFRESH_MASK; + while((a=*val++)<0) { + if (mask < 0) + val -= a; + num--; + mask <<= 1; + } + if(part2remain+num <= 0) { + num -= part2remain+num; + break; + } + + for(i=0;i<4;i++) { + if(!(i & 1)) { + if(!mc) { + mc = *m++; + cb = *m++; + if(cb == 21) + v = 0.0; + else + v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift]; + } + mc--; + } + if ( (a & (0x8>>i)) ) { + max = cb; + if(part2remain+num <= 0) { + break; + } + if(mask < 0) + *xrpnt++ = -v; + else + *xrpnt++ = v; + num--; + mask <<= 1; + } + else + *xrpnt++ = DOUBLE_TO_REAL(0.0); + } + } + + gr_info->maxbandl = max+1; + gr_info->maxb = longLimit[sfreq][gr_info->maxbandl]; + } + + part2remain += num; + backbits(num); + num = 0; + + while(xrpnt < &xr[SBLIMIT][0]) + *xrpnt++ = DOUBLE_TO_REAL(0.0); + + while( part2remain > 16 ) { + getbits(16); /* Dismiss stuffing Bits */ + part2remain -= 16; + } + if(part2remain > 0) + getbits(part2remain); + else if(part2remain < 0) { + return 1; /* -> error */ + } + return 0; +} + +/* + * III_stereo: calculate real channel values for Joint-I-Stereo-mode + */ +static void III_i_stereo(real xr_buf[2][SBLIMIT][SSLIMIT],int *scalefac, + struct gr_info_s *gr_info,int sfreq,int ms_stereo,int lsf) +{ + real (*xr)[SBLIMIT*SSLIMIT] = (real (*)[SBLIMIT*SSLIMIT] ) xr_buf; + struct bandInfoStruct *bi = &bandInfo[sfreq]; + + const real *tab1,*tab2; + +#if 1 + int tab; +/* TODO: optimize as static */ + static const real *tabs[3][2][2] = { + { { tan1_1,tan2_1 } , { tan1_2,tan2_2 } }, + { { pow1_1[0],pow2_1[0] } , { pow1_2[0],pow2_2[0] } } , + { { pow1_1[1],pow2_1[1] } , { pow1_2[1],pow2_2[1] } } + }; + + tab = lsf + (gr_info->scalefac_compress & lsf); + tab1 = tabs[tab][ms_stereo][0]; + tab2 = tabs[tab][ms_stereo][1]; +#else + if(lsf) { + int p = gr_info->scalefac_compress & 0x1; + if(ms_stereo) { + tab1 = pow1_2[p]; tab2 = pow2_2[p]; + } + else { + tab1 = pow1_1[p]; tab2 = pow2_1[p]; + } + } + else { + if(ms_stereo) { + tab1 = tan1_2; tab2 = tan2_2; + } + else { + tab1 = tan1_1; tab2 = tan2_1; + } + } +#endif + + if (gr_info->block_type == 2) { + int lwin,do_l = 0; + if( gr_info->mixed_block_flag ) + do_l = 1; + + for (lwin=0;lwin<3;lwin++) { /* process each window */ + /* get first band with zero values */ + int is_p,sb,idx,sfb = gr_info->maxband[lwin]; /* sfb is minimal 3 for mixed mode */ + if(sfb > 3) + do_l = 0; + + for(;sfb<12;sfb++) { + is_p = scalefac[sfb*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */ + if(is_p != 7) { + real t1,t2; + sb = bi->shortDiff[sfb]; + idx = bi->shortIdx[sfb] + lwin; + t1 = tab1[is_p]; t2 = tab2[is_p]; + for (; sb > 0; sb--,idx+=3) { + real v = xr[0][idx]; + xr[0][idx] = REAL_MUL(v, t1); + xr[1][idx] = REAL_MUL(v, t2); + } + } + } + +#if 1 +/* in the original: copy 10 to 11 , here: copy 11 to 12 +maybe still wrong??? (copy 12 to 13?) */ + is_p = scalefac[11*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */ + sb = bi->shortDiff[12]; + idx = bi->shortIdx[12] + lwin; +#else + is_p = scalefac[10*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */ + sb = bi->shortDiff[11]; + idx = bi->shortIdx[11] + lwin; +#endif + if(is_p != 7) { + real t1,t2; + t1 = tab1[is_p]; t2 = tab2[is_p]; + for ( ; sb > 0; sb--,idx+=3 ) { + real v = xr[0][idx]; + xr[0][idx] = REAL_MUL(v, t1); + xr[1][idx] = REAL_MUL(v, t2); + } + } + } /* end for(lwin; .. ; . ) */ + +/* also check l-part, if ALL bands in the three windows are 'empty' + * and mode = mixed_mode + */ + if (do_l) { + int sfb = gr_info->maxbandl; + int idx; + if(sfb > 21) return; /* similarity fix related to CVE-2006-1655 */ + idx = bi->longIdx[sfb]; + for ( ; sfb<8; sfb++ ) { + int sb = bi->longDiff[sfb]; + int is_p = scalefac[sfb]; /* scale: 0-15 */ + if(is_p != 7) { + real t1,t2; + t1 = tab1[is_p]; t2 = tab2[is_p]; + for ( ; sb > 0; sb--,idx++) { + real v = xr[0][idx]; + xr[0][idx] = REAL_MUL(v, t1); + xr[1][idx] = REAL_MUL(v, t2); + } + } + else + idx += sb; + } + } + } + else { /* ((gr_info->block_type != 2)) */ + int sfb = gr_info->maxbandl; + int is_p,idx; + if(sfb > 21) return; /* tightened fix for CVE-2006-1655 */ + idx = bi->longIdx[sfb]; + for ( ; sfb<21; sfb++) { + int sb = bi->longDiff[sfb]; + is_p = scalefac[sfb]; /* scale: 0-15 */ + if(is_p != 7) { + real t1,t2; + t1 = tab1[is_p]; t2 = tab2[is_p]; + for ( ; sb > 0; sb--,idx++) { + real v = xr[0][idx]; + xr[0][idx] = REAL_MUL(v, t1); + xr[1][idx] = REAL_MUL(v, t2); + } + } + else + idx += sb; + } + + is_p = scalefac[20]; + if(is_p != 7) { /* copy l-band 20 to l-band 21 */ + int sb; + real t1 = tab1[is_p],t2 = tab2[is_p]; + + for ( sb = bi->longDiff[21]; sb > 0; sb--,idx++ ) { + real v = xr[0][idx]; + xr[0][idx] = REAL_MUL(v, t1); + xr[1][idx] = REAL_MUL(v, t2); + } + } + } /* ... */ +} + +static void III_antialias(real xr[SBLIMIT][SSLIMIT],struct gr_info_s *gr_info) { + int sblim; + + if(gr_info->block_type == 2) { + if(!gr_info->mixed_block_flag) + return; + sblim = 1; + } + else { + sblim = gr_info->maxb-1; + } + + /* 31 alias-reduction operations between each pair of sub-bands */ + /* with 8 butterflies between each pair */ + + { + int sb; + real *xr1=(real *) xr[1]; + + for(sb=sblim;sb;sb--,xr1+=10) { + int ss; + real *cs=aa_cs,*ca=aa_ca; + real *xr2 = xr1; + + for(ss=7;ss>=0;ss--) + { /* upper and lower butterfly inputs */ + register real bu = *--xr2,bd = *xr1; + *xr2 = REAL_MUL(bu, *cs) - REAL_MUL(bd, *ca); + *xr1++ = REAL_MUL(bd, *cs++) + REAL_MUL(bu, *ca++); + } + } + } +} + +/* +// This is an optimized DCT from Jeff Tsay's maplay 1.2+ package. +// Saved one multiplication by doing the 'twiddle factor' stuff +// together with the window mul. (MH) +// +// This uses Byeong Gi Lee's Fast Cosine Transform algorithm, but the +// 9 point IDCT needs to be reduced further. Unfortunately, I don't +// know how to do that, because 9 is not an even number. - Jeff. +// +////////////////////////////////////////////////////////////////// +// +// 9 Point Inverse Discrete Cosine Transform +// +// This piece of code is Copyright 1997 Mikko Tommila and is freely usable +// by anybody. The algorithm itself is of course in the public domain. +// +// Again derived heuristically from the 9-point WFTA. +// +// The algorithm is optimized (?) for speed, not for small rounding errors or +// good readability. +// +// 36 additions, 11 multiplications +// +// Again this is very likely sub-optimal. +// +// The code is optimized to use a minimum number of temporary variables, +// so it should compile quite well even on 8-register Intel x86 processors. +// This makes the code quite obfuscated and very difficult to understand. +// +// References: +// [1] S. Winograd: "On Computing the Discrete Fourier Transform", +// Mathematics of Computation, Volume 32, Number 141, January 1978, +// Pages 175-199 +*/ + +/*------------------------------------------------------------------*/ +/* */ +/* Function: Calculation of the inverse MDCT */ +/* */ +/*------------------------------------------------------------------*/ +#ifdef USE_3DNOW +void dct36(real *inbuf,real *o1,real *o2,real *wintab,real *tsbuf) +#else +static void dct36(real *inbuf,real *o1,real *o2,real *wintab,real *tsbuf) +#endif +{ +#ifdef NEW_DCT9 + real tmp[18]; +#endif + + { + register real *in = inbuf; + + in[17]+=in[16]; in[16]+=in[15]; in[15]+=in[14]; + in[14]+=in[13]; in[13]+=in[12]; in[12]+=in[11]; + in[11]+=in[10]; in[10]+=in[9]; in[9] +=in[8]; + in[8] +=in[7]; in[7] +=in[6]; in[6] +=in[5]; + in[5] +=in[4]; in[4] +=in[3]; in[3] +=in[2]; + in[2] +=in[1]; in[1] +=in[0]; + + in[17]+=in[15]; in[15]+=in[13]; in[13]+=in[11]; in[11]+=in[9]; + in[9] +=in[7]; in[7] +=in[5]; in[5] +=in[3]; in[3] +=in[1]; + + +#ifdef NEW_DCT9 +#if 1 + { + real t3; + { + real t0, t1, t2; + + t0 = REAL_MUL(COS6_2, (in[8] + in[16] - in[4])); + t1 = REAL_MUL(COS6_2, in[12]); + + t3 = in[0]; + t2 = t3 - t1 - t1; + tmp[1] = tmp[7] = t2 - t0; + tmp[4] = t2 + t0 + t0; + t3 += t1; + + t2 = REAL_MUL(COS6_1, (in[10] + in[14] - in[2])); + tmp[1] -= t2; + tmp[7] += t2; + } + { + real t0, t1, t2; + + t0 = REAL_MUL(cos9[0], (in[4] + in[8] )); + t1 = REAL_MUL(cos9[1], (in[8] - in[16])); + t2 = REAL_MUL(cos9[2], (in[4] + in[16])); + + tmp[2] = tmp[6] = t3 - t0 - t2; + tmp[0] = tmp[8] = t3 + t0 + t1; + tmp[3] = tmp[5] = t3 - t1 + t2; + } + } + { + real t1, t2, t3; + + t1 = REAL_MUL(cos18[0], (in[2] + in[10])); + t2 = REAL_MUL(cos18[1], (in[10] - in[14])); + t3 = REAL_MUL(COS6_1, in[6]); + + { + real t0 = t1 + t2 + t3; + tmp[0] += t0; + tmp[8] -= t0; + } + + t2 -= t3; + t1 -= t3; + + t3 = REAL_MUL(cos18[2], (in[2] + in[14])); + + t1 += t3; + tmp[3] += t1; + tmp[5] -= t1; + + t2 -= t3; + tmp[2] += t2; + tmp[6] -= t2; + } + +#else + { + real t0, t1, t2, t3, t4, t5, t6, t7; + + t1 = REAL_MUL(COS6_2, in[12]); + t2 = REAL_MUL(COS6_2, (in[8] + in[16] - in[4])); + + t3 = in[0] + t1; + t4 = in[0] - t1 - t1; + t5 = t4 - t2; + tmp[4] = t4 + t2 + t2; + + t0 = REAL_MUL(cos9[0], (in[4] + in[8])); + t1 = REAL_MUL(cos9[1], (in[8] - in[16])); + + t2 = REAL_MUL(cos9[2], (in[4] + in[16])); + + t6 = t3 - t0 - t2; + t0 += t3 + t1; + t3 += t2 - t1; + + t2 = REAL_MUL(cos18[0], (in[2] + in[10])); + t4 = REAL_MUL(cos18[1], (in[10] - in[14])); + t7 = REAL_MUL(COS6_1, in[6]); + + t1 = t2 + t4 + t7; + tmp[0] = t0 + t1; + tmp[8] = t0 - t1; + t1 = REAL_MUL(cos18[2], (in[2] + in[14])); + t2 += t1 - t7; + + tmp[3] = t3 + t2; + t0 = REAL_MUL(COS6_1, (in[10] + in[14] - in[2])); + tmp[5] = t3 - t2; + + t4 -= t1 + t7; + + tmp[1] = t5 - t0; + tmp[7] = t5 + t0; + tmp[2] = t6 + t4; + tmp[6] = t6 - t4; + } +#endif + + { + real t0, t1, t2, t3, t4, t5, t6, t7; + + t1 = REAL_MUL(COS6_2, in[13]); + t2 = REAL_MUL(COS6_2, (in[9] + in[17] - in[5])); + + t3 = in[1] + t1; + t4 = in[1] - t1 - t1; + t5 = t4 - t2; + + t0 = REAL_MUL(cos9[0], (in[5] + in[9])); + t1 = REAL_MUL(cos9[1], (in[9] - in[17])); + + tmp[13] = REAL_MUL((t4 + t2 + t2), tfcos36[17-13]); + t2 = REAL_MUL(cos9[2], (in[5] + in[17])); + + t6 = t3 - t0 - t2; + t0 += t3 + t1; + t3 += t2 - t1; + + t2 = REAL_MUL(cos18[0], (in[3] + in[11])); + t4 = REAL_MUL(cos18[1], (in[11] - in[15])); + t7 = REAL_MUL(COS6_1, in[7]); + + t1 = t2 + t4 + t7; + tmp[17] = REAL_MUL((t0 + t1), tfcos36[17-17]); + tmp[9] = REAL_MUL((t0 - t1), tfcos36[17-9]); + t1 = REAL_MUL(cos18[2], (in[3] + in[15])); + t2 += t1 - t7; + + tmp[14] = REAL_MUL((t3 + t2), tfcos36[17-14]); + t0 = REAL_MUL(COS6_1, (in[11] + in[15] - in[3])); + tmp[12] = REAL_MUL((t3 - t2), tfcos36[17-12]); + + t4 -= t1 + t7; + + tmp[16] = REAL_MUL((t5 - t0), tfcos36[17-16]); + tmp[10] = REAL_MUL((t5 + t0), tfcos36[17-10]); + tmp[15] = REAL_MUL((t6 + t4), tfcos36[17-15]); + tmp[11] = REAL_MUL((t6 - t4), tfcos36[17-11]); + } + +#define MACRO(v) { \ + real tmpval; \ + tmpval = tmp[(v)] + tmp[17-(v)]; \ + out2[9+(v)] = REAL_MUL(tmpval, w[27+(v)]); \ + out2[8-(v)] = REAL_MUL(tmpval, w[26-(v)]); \ + tmpval = tmp[(v)] - tmp[17-(v)]; \ + ts[SBLIMIT*(8-(v))] = out1[8-(v)] + REAL_MUL(tmpval, w[8-(v)]); \ + ts[SBLIMIT*(9+(v))] = out1[9+(v)] + REAL_MUL(tmpval, w[9+(v)]); } + +{ + register real *out2 = o2; + register real *w = wintab; + register real *out1 = o1; + register real *ts = tsbuf; + + MACRO(0); + MACRO(1); + MACRO(2); + MACRO(3); + MACRO(4); + MACRO(5); + MACRO(6); + MACRO(7); + MACRO(8); +} + +#else + + { + +#define MACRO0(v) { \ + real tmp; \ + out2[9+(v)] = REAL_MUL((tmp = sum0 + sum1), w[27+(v)]); \ + out2[8-(v)] = REAL_MUL(tmp, w[26-(v)]); } \ + sum0 -= sum1; \ + ts[SBLIMIT*(8-(v))] = out1[8-(v)] + REAL_MUL(sum0, w[8-(v)]); \ + ts[SBLIMIT*(9+(v))] = out1[9+(v)] + REAL_MUL(sum0, w[9+(v)]); +#define MACRO1(v) { \ + real sum0,sum1; \ + sum0 = tmp1a + tmp2a; \ + sum1 = REAL_MUL((tmp1b + tmp2b), tfcos36[(v)]); \ + MACRO0(v); } +#define MACRO2(v) { \ + real sum0,sum1; \ + sum0 = tmp2a - tmp1a; \ + sum1 = REAL_MUL((tmp2b - tmp1b), tfcos36[(v)]); \ + MACRO0(v); } + + register const real *c = COS9; + register real *out2 = o2; + register real *w = wintab; + register real *out1 = o1; + register real *ts = tsbuf; + + real ta33,ta66,tb33,tb66; + + ta33 = REAL_MUL(in[2*3+0], c[3]); + ta66 = REAL_MUL(in[2*6+0], c[6]); + tb33 = REAL_MUL(in[2*3+1], c[3]); + tb66 = REAL_MUL(in[2*6+1], c[6]); + + { + real tmp1a,tmp2a,tmp1b,tmp2b; + tmp1a = REAL_MUL(in[2*1+0], c[1]) + ta33 + REAL_MUL(in[2*5+0], c[5]) + REAL_MUL(in[2*7+0], c[7]); + tmp1b = REAL_MUL(in[2*1+1], c[1]) + tb33 + REAL_MUL(in[2*5+1], c[5]) + REAL_MUL(in[2*7+1], c[7]); + tmp2a = REAL_MUL(in[2*2+0], c[2]) + REAL_MUL(in[2*4+0], c[4]) + ta66 + REAL_MUL(in[2*8+0], c[8]); + tmp2b = REAL_MUL(in[2*2+1], c[2]) + REAL_MUL(in[2*4+1], c[4]) + tb66 + REAL_MUL(in[2*8+1], c[8]); + + MACRO1(0); + MACRO2(8); + } + + { + real tmp1a,tmp2a,tmp1b,tmp2b; + tmp1a = REAL_MUL(( in[2*1+0] - in[2*5+0] - in[2*7+0] ), c[3]); + tmp1b = REAL_MUL(( in[2*1+1] - in[2*5+1] - in[2*7+1] ), c[3]); + tmp2a = REAL_MUL(( in[2*2+0] - in[2*4+0] - in[2*8+0] ), c[6]) - in[2*6+0] + in[2*0+0]; + tmp2b = REAL_MUL(( in[2*2+1] - in[2*4+1] - in[2*8+1] ), c[6]) - in[2*6+1] + in[2*0+1]; + + MACRO1(1); + MACRO2(7); + } + + { + real tmp1a,tmp2a,tmp1b,tmp2b; + tmp1a = REAL_MUL(in[2*1+0], c[5]) - ta33 - REAL_MUL(in[2*5+0], c[7]) + REAL_MUL(in[2*7+0], c[1]); + tmp1b = REAL_MUL(in[2*1+1], c[5]) - tb33 - REAL_MUL(in[2*5+1], c[7]) + REAL_MUL(in[2*7+1], c[1]); + tmp2a = - REAL_MUL(in[2*2+0], c[8]) - REAL_MUL(in[2*4+0], c[2]) + ta66 + REAL_MUL(in[2*8+0], c[4]); + tmp2b = - REAL_MUL(in[2*2+1], c[8]) - REAL_MUL(in[2*4+1], c[2]) + tb66 + REAL_MUL(in[2*8+1], c[4]); + + MACRO1(2); + MACRO2(6); + } + + { + real tmp1a,tmp2a,tmp1b,tmp2b; + tmp1a = REAL_MUL(in[2*1+0], c[7]) - ta33 + REAL_MUL(in[2*5+0], c[1]) - REAL_MUL(in[2*7+0], c[5]); + tmp1b = REAL_MUL(in[2*1+1], c[7]) - tb33 + REAL_MUL(in[2*5+1], c[1]) - REAL_MUL(in[2*7+1], c[5]); + tmp2a = - REAL_MUL(in[2*2+0], c[4]) + REAL_MUL(in[2*4+0], c[8]) + ta66 - REAL_MUL(in[2*8+0], c[2]); + tmp2b = - REAL_MUL(in[2*2+1], c[4]) + REAL_MUL(in[2*4+1], c[8]) + tb66 - REAL_MUL(in[2*8+1], c[2]); + + MACRO1(3); + MACRO2(5); + } + + { + real sum0,sum1; + sum0 = in[2*0+0] - in[2*2+0] + in[2*4+0] - in[2*6+0] + in[2*8+0]; + sum1 = REAL_MUL((in[2*0+1] - in[2*2+1] + in[2*4+1] - in[2*6+1] + in[2*8+1] ), tfcos36[4]); + MACRO0(4); + } + } +#endif + + } +} + +/* + * new DCT12 + */ +static void dct12(real *in,real *rawout1,real *rawout2,register real *wi,register real *ts) +{ +#define DCT12_PART1 \ + in5 = in[5*3]; \ + in5 += (in4 = in[4*3]); \ + in4 += (in3 = in[3*3]); \ + in3 += (in2 = in[2*3]); \ + in2 += (in1 = in[1*3]); \ + in1 += (in0 = in[0*3]); \ + \ + in5 += in3; in3 += in1; \ + \ + in2 = REAL_MUL(in2, COS6_1); \ + in3 = REAL_MUL(in3, COS6_1); \ + +#define DCT12_PART2 \ + in0 += REAL_MUL(in4, COS6_2); \ + \ + in4 = in0 + in2; \ + in0 -= in2; \ + \ + in1 += REAL_MUL(in5, COS6_2); \ + \ + in5 = REAL_MUL((in1 + in3), tfcos12[0]); \ + in1 = REAL_MUL((in1 - in3), tfcos12[2]); \ + \ + in3 = in4 + in5; \ + in4 -= in5; \ + \ + in2 = in0 + in1; \ + in0 -= in1; + + + { + real in0,in1,in2,in3,in4,in5; + register real *out1 = rawout1; + ts[SBLIMIT*0] = out1[0]; ts[SBLIMIT*1] = out1[1]; ts[SBLIMIT*2] = out1[2]; + ts[SBLIMIT*3] = out1[3]; ts[SBLIMIT*4] = out1[4]; ts[SBLIMIT*5] = out1[5]; + + DCT12_PART1 + + { + real tmp0,tmp1 = (in0 - in4); + { + real tmp2 = REAL_MUL((in1 - in5), tfcos12[1]); + tmp0 = tmp1 + tmp2; + tmp1 -= tmp2; + } + ts[(17-1)*SBLIMIT] = out1[17-1] + REAL_MUL(tmp0, wi[11-1]); + ts[(12+1)*SBLIMIT] = out1[12+1] + REAL_MUL(tmp0, wi[6+1]); + ts[(6 +1)*SBLIMIT] = out1[6 +1] + REAL_MUL(tmp1, wi[1]); + ts[(11-1)*SBLIMIT] = out1[11-1] + REAL_MUL(tmp1, wi[5-1]); + } + + DCT12_PART2 + + ts[(17-0)*SBLIMIT] = out1[17-0] + REAL_MUL(in2, wi[11-0]); + ts[(12+0)*SBLIMIT] = out1[12+0] + REAL_MUL(in2, wi[6+0]); + ts[(12+2)*SBLIMIT] = out1[12+2] + REAL_MUL(in3, wi[6+2]); + ts[(17-2)*SBLIMIT] = out1[17-2] + REAL_MUL(in3, wi[11-2]); + + ts[(6 +0)*SBLIMIT] = out1[6+0] + REAL_MUL(in0, wi[0]); + ts[(11-0)*SBLIMIT] = out1[11-0] + REAL_MUL(in0, wi[5-0]); + ts[(6 +2)*SBLIMIT] = out1[6+2] + REAL_MUL(in4, wi[2]); + ts[(11-2)*SBLIMIT] = out1[11-2] + REAL_MUL(in4, wi[5-2]); + } + + in++; + + { + real in0,in1,in2,in3,in4,in5; + register real *out2 = rawout2; + + DCT12_PART1 + + { + real tmp0,tmp1 = (in0 - in4); + { + real tmp2 = REAL_MUL((in1 - in5), tfcos12[1]); + tmp0 = tmp1 + tmp2; + tmp1 -= tmp2; + } + out2[5-1] = REAL_MUL(tmp0, wi[11-1]); + out2[0+1] = REAL_MUL(tmp0, wi[6+1]); + ts[(12+1)*SBLIMIT] += REAL_MUL(tmp1, wi[1]); + ts[(17-1)*SBLIMIT] += REAL_MUL(tmp1, wi[5-1]); + } + + DCT12_PART2 + + out2[5-0] = REAL_MUL(in2, wi[11-0]); + out2[0+0] = REAL_MUL(in2, wi[6+0]); + out2[0+2] = REAL_MUL(in3, wi[6+2]); + out2[5-2] = REAL_MUL(in3, wi[11-2]); + + ts[(12+0)*SBLIMIT] += REAL_MUL(in0, wi[0]); + ts[(17-0)*SBLIMIT] += REAL_MUL(in0, wi[5-0]); + ts[(12+2)*SBLIMIT] += REAL_MUL(in4, wi[2]); + ts[(17-2)*SBLIMIT] += REAL_MUL(in4, wi[5-2]); + } + + in++; + + { + real in0,in1,in2,in3,in4,in5; + register real *out2 = rawout2; + out2[12]=out2[13]=out2[14]=out2[15]=out2[16]=out2[17]=0.0; + + DCT12_PART1 + + { + real tmp0,tmp1 = (in0 - in4); + { + real tmp2 = REAL_MUL((in1 - in5), tfcos12[1]); + tmp0 = tmp1 + tmp2; + tmp1 -= tmp2; + } + out2[11-1] = REAL_MUL(tmp0, wi[11-1]); + out2[6 +1] = REAL_MUL(tmp0, wi[6+1]); + out2[0+1] += REAL_MUL(tmp1, wi[1]); + out2[5-1] += REAL_MUL(tmp1, wi[5-1]); + } + + DCT12_PART2 + + out2[11-0] = REAL_MUL(in2, wi[11-0]); + out2[6 +0] = REAL_MUL(in2, wi[6+0]); + out2[6 +2] = REAL_MUL(in3, wi[6+2]); + out2[11-2] = REAL_MUL(in3, wi[11-2]); + + out2[0+0] += REAL_MUL(in0, wi[0]); + out2[5-0] += REAL_MUL(in0, wi[5-0]); + out2[0+2] += REAL_MUL(in4, wi[2]); + out2[5-2] += REAL_MUL(in4, wi[5-2]); + } +} + +/* + * III_hybrid + */ +#ifdef USE_3DNOW +static void III_hybrid(real fsIn[SBLIMIT][SSLIMIT],real tsOut[SSLIMIT][SBLIMIT],int ch,struct gr_info_s *gr_info,struct frame *fr) +#else +static void III_hybrid(real fsIn[SBLIMIT][SSLIMIT],real tsOut[SSLIMIT][SBLIMIT], + int ch,struct gr_info_s *gr_info) +#endif +{ + static real block[2][2][SBLIMIT*SSLIMIT] = { { { 0, } } }; + static int blc[2]={0,0}; + + real *tspnt = (real *) tsOut; + real *rawout1,*rawout2; + int bt,sb = 0; + + { + int b = blc[ch]; + rawout1=block[b][ch]; + b=-b+1; + rawout2=block[b][ch]; + blc[ch] = b; + } + + if(gr_info->mixed_block_flag) { + sb = 2; +#ifdef USE_3DNOW + (fr->dct36)(fsIn[0],rawout1,rawout2,win[0],tspnt); + (fr->dct36)(fsIn[1],rawout1+18,rawout2+18,win1[0],tspnt+1); +#else + dct36(fsIn[0],rawout1,rawout2,win[0],tspnt); + dct36(fsIn[1],rawout1+18,rawout2+18,win1[0],tspnt+1); +#endif + rawout1 += 36; rawout2 += 36; tspnt += 2; + } + + bt = gr_info->block_type; + if(bt == 2) { + for (; sbmaxb; sb+=2,tspnt+=2,rawout1+=36,rawout2+=36) { + dct12(fsIn[sb] ,rawout1 ,rawout2 ,win[2] ,tspnt); + dct12(fsIn[sb+1],rawout1+18,rawout2+18,win1[2],tspnt+1); + } + } + else { + for (; sbmaxb; sb+=2,tspnt+=2,rawout1+=36,rawout2+=36) { +#ifdef USE_3DNOW + (fr->dct36)(fsIn[sb],rawout1,rawout2,win[bt],tspnt); + (fr->dct36)(fsIn[sb+1],rawout1+18,rawout2+18,win1[bt],tspnt+1); +#else + dct36(fsIn[sb],rawout1,rawout2,win[bt],tspnt); + dct36(fsIn[sb+1],rawout1+18,rawout2+18,win1[bt],tspnt+1); +#endif + } + } + + for(;sbstereo; + int single = fr->single; + int ms_stereo,i_stereo; + int sfreq = fr->sampling_frequency; + int stereo1,granules; + + if(stereo == 1) { /* stream is mono */ + stereo1 = 1; + single = 0; + } + else if(single >= 0) /* stream is stereo, but force to mono */ + stereo1 = 1; + else + stereo1 = 2; + + if(fr->mode == MPG_MD_JOINT_STEREO) { + ms_stereo = (fr->mode_ext & 0x2)>>1; + i_stereo = fr->mode_ext & 0x1; + } + else + ms_stereo = i_stereo = 0; + + if(fr->lsf) { + granules = 1; +#if 0 + III_get_side_info_2(&sideinfo,stereo,ms_stereo,sfreq,single); +#endif + } + else { + granules = 2; + } + /* quick hack to keep the music playing */ + /* after having seen this nasty test file... */ + if(III_get_side_info(&sideinfo,stereo,ms_stereo,sfreq,single,fr->lsf)) + { + return clip; + } + + set_pointer(sideinfo.main_data_begin); + + for (gr=0;grlsf) + part2bits = III_get_scale_factors_2(scalefacs[0],gr_info,0); + else + part2bits = III_get_scale_factors_1(scalefacs[0],gr_info,0,gr); + + if(III_dequantize_sample(hybridIn[0], scalefacs[0],gr_info,sfreq,part2bits)) + return clip; + } + + if(stereo == 2) { + struct gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]); + long part2bits; + if(fr->lsf) + part2bits = III_get_scale_factors_2(scalefacs[1],gr_info,i_stereo); + else + part2bits = III_get_scale_factors_1(scalefacs[1],gr_info,1,gr); + + if(III_dequantize_sample(hybridIn[1],scalefacs[1],gr_info,sfreq,part2bits)) + return clip; + + if(ms_stereo) { + int i; + int maxb = sideinfo.ch[0].gr[gr].maxb; + if(sideinfo.ch[1].gr[gr].maxb > maxb) + maxb = sideinfo.ch[1].gr[gr].maxb; + for(i=0;ilsf); + + if(ms_stereo || i_stereo || (single == 3) ) { + if(gr_info->maxb > sideinfo.ch[0].gr[gr].maxb) + sideinfo.ch[0].gr[gr].maxb = gr_info->maxb; + else + gr_info->maxb = sideinfo.ch[0].gr[gr].maxb; + } + + switch(single) { + case 3: + { + register int i; + register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1]; + for(i=0;imaxb;i++,in0++) + *in0 = (*in0 + *in1++); /* *0.5 done by pow-scale */ + } + break; + case 1: + { + register int i; + register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1]; + for(i=0;imaxb;i++) + *in0++ = *in1++; + } + break; + } + } + + for(ch=0;chsynth != synth_1to1 || single >= 0) { +#endif + for(ss=0;ss= 0) { + clip += (fr->synth_mono)(hybridOut[0][ss],pcm_sample,pcm_point); + } + else { + int p1=*pcm_point; + clip += (fr->synth)(hybridOut[0][ss],0,pcm_sample,&p1); + clip += (fr->synth)(hybridOut[1][ss],1,pcm_sample,pcm_point); + } + +#ifdef VARMODESUPPORT + if (playlimit < 128) { + pcm_point -= playlimit >> 1; + playlimit = 0; + } + else + playlimit -= 128; +#endif + } +#ifdef I486_OPT + } else { + /* Only stereo, 16 bits benefit from the 486 optimization. */ + ss=0; + while (ss < SSLIMIT) { + int n; + n=(0x40000 - *pcm_point) / (2*2*32); + if (n > (SSLIMIT-ss)) n=SSLIMIT-ss; + + synth_1to1_486(hybridOut[0][ss],0,pcm_sample+*pcm_point,n); + synth_1to1_486(hybridOut[1][ss],1,pcm_sample+*pcm_point,n); + ss+=n; + *pcm_point+=(2*2*32)*n; + } + } +#endif + } + + return clip; +} diff --git a/programs/media/ac97snd/trunk/mpg/layer3.h b/programs/media/ac97snd/trunk/mpg/layer3.h new file mode 100644 index 0000000000..ec90fcfef8 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/layer3.h @@ -0,0 +1,17 @@ +/* + layer3.h: some functions for interfacing to layer3 (gapless support) + + copyright 2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Thomas Orgis. +*/ + +/* init part 1; set start/end in samples_*/ +void layer3_gapless_init(unsigned long b, unsigned long e); +/* init part 2; transform to byte addresses with new info */ +void layer3_gapless_bytify(struct frame *fr, struct audio_info_struct *ai); +/* after some seeking action to a new frame, the decoder needs to know which one is coming next */ +void layer3_gapless_set_position(unsigned long frames, struct frame* fr, struct audio_info_struct *ai); + void layer3_gapless_set_ignore(unsigned long frames, struct frame* fr, struct audio_info_struct *ai); +/* removing the gaps from buffer */ +void layer3_gapless_buffercheck(); diff --git a/programs/media/ac97snd/trunk/mpg/math_private.h b/programs/media/ac97snd/trunk/mpg/math_private.h new file mode 100644 index 0000000000..81c3597060 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/math_private.h @@ -0,0 +1,209 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * from: @(#)fdlibm.h 5.1 93/09/24 + * $Id: math_private.h,v 1.8 1998/11/27 11:33:46 drepper Exp $ + */ + +#ifndef _MATH_PRIVATE_H_ +#define _MATH_PRIVATE_H_ + + +/* The original fdlibm code used statements like: + n0 = ((*(int*)&one)>>29)^1; * index of high word * + ix0 = *(n0+(int*)&x); * high word of x * + ix1 = *((1-n0)+(int*)&x); * low word of x * + to dig two 32 bit words out of the 64 bit IEEE floating point + value. That is non-ANSI, and, moreover, the gcc instruction + scheduler gets it wrong. We instead use the following macros. + Unlike the original code, we determine the endianness at compile + time, not at run time; I don't see much benefit to selecting + endianness at run time. */ + +/* A union which permits us to convert between a double and two 32 bit + ints. */ + +typedef int int32_t; +typedef unsigned int u_int32_t; + +typedef union +{ + double value; + struct + { + u_int32_t lsw; + u_int32_t msw; + } parts; +} ieee_double_shape_type; + +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +do { \ + ieee_double_shape_type gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} while (0) + +/* Get the less significant 32 bit int from a double. */ + +#define GET_LOW_WORD(i,d) \ +do { \ + ieee_double_shape_type gl_u; \ + gl_u.value = (d); \ + (i) = gl_u.parts.lsw; \ +} while (0) + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + +/* Set the more significant 32 bits of a double from an int. */ + +#define SET_HIGH_WORD(d,v) \ +do { \ + ieee_double_shape_type sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} while (0) + +/* Set the less significant 32 bits of a double from an int. */ + +#define SET_LOW_WORD(d,v) \ +do { \ + ieee_double_shape_type sl_u; \ + sl_u.value = (d); \ + sl_u.parts.lsw = (v); \ + (d) = sl_u.value; \ +} while (0) + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union +{ + float value; + u_int32_t word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +do { \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} while (0) + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +do { \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} while (0) + +/* A union which permits us to convert between a long double and + three 32 bit ints. */ + + +typedef union +{ + long double value; + struct + { + u_int32_t lsw; + u_int32_t msw; + unsigned int sign_exponent:16; + unsigned int empty:16; + } parts; +} ieee_long_double_shape_type; + +/* Get three 32 bit ints from a double. */ + +#define GET_LDOUBLE_WORDS(exp,ix0,ix1,d) \ +do { \ + ieee_long_double_shape_type ew_u; \ + ew_u.value = (d); \ + (exp) = ew_u.parts.sign_exponent; \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Set a double from two 32 bit ints. */ + +#define SET_LDOUBLE_WORDS(d,exp,ix0,ix1) \ +do { \ + ieee_long_double_shape_type iw_u; \ + iw_u.parts.sign_exponent = (exp); \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + +/* Get the more significant 32 bits of a long double mantissa. */ + +#define GET_LDOUBLE_MSW(v,d) \ +do { \ + ieee_long_double_shape_type sh_u; \ + sh_u.value = (d); \ + (v) = sh_u.parts.msw; \ +} while (0) + +/* Set the more significant 32 bits of a long double mantissa from an int. */ + +#define SET_LDOUBLE_MSW(d,v) \ +do { \ + ieee_long_double_shape_type sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} while (0) + +/* Get int from the exponent of a long double. */ + +#define GET_LDOUBLE_EXP(exp,d) \ +do { \ + ieee_long_double_shape_type ge_u; \ + ge_u.value = (d); \ + (exp) = ge_u.parts.sign_exponent; \ +} while (0) + +/* Set exponent of a long double from an int. */ + +#define SET_LDOUBLE_EXP(d,exp) \ +do { \ + ieee_long_double_shape_type se_u; \ + se_u.value = (d); \ + se_u.parts.sign_exponent = (exp); \ + (d) = se_u.value; \ +} while (0) + +#endif /* _MATH_PRIVATE_H_ */ diff --git a/programs/media/ac97snd/trunk/mpg/mpg.vcproj b/programs/media/ac97snd/trunk/mpg/mpg.vcproj new file mode 100644 index 0000000000..6b23039538 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/mpg.vcproj @@ -0,0 +1,365 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/programs/media/ac97snd/trunk/mpg/mpg123.h b/programs/media/ac97snd/trunk/mpg/mpg123.h new file mode 100644 index 0000000000..d97db75424 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/mpg123.h @@ -0,0 +1,358 @@ +/* + mpg123: main code of the program (not of the decoder...) + + copyright 1995-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Michael Hipp + + mpg123 defines + used source: musicout.h from mpegaudio package +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#ifndef _AUDIO_H_ +#define _AUDIO_H_ + +typedef unsigned char byte; +#define off_t long + +//#define I486_OPT 1 + +#define SKIP_JUNK 1 +# define M_PI 3.14159265358979323846 +# define M_SQRT2 1.41421356237309504880 +# define REAL_IS_FLOAT +# define NEW_DCT9 + +#ifdef REAL_IS_FLOAT +# define real float +# define REAL_SCANF "%f" +# define REAL_PRINTF "%f" +#else +# define real double +# define REAL_SCANF "%lf" +# define REAL_PRINTF "%f" +#endif + +#ifndef DOUBLE_TO_REAL +# define DOUBLE_TO_REAL(x) (x) +#endif +#ifndef REAL_TO_SHORT +# define REAL_TO_SHORT(x) (x) +#endif +#ifndef REAL_PLUS_32767 +# define REAL_PLUS_32767 32767.0 +#endif +#ifndef REAL_MINUS_32768 +# define REAL_MINUS_32768 -32768.0 +#endif +#ifndef REAL_MUL +# define REAL_MUL(x, y) ((x) * (y)) +#endif + +#define INLINE +/* AUDIOBUFSIZE = n*64 with n=1,2,3 ... */ +#define AUDIOBUFSIZE 16384 + +#define FALSE 0 +#define TRUE 1 + +#define MAX_NAME_SIZE 81 +#define SBLIMIT 32 +#define SCALE_BLOCK 12 +#define SSLIMIT 18 + +#define MPG_MD_STEREO 0 +#define MPG_MD_JOINT_STEREO 1 +#define MPG_MD_DUAL_CHANNEL 2 +#define MPG_MD_MONO 3 + +/* I suspect that 32767 would be a better idea here, but Michael put this in... */ +#define MAXOUTBURST 32768 + +/* Pre Shift fo 16 to 8 bit converter table */ +#define AUSHIFT (3) + +struct bitstream_info +{ int bitindex; + unsigned char *wordpointer; +}; +extern struct bitstream_info bsi; + +struct reader +{ char *hFile; + unsigned char *buffer; + unsigned char *stream; + int strpos; + int strremain; + int filelen; + int filepos; + + int (*head_read)(struct reader *,unsigned long *newhead); + int (*read_frame_body)(struct reader *,unsigned char *,int size); + }; + +struct al_table +{ short bits; + short d; +}; + +struct frame { + struct al_table *alloc; + int (*synth)(real *,int,unsigned char *,int *); + int (*synth_mono)(real *,unsigned char *,int *); + int stereo; /* I _think_ 1 for mono and 2 for stereo */ + int jsbound; + int single; + int II_sblimit; + int down_sample_sblimit; + int lsf; /* 0: MPEG 1.0; 1: MPEG 2.0/2.5 -- both used as bool and array index! */ + int mpeg25; + int down_sample; + int header_change; + int lay; + int (*do_layer)(struct frame *fr,byte *pcm_out, int *pcm_size); + int error_protection; + int bitrate_index; + int sampling_frequency; + int padding; + int extension; + int mode; + int mode_ext; + int copyright; + int original; + int emphasis; + int framesize; /* computed framesize */ + int vbr; /* 1 if variable bitrate was detected */ + unsigned long num; /* the nth frame in some stream... */ +}; + +#if 0 +struct parameter { + int aggressive; /* renice to max. priority */ + int shuffle; /* shuffle/random play */ + int remote; /* remote operation */ + int remote_err; /* remote operation to stderr */ + int outmode; /* where to out the decoded sampels */ + int quiet; /* shut up! */ + int xterm_title; /* Change xterm title to song names? */ + long usebuffer; /* second level buffer size */ + int tryresync; /* resync stream after error */ + int verbose; /* verbose level */ + int force_mono; + int force_stereo; + int force_8bit; + long force_rate; + int down_sample; + int checkrange; + long doublespeed; + long halfspeed; + int force_reopen; + long realtime; + char filename[256]; + long listentry; /* possibility to choose playback of one entry in playlist (0: off, > 0 : select, < 0; just show list*/ + int rva; /* (which) rva to do: <0: nothing, 0: radio/mix/track 1: album/audiophile */ + char* listname; /* name of playlist */ + int long_id3; +}; +#endif + +#if 0 +struct reader { + int (*init)(struct reader *); + void (*close)(struct reader *); + int (*head_read)(struct reader *,unsigned long *newhead); + int (*head_shift)(struct reader *,unsigned long *head); + long (*skip_bytes)(struct reader *,off_t len); + int (*read_frame_body)(struct reader *,unsigned char *,int size); + int (*back_bytes)(struct reader *,off_t bytes); + int (*back_frame)(struct reader *,struct frame *,long num); + off_t (*tell)(struct reader *); + void (*rewind)(struct reader *); + off_t filelen; + off_t filepos; + int filept; + int flags; + unsigned char id3buf[128]; +}; +#endif + +#define READER_FD_OPENED 0x1 +#define READER_ID3TAG 0x2 +#define READER_SEEKABLE 0x4 + +//extern void audio_flush(int, struct audio_info_struct *); + +//extern void print_header(struct frame *); +//extern void print_header_compact(struct frame *); +//extern void print_id3_tag(unsigned char *buf); + +//extern int split_dir_file(const char *path, char **dname, char **fname); + +extern unsigned int get1bit(void); +extern unsigned int getbits(int); +extern unsigned int getbits_fast(int); +//extern void backbits(int); +//extern int getbitoffset(void); +//extern int getbyte(void); + +//extern void set_pointer(long); + +//extern unsigned char *pcm_sample; +//extern int pcm_point; +//extern int audiobufsize; + +//extern int OutputDescriptor; + +#ifdef VARMODESUPPORT +extern int varmode; +extern int playlimit; +#endif + +struct gr_info_s { + int scfsi; + unsigned part2_3_length; + unsigned big_values; + unsigned scalefac_compress; + unsigned block_type; + unsigned mixed_block_flag; + unsigned table_select[3]; + unsigned subblock_gain[3]; + unsigned maxband[3]; + unsigned maxbandl; + unsigned maxb; + unsigned region1start; + unsigned region2start; + unsigned preflag; + unsigned scalefac_scale; + unsigned count1table_select; + real *full_gain[3]; + real *pow2gain; +}; + +struct III_sideinfo +{ + unsigned main_data_begin; + unsigned private_bits; + struct { + struct gr_info_s gr[2]; + } ch[2]; +}; + +extern int open_stream(char *,int fd); +extern void read_frame_init (struct frame* fr); +int read_frame(struct reader *rd, struct frame *fr); + + +/* why extern? */ +void prepare_audioinfo(struct frame *fr, struct audio_info_struct *nai); +int play_frame(int init,struct frame *fr); +int do_layer1(struct frame *fr,byte *pcm_sample, int *pcm_point); +int do_layer2(struct frame *fr,byte *pcm_sample, int *pcm_point); +int do_layer3(struct frame *fr,byte *pcm_sample, int *pcm_point); +extern void do_equalizer(real *bandPtr,int channel); + +#ifdef PENTIUM_OPT +extern int synth_1to1_pent (real *,int,unsigned char *); +#endif +extern int synth_1to1 (real *,int,unsigned char *,int *); +extern int synth_1to1_8bit (real *,int,unsigned char *,int *); +extern int synth_1to1_mono (real *,unsigned char *,int *); +extern int synth_1to1_mono2stereo (real *,unsigned char *,int *); +extern int synth_1to1_8bit_mono (real *,unsigned char *,int *); +extern int synth_1to1_8bit_mono2stereo (real *,unsigned char *,int *); + +extern int synth_2to1 (real *,int,unsigned char *,int *); +extern int synth_2to1_8bit (real *,int,unsigned char *,int *); +extern int synth_2to1_mono (real *,unsigned char *,int *); +extern int synth_2to1_mono2stereo (real *,unsigned char *,int *); +extern int synth_2to1_8bit_mono (real *,unsigned char *,int *); +extern int synth_2to1_8bit_mono2stereo (real *,unsigned char *,int *); + +extern int synth_4to1 (real *,int,unsigned char *,int *); +extern int synth_4to1_8bit (real *,int,unsigned char *,int *); +extern int synth_4to1_mono (real *,unsigned char *,int *); +extern int synth_4to1_mono2stereo (real *,unsigned char *,int *); +extern int synth_4to1_8bit_mono (real *,unsigned char *,int *); +extern int synth_4to1_8bit_mono2stereo (real *,unsigned char *,int *); + +extern int synth_ntom (real *,int,unsigned char *,int *); +extern int synth_ntom_8bit (real *,int,unsigned char *,int *); +extern int synth_ntom_mono (real *,unsigned char *,int *); +extern int synth_ntom_mono2stereo (real *,unsigned char *,int *); +extern int synth_ntom_8bit_mono (real *,unsigned char *,int *); +extern int synth_ntom_8bit_mono2stereo (real *,unsigned char *,int *); + +extern void rewindNbits(int bits); +extern int hsstell(void); +extern void set_pointer(long); +extern void huffman_decoder(int ,int *); +extern void huffman_count1(int,int *); +extern void print_stat(struct frame *fr,unsigned long no,long buffsize,struct audio_info_struct *ai); +extern int get_songlen(struct frame *fr,int no); + +extern void init_layer3(int); +extern void init_layer2(void); +extern void make_decode_tables(long scale); +extern int make_conv16to8_table(int); +extern void dct64(real *,real *,real *); + +#ifdef USE_MMX +extern void dct64_MMX(short *a,short *b,real *c); +extern int synth_1to1_MMX(real *, int, short *, short *, int *); +#endif + +extern int synth_ntom_set_step(long,long); + + +extern unsigned char *conv16to8; +extern long freqs[9]; +extern real muls[27][64]; +extern real decwin[512+32]; +#ifndef USE_MMX +extern real *pnts[5]; +#endif + +extern real equalizer[2][32]; +extern real equalizer_sum[2][32]; +extern int equalizer_cnt; + +extern struct audio_name audio_val2name[]; + +//extern struct parameter param; + +/* 486 optimizations */ +#define FIR_BUFFER_SIZE 128 +extern void dct64_486(int *a,int *b,real *c); +extern int synth_1to1_486(real *bandPtr,int channel,unsigned char *out,int nb_blocks); + +/* 3DNow! optimizations */ +#ifdef USE_3DNOW +extern int getcpuflags(void); +extern void dct36(real *,real *,real *,real *,real *); +extern void dct36_3dnow(real *,real *,real *,real *,real *); +extern int synth_1to1_3dnow(real *,int,unsigned char *,int *); +#endif + +/* avoid the SIGINT in terminal control */ +void next_track(void); +extern long outscale; + +#endif + +void set_pointer(long backstep); +int __stdcall create_reader(struct reader *rd,byte *buffer, int buffsize); +int __stdcall init_reader(struct reader *rd, char *file); +int __stdcall decode_header(struct frame *fr,unsigned long newhead); +int __stdcall set_reader(struct reader *rd, unsigned int filepos); +double pow_test(double, double); +void * __cdecl mem_cpy(void * dst,const void * src,size_t count); + +#ifdef __cplusplus +} +#endif diff --git a/programs/media/ac97snd/trunk/mpg/readers.c b/programs/media/ac97snd/trunk/mpg/readers.c new file mode 100644 index 0000000000..ab7a34f9d9 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/readers.c @@ -0,0 +1,880 @@ +#include "mpg123.h" +#include "..\kolibri.h" + +#define MAXFRAMESIZE 3456 + +static int fsizeold=0,ssize; +static unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */ +static unsigned char *bsbuf=bsspace[1],*bsbufold; +static int bsnum=0; + +static unsigned long oldhead = 0; +unsigned long firsthead=0; + +struct bitstream_info bsi; + +int tabsel_123[2][3][16] = { + { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,}, + {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,}, + {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} }, + + { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} } +}; + +int freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 }; + +int stream_head_read(struct reader *rd,unsigned long *newhead); +int stream_read_raw(struct reader *rd,unsigned char *buf, int size); + +void set_synth_functions(struct frame *fr) +{ +#ifdef USE_3DNOW + static func_dct36 funcs_dct36[2] = {dct36 , dct36_3dnow}; +#endif + + fr->synth = synth_1to1; + fr->synth_mono = synth_1to1_mono2stereo;; + +/* TODO: make autodetection for _all_ x86 optimizations (maybe just for i586+ and keep separate 486 build?) */ +#ifdef USE_3DNOW + /* check cpuflags bit 31 (3DNow!) and 23 (MMX) */ + if((param.stat_3dnow < 2) && + ((param.stat_3dnow == 1) || + (getcpuflags() & 0x80800000) == 0x80800000)) + { + fr->synth = funcs[2][ds]; /* 3DNow! optimized synth_1to1() */ + fr->dct36 = funcs_dct36[1]; /* 3DNow! optimized dct36() */ + } + else + { + fr->dct36 = funcs_dct36[0]; + } +#endif +} + +int __stdcall create_reader(struct reader *rd,byte *buffer, int buffsize) +{ rd->head_read = stream_head_read; + rd->read_frame_body = stream_read_raw; + + rd->buffer = buffer; + rd->stream = buffer; + rd->strpos = 0; + + rd->strremain = 0; + rd->filepos = 0; + return 1; +}; + +int __stdcall init_reader(struct reader *rd, char *file) +{ FILEINFO fileinfo; + int retval; + int bytes; + + rd->hFile = file; + get_fileinfo(file, &fileinfo); + + rd->filelen = fileinfo.size; + rd->strpos = 0; + retval=read_file (file,rd->buffer,0,0x10000,&bytes); + + if (retval) return 0; + + rd->strremain = bytes; + rd->filepos = bytes; + return 1; +}; + +static int fill_reader(struct reader *rd) +{ int retval; + int bytes; + + mem_cpy(rd->buffer,rd->stream,rd->strremain); + rd->stream = rd->buffer; + + retval=read_file (rd->hFile,rd->buffer+rd->strremain,rd->filepos, + 0x10000-rd->strremain,&bytes); + if (retval) return 0; + if(!bytes) return 0; + rd->strremain+=bytes; + rd->filepos+=bytes; + rd->strpos = 0; + return 1; +}; + +int __stdcall set_reader(struct reader *rd, unsigned int filepos) +{ int retval; + unsigned int bytes; + retval=read_file (rd->hFile,rd->buffer,filepos,0x10000,&bytes); + if (retval) return 0; + rd->stream = rd->buffer; + rd->strremain=bytes; + rd->filepos=filepos+bytes; + rd->strpos = 0; + return 1; +}; + +static int stream_head_read(struct reader *rd,unsigned long *newhead) +{ + if(rd->strremain < 4) + if( !fill_reader(rd)) + return 0; + *newhead = (rd->stream[0]<<24)|(rd->stream[1] << 16)| + (rd->stream[2] << 8)| rd->stream[3]; + rd->strpos+=4; + rd->stream+=4; + rd->strremain-=4; + return TRUE; +}; + +int stream_read_raw(struct reader *rd,unsigned char *buf, int size) +{ + if(rd->strremain < size) + if( !fill_reader(rd)) + return 0; + + mem_cpy(buf,rd->stream,size); + rd->strpos+=size; + rd->stream+=size; + rd->strremain-=size; + return 1; +}; + +void set_pointer(long backstep) +{ + bsi.wordpointer = bsbuf + ssize - backstep; + if (backstep) + mem_cpy(bsi.wordpointer,bsbufold+fsizeold-backstep,backstep); + bsi.bitindex = 0; +} + +int head_check(unsigned long head) +{ if + ( + /* first 11 bits are set to 1 for frame sync */ + ((head & 0xffe00000) != 0xffe00000) + || + /* layer: 01,10,11 is 1,2,3; 00 is reserved */ + (!((head>>17)&3)) + || + /* 1111 means bad bitrate */ + (((head>>12)&0xf) == 0xf) + || + /* 0000 means free format... */ + (((head>>12)&0xf) == 0x0) + || + /* sampling freq: 11 is reserved */ + (((head>>10)&0x3) == 0x3 ) + /* here used to be a mpeg 2.5 check... re-enabled 2.5 decoding due to lack of evidence that it is really not good */ + ) + { + return FALSE; + } + /* if no check failed, the header is valid (hopefully)*/ + else + { + return TRUE; + } +} + +int __stdcall decode_header(struct frame *fr,unsigned long newhead) +{ + if(!head_check(newhead)) + return 0; + if( newhead & (1<<20) ) + { fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1; + fr->mpeg25 = 0; + } + else + { fr->lsf = 1; + fr->mpeg25 = 1; + }; + + fr->lay = 4-((newhead>>17)&3); + if(fr->mpeg25) + fr->sampling_frequency = 6 + ((newhead>>10)&0x3); + else + fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3); + fr->error_protection = ((newhead>>16)&0x1)^0x1; + + fr->bitrate_index = ((newhead>>12)&0xf); + fr->padding = ((newhead>>9)&0x1); + fr->extension = ((newhead>>8)&0x1); + fr->mode = ((newhead>>6)&0x3); + fr->mode_ext = ((newhead>>4)&0x3); + fr->copyright = ((newhead>>3)&0x1); + fr->original = ((newhead>>2)&0x1); + fr->emphasis = newhead & 0x3; + + fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2; + + oldhead = newhead; + + if(!fr->bitrate_index) + return (0); + + switch(fr->lay) + { case 1: + fr->do_layer = do_layer1; +#ifdef VARMODESUPPORT + if (varmode) { + error("Sorry, layer-1 not supported in varmode."); + return (0); + } +#endif + fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000; + fr->framesize /= freqs[fr->sampling_frequency]; + fr->framesize = ((fr->framesize+fr->padding)<<2)-4; + break; + case 2: + fr->do_layer = do_layer2; +#ifdef VARMODESUPPORT + if (varmode) { + error("Sorry, layer-2 not supported in varmode."); + return (0); + } +#endif + fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000; + fr->framesize /= freqs[fr->sampling_frequency]; + fr->framesize += fr->padding - 4; + break; + case 3: + fr->do_layer = do_layer3; + if(fr->lsf) + ssize = (fr->stereo == 1) ? 9 : 17; + else + ssize = (fr->stereo == 1) ? 17 : 32; + if(fr->error_protection) + ssize += 2; + fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000; + fr->framesize /= freqs[fr->sampling_frequency]<<(fr->lsf); + fr->framesize = fr->framesize + fr->padding - 4; + break; + default: + return (0); + } + if (fr->framesize > MAXFRAMESIZE) + return (0); + return 1; +} + + +int read_frame(struct reader *rd, struct frame *fr) +{ unsigned long newhead; + static unsigned char ssave[34]; + //off_t framepos; + fsizeold=fr->framesize; /* for Layer3 */ + +read_again: + + if(!rd->head_read(rd,&newhead)) + return FALSE; + + if(!decode_header(fr,newhead)) + { rd->strpos-=3; + rd->stream-=3; + rd->strremain+=3; + goto read_again; + }; + +#if 0 + if(1 || oldhead != newhead || !oldhead) + { + +init_resync: + +#ifdef SKIP_JUNK + /* watch out for junk/tags on beginning of stream by invalid header */ + if(!firsthead && !head_check(newhead) && !free_format_header(newhead)) { + int i; + + /* check for id3v2; first three bytes (of 4) are "ID3" */ + if((newhead & (unsigned long) 0xffffff00) == (unsigned long) 0x49443300) + { + int id3length = 0; + id3length = parse_new_id3(newhead, rd); + goto read_again; + } + else if(param.verbose > 1) fprintf(stderr,"Note: Junk at the beginning (0x%08lx)\n",newhead); + + /* I even saw RIFF headers at the beginning of MPEG streams ;( */ + if(newhead == ('R'<<24)+('I'<<16)+('F'<<8)+'F') { + if(param.verbose > 1) fprintf(stderr, "Note: Looks like a RIFF header.\n"); + if(!rd->head_read(rd,&newhead)) + return 0; + while(newhead != ('d'<<24)+('a'<<16)+('t'<<8)+'a') { + if(!rd->head_shift(rd,&newhead)) + return 0; + } + if(!rd->head_read(rd,&newhead)) + return 0; + if(param.verbose > 1) fprintf(stderr,"Note: Skipped RIFF header!\n"); + goto read_again; + } + /* unhandled junk... just continue search for a header */ + /* step in byte steps through next 64K */ + for(i=0;i<65536;i++) { + if(!rd->head_shift(rd,&newhead)) + return 0; + /* if(head_check(newhead)) */ + if(head_check(newhead) && decode_header(fr, newhead)) + break; + } + if(i == 65536) { + if(!param.quiet) error("Giving up searching valid MPEG header after 64K of junk."); + return 0; + } + /* + * should we additionaly check, whether a new frame starts at + * the next expected position? (some kind of read ahead) + * We could implement this easily, at least for files. + */ + } +#endif + + /* first attempt of read ahead check to find the real first header; cannot believe what junk is out there! */ + /* for now, a spurious first free format header screws up here; need free format support for detecting false free format headers... */ + if(!firsthead && rd->flags & READER_SEEKABLE && head_check(newhead) && decode_header(fr, newhead)) + { + unsigned long nexthead = 0; + int hd = 0; + off_t start = rd->tell(rd); + debug1("doing ahead check with BPF %d", fr->framesize+4); + /* step framesize bytes forward and read next possible header*/ + if(rd->back_bytes(rd, -fr->framesize)) + { + error("cannot seek!"); + return 0; + } + hd = rd->head_read(rd,&nexthead); + if(rd->back_bytes(rd, rd->tell(rd)-start)) + { + error("cannot seek!"); + return 0; + } + if(!hd) + { + warning("cannot read next header, a one-frame stream? Duh..."); + } + else + { + debug2("does next header 0x%08lx match first 0x%08lx?", nexthead, newhead); + /* not allowing free format yet */ + if(!head_check(nexthead) || (nexthead & HDRCMPMASK) != (newhead & HDRCMPMASK)) + { + debug("No, the header was not valid, start from beginning..."); + /* try next byte for valid header */ + if(rd->back_bytes(rd, 3)) + { + error("cannot seek!"); + return 0; + } + goto read_again; + } + } + } + + /* why has this head check been avoided here before? */ + if(!head_check(newhead)) + { + if(!firsthead && free_format_header(newhead)) + { + error1("Header 0x%08lx seems to indicate a free format stream; I do not handle that yet", newhead); + goto read_again; + return 0; + } + /* and those ugly ID3 tags */ + if((newhead & 0xffffff00) == ('T'<<24)+('A'<<16)+('G'<<8)) { + rd->skip_bytes(rd,124); + if (param.verbose > 1) fprintf(stderr,"Note: Skipped ID3 Tag!\n"); + goto read_again; + } + /* duplicated code from above! */ + /* check for id3v2; first three bytes (of 4) are "ID3" */ + if((newhead & (unsigned long) 0xffffff00) == (unsigned long) 0x49443300) + { + int id3length = 0; + id3length = parse_new_id3(newhead, rd); + goto read_again; + } + else if (give_note) + { + fprintf(stderr,"Note: Illegal Audio-MPEG-Header 0x%08lx at offset 0x%lx.\n", newhead,rd->tell(rd)-4); + } + + if(give_note && (newhead & 0xffffff00) == ('b'<<24)+('m'<<16)+('p'<<8)) fprintf(stderr,"Note: Could be a BMP album art.\n"); + if (param.tryresync || do_recover) { + int try = 0; + /* TODO: make this more robust, I'd like to cat two mp3 fragments together (in a dirty way) and still have mpg123 beign able to decode all it somehow. */ + if(give_note) fprintf(stderr, "Note: Trying to resync...\n"); + /* Read more bytes until we find something that looks + reasonably like a valid header. This is not a + perfect strategy, but it should get us back on the + track within a short time (and hopefully without + too much distortion in the audio output). */ + do { + if(!rd->head_shift(rd,&newhead)) + return 0; + /* debug2("resync try %i, got newhead 0x%08lx", try, newhead); */ + if (!oldhead) + { + debug("going to init_resync..."); + goto init_resync; /* "considered harmful", eh? */ + } + /* we should perhaps collect a list of valid headers that occured in file... there can be more */ + /* Michael's new resync routine seems to work better with the one frame readahead (and some input buffering?) */ + } while + ( + ++try < RESYNC_LIMIT + && (newhead & HDRCMPMASK) != (oldhead & HDRCMPMASK) + && (newhead & HDRCMPMASK) != (firsthead & HDRCMPMASK) + ); + /* too many false positives + }while (!(head_check(newhead) && decode_header(fr, newhead))); */ + if(try == RESYNC_LIMIT) + { + error("giving up resync - your stream is not nice... perhaps an improved routine could catch up"); + return 0; + } + + if (give_note) + fprintf (stderr, "Note: Skipped %d bytes in input.\n", try); + } + else + { + error("not attempting to resync..."); + return (0); + } + } + + if (!firsthead) { + if(!decode_header(fr,newhead)) + { + error("decode header failed before first valid one, going to read again"); + goto read_again; + } + } + else + if(!decode_header(fr,newhead)) + { + error("decode header failed - goto resync"); + /* return 0; */ + goto init_resync; + } + } + else + fr->header_change = 0; +#endif + + bsbufold = bsbuf; + bsbuf = bsspace[bsnum]+512; + bsnum = (bsnum + 1) & 1; + /* if filepos is invalid, so is framepos */ + //framepos = rd->filepos - 4; + /* read main data into memory */ + /* 0 is error! */ + + if(!rd->read_frame_body(rd,bsbuf,fr->framesize)) + return 0; + +#if 0 + if(!firsthead) + { + /* following stuff is actually layer3 specific (in practice, not in theory) */ + if(fr->lay == 3) + { + /* + going to look for Xing or Info at some position after the header + MPEG 1 MPEG 2/2.5 (LSF) + Stereo, Joint Stereo, Dual Channel 32 17 + Mono 17 9 + + Also, how to avoid false positives? I guess I should interpret more of the header to rule that out(?). + I hope that ensuring all zeros until tag start is enough. + */ + size_t lame_offset = (fr->stereo == 2) ? (fr->lsf ? 17 : 32 ) : (fr->lsf ? 9 : 17); + if(fr->framesize >= 120+lame_offset) /* traditional Xing header is 120 bytes */ + { + size_t i; + int lame_type = 0; + /* only search for tag when all zero before it (apart from checksum) */ + for(i=2; i < lame_offset; ++i) if(bsbuf[i] != 0) break; + if(i == lame_offset) + { + if + ( + (bsbuf[lame_offset] == 'I') + && (bsbuf[lame_offset+1] == 'n') + && (bsbuf[lame_offset+2] == 'f') + && (bsbuf[lame_offset+3] == 'o') + ) + { + lame_type = 1; /* We still have to see what there is */ + } + else if + ( + (bsbuf[lame_offset] == 'X') + && (bsbuf[lame_offset+1] == 'i') + && (bsbuf[lame_offset+2] == 'n') + && (bsbuf[lame_offset+3] == 'g') + ) + { + lame_type = 2; + vbr = VBR; /* Xing header means always VBR */ + } + if(lame_type) + { + unsigned long xing_flags; + + /* we have one of these headers... */ + if(param.verbose > 1) fprintf(stderr, "Note: Xing/Lame/Info header detected\n"); + /* now interpret the Xing part, I have 120 bytes total for sure */ + /* there are 4 bytes for flags, but only the last byte contains known ones */ + lame_offset += 4; /* now first byte after Xing/Name */ + /* 4 bytes dword for flags */ + #define make_long(a, o) ((((unsigned long) a[o]) << 24) | (((unsigned long) a[o+1]) << 16) | (((unsigned long) a[o+2]) << 8) | ((unsigned long) a[o+3])) + /* 16 bit */ + #define make_short(a,o) ((((unsigned short) a[o]) << 8) | ((unsigned short) a[o+1])) + xing_flags = make_long(bsbuf, lame_offset); + lame_offset += 4; + debug1("Xing: flags 0x%08lx", xing_flags); + if(xing_flags & 1) /* frames */ + { + /* + In theory, one should use that value for skipping... + When I know the exact number of samples I could simply count in audio_flush, + but that's problematic with seeking and such. + I still miss the real solution for detecting the end. + */ + track_frames = make_long(bsbuf, lame_offset); + if(track_frames > TRACK_MAX_FRAMES) track_frames = 0; /* endless stream? */ + #ifdef GAPLESS + /* if no further info there, remove/add at least the decoder delay */ + if(param.gapless) + { + unsigned long length = track_frames * spf(fr); + if(length > 1) + layer3_gapless_init(DECODER_DELAY+GAP_SHIFT, length+DECODER_DELAY+GAP_SHIFT); + } + #endif + debug1("Xing: %lu frames", track_frames); + lame_offset += 4; + } + if(xing_flags & 0x2) /* bytes */ + { + #ifdef DEBUG + unsigned long xing_bytes = make_long(bsbuf, lame_offset); + debug1("Xing: %lu bytes", xing_bytes); + #endif + lame_offset += 4; + } + if(xing_flags & 0x4) /* TOC */ + { + lame_offset += 100; /* just skip */ + } + if(xing_flags & 0x8) /* VBR quality */ + { + #ifdef DEBUG + unsigned long xing_quality = make_long(bsbuf, lame_offset); + debug1("Xing: quality = %lu", xing_quality); + #endif + lame_offset += 4; + } + /* I guess that either 0 or LAME extra data follows */ + /* there may this crc16 be floating around... (?) */ + if(bsbuf[lame_offset] != 0) + { + unsigned char lame_vbr; + float replay_gain[2] = {0,0}; + float peak = 0; + float gain_offset = 0; /* going to be +6 for old lame that used 83dB */ + char nb[10]; + memcpy(nb, bsbuf+lame_offset, 9); + nb[9] = 0; + debug1("Info: Encoder: %s", nb); + if(!strncmp("LAME", nb, 4)) + { + gain_offset = 6; + debug("TODO: finish lame detetcion..."); + } + lame_offset += 9; + /* the 4 big bits are tag revision, the small bits vbr method */ + lame_vbr = bsbuf[lame_offset] & 15; + debug1("Info: rev %u", bsbuf[lame_offset] >> 4); + debug1("Info: vbr mode %u", lame_vbr); + lame_offset += 1; + switch(lame_vbr) + { + /* from rev1 proposal... not sure if all good in practice */ + case 1: + case 8: vbr = CBR; break; + case 2: + case 9: vbr = ABR; break; + default: vbr = VBR; /* 00==unknown is taken as VBR */ + } + /* skipping: lowpass filter value */ + lame_offset += 1; + /* replaygain */ + /* 32bit float: peak amplitude -- why did I parse it as int before??*/ + /* Ah, yes, lame seems to store it as int since some day in 2003; I've only seen zeros anyway until now, bah! */ + if + ( + (bsbuf[lame_offset] != 0) + || (bsbuf[lame_offset+1] != 0) + || (bsbuf[lame_offset+2] != 0) + || (bsbuf[lame_offset+3] != 0) + ) + { + debug("Wow! Is there _really_ a non-zero peak value? Now is it stored as float or int - how should I know?"); + peak = *(float*) (bsbuf+lame_offset); + } + debug1("Info: peak = %f (I won't use this)", peak); + peak = 0; /* until better times arrived */ + lame_offset += 4; + /* + ReplayGain values - lame only writes radio mode gain... + 16bit gain, 3 bits name, 3 bits originator, sign (1=-, 0=+), dB value*10 in 9 bits (fixed point) + ignore the setting if name or originator == 000! + radio 0 0 1 0 1 1 1 0 0 1 1 1 1 1 0 1 + audiophile 0 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0 + */ + + for(i =0; i < 2; ++i) + { + unsigned char origin = (bsbuf[lame_offset] >> 2) & 0x7; /* the 3 bits after that... */ + if(origin != 0) + { + unsigned char gt = bsbuf[lame_offset] >> 5; /* only first 3 bits */ + if(gt == 1) gt = 0; /* radio */ + else if(gt == 2) gt = 1; /* audiophile */ + else continue; + /* get the 9 bits into a number, divide by 10, multiply sign... happy bit banging */ + replay_gain[0] = ((bsbuf[lame_offset] & 0x2) ? -0.1 : 0.1) * (make_short(bsbuf, lame_offset) & 0x1f); + } + lame_offset += 2; + } + debug1("Info: Radio Gain = %03.1fdB", replay_gain[0]); + debug1("Info: Audiophile Gain = %03.1fdB", replay_gain[1]); + for(i=0; i < 2; ++i) + { + if(rva_level[i] <= 0) + { + rva_peak[i] = 0; /* at some time the parsed peak should be used */ + rva_gain[i] = replay_gain[i]; + rva_level[i] = 0; + } + } + lame_offset += 1; /* skipping encoding flags byte */ + if(vbr == ABR) + { + abr_rate = bsbuf[lame_offset]; + debug1("Info: ABR rate = %u", abr_rate); + } + lame_offset += 1; + /* encoder delay and padding, two 12 bit values... lame does write them from int ...*/ + #ifdef GAPLESS + if(param.gapless) + { + /* + Temporary hack that doesn't work with seeking and also is not waterproof but works most of the time; + in future the lame delay/padding and frame number info should be passed to layer3.c and the junk samples avoided at the source. + */ + unsigned long length = track_frames * spf(fr); + unsigned long skipbegin = DECODER_DELAY + ((((int) bsbuf[lame_offset]) << 4) | (((int) bsbuf[lame_offset+1]) >> 4)); + unsigned long skipend = -DECODER_DELAY + (((((int) bsbuf[lame_offset+1]) << 8) | (((int) bsbuf[lame_offset+2]))) & 0xfff); + debug3("preparing gapless mode for layer3: length %lu, skipbegin %lu, skipend %lu", length, skipbegin, skipend); + if(length > 1) + layer3_gapless_init(skipbegin+GAP_SHIFT, (skipend < length) ? length-skipend+GAP_SHIFT : length+GAP_SHIFT); + } + #endif + } + /* switch buffer back ... */ + bsbuf = bsspace[bsnum]+512; + bsnum = (bsnum + 1) & 1; + goto read_again; + } + } + } + } /* end block for Xing/Lame/Info tag */ + firsthead = newhead; /* _now_ it's time to store it... the first real header */ + debug1("firsthead: %08lx", firsthead); + /* now adjust volume */ + do_rva(); + /* and print id3 info */ + if(!param.quiet) print_id3_tag(rd->flags & READER_ID3TAG ? rd->id3buf : NULL); + } +#endif + + bsi.bitindex = 0; + bsi.wordpointer = (unsigned char *) bsbuf; + set_synth_functions(fr); + if (fr->error_protection) + getbits(16); + return 1; +} + + + +#if 0 +static int stream_back_bytes(struct reader *rds, off_t bytes) +{ + if(stream_lseek(rds,-bytes,SEEK_CUR) < 0) + return -1; + /* you sure you want the buffer to resync here? */ + if(param.usebuffer) + buffer_resync(); + return 0; +} + + +/* this function strangely is define to seek num frames _back_ (and is called with -offset - duh!) */ +/* also... let that int be a long in future! */ +static int stream_back_frame(struct reader *rds,struct frame *fr,long num) +{ + if(rds->flags & READER_SEEKABLE) + { + unsigned long newframe, preframe; + if(num > 0) /* back! */ + { + if(num > fr->num) newframe = 0; + else newframe = fr->num-num; + } + else newframe = fr->num-num; + + /* two leading frames? hm, doesn't seem to be really needed... */ + /*if(newframe > 1) newframe -= 2; + else newframe = 0;*/ + + /* now seek to nearest leading index position and read from there until newframe is reached */ + if(stream_lseek(rds,frame_index_find(newframe, &preframe),SEEK_SET) < 0) + return -1; + + debug2("going to %lu; just got %lu", newframe, preframe); + + fr->num = preframe; + + while(fr->num < newframe) + { + /* try to be non-fatal now... frameNum only gets advanced on success anyway */ + if(!read_frame(fr)) break; + } + + /* this is not needed at last? */ + /*read_frame(fr); + read_frame(fr);*/ + + if(fr->lay == 3) { + set_pointer(512); + } + + debug1("arrived at %lu", fr->num); + + if(param.usebuffer) + buffer_resync(); + + return 0; + + } + else return -1; /* invalid, no seek happened */ +} + +static int stream_head_read(struct reader *rds,unsigned long *newhead) +{ + unsigned char hbuf[4]; + + if(fullread(rds,hbuf,4) != 4) + return FALSE; + + *newhead = ((unsigned long) hbuf[0] << 24) | + ((unsigned long) hbuf[1] << 16) | + ((unsigned long) hbuf[2] << 8) | + (unsigned long) hbuf[3]; + + return TRUE; +} + +static int stream_head_shift(struct reader *rds,unsigned long *head) +{ + unsigned char hbuf; + + if(fullread(rds,&hbuf,1) != 1) + return 0; + *head <<= 8; + *head |= hbuf; + *head &= 0xffffffff; + return 1; +} + +static off_t stream_skip_bytes(struct reader *rds,off_t len) +{ + if (rds->filelen >= 0) { + off_t ret = stream_lseek(rds, len, SEEK_CUR); + if (param.usebuffer) + buffer_resync(); + return ret; + } else if (len >= 0) { + unsigned char buf[1024]; /* ThOr: Compaq cxx complained and it makes sense to me... or should one do a cast? What for? */ + off_t ret; + while (len > 0) { + off_t num = len < sizeof(buf) ? len : sizeof(buf); + ret = fullread(rds, buf, num); + if (ret < 0) + return ret; + len -= ret; + } + return rds->filepos; + } else + return -1; +} + +static int stream_read_frame_body(struct reader *rds,unsigned char *buf, + int size) +{ + long l; + + if( (l=fullread(rds,buf,size)) != size) + { + if(l <= 0) + return 0; + memset(buf+l,0,size-l); + } + + return 1; +} + +static off_t stream_tell(struct reader *rds) +{ + return rds->filepos; +} + +static void stream_rewind(struct reader *rds) +{ + stream_lseek(rds,0,SEEK_SET); + if(param.usebuffer) + buffer_resync(); +} + +static off_t get_fileinfo(struct reader *rds,char *buf) +{ + off_t len; + + if((len=lseek(rds->filept,0,SEEK_END)) < 0) { + return -1; + } + if(lseek(rds->filept,-128,SEEK_END) < 0) + return -1; + if(fullread(rds,(unsigned char *)buf,128) != 128) { + return -1; + } + if(!strncmp(buf,"TAG",3)) { + len -= 128; + } + if(lseek(rds->filept,0,SEEK_SET) < 0) + return -1; + if(len <= 0) + return -1; + return len; +} + +#endif \ No newline at end of file diff --git a/programs/media/ac97snd/trunk/mpg/tabinit.c b/programs/media/ac97snd/trunk/mpg/tabinit.c new file mode 100644 index 0000000000..ef4e743d57 --- /dev/null +++ b/programs/media/ac97snd/trunk/mpg/tabinit.c @@ -0,0 +1,159 @@ +/* + tabinit.c: initialize tables... + + copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Michael Hipp +*/ + +//#include + +//#include "config.h" +#include "mpg123.h" +//#include "debug.h" + +static unsigned char *conv16to8_buf = NULL; +unsigned char *conv16to8; + +#ifndef USE_MMX +real decwin[512+32]; +#ifdef USE_ALTIVEC +static real __attribute__ ((aligned (16))) cos64[16]; +static real __attribute__ ((aligned (16))) cos32[8]; +static real __attribute__ ((aligned (16))) cos16[4]; +static real __attribute__ ((aligned (16))) cos8[2]; +static real __attribute__ ((aligned (16))) cos4[1]; +#else +static real cos64[16],cos32[8],cos16[4],cos8[2],cos4[1]; +#endif + +real *pnts[] = { cos64,cos32,cos16,cos8,cos4 }; + + +static long intwinbase[] = { + 0, -1, -1, -1, -1, -1, -1, -2, -2, -2, + -2, -3, -3, -4, -4, -5, -5, -6, -7, -7, + -8, -9, -10, -11, -13, -14, -16, -17, -19, -21, + -24, -26, -29, -31, -35, -38, -41, -45, -49, -53, + -58, -63, -68, -73, -79, -85, -91, -97, -104, -111, + -117, -125, -132, -139, -147, -154, -161, -169, -176, -183, + -190, -196, -202, -208, -213, -218, -222, -225, -227, -228, + -228, -227, -224, -221, -215, -208, -200, -189, -177, -163, + -146, -127, -106, -83, -57, -29, 2, 36, 72, 111, + 153, 197, 244, 294, 347, 401, 459, 519, 581, 645, + 711, 779, 848, 919, 991, 1064, 1137, 1210, 1283, 1356, + 1428, 1498, 1567, 1634, 1698, 1759, 1817, 1870, 1919, 1962, + 2001, 2032, 2057, 2075, 2085, 2087, 2080, 2063, 2037, 2000, + 1952, 1893, 1822, 1739, 1644, 1535, 1414, 1280, 1131, 970, + 794, 605, 402, 185, -45, -288, -545, -814, -1095, -1388, + -1692, -2006, -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788, + -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, -7910, -8209, + -8491, -8755, -8998, -9219, -9416, -9585, -9727, -9838, -9916, -9959, + -9966, -9935, -9863, -9750, -9592, -9389, -9139, -8840, -8492, -8092, + -7640, -7134, -6574, -5959, -5288, -4561, -3776, -2935, -2037, -1082, + -70, 998, 2122, 3300, 4533, 5818, 7154, 8540, 9975, 11455, + 12980, 14548, 16155, 17799, 19478, 21189, 22929, 24694, 26482, 28289, + 30112, 31947, 33791, 35640, 37489, 39336, 41176, 43006, 44821, 46617, + 48390, 50137, 51853, 53534, 55178, 56778, 58333, 59838, 61289, 62684, + 64019, 65290, 66494, 67629, 68692, 69679, 70590, 71420, 72169, 72835, + 73415, 73908, 74313, 74630, 74856, 74992, 75038 }; + +#pragma warning(disable:4244) +void make_decode_tables(long scaleval) +{ + int i,j,k,kr,divv; + real *costab; + int idx; + + + for(i=0;i<5;i++) + { + kr=0x10>>i; divv=0x40>>i; + costab = pnts[i]; + for(k=0;k 255) + fprintf(stderr,"Converror %d %d\n",i,c1); + if(c1 == 0) + c1 = 2; + conv16to8[i] = (unsigned char) c1; + } + } + else if(mode == AUDIO_FORMAT_SIGNED_8) { + for(i=-4096;i<4096;i++) { + conv16to8[i] = i>>5; + } + } + else if(mode == AUDIO_FORMAT_UNSIGNED_8) { + for(i=-4096;i<4096;i++) { + conv16to8[i] = (i>>5)+128; + } + } + else { + for(i=-4096;i<4096;i++) { + conv16to8[i] = 0; + } + } + return 0; +} + + +#endif \ No newline at end of file