首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用speex抖动缓冲区

如何使用speex抖动缓冲区
EN

Stack Overflow用户
提问于 2012-03-06 06:09:20
回答 1查看 3.5K关注 0票数 2

我正在使用speex库来编码、解码和预处理音频数据。我认为speex库非常有用,但是当我使用speex 抖动缓冲区时,我遇到了一些问题。我使用多线程,一个线程将接收到的数据放入抖动缓冲区,另一个线程从活动抖动缓冲区获取数据,有时“获取”线程无法获得有效的数据,特别是当它比“放置数据”线程更快的时候。此外,我正在使用互斥保护抖动缓冲区。

我不知道如何准确地使用抖动缓冲区。我希望有人能帮我。

这是我的密码:

代码语言:javascript
复制
speex_jitter_buffer.h

#include <speex/speex_jitter.h>
#include <speex/speex.h>

/** @defgroup SpeexJitter SpeexJitter: Adaptive jitter buffer specifically for Speex
 *  This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size
 * to maintain good quality and low latency. This is a simplified version that works only
 * with Speex, but is much easier to use.
 *  @{
*/

/** Speex jitter-buffer state. Never use it directly! */
typedef struct SpeexJitter {
   SpeexBits current_packet;         /**< Current Speex packet */
   int valid_bits;                   /**< True if Speex bits are valid */
   JitterBuffer *packets;            /**< Generic jitter buffer state */
   void *dec;                        /**< Pointer to Speex decoder */
   spx_int32_t frame_size;           /**< Frame size of Speex decoder */
} SpeexJitter;

/** Initialise jitter buffer 
 * 
 * @param jitter State of the Speex jitter buffer
 * @param decoder Speex decoder to call
 * @param sampling_rate Sampling rate used by the decoder
*/
void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate);

/** Destroy jitter buffer */
void speex_jitter_destroy(SpeexJitter *jitter);

/** Put one packet into the jitter buffer */
void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp);

/** Get one packet from the jitter buffer */
void speex_jitter_get(SpeexJitter *jitter, spx_int16_t *out, int *start_offset);

/** Get pointer timestamp of jitter buffer */
int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter);

#ifdef __cplusplus
}
#endif

speex_jitter_buffer.cpp

代码语言:javascript
复制
#include <speex/speex_jitter.h>
#include "speex_jitter_buffer.h"

#ifndef NULL
#define NULL 0
#endif


void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate)
{
   jitter->dec = decoder;
   speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &jitter->frame_size);

   jitter->packets = jitter_buffer_init(jitter->frame_size);

   speex_bits_init(&jitter->current_packet);
   jitter->valid_bits = 0;

}

void speex_jitter_destroy(SpeexJitter *jitter)
{
   jitter_buffer_destroy(jitter->packets);
   speex_bits_destroy(&jitter->current_packet);
}

void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp)
{
   JitterBufferPacket p;
   p.data = packet;
   p.len = len;
   p.timestamp = timestamp;
   p.span = jitter->frame_size;
   jitter_buffer_put(jitter->packets, &p);
}

void speex_jitter_get(SpeexJitter *jitter, spx_int16_t *out, int *current_timestamp)
{
   int i;
   int ret;
   spx_int32_t activity;
   char data[2048];
   JitterBufferPacket packet;
   packet.data = data;

   if (jitter->valid_bits)
   {
      /* Try decoding last received packet */
      ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
      if (ret == 0)
      {
         jitter_buffer_tick(jitter->packets);
         return;
      } else {
         jitter->valid_bits = 0;
      }
   }

   ret = jitter_buffer_get(jitter->packets, &packet, jitter->frame_size, NULL);

   if (ret != JITTER_BUFFER_OK)
   {
      /* No packet found */

      /*fprintf (stderr, "lost/late frame\n");*/
      /*Packet is late or lost*/
      speex_decode_int(jitter->dec, NULL, out);
   } else {
      speex_bits_read_from(&jitter->current_packet, packet.data, packet.len);
      /* Decode packet */
      ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
      if (ret == 0)
      {
         jitter->valid_bits = 1;
      } else {
         /* Error while decoding */
         for (i=0;i<jitter->frame_size;i++)
            out[i]=0;
      }
   }
   speex_decoder_ctl(jitter->dec, SPEEX_GET_ACTIVITY, &activity);
   if (activity < 30)
      jitter_buffer_update_delay(jitter->packets, &packet, NULL);
   jitter_buffer_tick(jitter->packets);
}

int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter)
{
   return jitter_buffer_get_pointer_timestamp(jitter->packets);
}

然后我使用"speex_jitter_buffer.h“头文件。

“放置”线程代码:

代码语言:javascript
复制
m_jitter_mutex.lock();
speex_jitter_put(&jitter, recvBuf, payloadLength, timestamp);
m_jitter_mutex.unlock();

“获取”线程代码:

代码语言:javascript
复制
while(true)
{
    Sleep(20);

    m_jitter_mutex.lock();
    speex_jitter_get(&jitter, (spx_int16_t*)pcm_short, NULL);
    m_pOut->Play(pcm_char, pcm_data_length);  // play the pcm data
    m_jitter_mutex.lock();
}

我也想使用speex库来做回波消除,但我不知道如何准确地实现它。非常感谢。

EN

回答 1

Stack Overflow用户

发布于 2016-09-23 05:43:57

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9578764

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档