[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