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 :)
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.
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.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With