2010-11-25 3 views
2

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

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 ~ первые поплавки (после декодирования) равны 0. Я знаю, что это потеря, но там я теряю большую часть данных. Я также получаю некоторые значения neg, где у меня есть некоторые положительные значения. – dotminic 2010-11-25 18:33:13

+0

выглядит как проблема типа подписанного/неподписанного типа. – 2010-11-25 19:24:08

ответ

1

Я нашел причину, по которой кодированные данные были настолько разными. Существует тот факт, что это сжатие с потерями, как сказал Пауло Скардин, а также что 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, вы наблюдаете первые несколько образцов, чтобы быть «близко к нулю» ,

Чтобы получить правильное время, вы должны пропустить эти образцы, прежде чем получать фактические аудиоданные, которые вы загрузили в кодек. Почему это, я не знаю. Probalby автор speex никогда не заботился об этом, поскольку speex предназначен для потоковой передачи, а не только для хранения и восстановления аудиоданных. Другим обходным решением (чтобы не тратить пространство) является то, что вы подаете нулевые нули в кодек, перед подачей ваших фактических аудиоданных, а затем отбрасываете весь первый кадр-заглавное изображение.

Надеюсь, это прояснит все. Если кто-то, знакомый с Speex, читает это, не стесняйтесь исправить меня, если я ошибаюсь.

EDIT: На самом деле декодер и кодировщик имеют как временное время. Фактическая формула для задержки:

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