diff options
Diffstat (limited to 'heuristics.c')
| -rw-r--r-- | heuristics.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/heuristics.c b/heuristics.c new file mode 100644 index 0000000..429a612 --- /dev/null +++ b/heuristics.c | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | |||
| 3 | #include "vubars.h" | ||
| 4 | |||
| 5 | static void heuristics_getGesture( int const amount, int const off, int const * const values, | ||
| 6 | int *dxl, int *dyl, int *dxr, int *dyr ); | ||
| 7 | |||
| 8 | int heuristics_getEnergy( int const amount, int const * const values ) { | ||
| 9 | int energy = 0; | ||
| 10 | int i; | ||
| 11 | |||
| 12 | for( i = 0; i < amount-1; ++i ) | ||
| 13 | energy += values[i]*values[i+1]; | ||
| 14 | |||
| 15 | return energy; | ||
| 16 | } | ||
| 17 | |||
| 18 | // Gets the two longest consecutive gestures found | ||
| 19 | // in frames. -1 in off[ab] means no gesture found | ||
| 20 | |||
| 21 | // Here what counts: the bigger abs(dx[ab]), the longer the gesture | ||
| 22 | // the bigger dy[ab]/dx[ab], the slower the gesture | ||
| 23 | void heuristics_getGestures( int const amount, int const * const values, | ||
| 24 | int *offa, int *dxa, int *dya, int *dda, | ||
| 25 | int *offb, int *dxb, int *dyb, int *ddb ) | ||
| 26 | { | ||
| 27 | int i, l = 0; | ||
| 28 | int dxl [ amount ], dyl [ amount ], dxr [ amount ], dyr [ amount ]; | ||
| 29 | |||
| 30 | // Get the longest gestures for each point - both into left and rite | ||
| 31 | for( i=0; i<amount; ++i ) | ||
| 32 | heuristics_getGesture( amount, i, values, dxl + i, dyl + i, dxr + i, dyr + i ); | ||
| 33 | |||
| 34 | // "Sort" gesture by length | ||
| 35 | *offa = *dxa = *dya = 0; | ||
| 36 | for( i=0; i<amount; ++i ) { | ||
| 37 | if( dxr[ i ] > *dxa ) { *offa = i; *dxa = dxr[ i ]; *dya = dyr[ i ]; *dda = 1; } | ||
| 38 | if( dxl[ i ] > *dxa ) { *offa = i; *dxa = dxl[ i ]; *dya = dyl[ i ]; *dda =-1; } | ||
| 39 | } | ||
| 40 | |||
| 41 | // If no gesture found at all, invalidate off | ||
| 42 | // and return... second run wouldnt suddenly find a gesture | ||
| 43 | if( *dxa == 0 ) { *offa = *offb = -1; return; } | ||
| 44 | |||
| 45 | // Now clear the best result - this will find us the second best result | ||
| 46 | i = *offa; | ||
| 47 | if( *dda == 1 ) { | ||
| 48 | for( i=*offa; i < *offa + dxr[ *offa ]; ++i ) | ||
| 49 | dxr[ i ] = 0; | ||
| 50 | } else { | ||
| 51 | for( i=*offa; i > *offa - dxl[ *offa ]; --i ) | ||
| 52 | dxl[ i ] = 0; | ||
| 53 | } | ||
| 54 | |||
| 55 | // "Sort" remaining gestures by length | ||
| 56 | *offb = *dxb = *dyb = 0; | ||
| 57 | for( i=0; i<amount; ++i ) { | ||
| 58 | if( dxr[ i ] > *dxb ) { *offb = i; *dxb = dxr[ i ]; *dyb = dyr[ i ]; *ddb = 1;} | ||
| 59 | if( dxl[ i ] > *dxb ) { *offb = i; *dxb = -dxl[ i ]; *dyb = dyl[ i ]; *ddb =-1;} | ||
| 60 | } | ||
| 61 | |||
| 62 | // If no secondary gesture found, invalidate off | ||
| 63 | if( *dxb == 0 ) *offb = -1; | ||
| 64 | } | ||
| 65 | |||
| 66 | static void heuristics_getGesture( int const amount, int const off, int const * const values, | ||
| 67 | int * const dxl, int * const dyl, int * const dxr, int * const dyr ) | ||
| 68 | { | ||
| 69 | int i; | ||
| 70 | |||
| 71 | // Initialize as "nothing happened" | ||
| 72 | *dxl = *dxr = *dyl = *dyr = 0; | ||
| 73 | |||
| 74 | // if this didn't peak in last frame, we're not starting | ||
| 75 | // a gesture here. | ||
| 76 | if( values[off] != VU_PEAK ) return; | ||
| 77 | |||
| 78 | if( off > 0 ) *dyl = values[off]-values[off-1]; | ||
| 79 | if( off < amount-1 ) *dyr = values[off]-values[off+1]; | ||
| 80 | |||
| 81 | if( !*dyl && !*dyr ) return; | ||
| 82 | |||
| 83 | // Depending on where this peaks seems to have come from, | ||
| 84 | // chose direction where to follow it | ||
| 85 | // try to collect enough monotonic samples and calculate a | ||
| 86 | // slope. Since our sample peaks, all others cant be larger | ||
| 87 | if( (*dyl) && (*dyl < *dyr) ) { | ||
| 88 | (*dxl)++; | ||
| 89 | for( i=off-1; i>=0; --i ) { | ||
| 90 | int dy = values[i+1] - values[i]; | ||
| 91 | |||
| 92 | // If it scrolled out of scope, ignore it | ||
| 93 | if( !values[i] || dy < 0 ) break; | ||
| 94 | |||
| 95 | (*dxl)++; | ||
| 96 | (*dyl) += dy; | ||
| 97 | } | ||
| 98 | } else { | ||
| 99 | (*dxr)++; | ||
| 100 | // Do the same when going right | ||
| 101 | for( i=off+1; i<amount; ++i ) { | ||
| 102 | int dy = values[i-1] - values[i]; | ||
| 103 | |||
| 104 | // If it scrolled out of scope, ignore it | ||
| 105 | if( !values[i] || dy < 0 ) break; | ||
| 106 | |||
| 107 | (*dxr)++; | ||
| 108 | (*dyr) += dy; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | } | ||
