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

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_TimedMutingNode.cpp
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
11namespace tracktion { inline namespace engine
12{
13
14//==============================================================================
15//==============================================================================
16TimedMutingNode::TimedMutingNode (std::unique_ptr<tracktion::graph::Node> inputNode,
17 juce::Array<TimeRange> muteTimes_,
18 tracktion::graph::PlayHeadState& playHeadStateToUse)
19 : input (std::move (inputNode)),
20 playHeadState (playHeadStateToUse),
21 muteTimes (std::move (muteTimes_))
22{
23 jassert (! muteTimes.isEmpty());
24
25 setOptimisations ({ tracktion::graph::ClearBuffers::no,
26 tracktion::graph::AllocateAudioBuffer::yes });
27}
28
29//==============================================================================
30tracktion::graph::NodeProperties TimedMutingNode::getNodeProperties()
31{
32 auto props = input->getNodeProperties();
33 props.nodeID = 0;
34
35 return props;
36}
37
38std::vector<tracktion::graph::Node*> TimedMutingNode::getDirectInputNodes()
39{
40 return { input.get() };
41}
42
43void TimedMutingNode::prepareToPlay (const tracktion::graph::PlaybackInitialisationInfo& info)
44{
45 sampleRate = info.sampleRate;
46}
47
48bool TimedMutingNode::isReadyToProcess()
49{
50 return input->hasProcessed();
51}
52
53void TimedMutingNode::process (ProcessContext& pc)
54{
55 const auto timelineRange = referenceSampleRangeToSplitTimelineRange (playHeadState.playHead, pc.referenceSampleRange).timelineRange1;
56
57 auto sourceBuffers = input->getProcessedOutput();
58 auto destAudioBlock = pc.buffers.audio;
59 auto& destMidiBlock = pc.buffers.midi;
60 jassert (sourceBuffers.audio.getSize() == destAudioBlock.getSize());
61
62 destMidiBlock.copyFrom (sourceBuffers.midi);
63
64 if (! playHeadState.playHead.isPlaying())
65 {
66 // If we're not playing, jas pass the source to our destination
67 setAudioOutput (input.get(), sourceBuffers.audio);
68 return;
69 }
70
71 copy (destAudioBlock, sourceBuffers.audio);
72 processSection (destAudioBlock, tracktion::timeRangeFromSamples (timelineRange, sampleRate));
73}
74
75void TimedMutingNode::processSection (choc::buffer::ChannelArrayView<float> view, TimeRange editTime)
76{
77 for (auto r : muteTimes)
78 {
79 if (r.overlaps (editTime))
80 {
81 auto mute = r.getIntersectionWith (editTime);
82
83 if (! mute.isEmpty())
84 {
85 if (mute == editTime)
86 {
87 view.clear();
88 }
89 else if (editTime.contains (mute))
90 {
91 auto startSample = tracktion::toSamples (mute.getStart() - editTime.getStart(), sampleRate);
92 auto numSamples = tracktion::toSamples (mute.getLength(), sampleRate);
93 muteSection (view, startSample, numSamples);
94 }
95 else if (mute.getEnd() <= editTime.getEnd())
96 {
97 auto numSamples = tracktion::toSamples (editTime.getEnd() - mute.getEnd(), sampleRate);
98 muteSection (view, 0, numSamples);
99 }
100 else if (mute.getStart() >= editTime.getStart())
101 {
102 auto startSample = tracktion::toSamples (mute.getStart() - editTime.getStart(), sampleRate);
103 muteSection (view, startSample, choc::buffer::FrameCount (view.getNumFrames()) - startSample);
104 }
105 }
106 }
107
108 if (r.getEnd() >= editTime.getEnd())
109 return;
110 }
111}
112
113void TimedMutingNode::muteSection (choc::buffer::ChannelArrayView<float> block, int64_t startSample, int64_t numSamples)
114{
115 if (numSamples > 0)
116 block.getFrameRange ({ (choc::buffer::FrameCount) startSample,
117 (choc::buffer::FrameCount) (startSample + numSamples) }).clear();
118}
119
120}} // namespace tracktion { inline namespace engine
Struct to describe a single iteration of a process call.
Determines how this block releates to other previous render blocks and if the play head has jumped in...
#define jassert(expression)
T move(T... args)
constexpr int64_t toSamples(TimePosition, double sampleRate)
Converts a TimePosition to a number of samples.
SplitTimelineRange referenceSampleRangeToSplitTimelineRange(const PlayHead &playHead, juce::Range< int64_t > referenceSampleRange)
Converts a reference sample range to a TimelinePositionWindow which could have two time ranges if the...
Holds some really basic properties of a node.
Passed into Nodes when they are being initialised, to give them useful contextual information that th...