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 "AudioSegmentDistributeCommand.h"
20 
21 #include "base/Event.h"
22 #include "base/Composition.h"
23 #include "base/NotationTypes.h"
24 #include "base/RealTime.h"
25 #include "base/Segment.h"
26 #include "base/Selection.h"
27 #include "sound/AudioFile.h"
28 #include <QString>
29 
30 
31 namespace Rosegarden
32 {
33 
AudioSegmentDistributeCommand(Composition * comp,SegmentSelection & inputSelection,Segment * audioSegment)34 AudioSegmentDistributeCommand::AudioSegmentDistributeCommand(
35     Composition *comp,
36     SegmentSelection &inputSelection,
37     Segment *audioSegment):
38         NamedCommand(getGlobalName()),
39         m_composition(comp),
40         m_selection(inputSelection),
41         m_audioFile(nullptr),
42         m_audioSegment(audioSegment),
43         m_executed(false)
44 {}
45 
AudioSegmentDistributeCommand(Composition * comp,SegmentSelection & inputSelection,AudioFile * audioFile)46 AudioSegmentDistributeCommand::AudioSegmentDistributeCommand(
47     Composition *comp,
48     SegmentSelection &inputSelection,
49     AudioFile *audioFile):
50         NamedCommand(getGlobalName()),
51         m_composition(comp),
52         m_selection(inputSelection),
53         m_audioFile(audioFile),
54         m_audioSegment(nullptr),
55         m_executed(false)
56 {}
57 
~AudioSegmentDistributeCommand()58 AudioSegmentDistributeCommand::~AudioSegmentDistributeCommand()
59 {
60     if (m_executed) {
61         for (SegmentSelection::iterator i = m_selection.begin();
62                 i != m_selection.end(); ++i) {
63             delete *i;
64         }
65     } else {
66         for (size_t i = 0; i < m_newSegments.size(); ++i)
67             delete m_newSegments[i];
68     }
69 }
70 
71 void
execute()72 AudioSegmentDistributeCommand::execute()
73 {
74     // Store the insert times in a local vector
75     //
76     std::vector<timeT> insertTimes;
77 
78     bool addNew = m_newSegments.size() == 0 ? true : false;
79 
80     for (SegmentSelection::iterator i = m_selection.begin();
81             i != m_selection.end(); ++i) {
82         // For MIDI (Internal) Segments only of course
83         //
84         if ((*i)->getType() == Segment::Internal) {
85             if (addNew) {
86                 for (Segment::iterator it = (*i)->begin();
87                         it != (*i)->end(); ++it) {
88                     if ((*it)->isa(Note::EventType)) {
89                         Segment *segment =
90                             new Segment(
91                                 Segment::Audio,
92                                 (*it)->getAbsoluteTime());
93                         segment->setTrack((*i)->getTrack());
94 
95                         // If we've constructed against an AudioFile
96                         //
97                         if (m_audioFile) {
98                             segment->setAudioFileId(m_audioFile->getId());
99                             segment->setAudioStartTime(
100                                 RealTime::zeroTime);
101                             segment->setAudioEndTime(
102                                 m_audioFile->getLength());
103                         } else // or an audio Segment
104                         {
105                             segment->setAudioFileId(
106                                 m_audioSegment->getAudioFileId());
107                             segment->setAudioStartTime(
108                                 m_audioSegment->getAudioStartTime());
109                             segment->setAudioEndTime(
110                                 m_audioSegment->getAudioEndTime());
111                         }
112 
113                         m_composition->addSegment(segment);
114                         m_newSegments.push_back(segment);
115                     }
116                 }
117             }
118 
119             // Detach original Segment
120             //
121             m_composition->detachSegment(*i);
122         }
123 
124     }
125 
126     if (!addNew && !m_newSegments.empty()) {
127         // Reattach new segments
128         //
129         for (size_t i = 0; i < m_newSegments.size(); ++i)
130             m_composition->addSegment(m_newSegments[i]);
131     }
132 
133     m_executed = true;
134 }
135 
136 void
unexecute()137 AudioSegmentDistributeCommand::unexecute()
138 {
139     for (size_t i = 0; i < m_newSegments.size(); ++i)
140         m_composition->detachSegment(m_newSegments[i]);
141 
142     for (SegmentSelection::iterator it = m_selection.begin();
143             it != m_selection.end(); ++it)
144         m_composition->addSegment(*it);
145 
146     m_executed = false;
147 }
148 
149 }
150