You are here

Add new comment

I made a little patch, so that qtractor now happily obeys volume/pan controllers from my midi controller. I'm not sure this is "the right way" to do it. It is channel based, meaning that for every volume change received the program tries to find midi tracks corresponding to that channel. This may be a bit awkward, but I don't know how to do it otherwise. Also, qtractorTrackGainCommand with its redo/undo system is omitted; volume and pan is set directly through track->setPanning() and setVolume(). I did this because the first implementation had some feedback issues, events not coming back soon enough; there is a lot of happening if you push many faders at once :) I also had some crashes in appendMessages(), so I commented that out temporarily. Need to investigate that some more.

Below is what I added to void qtractorMainForm::midiControlEvent ( qtractorMidiControlEvent *pCtlEvent )

Bye, Marko

    // handle volume controls
    if (pCtlEvent->controller() == 7) {
        for (int i = 0; i < m_pSession->tracks().count(); i++)  {
            qtractorTrack* pTrack = m_pSession->tracks().at(i);
            if (pTrack && (pTrack->trackType() == qtractorTrack::Midi) &&
                    pTrack->midiChannel() == pCtlEvent->channel()) {
                float fGain  = float(pCtlEvent->value()) / 127.0f;
                // Set track gain directly bypassing undo/redo system
                // to avoid feedback issues with motorized external
                // controllers
                pTrack->setGain(fGain);
                qtractorMidiBus *pMidiBus
                    = static_cast (pTrack->outputBus());
                if (pMidiBus)
                    pMidiBus->setVolume(pTrack, fGain);
                qtractorMixer *pMixer = mixer();
                if (pMixer) {
                    qtractorMixerStrip *pStrip  
                        = pMixer->trackRack()->findStrip(pTrack->monitor());
                    if (pStrip && pStrip->meter())
                        pStrip->meter()->updateGain();
                }
                sCtlText += tr("(track %1, gain %2)").arg(i).arg(fGain);
            }
        }
    }

    // handle pan controls
    if (pCtlEvent->controller() == 10)
    {
        for (int i = 0; i < m_pSession->tracks().count(); i++) {
            qtractorTrack* pTrack = m_pSession->tracks().at(i);
            if (pTrack && (pTrack->trackType() == qtractorTrack::Midi) &&
                    pTrack->midiChannel() == pCtlEvent->channel()) {
                float fPanning  = (float(pCtlEvent->value()) - 63.0f) / 64.0f;
                pTrack->setPanning(fPanning);
                qtractorMidiBus *pMidiBus
                    = static_cast (pTrack->outputBus());
                if (pMidiBus)
                    pMidiBus->setPanning(pTrack, fPanning);
                qtractorMixer *pMixer = mixer();
                if (pMixer) {
                    qtractorMixerStrip *pStrip
                        = pMixer->trackRack()->findStrip(pTrack->monitor());
                    if (pStrip && pStrip->meter())
                        pStrip->meter()->updatePanning();
                }
                sCtlText += tr("(track %1, panning %2)").arg(i).arg(fPanning);
            }
        }
    }