Using any of the ebuilds from the Portage tree in a MIPS32 embedded processor produces noise in every application using libmad. Changing ebuild to use --enable-speed instead of --enable-accuracy instead solves this problem. I am running Gentoo on a Ben NanoNote running MIPS32r1-based embedded SoC. I verified that decoding is broken via qemu-mipsel and raw audio file output, so this is not a hardware issue. Minor point: --enable-speed option should also be accessible via use flag(s), so that resource limited embedded systems could benefit from it. Reproducible: Always Steps to Reproduce: 1. Get a Gentoo system installed in a MIPS32 machine 2. emerge libmad madplay 3. madplay some-audio.mp3 Actual Results: Annoying noise plays out. Expected Results: MP3 audio files should play properly, without noise.
I forgot, both madplay and mpg321 have -mips keyword set, so I had to change that to have them emerged. After building libmad with --enable-speed both players worked just fine. I'm not sure if broken libmad was the reason they got masked, but I verified that both players do work on mips when libmad issue is dealt with by --enable-speed workaround. Changelog on mpg321 says: 15 Apr 2005; Stephen P. Becker <geoman@gentoo.org> mpg321-0.2.10-r1.ebuild, mpg321-0.2.10-r2.ebuild: changed to -mips until mad issues are worked out
From libmad's configure, I see --enable-speed optimize for speed over accuracy --enable-accuracy optimize for accuracy over speed --enable-fpm=ARCH use ARCH-specific fixed-point math routines (one of: intel, arm, mips, sparc, ppc, 64bit, default) but in the ebuild, we have # Fix for b0rked sound on sparc64 (maybe also sparc32?) # default/approx is also possible, uses less cpu but sounds worse use sparc && myconf="${myconf} --enable-fpm=64bit" [[ $(tc-arch) == "amd64" ]] && myconf="${myconf} --enable-fpm=64bit" [[ $(tc-arch) == "x86" ]] && myconf="${myconf} --enable-fpm=intel" [[ $(tc-arch) == "ppc" ]] && myconf="${myconf} --enable-fpm=ppc" [[ $(tc-arch) == "ppc64" ]] && myconf="${myconf} --enable-fpm=64bit" Can you try adding a line like [[ $(tc-arch) == "mips" ]] && myconf="${myconf} --enable-fpm=mips" to the ebuild and see if it makes a difference? You might have to check for 'mipsel' instead of mips, I don't really know. I suspect this will fix it.
(In reply to comment #2) > but in the ebuild, we have > > # Fix for b0rked sound on sparc64 (maybe also sparc32?) > # default/approx is also possible, uses less cpu but sounds worse > use sparc && myconf="${myconf} --enable-fpm=64bit" > > [[ $(tc-arch) == "amd64" ]] && myconf="${myconf} --enable-fpm=64bit" > [[ $(tc-arch) == "x86" ]] && myconf="${myconf} --enable-fpm=intel" > [[ $(tc-arch) == "ppc" ]] && myconf="${myconf} --enable-fpm=ppc" > [[ $(tc-arch) == "ppc64" ]] && myconf="${myconf} --enable-fpm=64bit" > > Can you try adding a line like > > [[ $(tc-arch) == "mips" ]] && myconf="${myconf} --enable-fpm=mips" > > to the ebuild and see if it makes a difference? You might have to check for > 'mipsel' instead of mips, I don't really know. > > I suspect this will fix it. Tried that, nothing changes. In fact, these ebuild lines are redundant, because configure.ac does the following: AC_ARG_ENABLE(fpm, AC_HELP_STRING([--enable-fpm=ARCH], [use ARCH-specific fixed-point math routines (one of: intel, arm, mips, sparc, ppc, 64bit, default)]), [ case "$enableval" in yes) ;; no|default|approx) FPM="DEFAULT" ;; intel|i?86) FPM="INTEL" ;; arm) FPM="ARM" ;; mips) FPM="MIPS" ;; sparc) FPM="SPARC" ;; ppc|powerpc) FPM="PPC" ;; 64bit) FPM="64BIT" ;; float) FPM="FLOAT" ;; *) AC_MSG_RESULT(failed) AC_MSG_ERROR([bad --enable-fpm option]) ;; esac ]) if test -z "$FPM" && test "$GCC" = yes then case "$host" in i?86-*) FPM="INTEL" ;; arm*-*) FPM="ARM" ;; mips*-*) FPM="MIPS" ;; sparc*-*) FPM="SPARC" ;; powerpc*-*) FPM="PPC" ;; # FIXME: need to test for 64-bit long long... esac fi AC_MSG_RESULT(${FPM=DEFAULT}) Configure message and -DFPM_MIPS flag how that it's correctly detected without --enable-fpm. Disabling --enable-accuracy fixes broken sound. I suggest adding accuracy use flag, enabling it by default and masking on MIPS. Maybe someone will want to trade accuracy for speed, because redundant CPU cycles mean shorter battery life and there may be no real benefit from 64-bit fixed point precision except some rare corner cases and standard compliance.
sound@, can you add an accuracy USE flag that's on by default? Once it's in place, I'll mask it on MIPS until I can figure out why it causes problems.
(In reply to comment #4) > sound@, can you add an accuracy USE flag that's on by default? No. Why? The ebuild already enables accuracy by default. > Once it's in place, I'll mask it on MIPS until I can figure out why it causes > problems. Feel free to add line like [[ $(tc-arch) == "mips" ]] && myconf="${myconf} --disable-accuracy" if you think that's needed for your arch...
(In reply to comment #5) > (In reply to comment #4) > > sound@, can you add an accuracy USE flag that's on by default? > > No. Why? The ebuild already enables accuracy by default. From comment 3: Disabling --enable-accuracy fixes broken sound. I suggest adding accuracy use flag, enabling it by default and masking on MIPS. Maybe someone will want to trade accuracy for speed, because redundant CPU cycles mean shorter battery life and there may be no real benefit from 64-bit fixed point precision except some rare corner cases and standard compliance. You don't think this is worthwhile?
(In reply to comment #5) > (In reply to comment #4) > > sound@, can you add an accuracy USE flag that's on by default? > > No. Why? The ebuild already enables accuracy by default. So, perhaps you misunderstood my intention... Let's add an accuracy flag (that's switched on by default, since that's the current behavior of the ebuild). This would allow people to, for whatever reason, disable accuracy in favor of speed, as explained two other places in this bug report. It would also allow us (mips) to work around this stupid bug by masking the flag, which seems like a much less distasteful workaround than what you suggested. Do you really, seriously, have an objection to adding an accuracy flag?
Alright, I'll just commit my proposed change in a week or two if no one objects.
(In reply to comment #7) > Do you really, seriously, have an objection to adding an accuracy flag? Yes, because the package has long history of breaking in different ways depending on endianess, bits, and arch. By adding a USE flag for this, you'd be re-exposing already handled bugs Just make the change mips specific, no USE flag
Sergey, could you try the patch here: http://git.overlays.gentoo.org/gitweb/?p=proj/loongson.git;a=blob;f=media-libs/libmad/files/libmad-gcc4.4.patch;h=b768218825ad9cb71b0a239f6192f50a3f630dc6;hb=HEAD and let me know if it fixes the problem?
(In reply to comment #10) > Sergey, > > could you try the patch here: > > http://git.overlays.gentoo.org/gitweb/?p=proj/loongson.git;a=blob;f=media-libs/libmad/files/libmad-gcc4.4.patch;h=b768218825ad9cb71b0a239f6192f50a3f630dc6;hb=HEAD > > and let me know if it fixes the problem? Actually, that patch is bogus. Ignore this. Sigh.
Sergey: I tested madplay and mpg321 with libmad built with fpm={64bit,mips,default} and couldn't get anything but good sound. I decoded mp3s to wav and played them back on another system with a sound card and speakers. This is also on a big-endian/n32 system. To decode a long mp3 (Free Bird), the different fpm values took different amounts of time: real/user (seconds) 64-bit mpg321 : 19.5/18.6 64-bit madplay : 18.2/17.2 mips mpg321 : 22.6/21.8 mips madplay : 21.3/20.3 default mpg321 : 15.6/14.7 default madplay: 14.4/13.3 All of them produced good sound. So, what's the difference? ABI, endianness, fpm value? Since you're on MIPS32, you've got an O32 ABI, and little-endian byte order. Can you try other fpm values to see if some work and another doesn't?
> So, what's the difference? ABI, endianness, fpm value? Since you're on MIPS32, you've got an O32 ABI, and little-endian byte order. > Can you try other fpm values to see if some work and another doesn't? Have you specified --enable-accuracy in your build? Vanilla source defaults to --enable-speed, while gentoo ebuild always specifies --enable-accuracy. AFAIR every fpm={64bit,mips,default} worked without --enable-accuracy, while 64bit and mips failed with it. I don't remember the rest, so I'll retest it some time soon. > So, what's the difference? ABI, endianness, fpm value? Since you're on MIPS32, you've got an O32 ABI, and little-endian byte order. Yes, it's O32 little-endian softfloat target. I'm using uclibc-0.9.30 btw. jz4720 used in NanoNote MIPS32r1 compatible, and it supports most of MIPS32r2, but not everything. But qemu-mipsel fails to decode correctly too, so the chip is probably not to blame. Maybe --enable-accuracy never worked on little-endian mipses, since libmad has become unmaintained before embedded mips32 became widespread. The big desktop MIPS has always used big-endian, didn't it?
(In reply to comment #13) > AFAIR every fpm={64bit,mips,default} worked without --enable-accuracy, while > 64bit and mips failed with it. I don't remember the rest, so I'll retest it > some time soon. Sounds good. When you do, see if decoding to WAV and then playing back the WAV gives different results than playing back the mp3 directly. > Yes, it's O32 little-endian softfloat target. I'm using uclibc-0.9.30 btw. > jz4720 used in NanoNote MIPS32r1 compatible, and it supports most of MIPS32r2, > but not everything. But qemu-mipsel fails to decode correctly too, so the chip > is probably not to blame. Maybe --enable-accuracy never worked on little-endian > mipses, since libmad has become unmaintained before embedded mips32 became > widespread. The big desktop MIPS has always used big-endian, didn't it? All the SGI MIPS systems were indeed big-endian. I have a loongson laptop that I've been meaning to set up for a while, so I should be able to test with that -- or with this Broadcom system when I get the chance to rebuild its little-endian installation.
I tried with my Broadcom system in little-endian mode. Also unable to reproduce.
Although I don't use gentoo, on a n32 fuloong (loongson2f), for me lame and mpg123 fail to decode properly to WAV. Playing WAV files works fine. Both lame and mpg123 make a noise, but it's different. The first signed16 samples of the mp3 file I test should be zero values (when properly decoded). In these programs, instead, they give sequences like this: lame: ------- fffd fffd fffd fffd fffc fffc fffc fffc ... ... 8000 8000 8000 8000 8000 8000 8000 8000 ... ------- mpg123: ------- 0000 0000 0001 0000 0001 0000 0001 0001 .... 0000 0000 0000 0000 ff96 ff96 ff93 ff94 ... -------- In mpg321 (with libmad), all works fine.
Just to test, my lame was built with "-O3 -ffast-math -fomit-frame-pointer". I changed it to "-O2", and then it decoded properly. Same with "-O3". I'd guess it has to do with "-ffast-math" being somehow broken. I'm using gcc 4.6.3.