MixAudio

MixAudio — Object to support a single stream playback using hardware accelerated decoder.

Synopsis


#include <mixaudio.h>

enum                MixStreamState;
enum                MixState;
enum                MixCodecMode;
enum                MixVolType;
enum                MixVolRamp;
                    MixIOVec;
enum                MixDeviceState;
                    MixAudio;
MixAudio *          mix_audio_new                       (void);
MixAudio *          mix_audio_ref                       (MixAudio *mix);
#define             mix_audio_unref                     (obj)
MIX_RESULT          mix_audio_get_version               (guint *major,
                                                         guint *minor);
MIX_RESULT          mix_audio_initialize                (MixAudio *mix,
                                                         MixCodecMode mode,
                                                         MixAudioInitParams *aip,
                                                         MixDrmParams *drminitparams);
MIX_RESULT          mix_audio_configure                 (MixAudio *mix,
                                                         MixAudioConfigParams *audioconfigparams,
                                                         MixDrmParams *drmparams);
MIX_RESULT          mix_audio_decode                    (MixAudio *mix,
                                                         const MixIOVec *iovin,
                                                         gint iovincnt,
                                                         guint64 *insize,
                                                         MixIOVec *iovout,
                                                         gint iovoutcnt,
                                                         guint64 *outsize);
MIX_RESULT          mix_audio_capture_encode            (MixAudio *mix,
                                                         MixIOVec *iovout,
                                                         gint iovoutcnt);
MIX_RESULT          mix_audio_start                     (MixAudio *mix);
MIX_RESULT          mix_audio_stop_drop                 (MixAudio *mix);
MIX_RESULT          mix_audio_stop_drain                (MixAudio *mix);
MIX_RESULT          mix_audio_pause                     (MixAudio *mix);
MIX_RESULT          mix_audio_resume                    (MixAudio *mix);
MIX_RESULT          mix_audio_get_timestamp             (MixAudio *mix,
                                                         guint64 *msecs);
MIX_RESULT          mix_audio_set_mute                  (MixAudio *mix,
                                                         gboolean mute);
MIX_RESULT          mix_audio_get_mute                  (MixAudio *mix,
                                                         gboolean *muted);
MIX_RESULT          mix_audio_get_max_vol               (MixAudio *mix,
                                                         gint *maxvol);
MIX_RESULT          mix_audio_get_min_vol               (MixAudio *mix,
                                                         gint *minvol);
MIX_RESULT          mix_audio_get_volume                (MixAudio *mix,
                                                         gint *currvol,
                                                         MixVolType type);
MIX_RESULT          mix_audio_set_volume                (MixAudio *mix,
                                                         gint currvol,
                                                         MixVolType type,
                                                         gulong msecs,
                                                         MixVolRamp ramptype);
MIX_RESULT          mix_audio_deinitialize              (MixAudio *mix);
MIX_RESULT          mix_audio_get_stream_state          (MixAudio *mix,
                                                         MixStreamState *streamState);
MIX_RESULT          mix_audio_get_state                 (MixAudio *mix,
                                                         MixState *state);
gboolean            mix_audio_am_is_enabled             (MixAudio *mix);
MIX_RESULT          mix_audio_is_am_available           (MixAudio *mix,
                                                         MixAudioManager am,
                                                         gboolean *avail);
MIX_RESULT          mix_audio_get_output_configuration  (MixAudio *mix,
                                                         MixAudioConfigParams **audioconfigparams);
MIX_RESULT          mix_audio_get_stream_byte_decoded   (MixAudio *mix,
                                                         guint64 *byte);

Object Hierarchy

  GObject
   +----MixAudio

Description

MixAudio object provide thread-safe API for application and/or multimedia framework to take advantage of Intel Smart Sound Technology(TM) driver for hardware audio decode and render.

Each MixAudio object represents one streaming session with the Intel Smart Sound driver and provides configuration and control of the decoding and playback options.

The MixAudio object also support integration with Intel Audio Manager service.

An application can utilize the MixAudio object by calling the following sequence:

  1. mix_audio_new() to create a MixAudio instance.
  2. mix_audio_initialize() to allocate Intel Smart Sound Technology resource.
  3. mix_audio_configure() to configure stream parameters.
  4. mix_audio_decode() can be called repeatedly for decoding and, optionally, rendering.
  5. mix_audio_start() is called after the 1st mix_audio_decode() method to start rendering.
  6. mix_audio_stop_drain() is called after the last buffer is passed for decoding in with mix_audio_decode().
  7. mix_audio_deinitialize() to free resource once playback is completed.

Since mix_audio_decode() is a blocking call during playback, the following methods are called in a seperate thread to control progress:

Details

enum MixStreamState

typedef enum {
  MIX_STREAM_NULL=0,
  MIX_STREAM_STOPPED,
  MIX_STREAM_PLAYING,
  MIX_STREAM_PAUSED,
  MIX_STREAM_DRAINING,
  MIX_STREAM_LAST
} MixStreamState;

Stream State during Decode and Render or Encode mode. These states do not apply to Decode and Return mode.

MIX_STREAM_NULL

Stream is not allocated.

MIX_STREAM_STOPPED

Stream is at STOP state. This is the only state DNR is allowed.

MIX_STREAM_PLAYING

Stream is at Playing state.

MIX_STREAM_PAUSED

Stream is Paused.

MIX_STREAM_DRAINING

Stream is draining -- remaining of the buffer in the device are playing. This state is special due to the limitation that no other control operations are allowed at this state. Stream will become MIX_STREAM_STOPPED automatically when this data draining has completed.

MIX_STREAM_LAST

Last index in the enumeration.

enum MixState

typedef enum {
  MIX_STATE_NULL=0,
  MIX_STATE_UNINITIALIZED,
  MIX_STATE_INITIALIZED,
  MIX_STATE_CONFIGURED,
  MIX_STATE_LAST
} MixState;

The varies states the device is in.

MIX_STATE_NULL

MIX_STATE_UNINITIALIZED

MIX is not initialized.

MIX_STATE_INITIALIZED

MIX is initialized.

MIX_STATE_CONFIGURED

MIX is configured successfully.

MIX_STATE_LAST

Last index in the enumeration.

enum MixCodecMode

typedef enum {
  MIX_CODING_INVALID=0,
  MIX_CODING_ENCODE,
  MIX_CODING_DECODE,
  MIX_CODING_LAST
} MixCodecMode;

Mode where device is operating on. See mix_audio_initialize().

MIX_CODING_INVALID

Indicates device uninitialied for any mode.

MIX_CODING_ENCODE

Indicates device is opened for encoding.

MIX_CODING_DECODE

Indicates device is opened for decoding.

MIX_CODING_LAST

Last index in the enumeration.

enum MixVolType

typedef enum {
  MIX_VOL_PERCENT=0,
  MIX_VOL_DECIBELS,
  MIX_VOL_LAST
} MixVolType;

See mix_audio_getvolume() and mix_audio_setvolume().

MIX_VOL_PERCENT

volume is expressed in percentage.

MIX_VOL_DECIBELS

volume is expressed in decibel.

MIX_VOL_LAST

last entry.

enum MixVolRamp

typedef enum 
{
  MIX_RAMP_LINEAR = 0,
  MIX_RAMP_EXPONENTIAL,
  MIX_RAMP_LAST
} MixVolRamp;

See mix_audio_getvolume() and mix_audio_setvolume().

MIX_RAMP_LINEAR

volume is expressed in percentage.

MIX_RAMP_EXPONENTIAL

volume is expressed in decibel.

MIX_RAMP_LAST

last entry.

MixIOVec

typedef struct {
  guchar *data;
  gint size;
} MixIOVec;

Scatter-gather style structure. To be used by mix_audio_decode() method for input and output buffer.

guchar *data;

data pointer

gint size;

size of buffer in data

enum MixDeviceState

typedef enum {
  MIX_AUDIO_DEV_CLOSED=0,
  MIX_AUDIO_DEV_OPENED,
  MIX_AUDIO_DEV_ALLOCATED
} MixDeviceState;

Device state.

MIX_AUDIO_DEV_CLOSED

TBD

MIX_AUDIO_DEV_OPENED

TBD

MIX_AUDIO_DEV_ALLOCATED

TBD

MixAudio

typedef struct {
  GObject parent;
} MixAudio;

MI-X Audio object

GObject parent;

Parent object.

mix_audio_new ()

MixAudio *          mix_audio_new                       (void);

Use this method to create new instance of MixAudio

returns :

A newly allocated instance of MixAudio

mix_audio_ref ()

MixAudio *          mix_audio_ref                       (MixAudio *mix);

Add reference count.

mix :

object to add reference

returns :

the MixAudio instance where reference count has been increased.

mix_audio_unref()

#define mix_audio_unref(obj) g_object_unref (G_OBJECT(obj))

Decrement reference count of the object.

obj :

object to unref.

mix_audio_get_version ()

MIX_RESULT          mix_audio_get_version               (guint *major,
                                                         guint *minor);

Returns the version of the MI-X library.

returns :

MIX_RESULT_SUCCESS

mix_audio_initialize ()

MIX_RESULT          mix_audio_initialize                (MixAudio *mix,
                                                         MixCodecMode mode,
                                                         MixAudioInitParams *aip,
                                                         MixDrmParams *drminitparams);

This function will initialize an encode or decode session with this MixAudio instance. During this call, the device will be opened. If the device is not available, an error is returned to the caller so that an alternative (e.g. software decoding) can be configured instead. Use mix_audio_deinitialize() to close the device.

A previous initialized session must be de-initialized using mix_audio_deinitialize() before it can be initialized again.

mix :

MixAudio object.

mode :

Requested MixCodecMode.

aip :

Audio initialization parameters.

drminitparams :

Optional. DRM initialization param if applicable.

returns :

MIX_RESULT_SUCCESS on successful initilaization. MIX_RESULT_ALREADY_INIT if session is already initialized.

mix_audio_configure ()

MIX_RESULT          mix_audio_configure                 (MixAudio *mix,
                                                         MixAudioConfigParams *audioconfigparams,
                                                         MixDrmParams *drmparams);

This function can be used to configure a stream for the current session. The caller can use this function to do the following:

  • Choose decoding mode (direct-render or decode-return)
  • Provide DRM parameters (using DRMparams object)
  • Provide stream parameters (using STRMparams objects)
  • Provide a stream name for the Intel Smart Sound Technology stream

SST stream parameters will be set during this call, and stream resources allocated in SST.

Intel Audio Manager support:

If Intel Audio Manager support is enabled, and if mode is specified to MIX_DECODE_DIRECTRENDER, the SST stream will be registered with Intel Audio Manager in the context of this call, using the stream name provided in streamname. Application will receive a notification from Intel Audio Manager that the stream has been created during or soon after this call. The application should be ready to handle either possibility. A stream ID (associated with the stream name) will be provided by Intel Audio Manager which will be used for subsequent notifications from Intel Audio Manager or calls to Intel Audio Manager for muting, pause and resume. See mix_audio_getstreamid()

If a stream is already registered with Intel Audio Manager, application must pass the same streamname argument to retain the session. Otherwise, the existing stream will be unregistered and a new stream will be registered with the new streamname.

If mode is specified to MIX_DECODE_DIRECTRENDER but direct-render mode is not available (due to end user use of alternative output device), an error indication will be returned to the caller so that an alternate pipeline configuration can be created (e.g. including a Pulse Audio sink, and support for output buffers). In this case, the caller will need to call mix_audio_configure() again to with mode specify as MIX_DECODE_DECODERETURN to request decode-return mode.

This method can be called multiple times if reconfiguration of the stream is needed. However, this method must be called when the stream is in MIX_STREAM_STOPPED state.

mix :

MixAudio object.

audioconfigparams :

a MixAudioConfigParams derived object containing information for the specific stream type.

drmparams :

Optional. DRM initialization param if applicable.

returns :

Result indicates successful or not.

mix_audio_decode ()

MIX_RESULT          mix_audio_decode                    (MixAudio *mix,
                                                         const MixIOVec *iovin,
                                                         gint iovincnt,
                                                         guint64 *insize,
                                                         MixIOVec *iovout,
                                                         gint iovoutcnt,
                                                         guint64 *outsize);

This function is used to initiate HW accelerated decoding of encoded data buffers. This function may be used in two major modes, direct-render or decode-return.

With direct-render, input buffers are provided by the caller which hold encoded audio data, and no output buffers are provided. The encoded data is decoded, and the decoded data is sent directly to the output speaker. This allows very low power audio rendering and is the best choice of operation for longer battery life.

Intel Audio Manager Support

However, if the user has connected a different target output device, such as Bluetooth headphones, this mode cannot be used as the decoded audio must be directed to the Pulse Audio stack where the output to Bluetooth device can be supported, per Intel Audio Manager guidelines. This mode is called decode-return, and requires the caller to provide output buffers for the decoded data.

Input buffers in both modes are one or more user space buffers using a scatter/gather style vector interface.

Output buffers for the decode-return mode are one or more user space buffers in a scatter style vector interface. Buffers will be filled in order and lengths of data filled will be returned.

This call will block until data has been completely copied or queued to the driver. All user space buffers may be used or released when this call returns.

Note: If the stream is configured as MIX_DECODE_DIRECTRENDER, and whenever the stream in MIX_STREAM_STOPPED state, the call to mix_audio_decode() will not start the playback until mix_audio_start() is called. This behavior would allow application to queue up data but delay the playback until appropriate time.

mix :

MixAudio object.

iovin :

a pointer to an array of MixIOVec structure that contains the input buffers

iovincnt :

the number of entry in the iovin array

iovout :

a pointer to an arrya of MixIOVec structure that represent the output buffer. During input, each size in the MixIOVec array represents the available buffer size pointed to by data. Upon return, each size value will be updated to reflect how much data has been filled. This parameter is ignored if stream is configured to MIX_DECODE_DIRECTRENDER. See mix_audio_configure() for more detail.

iovoutcnt :

in/out parameter which when input, it contains the number of entry available in the iovout array. Upon return, this value will be updated to reflect how many entry in the iovout array has been populated with data. This parameter is ignored if stream is configured to MIX_DECODE_DIRECTRENDER. See mix_audio_configure() for more detail.

outsize :

Total number of bytes returned for the decode session. This parameter is ignored if stream is configured to MIX_DECODE_DIRECTRENDER.

returns :

MIX_RESULT

mix_audio_capture_encode ()

MIX_RESULT          mix_audio_capture_encode            (MixAudio *mix,
                                                         MixIOVec *iovout,
                                                         gint iovoutcnt);

To read encoded data from device.

NOTE: May need to rename to "read_encoded" or other name. Since "encode" seems to mean taking raw audio and convert to compressed audio.

mix :

MixAudio object.

iovout :

Capture audio samples.

iovoutcnt :

Number of entry in the input vector iovout.

returns :

MIX_RESULT

mix_audio_start ()

MIX_RESULT          mix_audio_start                     (MixAudio *mix);

If the stream is configured to MIX_DECODE_DIRECTRENDER, application use this call to change the stream out of the MIX_STREAM_STOPPED state. If mix_audio_decode() is called and blocking in a seperate thread prior to this call. This method causes the device to start rendering data.

In MIX_DECODE_DECODERETURN, this method is no op.

mix :

MixAudio object.

returns :

MIX_RESULT_SUCCESS if the resulting state is either MIX_STREAM_PLAYING or MIX_STREAM_PAUSED. Fail code otherwise.

mix_audio_stop_drop ()

MIX_RESULT          mix_audio_stop_drop                 (MixAudio *mix);

If the stream is configured to MIX_DECODE_DIRECTRENDER, application uses this function to stop the processing and playback of audio.

All remaining frames to be decoded or rendered will be discarded and playback will stop immediately, unblocks any pending mix_audio_decode().

If MIX_STOP_DRAIN is requested, the call will block with stream state set to MIX_STREAM_DRAINING, and return only until all remaining frame in previously submitted buffers are decoded and rendered. When MIX_STOP_DRAIN returns successfully, the stream would have reached MIX_STREAM_STOPPED successfully.

After this call, timestamp retrived by mix_audio_gettimestamp() is reset to zero.

Note that this method returns MIX_RESULT_WRONG_STATE if the stream is in MIX_STREAM_DRAINING state.

mix :

MixAudio object.

returns :

MIX_RESULT_SUCCESS if the resulting state has successfully reached MIX_STREAM_STOPPED. Fail code otherwise.

mix_audio_stop_drain ()

MIX_RESULT          mix_audio_stop_drain                (MixAudio *mix);

If the stream is configured to MIX_DECODE_DIRECTRENDER, application uses this function to stop the processing and playback of audio.

The call will block with stream state set to MIX_STREAM_DRAINING, and return only until all remaining frame in previously submitted buffers are decoded and rendered.

Note that this method blocks until MIX_STREAM_STOPPED is reached if it is called when the stream is already in MIX_STREAM_DRAINING state.

mix :

MixAudio object.

returns :

MIX_RESULT_SUCCESS if the resulting state has successfully reached MIX_STREAM_STOPPED. Fail code otherwise.

mix_audio_pause ()

MIX_RESULT          mix_audio_pause                     (MixAudio *mix);

If the stream is configured to MIX_DECODE_DIRECTRENDER, application uses this call to change the stream state from MIX_STREAM_PLAYING to MIX_STREAM_PAUSED. Note that this method returns sucessful only when the resulting state reaches MIX_STREAM_PAUSED. Meaning it will return fail code if it is called in a state such as MIX_STREAM_STOPPED, where transitioning to MIX_STREAM_PAUSED is not possible.

In some situation, where there is potential race condition with the DRAINING operation, this method may return MIX_RESULT_NEED_RETRY to indicate last operation result is inclusive and request caller to call again.

mix :

MixAudio object.

returns :

MIX_RESULT_SUCCESS if MIX_STREAM_PAUSED state is reached successfully. MIX_RESULT_WRONG_STATE if operation is not allowed with the current state.

mix_audio_resume ()

MIX_RESULT          mix_audio_resume                    (MixAudio *mix);

If the stream is configured to MIX_DECODE_DIRECTRENDER, application uses this call to change the stream state to MIX_STREAM_PLAYING. Note that this method returns sucessful only when the resulting state reaches MIX_STREAM_PAUSED. Meaning it will return fail code if it is called in a state such as MIX_STREAM_DRAINING, where transitioning to MIX_STREAM_PLAYING is not possible.

mix :

MixAudio object.

returns :

MIX_RESULT_SUCCESS if MIX_STREAM_PLAYING state is reached successfully. MIX_RESULT_WRONG_STATE if operation is not allowed with the current state.

mix_audio_get_timestamp ()

MIX_RESULT          mix_audio_get_timestamp             (MixAudio *mix,
                                                         guint64 *msecs);

This function can be used to retrieve the current timestamp for audio playback in milliseconds. The timestamp will reflect the amount of audio data rendered since the start of stream, or since the last stop. Note that the timestamp is always reset to zero when the stream enter MIX_STREAM_STOPPED state. The timestamp is an unsigned long value, so the value will wrap when the timestamp reaches ULONG_MAX. This function is only valid in direct-render mode.

mix :

MixAudio object.

msecs :

play time in milliseconds.

returns :

MIX_RESULT_SUCCESS if the timestamp is available. MIX_RESULT_WRONG_MODE if operation is not allowed with the current mode.

mix_audio_set_mute ()

MIX_RESULT          mix_audio_set_mute                  (MixAudio *mix,
                                                         gboolean mute);

This function is used to mute and unmute audio playback. While muted, playback would continue but silently. This function is only valid when the session is configured to MIX_DECODE_DIRECTRENDER mode.

Note that playback volumn may change due to change of global settings while stream is muted.

mix :

MixAudio object.

mute :

Turn mute on/off.

returns :

MIX_RESULT_SUCCESS on success or other fail code.

mix_audio_get_mute ()

MIX_RESULT          mix_audio_get_mute                  (MixAudio *mix,
                                                         gboolean *muted);

Get Mute.

mix :

MixAudio object.

muted :

current mute state.

returns :

MIX_RESULT_SUCCESS on success or other fail code.

mix_audio_get_max_vol ()

MIX_RESULT          mix_audio_get_max_vol               (MixAudio *mix,
                                                         gint *maxvol);

This function can be used if the application will be setting the audio volume using decibels instead of percentage. The maximum volume in decibels supported by the driver will be returned. This value can be used to determine the upper bound of the decibel range in calculating volume levels. This value is a signed integer. This function is only valid if stream is configured to MIX_DECODE_DIRECTRENDER mode.

mix :

MixAudio object.

maxvol :

pointer to receive max volumn.

returns :

MIX_RESULT_SUCCESS on success or other fail code.

mix_audio_get_min_vol ()

MIX_RESULT          mix_audio_get_min_vol               (MixAudio *mix,
                                                         gint *minvol);

This function can be used if the application will be setting the audio volume using decibels instead of percentage. The minimum volume in decibels supported by the driver will be returned. This value can be used to determine the lower bound of the decibel range in calculating volume levels. This value is a signed integer. This function is only valid if stream is configured to MIX_DECODE_DIRECTRENDER mode.

mix :

MixAudio object.

minvol :

pointer to receive max volumn.

returns :

MIX_RESULT_SUCCESS on success or other fail code.

mix_audio_get_volume ()

MIX_RESULT          mix_audio_get_volume                (MixAudio *mix,
                                                         gint *currvol,
                                                         MixVolType type);

This function returns the current volume setting in either decibels or percentage. This function is only valid if stream is configured to MIX_DECODE_DIRECTRENDER mode.

mix :

MixAudio object.

currvol :

Current volume. Note that if type equals MIX_VOL_PERCENT, this value will be return within the range of 0 to 100 inclusive.

type :

The type represented by currvol.

returns :

MIX_RESULT_SUCCESS on success or other fail code.

mix_audio_set_volume ()

MIX_RESULT          mix_audio_set_volume                (MixAudio *mix,
                                                         gint currvol,
                                                         MixVolType type,
                                                         gulong msecs,
                                                         MixVolRamp ramptype);

This function sets the current volume setting in either decibels or percentage. This function is only valid if the stream is configured to MIX_DECODE_DIRECTRENDER mode.

mix :

MixAudio object.

currvol :

Current volume. Note that if type equals MIX_VOL_PERCENT, this value will be trucated to within the range of 0 to 100 inclusive.

type :

The type represented by currvol.

returns :

MIX_RESULT_SUCCESS on success or other fail code.

mix_audio_deinitialize ()

MIX_RESULT          mix_audio_deinitialize              (MixAudio *mix);

This function will uninitialize a session with this MI-X instance. During this call, the SST device will be closed and resources including mmapped buffers would be freed.This function should be called by the application once mix_audio_init() has been called.

Intel Audio Manager Support

The SST stream would be unregistered with Intel Audio Manager if it was registered.

Note that if this method should not fail normally. If it does return failure, the state of this object and the underlying mechanism is compromised and application should not attempt to reuse this object.

mix :

MixAudio object.

returns :

MIX_RESULT_SUCCESS on success or other fail code.

mix_audio_get_stream_state ()

MIX_RESULT          mix_audio_get_stream_state          (MixAudio *mix,
                                                         MixStreamState *streamState);

Get the stream state of the current stream.

mix :

MixAudio object.

streamState :

pointer to receive stream state.

returns :

MIX_RESULT

mix_audio_get_state ()

MIX_RESULT          mix_audio_get_state                 (MixAudio *mix,
                                                         MixState *state);

Get the device state of the audio session.

mix :

MixAudio object.

state :

pointer to receive state

returns :

Current device state.

mix_audio_am_is_enabled ()

gboolean            mix_audio_am_is_enabled             (MixAudio *mix);

This method checks if the current session is configure to use Intel Audio Manager. Note that Intel Audio Manager is considered disabled if the stream has not be initialized to use the service explicitly.

mix :

MixAudio object.

returns :

boolean indicates if Intel Audio Manager is enabled with the current session.

mix_audio_is_am_available ()

MIX_RESULT          mix_audio_is_am_available           (MixAudio *mix,
                                                         MixAudioManager am,
                                                         gboolean *avail);

Check if AM is available.

mix :

TBD

am :

TBD

avail :

TBD

returns :

TBD

mix_audio_get_output_configuration ()

MIX_RESULT          mix_audio_get_output_configuration  (MixAudio *mix,
                                                         MixAudioConfigParams **audioconfigparams);

This method retrieve the current configuration. This can be called after initialization. If a stream has been configured, it returns the corresponding derive object of MixAudioConfigParams.

mix :

MixAudio object.

audioconfigparams :

double pointer to hold output configuration.

returns :

MIX_RESULT_SUCCESS on success or other fail code.

mix_audio_get_stream_byte_decoded ()

MIX_RESULT          mix_audio_get_stream_byte_decoded   (MixAudio *mix,
                                                         guint64 *byte);

Retrive the culmulative byte decoded.

Not Implemented.

mix :

MixAudio object.

msecs :

stream byte decoded..

returns :

MIX_RESULT_SUCCESS if the value is available. MIX_RESULT_WRONG_MODE if operation is not allowed with the current mode.