diff --git a/format/s3m/voice/voice.go b/format/s3m/voice/voice.go index f4803bc..237a135 100644 --- a/format/s3m/voice/voice.go +++ b/format/s3m/voice/voice.go @@ -150,6 +150,26 @@ func (v *s3mVoice) Setup(inst *instrument.Instrument[period.Amiga, s3mVolume.Fin return err } + // Build OPL2 register set from instrument definition. + instOPL := d + v.opl2 = component.OPL2Registers{ + Mod: component.OPL2Operator{ + Reg20: instOPL.Modulator.GetReg20(), + Reg40: instOPL.Modulator.GetReg40(), + Reg60: instOPL.Modulator.GetReg60(), + Reg80: instOPL.Modulator.GetReg80(), + RegE0: instOPL.Modulator.GetRegE0(), + }, + Car: component.OPL2Operator{ + Reg20: instOPL.Carrier.GetReg20(), + Reg40: instOPL.Carrier.GetReg40(), + Reg60: instOPL.Carrier.GetReg60(), + Reg80: instOPL.Carrier.GetReg80(), + RegE0: instOPL.Carrier.GetRegE0(), + }, + RegC0: instOPL.GetRegC0(), + } + var o component.OPL2[period.Amiga, s3mVolume.FineVolume, s3mVolume.Volume] o.Setup(v.opl2Chip, int(v.opl2Channel), v.opl2, s3mPeriod.S3MAmigaConverter, s3mSystem.DefaultC4SampleRate, inst.GetDefaultVolume()) v.voicer = &o diff --git a/go.mod b/go.mod index 34951f0..3652ac0 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module github.com/gotracker/playback -go 1.21 +go 1.24.0 require ( github.com/gotracker/goaudiofile v1.0.16 - github.com/gotracker/opl2 v1.0.1 + github.com/gotracker/opl2 v1.0.2 github.com/heucuva/comparison v1.0.0 github.com/heucuva/optional v0.0.1 - golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f + golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 ) diff --git a/go.sum b/go.sum index a8aafb6..cdc327b 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,14 @@ github.com/gotracker/goaudiofile v1.0.16 h1:+QlrDbZluWs01NZdg3JOuM+Zm98o1NNFVbtts2Fkw2M= github.com/gotracker/goaudiofile v1.0.16/go.mod h1:mX/CjpkoClUFrGQ8MU6x2hm4ma/ClQTh83wwHhLC7RY= -github.com/gotracker/opl2 v1.0.1 h1:1PVNs0dXqEAQxdws7fz2WEE3nSKkMb1osTTT7KgEi5g= -github.com/gotracker/opl2 v1.0.1/go.mod h1:lW1WbZlh7svEMpurp9LLYWSyf1WPAb750cQ7xGIhCnY= +github.com/gotracker/opl2 v1.0.2 h1:G1KaUAbl+3Khwq++1L+Bs55Iep1AimhCmGFs5hJOBOU= +github.com/gotracker/opl2 v1.0.2/go.mod h1:lW1WbZlh7svEMpurp9LLYWSyf1WPAb750cQ7xGIhCnY= github.com/heucuva/comparison v1.0.0 h1:xxXNKS9GKHetQavOz35FitlAXWvmvM3U6M5IRIw7kN8= github.com/heucuva/comparison v1.0.0/go.mod h1:5l0Va1uxFyy7S4DgdflnayxV2HStFwWI2rzbrlNNNMk= github.com/heucuva/optional v0.0.1 h1:tLbVBMQBKzQVfe43bHQFSxjhTzYcRK8frnTBG6FLksM= github.com/heucuva/optional v0.0.1/go.mod h1:2AtE/X9279wzrHLkCNvKl0xP7AiEIj3RijGKwbO8R3M= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f h1:3CW0unweImhOzd5FmYuRsD4Y4oQFKZIjAnKbjV4WIrw= -golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/voice/component/opl2.go b/voice/component/opl2.go index 02d5805..e707417 100755 --- a/voice/component/opl2.go +++ b/voice/component/opl2.go @@ -171,9 +171,20 @@ func (o *OPL2[TPeriod, TMixingVolume, TVolume]) calc40(reg40 uint8, vol volume.V } func (o *OPL2[TPeriod, TMixingVolume, TVolume]) periodToFreqBlock(p TPeriod, baseFreq frequency.Frequency) (uint16, uint8) { - modFreq := o.periodConverter.GetFrequency(p) - freq := float64(baseFreq) * float64(modFreq) / 261625 - + // The period converter can return either an absolute frequency (Hz) or a + // relative multiplier, depending on the converter implementation. For the + // legacy OPL path, absolute frequencies need to be scaled down to the + // expected OPL range (mirroring dbopl): baseFreq * freq / 261625. + modFreq := float64(o.periodConverter.GetFrequency(p)) + var freq float64 + if modFreq > 200 { // treat as absolute Hz (Amiga-style converters) + freq = float64(baseFreq) * modFreq / 261625.0 + } else { // treat as a ratio/multiplier (Linear-style converters) + freq = modFreq * float64(baseFreq) + } + if freq <= 0 { + return 0, 0 + } return o.freqToFnumBlock(freq) }