[Speex-dev] voice sound like robot voice :)
Greger Burman
greger at mobile-robotics.com
Thu Sep 3 01:21:49 PDT 2009
Hi Tim!
I haven't looked at your code. I would first make sure that recording and
playback of audio is working perfectly without the encoder. Bugs in the
handling of recording or playback can result in strange noises.
cheers
Greger
2009/9/2 Tim Rijavec <rico at gama.us>
> 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 |
> +--------------------------+
>
>
> _______________________________________________
> Speex-dev mailing list
> Speex-dev at xiph.org
> http://lists.xiph.org/mailman/listinfo/speex-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.xiph.org/pipermail/speex-dev/attachments/20090903/86415e92/attachment.htm
More information about the Speex-dev
mailing list