예제 #1
0
void
MidiProgramsEditor::slotNewPercussion()
{
    RG_DEBUG << "MidiProgramsEditor::slotNewPercussion" << endl;
    bool percussion = false; // Doesn't matter
    MidiBank *newBank;
    if (banklistContains(MidiBank(percussion, m_msb->value(), m_lsb->value()))) {
        RG_DEBUG << "MidiProgramsEditor::slotNewPercussion: calling setChecked(" << !percussion << ")" << endl;
        newBank = new MidiBank(m_percussion->isChecked(),
                         m_msb->value(),
                         m_lsb->value(), getCurrentBank()->getName());
    } else {
        newBank = new MidiBank(true,
                         m_msb->value(),
                         m_lsb->value());
    }
    modifyCurrentPrograms(*getCurrentBank(), *newBank);
    *getCurrentBank() = *newBank;
    m_bankEditor->slotApply();
    
    // Hack to force the percussion icons to switch state if needed.
    // code stole from populate.
    if (m_device) {
        bool haveKeyMappings = m_device->getKeyMappings().size() > 0;

        for (unsigned int i = 0; i < (unsigned int)m_names.size(); i++) {
            getKeyMapButton(i)->setEnabled(haveKeyMappings);
        }
    }
}
예제 #2
0
bool
MidiProgramsEditor::banklistContains(const MidiBank &bank)
{
    BankList::iterator it;

    MidiBank bankNotPercussion = MidiBank(!bank.isPercussion(),
                                          bank.getMSB(), bank.getLSB());
    
    for (it = m_bankList.begin(); it != m_bankList.end(); ++it)
        if (*it == bank || *it == bankNotPercussion)
            return true;

    return false;
}
예제 #3
0
int
MidiProgramsEditor::ensureUniqueLSB(int lsb, bool ascending)
{
    bool percussion = false; // Doesn't matter
    int newLSB = lsb;
    while (banklistContains(MidiBank(percussion,
                                     m_msb->value(), newLSB))
            && newLSB < 128
            && newLSB > -1)
        if (ascending)
            newLSB++;
        else
            newLSB--;

    if (newLSB == -1 || newLSB == 128)
        throw false;

    return newLSB;
}
void
MIDIInstrumentParameterPanel::updateVariationComboBox()
{
    RG_DEBUG << "updateVariationComboBox() begin...";

    if (!getSelectedInstrument())
        return;

    MidiDevice *md =
            dynamic_cast<MidiDevice *>(getSelectedInstrument()->getDevice());
    if (!md) {
        std::cerr << "WARNING: MIDIInstrumentParameterPanel::updateVariationComboBox(): No MidiDevice for Instrument " << getSelectedInstrument()->getId() << '\n';
        return;
    }

    RG_DEBUG << "updateVariationComboBox(): Variation type is " << md->getVariationType();

    if (md->getVariationType() == MidiDevice::NoVariations) {
        showVariation(false);
        return;
    }

    // Get the variations.

    bool useMSB = (md->getVariationType() == MidiDevice::VariationFromMSB);
    MidiByteList variationBanks;

    if (useMSB) {
        MidiByte lsb = getSelectedInstrument()->getLSB();
        variationBanks = md->getDistinctMSBs(getSelectedInstrument()->isPercussion(),
                                         lsb);
        RG_DEBUG << "updateVariationComboBox(): Have " << variationBanks.size() << " variations for LSB " << lsb;

    } else {
        MidiByte msb = getSelectedInstrument()->getMSB();
        variationBanks = md->getDistinctLSBs(getSelectedInstrument()->isPercussion(),
                                         msb);

        RG_DEBUG << "updateVariationComboBox(): Have " << variationBanks.size() << " variations for MSB " << msb;
    }

    // Convert variationBanks to a ProgramList.

    ProgramList variations;

    // For each variation
    for (size_t i = 0; i < variationBanks.size(); ++i) {
        // Assemble the program for the variation.
        MidiBank bank;
        if (useMSB) {
            bank = MidiBank(getSelectedInstrument()->isPercussion(),
                            variationBanks[i],
                            getSelectedInstrument()->getLSB());
        } else {
            bank = MidiBank(getSelectedInstrument()->isPercussion(),
                            getSelectedInstrument()->getMSB(),
                            variationBanks[i]);
        }
        MidiProgram program(bank, getSelectedInstrument()->getProgramChange());

        // Skip any programs without names.
        if (md->getProgramName(program) == "")
            continue;

        variations.push_back(program);
    }

    // Compute the current variation.
    // ??? This might be combined into the previous for loop.

    int currentVariation = -1;

    // For each variation
    for (size_t i = 0; i < variations.size(); ++i) {
        if (getSelectedInstrument()->getProgram().partialCompare(variations[i])) {
            currentVariation = i;
            break;
        }
    }

    // If the variations have changed, repopulate the combobox.
    if (!partialCompareWithName(variations, m_variations)) {
        RG_DEBUG << "updateVariationComboBox(): Repopulating the combobox";

        // Update the cache.
        m_variations = variations;

        // Copy from m_variations to m_variationComboBox.
        m_variationComboBox->clear();
        for (size_t i = 0; i < m_variations.size(); ++i) {
            std::string programName = md->getProgramName(m_variations[i]);

            // Pick the correct bank number.
            MidiBank bank = m_variations[i].getBank();
            MidiByte variationBank = useMSB ? bank.getMSB() : bank.getLSB();

            m_variationComboBox->addItem(QObject::tr("%1. %2")
                                         .arg(variationBank)
                                         .arg(QObject::tr(programName.c_str())));
        }
    }

    // Display the current variation.
    m_variationComboBox->setCurrentIndex(currentVariation);

    // Show the variation widgets in either of two cases:
    //   1. More than one variation is available for this program.
    //   2. The variation was not in the Device and there is a variation
    //      to choose from.
    showVariation(m_variations.size() > 1  ||
                  (currentVariation == -1  &&  !m_variations.empty()));

    m_variationComboBox->setEnabled(getSelectedInstrument()->sendsBankSelect());
}