1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4     Rosegarden
5     A sequencer and musical notation editor.
6     Copyright 2000-2021 the Rosegarden development team.
7     See the AUTHORS file for more details.
8 
9     This program is free software; you can redistribute it and/or
10     modify it under the terms of the GNU General Public License as
11     published by the Free Software Foundation; either version 2 of the
12     License, or (at your option) any later version.  See the file
13     COPYING included with this distribution for more information.
14 */
15 
16 #ifndef RG_QUANTIZER_H
17 #define RG_QUANTIZER_H
18 
19 #include "base/Segment.h"
20 
21 #include <string>
22 #include <vector>
23 
24 namespace Rosegarden {
25 
26 
27 class Event;
28 class EventSelection;
29 
30 /// Base class for quantizers.
31 /**
32  * See BasicQuantizer, LegatoQuantizer, and NotationQuantizer.
33  *
34  * The Quantizer class rounds the starting times and durations of note
35  * and rest events according to one of a set of possible criteria.
36  */
37 class Quantizer
38 {
39 public:
40     virtual ~Quantizer();
41 
42     /**
43      * Quantize a Segment.
44      */
45     void quantize(Segment *) const;
46 
47     /**
48      * Quantize a section of a Segment.
49      */
50     void quantize(Segment *,
51                   Segment::iterator from,
52                   Segment::iterator to) const;
53 
54     /**
55      * Quantize an EventSelection.
56      */
57     void quantize(EventSelection *);
58 
59     /**
60      * Quantize a section of a Segment, and force the quantized
61      * results into the formal absolute time and duration of
62      * the events.  This is a destructive operation that should
63      * not be carried out except on a user's explicit request.
64      * (If target is RawEventData, this will do nothing besides
65      * quantize.  In this case, but no other, unquantize will
66      * still work afterwards.)
67      */
68     void fixQuantizedValues(Segment *,
69                             Segment::iterator from,
70                             Segment::iterator to) const;
71 
72     /**
73      * Return the quantized duration of the event if it has been
74      * quantized -- otherwise just return the unquantized duration.
75      * Do not modify the event.
76      */
77     virtual timeT getQuantizedDuration(const Event *e) const;
78 
79     /**
80      * Return the quantized absolute time of the event if it has been
81      * quantized -- otherwise just return the unquantized time.  Do
82      * not modify the event.
83      */
84     virtual timeT getQuantizedAbsoluteTime(const Event *e) const;
85 
86     /**
87      * Return the unquantized absolute time of the event --
88      * the absolute time that would be restored by a call to
89      * unquantize.
90      */
91     virtual timeT getUnquantizedAbsoluteTime(Event *e) const;
92 
93     /**
94      * Return the unquantized absolute time of the event --
95      * the absolute time that would be restored by a call to
96      * unquantize.
97      */
98     virtual timeT getUnquantizedDuration(Event *e) const;
99 
100     /**
101      * Unquantize all events in the given range, for this
102      * quantizer.  Properties set by other quantizers with
103      * different propertyNamePrefix values will remain.
104      */
105     void unquantize(Segment *,
106                     Segment::iterator from, Segment::iterator to) const;
107 
108     /**
109      * Unquantize a selection of Events
110      */
111     void unquantize(EventSelection *) const;
112 
113     static const std::string RawEventData;
114     static const std::string DefaultTarget;
115     static const std::string GlobalSource;
116     static const std::string NotationPrefix;
117 
118 protected:
119     /**
120      * \arg source, target : Description of where to find the
121      * times to be quantized, and where to put the quantized results.
122      *
123      * These may be strings, specifying a prefix for the names
124      * of properties to contain the timings, or may be the special
125      * value RawEventData in which case the event's absolute time
126      * and duration will be used instead of properties.
127      *
128      * If source specifies a property prefix for properties that are
129      * found not to exist, they will be pre-filled from the original
130      * timings in the target values before being quantized and then
131      * set back into the target.  (This permits a quantizer to write
132      * directly into the Event's absolute time and duration without
133      * losing the original values, because they are backed up
134      * automatically into the source properties.)
135      *
136      * Note that because it's impossible to modify the duration or
137      * absolute time of an event after construction, if target is
138      * RawEventData the quantizer must re-construct each event in
139      * order to adjust its timings.  This operation (deliberately)
140      * loses any non-persistent properties in the events.  This
141      * does not happen if target is a property prefix.
142      *
143      *   Examples:
144      *
145      *   -- if source == RawEventData and target == "MyPrefix",
146      *   values will be read from the event's absolute time and
147      *   duration, quantized, and written into MyPrefixAbsoluteTime
148      *   and MyPrefixDuration properties on the event.  A call to
149      *   unquantize will simply delete these properties.
150      *
151      *   -- if source == "MyPrefix" and target == RawEventData,
152      *   the MyPrefixAbsoluteTime and MyPrefixDuration will be
153      *   populated if necessary from the event's absolute time and
154      *   duration, and then quantized and written back into the
155      *   event's values.  A call to unquantize will write the
156      *   MyPrefix-property timings back into the event's values,
157      *   and delete the MyPrefix properties.
158      *
159      *   -- if source == "YourPrefix" and target == "MyPrefix",
160      *   values will be read from YourPrefixAbsoluteTime and
161      *   YourPrefixDuration, quantized, and written into the
162      *   MyPrefix-properties.  This may be useful for piggybacking
163      *   onto another quantizer's output.
164      *
165      *   -- if source == RawEventData and target == RawEventData,
166      *   values will be read from the event's absolute time and
167      *   duration, quantized, and written back to these values.
168      */
169     Quantizer(std::string source, std::string target);
170 
171     /**
172      * If only target is supplied, source is deduced appropriately
173      * as GlobalSource if target == RawEventData and RawEventData
174      * otherwise.
175      */
176     Quantizer(std::string target);
177 
178     /**
179      * To implement a subclass of Quantizer, you should
180      * override either quantizeSingle (if your quantizer is simple
181      * enough only to have to look at a single event at a time) or
182      * quantizeRange.  The default implementation of quantizeRange
183      * simply calls quantizeSingle on each non-rest event in turn.
184      * The default implementation of quantizeSingle, as you see,
185      * does nothing.
186      *
187      * Note that implementations of these methods should call
188      * getFromSource and setToTarget to get and set the unquantized
189      * and quantized data; they should not query the event properties
190      * or timings directly.
191      *
192      * NOTE: It is vital that ordering is maintained after
193      * quantization.  That is, an event whose absolute time quantizes
194      * to a time t must appear in the original segment before all
195      * events whose times quantize to greater than t.  This means you
196      * must quantize the absolute times of non-note events as well as
197      * notes.  You don't need to worry about quantizing rests,
198      * however; they're only used for notation and will be
199      * automatically recalculated if the notation quantization values
200      * are seen to change.
201      */
202     virtual void quantizeSingle(Segment *,
203                                 Segment::iterator) const { }
204 
205     /**
206      * See note for quantizeSingle.
207      */
208     virtual void quantizeRange(Segment *,
209                                Segment::iterator,
210                                Segment::iterator) const;
211 
212     std::string m_source;
213     std::string m_target;
214     mutable std::pair<timeT, timeT> m_normalizeRegion;
215 
216     enum ValueType { AbsoluteTimeValue = 0, DurationValue = 1 };
217 
218     PropertyName m_sourceProperties[2];
219     PropertyName m_targetProperties[2];
220 
221 public: // should be protected, but gcc-2.95 doesn't like allowing NotationQuantizer::m_impl to access them
222     timeT getFromSource(Event *, ValueType) const;
223     timeT getFromTarget(Event *, ValueType) const;
224     void setToTarget(Segment *, Segment::iterator, timeT t, timeT d) const;
225     mutable std::vector<Event *> m_toInsert;
226 
227 protected:
228     void removeProperties(Event *) const;
229     void removeTargetProperties(Event *) const;
230     void makePropertyNames();
231 
232     void insertNewEvents(Segment *) const;
233 
234 private: // not provided
235     Quantizer(const Quantizer &);
236     Quantizer &operator=(const Quantizer &);
237     bool operator==(const Quantizer &) const;
238     bool operator!=(const Quantizer & c) const;
239 };
240 
241 
242 }
243 
244 #endif
245