2010-11-25 128 views
2

我正在使用speex编码一些音频数据并通过UDP发送,并在另一侧解码。 我用speex进行了一些测试,发现如果我在对它进行编码后直接对数据包进行解码,解码后的数据绝不会接近原始数据。缓冲区开始处的大部分字节为0. 因此,当我解码通过UDP发送的音频时,我所得到的只是噪声。 这是怎么了编码音频:speex解码出错

bool AudioEncoder::encode(float *raw, char *encoded_bits) 
{ 
    for (size_t i = 0; i < 256; i++) 
     this->_rfdata[i] = raw[i]; 
    speex_bits_reset(&this->_bits); 
    speex_encode(this->_state, this->_rfdata, &this->_bits); 
    int bytesWritten = speex_bits_write(&this->_bits, encoded_bits, 512); 
    if (bytesWritten) 
     return true; 
    return false; 
} 

这是怎么了解码音频:

float *f = new float[256]; 
// recvbuf is the buffer I pass to my recv function on the socket 
speex_bits_read_from(&this->_bits, recvbuf, 512); 
speex_decode(this->state, &this->_bits, f); 

我已经签出文档,以及我的大多数代码来自例子编码/解码来自speex网站的样本。 我不知道我在这里错过了什么。

+0

的Speex是一个有损编解码器,所产生的流将是从原始的不同,因为为了你松散信息来实现更好的压缩。 – 2010-11-25 18:23:11

+1

@Paulo Scardine如果我使用正弦波值对数组进行编码,则20〜1个浮点数(一旦解码)全部等于0。我知道这是有损的,但是我失去了大部分数据。如果我有一些正面价值,我也会得到一些负值。 – dotminic 2010-11-25 18:33:13

+0

看起来像一个签名/未签名的数据类型问题。 – 2010-11-25 19:24:08

回答

1

我发现编码数据如此不同的原因。事实上这是Paulo Scardine说的有损压缩,而且speex只能处理160帧,所以从portaudio到speex的数据时,它需要160帧的“数据包”。

1

其实讲引入了额外的延迟音频数据,我发现通过反向enginiering:

narrow band : delay = 200 - framesize + lookahead = 200 - 160 + 40 = 80 samples 

wide band : delay = 400 - framesize + lookahead = 400 - 320 + 143 = 223 samples 

uwide band : delay = 800 - framesize + lookahead = 800 - 640 + 349 = 509 samples 

由于先行与zereos初始化,您观察到的前几个样品是“接近零” 。

为了获得正确的时间,您必须先跳过这些样本,然后才能获得您已编入编解码器的实际音频数据。为什么是这样,我不知道。 Propelby的作者从来不关心这个问题,因为speex是用于流式传输,主要不是用于存储和恢复音频数据。 另一个解决方法(不浪费空间)是,在馈送实际音频数据之前,您将(帧大小延迟)零进入编解码器,然后丢弃整个第一个speex帧。

我希望这能够澄清一切。如果熟悉斯佩克斯的人阅读此文,请随时纠正我,如果我错了。

编辑:其实,解码器和编码器都有前瞻时间。延迟的实际计算公式为:

narrow band : delay = decoder_lh + encoder_lh = 40 + 40 = 80 samples 

wide band : delay = decoder_lh + encoder_lh = 80 + 143 = 223 samples 

uwide band : delay = decoder_lh + encoder_lh = 160 + 349 = 509 samples