diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/adlmidi.cpp | 10 | ||||
-rw-r--r-- | src/adlmidi_midiplay.cpp | 4 | ||||
-rw-r--r-- | src/adlmidi_opl3.cpp | 21 | ||||
-rw-r--r-- | src/adlmidi_private.hpp | 10 | ||||
-rw-r--r-- | src/chips/dosbox/dbopl.cpp | 22 | ||||
-rw-r--r-- | src/chips/dosbox/dbopl.h | 6 | ||||
-rw-r--r-- | src/chips/dosbox_opl3.cpp | 6 | ||||
-rw-r--r-- | src/chips/dosbox_opl3.h | 1 | ||||
-rw-r--r-- | src/chips/nuked/nukedopl3.c | 23 | ||||
-rw-r--r-- | src/chips/nuked/nukedopl3.h | 2 | ||||
-rw-r--r-- | src/chips/nuked/nukedopl3_174.c | 21 | ||||
-rw-r--r-- | src/chips/nuked/nukedopl3_174.h | 2 | ||||
-rw-r--r-- | src/chips/nuked_opl3.cpp | 6 | ||||
-rw-r--r-- | src/chips/nuked_opl3.h | 1 | ||||
-rw-r--r-- | src/chips/nuked_opl3_v174.cpp | 6 | ||||
-rw-r--r-- | src/chips/nuked_opl3_v174.h | 1 | ||||
-rw-r--r-- | src/chips/opl_chip_base.h | 3 |
17 files changed, 135 insertions, 10 deletions
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index 0e0b024..751afcf 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -447,6 +447,16 @@ ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn) #endif } +ADLMIDI_EXPORT void adl_setSoftPanEnabled(ADL_MIDIPlayer *device, int softPanEn) +{ + if (!device) + return; + MidiPlayer *play = GET_MIDI_PLAYER(device); + if (!play) + return; + play->m_synth.m_softPanning = softPanEn != 0; +} + /* !!!DEPRECATED!!! */ ADLMIDI_EXPORT void adl_setLogarithmicVolumes(struct ADL_MIDIPlayer *device, int logvol) { diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 62b1ef4..a4019b2 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -688,9 +688,7 @@ void MIDIplay::realTime_Controller(uint8_t channel, uint8_t type, uint8_t value) break; case 10: // Change panning - m_midiChannels[channel].panning = 0x00; - if(value < 64 + 32) m_midiChannels[channel].panning |= OPL_PANNING_LEFT; - if(value >= 64 - 32) m_midiChannels[channel].panning |= OPL_PANNING_RIGHT; + m_midiChannels[channel].panning = value; noteUpdateAll(channel, Upd_Pan); break; diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index 3e33e86..7075f66 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -194,6 +194,13 @@ void OPL3::writeRegI(size_t chip, uint32_t address, uint32_t value) #endif } +void OPL3::writePan(size_t chip, uint32_t address, uint32_t value) +{ +#ifndef ADLMIDI_HW_OPL + m_chips[chip]->writePan(static_cast<uint16_t>(address), static_cast<uint8_t>(value)); +#endif +} + void OPL3::noteOff(size_t c) { @@ -362,8 +369,18 @@ void OPL3::setPatch(size_t c, const adldata &instrument) void OPL3::setPan(size_t c, uint8_t value) { size_t chip = c / 23, cc = c % 23; - if(g_channelsMap[cc] != 0xFFF) - writeRegI(chip, 0xC0 + g_channelsMap[cc], m_insCache[c].feedconn | value); + if(g_channelsMap[cc] != 0xFFF) { + if (m_softPanning) { + writePan(chip, g_channelsMap[cc], value); + writeRegI(chip, 0xC0 + g_channelsMap[cc], m_insCache[c].feedconn | 0x30); + } + else { + int panning = 0; + if (value < 64 + 32) panning |= OPL_PANNING_LEFT; + if (value >= 64 - 32) panning |= OPL_PANNING_RIGHT; + writeRegI(chip, 0xC0 + g_channelsMap[cc], m_insCache[c].feedconn | panning); + } + } } void OPL3::silenceAll() // Silence all OPL channels. diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index 4fb3e7f..b9228dc 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -277,6 +277,8 @@ public: bool m_scaleModulators; //! Run emulator at PCM rate if that possible. Reduces sounding accuracy, but decreases CPU usage on lower rates. bool m_runAtPcmRate; + //! Enable soft panning + bool m_softPanning; //! Just a padding. Reserved. char _padding2[3]; @@ -381,6 +383,14 @@ public: void writeRegI(size_t chip, uint32_t address, uint32_t value); /** + * @brief Write to soft panning control of OPL3 chip emulator + * @param chip Index of emulated chip. + * @param address Register of channel to write + * @param value Value to write + */ + void writePan(size_t chip, uint32_t address, uint32_t value); + + /** * @brief Off the note in specified chip channel * @param c Channel of chip (Emulated chip choosing by next formula: [c = ch + (chipId * 23)]) */ diff --git a/src/chips/dosbox/dbopl.cpp b/src/chips/dosbox/dbopl.cpp index 7d78c5f..903c1bb 100644 --- a/src/chips/dosbox/dbopl.cpp +++ b/src/chips/dosbox/dbopl.cpp @@ -757,6 +757,11 @@ void Channel::WriteC0(const Chip* chip, Bit8u val) { UpdateSynth(chip); } +void Channel::WritePan(Bit8u val) { + panLeft = (Bit16u)(cos((float)val * (PI / 2.0f / 127.0f)) * 65535.0f); + panRight = (Bit16u)(sin((float)val * (PI / 2.0f / 127.0f)) * 65535.0f); +} + void Channel::UpdateSynth( const Chip* chip ) { //Select the new synth mode if ( chip->opl3Active ) { @@ -971,8 +976,8 @@ Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) { case sm3AMFM: case sm3FMAM: case sm3AMAM: - output[ i * 2 + 0 ] += sample & maskLeft; - output[ i * 2 + 1 ] += sample & maskRight; + output[ i * 2 + 0 ] += (sample * panLeft / 65535) & maskLeft; + output[ i * 2 + 1 ] += (sample * panRight / 65535) & maskRight; break; default: break; @@ -1388,6 +1393,10 @@ void Chip::Setup( Bit32u rate ) { WriteReg( i, 0xff ); WriteReg( i, 0x0 ); } + + for ( int i = 0; i < 18; i++ ) { + chan[i].WritePan( 0x40 ); + } } static bool doneTables = false; @@ -1614,5 +1623,14 @@ void Handler::Init( Bitu rate ) { chip.Setup( static_cast<Bit32u>(rate) ); } +void Handler::WritePan( Bit32u reg, Bit8u val ) +{ + Bitu index; + index = ((reg >> 4) & 0x10) | (reg & 0xf); + if (ChanOffsetTable[index]) { + Channel* regChan = (Channel*)(((char *)&chip) + ChanOffsetTable[index]); + regChan->WritePan(val); + } +} } //Namespace DBOPL diff --git a/src/chips/dosbox/dbopl.h b/src/chips/dosbox/dbopl.h index 73c0aa9..c265fc6 100644 --- a/src/chips/dosbox/dbopl.h +++ b/src/chips/dosbox/dbopl.h @@ -192,6 +192,9 @@ struct Channel { Bit8s maskLeft; //Sign extended values for both channel's panning Bit8s maskRight; + Bit16u panLeft; // Extended behavior, scale values for soft panning + Bit16u panRight; + //Forward the channel data to the operators of the channel void SetChanData( const Chip* chip, Bit32u data ); //Change in the chandata, check for new values and if we have to forward to operators @@ -201,6 +204,8 @@ struct Channel { void WriteB0( const Chip* chip, Bit8u val ); void WriteC0( const Chip* chip, Bit8u val ); + void WritePan( Bit8u val ); + //call this for the first channel template< bool opl3Mode > void GeneratePercussion( Chip* chip, Bit32s* output ); @@ -271,6 +276,7 @@ struct Chip { struct Handler { DBOPL::Chip chip; + void WritePan( Bit32u port, Bit8u val ); Bit32u WriteAddr( Bit32u port, Bit8u val ); void WriteReg( Bit32u addr, Bit8u val ); void GenerateArr(Bit32s *out, Bitu *samples); diff --git a/src/chips/dosbox_opl3.cpp b/src/chips/dosbox_opl3.cpp index f783afe..37f5e9c 100644 --- a/src/chips/dosbox_opl3.cpp +++ b/src/chips/dosbox_opl3.cpp @@ -61,6 +61,12 @@ void DosBoxOPL3::writeReg(uint16_t addr, uint8_t data) chip_r->WriteReg(static_cast<Bit32u>(addr), data); } +void DosBoxOPL3::writePan(uint16_t addr, uint8_t data) +{ + DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip); + chip_r->WritePan(static_cast<Bit32u>(addr), data); +} + void DosBoxOPL3::nativeGenerateN(int16_t *output, size_t frames) { DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip); diff --git a/src/chips/dosbox_opl3.h b/src/chips/dosbox_opl3.h index f966393..eb79300 100644 --- a/src/chips/dosbox_opl3.h +++ b/src/chips/dosbox_opl3.h @@ -34,6 +34,7 @@ public: void setRate(uint32_t rate) override; void reset() override; void writeReg(uint16_t addr, uint8_t data) override; + void writePan(uint16_t addr, uint8_t data) override; void nativePreGenerate() override {} void nativePostGenerate() override {} void nativeGenerateN(int16_t *output, size_t frames) override; diff --git a/src/chips/nuked/nukedopl3.c b/src/chips/nuked/nukedopl3.c index fe2313c..94b1f9d 100644 --- a/src/chips/nuked/nukedopl3.c +++ b/src/chips/nuked/nukedopl3.c @@ -36,6 +36,10 @@ #define RSM_FRAC 10 +#ifndef PI +#define PI 3.14159265358979323846 +#endif + /* Channel types */ enum { @@ -1071,7 +1075,7 @@ void OPL3_Generate(opl3_chip *chip, Bit16s *buf) { accm += *chip->channel[ii].out[jj]; } - chip->mixbuff[0] += (Bit16s)(accm & chip->channel[ii].cha); + chip->mixbuff[0] += (Bit16s)((accm * chip->channel[ii].chl / 65535) & chip->channel[ii].cha); } for (ii = 15; ii < 18; ii++) @@ -1100,7 +1104,7 @@ void OPL3_Generate(opl3_chip *chip, Bit16s *buf) { accm += *chip->channel[ii].out[jj]; } - chip->mixbuff[1] += (Bit16s)(accm & chip->channel[ii].chb); + chip->mixbuff[1] += (Bit16s)((accm * chip->channel[ii].chr / 65535) & chip->channel[ii].chb); } for (ii = 33; ii < 36; ii++) @@ -1232,6 +1236,8 @@ void OPL3_Reset(opl3_chip *chip, Bit32u samplerate) chip->channel[channum].chtype = ch_2op; chip->channel[channum].cha = 0xffff; chip->channel[channum].chb = 0xffff; + chip->channel[channum].chl = 0xffff; + chip->channel[channum].chr = 0xffff; chip->channel[channum].ch_num = channum; OPL3_ChannelSetupAlg(&chip->channel[channum]); } @@ -1241,6 +1247,19 @@ void OPL3_Reset(opl3_chip *chip, Bit32u samplerate) chip->vibshift = 1; } +static void OPL3_ChannelWritePan(opl3_channel *channel, Bit8u data) +{ + channel->chl = (Bit16u)(cos((float)data * (PI / 2.0f / 127.0f)) * 65535.0f); + channel->chr = (Bit16u)(sin((float)data * (PI / 2.0f / 127.0f)) * 65535.0f); +} + +void OPL3_WritePan(opl3_chip *chip, Bit16u reg, Bit8u v) +{ + Bit8u high = (reg >> 8) & 0x01; + Bit8u regm = reg & 0xff; + OPL3_ChannelWritePan(&chip->channel[9 * high + (regm & 0x0f)], v); +} + void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v) { Bit8u high = (reg >> 8) & 0x01; diff --git a/src/chips/nuked/nukedopl3.h b/src/chips/nuked/nukedopl3.h index 8d3318a..268e8de 100644 --- a/src/chips/nuked/nukedopl3.h +++ b/src/chips/nuked/nukedopl3.h @@ -101,6 +101,7 @@ struct _opl3_channel { Bit8u alg; Bit8u ksv; Bit16u cha, chb; + Bit16u chl, chr; Bit8u ch_num; }; @@ -153,6 +154,7 @@ void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf); void OPL3_Reset(opl3_chip *chip, Bit32u samplerate); void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v); void OPL3_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v); +void OPL3_WritePan(opl3_chip *chip, Bit16u reg, Bit8u v); void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples); void OPL3_GenerateStreamMix(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples); diff --git a/src/chips/nuked/nukedopl3_174.c b/src/chips/nuked/nukedopl3_174.c index 99eab16..a8b1f40 100644 --- a/src/chips/nuked/nukedopl3_174.c +++ b/src/chips/nuked/nukedopl3_174.c @@ -34,7 +34,11 @@ #define RSM_FRAC 10 -/* Channel types */ +#ifndef PI +#define PI 3.14159265358979323846 +#endif + + /* Channel types */ enum { ch_2op = 0, @@ -1222,6 +1226,8 @@ void OPL3v17_Reset(opl3_chip *chip, Bit32u samplerate) chip->channel[channum].chtype = ch_2op; chip->channel[channum].cha = ~0; chip->channel[channum].chb = ~0; + chip->channel[channum].chl = ~0; + chip->channel[channum].chr = ~0; OPL3_ChannelSetupAlg(&chip->channel[channum]); } chip->noise = 0x306600; @@ -1230,6 +1236,19 @@ void OPL3v17_Reset(opl3_chip *chip, Bit32u samplerate) chip->vibshift = 1; } +static void OPL3v17_ChannelWritePan(opl3_channel *channel, Bit8u data) +{ + channel->chl = (Bit16u)(cos((float)data * (PI / 2.0f / 127.0f)) * 65535.0f); + channel->chr = (Bit16u)(sin((float)data * (PI / 2.0f / 127.0f)) * 65535.0f); +} + +void OPL3v17_WritePan(opl3_chip *chip, Bit16u reg, Bit8u v) +{ + Bit8u high = (reg >> 8) & 0x01; + Bit8u regm = reg & 0xff; + OPL3v17_ChannelWritePan(&chip->channel[9 * high + (regm & 0x0f)], v); +} + void OPL3v17_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v) { Bit8u high = (reg >> 8) & 0x01; diff --git a/src/chips/nuked/nukedopl3_174.h b/src/chips/nuked/nukedopl3_174.h index 240802f..cd18562 100644 --- a/src/chips/nuked/nukedopl3_174.h +++ b/src/chips/nuked/nukedopl3_174.h @@ -103,6 +103,7 @@ struct _opl3_channel { Bit8u alg; Bit8u ksv; Bit16u cha, chb; + Bit16u chl, chr; }; typedef struct _opl3_writebuf { @@ -142,6 +143,7 @@ struct _opl3_chip { void OPL3v17_Generate(opl3_chip *chip, Bit16s *buf); void OPL3v17_GenerateResampled(opl3_chip *chip, Bit16s *buf); void OPL3v17_Reset(opl3_chip *chip, Bit32u samplerate); +void OPL3v17_WritePan(opl3_chip *chip, Bit16u reg, Bit8u v); void OPL3v17_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v); void OPL3v17_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v); void OPL3v17_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples); diff --git a/src/chips/nuked_opl3.cpp b/src/chips/nuked_opl3.cpp index e4f9764..bbf4a25 100644 --- a/src/chips/nuked_opl3.cpp +++ b/src/chips/nuked_opl3.cpp @@ -57,6 +57,12 @@ void NukedOPL3::writeReg(uint16_t addr, uint8_t data) OPL3_WriteRegBuffered(chip_r, addr, data); } +void NukedOPL3::writePan(uint16_t addr, uint8_t data) +{ + opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); + OPL3_WritePan(chip_r, addr, data); +} + void NukedOPL3::nativeGenerate(int16_t *frame) { opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); diff --git a/src/chips/nuked_opl3.h b/src/chips/nuked_opl3.h index 4b14b8b..33baf54 100644 --- a/src/chips/nuked_opl3.h +++ b/src/chips/nuked_opl3.h @@ -34,6 +34,7 @@ public: void setRate(uint32_t rate) override; void reset() override; void writeReg(uint16_t addr, uint8_t data) override; + void writePan(uint16_t addr, uint8_t data) override; void nativePreGenerate() override {} void nativePostGenerate() override {} void nativeGenerate(int16_t *frame) override; diff --git a/src/chips/nuked_opl3_v174.cpp b/src/chips/nuked_opl3_v174.cpp index 793af93..6bb06c2 100644 --- a/src/chips/nuked_opl3_v174.cpp +++ b/src/chips/nuked_opl3_v174.cpp @@ -57,6 +57,12 @@ void NukedOPL3v174::writeReg(uint16_t addr, uint8_t data) OPL3v17_WriteReg(chip_r, addr, data); } +void NukedOPL3v174::writePan(uint16_t addr, uint8_t data) +{ + opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); + OPL3v17_WritePan(chip_r, addr, data); +} + void NukedOPL3v174::nativeGenerate(int16_t *frame) { opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); diff --git a/src/chips/nuked_opl3_v174.h b/src/chips/nuked_opl3_v174.h index 9463a02..9eaeb19 100644 --- a/src/chips/nuked_opl3_v174.h +++ b/src/chips/nuked_opl3_v174.h @@ -34,6 +34,7 @@ public: void setRate(uint32_t rate) override; void reset() override; void writeReg(uint16_t addr, uint8_t data) override; + void writePan(uint16_t addr, uint8_t data) override; void nativePreGenerate() override {} void nativePostGenerate() override {} void nativeGenerate(int16_t *frame) override; diff --git a/src/chips/opl_chip_base.h b/src/chips/opl_chip_base.h index 8025d03..faee307 100644 --- a/src/chips/opl_chip_base.h +++ b/src/chips/opl_chip_base.h @@ -61,6 +61,9 @@ public: virtual void reset() = 0; virtual void writeReg(uint16_t addr, uint8_t data) = 0; + // extended + virtual void writePan(uint16_t addr, uint8_t data) { }; + virtual void nativePreGenerate() = 0; virtual void nativePostGenerate() = 0; virtual void nativeGenerate(int16_t *frame) = 0; |