diff --git a/game/sound/989snd/ame_handler.cpp b/game/sound/989snd/ame_handler.cpp index bb5f5051cd..37fba1b2e3 100644 --- a/game/sound/989snd/ame_handler.cpp +++ b/game/sound/989snd/ame_handler.cpp @@ -58,9 +58,17 @@ bool ame_handler::tick() { }; void ame_handler::start_segment(u32 id) { - auto midiblock = (MIDIBlockHeader*)(m_header->BlockPtr[id] + (uintptr_t)m_header); - m_midis.emplace(id, std::make_unique(midiblock, m_vm, m_sound, m_vol, m_pan, - m_locator, m_bank, this)); + if (m_midis.find(id) == m_midis.end()) { + auto midiblock = (MIDIBlockHeader*)(m_header->BlockPtr[id] + (uintptr_t)m_header); + auto sound_handler = (MIDISoundHandler*)((uintptr_t)midiblock + sizeof(MIDIBlockHeader)); + + // Skip adding if not midi type + u32 type = (sound_handler->OwnerID >> 24) & 0xf; + if (type == 1 || type == 3) { + m_midis.emplace(id, std::make_unique(midiblock, m_vm, m_sound, m_vol, m_pan, + m_locator, m_bank, this)); + } + } } void ame_handler::stop() { diff --git a/game/sound/989snd/midi_handler.cpp b/game/sound/989snd/midi_handler.cpp index 0e17c42350..c8918948c3 100644 --- a/game/sound/989snd/midi_handler.cpp +++ b/game/sound/989snd/midi_handler.cpp @@ -325,6 +325,14 @@ void midi_handler::meta_event() { m_seq_ptr += len + 2; } +static s16 midiTo360Pan(u8 pan) { + if (pan >= 64) { + return (s16)(90 * (pan - 64) / 63); + } else { + return (s16)(90 * pan / 64 + 270); + } +} + void midi_handler::controller_change() { u8 channel = m_status & 0xf; u8 controller = m_seq_ptr[0]; @@ -336,7 +344,7 @@ void midi_handler::controller_change() { m_chanvol[channel] = static_cast(value); } break; case 0xa: { - m_chanpan[channel] = static_cast(value); + m_chanpan[channel] = midiTo360Pan(static_cast(value)); } break; // case 0x40: {} break; // TODO damper default: diff --git a/game/sound/989snd/midi_handler.h b/game/sound/989snd/midi_handler.h index c8ae710457..d6de7408d6 100644 --- a/game/sound/989snd/midi_handler.h +++ b/game/sound/989snd/midi_handler.h @@ -108,7 +108,7 @@ class midi_handler : public sound_handler { std::array m_mute_state{}; std::array m_chanvol{}; - std::array m_chanpan{}; + std::array m_chanpan{}; std::array m_pitch_bend{}; u8* m_sample_data{nullptr}; diff --git a/game/sound/989snd/musicbank.h b/game/sound/989snd/musicbank.h index b67efaf3da..e00ce8bfcf 100644 --- a/game/sound/989snd/musicbank.h +++ b/game/sound/989snd/musicbank.h @@ -57,6 +57,11 @@ struct MIDISound { /* 18 */ /*void**/ u32 MIDIBlock; }; +// Annoyingly enough we need some data out of this struct +struct MIDISoundHandler { + u32 OwnerID; +}; + struct Prog; class MusicBank : public SoundBank { public: