Deluge Firmware 1.3.0
Build date: 2025.04.16
Loading...
Searching...
No Matches
audio_clip.h
1/*
2 * Copyright © 2019-2023 Synthstrom Audible Limited
3 *
4 * This file is part of The Synthstrom Audible Deluge Firmware.
5 *
6 * The Synthstrom Audible Deluge Firmware is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software Foundation,
8 * either version 3 of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with this program.
15 * If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#pragma once
19
20#include "definitions_cxx.hpp"
21#include "gui/views/audio_clip_view.h"
22#include "gui/waveform/waveform_render_data.h"
23#include "model/clip/clip.h"
24#include "model/sample/sample_controls.h"
25#include "model/sample/sample_holder_for_clip.h"
26#include "model/sample/sample_playback_guide.h"
27#include "model/song/song.h"
28#include "processing/audio_output.h"
29#include "util/d_string.h"
30
31class VoiceSample;
32class SampleRecorder;
34
35class AudioClip final : public Clip {
36public:
37 AudioClip();
38 ~AudioClip() override;
39 void processCurrentPos(ModelStackWithTimelineCounter* modelStack, uint32_t ticksSinceLast) override;
40 void expectNoFurtherTicks(Song* song, bool actuallySoundChange = true) override;
41 Error clone(ModelStackWithTimelineCounter* modelStack, bool shouldFlattenReversing = false) const override;
42 void render(ModelStackWithTimelineCounter* modelStack, std::span<q31_t> output, int32_t amplitude,
43 int32_t amplitudeIncrement, int32_t pitchAdjust);
44 void detachFromOutput(ModelStackWithTimelineCounter* modelStack, bool shouldRememberDrumName,
45 bool shouldDeleteEmptyNoteRowsAtEndOfList = false, bool shouldRetainLinksToSounds = false,
46 bool keepNoteRowsWithMIDIInput = true, bool shouldGrabMidiCommands = false,
47 bool shouldBackUpExpressionParamsToo = true) override;
48 bool renderAsSingleRow(ModelStackWithTimelineCounter* modelStack, TimelineView* editorScreen, int32_t xScroll,
49 uint32_t xZoom, RGB* image, uint8_t occupancyMask[], bool addUndefinedArea,
50 int32_t noteRowIndexStart = 0, int32_t noteRowIndexEnd = 2147483647, int32_t xStart = 0,
51 int32_t xEnd = kDisplayWidth, bool allowBlur = true, bool drawRepeats = false) override;
52 Error claimOutput(ModelStackWithTimelineCounter* modelStack) override;
53 void loadSample(bool mayActuallyReadFile);
54 bool wantsToBeginLinearRecording(Song* song) override;
55 bool isAbandonedOverdub() override;
56 void finishLinearRecording(ModelStackWithTimelineCounter* modelStack, Clip* nextPendingLoop,
57 int32_t buttonLatencyForTempolessRecord) override;
58 Error beginLinearRecording(ModelStackWithTimelineCounter* modelStack, int32_t buttonPressLatency) override;
59 void quantizeLengthForArrangementRecording(ModelStackWithTimelineCounter* modelStack, int32_t lengthSoFar,
60 uint32_t timeRemainder, int32_t suggestedLength,
61 int32_t alternativeLongerLength) override;
62
63 // we can only do in place overdubs if input monitoring is on right now, recording input seperately might come later
64 // if we're in rows mode then use the old cloning method instead
65 bool shouldCloneForOverdubs() override { return ((AudioOutput*)output)->mode != AudioOutputMode::looper; };
66 Clip* cloneAsNewOverdub(ModelStackWithTimelineCounter* modelStack, OverDubType newOverdubNature) override;
67 int64_t getSamplesFromTicks(int32_t ticks);
68 void unassignVoiceSample(bool wontBeUsedAgain);
69 void resumePlayback(ModelStackWithTimelineCounter* modelStack, bool mayMakeSound = true) override;
70 Error changeOutput(ModelStackWithTimelineCounter* modelStack, Output* newOutput);
71 Error setOutput(ModelStackWithTimelineCounter* modelStack, Output* newOutput,
72 AudioClip* favourClipForCloningParamManager = nullptr);
73 RGB getColour();
74 bool currentlyScrollableAndZoomable() override;
75 void getScrollAndZoomInSamples(int32_t xScroll, int32_t xZoom, int64_t* xScrollSamples, int64_t* xZoomSamples);
76 void clear(Action* action, ModelStackWithTimelineCounter* modelStack, bool clearAutomation,
77 bool clearSequenceAndMPE) override;
78 bool getCurrentlyRecordingLinearly() override;
79 void abortRecording() override;
80 void setupPlaybackBounds();
81 uint64_t getCullImmunity();
82 void posReachedEnd(ModelStackWithTimelineCounter* modelStack) override;
83 void copyBasicsFrom(Clip const* otherClip) override;
84 bool willCloneOutputForOverdub() override { return overdubsShouldCloneOutput; }
85 void sampleZoneChanged(ModelStackWithTimelineCounter const* modelStack);
86 int64_t getNumSamplesTilLoop(ModelStackWithTimelineCounter* modelStack);
87 void setPos(ModelStackWithTimelineCounter* modelStack, int32_t newPos, bool useActualPosForParamManagers) override;
89 bool shiftHorizontally(ModelStackWithTimelineCounter* modelStack, int32_t amount, bool shiftAutomation,
90 bool shiftSequenceAndMPE) override;
91
92 Error readFromFile(Deserializer& reader, Song* song) override;
93 void writeDataToFile(Serializer& writer, Song* song) override;
94 char const* getXMLTag() override { return "audioClip"; }
95 int32_t nextSampleRestartPos;
96 SampleControls sampleControls;
97
98 SampleHolderForClip sampleHolder;
99
100 VoiceSample* voiceSample;
101
102 SamplePlaybackGuide guide;
103
104 String outputNameWhileLoading; // Only valid while loading
105
106 WaveformRenderData renderData;
107 // TODO: For looping without monitoring we'll need a second recorder plus maybe a second sample player?
108 SampleRecorder* recorder; // Will be set to NULL right at the end of the loop's recording, even though the
109 // SampleRecorder itself will usually persist slightly longer
110 int32_t attack;
111
112 VoicePriority voicePriority;
113
114 bool doingLateStart;
115 bool maySetupCache;
116
117 bool renderSidebar(uint32_t whichRows = 0, RGB image[][kDisplayWidth + kSideBarWidth] = nullptr,
118 uint8_t occupancyMask[][kDisplayWidth + kSideBarWidth] = nullptr) override {
119 return audioClipView.renderSidebar(whichRows, image, occupancyMask);
120 };
121
122 ParamManagerForTimeline* getCurrentParamManager() override;
123
124 bool isEmpty(bool displayPopup = true) override;
125
126protected:
127 bool cloneOutput(ModelStackWithTimelineCounter* modelStack) override;
128
129private:
130 AudioClip* nextClipInSection;
131 void removeClipFromSection(AudioClip* clip);
132 void detachAudioClipFromOutput(Song* song, bool shouldRetainLinksToOutput, bool shouldTakeParamManagerWith = false);
133 LoopType getLoopingType(ModelStackWithTimelineCounter const* modelStack);
134};
Definition action.h:75
Definition audio_clip.h:35
bool shiftHorizontally(ModelStackWithTimelineCounter *modelStack, int32_t amount, bool shiftAutomation, bool shiftSequenceAndMPE) override
Return true if successfully shifted, as clip cannot be shifted past beginning.
Definition audio_clip.cpp:1320
bool shouldCloneForOverdubs() override
Definition audio_clip.h:65
Definition audio_output.h:37
Definition clip.h:46
Definition model_stack.h:129
Definition output.h:81
This class represents the colour format most used by the Deluge globally.
Definition rgb.h:14
Definition sample_recorder.h:49
Definition song.h:104
Definition timeline_view.h:27
Definition voice_sample.h:36