From e5d81bd694724f487522a6a4f3e9c20122b16b1c Mon Sep 17 00:00:00 2001 From: cam900 Date: Thu, 5 Jan 2023 08:40:44 +0900 Subject: [PATCH 1/9] Prepare to YMF289B OPL3-L support --- src/engine/platform/opl.cpp | 20 ++++++++++++++++++-- src/gui/presets.cpp | 10 ++++++++++ src/gui/sysConf.cpp | 15 +++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 5af5de8c6..ecb68bdf2 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1722,13 +1722,29 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) { case 0x04: chipClock=15000000.0; break; + case 0x05: + chipClock=33868800.0; + break; default: chipClock=COLOR_NTSC*4.0; break; } CHECK_CUSTOM_CLOCK; - rate=chipClock/288; - chipRateBase=rate; + switch (flags.getInt("chipType",0)) { + case 1: // YMF289B + chipFreqBase=32768*684; + rate=chipClock/684; + chipRateBase=chipClock/768; + downsample=true; + break; + default: // YMF262 + chipFreqBase=32768*288; + rate=chipClock/288; + chipRateBase=rate; + downsample=false; + break; + } + reset(); break; case 4: switch (flags.getInt("clockSel",0)) { diff --git a/src/gui/presets.cpp b/src/gui/presets.cpp index f0e4fe928..c01d2c4e6 100644 --- a/src/gui/presets.cpp +++ b/src/gui/presets.cpp @@ -2248,6 +2248,16 @@ void FurnaceGUI::initSystemPresets() { CH(DIV_SYSTEM_OPL3_DRUMS, 64, 0, "") } ); + ENTRY( + "Yamaha YMF289B (OPL3-L)", { + CH(DIV_SYSTEM_OPL3, 64, 0, "chipType=1") + } + ); + ENTRY( + "Yamaha YMF289B (drums mode)", { + CH(DIV_SYSTEM_OPL3_DRUMS, 64, 0, "chipType=1") + } + ); if (settings.hiddenSystems) { ENTRY( "Yamaha YMU759 (MA-2)", { diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index 8e41fa00c..ff60b3136 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -1182,6 +1182,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo case DIV_SYSTEM_OPL3: case DIV_SYSTEM_OPL3_DRUMS: { int clockSel=flags.getInt("clockSel",0); + int chipType=flags.getInt("chipType",0); ImGui::Text("Clock rate:"); if (ImGui::RadioButton("14.32MHz (NTSC)",clockSel==0)) { @@ -1204,10 +1205,24 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo clockSel=4; altered=true; } + if (ImGui::RadioButton("33.8688MHz (OPL3-L)",clockSel==5)) { + clockSel=5; + altered=true; + } + ImGui::Text("Chip type:"); + if (ImGui::RadioButton("OPL3 (YMF262)",chipType==0)) { + chipType=0; + altered=true; + } + if (ImGui::RadioButton("OPL3-L (YMF289B)",chipType==1)) { + chipType=1; + altered=true; + } if (altered) { e->lockSave([&]() { flags.set("clockSel",clockSel); + flags.set("chipType",chipType); }); } break; From f5c1273c2d71fff517087cb873e7c72eca9df2e6 Mon Sep 17 00:00:00 2001 From: cam900 Date: Thu, 5 Jan 2023 08:47:24 +0900 Subject: [PATCH 2/9] Clock preset fix --- src/gui/presets.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/gui/presets.cpp b/src/gui/presets.cpp index c01d2c4e6..375794668 100644 --- a/src/gui/presets.cpp +++ b/src/gui/presets.cpp @@ -2250,12 +2250,18 @@ void FurnaceGUI::initSystemPresets() { ); ENTRY( "Yamaha YMF289B (OPL3-L)", { - CH(DIV_SYSTEM_OPL3, 64, 0, "chipType=1") + CH(DIV_SYSTEM_OPL3, 64, 0, + "clockSel=5\n" + "chipType=1\n" + ) } ); ENTRY( "Yamaha YMF289B (drums mode)", { - CH(DIV_SYSTEM_OPL3_DRUMS, 64, 0, "chipType=1") + CH(DIV_SYSTEM_OPL3_DRUMS, 64, 0, + "clockSel=5\n" + "chipType=1\n" + ) } ); if (settings.hiddenSystems) { From 74e429fae24e878c4b464b7cc4e863e12c8a051c Mon Sep 17 00:00:00 2001 From: cam900 Date: Thu, 5 Jan 2023 08:51:25 +0900 Subject: [PATCH 3/9] Fix pitch --- src/engine/platform/opl.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index ecb68bdf2..8e1d1b11e 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1488,8 +1488,8 @@ void DivPlatformOPL::reset() { } */ if (downsample) { - const unsigned int downsampledRate=(unsigned int)((double)rate*rate/chipRateBase); - OPL3_Reset(&fm,downsampledRate); +// const unsigned int downsampledRate=(unsigned int)((double)rate*rate/chipRateBase); + OPL3_Reset(&fm,44100); } else { OPL3_Reset(&fm,rate); } @@ -1733,8 +1733,8 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) { switch (flags.getInt("chipType",0)) { case 1: // YMF289B chipFreqBase=32768*684; - rate=chipClock/684; - chipRateBase=chipClock/768; + rate=chipClock/768; + chipRateBase=chipClock/684; downsample=true; break; default: // YMF262 From 68964e384f417d4ee2bef739c48863aa5c225407 Mon Sep 17 00:00:00 2001 From: cam900 Date: Thu, 5 Jan 2023 08:51:44 +0900 Subject: [PATCH 4/9] Spacing --- src/engine/platform/opl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 8e1d1b11e..8c5f6c759 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1488,7 +1488,7 @@ void DivPlatformOPL::reset() { } */ if (downsample) { -// const unsigned int downsampledRate=(unsigned int)((double)rate*rate/chipRateBase); + //const unsigned int downsampledRate=(unsigned int)((double)rate*rate/chipRateBase); OPL3_Reset(&fm,44100); } else { OPL3_Reset(&fm,rate); From f6f5353987814584dcb65aeea18023fb93ee2208 Mon Sep 17 00:00:00 2001 From: cam900 Date: Sun, 15 Jan 2023 08:15:12 +0900 Subject: [PATCH 5/9] Fix volume --- src/gui/presets.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/presets.cpp b/src/gui/presets.cpp index 75d1ffb0e..fdb58dbfc 100644 --- a/src/gui/presets.cpp +++ b/src/gui/presets.cpp @@ -2250,7 +2250,7 @@ void FurnaceGUI::initSystemPresets() { ); ENTRY( "Yamaha YMF289B (OPL3-L)", { - CH(DIV_SYSTEM_OPL3, 64, 0, + CH(DIV_SYSTEM_OPL3, 1.0f, 0, "clockSel=5\n" "chipType=1\n" ) @@ -2258,7 +2258,7 @@ void FurnaceGUI::initSystemPresets() { ); ENTRY( "Yamaha YMF289B (drums mode)", { - CH(DIV_SYSTEM_OPL3_DRUMS, 64, 0, + CH(DIV_SYSTEM_OPL3_DRUMS, 1.0f, 0, "clockSel=5\n" "chipType=1\n" ) From 9ae12241a455316e5d5cecf8a9ff1925c65dc153 Mon Sep 17 00:00:00 2001 From: cam900 Date: Mon, 16 Jan 2023 10:25:59 +0900 Subject: [PATCH 6/9] Fix downsampled rate accuracy --- src/engine/platform/opl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 6ac489bfc..f3accd24a 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1548,8 +1548,8 @@ void DivPlatformOPL::reset() { } */ if (downsample) { - //const unsigned int downsampledRate=(unsigned int)((double)rate*rate/chipRateBase); - OPL3_Reset(&fm,44100); + const unsigned int downsampledRate=(unsigned int)((double)rate*49716.0/(double)chipRateBase); + OPL3_Reset(&fm,downsampledRate); } else { OPL3_Reset(&fm,rate); } From 0c5a6d976074f3ad2d3378f680d8467a973bb135 Mon Sep 17 00:00:00 2001 From: cam900 Date: Sat, 13 May 2023 18:54:05 +0900 Subject: [PATCH 7/9] Just resample rather than reset --- extern/opl/MODIFIED.md | 2 +- extern/opl/opl3.c | 5 +++++ extern/opl/opl3.h | 1 + src/engine/platform/opl.cpp | 7 ++++++- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/extern/opl/MODIFIED.md b/extern/opl/MODIFIED.md index 78341ad48..d5a39e9f7 100644 --- a/extern/opl/MODIFIED.md +++ b/extern/opl/MODIFIED.md @@ -1,4 +1,4 @@ # modification disclaimer -this is a modified version of Nuked-OPL3 which implements channel muting in the core. +this is a modified version of Nuked-OPL3 which implements channel muting in the core, and resampling function. see [this issue](https://github.com/tildearrow/furnace/issues/414) for more information. diff --git a/extern/opl/opl3.c b/extern/opl/opl3.c index 3358f0335..5acdca250 100644 --- a/extern/opl/opl3.c +++ b/extern/opl/opl3.c @@ -1362,6 +1362,11 @@ void OPL3_Reset(opl3_chip *chip, uint32_t samplerate) #endif } +void OPL3_Resample(opl3_chip *chip, uint32_t samplerate) +{ + chip->rateratio = (samplerate << RSM_FRAC) / 49716; +} + void OPL3_WriteReg(opl3_chip *chip, uint16_t reg, uint8_t v) { uint8_t high = (reg >> 8) & 0x01; diff --git a/extern/opl/opl3.h b/extern/opl/opl3.h index 8d5153237..1e88a8018 100644 --- a/extern/opl/opl3.h +++ b/extern/opl/opl3.h @@ -158,6 +158,7 @@ struct _opl3_chip { void OPL3_Generate(opl3_chip *chip, int16_t *buf); void OPL3_GenerateResampled(opl3_chip *chip, int16_t *buf); void OPL3_Reset(opl3_chip *chip, uint32_t samplerate); +void OPL3_Resample(opl3_chip *chip, uint32_t samplerate); void OPL3_WriteReg(opl3_chip *chip, uint16_t reg, uint8_t v); void OPL3_WriteRegBuffered(opl3_chip *chip, uint16_t reg, uint8_t v); void OPL3_GenerateStream(opl3_chip *chip, int16_t *sndptr, uint32_t numsamples); diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 3ce997e57..863663a59 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1866,7 +1866,12 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) { totalOutputs=4; break; } - reset(); + if (downsample) { + const unsigned int downsampledRate=(unsigned int)((double)rate*49716.0/(double)chipRateBase); + OPL3_Resample(&fm,downsampledRate); + } else { + OPL3_Resample(&fm,rate); + } break; case 4: switch (flags.getInt("clockSel",0)) { From a675494fc21eb27316e359cdb27880174c7f5e62 Mon Sep 17 00:00:00 2001 From: cam900 Date: Sat, 22 Jul 2023 10:43:21 +0900 Subject: [PATCH 8/9] Add part number for OPL3-L --- src/gui/sysPartNumber.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/gui/sysPartNumber.cpp b/src/gui/sysPartNumber.cpp index 7ca4489f3..585520f7c 100644 --- a/src/gui/sysPartNumber.cpp +++ b/src/gui/sysPartNumber.cpp @@ -159,9 +159,15 @@ const char* FurnaceGUI::getSystemPartNumber(DivSystem sys, DivConfig& flags) { return "YM3812"; break; case DIV_SYSTEM_OPL3: - case DIV_SYSTEM_OPL3_DRUMS: - return "YMF262"; + case DIV_SYSTEM_OPL3_DRUMS:{ + int chipType=flags.getInt("chipType",0); + if (chipType==1) { + return "YMF289B"; + } else { + return "YMF262"; + } break; + } case DIV_SYSTEM_OPL4: case DIV_SYSTEM_OPL4_DRUMS: return "OPL4"; From 3bafd4f6c03a197a440962c57bf6445a77aa8833 Mon Sep 17 00:00:00 2001 From: cam900 Date: Sun, 23 Jul 2023 17:39:38 +0900 Subject: [PATCH 9/9] update via PR comments --- src/engine/platform/opl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 638c31e83..6c3fa416d 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1599,7 +1599,7 @@ void DivPlatformOPL::reset() { } */ if (downsample) { - const unsigned int downsampledRate=(unsigned int)((double)rate*49716.0/(double)chipRateBase); + const unsigned int downsampledRate=(unsigned int)((double)rate*round(COLOR_NTSC/72.0)/(double)chipRateBase); OPL3_Reset(&fm,downsampledRate); } else { OPL3_Reset(&fm,rate); @@ -1865,7 +1865,7 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) { break; } if (downsample) { - const unsigned int downsampledRate=(unsigned int)((double)rate*49716.0/(double)chipRateBase); + const unsigned int downsampledRate=(unsigned int)((double)rate*round(COLOR_NTSC/72.0)/(double)chipRateBase); OPL3_Resample(&fm,downsampledRate); } else { OPL3_Resample(&fm,rate);