예제 #1
0
파일: MiscCommands.cpp 프로젝트: wolqws/sws
static void SelectAllNearestEditCursor(int flag, void *data)
{
    double editCursor = GetCursorPosition();
    RprMidiTakePtr midiTake = RprMidiTake::createFromMidiEditor();

    if (midiTake->countNotes() == 0)
        return;

    int closest = midiTake->getNoteAt(0)->getItemPosition();
    double closestDifference = std::fabs(editCursor - midiTake->getNoteAt(0)->getPosition());
    for(int i = 1; i < midiTake->countNotes(); i++) {
        RprMidiNote *note = midiTake->getNoteAt(i);
        double difference = std::fabs(editCursor - note->getPosition());
        if (difference < closestDifference) {
            closest = note->getItemPosition();
            closestDifference = difference;
        }
    }

    for(int i = 0; i < midiTake->countNotes(); i++) {
        RprMidiNote *note = midiTake->getNoteAt(i);
        if (note->getItemPosition() == closest) {
            note->setSelected(true);
        } else {
            note->setSelected(false);
        }
    }
}
예제 #2
0
파일: RprMidiTake.cpp 프로젝트: Breeder/sws
static void removeOverlaps(std::vector<RprMidiNote *> &midiNotes)
{
    for(int noteOffset = 0; (midiNotes.begin() + noteOffset) != midiNotes.end(); ++noteOffset)
    {
        std::vector<RprMidiNote *>::iterator i = midiNotes.begin() + noteOffset;
        RprMidiNote *lhs = *i;
        for(std::vector<RprMidiNote *>::iterator j = i + 1; j != midiNotes.end(); j++)
        {
            RprMidiNote *rhs = *j;
            if(rhs->getItemPosition() >= lhs->getItemPosition() + lhs->getItemLength())
            {
                break;
            }
            if(lhs->getPitch() != rhs->getPitch())
            {
                continue;
            }
            if(lhs->getChannel() != rhs->getChannel())
            {
                continue;
            }
            if(lhs->getItemPosition() + lhs->getItemLength() >= rhs->getItemPosition())
            {
                int lhsLength = rhs->getItemPosition() - lhs->getItemPosition();
                if(lhsLength <= 0)
                {
                    delete lhs;
                    i = midiNotes.erase(i);
                    noteOffset--;
                }
                else
                {
                    lhs->setItemLength(lhsLength);
                }
                break;
            }
        }
    }
}
예제 #3
0
파일: RprMidiTake.cpp 프로젝트: Breeder/sws
RprMidiTake::~RprMidiTake()
{
    if (isReadOnly())
    {
        cleanup();
        return;
    }

    std::vector<RprMidiEvent *> midiEvents;
    std::sort(mNotes.begin(), mNotes.end(), compareMidiPositions<RprMidiNote>);
    for(int i = 0; i < 128; i++)
    {
        std::sort(mCCs[i].begin(), mCCs[i].end(), compareMidiPositions<RprMidiCC>);
    }
    removeDuplicates(mNotes);
    removeDuplicates(mCCs);
    removeOverlaps(mNotes);
    midiEvents.reserve(mNotes.size() * 2 + mOtherEvents.size());

    RprMidiEvent* allNotesOffEvent = NULL;
    if (!mCCs[0x7b].empty())
    {
        allNotesOffEvent = (*mCCs[0x7b].begin())->mCC;
    }

    for(std::vector<RprMidiNote *>::const_iterator i = mNotes.begin();
        i != mNotes.end(); ++i)
    {
        RprMidiNote* note = *i;
        if (allNotesOffEvent)
        {
            if (note->getItemPosition() >= allNotesOffEvent->getOffset())
            {
                continue;
            }

            if (note->getItemPosition() + note->getItemLength() > allNotesOffEvent->getOffset())
            {
                note->setItemLength(allNotesOffEvent->getOffset() - note->getItemPosition()); 
            }
        }
        midiEvents.push_back((*i)->mNoteOn);
        midiEvents.push_back((*i)->mNoteOff);
    }

    for(int j = 0; j < 128; j++)
    {
        // ignore all-notes-off event, handle this separately below
        if (j == 0x7b)
        {
            continue;
        }

        for(std::vector<RprMidiCC *>::const_iterator i = mCCs[j].begin();
            i != mCCs[j].end(); ++i)
        {
            midiEvents.push_back((*i)->mCC);
        }
    }

    for(std::vector<RprMidiEvent *>::const_iterator i = mOtherEvents.begin();
        i != mOtherEvents.end(); ++i)
    {
        midiEvents.push_back(*i);
    }

    std::sort(midiEvents.begin(), midiEvents.end(), sortMidiBase);

    if (allNotesOffEvent)
    {
        midiEvents.push_back(allNotesOffEvent);
    }

    int firstEventOffset = 0;
    if (!midiEvents.empty())
    {
        firstEventOffset = (*midiEvents.begin())->getOffset();
    }

    int offset = 0;
    if (firstEventOffset < 0)
    {
        double takeStartPosition = mTake.getParent().getPosition() -
            mTake.getStartOffset() / mContext->getPlayRate();

        // convert to Quarter notes and subtract first event offset
        double newTakeQNStartPosition = TimeToQN(takeStartPosition) + ((double)firstEventOffset /
            mContext->getTicksPerQN()) / mContext->getPlayRate();
        //convert back to seconds / playrate
        mNewTakeOffset = takeStartPosition - QNtoTime(newTakeQNStartPosition) +
            mTake.getStartOffset() / mContext->getPlayRate();
        //convert to seconds
        mNewTakeOffset *= mContext->getPlayRate();
        // Hack! Have to set start offset after setting item state so
        // set a flag to indicate we need a new start offset set
        mSetNewTakeOffset = true;
        // set initial offset to -ve value to get rid of -ve deltas
        offset = firstEventOffset;
    }

    for(std::vector<RprMidiEvent *>::iterator i = midiEvents.begin(); i != midiEvents.end(); ++i)
    {
        RprMidiEvent *current = *i;
        int delta = current->getOffset() - offset;
        current->setDelta(delta);
        offset += delta;
    }

    midiEventsToMidiNode(midiEvents, RprMidiTemplate::getMidiSourceNode(),
        mMidiEventsOffset);

    cleanup();
}
예제 #4
0
파일: RprMidiTake.cpp 프로젝트: Breeder/sws
static void removeDuplicates(std::vector<RprMidiNote *> &midiNotes)
{
    for(int noteOffset = 0; (midiNotes.begin() + noteOffset) != midiNotes.end(); noteOffset++)
    {
		std::vector<RprMidiNote *>::iterator i = midiNotes.begin() + noteOffset;
        RprMidiNote *lhs = *i;
        for(std::vector<RprMidiNote *>::iterator j = i + 1; j != midiNotes.end(); j++)
        {
            RprMidiNote *rhs = *j;
            if (rhs->getItemPosition() > lhs->getItemPosition())
            {
                break;
            }

            if(lhs->getItemPosition() != rhs->getItemPosition())
            {
                continue;
            }
            if(lhs->getPitch() != rhs->getPitch())
            {
                continue;
            }
            if(lhs->getChannel() != rhs->getChannel())
            {
                continue;
            }
            if(lhs->getItemLength() > rhs->getItemLength())
            {
                delete rhs;
                j = midiNotes.erase(j);
                if (noteOffset+1 >= (int)midiNotes.size())
                    break;
            }
            else
            {
                delete lhs;
                i = midiNotes.erase(i);
                noteOffset--;
                break;
            }
        }
    }
}