[Speex-dev] voice sound like robot voice :)

Tim Rijavec rico at gama.us
Wed Sep 2 07:44:04 PDT 2009


hy,

here is my speex encoder/decoder .. the sampleRate i use is 16000 and
quality,complexity are at 5.

can someone take a look in to the code and see if there is something that is
making that robot voice

here is a link to colored and numbered code, same as below
http://barvanjekode.gama.us/temp/1257361243.html

thanx.

code
-----------------------
#include "codec.h"

/////////////////////////////////////////////////////////////////
// Constants
/////////////////////////////////////////////////////////////////
#define Cvoicecodecrawbuffersize       16 * Ckilobyte

/////////////////////////////////////////////////////////////////
//
// TVoiceCodec
//
/////////////////////////////////////////////////////////////////
TVoiceCodec::TVoiceCodec() :
pMode( NULL ),
pPreprocessorState( NULL ),
pCodecEncoderState( NULL ),
encoderQuality( 5 ),
encoderComplexity( 3 ),
encoderFrameSize( 0 ),
encodedFrameBytes( 0 ),
pCodecDecoderState( NULL ),
sampleRate( VOICE_SAMPLE_RATE ),
decoderFrameSize( 0 )
{
   /////////////////////////////////////////////////////////////////
   // Prepare buffers
   /////////////////////////////////////////////////////////////////
   uint voicememsize = Cvoicecodecrawbuffersize + CODEC_MAX_BUFFER_SIZE;
   byte *voicemem = (byte*)pMemoryMng->Alloc(voicememsize);
   memset( voicemem, 0, voicememsize );

   // raw voice input buffer
   pCodecRawBuffer = voicemem;
   pCodecRawBufferCur = pCodecRawBuffer;
   //
   voicemem += Cvoicecodecrawbuffersize;

   // input/output voice buffer
   pCodecBuffer = voicemem;
}


TVoiceCodec::~TVoiceCodec()
{
   if ( pCodecEncoderState )
   {
      speex_preprocess_state_destroy( pPreprocessorState );
      speex_encoder_destroy( pCodecEncoderState );
      speex_bits_destroy( &codecBits );
      pCodecEncoderState = NULL;
   }

   if ( pCodecDecoderState )
   {
      speex_decoder_destroy( pCodecDecoderState );
      speex_bits_destroy( &codecBits );
      pCodecDecoderState = NULL;
   }
}


void TVoiceCodec::setSampleRate( int samplerate )
{
   sampleRate = samplerate;

   // determine the mode
   int modeID = -1;

   // speex has limits [6000 - 48000]
   if ( sampleRate > 48000 )
      return;

   if ( sampleRate > 25000 )
      modeID = SPEEX_MODEID_UWB;
   else if ( sampleRate > 12500 )
      modeID = SPEEX_MODEID_WB;
   else if ( sampleRate >= 6000 )
      modeID = SPEEX_MODEID_NB;
   else
      return;

   // set up mode
   pMode = speex_lib_get_mode( modeID );
}

void TVoiceCodec::setupEncoder( uint quality, uint complexity  )
{
   encoderQuality = quality;
   encoderComplexity = complexity;

   // catch invalid sample rates resulting in invalid mode
   if ( !pMode )
      return;
   //
   assert( ( pCodecEncoderState == NULL ) && "encoder already initialized"
);
   //
   int enabled   = 1;
   int disabled  = 0;
   //
   float highpass = 80;

   // setup encoder
   pCodecEncoderState = speex_encoder_init( pMode );
   //
   speex_encoder_ctl( pCodecEncoderState, SPEEX_SET_SAMPLING_RATE,
&sampleRate );
   speex_encoder_ctl( pCodecEncoderState, SPEEX_SET_COMPLEXITY,
&encoderComplexity );
   speex_encoder_ctl( pCodecEncoderState, SPEEX_SET_QUALITY,
&encoderQuality );
   speex_encoder_ctl( pCodecEncoderState, SPEEX_SET_VBR,
&disabled );
   speex_encoder_ctl( pCodecEncoderState, SPEEX_SET_DTX,
&disabled );

   // init encoder
   speex_bits_init( &codecBits );
   speex_bits_reset( &codecBits );

   // determine encoded bytes per frame with spx_int16_t type, speex can
work with float;s, but not in this engine
   speex_encode_int( pCodecEncoderState, (spx_int16_t*)pCodecBuffer,
&codecBits );
   encodedFrameBytes = (uint)speex_bits_nbytes( &codecBits );

   // setup preprocessor
   speex_encoder_ctl( pCodecEncoderState, SPEEX_GET_FRAME_SIZE,
&encoderFrameSize );
   //
   pPreprocessorState = speex_preprocess_state_init( encoderFrameSize,
sampleRate );
   //
   speex_preprocess_ctl( pPreprocessorState, SPEEX_PREPROCESS_SET_DENOISE,
&enabled );
   speex_preprocess_ctl( pPreprocessorState, SPEEX_PREPROCESS_SET_VAD,
&disabled );
}

void TVoiceCodec::setupDecoder()
{
   // catch invalid sample rates resulting in invalid mode
   if ( !pMode )
      return;
   //
   assert( ( pCodecDecoderState == NULL ) && "decoder already initialized"
);
   //
   int enabled = 1;
   //
   pCodecDecoderState = speex_decoder_init( pMode );
   speex_decoder_ctl( pCodecDecoderState, SPEEX_SET_SAMPLING_RATE,
&sampleRate );
   speex_decoder_ctl( pCodecDecoderState, SPEEX_GET_FRAME_SIZE,
&decoderFrameSize );
   speex_decoder_ctl( pCodecDecoderState, SPEEX_SET_ENH,
&enabled );
   //
   speex_bits_init( &codecBits );
}

uint TVoiceCodec::encode( byte *rawsoundbuffer, uint length, char
*bitbuffer, float gain )
{
   if( !pCodecEncoderState )
      return 1;

   // copy raw voice data to temporary codec raw voice data buffer
   memcpy( pCodecRawBufferCur, rawsoundbuffer, length );
   pCodecRawBufferCur += length;

   // determine the size of data
   uint buffersize = (int)( pCodecRawBufferCur - pCodecRawBuffer );

   // do we have enough data for encoding?
   if ( buffersize < encoderFrameSize )
   {
      //pLog->Add("codec: encoder: return: buffersize: %d: needtoencode %d",
buffersize, encoderFrameSize);
      return 0;
   }

   int encodedbytes  = 0;
   int pos = 0;
   // while we have enough data
   while( (uint)( pCodecRawBufferCur - pCodecRawBuffer ) >= encoderFrameSize
)
   {
      // copy data from temporary buffer to codec buffer
      memcpy( pCodecBuffer, pCodecRawBuffer, encoderFrameSize );

      // move memory of temporary buffer
      memmove( pCodecRawBuffer, pCodecRawBuffer + encoderFrameSize,
buffersize - ( pos + encoderFrameSize ) );
      pCodecRawBufferCur -= encoderFrameSize;

      // increase current pos
      pos += encoderFrameSize;

      //encode
      speex_bits_reset( &codecBits );
      //
      speex_encode_int( pCodecEncoderState, (spx_int16_t*)pCodecBuffer,
&codecBits );
      //
      int nb = speex_bits_nbytes( &codecBits );
      encodedbytes += speex_bits_write( &codecBits,
&bitbuffer[encodedbytes], nb );
   }

   //pLog->Add("buffersize: %d: total left: %d enc buffersize: %d", length,
inputBufferArray.Count(), encodedbytes );
   return encodedbytes;
}

uint TVoiceCodec::decode( char *bitbuffer, uint length, byte *samplearray,
float gain )
{
   // return if decoder is not initialized
   if( !pCodecDecoderState )
      return 0;

   // return if there is not enough data to decode
   if ( length < encodedFrameBytes )
      return 0;

   int buffersize       = length;
   uint decodedbytes    = 0;
   int pos              = 0;
   //
   while( (int)buffersize - (int)encodedFrameBytes >= 0 )
   {
      speex_bits_reset( &codecBits );
      speex_bits_read_from( &codecBits, bitbuffer + pos, encodedFrameBytes
);
      //
      if( speex_decode_int( pCodecDecoderState, &codecBits,
(spx_int16_t*)pCodecBuffer ) == 0 )
      {
         memcpy( &samplearray[decodedbytes], pCodecBuffer, decoderFrameSize
);
         decodedbytes += decoderFrameSize;
      }
      //
      pos += encodedFrameBytes;
      buffersize -= encodedFrameBytes;
   }

   return decodedbytes;
}

-----------------------
code

Lp, Tim
+--------------------------+
| email: rico at gama.us      |
| www:    http://gama.us   |
|--------------------------|
| tel:    00386 31 457 627 |
+--------------------------+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.xiph.org/pipermail/speex-dev/attachments/20090902/21ea9253/attachment.htm 


More information about the Speex-dev mailing list