PC Speaker: timing improvements
This commit is contained in:
parent
50bdbb784a
commit
37539157be
|
|
@ -28,6 +28,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/kd.h>
|
#include <linux/kd.h>
|
||||||
|
#include <time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PCSPKR_DIVIDER 4
|
#define PCSPKR_DIVIDER 4
|
||||||
|
|
@ -44,10 +45,7 @@ void _pcSpeakerThread(void* inst) {
|
||||||
|
|
||||||
void DivPlatformPCSpeaker::pcSpeakerThread() {
|
void DivPlatformPCSpeaker::pcSpeakerThread() {
|
||||||
std::unique_lock<std::mutex> unique(realOutSelfLock);
|
std::unique_lock<std::mutex> unique(realOutSelfLock);
|
||||||
#ifdef __linux__
|
RealQueueVal r(0,0,0);
|
||||||
int lastDelay=0;
|
|
||||||
#endif
|
|
||||||
RealQueueVal r(0,0);
|
|
||||||
printf("starting\n");
|
printf("starting\n");
|
||||||
while (!realOutQuit) {
|
while (!realOutQuit) {
|
||||||
realQueueLock.lock();
|
realQueueLock.lock();
|
||||||
|
|
@ -62,15 +60,26 @@ void DivPlatformPCSpeaker::pcSpeakerThread() {
|
||||||
realQueueLock.unlock();
|
realQueueLock.unlock();
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
static struct input_event ie;
|
static struct input_event ie;
|
||||||
int nextSleep=r.delay-lastDelay;
|
static struct timespec ts, tSleep, rSleep;
|
||||||
lastDelay=r.delay;
|
if (clock_gettime(CLOCK_MONOTONIC,&ts)<0) {
|
||||||
if (nextSleep>0) {
|
printf("could not get time!\n");
|
||||||
int totalSleep=1000000.0*((double)nextSleep/(double)rate);
|
tSleep.tv_sec=0;
|
||||||
//printf("sleeping %d\n",totalSleep);
|
tSleep.tv_nsec=0;
|
||||||
usleep(totalSleep);
|
} else {
|
||||||
|
tSleep.tv_sec=r.tv_sec-ts.tv_sec;
|
||||||
|
tSleep.tv_nsec=r.tv_nsec-ts.tv_nsec;
|
||||||
|
if (tSleep.tv_nsec<0) {
|
||||||
|
tSleep.tv_sec--;
|
||||||
|
tSleep.tv_nsec+=1000000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tSleep.tv_nsec>0 || tSleep.tv_sec>0) {
|
||||||
|
nanosleep(&tSleep,&rSleep);
|
||||||
}
|
}
|
||||||
if (beepFD>=0) {
|
if (beepFD>=0) {
|
||||||
gettimeofday(&ie.time,NULL);
|
ie.time.tv_sec=r.tv_sec;
|
||||||
|
ie.time.tv_usec=r.tv_nsec/1000;
|
||||||
ie.type=EV_SND;
|
ie.type=EV_SND;
|
||||||
ie.code=SND_TONE;
|
ie.code=SND_TONE;
|
||||||
if (r.val>0) {
|
if (r.val>0) {
|
||||||
|
|
@ -181,7 +190,23 @@ void DivPlatformPCSpeaker::acquire_piezo(short* bufL, short* bufR, size_t start,
|
||||||
|
|
||||||
void DivPlatformPCSpeaker::beepFreq(int freq, int delay) {
|
void DivPlatformPCSpeaker::beepFreq(int freq, int delay) {
|
||||||
realQueueLock.lock();
|
realQueueLock.lock();
|
||||||
realQueue.push(RealQueueVal(delay,freq));
|
#ifdef __linux__
|
||||||
|
struct timespec ts;
|
||||||
|
double addition=1000000000.0*(double)delay/(double)rate;
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC,&ts)<0) {
|
||||||
|
ts.tv_sec=0;
|
||||||
|
ts.tv_nsec=0;
|
||||||
|
} else {
|
||||||
|
ts.tv_nsec+=addition;
|
||||||
|
while (ts.tv_nsec>=1000000000) {
|
||||||
|
ts.tv_sec++;
|
||||||
|
ts.tv_nsec-=1000000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
realQueue.push(RealQueueVal(ts.tv_sec,ts.tv_nsec,freq));
|
||||||
|
#else
|
||||||
|
realQueue.push(RealQueueVal(0,0,freq));
|
||||||
|
#endif
|
||||||
realQueueLock.unlock();
|
realQueueLock.unlock();
|
||||||
realOutCond.notify_one();
|
realOutCond.notify_one();
|
||||||
}
|
}
|
||||||
|
|
@ -495,15 +520,15 @@ void DivPlatformPCSpeaker::quit() {
|
||||||
if (speakerType==3) {
|
if (speakerType==3) {
|
||||||
beepFreq(0);
|
beepFreq(0);
|
||||||
}
|
}
|
||||||
#ifdef __linux__
|
|
||||||
if (beepFD>=0) close(beepFD);
|
|
||||||
#endif
|
|
||||||
if (realOutThread!=NULL) {
|
if (realOutThread!=NULL) {
|
||||||
realOutQuit=true;
|
realOutQuit=true;
|
||||||
realOutCond.notify_one();
|
realOutCond.notify_one();
|
||||||
realOutThread->join();
|
realOutThread->join();
|
||||||
delete realOutThread;
|
delete realOutThread;
|
||||||
}
|
}
|
||||||
|
#ifdef __linux__
|
||||||
|
if (beepFD>=0) close(beepFD);
|
||||||
|
#endif
|
||||||
delete oscBuf;
|
delete oscBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,10 +66,11 @@ class DivPlatformPCSpeaker: public DivDispatch {
|
||||||
std::condition_variable realOutCond;
|
std::condition_variable realOutCond;
|
||||||
bool realOutQuit;
|
bool realOutQuit;
|
||||||
struct RealQueueVal {
|
struct RealQueueVal {
|
||||||
int delay;
|
int tv_sec, tv_nsec;
|
||||||
unsigned short val;
|
unsigned short val;
|
||||||
RealQueueVal(int d, unsigned short v):
|
RealQueueVal(int sec, int nsec, unsigned short v):
|
||||||
delay(d),
|
tv_sec(sec),
|
||||||
|
tv_nsec(nsec),
|
||||||
val(v) {}
|
val(v) {}
|
||||||
};
|
};
|
||||||
std::queue<RealQueueVal> realQueue;
|
std::queue<RealQueueVal> realQueue;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue