سؤال

أنا أستخدم 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. لست متأكدًا مما أفتقده هنا.

هل كانت مفيدة؟

المحلول

لقد وجدت السبب في أن البيانات المشفرة كانت مختلفة للغاية. هناك حقيقة أن هذا ضغط ضائع كما قال باولو سكاردين ، وأيضًا أن Speex يعمل فقط مع 160 إطارًا ، لذلك عند الحصول على بيانات من Portaudio إلى Speex ، يجب أن يكون "حزم" من 160 إطارًا.

نصائح أخرى

في الواقع ، يقدم Speaks تأخيرًا إضافيًا لبيانات الصوت ، لقد اكتشفت عن طريق التنقل العكسي:

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

نظرًا لأن Lookahead تتم تهيئة مع Zereos ، فإنك تلاحظ أن العينات القليلة الأولى "قريبة من الصفر".

للحصول على التوقيت بشكل صحيح ، يجب عليك تخطي هذه العينات قبل أن تحصل على بيانات الصوت الفعلية التي قمت بتغطيتها في برنامج الترميز. لماذا هذا ، أنا لا أعرف. Probalby مؤلف SPEEX لم يهتم بذلك أبدًا لأن Speex مخصص للبث ، وليس في المقام الأول لتخزين واستعادة بيانات الصوت. هناك حل بديل آخر (لعدم إهدار مساحة) ، يمكنك إطعام الأصفار (الإطارات-تأخير) في برنامج الترميز ، قبل تغذية بيانات الصوت الفعلية ، ثم إسقاط أول إطار speex بالكامل.

آمل أن يوضح هذا كل شيء. إذا قرأ شخص ما على دراية بـ Speex هذا ، فلا تتردد في تصحيحي إذا كنت مخطئًا.

تحرير: في الواقع ، فإن فك التشفير والتشفير لديهما وقت lookahead. الصيغة الفعلية للتأخير هي:

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

قد ترغب في إلقاء نظرة هنا على بعض الترميز/فك التشفير البسيط:http://www.speex.org/docs/manual/speex-manual/node13.html#section0013100000000000000

نظرًا لأنك تستخدم UDP ، يمكنك أيضًا العمل مع المخزن المؤقت للارتعاش لإعادة ترتيب الحزم والأشياء.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top