Пример #1
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 "";
}
Пример #2
0
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;
}
Пример #3
0
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);
}