const MidiBank * MidiDevice::getBankByName(const std::string &name) const { for (BankList::const_iterator i = m_bankList.begin(); i != m_bankList.end(); ++i) { if (i->getName() == name) return &(*i); } return 0; }
std::string MidiDevice::getBankName(const MidiBank &bank) const { for (BankList::const_iterator it = m_bankList.begin(); it != m_bankList.end(); ++it) { if (*it == bank) return it->getName(); } return ""; }
BankList MidiDevice::getBanks(bool percussion) const { BankList banks; for (BankList::const_iterator it = m_bankList.begin(); it != m_bankList.end(); ++it) { if (it->isPercussion() == percussion) banks.push_back(*it); } return banks; }
BankList MidiDevice::getBanksByLSB(bool percussion, MidiByte lsb) const { BankList banks; for (BankList::const_iterator it = m_bankList.begin(); it != m_bankList.end(); ++it) { if (it->isPercussion() == percussion && it->getLSB() == lsb) banks.push_back(*it); } return banks; }
MidiByteList MidiDevice::getDistinctLSBs(bool percussion, int msb) const { std::set<MidiByte> lsbs; for (BankList::const_iterator it = m_bankList.begin(); it != m_bankList.end(); ++it) { if (it->isPercussion() == percussion && (msb == -1 || it->getMSB() == msb)) lsbs.insert(it->getLSB()); } MidiByteList v; for (std::set<MidiByte>::iterator i = lsbs.begin(); i != lsbs.end(); ++i) { v.push_back(*i); } return v; }
std::string MidiDevice::toXmlString() const { std::stringstream midiDevice; midiDevice << " <device id=\"" << m_id << "\" name=\"" << m_name << "\" direction=\"" << (m_direction == Play ? "play" : "record") << "\" variation=\"" << (m_variationType == VariationFromLSB ? "LSB" : m_variationType == VariationFromMSB ? "MSB" : "") << "\" connection=\"" << encode(m_connection) << "\" type=\"midi\">" << std::endl << std::endl; midiDevice << " <librarian name=\"" << encode(m_librarian.first) << "\" email=\"" << encode(m_librarian.second) << "\"/>" << std::endl; if (m_metronome) { // Write out the metronome - watch the MidiBytes // when using the stringstream // midiDevice << " <metronome " << "instrument=\"" << m_metronome->getInstrument() << "\" " << "barpitch=\"" << (int)m_metronome->getBarPitch() << "\" " << "beatpitch=\"" << (int)m_metronome->getBeatPitch() << "\" " << "subbeatpitch=\"" << (int)m_metronome->getSubBeatPitch() << "\" " << "depth=\"" << (int)m_metronome->getDepth() << "\" " << "barvelocity=\"" << (int)m_metronome->getBarVelocity() << "\" " << "beatvelocity=\"" << (int)m_metronome->getBeatVelocity() << "\" " << "subbeatvelocity=\"" << (int)m_metronome->getSubBeatVelocity() << "\"/>" << std::endl << std::endl; } // and now bank information // BankList::const_iterator it; InstrumentList::const_iterator iit; ProgramList::const_iterator pt; for (it = m_bankList.begin(); it != m_bankList.end(); ++it) { midiDevice << " <bank " << "name=\"" << encode(it->getName()) << "\" " << "percussion=\"" << (it->isPercussion() ? "true" : "false") << "\" " << "msb=\"" << (int)it->getMSB() << "\" " << "lsb=\"" << (int)it->getLSB() << "\">" << std::endl; // Not terribly efficient // for (pt = m_programList.begin(); pt != m_programList.end(); ++pt) { if (pt->getBank().partialCompare(*it)) { midiDevice << " <program " << "id=\"" << (int)pt->getProgram() << "\" " << "name=\"" << encode(pt->getName()) << "\" "; if (!pt->getKeyMapping().empty()) { midiDevice << "keymapping=\"" << encode(pt->getKeyMapping()) << "\" "; } midiDevice << "/>" << std::endl; } } midiDevice << " </bank>" << std::endl << std::endl; } // Now controllers (before Instruments, which can depend on // Controller colours) // midiDevice << " <controls>" << std::endl; ControlList::const_iterator cIt; for (cIt = m_controlList.begin(); cIt != m_controlList.end() ; ++cIt) midiDevice << cIt->toXmlString(); midiDevice << " </controls>" << std::endl << std::endl; // Add instruments // for (iit = m_instruments.begin(); iit != m_instruments.end(); ++iit) midiDevice << (*iit)->toXmlString(); KeyMappingList::const_iterator kit; for (kit = m_keyMappingList.begin(); kit != m_keyMappingList.end(); ++kit) { midiDevice << " <keymapping " << "name=\"" << encode(kit->getName()) << "\">\n"; for (MidiKeyMapping::KeyNameMap::const_iterator nmi = kit->getMap().begin(); nmi != kit->getMap().end(); ++nmi) { midiDevice << " <key number=\"" << (int)nmi->first << "\" name=\"" << encode(nmi->second) << "\"/>\n"; } midiDevice << " </keymapping>\n"; } midiDevice << " </device>" << std::endl; return midiDevice.str(); }
void MIDIInstrumentParameterPanel::updateBankComboBox() { RG_DEBUG << "updateBankComboBox()"; if (!getSelectedInstrument()) return; MidiDevice *md = dynamic_cast<MidiDevice *>(getSelectedInstrument()->getDevice()); if (!md) { std::cerr << "WARNING: MIDIInstrumentParameterPanel::updateBankComboBox(): No MidiDevice for Instrument " << getSelectedInstrument()->getId() << '\n'; return; } int currentBank = -1; BankList banks; RG_DEBUG << "updateBankComboBox(): Variation type is " << md->getVariationType(); if (md->getVariationType() == MidiDevice::NoVariations) { banks = md->getBanks(getSelectedInstrument()->isPercussion()); // If there are banks to display, show the bank widgets. // Why not showBank(banks.size()>1)? Because that would hide the // bank checkbox which would take away the user's ability to // enable/disable bank selects. If we do away with the checkbox // in the future, we should re-evaluate this decision. showBank(!banks.empty()); // Find the selected bank in the MIDI Device's bank list. for (unsigned int i = 0; i < banks.size(); ++i) { if (getSelectedInstrument()->getProgram().getBank().partialCompare(banks[i])) { currentBank = i; break; } } } else { // Usually in variation mode, the bank widgets will be hidden. // E.g. in GM2, the MSB for all banks is 121 with the variations // in the LSB numbered 0-9. If, however, there were another // MSB, say 122, with some variations in the LSB, this code would // display the Bank combobox to allow selection of the MSB. // If the variations are in the LSB, then the banks are in the MSB // and vice versa. bool useMSB = (md->getVariationType() == MidiDevice::VariationFromLSB); MidiByteList bytes; if (useMSB) { bytes = md->getDistinctMSBs(getSelectedInstrument()->isPercussion()); } else { bytes = md->getDistinctLSBs(getSelectedInstrument()->isPercussion()); } // If more than one bank value is found, show the bank widgets. showBank(bytes.size() > 1); // Load "banks" with the banks and figure out currentBank. if (useMSB) { for (unsigned int i = 0; i < bytes.size(); ++i) { BankList bl = md->getBanksByMSB (getSelectedInstrument()->isPercussion(), bytes[i]); RG_DEBUG << "updateBankComboBox(): Have " << bl.size() << " variations for MSB " << bytes[i]; if (bl.size() == 0) continue; if (getSelectedInstrument()->getMSB() == bytes[i]) { currentBank = banks.size(); } banks.push_back(bl[0]); } } else { for (unsigned int i = 0; i < bytes.size(); ++i) { BankList bl = md->getBanksByLSB (getSelectedInstrument()->isPercussion(), bytes[i]); RG_DEBUG << "updateBankComboBox(): Have " << bl.size() << " variations for LSB " << bytes[i]; if (bl.size() == 0) continue; if (getSelectedInstrument()->getLSB() == bytes[i]) { currentBank = banks.size(); } banks.push_back(bl[0]); } } } // Populate the combobox with bank names. // If we need to repopulate m_bankComboBox if (banks != m_banks) { // Update the cache. m_banks = banks; // Copy from m_banks to m_bankComboBox. m_bankComboBox->clear(); for (BankList::const_iterator i = m_banks.begin(); i != m_banks.end(); ++i) { m_bankComboBox->addItem(QObject::tr(i->getName().c_str())); } } m_bankComboBox->setEnabled(getSelectedInstrument()->sendsBankSelect()); #if 0 // ??? This is a pretty nifty idea, but unfortunately, it requires // that we maintain a bogus combobox entry. For now, we'll go // with the simpler "unselected" approach. // If the current bank was not found... if (currentBank < 0 && !banks.empty()) { // Format bank MSB:LSB and add to combobox. MidiBank bank = getSelectedInstrument()->getProgram().getBank(); QString bankString = QString("%1:%2").arg(bank.getMSB()).arg(bank.getLSB()); m_bankComboBox.addItem(bankString); currentBank = banks.size(); } #endif // If the bank wasn't in the Device, show the bank widgets so // the user can fix it if they want. if (currentBank == -1 && !banks.empty()) showBank(true); // Display the current bank. m_bankComboBox->setCurrentIndex(currentBank); }