Hi,
I'm very sorry if those questions are repeated over and over, but I
cannot find a solution on the net.
I try to use speex to encode/decode voice to send over the network.
My doubts are:
1. The Bits_Per_Sample I use, are independent from the speex
encoding/decoding? (So...can I use 8, 16, 24..and so on?)
2. If I have this situation:
SAMPLE RATE.....: 8000
BITS PER SAMPLE.: 16
CHANNELS........: 1
DATA TYPE.......: float
And I need to encode a buffer of 640 PCM float frames, the following
Encode method is correct?
Thanks in advance for the help!
Daniele.
class CSpeexCodec
{
public:
enum ESpeexCodecType
{
SC_ENCODER,
SC_DECODER
};
enum ESpeexCodecMode
{
SC_NARROWBAND, // 8 kHz
SC_WIDEBAND, // 16 kHz
SC_ULTRAWIDEBAND // 32 kHz
};
CSpeexCodec();
~CSpeexCodec();
BOOL Init();
UINT Encode( sample_type *inBuff, char **outBuff, UINT BufferFrames );
private:
SpeexBits spx_bits_;
void* spx_state_;
UINT spx_quality_;
UINT frameSize_;
char* outBuffer_;
};
BOOL CSpeexCodec::Init()
{
spx_state_ = speex_encoder_init(&speex_nb_mode);
speex_encoder_ctl(spx_state_, SPEEX_GET_FRAME_SIZE, &frameSize_);
// Create the output buffer
outBuffer_ = new char[frameSize_];
speex_bits_init(&spx_bits_);
}
UINT CSpeexCodec::Encode( float *inBuff,
char **outBuff,
UINT BufferFrames )
{
INT nBytes = 0;
float *pBuff = inBuff;
if (!spx_state_) return 0;
while (BufferFrames>0)
{
speex_bits_reset(&spx_bits_);
speex_encode(spx_state_, pBuff, &spx_bits_);
nBytes += speex_bits_write(&spx_bits_, outBuffer_, frameSize_);
pBuff += frameSize_;
BufferFrames -= frameSize_;
}
// Point the outBuff to the internal buffer
*outBuff = outBuffer_;
return nBytes;
};
Il 13/04/2010 16:57, Daniele Barzotti wrote:> > 2. If I have this situation: > > SAMPLE RATE.....: 8000 > BITS PER SAMPLE.: 16 > CHANNELS........: 1 > DATA TYPE.......: float > > And I need to encode a buffer of PCM float frames...I hope that someone can help me, because I cannot understand where I wrong, and I need to know if the mistake is in the encode/decode or in another part of my code I try to : 1. acquire audio from mic 2. encode it 3. send to a loopback VoIP session 4. decode it 5. playback to speakers But I get no sound (while, without using the encode/decode all works) This is my code: UINT CSpeexCodec::Encode( float *inBuff, const char **outBuff, UINT BufferFrames ) { INT nbBytes = 0; float *pBuff = inBuff; if (!spx_state_) return 0; if (spx_type_ != SC_ENCODER) return 0; EncOutBuffer_.Recycle(); speex_bits_reset(&spx_bits_); // The manual says that I have to call speex_encode many times before // calling speex_bits_write while (BufferFrames>0) { speex_encode(spx_state_, pBuff, &spx_bits_); // Move the pointers ahead of a frame size pBuff += spx_frame_size_; // Substract the amount of 1 frame from BufferFrames -= spx_frame_size_; } nbBytes = speex_bits_write(&spx_bits_, spx_enc_frame_, spx_frame_size_); // Save the speex frame into the buffer EncOutBuffer_.Write((void*)spx_enc_frame_, nbBytes); // Point the outBuff to the internal buffer *outBuff = (char*)EncOutBuffer_.GetRawData(); return nbBytes; }; //---------------------------------------------------------------------------- UINT CSpeexCodec::Decode( char *inBuff, UINT BuffLen, const sample_type **outBuff ) { if ( (!spx_state_) || (!outBuff) || (spx_type_ != SC_DECODER) ) return 0; INT nbBytes = 0; UINT nbBytesWritten = 0; DecOutBuffer_.Recycle(); speex_bits_reset(&spx_bits_); speex_bits_read_from(&spx_bits_, inBuff, BuffLen); nbBytes = speex_bits_remaining(&spx_bits_); while (nbBytes>0) { if ( speex_decode(spx_state_, &spx_bits_, spx_dec_frame_) != 0 ) break; nbBytes = speex_bits_remaining(&spx_bits_); // Save the speex frame into the buffer DecOutBuffer_.Write(spx_dec_frame_, spx_frame_size_); nbBytesWritten += spx_frame_size_; } // Point the outBuff to the internal buffer *outBuff = DecOutBuffer_.GetTypedData(); return nbBytesWritten; };