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/types.h"
11#include "utils/units.h"
12#include "utils/uuid_identifiable_object.h"
13
14namespace zrythm::dsp
15{
16
22class FileAudioSource final
23 : public QObject,
24 public utils::UuidIdentifiableObject<FileAudioSource>
25{
26 Q_OBJECT
27
28public:
29 using BitDepth = zrythm::utils::audio::BitDepth;
30 using AudioFile = zrythm::utils::audio::AudioFile;
31
32public:
33 FileAudioSource (QObject * parent = nullptr) : QObject (parent) { }
34
46 const fs::path &full_path,
47 units::sample_rate_t project_sample_rate,
48 bpm_t current_bpm,
49 QObject * parent = nullptr);
50
59 utils::audio::BitDepth bit_depth,
60 units::sample_rate_t project_sample_rate,
61 bpm_t current_bpm,
62 const utils::Utf8String &name,
63 QObject * parent = nullptr);
64
74 const float * arr,
75 unsigned_frame_t nframes,
76 channels_t channels,
77 zrythm::utils::audio::BitDepth bit_depth,
78 units::sample_rate_t project_sample_rate,
79 bpm_t current_bpm,
80 const utils::Utf8String &name,
81 QObject * parent = nullptr)
82 : FileAudioSource (
83 *utils::audio::AudioBuffer::from_interleaved (arr, nframes, channels),
84 bit_depth,
85 project_sample_rate,
86 current_bpm,
87 name,
88 parent)
89 {
90 }
91
102 channels_t channels,
103 unsigned_frame_t nframes,
104 units::sample_rate_t project_sample_rate,
105 bpm_t current_bpm,
106 const utils::Utf8String &name,
107 QObject * parent = nullptr);
108
109 // ========================================================================
110 // QML Interface
111 // ========================================================================
112
116 Q_SIGNAL void samplesChanged ();
117
118 // ========================================================================
119
120 auto get_bit_depth () const { return bit_depth_; }
121 auto get_name () const { return name_; }
122 auto get_bpm () const { return bpm_; }
123 const auto &get_samples () const { return ch_frames_; }
124 auto get_samplerate () const { return samplerate_; }
125
126 void set_name (const utils::Utf8String &name) { name_ = name; }
127
135
146 const utils::audio::AudioBuffer &src_frames,
147 unsigned_frame_t start_frame);
148
159 const float * frames,
160 unsigned_frame_t start_frame,
161 unsigned_frame_t num_frames_per_channel,
162 channels_t channels);
163
168 {
169 ch_frames_.setSize (ch_frames_.getNumChannels (), 0, false, true);
170 Q_EMIT samplesChanged ();
171 }
172
173 auto get_num_channels () const { return ch_frames_.getNumChannels (); };
174 auto get_num_frames () const { return ch_frames_.getNumSamples (); };
175
186 const fs::path &full_path,
187 units::sample_rate_t project_sample_rate,
188 std::optional<bpm_t> bpm_to_set);
189
190private:
191 friend void init_from (
192 FileAudioSource &obj,
193 const FileAudioSource &other,
194 utils::ObjectCloneType clone_type);
195
196 static constexpr auto kNameKey = "name"sv;
197 static constexpr auto kBpmKey = "bpm"sv;
198 static constexpr auto kBitDepthKey = "bitDepth"sv;
199 static constexpr auto kSamplerateKey = "samplerate"sv;
200 friend void to_json (nlohmann::json &j, const FileAudioSource &clip)
201 {
202 to_json (j, static_cast<const UuidIdentifiableObject &> (clip));
203 j[kNameKey] = clip.name_;
204 j[kBpmKey] = clip.bpm_;
205 j[kBitDepthKey] = clip.bit_depth_;
206 j[kSamplerateKey] = clip.samplerate_;
207 }
208 friend void from_json (const nlohmann::json &j, FileAudioSource &clip)
209 {
210 from_json (j, static_cast<UuidIdentifiableObject &> (clip));
211 j.at (kNameKey).get_to (clip.name_);
212 j.at (kBpmKey).get_to (clip.bpm_);
213 j.at (kBitDepthKey).get_to (clip.bit_depth_);
214 j.at (kSamplerateKey).get_to (clip.samplerate_);
215 }
216
217private:
219 utils::Utf8String name_;
220
224 utils::audio::AudioBuffer ch_frames_;
225
229 bpm_t bpm_{};
230
235 units::sample_rate_t samplerate_;
236
240 utils::audio::BitDepth bit_depth_{};
241};
242
243// ========================================================================
244
249{
250public:
260 const FileAudioSource &source,
261 fs::path path,
262 bool parts);
263
272
278
284
285private:
289 bool parts_;
290
291 const FileAudioSource &source_;
292 std::unique_ptr<juce::AudioFormatWriter> writer_;
293 fs::path writer_path_;
294
300 unsigned_frame_t frames_written_{};
301
309 utils::MonotonicTime last_write_{};
310};
311
312using FileAudioSourcePtrVariant = std::variant<FileAudioSource *>;
313using FileAudioSourceRegistry =
314 utils::OwningObjectRegistry<FileAudioSourcePtrVariant, FileAudioSource>;
315using FileAudioSourceUuidReference =
316 utils::UuidReference<FileAudioSourceRegistry>;
317
318} // namespace zrythm::dsp
319
320DEFINE_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.
FileAudioSourceWriter(const FileAudioSource &source, fs::path path, bool parts)
Writes the given audio clip data to a file.
void finalize_buffered_write()
To be called after the file has been written via write_file_buffered().
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, unsigned_frame_t start_frame)
Replaces the clip's frames starting from start_frame with frames.
FileAudioSource(const fs::path &full_path, units::sample_rate_t project_sample_rate, bpm_t current_bpm, QObject *parent=nullptr)
Creates an audio clip from a file.
FileAudioSource(channels_t channels, unsigned_frame_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.
void expand_with_frames(const utils::audio::AudioBuffer &frames)
Expands (appends to the end) the frames in the clip by the given frames.
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.
FileAudioSource(const float *arr, unsigned_frame_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.
Q_SIGNAL void samplesChanged()
Emitted when the source samples change.
void init_from_file(const fs::path &full_path, units::sample_rate_t project_sample_rate, std::optional< bpm_t > bpm_to_set)
Initializes members from an audio file.
Lightweight UTF-8 string wrapper with safe conversions.
Definition utf8_string.h:38
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:78
float bpm_t
The BPM type.
Definition types.h:70
uint_fast8_t channels_t
Number of channels.
Definition types.h:64
String utilities.
Definition algorithms.h:12