Search code examples
javascriptgesturevolumejplayerleap-motion

Leap Motion: Volume Control jPlayer (need to create smooth incremental values?)


I am building a leap motion controlled music player and have come to a roadblock.

The volume, I want this to work on 'circle' gestures clockwise being volume up and anticlockwise being volume down, however I cannot work out how to get the 'right' values to set the volume to.

I am using jPlayer as the audio player, the volume is set like so: $("#jquery_jplayer_1").jPlayer("volume", volumeValue); volumeValue needing to be between 0 and 1

I have it working so if you rotate clockwise it sets the volume to 0.75 and if rotate left 0.25, however cant work out how to increase the volume incrementally with rotation.

To get the number of rotations, this function can be used circleCount = gesture.progress.toFixed(2);

Below is my code... (obviously I realise this doesn't do much atm)

if (gesture.type == 'circle') {

        gesture.pointable = frame.pointable(gesture.pointableIds[i]);

        if(gesture.state == 'start') {
            clockwise = true;
        } else if (gesture.state == 'update') {
            direction = gesture.pointable.direction;

            if(direction) {
                normal = gesture.normal;

                clockwise = Leap.vec3.dot(direction, normal) > 0;
                if(clockwise) {
                    if (gesture.progress.toFixed(2) > 1) {
                        //volume up
                          ("#jquery_jplayer_1").jPlayer("volume", 0.75);

                    }
                } else {
                    if (gesture.progress.toFixed(2) > 1) {
                        //volume down
                         ("#jquery_jplayer_1").jPlayer("volume", 0.25);

                    }
                }
            }

            }
        }

Solution

  • When you put:

    gesture.progress.toFixed(2) > 1
    

    That means the volume will only ever change after a complete circle. The progress value isn't an integer, though, it varies fairly smoothly as you make the circle. If you want one full circle to change the volume between the minimum and the maximum, you could use the progress value directly. If you wanted it to take, for example, 3 full turns to go from minimum to maximum value, divide progress by three.

    [Edit] From your comment, it sounds like you want the circle progress to reach a threshold value and from there, it affects the volume. You could use something like:

    var threshold = 1;
    if (gesture.type == 'circle') {
    
        gesture.pointable = frame.pointable(gesture.pointableIds[i]);
    
        if(gesture.state == 'start') {
            clockwise = true;
        } else if (gesture.state == 'update') {
            direction = gesture.pointable.direction;
            var newVolume = 0;
            if(direction) {
                normal = gesture.normal;
    
                clockwise = Leap.vec3.dot(direction, normal) > 0;
                if(clockwise) {
                    if (gesture.progress > threshold) {
                        //volume up
                        newVolume = gesture.progress - threshold;
                        if(newVolume > 1) newVolume = 1;  
                    }
                } else {
                    if (gesture.progress > threshold) {
                        //volume down
                        newVolume = 1 - (gesture.progress - threshold);
                        if(newVolume < 0) newVolume = 0;
    
                    }
                }
            }
            ("#jquery_jplayer_1").jPlayer("volume", newVolume);
    
            }
        }
    

    (I didn't test this, so look out for syntax errors).