diff --git a/src/engine/platform/sid3.cpp b/src/engine/platform/sid3.cpp index cdbc121d3..df9312019 100644 --- a/src/engine/platform/sid3.cpp +++ b/src/engine/platform/sid3.cpp @@ -76,14 +76,6 @@ void DivPlatformSID3::acquire(short** buf, size_t len) { for (size_t i=0; idata16[chan[SID3_NUM_CHANNELS - 1].dacPos] + 32767; chan[SID3_NUM_CHANNELS - 1].dacOut=CLAMP(dacData,0,65535); - if (!isMuted[SID3_NUM_CHANNELS - 1]) + /*if (!isMuted[SID3_NUM_CHANNELS - 1]) { sid3_write(sid3, SID3_REGISTER_STREAMED_SAMPLE_HIGH + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL, chan[SID3_NUM_CHANNELS - 1].dacOut >> 8); sid3_write(sid3, SID3_REGISTER_STREAMED_SAMPLE_LOW + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL, chan[SID3_NUM_CHANNELS - 1].dacOut & 0xff); @@ -107,7 +99,10 @@ void DivPlatformSID3::acquire(short** buf, size_t len) { sid3_write(sid3, SID3_REGISTER_STREAMED_SAMPLE_HIGH + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL, 32768 >> 8); sid3_write(sid3, SID3_REGISTER_STREAMED_SAMPLE_LOW + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL, 32768 & 0xff); - } + }*/ + updateSample = true; + sampleTick = 0; + chan[SID3_NUM_CHANNELS - 1].dacPos++; if (s->isLoopable() && chan[SID3_NUM_CHANNELS - 1].dacPos>=(unsigned int)s->loopEnd) { @@ -120,6 +115,61 @@ void DivPlatformSID3::acquire(short** buf, size_t len) chan[SID3_NUM_CHANNELS - 1].dacPeriod-=rate; } } + + sampleTick++; + + if(chan[SID3_NUM_CHANNELS - 1].pcm) + { + if(sampleTick == 2 && updateSample) + { + if (!isMuted[SID3_NUM_CHANNELS - 1]) + { + sid3_write(sid3, SID3_REGISTER_STREAMED_SAMPLE_HIGH + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL, chan[SID3_NUM_CHANNELS - 1].dacOut >> 8); + regPool[SID3_REGISTER_STREAMED_SAMPLE_HIGH + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL]=chan[SID3_NUM_CHANNELS - 1].dacOut >> 8; + } + else + { + sid3_write(sid3, SID3_REGISTER_STREAMED_SAMPLE_HIGH + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL, 32768 >> 8); + regPool[SID3_REGISTER_STREAMED_SAMPLE_HIGH + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL]=32768 >> 8; + } + } + else if(sampleTick == 3 && updateSample) + { + if (!isMuted[SID3_NUM_CHANNELS - 1]) + { + sid3_write(sid3, SID3_REGISTER_STREAMED_SAMPLE_LOW + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL, chan[SID3_NUM_CHANNELS - 1].dacOut & 0xff); + regPool[SID3_REGISTER_STREAMED_SAMPLE_LOW + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL]=chan[SID3_NUM_CHANNELS - 1].dacOut & 0xff; + } + else + { + sid3_write(sid3, SID3_REGISTER_STREAMED_SAMPLE_LOW + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL, 32768 & 0xff); + regPool[SID3_REGISTER_STREAMED_SAMPLE_LOW + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL]=32768 & 0xff; + } + + sampleTick = 0; + updateSample = false; + } + else + { + if (!writes.empty()) + { + QueuedWrite w=writes.front(); + sid3_write(sid3, w.addr, w.val); + regPool[w.addr % SID3_NUM_REGISTERS]=w.val; + writes.pop(); + } + } + } + else + { + if (!writes.empty()) + { + QueuedWrite w=writes.front(); + sid3_write(sid3, w.addr, w.val); + regPool[w.addr % SID3_NUM_REGISTERS]=w.val; + writes.pop(); + } + } sid3_clock(sid3); @@ -502,7 +552,7 @@ void DivPlatformSID3::tick(bool sysTick) DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_SID3); if(i == SID3_NUM_CHANNELS - 1) { - if(ins->sid3.doWavetable) + if(ins->sid3.doWavetable && !ins->amiga.useSample) { rWrite(SID3_REGISTER_WAVEFORM + i * SID3_REGISTERS_PER_CHANNEL, 0); //wave channel mode } @@ -1041,6 +1091,9 @@ void DivPlatformSID3::reset() { chan[i].noiseLFSRMask = (1 << 29) | (1 << 5) | (1 << 3) | 1; //https://docs.amd.com/v/u/en-US/xapp052 for 30 bits: 30, 6, 4, 1 } + sampleTick = 0; + updateSample = false; + ws.setEngine(parent); ws.init(NULL,256,255,false); diff --git a/src/engine/platform/sid3.h b/src/engine/platform/sid3.h index caa499328..a89861a1f 100644 --- a/src/engine/platform/sid3.h +++ b/src/engine/platform/sid3.h @@ -136,7 +136,7 @@ class DivPlatformSID3: public DivDispatch { Channel(): SharedChannel(SID3_MAX_VOL), - prevFreq(0x1ffff), + prevFreq(0xffffff), wave(0), special_wave(0), attack(0), @@ -195,6 +195,9 @@ class DivPlatformSID3: public DivDispatch { unsigned char regPool[SID3_NUM_REGISTERS]; bool isMuted[SID3_NUM_CHANNELS]; + + unsigned char sampleTick; //used to update streamed sample and not clash with other reg writes at high rate samples + bool updateSample; friend void putDispatchChip(void*,int); friend void putDispatchChan(void*,int,int); diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 5baff3310..a9152ccdf 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -5990,14 +5990,21 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins) ImGui::EndTable(); } - strncpy(buffer,macroSID3WaveMixMode(0,(float)ins->sid2.mixMode,NULL).c_str(),40); - P(CWSliderScalar(_("Wave Mix Mode"),ImGuiDataType_U8,&ins->sid2.mixMode,&_ZERO,&_FOUR,buffer)); - P(CWSliderScalar(_("Duty"),ImGuiDataType_U16,&ins->c64.duty,&_ZERO,&_SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE)); rightClickable - P(CWSliderScalar(_("Feedback"),ImGuiDataType_U8,&ins->sid3.feedback,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); - bool resetDuty=ins->c64.resetDuty; - if (ImGui::Checkbox(_("Reset duty on new note"),&resetDuty)) - { PARAMETER - ins->c64.resetDuty=resetDuty; + if(!ins->sid3.doWavetable) + { + strncpy(buffer,macroSID3WaveMixMode(0,(float)ins->sid2.mixMode,NULL).c_str(),40); + P(CWSliderScalar(_("Wave Mix Mode"),ImGuiDataType_U8,&ins->sid2.mixMode,&_ZERO,&_FOUR,buffer)); + P(CWSliderScalar(_("Duty"),ImGuiDataType_U16,&ins->c64.duty,&_ZERO,&_SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE)); rightClickable + P(CWSliderScalar(_("Feedback"),ImGuiDataType_U8,&ins->sid3.feedback,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); + bool resetDuty=ins->c64.resetDuty; + if (ImGui::Checkbox(_("Reset duty on new note"),&resetDuty)) + { PARAMETER + ins->c64.resetDuty=resetDuty; + } + if (ImGui::Checkbox(_("Absolute Duty Macro"),&ins->c64.dutyIsAbs)) { + ins->std.dutyMacro.vZoom=-1; + PARAMETER; + } } bool ringMod=ins->c64.ringMod; @@ -6031,13 +6038,17 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins) P(CWSliderScalar(_("Source channel##pmsrc"),ImGuiDataType_U8,&ins->sid3.phase_mod_source,&_ZERO,&_SID3_NUM_CHANNELS_MINUS_ONE,buffer)); ImGui::Separator(); - bool sepNoisePitch=ins->sid3.separateNoisePitch; - if (ImGui::Checkbox(_("Separate noise pitch"),&sepNoisePitch)) { PARAMETER - ins->sid3.separateNoisePitch=sepNoisePitch; - } - if (ImGui::IsItemHovered()) + + if(!ins->sid3.doWavetable) { - ImGui::SetTooltip(_("Make noise pitch independent from other waves' pitch.\nNoise pitch will be controllable via macros.")); + bool sepNoisePitch=ins->sid3.separateNoisePitch; + if (ImGui::Checkbox(_("Separate noise pitch"),&sepNoisePitch)) { PARAMETER + ins->sid3.separateNoisePitch=sepNoisePitch; + } + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip(_("Make noise pitch independent from other waves' pitch.\nNoise pitch will be controllable via macros.")); + } } for(int i = 0; i < SID3_NUM_FILTERS; i++) @@ -6209,11 +6220,6 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins) ImGui::EndTable(); } - if (ImGui::Checkbox(_("Absolute Duty Macro"),&ins->c64.dutyIsAbs)) { - ins->std.dutyMacro.vZoom=-1; - PARAMETER; - } - ImGui::EndTabItem(); } @@ -6221,10 +6227,7 @@ void FurnaceGUI::drawInsSID3(DivInstrument* ins) { insTabWavetable(ins); } - if(!ins->sid3.doWavetable) - { - insTabSample(ins); - } + insTabSample(ins); std::vector macroList;