PC speaker: improvements

This commit is contained in:
tildearrow 2022-03-05 00:36:50 -05:00
parent b6717fd314
commit 16dfc785d3
4 changed files with 107 additions and 5 deletions

View file

@ -37,7 +37,10 @@ const char* DivPlatformPCSpeaker::getEffectName(unsigned char effect) {
return NULL;
}
void DivPlatformPCSpeaker::acquire(short* bufL, short* bufR, size_t start, size_t len) {
const float cut=0.05;
const float reso=0.06;
void DivPlatformPCSpeaker::acquire_unfilt(short* bufL, short* bufR, size_t start, size_t len) {
for (size_t i=start; i<start+len; i++) {
if (on) {
pos-=PCSPKR_DIVIDER;
@ -45,17 +48,78 @@ void DivPlatformPCSpeaker::acquire(short* bufL, short* bufR, size_t start, size_
if (freq<1) {
pos=1;
} else {
pos+=flip?(freq>>1):((freq+1)>>1);
pos+=freq;
}
flip=!flip;
}
bufL[i]=(flip && !isMuted[0])?32767:0;
bufL[i]=(pos>(freq>>1) && !isMuted[0])?32767:0;
} else {
bufL[i]=0;
}
}
}
void DivPlatformPCSpeaker::acquire_cone(short* bufL, short* bufR, size_t start, size_t len) {
for (size_t i=start; i<start+len; i++) {
if (on) {
pos-=PCSPKR_DIVIDER;
while (pos<0) {
if (freq<1) {
pos=1;
} else {
pos+=freq;
}
}
float next=(pos>((freq+16)>>1) && !isMuted[0])?1:0;
low+=0.04*band;
band+=0.04*(next-low-band);
float out=(low+band)*0.75;
if (out>1.0) out=1.0;
if (out<-1.0) out=-1.0;
bufL[i]=out*32767;
} else {
bufL[i]=0;
}
}
}
void DivPlatformPCSpeaker::acquire_piezo(short* bufL, short* bufR, size_t start, size_t len) {
for (size_t i=start; i<start+len; i++) {
if (on) {
pos-=PCSPKR_DIVIDER;
while (pos<0) {
if (freq<1) {
pos=1;
} else {
pos+=freq;
}
}
float next=(pos>((freq+64)>>1) && !isMuted[0])?1:0;
low+=cut*band;
band+=cut*(next-low-(reso*band));
float out=band*0.15-(next-low)*0.06;
if (out>1.0) out=1.0;
if (out<-1.0) out=-1.0;
bufL[i]=out*32767;
} else {
bufL[i]=0;
}
}
}
void DivPlatformPCSpeaker::acquire(short* bufL, short* bufR, size_t start, size_t len) {
switch (speakerType) {
case 0:
acquire_unfilt(bufL,bufR,start,len);
break;
case 1:
acquire_cone(bufL,bufR,start,len);
break;
case 2:
acquire_piezo(bufL,bufR,start,len);
break;
}
}
void DivPlatformPCSpeaker::tick() {
for (int i=0; i<1; i++) {
chan[i].std.next();
@ -221,6 +285,8 @@ void DivPlatformPCSpeaker::reset() {
freq=0;
pos=0;
flip=false;
low=0;
band=0;
memset(regPool,0,2);
}
@ -232,6 +298,7 @@ bool DivPlatformPCSpeaker::keyOffAffectsArp(int ch) {
void DivPlatformPCSpeaker::setFlags(unsigned int flags) {
chipClock=COLOR_NTSC/3.0;
rate=chipClock/PCSPKR_DIVIDER;
speakerType=flags&3;
}
void DivPlatformPCSpeaker::notifyInsDeletion(void* ins) {

View file

@ -53,12 +53,19 @@ class DivPlatformPCSpeaker: public DivDispatch {
Channel chan[1];
bool isMuted[1];
bool on, flip;
int pos;
int pos, speakerType;
float low, band;
float low2, high2, band2;
float low3, band3;
unsigned short freq;
unsigned char regPool[2];
friend void putDispatchChan(void*,int,int);
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_piezo(short* bufL, short* bufR, size_t start, size_t len);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);

View file

@ -215,6 +215,12 @@ struct DivSong {
// - 1: Amiga 1200
// - bit 8-14: stereo separation
// - 0 is 0% while 127 is 100%
// - PC Speaker:
// - bit 0-1: speaker type
// - 0: unfiltered
// - 1: cone
// - 2: piezo
// - 3: real (TODO)
// - QSound:
// - bit 12-20: echo feedback
// - Valid values are 0-255

View file

@ -4843,6 +4843,28 @@ bool FurnaceGUI::loop() {
}
break;
}
case DIV_SYSTEM_PCSPKR: {
ImGui::Text("Speaker type:");
if (ImGui::RadioButton("Unfiltered",(flags&3)==0)) {
e->setSysFlags(i,(flags&(~3))|0,restart);
updateWindowTitle();
}
if (ImGui::RadioButton("Cone",(flags&3)==1)) {
e->setSysFlags(i,(flags&(~3))|1,restart);
updateWindowTitle();
}
if (ImGui::RadioButton("Piezo",(flags&3)==2)) {
e->setSysFlags(i,(flags&(~3))|2,restart);
updateWindowTitle();
}
/*
if (ImGui::RadioButton("Use system beeper",(flags&3)==3)) {
e->setSysFlags(i,(flags&(~3))|3,restart);
updateWindowTitle();
}
*/
break;
}
case DIV_SYSTEM_QSOUND: {
ImGui::Text("Echo delay:");
int echoBufSize=2725 - (flags & 4095);