[Speex-dev] Re: just noise
zmorris at mac.com
zmorris at mac.com
Sat Apr 21 14:53:04 PDT 2007
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:
http://www.speex.org/docs/manual/speex-manual/
node13.html#SECTION000131000000000000000
To say something along the lines of "when using the example with WAV
files on a big endian architecture like powerpc, you must swap the
byte order of the samples with the following code:"
////////////////////////////////////////
/* 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
unsigned short be_short(unsigned short s)
{
unsigned short ret=s;
#ifndef WORDS_BIGENDIAN
ret = s>>8;
ret += s<<8;
#endif
return ret;
}
unsigned short le_short(unsigned short s)
{
unsigned short ret=s;
#ifdef WORDS_BIGENDIAN
ret = s>>8;
ret += s<<8;
#endif
return ret;
}
////////////////////////////////////////
These functions should really be inline or macros, and I believe the
| operator is faster than + on RISC because it can be executed faster
alongside << and >> in the pipeline but I could be wrong. Then you
need to change the 2 lines that convert the samples to floats to say:
////////////////////////////////////////
/*Copy the 16 bits values to float so Speex can work on them*/
for (i=0;i<FRAME_SIZE;i++)
input[i] = le_short( in[i] );
/*Copy from float to short (16 bits) for output*/
for (i=0;i<FRAME_SIZE;i++)
out[i] = le_short( output[i] );
////////////////////////////////////////
Also, endian issues are so important that they need to be discussed
in the manual more. You should probably mention:
#include <arpa/inet.h>
// from transmitting on network
ntohs()
htons()
from sockets, and:
#include <CoreFoundation/CFByteOrder.h>
// for import/export wav
CFSwapInt16LittleToHost()
CFSwapInt16HostToLittle()
// from transmitting on network
CFSwapInt16LittleToHost()
CFSwapInt16HostToLittle()
on Mac, right there on the example page. Also, please discuss the
format of the compressed bits from squeex, because it's not clear to
me if they are already big endian for sending over the network.
The real kicker is that after doing this, I am still getting noise!
I can make out the voice but it sounds 50% noisy now, and it's not
the minimal noise that is always present. This is full-blown-every-
other-sample-is-wrong noise.
To trace it to this point, I downloaded and installed libogg from:
http://xiph.org/downloads/
so that I could use speexenc and speexdec from the console, which
worked perfectly. Then I traced it back to where it was reading
samples and found the endian conversion. I will have to backtrack
even further now to find out exactly why my test still isn't working,
and it is becoming quite a waste of time. I've lost 2 days to this
so far and it's looking like that might become 3. This is all with
1.2beta1 so I will try 1.0.5 and see if it fixes the noise problem.
One way around all of this is to include more projects and not just
focus on win32. An xcode project showing the example would be a good
start. Adding a few lines to handle the WAV header would be ideal.
--Zack
More information about the Speex-dev
mailing list