#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;
-
Я получаю PCM для
sampleBlock
paError = Pa_ReadStream(**amp;stream, sampleBlock, totalFrames); if (paError != paNoError) { cout << "PortAudio error : " << Pa_GetErrorText(paError) << endl; std::system("pause"); }
-
Кодирование
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 -
Декодирование
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
-
Воспроизведение звука
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