1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
|
/*
Rosegarden
A MIDI and audio 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 <richard.bown@ferventsoftware.com>
The moral rights of Guillaume Laurent, Chris Cannam, and Richard
Bown to claim authorship of this work have been asserted.
Other copyrights also apply to some parts of this work. Please
see the AUTHORS file and individual file headers for details.
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 _RG_SEQUENCEMANAGER_H_
#define _RG_SEQUENCEMANAGER_H_
#include "base/Composition.h"
#include "base/Event.h"
#include "base/MidiProgram.h"
#include "base/RealTime.h"
#include "base/Track.h"
#include "gui/application/RosegardenDCOP.h"
#include "sound/MappedComposition.h"
#include "sound/MappedEvent.h"
#include <tqobject.h>
#include <tqstring.h>
#include <vector>
#include <map>
class TQTimer;
class TQTime;
class TQEvent;
namespace Rosegarden
{
class TransportDialog;
class Track;
class TimeSigSegmentMmapper;
class TempoSegmentMmapper;
class SequencerMapper;
class Segment;
class RosegardenGUIDoc;
class MetronomeMmapper;
class CountdownDialog;
class ControlBlockMmapper;
class CompositionMmapper;
class Composition;
class AudioManagerDialog;
class SequenceManager : public TQObject, public CompositionObserver
{
TQ_OBJECT
public:
SequenceManager(RosegardenGUIDoc *doc,
TransportDialog *transport);
~SequenceManager();
/**
* Replaces the internal document
*/
void setDocument(RosegardenGUIDoc*);
/**
* Return the current internal document
*/
RosegardenGUIDoc* getDocument();
//
// Transport controls
//
/// returns true if the call actually paused playback
bool play();
// We don't call stop() directly - using stopping() and then
// call stop().
//
void stop();
void stopping();
void rewind();
void fastforward();
void record(bool countIn);
void rewindToBeginning();
void fastForwardToEnd();
void setLoop(const timeT &lhs, const timeT &rhs);
void notifySequencerStatus(TransportStatus status);
void sendSequencerJump(const RealTime &time);
// Events coming in
void processAsynchronousMidi(const MappedComposition &mC,
AudioManagerDialog *aMD);
// Before playing and recording. If warnUser is true, show the
// user a warning dialog if there is a problem with the setup.
//
void checkSoundDriverStatus(bool warnUser);
/**
* Send program changes and align Instrument lists before playback
* starts.
* Also called at document loading (with arg set to true) to reset all instruments
* (fix for bug 820174)
*
* @arg forceProgramChanges if true, always send program changes even if the instrument is
* set not to send any.
*/
void preparePlayback(bool forceProgramChanges = false);
/// Check and set sequencer status
void setTransportStatus(const TransportStatus &status);
TransportStatus getTransportStatus() const { return m_transportStatus; }
/**
* Suspend the sequencer to allow for a safe DCOP call() i.e. one
* when we don't hang both clients 'cos they're blocking on each
* other.
*/
void suspendSequencer(bool value);
/// Send the audio level to VU meters
void sendAudioLevel(MappedEvent *mE);
/// Find what has been initialised and what hasn't
unsigned int getSoundDriverStatus() { return m_soundDriverStatus; }
/// Reset MIDI controllers
void resetControllers();
/// Reset MIDI network
void resetMidiNetwork();
/// Reinitialise the studio
void reinitialiseSequencerStudio();
/// Send JACK and MMC transport control statuses
void sendTransportControlStatuses();
/// Send all note offs and resets to MIDI devices
void panic();
/// Send an MC to the view
void showVisuals(const MappedComposition &mC);
/// Apply in-situ filtering to a MappedComposition
MappedComposition
applyFiltering(const MappedComposition &mC,
MappedEvent::MappedEventType filter);
CountdownDialog* getCountdownDialog() { return m_countdownDialog; }
//
// CompositionObserver interface
//
virtual void segmentAdded (const Composition*, Segment*);
virtual void segmentRemoved (const Composition*, Segment*);
virtual void segmentRepeatChanged (const Composition*, Segment*, bool);
virtual void segmentRepeatEndChanged (const Composition*, Segment*, timeT);
virtual void segmentEventsTimingChanged(const Composition*, Segment *, timeT delay, RealTime rtDelay);
virtual void segmentTransposeChanged (const Composition*, Segment *, int transpose);
virtual void segmentTrackChanged (const Composition*, Segment *, TrackId id);
virtual void segmentEndMarkerChanged (const Composition*, Segment *, bool);
virtual void endMarkerTimeChanged (const Composition*, bool shorten);
virtual void trackChanged (const Composition*, Track*);
virtual void trackDeleted (const Composition*, TrackId);
virtual void timeSignatureChanged (const Composition*);
virtual void metronomeChanged (const Composition*);
virtual void soloChanged (const Composition*, bool solo, TrackId selectedTrack);
virtual void tempoChanged (const Composition*);
void processAddedSegment(Segment*);
void processRemovedSegment(Segment*);
void segmentModified(Segment*);
virtual bool event(TQEvent *e);
/// for the gui to call to indicate that the metronome needs to be remapped
void metronomeChanged(InstrumentId id, bool regenerateTicks);
/// for the gui to call to indicate that a MIDI filter needs to be remapped
void filtersChanged(MidiFilter thruFilter,
MidiFilter recordFilter);
/// Return the current sequencer memory mapped file
SequencerMapper* getSequencerMapper() { return m_sequencerMapper; }
/// Ensure that the sequencer file is mapped
void mapSequencer();
void setTransport(TransportDialog* t) { m_transport = t; }
void enableMIDIThruRouting(bool state);
int getSampleRate(); // may return 0 if sequencer uncontactable
public slots:
void update();
signals:
void setProgress(int);
void incrementProgress(int);
void insertableNoteOnReceived(int pitch, int velocity);
void insertableNoteOffReceived(int pitch, int velocity);
void controllerDeviceEventReceived(MappedEvent *ev);
protected slots:
void slotCountdownTimerTimeout();
// Activated by timer to allow a message to be reported to
// the user - we use this mechanism so that the user isn't
// bombarded with dialogs in the event of lots of failures.
//
void slotAllowReport() { m_canReport = true; }
void slotFoundMountPoint(const TQString&,
unsigned long kBSize,
unsigned long kBUsed,
unsigned long kBAvail);
void slotScheduledCompositionMmapperReset() { resetCompositionMmapper(); }
protected:
void resetCompositionMmapper();
void resetControlBlockMmapper();
void resetMetronomeMmapper();
void resetTempoSegmentMmapper();
void resetTimeSigSegmentMmapper();
void checkRefreshStatus();
void sendMIDIRecordingDevice(const TQString recordDeviceStr);
void restoreRecordSubscriptions();
bool shouldWarnForImpreciseTimer();
//--------------- Data members ---------------------------------
MappedComposition m_mC;
RosegardenGUIDoc *m_doc;
CompositionMmapper *m_compositionMmapper;
ControlBlockMmapper *m_controlBlockMmapper;
MetronomeMmapper *m_metronomeMmapper;
TempoSegmentMmapper *m_tempoSegmentMmapper;
TimeSigSegmentMmapper *m_timeSigSegmentMmapper;
std::vector<Segment*> m_addedSegments;
std::vector<Segment*> m_removedSegments;
bool m_metronomeNeedsRefresh;
// statuses
TransportStatus m_transportStatus;
unsigned int m_soundDriverStatus;
// pointer to the transport dialog
TransportDialog *m_transport;
clock_t m_lastRewoundAt;
CountdownDialog *m_countdownDialog;
TQTimer *m_countdownTimer;
bool m_shownOverrunWarning;
// Keep a track of elapsed record time with this object
//
TQTime *m_recordTime;
typedef std::map<Segment *, int> SegmentRefreshMap;
SegmentRefreshMap m_segments; // map to refresh status id
SegmentRefreshMap m_triggerSegments;
unsigned int m_compositionRefreshStatusId;
bool m_updateRequested;
// used to schedule a composition mmapper reset when the composition end time marker changes
// this can be caused by a window resize, and since the reset is potentially expensive we want to collapse
// several following requests into one.
TQTimer *m_compositionMmapperResetTimer;
// Information that the sequencer is providing to us - for the moment
// it's only the position pointer.
//
SequencerMapper *m_sequencerMapper;
// Just to make sure we don't bother the user too often
//
TQTimer *m_reportTimer;
bool m_canReport;
bool m_gotDiskSpaceResult;
unsigned long m_diskSpaceKBAvail;
bool m_lastLowLatencySwitchSent;
timeT m_lastTransportStartPosition;
int m_sampleRate;
};
}
#endif
|