class Config
{
public:
- Config(uint32_t timestamp=0, uint32_t end=0, uint32_t time=0, uint32_t ticks=0,
+ Config(uint8_t buttons, uint32_t timestamp=0, uint32_t endtimestamp=0, uint32_t time=0, uint32_t ticks=0);
+
+ Config(uint32_t timestamp=0, uint32_t endtimestamp=0, uint32_t time=0, uint32_t ticks=0,
bool a=false, bool b=false, bool c=false, bool d=false, bool e=false);
Config(const Config &cf);
public:
Mixer();
~Mixer();
- static void playMusic(const String &);
+ static void loadMusic(const String &);
+ static void playMusic();
static void stopMusic();
void playSound(const String &);
void stopSound(const int &);
bool addSound(const String &s, const String &filename);
static void channelStopped(int);
- int getMusicVolume() const { return _musicVolume; }
+ int getMusicVolume() const { return _musicVolume; }
void setMusicVolume(const int &);
- int getSoundVolume() const { return _soundVolume; }
+ int getSoundVolume() const { return _soundVolume; }
void setSoundVolume(const int &);
static void initMixer();
//maximum number of bytes available, it will return only the\r
//bytes available. The function return -1 when nothing could\r
//be read, the number of bytes actually read.\r
- virtual int ReadData(char *buffer, unsigned int nbChar)=0;\r
+ virtual int ReadData(void *buffer, unsigned int nbChar)=0;\r
\r
//Writes data from a buffer through the Serial connection\r
//return true on success.\r
- virtual bool WriteData(char *buffer, unsigned int nbChar)=0;\r
+ virtual bool WriteData(void *buffer, unsigned int nbChar)=0;\r
\r
//Check if we are actually connected\r
bool IsConnected() { return _connected; }\r
//maximum number of bytes available, it will return only the\r
//bytes available. The function return -1 when nothing could\r
//be read, the number of bytes actually read.\r
- int ReadData(char *buffer, unsigned int nbChar);\r
+ int ReadData(void *buffer, unsigned int nbChar);\r
//Writes data from a buffer through the Serial connection\r
//return true on success.\r
- bool WriteData(char *buffer, unsigned int nbChar);\r
+ bool WriteData(void *buffer, unsigned int nbChar);\r
\r
\r
private:\r
Track(const Track &);
//create an empty track with the specified tempo and specified duration
Track(uint32_t tempo, uint32_t duration);
+ //create a track for speed/accuracy experiments
+ Track(uint8_t nbbuttons, uint8_t repetitions, uint8_t nbspeeds, uint32_t *speeds);
~Track();
void addKey(uint32_t time, uint8_t note);
{
}
+Config::Config(uint8_t buttons, uint32_t timestamp, uint32_t endtimestamp, uint32_t time, uint32_t ticks)
+:_timestamp(timestamp), _endtimestamp(endtimestamp), _time(time), _ticks(ticks),
+_a(buttons & 0x01), _b((buttons >> 1) & 0x01), _c((buttons >> 2) & 0x01), _d((buttons >> 3) & 0x01), _e((buttons >> 4) & 0x01)
+{
+}
+
Config::Config(const Config &cf)
:_timestamp(cf._timestamp), _endtimestamp(cf._endtimestamp), _time(cf._time), _ticks(cf._ticks),
_a(cf._a), _b(cf._b), _c(cf._c), _d(cf._d), _e(cf._e)
extern struct timeval start;
#endif
-#define BEFOREDELAY 150
+#define BEFOREDELAY 2000
extern FILE *logfile;
MetronomeHaptic::MetronomeHaptic(const Track *track, uint32_t nbbeats, uint32_t tempo, bool activated)
-:Metronome(track, nbbeats, tempo, activated), thread(NULL), _comport(new SerialWindows("COM5"))
+:Metronome(track, nbbeats, tempo, activated), thread(NULL), _comport(new SerialWindows("COM3"))
{
+ unsigned char buffer1[3];\r
+ buffer1[0] = 'N'; buffer1[1] = 0x00; buffer1[2] = 0x01;\r
+ unsigned char buffer2[6];\r
+ buffer2[0] = 0x01; //pattern\r
+ buffer2[1] = 0; buffer2[2] = 100; //duration\r
+ buffer2[3] = 0; buffer2[4] = 250; //frequency\r
+ buffer2[5] = 255; //amplitude\r
+\r
+ //Tacton 1\r
+ _comport->WriteData(buffer1, 3);
+ _comport->WriteData(buffer2, 6);
+\r
+/* char INBUFFER[128];\r
+ memset(INBUFFER, 0, 128);
+ int nbread = _comport->ReadData(INBUFFER, 128);
+ stringstream s;
+ s << nbread << " read:\n" << INBUFFER << endl;
+ OutputDebugString(s.str().c_str());*/\r
+ \r
+ //Tacton 2\r
+ buffer2[0] = 0x02; //pattern\r
+ _comport->WriteData(buffer1, 3);
+ _comport->WriteData(buffer2, 6);
+
+/* memset(INBUFFER, 0, 128);
+ nbread = _comport->ReadData(INBUFFER, 128);
+ stringstream s2;
+ s2 << nbread << " read:\n" << INBUFFER << endl;
+ OutputDebugString(s2.str().c_str());*/
+ \r
+ //Tacton 3\r
+ buffer2[0] = 0x04; //pattern\r
+ _comport->WriteData(buffer1, 3);
+ _comport->WriteData(buffer2, 6);
+
+/* memset(INBUFFER, 0, 128);
+ nbread = _comport->ReadData(INBUFFER, 128);
+ stringstream s3;
+ s3 << nbread << " read:\n" << INBUFFER << endl;
+ OutputDebugString(s3.str().c_str());*/
+
+ //Tacton 4\r
+ buffer2[0] = 0x08; //pattern\r
+ _comport->WriteData(buffer1, 3);
+ _comport->WriteData(buffer2, 6);
+
+/* memset(INBUFFER, 0, 128);
+ nbread = _comport->ReadData(INBUFFER, 128);
+ stringstream s4;
+ s4 << nbread << " read:\n" << INBUFFER << endl;
+ OutputDebugString(s4.str().c_str());*/
}
MetronomeHaptic::~MetronomeHaptic()
{
+ _comport->WriteData("Q", 1);
_activated = false;
delete _comport;
SDL_WaitThread(thread, NULL);
Metronome::setTempo(tempo);\r
//send info to Serial Port\r
//char outBuffer[5];\r
- char outBuffer[5];// = {'T', 'A', 'B', 'C', 'D'};\r
+ /*char outBuffer[5];// = {'T', 'A', 'B', 'C', 'D'};\r
memset(outBuffer, 0, 5);
- /*sprintf(OUTBUFFER, "T%3d\n", 60000000/tempo);*/\r
+ sprintf(OUTBUFFER, "T%3d\n", 60000000/tempo);\r
outBuffer[0] = 'T';\r
outBuffer[1] = (tempo & 0xff000000) >> 24;\r
outBuffer[2] = (tempo & 0x00ff0000) >> 16;\r
outBuffer[4] = tempo & 0x000000ff;\r
bool written = _comport->WriteData(outBuffer, 5);\r
- /*
+
char INBUFFER[128];\r
memset(INBUFFER, 0, 128);
int nbread = _comport->ReadData(INBUFFER, 128);
{
Metronome::setNbBeats(nbbeats);\r
//send info to Serial Port\r
- char outBuffer[5];// = {'B', '5', '6', '7', '8'};\r
+/* char outBuffer[5];// = {'B', '5', '6', '7', '8'};\r
memset(outBuffer, 0, 5);
-/* sprintf(OUTBUFFER, "B%3d\n", nbbeats);*/\r
+ sprintf(OUTBUFFER, "B%3d\n", nbbeats);\r
outBuffer[0] = 'B';\r
outBuffer[1] = (nbbeats & 0xff000000) >> 24;\r
outBuffer[2] = (nbbeats & 0x00ff0000) >> 16;\r
\r
bool written = _comport->WriteData(outBuffer, 5);\r
-/* char INBUFFER[128];\r
+ char INBUFFER[128];\r
memset(INBUFFER, 0, 128);
int nbread = _comport->ReadData(INBUFFER, 128);
stringstream s;
#ifdef WIN32
struct { int tv_sec, tv_usec; } now;//, start
- DWORD t = timeGetTime () - BEFOREDELAY;
+ DWORD t = timeGetTime () + BEFOREDELAY;
/* start.tv_sec = t / 1000;
start.tv_usec = (t % 1000) * 1000;*/
#else
#endif*/
//float currenttime = 0;
- char outBuffer[5];\r
- outBuffer[0] = 'S';\r
- outBuffer[1] = 0;\r
- outBuffer[2] = 0;\r
- outBuffer[3] = 0;\r
- outBuffer[4] = 0;\r
- bool written = thismetronome->_comport->WriteData(outBuffer, 5);
+ bool written = thismetronome->_comport->WriteData("S", 1);
+ unsigned char outBuffer[6];
+ outBuffer[0] = 'P';
+ unsigned char currentbeat = 0;
while(thismetronome->_activated)
{
while (cBips != bips->end() && currenttime >= BIPTIMESTAMP(*cBips))
{
- char outBuffer[5];\r
- outBuffer[0] = 'N';\r
- outBuffer[1] = (BIPTIMESTAMP(*cBips) & 0xff000000) >> 24;\r
- outBuffer[2] = (BIPTIMESTAMP(*cBips) & 0x00ff0000) >> 16;\r
- outBuffer[3] = (BIPTIMESTAMP(*cBips) & 0x0000ff00) >> 8;\r
- outBuffer[4] = BIPTIMESTAMP(*cBips) & 0x000000ff;\r
- \r
- bool written = thismetronome->_comport->WriteData(outBuffer, 5);\r
+/* char outBuffer[5];\r
+ outBuffer[0] = 'N';*/\r
+ outBuffer[1] = currentbeat % 4;\r
+ outBuffer[2] = (BIPTIMESTAMP(*cBips) & 0xff000000) >> 24;\r
+ outBuffer[3] = (BIPTIMESTAMP(*cBips) & 0x00ff0000) >> 16;\r
+ outBuffer[4] = (BIPTIMESTAMP(*cBips) & 0x0000ff00) >> 8;\r
+ outBuffer[5] = BIPTIMESTAMP(*cBips) & 0x000000ff;\r
+\r
+ bool written = thismetronome->_comport->WriteData(outBuffer, 6);\r
+/* char INBUFFER[128];\r
+ memset(INBUFFER, 0, 128);
+ int nbread = thismetronome->_comport->ReadData(INBUFFER, 128);
+ stringstream s;
+ s << nbread << " read:\n" << INBUFFER << endl;
+ OutputDebugString(s.str().c_str());*/\r
+
if (logfile)
fprintf(logfile, "BIP;%d;%d;%d\n", BIPTICK(*cBips), BIPTIMESTAMP(*cBips), currenttime);
+ currentbeat = (currentbeat + 1) % thismetronome->_nbbeats;
cBips++;
}
// on avance tant que les tempos sont dépassées
while (cTimesignature != timesignatures->end() && currenttime >= TIMESTAMP(*cTimesignature))
{
- char outBuffer[5];\r
+/* char outBuffer[5];\r
outBuffer[0] = 'B';\r
outBuffer[1] = (TIMESTAMP(*cTimesignature) & 0xff000000) >> 24;\r
outBuffer[2] = (TIMESTAMP(*cTimesignature) & 0x00ff0000) >> 16;\r
outBuffer[4] = TIMESTAMP(*cTimesignature) & 0x000000ff;\r
\r
bool written = thismetronome->_comport->WriteData(outBuffer, 5);\r
-
+ */
+ //tempo change
+ stringstream s;
+ s << "Time signature change at " << currenttime << " : tick=" << (*cTimesignature).first << " at " << (*cTimesignature).second.getX() << " for " << (*cTimesignature).second.getY() << " beats " << endl;
+ OutputDebugString(s.str().c_str());
+ thismetronome->_nbbeats = (*cTimesignature).second.getY();
cTimesignature++;
}
}*/
}
-void Mixer::playMusic(const String &filename)
+void Mixer::loadMusic(const String &filename)
{
//_debug_(stderr, "playMusic(%s)\n",filename.c_str());
if (_music)
if (buffer != "")
{
- SDL_mutexP(_mutex);
+// SDL_mutexP(_mutex);
_music = Mix_LoadMUS(buffer.c_str());
if(_music==NULL)
fprintf(stderr, "cannot load music %s\n",buffer.c_str());
- else
+/* else
{
Mix_PlayMusic(_music, -1);
Mix_HookMusicFinished(stopMusic);
- }
- SDL_mutexV(_mutex);
+ }*/
+// SDL_mutexV(_mutex);
}
else
fprintf(stderr, "music file %s not found\n",filename.c_str());
// cout << "music file " << filename << " not found" << endl;
}
+void Mixer::playMusic()
+{
+ if(_music != NULL)
+ {
+ Mix_PlayMusic(_music, -1);
+ Mix_HookMusicFinished(stopMusic);
+ }
+}
+
void Mixer::stopMusic()
{
Mix_HaltMusic();
snd = _sounds[s];
}
- SDL_mutexP(_mutex);
+// SDL_mutexP(_mutex);
bool res = snd->addSound(filename);
- SDL_mutexV(_mutex);
+// SDL_mutexV(_mutex);
return res;
}
throw "Impossible to initialize SDL_GL_MULTISAMPLESAMPLES";
// int flags = SDL_OPENGL | SDL_OPENGLBLIT | SDL_SWSURFACE | SDL_FULLSCREEN;
- int flags = SDL_OPENGL | SDL_FULLSCREEN;
+ int flags = SDL_OPENGL;// | SDL_FULLSCREEN;
SDL_Surface * screen;
+ resolution_x = 1024;
+ resolution_y = 768;
// if (!(screen = SDL_SetVideoMode(resolution_x, resolution_y, 0, flags)))
if (!(screen = SDL_SetVideoMode(resolution_x, resolution_y, 0, flags)))
throw "Impossible to change the video mode";
init();
cout << "Create Metronome" << endl;
- Metronome *m = new MetronomeAudio(&tr);
-// Metronome *m = new MetronomeHaptic(&tr);
+// Metronome *m = new MetronomeAudio(&tr);
+ Metronome *m = new MetronomeHaptic(&tr);
bool quitProgram = false;
cout << "Init paint" << endl;
initPaint();
+ Mixer::getInstance()->loadMusic(songname + "/tout.ogg");
//must be done before paint and metronomes
#ifdef WIN32
cout << "LET'S ROCK!" << endl;
//m->setActive(true);
- Mixer::getInstance()->playMusic(songname + "/tout.ogg");
+ Mixer::getInstance()->playMusic();
m->run();
/* Mixer::getInstance()->playSound("guitar");
if (rhythm)
}\r
}\r
\r
-int SerialWindows::ReadData(char *buffer, unsigned int nbChar)\r
+int SerialWindows::ReadData(void *buffer, unsigned int nbChar)\r
{\r
//Number of bytes we'll have read\r
DWORD bytesRead = 0;\r
}\r
\r
\r
-bool SerialWindows::WriteData(char *buffer, unsigned int nbChar)\r
+bool SerialWindows::WriteData(void *buffer, unsigned int nbChar)\r
{\r
DWORD bytesSend;\r
\r
//Try to write the buffer on the Serial port\r
- if(!WriteFile(_hSerial, (void *)buffer, nbChar, &bytesSend, 0))\r
+ if(!WriteFile(_hSerial, buffer, nbChar, &bytesSend, 0))\r
{\r
//In case it don't work get comm error and return false\r
ClearCommError(_hSerial, &_errors, &_status);\r
#include <windows.h>
#include <iostream>
#include <sstream>
+#include <algorithm>
+#include <vector>
using namespace std;
extern Texture* texturesteel, *texturefrett;
{
for (uint8_t i = 0 ; i < NBDIFFICULTIES ; i++)
{
- _currentconfig[i] = 0;
+ _currentconfig[i] = (uint8_t) 0;
_nbnotes[i] = 0;
_totallength[i] = 0;
}
_bips.push_back(Pair<uint32_t, uint32_t>(i, i * t / 1000 + 2000));
}
+/**
+ Experimentation track
+ nbbuttons: maximum buttons
+ repetitions: repetitions of all buttons configurations for a given speed
+ nbspeeds: number of speeds
+ speeds:
+*/
+Track::Track(uint8_t nbbuttons, uint8_t repetitions, uint8_t nbspeeds, uint32_t *speeds)
+{
+ uint32_t tick = 0, timestamp = 2000;
+ addTimesignature(0, 0, 1);
+
+ for (int n = 0 ; n < nbspeeds ; n++)
+ {
+ uint32_t tempo = 60000000 / speeds[n];
+ addTempo(tick, timestamp, tempo);
+ vector<uint8_t> configs;
+
+ for (int i = 1 ; i < (int)pow(2.0, (double)nbbuttons) ; i++)
+ for (int j = 0 ; j < repetitions ; j++)
+ configs.push_back(i);
+ random_shuffle(configs.begin(), configs.end());
+
+ for (vector<uint8_t>::iterator it = configs.begin() ; it != configs.end() ; it++)
+ {
+ for (int d=0 ; d < NBDIFFICULTIES ; d++)
+ _notes[d][tick] = Config(*it, timestamp, timestamp+100, tick, 1);
+ tick++;
+ timestamp += tempo / 1000;
+ }
+ }
+}
+
Track::~Track()
{
}
struct tm *t = gmtime(&tim);
cout << "Loading song" << endl;
+ //6 params => toms law experiment
+ // v0 = prog
+ // v1 = condition
+ // v2 = user
+ // v3 = speed
+ // v4 = duration
+ // v5 = distance
if (argc >= 6)
{
Track tr(atoi(argv[3]), atoi(argv[4]));
//run the game with a click track
loop(tr, songname);
}
+ //6 params => speed accuracy experiment
+ // v0 = prog
+ // v1 = condition
+ // v2 = user
+ // v3 = nbbuttons
+ // v4 = nbrepetitions
+ else if (argc >= 5)
+ {
+ uint32_t speeds[] = {40, 80, 120, 160, 200};
+ Track tr(atoi(argv[3]), atoi(argv[4]), 5, speeds);
+ SECONDSIZE = 0.08;
+
+ String logfilename = String(argv[1]) + "-" + String(argv[2]) + "-" + \
+ String(1900 + t->tm_year) + "-" + String(t->tm_mon) + "-" + String(t->tm_mday) + "-" + \
+ String(t->tm_hour) + "-" + String(t->tm_min) + "-" + String(t->tm_sec) + "-" + \
+ String(argv[3]) + "-" + String(argv[4]);
+ logfile = fopen(logfilename.c_str(), "w");
+ //run the game with the experiment track
+ loop(tr, songname);
+ }
else
{
if (argc >= 3)
{
- String logfilename = String(argv[1]) + "-" + String(argv[2]) + "-" + String(1900 + t->tm_year) + "-" + String(t->tm_mon) + "-" + String(t->tm_mday) + "-" + String(t->tm_hour) + "-" + String(t->tm_min) + "-" + String(t->tm_sec) + "-" + String(argv[1]);
+ String logfilename = String(argv[1]) + "-" + String(argv[2]) + "-" + String(1900 + t->tm_year) + "-" + String(t->tm_mon) + "-" + String(t->tm_mday) + "-" + String(t->tm_hour) + "-" + String(t->tm_min) + "-" + String(t->tm_sec);
logfile = fopen(logfilename.c_str(), "w");
}