1 //=========================================================
2 //  MusE
3 //  Linux Music Editor
4 //
5 //  latency_info.h
6 //  (C) Copyright 2019 Tim E. Real (terminator356 on users dot sourceforge dot net)
7 //
8 //  This program is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU General Public License
10 //  as published by the Free Software Foundation; version 2 of
11 //  the License, or (at your option) any later version.
12 //
13 //  This program is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //  GNU General Public License for more details.
17 //
18 //  You should have received a copy of the GNU General Public License
19 //  along with this program; if not, write to the Free Software
20 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 //
22 //=========================================================
23 
24 #ifndef __TRANSPORT_OBJ_H__
25 #define __TRANSPORT_OBJ_H__
26 
27 #include "latency_info.h"
28 
29 namespace MusECore {
30 
31 class TransportSource
32 {
33 private:
34   TrackLatencyInfo _latencyInfo;
35   float _transportLatencyOut;
36   bool _canCorrect;
37 
38 public:
TransportSource()39   TransportSource() { _latencyInfo.initialize(); _transportLatencyOut = 0.0f; _canCorrect = false; }
40 
41   // Initializes this track's latency information in preparation for a latency scan.
42   void prepareLatencyScan(bool can_correct_latency = false);
43   // Whether this track (and the branch it is in) can force other parallel branches to
44   //  increase their latency compensation to match this one.
45   // If false, this branch will NOT disturb other parallel branches' compensation,
46   //  intead only allowing compensation UP TO the worst case in other branches.
canDominateOutputLatency()47   bool canDominateOutputLatency() const { return false; }
canDominateInputLatency()48   bool canDominateInputLatency() const { return false; }
49   // Whether this track (and the branch it is in) can force other parallel branches to
50   //  increase their latency compensation to match this one - IF this track is an end-point
51   //  and the branch allows domination.
52   // If false, this branch will NOT disturb other parallel branches' compensation,
53   //  intead only allowing compensation UP TO the worst case in other branches.
canDominateEndPointLatency()54   bool canDominateEndPointLatency() const { return false; }
55   // Whether this track and its branch can correct for latency, not just compensate.
56   // Special for transport source: Yes, it can correct its own latency, but without
57   //  further mechanisms we cannot know whether the transport information affects the
58   //  actual sound, or just an arpeggiator for example. See getDominanceInfo() for info.
canCorrectOutputLatency()59   bool canCorrectOutputLatency() const { return true; }
60   // Whether the track can pass latency values through, the SAME as if record monitor is
61   //  supported and on BUT does not require record monitor support.
62   // This is for example in the metronome MetronomeSynthI, since it is unique in that it
63   //  can correct its own latency unlike other synths, but it does not 'pass through'
64   //  the latency values to what drives it like other synths.
canPassThruLatency()65   bool canPassThruLatency() const { return false; }
66   // Whether any of the connected output routes are effectively connected.
67   // That means track is not off, track is monitored where applicable, etc,
68   //   ie. signal can actually flow.
69   // For Wave Tracks for example, asks whether the track is an end-point from the view of the input side.
70   bool isLatencyInputTerminal();
71   // Whether any of the connected output routes are effectively connected.
72   // That means track is not off, track is monitored where applicable, etc,
73   //   ie. signal can actually flow.
74   // For Wave Tracks for example, asks whether the track is an end-point from the view of the playback side.
75   bool isLatencyOutputTerminal();
76 
77   TrackLatencyInfo& getDominanceInfo(bool input);
78   TrackLatencyInfo& getDominanceLatencyInfo(bool input);
79   // The finalWorstLatency is the grand final worst-case latency, of any output track or open branch,
80   //  determined in the complete getDominanceLatencyInfo() scan.
81   // The callerBranchLatency is the inherent branch latency of the calling track, or zero if calling from
82   //  the very top outside of the branch heads (outside of output tracks or open branches).
83   // The callerBranchLatency is accumulated as setCorrectionLatencyInfo() is called on each track
84   //  in a branch of the graph.
85   TrackLatencyInfo& setCorrectionLatencyInfo(
86     bool input, float finalWorstLatency,
87     float callerBranchLatency = 0.0f, bool commonProjectLatency = false);
88   // Argument 'input': Whether we want the input side of the track. For example un-monitored wave tracks
89   //  are considered two separate paths with a recording input side and a playback output side.
90   TrackLatencyInfo& getLatencyInfo(bool input);
91 
transportLatencyOut()92   float transportLatencyOut() const { return _transportLatencyOut; }
setTransportLatencyOut(float f)93   void setTransportLatencyOut(float f) { _transportLatencyOut = f; }
94 };
95 
96 } // namespace MusECore
97 
98 #endif
99