11
edits
Line 131: | Line 131: | ||
The callback model has some restrictions -- all functions except the callback itself will occur on the NPAPI thread. The callback will occur on a high priority thread dedicated to serving audio. This thread is created implicitly during initialization, and cleaned up automatically at shutdown. | The callback model has some restrictions -- all functions except the callback itself will occur on the NPAPI thread. The callback will occur on a high priority thread dedicated to serving audio. This thread is created implicitly during initialization, and cleaned up automatically at shutdown. | ||
=====Example Usage===== | |||
Once an audio extension is acquired via NPN_GetValue(), it can be queried, initialized, and | |||
shutdown. Stereo, int16 sample format are always guaranteed to be available. | |||
<pre> | |||
/* ...somewhere in application, from the NPAPI thread... */ | |||
/* variable 'npp' is a NPP plug-in instance... */ | |||
/* fill out request, use sample buffer size from configuration */ | |||
NPAudioConfig request; | |||
NPAudioConfig config; | |||
NPAudioContext context; | |||
int32 ret; | |||
request.sampleRate = NPAudioSampleRate44100Hz; | |||
request.sampleType = NPAudioSampleTypeInt16; | |||
request.sampleBufferSize = | |||
audio->queryCapability(npp, NPAudioQuerySampleFrameCount44100Hz); | |||
request.outputChannelMap = NPAudioChannelStereo; | |||
request.inputChannelMap = NPAudioChannelNone; | |||
request.flags = 0; | |||
/* specify callback function to enable callback mode */ | |||
request.callback = appCallback; | |||
request.userData = NULL; | |||
ret = audio->queryConfig(npp, &request, &config); | |||
if (NPERR_NO_ERROR == ret) { | |||
/* for this simple example, take the config we're given */ | |||
ret = audio->initializeContext(npp, | |||
&config, | |||
&context); | |||
if (NPERR_NO_ERROR == ret) { | |||
/* audio context aquired, set state to start streaming */ | |||
audio->setStateContext(npp, &context, | |||
NPAudioContextStateCallback, NPAudioCallbackStart); | |||
/* app_audio_callback will now be periodically invoked on */ | |||
/* an implicit high priority audio thread */ | |||
} | |||
} | |||
</pre> | |||
Later on, when the PEPPER application needs to shutdown audio: | |||
<pre> | |||
/*...somewhere in application, from the NPAPI thread...*/ | |||
audio->destroyContext(npp, &context); | |||
</pre> | |||
An example callback for the Initialization function. This callback does very little work. Most of the time, the implicit thread which invokes this callback will be sleeping, waiting for the audio context to request another buffer of audio data. When possible, this callback will be occurring in a thread whose priority is boosted. | |||
<pre> | |||
void appCallback(const NPAudioContext *context) { | |||
/* assume using int16 format */ | |||
int16 *outBuffer16 = (int16 *)context->outBuffer; | |||
for (int32 i = 0; i < context->sampleFrameCount; ++i) { | |||
/* generate noise */ | |||
outBuffer16[0] = int16(rand()); | |||
outBuffer16[1] = int16(rand()); | |||
outBuffer16 += 2; // next interleaved sample, 2 chn stereo | |||
} | |||
} |
edits