Как получить данные из веб-сборки до JavaScript? - PullRequest
0 голосов
/ 07 апреля 2020

Я собрал библиотеку 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. Пожалуйста, дайте мне знать, где я делаю ошибку. Любая помощь в этом будет оценена.

...