示例#1
0
文件: pyapi.cpp 项目: OpenGanesh/oom
PyObject* createPart(PyObject*, PyObject* args)
{
	const char* trackname;
	unsigned tick, tickLen;
	PyObject* part;

	if (!PyArg_ParseTuple(args, "siiO", &trackname, &tick, &tickLen, &part))
	{
		return NULL;
	}

	QString qtrackname(trackname);
	MidiTrack* track = (MidiTrack*) song->findTrack(trackname);
	if (track == NULL)
		return NULL;

	MidiPart* npart = new MidiPart(track);
	npart->setTick(tick);
	npart->setLenTick(tickLen);
	addPyPartEventsToOOMidiPart(npart, part);

	song->addPart(npart);
	QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_UPDATE, SC_TRACK_MODIFIED);
	QApplication::postEvent(song, pyevent);

	Py_INCREF(Py_None);
	return Py_None;
}
示例#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
void LOS::processTrack(MidiTrack* track)
{
    EventList* tevents = track->events();
    if (tevents->empty())
        return;

    //---------------------------------------------------
    // Identify Parts
    // The MIDI tracks are broken up into parts
    // A new Part will be located based on track.
    // Events will be aligned on new track
    //---------------------------------------------------

    PartList* pl = track->parts();

    int lastTick = 0;
    for (iEvent i = tevents->begin(); i != tevents->end(); ++i)
    {
        Event event = i->second;
        int epos = event.tick() + event.lenTick();
        if (epos > lastTick)
            lastTick = epos;
    }

    QString partname = track->name();
    int len = song->roundUpBar(lastTick + 1);

    // p3.3.27
    if (config.importMidiSplitParts)
    {

        int bar2, beat;
        unsigned tick;
        sigmap.tickValues(len, &bar2, &beat, &tick);

        int lastOff = 0;
        int st = -1; // start tick current part
        int x1 = 0; // start tick current measure
        int x2 = 0; // end tick current measure

        for (int bar = 0; bar < bar2; ++bar, x1 = x2)
        {
            ///x2 = sigmap.bar2tick(bar+1, 0, 0);
            x2 = sigmap.bar2tick(bar + 1, 0, 0);
            if (lastOff > x2)
            {
                // this measure is busy!
                continue;
            }
            iEvent i1 = tevents->lower_bound(x1);
            iEvent i2 = tevents->lower_bound(x2);

            if (i1 == i2)
            { // empty?
                if (st != -1)
                {
                    MidiPart* part = new MidiPart(track);
                    part->setTick(st);
                    part->setLenTick(x1 - st);
                    // printf("new part %d len: %d\n", st, x1-st);
                    part->setName(partname);
                    pl->add(part);
                    st = -1;
                }
            }
            else
            {
                if (st == -1)
                    st = x1; // begin new  part
                //HACK:
                //lastOff:
                for (iEvent i = i1; i != i2; ++i)
                {
                    Event event = i->second;
                    if (event.type() == Note)
                    {
                        int off = event.tick() + event.lenTick();
                        if (off > lastOff)
                            lastOff = off;
                    }
                }
            }
        }
        if (st != -1)
        {
            MidiPart* part = new MidiPart(track);
            part->setTick(st);
            // printf("new part %d len: %d\n", st, x2-st);
            part->setLenTick(x2 - st);
            part->setName(partname);
            pl->add(part);
        }
    }
    else
    {
        // Just one long part...
        MidiPart* part = new MidiPart(track);
        //part->setTick(st);
        part->setTick(0);
        part->setLenTick(len);
        part->setName(partname);
        pl->add(part);
    }

    //-------------------------------------------------------------
    //    assign events to parts
    //-------------------------------------------------------------

    for (iPart p = pl->begin(); p != pl->end(); ++p)
    {
        MidiPart* part = (MidiPart*) (p->second);
        int stick = part->tick();
        int etick = part->tick() + part->lenTick();
        iEvent r1 = tevents->lower_bound(stick);
        iEvent r2 = tevents->lower_bound(etick);
        int startTick = part->tick();

        EventList* el = part->events();
        for (iEvent i = r1; i != r2; ++i)
        {
            Event ev = i->second;
            int ntick = ev.tick() - startTick;
            ev.setTick(ntick);
            el->add(ev);
        }
        tevents->erase(r1, r2);
    }

    if (tevents->size())
        printf("-----------events left: %zd\n", tevents->size());
    for (iEvent i = tevents->begin(); i != tevents->end(); ++i)
    {
        printf("%d===\n", i->first);
        i->second.dump();
    }
    // all events should be processed:
    assert(tevents->empty());
}