Я собрал библиотеку libopus с использованием компилятора emscripten, написав поверх нее обертку и предоставив API-интерфейсу javaScript, который получит декодированные аудиоданные PCM-данных. Теперь я могу отправить данные в веб-сборку из javaScript для декодирования, но не знаю, как получить из памяти модуля в javaScript. Следующая оболочка, которую я написал поверх libopus.
extern "C" {
int EMSCRIPTEN_KEEPALIVE decode_opus(void * dec, unsigned char const * data, size_t datasz)
{
/* Decode the data. In this example, frame_size will be constant because
the encoder is using a constant frame size. However, that may not
be the case for all encoders, so the decoder must always check
the frame size returned. */
OpusDecoder *decoder=(OpusDecoder *)dec;
opus_int16 out[MAX_FRAME_SIZE*CHANNELS];
int frame_size,i;
frame_size = opus_decode(decoder, data, datasz, out, MAX_FRAME_SIZE, 0);
if (frame_size<0)
{
//fprintf(stderr, "decoder failed: %s\n", opus_strerror(frame_size));
emscripten_log(EM_LOG_CONSOLE, "decoder failed: %s\n", opus_strerror(frame_size));
return EXIT_FAILURE;
}
unsigned char pcm_bytes[MAX_FRAME_SIZE*CHANNELS*2];
/* Convert to little-endian ordering. */
for(i=0;i<CHANNELS*frame_size;i++)
{
pcm_bytes[2*i]=out[i]&0xFF;
pcm_bytes[2*i+1]=(out[i]>>8)&0xFF;
}
/* Write the decoded audio to file.
fwrite(pcm_bytes, sizeof(short), frame_size*CHANNELS, fout);
*/
//auto arrayPtr = &pcm_bytes[0];
frame_size=frame_size*CHANNELS;
EM_ASM_({
frame_opusCallback($0, $1);
},&pcm_bytes[0],frame_size
);
}
}
В javaScript Я получаю декодированные данные в обратном вызове frame_opusCallback Первый параметр $0
содержит декодированные данные, а второй параметр $ 1 содержит размер декодированных данных. Я реализовал следующий обратный вызов в javaScript.
function frame_opusCallback(a,b) {
console.log("Getting callback from liobopus"+b);
var arrayData = [];
for (let v=0; v < b; v++) {
arrayData.push(Module.HEAPF32[a/Float32Array.BYTES_PER_ELEMENT+v])
}
}
Обновление
Теперь у меня есть некоторые знания о Module
и как это работает, поэтому я имею обновил мой обработчик javascript, чтобы получить значение из Module
в памяти есть пары.
function convertBlock(incomingData) { // incoming data is a UInt8Array
var i, l = incomingData.length;
var outputData = new Float32Array(incomingData.length);
for (i = 0; i < l; i++) {
outputData[i] = (incomingData[i] - 128) / 128.0;
}
return outputData;
}
function frame_opusCallback(a,b)
{
//console.log("Getting callback from liobopus"+b);
var incomingData= new Uint8Array(Module.HEAP8.buffer, a, b);
var sampledata = convertBlock(incomingData);
postMessage({'data':sampledata});
}
После получения данных из обратного вызова я хочу играть в аудиоплеере PCM. Но в настоящее время он не воспроизводится.
Но когда я воспроизводю аудиоданные в проигрывателе PCM, он не воспроизводится. Насколько я знаю, для воспроизведения аудио он должен быть в Float32Array
, поэтому я преобразовал его с помощью функции convertBlock
. Пожалуйста, дайте мне знать, где я делаю ошибку. Любая помощь в этом будет оценена.