void
ControlEditorDialog::slotEdit(QTreeWidgetItem *i, int)
{
    RG_DEBUG << "ControlEditorDialog::slotEdit" << endl;

    ControlParameterItem *item =
        dynamic_cast<ControlParameterItem*>(i);

    MidiDevice *md =
        dynamic_cast<MidiDevice *>(m_studio->getDevice(m_device));

    if (item && md) {
        ControlParameterEditDialog dialog
        (this,
         md->getControlParameter(item->getId()), m_doc);

        if (dialog.exec() == QDialog::Accepted) {
            ModifyControlParameterCommand *command =
                new ModifyControlParameterCommand(m_studio,
                                                  m_device,
                                                  dialog.getControl(),
                                                  item->getId());

            addCommandToHistory(command);
        }
    }
}
Example #2
0
// Run through the Devices checking for MidiDevices and
// returning the first Metronome we come across
//
const MidiMetronome*
Studio::getMetronomeFromDevice(DeviceId id)
{
    std::vector<Device*>::iterator it;

    for (it = m_devices.begin(); it != m_devices.end(); ++it) {

        std::cerr << "Studio::getMetronomeFromDevice: Having a look at device " << (*it)->getId() << std::endl;

        MidiDevice *midiDevice = dynamic_cast<MidiDevice*>(*it);
        if (midiDevice &&
                midiDevice->getId() == id &&
                midiDevice->getMetronome()) {
            std::cerr << "Studio::getMetronomeFromDevice(" << id << "): device is a MIDI device" << std::endl;
            return midiDevice->getMetronome();
        }

        SoftSynthDevice *ssDevice = dynamic_cast<SoftSynthDevice *>(*it);
        if (ssDevice &&
                ssDevice->getId() == id &&
                ssDevice->getMetronome()) {
            std::cerr << "Studio::getMetronomeFromDevice(" << id << "): device is a soft synth device" << std::endl;
            return ssDevice->getMetronome();
        }
    }

    return 0;
}
Example #3
0
std::string
Studio::getSegmentName(InstrumentId id)
{
    MidiDevice *midiDevice;
    std::vector<Device*>::iterator it;
    Rosegarden::InstrumentList::iterator iit;
    Rosegarden::InstrumentList instList;

    for (it = m_devices.begin(); it != m_devices.end(); ++it)
    {
        midiDevice = dynamic_cast<MidiDevice*>(*it);

        if (midiDevice)
        {
            instList = (*it)->getAllInstruments();

            for (iit = instList.begin(); iit != instList.end(); ++iit)
            {
                if ((*iit)->getId() == id)
                {
                    if ((*iit)->sendsProgramChange())
                    {
                        return (*iit)->getProgramName();
                    }
                    else
                    {
                        return midiDevice->getName() + " " + (*iit)->getName();
                    }
                }
            }
        }
    }

    return std::string("");
}
Example #4
0
// From a user selection (from a "Presentation" list) return
// the matching Instrument
//
Instrument*
Studio::getInstrumentFromList(int index)
{
    std::vector<Device*>::iterator it;
    InstrumentList list;
    InstrumentList::iterator iit;
    int count = 0;

    for (it = m_devices.begin(); it != m_devices.end(); ++it)
    {
        MidiDevice *midiDevice = dynamic_cast<MidiDevice*>(*it);

        if (midiDevice)
        {
            // skip read-only devices
            if (midiDevice->getDirection() == MidiDevice::Record)
                continue;
        }

        list = (*it)->getPresentationInstruments();

        for (iit = list.begin(); iit != list.end(); ++iit)
        {
            if (count == index)
                return (*iit);

            count++;
        }
    }

    return 0;

}
void
MIDIInstrumentParameterPanel::slotSelectProgram(int index)
{
    RG_DEBUG << "slotSelectProgram()";

    if (!getSelectedInstrument())
        return;

    MidiDevice *md =
            dynamic_cast<MidiDevice *>(getSelectedInstrument()->getDevice());
    if (!md)
        return;

    const MidiProgram *prg = &m_programs[index];

    // If there has been no change, bail.
    if (getSelectedInstrument()->getProgramChange() == prg->getProgram())
        return;

    getSelectedInstrument()->setProgramChange(prg->getProgram());

    // In Variations mode, select the 0th variation.

    // In Variations mode, it's very easy to select an "invalid"
    // program change.  I.e. one for which the bank is not valid.  Go
    // from one program/variation to a program that doesn't have that
    // variation.  We need to handle that here by selecting the 0th
    // variation.  That's what the user expects.

    if (md->getVariationType() == MidiDevice::VariationFromMSB) {
        MidiBank bank = getSelectedInstrument()->getProgram().getBank();
        // Get the list of MSB variations.
        BankList bankList = md->getBanksByLSB(
                getSelectedInstrument()->isPercussion(), bank.getLSB());
        if (!bankList.empty()) {
            // Pick the first MSB variation
            getSelectedInstrument()->setMSB(bankList.front().getMSB());
        }
    }
    if (md->getVariationType() == MidiDevice::VariationFromLSB) {
        MidiBank bank = getSelectedInstrument()->getProgram().getBank();
        // Get the list of LSB variations.
        BankList bankList = md->getBanksByMSB(
                getSelectedInstrument()->isPercussion(), bank.getMSB());
        if (!bankList.empty()) {
            // Pick the first LSB variation
            getSelectedInstrument()->setLSB(bankList.front().getLSB());
        }
    }

    getSelectedInstrument()->sendChannelSetup();

    // Just one change notification for the two potential changes.
    // See comments in slotSelectBank() for further discussion.
    getSelectedInstrument()->changed();
}
Example #6
0
void
ModifyDeviceCommand::unexecute()
{
    Device *device = m_studio->getDevice(m_device);
    if (!device) {
        std::cerr << "ERROR: ModifyDeviceCommand::unexecute(): no such device as " << m_device << std::endl;
        return;
    }

    MidiDevice *midiDevice = dynamic_cast<MidiDevice *>(device);
    if (!midiDevice) {
        std::cerr << "ERROR: ModifyDeviceCommand::unexecute(): device " << m_device << " is not a MIDI device" << std::endl;
        return;
    }

    if (m_rename)
        midiDevice->setName(m_oldName);
    midiDevice->replaceBankList(m_oldBankList);
    midiDevice->replaceProgramList(m_oldProgramList);
    midiDevice->replaceControlParameters(m_oldControlList);
    midiDevice->replaceKeyMappingList(m_oldKeyMappingList);
    midiDevice->setLibrarian(m_oldLibrarianName, m_oldLibrarianEmail);
    if (m_changeVariation)
        midiDevice->setVariationType(m_oldVariationType);

    InstrumentList instruments = midiDevice->getAllInstruments();
    for (size_t i = 0; i < instruments.size(); ++i) {
        instruments[i]->setProgram(m_oldInstrumentPrograms[i]);
    }

    // ??? Instead of this kludge, we should be calling a Studio::hasChanged()
    //     which would then notify all observers (e.g. MIPP) who, in turn,
    //     would update themselves.
    RosegardenMainWindow::self()->uiUpdateKludge();
}
Example #7
0
MidiDevice::MidiDevice(const MidiDevice &dev) :
    Device(dev.getId(), dev.getName(), dev.getType()),
    Controllable(),
    m_programList(dev.m_programList),
    m_bankList(dev.m_bankList),
    m_controlList(dev.m_controlList),
    m_keyMappingList(dev.m_keyMappingList),
    m_metronome(0),
    m_direction(dev.getDirection()),
    m_variationType(dev.getVariationType()),
    m_librarian(dev.getLibrarian()),
    m_allocator(new AllocateChannels(ChannelSetup::MIDI))
{
    // Create and assign a metronome if required
    //
    if (dev.getMetronome())
    {
        m_metronome = new MidiMetronome(*dev.getMetronome());
    }

    // Copy the instruments
    //
    InstrumentList insList = dev.getAllInstruments();
    InstrumentList::iterator iIt = insList.begin();
    for (; iIt != insList.end(); ++iIt)
    {
        Instrument *newInst = new Instrument(**iIt);
        newInst->setDevice(this);
        m_instruments.push_back(newInst);
    }

    // generate presentation instruments
    generatePresentationList();
}
Example #8
0
bool
ImportDeviceDialog::importFromSF2(QString filename)
{
    SF2PatchExtractor::Device sf2device;
    try {
        sf2device = SF2PatchExtractor::read( qstrtostr(filename) );

        // These exceptions shouldn't happen -- the isSF2File call before this
        // one should have weeded them out
    } catch (SF2PatchExtractor::FileNotFoundException e) {
        return false;
    } catch (SF2PatchExtractor::WrongFileFormatException e) {
        return false;
    }

    std::vector<MidiBank> banks;
    std::vector<MidiProgram> programs;

    for (SF2PatchExtractor::Device::const_iterator i = sf2device.begin();
            i != sf2device.end(); ++i) {

        int bankNumber = i->first;
        const SF2PatchExtractor::Bank &sf2bank = i->second;

        int msb = bankNumber / 128;
        int lsb = bankNumber % 128;

        MidiBank bank
        (msb == 1, msb, lsb,
         qstrtostr(tr("Bank %1:%2").arg(msb).arg(lsb)));

        banks.push_back(bank);

        for (SF2PatchExtractor::Bank::const_iterator j = sf2bank.begin();
                j != sf2bank.end(); ++j) {

            MidiProgram program(bank, j->first, j->second);
            programs.push_back(program);
        }
    }

    // This is a temporary device, so we can use device and instrument
    // IDs that other devices in the Studio may also be using without
    // expecting any problems
    MidiDevice *device = new MidiDevice
        (0, MidiInstrumentBase, "", MidiDevice::Play);
    device->replaceBankList(banks);
    device->replaceProgramList(programs);
    m_devices.push_back(device);

    return true;
}
const MidiMetronome *
ManageMetronomeDialog::getMetronome(Device *dev)
{
    MidiDevice *md = dynamic_cast<MidiDevice *>(dev);
    if (md) {
        return md->getMetronome();
    }
    SoftSynthDevice *ssd = dynamic_cast<SoftSynthDevice *>(dev);
    if (ssd) {
        return ssd->getMetronome();
    }
    return 0;
}
void
ManageMetronomeDialog::setMetronome(Device *dev, const MidiMetronome &metronome)
{
    MidiDevice *md = dynamic_cast<MidiDevice *>(dev);
    if (md) {
        md->setMetronome(metronome);
        return;
    }
    SoftSynthDevice *ssd = dynamic_cast<SoftSynthDevice *>(dev);
    if (ssd) {
        ssd->setMetronome(metronome);
        return;
    }
}
void
AddControlParameterCommand::unexecute()
{
    MidiDevice *md = dynamic_cast<MidiDevice *>
                     (m_studio->getDevice(m_device));
    if (!md) {
        std::cerr << "WARNING: AddControlParameterCommand::unexecute: device "
        << m_device << " is not a MidiDevice in current studio"
        << std::endl;
        return ;
    }

    md->removeControlParameter(m_id);
}
Example #12
0
bool
ImportDeviceDialog::importFromRG(QString fileName)
{
    bool skipAutoload = true, clearCommandHistory = false;
    RosegardenDocument fileDoc(RosegardenMainWindow::self(), 0, 
                               skipAutoload, clearCommandHistory);

    if (!fileDoc.openDocument(fileName, false)) {
        return false;
    }

    for (int i = 0; i < (int)m_devices.size(); ++i) delete m_devices[i];
    m_devices.clear();

    DeviceList *list = fileDoc.getStudio().getDevices();
    if (list->size() == 0) {
        return true; // true because we successfully read the document
    }

    for (DeviceListIterator it = list->begin(); it != list->end(); ++it) {

        MidiDevice *device = dynamic_cast<MidiDevice*>(*it);

        if (device) {
            std::vector<MidiBank> banks = device->getBanks();

            // DMM - check for controllers too, because some users have
            // created .rgd files that contain only controllers
            // see bug #1183522
            //
            std::vector<ControlParameter> controllers =
                device->getControlParameters();

            // We've got a bank on a Device fom this file
            // (or a device that contains controllers or key mappings)
            //
            if (banks.size() ||
                controllers.size() ||
                device->getKeyMappings().size()) {
                m_devices.push_back(new MidiDevice(*device));
            }
        }
    }

    return true;
}
void
ModifyControlParameterCommand::execute()
{
    MidiDevice *md = dynamic_cast<MidiDevice *>
                     (m_studio->getDevice(m_device));
    if (!md) {
        std::cerr << "WARNING: ModifyControlParameterCommand::execute: device "
        << m_device << " is not a MidiDevice in current studio"
        << std::endl;
        return ;
    }

    ControlParameter *param = md->getControlParameter(m_id);
    if (param)
        m_originalControl = *param;
    md->modifyControlParameter(m_control, m_id);
}
Example #14
0
void
Studio::clearMidiBanksAndPrograms()
{
    MidiDevice *midiDevice;
    std::vector<Device*>::iterator it;

    for (it = m_devices.begin(); it != m_devices.end(); ++it)
    {
        midiDevice = dynamic_cast<MidiDevice*>(*it);

        if (midiDevice)
        {
            midiDevice->clearProgramList();
            midiDevice->clearBankList();
        }
    }
}
void
AddControlParameterCommand::execute()
{
    MidiDevice *md = dynamic_cast<MidiDevice *>
                     (m_studio->getDevice(m_device));
    if (!md) {
        std::cerr << "WARNING: AddControlParameterCommand::execute: device "
        << m_device << " is not a MidiDevice in current studio"
        << std::endl;
        return ;
    }

    md->addControlParameter(m_control, true);

    // store id of the new control
    m_id = int(md->getControlParameters().size()) - 1;
}
bool
ManageMetronomeDialog::isSuitable(Device *dev, bool *hasConnectionReturn)
{
    MidiDevice *md = dynamic_cast<MidiDevice *>(dev);
    if (md && md->getDirection() == MidiDevice::Play) {
        if (hasConnectionReturn) {
            QString conn = RosegardenSequencer::getInstance()->getConnection
                (md->getId());
            if (conn == "") *hasConnectionReturn = false;
            else *hasConnectionReturn = true;
        }
        return true;
    }
    if (dynamic_cast<SoftSynthDevice *>(dev)) {
        if (hasConnectionReturn) *hasConnectionReturn = true;
        return true;
    }
    return false;
}
Example #17
0
bool
ImportDeviceDialog::importFromLSCP(QString filename)
{
    LSCPPatchExtractor::Device lscpDevice;

    lscpDevice = LSCPPatchExtractor::extractContent(filename);
    std::vector<MidiBank> banks;
    std::vector<MidiProgram> programs;

    int comparableBankNumber = -1; //Make sure that first bank is read too by comparing to -1 first (invalid bank number)

    for (LSCPPatchExtractor::Device::const_iterator i = lscpDevice.begin();
    i != lscpDevice.end(); ++i) {

        int bankNumber = (*i).bankNumber; //Local variable bankNumber gets value from struct's member bankNumber

        std::string bankName = (*i).bankName; //Local variable bankName gets value from struct's member bankName
        int msb = bankNumber / 128;
        int lsb = bankNumber % 128;

        MidiBank bank (msb == 1, msb, lsb, bankName);

        if (comparableBankNumber != bankNumber) {
            banks.push_back(bank);
            comparableBankNumber = bankNumber;
        }

        MidiProgram program(bank, (*i).programNumber, (*i).programName);
        programs.push_back(program);
    }

    // This is a temporary device, so we can use device and instrument
    // IDs that other devices in the Studio may also be using without
    // expecting any problems
    MidiDevice *device = new MidiDevice
        (0, MidiInstrumentBase, "", MidiDevice::Play);
    device->replaceBankList(banks);
    device->replaceProgramList(programs);
    m_devices.push_back(device);

    return true;
}
Example #18
0
MidiDevice::MidiDevice(DeviceId id,
                       InstrumentId ibase,
                       const MidiDevice &dev) :
    Device(id, dev.getName(), Device::Midi),
    m_programList(dev.m_programList),
    m_bankList(dev.m_bankList),
    m_controlList(0),
    m_keyMappingList(dev.m_keyMappingList),
    m_metronome(0),
    m_direction(dev.getDirection()),
    m_variationType(dev.getVariationType()),
    m_librarian(dev.getLibrarian()),
    m_allocator(new AllocateChannels(ChannelSetup::MIDI))
{
    createInstruments(ibase);

    // Populate device and Instrument with Controllers.
    ControlList::const_iterator cIt = dev.m_controlList.begin();
    for(; cIt != dev.m_controlList.end(); ++cIt) {
        addControlParameter(*cIt, true);
    }
    
    
    // Create and assign a metronome if required
    //
    if (dev.getMetronome()) {
        m_metronome = new MidiMetronome(*dev.getMetronome());
    }

    generatePresentationList();
}
CreateOrDeleteDeviceCommand::CreateOrDeleteDeviceCommand(Studio *studio,
                                                         DeviceId id) :
    NamedCommand(getGlobalName(true)),
    m_studio(studio),
    m_deviceId(id),
    m_deviceCreated(true)
{
    Device *device = m_studio->getDevice(m_deviceId);

    if (device) {
        m_name = device->getName();
        m_type = device->getType();
        m_direction = MidiDevice::Play;
        MidiDevice *md = dynamic_cast<MidiDevice *>(device);
        if (md) m_direction = md->getDirection();
        m_connection = qstrtostr(RosegardenSequencer::getInstance()
                                 ->getConnection(md->getId()));
    } else {
        RG_DEBUG << "CreateOrDeleteDeviceCommand: No such device as "
                 << m_deviceId << endl;
    }
}
Example #20
0
QWidget* MenuList::createWidget(QWidget* parent)
{
	if(!_track)
		return 0;
	//if(!_track->isMidiTrack() || _track->type() != Track::AUDIO_SOFTSYNTH)
	//	return 0;
	MidiTrack* track = (MidiTrack*) _track;

	MidiDevice* md = 0;
	int port = -1;
	if (track->type() == Track::AUDIO_SOFTSYNTH)
	{
		md = dynamic_cast<MidiDevice*> (track);
		if (md)
			port = md->midiPort();
	}
	else
		port = track->outPort();
	list = new QListWidget(parent);
	list->setSelectionMode(QAbstractItemView::SingleSelection);
	list->setAlternatingRowColors(true);
	list->setEditTriggers(QAbstractItemView::NoEditTriggers);
	list->setFixedHeight(300);
	for (int i = 0; i < MIDI_PORTS; ++i)
	{
		QString name;
		name.sprintf("%d:%s", i + 1, midiPorts[i].portname().toLatin1().constData());
		list->insertItem(i, name);
		if (i == port)
			list->setCurrentRow(i);
	}
	connect(list, SIGNAL(itemPressed(QListWidgetItem*)), this, SLOT(updateData(QListWidgetItem*)));
	//connect(list, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(updateData(QListWidgetItem*)));
	//connect(list, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(updateData(QListWidgetItem*)));
	return list;
}
Example #21
0
File: midiseq.cpp Project: EQ4/muse
void MidiSeq::updatePollFd()
      {
      if (!isRunning())
            return;

      clearPollFd();
      addPollFd(timerFd, POLLIN, midiTick, this, 0);

      if (timerFd == -1) {
            fprintf(stderr, "updatePollFd: no timer fd\n");
            if (!MusEGlobal::debugMode)
                  exit(-1);
            }

      addPollFd(toThreadFdr, POLLIN, MusECore::readMsg, this, 0);

      //---------------------------------------------------
      //  midi ports
      //---------------------------------------------------

      for (iMidiDevice imd = MusEGlobal::midiDevices.begin(); imd != MusEGlobal::midiDevices.end(); ++imd) {
            MidiDevice* dev = *imd;
            int port = dev->midiPort();
            if (port == -1)
                  continue;
            if ((dev->rwFlags() & 0x2) || (MusEGlobal::extSyncFlag.value()
               && (MusEGlobal::midiPorts[port].syncInfo().MCIn())))
                  addPollFd(dev->selectRfd(), POLLIN, MusECore::midiRead, this, dev);
            if (dev->bytesToWrite())
                  addPollFd(dev->selectWfd(), POLLOUT, MusECore::midiWrite, this, dev);
            }
      // special handling for alsa midi:
      // (one fd for all devices)
      //    this allows for processing of some alsa events
      //    even if no alsa driver is active (assigned to a port)
      addPollFd(alsaSelectRfd(), POLLIN, MusECore::alsaMidiRead, this, 0);
      }
Example #22
0
void
MidiMixerWindow::slotUpdateInstrument(InstrumentId id)
{
    //RG_DEBUG << "MidiMixerWindow::slotUpdateInstrument - id = " << id << endl;

    DeviceListConstIterator it;
    MidiDevice *dev = 0;
    InstrumentList instruments;
    InstrumentList::const_iterator iIt;
    int count = 0;

    blockSignals(true);

    for (it = m_studio->begin(); it != m_studio->end(); ++it) {
        dev = dynamic_cast<MidiDevice*>(*it);

        if (dev) {
            instruments = dev->getPresentationInstruments();
            ControlList controls = getIPBForMidiMixer(dev);

            for (iIt = instruments.begin(); iIt != instruments.end(); ++iIt) {
                // Match and set
                //
                if ((*iIt)->getId() == id) {
                    // Set Volume fader
                    //
                    m_faders[count]->m_volumeFader->blockSignals(true);

                    MidiByte volumeValue;
                    try {
                        volumeValue = (*iIt)->
                                getControllerValue(MIDI_CONTROLLER_VOLUME);
                    } catch (std::string s) {
                        // This should never get called.
                        volumeValue = (*iIt)->getVolume();
                    }
                    
                    m_faders[count]->m_volumeFader->setFader(float(volumeValue));
                    m_faders[count]->m_volumeFader->blockSignals(false);

                    /*
                    StaticControllers &staticControls = 
                        (*iIt)->getStaticControllers();
                    RG_DEBUG << "STATIC CONTROLS SIZE = " 
                             << staticControls.size() << endl;
                    */

                    // Set all controllers for this Instrument
                    //
                    for (size_t i = 0; i < controls.size(); ++i) {
                        float value = 0.0;

                        m_faders[count]->m_controllerRotaries[i].second->blockSignals(true);

                        // The ControllerValues might not yet be set on
                        // the actual Instrument so don't always expect
                        // to find one.  There might be a hole here for
                        // deleted Controllers to hang around on
                        // Instruments..
                        //
                        try {
                            value = float((*iIt)->getControllerValue
                                          (controls[i].getControllerValue()));
                        } catch (std::string s) {
                            /*
                            RG_DEBUG << 
                            "MidiMixerWindow::slotUpdateInstrument - "
                                     << "can't match controller " 
                                     << int(controls[i].
                                         getControllerValue()) << " - \""
                                     << s << "\"" << endl;
                                     */
                            continue;
                        }

                        /*
                        RG_DEBUG << "MidiMixerWindow::slotUpdateInstrument"
                                 << " - MATCHED "
                                 << int(controls[i].getControllerValue())
                                 << endl;
                                 */

                        m_faders[count]->m_controllerRotaries[i].
                        second->setPosition(value);

                        m_faders[count]->m_controllerRotaries[i].second->blockSignals(false);
                    }
                }
                count++;
            }
        }
    }

    blockSignals(false);
}
void
CreateOrDeleteDeviceCommand::execute()
{
    if (!m_deviceCreated) {

        //!DEVPUSH: Not ideal; we probably just want to add it to the studio (and then trigger a re-push) rather than add it twice to studio and sequencer

        // Create

        // don't want to do this again on undo even if it fails -- only on redo
        m_deviceCreated = true;

        m_deviceId = m_studio->getSpareDeviceId(m_baseInstrumentId);

        bool success = RosegardenSequencer::getInstance()->
            addDevice(m_type, m_deviceId, m_baseInstrumentId, m_direction);

        if (!success) {
            SEQMAN_DEBUG << "CreateDeviceCommand::execute - "
                         << "sequencer addDevice failed" << endl;
            return ;
        }

        SEQMAN_DEBUG << "CreateDeviceCommand::execute - "
                     << " added device " << m_deviceId
                     << " with base instrument id " << m_baseInstrumentId
                     << endl;

        RosegardenSequencer::getInstance()->setConnection
            (m_deviceId, strtoqstr(m_connection));

        SEQMAN_DEBUG << "CreateDeviceCommand::execute - "
                     << " reconnected device " << m_deviceId
                     << " to " << m_connection << endl;

        m_studio->addDevice(m_name, m_deviceId, m_baseInstrumentId, m_type);
        Device *device = m_studio->getDevice(m_deviceId);
        if (device) {
            device->setConnection(m_connection);
            MidiDevice *md = dynamic_cast<MidiDevice *>(device);
            if (md) md->setDirection(m_direction);
        }

        /* update view automatically (without pressing refresh button) */
        DeviceManagerDialog *dmd=RosegardenMainWindow::self()->getDeviceManager();
        if (dmd!=NULL) {
          dmd->slotResyncDevicesReceived();
        }
    } else {

        // Delete

        RosegardenSequencer::getInstance()->removeDevice(m_deviceId);

        SEQMAN_DEBUG << "CreateDeviceCommand::unexecute - "
                     << " removed device " << m_deviceId << endl;

        m_studio->removeDevice(m_deviceId);

        m_deviceId = Device::NO_DEVICE;
        m_deviceCreated = false;
    }
}
SplitByRecordingSrcDialog::SplitByRecordingSrcDialog(QWidget *parent, RosegardenDocument *doc) :
        QDialog(parent)
{
    setModal(true);
    setWindowTitle(tr("Split by Recording Source"));

    QGridLayout *metagrid = new QGridLayout;
    setLayout(metagrid);
    QWidget *vBox = new QWidget(this);
    QVBoxLayout *vBoxLayout = new QVBoxLayout;
    metagrid->addWidget(vBox, 0, 0);


    QGroupBox *groupBox = new QGroupBox( tr("Recording Source"), vBox );
    groupBox->setContentsMargins(10, 10, 10, 10);
    QGridLayout *layout = new QGridLayout(groupBox);
    layout->setSpacing(5);
    vBoxLayout->addWidget(groupBox);
    vBox->setLayout(vBoxLayout);

    layout->addWidget(new QLabel( tr("Channel:"), groupBox ), 0, 0);
    m_channel = new QComboBox( groupBox );
    m_channel->setMaxVisibleItems( 17 );
    layout->addWidget(m_channel, 0, 1);
    QSpacerItem *spacer = new QSpacerItem( 1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum );
    layout->addItem( spacer, 0, 2 );

    m_channel->addItem(tr("any"));
    for (int i = 1; i < 17; ++i) {
        m_channel->addItem(QString::number(i));
    }

    layout->addWidget(new QLabel( tr("Device:"), groupBox ), 1, 0);
    m_device = new QComboBox( groupBox );
    layout->addWidget( m_device, 1, 1, 0+1, 2 - 1+1);

    m_deviceIds.clear();
    m_deviceIds.push_back( -1);
    m_device->addItem(tr("any"));

    DeviceList *devices = doc->getStudio().getDevices();
    DeviceListConstIterator it;
    for (it = devices->begin(); it != devices->end(); it++) {
        MidiDevice *dev =
            dynamic_cast<MidiDevice*>(*it);
        if (dev && dev->getDirection() == MidiDevice::Record) {
            QString label = QString::number(dev->getId());
            label += ": ";
            label += strtoqstr(dev->getName());
            QString connection = RosegardenSequencer::getInstance()->getConnection
                (dev->getId());
            label += " - ";
            if (connection == "")
                label += tr("No connection");
            else
                label += connection;
            m_device->addItem(label);
            m_deviceIds.push_back(dev->getId());
        }
    }

    m_channel->setCurrentIndex(0);
    m_device->setCurrentIndex(0);

    groupBox->setLayout(layout);

    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
    metagrid->addWidget(buttonBox, 1, 0);
    metagrid->setRowStretch(0, 10);
    connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
}
Example #25
0
void
MidiMixerWindow::setupTabs()
{
    DeviceListConstIterator it;
    MidiDevice *dev = 0;
    InstrumentList instruments;
    InstrumentList::const_iterator iIt;
    int faderCount = 0, deviceCount = 1;

    if (m_tabFrame)
        delete m_tabFrame;

    // Setup m_tabFrame
    //

    QWidget *blackWidget = new QWidget(this);
    setCentralWidget(blackWidget);
    QVBoxLayout *centralLayout = new QVBoxLayout;
    blackWidget->setLayout(centralLayout);

    m_tabWidget = new QTabWidget;
    centralLayout->addWidget(m_tabWidget);

    connect(m_tabWidget, SIGNAL(currentChanged(QWidget *)),
            this, SLOT(slotCurrentTabChanged(QWidget *)));
    m_tabWidget->setTabPosition(QTabWidget::South);
    setWindowTitle(tr("MIDI Mixer"));
    setWindowIcon(IconLoader().loadPixmap("window-midimixer"));


    for (it = m_studio->begin(); it != m_studio->end(); ++it) {
        dev = dynamic_cast<MidiDevice*>(*it);

        if (dev) {
            // Get the control parameters that are on the IPB (and hence can
            // be shown here too).
            //
            ControlList controls = getIPBForMidiMixer(dev);

            instruments = dev->getPresentationInstruments();

            // Don't add a frame for empty devices
            //
            if (!instruments.size())
                continue;

            m_tabFrame = new QFrame(m_tabWidget);
            m_tabFrame->setContentsMargins(10, 10, 10, 10);

            // m_tabFrame->setContentsMargins(5, 5, 5, 5); ???
            QGridLayout *mainLayout = new QGridLayout(m_tabFrame);

            // MIDI Mixer label
            QLabel *label = new QLabel("", m_tabFrame);
            mainLayout->addWidget(label, 0, 0, 0, 16, Qt::AlignCenter);

            // control labels
            for (size_t i = 0; i < controls.size(); ++i) {
                label = new QLabel(QObject::tr(controls[i].getName().c_str()), m_tabFrame);
                mainLayout->addWidget(label, i + 1, 0, Qt::AlignCenter);
            }

            // meter label
            // (obsolete abandoned code deleted here)

            // volume label
            label = new QLabel(tr("Volume"), m_tabFrame);
            mainLayout->addWidget(label, controls.size() + 2, 0,
                                  Qt::AlignCenter);

            // instrument label
            label = new QLabel(tr("Instrument"), m_tabFrame);
            label->setFixedWidth(80); //!!! this should come from metrics
            mainLayout->addWidget(label, controls.size() + 3, 0,
                                  Qt::AlignLeft);

            int posCount = 1;
            int firstInstrument = -1;

            for (iIt = instruments.begin(); iIt != instruments.end(); ++iIt) {

                // Add new fader struct
                //
                m_faders.push_back(new FaderStruct());

                // Store the first ID
                //
                if (firstInstrument == -1)
                    firstInstrument = (*iIt)->getId();


                // Add the controls
                //
                for (size_t i = 0; i < controls.size(); ++i) {
                    QColor knobColour = QColor(Qt::white);

                    if (controls[i].getColourIndex() > 0) {
                        Colour c =
                            m_document->getComposition().getGeneralColourMap().
                            getColourByIndex(controls[i].getColourIndex());

                        knobColour = QColor(c.getRed(),
                                            c.getGreen(), c.getBlue());
                    }

                    Rotary *controller =
                        new Rotary(m_tabFrame,
                                   controls[i].getMin(),
                                   controls[i].getMax(),
                                   1.0,
                                   5.0,
                                   controls[i].getDefault(),
                                   20,
                                   Rotary::NoTicks,
                                   false,
                                   controls[i].getDefault() == 64); //!!! hacky

                    controller->setKnobColour(knobColour);

                    connect(controller, SIGNAL(valueChanged(float)),
                            this, SLOT(slotControllerChanged(float)));

                    mainLayout->addWidget(controller, i + 1, posCount,
                                          Qt::AlignCenter);

                    // Store the rotary
                    //
                    m_faders[faderCount]->m_controllerRotaries.push_back(
                        std::pair<MidiByte, Rotary*>
                        (controls[i].getControllerValue(), controller));
                }

                // VU meter
                //
                MidiMixerVUMeter *meter =
                    new MidiMixerVUMeter(m_tabFrame,
                                         VUMeter::FixedHeightVisiblePeakHold, 6, 30);
                mainLayout->addWidget(meter, controls.size() + 1,
                                      posCount, Qt::AlignCenter);
                m_faders[faderCount]->m_vuMeter = meter;

                // Volume fader
                //
                Fader *fader =
                    new Fader(0, 127, 100, 20, 80, m_tabFrame);
                mainLayout->addWidget(fader, controls.size() + 2,
                                      posCount, Qt::AlignCenter);
                m_faders[faderCount]->m_volumeFader = fader;

                // Label
                //
                QLabel *idLabel = new QLabel(QString("%1").
                                             arg((*iIt)->getId() - firstInstrument + 1),
                                             m_tabFrame);
                idLabel->setObjectName("idLabel");

                mainLayout->addWidget(idLabel, controls.size() + 3,
                                      posCount, Qt::AlignCenter);

                // store id in struct
                m_faders[faderCount]->m_id = (*iIt)->getId();

                // Connect them up
                //
                connect(fader, SIGNAL(faderChanged(float)),
                        this, SLOT(slotFaderLevelChanged(float)));

                // Update all the faders and controllers
                //
                slotUpdateInstrument((*iIt)->getId());

                // Increment counters
                //
                posCount++;
                faderCount++;
            }

            QString name = QString("%1 (%2)")
                           .arg(QObject::tr(dev->getName().c_str()))
                           .arg(deviceCount++);

            addTab(m_tabFrame, name);
        }
    }
}
Example #26
0
File: conf.cpp Project: Adamiko/los
static void readConfigMidiPort(Xml& xml)/*{{{*/
{
    int idx = 0;
    qint64 id = -1;
    QString device;
    bool isGlobal = false;

    QString instrument("GM");

    QList<PatchSequence*> patchSequences;
    QList<QPair<int, QString> > presets;

    int openFlags = 1;
    int dic = 0;
    int doc = 0;
    int type = MidiDevice::ALSA_MIDI;
    bool cachenrpn = false;

    MidiDevice* dev = 0;

    for (;;)
    {
        Xml::Token token = xml.parse();
        if (token == Xml::Error || token == Xml::End)
            break;
        QString tag = xml.s1();
        switch (token)
        {
            case Xml::TagStart:
                if (tag == "name")
                {
                    device = xml.parse1();
                    if (!dev)//Look for it as an alsa or already created device
                        dev = midiDevices.find(device);
                }
                else if (tag == "type")
                {
                    type = xml.parseInt();
                }
                else if (tag == "record")
                {   // old
                    bool f = xml.parseInt();
                    if (f)
                        openFlags |= 2;
                }
                else if (tag == "openFlags")
                    openFlags = xml.parseInt();
                else if (tag == "defaultInChans")
                    dic = xml.parseInt();
                else if (tag == "defaultOutChans")
                    doc = xml.parseInt();
                else if (tag == "instrument")
                {
                    instrument = xml.parse1();
                }
                else if (tag == "channel")
                {
                    readPortChannel(xml, idx);
                }
                else if (tag == "preset" || tag == "patchSequence")
                {
                    PatchSequence* p = readMidiPortPatchSequences(xml);
                    if (p)
                        patchSequences.append(p);
                }
                else if(tag == "midiPreset")
                {
                    presets.append(readMidiPortPreset(xml));
                }
                else if(tag == "cacheNRPN")
                {
                    cachenrpn = xml.parseInt();
                }
                else
                    xml.skip(tag);
                break;
            case Xml::Attribut:
                if (tag == "idx")
                {//Check to see if this port is already used, and bump if so
                    idx = xml.s2().toInt();
                    int freePort = getFreeMidiPort();
                    if(freePort != idx)
                    {//Set a flag here so we know when loading tracks later that we are dealing with an old file or global inputs changed
                        idx = freePort;
                    }
                }
                else if(tag == "portId")
                {//New style
                    id = xml.s2().toLongLong();
                    idx = getFreeMidiPort();
                }
                else if(tag == "isGlobalInput")
                {//Find the matching input if posible and set our index to it
                    isGlobal = xml.s2().toInt();
                }
                break;
            case Xml::TagEnd:
                if (tag == "midiport")
                {
                    if(isGlobal)
                    {//Find the global input that matches
                        //
                        if(gInputListPorts.size())
                        {
                            int myport = -1;
                            for(int i = 0; i < gInputListPorts.size(); ++i)
                            {
                                myport =  gInputListPorts.at(i);

                                MidiPort* inport = &midiPorts[i];
                                if(inport && inport->device() && inport->device()->name() == device)
                                {
                                    idx = myport;
                                    break;
                                }
                            }
                        }
                    }

                    if (idx < 0 || idx >= MIDI_PORTS)
                    {
                        fprintf(stderr, "bad midi port %d (>%d)\n",
                                idx, MIDI_PORTS);
                        idx = 0;
                    }

                    if (!dev)
                    {
                        if (type == MidiDevice::JACK_MIDI)
                        {
                            dev = MidiJackDevice::createJackMidiDevice(device); // p3.3.55

                            if (debugMsg)
                                fprintf(stderr, "readConfigMidiPort: creating jack midi device %s\n", device.toLatin1().constData());
                        }
                        else
                            dev = midiDevices.find(device);
                    }

                    if (debugMsg && !dev)
                        fprintf(stderr, "readConfigMidiPort: device not found %s\n", device.toLatin1().constData());

                    MidiPort* mp = &midiPorts[idx];
                    if(id)
                        mp->setPortId(id);

                    mp->setInstrument(registerMidiInstrument(instrument));
                    mp->setDefaultInChannels(dic);
                    mp->setDefaultOutChannels(doc);

                    //Indicate the port was found in the song file, even if no device is assigned to it.
                    mp->setFoundInSongFile(true);

                    if (!patchSequences.isEmpty())
                    {
                        for (int i = 0; i < patchSequences.size(); ++i)
                        {
                            mp->appendPatchSequence(patchSequences.at(i));
                        }
                    }
                    if(!presets.isEmpty())
                    {
                        for(int i = 0; i < presets.size(); ++i)
                        {
                            QPair<int, QString> pair = presets.at(i);
                            mp->addPreset(pair.first, pair.second);
                        }
                    }

                    if (dev)
                    {
                        dev->setOpenFlags(openFlags);
                        midiSeq->msgSetMidiDevice(mp, dev);
                        dev->setCacheNRPN(cachenrpn);
                    }
                    losMidiPorts.insert(mp->id(), mp);
                    return;
                }
            default:
                break;
        }
    }
}/*}}}*/
Example #27
0
File: route.cpp Project: 87maxi/oom
void Route::read(Xml& xml)/*{{{*/
{
	QString s;
	int dtype = MidiDevice::ALSA_MIDI;
	int port = -1;
	unsigned char rtype = Route::TRACK_ROUTE;

	for (;;)
	{
		const QString& tag = xml.s1();
		Xml::Token token = xml.parse();
		switch (token)
		{
			case Xml::Error:
			case Xml::End:
				return;
			case Xml::Attribut:
#ifdef ROUTE_DEBUG
				printf("Route::read(): attribute:%s\n", tag.toLatin1().constData());
#endif
				if (tag == "type")
					rtype = xml.s2().toInt();
				else if (tag == "devtype")
				{
					dtype = xml.s2().toInt();
					rtype = Route::MIDI_DEVICE_ROUTE;
				}
				else if (tag == "name")
					s = xml.s2();
				else if(tag == "trackId")
				{
					trackId = xml.s2().toLongLong();
					rtype = Route::TRACK_ROUTE;
				}
				else if (tag == "mport") // p3.3.49
				{
					port = xml.s2().toInt();
					rtype = Route::MIDI_PORT_ROUTE;
				}
				else if(tag == "mportId")
				{
					midiPortId  = xml.s2().toLongLong();
					rtype = Route::MIDI_PORT_ROUTE;
				}
				else
					printf("Route::read(): unknown attribute:%s\n", tag.toLatin1().constData());
				break;
			case Xml::TagEnd:
#ifdef ROUTE_DEBUG
				printf("Route::read(): tag end type:%d channel:%d name:%s\n", rtype, channel, s.toLatin1().constData());
#endif
				if (rtype == MIDI_PORT_ROUTE)
				{
					if(midiPortId > 0)
					{
						//qDebug("Route::read(): MIDI_PORT_ROUTE Finding midiport from id");
						type = rtype;
						MidiPort *mp = oomMidiPorts.value(midiPortId);
						if(mp)
						{
							midiPort = mp->portno();
							//qDebug("Route::read(): Found midiport from id: %d", midiPort);
						}
					}
					else if (port >= 0 && port < MIDI_PORTS)
					{
						type = rtype;
						midiPort = port;
						MidiPort *mp = &midiPorts[midiPort];
						midiPortId = mp->id();
					}
					else
						printf("Route::read(): midi port <%d> out of range\n", port);
				}
				else if (!s.isEmpty())
				{
					if (rtype == TRACK_ROUTE)
					{
						if(trackId > 0)
						{
							track = song->findTrackById(trackId);
							type = rtype;
						}
						else
						{
							TrackList* tl = song->tracks();
							iTrack i = tl->begin();
							for (; i != tl->end(); ++i)
							{
								Track* t = *i;
								if (t->name() == s)
								{
									track = t;
									type = rtype;
									trackId = t->id();
									break;
								}
							}
							if (i == tl->end())
								printf("Route::read(): track <%s> not found\n", s.toLatin1().constData());
						}
					}
					else if (rtype == JACK_ROUTE)
					{
						void* jport = 0;
						if (audioDevice) //Fix from Robert at muse
							jport = audioDevice->findPort(s.toLatin1().constData());

						if (jport == 0)
							printf("Route::read(): jack port <%s> not found audioDevice(%p)\n", s.toLatin1().constData(), audioDevice);
						else
						{
							jackPort = jport;
							type = rtype;
						}
					}
					else if (rtype == MIDI_DEVICE_ROUTE)
					{
						iMidiDevice imd = midiDevices.begin();
						for (; imd != midiDevices.end(); ++imd)
						{
							MidiDevice* md = *imd;
							if (md->name() == s && md->deviceType() == dtype)
							{
								// We found a device, but if it is not in use by the song (port is -1), ignore it.
								// This prevents loading and propagation of bogus routes in the oom file.
								if (md->midiPort() == -1)
									break;

								device = md;
								type = rtype;
								break;
							}
						}
						if (imd == midiDevices.end())
							printf("Route::read(): midi device <%s> not found\n", s.toLatin1().constData());
					}
				}
				return;
			default:
				break;
		}
	}
}/*}}}*/
Example #28
0
void
MidiMixerWindow::slotControllerDeviceEventReceived(MappedEvent *e,
        const void *preferredCustomer)
{
    if (preferredCustomer != this)
        return ;
    RG_DEBUG << "MidiMixerWindow::slotControllerDeviceEventReceived: this one's for me" << endl;
    raise();

    // get channel number n from event
    // get nth instrument on current tab

    if (e->getType() != MappedEvent::MidiController)
        return ;
    unsigned int channel = e->getRecordedChannel();
    MidiByte controller = e->getData1();
    MidiByte value = e->getData2();

    int tabIndex = m_tabWidget->currentIndex();

    int i = 0;

    for (DeviceList::const_iterator it = m_studio->begin();
            it != m_studio->end(); ++it) {

        MidiDevice *dev =
            dynamic_cast<MidiDevice*>(*it);

        if (!dev)
            continue;
        if (i != tabIndex) {
            ++i;
            continue;
        }

        InstrumentList instruments = dev->getPresentationInstruments();

        for (InstrumentList::const_iterator iIt =
                    instruments.begin(); iIt != instruments.end(); ++iIt) {

            Instrument *instrument = *iIt;

            if (instrument->getNaturalChannel() != channel)
                continue;

            ControlList cl = dev->getIPBControlParameters();
            for (ControlList::const_iterator i = cl.begin();
                    i != cl.end(); ++i) {
                if ((*i).getControllerValue() == controller) {
                    RG_DEBUG << "Setting controller " << controller << " for instrument " << instrument->getId() << " to " << value << endl;
                    instrument->setControllerValue(controller, value);
                    break;
                }
            }

            slotUpdateInstrument(instrument->getId());
            emit instrumentParametersChanged(instrument->getId());
        }

        break;
    }
}
Example #29
0
File: conf.cpp Project: Adamiko/los
static void writeSeqConfiguration(int level, Xml& xml, bool writePortInfo)/*{{{*/
{
    xml.tag(level++, "sequencer");

    if (writePortInfo)
    {
        //
        // write information about all midi ports, their assigned
        // instruments and all managed midi controllers
        //
        for (int i = 0; i < MIDI_PORTS; ++i)
        {
            bool used = false;
            MidiPort* mport = &midiPorts[i];

            // Route check by Tim. Port can now be used for routing even if no device.
            // Also, check for other non-defaults and save port, to preserve settings even if no device.
            // Dont write the config for the global inputs list they will be auto created with each startup
            if (mport->defaultInChannels() || mport->defaultOutChannels() ||
                    (mport->instrument() && !mport->instrument()->iname().isEmpty() && mport->instrument()->iname() != "GM") /*|| !mport->syncInfo().isDefault()*/ )
            {
                used = true;
            }
            else
            {//Put the ID of this track into a list
                MidiTrackList* tl = song->midis();
                for (iMidiTrack it = tl->begin(); it != tl->end(); ++it)
                {
                    MidiTrack* t = *it;
                    if (t->outPort() == i)
                    {
                        used = true;
                        break;
                    }
                }
            }

            MidiDevice* dev = mport->device();
            if (!used && !dev)
                continue;
            bool isGlobal = gInputListPorts.contains(mport->portno());
            xml.tag(level++, "midiport portId=\"%lld\" isGlobalInput=\"%d\"", mport->id(), isGlobal);

            if (mport->defaultInChannels())
                xml.intTag(level, "defaultInChans", mport->defaultInChannels());
            if (mport->defaultOutChannels())
                xml.intTag(level, "defaultOutChans", mport->defaultOutChannels());

            if (mport->instrument() && !mport->instrument()->iname().isEmpty() &&
                    (mport->instrument()->iname() != "GM")) // FIXME: TODO: Make this user configurable.
            {
                xml.strTag(level, "instrument", mport->instrument()->iname());
            }

            if (dev)
            {
                xml.strTag(level, "name", dev->name());
                xml.intTag(level, "cacheNRPN", (int)dev->cacheNRPN());

                if (dev->deviceType() != MidiDevice::ALSA_MIDI)
                    xml.intTag(level, "type", dev->deviceType());

                xml.intTag(level, "openFlags", dev->openFlags());
            }
            // write out registered controller for all channels
            MidiCtrlValListList* vll = mport->controller();
            for (int k = 0; k < MIDI_CHANNELS; ++k)
            {
                int min = k << 24;
                int max = min + 0x100000;
                xml.tag(level++, "channel idx=\"%d\"", k);
                iMidiCtrlValList s = vll->lower_bound(min);
                iMidiCtrlValList e = vll->lower_bound(max);
                if (s != e)
                {
                    for (iMidiCtrlValList i = s; i != e; ++i)
                    {
                        if(i->second->num() != 262145)
                        {
                            xml.tag(level++, "controller id=\"%d\"", i->second->num());
                            if (i->second->hwVal() != CTRL_VAL_UNKNOWN)
                                xml.intTag(level, "val", i->second->hwVal());
                            xml.etag(--level, "controller");
                        }
                    }
                }
                xml.etag(--level, "channel");
            }
            QList<PatchSequence*> *patchSequences = mport->patchSequences();
            if (patchSequences && !patchSequences->isEmpty())
            {
                for (int p = 0; p < patchSequences->size(); ++p)
                {
                    PatchSequence* ps = patchSequences->at(p);
                    QString pm = ps->name.replace('\n', " ");
                    xml.put(level, "<patchSequence id=\"%d\" name=\"%s\" checked=\"%d\" />", ps->id, pm.toLatin1().constData(), ps->selected);
                }
            }
            if(!mport->presets()->isEmpty())
            {
                QHashIterator<int, QString> iter(*mport->presets());
                while(iter.hasNext())
                {
                    iter.next();
                    xml.put(level, "<midiPreset id=\"%d\" sysex=\"%s\"/>", iter.key(), iter.value().toLatin1().constData());
                }
            }
            xml.etag(--level, "midiport");
        }
    }
    xml.tag(--level, "/sequencer");
}/*}}}*/
Example #30
0
void
MidiMixerWindow::sendControllerRefresh()
{
    //!!! need to know if we have a current external controller device,
    // as this is expensive

    int tabIndex = m_tabWidget->currentIndex();
    RG_DEBUG << "MidiMixerWindow::slotCurrentTabChanged: current is " << tabIndex << endl;

    if (tabIndex < 0)
        return ;

    int i = 0;

    for (DeviceList::const_iterator dit = m_studio->begin();
            dit != m_studio->end(); ++dit) {

        MidiDevice *dev = dynamic_cast<MidiDevice*>(*dit);
        RG_DEBUG << "device is " << (*dit)->getId() << ", dev " << dev << endl;

        if (!dev)
            continue;
        if (i != tabIndex) {
            ++i;
            continue;
        }

        InstrumentList instruments = dev->getPresentationInstruments();
        ControlList controls = getIPBForMidiMixer(dev);

        RG_DEBUG << "device has " << instruments.size() << " presentation instruments, " << dev->getAllInstruments().size() << " instruments " << endl;

        for (InstrumentList::const_iterator iIt =
                    instruments.begin(); iIt != instruments.end(); ++iIt) {

            Instrument *instrument = *iIt;
            if (!instrument->hasFixedChannel()) { continue; }
            int channel = instrument->getNaturalChannel();

            RG_DEBUG << "instrument is " << instrument->getId() << endl;

            for (ControlList::const_iterator cIt =
                        controls.begin(); cIt != controls.end(); ++cIt) {

                int controller = (*cIt).getControllerValue();
                int value;
                try {
                    value = instrument->getControllerValue(controller);
                } catch (std::string s) {
                    std::cerr << "Exception in MidiMixerWindow::currentChanged: " << s << " (controller " << controller << ", instrument " << instrument->getId() << ")" << std::endl;
                    value = 0;
                }

                MappedEvent mE(instrument->getId(),
                               MappedEvent::MidiController,
                               controller, value);
                mE.setRecordedChannel(channel);
                mE.setRecordedDevice(Device::CONTROL_DEVICE);
                StudioControl::sendMappedEvent(mE);
            }

            MappedEvent mE(instrument->getId(),
                           MappedEvent::MidiController,
                           MIDI_CONTROLLER_VOLUME,
                           instrument->getVolume());
            mE.setRecordedChannel(channel);
            mE.setRecordedDevice(Device::CONTROL_DEVICE);
            RG_DEBUG << "sending controller mapped event for channel " << channel << ", volume " << instrument->getVolume() << endl;
            StudioControl::sendMappedEvent(mE);
        }

        break;
    }
}