NAME

tapbox - tap detection via the dual-channel tap encoder: TapGet()

SYNOPSIS

#include <tapbox_u.h>

int TapGet(tc, ti)
struct tapconnect tc;
struct tapinfo *ti;

DESCRIPTION

Detects taps via the dual-channel tap encoder built by John Andrews-Labenski.

TapGet(tc,ti)
TapGet() detects, and provides detailed information about, taps. An option for audio feedback is provided. The clock must be running. At least 5 msec should be allowed for TapGet() to initialize the hardware. If TapGet() detects an error, an explanatory message is placed in ti.error, and -1 is returned. Potential error messages include:

CLOCK_NOT_RUNNING
UNRECOG_CLOCK_RATE
CANNOT START SAMPLING
TAP_TIMEOUT
FIRST_EVENT_NOT_LO_THRESH_ON
SECOND_EVENT_NOT_HI_THRESH_ON
THIRD_EVENT_NOT_HI_THRESH_OFF
FOURTH_EVENT_NOT_LO_THRESH_OFF

struct tapconnect tc provides necessary information about wiring, audio feedback, and thresholds. TapGet() treats this structure as read-only. struct tapconnect is declared in tapbox_u.h as:

struct tapconnect {
  int       hand;              /* TAPBOX_HAND_LEFT || _RIGHT */
  unsigned  maxwait;           /* timeout when clock hits maxwait */
  unsigned *sound;             /* SoundPlay()-compatible object */
  int       da_hi_channel;     /* D/A channel: set high thresh */
  short     da_hi_thresh;      /* D/A value: high thresh */
  int       ad_peak_channel;   /* A/D channel: read peak force */
  unsigned  obuf_reset;        /* output bit: reset circuit */
  unsigned  ibuf_low;          /* input bit: low thresh */
  unsigned  ibuf_high;         /* input bit: high thresh */
};
If no audible feedback is desired, set click to NULL. The click will begin playing when the high threshold is crossed.

struct tapinfo *ti holds the result of a tap detection. struct tapinfo is declared in tapbox_u.h as:

struct tapinfo {
  unsigned LowOn;             /* time of low onset */
  unsigned LowOff;            /* time of low offset */
  unsigned HighOn;            /* time of high onset */
  unsigned HighOff;           /* time of high offset */
  int      peak;              /* value of peak force */
  char     error[30];         /* error message (if any) */
};

EXAMPLES

The following example waits for a left tap, then displays tap info on the console and on the Megatek display.
#include <stdio_p.h>
#include <tapbox_u.h>
#include <mpict_p.h>
#include <clock_u.h>
#include <ibuf_u.h>
#include <dmasound_u.h>


#define BUTTONBIT 1    /* input bit #1  causes tap monitoring */
#define FOOTBIT   14   /* input bit #14 causes tap monitoring */


void TapDisplay(ti) struct tapinfo ti; {

  PICT   l_tap[3], t_tap[3];
  PICT   l_error, t_error;
  char   str[3][50];
  int    i, y;

  sprintf(str[0],"      %5s %5s %5s",    "ON",     "OFF",   "PEAK");
  sprintf(str[1],"LOW:  %5u %5u %5d", ti.LowOn,  ti.LowOff, ti.peak);
  sprintf(str[2],"HIGH: %5u %5u", ti.HighOn, ti.HighOff);

  for (i=0; i<3; i++) {
    printf("%s\\n",str[i]);
    y = -512 - (i * 150);
    l_tap[i] = mktext(str[i],7);
    t_tap[i] = mktop(-2000, y, l_tap[i]);
    vad(t_tap[i]);
  }

  if (strcmp(ti.error,"")) {
    printf("%s\\n",ti.error);
    l_error = mktext(ti.error,7);
    t_error = mktop(-1000,0,l_error);
    vad(t_error);
  }

  while(ibufx(BUTTONBIT)==0 && ibufx(FOOTBIT)==0);
  ver();
  for (i=0; i<3; i++) {
    frpic(t_tap[i]);
    frpic(l_tap[i]);
  }
  if (strcmp(ti.error,"")) {
    frpic(l_error);
    frpic(t_error);
  }
}


int main() {

  struct    tapinfo    ti;             /* tap device setup */
  struct    tapconnect tc;             /* tap results */
  unsigned *click;                     /* audible feedback */
  unsigned  channel = DMA_SOUND_BOTH;  /* binaural monophonic */
  double    freq = 3000.0;             /* 3000 Hz */
  double    cycles = 15.0;             /* = 5 msec */
  double    amp = 1536.0;              /* high amplitude */
  double    ramp = 1.0;                /* 1 msec ramp (on each end) */

  printf("Grab a left tap and display info on console and Megatek.\\n");
  printf("Press foot pedal to go on to the next tap\\n");

  click = ToneSinCreate(channel, freq, cycles, amp, ramp);

  tc.hand = TAPBOX_HAND_LEFT; /* hand for tapping */
  tc.maxwait = 20000;         /* timeout when clock hits maxwait */
  tc.sound = click;           /* audio feedback */
  tc.da_hi_channel = 4;       /* D/A channel: set high thresh */
  tc.da_hi_thresh  = 128;     /* D/A value: high thresh */
  tc.ad_peak_channel = 3;     /* A/D channel: read peak force */
  tc.obuf_reset = 1;          /* output bit: reset circuit */
  tc.ibuf_low  = 7;           /* input bit: low  thresh */
  tc.ibuf_high = 9;           /* input bit: high thresh */

  for (;;) {
    ckreset(CKR_1MS);
    ckstart;
    TapGet(tc,&ti);
    ckstop;
    TapDisplay(ti);
  }
}

LIMITATIONS

TapGet() cannot correctly handle two simultaneous or near-simultaneous taps. Simultaneous tap detection is possible, but the complexity of such an interface and function is probably best left to a seperate routine.

SEE ALSO

dtoa(3U) , ibuf(3U) , obuf(3U) , dmasound(3U) , dual-channel tap encoder manual by John Andrews-Labenski.