Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
clip.h
1// SPDX-FileCopyrightText: © 2019-2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "utils/audio.h"
7#include "utils/audio_file.h"
8#include "utils/hash.h"
9#include "utils/icloneable.h"
10#include "utils/monotonic_time_provider.h"
11#include "utils/serialization.h"
12#include "utils/types.h"
13#include "utils/uuid_identifiable_object.h"
14
15using namespace zrythm;
16
22class AudioClip final
23 : public utils::UuidIdentifiableObject<AudioClip>,
25{
26public:
27 using BitDepth = zrythm::utils::audio::BitDepth;
28 using AudioFile = zrythm::utils::audio::AudioFile;
29
30public:
31 AudioClip () = default;
32
44 const fs::path &full_path,
45 sample_rate_t project_sample_rate,
46 bpm_t current_bpm);
47
56 utils::audio::BitDepth bit_depth,
57 sample_rate_t project_sample_rate,
58 bpm_t current_bpm,
59 const utils::Utf8String &name);
60
70 const float * arr,
71 unsigned_frame_t nframes,
72 channels_t channels,
73 zrythm::utils::audio::BitDepth bit_depth,
74 sample_rate_t project_sample_rate,
75 bpm_t current_bpm,
76 const utils::Utf8String &name)
77 : AudioClip (
78 *utils::audio::AudioBuffer::from_interleaved (arr, nframes, channels),
79 bit_depth,
80 project_sample_rate,
81 current_bpm,
82 name)
83 {
84 }
85
96 channels_t channels,
97 unsigned_frame_t nframes,
98 sample_rate_t project_sample_rate,
99 bpm_t current_bpm,
100 const utils::Utf8String &name);
101
102public:
103 static bool should_use_flac (zrythm::utils::audio::BitDepth bd)
104 {
105 return false;
106 /* FLAC seems to fail writing sometimes so disable for now */
107#if 0
108 return bd < BIT_DEPTH_32;
109#endif
110 }
111
112 friend void init_from (
113 AudioClip &obj,
114 const AudioClip &other,
115 utils::ObjectCloneType clone_type);
116
123 void init_loaded (const fs::path &full_path);
124
139 std::unique_ptr<AudioClip> edit_in_ext_program ();
140
148 void write_to_file (const fs::path &filepath, bool parts);
149
150 auto get_bit_depth () const { return bit_depth_; }
151 auto get_name () const { return name_; }
152 auto get_file_hash () const { return file_hash_; }
153 auto get_bpm () const { return bpm_; }
154 const auto &get_samples () const { return ch_frames_; }
155 auto get_last_write_to_file () const { return last_write_; }
156 auto get_use_flac () const { return use_flac_; }
157
158 void set_name (const utils::Utf8String &name) { name_ = name; }
159 void set_file_hash (utils::hash::HashT hash) { file_hash_ = hash; }
160
168
179 const utils::audio::AudioBuffer &src_frames,
180 unsigned_frame_t start_frame);
181
192 const float * frames,
193 unsigned_frame_t start_frame,
194 unsigned_frame_t num_frames_per_channel,
195 channels_t channels);
196
201 {
202 ch_frames_.setSize (ch_frames_.getNumChannels (), 0, false, true);
203 }
204
205 auto get_num_channels () const { return ch_frames_.getNumChannels (); };
206 auto get_num_frames () const { return ch_frames_.getNumSamples (); };
207
213
221 const fs::path &filepath,
222 sample_rate_t project_sample_rate,
223 bpm_t current_bpm) const;
224
230
231private:
232 static constexpr auto kNameKey = "name"sv;
233 static constexpr auto kFileHashKey = "fileHash"sv;
234 static constexpr auto kBpmKey = "bpm"sv;
235 static constexpr auto kBitDepthKey = "bitDepth"sv;
236 static constexpr auto kUseFlacKey = "useFlac"sv;
237 static constexpr auto kSamplerateKey = "samplerate"sv;
238 friend void to_json (nlohmann::json &j, const AudioClip &clip)
239 {
240 to_json (j, static_cast<const UuidIdentifiableObject &> (clip));
241 j[kNameKey] = clip.name_;
242 j[kFileHashKey] = clip.file_hash_;
243 j[kBpmKey] = clip.bpm_;
244 j[kBitDepthKey] = clip.bit_depth_;
245 j[kUseFlacKey] = clip.use_flac_;
246 j[kSamplerateKey] = clip.samplerate_;
247 }
248 friend void from_json (const nlohmann::json &j, AudioClip &clip)
249 {
250 from_json (j, static_cast<UuidIdentifiableObject &> (clip));
251 j.at (kNameKey).get_to (clip.name_);
252 j.at (kFileHashKey).get_to (clip.file_hash_);
253 j.at (kBpmKey).get_to (clip.bpm_);
254 j.at (kBitDepthKey).get_to (clip.bit_depth_);
255 j.at (kUseFlacKey).get_to (clip.use_flac_);
256 j.at (kSamplerateKey).get_to (clip.samplerate_);
257 }
258
268 void init_from_file (
269 const fs::path &full_path,
270 sample_rate_t project_sample_rate,
271 std::optional<bpm_t> bpm_to_set);
272
273private:
275 utils::Utf8String name_;
276
280 utils::audio::AudioBuffer ch_frames_;
281
285 bpm_t bpm_{};
286
291 sample_rate_t samplerate_{};
292
296 utils::audio::BitDepth bit_depth_{};
297
299 bool use_flac_{ false };
300
302 utils::hash::HashT file_hash_{};
303
309 unsigned_frame_t frames_written_{};
310
318 utils::MonotonicTime last_write_{};
319
324 std::unique_ptr<juce::AudioFormatWriter> writer_;
325 std::optional<fs::path> writer_path_;
326};
327
328using AudioClipResolverFunc =
329 std::function<AudioClip *(const AudioClip::Uuid &clip_id)>;
330using RegisterNewAudioClipFunc =
331 std::function<void (std::shared_ptr<AudioClip>)>;
332
333DEFINE_UUID_HASH_SPECIALIZATION (AudioClip::Uuid)
334
335
Audio clips for the pool.
Definition clip.h:25
bool verify_recorded_file(const fs::path &filepath, sample_rate_t project_sample_rate, bpm_t current_bpm) const
Used during tests to verify that the recorded file is valid.
std::unique_ptr< AudioClip > edit_in_ext_program()
Shows a dialog with info on how to edit a file, with an option to open an app launcher.
void expand_with_frames(const utils::audio::AudioBuffer &frames)
Expands (appends to the end) the frames in the clip by the given frames.
AudioClip(const utils::audio::AudioBuffer &buf, utils::audio::BitDepth bit_depth, sample_rate_t project_sample_rate, bpm_t current_bpm, const utils::Utf8String &name)
Creates an audio clip by copying the given buffer.
void replace_frames_from_interleaved(const float *frames, unsigned_frame_t start_frame, unsigned_frame_t num_frames_per_channel, channels_t channels)
Replaces the clip's frames starting from start_frame with frames.
void write_to_file(const fs::path &filepath, bool parts)
Writes the given audio clip data to a file.
bool enough_time_elapsed_since_last_write() const
Returns whether enough time has elapsed since the last write to file.
AudioClip(channels_t channels, unsigned_frame_t nframes, sample_rate_t project_sample_rate, bpm_t current_bpm, const utils::Utf8String &name)
Create an audio clip while recording.
AudioClip(const fs::path &full_path, sample_rate_t project_sample_rate, bpm_t current_bpm)
Creates an audio clip from a file.
AudioClip(const float *arr, unsigned_frame_t nframes, channels_t channels, zrythm::utils::audio::BitDepth bit_depth, sample_rate_t project_sample_rate, bpm_t current_bpm, const utils::Utf8String &name)
Creates an audio clip by copying the given interleaved float array.
Definition clip.h:69
void replace_frames(const utils::audio::AudioBuffer &src_frames, unsigned_frame_t start_frame)
Replaces the clip's frames starting from start_frame with frames.
void init_loaded(const fs::path &full_path)
Inits after loading a Project.
void finalize_buffered_write()
Finalizes buffered write to a file (when parts is true in write_to_file()).
void clear_frames()
Unloads the clip's frames from memory.
Definition clip.h:200
Lightweight UTF-8 string wrapper with safe conversions.
Definition string.h:39
Base class for objects that need to be uniquely identified by UUID.
RAII class to read and write audio files (or their metadata).
Definition audio_file.h:48
uint_fast64_t unsigned_frame_t
Unsigned type for frame index.
Definition types.h:83
uint32_t sample_rate_t
Sample rate.
Definition types.h:61
float bpm_t
The BPM type.
Definition types.h:73
uint_fast8_t channels_t
Number of channels.
Definition types.h:67
String utilities.
Definition algorithms.h:12