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_COMPOSITION_H
17 #define RG_COMPOSITION_H
18 
19 
20 #include "RealTime.h"
21 #include "base/Segment.h"
22 #include "Track.h"
23 #include "Configuration.h"
24 #include "XmlExportable.h"
25 #include "ColourMap.h"
26 #include "TriggerSegment.h"
27 
28 #include "Marker.h"
29 
30 // Qt
31 #include <QtCore/QWeakPointer>
32 
33 // System
34 #include <set>
35 #include <map>
36 
37 namespace Rosegarden
38 {
39 // We store tempo in quarter-notes per minute * 10^5 (hundred
40 // thousandths of a quarter-note per minute).  This means the maximum
41 // tempo in a 32-bit integer is about 21400 qpm.  We use a signed int
42 // for compatibility with the Event integer type -- but note that we
43 // use 0 (rather than -1) to indicate "tempo not set", by convention
44 // (though see usage of target tempo in e.g. addTempoAtTime).
45 typedef int tempoT;
46 
47 class Quantizer;
48 class BasicQuantizer;
49 class NotationQuantizer;
50 
51 class CompositionObserver;
52 
53 /// Composition contains a complete representation of a piece of music.
54 /**
55  * It is a container for multiple Segment objects (m_segments), as well as
56  * any associated non-Event data.
57  *
58  * The Composition owns the Segment objects it holds, and deletes them on
59  * destruction.  See deleteSegment() and detachSegment().
60  */
61 class ROSEGARDENPRIVATE_EXPORT Composition : public XmlExportable
62 {
63     friend class Track; // to call notifyTrackChanged()
64     friend class Segment; // to call notifySegmentRepeatChanged()
65 
66 public:
67     typedef SegmentMultiSet::iterator iterator;
68     typedef SegmentMultiSet::const_iterator const_iterator;
69 
70     typedef std::vector<Segment *> SegmentVec;
71 
72     typedef std::map<TrackId, Track*> trackcontainer;
73     typedef trackcontainer::iterator trackiterator;
74     typedef trackcontainer::const_iterator trackconstiterator;
75 
76     typedef std::vector<Marker*> markercontainer;
77     typedef markercontainer::iterator markeriterator;
78     typedef markercontainer::const_iterator markerconstiterator;
79 
80     typedef std::set<TriggerSegmentRec *, TriggerSegmentCmp> triggersegmentcontainer;
81     typedef triggersegmentcontainer::iterator triggersegmentcontaineriterator;
82     typedef triggersegmentcontainer::const_iterator triggersegmentcontainerconstiterator;
83 
84     typedef std::set<TrackId> recordtrackcontainer;
85     typedef recordtrackcontainer::iterator recordtrackiterator;
86     typedef recordtrackcontainer::const_iterator recordtrackconstiterator;
87 
88     Composition();
89     ~Composition() override;
90 
91 private:
92     Composition(const Composition &);
93     Composition &operator=(const Composition &);
94 public:
95 
96     /**
97      * Remove everything from the Composition.
98      */
99     void clear();
100 
101     /**
102      * Return the absolute end time of the segment that ends last
103      */
104     timeT getDuration() const;
105 
106 
107     //////
108     //
109     // START AND END MARKERS
110 
getStartMarker()111     timeT getStartMarker() const { return m_startMarker; }
getEndMarker()112     timeT getEndMarker() const { return m_endMarker; }
autoExpandEnabled()113     bool autoExpandEnabled() { return m_autoExpand; }
114 
115     void setStartMarker(const timeT &sM);
116     void setEndMarker(const timeT &eM);
setAutoExpand(bool autoExpand)117     void setAutoExpand(bool autoExpand) { m_autoExpand = autoExpand; }
118 
119 
120     //////
121     //
122     //  INSTRUMENT & TRACK
123 
124     Track* getTrackById(TrackId track) const;
125 
126     bool haveTrack(TrackId track) const;
127 
128     Track* getTrackByPosition(int position) const;
129 
130     int getTrackPositionById(TrackId track) const; // -1 if not found
131 
getTracks()132     trackcontainer& getTracks() { return m_tracks; }
133 
getTracks()134     const trackcontainer& getTracks() const { return m_tracks; }
135 
136     // Reset id and position
137     // unused
138 //    void resetTrackIdAndPosition(TrackId oldId, TrackId newId, int position);
139 
140     TrackId getMinTrackId() const;
141     TrackId getMaxTrackId() const;
142 
getRecordTracks()143     const recordtrackcontainer &getRecordTracks() const { return m_recordTracks; }
144     void setTrackRecording(TrackId track, bool recording);
145     bool isTrackRecording(TrackId track) const;
146     bool isInstrumentRecording(InstrumentId instrumentID) const;
147 
148     /**
149      * rename: getSelectedTrackId()
150      *
151      * @see setSelectedTrack()
152      */
getSelectedTrack()153     TrackId getSelectedTrack() const { return m_selectedTrackId; }
154 
155     InstrumentId getSelectedInstrumentId() const;
156 
157     /**
158      * rename: setSelectedTrackId()
159      *
160      * @see getSelectedTrack()
161      */
162     void setSelectedTrack(TrackId trackId);
163 
164     /// Total number of tracks in the composition.
getNbTracks()165     unsigned int getNbTracks() const { return m_tracks.size(); }
166 
167     /**
168      * Clear out the Track container
169      */
170     void clearTracks();
171 
172     /**
173      * Insert a new Track.  The Composition takes over ownership of
174      * the track object.
175      */
176     void addTrack(Track *track);
177 
178     /**
179      * Delete a Track by index
180      */
181     // unused
182 //    void deleteTrack(TrackId track);
183 
184     /**
185      * Detach a Track (revert ownership of the Track object to the
186      * caller).
187      */
188     bool detachTrack(Track *track);
189 
190     /**
191      * Get the highest running track id (generated and kept
192      * through addTrack)
193      */
194     TrackId getNewTrackId() const;
195 
196     bool hasTrack(InstrumentId) const;
197 
198     /**
199      * Get the Instrument Id of a given segment.
200      **/
getInstrumentId(const Segment * segment)201     InstrumentId getInstrumentId(const Segment *segment) const {
202         if (!segment)
203             return NoInstrument;
204 
205         const Track *track = getTrackById(segment->getTrack());
206         if (!track)
207             return NoInstrument;
208 
209         return track->getInstrument();
210     };
211 
212     /**
213      * Get all segments that play on the same instrument segment s
214      * plays on and start before t.
215      */
216     SegmentMultiSet getInstrumentSegments(Segment *s, timeT t) const;
217 
218     //////
219     //
220     // MARKERS
221 
getMarkers()222     markercontainer& getMarkers() { return m_markers; }
getMarkers()223     const markercontainer& getMarkers() const { return m_markers; }
224 
225     /**
226      * Add a new Marker.  The Composition takes ownership of the
227      * marker object.
228      */
229     void addMarker(Marker *marker);
230 
231     /**
232      * Detach a Marker (revert ownership of the Marker object to the
233      * caller).
234      */
235     bool detachMarker(Marker *marker);
236 
237     // unused
238 //    bool isMarkerAtPosition(timeT time) const;
239 
240     void clearMarkers();
241 
242 
243     //////
244     //
245     //  SEGMENT
246 
getSegments()247     SegmentMultiSet& getSegments() { return m_segments; }
getSegments()248     const SegmentMultiSet& getSegments() const { return m_segments; }
249 
250     Segment* getSegmentByMarking(const QString& Marking) const;
251 
getNbSegments()252     unsigned int getNbSegments() const { return m_segments.size(); }
253 
254     /**
255      * Add a new Segment and return an iterator pointing to it
256      * The inserted Segment is owned by the Composition object
257      */
258     iterator addSegment(Segment*);
259 
260     /**
261      * Delete the Segment pointed to by the specified iterator
262      *
263      * NOTE: The Segment is deleted from the Composition and
264      * destroyed
265      */
266     void deleteSegment(iterator);
267 
268     /**
269      * Delete the Segment if it is part of the Composition
270      * \return true if the Segment was found and deleted
271      *
272      * NOTE: The Segment is deleted from the composition and
273      * destroyed
274      */
275     bool deleteSegment(Segment*);
276 
277     /**
278      * DO NOT USE THIS METHOD
279      *
280      * Set a Segment's start time while keeping the integrity of the
281      * Composition multiset.
282      *
283      * The segment is removed and re-inserted from the composition
284      * so the ordering is preserved.
285      */
286     void setSegmentStartTime(Segment*, timeT);
287 
288     /**
289      * Test whether a Segment exists in this Composition.
290      */
291     bool contains(const Segment *);
292 
293     /**
294      * Return an iterator pointing at the given Segment, or end()
295      * if it does not exist in this Composition.
296      */
297     iterator findSegment(const Segment *);
298 
299     /**
300      * Remove the Segment if it is part of the Composition,
301      * but do not destroy it (passing it to addSegment again
302      * would restore it correctly).
303      * \return true if the Segment was found and removed
304      *
305      * NOTE: Many of the Segment methods will fail if the
306      * Segment is not in a Composition.  You should not
307      * expect to do anything meaningful with a Segment that
308      * has been detached from the Composition in this way.
309      */
310     bool detachSegment(Segment*);
311 
312     /**
313      * Add a new Segment which has been "weakly detached"
314      *
315      * Like addSegment(), but doesn't send the segmentAdded signal
316      * nor updating refresh statuses
317      */
318     iterator weakAddSegment(Segment*);
319 
320     /**
321      * Detach a segment which you're going to re-add (with weakAddSegment)
322      * later.
323      * Like detachSegment(), but without sending the segmentDeleted signal
324      * nor updating refresh statuses.
325      */
326     bool weakDetachSegment(Segment*);
327 
328     /**
329      * Get the largest number of segments that "overlap" at any one
330      * time on the given track.  I have given this function a nice
331      * long name to make it feel important.
332      */
333     int getMaxContemporaneousSegmentsOnTrack(TrackId track) const;
334 
335     /**
336      * Retrieve a "vertical" index for this segment within its track.
337      * Currently this is based on studying the way that segments on
338      * the track overlap and returning the lowest integer such that no
339      * prior starting segment that overlaps with this one would use
340      * the same integer.  In future this could use proper voice
341      * ordering.
342      */
343     int getSegmentVoiceIndex(const Segment *) const;
344 
345     /**
346      * Add every segment in SegmentMultiSet
347      */
348     void addAllSegments(SegmentMultiSet segments);
349     void addAllSegments(SegmentVec segments);
350 
351     /**
352      * Detach every segment in SegmentMultiSet
353      */
354     void detachAllSegments(SegmentMultiSet segments);
355     void detachAllSegments(SegmentVec segments);
356 
357     //////
358     //
359     //  TRIGGER SEGMENTS
360 
getTriggerSegments()361     triggersegmentcontainer &getTriggerSegments() { return m_triggerSegments; }
getTriggerSegments()362     const triggersegmentcontainer &getTriggerSegments() const { return m_triggerSegments; }
363 
364     /**
365      * Add a new trigger Segment with a given base pitch and base
366      * velocity, and return its record.  If pitch or velocity is -1,
367      * it will be taken from the first note event in the segment
368      */
369     TriggerSegmentRec *addTriggerSegment(Segment *, int pitch = -1, int velocity = -1);
370 
371     /**
372      * Delete a trigger Segment.
373      */
374     void deleteTriggerSegment(TriggerSegmentId);
375 
376     /**
377      * Detach a trigger Segment from the Composition.
378      */
379     void detachTriggerSegment(TriggerSegmentId);
380 
381     /**
382      * Delete all trigger Segments.
383      */
384     void clearTriggerSegments();
385 
386     /**
387      * Return the TriggerSegmentId for the given Segment, or -1 if it is
388      * not a trigger Segment.
389      */
390     int getTriggerSegmentId(Segment *);
391 
392     /**
393      * Return the Segment for a given TriggerSegmentId
394      */
395     Segment *getTriggerSegment(TriggerSegmentId);
396 
397     /**
398      * Return the TriggerSegmentRec (with Segment, base pitch, base velocity,
399      * references etc) for a given TriggerSegmentId
400      */
401     TriggerSegmentRec *getTriggerSegmentRec(TriggerSegmentId);
402 
403     /**
404      * As above for a given Event, or nullptr if none.
405      **/
406     TriggerSegmentRec *getTriggerSegmentRec(Event* e);
407     /**
408      * Add a new trigger Segment with a given ID and base pitch and
409      * velocity.  Fails and returns 0 if the ID is already in use.
410      * This is intended for use from file load or from undo/redo.
411      */
412     TriggerSegmentRec *addTriggerSegment(Segment *, TriggerSegmentId,
413                                          int basePitch = -1, int baseVelocity = -1);
414 
415     /**
416      * Get the ID of the next trigger segment that will be inserted.
417      */
418     TriggerSegmentId getNextTriggerSegmentId() const;
419 
420     /**
421      * Specify the next trigger ID.  This is intended for use from file
422      * load only.  Do not use this function unless you know what you're
423      * doing.
424      */
425     void setNextTriggerSegmentId(TriggerSegmentId);
426 
427     /**
428      * Update the trigger segment references for all trigger segments.
429      * To be called after file load.
430      */
431     void updateTriggerSegmentReferences();
432 
433     /**
434      * Clear refresh statuses of SegmentLinker after file load.
435      */
436     void resetLinkedSegmentRefreshStatuses();
437 
438     //////
439     //
440     //  BAR
441 
442     /**
443      * Return the total number of bars in the composition
444      */
445     int getNbBars() const;
446 
447     /**
448      * Return the number of the bar that starts at or contains time t.
449      *
450      * Will happily return computed bar numbers for times before
451      * the start or beyond the real end of the composition.
452      */
453     int getBarNumber(timeT t) const;
454 
455     /**
456      * Return the starting time of bar n
457      */
getBarStart(int n)458     timeT getBarStart(int n) const {
459         return getBarRange(n).first;
460     }
461 
462     /**
463      * Return the ending time of bar n
464      */
getBarEnd(int n)465     timeT getBarEnd(int n) const {
466         return getBarRange(n).second;
467     }
468 
469     /**
470      * Return the time range of bar n.
471      *
472      * Will happily return theoretical timings for bars before the
473      * start or beyond the end of composition (i.e. there is no
474      * requirement that 0 <= n < getNbBars()).
475      */
476     std::pair<timeT, timeT> getBarRange(int n) const;
477 
478     /**
479      * Return the starting time of the bar that contains time t
480      */
getBarStartForTime(timeT t)481     timeT getBarStartForTime(timeT t) const {
482         return getBarRangeForTime(t).first;
483     }
484 
485     /**
486      * Return the ending time of the bar that contains time t
487      */
getBarEndForTime(timeT t)488     timeT getBarEndForTime(timeT t) const {
489         return getBarRangeForTime(t).second;
490     }
491 
492     /**
493      * Return the starting and ending times of the bar that contains
494      * time t.
495      *
496      * Will happily return theoretical timings for bars before the
497      * start or beyond the end of composition.
498      *
499      * ??? typedef std::pair<timeT, timeT> BarRange;
500      */
501     std::pair<timeT, timeT> getBarRangeForTime(timeT t) const;
502 
503 
504     //////
505     //
506     //  TIME SIGNATURE
507 
508     /**
509      * Add the given time signature at the given time.  Returns the
510      * resulting index of the time signature (suitable for passing
511      * to removeTimeSignature, for example)
512      */
513     int addTimeSignature(timeT t, TimeSignature timeSig);
514 
515     /**
516      * Return the time signature in effect at time t
517      */
518     TimeSignature getTimeSignatureAt(timeT t) const;
519 
520     /**
521      * Return the time signature in effect at time t, and the time at
522      * which it came into effect
523      */
524     timeT getTimeSignatureAt(timeT, TimeSignature &) const;
525 
526     /**
527      * Return the time signature in effect in bar n.  Also sets
528      * isNew to true if the time signature is a new one that did
529      * not appear in the previous bar.
530      */
531     TimeSignature getTimeSignatureInBar(int n, bool &isNew) const;
532 
533     /**
534      * Return the total number of time signature changes in the
535      * composition.
536      */
537     int getTimeSignatureCount() const;
538 
539     /**
540      * Return the index of the last time signature change before
541      * or at the given time, in a range suitable for passing to
542      * getTimeSignatureChange.  Return -1 if there has been no
543      * time signature by this time.
544      */
545     int getTimeSignatureNumberAt(timeT time) const;
546 
547     /**
548      * Return the absolute time of and time signature introduced
549      * by time-signature change n.
550      */
551     std::pair<timeT, TimeSignature> getTimeSignatureChange(int n) const;
552 
553     /**
554      * Remove time signature change event n from the composition.
555      */
556     void removeTimeSignature(int n);
557 
558 
559 
560     //////
561     //
562     //  TEMPO
563 
564     /**
565      * Return the (approximate) number of quarters per minute for a
566      * given tempo.
567      */
getTempoQpm(tempoT tempo)568     static double getTempoQpm(tempoT tempo) { return double(tempo) / 100000.0; }
getTempoForQpm(double qpm)569     static tempoT getTempoForQpm(double qpm) { return tempoT(qpm * 100000 + 0.01); }
570 
571     /**
572      * Return the tempo in effect at time t.  If a ramped tempo change
573      * is in effect at the time, it will be properly interpolated and
574      * a computed value returned.
575      */
576     tempoT getTempoAtTime(timeT t) const;
577 
578     /**
579      * Return the tempo in effect at the current playback position.
580      */
getCurrentTempo()581     tempoT getCurrentTempo() const { return getTempoAtTime(getPosition()); }
582 
583     /**
584      * Set a default tempo for the composition.  This will be
585      * overridden by any tempo events encountered during playback.
586      */
setCompositionDefaultTempo(tempoT tempo)587     void setCompositionDefaultTempo(tempoT tempo) { m_defaultTempo = tempo; }
getCompositionDefaultTempo()588     tempoT getCompositionDefaultTempo() const { return m_defaultTempo; }
589 
590     /**
591      * Add a tempo-change event at the given time, to the given tempo.
592      * Removes any existing tempo event at that time.  Returns the
593      * index of the new tempo event in a form suitable for passing to
594      * removeTempoChange.
595      *
596      * If targetTempo == -1, adds a single constant tempo change.
597      * If targetTempo == 0, adds a smooth tempo ramp from this tempo
598      * change to the next.
599      * If targetTempo > 0, adds a smooth tempo ramp from this tempo
600      * ending at targetTempo at the time of the next tempo change.
601      */
602     int addTempoAtTime(timeT time, tempoT tempo, tempoT targetTempo = -1);
603 
604     /**
605      * Return the number of tempo changes in the composition.
606      */
607     int getTempoChangeCount() const;
608 
609     /**
610      * Return the index of the last tempo change before the given
611      * time, in a range suitable for passing to getTempoChange.
612      * Return -1 if the default tempo is in effect at this time.
613      */
614     int getTempoChangeNumberAt(timeT time) const;
615 
616     /**
617      * Return the absolute time of and tempo introduced by tempo
618      * change number n.  If the tempo is ramped, this returns only
619      * the starting tempo.
620      */
621     std::pair<timeT, tempoT> getTempoChange(int n) const;
622 
623     /**
624      * Return whether the tempo change number n is a ramped tempo or
625      * not, and if it is, return the target tempo for the ramp.
626      *
627      * If calculate is false, return a target tempo of 0 if the tempo
628      * change is defined to ramp to the following tempo.  If calculate
629      * is true, return a target tempo equal to the following tempo in
630      * this case.
631      */
632     std::pair<bool, tempoT> getTempoRamping(int n, bool calculate = true) const;
633 
634     /**
635      * Remove tempo change event n from the composition.
636      */
637     void removeTempoChange(int n);
638 
639     /**
640      * Get the slowest assigned tempo in the composition.
641      */
getMinTempo()642     tempoT getMinTempo() const {
643         return ((m_minTempo != 0) ? m_minTempo : m_defaultTempo);
644     }
645 
646     /**
647      * Get the fastest assigned tempo in the composition.
648      */
getMaxTempo()649     tempoT getMaxTempo() const {
650         return ((m_maxTempo != 0) ? m_maxTempo : m_defaultTempo);
651     }
652 
653 
654     //////
655     //
656     //  REAL TIME
657 
658     /**
659      * Return the number of microseconds elapsed between
660      * the beginning of the composition and the given timeT time.
661      * (timeT units are independent of tempo; this takes into
662      * account any tempo changes in the first t units of time.)
663      *
664      * This is a fairly efficient operation, not dependent on the
665      * magnitude of t or the number of tempo changes in the piece.
666      */
667     RealTime getElapsedRealTime(timeT t) const;
668 
669     /**
670      * Return the nearest time in timeT units to the point at the
671      * given number of microseconds after the beginning of the
672      * composition.  (timeT units are independent of tempo; this takes
673      * into account any tempo changes in the first t microseconds.)
674      * The result will be approximate, as timeT units are obviously
675      * less precise than microseconds.
676      *
677      * This is a fairly efficient operation, not dependent on the
678      * magnitude of t or the number of tempo changes in the piece.
679      */
680     timeT getElapsedTimeForRealTime(RealTime t) const;
681 
682     /**
683      * Return the number of microseconds elapsed between
684      * the two given timeT indices into the composition, taking
685      * into account any tempo changes between the two times.
686      */
getRealTimeDifference(timeT t0,timeT t1)687     RealTime getRealTimeDifference(timeT t0, timeT t1) const {
688         if (t1 > t0) return getElapsedRealTime(t1) - getElapsedRealTime(t0);
689         else         return getElapsedRealTime(t0) - getElapsedRealTime(t1);
690     }
691 
692     static tempoT
693         timeRatioToTempo(RealTime &realTime,
694                          timeT beatTime, tempoT rampTo);
695 
696     //////
697     //
698     //  OTHER TIME CONVERSIONS
699 
700     /**
701      * Return (by reference) the bar number and beat/division values
702      * corresponding to a given absolute time.
703      */
704     void getMusicalTimeForAbsoluteTime(timeT absoluteTime,
705                                        int &bar, int &beat,
706                                        int &fraction, int &remainder);
707 
708     /**
709      * Return (by reference) the number of bars and beats/divisions
710      * corresponding to a given duration.  The absolute time at which
711      * the duration starts is also required, so as to know the correct
712      * time signature.
713      */
714     void getMusicalTimeForDuration(timeT absoluteTime, timeT duration,
715                                    int &bars, int &beats,
716                                    int &fractions, int &remainder);
717 
718     /**
719      * Return the absolute time corresponding to a given bar number
720      * and beat/division values.
721      */
722     timeT getAbsoluteTimeForMusicalTime(int bar, int beat,
723                                         int fraction, int remainder);
724 
725     /**
726      * Return the duration corresponding to a given number of bars and
727      * beats/divisions.  The absolute time at which the duration
728      * starts is also required, so as to know the correct time
729      * signature.
730      */
731     timeT getDurationForMusicalTime(timeT absoluteTime,
732                                     int bars, int beats,
733                                     int fractions, int remainder);
734 
735 
736     /**
737      * Get the current playback position.
738      */
getPosition()739     timeT getPosition() const { return m_position; }
740 
741     /**
742      * Set the current playback position.
743      */
744     void setPosition(timeT position);
745 
746 
747 
748     //////
749     //
750     // LOOP
751 
getLoopStart()752     timeT getLoopStart() const { return m_loopStart; }
getLoopEnd()753     timeT getLoopEnd() const { return m_loopEnd;}
754 
setLoopStart(const timeT & lS)755     void setLoopStart(const timeT &lS) { m_loopStart = lS; }
setLoopEnd(const timeT & lE)756     void setLoopEnd(const timeT &lE) { m_loopEnd = lE; }
757 
758     // Determine if we're currently looping
759     //
isLooping()760     bool isLooping() const { return (m_loopStart != m_loopEnd); }
761 
762 
763 
764     //////
765     //
766     // OTHER STUFF
767 
768 
769     // Some set<> API delegation
770     /// Segment begin iterator.
begin()771     iterator       begin()       { return m_segments.begin(); }
772     /// Segment begin iterator.
begin()773     const_iterator begin() const { return m_segments.begin(); }
774     /// Segment end iterator.
end()775     iterator       end()         { return m_segments.end(); }
776     /// Segment end iterator.
end()777     const_iterator end() const   { return m_segments.end(); }
778 
779 
780     // XML exportable method
781     //
782     std::string toXmlString() const override;
783 
784     // Who's making this racket?
785     //
getMetadata()786     Configuration &getMetadata() {
787         return m_metadata;
788     }
getMetadata()789     const Configuration &getMetadata() const {
790         return m_metadata;
791     }
792 
getCopyrightNote()793     std::string getCopyrightNote() const {
794         return m_metadata.get<String>(CompositionMetadataKeys::Copyright,
795                                       "");
796     }
setCopyrightNote(const std::string & cr)797     void setCopyrightNote(const std::string &cr) {
798         m_metadata.set<String>(CompositionMetadataKeys::Copyright, cr);
799     }
800 
801 
802     // We can have the metronome on or off while playing or
803     // recording - get and set values from here
804     //
usePlayMetronome()805     bool usePlayMetronome() const { return m_playMetronome; }
useRecordMetronome()806     bool useRecordMetronome() const { return m_recordMetronome; }
807 
808     void setPlayMetronome(bool value);
809     void setRecordMetronome(bool value);
810 
811 
812     // Colour stuff
getSegmentColourMap()813     ColourMap& getSegmentColourMap() { return m_segmentColourMap; }
getSegmentColourMap()814     const ColourMap& getSegmentColourMap() const { return m_segmentColourMap; }
815     void setSegmentColourMap(ColourMap &newmap);
816 
817     // General colourmap for non-segments
818     //
getGeneralColourMap()819     ColourMap& getGeneralColourMap() { return m_generalColourMap; }
820     void setGeneralColourMap(ColourMap &newmap);
821 
822     /// NotationView spacing
823     int m_notationSpacing;
824 
825 
826     //////
827     //
828     // QUANTIZERS
829 
830     /**
831      * Return a quantizer that quantizes to the our most basic
832      * units (i.e. a unit quantizer whose unit is our shortest
833      * note duration).
834      */
getBasicQuantizer()835     const BasicQuantizer *getBasicQuantizer() const {
836         return m_basicQuantizer;
837     }
838 
839     /**
840      * Return a quantizer that does quantization for notation
841      * only.
842      */
getNotationQuantizer()843     const NotationQuantizer *getNotationQuantizer() const {
844         return m_notationQuantizer;
845     }
846 
847 
848     //////
849     //
850     // REFRESH STATUS
851 
852     // delegate RefreshStatusArray API
getNewRefreshStatusId()853     unsigned int getNewRefreshStatusId() {
854         return m_refreshStatusArray.getNewRefreshStatusId();
855     }
856 
getRefreshStatus(unsigned int id)857     RefreshStatus& getRefreshStatus(unsigned int id) {
858         return m_refreshStatusArray.getRefreshStatus(id);
859     }
860 
861     /// Set all refresh statuses to true
updateRefreshStatuses()862     void updateRefreshStatuses() {
863         m_refreshStatusArray.updateRefreshStatuses();
864     }
865 
866 
867     /// Change notification mechanism.
868     /// @see removeObserver()
869     /// @see notifyTracksAdded()
addObserver(CompositionObserver * obs)870     void    addObserver(CompositionObserver *obs) { m_observers.push_back(obs); }
871     /// Change notification mechanism.
872     /// @see addObserver()
removeObserver(CompositionObserver * obs)873     void removeObserver(CompositionObserver *obs) { m_observers.remove(obs); }
874 
875     /// Change notification mechanism.
876     /**
877      * See the various other "notify*" functions.
878      *
879      * These functions have been made public in the interests of improving
880      * performance.  There are at least two main approaches to sending change
881      * notifications to observers.  The first is to have each modifier
882      * function (e.g. deleteTrack()) send the change notification.  The second
883      * is to make the change notification functions public and let the code
884      * that modifies the object also call the change notification function.
885      * The first approach is convenient and less likely to be forgotten.  The
886      * second approach has the advantage of performance in situations where
887      * there are many changes being made at once.  All of the changes can be
888      * made, then a single notification can be sent out once the changes are
889      * complete.  With the first approach, many change notifications might get
890      * sent out, each of which might lead to a potentially costly UI update.
891      */
892     void notifyTracksAdded(std::vector<TrackId> trackIds) const;
893     /// Change notification mechanism.
894     /**
895      * @see notifyTracksAdded()
896      */
897     void notifyTrackChanged(Track*);
898     /// Change notification mechanism.
899     /**
900      * @see notifyTracksAdded()
901      */
902     void notifyTracksDeleted(std::vector<TrackId> trackIds) const;
903     /// Call when the selected track is changed.
904     /**
905      * @see setSelectedTrack()
906      * @see notifyTracksAdded()
907      */
908     void notifyTrackSelectionChanged(TrackId) const;
909 
910     //////
911     // LYRICS WITH REPEATED SEGMENTS
912     void distributeVerses();
913 
914     //////
915     // DEBUG FACILITIES
916     void dump() const;
917 
918 protected:
919 
920     static const std::string TempoEventType;
921     static const PropertyName TempoProperty;
922     static const PropertyName TargetTempoProperty;
923 
924     static const PropertyName NoAbsoluteTimeProperty;
925     static const PropertyName BarNumberProperty;
926     static const PropertyName TempoTimestampProperty;
927 
928 
929     struct ReferenceSegmentEventCmp
930     {
931         bool operator()(const Event &e1, const Event &e2) const;
operatorReferenceSegmentEventCmp932         bool operator()(const Event *e1, const Event *e2) const {
933             return operator()(*e1, *e2);
934         }
935     };
936 
937     struct BarNumberComparator
938     {
operatorBarNumberComparator939         bool operator()(const Event &e1, const Event &e2) const {
940             return (e1.get<Int>(BarNumberProperty) <
941                     e2.get<Int>(BarNumberProperty));
942         }
operatorBarNumberComparator943         bool operator()(const Event *e1, const Event *e2) const {
944             return operator()(*e1, *e2);
945         }
946     };
947 
948     /**
949      * Ensure the selected and record trackids still point to something valid
950      * Must be called after deletion of detach of a track
951      */
952     void checkSelectedAndRecordTracks();
953     TrackId getClosestValidTrackId(TrackId id) const;
954 
955 
956     //--------------- Data members ---------------------------------
957     //
958     trackcontainer m_tracks;
959     SegmentMultiSet m_segments;
960 
961     // The tracks we are armed for record on
962     //
963     recordtrackcontainer m_recordTracks;
964 
965     TrackId m_selectedTrackId;
966 
967     /**
968      * This is a bit like a segment, but can only contain one sort of
969      * event, and can only have one event at each absolute time
970      */
971     class ReferenceSegment
972     {
973 
974     public:
975         ReferenceSegment(std::string eventType);
976         ~ReferenceSegment();
977     private:
978         ReferenceSegment(const ReferenceSegment &);
979         ReferenceSegment& operator=(const ReferenceSegment &);
980     public:
981         typedef std::vector<Event*>::size_type size_type;
982         typedef std::vector<Event*>::iterator iterator;
983         typedef std::vector<Event*>::const_iterator const_iterator;
984 
985         iterator begin();
986         const_iterator begin() const;
987         iterator end();
988         const_iterator end() const;
989 
990         size_type size() const;
991         bool empty() const;
992         iterator erase(iterator position);
993         void clear();
994 
995         Event* operator[] (size_type n);
996         const Event* operator[] (size_type n) const;
997 
998         timeT getDuration() const;
999 
1000         /// Inserts a single event, removing any existing one at that time
1001         iterator insertEvent(Event *e); // may throw Event::BadType
1002 
1003         void eraseEvent(Event *e);
1004 
1005         iterator findTime(timeT time);
1006         iterator findNearestTime(timeT time);
1007 
1008         iterator findRealTime(RealTime time);
1009         iterator findNearestRealTime(RealTime time);
1010 
getEventType()1011         std::string getEventType() const { return m_eventType; }
1012 
1013     private:
1014         iterator find(Event *e);
1015         std::string m_eventType;
1016         // not a set: want random access for bars
1017         std::vector<Event*> m_events;
1018     };
1019 
1020     /// Contains time signature events
1021     mutable ReferenceSegment m_timeSigSegment;
1022 
1023     /// Contains tempo events
1024     mutable ReferenceSegment m_tempoSegment;
1025 
1026     /// affects m_timeSigSegment
1027     void calculateBarPositions() const;
1028     mutable bool m_barPositionsNeedCalculating;
1029     ReferenceSegment::iterator getTimeSignatureAtAux(timeT t) const;
1030 
1031     /// affects m_tempoSegment
1032     void calculateTempoTimestamps() const;
1033     mutable bool m_tempoTimestampsNeedCalculating;
1034     RealTime time2RealTime(timeT time, tempoT tempo) const;
1035     RealTime time2RealTime(timeT time, tempoT tempo,
1036                            timeT targetTempoTime, tempoT targetTempo) const;
1037     timeT realTime2Time(RealTime rtime, tempoT tempo) const;
1038     timeT realTime2Time(RealTime rtime, tempoT tempo,
1039                         timeT targetTempoTime, tempoT targetTempo) const;
1040     bool getTempoTarget(ReferenceSegment::const_iterator i,
1041                         tempoT &target,
1042                         timeT &targetTime) const;
1043 
1044     static RealTime getTempoTimestamp(const Event *e);
1045     static void setTempoTimestamp(Event *e, RealTime r);
1046 
1047     /// No more than one armed track per instrument.
1048     void enforceArmRule(const Track *track);
1049 
1050     typedef std::list<CompositionObserver *> ObserverSet;
1051     ObserverSet m_observers;
1052 
1053     void notifySegmentAdded(Segment *) const;
1054     void notifySegmentRemoved(Segment *) const;
1055     void notifySegmentRepeatChanged(Segment *, bool) const;
1056     void notifySegmentRepeatEndChanged(Segment *, timeT) const;
1057     void notifySegmentEventsTimingChanged(Segment *s, timeT delay, RealTime rtDelay) const;
1058     void notifySegmentTransposeChanged(Segment *s, int transpose) const;
1059     void notifySegmentTrackChanged(Segment *s, TrackId oldId, TrackId newId) const;
1060     void notifySegmentStartChanged(Segment *, timeT);
1061     void notifySegmentEndMarkerChange(Segment *s, bool shorten);
1062     void notifyEndMarkerChange(bool shorten) const;
1063     void notifyMetronomeChanged() const;
1064     void notifyTimeSignatureChanged() const;
1065     void notifyTempoChanged() const;
1066     void notifySelectedTrackChanged() const;
1067     void notifySourceDeletion() const;
1068 
1069     void clearVoiceCaches();
1070     void rebuildVoiceCaches() const;
1071 
1072     void updateExtremeTempos();
1073 
1074     BasicQuantizer                   *m_basicQuantizer;
1075     NotationQuantizer                *m_notationQuantizer;
1076 
1077     timeT                             m_position;
1078     tempoT                            m_defaultTempo;
1079     tempoT                            m_minTempo; // cached from tempo segment
1080     tempoT                            m_maxTempo; // cached from tempo segment
1081 
1082     // Notional Composition markers - these define buffers for the
1083     // start and end of the piece, Segments can still exist outside
1084     // of these markers - these are for visual and playback cueing.
1085     //
1086     timeT                             m_startMarker;
1087     timeT                             m_endMarker;
1088     bool                              m_autoExpand;
1089 
1090     // Loop start and end positions.  If they're both the same
1091     // value (usually 0) then there's no loop set.
1092     //
1093     timeT                             m_loopStart;
1094     timeT                             m_loopEnd;
1095 
1096     Configuration                     m_metadata;
1097 
1098     bool                              m_playMetronome;
1099     bool                              m_recordMetronome;
1100 
1101     RefreshStatusArray<RefreshStatus> m_refreshStatusArray;
1102 
1103     // User defined markers in the composition
1104     //
1105     markercontainer                   m_markers;
1106 
1107     // Trigger segments (unsorted segments fired by events elsewhere)
1108     //
1109     triggersegmentcontainer           m_triggerSegments;
1110     TriggerSegmentId                  m_nextTriggerSegmentId;
1111 
1112     ColourMap                         m_segmentColourMap;
1113     ColourMap                         m_generalColourMap;
1114 
1115     // Caches of segment voice indices and track voice counts
1116     //
1117     mutable std::map<TrackId, int>    m_trackVoiceCountCache;
1118     mutable std::map<const Segment *, int>  m_segmentVoiceIndexCache;
1119 };
1120 
1121 
1122 /// Base class for those that want notification of Composition changes.
1123 /**
1124  * If you subclass from CompositionObserver, you can then attach to a
1125  * Composition to receive notification when something changes.
1126  *
1127  * Normally all the methods in this class would be pure virtual.  But
1128  * because there are so many, that imposes far too much work on the
1129  * subclass implementation in a case where it only really wants to
1130  * know about one thing, such as segments being deleted.  So we have
1131  * empty default implementations, and you'll just have to take a bit
1132  * more care to make sure you really are making the correct
1133  * declarations in the subclass.
1134  */
1135 class CompositionObserver
1136 {
1137 public:
CompositionObserver()1138     CompositionObserver() : m_compositionDeleted(false)  { }
1139 
~CompositionObserver()1140     virtual ~CompositionObserver()  { }
1141 
1142     /// A segment has been added to the Composition.
segmentAdded(const Composition *,Segment *)1143     virtual void segmentAdded(const Composition *, Segment *) { }
1144 
1145     /// A Segment has been removed from the Composition.
1146     /**
1147      * Called before the Segment is deleted.
1148      */
segmentRemoved(const Composition *,Segment *)1149     virtual void segmentRemoved(const Composition *, Segment *) { }
1150 
1151     /// The Segment's repeat status has changed
segmentRepeatChanged(const Composition *,Segment *,bool)1152     virtual void segmentRepeatChanged(const Composition *, Segment *, bool) { }
1153 
1154     /// The Segment's repeat end time has changed.
segmentRepeatEndChanged(const Composition *,Segment *,timeT)1155     virtual void segmentRepeatEndChanged(const Composition *, Segment *, timeT) { }
1156 
1157     /// The Segment's delay timing has changed.
segmentEventsTimingChanged(const Composition *,Segment *,timeT,RealTime)1158     virtual void segmentEventsTimingChanged(const Composition *, Segment *,
1159                                             timeT /* delay */,
1160                                             RealTime /* rtDelay */) { }
1161 
1162     /// The Segment's transpose value has changed
segmentTransposeChanged(const Composition *,Segment *,int)1163     virtual void segmentTransposeChanged(const Composition *, Segment *,
1164                                          int /* transpose */) { }
1165 
1166     /// The Segment's start time has changed.
segmentStartChanged(const Composition *,Segment *,timeT)1167     virtual void segmentStartChanged(const Composition *, Segment *,
1168 				     timeT /* newStartTime */) { }
1169 
1170     /// The Segment's end marker time has changed
segmentEndMarkerChanged(const Composition *,Segment *,bool)1171     virtual void segmentEndMarkerChanged(const Composition *, Segment *,
1172                                          bool /* shorten */) { }
1173 
1174     /// The Segment's track has changed.
segmentTrackChanged(const Composition *,Segment *,TrackId)1175     virtual void segmentTrackChanged(const Composition *, Segment *,
1176                                      TrackId) { }
1177 
1178     /// The Composition's end time has been changed.
1179     /**
1180      * ??? rename: endTimeChanged() to differentiate from SegmentObserver.
1181      */
endMarkerTimeChanged(const Composition *,bool)1182     virtual void endMarkerTimeChanged(const Composition *,
1183                                       bool /* shorten */) { }
1184 
1185     /// A different track has been selected.
1186     /**
1187      * This can happen when the user clicks on a track label, or presses
1188      * the up/down arrow keys to change which track is currently selected.
1189      *
1190      * See selectedTrackChanged().
1191      */
trackSelectionChanged(const Composition *,TrackId)1192     virtual void trackSelectionChanged(const Composition *, TrackId) { }
1193 
1194     /// A Track has changed (instrument id, muted status...)
trackChanged(const Composition *,Track *)1195     virtual void trackChanged(const Composition *, Track *) { }
1196 
tracksDeleted(const Composition *,std::vector<TrackId> &)1197     virtual void tracksDeleted(const Composition *,
1198                                std::vector<TrackId> & /*trackIds*/) { }
1199 
tracksAdded(const Composition *,std::vector<TrackId> &)1200     virtual void tracksAdded(const Composition *,
1201                              std::vector<TrackId> & /*trackIds*/) { }
1202 
1203     /// Some time signature has changed.
timeSignatureChanged(const Composition *)1204     virtual void timeSignatureChanged(const Composition *) { }
1205 
1206     /// Metronome status has changed (on/off)
metronomeChanged(const Composition *)1207     virtual void metronomeChanged(const Composition *) { }
1208 
tempoChanged(const Composition *)1209     virtual void tempoChanged(const Composition *) { }
1210 
1211     /// Like trackChanged() but for the Track that is selected.
1212     /**
1213      * This avoids the need to check the TrackId with trackChanged().
1214      *
1215      * See trackChanged().
1216      *
1217      * ??? We can probably get rid of this easily and just use
1218      *     trackChanged().
1219      */
selectedTrackChanged(const Composition *)1220     virtual void selectedTrackChanged(const Composition *) { }
1221 
1222 
1223     /// Called from the Composition dtor.
compositionDeleted(const Composition *)1224     virtual void compositionDeleted(const Composition *) {
1225         m_compositionDeleted = true;
1226     }
1227 
isCompositionDeleted()1228     bool isCompositionDeleted()  { return m_compositionDeleted; }
1229 
1230 protected:
1231     bool m_compositionDeleted;
1232 };
1233 
1234 }
1235 
1236 
1237 #endif
1238 
1239