1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4     Rosegarden
5     A MIDI and audio sequencer and musical notation editor.
6     Copyright 2000-2021 the Rosegarden development team.
7 
8     Other copyrights also apply to some parts of this work.  Please
9     see the AUTHORS file and individual file headers for details.
10 
11     This program is free software; you can redistribute it and/or
12     modify it under the terms of the GNU General Public License as
13     published by the Free Software Foundation; either version 2 of the
14     License, or (at your option) any later version.  See the file
15     COPYING included with this distribution for more information.
16 */
17 
18 
19 #include "AudioSegmentResizeFromStartCommand.h"
20 
21 #include "base/Composition.h"
22 #include "base/RealTime.h"
23 #include "base/Segment.h"
24 #include <QObject>
25 
26 
27 namespace Rosegarden
28 {
29 
AudioSegmentResizeFromStartCommand(Segment * segment,timeT newStartTime)30 AudioSegmentResizeFromStartCommand::AudioSegmentResizeFromStartCommand(Segment *segment,
31         timeT newStartTime) :
32         NamedCommand(tr("Resize Segment")),
33         m_segment(segment),
34         m_newSegment(nullptr),
35         m_detached(false),
36         m_oldStartTime(segment->getStartTime()),
37         m_newStartTime(newStartTime)
38 {}
39 
~AudioSegmentResizeFromStartCommand()40 AudioSegmentResizeFromStartCommand::~AudioSegmentResizeFromStartCommand()
41 {
42     if (!m_detached)
43         delete m_segment;
44     else
45         delete m_newSegment;
46 }
47 
48 void
execute()49 AudioSegmentResizeFromStartCommand::execute()
50 {
51     Composition *c = m_segment->getComposition();
52 
53     if (!m_newSegment) {
54         RealTime oldRT = c->getElapsedRealTime(m_oldStartTime);
55         RealTime newRT = c->getElapsedRealTime(m_newStartTime);
56 
57         m_newSegment = m_segment->clone(false);
58         m_newSegment->setStartTime(m_newStartTime);
59 
60         // Compute an audio start time that will keep the audio exactly where
61         // it was in time.
62         RealTime audioStartTime =
63             m_segment->getAudioStartTime() - (oldRT - newRT);
64 
65         // Do not allow a negative audio start time.
66         // ??? This is a stopgap measure as the audio segment preview code
67         //   will crash if the audio start time is negative.  Need to fix the
68         //   preview code, then check to see if the playback code works
69         //   properly given a negative start time.  Then this can be removed.
70         if (audioStartTime <= RealTime::zeroTime)
71             m_newSegment->setAudioStartTime(RealTime::zeroTime);
72         else
73             m_newSegment->setAudioStartTime(
74                 m_segment->getAudioStartTime() - (oldRT - newRT));
75     }
76 
77     c->addSegment(m_newSegment);
78     m_newSegment->setEndMarkerTime(m_segment->getEndMarkerTime());
79     c->detachSegment(m_segment);
80 
81     m_detached = false;
82 }
83 
84 void
unexecute()85 AudioSegmentResizeFromStartCommand::unexecute()
86 {
87     Composition *c = m_newSegment->getComposition();
88     c->addSegment(m_segment);
89     c->detachSegment(m_newSegment);
90 
91     m_detached = true;
92 }
93 
94 }
95