#define _BSD_SOURCE
#include <fcntl.h>
#include <getopt.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/kd.h>

#ifndef CLOCK_TICK_RATE
  #define CLOCK_TICK_RATE 1193180
#endif

int console_fd = -1;

typedef struct beep_parms_t {
  float freq;
  int length;
  int reps;
  int delay;
  int end_delay;
  int stdin_beep;
} beep_parms_t;

void handle_signal(int signum) {
  switch(signum) {
    case SIGINT:
      if(console_fd >= 0) {
        ioctl(console_fd, KIOCSOUND, 0);
        close(console_fd);
        exit(signum);
      } else {

      /* Just quit gracefully */

      exit(signum);
    }
  }
}

void play_beep(beep_parms_t parms){
  int i;
  if((console_fd = open("/dev/tty1", O_WRONLY)) == -1) {
    fprintf(stderr, "Run as root/sudo\n");
    perror("open");
    exit(1);
  }

  /* Beep */
  for (i = 0; i < parms.reps; i++) {                    /* start beep */
    if(ioctl(console_fd, KIOCSOUND, (int)(CLOCK_TICK_RATE/parms.freq)) < 0) {
      perror("ioctl");
    }
    usleep(1000*parms.length);                          /* wait…    */
    ioctl(console_fd, KIOCSOUND, 0);                    /* stop beep  */
    if(parms.end_delay || (i+1 < parms.reps))
       usleep(1000*parms.delay);                        /* wait…    */

  }                                                     /* repeat.    */
  close(console_fd);
}


void playIt (float freq) {
  int len = 30;
  //char sin[4096], *ptr;

  beep_parms_t *parms = (beep_parms_t *)malloc(sizeof(beep_parms_t));
  parms->freq = freq; parms->length = len;parms->reps=40;parms->delay = 0.1;
  parms->end_delay  = 0; parms->stdin_beep = 2; signal(SIGINT, handle_signal);
  play_beep(*parms); free(parms);
}

void playUt (float freq) {
  int len = 8;
  //char sin[4096], *ptr;

  beep_parms_t *parms = (beep_parms_t *)malloc(sizeof(beep_parms_t));
  parms->freq = freq; parms->length = len;parms->reps=1;parms->delay =40;
  parms->end_delay  = 40; parms->stdin_beep = 2; signal(SIGINT, handle_signal);
  play_beep(*parms); free(parms); /* printf(” %f \n”, freq); */
}

void bass () { playUt(130.813); }
void snare () { playUt(523.252); }
void hh () { playUt(4186.016); }
void not () { playUt(2); }
void bass2() { playUt(110); }
void snare2 () { playUt(440); }
void hh2 () { playUt(3520); }


void beat () {
  bass();not();
  hh();not();
  snare();not();
  hh();not();
  bass();not();
  hh();not();
  snare();not();
  hh();not();
}


void beat2 () {
  bass2();not();
  hh2();not();
  snare2();not();
  hh2();not();
  bass2();not();
  hh2();not();
  snare2();not();
  hh2();not();
}

int main(int argc, char **argv) {
  (void) argc;
  (void) argv;

  signal(SIGINT, handle_signal);
  beat();beat();beat2();beat2();beat();beat();beat2();beat2();
  return 0;
}
