mp3blaster-3.2.6/0000755000112600011260000000000013106424300010562 500000000000000mp3blaster-3.2.6/mp3blaster.spec0000664000112600011260000000207612426044701013450 00000000000000Name: mp3blaster Summary: Mp3blaster is a text console audio player with an interactive interface Version: 3.2.5 Release: 1 Group: Applications/Multimedia Copyright: GPL Url: http://mp3blaster.sourceforge.net/ Packager: Bram Avontuur Distribution: N/A Source: http://www.stack.nl/~brama/mp3blaster/src/%{name}-%{version}.tar.gz Buildroot: /var/tmp/%{name}-%{version}-%{release}-root %description Mp3blaster is an audio player with a user-friendly interface that will run on any text console. The interface is built using ncurses, and features all common audio player controls. The playlist editor is very flexible and allows nested groups (albums). Supported audio media: mp3, ogg vorbis, wav, sid and streaming mp3 over HTTP. %prep %setup %build %configure make %install %makeinstall %clean rm -rf $RPM_BUILD_ROOT %files %doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO %{_bindir}/mp3blaster %{_bindir}/mp3tag %{_bindir}/splay %{_bindir}/nmixer %{_datadir}/mp3blaster/* %{_mandir}/man1/mp3blaster.1* %{_mandir}/man1/nmixer.1* %{_mandir}/man1/splay.1* mp3blaster-3.2.6/mpegsound/0000755000112600011260000000000013106424300012563 500000000000000mp3blaster-3.2.6/mpegsound/mpegsound.h0000644000112600011260000007203413106424065014673 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Woo-jae Jung */ // Mpegsound.h // This is typeset for functions in MPEG/WAVE Sound library. // Nasplayer class added by Willem (willem@stack.nl), thanks! /************************************/ /* Inlcude default library packages */ /************************************/ #include #include #include #ifdef LIBPTH # include #elif defined(PTHREADEDMPEG) # include #endif #ifndef _L__SOUND__ #define _L__SOUND__ /* Not all OSS implementations define an endian-independant samplesize. * This code is taken from linux' // Playing raw audio over a Network Audio System // By Willem (willem@stack.nl) class NASplayer : public Soundplayer { public: ~NASplayer(); static NASplayer *opendevice(const char *device); void abort(void); bool setsoundtype(int stereo, int samplesize, int speed); void set8bitmode() { want8bit = 1; } bool resetsoundtype(void); void releasedevice(void) {} bool attachdevice(void) { return true; } bool putblock(void *buffer, int size); int putblock_nt(void *buffer, int size); int getblocksize(void); int setvolume(int volume); AuBool event_handler(AuEvent *ev); private: NASplayer(AuServer *aud); AuServer *aud; AuFlowID flow; AuDeviceID dev; AuEventHandlerRec *evhnd; unsigned char format; int samplerate, channels; int want8bit; int buffer_ms; int req_size; }; #endif /*\ WANT_NAS \*/ /*********************************/ /* Data format converter classes */ /*********************************/ // Class for converting wave format to raw format class Wavetoraw { public: Wavetoraw(Soundinputstream *loader,Soundplayer *player); ~Wavetoraw(); bool initialize(void); void setforcetomono(short flag){forcetomonoflag=flag;}; bool run(void); int getfrequency(void) const {return speed;}; bool isstereo(void) const {return stereo;}; int getsamplesize(void) const {return samplesize;}; int geterrorcode(void) const {return __errorcode;}; int gettotallength(void) const {return size/pcmsize;}; int getcurrentpoint(void) const {return currentpoint/pcmsize;}; void setcurrentpoint(int p); private: int __errorcode; bool seterrorcode(int errorcode) {__errorcode=errorcode; return false; }; short forcetomonoflag; Soundinputstream *loader; Soundplayer *player; bool initialized; char *buffer; int buffersize; int samplesize,speed,stereo; int currentpoint,size; int pcmsize; bool testwave(char *buffer); }; // Class for Mpeg layer3 class Mpegbitwindow { public: Mpegbitwindow(){bitindex=point=0;}; void initialize(void) {bitindex=point=0;}; int gettotalbit(void) const {return bitindex;}; void putbyte(int c) {buffer[point&(WINDOWSIZE-1)]=c;point++;}; void wrap(void); void rewind(int bits) {bitindex-=bits;}; void forward(int bits) {bitindex+=bits;}; int getbit(void); int getbits9(int bits); int getbits(int bits); private: int point,bitindex; char buffer[2*WINDOWSIZE]; }; // Class for converting mpeg format to raw format class Mpegtoraw { /*****************************/ /* Constant tables for layer */ /*****************************/ private: static const int bitrate[2][3][15],frequencies[2][3]; static const REAL scalefactorstable[64]; static const HUFFMANCODETABLE ht[HTN]; static const REAL filter[512]; static REAL hcos_64[16],hcos_32[8],hcos_16[4],hcos_8[2],hcos_4; /*************************/ /* MPEG header variables */ /*************************/ private: int layer,protection,bitrateindex,padding,extendedmode, is_vbr; int first_layer; enum _mpegversion {mpeg1,mpeg2} version; enum _mode {fullstereo,joint,dual,single} mode; enum _frequency {frequency44100,frequency48000,frequency32000} frequency; /*************************/ /* Initialization vars */ /*************************/ struct mpeg_header { int layer; int protection; int bitrateindex; int padding; int extendedmode; _mpegversion version; _mode mode; _frequency frequency; } header_one; /*******************************************/ /* Functions getting MPEG header variables */ /*******************************************/ public: // General int getversion(void) const {return version;}; int getlayer(void) const {return layer;}; bool getcrccheck(void) const {return (!protection);}; // Stereo or not int getmode(void) const {return mode;}; const char *getmodestring(void) const { return (mode == fullstereo ? "Stereo" : (mode == joint ? "JointStereo" : (mode == dual ? "DualChannel" : "Mono"))); }; bool isstereo(void) const {return (getmode()!=single);}; // Frequency and bitrate int getfrequency(void) const {return frequencies[version][frequency];}; int getbitrate(void) const {return bitrate[version][layer-1][bitrateindex];}; /***************************************/ /* Interface for setting music quality */ /***************************************/ private: short forcetomonoflag; int downfrequency; public: void setforcetomono(short flag); void set8bitmode() { if(player) player->set8bitmode(); } void setdownfrequency(int value); /******************************************/ /* Functions getting other MPEG variables */ /******************************************/ public: short getforcetomono(void); int getdownfrequency(void); int getpcmperframe(void); /******************************/ /* Frame management variables */ /******************************/ private: int currentframe,totalframe; int decodeframe; int *frameoffsets; /******************************/ /* Frame management functions */ /******************************/ public: int getcurrentframe(void) const {return currentframe;}; int gettotalframe(void) const {return totalframe;}; void setframe(int framenumber); #ifdef NEWTHREAD int skip; unsigned char *sound_buf; void continueplaying(void); void createplayer(void); void abortplayer(void); void pauseplaying(void); private: void setdecodeframe(int framenumber); /*******************************/ /* Buffer management functions */ /*******************************/ private: void settotalbuffers(short amount); short request_buffer(void); void release_buffer(short index); void queue_buf(short index); void dequeue_buf(short index); void dequeue_first(); struct mpeg_buffer *get_buffer(short index); void makeroom(int size); public: void real_alarm_handler(int bla); int getfreebuffers(void); /*******************************/ /* Buffer management variables */ /*******************************/ private: FILE *debugfile; short no_buffers; short free_buffers; mpeg_buffer *buffers; buffer_node *queue; buffer_node *spare; #endif /***************************************/ /* Variables made by MPEG-Audio header */ /***************************************/ private: int tableindex,channelbitrate; int stereobound,subbandnumber,inputstereo,outputstereo; REAL scalefactor; int framesize; /********************/ /* Song information */ /********************/ private: struct { char name [30+1]; char artist [30+1]; char album [30+1]; char year [ 4+1]; char comment[30+1]; unsigned char genre; }songinfo; int totaltime; /* Song information functions */ public: const char *getname (void) const { return (const char *)songinfo.name; }; const char *getartist (void) const { return (const char *)songinfo.artist; }; const char *getalbum (void) const { return (const char *)songinfo.album; }; const char *getyear (void) const { return (const char *)songinfo.year; }; const char *getcomment (void) const { return (const char *)songinfo.comment;}; unsigned char getgenre (void) { return songinfo.genre; }; int gettotaltime() { return totaltime; } /*******************/ /* Mpegtoraw class */ /*******************/ public: Mpegtoraw(Soundinputstream *loader,Soundplayer *player); ~Mpegtoraw(); bool initialize(const char *filename); bool run(int frames); int geterrorcode(void) {return __errorcode;}; void clearbuffer(void); private: int __errorcode; bool seterrorcode(int errorno){__errorcode=errorno;return false;}; /*****************************/ /* Loading MPEG-Audio stream */ /*****************************/ public: void set_time_scan(short scan) { scan_mp3 = (scan ? 1 : 0); } private: Soundinputstream *loader; // Interface union { unsigned char store[4]; unsigned int current; }u; char buffer[4096]; int bitindex; short scan_mp3; //default = 1 => don't scan mp3 to calculate length in sec. bool fillbuffer(int size){bitindex=0;return loader->_readbuffer(buffer,size);}; void sync(void) {bitindex=(bitindex+7)&0xFFFFFFF8;}; bool issync(void){return (bitindex&7);}; int getbyte(void); int getbits(int bits); int getbits9(int bits); int getbits8(void); int getbit(void); /********************/ /* Global variables */ /********************/ private: int lastfrequency,laststereo; int suppress_sound; // for Layer3 int layer3slots,layer3framestart,layer3part2start; REAL prevblck[2][2][SBLIMIT][SSLIMIT]; int currentprevblock; layer3sideinfo sideinfo; layer3scalefactor scalefactors[2]; Mpegbitwindow bitwindow; int wgetbit(void); int wgetbits9(int bits); int wgetbits(int bits); /*************************************/ /* Decoding functions for each layer */ /*************************************/ private: bool loadheader(bool lookahead=true); // // Subbandsynthesis // REAL calcbufferL[2][CALCBUFFERSIZE],calcbufferR[2][CALCBUFFERSIZE]; int currentcalcbuffer,calcbufferoffset; void computebuffer(REAL *fraction,REAL buffer[2][CALCBUFFERSIZE]); void generatesingle(void); void generate(void); void subbandsynthesis(REAL *fractionL,REAL *fractionR); void computebuffer_2(REAL *fraction,REAL buffer[2][CALCBUFFERSIZE]); void generatesingle_2(void); void generate_2(void); void subbandsynthesis_2(REAL *fractionL,REAL *fractionR); // Extarctor void extractlayer1(void); // MPEG-1 void extractlayer2(void); void extractlayer3(void); void extractlayer3_2(void); // MPEG-2 // Functions for layer 3 void layer3initialize(void); bool layer3getsideinfo(void); bool layer3getsideinfo_2(void); void layer3getscalefactors(int ch,int gr); void layer3getscalefactors_2(int ch); void layer3huffmandecode(int ch,int gr,int out[SBLIMIT][SSLIMIT]); REAL layer3twopow2(int scale,int preflag,int pretab_offset,int l); REAL layer3twopow2_1(int a,int b,int c); void layer3dequantizesample(int ch,int gr,int in[SBLIMIT][SSLIMIT], REAL out[SBLIMIT][SSLIMIT]); void layer3fixtostereo(int gr,REAL in[2][SBLIMIT][SSLIMIT]); void layer3reorderandantialias(int ch,int gr,REAL in[SBLIMIT][SSLIMIT], REAL out[SBLIMIT][SSLIMIT]); void layer3hybrid(int ch,int gr,REAL in[SBLIMIT][SSLIMIT], REAL out[SSLIMIT][SBLIMIT]); void huffmandecoder_1(const HUFFMANCODETABLE *h,int *x,int *y); void huffmandecoder_2(const HUFFMANCODETABLE *h,int *x,int *y,int *v,int *w); /********************/ /* Playing raw data */ /********************/ private: Soundplayer *player; // General playing interface int rawdataoffset; short int rawdata[RAWDATASIZE]; void clearrawdata(void) {rawdataoffset=0;}; void putraw(short int pcm) {rawdata[rawdataoffset++]=pcm;}; #ifdef NEWTHREAD void flushrawdata(short index=0); #else void flushrawdata(void); #endif /***************************/ /* Interface for threading */ /***************************/ #ifdef NEWTHREAD public: pth_t play_thread; bool player_run; void threadplay(void *bla); #elif defined(PTHREADEDMPEG) private: struct { short int *buffer; int framenumber,frametail; int head,tail; int *sizes; }threadqueue; struct { bool thread; bool quit,done; bool pause; bool criticallock,criticalflag; }threadflags; pthread_t thread; public: void threadedplayer(void); bool makethreadedplayer(int framenumbers); void freethreadedplayer(void); void stopthreadedplayer(void); void pausethreadedplayer(void); void unpausethreadedplayer(void); bool existthread(void); int getframesaved(void); #endif /* NEWTHREAD */ }; /***********************/ /* File player classes */ /***********************/ // Superclass for playing file class Fileplayer { public: enum audiodriver_t { AUDIODRV_OSS, AUDIODRV_ESD, AUDIODRV_SDL, AUDIODRV_NAS }; virtual ~Fileplayer(); //anyone may destruct a FilePlayer object directly int geterrorcode(void) {return __errorcode;}; struct song_info getsonginfo() { return info;}; virtual bool openfile(const char *filename, const char *device, soundtype write2file=ST_NONE)=0; virtual void closefile(void) =0; virtual void setforcetomono(short flag) =0; virtual void setdownfrequency(int) =0; virtual void set8bitmode() =0; virtual bool playing() =0; virtual bool run(int) =0; virtual void skip(int) =0; virtual bool initialize(void *) =0; //if argument to forward < 0, will skip to end - virtual bool forward(int) =0; virtual bool rewind(int) =0; virtual bool pause() =0; virtual bool unpause() =0; virtual bool stop() =0; virtual bool ready() =0; virtual int elapsed_time() =0; virtual int remaining_time() =0; protected: Fileplayer(); //thou shallt not instantiate fileplayer itself. bool opendevice(const char *device, soundtype write2file=ST_NONE); void set_driver(audiodriver_t driver); bool seterrorcode(int errorno){__errorcode=errorno;return false;}; Soundplayer *player; struct song_info info; const char *filename; private: int __errorcode; audiodriver_t audiodriver; }; struct init_opts { char option[30]; void *value; struct init_opts *next; }; // Class for playing wave file class Wavefileplayer : public Fileplayer { public: Wavefileplayer(audiodriver_t driver); ~Wavefileplayer(); bool openfile(const char *filename, const char *device, soundtype write2file=ST_NONE); void closefile(void); void setforcetomono(short flag); void setdownfrequency(int value) { if (value); } void set8bitmode() { if(player) player->set8bitmode(); } bool playing(); bool run(int); bool initialize(void *); bool forward(int frames) { skip(frames); return true; } bool rewind(int frames) { skip(-frames); return true; } bool pause() { player->releasedevice(); return true; } bool ready() { return player->attachdevice(); } bool unpause() { return true; } bool stop() { return true; } int elapsed_time(); int remaining_time(); void skip(int); private: Soundinputstream *loader; protected: Wavetoraw *server; }; // Class for playing MPEG file class Mpegfileplayer : public Fileplayer { public: Mpegfileplayer(audiodriver_t driver); ~Mpegfileplayer(); bool openfile(const char *filename, const char *device, soundtype write2file=ST_NONE); void closefile(void); void setforcetomono(short flag); void set8bitmode() { if (server) server->set8bitmode(); } void setdownfrequency(int value); bool playing(); bool run(int); void skip(int); bool initialize(void *); bool forward(int); bool rewind(int); #ifdef NEWTHREAD bool pause() { server->pauseplaying(); player->releasedevice(); return true; } bool unpause() { server->continueplaying(); return player->attachdevice(); } #elif defined(PTHREADEDMPEG) bool pause() { if (use_threads) server->pausethreadedplayer(); player->releasedevice(); return true;} bool unpause() { if (use_threads) server->unpausethreadedplayer(); return player->attachdevice();} #else bool pause() { player->releasedevice(); return true;} bool unpause() { return player->attachdevice(); } #endif bool stop(); bool ready(); int elapsed_time(); int remaining_time(); #ifndef NEWTHREAD #if PTHREADEDMPEG bool playingwiththread(int framenumbers); #endif #endif /* NEWTHREAD */ private: Soundinputstream *loader; short use_threads; protected: Mpegtoraw *server; }; #ifdef INCLUDE_OGG #include "vorbis/vorbisfile.h" class Oggplayer : public Fileplayer { public: Oggplayer(audiodriver_t driver); ~Oggplayer(); bool openfile(const char *filename, const char *device, soundtype write2file=ST_NONE); void closefile(void); void setforcetomono(short flag); void set8bitmode(); void setdownfrequency(int value); bool playing(); bool run(int); void skip(int); bool initialize(void *); bool forward(int); bool rewind(int); bool pause(); bool unpause(); bool stop(); bool ready(); int elapsed_time(); int remaining_time(); private: short wordsize; short mono; short downfreq; short bigendian; short signeddata; int channels; long srate; short resetsound; protected: OggVorbis_File *of; char soundbuf[4096]; }; #endif /* INCLUDE_OGG */ #ifdef HAVE_SIDPLAYER //This is broken due to lack of functions #include #include #include class SIDfileplayer : public Fileplayer { public: SIDfileplayer(audiodriver_t driver); ~SIDfileplayer(); bool openfile(const char *filename, const char *device, soundtype write2file=ST_NONE); bool initialize(void *data) { if(data); return true; } void closefile(void); void setforcetomono(short flag); void setdownfrequency(int value); void set8bitmode() {} bool run(int frames); bool playing(); bool ready() { return true; } void skip(int) {} //TODO: implement int elapsed_time() { return 0; } //TODO: implement int remaining_time() { return 0; } bool forward(int sec) { skip(sec); return true; } bool rewind(int sec) { skip(-sec); return true; } bool pause() { return true; } bool unpause() { return true; } bool stop() { return true; } protected: emuEngine emu; struct emuConfig emuConf; sidTune *tune; struct sidTuneInfo sidInfo; int song; private: char *buffer; int bufSize; }; #endif /*\ HAVE_SIDPLAYER \*/ #endif mp3blaster-3.2.6/mpegsound/mpeglayer1.cc0000664000112600011260000000572712426044701015104 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Mpeglayer1.cc // It's for MPEG Layer 1 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mpegsound.h" // Tables for layer 1 static const REAL factortable[15] = { 0.0, (1.0/2.0) * (4.0/3.0), (1.0/4.0) * (8.0/7.0), (1.0/8.0) * (16.0/15.0), (1.0/16.0) * (32.0/31.0), (1.0/32.0) * (64.0/63.0), (1.0/64.0) * (128.0/127.0), (1.0/128.0) * (256.0/255.0), (1.0/256.0) * (512.0/511.0), (1.0/512.0) * (1024.0/1023.0), (1.0/1024.0) * (2048.0/2047.0), (1.0/2048.0) * (4096.0/4095.0), (1.0/4096.0) * (8192.0/8191.0), (1.0/8192.0) * (16384.0/16383.0), (1.0/16384.0) * (32768.0/32767.0) }; static const REAL offsettable[15] = { 0.0, ((1.0/2.0)-1.0) * (4.0/3.0), ((1.0/4.0)-1.0) * (8.0/7.0), ((1.0/8.0)-1.0) * (16.0/15.0), ((1.0/16.0)-1.0) * (32.0/31.0), ((1.0/32.0)-1.0) * (64.0/63.0), ((1.0/64.0)-1.0) * (128.0/127.0), ((1.0/128.0)-1.0) * (256.0/255.0), ((1.0/256.0)-1.0) * (512.0/511.0), ((1.0/512.0)-1.0) * (1024.0/1023.0), ((1.0/1024.0)-1.0) * (2048.0/2047.0), ((1.0/2048.0)-1.0) * (4096.0/4095.0), ((1.0/4096.0)-1.0) * (8192.0/8191.0), ((1.0/8192.0)-1.0) * (16384.0/16383.0), ((1.0/16384.0)-1.0) * (32768.0/32767.0) }; // Mpeg layer 1 void Mpegtoraw::extractlayer1(void) { REAL fraction[MAXCHANNEL][MAXSUBBAND]; REAL scalefactor[MAXCHANNEL][MAXSUBBAND]; int bitalloc[MAXCHANNEL][MAXSUBBAND], sample[MAXCHANNEL][MAXSUBBAND]; register int i,j; int s=stereobound,l; // Bitalloc for(i=0;i #include #include "mpegsound.h" #include "mpegsound_locals.h" inline void Mpegbitwindow::wrap(void) { int p=bitindex>>3; point&=(WINDOWSIZE-1); if(p>=point) { for(register int i=4;i>3)&(WINDOWSIZE-1)]>>(7-(bitindex&7)))&1; register int r=(buffer[bitindex>>3]>>(7-(bitindex&7)))&1; bitindex++; return r; }; inline int Mpegbitwindow::getbits9(int bits) { register unsigned short a; int offset=bitindex>>3; a=(((unsigned char)buffer[offset])<<8) | ((unsigned char)buffer[offset+1]); a<<=(bitindex&7); bitindex+=bits; return (int)((unsigned int)(a>>(16-bits))); } inline int Mpegtoraw::wgetbit (void) {return bitwindow.getbit (); } inline int Mpegtoraw::wgetbits9(int bits){return bitwindow.getbits9(bits);} inline int Mpegtoraw::wgetbits (int bits){return bitwindow.getbits (bits);} #define MUL3(a) (((a)<<1)+(a)) #define REAL0 0 #define ARRAYSIZE (SBLIMIT*SSLIMIT) #define REALSIZE (sizeof(REAL)) #ifdef PI #undef PI #endif #define PI 3.141593 #define PI_12 (PI/12.0) #define PI_18 (PI/18.0) #define PI_24 (PI/24.0) #define PI_36 (PI/36.0) #define PI_72 (PI/72.0) #ifdef NATIVE_ASSEMBLY inline void long_memset(void * s,unsigned int c,int count) { __asm__ __volatile__( "cld\n\t" "rep ; stosl\n\t" : /* no output */ :"a" (c), "c" (count/4), "D" ((long) s) :"cx","di","memory"); } #endif #define FOURTHIRDSTABLENUMBER (1<<13) static REAL two_to_negative_half_pow[40]; static REAL TO_FOUR_THIRDSTABLE[FOURTHIRDSTABLENUMBER*2]; static REAL POW2[256]; static REAL POW2_1[8][2][16]; static REAL ca[8],cs[8]; static REAL cos1_6=cos(PI/6.0*1.0); static REAL cos2_6=cos(PI/6.0*2.0); static REAL win[4][36]; static REAL cos_18[9]; static REAL hsec_36[9],hsec_12[3]; typedef struct { REAL l,r; }RATIOS; static RATIOS rat_1[16],rat_2[2][64]; void Mpegtoraw::layer3initialize(void) { static bool initializedlayer3=false; layer3framestart=0; currentprevblock=0; { int i,j,k,l; for(l=0;l<2;l++) for(i=0;i<2;i++) for(j=0;jpart2_3_length =getbits(12); gi->big_values =getbits(9); gi->global_gain =getbits(8); gi->scalefac_compress =getbits(4); gi->window_switching_flag=getbit(); if(gi->window_switching_flag) { gi->block_type =getbits(2); gi->mixed_block_flag=getbit(); gi->table_select[0] =getbits(5); gi->table_select[1] =getbits(5); gi->subblock_gain[0]=getbits(3); gi->subblock_gain[1]=getbits(3); gi->subblock_gain[2]=getbits(3); /* Set region_count parameters since they are implicit in this case. */ if(gi->block_type==0) { /* printf("Side info bad: block_type == 0 in split block.\n"); exit(0); */ return false; } else if (gi->block_type==2 && gi->mixed_block_flag==0) gi->region0_count=8; /* MI 9; */ else gi->region0_count=7; /* MI 8; */ gi->region1_count=20-(gi->region0_count); } else { gi->table_select[0] =getbits(5); gi->table_select[1] =getbits(5); gi->table_select[2] =getbits(5); gi->region0_count =getbits(4); gi->region1_count =getbits(3); gi->block_type =0; } gi->preflag =getbit(); gi->scalefac_scale =getbit(); gi->count1table_select=getbit(); gi->generalflag=gi->window_switching_flag && (gi->block_type==2); if(!inputstereo || ch)break; } return true; } bool Mpegtoraw::layer3getsideinfo_2(void) { sideinfo.main_data_begin=getbits(8); if(!inputstereo)sideinfo.private_bits=getbit(); else sideinfo.private_bits=getbits(2); for(int ch=0;;ch++) { layer3grinfo *gi=&(sideinfo.ch[ch].gr[0]); gi->part2_3_length =getbits(12); gi->big_values =getbits(9); gi->global_gain =getbits(8); gi->scalefac_compress =getbits(9); gi->window_switching_flag=getbit(); if(gi->window_switching_flag) { gi->block_type =getbits(2); gi->mixed_block_flag=getbit(); gi->table_select[0] =getbits(5); gi->table_select[1] =getbits(5); gi->subblock_gain[0]=getbits(3); gi->subblock_gain[1]=getbits(3); gi->subblock_gain[2]=getbits(3); /* Set region_count parameters since they are implicit in this case. */ if(gi->block_type==0) { /* printf("Side info bad: block_type == 0 in split block.\n"); exit(0); */ return false; } else if (gi->block_type==2 && gi->mixed_block_flag==0) gi->region0_count=8; /* MI 9; */ else gi->region0_count=7; /* MI 8; */ gi->region1_count=20-(gi->region0_count); } else { gi->table_select[0] =getbits(5); gi->table_select[1] =getbits(5); gi->table_select[2] =getbits(5); gi->region0_count =getbits(4); gi->region1_count =getbits(3); gi->block_type =0; } gi->scalefac_scale =getbit(); gi->count1table_select=getbit(); gi->generalflag=gi->window_switching_flag && (gi->block_type==2); if(!inputstereo || ch)break; } return true; } void Mpegtoraw::layer3getscalefactors(int ch,int gr) { static int 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}}; layer3grinfo *gi=&(sideinfo.ch[ch].gr[gr]); register layer3scalefactor *sf=(&scalefactors[ch]); int l0,l1; { int scale_comp=gi->scalefac_compress; l0=slen[0][scale_comp]; l1=slen[1][scale_comp]; } if(gi->generalflag) { if(gi->mixed_block_flag) { /* MIXED */ /* NEW-ag 11/25 */ sf->l[0]=wgetbits9(l0);sf->l[1]=wgetbits9(l0); sf->l[2]=wgetbits9(l0);sf->l[3]=wgetbits9(l0); sf->l[4]=wgetbits9(l0);sf->l[5]=wgetbits9(l0); sf->l[6]=wgetbits9(l0);sf->l[7]=wgetbits9(l0); sf->s[0][ 3]=wgetbits9(l0);sf->s[1][ 3]=wgetbits9(l0); sf->s[2][ 3]=wgetbits9(l0); sf->s[0][ 4]=wgetbits9(l0);sf->s[1][ 4]=wgetbits9(l0); sf->s[2][ 4]=wgetbits9(l0); sf->s[0][ 5]=wgetbits9(l0);sf->s[1][ 5]=wgetbits9(l0); sf->s[2][ 5]=wgetbits9(l0); sf->s[0][ 6]=wgetbits9(l1);sf->s[1][ 6]=wgetbits9(l1); sf->s[2][ 6]=wgetbits9(l1); sf->s[0][ 7]=wgetbits9(l1);sf->s[1][ 7]=wgetbits9(l1); sf->s[2][ 7]=wgetbits9(l1); sf->s[0][ 8]=wgetbits9(l1);sf->s[1][ 8]=wgetbits9(l1); sf->s[2][ 8]=wgetbits9(l1); sf->s[0][ 9]=wgetbits9(l1);sf->s[1][ 9]=wgetbits9(l1); sf->s[2][ 9]=wgetbits9(l1); sf->s[0][10]=wgetbits9(l1);sf->s[1][10]=wgetbits9(l1); sf->s[2][10]=wgetbits9(l1); sf->s[0][11]=wgetbits9(l1);sf->s[1][11]=wgetbits9(l1); sf->s[2][11]=wgetbits9(l1); sf->s[0][12]=sf->s[1][12]=sf->s[2][12]=0; } else { /* SHORT*/ sf->s[0][ 0]=wgetbits9(l0);sf->s[1][ 0]=wgetbits9(l0); sf->s[2][ 0]=wgetbits9(l0); sf->s[0][ 1]=wgetbits9(l0);sf->s[1][ 1]=wgetbits9(l0); sf->s[2][ 1]=wgetbits9(l0); sf->s[0][ 2]=wgetbits9(l0);sf->s[1][ 2]=wgetbits9(l0); sf->s[2][ 2]=wgetbits9(l0); sf->s[0][ 3]=wgetbits9(l0);sf->s[1][ 3]=wgetbits9(l0); sf->s[2][ 3]=wgetbits9(l0); sf->s[0][ 4]=wgetbits9(l0);sf->s[1][ 4]=wgetbits9(l0); sf->s[2][ 4]=wgetbits9(l0); sf->s[0][ 5]=wgetbits9(l0);sf->s[1][ 5]=wgetbits9(l0); sf->s[2][ 5]=wgetbits9(l0); sf->s[0][ 6]=wgetbits9(l1);sf->s[1][ 6]=wgetbits9(l1); sf->s[2][ 6]=wgetbits9(l1); sf->s[0][ 7]=wgetbits9(l1);sf->s[1][ 7]=wgetbits9(l1); sf->s[2][ 7]=wgetbits9(l1); sf->s[0][ 8]=wgetbits9(l1);sf->s[1][ 8]=wgetbits9(l1); sf->s[2][ 8]=wgetbits9(l1); sf->s[0][ 9]=wgetbits9(l1);sf->s[1][ 9]=wgetbits9(l1); sf->s[2][ 9]=wgetbits9(l1); sf->s[0][10]=wgetbits9(l1);sf->s[1][10]=wgetbits9(l1); sf->s[2][10]=wgetbits9(l1); sf->s[0][11]=wgetbits9(l1);sf->s[1][11]=wgetbits9(l1); sf->s[2][11]=wgetbits9(l1); sf->s[0][12]=sf->s[1][12]=sf->s[2][12]=0; } } else { /* LONG types 0,1,3 */ if(gr==0) { sf->l[ 0]=wgetbits9(l0);sf->l[ 1]=wgetbits9(l0); sf->l[ 2]=wgetbits9(l0);sf->l[ 3]=wgetbits9(l0); sf->l[ 4]=wgetbits9(l0);sf->l[ 5]=wgetbits9(l0); sf->l[ 6]=wgetbits9(l0);sf->l[ 7]=wgetbits9(l0); sf->l[ 8]=wgetbits9(l0);sf->l[ 9]=wgetbits9(l0); sf->l[10]=wgetbits9(l0); sf->l[11]=wgetbits9(l1);sf->l[12]=wgetbits9(l1); sf->l[13]=wgetbits9(l1);sf->l[14]=wgetbits9(l1); sf->l[15]=wgetbits9(l1); sf->l[16]=wgetbits9(l1);sf->l[17]=wgetbits9(l1); sf->l[18]=wgetbits9(l1);sf->l[19]=wgetbits9(l1); sf->l[20]=wgetbits9(l1); } else { if(sideinfo.ch[ch].scfsi[0]==0) { sf->l[ 0]=wgetbits9(l0);sf->l[ 1]=wgetbits9(l0); sf->l[ 2]=wgetbits9(l0);sf->l[ 3]=wgetbits9(l0); sf->l[ 4]=wgetbits9(l0);sf->l[ 5]=wgetbits9(l0); } if(sideinfo.ch[ch].scfsi[1]==0) { sf->l[ 6]=wgetbits9(l0);sf->l[ 7]=wgetbits9(l0); sf->l[ 8]=wgetbits9(l0);sf->l[ 9]=wgetbits9(l0); sf->l[10]=wgetbits9(l0); } if(sideinfo.ch[ch].scfsi[2]==0) { sf->l[11]=wgetbits9(l1);sf->l[12]=wgetbits9(l1); sf->l[13]=wgetbits9(l1);sf->l[14]=wgetbits9(l1); sf->l[15]=wgetbits9(l1); } if(sideinfo.ch[ch].scfsi[3]==0) { sf->l[16]=wgetbits9(l1);sf->l[17]=wgetbits9(l1); sf->l[18]=wgetbits9(l1);sf->l[19]=wgetbits9(l1); sf->l[20]=wgetbits9(l1); } } sf->l[21]=sf->l[22]=0; } } void Mpegtoraw::layer3getscalefactors_2(int ch) { static int sfbblockindex[6][3][4]= { {{ 6, 5, 5, 5},{ 9, 9, 9, 9},{ 6, 9, 9, 9}}, {{ 6, 5, 7, 3},{ 9, 9,12, 6},{ 6, 9,12, 6}}, {{11,10, 0, 0},{18,18, 0, 0},{15,18, 0, 0}}, {{ 7, 7, 7, 0},{12,12,12, 0},{ 6,15,12, 0}}, {{ 6, 6, 6, 3},{12, 9, 9, 6},{ 6,12, 9, 6}}, {{ 8, 8, 5, 0},{15,12, 9, 0},{ 6,18, 9, 0}} }; int sb[54]; layer3grinfo *gi=&(sideinfo.ch[ch].gr[0]); register layer3scalefactor *sf=(&scalefactors[ch]); { int blocktypenumber,sc; int blocknumber; int slen[4]; if(gi->block_type==2)blocktypenumber=1+gi->mixed_block_flag; else blocktypenumber=0; sc=gi->scalefac_compress; if(!((extendedmode==1 || extendedmode==3) && (ch==1))) { if(sc<400) { slen[0]=(sc>>4)/5; slen[1]=(sc>>4)%5; slen[2]=(sc%16)>>2; slen[3]=(sc%4); gi->preflag=0; blocknumber=0; } else if(sc<500) { sc-=400; slen[0]=(sc>>2)/5; slen[1]=(sc>>2)%5; slen[2]=sc%4; slen[3]=0; gi->preflag=0; blocknumber=1; } else // if(sc<512) { sc-=500; slen[0]=sc/3; slen[1]=sc%3; slen[2]=0; slen[3]=0; gi->preflag=1; blocknumber=2; } } else { sc>>=1; if(sc<180) { slen[0]=sc/36; slen[1]=(sc%36)/6; slen[2]=(sc%36)%6; slen[3]=0; gi->preflag=0; blocknumber=3; } else if(sc<244) { sc-=180; slen[0]=(sc%64)>>4; slen[1]=(sc%16)>>2; slen[2]=sc%4; slen[3]=0; gi->preflag=0; blocknumber=4; } else // if(sc<255) { sc-=244; slen[0]=sc/3; slen[1]=sc%3; slen[2]= slen[3]=0; gi->preflag=0; blocknumber=5; } } { int i,j,k,*si; si=sfbblockindex[blocknumber][blocktypenumber]; for(i=0;i<45;i++)sb[i]=0; for(k=i=0;i<4;i++) for(j=0;jwindow_switching_flag && (gi->block_type==2)) { if(gi->mixed_block_flag) { for(sfb=0;sfb<8;sfb++)sf->l[sfb]=sb[k++]; sfb=3; } else sfb=0; for(;sfb<12;sfb++) for(window=0;window<3;window++) sf->s[window][sfb]=sb[k++]; sf->s[0][12]=sf->s[1][12]=sf->s[2][12]=0; } else { for(sfb=0;sfb<21;sfb++) sf->l[sfb]=sb[k++]; sf->l[21]=sf->l[22]=0; } } } typedef unsigned int HUFFBITS; #define MXOFF 250 /* do the huffman-decoding */ /* note! for counta,countb -the 4 bit value is returned in y, discard x */ // Huffman decoder for tablename<32 inline void Mpegtoraw::huffmandecoder_1(const HUFFMANCODETABLE *h,int *x,int *y) { HUFFBITS level=(1<<(sizeof(HUFFBITS)*8-1)); int point=0; /* Lookup in Huffman table. */ for(;;) { if(h->val[point][0]==0) { /*end of tree*/ int xx,yy; xx=h->val[point][1]>>4; yy=h->val[point][1]&0xf; if(h->linbits) { if((h->xlen)==(unsigned)xx)xx+=wgetbits(h->linbits); if(xx)if(wgetbit())xx=-xx; if((h->ylen)==(unsigned)yy)yy+=wgetbits(h->linbits); if(yy)if(wgetbit())yy=-yy; } else { if(xx)if(wgetbit())xx=-xx; if(yy)if(wgetbit())yy=-yy; } *x=xx;*y=yy; break; } point+=h->val[point][wgetbit()]; level>>=1; if(!(level || ((unsigned)pointtreelen))) { register int xx,yy; xx=(h->xlen<<1);// set x and y to a medium value as a simple concealment yy=(h->ylen<<1); // h->xlen and h->ylen can't be 1 under tablename 32 // if(xx) if(wgetbit())xx=-xx; // if(yy) if(wgetbit())yy=-yy; *x=xx;*y=yy; break; } } } // Huffman decoder tablenumber>=32 inline void Mpegtoraw::huffmandecoder_2(const HUFFMANCODETABLE *h, int *x,int *y,int *v,int *w) { HUFFBITS level=(1<<(sizeof(HUFFBITS)*8-1)); int point=0; /* Lookup in Huffman table. */ for(;;) { if(h->val[point][0]==0) { /*end of tree*/ register int t=h->val[point][1]; if(t&8)*v=1-(wgetbit()<<1); else *v=0; if(t&4)*w=1-(wgetbit()<<1); else *w=0; if(t&2)*x=1-(wgetbit()<<1); else *x=0; if(t&1)*y=1-(wgetbit()<<1); else *y=0; break; } point+=h->val[point][wgetbit()]; level>>=1; if(!(level || ((unsigned)pointtreelen))) { *v=1-(wgetbit()<<1); *w=1-(wgetbit()<<1); *x=1-(wgetbit()<<1); *y=1-(wgetbit()<<1); break; } } } typedef struct { int l[23]; int s[14]; }SFBANDINDEX; static SFBANDINDEX sfBandIndextable[2][3]= { // MPEG 1 {{{0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576}, {0,4,8,12,16,22,30,40,52,66,84,106,136,192}}, {{0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576}, {0,4,8,12,16,22,28,38,50,64,80,100,126,192}}, {{0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576}, {0,4,8,12,16,22,30,42,58,78,104,138,180,192}}}, // MPEG 2 {{{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, {0,4,8,12,18,24,32,42,56,74,100,132,174,192}}, {{0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576}, {0,4,8,12,18,26,36,48,62,80,104,136,180,192}}, {{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, {0,4,8,12,18,26,36,48,62,80,104,134,174,192}}} }; void Mpegtoraw::layer3huffmandecode(int ch,int gr,int out[SBLIMIT][SSLIMIT]) { layer3grinfo *gi=&(sideinfo.ch[ch].gr[gr]); int part2_3_end=layer3part2start+(gi->part2_3_length); int region1Start,region2Start; int i,e=gi->big_values<<1; /* Find region boundary for short block case. */ if(gi->generalflag) { /* Region2. */ region1Start=36; /* sfb[9/3]*3=36 */ region2Start=576;/* No Region2 for short block case. */ } else { /* Find region boundary for long block case. */ region1Start=sfBandIndextable[version][frequency].l[gi->region0_count+1]; region2Start=sfBandIndextable[version][frequency].l[gi->region0_count+ gi->region1_count+2]; } /* Read bigvalues area. */ for(i=0;itable_select[0]]; if(region1Start>e)end=e; else end=region1Start; } else if(itable_select[1]]; if(region2Start>e)end=e; else end=region2Start; } else { h=&ht[gi->table_select[2]]; end=e; } if(h->treelen) while(icount1table_select+32]; while(bitwindow.gettotalbit()=ARRAYSIZE) { bitwindow.rewind(bitwindow.gettotalbit()-part2_3_end); return; } } for(;iglobal_gain]; REAL *TO_FOUR_THIRDS=TO_FOUR_THIRDSTABLE+FOURTHIRDSTABLENUMBER; /* choose correct scalefactor band per block type, initalize boundary */ /* and apply formula per block type */ if(!gi->generalflag) { /* LONG blocks: 0,1,3 */ int next_cb_boundary; int cb=-1,index=0; REAL factor; do { next_cb_boundary=sfBandIndex->l[(++cb)+1]; factor=globalgain* layer3twopow2(gi->scalefac_scale,gi->preflag, pretab[cb],scalefactors[ch].l[cb]); for(;indexmixed_block_flag) { int cb=0,index=0; int cb_width; do { cb_width=(sfBandIndex->s[cb+1]-sfBandIndex->s[cb])>>1; for(register int k=0;k<3;k++) { register REAL factor; register int count=cb_width; factor=globalgain* layer3twopow2_1(gi->subblock_gain[k],gi->scalefac_scale, scalefactors[ch].s[k][cb]); do{ out[0][index]=factor*TO_FOUR_THIRDS[in[0][index]];index++; out[0][index]=factor*TO_FOUR_THIRDS[in[0][index]];index++; }while(--count); } cb++; }while(indexl[1]; /* LONG blocks: 0,1,3 */ int index; /* Compute overall (global) scaling. */ { for(int sb=0;sbl[8]) { next_cb_boundary=sfBandIndex->s[4]; next_cb_boundary=MUL3(next_cb_boundary); cb=3; cb_width=sfBandIndex->s[4]-sfBandIndex->s[3]; cb_begin=sfBandIndex->s[3]; cb_begin=MUL3(cb_begin); } else if(indexl[8]) next_cb_boundary=sfBandIndex->l[(++cb)+1]; else { next_cb_boundary=sfBandIndex->s[(++cb)+1]; next_cb_boundary=MUL3(next_cb_boundary); cb_begin=sfBandIndex->s[cb]; cb_width=sfBandIndex->s[cb+1]-cb_begin; cb_begin=MUL3(cb_begin); } } /* LONG block types 0,1,3 & 1st 2 subbands of switched blocks */ out[0][index]*=layer3twopow2(gi->scalefac_scale,gi->preflag, pretab[cb],scalefactors[ch].l[cb]); } for(;indexl[8]) { next_cb_boundary=sfBandIndex->s[4]; next_cb_boundary=MUL3(next_cb_boundary); cb=3; cb_width=sfBandIndex->s[4]-sfBandIndex->s[3]; cb_begin=sfBandIndex->s[3]; cb_begin=(cb_begin<<2)-cb_begin; } else if(indexl[8]) next_cb_boundary=sfBandIndex->l[(++cb)+1]; else { next_cb_boundary=sfBandIndex->s[(++cb)+1]; next_cb_boundary=MUL3(next_cb_boundary); cb_begin=sfBandIndex->s[cb]; cb_width=sfBandIndex->s[cb+1]-cb_begin; cb_begin=MUL3(cb_begin); } } { int t_index = 0; if (cb_width) { t_index=(index-cb_begin)/cb_width; if (t_index > 2) t_index = 0; } else { debug("Very bad mp3 data\n"); } out[0][index]*=layer3twopow2_1(gi->subblock_gain[t_index], gi->scalefac_scale, scalefactors[ch].s[t_index][cb]); } } } } inline void Mpegtoraw::layer3fixtostereo(int gr,REAL in[2][SBLIMIT][SSLIMIT]) { layer3grinfo *gi=&(sideinfo.ch[0].gr[gr]); SFBANDINDEX *sfBandIndex=&(sfBandIndextable[version][frequency]); int ms_stereo=(mode==joint) && (extendedmode & 0x2); int i_stereo =(mode==joint) && (extendedmode & 0x1); if(!inputstereo) { /* mono , bypass xr[0][][] to lr[0][][]*/ // memcpy(out[0][0],in[0][0],ARRAYSIZE*REALSIZE); return; } if(i_stereo) { int i; int is_pos[ARRAYSIZE]; RATIOS is_ratio[ARRAYSIZE]; RATIOS *ratios; if(version)ratios=rat_2[gi->scalefac_compress%2]; else ratios=rat_1; /* initialization */ for(i=0;igeneralflag) { if(gi->mixed_block_flag) // Part I { int max_sfb=0; for(int j=0;j<3;j++) { int sfb,sfbcnt=2; for(sfb=12;sfb>=3;sfb--) { int lines; i=sfBandIndex->s[sfb]; lines=sfBandIndex->s[sfb+1]-i; i=MUL3(i)+(j+1)*lines-1; for(;lines>0;lines--,i--) if(in[1][0][i]!=0.0f) { sfbcnt=sfb; sfb=0;break; // quit loop } } sfb=sfbcnt+1; if(sfb>max_sfb)max_sfb=sfb; for(;sfb<12;sfb++) { int k,t; t=sfBandIndex->s[sfb]; k=sfBandIndex->s[sfb+1]-t; i=MUL3(t)+j*k; t=scalefactors[1].s[j][sfb]; if(t!=7) { RATIOS r=ratios[t]; for(;k>0;k--,i++){ is_pos[i]=t;is_ratio[i]=r;} } else for(;k>0;k--,i++)is_pos[i]=t; } sfb=sfBandIndex->s[10]; sfb=MUL3(sfb)+j*(sfBandIndex->s[11]-sfb); { int k,t; t=sfBandIndex->s[11]; k=sfBandIndex->s[12]-t; i=MUL3(t)+j*k; t=is_pos[sfb]; if(t!=7) { RATIOS r=is_ratio[sfb]; for(;k>0;k--,i++){ is_pos[i]=t;is_ratio[i]=r;} } else for(;k>0;k--,i++)is_pos[i]=t; } } if(max_sfb<=3) { { REAL temp; int k; temp=in[1][0][0];in[1][0][0]=1.0; for(k=3*SSLIMIT-1;in[1][0][k]==0.0;k--); in[1][0][0]=temp; for(i=0;sfBandIndex->l[i]<=k;i++); } { int sfb=i; i=sfBandIndex->l[i]; for(;sfb<8;sfb++) { int t=scalefactors[1].l[sfb]; int k=sfBandIndex->l[sfb+1]-sfBandIndex->l[sfb]; if(t!=7) { RATIOS r=ratios[t]; for(;k>0;k--,i++){ is_pos[i]=t;is_ratio[i]=r;} } else for(;k>0;k--,i++)is_pos[i]=t; } } } } else // Part II { for(int j=0;j<3;j++) { int sfbcnt=-1; for(int sfb=12;sfb>=0;sfb--) { int lines; { int t; t=sfBandIndex->s[sfb]; lines=sfBandIndex->s[sfb+1]-t; i=MUL3(t)+(j+1)*lines-1; } for(;lines>0;lines--,i--) if(in[1][0][i]!=0.0f) { sfbcnt=sfb; sfb=0;break; // quit loop } } for(int sfb=sfbcnt+1;sfb<12;sfb++) { int k,t; t=sfBandIndex->s[sfb]; k=sfBandIndex->s[sfb+1]-t; i=MUL3(t)+j*k; t=scalefactors[1].s[j][sfb]; if(t!=7) { RATIOS r=ratios[t]; for(;k>0;k--,i++){ is_pos[i]=t;is_ratio[i]=r;} } else for(;k>0;k--,i++)is_pos[i]=t; } { int t1=sfBandIndex->s[10], t2=sfBandIndex->s[11]; int k,tt; tt=MUL3(t1)+j*(t2-t1); k =sfBandIndex->s[12]-t2; if(is_pos[tt]!=7) { RATIOS r=is_ratio[tt]; int t=is_pos[tt]; i =MUL3(t1)+j*k; for(;k>0;k--,i++){ is_pos[i]=t;is_ratio[i]=r;} } else for(;k>0;k--,i++)is_pos[i]=7; } } } } else // ms-stereo (Part III) { { REAL temp; int k; temp=in[1][0][0];in[1][0][0]=1.0; for(k=ARRAYSIZE-1;in[1][0][k]==0.0;k--); in[1][0][0]=temp; for(i=0;sfBandIndex->l[i]<=k;i++); } { int sfb; sfb=i; i=sfBandIndex->l[i]; for(;sfb<21;sfb++) { int k,t; k=sfBandIndex->l[sfb+1]-sfBandIndex->l[sfb]; t=scalefactors[1].l[sfb]; if(t!=7) { RATIOS r=ratios[t]; for(;k>0;k--,i++){ is_pos[i]=t;is_ratio[i]=r;} } else for(;k>0;k--,i++)is_pos[i]=t; } } { int k,t,tt; tt=sfBandIndex->l[20]; k=576-sfBandIndex->l[21]; t=is_pos[tt]; if(t!=7) { RATIOS r=is_ratio[tt]; for(;k>0;k--,i++){ is_pos[i]=t;is_ratio[i]=r;} } else { for(;k>0;k--,i++) { if (i >= ARRAYSIZE) { debug("Broken mp3 data!\n"); } else { is_pos[i]=t; } } } } } if(ms_stereo) { i=ARRAYSIZE-1; do{ if(is_pos[i]==7) { register REAL t=in[LS][0][i]; in[LS][0][i]=(t+in[RS][0][i])*0.7071068f; in[RS][0][i]=(t-in[RS][0][i])*0.7071068f; } else { in[RS][0][i]=in[LS][0][i]*is_ratio[i].r; in[LS][0][i]*=is_ratio[i].l; } }while(i--); } else { i=ARRAYSIZE-1; do{ if(is_pos[i]!=7) { in[RS][0][i]=in[LS][0][i]*is_ratio[i].r; in[LS][0][i]*=is_ratio[i].l; } }while(i--); } } else { if(ms_stereo) { int i=ARRAYSIZE-1; do{ register REAL t=in[LS][0][i]; in[LS][0][i]=(t+in[RS][0][i])*0.7071068f; in[RS][0][i]=(t-in[RS][0][i])*0.7071068f; }while(i--); } } // channels==2 } inline void layer3reorder_1(int version,int frequency, REAL in[SBLIMIT][SSLIMIT], REAL out[SBLIMIT][SSLIMIT]) { SFBANDINDEX *sfBandIndex=&(sfBandIndextable[version][frequency]); int sfb,sfb_start,sfb_lines; /* NO REORDER FOR LOW 2 SUBBANDS */ out[0][ 0]=in[0][ 0];out[0][ 1]=in[0][ 1];out[0][ 2]=in[0][ 2]; out[0][ 3]=in[0][ 3];out[0][ 4]=in[0][ 4];out[0][ 5]=in[0][ 5]; out[0][ 6]=in[0][ 6];out[0][ 7]=in[0][ 7];out[0][ 8]=in[0][ 8]; out[0][ 9]=in[0][ 9];out[0][10]=in[0][10];out[0][11]=in[0][11]; out[0][12]=in[0][12];out[0][13]=in[0][13];out[0][14]=in[0][14]; out[0][15]=in[0][15];out[0][16]=in[0][16];out[0][17]=in[0][17]; out[1][ 0]=in[1][ 0];out[1][ 1]=in[1][ 1];out[1][ 2]=in[1][ 2]; out[1][ 3]=in[1][ 3];out[1][ 4]=in[1][ 4];out[1][ 5]=in[1][ 5]; out[1][ 6]=in[1][ 6];out[1][ 7]=in[1][ 7];out[1][ 8]=in[1][ 8]; out[1][ 9]=in[1][ 9];out[1][10]=in[1][10];out[1][11]=in[1][11]; out[1][12]=in[1][12];out[1][13]=in[1][13];out[1][14]=in[1][14]; out[1][15]=in[1][15];out[1][16]=in[1][16];out[1][17]=in[1][17]; /* REORDERING FOR REST SWITCHED SHORT */ for(sfb=3,sfb_start=sfBandIndex->s[3], sfb_lines=sfBandIndex->s[4]-sfb_start; sfb<13; sfb++,sfb_start=sfBandIndex->s[sfb], (sfb_lines=sfBandIndex->s[sfb+1]-sfb_start)) { for(int freq=0;freqs[1]; sfb<13; sfb++,sfb_start=sfBandIndex->s[sfb], (sfb_lines=sfBandIndex->s[sfb+1]-sfb_start)) { for(int freq=0;freqgeneralflag) { if(gi->mixed_block_flag) { debug("Mpegtoraw::layer3reorderandantialias:Not checked!"); layer3reorder_1 (version,frequency,in,out); // Not checked... layer3antialias_1(out); } else layer3reorder_2(version,frequency,in,out); } else layer3antialias_2(in,out); } static void dct36(REAL *inbuf,REAL *prevblk1,REAL *prevblk2,REAL *wi,REAL *out) { #define MACRO0(v) { \ REAL tmp; \ out2[9+(v)]=(tmp=sum0+sum1)*wi[27+(v)]; \ out2[8-(v)]=tmp * wi[26-(v)]; } \ sum0-=sum1; \ ts[SBLIMIT*(8-(v))]=out1[8-(v)]+sum0*wi[8-(v)]; \ ts[SBLIMIT*(9+(v))]=out1[9+(v)]+sum0*wi[9+(v)]; #define MACRO1(v) { \ REAL sum0,sum1; \ sum0=tmp1a+tmp2a; \ sum1=(tmp1b+tmp2b)*hsec_36[(v)]; \ MACRO0(v); } #define MACRO2(v) { \ REAL sum0,sum1; \ sum0=tmp2a-tmp1a; \ sum1=(tmp2b-tmp1b) * hsec_36[(v)]; \ MACRO0(v); } { 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]; { register REAL *c = cos_18; register REAL *out2 = prevblk2; register REAL *out1 = prevblk1; register REAL *ts = out; REAL ta33,ta66,tb33,tb66; ta33=in[2*3+0]*c[3]; ta66=in[2*6+0]*c[6]; tb33=in[2*3+1]*c[3]; tb66=in[2*6+1]*c[6]; { REAL tmp1a,tmp2a,tmp1b,tmp2b; tmp1a= in[2*1+0]*c[1]+ta33 +in[2*5+0]*c[5]+in[2*7+0]*c[7]; tmp1b= in[2*1+1]*c[1]+tb33 +in[2*5+1]*c[5]+in[2*7+1]*c[7]; tmp2a=in[2*0+0]+in[2*2+0]*c[2]+in[2*4+0]*c[4]+ta66 +in[2*8+0]*c[8]; tmp2b=in[2*0+1]+in[2*2+1]*c[2]+in[2*4+1]*c[4]+tb66 +in[2*8+1]*c[8]; MACRO1(0); MACRO2(8); } { REAL tmp1a,tmp2a,tmp1b,tmp2b; tmp1a=(in[2*1+0]-in[2*5+0]-in[2*7+0])*c[3]; tmp1b=(in[2*1+1]-in[2*5+1]-in[2*7+1])*c[3]; tmp2a=(in[2*2+0]-in[2*4+0]-in[2*8+0])*c[6]-in[2*6+0]+in[2*0+0]; tmp2b=(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= in[2*1+0]*c[5]-ta33 -in[2*5+0]*c[7]+in[2*7+0]*c[1]; tmp1b= in[2*1+1]*c[5]-tb33 -in[2*5+1]*c[7]+in[2*7+1]*c[1]; tmp2a=in[2*0+0]-in[2*2+0]*c[8]-in[2*4+0]*c[2]+ta66 +in[2*8+0]*c[4]; tmp2b=in[2*0+1]-in[2*2+1]*c[8]-in[2*4+1]*c[2]+tb66 +in[2*8+1]*c[4]; MACRO1(2); MACRO2(6); } { REAL tmp1a,tmp2a,tmp1b,tmp2b; tmp1a= in[2*1+0]*c[7]-ta33 +in[2*5+0]*c[1]-in[2*7+0]*c[5]; tmp1b= in[2*1+1]*c[7]-tb33 +in[2*5+1]*c[1]-in[2*7+1]*c[5]; tmp2a=in[2*0+0]-in[2*2+0]*c[4]+in[2*4+0]*c[8]+ta66 -in[2*8+0]*c[2]; tmp2b=in[2*0+1]-in[2*2+1]*c[4]+in[2*4+1]*c[8]+tb66 -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=(in[2*0+1]-in[2*2+1]+in[2*4+1]-in[2*6+1]+in[2*8+1])*hsec_36[4]; MACRO0(4); } } } } static void dct12(REAL *in,REAL *prevblk1,REAL *prevblk2,register REAL *wi,register REAL *out) { #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*=cos1_6; \ in3*=cos1_6; #define DCT12_PART2 \ in0+=in4*cos2_6; \ \ in4=in0+in2; \ in0-=in2; \ \ in1+=in5*cos2_6; \ \ in5=(in1+in3)*hsec_12[0]; \ in1=(in1-in3)*hsec_12[2]; \ \ in3=in4+in5; \ in4-=in5; \ \ in2=in0+in1; \ in0-=in1; { REAL in0,in1,in2,in3,in4,in5; register REAL *pb1=prevblk1; out[SBLIMIT*0]=pb1[0];out[SBLIMIT*1]=pb1[1];out[SBLIMIT*2]=pb1[2]; out[SBLIMIT*3]=pb1[3];out[SBLIMIT*4]=pb1[4];out[SBLIMIT*5]=pb1[5]; DCT12_PART1; { REAL tmp0,tmp1=(in0-in4); { register REAL tmp2=(in1-in5)*hsec_12[1]; tmp0=tmp1+tmp2; tmp1-=tmp2; } out[(17-1)*SBLIMIT]=pb1[17-1]+tmp0*wi[11-1]; out[(12+1)*SBLIMIT]=pb1[12+1]+tmp0*wi[ 6+1]; out[(6 +1)*SBLIMIT]=pb1[6 +1]+tmp1*wi[ 1 ]; out[(11-1)*SBLIMIT]=pb1[11-1]+tmp1*wi[ 5-1]; } DCT12_PART2; out[(17-0)*SBLIMIT]=pb1[17-0]+in2*wi[11-0]; out[(12+0)*SBLIMIT]=pb1[12+0]+in2*wi[ 6+0]; out[(12+2)*SBLIMIT]=pb1[12+2]+in3*wi[ 6+2]; out[(17-2)*SBLIMIT]=pb1[17-2]+in3*wi[11-2]; out[( 6+0)*SBLIMIT]=pb1[ 6+0]+in0*wi[0]; out[(11-0)*SBLIMIT]=pb1[11-0]+in0*wi[5-0]; out[( 6+2)*SBLIMIT]=pb1[ 6+2]+in4*wi[2]; out[(11-2)*SBLIMIT]=pb1[11-2]+in4*wi[5-2]; } in++; { REAL in0,in1,in2,in3,in4,in5; register REAL *pb2 = prevblk2; DCT12_PART1; { REAL tmp0,tmp1=(in0-in4); { REAL tmp2=(in1-in5)*hsec_12[1]; tmp0=tmp1+tmp2; tmp1-=tmp2; } pb2[5-1]=tmp0*wi[11-1]; pb2[0+1]=tmp0*wi[6+1]; out[(12+1)*SBLIMIT]+=tmp1*wi[1]; out[(17-1)*SBLIMIT]+=tmp1*wi[5-1]; } DCT12_PART2; pb2[5-0]=in2*wi[11-0]; pb2[0+0]=in2*wi[6+0]; pb2[0+2]=in3*wi[6+2]; pb2[5-2]=in3*wi[11-2]; out[(12+0)*SBLIMIT]+=in0*wi[0]; out[(17-0)*SBLIMIT]+=in0*wi[5-0]; out[(12+2)*SBLIMIT]+=in4*wi[2]; out[(17-2)*SBLIMIT]+=in4*wi[5-2]; } in++; { REAL in0,in1,in2,in3,in4,in5; register REAL *pb2 = prevblk2; pb2[12]=pb2[13]=pb2[14]=pb2[15]=pb2[16]=pb2[17]=0.0; DCT12_PART1; { REAL tmp0,tmp1=(in0-in4); { REAL tmp2=(in1-in5)*hsec_12[1]; tmp0=tmp1+tmp2; tmp1-=tmp2; } pb2[11-1]=tmp0*wi[11-1]; pb2[ 6+1]=tmp0*wi[6+1]; pb2[ 0+1]+=tmp1*wi[1]; pb2[ 5-1]+=tmp1*wi[5-1]; } DCT12_PART2; pb2[11-0]=in2*wi[11-0]; pb2[ 6+0]=in2*wi[ 6+0]; pb2[ 6+2]=in3*wi[ 6+2]; pb2[11-2]=in3*wi[11-2]; pb2[ 0+0]+=in0*wi[0 ]; pb2[ 5-0]+=in0*wi[5-0]; pb2[ 0+2]+=in4*wi[2 ]; pb2[ 5-2]+=in4*wi[5-2]; } } void Mpegtoraw::layer3hybrid(int ch,int gr,REAL in[SBLIMIT][SSLIMIT], REAL out[SSLIMIT][SBLIMIT]) { layer3grinfo *gi=&(sideinfo.ch[ch].gr[gr]); int bt1,bt2; REAL *prev1,*prev2; prev1=prevblck[ch][currentprevblock][0]; prev2=prevblck[ch][currentprevblock^1][0]; bt1 = gi->mixed_block_flag ? 0 : gi->block_type; bt2 = gi->block_type; { REAL *ci=(REAL *)in, *co=(REAL *)out; int i; if(downfrequency)i=(SBLIMIT/2)-2; else i=SBLIMIT-2; if(bt2==2) { if(!bt1) { dct36(ci,prev1,prev2,win[0],co); ci+=SSLIMIT;prev1+=SSLIMIT;prev2+=SSLIMIT;co++; dct36(ci,prev1,prev2,win[0],co); } else { dct12(ci,prev1,prev2,win[2],co); ci+=SSLIMIT;prev1+=SSLIMIT;prev2+=SSLIMIT;co++; dct12(ci,prev1,prev2,win[2],co); } do{ ci+=SSLIMIT;prev1+=SSLIMIT;prev2+=SSLIMIT;co++; dct12(ci,prev1,prev2,win[2],co); }while(--i); } else { dct36(ci,prev1,prev2,win[bt1],co); ci+=SSLIMIT;prev1+=SSLIMIT;prev2+=SSLIMIT;co++; dct36(ci,prev1,prev2,win[bt1],co); do { ci+=SSLIMIT;prev1+=SSLIMIT;prev2+=SSLIMIT;co++; dct36(ci,prev1,prev2,win[bt2],co); }while(--i); } } } #define NEG(a) (a)=-(a) void Mpegtoraw::extractlayer3(void) { if(version) { extractlayer3_2(); return; } { int main_data_end,flush_main; int bytes_to_discard; layer3getsideinfo(); if(issync()) { for(register int i=layer3slots;i>0;i--) // read main data. { bitwindow.putbyte(getbyte()); } } else { for(register int i=layer3slots;i>0;i--) // read main data. { bitwindow.putbyte(getbits8()); } } main_data_end=bitwindow.gettotalbit()>>3;// of previous frame if((flush_main=(bitwindow.gettotalbit() & 0x7))) { bitwindow.forward(8-flush_main); main_data_end++; } bytes_to_discard=layer3framestart-(main_data_end+sideinfo.main_data_begin); if(main_data_end>WINDOWSIZE) { layer3framestart-=WINDOWSIZE; bitwindow.rewind(WINDOWSIZE*8); } layer3framestart+=layer3slots; bitwindow.wrap(); if(bytes_to_discard<0) { return; } bitwindow.forward(bytes_to_discard<<3); } for(int gr=0;gr<2;gr++) { union { int is [SBLIMIT][SSLIMIT]; REAL hin [2][SBLIMIT][SSLIMIT]; }b1; union { REAL ro [2][SBLIMIT][SSLIMIT]; REAL lr [2][SBLIMIT][SSLIMIT]; REAL hout [2][SSLIMIT][SBLIMIT]; }b2; layer3part2start=bitwindow.gettotalbit(); layer3getscalefactors (LS,gr); layer3huffmandecode (LS,gr ,b1.is); layer3dequantizesample(LS,gr,b1.is,b2.ro[LS]); if(inputstereo) { layer3part2start=bitwindow.gettotalbit(); layer3getscalefactors (RS,gr); layer3huffmandecode (RS,gr ,b1.is); layer3dequantizesample(RS,gr,b1.is,b2.ro[RS]); } layer3fixtostereo(gr,b2.ro); // b2.ro -> b2.lr currentprevblock^=1; layer3reorderandantialias(LS,gr,b2.lr[LS],b1.hin[LS]); layer3hybrid (LS,gr,b1.hin[LS],b2.hout[LS]); if(outputstereo) { layer3reorderandantialias(RS,gr,b2.lr[RS],b1.hin[RS]); layer3hybrid (RS,gr,b1.hin[RS],b2.hout[RS]); register int i=2*SSLIMIT*SBLIMIT-1; do{ NEG(b2.hout[0][0][i ]);NEG(b2.hout[0][0][i- 2]); NEG(b2.hout[0][0][i- 4]);NEG(b2.hout[0][0][i- 6]); NEG(b2.hout[0][0][i- 8]);NEG(b2.hout[0][0][i-10]); NEG(b2.hout[0][0][i-12]);NEG(b2.hout[0][0][i-14]); NEG(b2.hout[0][0][i-16]);NEG(b2.hout[0][0][i-18]); NEG(b2.hout[0][0][i-20]);NEG(b2.hout[0][0][i-22]); NEG(b2.hout[0][0][i-24]);NEG(b2.hout[0][0][i-26]); NEG(b2.hout[0][0][i-28]);NEG(b2.hout[0][0][i-30]); }while((i-=2*SBLIMIT)>0); } else { register int i=SSLIMIT*SBLIMIT-1; do{ NEG(b2.hout[0][0][i ]);NEG(b2.hout[0][0][i- 2]); NEG(b2.hout[0][0][i- 4]);NEG(b2.hout[0][0][i- 6]); NEG(b2.hout[0][0][i- 8]);NEG(b2.hout[0][0][i-10]); NEG(b2.hout[0][0][i-12]);NEG(b2.hout[0][0][i-14]); NEG(b2.hout[0][0][i-16]);NEG(b2.hout[0][0][i-18]); NEG(b2.hout[0][0][i-20]);NEG(b2.hout[0][0][i-22]); NEG(b2.hout[0][0][i-24]);NEG(b2.hout[0][0][i-26]); NEG(b2.hout[0][0][i-28]);NEG(b2.hout[0][0][i-30]); }while((i-=2*SBLIMIT)>0); } for(int ss=0;ss0;i--) // read main data. bitwindow.putbyte(getbyte()); } else { for(register int i=layer3slots;i>0;i--) // read main data. bitwindow.putbyte(getbits8()); } bitwindow.wrap(); main_data_end=bitwindow.gettotalbit()>>3;// of previous frame if((flush_main=(bitwindow.gettotalbit() & 0x7))) { bitwindow.forward(8-flush_main); main_data_end++; } bytes_to_discard=layer3framestart-main_data_end-sideinfo.main_data_begin; if(main_data_end>WINDOWSIZE) { layer3framestart-=WINDOWSIZE; bitwindow.rewind(WINDOWSIZE*8); } layer3framestart+=layer3slots; if(bytes_to_discard<0)return; bitwindow.forward(bytes_to_discard<<3); } // for(int gr=0;gr<2;gr++) { union { int is [SBLIMIT][SSLIMIT]; REAL hin [2][SBLIMIT][SSLIMIT]; }b1; union { REAL ro [2][SBLIMIT][SSLIMIT]; REAL lr [2][SBLIMIT][SSLIMIT]; REAL hout [2][SSLIMIT][SBLIMIT]; }b2; layer3part2start=bitwindow.gettotalbit(); layer3getscalefactors_2(LS); layer3huffmandecode (LS,0 ,b1.is); layer3dequantizesample (LS,0,b1.is,b2.ro[LS]); if(inputstereo) { layer3part2start=bitwindow.gettotalbit(); layer3getscalefactors_2(RS); layer3huffmandecode (RS,0 ,b1.is); layer3dequantizesample (RS,0,b1.is,b2.ro[RS]); } layer3fixtostereo(0,b2.ro); // b2.ro -> b2.lr currentprevblock^=1; layer3reorderandantialias(LS,0,b2.lr[LS],b1.hin[LS]); layer3hybrid (LS,0,b1.hin[LS],b2.hout[LS]); if(outputstereo) { layer3reorderandantialias(RS,0,b2.lr[RS],b1.hin[RS]); layer3hybrid (RS,0,b1.hin[RS],b2.hout[RS]); register int i=2*SSLIMIT*SBLIMIT-1; do{ NEG(b2.hout[0][0][i-16]);NEG(b2.hout[0][0][i-18]); NEG(b2.hout[0][0][i-20]);NEG(b2.hout[0][0][i-22]); NEG(b2.hout[0][0][i-24]);NEG(b2.hout[0][0][i-26]); NEG(b2.hout[0][0][i-28]);NEG(b2.hout[0][0][i-30]); }while((i-=2*SBLIMIT)>0); } else { register int i=SSLIMIT*SBLIMIT-1; do{ NEG(b2.hout[0][0][i-16]);NEG(b2.hout[0][0][i-18]); NEG(b2.hout[0][0][i-20]);NEG(b2.hout[0][0][i-22]); NEG(b2.hout[0][0][i-24]);NEG(b2.hout[0][0][i-26]); NEG(b2.hout[0][0][i-28]);NEG(b2.hout[0][0][i-30]); }while((i-=2*SBLIMIT)>0); } for(int ss=0;ss #include #include #ifdef HAVE_ERRNO_H # include #endif /* HAVE_ERRNO_H */ #include #include #include #include #include #include #include "mpegsound.h" #include "mpegsound_locals.h" //blocksize to use when writing to esd #define ESD_BLOCK_SIZE 32768 EsdPlayer::EsdPlayer(const char *host) { this->esd_handle = -1; this->host = host; } EsdPlayer::~EsdPlayer() { if (esd_handle > -1) { (void)esd_close(esd_handle); } } void EsdPlayer::abort() { //doesn't seem like esd can be made to flush any caches. } bool EsdPlayer::setsoundtype(int stereo, int samplesize, int speed) { if (esd_handle != -1) { debug("setsoundtype() called while esd_handle exists"); seterrorcode(SOUND_ERROR_UNKNOWN); return false; //can only set soundtype once } rawstereo = stereo; rawsamplesize = samplesize; rawspeed = speed; return resetsoundtype(); } void EsdPlayer::set8bitmode() { //ignore forced 8bits output requests ; esd must downsample itself. } bool EsdPlayer::resetsoundtype() { int esd_format = 0; debug("esdplayer::resetsoundtype\n"); esd_format |= (rawstereo ? ESD_STEREO : ESD_MONO); esd_format |= (rawsamplesize == 8 ? ESD_BITS8 : ESD_BITS16); if (esd_handle != -1) { //connection still exists. close it. (void)esd_close(esd_handle); } //[re]open connection to esd esd_handle = esd_play_stream(esd_format, rawspeed, NULL, "mp3blaster"); if (esd_handle < 0) { debug("esd_play_stream failed: %s\n", strerror(errno)); seterrorcode(SOUND_ERROR_DEVOPENFAIL); return false; } return true; } void EsdPlayer::releasedevice() { /* releasing sound device is pointless when using a sound daemon */ } bool EsdPlayer::attachdevice() { /* releasing sound device is pointless when using a sound daemon */ return true; } bool EsdPlayer::putblock(void *buffer, int size) { int bytes_written = 0; if (esd_handle < 0) return false; #if defined(AUDIO_NONBLOCKING) || defined(NEWTHREAD) while (bytes_written != size) { int tmp_bytes_written = putblock_nt((char*)buffer + bytes_written, size - bytes_written); if (tmp_bytes_written < 0) { seterrorcode(SOUND_ERROR_DEVBUSY); return false; } bytes_written += tmp_bytes_written; } #else bytes_written = putblock_nt(buffer, size); if (bytes_written < 0) { seterrorcode(SOUND_ERROR_DEVBUSY); return false; } #endif return true; } int EsdPlayer::putblock_nt(void *buffer, int size) { #ifdef LIBPTH return pth_write(esd_handle, buffer, size); #else return write(esd_handle, buffer, size); #endif } int EsdPlayer::getblocksize() { return ESD_BLOCK_SIZE; //XXX: config? } int EsdPlayer::fix_samplesize(void *buffer, int size) { (void)buffer; //esd takes care of downsampling, no need to mangle samples return size; } #endif /* WANT_ESD */ mp3blaster-3.2.6/mpegsound/nasplayer.cc0000644000112600011260000001062213106424065015021 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Nasplayer.cc // Playing raw audio over Network Audio System (by NCD) // By Willem (willem@stack.nl) #include "config.h" #ifdef WANT_NAS #include "mpegsound.h" #include "mpegsound_locals.h" #include #include NASplayer::NASplayer(AuServer *aud) { this->aud = aud; dev = AuNone; format = AuNone; flow = 0; samplerate = 0; channels = 0; buffer_ms = 2500; req_size = 0; } NASplayer::~NASplayer() { if (aud) { if (flow) AuDestroyFlow(aud, flow, 0); AuCloseServer(aud); } } NASplayer *NASplayer::opendevice(char *server) { AuServer *aud; char *return_status; aud = AuOpenServer(server, 0, 0, 0, 0, &return_status); if (!aud) { debug("NASplayer:: AuOpenServer(%s) failed: %s\n", server, return_status); free(return_status); //should we? return NULL; } return new NASplayer(aud); } void NASplayer::abort(void) { if (!aud || !flow) return; AuStopFlow(aud, flow, 0); AuHandleEvents(aud); req_size = 0; AuStartFlow(aud, flow, 0); } bool NASplayer::setsoundtype(int stereo, int samplesize, int speed) { int changed = 0; unsigned char newf = AuNone; if (samplesize == 16) newf = AuFormatLinearSigned16LSB; //else newf = AuFormatLinearSigned8; else newf = AuFormatLinearUnsigned8; stereo = stereo ? 2 : 1; if (stereo != channels) { channels = stereo; changed++; } if (samplerate != speed) { samplerate = speed; changed++; } if (newf != format) { format = newf; changed++; } if (changed) return resetsoundtype(); return true; } static AuBool static_event_handler(AuServer *, AuEvent *ev, AuEventHandlerRec *hnd) { NASplayer *np = (NASplayer *)(hnd->data); return np->event_handler(ev); } bool NASplayer::resetsoundtype(void) { if (!aud) return seterrorcode(SOUND_ERROR_DEVOPENFAIL); if (flow) { AuUnregisterEventHandler(aud, evhnd); AuDestroyFlow(aud, flow, 0); } flow = 0; int i = 0; while(true) { if (i >= AuServerNumDevices(aud)) return seterrorcode(SOUND_ERROR_DEVCTRLERROR); if ((AuDeviceKind(AuServerDevice(aud, i)) == AuComponentKindPhysicalOutput) && AuDeviceNumTracks(AuServerDevice(aud, i)) == channels) { dev = AuDeviceIdentifier(AuServerDevice(aud, i)); break; } i++; } flow = AuCreateFlow(aud, 0); if (!flow) return seterrorcode(SOUND_ERROR_DEVCTRLERROR); AuElement elms[3]; int buffer_size = (buffer_ms * samplerate) / 1000; if (buffer_size < 8192) buffer_size = 8192; AuMakeElementImportClient(elms, samplerate, format, channels, AuTrue, buffer_size, buffer_size / 2, 0, 0); AuMakeElementExportDevice(elms+1, 0, dev, samplerate, AuUnlimitedSamples, 0, 0); AuSetElements(aud, flow, AuTrue, 2, elms, 0); evhnd = AuRegisterEventHandler(aud, AuEventHandlerIDMask, 0, flow, static_event_handler, (AuPointer) this); AuStartFlow(aud, flow, 0); req_size = 0; return true; } //non-blocking putblock, may do partial writes int NASplayer::putblock_nt(void *buffer, int size) { int writeSize; AuHandleEvents(aud); //check for events if (!req_size) return 0; //no space to write (yet) writeSize = req_size; if (req_size > size) { writeSize = size; } req_size -= writeSize; AuWriteElement(aud, flow, 0, writeSize, buffer, AuFalse, 0); return writeSize; } bool NASplayer::putblock(void *buffer, int size) { while (size > req_size) { USLEEP(3); AuHandleEvents(aud); } req_size -= size; AuWriteElement(aud, flow, 0, size, buffer, AuFalse, 0); return true; } int NASplayer::getblocksize(void) { return 2048; } int NASplayer::setvolume(int volume) { if (!aud) return 0; AuDeviceAttributes *da = AuGetDeviceAttributes(aud, dev, NULL); if (!da) return 0; if (volume > 100) volume = 100; if (volume > 0) { AuDeviceGain(da) = AuFixedPointFromSum(volume, 0); AuSetDeviceAttributes(aud, AuDeviceIdentifier(da), AuCompDeviceGainMask, da, NULL); AuFreeDeviceAttributes(aud, 1, da); da = AuGetDeviceAttributes(aud, dev, NULL); } return AuFixedPointRoundUp(AuDeviceGain(da)); } AuBool NASplayer::event_handler(AuEvent *ev) { switch (ev->type) { case AuEventTypeElementNotify: AuElementNotifyEvent *event = (AuElementNotifyEvent *)ev; switch (event->kind) { case AuElementNotifyKindLowWater: req_size += event->num_bytes; break; case AuElementNotifyKindState: switch (event->cur_state) { case AuStatePause: if (event->reason != AuReasonUser) req_size += event->num_bytes; break; } } } return AuTrue; } #endif /*\ WANT_NAS \*/ mp3blaster-3.2.6/mpegsound/httpinput.cc0000664000112600011260000001617512426044701015074 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Woo-jae Jung */ // Httpinputstream.cc // Inputstream for http // It's from mpg123 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "mpegsound.h" #include "mpegsound_locals.h" #include #include #include #include #include #include #include #include #ifdef HAVE_ERRNO_H #include #endif #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff #endif static const char *httpstr="http://"; bool Soundinputstreamfromhttp::writestring(int fd, char *string) { int result,bytes=strlen(string); while(bytes) { if((result=write(fd,string,bytes))<0 && errno!=EINTR) { seterrorcode(SOUND_ERROR_HTTPWRITEFAIL); return false; } else if(result==0) { seterrorcode(SOUND_ERROR_HTTPWRITEFAIL); return false; } string += result; bytes -= result; } return true; } bool Soundinputstreamfromhttp::readstring(char *string,int maxlen,FILE *f) { char *result; do{ result=fgets(string,maxlen,f); }while(!result && errno==EINTR); if(!result) { seterrorcode(SOUND_ERROR_FILEREADFAIL); return false; } return true; } static char *strndup(char *src,int num) { char *dst; if(!(dst=(char *)malloc(num+1)))return NULL; dst[num]='\0'; return strncpy(dst, src, num); } static char *url2hostport(char *url,char **hname, unsigned long *hip,unsigned int *port) { char *cptr; struct hostent *myhostent; struct in_addr myaddr; int isip=1; if(!(strncmp(url,httpstr,7)))url+=7; cptr=url; while(*cptr && *cptr!=':' && *cptr!='/') { if((*cptr<'0' || *cptr>'9') && *cptr!='.')isip=0; cptr++; } if(!(*hname=strndup(url,cptr-url))) { *hname=NULL; return NULL; } if(!isip) { if (!(myhostent=gethostbyname(*hname)))return NULL; memcpy(&myaddr,myhostent->h_addr,sizeof(myaddr)); *hip=myaddr.s_addr; } else if((*hip=inet_addr(*hname))==INADDR_NONE)return NULL; if(!*cptr || *cptr=='/') { *port=80; return cptr; } *port=atoi(++cptr); while(*cptr && *cptr!='/')cptr++; return cptr; } char *proxyurl=NULL; unsigned long proxyip=0; unsigned int proxyport; FILE *Soundinputstreamfromhttp::http_open(const char *urrel) { char *purl=NULL, *host = NULL, *request = NULL, *sptr = NULL, *url = NULL; char agent[50]; const char *url_part; int linelength; int sock; int relocate=0,numrelocs=0; int slash_count = 0; unsigned long myip; unsigned int myport; struct sockaddr_in server; FILE *myfile; url = new char[strlen(urrel) + 2]; strcpy(url, urrel); //find hostname from URL url_part = url; while ( (url_part = strchr(url_part, '/')) != NULL) { url_part++; slash_count++; } if (strlen(url) > 0 && url[strlen(url)-1] != '/' && slash_count == 2) { //add a trailing slash after the url's hostname url[strlen(url)] = '/'; url[strlen(url)+1] = '\0'; } if (!proxyip) { if (!proxyurl && !(proxyurl=getenv("MP3_HTTP_PROXY")) && !(proxyurl=getenv("http_proxy"))) { proxyurl = getenv("HTTP_PROXY"); } if (proxyurl && proxyurl[0] && strcmp(proxyurl, "none")) { if (!(url2hostport(proxyurl, &host, &proxyip, &proxyport))) { seterrorcode(SOUND_ERROR_UNKNOWNPROXY); return NULL; } if (host) { free(host); host = NULL; } } else proxyip = INADDR_NONE; } if (!(purl=(char *)malloc(1024))) { seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH); delete[] url; return NULL; } strncpy(purl,url,1022); purl[1022]= purl[1023] = '\0'; delete[] url; url = NULL; request = NULL; do { if (request) free(request); if ((linelength = strlen(purl) * 2 + 100) < 1024) linelength=1024; if (!(request=(char *)malloc(linelength))) { seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH); free(purl); return NULL; } if (host) free(host); host = NULL; strcpy(request,"GET "); if (proxyip!=INADDR_NONE) { if(strncmp(purl,httpstr,7)) strcat(request,httpstr); strcat(request,purl); myport=proxyport; myip=proxyip; } else { if (!(sptr=url2hostport(purl,&host,&myip,&myport))) { seterrorcode(SOUND_ERROR_UNKNOWNHOST); free(purl); free(request); return NULL; } strcat (request, sptr); } strcat(request, " HTTP/1.1\r\n"); if (host && proxyip == INADDR_NONE) { strcat(request, "Host: "); strcat(request, host); strcat(request, "\r\n"); free(host); host = NULL; } sprintf (agent, "User-Agent: %s/%s\r\n\r\n", "Mp3blaster",VERSION); strcat (request, agent); debug("HTTP Request:\n\n%s", request); server.sin_family = AF_INET; server.sin_port = htons(myport); server.sin_addr.s_addr = myip; if ((sock=socket(PF_INET,SOCK_STREAM,6))<0) { seterrorcode(SOUND_ERROR_SOCKET); free(purl); free(request); return NULL; } if (connect(sock,(struct sockaddr *)&server,sizeof(server))) { seterrorcode(SOUND_ERROR_CONNECT); free(purl); free(request); return NULL; } if (!writestring(sock,request)) { free(purl); free(request); return NULL; } if (!(myfile=fdopen(sock, "rb"))) { seterrorcode(SOUND_ERROR_FDOPEN); free(purl); return NULL; }; relocate=false; purl[0]='\0'; if (!readstring(request,linelength-1,myfile)) { free(purl); free(request); return NULL; } if ((sptr=strchr(request,' '))) { switch(sptr[1]) { case '3':relocate=true; case '2':break; default: seterrorcode(SOUND_ERROR_HTTPFAIL); free(purl); free(request); return NULL; } } do { if (!readstring(request,linelength-1,myfile)) { free(purl); free(request); return NULL; } if (!strncmp(request,"Location:",9)) strncpy (purl,request+10,1023); } while (request[0]!='\r' && request[0]!='n'); } while (relocate && purl[0] && numrelocs++<5); if (relocate) { seterrorcode(SOUND_ERROR_TOOMANYRELOC); return NULL; } free(purl); free(request); return myfile; } Soundinputstreamfromhttp::Soundinputstreamfromhttp() { fp=NULL; __canseek = false; } Soundinputstreamfromhttp::~Soundinputstreamfromhttp() { if(fp)fclose(fp); } bool Soundinputstreamfromhttp::open(const char *url) { if((fp=http_open(url))==NULL) { debug("Could not open url..\n"); seterrorcode(SOUND_ERROR_FILEOPENFAIL); return false; } debug("url opened\n"); return true; } int Soundinputstreamfromhttp::getbytedirect(void) { int c; if((c=getc(fp))<0) { seterrorcode(SOUND_ERROR_FILEREADFAIL); return -1; } return c; } bool Soundinputstreamfromhttp::_readbuffer(char *buffer,int size) { if(fread(buffer,size,1,fp)!=1) { seterrorcode(SOUND_ERROR_FILEREADFAIL); return false; } return true; } bool Soundinputstreamfromhttp::eof(void) { return feof(fp); }; int Soundinputstreamfromhttp::getblock(char *buffer,int size) { int l; l=fread(buffer,1,size,fp); if(l==0)seterrorcode(SOUND_ERROR_FILEREADFAIL); return l; } int Soundinputstreamfromhttp::getsize(void) { return 1; } void Soundinputstreamfromhttp::setposition(int) { } int Soundinputstreamfromhttp::getposition(void) { return 0; } mp3blaster-3.2.6/mpegsound/bitwindow.cc0000664000112600011260000000164312426044701015035 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Bitwindow.cc // It's bit reservior for MPEG layer 3 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mpegsound.h" #ifndef WORDS_BIGENDIAN #define _KEY 0 #else #define _KEY 3 #endif int Mpegbitwindow::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)&(WINDOWSIZE-1)]<>3]<>3)&(WINDOWSIZE-1)]; u.store[_KEY]=buffer[bitindex>>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); } mp3blaster-3.2.6/mpegsound/sidplayer.cc0000664000112600011260000000442112426044701015020 00000000000000/*\ |*| Class for playing C=64 tunes \*/ #include "config.h" #include "mpegsound.h" #include "mpegsound_locals.h" #ifdef HAVE_SIDPLAYER SIDfileplayer::SIDfileplayer(audiodriver_t driver) { bufSize = 0; buffer = 0; tune = 0; emu.getConfig(emuConf); set_driver(driver); #if 0 emuConf.frequency = 32000; emuConf.channels = SIDEMU_MONO; /*\ emuConf.autoPanning = SIDEMU_CENTEREDAUTOPANNING; emuConf.volumeControl = SIDEMU_FULLPANNING; \*/ emuConf.bitsPerSample = SIDEMU_8BIT; emuConf.sampleFormat = SIDEMU_SIGNED_PCM; #endif } SIDfileplayer::~SIDfileplayer() { if (tune) delete tune; if (buffer) delete buffer; } bool SIDfileplayer::openfile(const char *filename, const char *device, soundtype write2file) { int ssize; if (!opendevice(device, write2file)) return seterrorcode(SOUND_ERROR_DEVOPENFAIL); if (tune) delete tune; tune = new sidTune(filename); if ((!tune) || (!*tune)) return seterrorcode(SOUND_ERROR_FILEOPENFAIL); ssize = (emuConf.bitsPerSample == SIDEMU_16BIT ? 16 : 8); player->setsoundtype((emuConf.channels == SIDEMU_STEREO?1:0), ssize, emuConf.frequency); emu.setConfig(emuConf); if (bufSize != player->getblocksize()) { bufSize = player->getblocksize(); if (buffer) delete buffer; buffer = new char[bufSize]; if (!buffer) { bufSize = 0; return seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH); } } tune->getInfo(sidInfo); song = sidInfo.startSong; if (!sidEmuInitializeSong(emu, *tune, song)) return seterrorcode(SOUND_ERROR_FILEREADFAIL); tune->getInfo(sidInfo); return true; } void SIDfileplayer::closefile(void) { if (tune) delete tune; } void SIDfileplayer::setforcetomono(short flag) { (void)flag; /*\ emuConf.channels = flag ? SIDEMU_MONO : SIDEMU_STEREO; emu.setConfig(emuConf); \*/ } void SIDfileplayer::setdownfrequency(int value) { emuConf.frequency = value; emu.setConfig(emuConf); } bool SIDfileplayer::run(int frames) { tune->getInfo(sidInfo); if (song != sidInfo.currentSong) if (!sidEmuInitializeSong(emu, *tune, song)) return seterrorcode(SOUND_ERROR_FILEREADFAIL); while (--frames >= 0) { sidEmuFillBuffer(emu, *tune, buffer, bufSize); if (!player->putblock(buffer, bufSize)) return false; } return true; } bool SIDfileplayer::playing() { while (run(1)); return false; } #endif /* HAVE_SIDPLAYER */ mp3blaster-3.2.6/mpegsound/wavetoraw.cc0000664000112600011260000000620412426044701015044 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Wavetoraw.cc // Server which strips wave header. #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef HAVE_MALLOC_H # include #endif #include "mpegsound.h" #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #ifdef WORDS_BIGENDIAN typedef union { long arg; char byte_represent[4]; } endian_hack_1; typedef union { short arg; char byte_represent[2]; } endian_hack_2; inline short HOST_TO_LE16(short x) { endian_hack_2 in,out; in.arg=x; out.arg=0; out.byte_represent[0]=in.byte_represent[1]; out.byte_represent[1]=in.byte_represent[0]; return (short)out.arg; } inline int HOST_TO_LE32(int x) { endian_hack_1 in,out; in.arg=x; out.arg=0; out.byte_represent[0]=in.byte_represent[3]; out.byte_represent[1]=in.byte_represent[2]; out.byte_represent[2]=in.byte_represent[1]; out.byte_represent[3]=in.byte_represent[0]; return out.arg; } #else #define HOST_TO_LE16(x) (x) #define HOST_TO_LE32(x) (x) #endif Wavetoraw::Wavetoraw(Soundinputstream *loader,Soundplayer *player) { __errorcode=SOUND_ERROR_OK; initialized=false;buffer=NULL; this->loader=loader;this->player=player; }; Wavetoraw::~Wavetoraw() { if (buffer)free(buffer); }; // Convert wave format to raw format class bool Wavetoraw::initialize(void) { int c; char tmpbuffer[1024]; if ( !(c=loader->getblock(tmpbuffer,sizeof(WAVEHEADER))) ) { return seterrorcode(SOUND_ERROR_FILEREADFAIL); } if (!testwave(tmpbuffer)) return false; //int ssize = (samplesize == 16 ? AFMT_S16_LE : AFMT_U8); if (!(player->setsoundtype(stereo, samplesize, speed))) return false; if (!buffer) { buffersize=player->getblocksize(); if (buffersize < (int)sizeof(WAVEHEADER)) buffersize = sizeof(WAVEHEADER); if ((buffer=(char *)malloc(buffersize * sizeof(char)))==NULL) { return seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH); } } currentpoint=0; initialized=true; return true; } bool Wavetoraw::run(void) { int c; c=loader->getblock(buffer,buffersize); if (c==0) { return seterrorcode(SOUND_ERROR_FILEREADFAIL); } currentpoint+=c; if (player->putblock(buffer,buffersize) == false) return false; if (currentpoint >= size) { return seterrorcode(SOUND_ERROR_FINISH); } return true; } void Wavetoraw::setcurrentpoint(int p) { if (p*pcmsize>size)currentpoint=size; else currentpoint=p*pcmsize; loader->setposition(currentpoint+sizeof(WAVEHEADER)); } bool Wavetoraw::testwave(char *buffer) { WAVEHEADER *tmp = (WAVEHEADER *)buffer; if (tmp->main_chunk==RIFF && tmp->chunk_type==WAVE && tmp->sub_chunk==FMT && tmp->data_chunk==DATA) { if (tmp->format == PCM_CODE && (tmp->modus == WAVE_STEREO || tmp->modus == WAVE_MONO)) { stereo = (tmp->modus==WAVE_STEREO) ? 1 : 0; samplesize = HOST_TO_LE16((int)(tmp->bit_p_spl)); speed = HOST_TO_LE32((int)(tmp->sample_fq)); size = HOST_TO_LE32((int)(tmp->data_length)); pcmsize=1; if (stereo == 1) pcmsize *= 2; if (samplesize == 16) pcmsize*=2; return true; } } return seterrorcode(SOUND_ERROR_BAD); } mp3blaster-3.2.6/mpegsound/mpeglayer2.cc0000664000112600011260000010630312426044701015075 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Mpeglayer2.cc // It's for MPEG Layer 2 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mpegsound.h" #define MAXTABLE 2 // Tables for layer 2 static const int bitalloclengthtable[MAXTABLE][MAXSUBBAND]= {{4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3}, {4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3, 3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2}}; static const REAL group5bits[27*3]= { -2.0/3.0, -2.0/3.0, -2.0/3.0, 0.0, -2.0/3.0, -2.0/3.0, 2.0/3.0, -2.0/3.0, -2.0/3.0, -2.0/3.0, 0.0, -2.0/3.0, 0.0, 0.0, -2.0/3.0, 2.0/3.0, 0.0, -2.0/3.0, -2.0/3.0, 2.0/3.0, -2.0/3.0, 0.0, 2.0/3.0, -2.0/3.0, 2.0/3.0, 2.0/3.0, -2.0/3.0, -2.0/3.0, -2.0/3.0, 0.0, 0.0, -2.0/3.0, 0.0, 2.0/3.0, -2.0/3.0, 0.0, -2.0/3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0/3.0, 0.0, 0.0, -2.0/3.0, 2.0/3.0, 0.0, 0.0, 2.0/3.0, 0.0, 2.0/3.0, 2.0/3.0, 0.0, -2.0/3.0, -2.0/3.0, 2.0/3.0, 0.0, -2.0/3.0, 2.0/3.0, 2.0/3.0, -2.0/3.0, 2.0/3.0, -2.0/3.0, 0.0, 2.0/3.0, 0.0, 0.0, 2.0/3.0, 2.0/3.0, 0.0, 2.0/3.0, -2.0/3.0, 2.0/3.0, 2.0/3.0, 0.0, 2.0/3.0, 2.0/3.0, 2.0/3.0, 2.0/3.0, 2.0/3.0 }; static const REAL group7bits[125*3]= { -0.8,-0.8,-0.8, -0.4,-0.8,-0.8, 0.0,-0.8,-0.8, 0.4,-0.8,-0.8, 0.8,-0.8,-0.8, -0.8,-0.4,-0.8, -0.4,-0.4,-0.8, 0.0,-0.4,-0.8, 0.4,-0.4,-0.8, 0.8,-0.4,-0.8, -0.8, 0.0,-0.8, -0.4, 0.0,-0.8, 0.0, 0.0,-0.8, 0.4, 0.0,-0.8, 0.8, 0.0,-0.8, -0.8, 0.4,-0.8, -0.4, 0.4,-0.8, 0.0, 0.4,-0.8, 0.4, 0.4,-0.8, 0.8, 0.4,-0.8, -0.8, 0.8,-0.8, -0.4, 0.8,-0.8, 0.0, 0.8,-0.8, 0.4, 0.8,-0.8, 0.8, 0.8,-0.8, -0.8,-0.8,-0.4, -0.4,-0.8,-0.4, 0.0,-0.8,-0.4, 0.4,-0.8,-0.4, 0.8,-0.8,-0.4, -0.8,-0.4,-0.4, -0.4,-0.4,-0.4, 0.0,-0.4,-0.4, 0.4,-0.4,-0.4, 0.8,-0.4,-0.4, -0.8, 0.0,-0.4, -0.4, 0.0,-0.4, 0.0, 0.0,-0.4, 0.4, 0.0,-0.4, 0.8, 0.0,-0.4, -0.8, 0.4,-0.4, -0.4, 0.4,-0.4, 0.0, 0.4,-0.4, 0.4, 0.4,-0.4, 0.8, 0.4,-0.4, -0.8, 0.8,-0.4, -0.4, 0.8,-0.4, 0.0, 0.8,-0.4, 0.4, 0.8,-0.4, 0.8, 0.8,-0.4, -0.8,-0.8, 0.0, -0.4,-0.8, 0.0, 0.0,-0.8, 0.0, 0.4,-0.8, 0.0, 0.8,-0.8, 0.0, -0.8,-0.4, 0.0, -0.4,-0.4, 0.0, 0.0,-0.4, 0.0, 0.4,-0.4, 0.0, 0.8,-0.4, 0.0, -0.8, 0.0, 0.0, -0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4, 0.0, 0.0, 0.8, 0.0, 0.0, -0.8, 0.4, 0.0, -0.4, 0.4, 0.0, 0.0, 0.4, 0.0, 0.4, 0.4, 0.0, 0.8, 0.4, 0.0, -0.8, 0.8, 0.0, -0.4, 0.8, 0.0, 0.0, 0.8, 0.0, 0.4, 0.8, 0.0, 0.8, 0.8, 0.0, -0.8,-0.8, 0.4, -0.4,-0.8, 0.4, 0.0,-0.8, 0.4, 0.4,-0.8, 0.4, 0.8,-0.8, 0.4, -0.8,-0.4, 0.4, -0.4,-0.4, 0.4, 0.0,-0.4, 0.4, 0.4,-0.4, 0.4, 0.8,-0.4, 0.4, -0.8, 0.0, 0.4, -0.4, 0.0, 0.4, 0.0, 0.0, 0.4, 0.4, 0.0, 0.4, 0.8, 0.0, 0.4, -0.8, 0.4, 0.4, -0.4, 0.4, 0.4, 0.0, 0.4, 0.4, 0.4, 0.4, 0.4, 0.8, 0.4, 0.4, -0.8, 0.8, 0.4, -0.4, 0.8, 0.4, 0.0, 0.8, 0.4, 0.4, 0.8, 0.4, 0.8, 0.8, 0.4, -0.8,-0.8, 0.8, -0.4,-0.8, 0.8, 0.0,-0.8, 0.8, 0.4,-0.8, 0.8, 0.8,-0.8, 0.8, -0.8,-0.4, 0.8, -0.4,-0.4, 0.8, 0.0,-0.4, 0.8, 0.4,-0.4, 0.8, 0.8,-0.4, 0.8, -0.8, 0.0, 0.8, -0.4, 0.0, 0.8, 0.0, 0.0, 0.8, 0.4, 0.0, 0.8, 0.8, 0.0, 0.8, -0.8, 0.4, 0.8, -0.4, 0.4, 0.8, 0.0, 0.4, 0.8, 0.4, 0.4, 0.8, 0.8, 0.4, 0.8, -0.8, 0.8, 0.8, -0.4, 0.8, 0.8, 0.0, 0.8, 0.8, 0.4, 0.8, 0.8, 0.8, 0.8, 0.8 }; static const REAL group10bits[729*3]= { -8.0/9.0,-8.0/9.0,-8.0/9.0, -6.0/9.0,-8.0/9.0,-8.0/9.0, -4.0/9.0,-8.0/9.0,-8.0/9.0, -2.0/9.0,-8.0/9.0,-8.0/9.0, 0.0,-8.0/9.0,-8.0/9.0, 2.0/9.0,-8.0/9.0,-8.0/9.0, 4.0/9.0,-8.0/9.0,-8.0/9.0, 6.0/9.0,-8.0/9.0,-8.0/9.0, 8.0/9.0,-8.0/9.0,-8.0/9.0, -8.0/9.0,-6.0/9.0,-8.0/9.0, -6.0/9.0,-6.0/9.0,-8.0/9.0, -4.0/9.0,-6.0/9.0,-8.0/9.0, -2.0/9.0,-6.0/9.0,-8.0/9.0, 0.0,-6.0/9.0,-8.0/9.0, 2.0/9.0,-6.0/9.0,-8.0/9.0, 4.0/9.0,-6.0/9.0,-8.0/9.0, 6.0/9.0,-6.0/9.0,-8.0/9.0, 8.0/9.0,-6.0/9.0,-8.0/9.0, -8.0/9.0,-4.0/9.0,-8.0/9.0, -6.0/9.0,-4.0/9.0,-8.0/9.0, -4.0/9.0,-4.0/9.0,-8.0/9.0, -2.0/9.0,-4.0/9.0,-8.0/9.0, 0.0,-4.0/9.0,-8.0/9.0, 2.0/9.0,-4.0/9.0,-8.0/9.0, 4.0/9.0,-4.0/9.0,-8.0/9.0, 6.0/9.0,-4.0/9.0,-8.0/9.0, 8.0/9.0,-4.0/9.0,-8.0/9.0, -8.0/9.0,-2.0/9.0,-8.0/9.0, -6.0/9.0,-2.0/9.0,-8.0/9.0, -4.0/9.0,-2.0/9.0,-8.0/9.0, -2.0/9.0,-2.0/9.0,-8.0/9.0, 0.0,-2.0/9.0,-8.0/9.0, 2.0/9.0,-2.0/9.0,-8.0/9.0, 4.0/9.0,-2.0/9.0,-8.0/9.0, 6.0/9.0,-2.0/9.0,-8.0/9.0, 8.0/9.0,-2.0/9.0,-8.0/9.0, -8.0/9.0, 0.0,-8.0/9.0, -6.0/9.0, 0.0,-8.0/9.0, -4.0/9.0, 0.0,-8.0/9.0, -2.0/9.0, 0.0,-8.0/9.0, 0.0, 0.0,-8.0/9.0, 2.0/9.0, 0.0,-8.0/9.0, 4.0/9.0, 0.0,-8.0/9.0, 6.0/9.0, 0.0,-8.0/9.0, 8.0/9.0, 0.0,-8.0/9.0, -8.0/9.0, 2.0/9.0,-8.0/9.0, -6.0/9.0, 2.0/9.0,-8.0/9.0, -4.0/9.0, 2.0/9.0,-8.0/9.0, -2.0/9.0, 2.0/9.0,-8.0/9.0, 0.0, 2.0/9.0,-8.0/9.0, 2.0/9.0, 2.0/9.0,-8.0/9.0, 4.0/9.0, 2.0/9.0,-8.0/9.0, 6.0/9.0, 2.0/9.0,-8.0/9.0, 8.0/9.0, 2.0/9.0,-8.0/9.0, -8.0/9.0, 4.0/9.0,-8.0/9.0, -6.0/9.0, 4.0/9.0,-8.0/9.0, -4.0/9.0, 4.0/9.0,-8.0/9.0, -2.0/9.0, 4.0/9.0,-8.0/9.0, 0.0, 4.0/9.0,-8.0/9.0, 2.0/9.0, 4.0/9.0,-8.0/9.0, 4.0/9.0, 4.0/9.0,-8.0/9.0, 6.0/9.0, 4.0/9.0,-8.0/9.0, 8.0/9.0, 4.0/9.0,-8.0/9.0, -8.0/9.0, 6.0/9.0,-8.0/9.0, -6.0/9.0, 6.0/9.0,-8.0/9.0, -4.0/9.0, 6.0/9.0,-8.0/9.0, -2.0/9.0, 6.0/9.0,-8.0/9.0, 0.0, 6.0/9.0,-8.0/9.0, 2.0/9.0, 6.0/9.0,-8.0/9.0, 4.0/9.0, 6.0/9.0,-8.0/9.0, 6.0/9.0, 6.0/9.0,-8.0/9.0, 8.0/9.0, 6.0/9.0,-8.0/9.0, -8.0/9.0, 8.0/9.0,-8.0/9.0, -6.0/9.0, 8.0/9.0,-8.0/9.0, -4.0/9.0, 8.0/9.0,-8.0/9.0, -2.0/9.0, 8.0/9.0,-8.0/9.0, 0.0, 8.0/9.0,-8.0/9.0, 2.0/9.0, 8.0/9.0,-8.0/9.0, 4.0/9.0, 8.0/9.0,-8.0/9.0, 6.0/9.0, 8.0/9.0,-8.0/9.0, 8.0/9.0, 8.0/9.0,-8.0/9.0, -8.0/9.0,-8.0/9.0,-6.0/9.0, -6.0/9.0,-8.0/9.0,-6.0/9.0, -4.0/9.0,-8.0/9.0,-6.0/9.0, -2.0/9.0,-8.0/9.0,-6.0/9.0, 0.0,-8.0/9.0,-6.0/9.0, 2.0/9.0,-8.0/9.0,-6.0/9.0, 4.0/9.0,-8.0/9.0,-6.0/9.0, 6.0/9.0,-8.0/9.0,-6.0/9.0, 8.0/9.0,-8.0/9.0,-6.0/9.0, -8.0/9.0,-6.0/9.0,-6.0/9.0, -6.0/9.0,-6.0/9.0,-6.0/9.0, -4.0/9.0,-6.0/9.0,-6.0/9.0, -2.0/9.0,-6.0/9.0,-6.0/9.0, 0.0,-6.0/9.0,-6.0/9.0, 2.0/9.0,-6.0/9.0,-6.0/9.0, 4.0/9.0,-6.0/9.0,-6.0/9.0, 6.0/9.0,-6.0/9.0,-6.0/9.0, 8.0/9.0,-6.0/9.0,-6.0/9.0, -8.0/9.0,-4.0/9.0,-6.0/9.0, -6.0/9.0,-4.0/9.0,-6.0/9.0, -4.0/9.0,-4.0/9.0,-6.0/9.0, -2.0/9.0,-4.0/9.0,-6.0/9.0, 0.0,-4.0/9.0,-6.0/9.0, 2.0/9.0,-4.0/9.0,-6.0/9.0, 4.0/9.0,-4.0/9.0,-6.0/9.0, 6.0/9.0,-4.0/9.0,-6.0/9.0, 8.0/9.0,-4.0/9.0,-6.0/9.0, -8.0/9.0,-2.0/9.0,-6.0/9.0, -6.0/9.0,-2.0/9.0,-6.0/9.0, -4.0/9.0,-2.0/9.0,-6.0/9.0, -2.0/9.0,-2.0/9.0,-6.0/9.0, 0.0,-2.0/9.0,-6.0/9.0, 2.0/9.0,-2.0/9.0,-6.0/9.0, 4.0/9.0,-2.0/9.0,-6.0/9.0, 6.0/9.0,-2.0/9.0,-6.0/9.0, 8.0/9.0,-2.0/9.0,-6.0/9.0, -8.0/9.0, 0.0,-6.0/9.0, -6.0/9.0, 0.0,-6.0/9.0, -4.0/9.0, 0.0,-6.0/9.0, -2.0/9.0, 0.0,-6.0/9.0, 0.0, 0.0,-6.0/9.0, 2.0/9.0, 0.0,-6.0/9.0, 4.0/9.0, 0.0,-6.0/9.0, 6.0/9.0, 0.0,-6.0/9.0, 8.0/9.0, 0.0,-6.0/9.0, -8.0/9.0, 2.0/9.0,-6.0/9.0, -6.0/9.0, 2.0/9.0,-6.0/9.0, -4.0/9.0, 2.0/9.0,-6.0/9.0, -2.0/9.0, 2.0/9.0,-6.0/9.0, 0.0, 2.0/9.0,-6.0/9.0, 2.0/9.0, 2.0/9.0,-6.0/9.0, 4.0/9.0, 2.0/9.0,-6.0/9.0, 6.0/9.0, 2.0/9.0,-6.0/9.0, 8.0/9.0, 2.0/9.0,-6.0/9.0, -8.0/9.0, 4.0/9.0,-6.0/9.0, -6.0/9.0, 4.0/9.0,-6.0/9.0, -4.0/9.0, 4.0/9.0,-6.0/9.0, -2.0/9.0, 4.0/9.0,-6.0/9.0, 0.0, 4.0/9.0,-6.0/9.0, 2.0/9.0, 4.0/9.0,-6.0/9.0, 4.0/9.0, 4.0/9.0,-6.0/9.0, 6.0/9.0, 4.0/9.0,-6.0/9.0, 8.0/9.0, 4.0/9.0,-6.0/9.0, -8.0/9.0, 6.0/9.0,-6.0/9.0, -6.0/9.0, 6.0/9.0,-6.0/9.0, -4.0/9.0, 6.0/9.0,-6.0/9.0, -2.0/9.0, 6.0/9.0,-6.0/9.0, 0.0, 6.0/9.0,-6.0/9.0, 2.0/9.0, 6.0/9.0,-6.0/9.0, 4.0/9.0, 6.0/9.0,-6.0/9.0, 6.0/9.0, 6.0/9.0,-6.0/9.0, 8.0/9.0, 6.0/9.0,-6.0/9.0, -8.0/9.0, 8.0/9.0,-6.0/9.0, -6.0/9.0, 8.0/9.0,-6.0/9.0, -4.0/9.0, 8.0/9.0,-6.0/9.0, -2.0/9.0, 8.0/9.0,-6.0/9.0, 0.0, 8.0/9.0,-6.0/9.0, 2.0/9.0, 8.0/9.0,-6.0/9.0, 4.0/9.0, 8.0/9.0,-6.0/9.0, 6.0/9.0, 8.0/9.0,-6.0/9.0, 8.0/9.0, 8.0/9.0,-6.0/9.0, -8.0/9.0,-8.0/9.0,-4.0/9.0, -6.0/9.0,-8.0/9.0,-4.0/9.0, -4.0/9.0,-8.0/9.0,-4.0/9.0, -2.0/9.0,-8.0/9.0,-4.0/9.0, 0.0,-8.0/9.0,-4.0/9.0, 2.0/9.0,-8.0/9.0,-4.0/9.0, 4.0/9.0,-8.0/9.0,-4.0/9.0, 6.0/9.0,-8.0/9.0,-4.0/9.0, 8.0/9.0,-8.0/9.0,-4.0/9.0, -8.0/9.0,-6.0/9.0,-4.0/9.0, -6.0/9.0,-6.0/9.0,-4.0/9.0, -4.0/9.0,-6.0/9.0,-4.0/9.0, -2.0/9.0,-6.0/9.0,-4.0/9.0, 0.0,-6.0/9.0,-4.0/9.0, 2.0/9.0,-6.0/9.0,-4.0/9.0, 4.0/9.0,-6.0/9.0,-4.0/9.0, 6.0/9.0,-6.0/9.0,-4.0/9.0, 8.0/9.0,-6.0/9.0,-4.0/9.0, -8.0/9.0,-4.0/9.0,-4.0/9.0, -6.0/9.0,-4.0/9.0,-4.0/9.0, -4.0/9.0,-4.0/9.0,-4.0/9.0, -2.0/9.0,-4.0/9.0,-4.0/9.0, 0.0,-4.0/9.0,-4.0/9.0, 2.0/9.0,-4.0/9.0,-4.0/9.0, 4.0/9.0,-4.0/9.0,-4.0/9.0, 6.0/9.0,-4.0/9.0,-4.0/9.0, 8.0/9.0,-4.0/9.0,-4.0/9.0, -8.0/9.0,-2.0/9.0,-4.0/9.0, -6.0/9.0,-2.0/9.0,-4.0/9.0, -4.0/9.0,-2.0/9.0,-4.0/9.0, -2.0/9.0,-2.0/9.0,-4.0/9.0, 0.0,-2.0/9.0,-4.0/9.0, 2.0/9.0,-2.0/9.0,-4.0/9.0, 4.0/9.0,-2.0/9.0,-4.0/9.0, 6.0/9.0,-2.0/9.0,-4.0/9.0, 8.0/9.0,-2.0/9.0,-4.0/9.0, -8.0/9.0, 0.0,-4.0/9.0, -6.0/9.0, 0.0,-4.0/9.0, -4.0/9.0, 0.0,-4.0/9.0, -2.0/9.0, 0.0,-4.0/9.0, 0.0, 0.0,-4.0/9.0, 2.0/9.0, 0.0,-4.0/9.0, 4.0/9.0, 0.0,-4.0/9.0, 6.0/9.0, 0.0,-4.0/9.0, 8.0/9.0, 0.0,-4.0/9.0, -8.0/9.0, 2.0/9.0,-4.0/9.0, -6.0/9.0, 2.0/9.0,-4.0/9.0, -4.0/9.0, 2.0/9.0,-4.0/9.0, -2.0/9.0, 2.0/9.0,-4.0/9.0, 0.0, 2.0/9.0,-4.0/9.0, 2.0/9.0, 2.0/9.0,-4.0/9.0, 4.0/9.0, 2.0/9.0,-4.0/9.0, 6.0/9.0, 2.0/9.0,-4.0/9.0, 8.0/9.0, 2.0/9.0,-4.0/9.0, -8.0/9.0, 4.0/9.0,-4.0/9.0, -6.0/9.0, 4.0/9.0,-4.0/9.0, -4.0/9.0, 4.0/9.0,-4.0/9.0, -2.0/9.0, 4.0/9.0,-4.0/9.0, 0.0, 4.0/9.0,-4.0/9.0, 2.0/9.0, 4.0/9.0,-4.0/9.0, 4.0/9.0, 4.0/9.0,-4.0/9.0, 6.0/9.0, 4.0/9.0,-4.0/9.0, 8.0/9.0, 4.0/9.0,-4.0/9.0, -8.0/9.0, 6.0/9.0,-4.0/9.0, -6.0/9.0, 6.0/9.0,-4.0/9.0, -4.0/9.0, 6.0/9.0,-4.0/9.0, -2.0/9.0, 6.0/9.0,-4.0/9.0, 0.0, 6.0/9.0,-4.0/9.0, 2.0/9.0, 6.0/9.0,-4.0/9.0, 4.0/9.0, 6.0/9.0,-4.0/9.0, 6.0/9.0, 6.0/9.0,-4.0/9.0, 8.0/9.0, 6.0/9.0,-4.0/9.0, -8.0/9.0, 8.0/9.0,-4.0/9.0, -6.0/9.0, 8.0/9.0,-4.0/9.0, -4.0/9.0, 8.0/9.0,-4.0/9.0, -2.0/9.0, 8.0/9.0,-4.0/9.0, 0.0, 8.0/9.0,-4.0/9.0, 2.0/9.0, 8.0/9.0,-4.0/9.0, 4.0/9.0, 8.0/9.0,-4.0/9.0, 6.0/9.0, 8.0/9.0,-4.0/9.0, 8.0/9.0, 8.0/9.0,-4.0/9.0, -8.0/9.0,-8.0/9.0,-2.0/9.0, -6.0/9.0,-8.0/9.0,-2.0/9.0, -4.0/9.0,-8.0/9.0,-2.0/9.0, -2.0/9.0,-8.0/9.0,-2.0/9.0, 0.0,-8.0/9.0,-2.0/9.0, 2.0/9.0,-8.0/9.0,-2.0/9.0, 4.0/9.0,-8.0/9.0,-2.0/9.0, 6.0/9.0,-8.0/9.0,-2.0/9.0, 8.0/9.0,-8.0/9.0,-2.0/9.0, -8.0/9.0,-6.0/9.0,-2.0/9.0, -6.0/9.0,-6.0/9.0,-2.0/9.0, -4.0/9.0,-6.0/9.0,-2.0/9.0, -2.0/9.0,-6.0/9.0,-2.0/9.0, 0.0,-6.0/9.0,-2.0/9.0, 2.0/9.0,-6.0/9.0,-2.0/9.0, 4.0/9.0,-6.0/9.0,-2.0/9.0, 6.0/9.0,-6.0/9.0,-2.0/9.0, 8.0/9.0,-6.0/9.0,-2.0/9.0, -8.0/9.0,-4.0/9.0,-2.0/9.0, -6.0/9.0,-4.0/9.0,-2.0/9.0, -4.0/9.0,-4.0/9.0,-2.0/9.0, -2.0/9.0,-4.0/9.0,-2.0/9.0, 0.0,-4.0/9.0,-2.0/9.0, 2.0/9.0,-4.0/9.0,-2.0/9.0, 4.0/9.0,-4.0/9.0,-2.0/9.0, 6.0/9.0,-4.0/9.0,-2.0/9.0, 8.0/9.0,-4.0/9.0,-2.0/9.0, -8.0/9.0,-2.0/9.0,-2.0/9.0, -6.0/9.0,-2.0/9.0,-2.0/9.0, -4.0/9.0,-2.0/9.0,-2.0/9.0, -2.0/9.0,-2.0/9.0,-2.0/9.0, 0.0,-2.0/9.0,-2.0/9.0, 2.0/9.0,-2.0/9.0,-2.0/9.0, 4.0/9.0,-2.0/9.0,-2.0/9.0, 6.0/9.0,-2.0/9.0,-2.0/9.0, 8.0/9.0,-2.0/9.0,-2.0/9.0, -8.0/9.0, 0.0,-2.0/9.0, -6.0/9.0, 0.0,-2.0/9.0, -4.0/9.0, 0.0,-2.0/9.0, -2.0/9.0, 0.0,-2.0/9.0, 0.0, 0.0,-2.0/9.0, 2.0/9.0, 0.0,-2.0/9.0, 4.0/9.0, 0.0,-2.0/9.0, 6.0/9.0, 0.0,-2.0/9.0, 8.0/9.0, 0.0,-2.0/9.0, -8.0/9.0, 2.0/9.0,-2.0/9.0, -6.0/9.0, 2.0/9.0,-2.0/9.0, -4.0/9.0, 2.0/9.0,-2.0/9.0, -2.0/9.0, 2.0/9.0,-2.0/9.0, 0.0, 2.0/9.0,-2.0/9.0, 2.0/9.0, 2.0/9.0,-2.0/9.0, 4.0/9.0, 2.0/9.0,-2.0/9.0, 6.0/9.0, 2.0/9.0,-2.0/9.0, 8.0/9.0, 2.0/9.0,-2.0/9.0, -8.0/9.0, 4.0/9.0,-2.0/9.0, -6.0/9.0, 4.0/9.0,-2.0/9.0, -4.0/9.0, 4.0/9.0,-2.0/9.0, -2.0/9.0, 4.0/9.0,-2.0/9.0, 0.0, 4.0/9.0,-2.0/9.0, 2.0/9.0, 4.0/9.0,-2.0/9.0, 4.0/9.0, 4.0/9.0,-2.0/9.0, 6.0/9.0, 4.0/9.0,-2.0/9.0, 8.0/9.0, 4.0/9.0,-2.0/9.0, -8.0/9.0, 6.0/9.0,-2.0/9.0, -6.0/9.0, 6.0/9.0,-2.0/9.0, -4.0/9.0, 6.0/9.0,-2.0/9.0, -2.0/9.0, 6.0/9.0,-2.0/9.0, 0.0, 6.0/9.0,-2.0/9.0, 2.0/9.0, 6.0/9.0,-2.0/9.0, 4.0/9.0, 6.0/9.0,-2.0/9.0, 6.0/9.0, 6.0/9.0,-2.0/9.0, 8.0/9.0, 6.0/9.0,-2.0/9.0, -8.0/9.0, 8.0/9.0,-2.0/9.0, -6.0/9.0, 8.0/9.0,-2.0/9.0, -4.0/9.0, 8.0/9.0,-2.0/9.0, -2.0/9.0, 8.0/9.0,-2.0/9.0, 0.0, 8.0/9.0,-2.0/9.0, 2.0/9.0, 8.0/9.0,-2.0/9.0, 4.0/9.0, 8.0/9.0,-2.0/9.0, 6.0/9.0, 8.0/9.0,-2.0/9.0, 8.0/9.0, 8.0/9.0,-2.0/9.0, -8.0/9.0,-8.0/9.0, 0.0, -6.0/9.0,-8.0/9.0, 0.0, -4.0/9.0,-8.0/9.0, 0.0, -2.0/9.0,-8.0/9.0, 0.0, 0.0,-8.0/9.0, 0.0, 2.0/9.0,-8.0/9.0, 0.0, 4.0/9.0,-8.0/9.0, 0.0, 6.0/9.0,-8.0/9.0, 0.0, 8.0/9.0,-8.0/9.0, 0.0, -8.0/9.0,-6.0/9.0, 0.0, -6.0/9.0,-6.0/9.0, 0.0, -4.0/9.0,-6.0/9.0, 0.0, -2.0/9.0,-6.0/9.0, 0.0, 0.0,-6.0/9.0, 0.0, 2.0/9.0,-6.0/9.0, 0.0, 4.0/9.0,-6.0/9.0, 0.0, 6.0/9.0,-6.0/9.0, 0.0, 8.0/9.0,-6.0/9.0, 0.0, -8.0/9.0,-4.0/9.0, 0.0, -6.0/9.0,-4.0/9.0, 0.0, -4.0/9.0,-4.0/9.0, 0.0, -2.0/9.0,-4.0/9.0, 0.0, 0.0,-4.0/9.0, 0.0, 2.0/9.0,-4.0/9.0, 0.0, 4.0/9.0,-4.0/9.0, 0.0, 6.0/9.0,-4.0/9.0, 0.0, 8.0/9.0,-4.0/9.0, 0.0, -8.0/9.0,-2.0/9.0, 0.0, -6.0/9.0,-2.0/9.0, 0.0, -4.0/9.0,-2.0/9.0, 0.0, -2.0/9.0,-2.0/9.0, 0.0, 0.0,-2.0/9.0, 0.0, 2.0/9.0,-2.0/9.0, 0.0, 4.0/9.0,-2.0/9.0, 0.0, 6.0/9.0,-2.0/9.0, 0.0, 8.0/9.0,-2.0/9.0, 0.0, -8.0/9.0, 0.0, 0.0, -6.0/9.0, 0.0, 0.0, -4.0/9.0, 0.0, 0.0, -2.0/9.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0/9.0, 0.0, 0.0, 4.0/9.0, 0.0, 0.0, 6.0/9.0, 0.0, 0.0, 8.0/9.0, 0.0, 0.0, -8.0/9.0, 2.0/9.0, 0.0, -6.0/9.0, 2.0/9.0, 0.0, -4.0/9.0, 2.0/9.0, 0.0, -2.0/9.0, 2.0/9.0, 0.0, 0.0, 2.0/9.0, 0.0, 2.0/9.0, 2.0/9.0, 0.0, 4.0/9.0, 2.0/9.0, 0.0, 6.0/9.0, 2.0/9.0, 0.0, 8.0/9.0, 2.0/9.0, 0.0, -8.0/9.0, 4.0/9.0, 0.0, -6.0/9.0, 4.0/9.0, 0.0, -4.0/9.0, 4.0/9.0, 0.0, -2.0/9.0, 4.0/9.0, 0.0, 0.0, 4.0/9.0, 0.0, 2.0/9.0, 4.0/9.0, 0.0, 4.0/9.0, 4.0/9.0, 0.0, 6.0/9.0, 4.0/9.0, 0.0, 8.0/9.0, 4.0/9.0, 0.0, -8.0/9.0, 6.0/9.0, 0.0, -6.0/9.0, 6.0/9.0, 0.0, -4.0/9.0, 6.0/9.0, 0.0, -2.0/9.0, 6.0/9.0, 0.0, 0.0, 6.0/9.0, 0.0, 2.0/9.0, 6.0/9.0, 0.0, 4.0/9.0, 6.0/9.0, 0.0, 6.0/9.0, 6.0/9.0, 0.0, 8.0/9.0, 6.0/9.0, 0.0, -8.0/9.0, 8.0/9.0, 0.0, -6.0/9.0, 8.0/9.0, 0.0, -4.0/9.0, 8.0/9.0, 0.0, -2.0/9.0, 8.0/9.0, 0.0, 0.0, 8.0/9.0, 0.0, 2.0/9.0, 8.0/9.0, 0.0, 4.0/9.0, 8.0/9.0, 0.0, 6.0/9.0, 8.0/9.0, 0.0, 8.0/9.0, 8.0/9.0, 0.0, -8.0/9.0,-8.0/9.0, 2.0/9.0, -6.0/9.0,-8.0/9.0, 2.0/9.0, -4.0/9.0,-8.0/9.0, 2.0/9.0, -2.0/9.0,-8.0/9.0, 2.0/9.0, 0.0,-8.0/9.0, 2.0/9.0, 2.0/9.0,-8.0/9.0, 2.0/9.0, 4.0/9.0,-8.0/9.0, 2.0/9.0, 6.0/9.0,-8.0/9.0, 2.0/9.0, 8.0/9.0,-8.0/9.0, 2.0/9.0, -8.0/9.0,-6.0/9.0, 2.0/9.0, -6.0/9.0,-6.0/9.0, 2.0/9.0, -4.0/9.0,-6.0/9.0, 2.0/9.0, -2.0/9.0,-6.0/9.0, 2.0/9.0, 0.0,-6.0/9.0, 2.0/9.0, 2.0/9.0,-6.0/9.0, 2.0/9.0, 4.0/9.0,-6.0/9.0, 2.0/9.0, 6.0/9.0,-6.0/9.0, 2.0/9.0, 8.0/9.0,-6.0/9.0, 2.0/9.0, -8.0/9.0,-4.0/9.0, 2.0/9.0, -6.0/9.0,-4.0/9.0, 2.0/9.0, -4.0/9.0,-4.0/9.0, 2.0/9.0, -2.0/9.0,-4.0/9.0, 2.0/9.0, 0.0,-4.0/9.0, 2.0/9.0, 2.0/9.0,-4.0/9.0, 2.0/9.0, 4.0/9.0,-4.0/9.0, 2.0/9.0, 6.0/9.0,-4.0/9.0, 2.0/9.0, 8.0/9.0,-4.0/9.0, 2.0/9.0, -8.0/9.0,-2.0/9.0, 2.0/9.0, -6.0/9.0,-2.0/9.0, 2.0/9.0, -4.0/9.0,-2.0/9.0, 2.0/9.0, -2.0/9.0,-2.0/9.0, 2.0/9.0, 0.0,-2.0/9.0, 2.0/9.0, 2.0/9.0,-2.0/9.0, 2.0/9.0, 4.0/9.0,-2.0/9.0, 2.0/9.0, 6.0/9.0,-2.0/9.0, 2.0/9.0, 8.0/9.0,-2.0/9.0, 2.0/9.0, -8.0/9.0, 0.0, 2.0/9.0, -6.0/9.0, 0.0, 2.0/9.0, -4.0/9.0, 0.0, 2.0/9.0, -2.0/9.0, 0.0, 2.0/9.0, 0.0, 0.0, 2.0/9.0, 2.0/9.0, 0.0, 2.0/9.0, 4.0/9.0, 0.0, 2.0/9.0, 6.0/9.0, 0.0, 2.0/9.0, 8.0/9.0, 0.0, 2.0/9.0, -8.0/9.0, 2.0/9.0, 2.0/9.0, -6.0/9.0, 2.0/9.0, 2.0/9.0, -4.0/9.0, 2.0/9.0, 2.0/9.0, -2.0/9.0, 2.0/9.0, 2.0/9.0, 0.0, 2.0/9.0, 2.0/9.0, 2.0/9.0, 2.0/9.0, 2.0/9.0, 4.0/9.0, 2.0/9.0, 2.0/9.0, 6.0/9.0, 2.0/9.0, 2.0/9.0, 8.0/9.0, 2.0/9.0, 2.0/9.0, -8.0/9.0, 4.0/9.0, 2.0/9.0, -6.0/9.0, 4.0/9.0, 2.0/9.0, -4.0/9.0, 4.0/9.0, 2.0/9.0, -2.0/9.0, 4.0/9.0, 2.0/9.0, 0.0, 4.0/9.0, 2.0/9.0, 2.0/9.0, 4.0/9.0, 2.0/9.0, 4.0/9.0, 4.0/9.0, 2.0/9.0, 6.0/9.0, 4.0/9.0, 2.0/9.0, 8.0/9.0, 4.0/9.0, 2.0/9.0, -8.0/9.0, 6.0/9.0, 2.0/9.0, -6.0/9.0, 6.0/9.0, 2.0/9.0, -4.0/9.0, 6.0/9.0, 2.0/9.0, -2.0/9.0, 6.0/9.0, 2.0/9.0, 0.0, 6.0/9.0, 2.0/9.0, 2.0/9.0, 6.0/9.0, 2.0/9.0, 4.0/9.0, 6.0/9.0, 2.0/9.0, 6.0/9.0, 6.0/9.0, 2.0/9.0, 8.0/9.0, 6.0/9.0, 2.0/9.0, -8.0/9.0, 8.0/9.0, 2.0/9.0, -6.0/9.0, 8.0/9.0, 2.0/9.0, -4.0/9.0, 8.0/9.0, 2.0/9.0, -2.0/9.0, 8.0/9.0, 2.0/9.0, 0.0, 8.0/9.0, 2.0/9.0, 2.0/9.0, 8.0/9.0, 2.0/9.0, 4.0/9.0, 8.0/9.0, 2.0/9.0, 6.0/9.0, 8.0/9.0, 2.0/9.0, 8.0/9.0, 8.0/9.0, 2.0/9.0, -8.0/9.0,-8.0/9.0, 4.0/9.0, -6.0/9.0,-8.0/9.0, 4.0/9.0, -4.0/9.0,-8.0/9.0, 4.0/9.0, -2.0/9.0,-8.0/9.0, 4.0/9.0, 0.0,-8.0/9.0, 4.0/9.0, 2.0/9.0,-8.0/9.0, 4.0/9.0, 4.0/9.0,-8.0/9.0, 4.0/9.0, 6.0/9.0,-8.0/9.0, 4.0/9.0, 8.0/9.0,-8.0/9.0, 4.0/9.0, -8.0/9.0,-6.0/9.0, 4.0/9.0, -6.0/9.0,-6.0/9.0, 4.0/9.0, -4.0/9.0,-6.0/9.0, 4.0/9.0, -2.0/9.0,-6.0/9.0, 4.0/9.0, 0.0,-6.0/9.0, 4.0/9.0, 2.0/9.0,-6.0/9.0, 4.0/9.0, 4.0/9.0,-6.0/9.0, 4.0/9.0, 6.0/9.0,-6.0/9.0, 4.0/9.0, 8.0/9.0,-6.0/9.0, 4.0/9.0, -8.0/9.0,-4.0/9.0, 4.0/9.0, -6.0/9.0,-4.0/9.0, 4.0/9.0, -4.0/9.0,-4.0/9.0, 4.0/9.0, -2.0/9.0,-4.0/9.0, 4.0/9.0, 0.0,-4.0/9.0, 4.0/9.0, 2.0/9.0,-4.0/9.0, 4.0/9.0, 4.0/9.0,-4.0/9.0, 4.0/9.0, 6.0/9.0,-4.0/9.0, 4.0/9.0, 8.0/9.0,-4.0/9.0, 4.0/9.0, -8.0/9.0,-2.0/9.0, 4.0/9.0, -6.0/9.0,-2.0/9.0, 4.0/9.0, -4.0/9.0,-2.0/9.0, 4.0/9.0, -2.0/9.0,-2.0/9.0, 4.0/9.0, 0.0,-2.0/9.0, 4.0/9.0, 2.0/9.0,-2.0/9.0, 4.0/9.0, 4.0/9.0,-2.0/9.0, 4.0/9.0, 6.0/9.0,-2.0/9.0, 4.0/9.0, 8.0/9.0,-2.0/9.0, 4.0/9.0, -8.0/9.0, 0.0, 4.0/9.0, -6.0/9.0, 0.0, 4.0/9.0, -4.0/9.0, 0.0, 4.0/9.0, -2.0/9.0, 0.0, 4.0/9.0, 0.0, 0.0, 4.0/9.0, 2.0/9.0, 0.0, 4.0/9.0, 4.0/9.0, 0.0, 4.0/9.0, 6.0/9.0, 0.0, 4.0/9.0, 8.0/9.0, 0.0, 4.0/9.0, -8.0/9.0, 2.0/9.0, 4.0/9.0, -6.0/9.0, 2.0/9.0, 4.0/9.0, -4.0/9.0, 2.0/9.0, 4.0/9.0, -2.0/9.0, 2.0/9.0, 4.0/9.0, 0.0, 2.0/9.0, 4.0/9.0, 2.0/9.0, 2.0/9.0, 4.0/9.0, 4.0/9.0, 2.0/9.0, 4.0/9.0, 6.0/9.0, 2.0/9.0, 4.0/9.0, 8.0/9.0, 2.0/9.0, 4.0/9.0, -8.0/9.0, 4.0/9.0, 4.0/9.0, -6.0/9.0, 4.0/9.0, 4.0/9.0, -4.0/9.0, 4.0/9.0, 4.0/9.0, -2.0/9.0, 4.0/9.0, 4.0/9.0, 0.0, 4.0/9.0, 4.0/9.0, 2.0/9.0, 4.0/9.0, 4.0/9.0, 4.0/9.0, 4.0/9.0, 4.0/9.0, 6.0/9.0, 4.0/9.0, 4.0/9.0, 8.0/9.0, 4.0/9.0, 4.0/9.0, -8.0/9.0, 6.0/9.0, 4.0/9.0, -6.0/9.0, 6.0/9.0, 4.0/9.0, -4.0/9.0, 6.0/9.0, 4.0/9.0, -2.0/9.0, 6.0/9.0, 4.0/9.0, 0.0, 6.0/9.0, 4.0/9.0, 2.0/9.0, 6.0/9.0, 4.0/9.0, 4.0/9.0, 6.0/9.0, 4.0/9.0, 6.0/9.0, 6.0/9.0, 4.0/9.0, 8.0/9.0, 6.0/9.0, 4.0/9.0, -8.0/9.0, 8.0/9.0, 4.0/9.0, -6.0/9.0, 8.0/9.0, 4.0/9.0, -4.0/9.0, 8.0/9.0, 4.0/9.0, -2.0/9.0, 8.0/9.0, 4.0/9.0, 0.0, 8.0/9.0, 4.0/9.0, 2.0/9.0, 8.0/9.0, 4.0/9.0, 4.0/9.0, 8.0/9.0, 4.0/9.0, 6.0/9.0, 8.0/9.0, 4.0/9.0, 8.0/9.0, 8.0/9.0, 4.0/9.0, -8.0/9.0,-8.0/9.0, 6.0/9.0, -6.0/9.0,-8.0/9.0, 6.0/9.0, -4.0/9.0,-8.0/9.0, 6.0/9.0, -2.0/9.0,-8.0/9.0, 6.0/9.0, 0.0,-8.0/9.0, 6.0/9.0, 2.0/9.0,-8.0/9.0, 6.0/9.0, 4.0/9.0,-8.0/9.0, 6.0/9.0, 6.0/9.0,-8.0/9.0, 6.0/9.0, 8.0/9.0,-8.0/9.0, 6.0/9.0, -8.0/9.0,-6.0/9.0, 6.0/9.0, -6.0/9.0,-6.0/9.0, 6.0/9.0, -4.0/9.0,-6.0/9.0, 6.0/9.0, -2.0/9.0,-6.0/9.0, 6.0/9.0, 0.0,-6.0/9.0, 6.0/9.0, 2.0/9.0,-6.0/9.0, 6.0/9.0, 4.0/9.0,-6.0/9.0, 6.0/9.0, 6.0/9.0,-6.0/9.0, 6.0/9.0, 8.0/9.0,-6.0/9.0, 6.0/9.0, -8.0/9.0,-4.0/9.0, 6.0/9.0, -6.0/9.0,-4.0/9.0, 6.0/9.0, -4.0/9.0,-4.0/9.0, 6.0/9.0, -2.0/9.0,-4.0/9.0, 6.0/9.0, 0.0,-4.0/9.0, 6.0/9.0, 2.0/9.0,-4.0/9.0, 6.0/9.0, 4.0/9.0,-4.0/9.0, 6.0/9.0, 6.0/9.0,-4.0/9.0, 6.0/9.0, 8.0/9.0,-4.0/9.0, 6.0/9.0, -8.0/9.0,-2.0/9.0, 6.0/9.0, -6.0/9.0,-2.0/9.0, 6.0/9.0, -4.0/9.0,-2.0/9.0, 6.0/9.0, -2.0/9.0,-2.0/9.0, 6.0/9.0, 0.0,-2.0/9.0, 6.0/9.0, 2.0/9.0,-2.0/9.0, 6.0/9.0, 4.0/9.0,-2.0/9.0, 6.0/9.0, 6.0/9.0,-2.0/9.0, 6.0/9.0, 8.0/9.0,-2.0/9.0, 6.0/9.0, -8.0/9.0, 0.0, 6.0/9.0, -6.0/9.0, 0.0, 6.0/9.0, -4.0/9.0, 0.0, 6.0/9.0, -2.0/9.0, 0.0, 6.0/9.0, 0.0, 0.0, 6.0/9.0, 2.0/9.0, 0.0, 6.0/9.0, 4.0/9.0, 0.0, 6.0/9.0, 6.0/9.0, 0.0, 6.0/9.0, 8.0/9.0, 0.0, 6.0/9.0, -8.0/9.0, 2.0/9.0, 6.0/9.0, -6.0/9.0, 2.0/9.0, 6.0/9.0, -4.0/9.0, 2.0/9.0, 6.0/9.0, -2.0/9.0, 2.0/9.0, 6.0/9.0, 0.0, 2.0/9.0, 6.0/9.0, 2.0/9.0, 2.0/9.0, 6.0/9.0, 4.0/9.0, 2.0/9.0, 6.0/9.0, 6.0/9.0, 2.0/9.0, 6.0/9.0, 8.0/9.0, 2.0/9.0, 6.0/9.0, -8.0/9.0, 4.0/9.0, 6.0/9.0, -6.0/9.0, 4.0/9.0, 6.0/9.0, -4.0/9.0, 4.0/9.0, 6.0/9.0, -2.0/9.0, 4.0/9.0, 6.0/9.0, 0.0, 4.0/9.0, 6.0/9.0, 2.0/9.0, 4.0/9.0, 6.0/9.0, 4.0/9.0, 4.0/9.0, 6.0/9.0, 6.0/9.0, 4.0/9.0, 6.0/9.0, 8.0/9.0, 4.0/9.0, 6.0/9.0, -8.0/9.0, 6.0/9.0, 6.0/9.0, -6.0/9.0, 6.0/9.0, 6.0/9.0, -4.0/9.0, 6.0/9.0, 6.0/9.0, -2.0/9.0, 6.0/9.0, 6.0/9.0, 0.0, 6.0/9.0, 6.0/9.0, 2.0/9.0, 6.0/9.0, 6.0/9.0, 4.0/9.0, 6.0/9.0, 6.0/9.0, 6.0/9.0, 6.0/9.0, 6.0/9.0, 8.0/9.0, 6.0/9.0, 6.0/9.0, -8.0/9.0, 8.0/9.0, 6.0/9.0, -6.0/9.0, 8.0/9.0, 6.0/9.0, -4.0/9.0, 8.0/9.0, 6.0/9.0, -2.0/9.0, 8.0/9.0, 6.0/9.0, 0.0, 8.0/9.0, 6.0/9.0, 2.0/9.0, 8.0/9.0, 6.0/9.0, 4.0/9.0, 8.0/9.0, 6.0/9.0, 6.0/9.0, 8.0/9.0, 6.0/9.0, 8.0/9.0, 8.0/9.0, 6.0/9.0, -8.0/9.0,-8.0/9.0, 8.0/9.0, -6.0/9.0,-8.0/9.0, 8.0/9.0, -4.0/9.0,-8.0/9.0, 8.0/9.0, -2.0/9.0,-8.0/9.0, 8.0/9.0, 0.0,-8.0/9.0, 8.0/9.0, 2.0/9.0,-8.0/9.0, 8.0/9.0, 4.0/9.0,-8.0/9.0, 8.0/9.0, 6.0/9.0,-8.0/9.0, 8.0/9.0, 8.0/9.0,-8.0/9.0, 8.0/9.0, -8.0/9.0,-6.0/9.0, 8.0/9.0, -6.0/9.0,-6.0/9.0, 8.0/9.0, -4.0/9.0,-6.0/9.0, 8.0/9.0, -2.0/9.0,-6.0/9.0, 8.0/9.0, 0.0,-6.0/9.0, 8.0/9.0, 2.0/9.0,-6.0/9.0, 8.0/9.0, 4.0/9.0,-6.0/9.0, 8.0/9.0, 6.0/9.0,-6.0/9.0, 8.0/9.0, 8.0/9.0,-6.0/9.0, 8.0/9.0, -8.0/9.0,-4.0/9.0, 8.0/9.0, -6.0/9.0,-4.0/9.0, 8.0/9.0, -4.0/9.0,-4.0/9.0, 8.0/9.0, -2.0/9.0,-4.0/9.0, 8.0/9.0, 0.0,-4.0/9.0, 8.0/9.0, 2.0/9.0,-4.0/9.0, 8.0/9.0, 4.0/9.0,-4.0/9.0, 8.0/9.0, 6.0/9.0,-4.0/9.0, 8.0/9.0, 8.0/9.0,-4.0/9.0, 8.0/9.0, -8.0/9.0,-2.0/9.0, 8.0/9.0, -6.0/9.0,-2.0/9.0, 8.0/9.0, -4.0/9.0,-2.0/9.0, 8.0/9.0, -2.0/9.0,-2.0/9.0, 8.0/9.0, 0.0,-2.0/9.0, 8.0/9.0, 2.0/9.0,-2.0/9.0, 8.0/9.0, 4.0/9.0,-2.0/9.0, 8.0/9.0, 6.0/9.0,-2.0/9.0, 8.0/9.0, 8.0/9.0,-2.0/9.0, 8.0/9.0, -8.0/9.0, 0.0, 8.0/9.0, -6.0/9.0, 0.0, 8.0/9.0, -4.0/9.0, 0.0, 8.0/9.0, -2.0/9.0, 0.0, 8.0/9.0, 0.0, 0.0, 8.0/9.0, 2.0/9.0, 0.0, 8.0/9.0, 4.0/9.0, 0.0, 8.0/9.0, 6.0/9.0, 0.0, 8.0/9.0, 8.0/9.0, 0.0, 8.0/9.0, -8.0/9.0, 2.0/9.0, 8.0/9.0, -6.0/9.0, 2.0/9.0, 8.0/9.0, -4.0/9.0, 2.0/9.0, 8.0/9.0, -2.0/9.0, 2.0/9.0, 8.0/9.0, 0.0, 2.0/9.0, 8.0/9.0, 2.0/9.0, 2.0/9.0, 8.0/9.0, 4.0/9.0, 2.0/9.0, 8.0/9.0, 6.0/9.0, 2.0/9.0, 8.0/9.0, 8.0/9.0, 2.0/9.0, 8.0/9.0, -8.0/9.0, 4.0/9.0, 8.0/9.0, -6.0/9.0, 4.0/9.0, 8.0/9.0, -4.0/9.0, 4.0/9.0, 8.0/9.0, -2.0/9.0, 4.0/9.0, 8.0/9.0, 0.0, 4.0/9.0, 8.0/9.0, 2.0/9.0, 4.0/9.0, 8.0/9.0, 4.0/9.0, 4.0/9.0, 8.0/9.0, 6.0/9.0, 4.0/9.0, 8.0/9.0, 8.0/9.0, 4.0/9.0, 8.0/9.0, -8.0/9.0, 6.0/9.0, 8.0/9.0, -6.0/9.0, 6.0/9.0, 8.0/9.0, -4.0/9.0, 6.0/9.0, 8.0/9.0, -2.0/9.0, 6.0/9.0, 8.0/9.0, 0.0, 6.0/9.0, 8.0/9.0, 2.0/9.0, 6.0/9.0, 8.0/9.0, 4.0/9.0, 6.0/9.0, 8.0/9.0, 6.0/9.0, 6.0/9.0, 8.0/9.0, 8.0/9.0, 6.0/9.0, 8.0/9.0, -8.0/9.0, 8.0/9.0, 8.0/9.0, -6.0/9.0, 8.0/9.0, 8.0/9.0, -4.0/9.0, 8.0/9.0, 8.0/9.0, -2.0/9.0, 8.0/9.0, 8.0/9.0, 0.0, 8.0/9.0, 8.0/9.0, 2.0/9.0, 8.0/9.0, 8.0/9.0, 4.0/9.0, 8.0/9.0, 8.0/9.0, 6.0/9.0, 8.0/9.0, 8.0/9.0, 8.0/9.0, 8.0/9.0, 8.0/9.0 }; static const REAL *grouptableA[16] = { 0,group5bits,group7bits,group10bits,0,0,0,0,0,0,0,0,0,0,0,0}; static const REAL *grouptableB1[16] = { 0,group5bits,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; static const REAL *grouptableB234[16] = { 0,group5bits,group7bits,0,group10bits,0,0,0,0,0,0,0,0,0,0,0}; static const int codelengthtableA[16] = { 0, 5, 7, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; static const int codelengthtableB1[16] = { 0, 5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; static const int codelengthtableB2[16] = { 0, 5, 7, 3, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 }; static const int codelengthtableB3[8] = { 0, 5, 7, 3, 10, 4, 5, 16 }; static const int codelengthtableB4[4] = { 0, 5, 7, 16 }; static const REAL factortableA[16] = { 0.0, 1.0/2.0, 1.0/4.0, 1.0/8.0, 1.0/8.0, 1.0/16.0, 1.0/32.0, 1.0/64.0, 1.0/128.0, 1.0/256.0, 1.0/512.0, 1.0/1024.0, 1.0/2048.0, 1.0/4096.0, 1.0/8192.0, 1.0/16384.0 }; static const REAL factortableB1[16] = { 0.0, 1.0/2.0, 1.0/4.0, 1.0/8.0, 1.0/16.0, 1.0/32.0, 1.0/64.0, 1.0/128.0, 1.0/256.0, 1.0/512.0, 1.0/1024.0, 1.0/2048.0, 1.0/4096.0, 1.0/8192.0, 1.0/16384.0, 1.0/32768.0 }; static const REAL factortableB2[16] = { 0.0, 1.0/2.0, 1.0/4.0, 1.0/4.0, 1.0/8.0, 1.0/8.0, 1.0/16.0, 1.0/32.0, 1.0/64.0, 1.0/128.0, 1.0/256.0, 1.0/512.0, 1.0/1024.0, 1.0/2048.0, 1.0/4096.0, 1.0/32768.0 }; static const REAL factortableB3[8] = { 0.0, 1.0/2.0, 1.0/4.0, 1.0/4.0, 1.0/8.0, 1.0/8.0, 1.0/16.0, 1.0/32768.0 }; static const REAL factortableB4[4] = { 0.0, 1.0/2.0, 1.0/4.0, 1.0/32768.0 }; static const REAL ctableA[16]= { 0.0, 1.33333333333, 1.60000000000, 1.77777777777, 1.06666666666, 1.03225806452, 1.01587301587, 1.00787401575, 1.00392156863, 1.00195694716, 1.00097751711, 1.00048851979, 1.00024420024, 1.00012208522, 1.00006103888, 1.00003051851}; static const REAL ctableB1[16]= { 0.0, 1.33333333333, 1.14285714286, 1.06666666666, 1.03225806452, 1.01587301587, 1.00787401575, 1.00392156863, 1.00195694716, 1.00097751711, 1.00048851979, 1.00024420024, 1.00012208522, 1.00006103888, 1.00003051851, 1.00001525902}; static const REAL ctableB2[16] = { 0.0, 1.33333333333, 1.60000000000, 1.14285714286, 1.77777777777, 1.06666666666, 1.03225806452, 1.01587301587, 1.00787401575, 1.00392156863, 1.00195694716, 1.00097751711, 1.00048851979, 1.00024420024, 1.00012208522, 1.00001525902}; static const REAL ctableB3[8] = { 0.0, 1.33333333333, 1.60000000000, 1.14285714286, 1.77777777777, 1.06666666666, 1.03225806452, 1.00001525902 }; static const REAL ctableB4[4] = { 0.0, 1.33333333333, 1.60000000000, 1.00001525902 }; static const REAL dtableA[16]= { 0.0, 0.50000000000, 0.50000000000, 0.50000000000, 0.12500000000, 0.06250000000, 0.03125000000, 0.01562500000, 0.00781250000, 0.00390625000, 0.00195312500, 0.00097656250, 0.00048828125, 0.00024414063, 0.00012207031, 0.00006103516}; static const REAL dtableB1[16]= { 0.0, 0.50000000000, 0.25000000000, 0.12500000000, 0.06250000000, 0.03125000000, 0.01562500000, 0.00781250000, 0.00390625000, 0.00195312500, 0.00097656250, 0.00048828125, 0.00024414063, 0.00012207031, 0.00006103516, 0.00003051758}; static const REAL dtableB2[16]= { 0.0, 0.50000000000, 0.50000000000, 0.25000000000, 0.50000000000, 0.12500000000, 0.06250000000, 0.03125000000, 0.01562500000, 0.00781250000, 0.00390625000, 0.00195312500, 0.00097656250, 0.00048828125, 0.00024414063, 0.00003051758}; static const REAL dtableB3[8]= { 0.0, 0.50000000000, 0.50000000000, 0.25000000000, 0.50000000000, 0.12500000000, 0.06250000000, 0.00003051758}; static const REAL dtableB4[4]= {0.0, 0.50000000000, 0.50000000000, 0.00003051758}; // Mpeg layer 2 void Mpegtoraw::extractlayer2(void) { REAL fraction[MAXCHANNEL][3][MAXSUBBAND]; unsigned int bitalloc[MAXCHANNEL][MAXSUBBAND], scaleselector[MAXCHANNEL][MAXSUBBAND]; REAL scalefactor[2][3][MAXSUBBAND]; const REAL *group[MAXCHANNEL][MAXSUBBAND]; unsigned int codelength[MAXCHANNEL][MAXSUBBAND]; REAL factor[MAXCHANNEL][MAXSUBBAND]; REAL c[MAXCHANNEL][MAXSUBBAND],d[MAXCHANNEL][MAXSUBBAND]; int s=stereobound,n=subbandnumber; // Bitalloc { register int i; register const int *t=bitalloclengthtable[tableindex]; for(i=0;i>2][i]; fraction[LS][0][i]*=t; fraction[LS][1][i]*=t; fraction[LS][2][i]*=t; } if(bitalloc[RS][i]) { if(!group[RS][i]) { fraction[RS][0][i]=(fraction[RS][0][i]+d[RS][i])*c[LS][i]; fraction[RS][1][i]=(fraction[RS][1][i]+d[RS][i])*c[LS][i]; fraction[RS][2][i]=(fraction[RS][2][i]+d[RS][i])*c[LS][i]; } register REAL t=scalefactor[RS][l>>2][i]; fraction[RS][0][i]*=t; fraction[RS][1][i]*=t; fraction[RS][2][i]*=t; } } else for(i=0;i>2][i]; fraction[LS][0][i]*=t; fraction[LS][1][i]*=t; fraction[LS][2][i]*=t; } for(;i #include "cyclicbuffer.h" CyclicBuffer::CyclicBuffer(const unsigned int size) { this->buffer = new unsigned char[size]; this->bufferSize = size; this->readIndex = 0; this->writeIndex = 0; this->isFull = 0; #ifdef LIBPTH (void)pth_mutex_init(&rw_mutex); #elif defined(PTHREADEDMPEG) (void)pthread_mutex_init(&rw_mutex, NULL); #endif } CyclicBuffer::~CyclicBuffer() { delete[] buffer; } int CyclicBuffer::read(unsigned char * const buf, const unsigned int amount, const int partial) { unsigned int contentLength; unsigned int bytesRead; lock(); contentLength = this->contentSizeInternal(); if (contentLength < amount) { if (!partial) { //not enough to read. unlock(); return 0; } //partial read bytesRead = contentLength; } else { /* #bytes to read >= amount */ bytesRead = amount; } if (bytesRead > 0) { readData(buf, bytesRead); isFull = 0; //since we just read data, there's always space to write now } unlock(); return (int)bytesRead; } int CyclicBuffer::write(const unsigned char * const buf, const unsigned int amount, const int partial) { unsigned int emptySpace; unsigned int bytesWritten = 0; lock(); emptySpace = this->bufferSize - this->contentSizeInternal(); if (emptySpace == 0) { unlock(); return 0; //no space to write to } if (emptySpace < amount) { if (!partial) { unlock(); return 0; //not enough space to write to } //partial write bytesWritten = emptySpace; } else { bytesWritten = amount; } writeData(buf, bytesWritten); /* If we filled all of the buffer, toggle isFull. This is required since * it's otherwise impossible to tell if the buffer is full or empty when * the R/W pointers are equal! */ if (bytesWritten > 0 && this->readIndex == this->writeIndex) { isFull = 1; } unlock(); return (int)bytesWritten; } void CyclicBuffer::setEmpty() { lock(); this->readIndex = this->writeIndex; unlock(); } unsigned int CyclicBuffer::contentSize() { unsigned int returnValue; lock(); returnValue = contentSizeInternal(); unlock(); return returnValue; } /** * Returns the number of bytes in the buffer that contain data. The * empty space would then be the total bufer size minus the return value. * This function does not perform locking. */ unsigned int CyclicBuffer::contentSizeInternal() { if (this->readIndex == this->writeIndex) { // ____RW_____, either completely empty or completely filled if (isFull) { return this->bufferSize; } return 0; //no content } else if (this->readIndex < this->writeIndex) { // ___R******W___ return this->writeIndex - this->readIndex; } // ****W_______R**** /* readIndex > writeIndex. Content is from readIndex to end of buffer, * and start of buffer to writeIndex */ return (this->bufferSize - this->readIndex) + this->writeIndex; } unsigned int CyclicBuffer::emptySpace() { unsigned int returnValue; lock(); returnValue = emptySpaceInternal(); unlock(); return returnValue; } unsigned int CyclicBuffer::emptySpaceInternal() { return this->bufferSize - contentSizeInternal(); } unsigned int CyclicBuffer::size() { return bufferSize; } /* * Transfers data from the internal buffer into the supplied 'buf' * parameter. * * 'amount' must always be equal to, or less than, the contents in the * internal buffer. * * Adjusts internal buffer's read pointer. */ void CyclicBuffer::readData(unsigned char * const buf, const unsigned int amount) { unsigned int len; unsigned int toread = amount; unsigned int bytesRead = 0; /* area of bytes from read pointer to end of buffer pointer */ len = this->bufferSize - this->readIndex; if (len >= toread) { /* it fits within this part. */ memcpy(buf, buffer + readIndex, toread); this->readIndex += (int)toread; return; } else if (len > 0) { memcpy(buf, buffer + readIndex, len); toread -= len; bytesRead = len; } /* area of bytes from start of buffer to write pointer, which happens * when content wraps around to start of buffer */ memcpy(buf + bytesRead, buffer, toread); this->readIndex = (int)toread; } /* * amount must always be equal to, or less than, the empty space in the buffer. * Adjusts write pointer. */ void CyclicBuffer::writeData(const unsigned char * const buf, const unsigned int amount) { unsigned int len; unsigned int towrite = amount; unsigned int bytesWritten = 0; /* area of bytes from read pointer to end of buffer pointer */ len = this->bufferSize - this->writeIndex; if (len >= towrite) { /* it fits within this part. */ memcpy(buffer + writeIndex, buf, towrite); this->writeIndex += (int)towrite; return; } else if (len > 0) { memcpy(buffer + writeIndex, buf, len); towrite -= len; bytesWritten = len; } /* area of bytes from start of buffer to write pointer, which happens * when content wraps around to start of buffer */ memcpy(buffer, buf + bytesWritten, towrite); this->writeIndex = (int)towrite; } void CyclicBuffer::lock() { #ifdef LIBPTH (void)pth_mutex_acquire(&rw_mutex, FALSE, NULL); #elif defined(PTHREADEDMPEG) (void)pthread_mutex_lock(&rw_mutex); #endif } void CyclicBuffer::unlock() { #ifdef LIBPTH (void)pth_mutex_release(&rw_mutex); #elif defined(PTHREADEDMPEG) (void)pthread_mutex_unlock(&rw_mutex); #endif } mp3blaster-3.2.6/mpegsound/mpegtoraw.cc0000664000112600011260000007742312426044701015045 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Mpegtoraw.cc // Server which get mpeg format and put raw format. // Patched by Bram Avontuur to support more mp3 formats and to play mp3's // with bogus (?) headers. #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "mpegsound.h" #include "mpegsound_locals.h" #include "xingheader.h" #ifdef NEWTHREAD #include #include #include #include #include #include pth_mutex_t queue_mutex; Mpegtoraw *decoder; #define THREAD_TIMES 10 #define THREAD_LIMIT 512 #endif #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #define MY_PI 3.14159265358979323846 #undef DEBUG #ifdef NEWTHREAD void Mpegtoraw::settotalbuffers(short amount) { short bla=0; #if 0 int shm_id; /* Shared memory ID */ do{ shm_id=shmget(IPC_PRIVATE,sizeof(mpeg_buffer)*amount,IPC_CREAT | IPC_EXCL | 0666); amount-=10; } while (shm_id==-1 && (bla+10)>0); amount+=10; if(amount<=0) { fprintf(stderr,"Can't create shared memory!\n"); exit(1); } buffers=(mpeg_buffer *)shmat(shm_id,NULL,0); if(buffers==(mpeg_buffer *)-1) { perror("shmat"); exit(1); } if(shmctl(shm_id,IPC_RMID,NULL)) { perror("shmctl"); exit(1); } #else buffers = (mpeg_buffer*)malloc(amount * sizeof(mpeg_buffer)); if (!buffers) { //very blunt. fprintf(stderr, "Can't allocate buffer memory!\n"); exit(1); } #endif while(bla != amount) buffers[bla++].claimed=0; no_buffers=amount; free_buffers=no_buffers; } int Mpegtoraw::getfreebuffers(void) { return free_buffers; } short Mpegtoraw::request_buffer(void) { short temp=0; for(temp=0;temp!=no_buffers;temp++) { if(!buffers[temp].claimed) { buffers[temp].claimed=1; free_buffers--; return temp; } } return -1; } void Mpegtoraw::release_buffer(short index) { if(index>=no_buffers) return; buffers[index].claimed=0; free_buffers++; } void Mpegtoraw::queue_buf(short index) { buffer_node *bla; buffer_node *search; search=queue; bla=(buffer_node *)malloc(sizeof(buffer_node)); if(!bla) { seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH); return; } bla->index=index; bla->next=NULL; if(search==NULL) { queue=bla; return; } while(search->next!=NULL) search=search->next; search->next=bla; return; } void Mpegtoraw::dequeue_first(void) { buffer_node *temp; temp=queue; if(!temp) { return; } release_buffer(queue->index); queue=queue->next; free(temp); } void Mpegtoraw::dequeue_buf(short index) { buffer_node *temp; buffer_node *temp2; temp=queue; if(temp==NULL) { return; } if(temp->index==index) { release_buffer(index); queue=queue->next; free(temp); } else { while(temp!=NULL&&temp->next!=NULL&&temp->next->index!=index) temp=temp->next; if(temp==NULL||temp->next==NULL) { return; } release_buffer(temp->next->index); temp2=temp->next; temp->next=temp->next->next; free(temp2); } } void Mpegtoraw::threadplay(void *bla) { struct mpeg_buffer *bufje; int offset=0; int remaining=RAWDATASIZE*THREAD_TIMES*sizeof(short int); bla=bla; int processed=0; /* This has to be a static array, otherwise it is allocated from the * stack. threadplay() is called within a pth|pthreads thread, so stack * is scarce. Leads to very nasty (and very untrackable) segmentation * faults, happening at very odd places (since the stack has been * corrupted). Under normal conditions, the stack is automagically * expanded if so required, or a segmentation fault is generated when * stack and heap collide in case of an OS with a somewhat 'less * modern' memory system. MacOS prior to OS X comes to mind. * * Or a modern system when using threads.... * * Another option would be to make this a global variable, but that's * even more yucky. */ bufje=NULL; /* So gcc will not complain. Pfft. */ /* Enable other threads to kill us */ /* But only if we feel like it! */ pth_cancel_state(PTH_CANCEL_ENABLE|PTH_CANCEL_DEFERRED, NULL); /* Yes, I know that these are the defaults at this particular point in time/space. Linux and GNU-libc are doing a fine job in changing defaults and compliances these days, though. */ while(1) { pth_cancel_point(); /* Are we "requested" to sod off and die? */ pth_mutex_acquire(&queue_mutex, FALSE, NULL); /* Enter critical zone */ if(!player_run || !queue) { pth_event_t ev; pth_mutex_release(&queue_mutex); /* Leave critical zone */ ev=pth_event(PTH_EVENT_TIME,pth_timeout(0,100000)); pth_wait(ev); pth_event_free(ev,PTH_FREE_THIS); /* Player is either paused, or has a buffer underrun.Pause 100 msec. */ } else { /* Fill buffer as much as possible */ while (queue && (bufje=get_buffer(queue->index)) && bufje->framesize <= remaining ) { int modifiedsize; //amplify(bufje->data,bufje->framesize); memcpy(sound_buf+offset,bufje->data,bufje->framesize); modifiedsize=player->fix_samplesize( sound_buf+offset, bufje->framesize); offset+=modifiedsize; remaining-=modifiedsize; currentframe=bufje->framenumber; dequeue_first(); } pth_mutex_release(&queue_mutex); /* Leave critical zone */ /* So, the actual sound output is done -outside- the * critical zone. This means that the data is copied * once too much, but it prevents the decoding thread * from blocking because the playing thread is blocked * by the sound hardware while in the critical zone.*/ debug("Starting loop\n"); do { processed=player->putblock_nt(sound_buf,offset); debug("mpegtoraw.cc:putblock_nt: Wrote %d bytes.\n",processed); /* move processed data out of the way */ if (processed==-1) { if(errno!=EAGAIN) debug("putblock_nt: %s", strerror(errno)); } else { int tomove= offset - processed; memmove(sound_buf, sound_buf + processed, tomove); /* Patch offset and remaining */ offset=tomove; remaining=THREAD_TIMES*RAWDATASIZE * sizeof(short int) - offset; #if 0 /* enabling this code on my system totally prevents -1 writes. */ if (processed > 1024) { debug("Breaking, wrote enough for now.\n"); break; } #endif } } while (remaining > 0 && processed >= THREAD_LIMIT); pth_event_t ev; /* I really hoped to use something like ev=pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_WRITEABLE, player->audiohandle); * But this doesn't seem to work. The event occurs * immediately. Such a shame. */ ev=pth_event(PTH_EVENT_TIME,pth_timeout(0,5000)); pth_wait(ev); pth_event_free(ev,PTH_FREE_THIS); } } /* The playing thread never quits */ } void *tp_hack(void *bla) { decoder->threadplay(bla); /* The moron who decided that this should be a C++ class should be shot, if he hasn't been by now already.. */ return NULL; } struct mpeg_buffer * Mpegtoraw::get_buffer(short index) { return &buffers[index]; } void Mpegtoraw::createplayer(void) { pth_attr_t attr; if(play_thread) return; attr = pth_attr_new(); pth_attr_set(attr, PTH_ATTR_PRIO, PTH_PRIO_MAX); this->play_thread = pth_spawn(attr, tp_hack, NULL); } void Mpegtoraw::continueplaying(void) { this->player_run=1; } void Mpegtoraw::abortplayer(void) { pth_cancel(play_thread); if(!play_thread) return; if(!pth_join(play_thread,NULL)) /* Wait for the playthread to die! */ { perror("pth_join"); exit(1); } play_thread=(pth_t)NULL; } void Mpegtoraw::pauseplaying(void) { //why would you abort the player here?? //player->abort(); this->player_run=0; } void Mpegtoraw::setdecodeframe(int framenumber) { int pos=0; char d[100]; sprintf(d, "Framenumber = %d\n", framenumber); debug(d); if(frameoffsets==NULL)return; if(framenumber<=0) { pos=frameoffsets[0]; framenumber=0; } else { if (framenumber >= totalframe) framenumber=totalframe-1; pos = frameoffsets[framenumber]; if(pos==0) { int i; sprintf(d,"Bumped into an unset frame position (%d)!\n", framenumber); debug(d); for(i=framenumber-1;i>0;i--) if(frameoffsets[i]!=0)break; loader->setposition(frameoffsets[i]); sprintf(d,"Found first initialized frame at %d bytes (framenumber %d)\n", loader->getposition(), i); debug(d); while( i < framenumber ) { loadheader(); i++; frameoffsets[i]=loader->getposition(); } pos=frameoffsets[framenumber]; } } loader->setposition(pos); decodeframe=framenumber; } void Mpegtoraw::makeroom(int size) { int clean; int queuesize; buffer_node *temp,*temp2; if(free_buffers >= size) /* No need to throw away things ! */ return; clean=size-free_buffers; if(spare) /* Begin releasing from spare buffer */ { queuesize=0; temp=spare; while(temp) { queuesize++; temp=temp->next; } temp = spare; if(clean <= queuesize) { /* It fits !*/ queuesize-=clean; clean=0; while(queuesize-1) { temp=temp->next; queuesize--; } temp2=temp->next; temp->next=NULL; temp=temp2; } else { clean-=queuesize; spare=NULL; } while(temp) { release_buffer(temp->index); temp2=temp; temp=temp->next; free(temp2); } } if(clean&&queue) /* Begin releasing from spare buffer */ { queuesize=0; temp=queue; while(temp) { queuesize++; temp=temp->next; } temp = queue; if(clean <= queuesize) { /* It fits !*/ queuesize-=clean; clean=0; while(queuesize-1) { temp=temp->next; queuesize--; } temp2=temp->next; temp->next=NULL; temp=temp2; } else { clean-=queuesize; queue=NULL; } while(temp) { release_buffer(temp->index); temp2=temp; temp=temp->next; free(temp2); } } } #endif Mpegtoraw::Mpegtoraw(Soundinputstream *loader,Soundplayer *player) { __errorcode=SOUND_ERROR_OK; frameoffsets=NULL; forcetomonoflag = 0; downfrequency = 0; scan_mp3 = 1; this->loader=loader; this->player=player; #ifdef NEWTHREAD skip=5; //pre_amp=10; this->buffers=NULL; this->sound_buf=(unsigned char *)malloc(RAWDATASIZE*THREAD_TIMES*sizeof(short int)); this->settotalbuffers(1000); this->queue=NULL; this->spare=NULL; decoder=this; this->player_run=0; pth_mutex_init(&queue_mutex); play_thread=(pth_t)NULL; createplayer(); continueplaying(); #endif } Mpegtoraw::~Mpegtoraw() { if(frameoffsets) { delete [] frameoffsets; } #ifdef NEWTHREAD buffer_node *temp; abortplayer(); free(sound_buf); /* if(pthread_mutex_destroy(&queue_mutex)) { perror("pthread_mutex_destroy"); exit(1); } */ //shmdt((char *)buffers); if (buffers) { delete[] buffers; buffers = NULL; } while(queue) { temp=queue; queue=queue->next; free(temp); } while(spare) { temp=spare; spare=spare->next; free(temp); } #endif } #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(short flag) { forcetomonoflag=flag; } void Mpegtoraw::setdownfrequency(int value) { downfrequency = (value ? 1 : 0); } short 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; } #ifdef NEWTHREAD inline void Mpegtoraw::flushrawdata(short index) { struct mpeg_buffer *bufje; bufje=get_buffer(index); bufje->framenumber=decodeframe; bufje->framesize=rawdataoffset<<1; memcpy(bufje->data,rawdata,bufje->framesize); queue_buf(index); rawdataoffset=0; } #else inline void Mpegtoraw::flushrawdata(void) #ifdef PTHREADEDMPEG { if(threadflags.thread) { if(((threadqueue.tail+1)%threadqueue.framenumber)==threadqueue.head) { while(((threadqueue.tail+1)%threadqueue.framenumber)==threadqueue.head) USLEEP(200); } memcpy(threadqueue.buffer+(threadqueue.tail*RAWDATASIZE),rawdata, RAWDATASIZE*sizeof(short int)); threadqueue.sizes[threadqueue.tail]=(rawdataoffset<<1); if(threadqueue.tail>=threadqueue.frametail) threadqueue.tail=0; else threadqueue.tail++; } else { player->putblock((char *)rawdata,rawdataoffset<<1); currentframe++; } rawdataoffset=0; } #else { player->putblock((char *)rawdata,rawdataoffset<<1); currentframe++; rawdataoffset=0; } #endif #endif /* NEWTHREAD */ typedef struct { char *songname; char *artist; char *album; char *year; char *comment; unsigned char genre; }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 tryflag=0; data->songname[0]=0; data->artist [0]=0; data->album [0]=0; data->year [0]=0; data->comment [0]=0; data->genre=255; fp->setposition(fp->getsize()-128); for(;;) { if(fp->getbytedirect()==0x54) { if(fp->getbytedirect()==0x41) { if(fp->getbytedirect()==0x47) { char tmp; fp->_readbuffer(data->songname,30);strman(data->songname,30); fp->_readbuffer(data->artist ,30);strman(data->artist, 30); fp->_readbuffer(data->album ,30);strman(data->album, 30); fp->_readbuffer(data->year , 4);strman(data->year, 4); fp->_readbuffer(data->comment ,30);strman(data->comment, 30); fp->_readbuffer(&tmp,1); data->genre = (unsigned char)tmp; break; } } } tryflag++; if (tryflag == 1) fp->setposition(fp->getsize() - 125); // for mpd 0.1, Sorry.. else break; } fp->setposition(0); } // Convert mpeg to raw // Mpeg header class bool Mpegtoraw::initialize(const char *filename) { register int i; register REAL *s1,*s2; REAL *s3,*s4; static bool initialized=false; if (!filename) return false; 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(); currentframe=decodeframe=0; is_vbr = 0; int headcount = 0, first_offset = 0; bool found_first_frame = false; int frameinfo_layer = 0; int frameinfo_version = 0; int frameinfo_samplerate = 0; int frame_start; sync(); /* Try to find at least 3 valid mp3 frames at a position where we * expect it, with consistent data. If they can't be found, we don't * consider it to be an mp3. */ while (headcount < 3 && geterrorcode() != SOUND_ERROR_FINISH) { frame_start = loader->getposition(); if (!loadheader(false)) { debug("Found a bogus header (or EOF?) Resetting..\n"); /* found a bogus header. Reset header counter */ headcount = 0; found_first_frame = false; if (loader->canseek()) loader->setposition(frame_start + 1); /* for streams in which cannot be seeked, we just keep on searching * forward from where we are now, and hope we didn't just halfway into * what's really a valid header. Doesn't matter much though, eventually * we'll bump into a correct header. */ continue; } if (!found_first_frame) { /* we haven't found the first, valid frame yet. * Maybe this is the one! */ debug("Hopefully found the first valid frame at position %d\n", frame_start); first_offset = frame_start; found_first_frame = true; /* store frameinfo which must remain constant */ frameinfo_layer = layer; frameinfo_version = version; frameinfo_samplerate = frequency; } /* after a successful loadheader(), the loader is positioned at the * start of the next expected frame header. */ /* are the new frame settings consistent with the first found frame? */ if ((frameinfo_layer != layer || frameinfo_version != version || frameinfo_samplerate != frequency) ) { debug("Frame info inconsistent, finding new First Frame\n"); found_first_frame = false; headcount = 0; if (loader->canseek()) loader->setposition(frame_start + 1); continue; } headcount++; /* yay, valid frame */ if (headcount > 1) { debug("Found %d valid headers so far.\n", headcount); } } if (headcount != 3) { debug("Couldn't find 3 consecutive, valid mp3 frames!\n"); return false; /* invalid MP3 */ } /* store this mp3's frame info, for future error checking */ header_one.version = version; header_one.mode = mode; header_one.layer = layer; header_one.frequency = frequency; /* rewind to first valid frame and read info from it */ if (loader->canseek()) { loader->setposition(first_offset); loadheader(); loader->setposition(first_offset); } bool found_xing = false; XHEADDATA xingheader; xingheader.toc = NULL; /* Try to find a XING header to determine total song length first. * Note that this method only works if the FIRST valid mp3 frame found * contains the XING header. Order of headers in front of mp3's is not * specified though. */ /* framesize is set by loadheader, and is the size of the first frame */ unsigned char *buffer = new unsigned char[framesize * sizeof(char)]; if (loader->canseek() && (loader->getblock((char *)buffer, framesize * sizeof(char)) == (int)(framesize * sizeof(char))) && GetXingHeader(&xingheader, buffer)) { totalframe = xingheader.frames; found_xing = true; debug("Found XING header, and set total frames to %d.\n", totalframe); } else { debug("No XING header found, assuming CBR mp3.\n"); totalframe = (loader->getsize() + framesize - 1) / framesize; } delete[] buffer; buffer = NULL; if (loader->canseek()) loader->setposition(first_offset); if(frameoffsets) delete[] frameoffsets; songinfo.name[0]=0; if (totalframe > 0) { frameoffsets=new int[totalframe]; for(i=totalframe-1;i>=0;i--) frameoffsets[i]=0; //Bram Avontuur: I added this. The original author figured an mp3 //would always start with a valid header (which is false if there's a //sequence of 3 0xf's that's not part of a valid header) frameoffsets[0] = first_offset; //till here. And a loader->setposition later in this function. { ID3 data; data.songname=songinfo.name; data.artist =songinfo.artist; data.album =songinfo.album; data.year =songinfo.year; data.comment =songinfo.comment; //data.genre =songinfo.genre; parseID3(loader,&data); songinfo.genre = data.genre; } } else frameoffsets=NULL; #ifndef NEWTHREAD #ifdef PTHREADEDMPEG threadflags.thread=false; threadqueue.buffer=NULL; threadqueue.sizes=NULL; #endif #endif /* NEWTHREAD */ if (loader->canseek() && totalframe) { /*Calculate length of [vbr] mp3. Neat if you don't have XING headers, bad if you stream mp3's over a slow network connection/disk (since it seeks through the entire file) Note that it doesn't work well, since it uses a bogusly calculated totalframe, which means it can never detect songs that actually have *more* frames than that. */ if (scan_mp3 && !found_xing) { // Get frame offsets, by calculating all offsets of the headers. setframe(totalframe - 1); // Cut off last frame until there is an offset change int i; int lastOffset = frameoffsets[totalframe - 1]; for(i = totalframe - 2;i > 0;i--) { if(frameoffsets[i] != lastOffset) { break; } } totalframe = i; debug("Manually calculated total frames : %d\n", totalframe); // Reset position setframe(0); } loader->setposition(first_offset); seterrorcode(SOUND_ERROR_OK); } /* set loader to start of first valid frame. * Maybe it should point to the bytes FOLLOWING the header, I'm not sure.. * ::run() loads its own header first, so let's assume this is correct. */ if (loader->canseek()) loader->setposition(first_offset); return (totalframe != 0); } #ifdef NEWTHREAD void Mpegtoraw::setframe(int framenumber) { buffer_node *temp; abortplayer(); player->abort(); if(queue) { if(buffers[queue->index].framenumber < framenumber) { while(queue && buffers[queue->index].framenumber < framenumber) { dequeue_first(); } } else { makeroom(buffers[queue->index].framenumber - framenumber); if(spare) { temp=queue; while(temp->next) temp=temp->next; temp->next=spare; } spare=queue; queue=NULL; } } if(!queue) /* Hint: This is -not- the same as an 'else' from the previous if*/ { //can't skip 2 frames because initialization of frameoffsets[] in //setdecodeframe will fail to set the last 2 indices then. //setdecodeframe(framenumber-2); //skip=2; setdecodeframe(framenumber); skip=0; } createplayer(); } #else /* NEWTHREAD */ void Mpegtoraw::setframe(int framenumber) { int pos=0; char d[100]; 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]); sprintf(d, "Found first offset at %d (%d/%d)\n", loader->getposition(), i, framenumber); debug(d); while(i < framenumber) { i++; loadheader(); frameoffsets[i] = loader->getposition(); } pos = frameoffsets[framenumber]; } } clearbuffer(); loader->setposition(pos); decodeframe=currentframe=framenumber; } #endif /* NEWTHREAD */ void Mpegtoraw::clearbuffer(void) { debug("clearbuffer\n"); #ifndef NEWTHREAD #ifdef PTHREADEDMPEG if(threadflags.thread) { /* stop the playback loop */ threadflags.criticalflag=false; threadflags.criticallock=true; while(!threadflags.criticalflag)USLEEP(1); threadqueue.head=threadqueue.tail=0; } #endif #endif /* NEWTHREAD */ //give player the chance to reset itself player->abort(); player->resetsoundtype(); #ifndef NEWTHREAD #ifdef PTHREADEDMPEG if(threadflags.thread) { threadflags.criticallock=false; } #endif #endif /* NEWTHREAD */ } //find a valid frame. If an invalid frame is found, the filepointer //points to the location where the next frame is to be expected, and 'true' //is returned. //if 'lookahead' is false, loadheader will return false if the expected //header is not found at the exact location of the filepointer at call time. bool Mpegtoraw::loadheader(bool lookahead) { register int c; bool flag; int bytes_read = 0; sync(); // Synchronize flag=false; do { if ( (c = loader->getbytedirect()) < 0 ) break; bytes_read++; if (c == 0xff) { if ( (c = loader->getbytedirect()) < 0) break; bytes_read++; if ( (c&0xf0) == 0xf0 ) flag=true; else if (!lookahead) return seterrorcode(SOUND_ERROR_BAD); } else if (!lookahead) { return seterrorcode(SOUND_ERROR_BAD); } } while (!flag); if (c < 0) return seterrorcode(SOUND_ERROR_FINISH); // Analyzing c &= 0xf; /* c = 0 0 0 0 bit13 bit14 bit15 bit16 */ protection = c&1; /* bit16 */ layer = 4 - ( (c>>1)&3 ); /* bit 14 bit 15: 1..4, 4=invalid */ if (layer == 4) return seterrorcode(SOUND_ERROR_BAD); version = (_mpegversion)((c>>3)^1); /* bit 13 */ if ((c = loader->getbytedirect()) < 0) return seterrorcode(SOUND_ERROR_FINISH); bytes_read++; c >>= 1; /* c = 0 bit17 .. bit23 */ padding = (c&1); c >>= 1; frequency = (_frequency)(c&3); c >>= 2; if (frequency > 2) return seterrorcode(SOUND_ERROR_BAD); bitrateindex = (int)c; if (bitrateindex == 15 || !bitrateindex) return seterrorcode(SOUND_ERROR_BAD); if ((c = loader->getbytedirect()) < 0) return seterrorcode(SOUND_ERROR_FINISH); bytes_read++; c = ((unsigned int)c)>>4; /* c = 0 0 0 0 bit25 bit26 bit27 bit27 bit28 */ extendedmode = c&3; mode = (_mode)(c>>2); // Making information inputstereo = ( (mode==single) ? 0 : 1 ); if (forcetomonoflag) outputstereo = 0; else outputstereo = inputstereo; 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 (stereobound>subbandnumber) stereobound = subbandnumber; // framesize & slots if (layer==1) { framesize=(12000*bitrate[version][0][bitrateindex])/ frequencies[version][frequency]; if (frequency==frequency44100 && padding) framesize++; framesize<<=2; } else { framesize=(144000*bitrate[version][layer-1][bitrateindex])/ (frequencies[version][frequency]<eof()) return seterrorcode(SOUND_ERROR_FINISH); return true; } /***************************/ /* Playing in multi-thread */ /***************************/ #ifndef NEWTHREAD #ifdef PTHREADEDMPEG /* Player routine */ void Mpegtoraw::threadedplayer(void) { while(!threadflags.quit) { while(threadflags.pause || threadflags.criticallock) { threadflags.criticalflag=true; USLEEP(200); } if(threadqueue.head!=threadqueue.tail) { player->putblock(threadqueue.buffer+threadqueue.head*RAWDATASIZE, threadqueue.sizes[threadqueue.head]); currentframe++; if(threadqueue.head==threadqueue.frametail) threadqueue.head=0; else threadqueue.head++; } else { if(threadflags.done)break; // Terminate when done USLEEP(200); } } threadflags.thread=false; } static void *threadlinker(void *arg) { ((Mpegtoraw *)arg)->threadedplayer(); return NULL; } bool Mpegtoraw::makethreadedplayer(int framenumbers) { pthread_attr_t attrs; threadqueue.buffer= (short int *)malloc(sizeof(short int)*RAWDATASIZE*framenumbers); if(threadqueue.buffer==NULL) seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH); threadqueue.sizes=(int *)malloc(sizeof(int)*framenumbers); if(threadqueue.sizes==NULL) seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH); threadqueue.framenumber=framenumbers; threadqueue.frametail=framenumbers-1; threadqueue.head=threadqueue.tail=0; threadflags.quit=threadflags.done= threadflags.pause=threadflags.criticallock=false; threadflags.thread=true; (void)pthread_attr_init(&attrs); (void)pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED); if(pthread_create(&thread,&attrs,threadlinker,this)) { seterrorcode(SOUND_ERROR_THREADFAIL); return false; } return true; } void Mpegtoraw::freethreadedplayer(void) { threadflags.criticallock= threadflags.pause=false; threadflags.done=true; // Terminate thread player while(threadflags.thread)USLEEP(10); // Wait for done... if(threadqueue.buffer) { free(threadqueue.buffer); threadqueue.buffer = NULL; } if(threadqueue.sizes) { free(threadqueue.sizes); threadqueue.sizes = NULL; } } void Mpegtoraw::stopthreadedplayer(void) { threadflags.quit=true; }; void Mpegtoraw::pausethreadedplayer(void) { threadflags.pause=true; }; void Mpegtoraw::unpausethreadedplayer(void) { threadflags.pause=false; }; bool Mpegtoraw::existthread(void) { return threadflags.thread; } int Mpegtoraw::getframesaved(void) { if(threadqueue.framenumber) return ((threadqueue.tail+threadqueue.framenumber-threadqueue.head) %threadqueue.framenumber); return 0; } #endif #endif /* NEWTHREAD */ // Convert mpeg to raw bool Mpegtoraw::run(int frames) { #ifdef NEWTHREAD short buffer_number = -1; buffer_node *temp; #endif clearrawdata(); for(;frames;frames--) { #ifdef NEWTHREAD if(spare) /* There are frames in the spare buffer! */ { pth_mutex_acquire(&queue_mutex,FALSE,NULL); if(buffers[spare->index].framenumber < decodeframe) { /* Houston, we have a problem! */ while(spare && buffers[spare->index].framenumber < decodeframe) { release_buffer(spare->index); temp=spare; spare=spare->next; free(temp); } pth_mutex_release(&queue_mutex); continue; } if(buffers[spare->index].framenumber==decodeframe) { while(spare && buffers[spare->index].framenumber==decodeframe) { queue_buf(spare->index); spare=spare->next; decodeframe++; } setdecodeframe(decodeframe-5); /* Not that stupid as it seems */ skip=4; } pth_mutex_release(&queue_mutex); } /* If(spare) */ if(!skip) { pth_mutex_acquire(&queue_mutex,FALSE,NULL); buffer_number=request_buffer(); pth_mutex_release(&queue_mutex); if(buffer_number==-1) /* No free buffers available */ break; } else #endif if(totalframe>0) { if(decodeframegetposition(); } bool found_frame = false; while (!found_frame && !loader->eof()) { if(loadheader()==false) { /* loadheader advances the file stream pointer, so it's safe to * keep on calling it. */ debug("Invalid frame found (pos ~= %d)\n", loader->getposition()); continue; } if (version != header_one.version || mode != header_one.mode || layer != header_one.layer || frequency != header_one.frequency) { /* argh. Bogus frame. */ debug("Invalid frame found (pos ~= %d)\n", loader->getposition()); continue; } found_frame = true; } if(loader->eof()) { #ifdef NEWTHREAD if(!skip) { pth_mutex_acquire(&queue_mutex,FALSE,NULL); release_buffer(buffer_number); pth_mutex_release(&queue_mutex); } #endif seterrorcode(SOUND_ERROR_FINISH); break; } if (frames < 0) { if (!player->setsoundtype(outputstereo,16, frequencies[version][frequency]>>downfrequency)) { debug("Error in (re)setting sound type.\n"); return seterrorcode(player->geterrorcode()); } } if(frames<0) { frames=-frames; totaltime = (totalframe * framesize) / (getbitrate() * 125); } decodeframe++; if (layer==3)extractlayer3(); else if(layer==2)extractlayer2(); else if(layer==1)extractlayer1(); #ifdef NEWTHREAD if(skip) { skip--; rawdataoffset=0; } else { pth_mutex_acquire(&queue_mutex,FALSE,NULL); flushrawdata(buffer_number); pth_mutex_release(&queue_mutex); } #else flushrawdata(); #endif if(player->geterrorcode())seterrorcode(geterrorcode()); } #ifdef NEWTHREAD if (geterrorcode() != SOUND_ERROR_OK && queue) { /* Done decoding, but there's still music in the buffer */ USLEEP(10000); seterrorcode(SOUND_ERROR_OK); } if (getfreebuffers() < 10) //buffer is quite full, let's wait a bit USLEEP(10000); #endif if (geterrorcode()==SOUND_ERROR_OK || geterrorcode() == SOUND_ERROR_BAD || geterrorcode() == SOUND_ERROR_BADHEADER) return true; else return false; } mp3blaster-3.2.6/mpegsound/huffmantable.cc0000664000112600011260000010251012426044701015456 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Huffmantable.cc // It contains initialized huffman table for MPEG layer 3 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mpegsound.h" static const unsigned int htd01[ 7][2]={{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 16},{ 2, 1},{ 0, 1}, { 0, 17}}, htd02[ 17][2]={{ 2, 1},{ 0, 0},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1}, { 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32},{ 0, 33}, { 2, 1},{ 0, 18},{ 2, 1},{ 0, 2},{ 0, 34}}, htd03[ 17][2]={{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 1},{ 2, 1},{ 0, 17}, { 2, 1},{ 0, 16},{ 4, 1},{ 2, 1},{ 0, 32},{ 0, 33}, { 2, 1},{ 0, 18},{ 2, 1},{ 0, 2},{ 0, 34}}, htd05[ 31][2]={{ 2, 1},{ 0, 0},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1}, { 2, 1},{ 0, 17},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 32}, { 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 8, 1},{ 4, 1}, { 2, 1},{ 0, 34},{ 0, 48},{ 2, 1},{ 0, 3},{ 0, 19}, { 2, 1},{ 0, 49},{ 2, 1},{ 0, 50},{ 2, 1},{ 0, 35}, { 0, 51}}, htd06[ 31][2]={{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 16},{ 0, 17}, { 6, 1},{ 2, 1},{ 0, 1},{ 2, 1},{ 0, 32},{ 0, 33}, { 6, 1},{ 2, 1},{ 0, 18},{ 2, 1},{ 0, 2},{ 0, 34}, { 4, 1},{ 2, 1},{ 0, 49},{ 0, 19},{ 4, 1},{ 2, 1}, { 0, 48},{ 0, 50},{ 2, 1},{ 0, 35},{ 2, 1},{ 0, 3}, { 0, 51}}, htd07[ 71][2]={{ 2, 1},{ 0, 0},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1}, { 8, 1},{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32}, { 0, 2},{ 0, 33},{ 18, 1},{ 6, 1},{ 2, 1},{ 0, 18}, { 2, 1},{ 0, 34},{ 0, 48},{ 4, 1},{ 2, 1},{ 0, 49}, { 0, 19},{ 4, 1},{ 2, 1},{ 0, 3},{ 0, 50},{ 2, 1}, { 0, 35},{ 0, 4},{ 10, 1},{ 4, 1},{ 2, 1},{ 0, 64}, { 0, 65},{ 2, 1},{ 0, 20},{ 2, 1},{ 0, 66},{ 0, 36}, { 12, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 51},{ 0, 67}, { 0, 80},{ 4, 1},{ 2, 1},{ 0, 52},{ 0, 5},{ 0, 81}, { 6, 1},{ 2, 1},{ 0, 21},{ 2, 1},{ 0, 82},{ 0, 37}, { 4, 1},{ 2, 1},{ 0, 68},{ 0, 53},{ 4, 1},{ 2, 1}, { 0, 83},{ 0, 84},{ 2, 1},{ 0, 69},{ 0, 85}}, htd08[ 71][2]={{ 6, 1},{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 16},{ 0, 1}, { 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 33},{ 0, 18}, { 14, 1},{ 4, 1},{ 2, 1},{ 0, 32},{ 0, 2},{ 2, 1}, { 0, 34},{ 4, 1},{ 2, 1},{ 0, 48},{ 0, 3},{ 2, 1}, { 0, 49},{ 0, 19},{ 14, 1},{ 8, 1},{ 4, 1},{ 2, 1}, { 0, 50},{ 0, 35},{ 2, 1},{ 0, 64},{ 0, 4},{ 2, 1}, { 0, 65},{ 2, 1},{ 0, 20},{ 0, 66},{ 12, 1},{ 6, 1}, { 2, 1},{ 0, 36},{ 2, 1},{ 0, 51},{ 0, 80},{ 4, 1}, { 2, 1},{ 0, 67},{ 0, 52},{ 0, 81},{ 6, 1},{ 2, 1}, { 0, 21},{ 2, 1},{ 0, 5},{ 0, 82},{ 6, 1},{ 2, 1}, { 0, 37},{ 2, 1},{ 0, 68},{ 0, 53},{ 2, 1},{ 0, 83}, { 2, 1},{ 0, 69},{ 2, 1},{ 0, 84},{ 0, 85}}, htd09[ 71][2]={{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 16},{ 2, 1}, { 0, 1},{ 0, 17},{ 10, 1},{ 4, 1},{ 2, 1},{ 0, 32}, { 0, 33},{ 2, 1},{ 0, 18},{ 2, 1},{ 0, 2},{ 0, 34}, { 12, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 48},{ 0, 3}, { 0, 49},{ 2, 1},{ 0, 19},{ 2, 1},{ 0, 50},{ 0, 35}, { 12, 1},{ 4, 1},{ 2, 1},{ 0, 65},{ 0, 20},{ 4, 1}, { 2, 1},{ 0, 64},{ 0, 51},{ 2, 1},{ 0, 66},{ 0, 36}, { 10, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 4},{ 0, 80}, { 0, 67},{ 2, 1},{ 0, 52},{ 0, 81},{ 8, 1},{ 4, 1}, { 2, 1},{ 0, 21},{ 0, 82},{ 2, 1},{ 0, 37},{ 0, 68}, { 6, 1},{ 4, 1},{ 2, 1},{ 0, 5},{ 0, 84},{ 0, 83}, { 2, 1},{ 0, 53},{ 2, 1},{ 0, 69},{ 0, 85}}, htd10[127][2]={{ 2, 1},{ 0, 0},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1}, { 10, 1},{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32}, { 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 28, 1},{ 8, 1}, { 4, 1},{ 2, 1},{ 0, 34},{ 0, 48},{ 2, 1},{ 0, 49}, { 0, 19},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 3},{ 0, 50}, { 2, 1},{ 0, 35},{ 0, 64},{ 4, 1},{ 2, 1},{ 0, 65}, { 0, 20},{ 4, 1},{ 2, 1},{ 0, 4},{ 0, 51},{ 2, 1}, { 0, 66},{ 0, 36},{ 28, 1},{ 10, 1},{ 6, 1},{ 4, 1}, { 2, 1},{ 0, 80},{ 0, 5},{ 0, 96},{ 2, 1},{ 0, 97}, { 0, 22},{ 12, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 67}, { 0, 52},{ 0, 81},{ 2, 1},{ 0, 21},{ 2, 1},{ 0, 82}, { 0, 37},{ 4, 1},{ 2, 1},{ 0, 38},{ 0, 54},{ 0,113}, { 20, 1},{ 8, 1},{ 2, 1},{ 0, 23},{ 4, 1},{ 2, 1}, { 0, 68},{ 0, 83},{ 0, 6},{ 6, 1},{ 4, 1},{ 2, 1}, { 0, 53},{ 0, 69},{ 0, 98},{ 2, 1},{ 0,112},{ 2, 1}, { 0, 7},{ 0,100},{ 14, 1},{ 4, 1},{ 2, 1},{ 0,114}, { 0, 39},{ 6, 1},{ 2, 1},{ 0, 99},{ 2, 1},{ 0, 84}, { 0, 85},{ 2, 1},{ 0, 70},{ 0,115},{ 8, 1},{ 4, 1}, { 2, 1},{ 0, 55},{ 0,101},{ 2, 1},{ 0, 86},{ 0,116}, { 6, 1},{ 2, 1},{ 0, 71},{ 2, 1},{ 0,102},{ 0,117}, { 4, 1},{ 2, 1},{ 0, 87},{ 0,118},{ 2, 1},{ 0,103}, { 0,119}}, htd11[127][2]={{ 6, 1},{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 16},{ 0, 1}, { 8, 1},{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32}, { 0, 2},{ 0, 18},{ 24, 1},{ 8, 1},{ 2, 1},{ 0, 33}, { 2, 1},{ 0, 34},{ 2, 1},{ 0, 48},{ 0, 3},{ 4, 1}, { 2, 1},{ 0, 49},{ 0, 19},{ 4, 1},{ 2, 1},{ 0, 50}, { 0, 35},{ 4, 1},{ 2, 1},{ 0, 64},{ 0, 4},{ 2, 1}, { 0, 65},{ 0, 20},{ 30, 1},{ 16, 1},{ 10, 1},{ 4, 1}, { 2, 1},{ 0, 66},{ 0, 36},{ 4, 1},{ 2, 1},{ 0, 51}, { 0, 67},{ 0, 80},{ 4, 1},{ 2, 1},{ 0, 52},{ 0, 81}, { 0, 97},{ 6, 1},{ 2, 1},{ 0, 22},{ 2, 1},{ 0, 6}, { 0, 38},{ 2, 1},{ 0, 98},{ 2, 1},{ 0, 21},{ 2, 1}, { 0, 5},{ 0, 82},{ 16, 1},{ 10, 1},{ 6, 1},{ 4, 1}, { 2, 1},{ 0, 37},{ 0, 68},{ 0, 96},{ 2, 1},{ 0, 99}, { 0, 54},{ 4, 1},{ 2, 1},{ 0,112},{ 0, 23},{ 0,113}, { 16, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 7},{ 0,100}, { 0,114},{ 2, 1},{ 0, 39},{ 4, 1},{ 2, 1},{ 0, 83}, { 0, 53},{ 2, 1},{ 0, 84},{ 0, 69},{ 10, 1},{ 4, 1}, { 2, 1},{ 0, 70},{ 0,115},{ 2, 1},{ 0, 55},{ 2, 1}, { 0,101},{ 0, 86},{ 10, 1},{ 6, 1},{ 4, 1},{ 2, 1}, { 0, 85},{ 0, 87},{ 0,116},{ 2, 1},{ 0, 71},{ 0,102}, { 4, 1},{ 2, 1},{ 0,117},{ 0,118},{ 2, 1},{ 0,103}, { 0,119}}, htd12[127][2]={{ 12, 1},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1},{ 2, 1}, { 0, 17},{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 32},{ 0, 2}, { 16, 1},{ 4, 1},{ 2, 1},{ 0, 33},{ 0, 18},{ 4, 1}, { 2, 1},{ 0, 34},{ 0, 49},{ 2, 1},{ 0, 19},{ 2, 1}, { 0, 48},{ 2, 1},{ 0, 3},{ 0, 64},{ 26, 1},{ 8, 1}, { 4, 1},{ 2, 1},{ 0, 50},{ 0, 35},{ 2, 1},{ 0, 65}, { 0, 51},{ 10, 1},{ 4, 1},{ 2, 1},{ 0, 20},{ 0, 66}, { 2, 1},{ 0, 36},{ 2, 1},{ 0, 4},{ 0, 80},{ 4, 1}, { 2, 1},{ 0, 67},{ 0, 52},{ 2, 1},{ 0, 81},{ 0, 21}, { 28, 1},{ 14, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 82}, { 0, 37},{ 2, 1},{ 0, 83},{ 0, 53},{ 4, 1},{ 2, 1}, { 0, 96},{ 0, 22},{ 0, 97},{ 4, 1},{ 2, 1},{ 0, 98}, { 0, 38},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 5},{ 0, 6}, { 0, 68},{ 2, 1},{ 0, 84},{ 0, 69},{ 18, 1},{ 10, 1}, { 4, 1},{ 2, 1},{ 0, 99},{ 0, 54},{ 4, 1},{ 2, 1}, { 0,112},{ 0, 7},{ 0,113},{ 4, 1},{ 2, 1},{ 0, 23}, { 0,100},{ 2, 1},{ 0, 70},{ 0,114},{ 10, 1},{ 6, 1}, { 2, 1},{ 0, 39},{ 2, 1},{ 0, 85},{ 0,115},{ 2, 1}, { 0, 55},{ 0, 86},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,101}, { 0,116},{ 2, 1},{ 0, 71},{ 0,102},{ 4, 1},{ 2, 1}, { 0,117},{ 0, 87},{ 2, 1},{ 0,118},{ 2, 1},{ 0,103}, { 0,119}}, htd13[511][2]={{ 2, 1},{ 0, 0},{ 6, 1},{ 2, 1},{ 0, 16},{ 2, 1}, { 0, 1},{ 0, 17},{ 28, 1},{ 8, 1},{ 4, 1},{ 2, 1}, { 0, 32},{ 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 8, 1}, { 4, 1},{ 2, 1},{ 0, 34},{ 0, 48},{ 2, 1},{ 0, 3}, { 0, 49},{ 6, 1},{ 2, 1},{ 0, 19},{ 2, 1},{ 0, 50}, { 0, 35},{ 4, 1},{ 2, 1},{ 0, 64},{ 0, 4},{ 0, 65}, { 70, 1},{ 28, 1},{ 14, 1},{ 6, 1},{ 2, 1},{ 0, 20}, { 2, 1},{ 0, 51},{ 0, 66},{ 4, 1},{ 2, 1},{ 0, 36}, { 0, 80},{ 2, 1},{ 0, 67},{ 0, 52},{ 4, 1},{ 2, 1}, { 0, 81},{ 0, 21},{ 4, 1},{ 2, 1},{ 0, 5},{ 0, 82}, // 60 { 2, 1},{ 0, 37},{ 2, 1},{ 0, 68},{ 0, 83},{ 14, 1}, { 8, 1},{ 4, 1},{ 2, 1},{ 0, 96},{ 0, 6},{ 2, 1}, { 0, 97},{ 0, 22},{ 4, 1},{ 2, 1},{ 0,128},{ 0, 8}, { 0,129},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 53}, { 0, 98},{ 2, 1},{ 0, 38},{ 0, 84},{ 4, 1},{ 2, 1}, { 0, 69},{ 0, 99},{ 2, 1},{ 0, 54},{ 0,112},{ 6, 1}, { 4, 1},{ 2, 1},{ 0, 7},{ 0, 85},{ 0,113},{ 2, 1}, { 0, 23},{ 2, 1},{ 0, 39},{ 0, 55},{ 72, 1},{ 24, 1}, { 12, 1},{ 4, 1},{ 2, 1},{ 0, 24},{ 0,130},{ 2, 1}, { 0, 40},{ 4, 1},{ 2, 1},{ 0,100},{ 0, 70},{ 0,114}, // 120 { 8, 1},{ 4, 1},{ 2, 1},{ 0,132},{ 0, 72},{ 2, 1}, { 0,144},{ 0, 9},{ 2, 1},{ 0,145},{ 0, 25},{ 24, 1}, { 14, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,115},{ 0,101}, { 2, 1},{ 0, 86},{ 0,116},{ 4, 1},{ 2, 1},{ 0, 71}, { 0,102},{ 0,131},{ 6, 1},{ 2, 1},{ 0, 56},{ 2, 1}, { 0,117},{ 0, 87},{ 2, 1},{ 0,146},{ 0, 41},{ 14, 1}, { 8, 1},{ 4, 1},{ 2, 1},{ 0,103},{ 0,133},{ 2, 1}, { 0, 88},{ 0, 57},{ 2, 1},{ 0,147},{ 2, 1},{ 0, 73}, { 0,134},{ 6, 1},{ 2, 1},{ 0,160},{ 2, 1},{ 0,104}, { 0, 10},{ 2, 1},{ 0,161},{ 0, 26},{ 68, 1},{ 24, 1}, // 180 { 12, 1},{ 4, 1},{ 2, 1},{ 0,162},{ 0, 42},{ 4, 1}, { 2, 1},{ 0,149},{ 0, 89},{ 2, 1},{ 0,163},{ 0, 58}, { 8, 1},{ 4, 1},{ 2, 1},{ 0, 74},{ 0,150},{ 2, 1}, { 0,176},{ 0, 11},{ 2, 1},{ 0,177},{ 0, 27},{ 20, 1}, { 8, 1},{ 2, 1},{ 0,178},{ 4, 1},{ 2, 1},{ 0,118}, { 0,119},{ 0,148},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,135}, { 0,120},{ 0,164},{ 4, 1},{ 2, 1},{ 0,105},{ 0,165}, { 0, 43},{ 12, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 90}, { 0,136},{ 0,179},{ 2, 1},{ 0, 59},{ 2, 1},{ 0,121}, { 0,166},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,106},{ 0,180}, // 240 { 0,192},{ 4, 1},{ 2, 1},{ 0, 12},{ 0,152},{ 0,193}, { 60, 1},{ 22, 1},{ 10, 1},{ 6, 1},{ 2, 1},{ 0, 28}, { 2, 1},{ 0,137},{ 0,181},{ 2, 1},{ 0, 91},{ 0,194}, { 4, 1},{ 2, 1},{ 0, 44},{ 0, 60},{ 4, 1},{ 2, 1}, { 0,182},{ 0,107},{ 2, 1},{ 0,196},{ 0, 76},{ 16, 1}, { 8, 1},{ 4, 1},{ 2, 1},{ 0,168},{ 0,138},{ 2, 1}, { 0,208},{ 0, 13},{ 2, 1},{ 0,209},{ 2, 1},{ 0, 75}, { 2, 1},{ 0,151},{ 0,167},{ 12, 1},{ 6, 1},{ 2, 1}, { 0,195},{ 2, 1},{ 0,122},{ 0,153},{ 4, 1},{ 2, 1}, { 0,197},{ 0, 92},{ 0,183},{ 4, 1},{ 2, 1},{ 0, 29}, // 300 { 0,210},{ 2, 1},{ 0, 45},{ 2, 1},{ 0,123},{ 0,211}, { 52, 1},{ 28, 1},{ 12, 1},{ 4, 1},{ 2, 1},{ 0, 61}, { 0,198},{ 4, 1},{ 2, 1},{ 0,108},{ 0,169},{ 2, 1}, { 0,154},{ 0,212},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,184}, { 0,139},{ 2, 1},{ 0, 77},{ 0,199},{ 4, 1},{ 2, 1}, { 0,124},{ 0,213},{ 2, 1},{ 0, 93},{ 0,224},{ 10, 1}, { 4, 1},{ 2, 1},{ 0,225},{ 0, 30},{ 4, 1},{ 2, 1}, { 0, 14},{ 0, 46},{ 0,226},{ 8, 1},{ 4, 1},{ 2, 1}, { 0,227},{ 0,109},{ 2, 1},{ 0,140},{ 0,228},{ 4, 1}, { 2, 1},{ 0,229},{ 0,186},{ 0,240},{ 38, 1},{ 16, 1}, // 360 { 4, 1},{ 2, 1},{ 0,241},{ 0, 31},{ 6, 1},{ 4, 1}, { 2, 1},{ 0,170},{ 0,155},{ 0,185},{ 2, 1},{ 0, 62}, { 2, 1},{ 0,214},{ 0,200},{ 12, 1},{ 6, 1},{ 2, 1}, { 0, 78},{ 2, 1},{ 0,215},{ 0,125},{ 2, 1},{ 0,171}, { 2, 1},{ 0, 94},{ 0,201},{ 6, 1},{ 2, 1},{ 0, 15}, { 2, 1},{ 0,156},{ 0,110},{ 2, 1},{ 0,242},{ 0, 47}, { 32, 1},{ 16, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,216}, { 0,141},{ 0, 63},{ 6, 1},{ 2, 1},{ 0,243},{ 2, 1}, { 0,230},{ 0,202},{ 2, 1},{ 0,244},{ 0, 79},{ 8, 1}, { 4, 1},{ 2, 1},{ 0,187},{ 0,172},{ 2, 1},{ 0,231}, // 420 { 0,245},{ 4, 1},{ 2, 1},{ 0,217},{ 0,157},{ 2, 1}, { 0, 95},{ 0,232},{ 30, 1},{ 12, 1},{ 6, 1},{ 2, 1}, { 0,111},{ 2, 1},{ 0,246},{ 0,203},{ 4, 1},{ 2, 1}, { 0,188},{ 0,173},{ 0,218},{ 8, 1},{ 2, 1},{ 0,247}, { 4, 1},{ 2, 1},{ 0,126},{ 0,127},{ 0,142},{ 6, 1}, { 4, 1},{ 2, 1},{ 0,158},{ 0,174},{ 0,204},{ 2, 1}, { 0,248},{ 0,143},{ 18, 1},{ 8, 1},{ 4, 1},{ 2, 1}, { 0,219},{ 0,189},{ 2, 1},{ 0,234},{ 0,249},{ 4, 1}, { 2, 1},{ 0,159},{ 0,235},{ 2, 1},{ 0,190},{ 2, 1}, { 0,205},{ 0,250},{ 14, 1},{ 4, 1},{ 2, 1},{ 0,221}, // 480 { 0,236},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,233},{ 0,175}, { 0,220},{ 2, 1},{ 0,206},{ 0,251},{ 8, 1},{ 4, 1}, { 2, 1},{ 0,191},{ 0,222},{ 2, 1},{ 0,207},{ 0,238}, { 4, 1},{ 2, 1},{ 0,223},{ 0,239},{ 2, 1},{ 0,255}, { 2, 1},{ 0,237},{ 2, 1},{ 0,253},{ 2, 1},{ 0,252}, { 0,254}}, htd15[511][2]={{ 16, 1},{ 6, 1},{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 16}, { 0, 1},{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32}, { 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 50, 1},{ 16, 1}, { 6, 1},{ 2, 1},{ 0, 34},{ 2, 1},{ 0, 48},{ 0, 49}, { 6, 1},{ 2, 1},{ 0, 19},{ 2, 1},{ 0, 3},{ 0, 64}, { 2, 1},{ 0, 50},{ 0, 35},{ 14, 1},{ 6, 1},{ 4, 1}, { 2, 1},{ 0, 4},{ 0, 20},{ 0, 65},{ 4, 1},{ 2, 1}, { 0, 51},{ 0, 66},{ 2, 1},{ 0, 36},{ 0, 67},{ 10, 1}, { 6, 1},{ 2, 1},{ 0, 52},{ 2, 1},{ 0, 80},{ 0, 5}, { 2, 1},{ 0, 81},{ 0, 21},{ 4, 1},{ 2, 1},{ 0, 82}, // 60 { 0, 37},{ 4, 1},{ 2, 1},{ 0, 68},{ 0, 83},{ 0, 97}, { 90, 1},{ 36, 1},{ 18, 1},{ 10, 1},{ 6, 1},{ 2, 1}, { 0, 53},{ 2, 1},{ 0, 96},{ 0, 6},{ 2, 1},{ 0, 22}, { 0, 98},{ 4, 1},{ 2, 1},{ 0, 38},{ 0, 84},{ 2, 1}, { 0, 69},{ 0, 99},{ 10, 1},{ 6, 1},{ 2, 1},{ 0, 54}, { 2, 1},{ 0,112},{ 0, 7},{ 2, 1},{ 0,113},{ 0, 85}, { 4, 1},{ 2, 1},{ 0, 23},{ 0,100},{ 2, 1},{ 0,114}, { 0, 39},{ 24, 1},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1}, { 0, 70},{ 0,115},{ 2, 1},{ 0, 55},{ 0,101},{ 4, 1}, { 2, 1},{ 0, 86},{ 0,128},{ 2, 1},{ 0, 8},{ 0,116}, // 120 { 4, 1},{ 2, 1},{ 0,129},{ 0, 24},{ 2, 1},{ 0,130}, { 0, 40},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 71}, { 0,102},{ 2, 1},{ 0,131},{ 0, 56},{ 4, 1},{ 2, 1}, { 0,117},{ 0, 87},{ 2, 1},{ 0,132},{ 0, 72},{ 6, 1}, { 4, 1},{ 2, 1},{ 0,144},{ 0, 25},{ 0,145},{ 4, 1}, { 2, 1},{ 0,146},{ 0,118},{ 2, 1},{ 0,103},{ 0, 41}, { 92, 1},{ 36, 1},{ 18, 1},{ 10, 1},{ 4, 1},{ 2, 1}, { 0,133},{ 0, 88},{ 4, 1},{ 2, 1},{ 0, 9},{ 0,119}, { 0,147},{ 4, 1},{ 2, 1},{ 0, 57},{ 0,148},{ 2, 1}, { 0, 73},{ 0,134},{ 10, 1},{ 6, 1},{ 2, 1},{ 0,104}, // 180 { 2, 1},{ 0,160},{ 0, 10},{ 2, 1},{ 0,161},{ 0, 26}, { 4, 1},{ 2, 1},{ 0,162},{ 0, 42},{ 2, 1},{ 0,149}, { 0, 89},{ 26, 1},{ 14, 1},{ 6, 1},{ 2, 1},{ 0,163}, { 2, 1},{ 0, 58},{ 0,135},{ 4, 1},{ 2, 1},{ 0,120}, { 0,164},{ 2, 1},{ 0, 74},{ 0,150},{ 6, 1},{ 4, 1}, { 2, 1},{ 0,105},{ 0,176},{ 0,177},{ 4, 1},{ 2, 1}, { 0, 27},{ 0,165},{ 0,178},{ 14, 1},{ 8, 1},{ 4, 1}, { 2, 1},{ 0, 90},{ 0, 43},{ 2, 1},{ 0,136},{ 0,151}, { 2, 1},{ 0,179},{ 2, 1},{ 0,121},{ 0, 59},{ 8, 1}, { 4, 1},{ 2, 1},{ 0,106},{ 0,180},{ 2, 1},{ 0, 75}, // 240 { 0,193},{ 4, 1},{ 2, 1},{ 0,152},{ 0,137},{ 2, 1}, { 0, 28},{ 0,181},{ 80, 1},{ 34, 1},{ 16, 1},{ 6, 1}, { 4, 1},{ 2, 1},{ 0, 91},{ 0, 44},{ 0,194},{ 6, 1}, { 4, 1},{ 2, 1},{ 0, 11},{ 0,192},{ 0,166},{ 2, 1}, { 0,167},{ 0,122},{ 10, 1},{ 4, 1},{ 2, 1},{ 0,195}, { 0, 60},{ 4, 1},{ 2, 1},{ 0, 12},{ 0,153},{ 0,182}, { 4, 1},{ 2, 1},{ 0,107},{ 0,196},{ 2, 1},{ 0, 76}, { 0,168},{ 20, 1},{ 10, 1},{ 4, 1},{ 2, 1},{ 0,138}, { 0,197},{ 4, 1},{ 2, 1},{ 0,208},{ 0, 92},{ 0,209}, { 4, 1},{ 2, 1},{ 0,183},{ 0,123},{ 2, 1},{ 0, 29}, // 300 { 2, 1},{ 0, 13},{ 0, 45},{ 12, 1},{ 4, 1},{ 2, 1}, { 0,210},{ 0,211},{ 4, 1},{ 2, 1},{ 0, 61},{ 0,198}, { 2, 1},{ 0,108},{ 0,169},{ 6, 1},{ 4, 1},{ 2, 1}, { 0,154},{ 0,184},{ 0,212},{ 4, 1},{ 2, 1},{ 0,139}, { 0, 77},{ 2, 1},{ 0,199},{ 0,124},{ 68, 1},{ 34, 1}, { 18, 1},{ 10, 1},{ 4, 1},{ 2, 1},{ 0,213},{ 0, 93}, { 4, 1},{ 2, 1},{ 0,224},{ 0, 14},{ 0,225},{ 4, 1}, { 2, 1},{ 0, 30},{ 0,226},{ 2, 1},{ 0,170},{ 0, 46}, { 8, 1},{ 4, 1},{ 2, 1},{ 0,185},{ 0,155},{ 2, 1}, { 0,227},{ 0,214},{ 4, 1},{ 2, 1},{ 0,109},{ 0, 62}, // 360 { 2, 1},{ 0,200},{ 0,140},{ 16, 1},{ 8, 1},{ 4, 1}, { 2, 1},{ 0,228},{ 0, 78},{ 2, 1},{ 0,215},{ 0,125}, { 4, 1},{ 2, 1},{ 0,229},{ 0,186},{ 2, 1},{ 0,171}, { 0, 94},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,201},{ 0,156}, { 2, 1},{ 0,241},{ 0, 31},{ 6, 1},{ 4, 1},{ 2, 1}, { 0,240},{ 0,110},{ 0,242},{ 2, 1},{ 0, 47},{ 0,230}, { 38, 1},{ 18, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,216}, { 0,243},{ 2, 1},{ 0, 63},{ 0,244},{ 6, 1},{ 2, 1}, { 0, 79},{ 2, 1},{ 0,141},{ 0,217},{ 2, 1},{ 0,187}, { 0,202},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,172},{ 0,231}, // 420 { 2, 1},{ 0,126},{ 0,245},{ 8, 1},{ 4, 1},{ 2, 1}, { 0,157},{ 0, 95},{ 2, 1},{ 0,232},{ 0,142},{ 2, 1}, { 0,246},{ 0,203},{ 34, 1},{ 18, 1},{ 10, 1},{ 6, 1}, { 4, 1},{ 2, 1},{ 0, 15},{ 0,174},{ 0,111},{ 2, 1}, { 0,188},{ 0,218},{ 4, 1},{ 2, 1},{ 0,173},{ 0,247}, { 2, 1},{ 0,127},{ 0,233},{ 8, 1},{ 4, 1},{ 2, 1}, { 0,158},{ 0,204},{ 2, 1},{ 0,248},{ 0,143},{ 4, 1}, { 2, 1},{ 0,219},{ 0,189},{ 2, 1},{ 0,234},{ 0,249}, { 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,159},{ 0,220}, { 2, 1},{ 0,205},{ 0,235},{ 4, 1},{ 2, 1},{ 0,190}, // 480 { 0,250},{ 2, 1},{ 0,175},{ 0,221},{ 14, 1},{ 6, 1}, { 4, 1},{ 2, 1},{ 0,236},{ 0,206},{ 0,251},{ 4, 1}, { 2, 1},{ 0,191},{ 0,237},{ 2, 1},{ 0,222},{ 0,252}, { 6, 1},{ 4, 1},{ 2, 1},{ 0,207},{ 0,253},{ 0,238}, { 4, 1},{ 2, 1},{ 0,223},{ 0,254},{ 2, 1},{ 0,239}, { 0,255}}, htd16[511][2]={{ 2, 1},{ 0, 0},{ 6, 1},{ 2, 1},{ 0, 16},{ 2, 1}, { 0, 1},{ 0, 17},{ 42, 1},{ 8, 1},{ 4, 1},{ 2, 1}, { 0, 32},{ 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 10, 1}, { 6, 1},{ 2, 1},{ 0, 34},{ 2, 1},{ 0, 48},{ 0, 3}, { 2, 1},{ 0, 49},{ 0, 19},{ 10, 1},{ 4, 1},{ 2, 1}, { 0, 50},{ 0, 35},{ 4, 1},{ 2, 1},{ 0, 64},{ 0, 4}, { 0, 65},{ 6, 1},{ 2, 1},{ 0, 20},{ 2, 1},{ 0, 51}, { 0, 66},{ 4, 1},{ 2, 1},{ 0, 36},{ 0, 80},{ 2, 1}, { 0, 67},{ 0, 52},{138, 1},{ 40, 1},{ 16, 1},{ 6, 1}, { 4, 1},{ 2, 1},{ 0, 5},{ 0, 21},{ 0, 81},{ 4, 1}, // 60 { 2, 1},{ 0, 82},{ 0, 37},{ 4, 1},{ 2, 1},{ 0, 68}, { 0, 53},{ 0, 83},{ 10, 1},{ 6, 1},{ 4, 1},{ 2, 1}, { 0, 96},{ 0, 6},{ 0, 97},{ 2, 1},{ 0, 22},{ 0, 98}, { 8, 1},{ 4, 1},{ 2, 1},{ 0, 38},{ 0, 84},{ 2, 1}, { 0, 69},{ 0, 99},{ 4, 1},{ 2, 1},{ 0, 54},{ 0,112}, { 0,113},{ 40, 1},{ 18, 1},{ 8, 1},{ 2, 1},{ 0, 23}, { 2, 1},{ 0, 7},{ 2, 1},{ 0, 85},{ 0,100},{ 4, 1}, { 2, 1},{ 0,114},{ 0, 39},{ 4, 1},{ 2, 1},{ 0, 70}, { 0,101},{ 0,115},{ 10, 1},{ 6, 1},{ 2, 1},{ 0, 55}, { 2, 1},{ 0, 86},{ 0, 8},{ 2, 1},{ 0,128},{ 0,129}, // 120 { 6, 1},{ 2, 1},{ 0, 24},{ 2, 1},{ 0,116},{ 0, 71}, { 2, 1},{ 0,130},{ 2, 1},{ 0, 40},{ 0,102},{ 24, 1}, { 14, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,131},{ 0, 56}, { 2, 1},{ 0,117},{ 0,132},{ 4, 1},{ 2, 1},{ 0, 72}, { 0,144},{ 0,145},{ 6, 1},{ 2, 1},{ 0, 25},{ 2, 1}, { 0, 9},{ 0,118},{ 2, 1},{ 0,146},{ 0, 41},{ 14, 1}, { 8, 1},{ 4, 1},{ 2, 1},{ 0,133},{ 0, 88},{ 2, 1}, { 0,147},{ 0, 57},{ 4, 1},{ 2, 1},{ 0,160},{ 0, 10}, { 0, 26},{ 8, 1},{ 2, 1},{ 0,162},{ 2, 1},{ 0,103}, { 2, 1},{ 0, 87},{ 0, 73},{ 6, 1},{ 2, 1},{ 0,148}, // 180 { 2, 1},{ 0,119},{ 0,134},{ 2, 1},{ 0,161},{ 2, 1}, { 0,104},{ 0,149},{220, 1},{126, 1},{ 50, 1},{ 26, 1}, { 12, 1},{ 6, 1},{ 2, 1},{ 0, 42},{ 2, 1},{ 0, 89}, { 0, 58},{ 2, 1},{ 0,163},{ 2, 1},{ 0,135},{ 0,120}, { 8, 1},{ 4, 1},{ 2, 1},{ 0,164},{ 0, 74},{ 2, 1}, { 0,150},{ 0,105},{ 4, 1},{ 2, 1},{ 0,176},{ 0, 11}, { 0,177},{ 10, 1},{ 4, 1},{ 2, 1},{ 0, 27},{ 0,178}, { 2, 1},{ 0, 43},{ 2, 1},{ 0,165},{ 0, 90},{ 6, 1}, { 2, 1},{ 0,179},{ 2, 1},{ 0,166},{ 0,106},{ 4, 1}, { 2, 1},{ 0,180},{ 0, 75},{ 2, 1},{ 0, 12},{ 0,193}, // 240 { 30, 1},{ 14, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,181}, { 0,194},{ 0, 44},{ 4, 1},{ 2, 1},{ 0,167},{ 0,195}, { 2, 1},{ 0,107},{ 0,196},{ 8, 1},{ 2, 1},{ 0, 29}, { 4, 1},{ 2, 1},{ 0,136},{ 0,151},{ 0, 59},{ 4, 1}, { 2, 1},{ 0,209},{ 0,210},{ 2, 1},{ 0, 45},{ 0,211}, { 18, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 30},{ 0, 46}, { 0,226},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,121},{ 0,152}, { 0,192},{ 2, 1},{ 0, 28},{ 2, 1},{ 0,137},{ 0, 91}, { 14, 1},{ 6, 1},{ 2, 1},{ 0, 60},{ 2, 1},{ 0,122}, { 0,182},{ 4, 1},{ 2, 1},{ 0, 76},{ 0,153},{ 2, 1}, // 300 { 0,168},{ 0,138},{ 6, 1},{ 2, 1},{ 0, 13},{ 2, 1}, { 0,197},{ 0, 92},{ 4, 1},{ 2, 1},{ 0, 61},{ 0,198}, { 2, 1},{ 0,108},{ 0,154},{ 88, 1},{ 86, 1},{ 36, 1}, { 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,139},{ 0, 77}, { 2, 1},{ 0,199},{ 0,124},{ 4, 1},{ 2, 1},{ 0,213}, { 0, 93},{ 2, 1},{ 0,224},{ 0, 14},{ 8, 1},{ 2, 1}, { 0,227},{ 4, 1},{ 2, 1},{ 0,208},{ 0,183},{ 0,123}, { 6, 1},{ 4, 1},{ 2, 1},{ 0,169},{ 0,184},{ 0,212}, { 2, 1},{ 0,225},{ 2, 1},{ 0,170},{ 0,185},{ 24, 1}, { 10, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,155},{ 0,214}, // 360 { 0,109},{ 2, 1},{ 0, 62},{ 0,200},{ 6, 1},{ 4, 1}, { 2, 1},{ 0,140},{ 0,228},{ 0, 78},{ 4, 1},{ 2, 1}, { 0,215},{ 0,229},{ 2, 1},{ 0,186},{ 0,171},{ 12, 1}, { 4, 1},{ 2, 1},{ 0,156},{ 0,230},{ 4, 1},{ 2, 1}, { 0,110},{ 0,216},{ 2, 1},{ 0,141},{ 0,187},{ 8, 1}, { 4, 1},{ 2, 1},{ 0,231},{ 0,157},{ 2, 1},{ 0,232}, { 0,142},{ 4, 1},{ 2, 1},{ 0,203},{ 0,188},{ 0,158}, { 0,241},{ 2, 1},{ 0, 31},{ 2, 1},{ 0, 15},{ 0, 47}, { 66, 1},{ 56, 1},{ 2, 1},{ 0,242},{ 52, 1},{ 50, 1}, { 20, 1},{ 8, 1},{ 2, 1},{ 0,189},{ 2, 1},{ 0, 94}, // 420 { 2, 1},{ 0,125},{ 0,201},{ 6, 1},{ 2, 1},{ 0,202}, { 2, 1},{ 0,172},{ 0,126},{ 4, 1},{ 2, 1},{ 0,218}, { 0,173},{ 0,204},{ 10, 1},{ 6, 1},{ 2, 1},{ 0,174}, { 2, 1},{ 0,219},{ 0,220},{ 2, 1},{ 0,205},{ 0,190}, { 6, 1},{ 4, 1},{ 2, 1},{ 0,235},{ 0,237},{ 0,238}, { 6, 1},{ 4, 1},{ 2, 1},{ 0,217},{ 0,234},{ 0,233}, { 2, 1},{ 0,222},{ 4, 1},{ 2, 1},{ 0,221},{ 0,236}, { 0,206},{ 0, 63},{ 0,240},{ 4, 1},{ 2, 1},{ 0,243}, { 0,244},{ 2, 1},{ 0, 79},{ 2, 1},{ 0,245},{ 0, 95}, { 10, 1},{ 2, 1},{ 0,255},{ 4, 1},{ 2, 1},{ 0,246}, // 480 { 0,111},{ 2, 1},{ 0,247},{ 0,127},{ 12, 1},{ 6, 1}, { 2, 1},{ 0,143},{ 2, 1},{ 0,248},{ 0,249},{ 4, 1}, { 2, 1},{ 0,159},{ 0,250},{ 0,175},{ 8, 1},{ 4, 1}, { 2, 1},{ 0,251},{ 0,191},{ 2, 1},{ 0,252},{ 0,207}, { 4, 1},{ 2, 1},{ 0,253},{ 0,223},{ 2, 1},{ 0,254}, { 0,239}}, htd24[512][2]={{ 60, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 16}, { 2, 1},{ 0, 1},{ 0, 17},{ 14, 1},{ 6, 1},{ 4, 1}, { 2, 1},{ 0, 32},{ 0, 2},{ 0, 33},{ 2, 1},{ 0, 18}, { 2, 1},{ 0, 34},{ 2, 1},{ 0, 48},{ 0, 3},{ 14, 1}, { 4, 1},{ 2, 1},{ 0, 49},{ 0, 19},{ 4, 1},{ 2, 1}, { 0, 50},{ 0, 35},{ 4, 1},{ 2, 1},{ 0, 64},{ 0, 4}, { 0, 65},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 20},{ 0, 51}, { 2, 1},{ 0, 66},{ 0, 36},{ 6, 1},{ 4, 1},{ 2, 1}, { 0, 67},{ 0, 52},{ 0, 81},{ 6, 1},{ 4, 1},{ 2, 1}, { 0, 80},{ 0, 5},{ 0, 21},{ 2, 1},{ 0, 82},{ 0, 37}, // 60 {250+85, 1},{ 98, 1},{ 34, 1},{ 18, 1},{ 10, 1},{ 4, 1}, { 2, 1},{ 0, 68},{ 0, 83},{ 2, 1},{ 0, 53},{ 2, 1}, { 0, 96},{ 0, 6},{ 4, 1},{ 2, 1},{ 0, 97},{ 0, 22}, { 2, 1},{ 0, 98},{ 0, 38},{ 8, 1},{ 4, 1},{ 2, 1}, { 0, 84},{ 0, 69},{ 2, 1},{ 0, 99},{ 0, 54},{ 4, 1}, { 2, 1},{ 0,113},{ 0, 85},{ 2, 1},{ 0,100},{ 0, 70}, { 32, 1},{ 14, 1},{ 6, 1},{ 2, 1},{ 0,114},{ 2, 1}, { 0, 39},{ 0, 55},{ 2, 1},{ 0,115},{ 4, 1},{ 2, 1}, { 0,112},{ 0, 7},{ 0, 23},{ 10, 1},{ 4, 1},{ 2, 1}, { 0,101},{ 0, 86},{ 4, 1},{ 2, 1},{ 0,128},{ 0, 8}, // 120 { 0,129},{ 4, 1},{ 2, 1},{ 0,116},{ 0, 71},{ 2, 1}, { 0, 24},{ 0,130},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1}, { 0, 40},{ 0,102},{ 2, 1},{ 0,131},{ 0, 56},{ 4, 1}, { 2, 1},{ 0,117},{ 0, 87},{ 2, 1},{ 0,132},{ 0, 72}, { 8, 1},{ 4, 1},{ 2, 1},{ 0,145},{ 0, 25},{ 2, 1}, { 0,146},{ 0,118},{ 4, 1},{ 2, 1},{ 0,103},{ 0, 41}, { 2, 1},{ 0,133},{ 0, 88},{ 92, 1},{ 34, 1},{ 16, 1}, { 8, 1},{ 4, 1},{ 2, 1},{ 0,147},{ 0, 57},{ 2, 1}, { 0,148},{ 0, 73},{ 4, 1},{ 2, 1},{ 0,119},{ 0,134}, { 2, 1},{ 0,104},{ 0,161},{ 8, 1},{ 4, 1},{ 2, 1}, // 180 { 0,162},{ 0, 42},{ 2, 1},{ 0,149},{ 0, 89},{ 4, 1}, { 2, 1},{ 0,163},{ 0, 58},{ 2, 1},{ 0,135},{ 2, 1}, { 0,120},{ 0, 74},{ 22, 1},{ 12, 1},{ 4, 1},{ 2, 1}, { 0,164},{ 0,150},{ 4, 1},{ 2, 1},{ 0,105},{ 0,177}, { 2, 1},{ 0, 27},{ 0,165},{ 6, 1},{ 2, 1},{ 0,178}, { 2, 1},{ 0, 90},{ 0, 43},{ 2, 1},{ 0,136},{ 0,179}, { 16, 1},{ 10, 1},{ 6, 1},{ 2, 1},{ 0,144},{ 2, 1}, { 0, 9},{ 0,160},{ 2, 1},{ 0,151},{ 0,121},{ 4, 1}, { 2, 1},{ 0,166},{ 0,106},{ 0,180},{ 12, 1},{ 6, 1}, { 2, 1},{ 0, 26},{ 2, 1},{ 0, 10},{ 0,176},{ 2, 1}, // 240 { 0, 59},{ 2, 1},{ 0, 11},{ 0,192},{ 4, 1},{ 2, 1}, { 0, 75},{ 0,193},{ 2, 1},{ 0,152},{ 0,137},{ 67, 1}, { 34, 1},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 28}, { 0,181},{ 2, 1},{ 0, 91},{ 0,194},{ 4, 1},{ 2, 1}, { 0, 44},{ 0,167},{ 2, 1},{ 0,122},{ 0,195},{ 10, 1}, { 6, 1},{ 2, 1},{ 0, 60},{ 2, 1},{ 0, 12},{ 0,208}, { 2, 1},{ 0,182},{ 0,107},{ 4, 1},{ 2, 1},{ 0,196}, { 0, 76},{ 2, 1},{ 0,153},{ 0,168},{ 16, 1},{ 8, 1}, { 4, 1},{ 2, 1},{ 0,138},{ 0,197},{ 2, 1},{ 0, 92}, { 0,209},{ 4, 1},{ 2, 1},{ 0,183},{ 0,123},{ 2, 1}, // 300 { 0, 29},{ 0,210},{ 9, 1},{ 4, 1},{ 2, 1},{ 0, 45}, { 0,211},{ 2, 1},{ 0, 61},{ 0,198},{ 85,250},{ 4, 1}, // 306 - { 2, 1},{ 0,108},{ 0,169},{ 2, 1},{ 0,154},{ 0,212}, { 32, 1},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,184}, { 0,139},{ 2, 1},{ 0, 77},{ 0,199},{ 4, 1},{ 2, 1}, { 0,124},{ 0,213},{ 2, 1},{ 0, 93},{ 0,225},{ 8, 1}, { 4, 1},{ 2, 1},{ 0, 30},{ 0,226},{ 2, 1},{ 0,170}, { 0,185},{ 4, 1},{ 2, 1},{ 0,155},{ 0,227},{ 2, 1}, { 0,214},{ 0,109},{ 20, 1},{ 10, 1},{ 6, 1},{ 2, 1}, { 0, 62},{ 2, 1},{ 0, 46},{ 0, 78},{ 2, 1},{ 0,200}, // 360 { 0,140},{ 4, 1},{ 2, 1},{ 0,228},{ 0,215},{ 4, 1}, { 2, 1},{ 0,125},{ 0,171},{ 0,229},{ 10, 1},{ 4, 1}, { 2, 1},{ 0,186},{ 0, 94},{ 2, 1},{ 0,201},{ 2, 1}, { 0,156},{ 0,110},{ 8, 1},{ 2, 1},{ 0,230},{ 2, 1}, { 0, 13},{ 2, 1},{ 0,224},{ 0, 14},{ 4, 1},{ 2, 1}, { 0,216},{ 0,141},{ 2, 1},{ 0,187},{ 0,202},{ 74, 1}, { 2, 1},{ 0,255},{ 64, 1},{ 58, 1},{ 32, 1},{ 16, 1}, { 8, 1},{ 4, 1},{ 2, 1},{ 0,172},{ 0,231},{ 2, 1}, { 0,126},{ 0,217},{ 4, 1},{ 2, 1},{ 0,157},{ 0,232}, { 2, 1},{ 0,142},{ 0,203},{ 8, 1},{ 4, 1},{ 2, 1}, // 420 { 0,188},{ 0,218},{ 2, 1},{ 0,173},{ 0,233},{ 4, 1}, { 2, 1},{ 0,158},{ 0,204},{ 2, 1},{ 0,219},{ 0,189}, { 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,234},{ 0,174}, { 2, 1},{ 0,220},{ 0,205},{ 4, 1},{ 2, 1},{ 0,235}, { 0,190},{ 2, 1},{ 0,221},{ 0,236},{ 8, 1},{ 4, 1}, { 2, 1},{ 0,206},{ 0,237},{ 2, 1},{ 0,222},{ 0,238}, { 0, 15},{ 4, 1},{ 2, 1},{ 0,240},{ 0, 31},{ 0,241}, { 4, 1},{ 2, 1},{ 0,242},{ 0, 47},{ 2, 1},{ 0,243}, { 0, 63},{ 18, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,244}, { 0, 79},{ 2, 1},{ 0,245},{ 0, 95},{ 4, 1},{ 2, 1}, // 480 { 0,246},{ 0,111},{ 2, 1},{ 0,247},{ 2, 1},{ 0,127}, { 0,143},{ 10, 1},{ 4, 1},{ 2, 1},{ 0,248},{ 0,249}, { 4, 1},{ 2, 1},{ 0,159},{ 0,175},{ 0,250},{ 8, 1}, { 4, 1},{ 2, 1},{ 0,251},{ 0,191},{ 2, 1},{ 0,252}, { 0,207},{ 4, 1},{ 2, 1},{ 0,253},{ 0,223},{ 2, 1}, { 0,254},{ 0,239}}, htd32[ 31][2]={{ 2, 1},{ 0, 0},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 8}, { 0, 4},{ 2, 1},{ 0, 1},{ 0, 2},{ 8, 1},{ 4, 1}, { 2, 1},{ 0, 12},{ 0, 10},{ 2, 1},{ 0, 3},{ 0, 6}, { 6, 1},{ 2, 1},{ 0, 9},{ 2, 1},{ 0, 5},{ 0, 7}, { 4, 1},{ 2, 1},{ 0, 14},{ 0, 13},{ 2, 1},{ 0, 15}, { 0, 11}}, htd33[ 31][2]={{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 1}, { 2, 1},{ 0, 2},{ 0, 3},{ 4, 1},{ 2, 1},{ 0, 4}, { 0, 5},{ 2, 1},{ 0, 6},{ 0, 7},{ 8, 1},{ 4, 1}, { 2, 1},{ 0, 8},{ 0, 9},{ 2, 1},{ 0, 10},{ 0, 11}, { 4, 1},{ 2, 1},{ 0, 12},{ 0, 13},{ 2, 1},{ 0, 14}, { 0, 15}}; const HUFFMANCODETABLE Mpegtoraw::ht[HTN]= { { 0, 0-1, 0-1, 0, 0, htd33}, { 1, 2-1, 2-1, 0, 7,htd01}, { 2, 3-1, 3-1, 0, 17,htd02}, { 3, 3-1, 3-1, 0, 17,htd03}, { 4, 0-1, 0-1, 0, 0, htd33}, { 5, 4-1, 4-1, 0, 31,htd05}, { 6, 4-1, 4-1, 0, 31,htd06}, { 7, 6-1, 6-1, 0, 71,htd07}, { 8, 6-1, 6-1, 0, 71,htd08}, { 9, 6-1, 6-1, 0, 71,htd09}, {10, 8-1, 8-1, 0,127,htd10}, {11, 8-1, 8-1, 0,127,htd11}, {12, 8-1, 8-1, 0,127,htd12}, {13,16-1,16-1, 0,511,htd13}, {14, 0-1, 0-1, 0, 0, htd33}, {15,16-1,16-1, 0,511,htd15}, {16,16-1,16-1, 1,511,htd16}, {17,16-1,16-1, 2,511,htd16}, {18,16-1,16-1, 3,511,htd16}, {19,16-1,16-1, 4,511,htd16}, {20,16-1,16-1, 6,511,htd16}, {21,16-1,16-1, 8,511,htd16}, {22,16-1,16-1,10,511,htd16}, {23,16-1,16-1,13,511,htd16}, {24,16-1,16-1, 4,512,htd24}, {25,16-1,16-1, 5,512,htd24}, {26,16-1,16-1, 6,512,htd24}, {27,16-1,16-1, 7,512,htd24}, {28,16-1,16-1, 8,512,htd24}, {29,16-1,16-1, 9,512,htd24}, {30,16-1,16-1,11,512,htd24}, {31,16-1,16-1,13,512,htd24}, {32, 1-1,16-1, 0, 31,htd32}, {33, 1-1,16-1, 0, 31,htd33} }; mp3blaster-3.2.6/mpegsound/fileinput.cc0000664000112600011260000000333012426044701015021 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Woo-jae Jung */ // Binput.cc // Inputstream from file #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "mpegsound.h" /************************/ /* Input bitstrem class */ /************************/ Soundinputstreamfromfile::Soundinputstreamfromfile() { fp = NULL; __canseek = true; } Soundinputstreamfromfile::~Soundinputstreamfromfile() { if(fp) fclose(fp); } bool Soundinputstreamfromfile::open(const char *filename) { struct stat buf; if(filename==NULL) { fp=stdin; size=0; return true; } else if((fp=fopen(filename,"r"))==NULL) { seterrorcode(SOUND_ERROR_FILEOPENFAIL); return false; } stat(filename,&buf); size=buf.st_size; if (size < 10 * 1024) { seterrorcode(SOUND_ERROR_FILEOPENFAIL); return false; } return true; } int Soundinputstreamfromfile::getbytedirect(void) { int c; if((c=getc(fp))<0) seterrorcode(SOUND_ERROR_FILEREADFAIL); return c; } bool Soundinputstreamfromfile::_readbuffer(char *buffer,int size) { if(fread(buffer,size,1,fp)!=1) { seterrorcode(SOUND_ERROR_FILEREADFAIL); return false; } return true; } bool Soundinputstreamfromfile::eof(void) { return feof(fp); }; int Soundinputstreamfromfile::getblock(char *buffer,int size) { return fread(buffer,1,size,fp); } int Soundinputstreamfromfile::getsize(void) { return size; } void Soundinputstreamfromfile::setposition(int pos) { if(fp==stdin)return; fseek(fp,(long)pos,SEEK_SET); } int Soundinputstreamfromfile::getposition(void) { if(fp==stdin)return 0; return (int)ftell(fp); } void Soundinputstreamfromfile::close(void) { if (fp) { fclose(fp); fp = NULL; } } mp3blaster-3.2.6/mpegsound/filter.cc0000664000112600011260000002346212426044701014317 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Filter.cc // Subbandsynthesis routines from maplay 1.2 for Linux // I've modified some macros for reducing source code. #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mpegsound.h" void Mpegtoraw::computebuffer(REAL *fraction,REAL buffer[2][CALCBUFFERSIZE]) { REAL p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pa,pb,pc,pd,pe,pf; REAL q0,q1,q2,q3,q4,q5,q6,q7,q8,q9,qa,qb,qc,qd,qe,qf; REAL *out1,*out2; out1=buffer[currentcalcbuffer]+calcbufferoffset; out2=buffer[currentcalcbuffer^1]+calcbufferoffset; #define OUT1(v,t) out1[(32-(v))*16] =(-(out1[(v)*16]=t)) #define OUT2(v) out2[(96-(v)-32)*16]=out2[((v)-32)*16] // compute new values via a fast cosine transform: { register REAL *x=fraction; p0=x[ 0]+x[31];p1=x[ 1]+x[30];p2=x[ 2]+x[29];p3=x[ 3]+x[28]; p4=x[ 4]+x[27];p5=x[ 5]+x[26];p6=x[ 6]+x[25];p7=x[ 7]+x[24]; p8=x[ 8]+x[23];p9=x[ 9]+x[22];pa=x[10]+x[21];pb=x[11]+x[20]; pc=x[12]+x[19];pd=x[13]+x[18];pe=x[14]+x[17];pf=x[15]+x[16]; } q0=p0+pf;q1=p1+pe;q2=p2+pd;q3=p3+pc; q4=p4+pb;q5=p5+pa;q6=p6+p9;q7=p7+p8; q8=hcos_32[0]*(p0-pf);q9=hcos_32[1]*(p1-pe); qa=hcos_32[2]*(p2-pd);qb=hcos_32[3]*(p3-pc); qc=hcos_32[4]*(p4-pb);qd=hcos_32[5]*(p5-pa); qe=hcos_32[6]*(p6-p9);qf=hcos_32[7]*(p7-p8); p0=q0+q7;p1=q1+q6;p2=q2+q5;p3=q3+q4; p4=hcos_16[0]*(q0-q7);p5=hcos_16[1]*(q1-q6); p6=hcos_16[2]*(q2-q5);p7=hcos_16[3]*(q3-q4); p8=q8+qf;p9=q9+qe;pa=qa+qd;pb=qb+qc; pc=hcos_16[0]*(q8-qf);pd=hcos_16[1]*(q9-qe); pe=hcos_16[2]*(qa-qd);pf=hcos_16[3]*(qb-qc); q0=p0+p3;q1=p1+p2;q2=hcos_8[0]*(p0-p3);q3=hcos_8[1]*(p1-p2); q4=p4+p7;q5=p5+p6;q6=hcos_8[0]*(p4-p7);q7=hcos_8[1]*(p5-p6); q8=p8+pb;q9=p9+pa;qa=hcos_8[0]*(p8-pb);qb=hcos_8[1]*(p9-pa); qc=pc+pf;qd=pd+pe;qe=hcos_8[0]*(pc-pf);qf=hcos_8[1]*(pd-pe); p0=q0+q1;p1=hcos_4*(q0-q1);p2=q2+q3;p3=hcos_4*(q2-q3); p4=q4+q5;p5=hcos_4*(q4-q5);p6=q6+q7;p7=hcos_4*(q6-q7); p8=q8+q9;p9=hcos_4*(q8-q9);pa=qa+qb;pb=hcos_4*(qa-qb); pc=qc+qd;pd=hcos_4*(qc-qd);pe=qe+qf;pf=hcos_4*(qe-qf); { register REAL tmp; tmp=p6+p7; OUT2(36)=-(p5+tmp); OUT2(44)=-(p4+tmp); tmp=pb+pf; OUT1(10,tmp); OUT1(6,pd+tmp); tmp=pe+pf; OUT2(46)=-(p8+pc+tmp); OUT2(34)=-(p9+pd+tmp); tmp+=pa+pb; OUT2(38)=-(pd+tmp); OUT2(42)=-(pc+tmp); OUT1(2,p9+pd+pf); OUT1(4,p5+p7); OUT2(48)=-p0; out2[0]=-(out1[0]=p1); OUT1( 8,p3); OUT1(12,p7); OUT1(14,pf); OUT2(40)=-(p2+p3); } { register REAL *x=fraction; p0=hcos_64[ 0]*(x[ 0]-x[31]);p1=hcos_64[ 1]*(x[ 1]-x[30]); p2=hcos_64[ 2]*(x[ 2]-x[29]);p3=hcos_64[ 3]*(x[ 3]-x[28]); p4=hcos_64[ 4]*(x[ 4]-x[27]);p5=hcos_64[ 5]*(x[ 5]-x[26]); p6=hcos_64[ 6]*(x[ 6]-x[25]);p7=hcos_64[ 7]*(x[ 7]-x[24]); p8=hcos_64[ 8]*(x[ 8]-x[23]);p9=hcos_64[ 9]*(x[ 9]-x[22]); pa=hcos_64[10]*(x[10]-x[21]);pb=hcos_64[11]*(x[11]-x[20]); pc=hcos_64[12]*(x[12]-x[19]);pd=hcos_64[13]*(x[13]-x[18]); pe=hcos_64[14]*(x[14]-x[17]);pf=hcos_64[15]*(x[15]-x[16]); } q0=p0+pf;q1=p1+pe;q2=p2+pd;q3=p3+pc; q4=p4+pb;q5=p5+pa;q6=p6+p9;q7=p7+p8; q8=hcos_32[0]*(p0-pf);q9=hcos_32[1]*(p1-pe); qa=hcos_32[2]*(p2-pd);qb=hcos_32[3]*(p3-pc); qc=hcos_32[4]*(p4-pb);qd=hcos_32[5]*(p5-pa); qe=hcos_32[6]*(p6-p9);qf=hcos_32[7]*(p7-p8); p0=q0+q7;p1=q1+q6;p2=q2+q5;p3=q3+q4; p4=hcos_16[0]*(q0-q7);p5=hcos_16[1]*(q1-q6); p6=hcos_16[2]*(q2-q5);p7=hcos_16[3]*(q3-q4); p8=q8+qf;p9=q9+qe;pa=qa+qd;pb=qb+qc; pc=hcos_16[0]*(q8-qf);pd=hcos_16[1]*(q9-qe); pe=hcos_16[2]*(qa-qd);pf=hcos_16[3]*(qb-qc); q0=p0+p3;q1=p1+p2;q2=hcos_8[0]*(p0-p3);q3=hcos_8[1]*(p1-p2); q4=p4+p7;q5=p5+p6;q6=hcos_8[0]*(p4-p7);q7=hcos_8[1]*(p5-p6); q8=p8+pb;q9=p9+pa;qa=hcos_8[0]*(p8-pb);qb=hcos_8[1]*(p9-pa); qc=pc+pf;qd=pd+pe;qe=hcos_8[0]*(pc-pf);qf=hcos_8[1]*(pd-pe); p0=q0+q1;p1=hcos_4*(q0-q1); p2=q2+q3;p3=hcos_4*(q2-q3); p4=q4+q5;p5=hcos_4*(q4-q5); p6=q6+q7;p7=hcos_4*(q6-q7); p8=q8+q9;p9=hcos_4*(q8-q9); pa=qa+qb;pb=hcos_4*(qa-qb); pc=qc+qd;pd=hcos_4*(qc-qd); pe=qe+qf;pf=hcos_4*(qe-qf); { REAL tmp; tmp=pd+pf; OUT1(5,p5+p7+pb+tmp); tmp+=p9; OUT1(1,p1+tmp); OUT2(33)=-(p1+pe+tmp); tmp+=p5+p7; OUT1(3,tmp); OUT2(35)=-(p6+pe+tmp); tmp=pa+pb+pc+pd+pe+pf; OUT2(39)=-(p2+p3+tmp-pc); OUT2(43)=-(p4+p6+p7+tmp-pd); OUT2(37)=-(p5+p6+p7+tmp-pc); OUT2(41)=-(p2+p3+tmp-pd); tmp=p8+pc+pe+pf; OUT2(47)=-(p0+tmp); OUT2(45)=-(p4+p6+p7+tmp); tmp=pb+pf; OUT1(11,p7+tmp); tmp+=p3; OUT1( 9,tmp); OUT1( 7,pd+tmp); OUT1(13,p7+pf); OUT1(15,pf); } } #define SAVE \ raw=(int)(r*scalefactor); \ if(raw>MAXSCALE)raw=MAXSCALE;else if(rawMAXSCALE)raw=MAXSCALE;else if(rawMAXSCALE)raw=MAXSCALE;else if(raw #include #include "mpegsound.h" #include "mpegsound_locals.h" #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #ifdef WORDS_BIGENDIAN typedef union { long arg; char byte_represent[4]; } endian_hack_1; typedef union { short arg; char byte_represent[2]; } endian_hack_2; inline short HOST_TO_LE16(short x) { endian_hack_2 in,out; in.arg=x; out.arg=0; out.byte_represent[0]=in.byte_represent[1]; out.byte_represent[1]=in.byte_represent[0]; return (short)out.arg; } inline int HOST_TO_LE32(int x) { endian_hack_1 in,out; in.arg=x; out.arg=0; out.byte_represent[0]=in.byte_represent[3]; out.byte_represent[1]=in.byte_represent[2]; out.byte_represent[2]=in.byte_represent[1]; out.byte_represent[3]=in.byte_represent[0]; return out.arg; } #else #define HOST_TO_LE16(x) (x) #define HOST_TO_LE32(x) (x) #endif // Rawplayer class Rawtofile::~Rawtofile() { if (filetype == ST_WAV) { off_t filelen = lseek(audiohandle, 0, SEEK_CUR); lseek(audiohandle, 0, SEEK_SET); hdr.length = HOST_TO_LE32((u_int32_t)(filelen-8)); /* file length */ hdr.data_length = HOST_TO_LE32((u_int32_t)(filelen - 44)); (void)write(audiohandle, &hdr, sizeof(hdr)); } close(audiohandle); } Rawtofile::Rawtofile(int audiohandle) { this->audiohandle = audiohandle; init_putblock = 1; } Rawtofile *Rawtofile::opendevice(const char *filename) { int audiohandle; if(filename==NULL)audiohandle=1; else if((audiohandle=creat(filename,0644))==-1) return NULL; if (isatty(audiohandle)) return NULL; return new Rawtofile(audiohandle); } bool Rawtofile::setsoundtype(int stereo,int samplesize,int speed) { static bool myinit = false; /* changing sample specs when writing to a file is not done! */ if (myinit && ( (rawstereo != stereo) || (rawsamplesize != samplesize) || (rawspeed != speed))) { debug("Change in sample size/speed/mode.\n"); return false; } else myinit = true; rawstereo=stereo; rawsamplesize=samplesize; rawspeed=speed; return true; } /* set type of file to write. Default: ST_RAW (no header) */ bool Rawtofile::setfiletype(soundtype filetype) { if (filetype != ST_RAW && filetype != ST_WAV) return false; this->filetype = filetype; return true; } int Rawtofile::putblock_nt(void *buffer, int size) { if (init_putblock && filetype != ST_RAW) { int wordsize; wordsize = rawsamplesize; if (filetype == ST_WAV) { //initial datasize = 0...when all data is written, determine filesize //and rewrite the header. hdr.main_chunk = RIFF; hdr.length = HOST_TO_LE32(0 + 36); /* file length */ hdr.chunk_type = WAVE; hdr.sub_chunk = FMT; hdr.sc_len = HOST_TO_LE32(wordsize); /* = 16 */ hdr.format = PCM_CODE; hdr.modus = (rawstereo ? WAVE_STEREO : WAVE_MONO); /* stereo, 1 = mono */ hdr.sample_fq = HOST_TO_LE32(rawspeed); /* sample frequency */ hdr.byte_p_sec = HOST_TO_LE32((rawspeed * (wordsize/8) * (rawstereo?2:1))); hdr.byte_p_spl = HOST_TO_LE16((rawstereo?2:1) * (wordsize/8)); hdr.bit_p_spl = HOST_TO_LE16(wordsize); /* 8, 12, or 16 bit */ hdr.data_chunk = DATA; hdr.data_length = 0; /* file length without this header */ if (write(audiohandle, &hdr, sizeof(hdr)) != sizeof(hdr)) return false; } } init_putblock = 0; #ifdef WORDS_BIGENDIAN if (rawsamplesize == 16) { /* big endian -> switch bytes in output file */ unsigned short *sh_buffer=(unsigned short *)(buffer); int modifiedsize=size/2; /* data is in 16 bits bigendian, target is 16 bits little endian. */ while(modifiedsize--) { sh_buffer[modifiedsize]=HOST_TO_LE16(sh_buffer[modifiedsize]); } } #endif return write(audiohandle,buffer,size); } bool Rawtofile::putblock(void *buffer,int size) { return putblock_nt(buffer,size)==size; }; mp3blaster-3.2.6/mpegsound/rawplayer.cc0000664000112600011260000002430012426044701015030 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae Altered heavily by Bram Avontuur and others */ // Rawplayer.cc // Playing raw data with sound type. // Runs on linux and some flavours of bsd #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef WANT_OSS #include #include #include #include #include #include #include #include "mpegsound.h" #include "mpegsound_locals.h" #ifdef __cplusplus extern "C" { #endif #include SOUNDCARD_HEADERFILE #ifdef __cplusplus } #endif /* IOCTL */ #ifdef SOUND_VERSION #define IOCTL(a,b,c) ioctl(a,b,&c) #else #define IOCTL(a,b,c) (c = ioctl(a,b,c) ) #endif /* IOTRUBBEL : Massive debugging of my implementation of blocking writes..*/ #undef IOTRUBBEL /* AUDIO_NONBLOCKING : If defined, non-blocking audio playback is used. */ const char *Rawplayer::defaultdevice=SOUND_DEVICE; /* Volume */ int Rawplayer::setvolume(int volume) { int handle; int r; handle=open("/dev/mixer",O_RDWR); if(volume>100)volume=100; if(volume>=0) { r=(volume<<8) | volume; ioctl(handle,MIXER_WRITE(SOUND_MIXER_VOLUME),&r); } ioctl(handle,MIXER_READ(SOUND_MIXER_VOLUME),&r); close(handle); return (r&0xFF); } /*******************/ /* Rawplayer class */ /*******************/ // Rawplayer class /* filename is stored in case audiohandle needs to be reopened */ Rawplayer::Rawplayer(const char *filename, int audiohandle, int audiobuffersize) { this->audiohandle = audiohandle; this->audiobuffersize = audiobuffersize; this->filename = strdup(filename); //need to do this when object of this class is used for more than one //mp3. rawstereo = rawsamplesize = rawspeed = want8bit = 0; rawbuffersize = 0; quota = 0; first_init = 1; /* !! Only read audiobuffersize (using getblocksize()) after a call to * setsoundtype()!!!!!!!! (OSS manual says so) */ } Rawplayer::~Rawplayer() { if (audiohandle != -1) { close(audiohandle); } if (this->filename) free(this->filename); } int Rawplayer::getdevicehandle(const char *filename) { int audiohandle; #if defined(AUDIO_NONBLOCKING) || defined(NEWTHREAD) if((audiohandle=open(filename,O_WRONLY|O_NDELAY,0))==-1) #else if((audiohandle=open(filename,O_WRONLY,0))==-1) #endif { return -1; } #ifdef AIOSSIZE debug("AIOSSIZE defined\n"); struct snd_size blocksize; blocksize.play_size = RAWDATASIZE * sizeof(short int); blocksize.rec_size = RAWDATASIZE * sizeof(short int); IOCTL(audiohandle,AIOSSIZE, blocksize); #endif //maybe this will prevent sound hickups on some cards.. #if 0 int fragsize = (16<<16) | 10; /* XXX */ fragsize=2048; ioctl(audiohandle, SNDCTL_DSP_SETFRAGMENT, &fragsize); #endif return audiohandle; } Rawplayer *Rawplayer::opendevice(const char *filename) { int audiohandle, audiobuffersize; if (!filename) filename = defaultdevice; audiohandle = getdevicehandle(filename); if (audiohandle == -1) return NULL; /* Bad, you have to setsoundtype prior to query audiobuffersize */ #if 0 IOCTL(audiohandle,SNDCTL_DSP_GETBLKSIZE,audiobuffersize); if(audiobuffersize<4 || audiobuffersize>65536) return NULL; #else audiobuffersize = 1024; //it's properly set at setsoundtype(). #endif return new Rawplayer(filename, audiohandle, audiobuffersize); } void Rawplayer::abort(void) { int a; IOCTL(audiohandle,SNDCTL_DSP_RESET,a); } bool Rawplayer::setsoundtype(int stereo,int samplesize,int speed) { int changed = 0; int samplesize_oss = (samplesize == 16 ? AFMT_S16_NE : AFMT_U8); debug("Rawplayer::setsoundtype(%d,%d,%d)\n", stereo, samplesize, speed); if (rawstereo != stereo) { rawstereo = stereo; changed++; } if (rawsamplesize != samplesize_oss) { rawsamplesize = samplesize_oss; changed++; } if (rawspeed != speed) { rawspeed = speed; changed++; } forceto8 = (want8bit && samplesize == AFMT_S16_NE ? true : false); forcetomono = 0; if (changed) return resetsoundtype(); return true; } bool Rawplayer::resetsoundtype(void) { int tmp; if (!first_init) { if (audiohandle == -1) return false; debug("Resetting soundcard! (%d, %d, %d)\n", rawstereo, rawsamplesize, rawspeed); return seterrorcode(SOUND_ERROR_DEVCTRLERROR); #if 0 /* flush all data in soundcard's buffer first. */ if(ioctl(audiohandle,SNDCTL_DSP_SYNC,NULL)<0) return seterrorcode(SOUND_ERROR_DEVCTRLERROR); /* reset the bastard */ if(ioctl(audiohandle,SNDCTL_DSP_RESET,NULL)<0) return seterrorcode(SOUND_ERROR_DEVCTRLERROR); #endif /* OSS tells us to reopen the handle after a change in sample props */ if (close(audiohandle) == -1) { debug("Couldn't close audiohandle\n"); return seterrorcode(SOUND_ERROR_DEVCTRLERROR); } #if defined(AUDIO_NONBLOCKING) || defined(NEWTHREAD) if((audiohandle=open(filename,O_WRONLY|O_NDELAY,0))==-1) #else if((audiohandle=open(filename,O_WRONLY,0))==-1) #endif { debug("Couldn't reopen audiohandle\n"); return seterrorcode(SOUND_ERROR_DEVCTRLERROR); } debug("Soundcard successfully reopened.\n"); } else first_init = 0; if (want8bit && rawsamplesize != AFMT_U8) forceto8 = true; /* OSS manual says: first samplesize, then channels, then speed */ tmp = ( want8bit ? AFMT_U8 : rawsamplesize); debug("Resetsound: samplesize = %d\n", tmp); IOCTL(audiohandle,SNDCTL_DSP_SAMPLESIZE,tmp); debug("Resetsound: samplesize = %d (2)\n", tmp); /* maybe the soundcard doesn't do 16 bits sound */ if(!want8bit && tmp!=rawsamplesize) { if(rawsamplesize == AFMT_S16_NE) { rawsamplesize = AFMT_U8; //most boxen use unsigned for 8bits! debug("Resetsound: samplesize_encore = %d\n", rawsamplesize); IOCTL(audiohandle,SNDCTL_DSP_SAMPLESIZE,rawsamplesize); debug("Resetsound: samplesize_encore(2) = %d\n", rawsamplesize); if(rawsamplesize!=AFMT_U8) return seterrorcode(SOUND_ERROR_DEVCTRLERROR); forceto8=true; } else return seterrorcode(SOUND_ERROR_DEVCTRLERROR); } else if (want8bit && tmp != AFMT_U8) return seterrorcode(SOUND_ERROR_DEVCTRLERROR); /* if (want8bit) forceto8 = true; */ debug("Resetsound: rawstereo=%d\n", rawstereo); #ifdef SOUND_VERSION if(ioctl(audiohandle,SNDCTL_DSP_STEREO,&rawstereo)<0) #else if(rawstereo!=ioctl(audiohandle,SNDCTL_DSP_STEREO,rawstereo)) #endif { //TODO: Now setsoundtype will *always* call resetsoundtype.... rawstereo=MODE_MONO; forcetomono=1; } debug("Resetsound: rawspeed=%d\n", rawspeed); if(IOCTL(audiohandle,SNDCTL_DSP_SPEED,rawspeed)<0) return seterrorcode(SOUND_ERROR_DEVCTRLERROR); /* NOW we can set audiobuffersize without breaking with OSS specs */ IOCTL(audiohandle,SNDCTL_DSP_GETBLKSIZE,audiobuffersize); if(audiobuffersize<4 || audiobuffersize>65536) return seterrorcode(SOUND_ERROR_DEVCTRLERROR); return true; } void Rawplayer::releasedevice() { if (audiohandle != -1) { /* abort(); <= prevents opening the sound device on my box! */ if (close(audiohandle) == -1) debug("releasedevice: Couldn't close audiohandle!\n"); audiohandle = -1; } } bool Rawplayer::attachdevice() { /* make sure it's closed.. */ if (audiohandle != -1) { debug("attachdevice(): audiohandle wasn't closed?\n"); releasedevice(); } audiohandle = getdevicehandle(filename); if (audiohandle == -1) return false; first_init = 1; if (!resetsoundtype()) return false; return true; } int Rawplayer::fix_samplesize(void *buffer, int size) { int modifiedsize=size; if(forcetomono || forceto8) { register unsigned char modify=0; register unsigned char *source,*dest; int increment=0,c; source=dest=(unsigned char *)buffer; if(forcetomono)increment++; if(forceto8) { increment++; #ifndef WORDS_BIGENDIAN source++; #endif modify=128; } c=modifiedsize=size>>increment; increment<<=1; while(c--) { *(dest++)=(*source)+modify; source+=increment; } } return modifiedsize; } int Rawplayer::putblock_nt(void *buffer, int size) { if (audiohandle == -1) return -1; /* I'm not sure if pth_write is called for here, since we're doing non-blocked I/O anyway */ #ifdef LIBPTH return pth_write(audiohandle, buffer, size); #else return write(audiohandle, buffer, size); #endif } bool Rawplayer::putblock(void *buffer,int size) { int modifiedsize=size; if (audiohandle == -1) return false; if(forcetomono || forceto8) { register unsigned char modify=0; register unsigned char *source,*dest; int increment=0,c; source=dest=(unsigned char *)buffer; if(forcetomono)increment++; if(forceto8) { increment++; #ifndef WORDS_BIGENDIAN source++; #endif modify=128; } c=modifiedsize=size>>increment; increment<<=1; while(c--) { *(dest++)=(*source)+modify; source+=increment; } } #if defined(AUDIO_NONBLOCKING) || defined(NEWTHREAD) register ssize_t wsize, remainsize = modifiedsize; char *wbuf = (char*)buffer; /* In an ideal world, one would use select() to see if the device is ready * to accept data. However, this doesn't seem to work very well with sound * devices so I left it out. One the one FreeBSD box where I got this to * work, it didn't consume significantly less CPU time compared to using * usleep() to wait between writes. On my box, select() on the sound device * seems broken (it never appears ready). */ #if 0 struct fd_set writefds; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 100000; FD_ZERO(&writefds); FD_SET(audiohandle, &writefds); int selectval; while ((selectval = select(audiohandle + 1, NULL, &writefds, NULL, &tv)) != 1) { debug("Selectval is: %d\n", selectval); } #endif #ifdef IOTRUBBEL int loop = 0; #endif while(remainsize > 0 && (wsize = write(audiohandle,(void*)wbuf,remainsize)) != remainsize) { #ifdef IOTRUBBEL loop++; if (loop > 1) { char fiepje[255]; sprintf(fiepje,"Partial/bad write, wsize=%d remainsize=%d wbuf=%d (%d)\n", wsize, remainsize-wsize,(int)wbuf, loop); debug(fiepje); } #endif if (wsize > 0) { remainsize -= wsize; wbuf += wsize; } USLEEP(10000); //always sleep a bit at bad/partial writes.. } #ifdef IOTRUBBEL if (loop > 1) debug("Done (write)\n"); #endif #else /* AUDIO_NONBLOCKING */ #ifdef LIBPTH pth_write(audiohandle, buffer, modifiedsize); #else write(audiohandle, buffer, modifiedsize); #endif #endif /* AUDIO_NONBLOCKING */ return true; } int Rawplayer::getblocksize(void) { return audiobuffersize; } #endif /* WANT_OSS */ mp3blaster-3.2.6/mpegsound/filter_2.cc0000664000112600011260000002515412426044701014540 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Filter.cc // Subbandsynthesis routines from maplay 1.2 for Linux // I've modified some macros for reducing source code. #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mpegsound.h" void Mpegtoraw::computebuffer_2(REAL *fraction,REAL buffer[2][CALCBUFFERSIZE]) { REAL p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pa,pb,pc,pd,pe,pf; REAL q0,q1,q2,q3,q4,q5,q6,q7,q8,q9,qa,qb,qc,qd,qe,qf; REAL *out1,*out2; out1=buffer[currentcalcbuffer]+calcbufferoffset; out2=buffer[currentcalcbuffer^1]+calcbufferoffset; #define OUT1(v,t) out1[(32-(v))*16] =(-(out1[(v)*16]=t)) #define OUT2(v) out2[(96-(v)-32)*16]=out2[((v)-32)*16] // compute new values via a fast cosine transform: /* { register REAL *x=fraction; p0=x[ 0]+x[31];p1=x[ 1]+x[30];p2=x[ 2]+x[29];p3=x[ 3]+x[28]; p4=x[ 4]+x[27];p5=x[ 5]+x[26];p6=x[ 6]+x[25];p7=x[ 7]+x[24]; p8=x[ 8]+x[23];p9=x[ 9]+x[22];pa=x[10]+x[21];pb=x[11]+x[20]; pc=x[12]+x[19];pd=x[13]+x[18];pe=x[14]+x[17];pf=x[15]+x[16]; } q0=p0+pf;q1=p1+pe;q2=p2+pd;q3=p3+pc; q4=p4+pb;q5=p5+pa;q6=p6+p9;q7=p7+p8; q8=hcos_32[0]*(p0-pf);q9=hcos_32[1]*(p1-pe); qa=hcos_32[2]*(p2-pd);qb=hcos_32[3]*(p3-pc); qc=hcos_32[4]*(p4-pb);qd=hcos_32[5]*(p5-pa); qe=hcos_32[6]*(p6-p9);qf=hcos_32[7]*(p7-p8); */ { register REAL *x=fraction; q0=x[ 0]+x[15];q1=x[ 1]+x[14];q2=x[ 2]+x[13];q3=x[ 3]+x[12]; q4=x[ 4]+x[11];q5=x[ 5]+x[10];q6=x[ 6]+x[ 9];q7=x[ 7]+x[ 8]; q8=hcos_32[0]*(x[ 0]-x[15]);q9=hcos_32[1]*(x[ 1]-x[14]); qa=hcos_32[2]*(x[ 2]-x[13]);qb=hcos_32[3]*(x[ 3]-x[12]); qc=hcos_32[4]*(x[ 4]-x[11]);qd=hcos_32[5]*(x[ 5]-x[10]); qe=hcos_32[6]*(x[ 6]-x[ 9]);qf=hcos_32[7]*(x[ 7]-x[ 8]); } p0=q0+q7;p1=q1+q6;p2=q2+q5;p3=q3+q4; p4=hcos_16[0]*(q0-q7);p5=hcos_16[1]*(q1-q6); p6=hcos_16[2]*(q2-q5);p7=hcos_16[3]*(q3-q4); p8=q8+qf;p9=q9+qe;pa=qa+qd;pb=qb+qc; pc=hcos_16[0]*(q8-qf);pd=hcos_16[1]*(q9-qe); pe=hcos_16[2]*(qa-qd);pf=hcos_16[3]*(qb-qc); q0=p0+p3;q1=p1+p2;q2=hcos_8[0]*(p0-p3);q3=hcos_8[1]*(p1-p2); q4=p4+p7;q5=p5+p6;q6=hcos_8[0]*(p4-p7);q7=hcos_8[1]*(p5-p6); q8=p8+pb;q9=p9+pa;qa=hcos_8[0]*(p8-pb);qb=hcos_8[1]*(p9-pa); qc=pc+pf;qd=pd+pe;qe=hcos_8[0]*(pc-pf);qf=hcos_8[1]*(pd-pe); p0=q0+q1;p1=hcos_4*(q0-q1);p2=q2+q3;p3=hcos_4*(q2-q3); p4=q4+q5;p5=hcos_4*(q4-q5);p6=q6+q7;p7=hcos_4*(q6-q7); p8=q8+q9;p9=hcos_4*(q8-q9);pa=qa+qb;pb=hcos_4*(qa-qb); pc=qc+qd;pd=hcos_4*(qc-qd);pe=qe+qf;pf=hcos_4*(qe-qf); { register REAL tmp; tmp=p6+p7; OUT2(36)=-(p5+tmp); OUT2(44)=-(p4+tmp); tmp=pb+pf; OUT1(10,tmp); OUT1(6,pd+tmp); tmp=pe+pf; OUT2(46)=-(p8+pc+tmp); OUT2(34)=-(p9+pd+tmp); tmp+=pa+pb; OUT2(38)=-(pd+tmp); OUT2(42)=-(pc+tmp); OUT1(2,p9+pd+pf); OUT1(4,p5+p7); OUT2(48)=-p0; out2[0]=-(out1[0]=p1); OUT1( 8,p3); OUT1(12,p7); OUT1(14,pf); OUT2(40)=-(p2+p3); } { register REAL *x=fraction; /* p0=hcos_64[ 0]*(x[ 0]-x[31]);p1=hcos_64[ 1]*(x[ 1]-x[30]); p2=hcos_64[ 2]*(x[ 2]-x[29]);p3=hcos_64[ 3]*(x[ 3]-x[28]); p4=hcos_64[ 4]*(x[ 4]-x[27]);p5=hcos_64[ 5]*(x[ 5]-x[26]); p6=hcos_64[ 6]*(x[ 6]-x[25]);p7=hcos_64[ 7]*(x[ 7]-x[24]); p8=hcos_64[ 8]*(x[ 8]-x[23]);p9=hcos_64[ 9]*(x[ 9]-x[22]); pa=hcos_64[10]*(x[10]-x[21]);pb=hcos_64[11]*(x[11]-x[20]); pc=hcos_64[12]*(x[12]-x[19]);pd=hcos_64[13]*(x[13]-x[18]); pe=hcos_64[14]*(x[14]-x[17]);pf=hcos_64[15]*(x[15]-x[16]); */ p0=hcos_64[ 0]*x[ 0];p1=hcos_64[ 1]*x[ 1]; p2=hcos_64[ 2]*x[ 2];p3=hcos_64[ 3]*x[ 3]; p4=hcos_64[ 4]*x[ 4];p5=hcos_64[ 5]*x[ 5]; p6=hcos_64[ 6]*x[ 6];p7=hcos_64[ 7]*x[ 7]; p8=hcos_64[ 8]*x[ 8];p9=hcos_64[ 9]*x[ 9]; pa=hcos_64[10]*x[10];pb=hcos_64[11]*x[11]; pc=hcos_64[12]*x[12];pd=hcos_64[13]*x[13]; pe=hcos_64[14]*x[14];pf=hcos_64[15]*x[15]; } q0=p0+pf;q1=p1+pe;q2=p2+pd;q3=p3+pc; q4=p4+pb;q5=p5+pa;q6=p6+p9;q7=p7+p8; q8=hcos_32[0]*(p0-pf);q9=hcos_32[1]*(p1-pe); qa=hcos_32[2]*(p2-pd);qb=hcos_32[3]*(p3-pc); qc=hcos_32[4]*(p4-pb);qd=hcos_32[5]*(p5-pa); qe=hcos_32[6]*(p6-p9);qf=hcos_32[7]*(p7-p8); p0=q0+q7;p1=q1+q6;p2=q2+q5;p3=q3+q4; p4=hcos_16[0]*(q0-q7);p5=hcos_16[1]*(q1-q6); p6=hcos_16[2]*(q2-q5);p7=hcos_16[3]*(q3-q4); p8=q8+qf;p9=q9+qe;pa=qa+qd;pb=qb+qc; pc=hcos_16[0]*(q8-qf);pd=hcos_16[1]*(q9-qe); pe=hcos_16[2]*(qa-qd);pf=hcos_16[3]*(qb-qc); q0=p0+p3;q1=p1+p2;q2=hcos_8[0]*(p0-p3);q3=hcos_8[1]*(p1-p2); q4=p4+p7;q5=p5+p6;q6=hcos_8[0]*(p4-p7);q7=hcos_8[1]*(p5-p6); q8=p8+pb;q9=p9+pa;qa=hcos_8[0]*(p8-pb);qb=hcos_8[1]*(p9-pa); qc=pc+pf;qd=pd+pe;qe=hcos_8[0]*(pc-pf);qf=hcos_8[1]*(pd-pe); p0=q0+q1;p1=hcos_4*(q0-q1); p2=q2+q3;p3=hcos_4*(q2-q3); p4=q4+q5;p5=hcos_4*(q4-q5); p6=q6+q7;p7=hcos_4*(q6-q7); p8=q8+q9;p9=hcos_4*(q8-q9); pa=qa+qb;pb=hcos_4*(qa-qb); pc=qc+qd;pd=hcos_4*(qc-qd); pe=qe+qf;pf=hcos_4*(qe-qf); { REAL tmp; tmp=pd+pf; OUT1(5,p5+p7+pb+tmp); tmp+=p9; OUT1(1,p1+tmp); OUT2(33)=-(p1+pe+tmp); tmp+=p5+p7; OUT1(3,tmp); OUT2(35)=-(p6+pe+tmp); tmp=pa+pb+pc+pd+pe+pf; OUT2(39)=-(p2+p3+tmp-pc); OUT2(43)=-(p4+p6+p7+tmp-pd); OUT2(37)=-(p5+p6+p7+tmp-pc); OUT2(41)=-(p2+p3+tmp-pd); tmp=p8+pc+pe+pf; OUT2(47)=-(p0+tmp); OUT2(45)=-(p4+p6+p7+tmp); tmp=pb+pf; OUT1(11,p7+tmp); tmp+=p3; OUT1( 9,tmp); OUT1( 7,pd+tmp); OUT1(13,p7+pf); OUT1(15,pf); } } #define SAVE \ raw=(int)(r*scalefactor); \ if(raw>MAXSCALE)raw=MAXSCALE;else if(rawMAXSCALE)raw=MAXSCALE;else if(rawMAXSCALE)raw=MAXSCALE;else if(raw #include #include #ifdef HAVE_ERRNO_H # include #endif /* HAVE_ERRNO_H */ #include #include #include #include #include #include #include #include "mpegsound.h" #include "mpegsound_locals.h" #include "cyclicbuffer.h" #define SDL_BLOCK_SIZE 32768 //number of seconds of audio to keep in local buffer #define BUFFER_SECONDS 2 int SDLPlayer::sdl_init = 0; SDLPlayer::SDLPlayer() { this->buffer = NULL; } SDLPlayer::~SDLPlayer() { if (this->buffer) { SDL_CloseAudio(); //!important! before deleting buffer delete buffer; } } void SDLPlayer::abort() { debug("sdl::abort\n"); //clear buffer if (this->buffer) { buffer->setEmpty(); } } bool SDLPlayer::setsoundtype(int stereo, int samplesize, int speed) { debug("sdl::setsoundtype()\n"); if (buffer != NULL) { debug("setsoundtype() called while buffer exists"); seterrorcode(SOUND_ERROR_UNKNOWN); return false; //can only set soundtype once } if (!sdl_init && SDL_Init(SDL_INIT_AUDIO) < 0) { debug("SDL_Init failed: %s\n", SDL_GetError()); seterrorcode(SOUND_ERROR_DEVOPENFAIL); return false; } sdl_init = 1; //static;only necessary once for the application's life span. rawstereo = stereo; rawsamplesize = samplesize; rawspeed = speed; return resetsoundtype(); } void SDLPlayer::set8bitmode() { //ignore forced 8bits output requests ; sdl will downsample itself. } //sdl callback function void SDLCallback(void *localbuffer, Uint8 *stream, int len) { CyclicBuffer *myBuffer = (CyclicBuffer*)localbuffer; //blocks on read. I hope the SDL_CloseAudio() properly kills the thread //that's waiting on this read.. (void)myBuffer->read((unsigned char * const)stream, (unsigned int)len); } bool SDLPlayer::resetsoundtype() { SDL_AudioSpec fmt; if (this->buffer) { SDL_CloseAudio(); delete buffer; } buffer = new CyclicBuffer(BUFFER_SECONDS * rawspeed * (rawstereo ? 2 : 1) * (rawsamplesize / 8)); //(re)set audiospec fmt.channels = (rawstereo ? 2 : 1); fmt.freq = rawspeed; fmt.format = (rawsamplesize == 8 ? AUDIO_S8 : AUDIO_S16SYS); fmt.callback = SDLCallback; fmt.userdata = buffer; fmt.samples = 2048; //bigger: less hicks, more latency, and vice versa /* open sdl audio dev */ if (SDL_OpenAudio(&fmt, NULL) < 0) { debug("sdl_openaudio() failed: %s", SDL_GetError()); seterrorcode(SOUND_ERROR_DEVOPENFAIL); delete buffer; buffer = NULL; return false; } SDL_PauseAudio(0); //default is to start paused return true; } void SDLPlayer::releasedevice() { if (buffer) { SDL_PauseAudio(1); //hopefully releases audiodev. } } bool SDLPlayer::attachdevice() { if (buffer) { SDL_PauseAudio(0); } return true; } //write all of buffer's content (blocking) bool SDLPlayer::putblock(void *buffer, int size) { unsigned int counter = 0; if (!this->buffer) return false; if (!size) { return true; //writing nothing is really fast. } //potential race condition if sdl doesn't read from the buffer. while (0 == this->buffer->write((const unsigned char * const)buffer, (unsigned int)size) && counter < 1000) { usleep(10000); //sleep 10 millisec ++counter; } if (1000 == counter) { //waited 20 seconds. I call that a race condition. debug("Timeout while trying to write %d bytes to cyclic buffer\n", size); return seterrorcode(SOUND_ERROR_DEVBUSY); } return true; } int SDLPlayer::putblock_nt(void *buffer, int size) { if (!buffer) { return -1; } //potentially partial write return this->buffer->write((const unsigned char * const)buffer, (unsigned int)size, 1); } int SDLPlayer::getblocksize() { return SDL_BLOCK_SIZE; //XXX: config? } int SDLPlayer::fix_samplesize(void *buffer, int size) { (void)buffer; //sdl takes care of downsampling, no need to mangle samples return size; } #endif /* WANT_SDL */ mp3blaster-3.2.6/mpegsound/cyclicbuffer.h0000664000112600011260000000520112426044701015323 00000000000000#ifndef _MPEGSOUND_CYCLICBUFFER_ #define _MPEGSOUND_CYCLICBUFFER_ #ifdef LIBPTH # include #elif defined(PTHREADEDMPEG) # include #endif class CyclicBuffer { public: CyclicBuffer(const unsigned int size); ~CyclicBuffer(); /* Function : read * Description: Read bytes from the buffer * Parameters : buf * : Buffer to store read data in. Must be large enough. * : amount * : Amount of data to read * : partial * : If non-zero, allow partial reads (e.g. less than requested) * Returns : The number of bytes read into the buffer * SideEffects: None. */ int read(unsigned char * const buf, const unsigned int amount, const int partial = 0); /* Function : write * Description: Writes data into the buffer. * Parameters : buf * : Buffer containing the data to be written * : amount * : Number of bytes to write * : partial * : If non-zero, allow partial writes (e.g. less than requested) * Returns : The number of bytes written into the buffer * SideEffects: None. */ int write(const unsigned char * const buf, const unsigned int amount, const int partial = 0); /* Function : setEmpty * Description: Empty the contents of the buffer. The size of the buffer * : is unaffected. * Parameters : None. * Returns : Nothing. * SideEffects: None. */ void setEmpty(void); /* Function : contentSize * Description: Calculates the size of the contents of the buffer * Parameters : None. * Returns : The number of stored, non-read bytes in the buffer. * SideEffects: None. */ unsigned int contentSize(void); /* total size - contentsize */ unsigned int emptySpace(void); /* Function : size * Description: Size of the entire buffer. * Parameters : None. * Returns : Number of bytes this buffer can contain * SideEffects: None. */ unsigned int size(void); private: void readData(unsigned char * const buf, const unsigned int amount); void writeData(const unsigned char * const buf, const unsigned int amount); void lock(void); void unlock(void); unsigned int contentSizeInternal(void); //does not lock/unlock unsigned int emptySpaceInternal(void); //does not lock/unlock unsigned char *buffer; int readIndex; //where are we reading int writeIndex; //where are we writing int isFull; //if readIndex==writeIndex, this indicates the filled status unsigned int bufferSize; //size of buffer #ifdef LIBPTH pth_mutex_t rw_mutex; #elif defined(PTHREADEDMPEG) pthread_mutex_t rw_mutex; #endif }; #endif /* _MPEGSOUND_CYCLICBUFFER_ */ mp3blaster-3.2.6/mpegsound/fileplayer.cc0000664000112600011260000002271612426044701015167 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Fileplayer.cc // It's an example for how to use MPEG/WAVE Sound library #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "mpegsound.h" #include "mpegsound_locals.h" // File player superclass Fileplayer::Fileplayer() { __errorcode=SOUND_ERROR_OK; player=NULL; filename = NULL; info.songname[0] = '\0'; info.artist[0] = '\0'; info.comment[0] = '\0'; info.year[0] = '\0'; info.album[0] = '\0'; info.genre = 0; info.mode[0] = '\0'; info.bitrate=0; info.mp3_layer = 0; info.mp3_version = 0; info.samplerate = 0; info.totaltime = 0; audiodriver = AUDIODRV_OSS; //default audio driver }; Fileplayer::~Fileplayer() { delete player; }; /* shared by all subclasses */ bool Fileplayer::opendevice(const char *device, soundtype write2file) { delete player; //delete possibly existing player if (write2file) { player = Rawtofile::opendevice(device); return (player && ((Rawtofile*)player)->setfiletype(write2file)); } //Choose an audio driver for audio playback switch (audiodriver) { #ifdef WANT_OSS case AUDIODRV_OSS: debug("Using OSS audiodriver\n"); player = Rawplayer::opendevice(device); break; #endif #ifdef WANT_NAS case AUDIODRV_NAS: debug("Using NAS audiodriver\n"); player = NASplayer::opendevice(device); break; #endif #ifdef WANT_ESD case AUDIODRV_ESD: debug("Using ESD audiodriver\n"); player = new EsdPlayer(); //TODO: accept HOST param break; #endif #ifdef WANT_SDL case AUDIODRV_SDL: debug("Using SDL audiodriver\n"); player = new SDLPlayer(); break; #endif default: debug("Unsupported audiodriver!\n"); return false; } return player != NULL; } void Fileplayer::set_driver(audiodriver_t driver) { this->audiodriver = driver; } // Wave file player Wavefileplayer::Wavefileplayer(audiodriver_t driver) { loader=NULL; server=NULL; filename = NULL; set_driver(driver); } Wavefileplayer::~Wavefileplayer() { if(loader)delete loader; if(server)delete server; } bool Wavefileplayer::openfile(const char *filename, const char *device, soundtype write2file) { // Player if (!opendevice(device, write2file)) return seterrorcode(SOUND_ERROR_DEVOPENFAIL); // Loader { int err; if((loader=Soundinputstream::hopen(filename,&err))==NULL) return seterrorcode(err); } // Server if (server) delete server; if((server=new Wavetoraw(loader,player))==NULL) return seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH); return true; } void Wavefileplayer::closefile(void) { if (loader) loader->close(); } void Wavefileplayer::setforcetomono(short flag) { server->setforcetomono(flag); }; bool Wavefileplayer::playing() { if(!server->run()) { return false; // Read first time } while(server->run()) { // Playing } seterrorcode(server->geterrorcode()); return (geterrorcode() == SOUND_ERROR_FINISH); } bool Wavefileplayer::run(int) { if (!server->run()) { seterrorcode(server->geterrorcode()); return false; } return true; } int Wavefileplayer::elapsed_time() { return server->getcurrentpoint() / server->getfrequency(); } int Wavefileplayer::remaining_time() { return info.totaltime - elapsed_time(); } void Wavefileplayer::skip(int sec) { int nrsamples = sec * server->getfrequency(); server->setcurrentpoint(server->getcurrentpoint() + nrsamples); } bool Wavefileplayer::initialize(void *init_args) { if (init_args); //prevent warning if (!server->initialize()) return seterrorcode(server->geterrorcode()); if (!server->run()) { seterrorcode(server->geterrorcode()); return false; } info.songname[0] = 0; info.artist[0] = 0; info.comment[0] = 0; info.year[0] = 0; info.album[0] = 0; info.genre = 255; info.bitrate = 0; info.mp3_layer = 0; info.mp3_version = 0; info.samplerate = server->getfrequency(); if (server->getfrequency()) info.totaltime = server->gettotallength() / server->getfrequency(); else info.totaltime = 0; if (server->isstereo()) strcpy(info.mode, "stereo"); else strcpy(info.mode, "mono"); return true; } // Mpegfileplayer Mpegfileplayer::Mpegfileplayer(audiodriver_t driver) { loader=NULL; server=NULL; player=NULL; filename = NULL; use_threads = 0; set_driver(driver); }; Mpegfileplayer::~Mpegfileplayer() { #if !defined(NEWTHREAD) && defined(PTHREADEDMPEG) if (use_threads && server) server->freethreadedplayer(); #endif if(loader)delete loader; if(server)delete server; } /* if device[0] == '-' output will be written to stdout. * if write2file != 0, output will be written to file `device' */ bool Mpegfileplayer::openfile(const char *filename, const char *device, soundtype write2file) { // Player if (!opendevice(device, write2file)) return seterrorcode(SOUND_ERROR_DEVOPENFAIL); // Loader { int err; if (loader) delete loader; if((loader=Soundinputstream::hopen(filename,&err))==NULL) { return seterrorcode(err); } } // Server if (server) delete server; if((server=new Mpegtoraw(loader,player))==NULL) { return seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH); } if (this->filename) delete[] this->filename; this->filename = filename; //now needed for server->initialize() return true; } void Mpegfileplayer::closefile(void) { if (loader) loader->close(); } void Mpegfileplayer::setforcetomono(short flag) { server->setforcetomono(flag); }; void Mpegfileplayer::setdownfrequency(int value) { server->setdownfrequency(value); }; bool Mpegfileplayer::playing() { if(!server->run(-1))return false; // Initialize MPEG Layer 3 while(server->run(10))USLEEP(10000); // Playing seterrorcode(server->geterrorcode()); return geterrorcode() == SOUND_ERROR_FINISH; } bool Mpegfileplayer::initialize(void *init_args) { int threads = 0; //struct init_opts *opts = NULL; init_opts *opts = NULL; if (init_args) opts = (struct init_opts *)init_args; //scan init_args while (opts) { const char *on = opts->option; if (!strcmp(on, "threads")) threads = *((int*)(opts->value)); else if (!strcmp(on, "scanmp3s")) server->set_time_scan(*((short*)(opts->value))); opts = opts->next; } // Initialize server if (!server->initialize(filename)) { return seterrorcode(server->geterrorcode()); } #ifndef NEWTHREAD #ifdef PTHREADEDMPEG if (threads > 20) { use_threads = 1; server->makethreadedplayer(threads); } #endif #endif /* NEWTHREAD */ if (!server->run(-20)) { seterrorcode(server->geterrorcode()); return false; } #ifdef NEWTHREAD server->continueplaying(); #endif info.mp3_layer = server->getlayer(); info.mp3_version = server->getversion(); strcpy(info.mode, server->getmodestring()); info.samplerate = server->getfrequency(); info.bitrate = server->getbitrate(); info.genre = server->getgenre(); info.totaltime = server->gettotaltime(); strcpy(info.songname, server->getname()); strcpy(info.artist, server->getartist()); strcpy(info.comment, server->getcomment()); strcpy(info.year, server->getyear()); strcpy(info.album, server->getalbum()); return true; } bool Mpegfileplayer::run(int frames) { if (!server->run(frames)) { seterrorcode(server->geterrorcode()); return false; } return true; } bool Mpegfileplayer::forward(int skipframes) { int maxframe = server->gettotalframe(), curframe = server->getcurrentframe(); //since skipframes resembles seconds, multiply it by 75 to match #frames skipframes *= 38; if (skipframes < 0) //jump to end of file curframe = maxframe + skipframes; else curframe += skipframes; if (curframe > maxframe) curframe = maxframe - 1; server->setframe(curframe); return true; } bool Mpegfileplayer::rewind(int skipframes) { int curframe = server->getcurrentframe(); curframe -= (skipframes * 38); if (curframe < 0) curframe = 0; server->setframe(curframe); return true; } int Mpegfileplayer::elapsed_time() { int curr = server->getcurrentframe(), total = server->gettotalframe(), playtime = ((int)(curr * server->gettotaltime()) / total); return playtime; } int Mpegfileplayer::remaining_time() { int curr = server->getcurrentframe(), total = server->gettotalframe(), playtime = ((int)(curr * server->gettotaltime()) / total); return server->gettotaltime() - playtime; } void Mpegfileplayer::skip(int frames) { int maxframe = server->gettotalframe(), curframe = server->getcurrentframe(); curframe += frames; if (curframe > maxframe) curframe = maxframe - 1; if (curframe < 0) curframe = 0; server->setframe(curframe); } #ifndef NEWTHREAD #ifdef PTHREADEDMPEG bool Mpegfileplayer::playingwiththread(int framenumbers) { if(framenumbers<20)return playing(); if (!server->makethreadedplayer(framenumbers)) { return seterrorcode(server->geterrorcode()); } if(!server->run(-1)) { server->freethreadedplayer(); return seterrorcode(server->geterrorcode()); } while(server->run(100)) { //Playing } server->freethreadedplayer(); seterrorcode(server->geterrorcode()); return geterrorcode() == SOUND_ERROR_FINISH; } #endif #endif /* NEWTHREAD */ bool Mpegfileplayer::stop() { #if !defined(NEWTHREAD) && defined(PTHREADEDMPEG) if (use_threads && server) server->stopthreadedplayer(); //server->freethreadedplayer(); #endif return true; } /* all sound output has been sent to the sound card? */ bool Mpegfileplayer::ready() { #if !defined(NEWTHREAD) && defined(PTHREADEDMPEG) if (use_threads && server && server->getframesaved() && (server->geterrorcode() == SOUND_ERROR_OK || server->geterrorcode() == SOUND_ERROR_FINISH)) return false; #endif return true; } mp3blaster-3.2.6/mpegsound/Makefile.am0000644000112600011260000000114713106424065014552 00000000000000noinst_LIBRARIES = libmpegsound.a libmpegsound_a_SOURCES = soundinputstream.cc fileinput.cc httpinput.cc \ soundplayer.cc rawplayer.cc rawtofile.cc \ mpegtable.cc filter.cc filter_2.cc \ mpegtoraw.cc mpeglayer1.cc mpeglayer2.cc \ mpeglayer3.cc bitwindow.cc huffmantable.cc \ wavetoraw.cc sidplayer.cc \ fileplayer.cc nasplayer.cc oggplayer.cc \ xingheader.cc xingheader.h esdplayer.cc \ sdlplayer.cc cyclicbuffer.cc cyclicbuffer.h noinst_HEADERS = mpegsound.h mpegsound_locals.h INCLUDES = -I$(srcdir) -I$(includedir) AM_CXXFLAGS = @NAS_CFLAGS@ mp3blaster-3.2.6/mpegsound/oggplayer.cc0000644000112600011260000001227213103672224015016 00000000000000/* (C) Bram Avontuur, bram@mp3blaster.avontuur.org * For more information about OggVorbis, check http://www.xiph.org/ogg/vorbis/ */ #include #include "mpegsound_locals.h" #ifdef INCLUDE_OGG #include #include #include #include Oggplayer::Oggplayer(audiodriver_t driver) { of = NULL; wordsize = 2; //2 bytes #ifdef WORDS_BIGENDIAN bigendian = 1; #else bigendian = 0; #endif signeddata = 1; mono = 0; downfreq = 0; resetsound = 1; set_driver(driver); } Oggplayer::~Oggplayer() { if (of) { ov_clear(of); delete of; of = NULL; } } bool Oggplayer::openfile(const char *filename, const char *device, soundtype write2file) { FILE *f; int openres; if (of) { ov_clear(of); delete of; of = NULL; } //initialize player object that writes to sound device/file if (!opendevice(device, write2file)) return seterrorcode(SOUND_ERROR_DEVOPENFAIL); if (!(f = fopen(filename, "r"))) return seterrorcode(SOUND_ERROR_FILEOPENFAIL); of = new OggVorbis_File; //initialize OggVorbis structure if ( (openres = ov_open(f, of, NULL, 0)) < 0) { switch(openres) { case OV_EREAD: seterrorcode(SOUND_ERROR_FILEREADFAIL); break; case OV_EVERSION: case OV_ENOTVORBIS: seterrorcode(SOUND_ERROR_BAD); break; case OV_EBADHEADER: seterrorcode(SOUND_ERROR_BADHEADER); break; default: seterrorcode(SOUND_ERROR_UNKNOWN); } delete of; of = NULL; fclose(f); //if ov_open fails, it's safe to use fclose() return false; } vorbis_info *vi = ov_info(of, -1); channels = vi->channels - 1; srate = vi->rate; resetsound = 1; info.bitrate = (int)vi->bitrate_nominal; if (info.bitrate > 1000) info.bitrate /= 1000; info.mp3_version = vi->version; info.samplerate = (int)vi->rate; double totaltime = ov_time_total(of, -1); if (totaltime > 0) info.totaltime = int(totaltime); //retrieve interesting information from the user comments. char **ptr = ov_comment(of, -1)->user_comments; while (*ptr) { char hdr[strlen(*ptr)+1], value[strlen(*ptr)+1]; int sval = sscanf(*ptr, "%[^=]=%[^\n]", hdr, value); //lazy, but works. if (sval == 2) { if (!strcasecmp(hdr, "album")) { strncpy(info.album, value, 30); info.album[30] = '\0'; } else if (!strcasecmp(hdr, "artist")) { strncpy(info.artist, value, 30); info.artist[30] = '\0'; } else if (!strcasecmp(hdr, "title")) { strncpy(info.songname, value, 30); info.songname[30] = '\0'; } else { debug("OggVorbis Unkown Fieldname '%s' with value '%s'\n", hdr, value); } } ++ptr; } return true; } void Oggplayer::closefile() { if (of) ov_clear(of); delete of; of = NULL; } void Oggplayer::setforcetomono(short flag) { if (flag) mono = 1; //TODO: make a function in soundplayer class to force mono. } void Oggplayer::set8bitmode() { wordsize = 1; player->set8bitmode(); } void Oggplayer::setdownfrequency(int value) { downfreq = (value ? 1 : 0); //TODO: This doesn't do anything yet. } bool Oggplayer::playing() { return true; } bool Oggplayer::run(int sec) { int bitstream; long bytes_read = ov_read(of, soundbuf, 4096, bigendian, wordsize, signeddata, &bitstream); if (sec); //prevent warning if (bytes_read < 0) return seterrorcode(SOUND_ERROR_BAD); if (!bytes_read) return seterrorcode(SOUND_ERROR_FINISH); vorbis_info *vi = ov_info(of, bitstream); if (channels != vi->channels) channels = vi->channels, resetsound++; if (srate != vi->rate) srate = vi->rate, resetsound++; if (resetsound) { debug("OggVorbis channels/samplerate changed.\n"); player->setsoundtype(vi->channels - 1, (wordsize == 2 ? 16 : 8), vi->rate >> downfreq); char bla[100]; sprintf(bla, "channels/wordsize/rate=%d/%d/%ld\n",vi->channels,wordsize, vi->rate >> downfreq); debug(bla); resetsound = 0; } //If downsampling, we only need every other frame. We do this by //removing every other frame. //TODO: optimize! if (downfreq) { char *src, *dst, ssize = 1; int c, i; src=dst=(char*)soundbuf; ssize *= vi->channels; ssize *= wordsize; //ssize is #bytes for each sample. c = bytes_read / (ssize<<1); //nr. of samples to chop == half of total# while (c--) { i = ssize; while (--i > -1) //copy ssize bytes of each sample. *(dst + i) = *(src + i); dst += ssize; src += (ssize<<1); //skip 50% of samples. } } if (!player->putblock(soundbuf, (unsigned int)(bytes_read>>downfreq))) return seterrorcode(SOUND_ERROR_UNKNOWN); return true; } void Oggplayer::skip(int sec) { double current_secs = elapsed_time(); current_secs += (double)sec; ov_time_seek(of, current_secs); } bool Oggplayer::initialize(void *data) { if (data); return true; } bool Oggplayer::forward(int sec) { skip(sec); return true; } bool Oggplayer::rewind(int sec) { skip(-sec); return true; } bool Oggplayer::pause() { player->releasedevice(); return true; } bool Oggplayer::unpause() { return player->attachdevice(); } bool Oggplayer::stop() { return true; } bool Oggplayer::ready() { return true; } int Oggplayer::elapsed_time() { double elapsed = ov_time_tell(of); return (int)elapsed; } int Oggplayer::remaining_time() { return info.totaltime - elapsed_time(); } #endif /* INCLUDE_OGG */ mp3blaster-3.2.6/mpegsound/mpegsound_locals.h0000664000112600011260000000174612426044701016233 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Mpegsound_locals.h // It is used for compiling library #ifndef _L__SOUND_LOCALS__ #define _L__SOUND_LOCALS__ extern void debug(const char*, ... ); // Inline functions inline int Mpegtoraw::getbyte(void) { int r=(unsigned char)buffer[bitindex>>3]; bitindex+=8; return r; }; inline int Mpegtoraw::getbits9(int bits) { register unsigned short a; int offset=bitindex>>3; a=(((unsigned char)buffer[offset])<<8) | ((unsigned char)buffer[offset+1]); a<<=(bitindex&7); bitindex+=bits; return (int)((unsigned int)(a>>(16-bits))); }; inline int Mpegtoraw::getbits8(void) { register unsigned short a; int offset=bitindex>>3; a=(((unsigned char)buffer[offset])<<8) | ((unsigned char)buffer[offset+1]); a<<=(bitindex&7); bitindex+=8; return (int)((unsigned int)(a>>8)); }; inline int Mpegtoraw::getbit(void) { register int r=(buffer[bitindex>>3]>>(7-(bitindex&7)))&1; bitindex++; return r; }; #endif mp3blaster-3.2.6/mpegsound/soundplayer.cc0000664000112600011260000000120712426044701015370 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Soundplayer.cc // Superclass of Rawplayer and Rawtofile // It's used for set player of Mpegtoraw & Wavetoraw #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mpegsound.h" /*********************/ /* Soundplayer class */ /*********************/ Soundplayer::~Soundplayer() { // Nothing... } void Soundplayer::abort(void) { // Nothing.... } bool Soundplayer::resetsoundtype(void) { return true; } int Soundplayer::getblocksize(void) { return 1024; // Default value } int Soundplayer::fix_samplesize(void *buffer, int size) { buffer=buffer; return size; } mp3blaster-3.2.6/mpegsound/soundinputstream.cc0000664000112600011260000000155012426044701016450 00000000000000/* MPEG/WAVE Sound library (C) 1997 by Woo-jae Jung */ // Soundinputstream.cc // Abstractclass of inputstreams #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "mpegsound.h" Soundinputstream::Soundinputstream() { __errorcode=SOUND_ERROR_OK; }; Soundinputstream::~Soundinputstream() { // Nothing... }; /********************/ /* File & Http open */ /********************/ Soundinputstream *Soundinputstream::hopen(const char *filename,int *errorcode) { Soundinputstream *st; if (filename==NULL) st=new Soundinputstreamfromfile; else if (strstr(filename,"://")) st=new Soundinputstreamfromhttp; else st=new Soundinputstreamfromfile; if (st==NULL) { *errorcode=SOUND_ERROR_MEMORYNOTENOUGH; return NULL; } if (!st->open(filename)) { *errorcode=st->geterrorcode(); delete st; return NULL; } return st; } mp3blaster-3.2.6/mpegsound/Makefile.in0000644000112600011260000004571413106424274014575 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = mpegsound DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \ $(noinst_HEADERS) AUTHORS ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libmpegsound_a_AR = $(AR) $(ARFLAGS) libmpegsound_a_LIBADD = am_libmpegsound_a_OBJECTS = soundinputstream.$(OBJEXT) \ fileinput.$(OBJEXT) httpinput.$(OBJEXT) soundplayer.$(OBJEXT) \ rawplayer.$(OBJEXT) rawtofile.$(OBJEXT) mpegtable.$(OBJEXT) \ filter.$(OBJEXT) filter_2.$(OBJEXT) mpegtoraw.$(OBJEXT) \ mpeglayer1.$(OBJEXT) mpeglayer2.$(OBJEXT) mpeglayer3.$(OBJEXT) \ bitwindow.$(OBJEXT) huffmantable.$(OBJEXT) wavetoraw.$(OBJEXT) \ sidplayer.$(OBJEXT) fileplayer.$(OBJEXT) nasplayer.$(OBJEXT) \ oggplayer.$(OBJEXT) xingheader.$(OBJEXT) esdplayer.$(OBJEXT) \ sdlplayer.$(OBJEXT) cyclicbuffer.$(OBJEXT) libmpegsound_a_OBJECTS = $(am_libmpegsound_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libmpegsound_a_SOURCES) DIST_SOURCES = $(libmpegsound_a_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBESD = @LIBESD@ LIBMPEGSOUND = @LIBMPEGSOUND@ LIBNMIXER = @LIBNMIXER@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSDL = @LIBSDL@ LIRC_LIBS = @LIRC_LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NAS_CFLAGS = @NAS_CFLAGS@ NAS_LIBS = @NAS_LIBS@ NCURSES_LIBS = @NCURSES_LIBS@ OBJEXT = @OBJEXT@ OGG_LIBS = @OGG_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SDL11_CONFIG = @SDL11_CONFIG@ SDL12_CONFIG = @SDL12_CONFIG@ SDL_CONFIG = @SDL_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SID_LIBS = @SID_LIBS@ SRCDIRS = @SRCDIRS@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LIBRARIES = libmpegsound.a libmpegsound_a_SOURCES = soundinputstream.cc fileinput.cc httpinput.cc \ soundplayer.cc rawplayer.cc rawtofile.cc \ mpegtable.cc filter.cc filter_2.cc \ mpegtoraw.cc mpeglayer1.cc mpeglayer2.cc \ mpeglayer3.cc bitwindow.cc huffmantable.cc \ wavetoraw.cc sidplayer.cc \ fileplayer.cc nasplayer.cc oggplayer.cc \ xingheader.cc xingheader.h esdplayer.cc \ sdlplayer.cc cyclicbuffer.cc cyclicbuffer.h noinst_HEADERS = mpegsound.h mpegsound_locals.h INCLUDES = -I$(srcdir) -I$(includedir) AM_CXXFLAGS = @NAS_CFLAGS@ all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu mpegsound/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu mpegsound/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libmpegsound.a: $(libmpegsound_a_OBJECTS) $(libmpegsound_a_DEPENDENCIES) $(EXTRA_libmpegsound_a_DEPENDENCIES) $(AM_V_at)-rm -f libmpegsound.a $(AM_V_AR)$(libmpegsound_a_AR) libmpegsound.a $(libmpegsound_a_OBJECTS) $(libmpegsound_a_LIBADD) $(AM_V_at)$(RANLIB) libmpegsound.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitwindow.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cyclicbuffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/esdplayer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileinput.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileplayer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filter_2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpinput.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/huffmantable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpeglayer1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpeglayer2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpeglayer3.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpegtable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpegtoraw.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nasplayer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oggplayer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rawplayer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rawtofile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdlplayer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sidplayer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/soundinputstream.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/soundplayer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wavetoraw.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xingheader.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) $(HEADERS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: mp3blaster-3.2.6/mpegsound/xingheader.cc0000664000112600011260000000547712426044701015156 00000000000000/*---- DXhead.c -------------------------------------------- decoder MPEG Layer III handle Xing header mod 12/7/98 add vbr scale Copyright 1998 Xing Technology Corp. -----------------------------------------------------------*/ #include #include #include #include #include #include "xingheader.h" // 4 Xing // 4 flags // 4 frames // 4 bytes // 100 toc /*-------------------------------------------------------------*/ static int ExtractI4(unsigned char *buf) { int x; // big endian extract x = buf[0]; x <<= 8; x |= buf[1]; x <<= 8; x |= buf[2]; x <<= 8; x |= buf[3]; return x; } /*-------------------------------------------------------------*/ int GetXingHeader(XHEADDATA *X, unsigned char *buf) { int i, head_flags; int h_id, h_mode, h_sr_index; static int sr_table[4] = { 44100, 48000, 32000, 99999 }; // get Xing header data X->flags = 0; // clear to null incase fail // get selected MPEG header data h_id = (buf[1] >> 3) & 1; h_sr_index = (buf[2] >> 2) & 3; h_mode = (buf[3] >> 6) & 3; // determine offset of header if( h_id ) { // mpeg1 if( h_mode != 3 ) buf+=(32+4); else buf+=(17+4); } else { // mpeg2 if( h_mode != 3 ) buf+=(17+4); else buf+=(9+4); } if( buf[0] != 'X' ) return 0; // fail if( buf[1] != 'i' ) return 0; // header not found if( buf[2] != 'n' ) return 0; if( buf[3] != 'g' ) return 0; buf+=4; X->h_id = h_id; X->samprate = sr_table[h_sr_index]; if( h_id == 0 ) X->samprate >>= 1; head_flags = X->flags = ExtractI4(buf); buf+=4; // get flags if( head_flags & FRAMES_FLAG ) {X->frames = ExtractI4(buf); buf+=4;} if( head_flags & BYTES_FLAG ) {X->bytes = ExtractI4(buf); buf+=4;} if( head_flags & TOC_FLAG ) { if( X->toc != NULL ) { for(i=0;i<100;i++) X->toc[i] = buf[i]; } buf+=100; } X->vbr_scale = -1; if( head_flags & VBR_SCALE_FLAG ) {X->vbr_scale = ExtractI4(buf); buf+=4;} //if( X->toc != NULL ) { //for(i=0;i<100;i++) { // if( (i%10) == 0 ) printf("\n"); // printf(" %3d", (int)(X->toc[i])); //} //} return 1; // success } /*-------------------------------------------------------------*/ int SeekPoint(unsigned char TOC[100], int file_bytes, float percent) { // interpolate in TOC to get file seek point in bytes int a, seekpoint; float fa, fb, fx; if( percent < 0.0f ) percent = 0.0f; if( percent > 100.0f ) percent = 100.0f; a = (int)percent; if( a > 99 ) a = 99; fa = TOC[a]; if( a < 99 ) { fb = TOC[a+1]; } else { fb = 256.0f; } fx = fa + (fb-fa)*(percent-a); seekpoint = (int)((1.0f/256.0f)*fx*file_bytes); return seekpoint; } /*-------------------------------------------------------------*/ mp3blaster-3.2.6/mpegsound/AUTHORS0000664000112600011260000000000012426044701013552 00000000000000mp3blaster-3.2.6/README0000664000112600011260000001140312426044701011372 00000000000000--------------------------------------------------------------------- MP3Blaster README --------------------------------------------------------------------- Table of Contents ------------------------ 1. Introduction 2. Prerequisites 3. Installation 4. Usage 5. Examples (TODO) 6. Configuration 7. Availability 8. Bugs 9. Frequently Asked Questions 10. Developer Information 11. Links 12. Copyright 1. Introduction ------------------------- MP3Blaster is a text console based program for playing mainly mp3 audio files. It is very interactive, and has a great list of features. Its playlist can be divided in albums or categories (called 'groups'), which allows for very sophisticated playback orders. 2. Prerequisites ------------------------- - One of the following Operating Systems is currently supported: FreeBSD, Linux, NetBSD, OpenBSD. It should be trivial to port MP3Blaster to other UNIX-like Operating Systems. - A soundcard. Although 8-bit soundcards, and those that are limited to 22 Khz playback will work, a 44Khz capable 16 bits soundcard (as all new cards are) is recommended. - Threads. Most Operating Systems have a pthreads implementation. If yours doesn't, you can use libpth instead (see section Links for the URL) by conifuring with an extra flag '--with-pth'. 3. Installation ------------------------- If you're eager to start, this will do: ./configure make make install Run './configure --help' to get a list of compile-time options. There are a few important options that can have an impact on the quality of audio-playback and CPU usage on your system. These are: --enable-newthreads (auto-enables --with-pth) This will use an alternative playback buffering system. It might work better than the conventional buffering system on many systems. Please give it a try if you're experiencing skips during sound playback. Mail problems / successes. --with-pth (without --enable-newthreads) Uses libpth instead of the OS-specific pthreads implementation. This might reduce CPU-overhead and improve sound playback. Please try this and reports problems / successes. If you don't supply any of the above mentioned flags, the OS-specific pthreads implementation will be used, with default buffering mechanism. On FreeBSD no buffering will be used by default since it will probably hog your CPU or simply hang. using libpth on Free(/Net/Open)BSD is therefor recommended. 4. Usage ------------------------- Read the MP3Blaster manpage (man mp3blaster or man -lmp3blaster.1 from source) for information about commandline parameters, config files, usage, etc. Read the next section for some examples 5. Examples ------------------------- MP3Blaster's defaults should be good for most systems. Most keybindings can be reconfigured easily using a config file. A simple way to play a lot of mp3's from the command line in random order: mp3blaster -p allrandom /my/mp3s/*.mp3 Load a playlist and start playing immediately: mp3blaster -a /my/playlists/coolsongs.lst Use mp3blaster with an old, 8 bit soundcard that can do 22Khz sampling: mp3blaster -28 6. Configuration ------------------------- For an example configuration file, see or copy doc/sample.mp3blasterrc* to ~/.mp3blasterrc and modify to tastes. The man page has information on all available settings possible in the file. 7. Availability ------------------------- MP3Blaster can be downloaded from: http://mp3blaster.sourceforge.net/ 8. Bugs ------------------------- None. MP3Blaster happens to be fully bug-free. If you find a bug, it's probably a real life one buzzing around your head. If you believed that, and you run a nice IT company, please contact me ;-) Otherwise, read the "TODO" and "ChangeLog" files for known bugs, or features on the drawing board. If you find any bugs, please report them (see section 'Developer Information') 9. Frequently Asked Questions ---------------------------------- Read the "FAQ" on the sourceforge project page. 10. Developer Information ---------------------------------- All code used by and written for MP3Blaster is GPL'd. Read the "COPYING" file for more information about the GPL license. If you want to report bugs, ask development-related questions, or just want a taste of celebrity, surf to the sourceforge project page. 11. Links ---------------------------------- MP3Blaster http://mp3blaster.sourceforge.net/ libpth http://www.gnu.org/software/pth/pth.html 12. Copyright ---------------------------------- All code used by and written for MP3Blaster is GPL'd. Read the "COPYING" file for more information about the GPL license. mp3blaster-3.2.6/config.h.in0000644000112600011260000001101113106424300012517 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* write audiodata to the sound device without blocking */ #undef AUDIO_NONBLOCKING /* Compile-time audio output driver info */ #undef BUILDOPTS_AUDIODRIVERS /* Compile-time audio foramt support info */ #undef BUILDOPTS_AUDIOFORMATS /* Compile-time features info */ #undef BUILDOPTS_FEATURES /* Define to 1 if you have the header file. */ #undef HAVE_BOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_ERRNO_H /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the `ossaudio' library (-lossaudio). */ #undef HAVE_LIBOSSAUDIO /* Define to 1 if you have the `pthread' library (-lpthread). */ #undef HAVE_LIBPTHREAD /* Define to 1 if you have the header file. */ #undef HAVE_MACHINE_SOUNDCARD_H /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_PTHREAD_H /* Define to 1 if you have the header file. */ #undef HAVE_PTHREAD_MIT_PTHREAD_H /* Define to 1 if you have the header file. */ #undef HAVE_PTH_H /* SID Playback support */ #undef HAVE_SIDPLAYER /* Define to 1 if you have the header file. */ #undef HAVE_SOUNDCARD_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOUNDCARD_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* LIRC support */ #undef INCLUDE_LIRC /* OGG playback support */ #undef INCLUDE_OGG /* Use PTH as posix threads library */ #undef LIBPTH /* Which headerfile to include for ncurses support */ #undef NCURSES_HEADER /* Use alternative buffering mechanism when using OSS output driver */ #undef NEWTHREAD /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Use pthreads for buffered audio playback (OSS only) */ #undef PTHREADEDMPEG /* OSS driver include file */ #undef SOUNDCARD_HEADERFILE /* Default OSS sound device to use */ #undef SOUND_DEVICE /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* ESD audio output support */ #undef WANT_ESD /* NAS audio output support */ #undef WANT_NAS /* OSS audio output support */ #undef WANT_OSS /* SDL audio output support */ #undef WANT_SDL /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Define to 1 if the X Window System is missing or not being used. */ #undef X_DISPLAY_MISSING /* Pthreads-required symbol on some systems */ #undef _REENTRANT /* Pthreads-required symbol on some systems */ #undef _THREAD_SAFE /* Define to empty if `const' does not conform to ANSI C. */ #undef const mp3blaster-3.2.6/splay.10000664000112600011260000000462712426044701011736 00000000000000.ds PX \s-1UNIX\s+1 .TH SPLAY 1 "Aug 3 1997" "by Woo-jae Jung" "Applications/Sound" .SH NAME splay \- MPEG-1,2 Audio layer 1,2,3 and Wave file player .SH SYNOPSIS .B splay [-2VMWmrsv] [-d dev] [-l list] [-t num] .I filenames... .B xsplay [-2Vemrsv] [-d dev] [-l list] [-t num] .I filenames... .SH DESCRIPTION .I Splay is the sound file player such as MPEG-1,2 Audio files and Wave files. And you can play these files using list file. With pthread, it can play sound files smoother. And it has X-interface with libqt. Splay with qt may make you splay easily. .SH OPTIONS .I Splay has several options. .TP .BI \-2 play MPEG-Audio files with half-frequency.\fR If you use this option, you may play MPEG audio files with job which exhausts CPU very much. .PD 0 .TP .BI \-e exit when play is done. (xsplay) .TP .BI \-m force to mono.\fR .PD 0 Play with mono even if file have stereo quality. .PD 0 .TP .BI \-r Repeat forever. (Not X-interface) If you \-r with \-s, list files would be shuffled everytime. .PD 0 .TP .BI \-s Shuffle play. If you give list file or a number of files, Splay will makes them rearranged randomly. And with \-r Everytime the order of files would be changed. .PD 0 .TP .BI \-v Verbose, Very verbose, Very very verbose. (Note: splay version supplied with mp3blaster does not have this feature anymore) .PD 0 .TP .BI \-M Play MPEG file as standard input. .PD 0 .TP .BI \-W Play Wave file as standard input. .PD 0 .TP .BI \-V Show version number. .TP .PD .B \-t " num" .I num of frames were saved during playing. When CPU is so busy and prevents splay from decoding, splay will play back using saved frames. This feature makes you do other job freely with listing MPEG music. .PD 0 .TP .B \-d " dev" Change device file. Default device file is .I /dev/dsp. If you can't use this device file or you can output raw type data to file, you can use this option. If the first character of .I dev is .B / , .I dev would be considered as device file, If the first character of .I dev is .B - , .I dev would be considered as standard output, otherwise .I dev would be considered as normal file. .PD 0 .TP .B \-l " list" Select list file. .B http:// can be used. (e.g. http://localhost/abc.m3u) .PD 0 .TP .B filenames You can put several files, and use .B http:// If filename contains .mp or .MP, it will be considered as MPEG-Audio file. Otherwise be considered as Wave file. But if you use .B -l option, these will be ignored. .SH SEE ALSO mp3blaster-3.2.6/BUGS0000664000112600011260000000001312426044701011170 00000000000000See 'TODO' mp3blaster-3.2.6/compile0000755000112600011260000001624513103664455012106 00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2013 Free Software Foundation, Inc. # Written by Tom Tromey . # # 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, 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. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: mp3blaster-3.2.6/install-sh0000775000112600011260000001272112426044701012522 00000000000000#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 mp3blaster-3.2.6/missing0000775000112600011260000002123112426044701012111 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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, 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. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.3 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar ${1+"$@"} && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar ${1+"$@"} && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" ${1+"$@"} && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" ${1+"$@"} && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 mp3blaster-3.2.6/FAQ0000664000112600011260000000004512426044701011044 00000000000000See FAQ on http://mp3blaster.sf.net/ mp3blaster-3.2.6/TODO0000664000112600011260000000601412426044701011204 00000000000000INTERFACE -better distinction between file manager and playlist => file manager should get a different colour and window styles? Or just a complete overlay on the entire interface.. -Rename GroupShuffle to Shuffle -Select a Directory in FM -> add it to the group BUGS -make '<' and '>' mixer keys remappable -fix warnings -fix colour stuff IMPORTANT -Quiting with an unsaved playlist should display a warning (unless one explicitly configures it not to, of course) -Add 'readonly' mode (similar to '%' in mutt), enable it by default, to prevent people from accidentally deleting their mp3 collection. -warn about double keybindings (2 actions to 1 keycode) -allow 1 action mapped to multiple keycodes -22Khz vorbis files play too fast? -save shuffle mode for main group, and playback mode for entire group in playlist SMALL & SIMPLE -configfile keyword for items in mixer (shortens cycle) -file search with '/' optionally case-insensitive -mp3 search in normal mode with '/' too -jump to dir-entry one came from after going to '..' -hide 'hidden files' (.??*) INTERESTING -ogg streaming (have oggplayer class use soundinputstream) -implement ID3v2 tag parsing (id3lib.sourceforge.net, www.id3v2.org) -skip to place in playlist on request. -FLAC support (flawless audio codec, http://flac.sourceforge.net/) -make File.ID3Names a sscanf-like pattern that determines *how* id3 names are shown. -stream preferences (although that's basically just a playlist with groups, in which each group contains a stream..) -fix information display so that it will display information relevant to the format being played. -read/write playlist +save tmp.playlist to continue it later. (partly done) -'enqueue' mp3's from filemanager (implement as another playlist, do 'previous played tracks' in the same way) (aka 'hotkey' playlist) -when directories are given as final cmdline args, assume recursive search of mp3's in that dir. -F5/F3 in filemanager mode: instead of using currently highlighted dir, check if multiple dirs have been selected and use all those dirs to add mp3's instd. -check existence of files on playlistload (and report status, including total time etc) -'skip to next mp3 and delete this one from list' -Shout/IceCast .pls support (HTTP streaming works). -make 'next song' skippable (could be tough, it's not a pointer to a group member, but just a const char *..) -Total playlist time displayed somewhere -optionally replace all '\''s with '/''s in playlist (to read DOS playlists) -lower screenwidth/height requirement -fade cross-over to new song / preload new song before old one ends LOW PRIORITY -save session-info (like last dir one was in last time) -recode layout of code (currently, too much is stuffed in main.cc) -move all selected files in filemanager to current dir (m) (!) -clear mpeg-info when songplay's finished. -file viewer in filemanager. -rename group->getPlayedmode() to group->randomOrder() -pulldown menus instead of space-consuming help window/option to hide help -move copies of getopt.[ch] to a shared dir instead of copying them mp3blaster-3.2.6/nmixer/0000755000112600011260000000000013106424300012064 500000000000000mp3blaster-3.2.6/nmixer/nasmixer.cc0000664000112600011260000000310112426044701014145 00000000000000#include "config.h" /*\ |*| Network Audio System specific mixer routines \*/ #ifdef HAVE_NASPLAYER #include #include #include