jack1 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
2.7KB

  1. // After looking at how pulseaudio is doing things,
  2. // i have came to the conclusion, that forgetting
  3. // about statistics is a bad idea ;)
  4. //
  5. // i am loosely basing this on pulsecore/time-smoother.c
  6. #include "time_smoother.h"
  7. #include <stdlib.h>
  8. #include <assert.h>
  9. time_smoother *time_smoother_new( int history_size )
  10. {
  11. time_smoother *retval = malloc( sizeof( time_smoother ) );
  12. if( !retval )
  13. return NULL;
  14. retval->x = malloc( sizeof(jack_nframes_t) * history_size );
  15. if( !retval->x ) {
  16. free( retval );
  17. return NULL;
  18. }
  19. retval->y = malloc( sizeof(jack_nframes_t) * history_size );
  20. if( !retval->y ) {
  21. free( retval->x );
  22. free( retval );
  23. return NULL;
  24. }
  25. retval->history_size = history_size;
  26. retval->num_valid = 0;
  27. return retval;
  28. }
  29. void time_smoother_free( time_smoother *ts )
  30. {
  31. free( ts->x );
  32. free( ts->y );
  33. free( ts );
  34. }
  35. // put a time measurement into the smoother.
  36. // assume monotonically increasing x.
  37. void time_smoother_put ( time_smoother *ts, jack_nframes_t x, jack_nframes_t y )
  38. {
  39. int i;
  40. int oldest_index;
  41. jack_nframes_t oldest_diff;
  42. if( ts->num_valid < ts->history_size ) {
  43. ts->x[ts->num_valid] = x;
  44. ts->y[ts->num_valid] = y;
  45. ts->num_valid += 1;
  46. return;
  47. }
  48. // Its full. find oldest value and replace.
  49. oldest_index = -1;
  50. oldest_diff = 0;
  51. for( i=0; i<ts->history_size; i++ ) {
  52. if( (x - ts->x[i]) > oldest_diff ) {
  53. oldest_diff = (x - ts->x[i]);
  54. oldest_index = i;
  55. }
  56. }
  57. assert( oldest_index != -1 );
  58. ts->x[oldest_index] = x;
  59. ts->y[oldest_index] = y;
  60. }
  61. // return a and b for the linear regression line,
  62. // such that y=a+bx;
  63. void time_smoother_get_linear_params( time_smoother *ts,
  64. jack_nframes_t now_x,
  65. jack_nframes_t now_y,
  66. jack_nframes_t history,
  67. double *a, double *b )
  68. {
  69. int i;
  70. jack_nframes_t sum_x = 0;
  71. jack_nframes_t sum_y = 0;
  72. int num_values = 0;
  73. double mean_x, mean_y;
  74. double sxx = 0.0;
  75. double sxy = 0.0;
  76. double val_a, val_b;
  77. for( i=0; i<ts->num_valid; i++ ) {
  78. if( (now_x - ts->x[i]) < history ) {
  79. sum_x += (now_x - ts->x[i]);
  80. sum_y += (now_y - ts->y[i]);
  81. num_values += 1;
  82. }
  83. }
  84. // Give some valid values if we dont have
  85. // enough data;
  86. if( num_values < 10 ) {
  87. if( a ) *a = 0.0;
  88. if( b ) *b = 1.0;
  89. return;
  90. }
  91. mean_x = (double) sum_x / (double) num_values;
  92. mean_y = (double) sum_y / (double) num_values;
  93. //printf( "mean: %f %f\n", (float) mean_x, (float) mean_y );
  94. for( i=0; i<ts->num_valid; i++ ) {
  95. if( (now_x - ts->x[i]) < history ) {
  96. sxx += ((double)(now_x-ts->x[i])-mean_x) * ((double)(now_x-ts->x[i])-mean_x);
  97. sxy += ((double)(now_x-ts->x[i])-mean_x) * ((double)(now_y-ts->y[i])-mean_y);
  98. }
  99. }
  100. val_b = sxy/sxx;
  101. val_a = mean_y - val_b*mean_x;
  102. if( a )
  103. *a = val_a;
  104. if( b )
  105. *b = val_b;
  106. }