i'm working on gesture recognition application and i would like to implement timer but i don't know how.
here is what i want to do: user should be showing one gesture for 3 seconds before next function happens.
now it looks like this:
if(left_index==1)
{
putText("correct",Point(95,195),FONT_HERSHEY_COMPLEX_SMALL,0.8,Scalar(0,255,0),1,CV_AA);
correct = true;
}
break;
i would like it to be like this: if(left_index==1) <- if this is true for 3 seconds than the {} happens.
thank you for help.
there is a built-in function called sleep. It will kind of put your program at rest for int x milliseconds
I will make a function wait(int seconds):
void wait(long seconds)
{
seconds = seconds * 1000;
sleep(seconds);
}
wait(1); //waits for 1 second or 1000 milliseconds
You could try the following:
#include <time.h>
#include <unistd.h>
// Whatever your context is ...
if(left_index==1)
{
clock_t init, now;
init=clock();
now=clock();
while((left_index==1) && ((now-init) / CLOCKS_PER_SEC) < 3))
{
sleep(100); // give other threads a chance!
now=clock();
}
if((left_index==1) && (now-init) / CLOCKS_PER_SEC) >= 3))
{
// proceed with stuff
putText
( "correct"
, Point(95,195)
, FONT_HERSHEY_COMPLEX_SMALL,0.8,Scalar(0,255,0),1,CV_AA);
correct = true;
}
}
For c++11 I'd prefer a solution involving the classes from std::chrono instead working with time.h.
Also, you can try doing the following :
#include <time.h>
clock_t init, final;
init=clock();
//
// do stuff
//
final=clock()-init;
cout << (double)final / ((double)CLOCKS_PER_SEC);
Check these links out for further reference :
http://www.cplusplus.com/forum/beginner/317/
http://www.cplusplus.com/reference/ctime/
assuming your app is running an update loop.
bool gesture_testing = false;
std::chrono::time_point time_start;
while(app_running) {
if (! gesture_testing) {
if (left_index == 1) {
gesture_testing = true;
time_start = std::chrono::high_resolution_clock::now();
}
} else {
if (left_index != 1) {
gesture_testing = false;
} else {
auto time_end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::seconds>(time_end - time_start);
if (duration.count() == 3) {
// do gesture function
gesture_testing = false;
}
}
}
}
this is the basic logic, you can write a timer class and refactor the body into one function to make room for other part of your app.
Related
What would be the best way to add a chronometer because this type of chronometer that I invented makes my game snake advance in 1 second and its really slow
void timer()
{
int g = 1;
int h = 0;
while (g != 0)
{
Sleep(1000);
h = h + 1;
gotoxy(50, 1); printf("Tiempo: %d",h);
}
}
Some pseudo-code to give you an idea of how it could be done:
time_type last_time = now(); // Initialize to the current time
// Main game loop
forever
{
// Do other game-related things...
// Now handle things that should be done on regular intervals
time_type current_time = now();
time_diff_type difference = current_time - last_time;
if (difference > 2 second)
{
// Do things that should be done every two seconds
}
if (difference > 1 second)
{
// Do things that should be done every second
}
last_time = current_time;
}
For the time_type and now functions, use the functionality in std::chrono.
For example, to get the current time do e.g.
auto current_time = std::chrono::system_clock::now();
And with a newer compiler and a using namespace std::literals::chrono_literals; you could actually use e.g. 1s as a second:
auto difference = current_time - last_time;
if (difference > 1s) { /* Code here... */ }
The above is valid C++ code.
I want to implement a timer that starts if a condition is true, after 3 seconds I want it to reset the timer and it shall not start to count untill the condition in the if-statement is true again. See my code below:
//--here I want to check if 3 sec has gone, and if yes, do something and reset it--
int duration;
std::clock_t start;
while (1) {
//some things here
for (something) {
//some things happening here
if (a Condition) {
start = std::clock(); <- start the timer here
}
}
}
I will use this with a video stream (opencv), thats why I have the while loop in case you wonder. I have not succeeded with this after several tries.
I am able to start the timer but then I want to have an if-statement to check if 3 seconds has passed duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC; but I am still unable solve it (both to check if time has passed and then to reset it). Any ideas will be appreciated!
Try something like this:
const std::clock_t notrunning = (std::clock_t)(-1);
inline void checkTimerReset(std::clock_t &start)
{
if (start != notrunning) {
if (((std::clock() - start) / CLOCKS_PER_SEC) >= 3)
start = notrunning;
}
}
...
std::clock_t start = notrunning;
while (1) {
some things here
for (something) {
some things happening here
if (something) {
if (start == notrunning) {
start = std::clock();
}
}
checkTimerReset(start);
}
checkTimerReset(start);
}
I have made a soft synthesizer in Visual Studio 2012 with C++, MFC and DirectX. Despite having added code to rapidly fade out the sound I am experiencing popping / clicking when stopping playback (also when starting).
I copied the DirectX code from this project: http://www.codeproject.com/Articles/7474/Sound-Generator-How-to-create-alien-sounds-using-m
I'm not sure if I'm allowed to cut and paste all the code from the Code Project. Basically I use the Player class from that project as is, the instance of this class is called m_player in my code. The Stop member function in that class calls the Stop function of LPDIRECTSOUNDBUFFER:
void Player::Stop()
{
DWORD status;
if (m_lpDSBuffer == NULL)
return;
HRESULT hres = m_lpDSBuffer->GetStatus(&status);
if (FAILED(hres))
EXCEP(DirectSoundErr::GetErrDesc(hres), "Player::Stop GetStatus");
if ((status & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
{
hres = m_lpDSBuffer->Stop();
if (FAILED(hres))
EXCEP(DirectSoundErr::GetErrDesc(hres), "Player::Stop Stop");
}
}
Here is the notification code (with some supporting code) in my project that fills the sound buffer. Note that the rend function always returns a double between -1 to 1, m_ev_smps = 441, m_n_evs = 3 and m_ev_sz = 882. subInit is called from OnInitDialog:
#define FD_STEP 0.0005
#define SC_NOT_PLYD 0
#define SC_PLYNG 1
#define SC_FD_OUT 2
#define SC_FD_IN 3
#define SC_STPNG 4
#define SC_STPD 5
bool CMainDlg::subInit()
// initialises various variables and the sound player
{
Player *pPlayer;
SOUNDFORMAT format;
std::vector<DWORD> events;
int t, buf_sz;
try
{
pPlayer = new Player();
pPlayer->SetHWnd(m_hWnd);
m_player = pPlayer;
m_player->Init();
format.NbBitsPerSample = 16;
format.NbChannels = 1;
format.SamplingRate = 44100;
m_ev_smps = 441;
m_n_evs = 3;
m_smps = new short[m_ev_smps];
m_smp_scale = (int)pow(2, format.NbBitsPerSample - 1);
m_max_tm = (int)((double)m_ev_smps / (double)(format.SamplingRate * 1000));
m_ev_sz = m_ev_smps * format.NbBitsPerSample/8;
buf_sz = m_ev_sz * m_n_evs;
m_player->CreateSoundBuffer(format, buf_sz, 0);
m_player->SetSoundEventListener(this);
for(t = 0; t < m_n_evs; t++)
events.push_back((int)((t + 1)*m_ev_sz - m_ev_sz * 0.95));
m_player->CreateEventReadNotification(events);
m_status = SC_NOT_PLYD;
}
catch(MATExceptions &e)
{
MessageBox(e.getAllExceptionStr().c_str(), "Error initializing the sound player");
EndDialog(IDCANCEL);
return FALSE;
}
return TRUE;
}
void CMainDlg::Stop()
// stop playing
{
m_player->Stop();
m_status = SC_STPD;
}
void CMainDlg::OnBnClickedStop()
// causes fade out
{
m_status = SC_FD_OUT;
}
void CMainDlg::OnSoundPlayerNotify(int ev_num)
// render some sound samples and check for errors
{
ScopeGuardMutex guard(&m_mutex);
int s, end, begin, elapsed;
if (m_status != SC_STPNG)
{
begin = GetTickCount();
try
{
for(s = 0; s < m_ev_smps; s++)
{
m_smps[s] = (int)(m_synth->rend() * 32768 * m_fade);
if (m_status == SC_FD_IN)
{
m_fade += FD_STEP;
if (m_fade > 1)
{
m_fade = 1;
m_status = SC_PLYNG;
}
}
else if (m_status == SC_FD_OUT)
{
m_fade -= FD_STEP;
if (m_fade < 0)
{
m_fade = 0;
m_status = SC_STPNG;
}
}
}
}
catch(MATExceptions &e)
{
OutputDebugString(e.getAllExceptionStr().c_str());
}
try
{
m_player->Write(((ev_num + 1) % m_n_evs)*m_ev_sz, (unsigned char*)m_smps, m_ev_sz);
}
catch(MATExceptions &e)
{
OutputDebugString(e.getAllExceptionStr().c_str());
}
end = GetTickCount();
elapsed = end - begin;
if(elapsed > m_max_tm)
m_warn_msg.Format(_T("Warning! compute time: %dms"), elapsed);
else
m_warn_msg.Format(_T("compute time: %dms"), elapsed);
}
if (m_status == SC_STPNG)
Stop();
}
It seems like the buffer is not always sounding out when the stop button is clicked. I don't have any specific code for waiting for the sound buffer to finish playing before the DirectX Stop is called. Other than that the sound playback is working just fine, so at least I am initialising the player correctly and notification code is working in that respect.
Try replacing 32768 with 32767. Not by any means sure this is your issue, but it could overflow the positive short int range (assuming your audio is 16-bit) and cause a "pop".
I got rid of the pops / clicks when stopping playback, by filling the buffer with zeros after the fade out. However I still get pops when re-starting playback, despite filling with zeros and then fading back in (it is frustrating).
I have a recursive function in C++ and I need to immediately terminate the function including all calls which have recursively made after a specific time, say 60 secs.
I have tried the following but doesn't work. takesTooLong is a global variable but if its value changes to 1 in one call, other calls keep seeing it as 0.
The OS is Ubuntu 12.10.
main() is something like this:
int main()
{
takesTooLong = 0;
startTime = clock();
RecursiveFunction();
endTime = clock();
printf("Elapsed time: %f", CalculateElapsedTime(startTime, endTime));
return 0;
}
My recursive function:
void RecursiveFunction(Some Parameters)
{
if (takesTooLong == 1)
return;
endTime = clock();
differenceTime = CalculateElapsedTime(startTime, endTime);
if (differenceTime > MAX_SECONDS)
{
takesTooLong = 1;
}
if (takesTooLong == 0)
{
for (i = 0; i < n && takesTooLong == 0; i++)
{
RecursiveFunction(Some Updated Parameters);
}
}
}
Pseudocode:
typedef ??? Time;//time type
Time getCurrentTime(); //returns time. Or ticks. Anything you could use to measure time.
void recursiveFunction(Time startTime){
...//do something here
Time currentTime = getCurrentTime();
if ((currentTime - startTime) > limit)
return;
recursiveFunction(startTime);
}
void recursiveFunction(){
Time startTime = getCurrentTime();
recursiveFunction(startTime);
}
Yes, you still have to unroll the stack but the alternatives are all ugly, the best probably being longjmp. If you need greater resolution than seconds, or you want to measure process/kernel time rather than wall clock time, use alternatives like timer_create or setitimer.
void alarmHandler (int sig)
{
timedOut = 1;
}
signal(SIGALRM, alarmHandler);
alarm(60);
RecursiveFunction();
alarm(0);
if (timedOut)
{
//report something
timedOut = 0;
}
void RecursiveFunction(Some Parameters)
{
if (timedOut)
return;
//........
}
The easiest way to exit an unknown number of recursions is by throwing an exception. Since you're doing it at most once every 60 seconds, this isn't too bad. Just make it a class TimeLimitExceeded : public std::runtime_error and catch that in the top level wrapper†.
† Most recursive functions should not be called directly, but via a non-recursive wrapper. The signature of the recursive function usually is inconvenient for callers, as it contains implementation details that are irrelevant to the caller.
I am designing a time class that will only perform an action after a predefined time but I still cannot figure out the way to reset the time. Is that anyway to reset the time back to zero or temporarily stop and resume the time?
so, my goal is to reset the time each time the condtion A meets so that it won't screw up delayTime function that it still keep the previous time and end up wrong time calculation.
if ( condition A )
{
if ( time.delayTime( 5.0f ) )
{
doActionA();
}
}
TimeClass.h
#ifndef _TIMECLASS_H_
#define _TIMECLASS_H_
#include <windows.h>
class TimeClass
{
public:
TimeClass();
~TimeClass();
bool delayTime( float second );
float getSecond();
void reset();
private:
float getGameTime();
float currentTime;
UINT64 ticks;
float time;
float timeAtGameStart;
UINT64 ticksPerSecond;
};
#endif
TimeClass.cpp
#include "TimeClass.h"
TimeClass::TimeClass()
{
// We need to know how often the clock is updated
if( !QueryPerformanceFrequency((LARGE_INTEGER *)&ticksPerSecond) )
ticksPerSecond = 1000;
// If timeAtGameStart is 0 then we get the time since
// the start of the computer when we call GetGameTime()
timeAtGameStart = 0;
timeAtGameStart = getGameTime();
}
float TimeClass::getGameTime()
{
// This is the number of clock ticks since start
if( !QueryPerformanceCounter((LARGE_INTEGER *)&ticks) )
ticks = (UINT64)timeGetTime();
// Divide by frequency to get the time in seconds
time = (float)(__int64)ticks/(float)(__int64)ticksPerSecond;
// Subtract the time at game start to get
// the time since the game started
time -= timeAtGameStart;
return time;
}
bool TimeClass::delayTime( float second )
{
currentTime = getGameTime();
static float totalTime = second + getGameTime();
if ( currentTime >= totalTime )
{
totalTime = second + getGameTime();
return true;
}
else
{
return false;
}
}
float TimeClass::getSecond()
{
currentTime = getGameTime();
static float totalTime = 1 + getGameTime();
if ( currentTime >= totalTime )
{
totalTime = 1 + getGameTime();
return currentTime;
}
else
{
return currentTime;
}
}
void TimeClass::reset()
{
timeAtGameStart = 0;
timeAtGameStart = getGameTime();
}
TimeClass::~TimeClass()
{
}
Standard Library
As already stated simply use the std::chrono::high_resolution_clock. If you use the Visual C++ Compiler there is an actual bug report on the resolution of the high_resolution_clock and it's NOT the same as the QueryPerformanceCounter.
Example
auto t1 = std::chrono::high_resolution_clock::now();
// Do something
auto t2 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
double dt = duration.count();
TimeClass
The main problem you're facing right now is that you are using static variables. You are looking for a way to reset the static variable from another function than the delayTime. If you would introduce member variables to get rid of the static variables it would make things a lot easier (Note: static variables within functions are bad practice as they are holding the state => bad for multi-threading). Well what about something like this:
class Event {
std::chrono::high_resolution_clock::time_point lastEventOccurred;
double timeBetweenEvents;
public:
Event(double timeBetweenEvents)
: timeBetweenEvents(timeBetweenEvents)
, lastEventOccurred(std::chrono::high_resolution_clock::now()) { }
bool ready() {
auto currentTime = std::chrono::high_resolution_clock::now();
auto elapsedTime = std::chrono::duration_cast<std::chrono::duration<double>>(currentTime - lastEventOccurred).count();
if(elapsedTime > timeBetweenEvents) {
reset();
return true;
} else
return false;
}
void reset() {
lastEventOccurred = std::chrono::high_resolution_clock::now();
}
};
Usage:
Event evtDelay = Event(5.0);
if(condition A) {
if(evtDelay.ready()) {
doActionA();
}
} else if(condition B) {
evtDelay.reset();
}
Another approach would be to use a capturing state and an update method. As I can see you are using this for a game so the updating could be done in the update method of your game. Assuming the event would have a state like {Active, Inactive} and a member for the elapsed time, every time you call update you add the elapsed time since the last update call if the state is Active. Therefore the ready function would only check if the elapsed time is greater than the defined threshold.
class Event {
std::chrono::high_resolution_clock::time_point lastUpdateCall;
double timeBetweenEvents;
double elapsedTime;
bool active;
public:
Event(double timeBetweenEvents)
: timeBetweenEvents(timeBetweenEvents)
, lastUpdateCall(std::chrono::high_resolution_clock::now())
, elapsedTime(0.0)
, active(true) { }
bool ready() {
return elapsedTime >= timeBetweenEvents;
}
void reset() {
elapsedTime = 0.0;
}
void setActive(bool state) {
active = state;
}
void update() {
auto currentTime = std::chrono::high_resolution_clock::now();
if(active) {
auto dt = std::chrono::duration_cast<std::chrono::duration<double>>(currentTime - lastUpdateCall).count();
elapsedTime += dt;
}
lastUpdateCall = currentTime;
}
};
From your questions it is not quite clear what exactly you want to achieve: clock resetting, pausing/resuming, interval measuring, or timed triggers, or all of this. So I will just describe all of this. =)
Just to make it clear
do not use static variables in member functions (methods), it makes your code harder to understand and error-prone. Instead use class member variables (fields)
do not store time in (milli)seconds float format. I has too low precision. Even double is not recommended. Instead, store it in API-native format: some kind of CPU ticks: let's wrap it in struct time_point and convert to float only when user asks for it:
struct time_point
{
LARGE_INTEGER value;
};
The functions you'll need from your underlying API are:
function to get current time: let's call it
private:
time_point now(); // Here you wrap QueryPerformanceCounter() or `boost::chrono::...::now();` stuff
functions to reinterpret difference (time duration) between two time_point to usable units (such as nanoseconds long long of (milli)seconds float)
private:
float Duration(const time_point& from, const time_point& to); // Here you divide by frequence
(also, you can make time_point class and make this functions members)
All other functions can be API-agnostic.
Following this design, you can abstract out underlying API from user and make your app more portable.
Resetting
Is that anyway to reset the time back to zero
But, wait, you've already implemented "reset the time back to zero":
void TimeClass::reset()
{
//timeAtGameStart = 0;
timeAtGameStart = getGameTime();
}
(timeAtGameStart = 0; commented as it non needed)
You just saying that start is now(), so difference between start and now() becomes zero.
Stopping and resuming
or temporarily stop and resume the time?
you can achieve "time stop/resume" effect by:
adding bool isPaused member varible (don't forget to init it to false in constructor)
adding timePaused member varible (of type of your time units: time_point in my case)
altering your getGameTime() function: when paused it will return timePaused instead of current time
and of course, introducing Pause()/Resume() functions
Here is example code (naming is a little different to yours)
void Pause()
{
if (!isPaused)
{
timePaused = clock::now();
isPaused = true;
}
}
void Resume()
{
if (isPaused)
{
isPaused = false;
start -= clock::now() - timePaused;
}
}
float Now() const
{
if (isPaused)
{
return Duration(start, timePaused);
}
return Duration(start, clock::now()); // basically it is your getGameTime()
}
Delta (basic interval measuring)
Sometimes you will want to know how much time passed between some places in your program. For example, to measure FPS in game, you will need to know delta time between frames.
To implement this we will need members:
time_point prevTick; // time of previous tick
time_point currTick; // time of current tick
void Tick() // user must call it each frame
{
prevTick = currTick;
currTick = clock::now();
}
const float GetDelta() const // user must call it to know frame time
{
return Duration(prevTick, currTick);
}
Stopwatch (advanced interval measuring)
Now, we need to have some kind of timed trigger. It is a good idea to separate this triggerfrom timer, so:
you can have multiple trigger with different start time and different trigger intervals
all of this triggers must be independent from each other
global clocks will not be altered, so all triggers remain valid
So let's wrap it to class:
class Stopwatch
{
private:
float m_Interval;
float m_Time;
float m_PrevTime;
public:
Stopwatch(float interval_ms = 1000.0f) :
m_Interval(interval_ms),
m_Time(0.0f),
m_PrevTime(m_Time)
{}
float GetRefreshInterval() const { return m_Interval; }
void SetRefreshInterval(float interval_ms) { m_Interval = interval_ms; }
// Update as frequent as possible
inline void Update(float dt)
{
m_Time += dt;
}
// Check if time interval reached
inline bool IsAboutTime()
{
if (m_Time >= m_Interval)
{
m_PrevTime = m_Time;
m_Time = 0.0f;
return true;
}
return false;
}
// exact value of last interval
inline float GetLastTime() const
{
return m_PrevTime;
}
};
Usage example:
Stopwatch stopwatch(5000.0f); // will trigger each 5 seconds
...
stopwatch.Update(timer.GetDelta()); // GetDelta() returns time difference between update frames
if ( condition A )
{
if ( stopwatch.IsAboutTime() )
{
doActionA();
}
}
Another possible ways to design stopwatch are:
inherit from clock
pass current time to IsAboutTime() so no need to Update()
Happy coding! =)