Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
file_audio_source.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/icloneable.h"
9#include "utils/monotonic_time_provider.h"
10#include "utils/units.h"
11#include "utils/uuid_identifiable_object.h"
12
13#include <juce_audio_formats/juce_audio_formats.h>
14
15namespace zrythm::dsp
16{
17
23class FileAudioSource final
24 : public QObject,
25 public utils::UuidIdentifiableObject<FileAudioSource>
26{
27 Q_OBJECT
28
29public:
30 using BitDepth = zrythm::utils::audio::BitDepth;
31 using AudioFile = zrythm::utils::audio::AudioFile;
32 using channels_t = uint_fast8_t;
33 using bpm_t = float;
34
35public:
36 FileAudioSource (QObject * parent = nullptr) : QObject (parent) { }
37
49 const std::filesystem::path &full_path,
50 units::sample_rate_t project_sample_rate,
51 bpm_t current_bpm,
52 QObject * parent = nullptr);
53
62 utils::audio::BitDepth bit_depth,
63 units::sample_rate_t project_sample_rate,
64 bpm_t current_bpm,
65 const utils::Utf8String &name,
66 QObject * parent = nullptr);
67
77 const float * arr,
78 units::sample_u64_t nframes,
79 channels_t channels,
80 zrythm::utils::audio::BitDepth bit_depth,
81 units::sample_rate_t project_sample_rate,
82 bpm_t current_bpm,
83 const utils::Utf8String &name,
84 QObject * parent = nullptr)
85 : FileAudioSource (
86 *utils::audio::AudioBuffer::
87 from_interleaved (arr, nframes.in (units::samples), channels),
88 bit_depth,
89 project_sample_rate,
90 current_bpm,
91 name,
92 parent)
93 {
94 }
95
106 channels_t channels,
107 units::sample_u64_t nframes,
108 units::sample_rate_t project_sample_rate,
109 bpm_t current_bpm,
110 const utils::Utf8String &name,
111 QObject * parent = nullptr);
112
113 // ========================================================================
114 // QML Interface
115 // ========================================================================
116
120 Q_SIGNAL void samplesChanged ();
121
122 // ========================================================================
123
124 auto get_bit_depth () const { return bit_depth_; }
125 auto get_name () const { return name_; }
126 auto get_bpm () const { return bpm_; }
127 const auto &get_samples () const { return ch_frames_; }
128 auto get_samplerate () const { return samplerate_; }
129
130 void set_name (const utils::Utf8String &name) { name_ = name; }
131
139
150 const utils::audio::AudioBuffer &src_frames,
151 units::sample_u64_t start_frame);
152
163 const float * frames,
164 units::sample_u64_t start_frame,
165 units::sample_u64_t num_frames_per_channel,
166 channels_t channels);
167
172 {
173 ch_frames_.setSize (ch_frames_.getNumChannels (), 0, false, true);
174 Q_EMIT samplesChanged ();
175 }
176
177 auto get_num_channels () const { return ch_frames_.getNumChannels (); };
178 auto get_num_frames () const { return ch_frames_.getNumSamples (); };
179
190 const std::filesystem::path &full_path,
191 units::sample_rate_t project_sample_rate,
192 std::optional<bpm_t> bpm_to_set);
193
194private:
195 friend void init_from (
196 FileAudioSource &obj,
197 const FileAudioSource &other,
198 utils::ObjectCloneType clone_type);
199
200 void convert_mono_to_stereo ();
201
202 static constexpr auto kNameKey = "name"sv;
203 static constexpr auto kBpmKey = "bpm"sv;
204 friend void to_json (nlohmann::json &j, const FileAudioSource &clip);
205 friend void from_json (const nlohmann::json &j, FileAudioSource &clip);
206
207private:
209 utils::Utf8String name_;
210
214 utils::audio::AudioBuffer ch_frames_;
215
219 bpm_t bpm_{};
220
225 units::sample_rate_t samplerate_;
226
230 utils::audio::BitDepth bit_depth_{};
231};
232
233// ========================================================================
234
239{
240public:
250 const FileAudioSource &source,
251 std::filesystem::path path,
252 bool parts);
253
262
268
274
275private:
279 bool parts_;
280
281 const FileAudioSource &source_;
282 std::unique_ptr<juce::AudioFormatWriter> writer_;
283 std::filesystem::path writer_path_;
284
290 units::sample_u64_t frames_written_;
291
299 utils::MonotonicTime last_write_{};
300};
301
302using FileAudioSourcePtrVariant = std::variant<FileAudioSource *>;
303using FileAudioSourceRegistry =
305using FileAudioSourceUuidReference =
307
308} // namespace zrythm::dsp
309
310DEFINE_UUID_HASH_SPECIALIZATION (zrythm::dsp::FileAudioSource::Uuid)
bool enough_time_elapsed_since_last_write() const
Returns whether enough time has elapsed since the last write to file.
void finalize_buffered_write()
To be called after the file has been written via write_file_buffered().
FileAudioSourceWriter(const FileAudioSource &source, std::filesystem::path path, bool parts)
Writes the given audio clip data to a file.
void write_to_file()
Write the file either in parts or whole (depending on constructor param).
Audio clips for the pool.
FileAudioSource(const utils::audio::AudioBuffer &buf, utils::audio::BitDepth bit_depth, units::sample_rate_t project_sample_rate, bpm_t current_bpm, const utils::Utf8String &name, QObject *parent=nullptr)
Creates an audio clip by copying the given buffer.
void clear_frames()
Unloads the clip's frames from memory.
void replace_frames(const utils::audio::AudioBuffer &src_frames, units::sample_u64_t start_frame)
Replaces the clip's frames starting from start_frame with frames.
FileAudioSource(channels_t channels, units::sample_u64_t nframes, units::sample_rate_t project_sample_rate, bpm_t current_bpm, const utils::Utf8String &name, QObject *parent=nullptr)
Create an audio clip while recording.
FileAudioSource(const float *arr, units::sample_u64_t nframes, channels_t channels, zrythm::utils::audio::BitDepth bit_depth, units::sample_rate_t project_sample_rate, bpm_t current_bpm, const utils::Utf8String &name, QObject *parent=nullptr)
Creates an audio clip by copying the given interleaved float array.
void init_from_file(const std::filesystem::path &full_path, units::sample_rate_t project_sample_rate, std::optional< bpm_t > bpm_to_set)
Initializes members from an audio file.
void replace_frames_from_interleaved(const float *frames, units::sample_u64_t start_frame, units::sample_u64_t num_frames_per_channel, channels_t channels)
Replaces the clip's frames starting from start_frame with frames.
void expand_with_frames(const utils::audio::AudioBuffer &frames)
Expands (appends to the end) the frames in the clip by the given frames.
FileAudioSource(const std::filesystem::path &full_path, units::sample_rate_t project_sample_rate, bpm_t current_bpm, QObject *parent=nullptr)
Creates an audio clip from a file.
Q_SIGNAL void samplesChanged()
Emitted when the source samples change.
A registry that owns and manages objects identified by a UUID.
Lightweight UTF-8 string wrapper with safe conversions.
Definition utf8_string.h:37
Base class for objects that need to be uniquely identified by UUID.
A reference-counted RAII wrapper for a UUID in a registry.
RAII class to read and write audio files (or their metadata).
Definition audio_file.h:44
String utilities.