Plugins:PepperAudioAPI: Difference between revisions

Jump to navigation Jump to search
Line 264: Line 264:
   return NULL;
   return NULL;
}
}
</pre>
=====Switching to Low Power (Silence)=====
Callback Mode: While an application is performing audio output, it will receive callbacks at a regular interval. If an application needs to enter a state where audio output isn't required, it may wish to suppress the callback to save power and/or CPU cycles. The application can suppress the audio callback in two ways: 1) It can shutdown the audio context, and at a later time, when the application needs to resume audio output, it can re-initialize a new audio context. This approach may have long latency. 2) If setStateContext(npp, NPAudioContextStateCallback, NPAudioCallbackStop) is invoked on the NPAPI thread, callbacks will be suspended and the implicit audio thread will go into a sleep state. To resume audio playback and callbacks, the NPAPI thread should invoke setStateContext(npp,NPAudioContextStateCallback, NPAudioCallbackStop), which will resume callbacks in a low latency time frame.
Push Mode: In the blocking push model, flushContext() will block (sleep) until the audio context is ready to consume another chunk of sample data. If the audio thread does not call flushContext() within a short period of time (the duration of which depends on the sample frame count and sample frequency), the audio context will automatically emit silience. Normally, an audio thread will continuously make calls to the blocking flushContext() call to emit long continuous periods of audio output. If the application enters a state where no audio output is needed for an extended duration and it wishes to reduce CPU load, the application has one of two options. 1) Shutdown the audio context and exit the audio thread. When audio playback needs to resume, it can re-spawn the audio thread and re-initialize an audio context. This approach may have a long latency. 2) The application can sleep the audio thread during long periods of silence by waiting on a pthread cond_var. When the main thread is ready to resume audio playback, it can signal the condition variable to wake up the sleeping audio thread. This approach is expected to resume audio output in a low latency time frame.
=====Basic API=====
The basic Pepper API consists of: queryCapability, queryConfig, initializeContext, setStateContext, getStateContext, flushContext, and destroyContext.
<pre>
/* min & max sample frame count */
static const int32 NPAudioMinSampleFrameCount = 64;
static const int32 NPAudioMaxSampleFrameCount = 32768;
/* supported sample rates */
static const int32 NPAudioSampleRate44100Hz = 44100;
static const int32 NPAudioSampleRate48000Hz = 48000;
static const int32 NPAudioSampleRate96000Hz = 96000;
/* supported sample formats */
static const int32 NPAudioSampleTypeInt16 = 0;
static const int32 NPAudioSampleTypeFloat32 = 1;
/* supported channel layouts */
static const int32 NPAudioChannelNone = 0;
static const int32 NPAudioChannelMono = 1;
static const int32 NPAudioChannelStereo = 2;
static const int32 NPAudioChannelThree = 3;
static const int32 NPAudioChannelFour = 4;
static const int32 NPAudioChannelFive = 5;
static const int32 NPAudioChannelFiveOne = 6;
static const int32 NPAudioChannelSeven = 7;
static const int32 NPAudioChannelSevenOne = 8;
/* audio context states */
static const int32 NPAudioContextStateCallback = 0;
static const int32 NPAudioContextStateUnderrunCounter = 1;
/* audio context state values */
static const int32 NPAudioCallbackStop = 0;
static const int32 NPAudioCallbackStart = 1;
/* audio query capabilities */
static const int32 NPAudioCapabilitySampleRate = 0;
static const int32 NPAudioCapabilitySampleType = 1;
static const int32 NPAudioCapabilitySampleFrameCount = 2;
static const int32 NPAudioCapabilitySampleFrameCount44100Hz = 3;
static const int32 NPAudioCapabilitySampleFrameCount48000Hz = 4;
static const int32 NPAudioCapabilitySampleFrameCount96000Hz = 5;
static const int32 NPAudioCapabilityOutputChannelMap = 6;
static const int32 NPAudioCapabilityInputChannelMap = 7;
/* forward decls */
typedef struct NPAudioContext NPAudioContext;
typedef struct NPAudioConfig NPAudioConfig;
/* user supplied callback function */
typedef void (*NPAudioCallback)(const NPAudioContext *context);
/* Audio config structure */
struct NPAudioConfig {
int32 sampleRate;
int32 sampleType;
int32 outputChannelMap;
int32 inputChannelMap;
int32 sampleFrameCount;
uint32 flags;
NPAudioCallback callback;
void *userData;
};
/* Audio context structure */
struct NPAudioContext {
NPP npp;
NPAudioConfig config;
void *outBuffer;
void *inBuffer;
void *private;
};
</pre>
'''NPError queryCapability(NPP npp, int32 query, int32 *value)'''
<pre>
inputs:
  NPP npp
Plug-in instance npp
NPDeviceCapability query
NPAudioCapabilitySampleRate
NPAudioCapabilitySampleType
NPAudioCapabilitySampleFrameCount
NPAudioCapabilitySampleFrameCount44100Hz
NPAudioCapabilitySampleFrameCount48000Hz
NPAudioCapabilitySampleFrameCount96000Hz
NPAudioCapabilityOutputChannelMap
NPAudioCapabilityInputChannelMap
outputs:
*value
Value based on input query. See section "NPAudioCapability
Details" for input & output values.
returns:
NPERR_NO_ERROR
NPERR_INVALID_PARAM
</pre>
'''NPError queryConfig(NPP npp, NPAudioConfig *request, NPAudioConfig *obtain)'''
<pre>
  inputs:
NPP npp
Plug-in instance npp
NPAudioConfig *request
A requested configuration, which is a set of capabilities
outputs:
NPAudioConfig *obtain
The set of capabilities obtained, which may or may not match
request input.
returns:
NPERR_NO_ERROR
NPERR_INVALID_PARAM
notes:
Okay if request & obtain pointers are the same.
</pre>
'''NPError initializeContext(NPP npp, const NPAudioConfig *config,
NPAudioContext *context)'''
<pre>
inputs:
NPP npp
Plug-in instance npp
NPAudioConfig *config - a structure with which to configure the
audio device
int32 sampleRate
Both NPAudioSampleRate44100Hz and
NPAudioSampleRate48000Hz will always be supported.
int32 sampleType
Size and format of audio sample.
NPAudioSampleTypeInt16 will always be supported.
int32 outputChannelMap
Describes output channel mapping.
NPAudioChannelStereo will always be supported, regardless
of the physical speaker configuration.
NPAudioChannelNone describes no output will occur and
out_buffer on the callback will be NULL.
int32 inputChannelMap
Describes input channel layout.
NPAudioChannelNone describes no input will occur and
inBuffer on the callback will be NULL.
int32 sampleFrameCount
Requested sample frame count ranging from
NPAudioMinSampleFrameCount..NPAudioMaxSampleFrameCount.
The sample frame count will determine sample buffer size
and overall latency. Count value is in sample frames,
which are independent of the number of audio channels --
a single sample frame on a stereo device means one value
for the left channel and one value for the right channel.
int32 flags:
Reserved, set to 0.
callback
Pointer to application supplied callback function.
NULL: Audio context is initialized in blocking push
mode.
!NULL: Audio context is initialized in callback
mode.
void *userData
pointer to user data for callback. Can be NULL.
outputs:
NPAudioContext *context
Filled in, used to identify audio context.
returns:
NPERR_NO_ERROR
NPERR_INVALID_PARAM
notes:
Callable only from the NPAPI thread.
An application is free to always select either 44.1kHz or 48kHz.
In callback mode:
Audio context is initialized in the stopped state. Use
setStateContext(npp, NPAudioContextStateCallback,
NPAudioCallbackStart) to begin callbacks. Repeated callbacks
will occur until either setStateContext(npp,
NPAudioContextStateCallback, NPAudioCallbackStop) or
destroyContext(npp, context) is issued on the NPAPI thread.
In blocking push mode:
From a thread dedicated to audio, use flushContext(npp,
context) to push the contents of context->outBuffer and
context->inBuffer to and from the audio device.
</pre>
'''NPError setStateContext(NPP npp, NPAudioContext *context, int32 state, int32 value)'''
<pre>
        inputs:
NPP npp
Plug-in instance npp
NPAudioContext *context
audio context to apply state
int32 state
NPAudioContextStateCallback
Start & Stop playback when in callback mode. Audio
device will emit silence and callbacks will be suspended.
int32 value
returns:
NPERR_NO_ERROR
NPERR_INVALID_PARAM
NPERR_GENERIC_ERROR
notes:
Callable only from the NPAPI thread.
Use setStateContext(npp, context, NPAudioContextStateCallback,
NPAudioCallbackStart) to resume stopped playback.
When stopping, after a successful return value, no callbacks should
occur. If a pending callback is taking too long, this function
will fail with a return value of NPERR_GENERIC_ERROR.
After initialization in callback mode, an audio context will be in
the NPAudioCallbackStop state.
</pre>
'''NPError getStateContext(NPP npp, NPAudioContext *context, int32 state, int32 *value)'''
<pre>
inputs:
NPP npp
Plug-in instance npp
NPAudioContext *context
audio context to apply state
int32 state
new state value
NPAudioContextStateCallback
Get current state of callback.
NPAudioContextStateUnderrunCounter
Get current detectable underrun count since
initialization.
output:
int32 *value
returns:
NPERR_NO_ERROR
NPERR_INVALID_PARAM
notes:
Callable only from the NPAPI thread.
</pre>
'''NPError flushContext(NPP npp, NPAudioContext *context)'''
<pre>
        inputs:
NPP npp
For audio, this function is invoked from a non-NPAPI thread,
so npp is ignored.
NPAudioContext *context
context->outBuffer
pointer to output data. If this field is NULL, no output
(or silence) will occur.
context->inBuffer
pointer to input data. If this field is NULL, no input
will occur.
returns:
NPERR_NO_ERROR
NPERR_INVALID_PARAM
NPERR_GENERIC_ERROR
notes:
This is a blocking call. Data in context->outBuffer is streamed to
the audio device. The call then blocks until the audio device is
ready to receive the next buffer payload. If the audio device does
not receive data within a certain time frame, it will begin to emit
silence. For an application to emit continuous audio without gaps
of silence, it will need to perform a minimal amount of computation
between consecutive flushDevice() calls on a priority boosted
dedicated audio thread. If the audio device is initialized with
both input channel(s) and output channel(s), audio can stream
isochronously on the same flushContext() call.
In the case of audio, it is highly recommend not to make this call
from the NPAPI thread.
If the audio device was initialized in callback mode,
flushContext() will do nothing and return NPERR_GENERIC_ERROR
If the audio device is in blocking push mode and
destroyContext(npp, context) is performed in the NPAPI thread,
pending blocking flushContext calls will return with
NPERR_GENERIC_ERROR.
</pre>
'''NPError destroyContext(NPP npp, NPAudioContext *context)'''
<pre>
        inputs:
NPP npp
Plug-in instance npp
NPAudioContext context
audio context to shutdown
returns:
NPERR_NO_ERROR
NPERR_INVALID_PARAM
notes:
callback mode:
Waits for pending callback (if applicable) to complete (or
times out) Upon return from shutdown, no further callbacks
will occur.
blocking push mode:
Does _not_ automatically terminate pending blocking
flushContext() calls occuring other threads. It is highly
recommended that other threads suspend calls to flushContext()
_before_ invoking destroyContext(npp, context).
other:
Callable only from the NPAPI thread. Application's
responsibility to cleanly bring down audio before Shutdown to
avoid clicks / pops.
</pre>
'''void (NPAudioCallback *)(NPAudioContext *context);'''
<pre>
        inputs:
NPAudioContext context
Audio context that generated this callback. Fields within the
context
context->config.sampleFrameCount
Number of sample frames to write into buffers. This will
always be the obtained sample frame count returned at
initialization. An application should never write more
than sample_frame_count sample frames. An application
should avoid writing fewer than sample_frame_count sample
frames. Sample frame count is independent of the number
of channels. A sample frame count of 1 on a stereo
device means write one left channel sample, and one right
channel sample.
context->outBuffer
Pointer to output sample buffer, channels are
interleaved.
For a stereo int16 configuration:
int16 *buffer16 = (int16 *)buffer;
buffer16[0] is the first left channel sample
buffer16[1] is the first right channel sample
buffer16[2] is the second left channel sample
buffer16[3] is the second right channel sample
Data will always be in the native endian format of
the platform.
context->inBuffer
audio input data, NULL if no input.
in_buffer and out_buffer will have the same sample rate,
sample type, and sample frame count. Only the number of
channels can differ (note that the channel format
determines how data is interleaved.)
context->userData
Void pointer to user data (same pointer supplied during
initialization) Can be NULL.
notes:
Callbacks occur on thread(s) other than the NPAPI thread. Deliver
audio data to the buffer(s) in a timely fashion to avoid
underruns. Do not make NPAPI calls from the callback function.
Avoid calling functions that might cause the OS scheduler to
transfer execution, such as sleep(). Callbacks will not occur
after return from Shutdown. If the audio device is initialized
with both input channel(s) and output channel(s), audio can stream
isochronously on the same callback.
</pre>
</pre>
11

edits

Navigation menu