Merge branch 'master' of https://github.com/tildearrow/furnace into es5506_alt

* 'master' of https://github.com/tildearrow/furnace:
  full linear pitch is now the default
  add a full linear pitch mode, part 7
  X1-010: implement linear pitch (part 6)
  VERA: implement full linear pitch (part 5)
  YM2610(B): implement full linear pitch (part 4)
  add a full linear pitch mode, part 3
  YM2612: implement full linear pitch (part 2)
  update readme
  re-enable warnings are errors on MSVC
  YM2612: early full linear pitch experiment
  GUI: window movement only by clicking on title bar
  Fix GCC errors 2
  Fix GCC errors
  Remove SCC from TODO.md
  SCC has no config flags currently
  Add SCC and SCC+ support

# Conflicts:
#	CMakeLists.txt
#	src/engine/dispatchContainer.cpp
#	src/gui/guiConst.cpp
This commit is contained in:
cam900 2022-05-16 00:37:07 +09:00
commit 2a19834e14
29 changed files with 1541 additions and 130 deletions

View file

@ -996,46 +996,55 @@ double DivEngine::calcBaseFreq(double clock, double divider, int note, bool peri
base*(divider/clock);
}
unsigned short DivEngine::calcBaseFreqFNumBlock(double clock, double divider, int note, int bits) {
#define CONVERT_FNUM_BLOCK(bf,bits,note) \
double tuning=song.tuning; \
if (tuning<400.0) tuning=400.0; \
if (tuning>500.0) tuning=500.0; \
int boundaryBottom=tuning*pow(2.0,0.25)*(divider/clock); \
int boundaryTop=2.0*tuning*pow(2.0,0.25)*(divider/clock); \
int block=(note)/12; \
if (block<0) block=0; \
if (block>7) block=7; \
bf>>=block; \
if (bf<0) bf=0; \
/* octave boundaries */ \
while (bf>0 && bf<boundaryBottom && block>0) { \
bf<<=1; \
block--; \
} \
if (bf>boundaryTop) { \
while (block<7 && bf>boundaryTop) { \
bf>>=1; \
block++; \
} \
if (bf>((1<<bits)-1)) { \
bf=(1<<bits)-1; \
} \
} \
/* logV("f-num: %d block: %d",bf,block); */ \
return bf|(block<<bits);
int DivEngine::calcBaseFreqFNumBlock(double clock, double divider, int note, int bits) {
if (song.linearPitch==2) { // full linear
return (note<<7);
}
double tuning=song.tuning;
if (tuning<400.0) tuning=400.0;
if (tuning>500.0) tuning=500.0;
int bf=calcBaseFreq(clock,divider,note,false);
int boundaryBottom=tuning*pow(2.0,0.25)*(divider/clock);
int boundaryTop=2.0*tuning*pow(2.0,0.25)*(divider/clock);
int block=note/12;
if (block<0) block=0;
if (block>7) block=7;
bf>>=block;
if (bf<0) bf=0;
// octave boundaries
while (bf>0 && bf<boundaryBottom && block>0) {
bf<<=1;
block--;
}
if (bf>boundaryTop) {
while (block<7 && bf>boundaryTop) {
bf>>=1;
block++;
}
if (bf>((1<<bits)-1)) {
bf=(1<<bits)-1;
}
}
//logV("f-num: %d block: %d",bf,block);
return bf|(block<<bits);
CONVERT_FNUM_BLOCK(bf,bits,note)
}
int DivEngine::calcFreq(int base, int pitch, bool period, int octave, int pitch2, double clock, double divider) {
int DivEngine::calcFreq(int base, int pitch, bool period, int octave, int pitch2, double clock, double divider, int blockBits) {
if (song.linearPitch==2) {
// do frequency calculation here
double fbase=(period?(song.tuning*0.0625):song.tuning)*pow(2.0,(float)(base+pitch+384)/(128.0*12.0));
return period?
(clock/fbase)/divider:
fbase*(divider/clock);
int nbase=base+pitch+pitch2;
double fbase=(period?(song.tuning*0.0625):song.tuning)*pow(2.0,(float)(nbase+384)/(128.0*12.0));
int bf=period?
round((clock/fbase)/divider):
round(fbase*(divider/clock));
if (blockBits>0) {
CONVERT_FNUM_BLOCK(bf,blockBits,nbase>>7)
} else {
return bf;
}
}
if (song.linearPitch==1) {
// global pitch multiplier