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; };