Speex декодирование идет не так - PullRequest
2 голосов
/ 25 ноября 2010

Я использую speex для кодирования некоторых аудиоданных, отправки их по UDP и декодирования на другой стороне. Я провел несколько тестов со speex и заметил, что если я декодирую пакет сразу после того, как закодировал его, декодированные данные никоим образом не близки к исходным данным. Большинство байтов в начале буфера равны 0. Поэтому, когда я декодирую аудио, передаваемое по UDP, все, что я получаю, это шум. Вот как я кодирую аудио:

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. Я не уверен, что мне здесь не хватает.

Ответы [ 3 ]

1 голос
/ 30 ноября 2010

Я нашел причину, по которой закодированные данные были такими разными.По словам Пауло Скардина, есть факт, что это сжатие с потерями, а также то, что speex работает только с 160 кадрами, поэтому при получении данных из portaudio в speex это должны быть «пакеты» из 160 кадров.

1 голос
/ 07 апреля 2012

На самом деле говорит вводит дополнительную задержку для аудиоданных, я обнаружил путем обратной инженерии:

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, вы наблюдаете, что первые несколько образцов "близки к нулю".

Чтобы правильно выбрать время, вы должны пропустить эти сэмплы, прежде чем вы получите фактические аудиоданные, которые вы ввели в кодек. Почему это, я не знаю. Probalby, автор speex, никогда не заботился об этом, поскольку speex предназначен для потоковой передачи, а не для хранения и восстановления аудиоданных. Другой обходной путь (чтобы не тратить пространство) состоит в том, что вы вводите нули (frameize-delay) в кодек перед подачей реальных аудиоданных, а затем отбрасываете весь первый 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
0 голосов
/ 25 ноября 2010

Возможно, вы захотите взглянуть сюда для некоторого простого кодирования / декодирования: http://www.speex.org/docs/manual/speex-manual/node13.html#SECTION001310000000000000000

Поскольку вы используете UDP, вы также можете работать с буфером дрожания для переупорядочения пакетов и прочего.

...