S3M import: use PCM DACs

This commit is contained in:
tildearrow 2024-06-22 17:25:23 -05:00
parent cc32d89d77
commit 2782123565
4 changed files with 25 additions and 7 deletions

View file

@ -167,6 +167,8 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
reader.readC(); // UC reader.readC(); // UC
unsigned char defaultPan=(unsigned char)reader.readC(); unsigned char defaultPan=(unsigned char)reader.readC();
mustCommitPanning=masterVol&128;
logV("defaultPan: %d",defaultPan); logV("defaultPan: %d",defaultPan);
reader.readS(); // reserved reader.readS(); // reserved
@ -226,7 +228,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
reader.read(chanPan,16); reader.read(chanPan,16);
} else { } else {
logV("default channel pan"); logV("default channel pan");
memset(chanPan,0,16); memset(chanPan,16,16);
} }
// determine chips to use // determine chips to use
@ -234,6 +236,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
bool hasPCM=false; bool hasPCM=false;
bool hasFM=false; bool hasFM=false;
int numChans=0;
for (int i=0; i<32; i++) { for (int i=0; i<32; i++) {
if (chanSettings[i]==255) continue; if (chanSettings[i]==255) continue;
@ -242,6 +245,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
hasFM=true; hasFM=true;
} else { } else {
hasPCM=true; hasPCM=true;
numChans++;
} }
if (hasFM && hasPCM) break; if (hasFM && hasPCM) break;
@ -250,10 +254,13 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
ds.systemName="PC"; ds.systemName="PC";
// would use ES5506 but it has log volume // would use ES5506 but it has log volume
if (hasPCM) { if (hasPCM) {
ds.system[ds.systemLen]=DIV_SYSTEM_NDS; for (int i=0; i<numChans; i++) {
ds.systemVol[ds.systemLen]=1.0f; ds.system[ds.systemLen]=DIV_SYSTEM_PCM_DAC;
ds.systemPan[ds.systemLen]=0; ds.systemVol[ds.systemLen]=(float)globalVol/256.0;
ds.systemLen++; ds.systemPan[ds.systemLen]=0;
ds.systemFlags[ds.systemLen].set("volMax",64);
ds.systemLen++;
}
} }
if (hasFM) { if (hasFM) {
ds.system[ds.systemLen]=DIV_SYSTEM_OPL2; ds.system[ds.systemLen]=DIV_SYSTEM_OPL2;

View file

@ -227,7 +227,7 @@ void DivPlatformPCMDAC::acquire(short** buf, size_t len) {
if (isMuted) { if (isMuted) {
output=0; output=0;
} else { } else {
output=output*chan[0].vol*chan[0].envVol/16384; output=((output*MIN(volMax,chan[0].vol)*MIN(chan[0].envVol,64))>>6)/volMax;
} }
oscBuf->data[oscBuf->needle++]=((output>>depthScale)<<depthScale)>>1; oscBuf->data[oscBuf->needle++]=((output>>depthScale)<<depthScale)>>1;
if (outStereo) { if (outStereo) {
@ -451,7 +451,7 @@ int DivPlatformPCMDAC::dispatch(DivCommand c) {
chan[0].setPos=true; chan[0].setPos=true;
break; break;
case DIV_CMD_GET_VOLMAX: case DIV_CMD_GET_VOLMAX:
return 255; return volMax;
break; break;
case DIV_CMD_MACRO_OFF: case DIV_CMD_MACRO_OFF:
chan[c.chan].std.mask(c.value,true); chan[c.chan].std.mask(c.value,true);
@ -543,6 +543,8 @@ void DivPlatformPCMDAC::setFlags(const DivConfig& flags) {
outStereo=flags.getBool("stereo",true); outStereo=flags.getBool("stereo",true);
interp=flags.getInt("interpolation",0); interp=flags.getInt("interpolation",0);
oscBuf->rate=rate; oscBuf->rate=rate;
volMax=flags.getInt("volMax",255);
if (volMax<1) volMax=1;
} }
int DivPlatformPCMDAC::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { int DivPlatformPCMDAC::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {

View file

@ -62,6 +62,7 @@ class DivPlatformPCMDAC: public DivDispatch {
// - 2: cubic spline // - 2: cubic spline
// - 3: sinc // - 3: sinc
int interp; int interp;
int volMax;
bool outStereo; bool outStereo;
friend void putDispatchChip(void*,int); friend void putDispatchChip(void*,int);

View file

@ -1847,6 +1847,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
int sampRate=flags.getInt("rate",44100); int sampRate=flags.getInt("rate",44100);
int bitDepth=flags.getInt("outDepth",15)+1; int bitDepth=flags.getInt("outDepth",15)+1;
int interpolation=flags.getInt("interpolation",0); int interpolation=flags.getInt("interpolation",0);
int volMax=flags.getInt("volMax",255);
bool stereo=flags.getBool("stereo",false); bool stereo=flags.getBool("stereo",false);
ImGui::Text(_("Output rate:")); ImGui::Text(_("Output rate:"));
@ -1861,6 +1862,12 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
if (bitDepth>16) bitDepth=16; if (bitDepth>16) bitDepth=16;
altered=true; altered=true;
} rightClickable } rightClickable
ImGui::Text(_("Maximum volume:"));
if (CWSliderInt("##VolMax",&volMax,1,255)) {
if (volMax<1) volMax=1;
if (volMax>255) volMax=255;
altered=true;
} rightClickable
if (ImGui::Checkbox(_("Stereo"),&stereo)) { if (ImGui::Checkbox(_("Stereo"),&stereo)) {
altered=true; altered=true;
} }
@ -1891,6 +1898,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
flags.set("outDepth",bitDepth-1); flags.set("outDepth",bitDepth-1);
flags.set("stereo",stereo); flags.set("stereo",stereo);
flags.set("interpolation",interpolation); flags.set("interpolation",interpolation);
flags.set("volMax",volMax);
}); });
} }
break; break;