This commit is contained in:
tildearrow 2022-06-02 02:59:07 -05:00
parent 131bef2689
commit e2f3a89513
2 changed files with 88 additions and 21 deletions

View File

@ -38,6 +38,57 @@ const char* regCheatSheetPCSpeaker[]={
NULL NULL
}; };
void _pcSpeakerThread(void* inst) {
((DivPlatformPCSpeaker*)inst)->pcSpeakerThread();
}
void DivPlatformPCSpeaker::pcSpeakerThread() {
std::unique_lock<std::mutex> unique(realOutSelfLock);
int lastDelay=0;
RealQueueVal r(0,0);
printf("starting\n");
while (!realOutQuit) {
realQueueLock.lock();
if (realQueue.empty()) {
realQueueLock.unlock();
realOutCond.wait(unique);
continue;
} else {
r=realQueue.front();
realQueue.pop();
}
realQueueLock.unlock();
#ifdef __linux__
static struct input_event ie;
int nextSleep=r.delay-lastDelay;
lastDelay=r.delay;
if (nextSleep>0) {
int totalSleep=1000000.0*((double)nextSleep/(double)rate);
//printf("sleeping %d\n",totalSleep);
usleep(totalSleep);
}
if (beepFD>=0) {
gettimeofday(&ie.time,NULL);
ie.type=EV_SND;
ie.code=SND_TONE;
if (r.val>0) {
ie.value=chipClock/r.val;
} else {
ie.value=0;
}
if (write(beepFD,&ie,sizeof(struct input_event))<0) {
perror("error while writing frequency!");
} else {
//printf("writing freq: %d\n",r.val);
}
} else {
printf("not writing because fd is less than 0\n");
}
#endif
}
printf("stopping\n");
}
const char** DivPlatformPCSpeaker::getRegisterSheet() { const char** DivPlatformPCSpeaker::getRegisterSheet() {
return regCheatSheetPCSpeaker; return regCheatSheetPCSpeaker;
} }
@ -126,25 +177,11 @@ void DivPlatformPCSpeaker::acquire_piezo(short* bufL, short* bufR, size_t start,
} }
} }
void DivPlatformPCSpeaker::beepFreq(int freq) { void DivPlatformPCSpeaker::beepFreq(int freq, int delay) {
#ifdef __linux__ realQueueLock.lock();
static struct input_event ie; realQueue.push(RealQueueVal(freq,delay));
if (beepFD>=0) { realQueueLock.unlock();
gettimeofday(&ie.time,NULL); realOutCond.notify_one();
ie.type=EV_SND;
ie.code=SND_TONE;
if (freq>0) {
ie.value=chipClock/freq;
} else {
ie.value=0;
}
if (write(beepFD,&ie,sizeof(struct input_event))<0) {
perror("error while writing frequency!");
} else {
//printf("writing freq: %d\n",freq);
}
}
#endif
} }
void DivPlatformPCSpeaker::acquire_real(short* bufL, short* bufR, size_t start, size_t len) { void DivPlatformPCSpeaker::acquire_real(short* bufL, short* bufR, size_t start, size_t len) {
@ -152,7 +189,7 @@ void DivPlatformPCSpeaker::acquire_real(short* bufL, short* bufR, size_t start,
if (lastOn!=on || lastFreq!=freq) { if (lastOn!=on || lastFreq!=freq) {
lastOn=on; lastOn=on;
lastFreq=freq; lastFreq=freq;
beepFreq((on && !isMuted[0])?freq:0); beepFreq((on && !isMuted[0])?freq:0,start);
} }
for (size_t i=start; i<start+len; i++) { for (size_t i=start; i<start+len; i++) {
if (on) { if (on) {
@ -399,6 +436,10 @@ void DivPlatformPCSpeaker::reset() {
beepFreq(0); beepFreq(0);
} }
if (realOutThread==NULL) {
realOutThread=new std::thread(_pcSpeakerThread,this);
}
memset(regPool,0,2); memset(regPool,0,2);
} }
@ -436,6 +477,8 @@ int DivPlatformPCSpeaker::init(DivEngine* p, int channels, int sugRate, unsigned
dumpWrites=false; dumpWrites=false;
skipRegisterWrites=false; skipRegisterWrites=false;
beepFD=-1; beepFD=-1;
realOutQuit=false;
realOutThread=NULL;
for (int i=0; i<1; i++) { for (int i=0; i<1; i++) {
isMuted[i]=false; isMuted[i]=false;
} }
@ -453,6 +496,12 @@ void DivPlatformPCSpeaker::quit() {
#ifdef __linux__ #ifdef __linux__
if (beepFD>=0) close(beepFD); if (beepFD>=0) close(beepFD);
#endif #endif
if (realOutThread!=NULL) {
realOutQuit=true;
realOutCond.notify_one();
realOutThread->join();
delete realOutThread;
}
delete oscBuf; delete oscBuf;
} }

View File

@ -22,6 +22,10 @@
#include "../dispatch.h" #include "../dispatch.h"
#include "../macroInt.h" #include "../macroInt.h"
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
class DivPlatformPCSpeaker: public DivDispatch { class DivPlatformPCSpeaker: public DivDispatch {
struct Channel { struct Channel {
@ -57,6 +61,19 @@ class DivPlatformPCSpeaker: public DivDispatch {
}; };
Channel chan[1]; Channel chan[1];
DivDispatchOscBuffer* oscBuf; DivDispatchOscBuffer* oscBuf;
std::thread* realOutThread;
std::mutex realOutSelfLock;
std::condition_variable realOutCond;
bool realOutQuit;
struct RealQueueVal {
int delay;
unsigned short val;
RealQueueVal(int d, unsigned short v):
delay(d),
val(v) {}
};
std::queue<RealQueueVal> realQueue;
std::mutex realQueueLock;
bool isMuted[1]; bool isMuted[1];
bool on, flip, lastOn; bool on, flip, lastOn;
int pos, speakerType, beepFD; int pos, speakerType, beepFD;
@ -68,7 +85,7 @@ class DivPlatformPCSpeaker: public DivDispatch {
friend void putDispatchChan(void*,int,int); friend void putDispatchChan(void*,int,int);
void beepFreq(int freq); void beepFreq(int freq, int delay=0);
void acquire_unfilt(short* bufL, short* bufR, size_t start, size_t len); void acquire_unfilt(short* bufL, short* bufR, size_t start, size_t len);
void acquire_cone(short* bufL, short* bufR, size_t start, size_t len); void acquire_cone(short* bufL, short* bufR, size_t start, size_t len);
@ -76,6 +93,7 @@ class DivPlatformPCSpeaker: public DivDispatch {
void acquire_real(short* bufL, short* bufR, size_t start, size_t len); void acquire_real(short* bufL, short* bufR, size_t start, size_t len);
public: public:
void pcSpeakerThread();
void acquire(short* bufL, short* bufR, size_t start, size_t len); void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c); int dispatch(DivCommand c);
void* getChanState(int chan); void* getChanState(int chan);