Question

J'utilise Speex pour coder des données audio et l'envoyer sur UDP, et le décoder de l'autre côté. J'ai couru quelques tests avec Speex, et a remarqué que si je décode un paquet droit après avoir encodé, les données décodées est en aucune façon proche des données d'origine. La plupart des octets au début de la mémoire tampon sont 0. Alors, quand je décode l'audio sur UDP envoyés, tout ce que je get est le bruit. Voilà comment je suis l'encodage audio:

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

est ainsi que je suis en train de décoder l'audio:

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

J'ai vérifier les documents, et la plupart de mon code provient de l'exemple de codage / décodage exemple à partir du site de Speex. Je ne sais pas ce que je suis absent ici.

Était-ce utile?

La solution

Je trouve la raison pour laquelle les données codées était si différent. Il est le fait qu'il est une compression avec perte comme dit Paulo Scardine, et que Speex fonctionne uniquement avec 160 cadres, de sorte que lors de l'obtention des données de portaudio à Speex, il doit être par « paquets » de 160 images.

Autres conseils

En fait, parle introduit un délai supplémentaire aux données audio, j'ai trouvé par enginiering inverse:

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

Depuis l'préanalyse est initialisé avec zereos, vous observez les premiers échantillons à être « proche de zéro ».

Pour obtenir le bon timing, vous devez ignorer ces échantillons avant d'obtenir les données audio réelles que vous avez dans le codec qu'on nourrit. Pourquoi c'est, je ne sais pas. Probalby l'auteur de Speex jamais pris soin de cela depuis Speex est pour le streaming, pas principalement pour le stockage et la restauration des données audio. Une autre solution (à ne pas perdre de l'espace) est, vous nourrissez des zéros (framesize-retard) dans le codec, avant d'alimenter vos données audio réelles, puis laisser tomber toute première image speex.

J'espère que ce tout les clarifie. Si quelqu'un familier avec Speex lit ceci, ne hésitez pas à me corriger si je me trompe.

EDIT: En fait, décodeur et encodeur ont à la fois un temps d'anticipation. La formule réelle pour le retard est la suivante:

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

Vous voudrez peut-être jeter un oeil ici pour un codage / décodage simple: http://www.speex.org/docs/manual/speex -manual / node13.html # SECTION001310000000000000000

Puisque vous utilisez UDP, vous pouvez également travailler avec un tampon de gigue aux paquets Réorganiser et des choses.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top