[Speex-dev] voice sound like robot voice :)
Tim Rijavec
rico at gama.us
Thu Sep 3 05:20:38 PDT 2009
hy,
recording and playback without speex is working perfectly
Lp, Tim
+--------------------------+
| email: rico at gama.us |
| www: http://gama.us |
|--------------------------|
| tel: 00386 31 457 627 |
+--------------------------+
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 |
> +--------------------------+
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.xiph.org/pipermail/speex-dev/attachments/20090903/5a8cf708/attachment-0001.htm
More information about the Speex-dev
mailing list