//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Thu Sep 22 22:51:04 GMTDT 2005
// Last Modofied: 6 October 2005
// Filename: ...sig/doc/examples/improv/synthImprov/backbeat/backbeat.cpp
// Syntax: C++; synthImprov 2.0
//
// Description: Records reverse conducting data for the Mazurka Project.
//
//
#include "synthImprov.h"
#include <ctype.h>
#ifdef OLDCPP
#include <fstream.h>
#include <iomanip.h>
#else
#include <fstream>
#include <iomanip>
using namespace std;
#endif
// include files for timing info
#include <time.h>
#include <stdio.h>
#include <sys/timeb.h>
void measureCPU(void);
void findClockBoundary(int64bits& cycles, time_t& seconds, int& millisec);
/*----------------- beginning of improvization algorithms ---------------*/
int measureno = 2;
int pickupQ = 0; // toggle for changing the starting beat position
int beatno = 1;
int beatsperbar = 3;
int starttime = -1;
ofstream outputfile;
/*--------------------- maintenance algorithms --------------------------*/
void description(void) {
printboxtop();
psl(
" BACKBEAT - by Craig Stuart Sapp <craig@ccrma.stanford.edu> - 21 Sep 2005");
psl("");
printintermediateline();
psl(" Press upper case 'C' to set the CPU speed of your computer first,");
psl(" then press the space bar for beats and any other key for a beat");
psl(" in a new measure. Triple meter is the default beat counting method.");
psl(" Press the a number key to select a different number of beats per bar.");
psl("");
psl(" The data is echoed to the screen and also to a file called test.dat.");
psl(" Rename test.dat after exiting the data entry program to save the data");
psl(" before running this program again, since it will erase the previous");
psl(" contents of test.dat.");
printboxbottom();
}
void initialization(void) {
description();
outputfile.open("test.dat");
}
void finishup(void) {
cout << "*-\t*-\t*-\t*-\n";
outputfile << "*-\t*-\t*-\t*-\n";
outputfile.close();
}
/*-------------------- main loop algorithms -----------------------------*/
void mainloopalgorithms(void) {
}
/*-------------------- triggered algorithms -----------------------------*/
void keyboardchar(int key) {
static int lasttime = -1;
int atime = 0;
int dtime = 0;
int value;
if (key == 'p') {
pickupQ = 1;
cout << "Select pickup beat number." << endl;
return;
}
if (!isdigit(key)) {
pickupQ = 0;
}
if ((pickupQ == 1) && isdigit(key)) {
// set the starting beat of the pickup
value = key - '0';
if (value < 1) {
value = 1;
} else if (value > beatsperbar) {
value = beatsperbar;
}
beatno = value;
cout << "Pickup beat set to : " << value << endl;
pickupQ = 0;
return;
}
if (!isdigit(key)) {
if (starttime <= 0) {
starttime = t_time;
cout << "**kern\t**beat\t**abstime\t**deltatime\n";
outputfile << "**kern\t**beat\t**abstime\t**deltatime\n";
}
if (lasttime < 0) {
lasttime = 0;
}
atime = t_time - starttime;
dtime = atime - lasttime;
lasttime = atime;
}
switch (key) {
case ' ': // beat marker
cout << "4\t" << beatno << "\t" << atime << "\t" << dtime << endl;
outputfile << "4\t" << beatno << "\t" << atime << "\t" << dtime << endl;
break;
case '1': beatsperbar = 1; cout << "Beats per bar = 1" << endl; break;
case '2': beatsperbar = 2; cout << "Beats per bar = 2" << endl; break;
case '3': beatsperbar = 3; cout << "Beats per bar = 3" << endl; break;
case '4': beatsperbar = 4; cout << "Beats per bar = 4" << endl; break;
case '5': beatsperbar = 5; cout << "Beats per bar = 5" << endl; break;
case '6': beatsperbar = 6; cout << "Beats per bar = 6" << endl; break;
case '7': beatsperbar = 7; cout << "Beats per bar = 7" << endl; break;
case '8': beatsperbar = 8; cout << "Beats per bar = 8" << endl; break;
case '9': beatsperbar = 9; cout << "Beats per bar = 9" << endl; break;
case '0': measureCPU(); break;
default:
cout << "=" << measureno << "\t=" << measureno << "\t=" << measureno << "\n";
outputfile << "=" << measureno << "\t=" << measureno
<< "\t=" << measureno << "\t=" << measureno << "\n";
measureno++;
cout << "4\t" << beatno << "\t" << atime << "\t" << dtime << endl;
outputfile << "4\t" << beatno << "\t" << atime << "\t" << dtime << endl;
}
if (!isdigit(key)) {
beatno++;
if (beatno > beatsperbar) {
beatno = 1;
}
}
}
//////////////////////////////
//
// measureCPU -- measure the CPU speed of the computer more accurately.
//
// reference: http://msdn.microsoft.com/library/en-us/vclib/html/_crt_time.asp
//
void measureCPU(void) {
static int init = -1;
static int64bits startcycles;
static time_t startseconds;
static int startmilliseconds;
time_t currentseconds;
int currentmilliseconds;
// struct timeb tstruct;
int64bits currentcycles;
int64bits totalms;
int64bits cyclediff;
double cpuspeed;
double maxcpuspeed;
double drift;
if (init <= 0) {
init = 1;
// time(&startseconds); // second since 1/1/70
// ftime(&tstruct);
// startmilliseconds = tstruct.millitm;
// startcycles = SigTimer::clockCycles();
findClockBoundary(startcycles, startseconds, startmilliseconds);
} else {
//time(¤tseconds);
//ftime(&tstruct);
//currentmilliseconds = tstruct.millitm;
//currentcycles = SigTimer::clockCycles();
findClockBoundary(currentcycles, currentseconds, currentmilliseconds);
totalms = (currentseconds - startseconds) * 1000;
totalms = totalms - startmilliseconds;
totalms = totalms + currentmilliseconds;
// the totalms value is accurate to within +/- 20 milliseconds
// so calculate the cpu speed and the possible error in the
// timing measurement
cyclediff = currentcycles - startcycles;
cpuspeed = cyclediff / totalms * 1000.0;
maxcpuspeed = cyclediff / (totalms - 20) * 1000.0;
drift = 1.0 / (maxcpuspeed - cpuspeed);
drift = 1000.0 * drift / totalms * 3600000.0;
drift = maxcpuspeed - cpuspeed;
drift = drift / cpuspeed * 3600000.0;
maxcpuspeed = maxcpuspeed / 1000.0 / 1000.0;
cpuspeed = cpuspeed / 1000.0 / 1000.0;
cout << "Measured CPU speed: " << setprecision(9) << cpuspeed
<< " MHz +/- " << setprecision(9) << maxcpuspeed - cpuspeed
<< " MHz, drift +/- " << drift << " ms/hr" << endl;
}
}
void findClockBoundary(int64bits& cycles, time_t& seconds, int& millisec) {
time_t startseconds;
int startmilliseconds;
struct timeb tstruct;
time(&startseconds);
ftime(&tstruct);
startmilliseconds = tstruct.millitm;
seconds = startseconds;
millisec = startmilliseconds;
while (millisec == startmilliseconds) {
ftime(&tstruct);
millisec = tstruct.millitm;
}
cycles = SigTimer::clockCycles();
time(&seconds);
cout << "Millidif = " << millisec << " - " << startmilliseconds
<< " = " << millisec - startmilliseconds << endl;
}
/*------------------ end improvization algorithms -----------------------*/
// md5sum: 6cd3870b213a449079f2c812850a71b1 backbeat.cpp [20090615]