Re: [MP3 ENCODER] Please Vote: Interface types
On Wed, 27 Sep 2000, Frank Klemm wrote: > +--X8X8---+ > | [_] I do not vote| > | [_] pointer to a public structure| > | [_] private struct | > | [X] pointer to a private struct | > | [_] lame handle | > +--X8X8---+ -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re[2]: [MP3 ENCODER] 3.87b MMX and no MMX give different results + some 3.87 comments
Hello Robert, Thursday, September 28, 2000, 1:14:17 AM, you wrote: RH> At least your 3.87 MMX version seems to be compiled with the RH> Makefile.MSVC I checked in, with RH_AMP and RH_VALIDATE_MS RH> enabled. Dmitry, is that right? yes. i used your defult Makefile.MSVC, but with commented gtk. Best regards, Dmitrymail to: [EMAIL PROTECTED] -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
[MP3 ENCODER] Re: 3.87b MMX and no MMX give different results + some 3.87 comments
In the last episode (Sep 28), Mark Powell said: > BTW The gcc 2.95.2 options are perfectly valid for FreeBSD as well as > Linux. Obviously :) Can they be copied into the FBSD section too? > > # these options for gcc-2.95.2 to produce fast code > # CC_OPTS = \ > # -Wall -O9 -fomit-frame-pointer -march=pentium \ > # -finline-functions -fexpensive-optimizations \ > # -funroll-loops -funroll-all-loops -pipe -fschedule-insns2 \ > # -fstrength-reduce \ > # -malign-double -mfancy-math-387 -ffast-math I object to half of these options because whoever added obviously never tested his additions one at a time to verify that they actually help. 1) There is no -O level above 3 2) You can't assume the user is compiling on a 586 3) Here is a list of the -f options listed, and which -O level automatically enables them: -fomit-frame-pointer - -finline-functions 3 -fexpensive-optimizations2 -funroll-all-loops - -funroll-loops enabled by -funroll-all-loops -fschedule-insns22 -fstrength-reduce2 -ffast-math - So at minimum, the CC_OPTS should read -Wall -pipe -O3 -fomit-frame-pointer -funroll-all-loops -ffast-math -malign-double mfancy-math-387 And it's debatable whether unroll-all-loops is a win or not (depends on whether the unrolled code is larger than your CPU's cache). -- Dan Nelson [EMAIL PROTECTED] -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] 3.87b MMX and no MMX give different results + some3.87 comments
> "M" == Mark Powell <[EMAIL PROTECTED]> writes: M> BTW The gcc 2.95.2 options are perfectly valid for FreeBSD as M> well as Linux. Obviously :) Can they be copied into the FBSD M> section too? silly thing. you had better detect CPU/Compiler by configure and output the option to Makefile. --- [EMAIL PROTECTED] // may the source be with you! -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
[MP3 ENCODER] MMX support
> "M" == Mark Powell <[EMAIL PROTECTED]> writes: M> How did you get the Linux version to assemble the MMX code? M> I've had no luck with GNU as v2.10.0 under FreeBSD. I'm M> obviously missing something? you are missing NASM. --- [EMAIL PROTECTED] // may the source be with you! -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] 3.87b MMX and no MMX give different results + some3.87 comments
On Wed, 27 Sep 2000, Roel VdB wrote: > 1b)3.87 -V1 is 20% faster than 3.86 (thanks Robert!) > 1c)3.87 -V1 MMX is 35% faster than 3.86 (thanks Takehiro!) I'll second the thanks to you both :) > 2) I miss the # of frames in each bitrate mode. The new real-time % >data looks really neat, but please re-instate the # frames. > 3) Would be really something if it would also say [total# frames/total ># of S frames/ total # of M/S frames]. Room enough on the lines :) I like this idea too, Roel. Cheers. Mark Powell - UNIX System Administrator - The University of Salford Academic Information Services, Clifford Whitworth Building, Salford University, Manchester, M5 4WT, UK. Tel: +44 161 295 5936 Fax: +44 161 295 5888 www.pgp.com for PGP key -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] 3.87b MMX and no MMX give different results + some3.87 comments
On Wed, 27 Sep 2000, Robert Hegemann wrote: > At least your 3.87 MMX version seems to be compiled with the > Makefile.MSVC I checked in, with RH_AMP and RH_VALIDATE_MS > enabled. Dmitry, is that right? BTW Robert, are you recommending these options for improved quality? Would that also be inconjunction with the --raise-smr 1 flag for VBR? Cheers. Mark Powell - UNIX System Administrator - The University of Salford Academic Information Services, Clifford Whitworth Building, Salford University, Manchester, M5 4WT, UK. Tel: +44 161 295 5936 Fax: +44 161 295 5888 www.pgp.com for PGP key -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] 3.87b MMX and no MMX give different results + some3.87 comments
On Wed, 27 Sep 2000, Robert Hegemann wrote: > On my Linux Box with a Pentium 166 MMX the MMX and non-MMX > version produce bit identical results. How did you get the Linux version to assemble the MMX code? I've had no luck with GNU as v2.10.0 under FreeBSD. I'm obviously missing something? BTW The gcc 2.95.2 options are perfectly valid for FreeBSD as well as Linux. Obviously :) Can they be copied into the FBSD section too? - ## # FreeBSD ## ifeq ($(UNAME),FreeBSD) # some alternate code (work in progress [EMAIL PROTECTED]) # CPP_OPTS += -DRH_AMP -DRH_VALIDATE_MS # these options for gcc-2.95.2 to produce fast code # CC_OPTS = \ # -Wall -O9 -fomit-frame-pointer -march=pentium \ # -finline-functions -fexpensive-optimizations \ # -funroll-loops -funroll-all-loops -pipe -fschedule-insns2 \ # -fstrength-reduce \ # -malign-double -mfancy-math-387 -ffast-math endif - Mark Powell - UNIX System Administrator - The University of Salford Academic Information Services, Clifford Whitworth Building, Salford University, Manchester, M5 4WT, UK. Tel: +44 161 295 5936 Fax: +44 161 295 5888 www.pgp.com for PGP key -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] 3.87b MMX and no MMX give different results + some 3.87 comments
> At least your 3.87 MMX version seems to be compiled with the > Makefile.MSVC I checked in, with RH_AMP and RH_VALIDATE_MS > enabled. Dmitry, is that right? Should they be considered as default switches? In this case, why aren't they defined in the VC project? Regards, -- Gabriel Bouvigne - France [EMAIL PROTECTED] mobile phone: [EMAIL PROTECTED] icq: 12138873 MP3' Tech: www.mp3-tech.org -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] Please Vote: Interface types
Frank Klemm schrieb am Mit, 27 Sep 2000: > To avoid endless debates about the interface without clearifying the basic > concept I do introduce all possible methods I know (for C) with explaining > all pro and cons I know. I hope this is the best I can do. > > +--X8X8---+ > | [_] I do not vote| > | [_] pointer to a public structure| > | [_] private struct | > | [X] pointer to a private struct | > | [_] lame handle | > +--X8X8---+ Ciao Robert -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] 3.87b MMX and no MMX give different results + some 3.87 comments
Roel VdB schrieb am Mit, 27 Sep 2000: > 3.86 (nommx) > > average: 235 kbs > > 3.87 nommx: > > average: 225.8 kbps > > 3.87 MMX > > average: 224.6 kbps > > remarks: > 1) 3.87 MMX is smaller, yet it sounds better (???) (velvet JS noise) does it sound better than 3.87 non-MMX or 3.86? > 1b)3.87 -V1 is 20% faster than 3.86 (thanks Robert!) > 1c)3.87 -V1 MMX is 35% faster than 3.86 (thanks Takehiro!) > 2) I miss the # of frames in each bitrate mode. The new real-time % >data looks really neat, but please re-instate the # frames. > 3) Would be really something if it would also say [total# frames/total ># of S frames/ total # of M/S frames]. Room enough on the lines :) > 4) Why does the MMX mode and non-MMX mode give different output on my >Cel450/Win95OSR2? Isn't MMX supposed to give same results? On my Linux Box with a Pentium 166 MMX the MMX and non-MMX version produce bit identical results. At least your 3.87 MMX version seems to be compiled with the Makefile.MSVC I checked in, with RH_AMP and RH_VALIDATE_MS enabled. Dmitry, is that right? Ciao Robert -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] TagItem issues...
:: /* Usage : :: lame_set_parameters(gfp, LAME_SAMP_FREQ__INT, 44100 , :: LAME_NR_CHANNELS__INT , 2 , :: LAME_LOW_PASS_VALUE__FLOAT , 16.050 , :: LAME_LOW_PASS_WIDTH__FLOAT , 0.75, :: LAME_COMMENT__STRING , "This is cool" , :: LAME_END_MARKER); :: :: LAME_END_MARKER informs the lame_set_parameters to stop reading values, :: as AFAIK :: there is not other way to determine whether all the args has been read :: :: the __FLOAT and __INT attachments are there only to help illustrate my :: idea, :: but could be helpful in the actual implementation too :: :: */ :: One function, but is this simple? No error checking, a lot of really strange constants, mixing Hz and kHz. Do you like bugs? Do you love bugs? Do you buy a car with only one joystick to do all operations (including wheel- and oil-change)? Only one joystick, that means very simple operations! Welcome on the graveyard. typedef struct { void* ptr; const size_t size; size_t len; } bytebuffer_t; bytebuffer_t bb; LAME* gfp; gfp = lame_open (); lame_set_samplefreq( gfp, 44100.0 ); lame_set_channels ( gfp, 2 ); lame_set_lowpass ( gfp, 16050.0 ); lame_set_lowpass_width ( gfp, 750.0 ); lame_set_lowpass_type ( gfp, lame_filter_chebychev, 8, 0.5 ); lame_set_comment ( gfp, "This is not error prone" ); lame_add_comment ( gfp, "Developers will not hate lame developers" ); lame_add_comment ( gfp, "Lame developers do not need a body guard" ); alloc_bytebuffer ( &bb, 16384 ); error = lame_encode_buffer ( gfp, &bb, 88200, channel_left, channel_right ); if (error) lame_perror ( "The following error occured", error ); fwrite ( fp, 1, bb.len, bb.ptr ); error = lame_encode_interleaved_buffer ( gfp, &bb, 88200, interleaved_buffer ); if (error) lame_perror ( "The following error occured", error ); fwrite ( fp, 1, bb.len, bb.ptr ); error = lame_encode_finish ( gfp, &bb ); if (error) lame_perror ( "The following error occured", error ); fwrite ( fp, 1, bb.len, bb.ptr ); if ( bb.size > 16384 ) printf ( "BitBuffer was increased by a subroutine, instead of crashing!\n" ); free_bytebuffer ( &bb ); error = lame_close ( gfp ); if (error) lame_perror ( "Shit, the last operation and a error", error ); -- Mit freundlichen Grüßen Frank Klemm eMail | [EMAIL PROTECTED] home: [EMAIL PROTECTED] phone | +49 (3641) 64-2721home: +49 (3641) 390545 sMail | R.-Breitscheid-Str. 43, 07747 Jena, Germany -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
[MP3 ENCODER] Please Vote: Interface types
To avoid endless debates about the interface without clearifying the basic concept I do introduce all possible methods I know (for C) with explaining all pro and cons I know. I hope this is the best I can do. +--X8X8---+ | [_] I do not vote| | [_] pointer to a public structure| | [_] private struct | | [_] pointer to a private struct | | [_] lame handle | +--X8X8---+ a) pointer to a public structure Program have to allocate a struct on stack, heap or statically (or lame_open has to do this) and have to release this at the end. The structure of this struct is well known, every element can be accessed via read and write. All lame functions get as first argument a pointer to this struct. Interface is peeking and poking this structure. + source code compatible with the current version (you only need to recompile, if you have all the sources) - problems while extending, reording, changing structure removing, changing, promoting elements of this structure (this can be avoid with more or less effort until a given degree, but this also will hinder development, and finally it goes wrong) - problems when compiler will change binary structure representation - problems when structure must be extended - problems when changing the libmp3lame.so due to the points mentioned above - the are some ambiguous situations (example: VBR_q=0: quality=standard or quality=0) - error handling is more difficult (who is the guilty?) Note: Changing an interface not become easier in the future. Note: If necessary a wrapper can be written to support the old interface. b) private struct Program have to allocate a struct on stack, heap or statically. The structure of this struct is not known, so access is possible, but only with obvious very dirty methods. All lame function get as first argument a pointer to this struct. Interface are well defined function calls. - problems when the struct must be enlarged o rest see c) c) pointer to a private struct Program calls lame_open and gets back a pointer to a structure. The structure of this struct is not known, so access is possible, but only with obvious very dirty methods. All lame function get as first argument this struct pointer. Interface are well defined function calls. - not source code compatible with the current version + no problems changing the internal structure. You can do nearly everything + no problems changing the shared lib without recompiling all programs + no compiler representation problems + structure can be extended without any problem + well defined interface with the possibilty of error handling Note: UNIX/C buffered FILE I/O works in this way: fopen/fread/fwrite/fputs/fclose/setvbuf/fseek/... d) lame handle Program calls lame_open and gets back an integer value. This value is an index into an internal lame table. Access to this internal table is also only possible via obvious very dirty methods. All lame function get as first argument this integer value. Interface are well defined function calls. o first see c) + better anonymization of the structure + needs not the trick of mapping two different structures in API and Lame - a little bit less error checking is possible (first parameter is an int, here you can pass a lot of trash: 44100/1050 ) Note: POSIX unbuffered I/O works in this way: open/read/write/close/lseek/dup/dup2 Good operating Systems also hiding the internal structure by memory protection (Kernel/User space). Hope this helps. -- Mit freundlichen Grüßen Frank Klemm eMail | [EMAIL PROTECTED] home: [EMAIL PROTECTED] phone | +49 (3641) 64-2721home: +49 (3641) 390545 sMail | R.-Breitscheid-Str. 43, 07747 Jena, Germany -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
RE: [MP3 ENCODER] 3.87b MMX and no MMX give different results + some 3.87 comments
I had the same problem of MMX giving different results than the non-mmx. Maybe the algorithms are different? Is that correct? Isn't MMX (assembly in general) going to use a different algorithm, because if you are using the same algorithm for assembly as you do in C, shouldn't the C compiler give the same assembly as you just wrote? Am I way off? Also I was compiling both with MSVC and DJGPP. I thought I had basically the same options when compiling, I had none of the optional stuff like IEEE hack and Takehiro's modifications. But when the same commandline is used with LameVC (compiled with Visual C) and then again with LameDJ (Lame compiled with DJGPP), the outputs are different. I used constant bitrate encoding. Does anyone know how to build the DLL for Win32 using VC or DJGPP from the commandline ie make or nmake? thanks, Nathan D. Blomquist http://www.win32lame.com -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]On Behalf Of Roel VdB Sent: Wednesday, September 27, 2000 1:57 PM To: [EMAIL PROTECTED] Subject: [MP3 ENCODER] 3.87b MMX and no MMX give different results + some 3.87 comments Hello, first some data: (-V1 -mj -h -b128 -q1) 3.86 (nommx) > Encoding c.wav to c-386-nommx.mp3 > Encoding as 44.1 kHz VBR(q=1) j-stereo MPEG1 LayerIII ( 6.0x estimated) qval=1 > Frame | CPU/estimated | time/estimated | play/CPU | ETA > 12498/ 12498(100%)| 0:04:07/ 0:04:07| 0:04:07/ 0:04:07|1.3215| 0:00:00 > - bitrate statistics - > [kbps] frames > 32 9 (0.1%) >128 109 (0.9%) >160 1270 (10.2%) >192 4365 (34.9%) >224 2074 (16.6%) >256 1305 (10.4%) >320 3367 (26.9%) > > average: 235 kbs 3.87 nommx: > LAME version 3.87 (beta 1, Sep 26 2000)(http://www.mp3dev.org) > Win32 binaries from www.chat.ru/~dkutsanov/ > polyphase lowpass filter disabled > Encoding c.wav to c-ic-nommx.mp3 > Encoding as 44.1 kHz VBR(q=1) j-stereo MPEG-1 LayerIII ( 6.0x estimated) qval=1 > Frame | CPU time/estim | REAL time/estim | play/CPU |ETA > 12498/12498 (100%)|3:25/3:25|3:26/3:26| 1.5855x| 0:00 > 32 [%.1]* > 128 [ 2%]*** > 160 [19%]* > 192 [33%]** > 224 [13%] > 256 [10%]*** > 320 [24%]* > average: 225.8 kbps 3.87 MMX > LAME version 3.87 (beta 1, Sep 27 2000)(http://www.mp3dev.org) > Win32 binaries from www.chat.ru/~dkutsanov/ > polyphase lowpass filter disabled > Encoding c.wav to c-ic.mp3 > Encoding as 44.1 kHz VBR(q=1) j-stereo MPEG-1 LayerIII ( 6.0x estimated) qval=1 > Frame | CPU time/estim | REAL time/estim | play/CPU |ETA > 12498/12498 (100%)|3:03/3:03|3:03/3:03| 1.7822x| 0:00 > 32 [%.1]* > 128 [ 2%]*** > 160 [18%] > 192 [33%]** > 224 [13%] > 256 [11%]* > 320 [22%]** > average: 224.6 kbps remarks: 1) 3.87 MMX is smaller, yet it sounds better (???) (velvet JS noise) 1b)3.87 -V1 is 20% faster than 3.86 (thanks Robert!) 1c)3.87 -V1 MMX is 35% faster than 3.86 (thanks Takehiro!) 2) I miss the # of frames in each bitrate mode. The new real-time % data looks really neat, but please re-instate the # frames. 3) Would be really something if it would also say [total# frames/total # of S frames/ total # of M/S frames]. Room enough on the lines :) 4) Why does the MMX mode and non-MMX mode give different output on my Cel450/Win95OSR2? Isn't MMX supposed to give same results? thanks and Best regards, Roel mailto:[EMAIL PROTECTED] -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ ) -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
[MP3 ENCODER] 3.87b MMX and no MMX give different results + some 3.87 comments
Hello, first some data: (-V1 -mj -h -b128 -q1) 3.86 (nommx) > Encoding c.wav to c-386-nommx.mp3 > Encoding as 44.1 kHz VBR(q=1) j-stereo MPEG1 LayerIII ( 6.0x estimated) qval=1 > Frame | CPU/estimated | time/estimated | play/CPU | ETA > 12498/ 12498(100%)| 0:04:07/ 0:04:07| 0:04:07/ 0:04:07|1.3215| 0:00:00 > - bitrate statistics - > [kbps] frames > 32 9 (0.1%) >128 109 (0.9%) >160 1270 (10.2%) >192 4365 (34.9%) >224 2074 (16.6%) >256 1305 (10.4%) >320 3367 (26.9%) > > average: 235 kbs 3.87 nommx: > LAME version 3.87 (beta 1, Sep 26 2000)(http://www.mp3dev.org) > Win32 binaries from www.chat.ru/~dkutsanov/ > polyphase lowpass filter disabled > Encoding c.wav to c-ic-nommx.mp3 > Encoding as 44.1 kHz VBR(q=1) j-stereo MPEG-1 LayerIII ( 6.0x estimated) qval=1 > Frame | CPU time/estim | REAL time/estim | play/CPU |ETA > 12498/12498 (100%)|3:25/3:25|3:26/3:26| 1.5855x|0:00 > 32 [%.1]* > 128 [ 2%]*** > 160 [19%]* > 192 [33%]** > 224 [13%] > 256 [10%]*** > 320 [24%]* > average: 225.8 kbps 3.87 MMX > LAME version 3.87 (beta 1, Sep 27 2000)(http://www.mp3dev.org) > Win32 binaries from www.chat.ru/~dkutsanov/ > polyphase lowpass filter disabled > Encoding c.wav to c-ic.mp3 > Encoding as 44.1 kHz VBR(q=1) j-stereo MPEG-1 LayerIII ( 6.0x estimated) qval=1 > Frame | CPU time/estim | REAL time/estim | play/CPU |ETA > 12498/12498 (100%)|3:03/3:03|3:03/3:03| 1.7822x|0:00 > 32 [%.1]* > 128 [ 2%]*** > 160 [18%] > 192 [33%]** > 224 [13%] > 256 [11%]* > 320 [22%]** > average: 224.6 kbps remarks: 1) 3.87 MMX is smaller, yet it sounds better (???) (velvet JS noise) 1b)3.87 -V1 is 20% faster than 3.86 (thanks Robert!) 1c)3.87 -V1 MMX is 35% faster than 3.86 (thanks Takehiro!) 2) I miss the # of frames in each bitrate mode. The new real-time % data looks really neat, but please re-instate the # frames. 3) Would be really something if it would also say [total# frames/total # of S frames/ total # of M/S frames]. Room enough on the lines :) 4) Why does the MMX mode and non-MMX mode give different output on my Cel450/Win95OSR2? Isn't MMX supposed to give same results? thanks and Best regards, Roel mailto:[EMAIL PROTECTED] -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] TagItem issues...
>> This is how it looks now, better than using va_arg() at each case imho... >Why is it better ? >You wasted an additional variable and gained ( maybe ) some code space >by not doing a function call ( or maybe it is a macro , probably >platform dependant ) every time. It's usually a (rather messy) macro. ;) >By writing almost the same code 3 times you increase the likehood of >bugs 3 times :-) >Alltough most of the code would be repeated anyway. True, but there's not much space for error. ;) [...] >#define CASE(TAG,elem,type) case LAME_ ## TAG : gfp -> elem = >va_arg(args, type); break; > CASE( SET_SAMPLING_FREQ , samp_freq, int ) [...] That's actually not a bad idea... >/* in my man page va_start has only one argument (ap) ... */ Your man-page is wrong then I think, the second argument is so that va_arg() knows where to start (ie, it makes ap point to the next argument). >> I can still implement a way to have the tag also contain the type of the >> parameter, but since the general consensus seemed to be that this would be >> too complicated I went for this approach... ;) >But your existing tag "contain" the type , at least as much as they >would in my method. What I meant was that I could device another way of passing the tags that would allow me to supply information of the parameters type (ptr/float/int), but this isn't too convenient at the calling end. >#ifdef YOU >#define SOME_TAG some_int_value >#else >#define SOME_TAG some_int_value >#end What was the purpose of this? >Unless I use >SOME_TAG__WARNING_THIS_IS_FLOAT_AND_NOT_INT_OR_ANYTHING_ELSE, >but that is not the point , since it would work both with your and my >code. The advantage of having 3 different functions is also that you at a later stage can change the type of the internal parameter, and still accept the old without having to add a duplicate tag (f.ex. if you change from int to float, then you can just add the tag to lame_set_float(), and add a cast in lame_set_int)... - CISC -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] TagItem issues...
Sigbjřrn Skjćret wrote: > > >> and parsing gets abit more messy... > >How ? > [...] > > This is how it looks now, better than using va_arg() at each case imho... Why is it better ? You wasted an additional variable and gained ( maybe ) some code space by not doing a function call ( or maybe it is a macro , probably platform dependant ) every time. By writing almost the same code 3 times you increase the likehood of bugs 3 times :-) Alltough most of the code would be repeated anyway. My "more clear" version of the day : ( after the code are some more replyes to the original message ) int lame_set_parameters(lama_global_flags *gfp,...) { va_list args; LAME_TAG_TYPE current_tag; va_start(args); current_tag = va_arg(args,LAME_TAG_TYPE); while(current_tag != LAME_TAG_END ) { #define CASE(TAG,elem,type) case LAME_ ## TAG : gfp -> elem = va_arg(args, type); break; switch(current_tag) { CASE( SET_SAMPLING_FREQ , samp_freq, int ) CASE( SET_NR_CHAN , nr_channels , int ) CASE( FILTER_WIDTH , filter_width , float ) CASE( SOME_COMMENT , some_comment , char* ) /* some other integer, string or float or whatever parameters . */ #undef CASE default : return RET_TAG_ERROR_CODE; /* also print a warning ? probably not if this is a library. default : return -current_tag; so the app knows which tag is problematic or maybe return the position of the bad tag ? */ } current_tag = va_arg(args,LAME_TAG_TYPE); } va_end(args); } Here is the old version for reference : ( there is a bug already ! it should be lame_struct -> xxx and not lame_struct.xxx ) lame_set_parameters(lama_global_flags *lame_struct,...) { va_list args; LAME_TAG_TYPE current_tag; va_start(args); current_tag = va_arg(args,LAME_TAG_TYPE); while(current_tag != LAME_TAG_END ) { switch(current_tag) { case LAME_SET_SAMPLING_FREQ : lame_struct.samp_freq = va_arg(args,int); break; case LAME_SET_NR_CHAN : lame_struct.nr_channels = va_arg(args,int); break; case LAME_FILTER_WIDTH : lame_struct.filter_width = va_arg(args,float); break; /* some other integer, string or float or whatever parameters */ } current_tag = va_arg(args,LAME_TAG_TYPE); } va_end(args); } > void lame_set_int(lame_global_flags *gfp, lame_param_tag tag1, ...) > { >va_list ap; >int param; /* (varargs promotes integrals to int) */ > >va_start(ap, tag1); /* in my man page va_start has only one argument (ap) ... */ >while (tag1 != TAG_END) >{ > param = va_arg(ap, int); > > switch (tag1) > { >case LAMEtag1: > gfp->test1 = param; > break; > >case LAMEtag2: > gfp->test2 = param; > break; > >default: > break; > } > > tag1 = va_arg(ap, lame_param_tag); >} >va_end(ap); > } > > I can still implement a way to have the tag also contain the type of the > parameter, but since the general consensus seemed to be that this would be > too complicated I went for this approach... ;) But your existing tag "contain" the type , at least as much as they would in my method. #ifdef YOU #define SOME_TAG some_int_value #else #define SOME_TAG some_int_value #end Unless I use SOME_TAG__WARNING_THIS_IS_FLOAT_AND_NOT_INT_OR_ANYTHING_ELSE, but that is not the point , since it would work both with your and my code. I'm in hurry, forgive any mistakes :-) > - CISC > > -- > MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ ) -- David Balazic -- "Be excellent to each other." - Bill & Ted - - - - - - - - - - - - - - - - - - - - - - -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] TagItem issues...
>> and parsing gets abit more messy... >How ? [...] This is how it looks now, better than using va_arg() at each case imho... void lame_set_int(lame_global_flags *gfp, lame_param_tag tag1, ...) { va_list ap; int param; /* (varargs promotes integrals to int) */ va_start(ap, tag1); while (tag1 != TAG_END) { param = va_arg(ap, int); switch (tag1) { case LAMEtag1: gfp->test1 = param; break; case LAMEtag2: gfp->test2 = param; break; default: break; } tag1 = va_arg(ap, lame_param_tag); } va_end(ap); } I can still implement a way to have the tag also contain the type of the parameter, but since the general consensus seemed to be that this would be too complicated I went for this approach... ;) - CISC -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] TagItem issues...
Sigbjřrn Skjćret wrote: > >there is not other way to determine whether all the args has been read > >the __FLOAT and __INT attachments are there only to help illustrate my > >idea, > >but could be helpful in the actual implementation too > > Yes, but this still requires the parameters to be correct, I don't think there is a way to make it work with incorrect parameters :-) > and parsing gets abit more messy... How ? The 3 functions method , the one for int parameters : lame_set_parameter_int(lama_global_flags *lame_struct,...) { va_list args; LAME_TAG_TYPE current_tag; va_start(args); current_tag = va_arg(args,LAME_TAG_TYPE); while(current_tag != LAME_TAG_END ) { switch(current_tag) { case LAME_SET_SAMPLING_FREQ : lame_struct.samp_freq = va_arg(args,int); break; case LAME_SET_NR_CHAN :lame_struct.nr_channels = va_arg(args,int); break; /* some other integer parameters */ } current_tag = va_arg(args,LAME_TAG_TYPE); } va_end(args); } the "unified function version : lame_set_parameters(lama_global_flags *lame_struct,...) { va_list args; LAME_TAG_TYPE current_tag; va_start(args); current_tag = va_arg(args,LAME_TAG_TYPE); while(current_tag != LAME_TAG_END ) { switch(current_tag) { case LAME_SET_SAMPLING_FREQ : lame_struct.samp_freq = va_arg(args,int); break; case LAME_SET_NR_CHAN : lame_struct.nr_channels = va_arg(args,int); break; case LAME_FILTER_WIDTH : lame_struct.filter_width = va_arg(args,float); break; /* some other integer, string or float or whatever parameters */ } current_tag = va_arg(args,LAME_TAG_TYPE); } va_end(args); } -- David Balazic -- "Be excellent to each other." - Bill & Ted - - - - - - - - - - - - - - - - - - - - - - -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] ieee754 hack and 3.87
> "G" == Gabriel Bouvigne <[EMAIL PROTECTED]> writes: G> With VC6 I got: G> warning C4307: '*' : integral constant overflow Sun's CC(Workshop 4.2) on Solaris 2.6 says same warning, but the binary runs fine. --- Takehiro TOMINAGA // may the source be with you! -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] TagItem issues...
>> o main.c can't hold lame_global_flags, change lame_init() to allocate and >> return a pointer to lame_global_flags. >> o Move lame_global_flags out of lame.h, it should never be accessed >> externally. >I think we have to keep the old interface, since several applications >use it. So lame_global_flags will still have to be instantiated by the >calling program and exposed to the calling program. I dont think this >is incompatiable with a shared library? Yes, it is, because the structure itself can expand and change at any given time internally, and if it's allocated and/or changed externally it will most surely get corrupted by any program using a different version of the structure than the library itself... - CISC -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] TagItem issues...
>IIRC, if you use varargs then the compiler can't detect if the supplied >parameters >are of wrong type. Example : [...] >The compiler won't notice that the parameter is of wrong type >and when the function will try to extract an int from the stack, >it will get garbage. This is indeed true, and that's why I chose to divide the function in 3 to clarify this to the user. >But if this is of no concern , then a simpler interface can be used : [...] >LAME_END_MARKER informs the lame_set_parameters to stop reading values, >as AFAIK This is exactly how my current interface works (based on TagItems when passed on stack). >there is not other way to determine whether all the args has been read >the __FLOAT and __INT attachments are there only to help illustrate my >idea, >but could be helpful in the actual implementation too Yes, but this still requires the parameters to be correct, and parsing gets abit more messy... - CISC -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
[MP3 ENCODER] ieee754 hack and 3.87
With VC6 I got: D:\Prog\lame\quantize_pvt.c(932) : warning C4307: '*' : integral constant overflow D:\Prog\lame\quantize_pvt.c(933) : warning C4307: '*' : integral constant overflow D:\Prog\lame\quantize_pvt.c(934) : warning C4307: '*' : integral constant overflow D:\Prog\lame\quantize_pvt.c(935) : warning C4307: '*' : integral constant overflow Regards, -- Gabriel Bouvigne - France [EMAIL PROTECTED] mobile phone: [EMAIL PROTECTED] icq: 12138873 MP3' Tech: www.mp3-tech.org -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
[MP3 ENCODER] 3.87 doc
Here is the 3.87 html doc. Some files of the old doc are now useless Regards, -- Gabriel Bouvigne - France [EMAIL PROTECTED] mobile phone: [EMAIL PROTECTED] icq: 12138873 MP3' Tech: www.mp3-tech.org html.zip
Re: [MP3 ENCODER] intensity (was: Miscellaneous MP3 questions)
> Yes, this is how the decoder figures out the break between M/S or L/R and > intensity. But how does the encoder decide where to put the break? Clearly > it is a tradeoff between quality and bit usage. A naive algorithm would > exhaustively try all 13 or 21 possibilities for intensity start bands and > choose the one which had the highest quality/lowest bit usage (reconciling > the two is clearly a problem), but this seems prohibitively computationally > intensive... > > I'm wondering if anyone knows of a less naive approach. > Here is what I think: First of all, I would encode each time m/s instead of l/r, as (if I'm not wrong) the middle channel can be used for the intensity encoding by just dropping the side. Humans are less sensitives to the direction of the sound at both extremities of the audible freqs. So I'd start by encoding in i mode the first subband (like in triphonic systems), and after reducing to i mode starting from the latest band (22th) down to a given freq, according to the number of bits you need to save. According to the DTS whitepaper you can go down to 3-4kHz. But it's perhaps a little too simplist. Regards, -- Gabriel Bouvigne - France [EMAIL PROTECTED] mobile phone: [EMAIL PROTECTED] icq: 12138873 MP3' Tech: www.mp3-tech.org -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] TagItem issues...
> "R" == Robert Hegemann <[EMAIL PROTECTED]> writes: R> Mark Taylor schrieb am Die, 26 Sep 2000: >> I think we have to keep the old interface, since several >> applications use it. So lame_global_flags will still have to >> be instantiated by the calling program and exposed to the >> calling program. I dont think this is incompatiable with a >> shared library? >> >> Mark R> Doing so would require to recompile every client if we add an R> entry in lame_global_flags, even if the client will not care R> about the new entry. Yes, That is the most heavy problem. even worse, changing compiler or compiler option will make it require to recompile every client. R> The client shouldn't know about internal data structures. So, R> doing as Frank previously suggested would be OK. I agree, too. --- Takehiro TOMINAGA // may the source be with you! -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] TagItem issues...
Sigbjřrn Skjćret wrote: > > >> >This way there is no need to parse any strings, we don't pass > >> >any pointers, the setup routine would just be a big switch/case. > >> This is basically the way TagItems work when passed on stack, in fact, that > >> combined with another identical function that does float we're pretty much > >> set. > > Why do we need float at this point ?? > > Because several of the parsed arguments are floats? > > Well, anyway, I just finished up the following: > > /* Set a parameter with string-pointer */ > void lame_set_string(lame_global_flags *gfp, lame_param_tag tag1, ...); > > /* Set a parameter with float or double value (varargs promotes floats to double) */ > void lame_set_float(lame_global_flags *gfp, lame_param_tag tag1, ...); > > /* Set a parameter with char, short or int value (varargs promotes integrals to int) >*/ > void lame_set_int(lame_global_flags *gfp, lame_param_tag tag1, ...); IIRC, if you use varargs then the compiler can't detect if the supplied parameters are of wrong type. Example : /* sample freq is an int , but be supply a float */ lame_set_int(gfp, LAME_SAMP_FREQ, 44101.213 ); The compiler won't notice that the parameter is of wrong type and when the function will try to extract an int from the stack, it will get garbage. But if this is of no concern , then a simpler interface can be used : lame_set_parameters(lame_global_flags *gfp, ...); /* or this one , as the type of the first argument is always the same */ lame_set_parameters(lame_global_flags *gfp, lame_param_tag tag1, ...); /* Usage : lame_set_parameters(gfp, LAME_SAMP_FREQ__INT, 44100 , LAME_NR_CHANNELS__INT , 2 , LAME_LOW_PASS_VALUE__FLOAT , 16.050 , LAME_LOW_PASS_WIDTH__FLOAT , 0.75, LAME_COMMENT__STRING , "This is cool" , LAME_END_MARKER); LAME_END_MARKER informs the lame_set_parameters to stop reading values, as AFAIK there is not other way to determine whether all the args has been read the __FLOAT and __INT attachments are there only to help illustrate my idea, but could be helpful in the actual implementation too */ > This can cater for any kind of parameter, and the functions themselves are > very simple, yet can take several parameters in a row... > > Should I start implementing this now, or wait after 3.87 release? > > Mark? > > What needs to be changed to make a real shared library: > > o Exchange all direct access to lame_global_flags in parse.c with calls to > lame_set_xxx(). > > o main.c can't hold lame_global_flags, change lame_init() to allocate and > return a pointer to lame_global_flags. > > o Move lame_global_flags out of lame.h, it should never be accessed externally. > > o ..and any other changes still needed for re-entrance ofcos. > > - CISC > > -- > MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ ) -- David Balazic -- "Be excellent to each other." - Bill & Ted - - - - - - - - - - - - - - - - - - - - - - -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] Free format
:: :: another thing that does not work: :: :: lame -b640 --freeformat -g fatboy.wav fatboy.mp3 :: fatal error. MAXFRAMESIZE not large enough. :: :: in mpg123.h MAXFRAMESIZE is defined as 1792, but a 32 kHz 640 kps MP3 :: consists of 2880 bytes per frame (2090 at 44.1 kHz, 1920 at 48 kHz). :: Changing this seems to trigger another BUG somewhere: :: LAME stops with: Only 8 and 16 bit input files supported :: :: 1792*8 = 14336 bits, :: 1920*8 = 15360 bits, :: 2090*8 = 16720 bits, more than 32767/2, reason for BUG? :: 2880*8 = 23040 bits, more than 32767/2, reason for BUG? :: :: I haven't looked deeper at this, I had no time yet :-(. :: test this also with --noshort. --decoder crashs on larger data rates and --noshort. -- Mit freundlichen Grüßen Frank Klemm eMail | [EMAIL PROTECTED] home: [EMAIL PROTECTED] phone | +49 (3641) 64-2721home: +49 (3641) 390545 sMail | R.-Breitscheid-Str. 43, 07747 Jena, Germany -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] Some suggestions for LAME - please review
Hi Mark, :: A couple of comments/questions: :: > :: > :: Also, every transition from two different size windows is lossy. The :: > :: MDCT is only lossless for overlapping windows of the same size. :: > :: :: > Is this a problem of bad designed (asymmetric) window functions or a :: > problem of the MDCT (different from DCT). :: > :: :: It is a problem with all lapped transforms (like the MDCT). :: You need at least a 50% overlap to get a lossless transform. :: In AAC, a 1024 frame followed by a 128 frame, the 128 frame :: will use a window of size 256, so it only extends 64 samples into :: the 1024 frame. :: I've tested a (slow stupid)FT transform based system with randomly switching window size and had only rounding errors. The signal is devided into arbitrary blocks. Every FFT blocks uses two of these blocks uses two (often different) cos² functions for cross fading. The blocks are cosine transformed. When I have time, I will test this again (I'm not so familar with the DCT, I'm only familar with LTI, FT, zT, LT is also a little bit more difficult). :: > 4. The prefilter has a extremly short size of 4 or 5 TAPs, which is :: >far below 128, 192, 576, or 1024. :: > :: > :: If this is true, then the 1024 FFT should have plenty of frequency :: resolution and the prefilter can be easily implimented via the FFT :: coefficients. So no need for a new filter? :: 1. FFT filters are strictly speaking no filters (they are not a LTI system), so they have some nasty properties, which are more or less audible. The audibility depends on the steepness of the filter. So high passes should never be made by FFT filters. Never ever. Filter flanks modulating the signal, a property LTI systems NEVER have. May be also low pass filter are a bad idea. For high pass filters I'm absolutely sure. 2. FFT filters approximating non recursive filter (often called FIR filters, which is not correct), but actually they are a mixture of a frequency dependent modulator and a filter. Non recursive filters are only a very special class of filters. All LTI filtering is done by: A B y(n) := Sum a(i) x(n-i) - Sum b(i) y(n-i) i=0 i=1 Every Filter can be characterized by the a(0...A) and b(1...B). For non recursive filters is B=0 and A>=0 (also called moving average filters), for absolute phase filters is A=0 and B>0 (also called auto regression filter). Filters with B>0 and A>0 are mixing both base vectors of filters and are also called auto regression moving average filters. You can divide ever (LTI) filter into two filters, a MA and a AR filter: A v(n) := Sum a(i) x(n-i) i=0 B y(n) := v(n) - Sum b(i) y(n-i) i=1 Now you can set b(0):=1 A v(n) := Sum a(i) x(n-i) i=0 B v(n) := Sum b(i) y(n-i) i=0 This gives (x,y,z complex, O is a big omega and omega/fs, j is sqrt(-1) ) A v(w)/x(w) = Sum a(i) exp (jOi/fs) i=0 B v(w)/y(w) = Sum b(i) exp (jOi/fs) i=0 Substituting exp(jO/fs) = z gives Ai v/x = Sum a(i) z i=0 Bi v/y = Sum b(i) z i=0 and Ai Sum a(i) z i=0 y/x = --- Bi Sum b(i) z i=0 So you can see: MA = P_A(z), AR = 1/Q_B(z) and ARMA = P_A(z)/Q_B(z). Example: The easiest AR filter, a integrator (1st order) can only be programmed by a infinite long MA filter. Are polyphase filters LTI systems? FFT filters aren't. And they are comparable with the subset of MA filters. -- Mit freundlichen Grüßen Frank Klemm eMail | [EMAIL PROTECTED] home: [EMAIL PROTECTED] phone | +49 (3641) 64-2721home: +49 (3641) 390545 sMail | R.-Breitscheid-Str. 43, 07747 Jena, Germany -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] TagItem issues...
:: Sigbjørn Skjæret schrieb am Die, 26 Sep 2000: :: > > Why do we need float at this point ?? :: > :: > Because several of the parsed arguments are floats? :: :: ie. frequencies could be passed in Hertz as ints, :: was just something to think about now while we :: change the API anyway :: What about not integer value sampling frequencies? For stand alone audio rounding is no problem. But for audio/video and unbuffered streaming this may produce really unnecessary problems. For instance AIFF stores sampling frequency as 80 bit-IEEE-754 long double. Avoid problems instead of patching the results of this problems. -- Mit freundlichen Grüßen Frank Klemm eMail | [EMAIL PROTECTED] home: [EMAIL PROTECTED] phone | +49 (3641) 64-2721home: +49 (3641) 390545 sMail | R.-Breitscheid-Str. 43, 07747 Jena, Germany -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
[MP3 ENCODER] Mp3 Programmers Needed
I am looking to hire one or more mp3 programmers for a large and extremely interesting project. The programmers must be very familar with one of the existing cross platform open source players (like Xaudio or mpg123) and have lots of experience with Mpeg player technology. We will be working with the data as it is read in frame by frame and I need people who can handle this. You'll be able to work from home (wherever that might be) and work full or part-time. The first phase of the project will last two months and will be immediately followed by on-going development. Let me know if you're interested. Steve Wolk CEO StartIT2000 310 434-1198 (Direct) e-mail: [EMAIL PROTECTED] -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] TagItem issues...
Mark Taylor schrieb am Die, 26 Sep 2000: > I think we have to keep the old interface, since several applications > use it. So lame_global_flags will still have to be instantiated by the > calling program and exposed to the calling program. I dont think this > is incompatiable with a shared library? > > Mark Doing so would require to recompile every client if we add an entry in lame_global_flags, even if the client will not care about the new entry. The client shouldn't know about internal data structures. So, doing as Frank previously suggested would be OK. Ciao Robert -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] Free format
> > I'm not surprised, considering you are probably only the 3rd > > person to ever use freeformat :-) > > first is Mark, who is the second person? Not the second, but, I find free-format *really* useful. However, I am using it for very *low* bitrates. ie: 8 to 32. Owen -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
RE: [MP3 ENCODER] realtime encoding specs ?
Title: RE: [MP3 ENCODER] realtime encoding specs ? Mark Powell wrote: > That was with the options: > > -V1 -b128 -mj -h > > under FreeBSD. It wasn't a competition I was just giving him some > empirical evidence to work with :) My reults were based on -V4 -b32 -mj -h Ross.
RE: [MP3 ENCODER] Miscellaneous MP3 questions
Howdy Robert, Thanks for the quick response. > > 2) In layer-II coding, the first band to code using > intensity is specified > > by the mode extension - in layer-III it can by dynamically > varied and is > > understood implicitly from the bitstream by the decoder. > But the spec gives > > no suggestions for algorithms on where to begin using > intensity. (I used a > > fixed #define.) Does anyone have a reference on this? > (Exhaustive search > > is not really an option?) > > If I understand the DOCs right, then in IS mode, starting at > lower frequency bands, the last right channel scalefactor band > not completely zero marks the last MS or LR coded band. > All bands > above are intensity stereo coded, magnitudes in left channel, > position in right channel. Bands with illegal intensity position > have to be MS or LR decoded. Yes, this is how the decoder figures out the break between M/S or L/R and intensity. But how does the encoder decide where to put the break? Clearly it is a tradeoff between quality and bit usage. A naive algorithm would exhaustively try all 13 or 21 possibilities for intensity start bands and choose the one which had the highest quality/lowest bit usage (reconciling the two is clearly a problem), but this seems prohibitively computationally intensive... I'm wondering if anyone knows of a less naive approach. Thanks, Alex -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )