Plugins:PepperAudioAPI: Difference between revisions

Jump to navigation Jump to search
Line 193: Line 193:
   }
   }
}
}
===Model Two: Blocking Push Model===
The blocking push model allows the application to explicitly create the dedicated audio thread, and from this thread is can use blocking calls to flushContext() to push audio data. The flushContext() call is the only call that is permitted to be directly callable from a non-Tp (NPAPI) thread. We justify this because low latency audio needs to be done from a thread dedicated entirely to audio. This thread may need its priority explicitly boosted in order to
satisfy scheduling demands. This model assumes the application programmer will setup the dedicated audio thread (and has access to a thread API such as pthreads.)
=====Example Usage=====
<pre>
/* From the application's NPAPI thread... */
/* setup request structure, use sample_buffer_size from configuration */
NPAudioConfiguration request;
NPAudioConfiguration config;
pthread_t appAudioThreadID = 0;
volatile appAudioDone = false;
request.sampleRate = NPAudioSampleRate44100Hz;
request.sampleType = NPAudioSampleTypeInt16;
audio->queryCapability(npp,
  NPAudioCapabilitySampleFrameCount44100Hz,
  &request.sampleFrameCount);
request.outputChannelMap = NPAudioChannelStereo;
request.inputChannelMap = NPAudioChannelNone;
request.flags = 0;
/* specify NULL callback to enable blocking push model */
request.callback = NULL;
/* use userData field to transfer audio interface to audio thread */
request.userData = audio;
ret = audio->queryConfig(npp, &request, &config);
if (NPERR_NO_ERROR == ret) {
  ret = audio->initializeContext(npp, &config, &context);
  if (NPERR_NO_ERROR == ret) {
    int p = pthread_create(&appAudioThreadID, NULL,
    appAudioThread, &context);
    /* wait for a while */
    sleep(100);
    /* notify audio thread we're done */
    appAudioDone = true;
    /* (technically, we should wait until pending flush completes) */
    audio->shutdownContext(npp, &context);
  }
}
/* application's thread dedicated to audio */
void* appAudioThread(void *userData) {
  /* context is sent via pthread's userData function arg */
  NPAudioContext *context = (NPAudioContext *)userData;
  /* get pepper audio extensions (so we can call flushContext) */
  NPAudio *audio = (NPAudio *)context->userData;
  /* simple audio loop for this example, poll global variable */
  while (!appAudioDone) {
    int16 *outBuffer16 = (int16 *)context->outBuffer;
    for (int32 i = 0; i < obtained.sample_buffer_size; ++i) {
      /* example: generate some noise */
      outBuffer16[0] = int16(rand());
      outBuffer16[1] = int16(rand());
      outBuffer16 += 2;
    }
    /*
    * steam will output buffer to audio context, then block until
    * context is ready to consume the next output buffer. Most
    * of the time, this audio thread will be sleeping in this
    * blocking call.
    */
    audio->flushContext(npp, context);
  }
  /* pthread exit point */
  return NULL;
}
</pre>
11

edits

Navigation menu