Exemple #1
0
void addPortCtrlEvents(Part* part, bool doClones)/*{{{*/
{
    // Traverse and process the clone chain ring until we arrive at the same part again.
    // The loop is a safety net.
    // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents,
    //  we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain.
    Part* p = part;
    //int j = doClones ? p->cevents()->arefCount() : 1;
    //if(j > 0)
    {
        //for(int i = 0; i < j; ++i)
        while (1)
        {
            // Added by Tim. p3.3.6
            //printf("addPortCtrlEvents i:%d %s %p events %p refs:%d arefs:%d\n", i, p->name().toLatin1().constData(), p, part->cevents(), part->cevents()->refCount(), j);

            MidiTrack* t = p->track();
            if (t)
            {
                MidiTrack* mt = (MidiTrack*) t;
                int port = mt->outPort();
                const EventList* el = p->cevents();
                unsigned len = p->lenTick();
                for (ciEvent ie = el->begin(); ie != el->end(); ++ie)
                {
                    const Event& ev = ie->second;
                    // Added by T356. Do not add events which are past the end of the part.
                    if (ev.tick() >= len)
                        break;

                    if (ev.type() == Controller)
                    {
                        int ch = mt->outChannel();
                        int tck = ev.tick() + p->tick();
                        int cntrl = ev.dataA();
                        int val = ev.dataB();
                        MidiPort* mp = &midiPorts[port];

                        mp->setControllerVal(ch, tck, cntrl, val, p);
                    }
                }
            }
            if (!doClones)
                break;
            // Get the next clone in the chain ring.
            p = p->nextClone();
            // Same as original part? Finished.
            if (p == part)
                break;
        }
    }
}/*}}}*/
Exemple #2
0
void removePortCtrlEvents(Part* part, bool doClones)/*{{{*/
{
    // Traverse and process the clone chain ring until we arrive at the same part again.
    // The loop is a safety net.
    // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents,
    //  we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain.
    Part* p = part;
    //int j = doClones ? p->cevents()->arefCount() : 1;
    //if(j > 0)
    {
        //for(int i = 0; i < j; ++i)
        while (1)
        {
            MidiTrack* t = p->track();
            if (t)
            {
                MidiTrack* mt = (MidiTrack*) t;
                int port = mt->outPort();
                const EventList* el = p->cevents();
                //unsigned len = p->lenTick();
                for (ciEvent ie = el->begin(); ie != el->end(); ++ie)
                {
                    const Event& ev = ie->second;
                    // Added by T356. Do not remove events which are past the end of the part.
                    // No, actually, do remove ALL of them belonging to the part.
                    // Just in case there are stray values left after the part end.
                    //if(ev.tick() >= len)
                    //  break;

                    if (ev.type() == Controller)
                    {
                        int ch = mt->outChannel();
                        int tck = ev.tick() + p->tick();
                        int cntrl = ev.dataA();
                        MidiPort* mp = &midiPorts[port];

                        mp->deleteController(ch, tck, cntrl, p);
                    }
                }
            }

            if (!doClones)
                break;
            // Get the next clone in the chain ring.
            p = p->nextClone();
            // Same as original part? Finished.
            if (p == part)
                break;
        }
    }
}/*}}}*/
Exemple #3
0
void chainTrackParts(MidiTrack* t, bool incRefCount)/*{{{*/
{
    PartList* pl = t->parts();
    for (iPart ip = pl->begin(); ip != pl->end(); ++ip)
    {
        Part* p = ip->second;
        chainCheckErr(p);

        // Do we want to increase the reference count?
        if (incRefCount)
            p->events()->incARef(1);

        // Added by Tim. p3.3.6
        //printf("chainTrackParts track %p %s part %p %s evlist %p\n", t, t->name().toLatin1().constData(), p, p->name().toLatin1().constData(), p->cevents());

        Part* p1 = 0;

        // Look for a part with the same event list, that we can chain to.
        // It's faster if track type is known...

        {
            MidiTrack* mt = 0;
            MidiTrackList* mtl = song->midis();
            for (ciMidiTrack imt = mtl->begin(); imt != mtl->end(); ++imt)
            {
                mt = *imt;
                const PartList* pl = mt->cparts();
                for (ciPart ip = pl->begin(); ip != pl->end(); ++ip)
                {
                    // Added by Tim. p3.3.6
                    //printf("chainTrackParts track %p %s part %p %s evlist %p\n", mt, mt->name().toLatin1().constData(), ip->second, ip->second->name().toLatin1().constData(), ip->second->cevents());

                    if (ip->second != p && ip->second->cevents() == p->cevents())
                    {
                        p1 = ip->second;
                        break;
                    }
                }
                // If a suitable part was found on a different track, we're done. We will chain to it.
                // Otherwise keep looking for parts on another track. If no others found, then we
                //  chain to any suitable part which was found on the same given track t.
                if (p1 && mt != t)
                    break;
            }
        }

        // No part found with same event list? Done.
        if (!p1)
            continue;

        // Make sure the part to be chained is unchained first.
        p->prevClone()->setNextClone(p->nextClone());
        p->nextClone()->setPrevClone(p->prevClone());

        // Link the part to be chained.
        p->setPrevClone(p1);
        p->setNextClone(p1->nextClone());

        // Re-link the existing part.
        p1->nextClone()->setPrevClone(p);
        p1->setNextClone(p);
    }
}/*}}}*/