diff options
author | Wohlstand <admin@wohlnet.ru> | 2017-11-26 03:08:47 +0300 |
---|---|---|
committer | Wohlstand <admin@wohlnet.ru> | 2017-11-26 03:08:47 +0300 |
commit | b92cc8e942b91268b096757fe22aca8368ea3de6 (patch) | |
tree | 086ee97fed7ed2aad2e64e8870021ba032fd9c59 /src | |
parent | 52bbba002d7f39334e833f3ec9e1de010d161bdf (diff) | |
parent | 5fa684bd2732f638763cd62bed831ccc6aafc0bf (diff) | |
download | libADLMIDI-b92cc8e942b91268b096757fe22aca8368ea3de6.tar.gz libADLMIDI-b92cc8e942b91268b096757fe22aca8368ea3de6.tar.bz2 libADLMIDI-b92cc8e942b91268b096757fe22aca8368ea3de6.zip |
Merge branch 'master' into get-rid-of-backup-buffer
Diffstat (limited to 'src')
-rw-r--r-- | src/adlmidi_midiplay.cpp | 29 | ||||
-rw-r--r-- | src/adlmidi_opl3.cpp | 19 | ||||
-rw-r--r-- | src/adlmidi_private.hpp | 41 |
3 files changed, 67 insertions, 22 deletions
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index ea46f16..69db6b0 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -110,6 +110,11 @@ static const uint8_t PercussionMap[256] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; +inline bool isXgPercChannel(uint8_t msb, uint8_t lsb) +{ + return (msb == 0x7E || msb == 0x7F) && (lsb == 0); +} + void MIDIplay::AdlChannel::AddAge(int64_t ms) { if(users.empty()) @@ -908,6 +913,7 @@ void MIDIplay::realTime_ResetState() chan.lastlrpn = 0; chan.lastmrpn = 0; chan.nrpn = false; + chan.brightness = 127; NoteUpdate_All(uint16_t(ch), Upd_All); NoteUpdate_All(uint16_t(ch), Upd_Off); } @@ -1194,10 +1200,12 @@ void MIDIplay::realTime_Controller(uint8_t channel, uint8_t type, uint8_t value) case 0: // Set bank msb (GM bank) Ch[channel].bank_msb = value; + Ch[channel].is_xg_percussion = isXgPercChannel(Ch[channel].bank_msb, Ch[channel].bank_lsb); break; case 32: // Set bank lsb (XG bank) Ch[channel].bank_lsb = value; + Ch[channel].is_xg_percussion = isXgPercChannel(Ch[channel].bank_msb, Ch[channel].bank_lsb); break; case 5: // Set portamento msb @@ -1220,11 +1228,14 @@ void MIDIplay::realTime_Controller(uint8_t channel, uint8_t type, uint8_t value) NoteUpdate_All(channel, Upd_Volume); break; + case 74: // Change brightness + Ch[channel].brightness = value; + NoteUpdate_All(channel, Upd_Volume); + break; + case 64: // Enable/disable sustain Ch[channel].sustain = value; - if(!value) KillSustainingNotes(channel); - break; case 11: // Change expression (another volume factor) @@ -1251,6 +1262,7 @@ void MIDIplay::realTime_Controller(uint8_t channel, uint8_t type, uint8_t value) Ch[channel].vibdelay = 0; Ch[channel].panning = 0x30; Ch[channel].portamento = 0; + Ch[channel].brightness = 127; //UpdatePortamento(MidCh); NoteUpdate_All(channel, Upd_Pan + Upd_Volume + Upd_Pitch); // Kill all sustained notes @@ -1449,6 +1461,8 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, if(props_mask & Upd_Volume) { uint32_t volume; + bool is_percussion = (MidCh == 9) || Ch[MidCh].is_xg_percussion; + uint8_t brightness = is_percussion ? 127 : Ch[MidCh].brightness; switch(opl.m_volumeScale) { @@ -1471,12 +1485,11 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, else { // The formula below: SOLVE(V=127^3 * 2^( (A-63.49999) / 8), A) - volume = volume > 8725 ? static_cast<unsigned int>(std::log((double)volume) * 11.541561 + (0.5 - 104.22845)) : 0; + volume = volume > 8725 ? static_cast<uint32_t>(std::log(static_cast<double>(volume)) * 11.541561 + (0.5 - 104.22845)) : 0; // The incorrect formula below: SOLVE(V=127^3 * (2^(A/63)-1), A) //opl.Touch_Real(c, volume>11210 ? 91.61112 * std::log(4.8819E-7*volume + 1.0)+0.5 : 0); } - - opl.Touch_Real(c, volume); + opl.Touch_Real(c, volume, brightness); //opl.Touch(c, volume); } break; @@ -1486,7 +1499,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, volume = 2 * ((Ch[MidCh].volume * Ch[MidCh].expression) * 127 / 16129) + 1; //volume = 2 * (Ch[MidCh].volume) + 1; volume = (DMX_volume_mapping_table[vol] * volume) >> 9; - opl.Touch_Real(c, volume); + opl.Touch_Real(c, volume, brightness); } break; @@ -1495,7 +1508,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, volume = ((Ch[MidCh].volume * Ch[MidCh].expression) * 127 / 16129); volume = ((64 * (vol + 0x80)) * volume) >> 15; //volume = ((63 * (vol + 0x80)) * Ch[MidCh].volume) >> 15; - opl.Touch_Real(c, volume); + opl.Touch_Real(c, volume, brightness); } break; @@ -1504,7 +1517,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, //volume = 63 - W9X_volume_mapping_table[(((vol * Ch[MidCh].volume /** Ch[MidCh].expression*/) * 127 / 16129 /*2048383*/) >> 2)]; volume = 63 - W9X_volume_mapping_table[(((vol * Ch[MidCh].volume * Ch[MidCh].expression) * 127 / 2048383) >> 2)]; //volume = W9X_volume_mapping_table[vol >> 2] + volume; - opl.Touch_Real(c, volume); + opl.Touch_Real(c, volume, brightness); } break; } diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index 421148d..2d1f3e8 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -271,7 +271,7 @@ void OPL3::NoteOn(unsigned c, double hertz) // Hertz range: 0..131071 } } -void OPL3::Touch_Real(unsigned c, unsigned volume) +void OPL3::Touch_Real(unsigned c, unsigned volume, uint8_t brightness) { if(volume > 63) volume = 63; @@ -332,9 +332,22 @@ void OPL3::Touch_Real(unsigned c, unsigned volume) { bool do_modulator = do_ops[ mode ][ 0 ] || ScaleModulators; bool do_carrier = do_ops[ mode ][ 1 ] || ScaleModulators; - Poke(card, 0x40 + o1, do_modulator ? (x | 63) - volume + volume * (x & 63) / 63 : x); + + uint32_t modulator = do_modulator ? (x | 63) - volume + volume * (x & 63) / 63 : x; + uint32_t carrier = do_carrier ? (y | 63) - volume + volume * (y & 63) / 63 : y; + + if(brightness != 127) + { + brightness = static_cast<uint8_t>(std::round(127.0 * std::sqrt((static_cast<double>(brightness)) * (1.0 / 127.0))) / 2.0); + if(!do_modulator) + modulator = (modulator | 63) - brightness + brightness * (modulator & 63) / 63; + if(!do_carrier) + carrier = (carrier | 63) - brightness + brightness * (carrier & 63) / 63; + } + + Poke(card, 0x40 + o1, modulator); if(o2 != 0xFFF) - Poke(card, 0x40 + o2, do_carrier ? (y | 63) - volume + volume * (y & 63) / 63 : y); + Poke(card, 0x40 + o2, carrier); } // Correct formula (ST3, AdPlug): diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index f58f02f..32c3637 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -249,7 +249,7 @@ public: void NoteOff(size_t c); void NoteOn(unsigned c, double hertz); - void Touch_Real(unsigned c, unsigned volume); + void Touch_Real(unsigned c, unsigned volume, uint8_t brightness = 127); //void Touch(unsigned c, unsigned volume) void Patch(uint16_t c, size_t i); @@ -465,6 +465,8 @@ public: int64_t vibdelay; uint8_t lastlrpn, lastmrpn; bool nrpn; + uint8_t brightness; + bool is_xg_percussion; struct NoteInfo { // Current pressure @@ -501,17 +503,34 @@ public: typedef activenotemap_t::iterator activenoteiterator; char ____padding2[5]; activenotemap_t activenotes; - + void reset() + { + portamento = 0; + bank_lsb = 0; + bank_msb = 0; + patch = 0; + volume = 100; + expression = 127; + panning = 0x30; + vibrato = 0; + sustain = 0; + bend = 0.0; + bendsense = 2 / 8192.0; + vibpos = 0; + vibspeed = 2 * 3.141592653 * 5.0; + vibdepth = 0.5 / 127; + vibdelay = 0; + lastlrpn = 0; + lastmrpn = 0; + nrpn = false; + brightness = 127; + is_xg_percussion = false; + } MIDIchannel() - : portamento(0), - bank_lsb(0), bank_msb(0), patch(0), - volume(100), expression(127), - panning(0x30), vibrato(0), sustain(0), - bend(0.0), bendsense(2 / 8192.0), - vibpos(0), vibspeed(2 * 3.141592653 * 5.0), - vibdepth(0.5 / 127), vibdelay(0), - lastlrpn(0), lastmrpn(0), nrpn(false), - activenotes() { } + : activenotes() + { + reset(); + } }; // Additional information about OPL3 channels |