From 08960fd4ba07db50e078b13f01f37ae1d175e86f Mon Sep 17 00:00:00 2001 From: rncbc Date: Sat, 18 Nov 2023 13:20:45 +0000 Subject: [PATCH] - Fixed automation curve rescaling across multiple, more than just one or two, tempo-map node changes. (EXPERIMENTAL) --- ChangeLog | 3 ++ src/qtractorTimeScaleCommand.cpp | 73 +++++++++++++++++++++++--------- src/qtractorTimeScaleCommand.h | 6 ++- src/translations/qtractor_cs.ts | 24 +++++------ src/translations/qtractor_de.ts | 24 +++++------ src/translations/qtractor_es.ts | 24 +++++------ src/translations/qtractor_fr.ts | 24 +++++------ src/translations/qtractor_it.ts | 24 +++++------ src/translations/qtractor_ja.ts | 24 +++++------ src/translations/qtractor_pt.ts | 24 +++++------ src/translations/qtractor_ru.ts | 24 +++++------ src/translations/qtractor_uk.ts | 24 +++++------ 12 files changed, 168 insertions(+), 130 deletions(-) diff --git a/ChangeLog b/ChangeLog index f099c8872..c9950f195 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,9 @@ ChangeLog GIT HEAD +- Fixed automation curve rescaling across multiple, more than just + one or two, tempo-map node changes. (EXPERIMENTAL) + - New MIDI Tool Resize / Legato duration option added. (EXPERIMENTAL) - MIDI Clip Editor (aka. piano-roll) thumb-view now taking tempo-map diff --git a/src/qtractorTimeScaleCommand.cpp b/src/qtractorTimeScaleCommand.cpp index f132f1337..cd04c41fa 100644 --- a/src/qtractorTimeScaleCommand.cpp +++ b/src/qtractorTimeScaleCommand.cpp @@ -87,12 +87,19 @@ bool qtractorTimeScaleNodeCommand::addNode (void) if (bPlaying) pSession->seek(0, false); + qtractorTimeScale::Node *pNext = pNode->next(); + const unsigned long iFrameStart = m_iFrame; + const unsigned long iFrameEnd + = (pNext ? pNext->frame : pSession->sessionEnd()); + const float fOldTempo = pNode->tempo; const float fNewTempo = m_fTempo; const bool bRedoClipCommand = (m_pClipCommand == nullptr); - if (bRedoClipCommand) - m_pClipCommand = createClipCommand(pNode, fNewTempo, fOldTempo); + if (bRedoClipCommand) { + m_pClipCommand = createClipCommand( + iFrameStart, iFrameEnd, fNewTempo, fOldTempo); + } else if (m_pClipCommand) { m_pClipCommand->undo(); @@ -107,7 +114,7 @@ bool qtractorTimeScaleNodeCommand::addNode (void) const bool bRedoCurveEditCommands = m_curveEditCommands.isEmpty(); if (bRedoCurveEditCommands) { - addCurveEditCommands(pNode->frame, fNewTempo, fOldTempo); + addCurveEditCommands(iFrameStart, iFrameEnd, fNewTempo, fOldTempo); } else { QListIterator undos(m_curveEditCommands); while (undos.hasNext()) @@ -175,12 +182,19 @@ bool qtractorTimeScaleNodeCommand::updateNode (void) const unsigned short iBeatsPerBar = pNode->beatsPerBar; const unsigned short iBeatDivisor = pNode->beatDivisor; + qtractorTimeScale::Node *pNext = pNode->next(); + const unsigned long iFrameStart = pNode->frame; + const unsigned long iFrameEnd + = (pNext ? pNext->frame : pSession->sessionEnd()); + const float fOldTempo = pNode->tempo; const float fNewTempo = m_fTempo; const bool bRedoClipCommand = (m_pClipCommand == nullptr); - if (bRedoClipCommand) - m_pClipCommand = createClipCommand(pNode, fNewTempo, fOldTempo); + if (bRedoClipCommand) { + m_pClipCommand = createClipCommand( + iFrameStart, iFrameEnd, fNewTempo, fOldTempo); + } else if (m_pClipCommand) { m_pClipCommand->undo(); @@ -190,7 +204,7 @@ bool qtractorTimeScaleNodeCommand::updateNode (void) const bool bRedoCurveEditCommands = m_curveEditCommands.isEmpty(); if (bRedoCurveEditCommands) { - addCurveEditCommands(pNode->frame, fNewTempo, fOldTempo); + addCurveEditCommands(iFrameStart, iFrameEnd, fNewTempo, fOldTempo); } else { QListIterator undos(m_curveEditCommands); while (undos.hasNext()) @@ -265,13 +279,20 @@ bool qtractorTimeScaleNodeCommand::removeNode (void) if (bPlaying) pSession->seek(0, false); + qtractorTimeScale::Node *pNext = pNode->next(); + const unsigned long iFrameStart = pNode->frame; + const unsigned long iFrameEnd + = (pNext ? pNext->frame : pSession->sessionEnd()); + qtractorTimeScale::Node *pPrev = pNode->prev(); const float fOldTempo = pNode->tempo; const float fNewTempo = (pPrev ? pPrev->tempo : m_pTimeScale->tempo()); const bool bRedoClipCommand = (m_pClipCommand == nullptr); - if (bRedoClipCommand) - m_pClipCommand = createClipCommand(pNode, fNewTempo, fOldTempo); + if (bRedoClipCommand) { + m_pClipCommand = createClipCommand( + iFrameStart, iFrameEnd, fNewTempo, fOldTempo); + } else if (m_pClipCommand) { m_pClipCommand->undo(); @@ -281,7 +302,7 @@ bool qtractorTimeScaleNodeCommand::removeNode (void) const bool bRedoCurveEditCommands = m_curveEditCommands.isEmpty(); if (bRedoCurveEditCommands) { - addCurveEditCommands(pNode->frame, fNewTempo, fOldTempo); + addCurveEditCommands(iFrameStart, iFrameEnd, fNewTempo, fOldTempo); } else { QListIterator undos(m_curveEditCommands); while (undos.hasNext()) @@ -330,21 +351,18 @@ bool qtractorTimeScaleNodeCommand::removeNode (void) // Make it automatic clip time-stretching command (static). qtractorClipCommand *qtractorTimeScaleNodeCommand::createClipCommand ( - qtractorTimeScale::Node *pNode, float fNewTempo, float fOldTempo ) + unsigned long iFrameStart, unsigned long iFrameEnd, + float fNewTempo, float fOldTempo ) { - if (pNode == nullptr) + if (iFrameStart >= iFrameEnd) return nullptr; - if (fNewTempo == fOldTempo) + if (qAbs(fNewTempo - fOldTempo) < 0.1f) return nullptr; qtractorSession *pSession = qtractorSession::getInstance(); if (pSession == nullptr) return nullptr; - qtractorTimeScale::Node *pNext = pNode->next(); - const unsigned long iFrameStart = pNode->frame; - const unsigned long iFrameEnd = (pNext ? pNext->frame : pSession->sessionEnd()); - qtractorClipCommand *pClipCommand = nullptr; for (qtractorTrack *pTrack = pSession->tracks().first(); @@ -384,19 +402,25 @@ qtractorClipCommand *qtractorTimeScaleNodeCommand::createClipCommand ( // Automation curve time-stretching command (static). void qtractorTimeScaleNodeCommand::addCurveEditCommands ( - unsigned long iFrame, float fNewTempo, float fOldTempo ) + unsigned long iFrameStart, unsigned long iFrameEnd, + float fNewTempo, float fOldTempo ) { - if (qAbs(fNewTempo - fOldTempo) < 0.01f) + if (iFrameStart >= iFrameEnd) + return; + if (qAbs(fNewTempo - fOldTempo) < 0.1f) return; qtractorSession *pSession = qtractorSession::getInstance(); if (pSession == nullptr) return; - const unsigned long iFrameStart = iFrame; const float fFactor = (fOldTempo / fNewTempo); const bool bReverse = (fOldTempo > fNewTempo); + const long iFrameDelta + = long(iFrameStart) - long(iFrameEnd) + + long(float(iFrameEnd - iFrameStart) * fFactor); + for (qtractorTrack *pTrack = pSession->tracks().first(); pTrack; pTrack = pTrack->next()) { qtractorCurveList *pCurveList = pTrack->curveList(); @@ -410,13 +434,22 @@ void qtractorTimeScaleNodeCommand::addCurveEditCommands ( qtractorCurve::Node *pCurveNode = (bReverse ? pCurve->nodes().last() : pCurve->seek(iFrameStart)); while (pCurveNode) { + if (pCurveNode->frame >= iFrameEnd) { + const unsigned long iFrame = pCurveNode->frame + iFrameDelta; + const float fValue = pCurveNode->value; + pCurveEditCommand->moveNode(pCurveNode, iFrame, fValue); + ++iCurveEditUpdate; + } + else if (pCurveNode->frame >= iFrameStart) { const unsigned long iFrame = iFrameStart + (unsigned long) (float(pCurveNode->frame - iFrameStart) * fFactor); const float fValue = pCurveNode->value; pCurveEditCommand->moveNode(pCurveNode, iFrame, fValue); ++iCurveEditUpdate; - } else if (bReverse) + } + else + if (bReverse) break; if (bReverse) pCurveNode = pCurveNode->prev(); diff --git a/src/qtractorTimeScaleCommand.h b/src/qtractorTimeScaleCommand.h index 857de5f24..7b35d92b3 100644 --- a/src/qtractorTimeScaleCommand.h +++ b/src/qtractorTimeScaleCommand.h @@ -76,11 +76,13 @@ class qtractorTimeScaleNodeCommand : public qtractorCommand // Make it automatic clip time-stretching command (static). qtractorClipCommand *createClipCommand( - qtractorTimeScale::Node *pNode, float fOldTempo, float fNewTempo); + unsigned long iFrameStart, unsigned long iFrameEnd, + float fOldTempo, float fNewTempo); // Automation curve time-stretching command (static). void addCurveEditCommands( - unsigned long iFrame, float fOldTempo, float fNewTempo); + unsigned long iFrameStart, unsigned long iFrameEnd, + float fOldTempo, float fNewTempo); private: diff --git a/src/translations/qtractor_cs.ts b/src/translations/qtractor_cs.ts index a4f2575c9..23f41e6ee 100644 --- a/src/translations/qtractor_cs.ts +++ b/src/translations/qtractor_cs.ts @@ -560,62 +560,62 @@ Stopa: "%1" Vstup: "%2" Výstup: "%3"%1 (%2) - + add tempo node Přidat uzel s tempem - + update tempo node Obnovit uzel s tempem - + remove tempo node Odstranit uzel s tempem - + move tempo node Přesunout uzel s tempem - + add marker Přidat značku - + update marker Obnovit značku - + remove marker Odstranit značku - + add key signature Přidat předznamenání - + update key signature Aktualizovat předznamenání - + remove key signature Odstranit předznamenání - + move marker Přesunout značku - + change time-sig. Změnit taktové označení diff --git a/src/translations/qtractor_de.ts b/src/translations/qtractor_de.ts index 3815a5b1d..1b59682cf 100644 --- a/src/translations/qtractor_de.ts +++ b/src/translations/qtractor_de.ts @@ -575,62 +575,62 @@ MIDI: Taktschlag - + add tempo node - + update tempo node - + remove tempo node - + move tempo node - + add marker Markierung hinzufügen - + update marker Markierung aktualisieren - + remove marker Markierung entfernen - + add key signature - + update key signature - + remove key signature - + move marker Markierung verschieben - + change time-sig. diff --git a/src/translations/qtractor_es.ts b/src/translations/qtractor_es.ts index e6d55bc8d..9a3117082 100644 --- a/src/translations/qtractor_es.ts +++ b/src/translations/qtractor_es.ts @@ -659,62 +659,62 @@ MIDI: Pulso - + add tempo node añadir nodo de tempo - + update tempo node actualizar nodo de tempo - + remove tempo node quitar nodo de tempo - + move tempo node mover nodo de tempo - + add marker añadir marcador - + update marker actualizar marcador - + remove marker quitar marcador - + add key signature añadir armadura - + update key signature actualizar armadura - + remove key signature remover armadura - + move marker mover marcador - + change time-sig. cambiar compás. diff --git a/src/translations/qtractor_fr.ts b/src/translations/qtractor_fr.ts index c320d3e61..42073aaf5 100644 --- a/src/translations/qtractor_fr.ts +++ b/src/translations/qtractor_fr.ts @@ -576,62 +576,62 @@ MIDI: Battement - + add tempo node ajouter un noeud tempo - + update tempo node mise à jour du noeud tempo - + remove tempo node enlever le noeud tempo - + move tempo node déplacer le noeud tempo - + add marker ajouter un marqueur - + update marker mettre à jour un marqueur - + remove marker enlever un marqueur - + add key signature ajouter une clef de signature - + update key signature mettre à jour la clef de signature - + remove key signature enlever la clef de signature - + move marker déplacer un marqueur - + change time-sig. modifier la signature temporelle. diff --git a/src/translations/qtractor_it.ts b/src/translations/qtractor_it.ts index b2bfd618f..efddafd24 100644 --- a/src/translations/qtractor_it.ts +++ b/src/translations/qtractor_it.ts @@ -577,62 +577,62 @@ MIDI: Battito - + add tempo node aggiungi nodo tempo - + update tempo node aggiorna nodo tempo - + remove tempo node rimuovi nodo tempo - + move tempo node sposta nodo tempo - + add marker aggiungi marker - + update marker aggiorna marker - + remove marker elimina marker - + add key signature - + update key signature - + remove key signature - + move marker sposta marker - + change time-sig. diff --git a/src/translations/qtractor_ja.ts b/src/translations/qtractor_ja.ts index 08fe39a9e..9dbd38abb 100644 --- a/src/translations/qtractor_ja.ts +++ b/src/translations/qtractor_ja.ts @@ -576,62 +576,62 @@ MIDI: - + add tempo node テンポノードを追加 - + update tempo node テンポノードを更新 - + remove tempo node テンポノードを削除 - + move tempo node テンポノードを移動 - + add marker マーカーの追加 - + update marker マーカーの更新 - + remove marker マーカーの削除 - + add key signature 調号の追加 - + update key signature 調号の更新 - + remove key signature 調号の削除 - + move marker マーカーの異動 - + change time-sig. 拍子の変更。 diff --git a/src/translations/qtractor_pt.ts b/src/translations/qtractor_pt.ts index ed121274e..a27df3557 100644 --- a/src/translations/qtractor_pt.ts +++ b/src/translations/qtractor_pt.ts @@ -469,32 +469,32 @@ MIDI: importar plugins - + add marker adicionar marcador - + add key signature adicionar fórmula de compasso - + update key signature atualizar fórmula de compasso - + remove key signature remover fórmula de compasso - + move marker mover marcador - + change time-sig. alterar formula-compasso. @@ -718,7 +718,7 @@ MIDI: %1 - Banco %2 - + remove tempo node remover nó de tempo @@ -729,12 +729,12 @@ MIDI: Tudo (*.*) - + update marker atualizar marcador - + move tempo node mover nó de tempo @@ -799,7 +799,7 @@ Pista: "%1" Entrada: "%2" Saída: "%3"Autor: - + update tempo node nó de atualização de tempo @@ -809,7 +809,7 @@ Pista: "%1" Entrada: "%2" Saída: "%3", %1 pistas, %2 tpqn - + add tempo node adicionar nó de tempo @@ -881,7 +881,7 @@ Pista: "%1" Entrada: "%2" Saída: "%3" - + remove marker remover marcador diff --git a/src/translations/qtractor_ru.ts b/src/translations/qtractor_ru.ts index 06941f7dd..eb2bc5bc2 100644 --- a/src/translations/qtractor_ru.ts +++ b/src/translations/qtractor_ru.ts @@ -530,62 +530,62 @@ Track: "%1" Input: "%2" Output: "%3" %1 (*.%2) - + add tempo node добавление смены темпа - + update tempo node обновление смены темпа - + remove tempo node удаление смены темпа - + move tempo node перемещение смены темпа - + add marker добавление маркера - + update marker обновление маркера - + remove marker удаление маркера - + add key signature - + update key signature - + remove key signature - + move marker перемещение маркера - + change time-sig. diff --git a/src/translations/qtractor_uk.ts b/src/translations/qtractor_uk.ts index 3af588b93..3f3ea8cb4 100644 --- a/src/translations/qtractor_uk.ts +++ b/src/translations/qtractor_uk.ts @@ -712,62 +712,62 @@ MIDI: Біт - + add tempo node додати вузол ритму - + update tempo node оновити вузол ритму - + remove tempo node вилучити вузол ритму - + move tempo node пересунути вузол ритму - + add marker додати позначку - + update marker оновити позначку - + remove marker вилучити позначку - + add key signature додати підпис ключа - + update key signature оновити підпис ключа - + remove key signature вилучити підпис ключа - + move marker пересунути позначку - + change time-sig. змінити часовий підпис.