Правильное декодирование опуса - PullRequest
1 голос
/ 09 марта 2019

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

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. Я получаю ПК до sampleBlock

    paError = Pa_ReadStream(**&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, &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, &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(**&stream, sampleBlock, totalFrames);
    if (paError != paNoError) {
        cout << "PortAudio error : " << Pa_GetErrorText(paError) << endl;
        std::system("pause");
    }
    

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

1 Ответ

0 голосов
/ 03 мая 2019

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

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

Дамиано

...