[xiph-commits] r17689 - trunk/squishyball

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Mon Nov 29 19:44:05 PST 2010


Author: xiphmont
Date: 2010-11-29 19:44:05 -0800 (Mon, 29 Nov 2010)
New Revision: 17689

Modified:
   trunk/squishyball/main.c
   trunk/squishyball/main.h
   trunk/squishyball/squishyball.1
   trunk/squishyball/tty.c
Log:
Add running totals (-g)
Tweak statistics reporting
Increase max and default trials



Modified: trunk/squishyball/main.c
===================================================================
--- trunk/squishyball/main.c	2010-11-29 23:53:30 UTC (rev 17688)
+++ trunk/squishyball/main.c	2010-11-30 03:44:05 UTC (rev 17689)
@@ -107,7 +107,7 @@
           "  -M --mark-flip         : Mark transitions between samples with\n"
           "                           a short period of silence\n"
           "  -n --trials <n>        : Set desired number of trials\n"
-          "                           (default: 10)\n"
+          "                           (default: 20)\n"
           "  -r --restart-after     : Restart playback from sample start\n"
           "                           after every trial.\n"
           "  -R --restart-every     : Restart playback from sample start\n"
@@ -222,6 +222,28 @@
   return f;
 }
 
+double compute_psingle(int correct, int tests){
+  int i;
+  // 0.5^20*(20!/(17!*3!))
+  double p=0;
+  for(i=correct;i<=tests;i++)
+    p += pow(.5,tests) * (factorial(tests) / (factorial(tests-i)*factorial(i)));
+  return p;
+}
+
+double compute_pdual(int score, int tests){
+  int i;
+  double p=0;
+  if(tests-score>score)
+    score=tests-score;
+  for(i=score;i<=tests;i++){
+    double lp = pow(.5,tests) * (factorial(tests) / (factorial(tests-i)*factorial(i)));
+    if(tests-i != i) lp*=2;
+    p+=lp;
+  }
+  return p;
+}
+
 typedef struct {
   pthread_mutex_t mutex;
   pthread_cond_t main_cond;
@@ -323,7 +345,7 @@
   int force_truncate=0;
   int restart_mode=0;
   int beep_mode=3;
-  int tests=10;
+  int tests=20;
   double start=0;
   double end=-1;
   int outbits=0;
@@ -587,7 +609,7 @@
     /* set up terminal */
     atexit(min_panel_remove);
     panel_init(pcm, test_files, test_mode, start, end>0 ? end : len, len,
-               beep_mode, restart_mode, tests, "");
+               beep_mode, restart_mode, tests, running_score);
 
     /* set up shared state */
     memset(&state,0,sizeof(state));
@@ -653,6 +675,7 @@
           /* range checking enforced later */
           break;
         case 10: /* enter */
+        case 13: /* return */
           /* guarded below */
           flip_to = current_choice;
           do_select=1;
@@ -751,11 +774,11 @@
           panel_toggle_keymap();
           break;
         case 331:
-          if(tests_cursor<tests_total)
+          if(tests_cursor<tests_total && !running_score)
             tests_cursor++;
           break;
         case 330:
-          if(tests_cursor>0)
+          if(tests_cursor>0 && !running_score)
             tests_cursor--;
             break;
         }
@@ -811,7 +834,7 @@
         panel_update_playing(current_choice);
         panel_update_repeat_mode(restart_mode);
         panel_update_flip_mode(beep_mode);
-        panel_update_trials(choice_list,tests_cursor);
+        panel_update_trials(choice_list,sample_list,tests_cursor);
         min_flush();
         pthread_mutex_lock(&state.mutex);
       }
@@ -962,17 +985,24 @@
   pthread_cancel(fd_handle);
   pthread_mutex_unlock(&state.mutex);
 
+  fprintf(stdout,"\n");
+
   if(test_mode!=3 && tests_cursor>0){
     int total1=0;
+
+    if(running_score)
+      fprintf(stdout,"Running totals (-g) displayed during test.\n");
+    if(tests_cursor<tests)
+      fprintf(stdout,"Test was aborted early.\n");
+
     tests=tests_cursor;
     for(i=0;i<tests;i++)
       total1+=sample_list[i];
-
     switch(test_mode){
     case 0:
       fprintf(stdout, "\nA/B test results:\n");
-      fprintf(stdout, "\tSample 1 (%s) chosen %d/%d trials.\n",pcm[0]->path,tests-total1,tests);
-      fprintf(stdout, "\tSample 2 (%s) chosen %d/%d trials.\n",pcm[1]->path,total1,tests);
+      fprintf(stdout, "\tSample 1 (%s): %d/%d trials.\n",pcm[0]->path,tests-total1,tests);
+      fprintf(stdout, "\tSample 2 (%s): %d/%d trials.\n",pcm[1]->path,total1,tests);
       break;
     case 1:
       fprintf(stdout, "\nA/B/X test results:\n");
@@ -984,14 +1014,23 @@
       break;
     }
 
-    if(test_mode==1 || test_mode==2){
+    if(test_mode==0){
+      double p = compute_pdual(total1,tests);
+      if(total1>0 && total1<tests)
+        fprintf(stdout, "\tProbability of equal/more significant result via random chance: %.2f%%\n",p*100);
+      else
+        fprintf(stdout, "\tProbability of equally significant result via random chance: %.2f%%\n",p*100);
+      if(p<.01)
+        fprintf(stdout,"\tStatistically significant result (>=99%% confidence)\n");
+    }else{
       // 0.5^20*(20!/(17!*3!))
-      double p=0;
-      for(i=total1;i<=tests;i++)
-        p += pow(.5,tests) * (factorial(tests) / (factorial(tests-i)*factorial(i)));
-      fprintf(stdout, "\tProbability of %d or better correct via random chance: %.2f%%\n",total1,p*100);
-      if(p<.05)
-        fprintf(stdout,"\tStatistically significant result (>=95%% confidence)\n");
+      double p = compute_psingle(total1,tests);
+      if(total1<tests)
+        fprintf(stdout, "\tProbability of %d or better correct via random chance: %.2f%%\n",total1,p*100);
+      else
+        fprintf(stdout, "\tProbability of %d correct via random chance: %.2f%%\n",total1,p*100);
+      if(p<.01)
+        fprintf(stdout,"\tStatistically significant result (>=99%% confidence)\n");
     }
     fprintf(stdout,"\n");
   }

Modified: trunk/squishyball/main.h
===================================================================
--- trunk/squishyball/main.h	2010-11-29 23:53:30 UTC (rev 17688)
+++ trunk/squishyball/main.h	2010-11-30 03:44:05 UTC (rev 17689)
@@ -25,7 +25,7 @@
 #define _SB__H_
 #include <ao/ao.h>
 
-#define MAXTRIALS 50
+#define MAXTRIALS 150
 typedef struct pcm_struct pcm_t;
 
 struct pcm_struct {
@@ -62,14 +62,16 @@
 
 extern char *make_time_string(double s,int pad);
 extern void panel_init(pcm_t **pcm, int test_files, int test_mode, double start, double end, double size,
-                       int flip_mode,int repeat_mode,int trials,char *trial_list);
+                       int flip_mode,int repeat_mode,int trials,int gabba);
 extern void panel_update_playing(int n);
 extern void panel_update_start(double time);
 extern void panel_update_current(double time);
 extern void panel_update_end(double time);
 extern void panel_update_repeat_mode(int mode);
 extern void panel_update_flip_mode(int mode);
-extern void panel_update_trials(char *trial_list, int n);
+extern void panel_update_trials(char *trial_list, char *trial_correct, int n);
 extern void panel_update_pause(int flag);
 extern void panel_toggle_keymap(void);
+extern double compute_psingle(int correct, int tests);
+extern double compute_pdual(int count, int tests);
 #endif

Modified: trunk/squishyball/squishyball.1
===================================================================
--- trunk/squishyball/squishyball.1	2010-11-29 23:53:30 UTC (rev 17688)
+++ trunk/squishyball/squishyball.1	2010-11-30 03:44:05 UTC (rev 17689)
@@ -84,12 +84,15 @@
 \fRbelow for more details.
 .IP "\fB-e --end-time \fR[[\fIhh\fB:\fR]\fImm\fB:\fR]\fIss\fR[\fB.\fIff\fR]"
 Set sample end time for playback.
+.IP "\fB-g --gabbagabbahey \fR| \fB--score-display"
+Show running score and probability figures of trials so far while
+testing. Can only be used with \fB-a\fR, \fB-b\fR, or \fB-x\fR.
 .IP "\fB-h --help"
 Print usage summary to stdout and exit.
 .IP "\fB-M --mark-flip"
 Mark transitions between samples with a short period of silence (default).
 .IP "\fB-n --trials \fIn"
-Set desired number of comparison trials (default: 10).
+Set desired number of comparison trials (default: 20).
 .IP "\fB-r --restart-after"
 Set 'restart-after mode', where sample playback restarts from start point
 after every trial.

Modified: trunk/squishyball/tty.c
===================================================================
--- trunk/squishyball/tty.c	2010-11-29 23:53:30 UTC (rev 17688)
+++ trunk/squishyball/tty.c	2010-11-30 03:44:05 UTC (rev 17689)
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <limits.h>
 #include <unistd.h>
 #include <math.h>
 #include <errno.h>
@@ -35,9 +36,9 @@
 #include "mincurses.h"
 
 static int force=0;
-static int p_tm,p_ch,p_b,p_r,p_fm,p_rm,pcm_n,p_tr,p_tmax,p_pau,p_pl,p_tn;
+static int p_tm,p_ch,p_b,p_r,p_fm,p_rm,pcm_n,p_tr,p_tmax,p_pau,p_pl,p_tn,p_g;
 static double p_st,p_cur,p_end,p_len;
-static char p_tl[MAXTRIALS];
+static char p_tl[MAXTRIALS],p_tc[MAXTRIALS];
 static pcm_t **pcm_p;
 
 static char timebuffer[80];
@@ -80,7 +81,7 @@
 static int boxrow;
 static int fliprow;
 
-static void draw_topbar(int row){
+static int draw_topbar(int row){
   char buf[columns+1];
   int i=0,j;
   toprow=row;
@@ -136,9 +137,10 @@
     min_putchar(ACS_HLINE);
   min_putchar(ACS_LLCORNER);
   min_unset();
+  return 2;
 }
 
-static void draw_timebar(int row){
+static int draw_timebar(int row){
   char buf[columns+1];
   timerow=row;
 
@@ -155,9 +157,10 @@
     char *time=make_time_string(p_len,1);
     min_putstr(time);
   }
+  return 1;
 }
 
-static void draw_playbar(int row){
+static int draw_playbar(int row){
   int pre = floor(p_st/p_len*columns);
   int post = columns-floor(p_end/p_len*columns+1.e-6f);
   int i;
@@ -181,12 +184,13 @@
     i++;
   }
   min_unset();
+  return 1;
 }
 
-static void draw_trials_box(int row){
+static int draw_trials_box(int row){
+  int i;
   char buf[columns+1];
   boxrow=row;
-  fliprow=row+2;
 
   /* top line of box */
   fill(buf,ACS_HLINE,columns);
@@ -196,22 +200,28 @@
   min_gfx(1);
   min_fg(COLOR_CYAN);
   min_putstr(buf);
+  row++;
 
-  /* trials line */
-  min_mvcur(0,row+1);
-  min_putchar(ACS_VLINE);
-  min_mvcur(columns-1,row+1);
-  min_putchar(ACS_VLINE);
+  /* trials line[s] */
+  for(i=0;i<1+(p_g?1:0);i++){
+    min_mvcur(0,row);
+    min_putchar(ACS_VLINE);
+    min_mvcur(columns-1,row);
+    min_putchar(ACS_VLINE);
+    row++;
+  }
 
-  min_mvcur(0,row+2);
+  fliprow=row;
+  min_mvcur(0,row);
   fill(buf,ACS_HLINE,columns);
   buf[0]=ACS_LLCORNER;
   buf[columns-1]=ACS_LRCORNER;
   min_putstr(buf);
   min_unset();
+  return (p_g?1:0)+3;
 }
 
-static void draw_samples_box(int row){
+static int draw_samples_box(int row){
   char buf[columns+1];
   int i;
   boxrow=row;
@@ -255,20 +265,19 @@
   buf[columns-1]=ACS_LRCORNER;
   min_putstr(buf);
   min_unset();
+  return p_tn+2;
 }
 
 void panel_redraw_full(void){
   int i=2;
 
   if(p_tm==3){
-    draw_samples_box(i);
-    i+=pcm_n+2;
+    i+=draw_samples_box(i);
   }else{
-    draw_trials_box(i);
-    i+=3;
+    i+=draw_trials_box(i);
   }
-  draw_playbar(i++);
-  draw_timebar(i++);
+  i+=draw_playbar(i);
+  i+=draw_timebar(i);
   draw_topbar(1);
   force=1;
   panel_update_pause(p_pau);
@@ -279,15 +288,15 @@
   panel_update_repeat_mode(p_rm);
   panel_update_flip_mode(p_fm);
   if(p_tm!=3)
-    panel_update_trials(p_tl,p_tn);
+    panel_update_trials(p_tl,p_tc,p_tn);
   force=0;
   min_flush();
 }
 
 void panel_init(pcm_t **pcm, int test_files, int test_mode, double start, double end, double size,
-                int flip_mode,int repeat_mode,int trials,char *trial_list){
+                int flip_mode,int repeat_mode,int trials,int gabba){
 
-  if(min_panel_init(test_mode==3 ? test_files+6:7)){
+  if(min_panel_init((test_mode==3 ? test_files+6:7) + (gabba ? 1:0))){
     fprintf(stderr,"Unable to initialize terminal (possibly insufficient lines)\n");
     exit(101);
   }
@@ -314,6 +323,7 @@
   pcm_n=test_files;
   pcm_p=pcm;
   p_pau=0;
+  p_g=gabba;
 
   min_hidecur();
   panel_redraw_full();
@@ -463,7 +473,20 @@
   }
 }
 
-void panel_update_trials(char *choices, int n){
+char *dottrim(char *in, int l){
+  int m=strlen(in);
+  if(m>l){
+    if(l<1)return "";
+    if(l<2)return ".";
+    if(l<3)return "..";
+    if(l<4)return "...";
+    in+=m-l;
+    in[0]=in[1]=in[2]='.';
+  }
+  return in;
+}
+
+void panel_update_trials(char *choices, char *correct, int n){
   if(force || n!=p_tn || memcmp(p_tl,choices,n)){
     char buf[columns+1];
     int i;
@@ -474,15 +497,112 @@
     min_putstr(buf);
 
     memcpy(p_tl,choices,n);
-    for(i=0;i<n;i++)
+    memcpy(p_tc,correct,n);
+
+    if(n>columns-strlen(buf)-3){
+      min_fg(COLOR_CYAN);
+      min_putstr("...");
+      i=n-columns+strlen(buf)+6;
+    }else{
+      i=0;
+    }
+    for(;i<n;i++){
+      if(p_g){
+        if(correct[i]==0){
+          if(p_tm==0){
+            min_fg(COLOR_MAGENTA);
+          }else{
+            min_fg(COLOR_RED);
+          }
+        }else{
+          if(p_tm==0){
+            min_fg(COLOR_CYAN);
+          }else{
+            min_fg(COLOR_GREEN);
+          }
+        }
+      }
+
       if(p_tm<2){
         min_putchar(p_tl[i]+'A');
       }else{
         min_putchar(p_tl[i]+'1');
       }
+    }
+    min_unset();
     i+=strlen(buf);
     for(;i<columns-2;i++)
       min_putchar(' ');
+
+    if(p_g){
+      int count=0;
+      for(i=0;i<n;i++)
+        count+=correct[i];
+
+      min_mvcur(1,boxrow+2);
+      if(p_tm==0){
+        /* A/B */
+        int col = columns - 4, Ac, Bc;
+        char bufA[PATH_MAX];
+        char bufB[PATH_MAX];
+        char bufAn[10];
+        char bufBn[10];
+        char *Ap=bufA,*Bp=bufB;
+        double p=compute_pdual(count,n);
+        snprintf(bufA,PATH_MAX,"%s: ",pcm_p[0]->path);
+        snprintf(bufB,PATH_MAX,"%s: ",pcm_p[1]->path);
+        snprintf(bufAn,10,"%d ",n-count);
+        snprintf(bufBn,10,"%d ",count);
+        if(n>1)
+          sprintf(buf," p': %.2g ",(float)p);
+        else
+          sprintf(buf," p': --- ");
+        col-=strlen(buf);
+        Ac=strlen(bufA)+strlen(bufAn);
+        Bc=strlen(bufB)+strlen(bufBn);
+
+        if(Ac+Bc > col){
+          if(Ac<=col/2){
+            Bp = dottrim(bufB, col-Ac-strlen(bufBn));
+          }else if(Bc<=col/2){
+            Ap = dottrim(bufA, col-Bc-strlen(bufAn));
+          }else{
+            Ap = dottrim(bufA, col/2-strlen(bufAn));
+            Bp = dottrim(bufB, col-col/2-strlen(bufBn));
+          }
+        }
+
+        min_putchar(' ');
+        min_putstr(Ap);
+        min_fg(COLOR_MAGENTA);
+        min_putstr(bufAn);
+        min_unset();
+        min_putchar(' ');
+        min_putstr(Bp);
+        min_fg(COLOR_CYAN);
+        min_putstr(bufBn);
+        min_unset();
+        min_putstr(" p': ");
+        if(p<.01)
+          min_fg(COLOR_GREEN);
+        min_putstr(buf+5);
+     }else{
+        /* A/B/X, X/X/Y */
+        double p=compute_psingle(count,n);
+        sprintf(buf," Score: %d/%d  p': ",count,n);
+        min_putstr(buf);
+        if(n){
+          sprintf(buf,"%.2g   ",(float)p);
+          if(p<.01)
+            min_fg(COLOR_GREEN);
+        }else{
+          min_fg(COLOR_CYAN);
+          sprintf(buf,"---    ");
+        }
+        min_putstr(buf);
+      }
+    }
+    min_unset();
   }
 }
 



More information about the commits mailing list