On Apr 21, 2007, at 3:53 PM, zmorris@mac.com wrote:> On Apr 21, 2007, at 12:36 PM, zmorris@mac.com wrote: > >> Hi, I tried both the stable and beta versions of the speex source >> code download on Mac OS 10.4.9. I just do: >> >> ... >> >> However, when I play the output file, I get the header and a >> second of audio, but the rest is just noise. > > I figured it out, the problem is that WAV files are little endian > and I am on powerpc, so the sample byte order must be swapped. > That still isn't the whole story, and I will explain how it's still > not working, but first you need to update your example at:OK I finally figured out the second noise problem. It's a riddle wrapped in a mystery inside an enigma. Judging by the somewhat odd structure of le_short() and be_short(), I think this keeps coming up over and over again. Even Apple's byte swapping macros fail under certain circumstances, and here's why: 1. Logical shifting must be used, not arithmetic (or else the high bit is wrong) 2. Conversion from short to float must be signed, not unsigned (or else the line level is wrong) 3. The order of operations must be written just-so, or gcc stumbles over the conversion from short to float The offending line was this one: for (i=0;i<FRAME_SIZE;i++) input[i] = le_short( in[i] ); This always fails with the current le_short() function. Here are updated versions, in both macro and inline form. You can leave inline off of the function version and it still works fine: //////////////////////////////////////// /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #define WORDS_BIGENDIAN 1 #ifdef WORDS_BIGENDIAN #define le_short( s ) ((short) ((unsigned short) (s) << 8) | ((unsigned short) (s) >> 8)) #define be_short( s ) ((short) (s)) #else #define le_short( s ) ((short) (s)) #define be_short( s ) ((short) ((unsigned short) (s) << 8) | ((unsigned short) (s) >> 8)) #endif inline short le_short( unsigned short s ) { #ifdef WORDS_BIGENDIAN return( (s << 8) | (s >> 8) ); #endif return s; } inline short be_short( unsigned short s ) { #ifndef WORDS_BIGENDIAN return( (s << 8) | (s >> 8) ); #endif return s; } //////////////////////////////////////// Now I am sorry to rant a moment, but I am getting too old for this stuff. Whenever I am speaking with fellow programmers, they love to jump to the conclusion that the problem is mine and that there is nothing wrong with the code. I am experienced enough to know that there are multitudes of reasons why things fail and that yes, even vanilla code examples often fail. I tried your sample code and it didn't work, plain and simple. UNIX is like this through and through. Whenever I try something, I just know it won't work, like I knew this wouldn't work. The fault is almost never mine (at least not through incompetence, because I follow directions explicitly), but is cause by assumptions about the infrastructure by myself and others. For all its benefits, the unix mindset can easily condemn us to a life of servitude, baby sitting our computers instead of getting real work done. Anyway, I hope this series of emails shows the importance of providing full examples for the target environments. If you ever want speex to catch on in the mainstream, everyday people need to be able to drop it in, but at this point only hackers can really do that. I mean the kind of hackers willing to spend 2 days to fix 2 lines of code that should "just work." So I thank you from the bottom of my heart for making such a brilliant piece of software as speex, I really appreciate what you guys stand for :) I just hope that you get some time to step back and polish up the sample code and manual just a hair. I know how it goes when you have to spend all of your time on development to keep something even just working, so this rant is not directed at anyone in particular :) --Zack
On Apr 21, 2007, at 5:49 PM, zmorris@mac.com wrote:> On Apr 21, 2007, at 3:53 PM, zmorris@mac.com wrote: > >> On Apr 21, 2007, at 12:36 PM, zmorris@mac.com wrote: >> >>> Hi, I tried both the stable and beta versions of the speex source >>> code download on Mac OS 10.4.9. I just do: >>> >>> ... >>> >>> However, when I play the output file, I get the header and a >>> second of audio, but the rest is just noise. >> >> I figured it out, the problem is that WAV files are little endian >> and I am on powerpc, so the sample byte order must be swapped. >> That still isn't the whole story, and I will explain how it's >> still not working, but first you need to update your example at: > > OK I finally figured out the second noise problem. It's a riddle > wrapped in a mystery inside an enigma. Judging by the somewhat odd > structure of le_short() and be_short(), I think this keeps coming > up over and over again. Even Apple's byte swapping macros fail > under certain circumstances, and here's why:Hi all, sorry my messages came out of order. I believe the order went 2-3-1. I don't know if there is something wrong with my mac.com account, or the xiph list server, but I got several "message couldn't be delivered for..." warnings. Anyway, I got all of the endian issues sorted out and have a codewarrior and xcode project if you are interested in adding a mac example alongside the speex download. I also have a codewarrior project to create a speex bundle and make a CFM lib with glue code, to access it from carbon. Codewarrior is a dead IDE, but several of us mac users still prefer prototyping in it vs. xcode. I've never really contributed to an open source project so don't know how to go about it. Thanx, ------------------------------------------------------------------------ Zack Morris Z Sculpt Entertainment This Space zmorris@zsculpt.com http://www.zsculpt.com For Rent ------------------------------------------------------------------------ If the doors of perception were cleansed, everything would appear to man as it is, infinite. -William Blake, The Marriage of Heaven and Hell
> OK I finally figured out the second noise problem. It's a riddle > wrapped in a mystery inside an enigma. Judging by the somewhat odd > structure of le_short() and be_short(), I think this keeps coming up > over and over again. Even Apple's byte swapping macros fail under > certain circumstances, and here's why:Funny thing is you seem to be the first to report that... not quite sure why.> 1. Logical shifting must be used, not arithmetic (or else the high bit > is wrong)So far so good.> 2. Conversion from short to float must be signed, not unsigned (or else > the line level is wrong)Seems like there was a problem there and I ended up with a +32768 offset -- not good.> 3. The order of operations must be written just-so, or gcc stumbles over > the conversion from short to floatwhat do you mean here?> The offending line was this one: > > for (i=0;i<FRAME_SIZE;i++) > input[i] = le_short( in[i] ); > > This always fails with the current le_short() function. Here are > updated versions, in both macro and inline form. You can leave inline > off of the function version and it still works fine:<snip> I'll fix that for the next release (hopefully soon).> Now I am sorry to rant a moment, but I am getting too old for this > stuff. Whenever I am speaking with fellow programmers, they love to > jump to the conclusion that the problem is mine and that there is > nothing wrong with the code. I am experienced enough to know that there > are multitudes of reasons why things fail and that yes, even vanilla > code examples often fail. I tried your sample code and it didn't work, > plain and simple.Well, it didn't work on big-endian machines and I happen not to have any such machine, which is why I rely on bug reports for these architectures. As for which code to blame, my experience with Speex is that 95% of the problems are with code using Speex and not with the Speex code (I'm not going into the reason why code is broken).> UNIX is like this through and through. Whenever I try something, I just > know it won't work, like I knew this wouldn't work. The fault is almost > never mine (at least not through incompetence, because I follow > directions explicitly), but is cause by assumptions about the > infrastructure by myself and others. For all its benefits, the unix > mindset can easily condemn us to a life of servitude, baby sitting our > computers instead of getting real work done.I guess you could always switch to this Windows OS people keep talking about. I've never really used it, but everyone keeps saying lots of nice things about it ;-)> Anyway, I hope this series of emails shows the importance of providing > full examples for the target environments. If you ever want speex to > catch on in the mainstream, everyday people need to be able to drop it > in, but at this point only hackers can really do that. I mean the kind > of hackers willing to spend 2 days to fix 2 lines of code that should > "just work."All I can say is "shit happens" (and endianness bugs too). However, most people who know what they're doing (e.g. don't attempt to pass u-law instead of floats to get 4x the compression) usually get Speex working rather quickly.> So I thank you from the bottom of my heart for making such a brilliant > piece of software as speex, I really appreciate what you guys stand for > :) I just hope that you get some time to step back and polish up the > sample code and manual just a hair. I know how it goes when you have to > spend all of your time on development to keep something even just > working, so this rant is not directed at anyone in particular :)What kind of polish to the sample code. Can you send a patch? Jean-Marc
> Funny thing is you seem to be the first to report > that... not quite sure > why. >it's true, I had the same problem with MACOSX trying to use Speex AEC, but than I realized it's Endianess and switched to my Intel based Linux box. so I can help to you both to test fixes/patche on my macosx build environment too. just let me know, when SVN will have them. thanks Oleg