tracktion-engine 3.0-10-g034fdde4aa5
Tracktion Engine — High level data model for audio applications

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_LatencyProcessor.h
Go to the documentation of this file.
1 /*
2 ,--. ,--. ,--. ,--.
3 ,-' '-.,--.--.,--,--.,---.| |,-.,-' '-.`--' ,---. ,--,--, Copyright 2024
4 '-. .-'| .--' ,-. | .--'| /'-. .-',--.| .-. || \ Tracktion Software
5 | | | | \ '-' \ `--.| \ \ | | | |' '-' '| || | Corporation
6 `---' `--' `--`--'`---'`--'`--' `---' `--' `---' `--''--' www.tracktion.com
7
8 Tracktion Engine uses a GPL/commercial licence - see LICENCE.md for details.
9*/
10
11#pragma once
12
13namespace tracktion { inline namespace graph
14{
15
16//==============================================================================
17//==============================================================================
19{
20 LatencyProcessor() = default;
21
24 {
25 return latencyNumSamples == o.latencyNumSamples
26 && sampleRate == o.sampleRate
27 && fifo.getNumChannels() == o.fifo.getNumChannels();
28 }
29
31 bool hasConfiguration (int numLatencySamples, double preparedSampleRate, int numberOfChannels) const
32 {
33 return latencyNumSamples == numLatencySamples
34 && sampleRate == preparedSampleRate
35 && fifo.getNumChannels() == (choc::buffer::ChannelCount) numberOfChannels;
36 }
37
38 int getLatencyNumSamples() const
39 {
40 return latencyNumSamples;
41 }
42
43 void setLatencyNumSamples (int numLatencySamples)
44 {
45 assert (numLatencySamples < (196'000 * 60) && "Invalid latency size");
46 latencyNumSamples = numLatencySamples;
47 }
48
49 void prepareToPlay (double sampleRateToUse, int blockSize, int numChannels)
50 {
51 sampleRate = sampleRateToUse;
52 latencyTimeSeconds = sampleToTime (latencyNumSamples, sampleRate);
53
54 fifo.setSize ((choc::buffer::ChannelCount) numChannels, (choc::buffer::FrameCount) (latencyNumSamples + blockSize + 1));
55 fifo.writeSilence ((choc::buffer::FrameCount) latencyNumSamples);
56 jassert (fifo.getNumReady() == latencyNumSamples);
57 }
58
59 void writeAudio (choc::buffer::ChannelArrayView<float> src)
60 {
61 if (fifo.getNumChannels() == 0)
62 return;
63
64 jassert (fifo.getNumChannels() >= src.getNumChannels());
65 fifo.write (src);
66 }
67
68 void writeMIDI (const tracktion_engine::MidiMessageArray& src)
69 {
70 midi.mergeFromWithOffset (src, latencyTimeSeconds);
71 }
72
73 void readAudioAdding (choc::buffer::ChannelArrayView<float> dst)
74 {
75 if (fifo.getNumChannels() == 0)
76 return;
77
78 jassert (fifo.getNumReady() >= (int) dst.getNumFrames());
79 fifo.readAdding (dst);
80 }
81
82 void readAudioOverwriting (choc::buffer::ChannelArrayView<float> dst)
83 {
84 if (fifo.getNumChannels() == 0)
85 return;
86
87 jassert (fifo.getNumReady() >= (int) dst.getNumFrames());
88 fifo.readOverwriting (dst);
89 }
90
91 void readMIDI (tracktion_engine::MidiMessageArray& dst, int numSamples)
92 {
93 // And read out any delayed items
94 const double blockTimeSeconds = sampleToTime (numSamples, sampleRate);
95
96 for (int i = midi.size(); --i >= 0;)
97 {
98 auto& m = midi[i];
99
100 if (m.getTimeStamp() <= blockTimeSeconds)
101 {
102 dst.add (m);
103 midi.remove (i);
104 // TODO: This will deallocate, we need a MIDI message array that doesn't adjust its storage
105 }
106 }
107
108 // Shuffle down remaining items by block time
109 midi.addToTimestamps (-blockTimeSeconds);
110
111 // Ensure there are no negative time messages
112 for (auto& m : midi)
113 {
115 jassert (m.getTimeStamp() >= 0.0);
116 }
117 }
118
119 void clearAudio (int numSamples)
120 {
121 fifo.removeSamples (numSamples);
122 }
123
124 void clearMIDI (int numSamples)
125 {
126 // And read out any delayed items
127 const double blockTimeSeconds = sampleToTime (numSamples, sampleRate);
128
129 // TODO: This will deallocate, we need a MIDI message array that doesn't adjust its storage
130 for (int i = midi.size(); --i >= 0;)
131 if (midi[i].getTimeStamp() <= blockTimeSeconds)
132 midi.remove (i);
133
134 // Shuffle down remaining items by block time
135 midi.addToTimestamps (-blockTimeSeconds);
136
137 // Ensure there are no negative time messages
138 for (auto& m : midi)
139 {
141 jassert (m.getTimeStamp() >= 0.0);
142 }
143 }
144
145private:
146 int latencyNumSamples = 0;
147 double sampleRate = 44100.0;
148 double latencyTimeSeconds = 0.0;
149 AudioFifo fifo { 1, 32 };
151};
152
153}}
assert
#define jassert(expression)
void ignoreUnused(Types &&...) noexcept
constexpr double sampleToTime(IntType samplePosition, double sampleRate)
Converts an integer sample number to a time in seconds.
bool hasConfiguration(int numLatencySamples, double preparedSampleRate, int numberOfChannels) const
Returns ture if the the sample rate, channels etc.
bool hasSameConfigurationAs(const LatencyProcessor &o) const
Returns ture if the the sample rate, channels etc.