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