[Speex-dev] Re: just noise

zmorris at mac.com zmorris at mac.com
Sat Apr 21 16:49:45 PDT 2007


On Apr 21, 2007, at 3:53 PM, zmorris at mac.com wrote:

> On Apr 21, 2007, at 12:36 PM, zmorris at 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


More information about the Speex-dev mailing list