Use bsr() in frequency shift calculations
This commit is contained in:
parent
9905981e61
commit
6a58797669
|
@ -61,25 +61,52 @@ static inline int bsr32(unsigned int v) {
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static inline int bsr(unsigned short v) {
|
static inline int bsr(unsigned short v) {
|
||||||
unsigned short mask = 0x8000;
|
if (v==0) return -1;
|
||||||
for (int i = 16; i >= 0; --i) {
|
if (v&0x8000) return 16;
|
||||||
if (v&mask)
|
int o=16;
|
||||||
return i;
|
if (!(v&0xff00)) {
|
||||||
mask>>=1;
|
o-=8;
|
||||||
|
v<<=8;
|
||||||
|
if (v&0x8000) return o;
|
||||||
}
|
}
|
||||||
|
if (!(v&0xf000)) {
|
||||||
return -1;
|
o-=4;
|
||||||
|
v<<=4;
|
||||||
|
if (v&0x8000) return o;
|
||||||
|
}
|
||||||
|
if (!(v&0xc000)) {
|
||||||
|
o-=2;
|
||||||
|
v<<=2;
|
||||||
|
if (v&0x8000) return o;
|
||||||
|
}
|
||||||
|
return (v&0x8000) ? o : o-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int bsr32(unsigned int v) {
|
static inline int bsr32(unsigned int v) {
|
||||||
unsigned int mask = 0x80000000;
|
if (v==0) return -1;
|
||||||
for (int i = 32; i >= 0; --i) {
|
if (v&0x80000000) return 32;
|
||||||
if (v&mask)
|
int o=32;
|
||||||
return i;
|
if (!(v&0xffff0000)) {
|
||||||
mask>>=1;
|
o-=16;
|
||||||
|
v<<=16;
|
||||||
|
if (v&0x80000000) return o;
|
||||||
}
|
}
|
||||||
|
if (!(v&0xff000000)) {
|
||||||
return -1;
|
o-=8;
|
||||||
|
v<<=8;
|
||||||
|
if (v&0x80000000) return o;
|
||||||
|
}
|
||||||
|
if (!(v&0xf0000000)) {
|
||||||
|
o-=4;
|
||||||
|
v<<=4;
|
||||||
|
if (v&0x80000000) return o;
|
||||||
|
}
|
||||||
|
if (!(v&0xc0000000)) {
|
||||||
|
o-=2;
|
||||||
|
v<<=2;
|
||||||
|
if (v&0x80000000) return o;
|
||||||
|
}
|
||||||
|
return (v&0x80000000) ? o : o-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "esfm.h"
|
#include "esfm.h"
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
|
#include "../bsr.h"
|
||||||
#include "../../ta-log.h"
|
#include "../../ta-log.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -366,21 +367,19 @@ void DivPlatformESFM::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformESFM::octave(int freq) {
|
int DivPlatformESFM::octave(int freq) {
|
||||||
int result=1;
|
if (freq>0x3ff) {
|
||||||
while (freq>0x3ff) {
|
return 1<<(bsr32(freq)-10);
|
||||||
freq>>=1;
|
|
||||||
result<<=1;
|
|
||||||
}
|
}
|
||||||
return result;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformESFM::toFreq(int freq) {
|
int DivPlatformESFM::toFreq(int freq) {
|
||||||
int block=0;
|
int block=0;
|
||||||
while (freq>0x3ff) {
|
if (freq>0x3ff) {
|
||||||
freq>>=1;
|
block=bsr32(freq)-10;
|
||||||
block++;
|
freq>>=block;
|
||||||
}
|
}
|
||||||
return ((block&7)<<10)|(freq&0x3ff);
|
return (block<<10)|(freq&0x3ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformESFM::muteChannel(int ch, bool mute) {
|
void DivPlatformESFM::muteChannel(int ch, bool mute) {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "opl.h"
|
#include "opl.h"
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
|
#include "../bsr.h"
|
||||||
#include "../../ta-log.h"
|
#include "../../ta-log.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -1386,39 +1387,12 @@ void DivPlatformOPL::tick(bool sysTick) {
|
||||||
double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0;
|
double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0;
|
||||||
chan[i].freq=(int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,(524288*768)));
|
chan[i].freq=(int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,(524288*768)));
|
||||||
if (chan[i].freq<0x400) chan[i].freq=0x400;
|
if (chan[i].freq<0x400) chan[i].freq=0x400;
|
||||||
if (chan[i].freq>0x3ffffff) chan[i].freq=0x3ffffff;
|
|
||||||
if (chan[i].freq>=0x2000000) {
|
|
||||||
chan[i].freqH=15;
|
|
||||||
} else if (chan[i].freq>=0x1000000) {
|
|
||||||
chan[i].freqH=14;
|
|
||||||
} else if (chan[i].freq>=0x800000) {
|
|
||||||
chan[i].freqH=13;
|
|
||||||
} else if (chan[i].freq>=0x400000) {
|
|
||||||
chan[i].freqH=12;
|
|
||||||
} else if (chan[i].freq>=0x200000) {
|
|
||||||
chan[i].freqH=11;
|
|
||||||
} else if (chan[i].freq>=0x100000) {
|
|
||||||
chan[i].freqH=10;
|
|
||||||
} else if (chan[i].freq>=0x80000) {
|
|
||||||
chan[i].freqH=9;
|
|
||||||
} else if (chan[i].freq>=0x40000) {
|
|
||||||
chan[i].freqH=8;
|
|
||||||
} else if (chan[i].freq>=0x20000) {
|
|
||||||
chan[i].freqH=7;
|
|
||||||
} else if (chan[i].freq>=0x10000) {
|
|
||||||
chan[i].freqH=6;
|
|
||||||
} else if (chan[i].freq>=0x8000) {
|
|
||||||
chan[i].freqH=5;
|
|
||||||
} else if (chan[i].freq>=0x4000) {
|
|
||||||
chan[i].freqH=4;
|
|
||||||
} else if (chan[i].freq>=0x2000) {
|
|
||||||
chan[i].freqH=3;
|
|
||||||
} else if (chan[i].freq>=0x1000) {
|
|
||||||
chan[i].freqH=2;
|
|
||||||
} else if (chan[i].freq>=0x800) {
|
|
||||||
chan[i].freqH=1;
|
|
||||||
} else {
|
|
||||||
chan[i].freqH=0;
|
chan[i].freqH=0;
|
||||||
|
if (chan[i].freq>0x3ffffff) {
|
||||||
|
chan[i].freq=0x3ffffff;
|
||||||
|
chan[i].freqH=15;
|
||||||
|
} else if (chan[i].freq>=0x800) {
|
||||||
|
chan[i].freqH=bsr32(chan[i].freq)-11;
|
||||||
}
|
}
|
||||||
chan[i].freqL=(chan[i].freq>>chan[i].freqH)&0x3ff;
|
chan[i].freqL=(chan[i].freq>>chan[i].freqH)&0x3ff;
|
||||||
chan[i].freqH=8^chan[i].freqH;
|
chan[i].freqH=8^chan[i].freqH;
|
||||||
|
@ -1528,44 +1502,15 @@ void DivPlatformOPL::tick(bool sysTick) {
|
||||||
#define OPLL_C_NUM 686
|
#define OPLL_C_NUM 686
|
||||||
|
|
||||||
int DivPlatformOPL::octave(int freq) {
|
int DivPlatformOPL::octave(int freq) {
|
||||||
if (freq>=OPLL_C_NUM*64) {
|
freq/=OPLL_C_NUM;
|
||||||
return 128;
|
if (freq==0) return 1;
|
||||||
} else if (freq>=OPLL_C_NUM*32) {
|
return 1<<bsr(freq);
|
||||||
return 64;
|
|
||||||
} else if (freq>=OPLL_C_NUM*16) {
|
|
||||||
return 32;
|
|
||||||
} else if (freq>=OPLL_C_NUM*8) {
|
|
||||||
return 16;
|
|
||||||
} else if (freq>=OPLL_C_NUM*4) {
|
|
||||||
return 8;
|
|
||||||
} else if (freq>=OPLL_C_NUM*2) {
|
|
||||||
return 4;
|
|
||||||
} else if (freq>=OPLL_C_NUM) {
|
|
||||||
return 2;
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformOPL::toFreq(int freq) {
|
int DivPlatformOPL::toFreq(int freq) {
|
||||||
if (freq>=OPLL_C_NUM*64) {
|
int block=freq/OPLL_C_NUM;
|
||||||
return 0x1c00|((freq>>7)&0x3ff);
|
if (block>0) block=bsr(block);
|
||||||
} else if (freq>=OPLL_C_NUM*32) {
|
return (block<<10)|((freq>>block)&0x3ff);
|
||||||
return 0x1800|((freq>>6)&0x3ff);
|
|
||||||
} else if (freq>=OPLL_C_NUM*16) {
|
|
||||||
return 0x1400|((freq>>5)&0x3ff);
|
|
||||||
} else if (freq>=OPLL_C_NUM*8) {
|
|
||||||
return 0x1000|((freq>>4)&0x3ff);
|
|
||||||
} else if (freq>=OPLL_C_NUM*4) {
|
|
||||||
return 0xc00|((freq>>3)&0x3ff);
|
|
||||||
} else if (freq>=OPLL_C_NUM*2) {
|
|
||||||
return 0x800|((freq>>2)&0x3ff);
|
|
||||||
} else if (freq>=OPLL_C_NUM) {
|
|
||||||
return 0x400|((freq>>1)&0x3ff);
|
|
||||||
} else {
|
|
||||||
return freq&0x3ff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformOPL::muteChannel(int ch, bool mute) {
|
void DivPlatformOPL::muteChannel(int ch, bool mute) {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "opll.h"
|
#include "opll.h"
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
|
#include "../bsr.h"
|
||||||
#include "../../ta-log.h"
|
#include "../../ta-log.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -352,44 +353,15 @@ void DivPlatformOPLL::tick(bool sysTick) {
|
||||||
#define OPLL_C_NUM 343
|
#define OPLL_C_NUM 343
|
||||||
|
|
||||||
int DivPlatformOPLL::octave(int freq) {
|
int DivPlatformOPLL::octave(int freq) {
|
||||||
if (freq>=OPLL_C_NUM*64) {
|
freq/=OPLL_C_NUM;
|
||||||
return 128;
|
if (freq==0) return 1;
|
||||||
} else if (freq>=OPLL_C_NUM*32) {
|
return 1<<bsr(freq);
|
||||||
return 64;
|
|
||||||
} else if (freq>=OPLL_C_NUM*16) {
|
|
||||||
return 32;
|
|
||||||
} else if (freq>=OPLL_C_NUM*8) {
|
|
||||||
return 16;
|
|
||||||
} else if (freq>=OPLL_C_NUM*4) {
|
|
||||||
return 8;
|
|
||||||
} else if (freq>=OPLL_C_NUM*2) {
|
|
||||||
return 4;
|
|
||||||
} else if (freq>=OPLL_C_NUM) {
|
|
||||||
return 2;
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformOPLL::toFreq(int freq) {
|
int DivPlatformOPLL::toFreq(int freq) {
|
||||||
if (freq>=OPLL_C_NUM*64) {
|
int block=freq/OPLL_C_NUM;
|
||||||
return 0xe00|((freq>>7)&0x1ff);
|
if (block>0) block=bsr(block);
|
||||||
} else if (freq>=OPLL_C_NUM*32) {
|
return (block<<9)|((freq>>block)&0x1ff);
|
||||||
return 0xc00|((freq>>6)&0x1ff);
|
|
||||||
} else if (freq>=OPLL_C_NUM*16) {
|
|
||||||
return 0xa00|((freq>>5)&0x1ff);
|
|
||||||
} else if (freq>=OPLL_C_NUM*8) {
|
|
||||||
return 0x800|((freq>>4)&0x1ff);
|
|
||||||
} else if (freq>=OPLL_C_NUM*4) {
|
|
||||||
return 0x600|((freq>>3)&0x1ff);
|
|
||||||
} else if (freq>=OPLL_C_NUM*2) {
|
|
||||||
return 0x400|((freq>>2)&0x1ff);
|
|
||||||
} else if (freq>=OPLL_C_NUM) {
|
|
||||||
return 0x200|((freq>>1)&0x1ff);
|
|
||||||
} else {
|
|
||||||
return freq&0x1ff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformOPLL::muteChannel(int ch, bool mute) {
|
void DivPlatformOPLL::muteChannel(int ch, bool mute) {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "saa.h"
|
#include "saa.h"
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
|
#include "../bsr.h"
|
||||||
#include "sound/saa1099.h"
|
#include "sound/saa1099.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -155,22 +156,9 @@ void DivPlatformSAA1099::tick(bool sysTick) {
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER);
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER);
|
||||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||||
if (chan[i].freq>=32768) {
|
|
||||||
chan[i].freqH=7;
|
|
||||||
} else if (chan[i].freq>=16384) {
|
|
||||||
chan[i].freqH=6;
|
|
||||||
} else if (chan[i].freq>=8192) {
|
|
||||||
chan[i].freqH=5;
|
|
||||||
} else if (chan[i].freq>=4096) {
|
|
||||||
chan[i].freqH=4;
|
|
||||||
} else if (chan[i].freq>=2048) {
|
|
||||||
chan[i].freqH=3;
|
|
||||||
} else if (chan[i].freq>=1024) {
|
|
||||||
chan[i].freqH=2;
|
|
||||||
} else if (chan[i].freq>=512) {
|
|
||||||
chan[i].freqH=1;
|
|
||||||
} else {
|
|
||||||
chan[i].freqH=0;
|
chan[i].freqH=0;
|
||||||
|
if (chan[i].freq>511) {
|
||||||
|
chan[i].freqH=bsr((unsigned short)chan[i].freq)-9;
|
||||||
}
|
}
|
||||||
chan[i].freqL=0xff-(chan[i].freq>>chan[i].freqH);
|
chan[i].freqL=0xff-(chan[i].freq>>chan[i].freqH);
|
||||||
chan[i].freqH=7-chan[i].freqH;
|
chan[i].freqH=7-chan[i].freqH;
|
||||||
|
|
|
@ -27,6 +27,7 @@ extern "C" {
|
||||||
#include "../../extern/Nuked-OPLL/opll.h"
|
#include "../../extern/Nuked-OPLL/opll.h"
|
||||||
}
|
}
|
||||||
#include "../engine/platform/sound/ymfm/ymfm_opz.h"
|
#include "../engine/platform/sound/ymfm/ymfm_opz.h"
|
||||||
|
#include "../engine/bsr.h"
|
||||||
|
|
||||||
#define OPN_WRITE(addr,val) \
|
#define OPN_WRITE(addr,val) \
|
||||||
OPN2_Write((ym3438_t*)fmPreviewOPN,0,(addr)); \
|
OPN2_Write((ym3438_t*)fmPreviewOPN,0,(addr)); \
|
||||||
|
@ -388,9 +389,9 @@ void FurnaceGUI::renderFMPreviewESFM(const DivInstrumentFM& params, const DivIns
|
||||||
double fbase=(mult0?2048.0:1024.0)*pow(2.0,(float)offset/(128.0*12.0));
|
double fbase=(mult0?2048.0:1024.0)*pow(2.0,(float)offset/(128.0*12.0));
|
||||||
int bf=round(fbase);
|
int bf=round(fbase);
|
||||||
int block=0;
|
int block=0;
|
||||||
while (bf>0x3ff) {
|
if (bf>0x3ff) {
|
||||||
bf>>=1;
|
block=bsr32(bf)-10;
|
||||||
block++;
|
bf>>=block;
|
||||||
}
|
}
|
||||||
freqL=bf&0xff;
|
freqL=bf&0xff;
|
||||||
freqH=((block&7)<<2)|((bf>>8)&3);
|
freqH=((block&7)<<2)|((bf>>8)&3);
|
||||||
|
|
Loading…
Reference in a new issue