Операция правильного декодирования

#portaudio #opus

#portaudio #opus

Вопрос:

У меня возникла необходимость передавать звук по сети и для этого я выбрал библиотеки «PortAudio» и «Opus». Я новичок в работе со звуком и поэтому многого не знаю.Я новичок в работе со звуком и поэтому многого не знаю, но я прочитал документацию и просмотрел несколько примеров, но у меня все еще есть некоторые проблемы с кодированием / декодированием с помощью Opus. Я не понимаю, как правильно восстановить исходный кодированный PCM.У меня есть некоторая последовательность действий: Некоторые концы

 const int FRAMES_PER_BUFFER = 960;
const int SAMPLE_RATE = 48000;
int NUM_CHANNELS = 2;
int totalFrames = 2 * SAMPLE_RATE; /* Record for a few seconds. */
int numSamples = totalFrames * 2;
int numBytes = numSamples * sizeof(float);
float *sampleBlock = nullptr;
int bytesOfPacket = 0;
unsigned char *packet = nullptr;
  
  1. Я получаю PCM для sampleBlock

     paError = Pa_ReadStream(**amp;stream, sampleBlock, totalFrames);
    if (paError != paNoError) {
        cout << "PortAudio error : " << Pa_GetErrorText(paError) << endl;
        std::system("pause");
    }
      
  2. Кодирование sampleBlock

     OpusEncoder *encoder;
    int error;
    int size;
    encoder = opus_encoder_create(SAMPLE_RATE, NUM_CHANNELS, OPUS_APPLICATION_VOIP, amp;error);
    size = opus_encoder_get_size(NUM_CHANNELS);
    encoder = (OpusEncoder *)malloc(size);
    packet = new unsigned char[480];
    
    error = opus_encoder_init(encoder, SAMPLE_RATE, NUM_CHANNELS, OPUS_APPLICATION_VOIP);
    if (error == -1) {
        return -1;
    }
    
    bytesOfPacket = opus_encode_float(encoder, sampleBlock, FRAMES_PER_BUFFER, packet, 480);
    opus_encoder_destroy(encoder);
      

    Хорошо, я получил закодированное packet в Opus

  3. Декодирование

     OpusDecoder *decoder;
    int error;
    int size;
    decoder = opus_decoder_create(SAMPLE_RATE, NUM_CHANNELS, amp;error);
    size = opus_decoder_get_size(NUM_CHANNELS);
    decoder = (OpusDecoder *)malloc(size);
    error = opus_decoder_init(decoder, SAMPLE_RATE, NUM_CHANNELS);
    
    opus_decode_float(decoder, packet, bytesOfPacket, sampleBlock, 480, 0);
    opus_decoder_destroy(decoder);
      

    Здесь я пытаюсь расшифровать Opus обратно в PCM и сохранить результат в sampleBlock

  4. Воспроизведение звука

     paError = Pa_WriteStream(**amp;stream, sampleBlock, totalFrames);
    if (paError != paNoError) {
        cout << "PortAudio error : " << Pa_GetErrorText(paError) << endl;
        std::system("pause");
    }
      

    Я получаю тишину. Я не очень разбираюсь в тонкостях работы со звуком, так как я новичок в этом бизнесе. Помогите, пожалуйста, понять, что не так.

Ответ №1:

Что касается ваших настроек, вы кодируете 20 мс звука за вызов opus_encode_float. Я не вижу никаких итераций по этому вызову, поэтому я полагаю, вы ничего не слышите, потому что вы кодируете только 20 мс аудио. Вы должны передать в opus_encode_float выборки объемом 20 мс с вашим указателем sampleBlock, увеличив его через весь буфер x раз.

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

Damiano