|
|
|
/*
|
|
|
|
Rosegarden
|
|
|
|
A sequencer and musical notation editor.
|
|
|
|
|
|
|
|
This program is Copyright 2000-2008
|
|
|
|
Guillaume Laurent <glaurent@telegraph-road.org>,
|
|
|
|
Chris Cannam <cannam@all-day-breakfast.com>,
|
|
|
|
Richard Bown <bownie@bownie.com>
|
|
|
|
|
|
|
|
The moral right of the authors to claim authorship of this work
|
|
|
|
has been asserted.
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License as
|
|
|
|
published by the Free Software Foundation; either version 2 of the
|
|
|
|
License, or (at your option) any later version. See the file
|
|
|
|
COPYING included with this distribution for more information.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef QUANTIZER_H
|
|
|
|
#define QUANTIZER_H
|
|
|
|
|
|
|
|
#include "Segment.h"
|
|
|
|
#include "Event.h"
|
|
|
|
#include "NotationTypes.h"
|
|
|
|
#include "FastVector.h"
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
namespace Rosegarden {
|
|
|
|
|
|
|
|
class EventSelection;
|
|
|
|
|
|
|
|
/**
|
|
|
|
The Quantizer class rounds the starting times and durations of note
|
|
|
|
and rest events according to one of a set of possible criteria.
|
|
|
|
*/
|
|
|
|
|
|
|
|
class Quantizer
|
|
|
|
{
|
|
|
|
// define the Quantizer API
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual ~Quantizer();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Quantize a Segment.
|
|
|
|
*/
|
|
|
|
void quantize(Segment *) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Quantize a section of a Segment.
|
|
|
|
*/
|
|
|
|
void quantize(Segment *,
|
|
|
|
Segment::iterator from,
|
|
|
|
Segment::iterator to) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Quantize an EventSelection.
|
|
|
|
*/
|
|
|
|
void quantize(EventSelection *);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Quantize a section of a Segment, and force the quantized
|
|
|
|
* results into the formal absolute time and duration of
|
|
|
|
* the events. This is a destructive operation that should
|
|
|
|
* not be carried out except on a user's explicit request.
|
|
|
|
* (If target is RawEventData, this will do nothing besides
|
|
|
|
* quantize. In this case, but no other, unquantize will
|
|
|
|
* still work afterwards.)
|
|
|
|
*/
|
|
|
|
void fixQuantizedValues(Segment *,
|
|
|
|
Segment::iterator from,
|
|
|
|
Segment::iterator to) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the quantized duration of the event if it has been
|
|
|
|
* quantized -- otherwise just return the unquantized duration.
|
|
|
|
* Do not modify the event.
|
|
|
|
*/
|
|
|
|
virtual timeT getQuantizedDuration(const Event *e) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the quantized absolute time of the event if it has been
|
|
|
|
* quantized -- otherwise just return the unquantized time. Do
|
|
|
|
* not modify the event.
|
|
|
|
*/
|
|
|
|
virtual timeT getQuantizedAbsoluteTime(const Event *e) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the unquantized absolute time of the event --
|
|
|
|
* the absolute time that would be restored by a call to
|
|
|
|
* unquantize.
|
|
|
|
*/
|
|
|
|
virtual timeT getUnquantizedAbsoluteTime(Event *e) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the unquantized absolute time of the event --
|
|
|
|
* the absolute time that would be restored by a call to
|
|
|
|
* unquantize.
|
|
|
|
*/
|
|
|
|
virtual timeT getUnquantizedDuration(Event *e) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unquantize all events in the given range, for this
|
|
|
|
* quantizer. Properties set by other quantizers with
|
|
|
|
* different propertyNamePrefix values will remain.
|
|
|
|
*/
|
|
|
|
void unquantize(Segment *,
|
|
|
|
Segment::iterator from, Segment::iterator to) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unquantize a selection of Events
|
|
|
|
*/
|
|
|
|
void unquantize(EventSelection *) const;
|
|
|
|
|
|
|
|
static const std::string RawEventData;
|
|
|
|
static const std::string DefaultTarget;
|
|
|
|
static const std::string GlobalSource;
|
|
|
|
static const std::string NotationPrefix;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/**
|
|
|
|
* \arg source, target : Description of where to find the
|
|
|
|
* times to be quantized, and where to put the quantized results.
|
|
|
|
*
|
|
|
|
* These may be strings, specifying a prefix for the names
|
|
|
|
* of properties to contain the timings, or may be the special
|
|
|
|
* value RawEventData in which case the event's absolute time
|
|
|
|
* and duration will be used instead of properties.
|
|
|
|
*
|
|
|
|
* If source specifies a property prefix for properties that are
|
|
|
|
* found not to exist, they will be pre-filled from the original
|
|
|
|
* timings in the target values before being quantized and then
|
|
|
|
* set back into the target. (This permits a quantizer to write
|
|
|
|
* directly into the Event's absolute time and duration without
|
|
|
|
* losing the original values, because they are backed up
|
|
|
|
* automatically into the source properties.)
|
|
|
|
*
|
|
|
|
* Note that because it's impossible to modify the duration or
|
|
|
|
* absolute time of an event after construction, if target is
|
|
|
|
* RawEventData the quantizer must re-construct each event in
|
|
|
|
* order to adjust its timings. This operation (deliberately)
|
|
|
|
* loses any non-persistent properties in the events. This
|
|
|
|
* does not happen if target is a property prefix.
|
|
|
|
*
|
|
|
|
* Examples:
|
|
|
|
*
|
|
|
|
* -- if source == RawEventData and target == "MyPrefix",
|
|
|
|
* values will be read from the event's absolute time and
|
|
|
|
* duration, quantized, and written into MyPrefixAbsoluteTime
|
|
|
|
* and MyPrefixDuration properties on the event. A call to
|
|
|
|
* unquantize will simply delete these properties.
|
|
|
|
*
|
|
|
|
* -- if source == "MyPrefix" and target == RawEventData,
|
|
|
|
* the MyPrefixAbsoluteTime and MyPrefixDuration will be
|
|
|
|
* populated if necessary from the event's absolute time and
|
|
|
|
* duration, and then quantized and written back into the
|
|
|
|
* event's values. A call to unquantize will write the
|
|
|
|
* MyPrefix-property timings back into the event's values,
|
|
|
|
* and delete the MyPrefix properties.
|
|
|
|
*
|
|
|
|
* -- if source == "YourPrefix" and target == "MyPrefix",
|
|
|
|
* values will be read from YourPrefixAbsoluteTime and
|
|
|
|
* YourPrefixDuration, quantized, and written into the
|
|
|
|
* MyPrefix-properties. This may be useful for piggybacking
|
|
|
|
* onto another quantizer's output.
|
|
|
|
*
|
|
|
|
* -- if source == RawEventData and target == RawEventData,
|
|
|
|
* values will be read from the event's absolute time and
|
|
|
|
* duration, quantized, and written back to these values.
|
|
|
|
*/
|
|
|
|
Quantizer(std::string source, std::string target);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If only target is supplied, source is deduced appropriately
|
|
|
|
* as GlobalSource if target == RawEventData and RawEventData
|
|
|
|
* otherwise.
|
|
|
|
*/
|
|
|
|
Quantizer(std::string target);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* To implement a subclass of Quantizer, you should
|
|
|
|
* override either quantizeSingle (if your quantizer is simple
|
|
|
|
* enough only to have to look at a single event at a time) or
|
|
|
|
* quantizeRange. The default implementation of quantizeRange
|
|
|
|
* simply calls quantizeSingle on each non-rest event in turn.
|
|
|
|
* The default implementation of quantizeSingle, as you see,
|
|
|
|
* does nothing.
|
|
|
|
*
|
|
|
|
* Note that implementations of these methods should call
|
|
|
|
* getFromSource and setToTarget to get and set the unquantized
|
|
|
|
* and quantized data; they should not query the event properties
|
|
|
|
* or timings directly.
|
|
|
|
*
|
|
|
|
* NOTE: It is vital that ordering is maintained after
|
|
|
|
* quantization. That is, an event whose absolute time quantizes
|
|
|
|
* to a time t must appear in the original segment before all
|
|
|
|
* events whose times quantize to greater than t. This means you
|
|
|
|
* must quantize the absolute times of non-note events as well as
|
|
|
|
* notes. You don't need to worry about quantizing rests,
|
|
|
|
* however; they're only used for notation and will be
|
|
|
|
* automatically recalculated if the notation quantization values
|
|
|
|
* are seen to change.
|
|
|
|
*/
|
|
|
|
virtual void quantizeSingle(Segment *,
|
|
|
|
Segment::iterator) const { }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* See note for quantizeSingle.
|
|
|
|
*/
|
|
|
|
virtual void quantizeRange(Segment *,
|
|
|
|
Segment::iterator,
|
|
|
|
Segment::iterator) const;
|
|
|
|
|
|
|
|
std::string m_source;
|
|
|
|
std::string m_target;
|
|
|
|
mutable std::pair<timeT, timeT> m_normalizeRegion;
|
|
|
|
|
|
|
|
enum ValueType { AbsoluteTimeValue = 0, DurationValue = 1 };
|
|
|
|
|
|
|
|
PropertyName m_sourceProperties[2];
|
|
|
|
PropertyName m_targetProperties[2];
|
|
|
|
|
|
|
|
public: // should be protected, but gcc-2.95 doesn't like allowing NotationQuantizer::m_impl to access them
|
|
|
|
timeT getFromSource(Event *, ValueType) const;
|
|
|
|
timeT getFromTarget(Event *, ValueType) const;
|
|
|
|
void setToTarget(Segment *, Segment::iterator, timeT t, timeT d) const;
|
|
|
|
mutable FastVector<Event *> m_toInsert;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void removeProperties(Event *) const;
|
|
|
|
void removeTargetProperties(Event *) const;
|
|
|
|
void makePropertyNames();
|
|
|
|
|
|
|
|
void insertNewEvents(Segment *) const;
|
|
|
|
|
|
|
|
private: // not provided
|
|
|
|
Quantizer(const Quantizer &);
|
|
|
|
Quantizer &operator=(const Quantizer &);
|
|
|
|
bool operator==(const Quantizer &) const;
|
|
|
|
bool operator!=(const Quantizer & c) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|