Пример #1
0
void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len)/*{{{*/
{
        {
            startUndo();

            MidiPart* nPart = new MidiPart(*(MidiPart*) oPart);
            nPart->setLenTick(len);
            // Indicate no undo, and do port controller values but not clone parts.
            audio->msgChangePart(oPart, nPart, false, true, false);

            // cut Events in nPart
            // Changed by T356. Don't delete events if this is a clone part.
            // The other clones might be longer than this one and need these events.
            if (nPart->cevents()->arefCount() <= 1)
            {
                if (oPart->lenTick() > len)
                {
                    EventList* el = nPart->events();
                    iEvent ie = el->lower_bound(len);
                    for (; ie != el->end();)
                    {
                        iEvent i = ie;
                        ++ie;
                        // Indicate no undo, and do port controller values and clone parts.
                        audio->msgDeleteEvent(i->second, nPart, false, true, true);
                    }
                }
            }

            /*
            // cut Events in nPart
            // Changed by T356. Don't delete events if this is a clone part.
            // The other clones might be longer than this one and need these events.
            if(oPart->cevents()->arefCount() <= 1)
            {
              if (oPart->lenTick() > len) {
                    EventList* el = nPart->events();
                    iEvent ie = el->lower_bound(len);
                    for (; ie != el->end();) {
                          iEvent i = ie;
                          ++ie;
                          // Indicate no undo, and do not do port controller values and clone parts.
                          //audio->msgDeleteEvent(i->second, nPart, false);
                          audio->msgDeleteEvent(i->second, nPart, false, false, 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);
        }
}/*}}}*/
Пример #2
0
void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len)
{
	switch (track->type())
	{
		case Track::WAVE:
		{
			WavePart* nPart = new WavePart(*(WavePart*) oPart);
			EventList* el = nPart->events();
			unsigned new_partlength = tempomap.deltaTick2frame(oPart->tick(), oPart->tick() + len);
			//printf("new partlength in frames: %d\n", new_partlength);

			// If new nr of frames is less than previous what can happen is:
			// -   0 or more events are beginning after the new final position. Those are removed from the part
			// -   The last event begins before new final position and ends after it. If so, it will be resized to end at new part length
			if (new_partlength < oPart->lenFrame())
			{
				startUndo();

				for (iEvent i = el->begin(); i != el->end(); i++)
				{
					Event e = i->second;
					unsigned event_startframe = e.frame();
					unsigned event_endframe = event_startframe + e.lenFrame();
					//printf("Event frame=%d, length=%d\n", event_startframe, event_length);
					if (event_endframe < new_partlength)
						continue;
					if (event_startframe > new_partlength)
					{ // If event start was after the new length, remove it from part
						// Indicate no undo, and do not do port controller values and clone parts.
						//audio->msgDeleteEvent(e, nPart, false);
						audio->msgDeleteEvent(e, nPart, false, false, false);
						continue;
					}
					if (event_endframe > new_partlength)
					{ // If this event starts before new length and ends after, shrink it
						Event newEvent = e.clone();
						newEvent.setLenFrame(new_partlength - event_startframe);
						// Indicate no undo, and do not do port controller values and clone parts.
						//audio->msgChangeEvent(e, newEvent, nPart, false);
						audio->msgChangeEvent(e, newEvent, nPart, false, false, false);
					}
				}
				nPart->setLenFrame(new_partlength);
				// Indicate no undo, and do not do port controller values and clone parts.
				//audio->msgChangePart(oPart, nPart, false);
				audio->msgChangePart(oPart, nPart, false, false, false);

				endUndo(SC_PART_MODIFIED);
			}
				// If the part is expanded there can be no additional events beginning after the previous final position
				// since those are removed if the part has been shrunk at some time (see above)
				// The only thing we need to check is the final event: If it has data after the previous final position,
				// we'll expand that event
			else
			{
				if (!el->empty())
				{
					iEvent i = el->end();
					i--;
					Event last = i->second;
					unsigned last_start = last.frame();
					SndFileR file = last.sndFile();
					if (file.isNull())
						return;

					unsigned clipframes = (file.samples() - last.spos()); // / file.channels();
					Event newEvent = last.clone();
					//printf("SndFileR samples=%d channels=%d event samplepos=%d clipframes=%d\n", file.samples(), file.channels(), last.spos(), clipframes);

					unsigned new_eventlength = new_partlength - last_start;
					if (new_eventlength > clipframes) // Shrink event length if new partlength exceeds last clip
						new_eventlength = clipframes;

					newEvent.setLenFrame(new_eventlength);
					startUndo();
					// Indicate no undo, and do not do port controller values and clone parts.
					//audio->msgChangeEvent(last, newEvent, nPart, false);
					audio->msgChangeEvent(last, newEvent, nPart, false, false, false);
				}
				else
				{
					startUndo();
				}

				nPart->setLenFrame(new_partlength);
				// Indicate no undo, and do not do port controller values and clone parts.
				//audio->msgChangePart(oPart, nPart, false);
				audio->msgChangePart(oPart, nPart, false, false, false);
				endUndo(SC_PART_MODIFIED);
			}
		}
			break;
		case Track::MIDI:
		case Track::DRUM:
		{
			startUndo();

			MidiPart* nPart = new MidiPart(*(MidiPart*) oPart);
			nPart->setLenTick(len);
			// Indicate no undo, and do port controller values but not clone parts.
			audio->msgChangePart(oPart, nPart, false, true, false);

			// cut Events in nPart
			// Changed by T356. Don't delete events if this is a clone part.
			// The other clones might be longer than this one and need these events.
			if (nPart->cevents()->arefCount() <= 1)
			{
				if (oPart->lenTick() > len)
				{
					EventList* el = nPart->events();
					iEvent ie = el->lower_bound(len);
					for (; ie != el->end();)
					{
						iEvent i = ie;
						++ie;
						// Indicate no undo, and do port controller values and clone parts.
						audio->msgDeleteEvent(i->second, nPart, false, true, true);
					}
				}
			}

			/*
			// cut Events in nPart
			// Changed by T356. Don't delete events if this is a clone part.
			// The other clones might be longer than this one and need these events.
			if(oPart->cevents()->arefCount() <= 1)
			{
			  if (oPart->lenTick() > len) {
					EventList* el = nPart->events();
					iEvent ie = el->lower_bound(len);
					for (; ie != el->end();) {
						  iEvent i = ie;
						  ++ie;
						  // Indicate no undo, and do not do port controller values and clone parts.
						  //audio->msgDeleteEvent(i->second, nPart, false);
						  audio->msgDeleteEvent(i->second, nPart, false, false, 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);
			break;
		}
		default:
			break;
	}
}