/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Mpegtoraw.cc // Server which get mpeg format and put raw format. #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include //#include #include "mpegsound.h" #include "mpegsound_locals.h" #define MY_PI 3.14159265358979323846 Mpegtoraw::~Mpegtoraw() { // if(frameoffsets)delete [] frameoffsets; } #ifndef WORDS_BIGENDIAN #define _KEY 0 #else #define _KEY 3 #endif int Mpegtoraw::getbits(int bits) { union { char store[4]; int current; }u; int bi; if(!bits)return 0; u.current=0; bi=(bitindex&7); u.store[_KEY]=buffer[bitindex>>3]<>3]; bitindex+=8; bi=8; } if(bits>=bi) { u.current<<=bi; bits-=bi; bi=0; } else { u.current<<=bits; bi-=bits; bits=0; } } bitindex-=bi; return (u.current>>8); } void Mpegtoraw::setforcetomono(bool flag) { forcetomonoflag=flag; } void Mpegtoraw::setdownfrequency(int value) { downfrequency=0; if(value)downfrequency=1; } bool Mpegtoraw::getforcetomono(void) { return forcetomonoflag; } int Mpegtoraw::getdownfrequency(void) { return downfrequency; } int Mpegtoraw::getpcmperframe(void) { int s; s=32; if(layer==3) { s*=18; if(version==0)s*=2; } else { s*=SCALEBLOCK; if(layer==2)s*=3; } return s; } inline int Mpegtoraw::flushrawdata(void) { // player->putblock((char *)rawdata,rawdataoffset<<1); if(local_dest_buffer_size<(rawdataoffset<<1)) return -1; memcpy(local_dest_buffer, rawdata, rawdataoffset<<1); local_dest_buffer+=rawdataoffset<<1; local_dest_buffer_size-=rawdataoffset<<1; currentframe++; rawdataoffset=0; return 0; }; typedef struct { char *songname; char *musican; char *type; char *year; char *etc; }ID3; static void strman(char *str,int max) { int i; str[max]=0; for(i=max-1;i>=0;i--) if(((unsigned char)str[i])<26 || str[i]==' ')str[i]=0; else break; } /* inline void parseID3(Soundinputstream *fp,ID3 *data) { int c,flag=0; fp->setposition(fp->getsize()-1000); data->songname[0]=0; data->musican [0]=0; data->type [0]=0; data->year [0]=0; data->etc [0]=0; for(;;) { if((c=fp->getbytedirect())<0)break; else if(c==0xFF)flag++; else if(c==0x54 && flag>=28) { if(fp->getbytedirect()==0x41) { if(fp->getbytedirect()==0x47) { fp->_readbuffer(data->songname,30);strman(data->songname,30); fp->_readbuffer(data->musican ,30);strman(data->musican, 30); fp->_readbuffer(data->type ,30);strman(data->type, 30); fp->_readbuffer(data->year , 7);strman(data->year, 7); fp->_readbuffer(data->etc ,25);strman(data->etc, 25); break; } } flag=0; } else flag=0; } fp->setposition(0); } */ inline void stripfilename(char *dtr,char *str,int max) { char *ss; int p=0,s=0; for(;str[p];p++) if(str[p]=='/') { p++; s=p; } ss=str+s; for(p=0;ploader=loader; // this->player=player; static bool initialized=false; register int i; register REAL *s1,*s2; REAL *s3,*s4; scalefactor=SCALE; calcbufferoffset=15; currentcalcbuffer=0; s1=calcbufferL[0];s2=calcbufferR[0]; s3=calcbufferL[1];s4=calcbufferR[1]; for(i=CALCBUFFERSIZE-1;i>=0;i--) calcbufferL[0][i]=calcbufferL[1][i]= calcbufferR[0][i]=calcbufferR[1][i]=0.0; if(!initialized) { for(i=0;i<16;i++)hcos_64[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/64.0)); for(i=0;i< 8;i++)hcos_32[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/32.0)); for(i=0;i< 4;i++)hcos_16[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/16.0)); for(i=0;i< 2;i++)hcos_8 [i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/ 8.0)); hcos_4=1.0/(2.0*cos(MY_PI*1.0/4.0)); initialized=true; } layer3initialize(); clearrawdata(); currentframe=decodeframe=0; /* if(loadheader()) { totalframe=(loader->getsize()+framesize-1)/framesize; loader->setposition(0); } else totalframe=0; if(frameoffsets)delete [] frameoffsets; song.name[0]=0; if(totalframe>0) { frameoffsets=new int[totalframe]; for(i=totalframe-1;i>=0;i--) frameoffsets[i]=0; { ID3 data; data.songname=song.name; data.musican =song.musican; data.type =song.type; data.year =song.year; data.etc =song.etc; parseID3(loader,&data); } } else frameoffsets=NULL; */ }; /* void Mpegtoraw::setframe(int framenumber) { int pos=0; if(frameoffsets==NULL)return; if(framenumber==0)pos=frameoffsets[0]; else { if(framenumber>=totalframe)framenumber=totalframe-1; pos=frameoffsets[framenumber]; if(pos==0) { int i; for(i=framenumber-1;i>0;i--) if(frameoffsets[i]!=0)break; loader->setposition(frameoffsets[i]); while(igetposition(); } pos=frameoffsets[framenumber]; } } clearbuffer(); loader->setposition(pos); decodeframe=currentframe=framenumber; } */ /* void Mpegtoraw::clearbuffer(void) { player->abort(); player->resetsoundtype(); }*/ int Mpegtoraw::Convert(unsigned char* input_buffer, Unsigned in_size, unsigned char* output_buffer, Unsigned out_size, Unsigned* size_read, Unsigned* size_written) /*int Mpegtoraw::decode_frames ( unsigned char* input_buffer, unsigned char* output_buffer, unsigned& input_size, unsigned output_size,//unused out_format* format) */ { static int declined=0; if(input_buffer==0) return -1; if(output_buffer==0) return -1; /* if(declined) if(declined!=*(int*)input_buffer) { printf("ERROR: declined data is not equal to new \n"); } */ local_src_buffer=input_buffer; local_dest_buffer=output_buffer; local_src_buffer_size=in_size; local_dest_buffer_size=out_size; // clearrawdata(); flushrawdata(); // for(;frames;frames--) while(1) { // if(totalframe>0) // { // if(decodeframegetposition(); // } // if(loader->eof()) // { // seterrorcode(SOUND_ERROR_FINISH); // break; // } // flushrawdata(); unsigned char* rest_lb=local_src_buffer; unsigned rest_lc=local_src_buffer_size; unsigned rest_dc=local_dest_buffer_size; if(loadheader()==false) { local_src_buffer=rest_lb; local_src_buffer_size=rest_lc; local_dest_buffer_size=rest_dc; clearrawdata(); break; } if(frequency!=lastfrequency) { if(lastfrequency>0)seterrorcode(SOUND_ERROR_BAD); lastfrequency=frequency; } decodeframe++; if (layer==3)extractlayer3(); else if(layer==2)extractlayer2(); else if(layer==1)extractlayer1(); if(flushrawdata()!=0) { // printf("flushrawdata() failed: restoring %d/%d\n", rest_lc, rest_dc); // local_src_buffer=rest_lb; // local_src_buffer_size=rest_lc; // local_dest_buffer_size=rest_dc; // declined=*(int*)local_src_buffer; /* FILE* zz=fopen("./log.mp3", "ab"); fwrite(input_buffer, in_size-local_src_buffer_size, 1, zz); fclose(zz); zz=fopen("./log.raw", "ab"); fwrite(output_buffer, out_size-local_dest_buffer_size, 1, zz); fclose(zz);*/ if(size_read) *size_read=in_size-local_src_buffer_size; if(size_written) *size_written=out_size-local_dest_buffer_size; if(out_size-local_dest_buffer_size) return 0; else return -1; } } // printf("Success\n"); if(size_read) *size_read=in_size-local_src_buffer_size; if(size_written) *size_written=out_size-local_dest_buffer_size; if(size_written) return 0; else return -1; } bool Mpegtoraw::loadheader(void) { // unsigned char* rest_lb=local_src_buffer; // unsigned rest_lc=local_src_buffer_size; register int c; bool flag; sync(); // Synchronize flag=false; do { if((c=getbytedirect())<0)break; if(c==0xff) while(!flag) { if((c=getbytedirect())<0) { flag=true; break; } if((c&0xe0)==0xe0) { flag=true; break; } else if(c!=0xff)break; } }while(!flag); //c=getbytedirect(); if(c<0) { // local_src_buffer=rest_lb; // local_src_buffer_size=rest_lc; // return seterrorcode(SOUND_ERROR_FINISH); return false; } // Analyzing if (c&0x10) { mpeg25=false; } else { mpeg25=true; c=c+0x10; } c&=0xf; protection=c&1; layer=4-((c>>1)&3); version=(_mpegversion)((c>>3)^1); c=((getbytedirect()))>>1; padding=(c&1); c>>=1; frequency=(_frequency)(c&3); c>>=2; bitrateindex=(int)c; if(bitrateindex==15)return seterrorcode(SOUND_ERROR_BAD); c=((unsigned int)(getbytedirect()))>>4; extendedmode=c&3; mode=(_mode)(c>>2); // Making information inputstereo= (mode==single)?0:1; if(forcetomonoflag)outputstereo=0; else outputstereo=inputstereo; /* if(layer==2) if((bitrateindex>=1 && bitrateindex<=3) || (bitrateindex==5)) { if(inputstereo)return seterrorcode(SOUND_ERROR_BAD); } else if(bitrateindex==11 && mode==single) return seterrorcode(SOUND_ERROR_BAD); */ channelbitrate=bitrateindex; if(inputstereo) if(channelbitrate==4)channelbitrate=1; else channelbitrate-=4; if(channelbitrate==1 || channelbitrate==2)tableindex=0; else tableindex=1; if(layer==1)subbandnumber=MAXSUBBAND; else { if(!tableindex) if(frequency==frequency32000)subbandnumber=12; else subbandnumber=8; else if(frequency==frequency48000|| (channelbitrate>=3 && channelbitrate<=5)) subbandnumber=27; else subbandnumber=30; } if(mode==single)stereobound=0; else if(mode==joint)stereobound=(extendedmode+1)<<2; else stereobound=subbandnumber; if(frequency==3)return false; if(stereobound>subbandnumber)stereobound=subbandnumber; // printf("Layer %d, mode %d, frequency %d\n", layer, mode, frequency); // framesize & slots if(layer==1) { framesize=(12000*bitrate[version][0][bitrateindex])/ frequencies[version][frequency]; if(frequency==frequency44100 && padding)framesize++; framesize<<=2; } else { if(mpeg25) { framesize=(144000*bitrate[version][layer-1][bitrateindex])/ (frequencies[2][frequency]<0) { if(decodeframegetposition(); } if(loader->eof()) { seterrorcode(SOUND_ERROR_FINISH); break; } if(loadheader()==false)break; if(frequency!=lastfrequency) { if(lastfrequency>0)seterrorcode(SOUND_ERROR_BAD); lastfrequency=frequency; } if(frames<0) { frames=-frames; if (mpeg25) player->setsoundtype(outputstereo,16, frequencies[2][frequency]>>downfrequency); else player->setsoundtype(outputstereo,16, frequencies[version][frequency]>>downfrequency); } decodeframe++; if (layer==3)extractlayer3(); else if(layer==2)extractlayer2(); else if(layer==1)extractlayer1(); flushrawdata(); if(player->geterrorcode())seterrorcode(geterrorcode()); } return (geterrorcode()==SOUND_ERROR_OK); }*/