#include "MIDIReader.hpp" #include "MainWindow.hpp" #include MIDIReader::MIDIReader(amuse::Engine& engine, bool useLock) : amuse::BooBackendMIDIReader(engine, useLock) {} void MIDIReader::noteOff(uint8_t chan, uint8_t key, uint8_t velocity) { if (g_MainWindow->m_interactiveSeq) { g_MainWindow->m_interactiveSeq->keyOff(chan, key, velocity); return; } auto keySearch = m_chanVoxs.find(key); if (keySearch == m_chanVoxs.cend()) return; if ((m_lastVoice && m_lastVoice->isDestroyed()) || keySearch->second == m_lastVoice) m_lastVoice.reset(); keySearch->second->keyOff(); m_keyoffVoxs.emplace(std::move(keySearch->second)); m_chanVoxs.erase(keySearch); } void MIDIReader::noteOn(uint8_t chan, uint8_t key, uint8_t velocity) { if (g_MainWindow->m_interactiveSeq) { g_MainWindow->m_interactiveSeq->keyOn(chan, key, velocity); return; } if (m_lastVoice && m_lastVoice->isDestroyed()) m_lastVoice.reset(); /* If portamento is enabled for voice, pre-empt spawning new voices */ if (amuse::ObjToken lastVoice = m_lastVoice) { uint8_t lastNote = lastVoice->getLastNote(); if (lastVoice->doPortamento(key)) { m_chanVoxs.erase(lastNote); m_chanVoxs[key] = lastVoice; return; } } /* Ensure keyoff sent first */ auto keySearch = m_chanVoxs.find(key); if (keySearch != m_chanVoxs.cend()) { if (keySearch->second == m_lastVoice) m_lastVoice.reset(); keySearch->second->keyOff(); keySearch->second->setPedal(false); m_keyoffVoxs.emplace(std::move(keySearch->second)); m_chanVoxs.erase(keySearch); } amuse::ObjToken newVox = g_MainWindow->startEditorVoice(key, velocity); if (newVox) { m_chanVoxs[key] = newVox; m_lastVoice = newVox; } } void MIDIReader::notePressure(uint8_t /*chan*/, uint8_t /*key*/, uint8_t /*pressure*/) {} void MIDIReader::controlChange(uint8_t chan, uint8_t control, uint8_t value) { if (g_MainWindow->m_interactiveSeq) { g_MainWindow->m_interactiveSeq->setCtrlValue(chan, control, value); return; } if (control == 1) { g_MainWindow->m_ui.modulationSlider->setValue(int(value)); } else if (control == 64) { g_MainWindow->setSustain(value >= 0x40); } else { for (auto& v : m_engine.getActiveVoices()) v->setCtrlValue(control, value); } g_MainWindow->m_ctrlVals[control] = value; } void MIDIReader::programChange(uint8_t chan, uint8_t program) { if (g_MainWindow->m_interactiveSeq) g_MainWindow->m_interactiveSeq->setChanProgram(chan, program); } void MIDIReader::channelPressure(uint8_t /*chan*/, uint8_t /*pressure*/) {} void MIDIReader::pitchBend(uint8_t chan, int16_t pitch) { float pWheel = (pitch - 0x2000) / float(0x2000); if (g_MainWindow->m_interactiveSeq) g_MainWindow->m_interactiveSeq->setPitchWheel(chan, pWheel); else g_MainWindow->m_ui.pitchSlider->setValue(int(pWheel * 2048.f)); } void MIDIReader::allSoundOff(uint8_t chan) { if (g_MainWindow->m_interactiveSeq) { g_MainWindow->m_interactiveSeq->kill(); return; } for (auto& v : m_engine.getActiveVoices()) v->kill(); } void MIDIReader::resetAllControllers(uint8_t /*chan*/) {} void MIDIReader::localControl(uint8_t /*chan*/, bool /*on*/) {} void MIDIReader::allNotesOff(uint8_t chan) { if (g_MainWindow->m_interactiveSeq) { g_MainWindow->m_interactiveSeq->kill(); return; } for (auto& v : m_engine.getActiveVoices()) v->kill(); } void MIDIReader::omniMode(uint8_t /*chan*/, bool /*on*/) {} void MIDIReader::polyMode(uint8_t /*chan*/, bool /*on*/) {} void MIDIReader::sysex(const void* /*data*/, size_t /*len*/) {} void MIDIReader::timeCodeQuarterFrame(uint8_t /*message*/, uint8_t /*value*/) {} void MIDIReader::songPositionPointer(uint16_t /*pointer*/) {} void MIDIReader::songSelect(uint8_t /*song*/) {} void MIDIReader::tuneRequest() {} void MIDIReader::startSeq() {} void MIDIReader::continueSeq() {} void MIDIReader::stopSeq() {} void MIDIReader::reset() {} VoiceAllocator::VoiceAllocator(boo::IAudioVoiceEngine& booEngine) : amuse::BooBackendVoiceAllocator(booEngine) {} std::unique_ptr VoiceAllocator::allocateMIDIReader(amuse::Engine& engine) { return std::make_unique(engine, m_booEngine.useMIDILock()); }