This file is indexed.

/usr/include/tse3/Transport.h is in libtse3-dev 0.3.1-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
/*
 * @(#)Transport.h 3.00 25 May 1999
 *
 * Copyright (c) 2000 Pete Goodliffe (pete@cthree.org)
 *
 * This file is part of TSE3 - the Trax Sequencer Engine version 3.00.
 *
 * This library is modifiable/redistributable under the terms of the GNU
 * General Public License.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; see the file COPYING. If not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 */

#ifndef TSE3_TRANSPORT_H
#define TSE3_TRANSPORT_H

#include "tse3/listen/Transport.h"

#include "tse3/Notifier.h"
#include "tse3/Panic.h"
#include "tse3/MidiMapper.h"
#include "tse3/MidiEcho.h"
#include "tse3/listen/Playable.h"
#include "tse3/listen/PhraseEdit.h"
#include "tse3/listen/MidiScheduler.h"
#include "tse3/listen/FlagTrack.h"
#include "tse3/listen/Metronome.h"

#include <queue>
#include <list>

namespace TSE3
{
    /**
     * This object handles the playback/record mechanism. It is the central
     * control for musical input and output.
     *
     * It usually plays a @ref Song, but isn't restricted to @ref Songs since
     * it uses the abstract @ref Playable interface as the music source.
     *
     * When using this class it is important to call the @ref poll method
     * as often as possible: it does most of the work. It would be a good idea
     * to do this polling in a background thread (see @ref Impl::Mutex for
     * information on threading issues).
     *
     * Facilities provided by the Transport class include:
     * @li Play
     * @li Record into @ref PhraseEdit
     * @li Fast forward and rewind
     * @li Ability to attach callbacks which are kept informed of MIDI activity
     *     coming into or leaving the Transport object
     * @li Uses @ref Panic objects (for start and stop reset sequences), a
     *     @ref MidiEcho object
     * @li Synchro start (playback starts when MIDI input recieved)
     * @li Uses a @ref FlagTrack to move around the @ref Playable easily
     * @li Auto stop at the end of the @ref Playable object
     * @li Lead in values for play and record
     * @li Adaptive look ahead
     * @li Ability to 'inject' a @ref MidiCommand into the Transport stream.
     *
     * @short   Manager of transport facilities
     * @author  Pete Goodliffe
     * @version 3.00
     * @see     Song
     * @see     Playable
     * @see     TransportCallback
     */
    class Transport : public Listener<MidiSchedulerListener>,
                      public Listener<FlagTrackListener>,
                      public Listener<PhraseEditListener>,
                      public Listener<MetronomeListener>,
                      public Listener<PlayableListener>,
                      public Notifier<TransportListener>
    {
        public:

            /**
             * The Transport object starts up in resting mode.
             *
             * It is presumed that neither the metronome or scheduler objects
             * will be deleted whilst the Transport object exists.
             *
             * @param metronome @ref Metronome object to use
             * @param scheduler @ref MidiScheduler object to use
             * @see status
             */
            Transport(Metronome     *metronome,
                      MidiScheduler *scheduler);
            virtual ~Transport();

            /**
             * Register a callback object.
             *
             * @param c @ref TransportCallback object to attach
             */
            void attachCallback(TransportCallback *c);

            /**
             * Detach a callback object.
             *
             * @param c @ref TransportCallback object to detach
             */
            void detachCallback(TransportCallback *c);

            /**
             * Returns the @ref MidiScheduler that this Transport object
             * is using.
             *
             * @return MidiScheduler in use
             */
            MidiScheduler *scheduler() const { return _scheduler; }

            /**
             * @ref MidiFilter that affects how all @ref MidiEvents
             * are sent from the Transport object. You can use this to set
             * global overrides for some @ref Song setup; for example to
             * for every @ref MidiEvent to a specific port.
             *
             * @return The Part's @ref MidiFilter object
             */
            MidiFilter *filter() { return &_filter; };

            /**
             * The @ref Panic object used to send reset data at transport start.
             *
             * @return Transport's start @ref Panic object
             */
            Panic *startPanic() { return &_startPanic; }

            /**
             * The @ref Panic object used to send reset data at transport end.
             *
             * @return Transport's end @ref Panic object
             */
            Panic *endPanic() { return &_endPanic; }

            /**
             * This @ref MidiMapper object used to alter output destination.
             *
             * @return Transport's @ref MidiMapper object
             */
            MidiMapper *midiMapper() { return &_midiMapper; }

            /**
             * Returns the @ref MidiEcho object used to provide soft MIDI Thru.
             *
             * @return Transport's @ref MidiEcho object
             */
            MidiEcho *midiEcho() { return &_midiEcho; }

            /**
             * Set the @ref FlagTrack. You can specify the value 0 for no
             * @ref FlagTrack. The FlagTrack should be set if your playable
             * object is a @ref Song. If it is not, it's best to reset the
             * @ref FlagTrack value to 0.
             *
             * This is used when transport is resting and stop is called to
             * snap the stop position to a @ref Flag position.
             *
             * @param f @ref FlagTrack to use - it should tally with the
             *          current @ref Song
             */
            void setFlagTrack(FlagTrack *f) { flagTrack = f; }

            /**
             * Returns the current synchro mode.
             *
             * When enabled, transport will not start immediately when
             * play/record is called: it will only start when MIDI input is
             * recieved from the scheduler.
             *
             * @return Synchro mode status
             * @see    setSynchro
             */
            bool synchro() const { return _synchro; }

            /**
             * Set the synchro status.
             *
             * @param s New synchro mode status
             * @see   synchro
             */
            void setSynchro(bool s);

            /**
             * Returns the currrent punch-in record status.
             *
             * This effects how the recording is handled. When disabled, record
             * will mute the record channel. When enabled, muting only occurs
             * when the first MIDI input is recieved.
             *
             * @return Punch in status
             * @see    setPunchIn
             */
            bool punchIn() const { return _punchIn; }

            /**
             * Set the punch-in record status.
             *
             * @param p New punch in status
             * @see   punchIn
             */
            void setPunchIn(bool p);

            /**
             * Returns the currrent auto stop status.
             *
             * When enabled playback will automatically stop at the end of
             * the Playable object. This will not occur in recording mode.
             *
             * @return Auto stop mode status
             * @see    setAutoStop
             */
            bool autoStop() const { return _autoStop; }

            /**
             * Set the auto stop status.
             *
             * @param s New auto stop mode status
             * @see   setAutoStop
             */
            void setAutoStop(bool s);

            /**
             * Returns the playback lead in, the number of PPQN before
             * Song playback begins.
             *
             * @return The playback lead in
             * @see    setPlaybackLeadIn
             */
            Clock playLeadIn() const { return _playLeadIn; }

            /**
             * Sets the value of the playback lead in.
             *
             * @param c New playback lead in
             * @see   playbackLeadIn
             */
            void setPlayLeadIn(Clock c);

            /**
             * Returns the record lead in, the number of PPQN before
             * Song recording begins.
             *
             * @return The record lead in
             * @see    setRecordLeadIn
             */
            Clock recordLeadIn() const { return _recLeadIn; }

            /**
             * Sets the value of the record lead in.
             *
             * @param c New record lead in
             * @see   recordLeadIn
             */
            void setRecordLeadIn(Clock c);

            /**
             * Call this to start playback.
             *
             * If the request is successful, an event will be returned to all
             * @ref TransportListeners.
             *
             * @param p         The object to play.
             * @param startTime The time to start playback from.
             */
            void play(Playable *p, Clock startTime);

            /**
             * Call this to start recording.
             *
             * Whilst you are recording, a @ref Playable can be
             * played back (this will normally be the @ref Song you are working
             * on. You can optionally mute a @ref Track (well, it will
             * normally be a @ref Track) by specifying it's
             * @ref MidiFilter. (The 'setStatus' method is used to
             * perform the muting - it will be reset correctly afterwards).
             *
             * If course, you do not have to perform a mute, or do any playback
             * at all if you so wish.
             *
             * You would want to specify a mute @ref Track to silence the
             * @ref Track that the user thinks recording is taking place on
             * (when at the moment the @ref Song is not being altered by
             * the Transport's recording process at all).
             *
             * If the record request is successful, an event will be returned
             * to all @ref TransportListeners. Record may not do anything
             * (for example, you cannot enter Recording mode from Playing mode).
             *
             * If punch-in mode is enabled, the @ref Track the user thinks
             * recording is being performed on (when it's in fact going into
             * a @ref PhraseEdit object) will be muted when MIDI input is first
             * recieved. This muting is achieved by setting the @ref Track's
             * @ref MidiFilter status to false. It will be restored
             * when stop is called.
             *
             * If punch-in mode is disabled, then the filter will be muted
             * immediately, and restored when stop is called.
             *
             * If 0 is passed in filter then no muting will occur.
             *
             * @param p         The object to play.
             * @param startTime The time to start recording from.
             * @param pe        The PhraseEdit to record into.
             * @param filter    The filter for punch-in track (or 0).
             */
            void record(Playable *p, Clock startTime,
                        PhraseEdit *pe, MidiFilter *filter = 0);

            /**
             * Stop playback.
             *
             * If the request is successful, an event will be returned to all
             * @ref TransportListeners.
             *
             * If in Resting mode, then the 'resting clock' will be moved to
             * time zero.
             */
            void stop();

            /**
             * Fast forward.
             *
             * Makes the playback position jump forwards by
             * @ref Clock::PPQN.
             *
             * @param strong If true, fast forwards four times faster.
             */
            void ff(bool strong);

            /**
             * Fast forward to next flag position, if there is one.
             */
            void ffFlag();

            /**
             * Rewind.
             *
             * Makes the playback position jump backwards by
             * @ref Clock::PPQN.
             *
             * @param strong If true, rewinds four times faster.
             */
            void rew(bool strong);

            /**
             * Rewind to previous flag position, or the start if there is none.
             */
            void rewFlag();

            /**
             * The Transport object activity poll interface.
             *
             * This must be called often and rapidly (say every 10 usecs) if
             * you want to handle MIDI input properly. This includes recording
             * and MIDI echo.
             *
             * If you're only doing playback (and have disabled the MIDI echo
             * facility) then you can afford to call this only as often as you
             * need to (this is dependant on the @ref lookAhead()). This will
             * give your processor quite a rest.
             *
             * The poll method schedules an amount of musical data for playback
             * via the @ref MidiScheduler. The size of this 'window' of data
             * that is scheduled ahead of time is set by @ref lookAhead().
             */
            void poll();

            /**
             * Returns the current state of the Transport object
             *
             * @return Current Transport state
             */
            int status() const { return _status; }

            /**
             * If @ref status is not @ref Resting, then this will return
             * a pointer to the current @ref Playable object.
             *
             * When resting, this returns zero.
             *
             * @return Current playable
             * @see    play
             * @see    record
             */
            Playable *playable() const { return _playable; }

            /**
             * Transport status definitions for the current mode, as returned
             * by the @ref status method.
             */
            enum TransportMode
            {
                Resting,
                Playing,
                Recording,
                SynchroPlaying,
                SynchroRecording
            };

            /**
             * Returns the look ahead value. This is the amount of
             * data that the Transport object will schedule ahead of time
             * to ensure smooth and unbroken playback.
             *
             * @return Look ahead value
             * @see setLookAhead
             * @see minimumLookAhead
             * @see adaptiveLookAhead
             */
            Clock lookAhead() const { return _lookAhead; }

            /**
             * Sets the look ahead value.
             *
             * @param c New look ahead value
             * @see   lookAhead
             */
            void setLookAhead(Clock c);

            /**
             * Returns the minimum value @ref lookAhead can be set to. (There
             * has to be some kind of limit, setting it to zero is just asking
             * for trouble.)
             *
             * @return Minimum look ahead value
             * @see    lookAhead
             * @see    setLookAhead
             */
            Clock minimumLookAhead() const { return _minimumLookAhead; }

            /**
             * Returns whether the 'adaptive look ahead' facility is active.
             *
             * Adaptive look ahead causes the @ref poll method to calculate
             * the best value for @ref lookAhead. The calculation is based on
             * the frequency of calls to @ref poll and aims to reduce the
             * look ahead as much as possible (in order to increase system
             * responsivity) whilst ensuring that it is not so low as to
             * cause playback break-up.
             *
             * @return Adaptive look ahead status
             * @see    setAdaptiveLookAhead
             * @see    lookAhead
             * @see    setLookAhead
             */
            bool adaptiveLookAhead() const { return _adaptiveLookAhead; }

            /**
             * Set the value of the adaptive look ahead feature.
             *
             * @param ala New adaptive look ahead status
             * @see   adaptiveLookAhead
             */
            void setAdaptiveLookAhead(bool ala);

            /**
             * Returns the number of times playback has 'broken up' during the
             * current run of the Transport object. If this returns true you
             * may wish to increase the value of @ref lookAhead.
             *
             * @return The number of time playback has 'broken up'
             * @see    lookAhead
             * @see    setLookAhead
             */
            int breakUps() const { return _breakUps; }

            /**
             * Injects a @ref MidiCommand into the Transport object. This is a
             * facility used by components such as an on-screen keyboard.
             *
             * The Transport object acts as if this @ref MidiCommand was
             * recieved from the @ref MidiScheduler object, recording/echoing
             * it.
             *
             * The side effect of calling this member function is that a
             * call to @ref poll will be made (to process the injected @ref
             * MidiCommand.
             *
             * Take care: if you inject a @ref MidiCommand_NoteOn you must
             * ballance it with a @ref MidiCommand_NoteOff later on or
             * you will experience 'hanging notes'.
             *
             * @param c The @ref MidiCommand to inject
             */
            void inject(MidiCommand c);

            /**
             * @reimplemented
             */
            virtual void MidiScheduler_Started(MidiScheduler *);

            /**
             * @reimplemented
             */
            virtual void MidiScheduler_Stopped(MidiScheduler *);

            /**
             * @reimplemented
             */
            virtual void MidiScheduler_Moved(MidiScheduler *);

            /**
             * @reimplemented
             */
            virtual void Notifier_Deleted(FlagTrack *);

            /**
             * @reimplemented
             */
            virtual void Notifier_Deleted(Metronome *);

            /**
             * @reimplemented
             */
            virtual void Notifier_Deleted(MidiScheduler *);

            /**
             * @reimplemented
             */
            virtual void Notifier_Deleted(PhraseEdit *);

            /**
             * @reimplemented
             */
            virtual void Notifier_Deleted(Playable *);

        private:

            Transport &operator=(const Transport &);
            Transport(const Transport &);

            void startPlayback();

            /**
             * This method handles the playback of @ref MidiEvents read through
             * @ref Playable interfaces, sending them to the @ref MidiScheduler.
             */
            void pollPlayback();

            /**
             * Flushes the scheduler buffer and sends any pending
             * MidiCommand_NoteOffs immediately.
             */
            void stopPlayback(Clock stopTime);

            /**
             * Used by ff/rew methods.
             *
             * The c value is added, and then the final position is rounded
             * down to the previous whole @ref Clock::PPQN division.
             */
            void shiftBy(Clock c);

            /**
             * Sends Transport_MidiOut to all attached callbacks.
             */
            void callback_MidiOut(MidiCommand c);

            /**
             * Sends Transport_MidiIn to all attached callbacks.
             */
            void callback_MidiIn(MidiCommand c);

            /**
             * A single handler for every MidiSchedulerEvent except
             * the deleted event.
             */
            void handleMidiSchedulerEvent();

            std::list<TransportCallback *>  callbacks;
            Playable                       *_playable;
            PlayableIterator               *iterator;
            FlagTrack                      *flagTrack;
            PhraseEdit                     *recPE;
            std::priority_queue<MidiEvent,
                                std::vector<MidiEvent>,
                                std::greater<MidiEvent> >
                                            noteOffBuffer;
            Metronome                      *metronome;
            PlayableIterator               *metronomeIterator;
            MidiScheduler                  *_scheduler;
            MidiFilter                      _filter;
            Panic                           _startPanic;
            Panic                           _endPanic;
            MidiMapper                      _midiMapper;
            MidiEcho                        _midiEcho;

            int                             _status;
            bool                            _synchro;
            bool                            _punchIn;
            bool                            _autoStop;
            Clock                           lastScheduledClock;
            Clock                           lastPollPlaybackClock;
            bool                            _adaptiveLookAhead;
            Clock                           _lookAhead;
            static const Clock              _minimumLookAhead;
            int                             _breakUps;
            bool                            punchedInYet;
            MidiFilter                     *punchInFilter;
            bool                            punchInStatus;
            MidiCommand                     injectedMidiCommand;

            Clock                           _playLeadIn;
            Clock                           _recLeadIn;

            /**
             * The small amount of time which playback starts before the
             * specified time to give the transport object enough time to
             * get some MidiEvents into the scheduler.
             */
            Clock transportLeadIn;
    };
}

#endif