예제 #1
0
파일: part.cpp 프로젝트: ViktorNova/los
void Song::cmdGluePart(Track* track, Part* oPart)
{
    PartList* pl = track->parts();
    Part* nextPart = 0;

    for (iPart ip = pl->begin(); ip != pl->end(); ++ip)
    {
        if (ip->second == oPart)
        {
            ++ip;
            if (ip == pl->end())
                return;
            nextPart = ip->second;
            break;
        }
    }

    Part* nPart = track->newPart(oPart);
    nPart->setLenTick(nextPart->tick() + nextPart->lenTick() - oPart->tick());

    // populate nPart with Events from oPart and nextPart

    EventList* sl1 = oPart->events();
    EventList* dl = nPart->events();

    for (iEvent ie = sl1->begin(); ie != sl1->end(); ++ie)
        dl->add(ie->second);

    EventList* sl2 = nextPart->events();

    //int frameOffset = nextPart->frame() - oPart->frame();
    //for (iEvent ie = sl2->begin(); ie != sl2->end(); ++ie) {
    //      Event event = ie->second.clone();
    //      event.setFrame(event.frame() + frameOffset);
    //      dl->add(event);
    //      }
    // p3.3.54 Changed.

    {
        int tickOffset = nextPart->tick() - oPart->tick();
        for (iEvent ie = sl2->begin(); ie != sl2->end(); ++ie)
        {
            Event event = ie->second.clone();
            event.setTick(event.tick() + tickOffset);
            dl->add(event);
        }
    }

    startUndo();
    audio->msgRemovePart(nextPart, false);
    // Indicate no undo, and do port controller values but not clone parts.
    //audio->msgChangePart(oPart, nPart, false);
    audio->msgChangePart(oPart, nPart, false, true, false);
    endUndo(SC_PART_MODIFIED | SC_PART_REMOVED);
}
예제 #2
0
파일: pyapi.cpp 프로젝트: OpenGanesh/oom
PyObject* modifyPart(PyObject*, PyObject* part)
{
	int id = getPythonPartId(part);

	Part* opart = NULL;
	// Verify a part with that id actually exists, then get it
	TrackList* tracks = song->tracks();
	for (ciTrack t = tracks->begin(); t != tracks->end(); ++t)
	{
		Track* track = *t;
		for (ciPart p = track->parts()->begin(); p != track->parts()->end(); p++)
		{
			if (p->second->sn() == id)
			{
				opart = p->second;
				break;
			}
		}
	}

	if (opart == NULL)
	{
		printf("Part doesn't exist!\n");
		return NULL;
	}

	// Remove all note and controller events from current part eventlist
	std::list< std::pair<const unsigned, Event> > elist;
	MidiPart* npart = new MidiPart((MidiTrack*) opart->track());
	npart->setTick(opart->tick());
	npart->setLenTick(opart->lenTick());
	npart->setSn(opart->sn());

	for (iEvent e = opart->events()->begin(); e != opart->events()->end(); e++)
	{
		Event& event = e->second;
		if (event.type() == Note || event.type() == Controller)
			continue;

		npart->events()->add(event);
	}

	addPyPartEventsToOOMidiPart(npart, part);

	//song->startUndo();
	song->changePart(opart, npart);
	//song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED); // Crash! Probably since the call ends up in Qt GUI thread from this thread

	QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_UPDATE, SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED);
	QApplication::postEvent(song, pyevent);


	Py_INCREF(Py_None);
	return Py_None;
}
예제 #3
0
파일: part.cpp 프로젝트: ViktorNova/los
void unchainTrackParts(MidiTrack* t, bool decRefCount)/*{{{*/
{
    PartList* pl = t->parts();
    for (iPart ip = pl->begin(); ip != pl->end(); ++ip)
    {
        Part* p = ip->second;
        chainCheckErr(p);

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

        // Unchain the part.
        p->prevClone()->setNextClone(p->nextClone());
        p->nextClone()->setPrevClone(p->prevClone());

        // Isolate the part.
        p->setPrevClone(p);
        p->setNextClone(p);
    }
}/*}}}*/
예제 #4
0
파일: part.cpp 프로젝트: ViktorNova/los
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);
    }
}/*}}}*/
예제 #5
0
void globalCut(bool onlySelectedTracks)
      {
      int lpos = MusEGlobal::song->lpos();
      int rpos = MusEGlobal::song->rpos();
      if ((lpos - rpos) >= 0)
            return;

      Undo operations;
      TrackList* tracks = MusEGlobal::song->tracks();
      
      for (iTrack it = tracks->begin(); it != tracks->end(); ++it) {
            Track* track = *it;
            if (track == 0 || (onlySelectedTracks && !track->selected()))
                  continue;
            PartList* pl = track->parts();
            for (iPart p = pl->begin(); p != pl->end(); ++p) {
                  Part* part = p->second;
                  int t = part->tick();
                  int l = part->lenTick();
                  if (t + l <= lpos)
                        continue;
                  if ((t >= lpos) && ((t+l) <= rpos)) {
                        operations.push_back(UndoOp(UndoOp::DeletePart,part));
                        }
                  else if ((t < lpos) && ((t+l) > lpos) && ((t+l) <= rpos)) {
                      // remove part tail
                      int len = lpos - t;
                      
                      if (part->nextClone()==part) // no clones
                      {
                            // cut Events
                            const EventList& el = part->events();
                            for (ciEvent ie = el.lower_bound(len); ie != el.end(); ++ie)
                                    operations.push_back(UndoOp(UndoOp::DeleteEvent,ie->second, part, false, false));
                      }
                      operations.push_back(UndoOp(UndoOp::ModifyPartLength, part, part->lenTick(), len, true, true));
                  }
                  else if ((t < lpos) && ((t+l) > lpos) && ((t+l) > rpos)) {
                        //----------------------
                        // remove part middle
                        //----------------------
                        Part* p1;
                        Part* p2;
                        Part* p3;
                        part->splitPart(lpos, p1, p2);
                        delete p2;
                        part->splitPart(rpos, p2, p3);
                        delete p2;
                        p3->setTick(lpos);

                        MusEGlobal::song->informAboutNewParts(part,p1,p3);
                        operations.push_back(UndoOp(UndoOp::DeletePart,part));
                        operations.push_back(UndoOp(UndoOp::AddPart,p1));
                        operations.push_back(UndoOp(UndoOp::AddPart,p3));
                        }
                  else if ((t >= lpos) && (t < rpos) && (t+l) > rpos) {
                        // remove part head
                        
                        Part* p1;
                        Part* p2;
                        part->splitPart(rpos, p1, p2);
                        delete p1;
                        p2->setTick(lpos);
                        
                        MusEGlobal::song->informAboutNewParts(part,p2);
                        operations.push_back(UndoOp(UndoOp::DeletePart,part));
                        operations.push_back(UndoOp(UndoOp::AddPart,p2));
                        }
                  else if (t >= rpos) {
                        // move part to the left
                        int nt = part->tick();
                        operations.push_back(UndoOp(UndoOp::ModifyPartTick,part,part->tick(), nt - (rpos -lpos) ));
                        }
                  }
            }
      int diff = lpos - rpos;
      adjustGlobalLists(operations, lpos, diff);

      MusEGlobal::song->applyOperationGroup(operations);
      }