Haptics API
Changes in Haptics API documentation
Changes in Haptics API
Purpose
With the Haptics API it is possible to produce haptic effects and
control their behavior in the device. E.g., playing an explosion effect
in a game with the device's vibration feature allows the user to feel
the haptic feedback in his hand. The purpose of this API is to provide
developers an easy way to create and use haptic effects. This API
provides application developers a unified interface across different
products. The actual physical vibration and/or motion depends on the
settings and the device's configuration. This document is valid from
release 5.1 onwards.
There are also a few related APIs:
-
Tactile Feedback API is used to produce simple haptic feedback,
e.g., from UI controls.
-
Tacticons API is used to play tacticons.
Both of these APIs use the Haptics API to play the actual effects.
Often, in order to produce just simple haptic effects, it is recommended
to use these two APIs instead of the Haptics API directly.
In addition, the Vibra API is available for even simpler vibration
effects.
Constraints
-
This API is valid for all devices running on Symbian OS, S60
5.1 or later releases.
-
Periodic effects accurately produce vibration frequencies up to
ca. 30 Hz, depending on the device.
-
Depending on the device, only a subset of all possible logical
actuators can be supported.
Classification and release information
This API is an SDK API and was first published for Symbian OS,
S60 5.1.
Emulator support
The Haptics API has limited support in the WINS/WINSCW emulator
environment. Obviously, it is not possible to feel the physical vibrations
in emulator environment. In target environment, the adaptation layer
plug-in dispatches various haptics-related requests and responses
between the API and physical vibration device driver service. In emulator
environment, the plug-in is just a stub that emulates successful functionality.
API description
The Haptics API provides methods for controlling the haptics feature
of the device. Both synchronous and asynchronous versions are provided
for playing various types of effects. Only synchronous methods are
provided for other functionalities, such as opening and closing an
actuator, reserving and releasing the haptics feature, and for getting
various state and system information from the haptics. This API is
meant for any application that needs to control the device's haptics
feature.
The Haptics API is a Library API that has been implemented using
the client-server architecture. Most of the processing is done on
the server side, the client side acting mostly as a message passing
proxy. However, there is a cache of loaded effect data that is handled
in the client side.
The Haptics API does not require any platform security capabilities.
Use cases
The most common use cases are listed below:
Initialization
-
Enquiring which logical actuators are supported by the device
-
Opening a supported logical actuator
-
Enquiring the capabilities of an actuator
-
Setting the license key
Playing the effects
-
Playing magnitude sweep effects
-
Playing periodic effects
-
Playing all kinds of effects (including timeline effects) that
are defined in an effect data buffer read, for example, from a file
-
Repeating effects (applicable for timeline effects)
-
Creating and playing streaming effects
-
Playing multiple effects at the same time
-
Pausing and resuming the playing of effects
-
Stopping a specific effect or all effects that are playing
-
Enquiring the state of the effects (whether playing, paused or
not playing)
Using two or more haptics instances
-
Automatic priority handling via setting the priority level of
the client when using the same logical actuator
-
Playing multiple effects via different haptics instances
-
Reserving, and later releasing, the haptics feature for exclusive
use
Effects defined in effect data buffers
-
Loading one or more effect data buffers for simultaneous use
-
Enquiring information about effects that have been defined within
the loaded effect data buffer(s)
-
Deleting/unloading effect data buffers after use
API class structure
The client creates an instance of the Haptics API's main class
CHWRMHaptics
. If a callback interface is required, the client
must implement the appropriate M class and provide a pointer to the
corresponding implementation object when instantiating the
CHWRMHaptics
object. The
THWRMLogicalActuators
enumeration lists the available logical actuators. Some of the logical
actuators listed in the enumeration may not be supported in a particular
device. Therefore, before trying to open an actuator, the developer
must check which logical actuators are actually supported in the device.
Related APIs
-
CHWRMHaptics
-
THWRMLogicalActuators
Using the Haptics API
In general, using the API consists of the following steps:
-
Link the Haptics library (
hwrmhapticsclient.lib
) to the
client application.
-
Instantiate an instance of the
CHWRMHaptics
class
using the
NewL()
static method.
Give pointers to
objects that implement the
MHWRMHapticsObserver
and
MHWRMHapticsActuatorObserver
abstract interfaces to
NewL()
if you want to use observers for haptics-related
notifications.
Get a bitmask of supported logical actuators by calling
SupportedActuators()
.
Open a supported logical actuator by calling
OpenActuatorL()
.
Set the license key by calling
SetDeviceProperty()
with the
EHWRMHapticsLicensekey
property.
After the above steps, the rest of the haptics functionality is
ready to be used. This includes playing various types of effects,
loading effect definitions (from effect data buffers), enquiring actuator
capabilities, modifying the effects, etc.
More detailed instructions for using the API are given in the following
sections.
Preparing Haptics API for use
The Haptics API must be initialized by following these steps.
If these steps are not followed, the API is unusable as most methods
fail and return either
KErrNotReady
or
KErrAccessDenied
error code.
To use all methods of the API, the client must open a logical actuator
that is supported in the system and must set a valid license key.
Instantiating with and without observers
First the developer must create an instance of the haptics by calling
the static
NewL()
method. The
NewL()
method takes pointers to
MHWRMHapticsObserver
and
MHWRMHapticsActuatorObserver
as arguments. These can be
set to
NULL
if the developer does not want to observe
haptics-related status change notifications.
// CMyClass example myclass.h file
#include <hwrmhaptics.h>
class CMyClass : public MHWRMHapticsObserver, MHWRMHapticsActuatorObserver
{
public:
static CMyClass NewL();
~CMyClass();
public:
/**
* Inherited from MHWRMHapticsObserver
*/
/**
* Notification of status changes of the haptics feature itself
* such as e.g. EHWRMHapticsStatusOn or EHWRMHapticsStatusStopped
*/
void HapticsStatusChangedL( THWRMHapticsStatus aStatus );
/**
* Notification of the completion of playing of an effect
*/
void EffectCompletedL( TInt aError, TInt aEffectHandle );
public:
/**
* Inherited from MHWRMHapticsActuatorObserver
*/
/**
* Notification of logical actuator related event. Currently
* there are events defined for attaching an actuator,
* detaching an actuator, and for enabling and disabling one
*/
void ActuatorEventL( THWRMActuatorEvents aEvent, THWRMLogicalActuators aActuator );
private:
CMyClass();
void ConstructL();
void InitializeActuatorL( const TDesC8& aLicenseKey );
private:
CHWRMHaptics* iHaptics;
};
// ...
// ------------------------------------------
// CMyClass example *.cpp file
#include "myclass.h"
void CMyClass::ConstructL()
{
// Instantiating with no observers
iHaptics = CHWRMHaptics::NewL( NULL, NULL );
// Example for instantiating with haptics status observer
CHWRMHaptics* haptics1 = CHWRMHaptics::NewL( this, NULL );
CleanupStack::PushL( haptics1 );
// Example for instantiating with both haptics status observer and actuator observer
CHWRMHaptics* haptics2 = CHWRMHaptics::NewL( this, this );
CleanupStack::PushL( haptics2 );
// ...
CleanupStack::PopAndDestroy( haptics2 );
CleanupStack::PopAndDestroy( haptics1 );
}
Related APIs
-
MHWRMHapticsActuatorObserver
-
MHWRMHapticsObserver
-
NULL
-
NewL()
Checking supported logical actuators
Checking which logical actuators are supported in the device is
done by calling the
SupportedActuators()
method.
As a parameter, the method takes a reference to a
TUint32
variable, which contains a bitmask of supported logical actuators.
The bitmask is populated using
THWRMLogicalActuators
enumerations, and can be evaluated using bitwise operators with
these enumerations. An example is shown below.
...
// Variable for receiving the bitmask of logical actuators supported in the device.
TUint32 suppActuators( 0 );
User::LeaveIfError( iHaptics->SupportedActuators( suppActuators ) );
// Check the returned bitmask against logical actuators enumerations
// and choose the most suitable for the given application, e.g.
if ( EHWRMLogicalActuatorGame & suppActuators )
{
// Open the most suitable supported actuator (see next section)
}
else if ( EHWRMLogicalActuatorDevice & suppActuators )
{
// Open the second most suitable supported actuator
}
// etc.
Related APIs
-
SupportedActuators()
-
THWRMLogicalActuators
-
TUint32
Opening a supported logical actuator
Opening the actuator is done by calling the
OpenActuatorL()
method. Immediately after opening an actuator, it is necessary to
set a license key for the haptics in order to unlock the Haptics API's
full functionality. The license key is set by calling the
SetDeviceProperty()
method for the
EHWRMHapticsLicensekey
property. The property value must be set to a platform-dependent
license key issued by Forum Nokia.
// Note: License keys are 32 bytes long data buffers of TUint8 data
void CMyClass::InitializeActuatorL( const TDesC8& aLicenseKey )
{
// open a supported logical actuator
iHaptics->OpenActuatorL( EHWRMLogicalActuatorGame );
// set the license key for the opened logical actuator
TInt licenseErr( 0 );
licenseErr = iHaptics->SetDeviceProperty( CHWRMHaptics::EHWRMHapticsLicensekey, aLicenseKey );
if( licenseErr == KErrAccessDenied )
{
// the license key was wrong
}
}
Related APIs
-
EHWRMHapticsLicensekey
-
OpenActuatorL()
-
SetDeviceProperty()
Checking the capabilities of a supported logical actuator
In some cases the application may need to enquire the capabilities
of an actuator. For example, it needs to take specific actions depending
on, e.g., such capabilities as the number of effect slots or the minimum
period for periodic effects.
The capabilities of a supported logical actuator are checked by
calling the
GetDeviceCapability()
method with one
of the
THWRMHapticsDeviceCapabilityTypes
enumerations
as the first parameter. A reference to a variable into which the returned
capability value is to be stored is given as the second parameter.
Depending on the capability in question, the returned capability value
can be an integer or a descriptor containing an 8-bit data buffer.
The
GetDeviceCapability()
method has overloaded versions
where the second parameter is either a
TInt&
reference
or a
TDes8&
reference.
// Example: fetching the actuator's minimum period value and name
TInt minPeriod( 0 ); // variable to receive the mimimun period for periodic effects
User::LeaveIfError( iHaptics->GetDeviceCapability( CHWRMHaptics::EHWRMHapticsMinPeriod, minPeriod ) );
RBuf8 name;
name.CreateL( iHaptics->MaxDeviceNameLength() );
CleanupClosePushL( name );
User::LeaveIfError( iHaptics->GetDeviceCapability( CHWRMHaptics::EHWRMHapticsDeviceName, name ) );
// ...
CleanupStack::PopAndDestroy( &name );
Related APIs
-
GetDeviceCapability()
-
TDes8&
-
THWRMHapticsDeviceCapabilityTypes
-
TInt&
Checking and setting the haptics properties
The Haptics API provides means for getting and setting some of
the haptics properties. The available properties are defined in the
THWRMHapticsDevicePropertyType
enumeration. These include
such items as the already demonstrated license key, various strength
and priority settings, and a setting that determines whether the effect
playing is disabled or not. Successfully setting some of these can
require a prior setting of the OEM license key. The example below
shows how to get and set the strength property.
// the actuator has been opened and the license key has been set successfully.
TInt strength;
User::LeaveIfError( iHaptics->GetDeviceProperty( CHWRMHaptics::EHWRMHapticsStrength, strength ) );
// E.g., forcing the value to meet the threshold criteria.
// This setting has an impact on all effects of this client
if ( strength < 5000 )
{
User::LeaveIfError( iHaptics->SetDeviceProperty( CHWRMHaptics::EHWRMHapticsStrength, 5000 ) );
}
Related APIs
-
THWRMHapticsDevicePropertyType
Reserving haptics
The Haptics API allows a client to exclusively reserve the haptics
feature. This may be feasible, e.g., in game applications where the
haptic effects from other sources than the game itself may be undesirable.
It is possible for a higher priority client application to override
previous reservation made by a lower priority application. This new
reservation suspends the current reservation until the higher priority
reservation is released.
Note:
The suspension applies only to the use of the haptics
feature, i.e., except for the haptics, the suspended application can
continue its processing normally.
There are two kinds of reservations: one in which the foreground/background
status of the application determines whether the reservation is applied,
and one in which the reservation is forced and held by the reserving
application regardless of its foreground/background status. Only trusted
applications may reserve the haptics in the forced mode. The client
application is considered trusted if it has a priority defined in
the haptics policy file. The policy files can be modified by the Symbian
device manufacturers.
// Reserving the haptics
TBool forcedReserve( EFalse );
TRAPD( err, iHaptics->ReserveHapticsL( forcedReserve ) );
if ( !err )
{
// haptics is now reserved for this application..
// ...
// Release the reservation
iHaptics->ReleaseHaptics(); // always succeeds
}
Related APIs
-
KErrAccessDenied
-
KErrNotReady
Effects
The Haptics API can be used to play different types of effects.
There are three categories of effects:
Streaming effects
Streaming effects allow for fine-tuned haptics
synchronization, for example, with sound. The application provides
periodically smallish effect samples that are then played by the haptics
player.
Timeline effects
The timeline effects are constructed from possibly
several simple effects that have been scheduled over time. The timeline
effects cannot be created and played directly using the API methods.
They must be defined in an effect data buffer.
Once the effects have been created, the effect-definitions are
exported to a binary format file that is loaded to the mobile device.
The Haptics API has methods for loading the effect data buffer (read
from a file) to the Haptics subsystem and methods for, e.g., playing
and modifying the effects contained within the file.
Note:
Although the sections below introduce synchronous
versions of the play and modify methods, there are also asynchronous
variants of these methods that take a
TRequestStatus
reference as an argument and return immediately. The synchronous
versions of the methods shown in the sections below usually return
after the Haptics command data corresponding to the API call has been
propagated to Haptics server side and the server has sent back a response.
This does not mean that, e.g., the synchronous play method call only
returns when the effect has stopped playing. Instead, this means that
the server side has received the data needed for playing the effect,
evaluated the data, created an effect handle and returned the handle
to the client side.
Simple effects
There are two types of simple effects: magnitude sweep effects
and period effects. Magnitude sweep effects vibrate at a magnitude
and device-dependent constant rate (vibration frequency). Periodic
effects allow the period of vibration (frequency) to be explicitly
controlled independently of magnitude.
Both magnitude sweep and periodic effects have a set of envelope
parameters that control the duration and strength of the vibration.
They are defined in
THWRMHapticsMagSweepEffect
and
THWRMHapticsPeriodicEffect
structs. Effects can be formed
at run-time by creating and filling in structs with effect-specific
data, and then played by calling the
PlayMagSweepEffect()
and
PlayPeriodicEffect()
methods with the created
structs as arguments. There are different effect styles (defined in
THWRMHapticsEffectStyles
enumeration) that have an impact
on the feel of the effects.
The example below shows how magnitude sweep and periodic effects
are formed and played. It also shows a couple of ways to stop playing
effects before their defined playing duration expires.
/**
* Defining magnitude sweep effect parameters
*/
CHWRMHaptics::THWRMHapticsMagSweepEffect magSweepEff;
magSweepEff.iDuration = 5000; // Duration of the effect in milliseconds.
magSweepEff.iMagnitude = KHWRMHapticsMaxMagnitude/2; // Magnitude, 50% of maximum
magSweepEff.iStyle = CHWRMHaptics::EHWRMHapticsStyleSharp; // Style of the effect.
magSweepEff.iAttackTime = 250; // Time to ramp up from the level of magnitude defined
// in iAttackLevel to the magnitude defined in iMagnitude
// in the beginning of the effect.
magSweepEff.iAttackLevel = KHWRMHapticsMaxMagnitude; // Attack level ranges from KHWRMHapticsMinMagnitude
// to KHWRMHapticsMaxMagnitude.
magsWeepEff.iFadeTime = 250; // Time ramp down the effect to the level of magnitude
// defined by iFadeLevel in the end of the effect.
magsweepEff.iFadeLevel = 0; // Fade level of attack level ranges from KHWRMHapticsMinMagnitude
// to KHWRMHapticsMaxMagnitude.
/**
* Playing a MagSweep effect and stopping it
*/
// Variable whose reference is given as an argument to PlayMagSweepEffect.
// The reference is used to return handle for the playing effect.
TInt magSweepHandle ( 0 );
iHaptics->PlayMagSweepEffect( magSweepEff, magSweepHandle );
// This delay is just an example. The effect is stopped after a delay
TTimeIntervalMicroSeconds32 delay( 2000000 );
User::After( delay );
// Use the effect handle to define which effect to stop
iHaptics->StopPlayingEffect( magSweepHandle );
/**
* Playing a Periodic effect and stopping all playing effects
*/
CHWRMHaptics::THWRMHapticsPeriodicEffect periodicEff;
// This example shows how to define infinite playing duration
periodicEff.iDuration = iHaptics->InfiniteDuration();
periodicEff.iMagnitude = KHWRMHapticsMaxMagnitude/4; // 25% of maximum
// Struct for defining periodic effects has an extra data member that can be used
// to define the period of vibration in milliseconds.
periodicEff.iPeriod = 200;
periodicEff.iStyle = CHWRMHaptics::EHWRMHapticsStyleSmooth;
periodicEff.iAttackTime = 250;
periodicEff.iAttackLevel = 0;
periodicEff.iFadeTime = 250;
periodicEff.iFadeLevel = 0;
TInt periodicHandle( 0 );
iHaptics->PlayPeriodicEffect( periodicEff, periodicHandle );
TTimeIntervalMicroSeconds32 delay( 1000000 );
User::After( delay );
// There's a special API method for stopping all playing effects of
// the client application.
iHaptics->StopAllPlayingEffects();
Related APIs
-
PlayMagSweepEffect()
-
PlayPeriodicEffect()
-
THWRMHapticsEffectStyles
-
THWRMHapticsMagSweepEffect
-
THWRMHapticsPeriodicEffect
Modifying a currently playing simple effect
The Haptics API provides methods for modifying simple effects that
are already playing. The parameters that are used to modify an effect
are the same as those used to play the effect, except that the effect
handle obtained from initially playing the effect is passed as an
input argument to the modify method.
/**
* Playing a MagSweep effect and modifying it.
*/
magSweepEff.iDuration = 6000; // duration in milliseconds
magSweepEff.iMagnitude = KHWRMHapticsMaxMagnitude/5; // 20% magnitude of the max magnitude.
TInt magSweepHandle( 0 );
haptics->PlayMagSweepEffect( magSweepEff, magSweepHandle );
// this delay is just an example
// effect duration was 6 secs, so wait 2 secs to allow the effect to start playing
TTimeIntervalMicroSeconds32 delay( 2000000 );
User::After( delay );
magSweepEff.iMagnitude = KHWRMHapticsMaxMagnitude/2; // change the magnitude of the effect
User::LeaveIfError( haptics->ModifyPlayingMagSweepEffect( magSweepHandle, magSweepEff ) );
Streaming effects
The streaming effect functionality is designed for using haptics
with streaming media applications. When using the streaming functionality,
the application periodically supplies small samples of effect data
to be rendered by calling the
PlayStreamingSample()
method. Streaming effects allow for proper multimedia synchronization
over arbitrary time spans.
/**
* Creating a streaming effect, playing streaming samples
* and destroying a streaming effect
*/
// Variable whose reference is given as an argument to CreateStreamingEffect.
// The reference is used to return a handle to the created streaming effect.
TInt streamingHandle( 0 );
User::LeaveIfError( iHaptics->CreateStreamingEffect( streamingHandle ) );
...
// Example of a function that gets called when a new streaming sample is ready.
void StreamingDataUpdated( const TDesC8& aData, TInt aStreamingHandle )
{
// PlayStreamingSample method is called with the handle obtained from creation of
// the streaming effect above and with the new data sample
iHaptics->PlayStreamingSample( aStreamingHandle, aData );
}
...
// Eventually the streaming effect should be destroyed to release any reserved resources.
iHaptics->DestroyStreamingEffect( streamingHandle );
Related APIs
Effect data buffers
The Haptics API provides methods for playing effects defined in
effect data buffers. An effect data buffer is a binary buffer that
contains effect definitions and additional metadata relating to those
effects. The buffer can contain just simple effects or simple effects
and timeline effects that are constructed from those simple effects
scheduled over time.
Effect data buffers provide an alternative way of defining simple
effects, besides using the Haptics API methods to programmatically
create haptic effects with parameter values. The Haptics API does
not provide functions to explicitly define timeline effects. Therefore
the effect data buffers are the only way to present timeline effects
to the Haptics API.
There are two ways to play effects from effect data buffers. Either
by directly calling a
PlayEffect()
variant that takes
as an argument a descriptor containing the data, or by first loading
the data buffer to the Haptics system (
LoadEffectFile()
) and then using a variant of
PlayEffect()
that
does not take the data buffer as an argument but instead uses the
previously loaded data. The call to
LoadEffectFile()
returns a file handle to the caller. The handle is then given as
an argument to the play method, thus allowing the haptics system to
distinguish from which loaded effect data buffer to play the effect.
The example below shows both of these alternatives. Note that it is
possible to load data from several data buffers into the Haptics system.
The file handles returned from the
LoadEffectData()
call are used to distinguish between the effects defined in different
loaded buffers.
Once the data from an effect data buffer has been loaded into the
Haptics system, there are methods for enquiring various attributes
of the effects contained within the loaded data. The
GetEffectCount()
method returns the number of individual effects within the data.
GetEffectType()
,
GetEffectDuration()
and
GetEffectName()
methods are used (with index of the effect
given as an argument) to get effect-specific information. For magnitude
sweep and periodic effects, it is possible to get the whole effect
definition by calling
GetMagSweepEffectDefinition()
or
GetPeriodicEffectDefinition()
. There is also
a useful
GetEffectIndexFromName()
method that can
be used to get the index of an effect within the effect data buffer
from the effect's name as shown in the example below.
/**
* Preparing to use an effect file.
*/
RFs fs;
CleanupClosePushL( fs );
User::LeaveIfError( fs.Connect() );
_LIT( KPathToEffectDataFolder, "C://SomePathTo//EffectDataFolder//" );
fs.SetSessionPath( KPathToEffectDataFolder );
RFile file;
CleanupClosePushL( file );
_LIT( KFileName, "ExampleEffectsFile" );
User::LeaveIfError( file.Open( fs, KFileName, EFileRead ) );
TInt fileSize( 0 );
User::LeaveIfError( file.Size( fileSize ) );
HBufC8* dataBuffer = HBufC8::NewLC( fileSize );
TPtr8 readBuf = dataBuffer->Des();
User::LeaveIfError( file.Read( readBuf ) );
/**
* Load effect data buffer first. Then play an effect from it.
*/
// A variable into which a handle for the loaded data is stored. A reference to
// this variable is given as an argument to LoadEffectFile for the Haptics to assign.
TInt fileHandle( 0 );
User::LeaveIfError( iHaptics->LoadEffectFile( *dataBuffer, fileHandle ) );
TInt effectIndex( 1 ); // index of the effect inside the data that we want to play;
TInt effectHandle( 0 ); // variable to receive the effect handle of the playing effect
iHaptics->PlayEffect( fileHandle, effectIndex, effectHandle );
// Often the index of an individual effect inside the data is not known beforehand. It can be queried
// using the effect's name
_LIT( KEffectName, "ExampleEffect" );
User::LeaveIfError( iHaptics->GetEffectIndexFromName( fileHandle, KEffectName, effectIndex ) );
iHaptics->PlayEffect( fileHandle, effectIndex, effectHandle );
/**
* Effects can also be played directly (without first loading the effect data buffer to Haptics)
* by giving a reference to a descriptor containing the data buffer as an argument.
*/
iHaptics->PlayEffect( *dataBuffer, effectIndex, effectHandle );
CleanupStack::PopAndDestroy( dataBuffer );
CleanupStack::PopAndDestroy( &file );
CleanupStack::PopAndDestroy( &fs );
//...
// Eventually the loaded data should be deleted to release reserved resources
// Note: Actually the resources are released also when client closes the haptics
iHaptics->DeleteEffectData( fileHandle ); // or iHaptics->DeleteAllEffectData() to delete all datas
// loaded by this application.
Note:
For timeline effects there is also a method called
PlayEffectRepeat()
that can be used to request repeated
playing of an effect. The number of repeats is given as an argument.
If a timeline effect needs to be repeated infinite times, the value
returned from a call to the Haptics API's
InfiniteRepeat()
method must be used as a repeat argument. For other types of effects
than timeline effects, the repeat method plays the effect just once
(i.e., for non-timeline effects this is equivalent to the normal
PlayEffect()
method).
Related APIs
-
GetEffectCount()
-
GetEffectDuration()
-
GetEffectIndexFromName()
-
GetEffectName()
-
GetEffectType()
-
GetMagSweepEffectDefinition()
-
GetPeriodicEffectDefinition()
-
InfiniteRepeat()
-
LoadEffectData()
-
LoadEffectFile()
-
PlayEffect()
-
PlayEffectRepeat()
Pausing and resuming playing of effects
It is possible to pause an effect during its playing and then later
resume the playing using the Haptics API's methods
PausePlayingEffect()
and
ResumePausedEffect()
respectively as shown
in the example below. After resuming the previously paused effect,
its playing is continued from the point where it was paused.
// we have started the playing of a longish effect and have stored its handle to the effectHandle variable
// First, pause the playing of the effect
User::LeaveIfError( iHaptics->PausePlayingEffect( effectHandle ) );
// Then, resume the playing
User::LeaveIfError( iHaptics->ResumePausedEffect( effectHandle ) );
Related APIs
-
PausePlayingEffect()
-
ResumePausedEffect()
Related APIs
Error handling
The leave mechanism and return values are used to indicate errors.
Normal Symbian error handling practices should be used,
including, e.g., using the cleanup stack and the
TRAP
harness.
Some typical error codes:
-
KErrAccessDenied
: the license key is not set
or when setting the license key, the provided key is not accepted.
A typical license key format is a 32-character-long string. Characters
are encoded in 8-bytes, thus not in Unicode.
KErrNotSupported
, when calling
OpenActuatorL()
with a logical actuator that is not supported by the system. This
error code is also returned if trying to set or get an incompatible
property or capability type.
KErrArgument
, argument passed to a method was
invalid.
KErrNotReady
, when trying to use the Haptics
API's methods before it has been properly initialized.
The Haptics API does not have many leaving methods as handling
leaves is slow. An opportunity to do something about an error has
already passed when the leave is caught in the TRAP harness.
Related APIs
-
KErrAccessDenied
-
KErrArgument
-
KErrNotReady
-
KErrNotSupported
-
OpenActuatorL()
-
TRAP
Memory overhead
Using of the Haptics API can cause an additional memory overhead
since a loaded effect data buffer cache is implemented in the client
side. The amount of memory needed depends on the number and size of
the loaded data buffers. In real life situations, the memory overhead
is quite small though since the binary format of the effect data is
compact and usually there are only a few effect data buffers loaded
simultaneously per client. To keep the memory overhead as low as possible,
the client should delete the loaded effect data buffers (
DeleteEffectData()
) whenever the data buffer becomes obsolete.
Related APIs
Extensions to the API
The API does not explicitly support any kinds of extensions to
it.
Limitations of the API
A valid license key is needed for using the Haptics API. See Forum
Nokia web site (
http://www.forum.nokia.com/
) for information how a license key can be acquired.
Related APIs
-
CHWRMHaptics
-
EHWRMHapticsLicensekey
-
MHWRMHapticsActuatorObserver
-
MHWRMHapticsObserver
-
NewL()
-
OpenActuatorL()
-
SetDeviceProperty()
-
SupportedActuators()
Glossary
Abbreviations
API
|
Application Programming Interface
|
WINS
|
Windows (Visual Studio®) compilation
|
WINSCW
|
Windows (CodeWarrior®) compilation
|
Definitions
Haptics
|
Haptics technology refers to technology which interfaces
with the user via the sense of touch by applying forces, vibrations
and/or motions to the user.
|
Magnitude Sweep effect (MagSweep)
|
Type of simple effect. Vibrates at a magnitude and device-dependent
rate.
|
Periodic effect (Periodic)
|
Type of simple effect. Periodic effects allow the period or
speed of vibration to be explicitly controlled independent of magnitude.
|
Timeline effect
|
Type of effect that consists of simple effects scheduled over
time.
|
Effect data buffer
|
Binary data buffer that contains effect definitions. It can
have simple effects only or simple effects and timeline effects constructed
from those simple effects.
|
Actuator
|
In haptics context, an actuator refers to any kind of mechanic
device that creates the physical movement in the device, e.g., Vibra.
|
Haptics device capability
|
Capability of an actuator, e.g., minimum and maximum period
and duration of effect playing, actuator type, etc.
|
Haptics device property
|
Properties of the haptics system that can be set and enquired.
The most essential is the license key that must be correctly set by
the application in order to unlock the full functionality of the haptics
system. Others include haptics instance and system-wide strength and
priority settings.
|
|