Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm for generating vibration patterns ranging in intensity in Android?

I am attempting to programmatically generate Android vibration patterns with 'micro pulses' on and off to control how strong the vibration feels to the end user. This is the solution I've seen recommended in a few similar topics, to the problem of the API not providing an interface for controlling the vibration strength (because of how the hardware functions, as I understand it).

The algorithm for generating these patterns, however, seems to only be hinted at, but no actual algorithm posted.

What I would like to do is, given an input intensity between 0.0f and 1.0f, generate an array following a pattern something like this:

(zero intensity)
[20,0]

[9,1,9,1]
...

[3,1,3,1,3,1,3,1,3,1]

[2,1,2,1,2,1,2,1,2,1,2,1,2]

(half intensity)
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]

[1,2,1,2,1,2,1,2,1,2,1,2,1,1]

[1,3,1,3,1,3,1,3,1,3]
...

[1,9,1,9]

(full intensity)
[0,20]

Any help with writing such an algorithm (or suggestions for a better strategy to meet the same goal)?

Edit: I've added a bounty of 100 reputation to the mix :)

like image 314
paulscode Avatar asked Dec 27 '13 22:12

paulscode


People also ask

How do you make a vibration pattern on a Samsung?

Tap on the “More option > Vibration pattern,” and it will be set to default. When you tap on this option, your Android device will open to the stock vibration patterns it has. You can choose from patterns such as default, basic call, heartbeat, ticktock, waltz, and zig-zig-zig.

How do you make a custom vibration for an app?

Tap any app to bring up a list of your currently installed apps. Tap each app on this list that you want to set up a custom notification vibration pattern for, then press the Pick Apps button at the bottom. Press contains anything for an overview of the options you can choose for the custom notification.


1 Answers

After looking at the problem for a while, and not being not very mathematically talented, I came up with an overly simplified algorithm (compared to some of the PWM formulas I found after Dithermaster pointed me in that direction). A couple of assumptions I made were first that the short pulse width is always 1, and the long pulse width is an integer between 1 and the vibration duration. I also assumed the long pulse width is a linear function of the vibration strength. In particular, the latter assumption is not accurate. I'm guessing the function should be something more like a decibel calculation ("strength" of vibration is akin to "loudness" of a sound).

Posting my simplified solution in case it is useful for anyone else who ends up here. This is close enough for the application I am using it for, but I would still like something better. If anyone posts an alternative answer, I'll test and accept it if it is better.

public long[] genVibratorPattern( float intensity, long duration )
{
    float dutyCycle = Math.abs( ( intensity * 2.0f ) - 1.0f );
    long hWidth = (long) ( dutyCycle * ( duration - 1 ) ) + 1;
    long lWidth = dutyCycle == 1.0f ? 0 : 1;

    int pulseCount = (int) ( 2.0f * ( (float) duration / (float) ( hWidth + lWidth ) ) );
    long[] pattern = new long[ pulseCount ];

    for( int i = 0; i < pulseCount; i++ )
    {
        pattern[i] = intensity < 0.5f ? ( i % 2 == 0 ? hWidth : lWidth ) : ( i % 2 == 0 ? lWidth : hWidth );
    }

    return pattern;
}
like image 73
paulscode Avatar answered Sep 30 '22 13:09

paulscode